Posted on Leave a comment

How to Print Without Newline in Python—A Simple Illustrated Guide

Summary: To print without the newline character in Python 3, set the end argument in the print() function to the empty string or the single whitespace character. This ensures that there won’t be a newline in the standard output after each execution of print(). Alternatively, unpack the iterable into the print() function to avoid the use of multiple print() statements: print(*iter).

Print Without Newline Python (End Argument)

Let’s go over this problem and these two solutions step-by-step.

Problem: How to use the print() function without printing an implicit newline character to the Python shell?

Example: Say, you want to use the print() function within a for loop—but you don’t want to see multiple newlines between the printed output:

for i in range(1,5): print(i)

The default standard output is the following:

1
2
3
4

But you want to get the following output in a single line of Python code.

1 2 3 4

How to accomplish this in Python 3?

Solution: I’ll give you the quick solution in an interactive Python shell here:

By reading on, you’ll understand how this works and become a better coder in the process.

Let’s have a quick recap of the Python print() function!

Python Print Function – Quick Start Guide

There are two little-used arguments of the print function in Python.

  • The argument sep indicates the separator which is printed between the objects.
  • The argument end defines what comes at the end of each line.

Related Article: Python Print Function [And Its SECRET Separator & End Arguments]

Consider the following example:

a = 'hello'
b = 'world' print(a, b, sep=' Python ', end='!')

Try it yourself in our interactive code shell:

Exercise: Click “Run” to execute the shell and see the output. What has changed?

Solution 1: End Argument of Print Function

Having studied this short guide, you can now see how to solve the problem:

To print the output of the for loop to a single line, you need to define the end argument of the print function to be something different than the default newline character. In our example, we want to use the empty space after each string we pass into the print() function. Here’s how you accomplish this:

for i in range(1,5): print(i, end=' ')

The shell output concentrates on a single line:

1 2 3 4 

By defining the end argument, you can customize the output to your problem.

Solution 2: Unpacking

However, there’s an even more advanced solution that’s more concise and more Pythonic. It makes use of the unpacking feature in Python.

print(*range(1,5))
# 1 2 3 4

The asterisk prefix * before the range(1,5) unpacks all values in the range iterable into the print function. This way, it becomes similar to the function execution print(1, 2, 3, 4) with comma-separated arguments. You can use an arbitrary number of arguments in the print() function.

Per default, Python will print these arguments with an empty space in between. If you want to customize this separator string, you can use the sep argument as you’ve learned above.

How to Print a List?

Do you want to print a list to the shell? Just follow these simple steps:

  • Pass a list as an input to the print() function in Python.
  • Use the asterisk operator * in front of the list to “unpack” the list into the print function.
  • Use the sep argument to define how to separate two list elements visually.

Here’s the code:

# Create the Python List
lst = [1, 2, 3, 4, 5] # Use three underscores as separator
print(*lst, sep='___')
# 1___2___3___4___5 # Use an arrow as separator
print(*lst, sep='-->')
# 1-->2-->3-->4-->5

Try It Yourself in Our Interactive Code Shell:

This is the best and most Pythonic way to print a Python list. If you still want to learn about alternatives—and improve your Python skills in the process of doing so—read the following tutorial!

Related Article: Print a Python List Beautifully [Click & Run Code]

Where to Go From Here?

Enough theory, let’s get some practice!

To become successful in coding, you need to get out there and solve real problems for real people. That’s how you can become a six-figure earner easily. And that’s how you polish the skills you really need in practice. After all, what’s the use of learning theory that nobody ever needs?

Practice projects is how you sharpen your saw in coding!

Do you want to become a code master by focusing on practical code projects that actually earn you money and solve problems for people?

Then become a Python freelance developer! It’s the best way of approaching the task of improving your Python skills—even if you are a complete beginner.

Join my free webinar “How to Build Your High-Income Skill Python” and watch how I grew my coding business online and how you can, too—from the comfort of your own home.

Join the free webinar now!

Posted on Leave a comment

Python One Line And/Or

How do the Boolean and and or operators work in the context of Python one-liners?

You may know the standard use of the logical operators applied to Boolean values:

>>> True and False
False
>>> False or True
True

But there’s more to these operators that only experts in the art of writing concise Python one-liners know.

For instance, the following use of the or operator applied to non-Boolean values is little known:

>>> 'hello' or 42 'hello'
>>> [] or 42
42

Similarly, the following use of the and operator often causes confusion in readers of advanced Python one-liners:

>>> 'hello' and 42
42
>>> [] and 42
[]

How do the and and or operator work when applied to non-Boolean operands?

To understand what is going on, you need to look at the definitions of the Boolean operators:

Operator Description
a or b Returns b if the expression a evaluates to False using implicit Boolean conversion. If the expression a evaluates to True, the expression a is returned.
a and b Returns b if the expression a evaluates to True using implicit Boolean conversion. If the expression a evaluates to False, the expression a is returned.

Study these explanations thoroughly! The return value is of the same data type of the operands—they only return a Boolean value if the operands are already Boolean!

This optimization is called short-circuiting and it’s common practice in many programming languages. For example, it’s not necessary to evaluate the result of the second operand of an and operation if the first operand evaluates to False. The whole operation must evaluate to False in this case because the logical and only returns True if both operands are True.

Python goes one step further using the property of implicit Boolean conversion. Every object can be implicitly converted to a Boolean value. That’s why you see code like this:

l = []
if l: print('hi')
else: print('bye')
# bye

You pass a list into the if condition. Python then converts the list to a Boolean value to determine which branch to visit next. The empty list evaluates to False. All other lists evaluate to True, so the result is bye.

Together, short circuiting and implicit Boolean conversion allow the logical operators and and or to be applied to any two Python objects as operands. The return value always is one of the two operands using the short circuiting rules described in the table.

Try it yourself in our interactive code shell:

Exercise: Guess the output! Then check if you were right! Create your own crazy operands and evaluate them by executing the code in your browser.

Python One-Liners Book

Python programmers will improve their computer science skills with these useful one-liners.

Python One-Liners

Python One-Liners will teach you how to read and write “one-liners”: concise statements of useful functionality packed into a single line of code. You’ll learn how to systematically unpack and understand any line of Python code, and write eloquent, powerfully compressed Python like an expert.

The book’s five chapters cover tips and tricks, regular expressions, machine learning, core data science topics, and useful algorithms. Detailed explanations of one-liners introduce key computer science concepts and boost your coding and analytical skills. You’ll learn about advanced Python features such as list comprehension, slicing, lambda functions, regular expressions, map and reduce functions, and slice assignments. You’ll also learn how to:

  Leverage data structures to solve real-world problems, like using Boolean indexing to find cities with above-average pollution
  Use NumPy basics such as array, shape, axis, type, broadcasting, advanced indexing, slicing, sorting, searching, aggregating, and statistics
  Calculate basic statistics of multidimensional data arrays and the K-Means algorithms for unsupervised learning
  Create more advanced regular expressions using grouping and named groups, negative lookaheads, escaped characters, whitespaces, character sets (and negative characters sets), and greedy/nongreedy operators
  Understand a wide range of computer science topics, including anagrams, palindromes, supersets, permutations, factorials, prime numbers, Fibonacci numbers, obfuscation, searching, and algorithmic sorting

By the end of the book, you’ll know how to write Python at its most refined, and create concise, beautiful pieces of “Python art” in merely a single line.

Get your Python One-Liners Now!!

Posted on Leave a comment

Python Small Integer Caching: == versus is

This interesting code snippet was brought to my attention by Finxter reader Albrecht.

