





















































Hi ,
"It's the Most Wonderful Time of the Year🌟...It's the hap-happiest season of all" 🎵 - Andy Williams
Welcome to our very last issue, for the year 2024! We will be taking our usual year end break and return again on the 16th of January 2025. In the meanwhile, do keep any eye out. Packt x Santa🎅 are busy working on some unmissable deals for you to unwrap over the holidays! Now let's get down to business.
In today’sExpert Insight, we bring you an excerpt from the recently published book, Learn Python Programming - Fourth Edition, which demonstrates best practices for creating custom debugging functions in Python.
News Highlights:Python is set to win Tiobe's "Language of the Year" for its growth in AI and data mining; Go overtakes Node.js in API requests with a 40% rise; Google introduces Gemini 2.0 and AI coding agent Jules; and SQLite is re-implemented in Rust for async I/O and memory safety.
My top 5 picks from today’s learning resources:
But there’s more, so dive right in.
Before signing off, I would like to say thank you to all readers who have been on this journey with me this year. A very Merry Christmas and Wonderful New Year 2025 to you all!
Don't forget to Stay Awesome!
Divya Anne Selvaraj
Editor-in-Chief
Sum
method in .NET 8, leveraging SIMD principles and advanced techniques like loop unrolling.Directory.Packages.props
file.ErrorMessage
.io.github.xz-java:xz-java
, impersonating the legitimate XZ for Java
library (org.tukaani:xz
).@typescript_eslinter/prettier
, remains live, escalating the risk.testing/synctest
package in Go 1.24, designed to improve testing involving time and concurrency.Hash
and Hasher
traits for flexibility, highlighting inefficiencies in handling block-wise hashing, variable-length inputs, and more.UserService
from specific repository dependencies through a RepositoryManagerInterface
.puts
statements, interactive consoles, and advanced tools.Here’s an excerpt from “Chapter 11: Debugging and Profiling" in the book, Learn Python Programming - Fourth Edition by Fabrizio Romano and Heinrich Kruger, published in November 2024.
Having a custom debugging function saved in a file somewhere that you can quickly grab and paste into the code can be particularly useful. If you are fast, you can also code one on the fly. The important thing is to write it in such a
way that it will not leave anything behind when you eventually remove the calls and their definitions. Therefore, it is important to code it in a way that is completely self-contained. Another good reason for this requirement is that it will avoid potential name clashes with the rest of the code.
Let us see an example of such a function:
# custom.py
def debug(*msg, print_separator=True):
print(*msg)
if print_separator:
print("-" * 40)
debug("Data is ...")
debug("Different", "Strings", "Are not a problem")
debug("After while loop", print_separator=False)
$ python custom.py
Data is ...
----------------------------------------
Different Strings Are not a problem
----------------------------------------
After while loop
As you can see, there is no separator after the last line.
This is just one easy way to augment a simple call to theprint()
function. Let us see how we can calculate a time difference between calls, using one of Python’s tricky features to our advantage:
# custom_timestamp.py
from time import sleep
def debug(*msg, timestamp=[None]):
from time import time # local import
print(*msg)
if timestamp[0] is None:
timestamp[0] = time() # 1
else:
now = time()
print(f" Time elapsed: {now - timestamp[0]:.3f}s")
timestamp[0] = now # 2
debug("Entering buggy piece of code...")
sleep(0.3)
debug("First step done.")
sleep(0.5)
debug("Second step done.")
This is a bit more complicated. First, notice that we used animport
statementinsidethedebug()
function to import thetime()
function from thetime
module. This allows us to avoid having to add thatimport
outside the function and risk forgetting to remove it.
Look at how we definedtimestamp
. It is a function parameter with a list as its default value. InChapter 4,Functions, the Building Blocks of Code, we warned against using mutable defaults for parameters because the default value is initialized when Python parses the function, and the same object persists across different calls to the function. Most of the time, this is not the behavior you want. In this case, however, we are taking advantage of this feature to store a timestamp from the previous call to the function, without having to use an external global variable. We borrowed this trick from our studies onclosures, a technique that we encourage you to read about.
After printing the message, we inspect the content of the only item intimestamp
. If it isNone
, we have no previous timestamp, so we set the value to the current time (#1
). On the other hand, if we have a previous timestamp, we can calculate a difference (which we neatly format to three decimal digits), and finally, we put the current time intimestamp
(#2
).
Running this code outputs the following:
$ python custom_timestamp.py
Entering buggy piece of code...
First step done.
Time elapsed: 0.300s
Second step done.
Time elapsed: 0.500s
Using a custom debug function solves some of the problems associated with just usingprint()
. It reduces duplication of debugging code and makes it easier to remove all your debugging code when you no longer need it. However, it still requires modifying the code and running it in a console where you can inspect the output. Later in this chapter, we will see how we can overcome those difficulties by adding logging to our code.
Learn Python Programming - Fourth Editionwas published in Novemver 2024. Packt library subscribers can continue reading the entire book for free or you can buy the book here!
That’s all for today.
We have an entire range of newsletters with focused content for tech pros. Subscribe to the ones you find the most usefulhere.
If your company is interested in reaching an audience of developers, software engineers, and tech decision makers, you may want toadvertise with us.
If you have any suggestions or feedback, or would like us to find you a learning resource on a particular subject, just respond to this email!