Style Guide & Good Practices#


Easter-Egg: The Zen of Python#

import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

PEPs: Python Enhancement Proposals#

Have a close look at https://www.python.org/dev/peps and especially PEP 8 – Style Guide for Python Code, which you can find here: https://www.python.org/dev/peps/pep-0008

Have a close look at:

Functions#


def mySquare(x):
    return x**2

b = mySquare(7)

print( b )
49

Docstrings#

A docstring is a string literal that occurs as the first statement in a module, function, class, or method definition. Such a docstring becomes the doc special attribute of that object.

For more details see PEP 257 – Docstring Conventions at https://www.python.org/dev/peps/pep-0257

def mySquare(x):
    """Calculate the square of a number y = x^2."""
    
    return x**2

?mySquare
def mySquare(x):
    """Calculate the square of a number y = x^2.
    
    Arguments:
        x -- a number
         
    Returns:
        y -- a number
         
    """
    
    return x**2

?mySquare
?print

Asserts#

mySquare('string')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[6], line 1
----> 1 mySquare('string')

Cell In[4], line 12, in mySquare(x)
      1 def mySquare(x):
      2     """Calculate the square of a number y = x^2.
      3 
      4     Arguments:
   (...)      9 
     10     """
---> 12     return x**2

TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'

An assert tests if a condition is True. If it is not True, it will raise an AssertionError

See also: https://wiki.python.org/moin/UsingAssertionsEffectively

This is very useful to make sure that functions arguments are of the expected type.

def mySquare(x):
    """Calculate the square of a number y = x^2.
    
    Arguments:
        x -- a number
         
    Returns:
        y -- a number
         
    """
    
    assert isinstance(x, float), "x must be number."
    
    return x**2

mySquare('string')
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
Cell In[8], line 16
     12     assert isinstance(x, float), "x must be number."
     14     return x**2
---> 16 mySquare('string')

Cell In[8], line 12, in mySquare(x)
      1 def mySquare(x):
      2     """Calculate the square of a number y = x^2.
      3     
      4     Arguments:
   (...)
      9          
     10     """
---> 12     assert isinstance(x, float), "x must be number."
     14     return x**2

AssertionError: x must be number.

But we can also be too strict:

mySquare(5)
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
Cell In[9], line 1
----> 1 mySquare(5)

Cell In[8], line 12, in mySquare(x)
      1 def mySquare(x):
      2     """Calculate the square of a number y = x^2.
      3     
      4     Arguments:
   (...)
      9          
     10     """
---> 12     assert isinstance(x, float), "x must be number."
     14     return x**2

AssertionError: x must be number.
def mySquare(x):
    """Calculate the square of a number y = x^2.
    
    Arguments:
        x -- a number
         
    Returns:
        y -- a number
         
    """
    
    assert type(x) in [int, float, complex], "x must be number."
    
    return x**2

print( mySquare(5) )
print( mySquare(5.0) )
print( mySquare(-5.0) )
print( mySquare(-5.0j) )
25
25.0
25.0
(-25+0j)

Lambda Functions#


Lambda function are (small) anonymous functions which can be defined within a single line.

mySquare = lambda x: x**2

b = mySquare(3)

print( b )
9

Lambda functions can have multiple arguments:

mySum = lambda x,y: x+y

b = mySum(4, -2)

print( b )
2

And we can make it even shorter via:

b = (lambda x,y: x+y)(4, 4)

print( b )
8

This can be very handy if we remember that functions can also return functions:

def myFunc(n):
    return lambda x: x**n

aFunc = myFunc(3)
type(aFunc)
function
print( aFunc(3) )
27
print( myFunc(3)(6) )
216