a, b = 250, 250
for i in range(250, 260): if a is not b: break a += 1 b += 1
print(a)
# What's the output of this code snippet?

You’d guess that the for loop goes from i=250 to i=259, each time incrementing a and b. As Python creates one integer object to which both names refer, the command a is not b should always be False. Thus, the result is a=259, right?

WRONG!!! $%&&%$

Try it yourself in our interactive code shell:

Exercise: Run the code and check the result. Did you expect this?

The result is a=257.

The reason is an implementation detail of the CPython implementation called “Small Integer Caching” — the internal cache of integers in Python.

If you create an integer object that falls into the range of -5 to 256, Python will only return a reference to this object — which is already cached in memory.

“The current implementation keeps an array of integer objects for all integers between -5 and 256, when you create an int in that range you actually just get back a reference to the existing object.”

Python Docs

You can visualize the code execution in this interactive memory visualizer:

Exercise: Click next until you see the result. How many integers are in memory?

Let’s quickly examine the meaning of “is” in Python.

The is operator

The is operator checks if two variable names point to the same object in memory:

>>> a = "hello"
>>> b = "hello"
>>> a is b
True

Both variables a and b point to the string "hello". Python doesn’t store the same string twice but creates it only once in memory. This saves memory and makes Python faster and more efficient. And it’s not a problem because strings are immutable — so one variable cannot “overshadow” a string object of another variable.

Note that we can use the id() function to check an integer representation of the memory address:

>>> a = "hello"
>>> b = "hello"
>>> id(a)
1505840752992
>>> id(b)
1505840752992

They both point to the same location in memory! Therefore, the is operator returns True!

Small Integer Caching

Again, if you create an integer object that falls into the range of -5 to 256, Python will only return a reference to this object — which is already cached in memory. But if we create an integer object that does not fall into this range, Python may return a new integer object with the same value.

If we now check a is not b, Python will give us the correct result True.

In fact, this leads to the strange behavior of the C implementation of Python 3:

>>> a = 256
>>> b = 256
>>> a is b
True
>>> a = 257
>>> b = 257
>>> a is b
False

Therefore, you should always compare integers by using the == operator in Python. This ensures that Python performs a semantic comparison, and not a mere memory address comparison:

>>> a = 256
>>> b = 256
>>> a == b
True
>>> a = 257
>>> b = 257
>>> a == b
True

What can you learn from this? Implementation details matter!

Where to Go From Here?

Enough theory, let’s get some practice!

To become successful in coding, you need to get out there and solve real problems for real people. That’s how you can become a six-figure earner easily. And that’s how you polish the skills you really need in practice. After all, what’s the use of learning theory that nobody ever needs?

Practice projects is how you sharpen your saw in coding!

Do you want to become a code master by focusing on practical code projects that actually earn you money and solve problems for people?

Then become a Python freelance developer! It’s the best way of approaching the task of improving your Python skills—even if you are a complete beginner.

Join my free webinar “How to Build Your High-Income Skill Python” and watch how I grew my coding business online and how you can, too—from the comfort of your own home.

Join the free webinar now!

Posted on Leave a comment

[Collection] URL Decoding Methods

URL encoding “is a method to encode information in a Uniform Resource Identifier (URI)”. It is also called Percent-encoding because percentage symbols are used to encode certain reserved characters:

! # $ % & ' ( ) * + , / : ; = ? @ [ ]
%21 %23 %24 %25 %26 %27 %28 %29 %2A %2B %2C %2F %3A %3B %3D %3F %40 %5B %5D

This article collects various ways to decode an URL encoded string. Let’s get started!

Python 2

$ alias urldecode='python -c "import sys, urllib as ul; \ print ul.unquote_plus(sys.argv[1])"' $ alias urlencode='python -c "import sys, urllib as ul; \ print ul.quote_plus(sys.argv[1])"'

Source

Here’s an example usage:

$ urldecode 'q+werty%3D%2F%3B'
q werty=/; $ urlencode 'q werty=/;'
q+werty%3D%2F%3B

Python 3

$ alias urldecode='python3 -c "import sys, urllib.parse as ul; \ print(ul.unquote_plus(sys.argv[1]))"' $ alias urlencode='python3 -c "import sys, urllib.parse as ul; \ print (ul.quote_plus(sys.argv[1]))"'

Here’s an example usage:

$ urldecode 'q+werty%3D%2F%3B'
q werty=/; $ urlencode 'q werty=/;'
q+werty%3D%2F%3B

Source

sed

$ sed 's@+@ @g;s@%@\\x@g' file | xargs -0 printf "%b"

Source

sed with echo -e

$ sed -e's/%\([0-9A-F][0-9A-F]\)/\\\\\x\1/g' file | xargs echo -e

Source

sed with alias

For convenience, you may want to use an alias:

$ alias urldecode='sed "s@+@ @g;s@%@\\\\x@g" | xargs -0 printf "%b"'

If you want to decode, you can now simply use:

$ echo "http%3A%2F%2Fwww" | urldecode
http://www

Source

Bash

input="http%3A%2F%2Fwww"
decoded=$(printf '%b' "${input//%/\\x}")

Source

To handle pluses (+) correctly, replace them with spaces using sed:

decoded=$(input=${input//+/ }; printf "${input//%/\\x}")

Bash + urlencode() + urldecode() Functions

urlencode() { # urlencode <string> local length="${#1}" for (( i = 0; i < length; i++ )); do local c="${1:i:1}" case $c in [a-zA-Z0-9.~_-]) printf "$c" ;; *) printf '%%%02X' "'$c" ;; esac done
} urldecode() { # urldecode <string> local url_encoded="${1//+/ }" printf '%b' "${url_encoded//%/\\x}"
}

Sources:

bash + xxd

urlencode() { local length="${#1}" for (( i = 0; i < length; i++ )); do local c="${1:i:1}" case $c in [a-zA-Z0-9.~_-]) printf "$c" ;; *) printf "$c" | xxd -p -c1 | while read x;do printf "%%%s" "$x";done esac
done
}

Sources:

PHP

$ echo oil+and+gas | php -r 'echo urldecode(fgets(STDIN));' // Or: php://stdin
oil and gas

Source

PHP Library

php -r 'echo urldecode("oil+and+gas");'

Source

Perl

decoded_url=$(perl -MURI::Escape -e 'print uri_unescape($ARGV[0])' "$encoded_url")

Source

Perl to Process File

perl -i -MURI::Escape -e 'print uri_unescape($ARGV[0])' file

Source

awk

awk -niord '{printf RT?$0chr("0x"substr(RT,2)):$0}' RS=%..

Sources:

Python 2 urllib.unquote

The urllib.unquote is a special function in Python’s built-in standard library urllib that does what you need:

decoded_url=$(python2 -c 'import sys, urllib; print urllib.unquote(sys.argv[1])' "$encoded_url")

You can also use it to modify a file:

python2 -c 'import sys, urllib; print urllib.unquote(sys.stdin.read())' <file >file.new &&
mv -f file.new file

Source: https://unix.stackexchange.com/questions/159253/decoding-url-encoding-percent-encoding

Python 3 urllib.parse.unquote

If you run Python 3 on your system (like most people would), use the alternative function urllib.parse.unquote. To check your version, visit this article.

decoded_url=$(python3 -c 'import sys, urllib.parse; print(urllib.parse.unquote(sys.argv[1]))' "$encoded_url")

Again, you can use the function to process a file as follows:

python3 -c 'import sys, urllib; print(urllib.parse.unquote(sys.stdin.read()))' <file >file.new &&
mv -f file.new file

Source: https://unix.stackexchange.com/questions/159253/decoding-url-encoding-percent-encoding

Perl URI::Escape

The URI::Escape solves the problem of URL decoding for Perl users.

decoded_url=$(perl -MURI::Escape -e 'print uri_unescape($ARGV[0])' "$encoded_url")

You can use the function to process a file as follows:

perl -i -MURI::Escape -e 'print uri_unescape($ARGV[0])' file

Source: https://unix.stackexchange.com/questions/159253/decoding-url-encoding-percent-encoding

Perl One-Liner Without Installing Modules

$ perl -pe 's/\%(\w\w)/chr hex $1/ge'

Here’s a usage example:

$ echo '%21%22' | perl -pe 's/\%(\w\w)/chr hex $1/ge'
!"

Source: https://unix.stackexchange.com/questions/159253/decoding-url-encoding-percent-encoding

Bash Regex

$ function urldecode() { : "${*//+/ }"; echo -e "${_//%/\\x}"; }

Now, you can use the function as a command like this:

$ urldecode https%3A%2F%2Fgoogle.com%2Fsearch%3Fq%3Durldecode%2Bbash
https://google.com/search?q=urldecode+bash

If you need to assign some variables, use this strategy:

$ x="http%3A%2F%2Fstackoverflow.com%2Fsearch%3Fq%3Durldecode%2Bbash"
$ y=$(urldecode "$x")
$ echo "$y"
http://stackoverflow.com/search?q=urldecode+bash

Source: https://stackoverflow.com/questions/6250698/how-to-decode-url-encoded-string-in-shell

GNU Awk

#!/usr/bin/awk -fn
@include "ord"
BEGIN { RS = "%.."
}
{ printf "%s", $0 if (RT != "") { printf "%s", chr("0x" substr(RT, 2)) }
}

Source: https://stackoverflow.com/questions/6250698/how-to-decode-url-encoded-string-in-shell

References

Posted on Leave a comment

Python One Line to Multiple Lines

To break one line into multiple lines in Python, use an opening parenthesis in the line you want to break. Now, Python expects the closing parenthesis in one of the next lines and the expression is evaluated across line boundaries. As an alternative, you can also use the backslash \ just in front of the line break to escape the newline character.

After publishing an article on how to condense multiple lines into a single line of Python code, many Finxters asked: How to break a long line to multiple lines in Python? This article shows you the best way of breaking a long-winded one-liner into multiple lines to improve readability and unclutter your code.

Problem: Given a long line of Python code. How to break it into multiple lines?

There are multiple ways of breaking this into multiple lines. Let’s get an overview first:

Exercise: Run the code. What’s the output? Modify Method 3 and write it as a one-liner again!

We now dive into each of those methods.

Method 1: Implicit Line Continuation — Use Parentheses to Avoid Line Break Backslashes

Break a Long Line to Multiple Lines Python

The PEP 8 – Style Guide argues that the best way to break long lines into multiple lines of code is to use implicit line continuation by using parentheses. An opening parenthesis signals to Python that the expression has not finished, yet. So, the Python interpreter keeps looking in the following line to close the currently open expression. This way, you can rewrite any Python one-liner to a multi-liner just by using one or more pairs of parentheses.

Here’s the original statement from the PEP 8 style guide (emphasis by me):

The preferred way of wrapping long lines is by using Python’s implied line continuation inside parentheses, brackets and braces. If necessary, you can add an extra pair of parentheses around an expression, but sometimes using a backslash looks better. Make sure to indent the continued line appropriately.

Do you need an example for implicit line continuation? Here it is:

# Long Line
a = list(zip(['Alice', 'Bob', 'Liz', 'Ann'], [18, 24, 19, 16])) # Implicit Line Continuation
b = list(zip(['Alice', 'Bob', 'Liz', 'Ann'], [18, 24, 19, 16])) print(a)
# [('Alice', 18), ('Bob', 24), ('Liz', 19), ('Ann', 16)] print(b)
# [('Alice', 18), ('Bob', 24), ('Liz', 19), ('Ann', 16)]

The long line a = list(zip(['Alice', 'Bob', 'Liz', 'Ann'], [18, 24, 19, 16])) zips together two lists to obtain the result [('Alice', 18), ('Bob', 24), ('Liz', 19), ('Ann', 16)]. You can rewrite this into multiple lines by using the existing parentheses. Note that it is good style to hierarchically align the lines in Python. In our example, the two lists are aligned when creating the multi-line statement to assign the variable b.

Remember: you can always break lines if an opened bracket, parenthesis, or bracelet has not been closed!

Method 2: Explicit Line Continuation — Use the Line Break Backslash \

However, what if you don’t want to introduce new parentheses into your expression? Can you still break up a one-liner into multiple lines?

The answer is: yes! Just use the line break backslash \ which you may call explicit line continuation. With the backslash, you can break at any position in your expression. Technically, the backslash character “escapes” the newline character that follows immediately afterwards. By escaping the newline character, it loses its meaning and Python simply ignores it. This way, you don’t have to introduce any new parentheses.

Here’s a minimal example that shows the flexibility with which you can break new lines this way:

a = 1 + 2 + 3 + 4 - 5 * 2 b = 1 \ + 2 + \ 3 + 4\ - 5 *\ 2 print(a)
# 0 print(b)
# 0

Seeing the messy code in the previous example may cause you to ask:

Should a Line Break Before or After a Binary Operator?

I’ll give the following answer based on the PEP 8 Style Guide (highlights by me):

For decades the recommended style was to break after binary operators. But this can hurt readability in two ways:

  • the operators tend to get scattered across different columns on the screen, and
  • each operator is moved away from its operand and onto the previous line.

Here, the eye has to do extra work to tell which items are added and which are subtracted:

# Wrong:
results = (variable1 + variable2 + (variable3 - variable4) - variable5 - variable6)

To solve this readability problem, mathematicians and their publishers follow the opposite convention.

Donald Knuth explains the traditional rule in his Computers and Typesetting series: “Although formulas within a paragraph always break after binary operations and relations, displayed formulas always break before binary operations” [3].

Thus, the following code is proposed:

# Correct:
results = (variable1 + variable2 + (variable3 - variable4) - variable5 - variable6)

You can do both in Python but you should prefer the latter to improve readability of your code!

Method 3: Break a String by Using a Multi-Line String with Triple Quotes

Example: Say, you have the following long string from Romeo and Juliet:

s = 'Mistress! what, mistress! Juliet! fast, I warrant her, she:\n Why, lamb! why, lady! fie, you slug-a-bed!\n Why, love, I say! madam! sweet-heart! why, bride!\n What, not a word? you take your pennyworths now;\n Sleep for a week; for the next night, I warrant'

Note the newline character in the string: it’s really a multip-line string! Can you rewrite this into multiple lines to improve readability?

You can restructure strings by using the triple quotes that allows you to define a multi-line string without the newline character '\n' in the string. This significantly improves readability of multi-line strings! Here’s an example:

s1 = 'Mistress! what, mistress! Juliet! fast, I warrant her, she:\n Why, lamb! why, lady! fie, you slug-a-bed!\n Why, love, I say! madam! sweet-heart! why, bride!\n What, not a word? you take your pennyworths now;\n Sleep for a week; for the next night, I warrant' # MULTI-LINE
s2 = '''Mistress! what, mistress! Juliet! fast, I warrant her, she: Why, lamb! why, lady! fie, you slug-a-bed! Why, love, I say! madam! sweet-heart! why, bride! What, not a word? you take your pennyworths now; Sleep for a week; for the next night, I warrant''' print(s1 == s2)
# True

These are two ways of defining the same string. If you compare them, the result is True. However, the second way is far more readable and should be preferred!

Where to Go From Here?

Enough theory, let’s get some practice!

To become successful in coding, you need to get out there and solve real problems for real people. That’s how you can become a six-figure earner easily. And that’s how you polish the skills you really need in practice. After all, what’s the use of learning theory that nobody ever needs?

Practice projects is how you sharpen your saw in coding!

Do you want to become a code master by focusing on practical code projects that actually earn you money and solve problems for people?

Then become a Python freelance developer! It’s the best way of approaching the task of improving your Python skills—even if you are a complete beginner.

Join my free webinar “How to Build Your High-Income Skill Python” and watch how I grew my coding business online and how you can, too—from the comfort of your own home.

Join the free webinar now!

Posted on Leave a comment

The 80/20 Principle in Programming

In this article, you’ll learn about the profound impact of the 80/20 principle on your life as a programmer. It’s based on a first draft of a chapter from my upcoming book “From 1 to 0: A Minimalistic Approach to Programming”.

The 80/20 principle has many names but the second most famous is the Pareto principle, named after his discoverer Vilfredo Pareto. So, how does the principle work and why should you care?

Pareto Principle Basics

The principle says that the majority of effects come from the minority of causes. For example, the majority of income is earned by the minority of people, the majority of innovations come from the minority of researchers, the majority of books is written by the minority of authors, the majority of the sales come from a minority of the clients, and the majority of goals are shot by the minority of soccer players.

Most likely, you’ve already heard about the 80/20 principle—it’s everywhere in personal productivity literature. The reason for its popularity is two-fold. First, the principle allows you to be lazy and productive at the same time—if you can figure out the things that matter and focus on those relentlessly. Second, the principle is observable everywhere in the real world. It’s very difficult to even come up with some phenomenon where the effects come equally from the causes. Go ahead and try to find some examples of 50/50 distributions where 50% of the effects come from 50% of causes! Sure, the distribution is not always 80/20. The concrete numbers can change to 70/30, 90/10, or even 95/5. However, the distribution is always heavily skewed towards the minority of the causes that produce the majority of effects.

Here’s an example of a Pareto distribution:

Figure: Example of a Pareto distribution: the causes are ordered according to the results they produce.

You can see the mathematical plot of a Pareto distribution that plots the generalized results against the causes—assuming the causes are ordered according to the results they produce.

Application Software Optimization

The following figure shows the application of the Pareto distribution to a software project: the minority of the code is responsible for the majority of the runtime. The x-axis shows code functions sorted by the runtime they incur. The y-axis shows the runtime of those code functions. The units don’t really matter here, but you should realize that the shaded area dominates the overall area under the plot. Most code functions contribute much less to the overall runtime than a few selected code functions. Spending a lot of time optimizing the “trivial many” barely produces any improvement of the overall runtime.

Figure: Example of a Pareto distribution in software engineering: most functions contribute little to the overall runtime but some functions contribute heavily.

While the principle is easily understandable, most people don’t intuitively understand the relevance of the principle in their own lives. How can you make use of the principle to get more done in less time?

Few people know that the principle was successfully employed by large computing companies such as IBM, Microsoft, and Apple to build computers that feel much faster and to create a user experience that has previously been unheard of. How did they do this? They channeled their focus on the “Top 20%”—by repeatedly optimizing the 20% of the code that was executed most often by the average user. Not all code is created equal. A minority of code has a dominating impact on the user experience while much of the code has little impact on it. For example, you double-click on an icon multiple times per day—programs should load very fast for great user experience—but you change the access rights of a file only seldomly, if at all. The 80/20 principle tells you where to focus your optimization efforts!

Productivity

In fact, the 80/20 principle is a principle of focus. By focusing on the vital few rather than the trivial many, you can 10x, even 100x your productivity at work. Don’t believe me? Let’s calculate where these numbers come from, assuming an underlying 80/20 distribution.

Figure: The average output of the 20% top performers is 16x the average output of the 80% bottom performers.

The real world tells us that a minority of people produces the majority of results. This fundamental principle is observable in a wide variety of different applications. Let’s plug in some numbers to get an intuition how large the performance difference is. For instance, let’s use the conservative 80/20 parameters: 80% of the results come from 20% of the people. In some fields (like programming), the distribution is probably much more skewed.

The previous figure shows that in a company of 10 persons, only two persons produce 80% of the results while eight produce 20% of the results—a direct consequence of the 80/20 principle.  If you divide 80% by two, you get an average output of 40% per top-performing person in the company. At the same time, if you divide the 20% of results generated by the eight persons, you obtain an average of 2.5% per bottom-performing person. The difference in performance is 16x!

And note that this is not a theoretical difference that could be achieved under some impractical settings—this 16x difference in average performance is already a fact in millions of organizations throughout the world.

The performance difference exists: there are two persons in your organization who create more than 10x higher output than a “normal” employee. The question is: how can you become one of those two? Or, to formulate it more generally: how can you “move to the left” on the Pareto distribution curve in your organization (see figure)?

Figure: To create more output, you need to constantly move to the left of the curve.

On the y-axis in our 80/20 world, I used the label “Output” to keep it general. You may want to optimize for income (20% of the people earn 80% of the incomes). You may want to optimize for happiness (20% of the people enjoy 80% of the happiness at work). You may want to optimize for monthly active users (20% of the websites have 80% of the monthly active users). You may want to optimize for book sales (20% of the books receive 80% of the sales). Or you may want to optimize for citations (20% of the researchers receive 80% of the citations).

This shows a critical take-away that follows from the 80/20 principle: be clear what you want to optimize.

Success Metrics

Let’s say, we want to optimize for income as a proxy for happiness. How can you move to the left in the Pareto curve?

Now, you’re leaving exact science because you need to find the reasons why some people succeed: which of their expertise generates most of the success? You need to find a plausible, simplifying argument in your specific industry and develop actionable success metrics you can control. If you do more of them, you’ll become more successful. If you do less of them, you’ll become less successful. The tricky thing is that the success metrics are different in most fields. In fact, the 80/20 principle also applies to success metrics: some success metrics have a dominating impact on your performance in a field, while others barely matter at all.

For example, when working as a doctoral researcher, I soon realized that it’s all about citations. The more citations you have as a researcher, the more credibility, visibility, and opportunities you’ll experience in science. How can we influence citations (“today, I’ll increase the number of citations” is hardly an actionable success metric)? Citations come from high-class papers. If you publish more high-class papers, you’ll receive more citations. So, writing high-class papers is the most important activity for most scientists. However, many researchers get distracted by secondary activities such as preparing presentations, organizing, teaching, drinking coffee, the most successful researchers focus heavily on generating a maximal number of high-quality papers. For researchers, the Pareto distribution of the success metric for researchers may look like this:

Figure: Success metric in research: number of words written towards high-class paper.

By replacing the generalized “Output” with the new success metric “Number of words written towards high-class paper”, you have gained crystal clear insight into what you must do every day to push towards the left in research. If you write more words today, you’ll publish your next high-class paper sooner, receive more citations faster, grow your scientific footprint, and become a more successful scientist as a result. The beauty of this 80/20 approach is that it allows you to find your focus. Everything else doesn’t matter. You can relax, lean back, and focus on the things that are very important. You can spend less time on all the different tasks. You don’t have to die the death of a thousand cuts. You can be lazy with all activities but one: writing papers. You can blend most things out, ignore emails, don’t go to meetings that don’t push you to more papers, be lazy in all the other activities. Say, you work 8h per day and you spread your day into eight one-hour activities. After completing the success metric exercise, you realize that you can skip two 1h activities per day and reduce four of them by half to complete them in half an hour instead of an hour (being less perfectionistic). You have saved 4h per day but you still accomplish, say, 80% of your results. Now, you invest 2h into writing more words towards high-class papers per day. Within a few months, you’ll have submitted an extra paper and over time, you’ll submit much more papers than any other of your colleague. You work only 6h per day and you generate imperfect quality in most of your work tasks. But you shine on where it matters: you submit more research papers than anyone else in your environment. As a result, you’ll soon be one of the top 20% of researchers. You generate more with less.

This is the power of 80/20 thinking: you invest resources where they have the highest leverage. You create more results by investing less time, effort, money. You become lazy in most things in life. But you focus some of the saved time, energy, and money on the ones that are wildly important. Instead of becoming a “Jack of all trades, master of none”, you become a one-trick pony. You heavily focus on the vital few and ignore the trivial many. You lead a less stressful life, but you enjoy more fruits from your invested labor, efforts, time, and money.

Pareto Implications for Coders

Let’s consider another example: if you’re reading this book, you’re a programmer. In programming, the results are much more heavily skewed towards the top than in most other fields. Instead of 80/20, the distribution often looks more like 90/10. Bill Gates said that a “great lathe operator commands several times the wage of an average lathe operator, but a great writer of software code is worth 10,000 times the price of an average software writer”. Bill Gates has overseen hundreds of thousands of programmers and software developers and if he makes this statement, it must have some merit. Interestingly, the difference is not 16x like you’ve seen previously. The difference between a great and an average software writer is 10,000x! How can this be? Well, here are a number of reasons why this extreme Pareto distribution holds especially in the software world:

  • A great programmer can solve some problems that the average programmer simply cannot solve. In some instances, this makes him infinitely-times more productive.
  • A great programmer can write code that is 10,000 times faster than the code of an average programmer. This can make or break the viability of a whole product line of a billion-dollar company.
  • A great programmer will write code that has fewer bugs. Think about the effect of a single security bug on Microsoft’s reputation and brand!
  • A great programmer will write code that is easier to extend which may improve the productivity of thousands of developers that work on his code at a later stage of the software developing process.
  • A great programmer will think out of the box and find creative solutions to circumvent costly development efforts and help focus on the most important things.

Each of the previously stated arguments show why a great software developer can be 10,000 times more productive. In practice, a combination of those factors is at play so that the difference can be even higher.

The key question is: how do you become a great programmer? Because if you can become a great programmer, you’ll always have much more work than you can handle, and the most successful companies in the world—Google, Facebook, Amazon, Apple, and Microsoft—will be happy to pay you big premiums for your services.

A Success Metric for Programmers

Unfortunately, the statement “become a great programmer” is not a success metric you can directly optimize—it’s a multi-dimensional problem. A great programmer can mean a lot of things. He or she understands code quickly, knows algorithms and data structures, knows different technologies and their strengths and weaknesses, can collaborate with other people, is communicative and creative, stays educated and knows about ways to organize the software development process, and possesses hundreds of soft- and hard-skills. But you cannot master all of those! If you don’t focus on the vital few, you’ll become enslaved by the trivial many. To become a great programmer, you must focus on the vital few. One of those vital few activities that will ensure that you become a better coder over time is the success metric “write more lines of code”. If you write more lines of code than your peers, you’ll become a better coder than most of your peers. It’s a simplification of the multi-dimensional problem but we simplified towards the vital few—by optimizing the proxy metric “write more lines of code”, we increased our odds of succeeding at the target metric “become a great writer of software code” (see figure).

Figure: Success metric in programming: number of lines of code written.

By writing more code, you create a self-reinforcing feedback loop. By writing more code, you begin to understand code better. You talk and behave more like an expert coder. You attract better coders and more challenging programming tasks, so you write more code and become even better. You get paid more and more per line of code you write, thus, it makes economic sense to write more code instead of doing housework or doing tedious non-programming tasks at work. You or your company outsource everything else. The more you code, the more successful you’ll become. Here you have the 80/20 activity you can follow every day: track the number of lines you code every day and optimize it. Make it a game to at least match your average every day. If you code more, you’ll ultimately join the top 10% of coders with income levels far above six figures.

Relationship Between Focus and the Pareto Distribution

A closely related topic I want to discuss is focus. The 80/20 principle explains why focus is so powerful. Let’s dive into the argument!

Consider the Pareto distribution in the next figure that shows the percentage improvement of moving towards the top of the distribution. Alice is the fifth most productive person in the organization. If she just overtakes one person in the organization, thereby becoming the fourth most productive person, she’d increase her output (e.g., salary) by 10%. If she moves one step further, her output increases by additional 20%. Think about this: even if she could keep increasing her income by 10% repeatedly, this would be great because she would experience superlinear growth. But in a Pareto-distribution, the growth per rank explodes. This is why even small increases of productivity can result in big increases of income. If you can move towards the top 10% in any Pareto distribution, you’ll be a wildly successful person with massive results in your life. It doesn’t matter if you’re a golfer, Poker player, programmer, or machine learning engineer. Increasing your productivity leads to super-linear improvements of your income, happiness, and joy at work. Some call this phenomenon: the winner takes it all.

Figure: Disproportional benefit of improving your rank in a Pareto distribution.

That’s why it doesn’t pay not to focus: if you don’t focus, you participate in many pareto distributions. Let’s consider the following graphic of two persons: Alice and Bob. Both have three units learning efforts every day. Alice focuses on one thing: programming. She’s neither a good chess player, nor a good golfer, nor good at politics. She just spends three units of efforts in learning to code. Bob spreads his focus to multiple disciplines. He spends one unit of time polishing his chess skills, one unit training his programming skills, and one unit training his politics skills. As a result, he’s reached average skills and output in each of the three areas. However, due to the nature of the Pareto distribution to disproportionally reward the winners in any Pareto distribution, Alice collects more total output (e.g., income or happiness) than Bob through her focusing strategy.

Figure: Non-linearity of rank output – A strategic explanation attempt for the power of focus.

Note that this holds true not only across broad and independent areas such as programming, chess, and politics. It also applies within narrow areas such as programming. For instance, Bob may spend his time reading three general books (let’s call them: Introduction to Python, Introduction to C++, and Introduction to Java) while Alice reads three books diving deep into Python (let’s call them: Introduction to Python, Introduction to Machine Learning with Python, and Machine Learning for Experts).  As a result, Alice will focus in becoming a machine learning expert and can demand a higher salary for her specialized skill set.

Github Contributions

Another example for a Pareto distribution gone extreme can be seen in contributions to Github repositories. There’s scientific evidence that contributions to open-source projects are Pareto distributed.[1] Let’s consider a wildly repository for machine learning computations in Python: TensorFlow. Here are the top seven contributors to the Github repository:

Figure: TensorFlow Github repository “commit” distribution.[2]

Here’s the table showing the same data numerically:

Contributor Commits
tensorflower-gardener 21426
yongtang 1251
mrry 1120
gunan 1091
River707 868
benoitsteiner 838
sanjoy 795

The user tensorflow-gardener contributed more than 20% of the 93,000 commits to this repository. Given that there are thousands of contributors, the distribution is much more extreme than the 80/20 distribution. The reason for this extreme skewness is that the contributor tensorflow-gardener consists of a team of coders at Google who create and maintain this repository. The interesting observation, however, is that the top contributors are extremely successful programmers with impressive track records working for some of the most successful companies in the world. You can check them out publicly on the Github page. Whether they became successful before or after they generated a large amount of commits to the open-source repository is a mere theoretical discussion. For all practical matters, you should start your success habit write more lines of code every day now. There’s nothing stopping you from becoming #2 on the TensorFlow repository – by committing valuable code to the TensorFlow repository 2-3 times per day for the next 2-3 years. If you persist, you can join the ranks of the most successful coders on earth – by choosing one powerful habit and sticking to it for three years!

The underlying driver of excellence is to leverage the 80/20 principle on multiple fronts: First, you focus on the minority of activities that are most able to push you to success in your profession. Second, you do more of these activities than 80% of the professionals in your industry so that you belong to the top 20% of the professionals regarding these selected activities. By chaining these two Pareto distributions—select the top 20% of activities and join the top 20% in terms of activity execution quantity—you maximally leverage your resources and you’ll become an unstoppable force in your industry. Are you prepared to take a ride to the moon?

Programmer Net Worth

Sure enough, the net worth of programmers is also Pareto distributed. For privacy reasons, it’s hard to get data about individual’s net worth but one page[3] shows the self-reported net worth of computer programmers. Although the data may be noisy, it shows the characteristic skewness of real-world Pareto distributions:

Figure: Self-reported net worth of 60 programmers.

In fact, the curve is likely to be even more skewed in the real-world because there are many billionaire programmers who’ve initiated software services used by billions of people –

Mark Zuckerberg, Bill Gates, Elon Musk, Steve Wozniak come to mind. Each of those tech geniuses created the prototypes of their services themselves laying hand on the source code. The number of software millionaires is significant.


[1] https://www.researchgate.net/publication/228728263_Evidence_for_the_Pareto_principle_in_Open_Source_Software_Activity

[2] https://github.com/tensorflow/tensorflow/graphs/contributors

[3] https://www.networthshare.com/publicprofiles/Occupation/11

Posted on Leave a comment

How to Allocate Your Time as a Freelance Developer? The 40/30/30 Rule for Maximal Productivity

Here’s the time allocation for freelance developers:

  • 20% Become a Business Genius: Read business books and complete business courses.
  • 20% Master Your Niche: Read programming books and specialize.
  • 30% Increase Demand for Your Services: Apply for gigs and generate leads into your business. Learn more here.
  • 30% Do Work For Clients: Always overdeliver to feed into the previous step.

By reading business books, you’ll become more and more efficient in building your business and your business will transform over time to the better. By reading programming books, you’ll be able to solve problems for clients much faster. Expert coders can complete gigs faster and produce better quality. These two learning habits will ensure that you maximize the leverage of your time and it’s the best investment you can make.

Now you have the skills—but to earn higher hourly rates, you need to increase demand for your services. As a rule of thumb: double the demand for your services will double your hourly rate. How can you increase demand? Build a loyal client base of business owners who know, like, and trust you. You accomplish this by always giving them more value than they pay for. The most crude way to get clients is to apply for gigs on Upwork and Fiverr. Do it if necessary!

Finally, you need to do the work. But most of the time you should invest in the previous steps to sharpen your saw and build a sustainable business. Doing the work will be easier and more profitable as a result!

Where to Go From Here?

Enough theory, let’s get some practice!

To become successful in coding, you need to get out there and solve real problems for real people. That’s how you can become a six-figure earner easily. And that’s how you polish the skills you really need in practice. After all, what’s the use of learning theory that nobody ever needs?

Practice projects is how you sharpen your saw in coding!

Do you want to become a code master by focusing on practical code projects that actually earn you money and solve problems for people?

Then become a Python freelance developer! It’s the best way of approaching the task of improving your Python skills—even if you are a complete beginner.

Join my free webinar “How to Build Your High-Income Skill Python” and watch how I grew my coding business online and how you can, too—from the comfort of your own home.

Join the free webinar now!

Posted on Leave a comment

Closures and Decorators in Python

This tutorial teaches you two advanced Python skills: closures and decorators. Mastering them will make you a better coder today—so, let’s dive right into them!

Closures

Every function in Python is first class, because they can be passed around like any other object. Usually, when a programming language creates a function just like other data types, that programming language supports something called Closures.

A closure is a nested function. It is defined within an outer function.

def outer_hello_fn(): def hello(): print("Hello Finxter!") hello()

Here, we have an outer function called outer_ hello_ fn, it has no input arguments. The function hello is a nested function defined within the outer function. The hello function is a closure.

Try It Yourself:

Exercise: What’s the output of this code snippet? Run the code to test if you’re correct.

When the outer function is called, the hello function within it will be defined and then invoked. Here is the function call and output:

outer_hello_fn()

Output:

Hello Finxter!

hello has been defined within outer_hello_fn, which means if you try and invoke the hello function, it will not work.

hello()

Output:

NameError: name 'hello' is not defined

If you want access to a function that is defined within another function, return the function object itself. Here is how.

def get_hello_fn(): def hello(): print("Hello Finxter!") return hello

The outer function is called get_hello_fn. hello, is an inner function, or closure. Instead of invoking this hello function, simply return the hello function to whoever calls get_hello_fn. For example:

hello_fn = get_hello_fn()

Invoking get_hello_fn stores the return function object in the hello_fn variable. If you explore the contents of this hello_fn variable, you will see that it is a function object.

hello_fn

Output:

<function __main__.get_hello_fn.<locals>.hello>

As you can see in the structure, it is a locally defined function within get_hello_fn, that is, a function defined within another function, that is a closure. Now, this closure can be invoked by using the hello_fn variable.

hello_fn()

Output:

Hello Finxter!

Invoke hello_fn() will print out Hello Finxter! to screen. A closure is something more than just an inner function defined within an outer function. There is more to it. Here is another example:

def hello_by_name(name): def hello(): print("Hello!", name) hello() return hello

Here, the outer function is called hello_by_name, which takes in one input argument, the name of an individual. Within this outer function, there is the hello inner function. It prints to the screen Hello!, and the value of the name.

The name variable is an input argument to the outer function. It is also accessible within the inner hello function. The name variable here can be thought of as a variable that is local to the outer function. Local variables in the outer function can be accessed by closures. Here is an example of passing an argument to the outside function:

greet_hello_fn = hello_by_name("Chris")

The function hello is returned and it is stored in the greet_hello_fn variable.

Executing this prints out Hello! Chris to screen. That is because we invoked the closure from within the outer function. We have a reference to the closure that was defined by the outer function.

greet_hello_fn()

Output:

Hello! Chris

Notice something interesting here. Chris is available in the variable name which is local to the hello_by_name function.

Now, we have already invoked and exited hello_by_name but the value in the name variable is still available to our closure. And this is another important concept about closures in Python. They hold the reference to the local state even after the outer function that has defined the local state has executed and no longer exists. Here is another slightly different example illustrating this concept.

def greet_by_name(name): greeting_msg = "Hi there!" def greeting(): print(greeting_msg, name) return greeting

The outer function, greet_by_name, takes in one input argument, name. Within the outer function, a local variable called greeting_msg is defined which says, “Hi there!”. A closure called greeting is defined within the outer function. It accesses the local variable greeting_msg as well as the input argument name. A reference to this greeting closure is returned from the outer greet_by_name function.

Let’s go ahead and invoke greet_by_name and store the function object that it returns in the greet_fn variable. We will use this function object to greet Ray by name. Go ahead and invoke the greet_fn() by specifying parentheses. And it should say, Hi there! Ray. Observe how the closure has access not just to the name Ray but also to the greeting message, even after we have executed and exited the outer function.

greet_fn = greet_by_name("Ray")
greet_fn()

Output:

Hi there! Ray

Closures carry around information about the local state. Let’s see what happens when the greet_by_name function is deleted, so you no longer have access to the outer function.

del greet_by_name

Now, remember that name and greeting message are both variables that were defined in the outer function. What happens to them? Now if you try to invoke greet by name.

greet_by_name("Ray")

Output:

NameError: name 'greet_by_name' is not defined

What about the greet_fn?

Remember that greet_fn is a reference to our closure. Does this still work?

greet_fn()

Output:

Hi there! Ray

Not only does it work, but it still has access to the local variables that were defined in the outer function. The outer function no longer exists in Python memory, but the local variables are still available along with our closure.

Decorators – Code Modification

Decorators help to add functionality to existing code without having to modify the code itself. Decorators are so-called because they decorate code, they do not modify the code, but they make the code do different things using decoration. Now that we have understood closures, we can work our way step by step to understanding and using decorators.

def print_message(): print("Decorators are cool!")

Here is a simple function that prints a message to screen.

print_message()

Output:

Decorators are cool!

Each time you invoke this function it will always print the same message. I want to use a few characters to decorate the original message, and I do this using the highlight function.

import random def highlight(): annotations = ['-', '*', '+', ':', '^'] annotate = random.choice(annotations) print(annotate * 50) print_message() print(annotate * 50)

The outer function highlight has no input arguments. Within the highlight function, a random choice of annotations is used to decorate the original message. The message will be highlighted with a random choice between the dash, the asterisk, the plus, the colon, and the caret.  The output will have an annotation of 50 characters before and after the message which is inside the print_message function.

Try It Yourself:

Exercise: What’s the output of this code snippet? Run the code to test your understanding!

highlight()

Output:

::::::::::::::::::::::::::::::::::::::::::::::::::
Decorators are cool!
::::::::::::::::::::::::::::::::::::::::::::::::::

Here is another function with a different message, print_another_message.

def print_another_message(): print("Decorators use closures.")

Now if I want to highlight this message as well, the existing highlight function will not work because it has been hardcoded to invoke the print_message function. So how do I change this highlight function so that it is capable of highlighting any message that I want printed out to screen? Remember that functions are first-class citizens in Python, which means whatever print function you have, you can pass it as an input argument to the highlight function. Here is a redefined highlight function, make_highlighted.

def make_highlighted(func): annotations = ['-', '*', '+', ':', '^'] annotate = random.choice(annotations) def highlight(): print(annotate * 50) func() print(annotate * 50) return highlight

The only difference here is that make_highlighted takes in an input argument that is a function. This function is what will print out the message to be displayed. The next change is that within the highlight closure, the function object that was passed in is invoked. That is the function object that will print out the message. Now we have two print functions so far.

print_message()
print_another_message()

And now with the help of  make_highlighted function, any printed message can be highlighted. For example:

highlight_and_print_message = make_highlighted(print_message) highlight_and_print_message()

Output:

++++++++++++++++++++++++++++++++++++++++++++++++++
Decorators are cool!
++++++++++++++++++++++++++++++++++++++++++++++++++

To print a different message and have it highlighted, simply pass a different function object to the make_highlighted function.

highlight_and_print_another_message = make_highlighted(print_another_message) highlight_and_print_another_message()

Output:

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Decorators use closures.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

It is clear that the make_highlighted function is very generic, you can use it to highlight any message that you want printed to screen. The function make_highlighted is a decorator.

Why is it a decorator? Well, it takes in a function object and decorates it and changes it. In this example, it highlights the function with random characters. Decorators are a standard design pattern, and in Python, you can use decorators more easily. Instead of passing in a function object to make_highlighted, accessing the closure, and then invoking the closure, you can simply decorate any function by using @ and placing the decorator before the function to decorate.

@make_highlighted
def print_a_third_message(): print("This is how decorators are used")

The use of the decorator @make_highlighted will automatically pass the function print_a_third_message as an input to make_highlighted and highlight the message.

print_a_third_message()

Output:

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This is how decorators are used
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Now you can use the decorator to highlight any messages.

@make_highlighted
def print_any_message(): print("This message is highlighted!")

And now if you invoke print_any_message, you will find that the result that is displayed to screen is highlighted.

print_any_message()

Output:

++++++++++++++++++++++++++++++++++++++++++++++++++
This message is highlighted!
++++++++++++++++++++++++++++++++++++++++++++++++++

Decorators – Customization

Let’s see another example of a Decorator that will do some work. It will do some error checking for us.

Here are two functions that will be the input to our decorator

def square_area(length): return length**2 def square_perimeter(length): return 4 * length

We assume that the value of the radius passed in is positive and correct.

square_area(5)

Output:

25

What if I invoke the square_area and pass in -1?

square_area(-1)

Output:

-4

The input -1 doesn’t make sense as a value for the length. The function should have thrown an error or told us in some way that negative values of length are not valid. Now, if you were to perform an error check for each of these functions, we would have to do it individually. We would have to have an if statement within the area function as well as the perimeter function. Instead of that, let’s write a decorator that will perform this error checking for us. The decorator safe_calculate takes in one input argument that is a function object.

def safe_calculate(func): def calculate(length): if length <= 0: raise ValueError("Length cannot be negative or zero") return func(length) return calculate

This is the function object that will perform the calculation. Within the safe_calculate outer function, the inner function called calculate is the closure. calculate takes in one input argument, the length. It checks to see whether length is less than or equal to 0. If yes, it throws an error. And the way it throws an error is by simply calling a raise ValueError, “Length cannot be negative or zero”. Once we raise this error, Python will stop the execution. But if length is positive, it will invoke func and pass in length as an input argument. The safe_calculate is our decorator, which takes as its input a function object and returns a closure that will perform the safe calculation.

square_area_safe = safe_calculate(square_area)

Let’s test it first:

square_area_safe(5)

This is safe and I get the result here on the screen.

25

Invoking it with a negative number will raise an error

square_area_safe(-1)

Output:

ValueError: Length cannot be negative or zero

Let’s decorate the perimeter function as well with the safe_calculate.

square_perimeter_safe = safe_calculate(square_perimeter) square_perimeter(10)

Output:

40

But if you were to call square_perimeter_safe with a negative value for length well, that is a ValueError.

square_perimeter_safe(-10)

Output:

ValueError: Length cannot be negative or zero

Now that you have a decorator, you should decorate your functions rather than use the way that we have been using so far.

@safe_calculate
def square_area(length): return length**2 @safe_calculate
def square_perimeter(length): return 4 * length

Now, the next time square_area or the square_perimeter is called, the safety check will be performed.

square_perimeter(3)

Output:

12

If you try to calculate the perimeter for a negative value of the length, you will get a ValueError. The safe_calculate function that we set up earlier has a limitation, and you will see what it in a future example.

square_perimeter(-3)

Output:

ValueError: Length cannot be negative or zero

What happens when you have more than one input? Here is a function that calculates the area of a rectangle.

@safe_calculate
def rectangle_area(length, width): return length * width

Within our safe_calculate function, we had invoked the func object which performs the calculation with just one input argument, with just the variable length. This is going to cause a problem when we use the safe_calculate decorator for the rectangle_area function.

Once I have decorated this function, I’m going to invoke it with 4, 5.

rectangle_area(4, 5)

Output:

TypeError: calculate() takes 1 positional argument but 2 were given

The problem is with the way we had defined the closure inside the safe_calculate function.

The calculate closure takes in just one input argument. If a function has multiple input arguments, then safe_calculate cannot be used. A redefined safe_calculate_all function is shown below:

def safe_calculate_all(func): def calculate(*args): for arg in args: if arg <= 0: raise ValueError("Argument cannot be negative or zero") return func(*args) return calculate. 

It takes in one input argument that is the function object that is to be decorated. The main change is in the input arguments that are passed into the calculate closure. The function calculate now takes in variable length arguments, *args.  The function iterates over all of the arguments that were passed in, and checks to see whether the argument is less than or equal to 0. If any of the arguments are less than or equal to 0, a ValueError will be raised. Remember, *args will unpack the original arguments so that the elements of the tuple are passed in individually to the function object, func. You can now use this safe_calculate_all decorator with functions that have any number of arguments.

@safe_calculate_all
def rectangle_area(length, width): return length * width
rectangle_area(10, 3)

Output:

30

Let’s try invoking the same function, but this time one of the arguments is negative. Width is negative and that gives me a ValueError, thanks to our safe_calculate_all decorator.

rectangle_area(10, -3)

When you invoke this function, it will check all arguments.

ValueError: Argument cannot be negative or zero

It doesn’t matter which argument is negative, you still get the ValueError. Here the length is negative:

rectangle_area(-10, 3)

Output:

ValueError: Argument cannot be negative or zero

Chaining Decorators

You can have a function decorated using multiple decorators. And these decorators will be chained together.

Here are two decorators, one prints asterisks and the other plus signs

def asterisk_highlight(func): def highlight(): print("*" * 50) func() print("*" * 50) return highlight def plus_highlight(func): def highlight(): print("+" * 50) func() print("+" * 50) return highlight

The print_message_one is decorated with the asterisk_highlight.

@asterisk_highlight
def print_message_one(): print("Decorators are cool!") print_message_one()

Output:

**************************************************
Decorators are cool!
**************************************************

Now let’s define another print function, but this time we will decorate it using two decorators, the plus_highlight and the asterisk_highlight.

@plus_highlight
@asterisk_highlight
def print_message_one(): print("Decorators are cool!")

What you see here is an example of chaining decorators together. But how are they chained? Which decoration comes first, the asterisk_highlight, or the plus_highlight? Whichever decorator is the closest to the function definition is what is executed first, and then the decorator which is further away from the function definition. This means that the message will be first highlighted with the asterisk, then the plus.

print_message_one()

Output:

++++++++++++++++++++++++++++++++++++++++++++++++++
**************************************************
Decorators are cool!
**************************************************
++++++++++++++++++++++++++++++++++++++++++++++++++

If you change the order of the decorators, the decorations order will change as well.

@asterisk_highlight
@plus_highlight
def print_message_one(): print("Decorators are cool!") 

You will have the same function print_message_one, but the decorator that is closest to the function definition is the plus_highlight and then the asterisk_highlight.

print_message_one()

Output:

**************************************************
++++++++++++++++++++++++++++++++++++++++++++++++++
Decorators are cool!
++++++++++++++++++++++++++++++++++++++++++++++++++
**************************************************

Use of kwargs in Decorators

In this example we are using kwargs to display different messages for a decorator that times the execution of a function

def timeit(func): def timed(*args, **kw): if 'start_timeit_desc' in kw: print(kw.get('start_timeit_desc')) ts = time.time() result = func(*args, **kw) te = time.time() if 'end_timeit_desc' in kw: print('Running time for {} is {} ms'.format(kw.get('end_timeit_desc'), (te - ts) * 1000)) return result return timed 

The timeit decorator is used for the test function.  Three parameters are passed to the function test: a, b and, **kwargs. The parameters a and b are handled in the decorator with *args as we have seen before.  The **kwargs parameter is used to pass descriptions for the function.  These parameters are start_timeit_desc and end_timeit_desc.  These two parameters are checked inside the timed closure and will display the messages that are in them.

@timeit
def test(a,b, **kwargs): return a * b result = test(10,20, start_timeit_desc = "Start of test(10,20)...", end_timeit_desc = "End of test(10,20)")
print("result of test(10,20) = " + str(result))
Output:
Start of test(10,20)...
Running time for End of test(10,20) is 0.0 ms
result of test(10,20) = 200
Posted on Leave a comment

How to Write Multiple Statements on a Single Line in Python?

Problem: Given multiple Python statements. How to write them as a Python One-Liner?

Example: Consider the following example of four statements in a block with uniform indentation:

a = 1
b = 2
c = a + b
print(c)

Each of the four statements is written in a separate line in a code editor—this is the normal procedure. However, what if you want to one-linerize those:

How to write all four statements in a single line of code?

Solution: The answer is simple if all statements have a uniform indentation and there’s no nested block. In this case, you can use the semicolon as a separator between the statements:

a = 1; b = 2; c = a + b; print(c)

Let’s do some practice testing to learn and improve your Python skills:

Exercise: one-linerize the given code! Run the code and check if the one-liner does the same as the original code!

Indented Block

While this works beautifully, if all statements are not indented—does it still work if you have an indentation block that starts with the colon : symbol after if, elif, else, for, while, or try/except statements?

Here’s an example of such a block:

for i in range(10): c = i ** 2 print (c)

You try the following one-liner using the semicolon as a separator between the two statements in the block

for i in range(10): c = i ** 2; print(c) '''
0
1
4
9
16
25
36
49
64
81 '''

This works beautifully and Python understands what you are trying to do. However, if you have nested indentation blocks, this doesn’t work anymore.

Consider the following example:

for i in range(3): for j in range(3): print(i, j)

If you write this in a single line, Python throws a syntax error:

While you can discuss if this makes sense or not—given that the syntax is not ambiguous here—it doesn’t change the fact: nested block cannot be one-linerized in a straightforward way. But this doesn’t prevent us from doing it, right?

Nested Indentation Blocks

Read the following article to learn how to compress multiple lines of code into a single line!

Summary: To make a Python one-liner out of any multi-line Python script, replace the new lines with a new line character '\n' and pass the result into the exec(...) function. You can run this script from the outside (command line, shell, terminal) by using the command python -c "exec(...)".

This method is very powerful and it allows you to compress any complicated multi-line script in a single line of Python code!

Python One-Liners Book

Python programmers will improve their computer science skills with these useful one-liners.

Python One-Liners

Python One-Liners will teach you how to read and write “one-liners”: concise statements of useful functionality packed into a single line of code. You’ll learn how to systematically unpack and understand any line of Python code, and write eloquent, powerfully compressed Python like an expert.

The book’s five chapters cover tips and tricks, regular expressions, machine learning, core data science topics, and useful algorithms. Detailed explanations of one-liners introduce key computer science concepts and boost your coding and analytical skills. You’ll learn about advanced Python features such as list comprehension, slicing, lambda functions, regular expressions, map and reduce functions, and slice assignments. You’ll also learn how to:

  Leverage data structures to solve real-world problems, like using Boolean indexing to find cities with above-average pollution
  Use NumPy basics such as array, shape, axis, type, broadcasting, advanced indexing, slicing, sorting, searching, aggregating, and statistics
  Calculate basic statistics of multidimensional data arrays and the K-Means algorithms for unsupervised learning
  Create more advanced regular expressions using grouping and named groups, negative lookaheads, escaped characters, whitespaces, character sets (and negative characters sets), and greedy/nongreedy operators
  Understand a wide range of computer science topics, including anagrams, palindromes, supersets, permutations, factorials, prime numbers, Fibonacci numbers, obfuscation, searching, and algorithmic sorting

By the end of the book, you’ll know how to write Python at its most refined, and create concise, beautiful pieces of “Python art” in merely a single line.

Get your Python One-Liners Now!!