Fundamentals (Good)

What to expect in this chapter

In the previous chapter, you learned some essential basics of Python. In this chapter, I will build on those earlier concepts to add more details to the same ideas. I will also introduce different data types and how to combine variables with English.

1 There is more to if

There are situations when we need more branches in an if statement. Python has the elif (else if) statement for such cases. Here is how it works

name = 'Batman'

if name == 'Batman':
    print('Hello Batman!')
elif name == 'Robin':
    print('Hello Sidekick!')
else:
    print('Hello World!')

2 Asking questions

To use if to make decisions we need to be able to ask questions; some of which might be complicated. Let’s now look at a few more examples of how we can do this.

I will ask some questions about the following two lists.

fruits = ['apple', 'banana', 'pineapple', 'jackfruit']
vegetables = ['celery', 'potato', 'broccoli', 'kale']
  1. 'apple' in fruits

    Is ‘apple’ in the list fruits?

    True
  2. 'peach' in fruits

    Is ‘peach’ in the list fruits?

    False
  3. 'peach' not in fruits

    Is ‘peach’ not in the list fruits?

    True
  4. ('apple' in fruits) and ('celery' in vegetables)

    Is ‘apple’ in the list fruits and is ‘celery’ in the list vegetables?

    True
  5. ('apple' in fruits) or ('celery' in vegetables)

    Is ‘apple’ in the list fruits or is ‘celery’ in the list vegetables?

    True
  6. 'app' in 'apple'

    Is ‘app’ in ‘apple’?

    True
Remember

not, in, and, or are some Python keywords that are useful in asking questions.

In asking questions it is important to understand that basic Python only knows how to compare similar things (types) (e.g. numbers or English). So, 3 > 10.5 will work, but 3 > 'apple' will not.

However, Python1 can compare 'apples' and 'oranges':

'apples' > 'oranges'
False

This comparison works because English letters are internally represented as numbers. For example, 'a' is 97 and 'o' is 111. This will become even clearer after you have worked on the section below on data types.

2.1 Asking Math questions

  • You will find the following useful when asking mathematical questions:
Question/Condition Math Symbol Python Symbols
Equals? = ==
Not equal? !=
Less than? < <
Greater than? > >
Less than or equal? <=
Greater than or equal? >=
  • Python also (thankfully) accepts all the following syntax:

    x > 5 and x < 15
    (x > 5) and (x < 15)
    5 < x < 15

    Clearly, the last format is the neatest and easiest to read. Notice also how the brackets increase the readability of the statement.

3 Python stores information in different formats or types

For efficiency (i.e., speed and memory), computers store information in different ways. For example, here are four ways we can store the number 1.234. We are also using the function type() to ask Python how it is storing the information.

  1. x = int(1.234)
    print(x, type(x))

    As an integer (int).
    Notice how this ends up dropping the decimal portion!

    1 <class 'int'>
  2. x = str(1.234)
    print(x, type(x))

    As an English word (str).

    1.234 <class 'str'>
  3. x = float(1.234)
    print(x, type(x))

    As a decimal number (float).

    1.234 <class 'float'>
  4. x = complex(1.234)
    print(x, type(x))

    As a complex number (complex).
    This will include an imaginary part of the number.

    (1.234+0j) <class 'complex'>

There are many other types of data (see here for more details). Often2 we will need to change the type of a variable.

x = '1.234'        # x is a string
print(x, type(x))
1.234 <class 'str'>
x = float(x)       # x is now a decimal number
print(x, type(x))
1.234 <class 'float'>

This is called typecasting; where we cast x to the type float.

4 Never compare floats directly

4.1 The Problem

when often need to compare numbers, especially for scientific work. Unfortunately, since computers have finite (hardware) resources, floating point numbers cannot be exactly stored in a computer3. This leads to errors called roundoff errors. Let me demonstrate:

Try the following code which compares \(0.1\times 3\) with \(0.3\).

a = 0.1
a3 = 0.3
a * 3 == a3
False

To convince you further, let’s try printing \(0.3\) to 17 decimal places:

f'{0.3:.17f}'
'0.29999999999999999'

4.2 A solution

To get around these types of issues, you should check if the variable is close to the expected values instead of checking for equality.

eps = 1E-10
abs(a * 3 - a3) < eps
True

Or just use Numpy

np.isclose(a * 3, a3)
True

5 Combining English and variables

Although often underappreciated, one of the most valuable coding skills is the ability to seamlessly combine strings (i.e., English) with variables. This will be useful for example when automating personalized emails to a large class.

Combining text and variables is so easy in newer versions of Python. Let me show you a few examples:

  1. name = "Batman"
    print(f"Hello {name}!")
    Hello Batman!
  2. name = "Batman"
    print(f"Hello {name.upper()}!")
    Hello BATMAN!
  3. x = 10
    print(f"The value of {x} squared is {x**2}!")
    The value of 10 squared is 100!

Note the f and the { } in the above command. This is called f-string or string interpolation.

You can do more with f-strings, like formatting a string or number. Let me show you three more examples.

  1. Using f-strings to format text (strings).

    text = 'Bruce Wayne is Batman.'
    print(f'{text}')
    Bruce Wayne is Batman.
    print(f'{text:>30}')      # A block of 30 characters;
                              # aligned right
            Bruce Wayne is Batman.
    print(f'{text:^30}')      # A block of 30 characters;
                              # aligned centre
        Bruce Wayne is Batman.    
    print(f'{text:<30}')      # A block of 30 characters;
                              # aligned left
    Bruce Wayne is Batman.        
  2. Using f-string to format numbers.

    print(f'The cube of pi to 6 decimal places is {np.pi**3:.6f}')
    The cube of pi to 6 decimal places is 31.006277

    The f in .6f is used to tell the f-string to output the number in decimal notation.

  3. print(f'The cube of pi to 6 decimal places is {np.pi**3:.6e}')
    The cube of pi to 6 decimal places is 3.100628e+01

    The e in .6e is used to tell the f-string to output the number in scientific notation.

5.1 Structure of f-strings

f-string formatting has the structure {X:>0Y.ZW}. Here is more information about the letters X,Y,>, 0,Z and W.

Letter Action Possible Options
X Variable to format Can be a number or a string
> Alignment
  • < (Left justified)
  • > (Right justified)
  • ^ (Centre justified)
0 Use 0’s to pad the spaces You can use other characters like a space .
Y Total number of characters
Z Number of decimal places
W Specifies the type of variable.
  • f (float)
  • d (integer)
  • s (string)
  • g (Asks Python to figure out)

You can refer to this website for more information about f-strings.

6 Escape sequences

This is a good point to highlight escape sequences. Despite the funky name, it refers to special characters we sometimes need when writing English. For example, to break a line and add a tab:

print('Line 1\n\tLine 2\n\t\tLine 3')
Line 1
    Line 2
        Line 3

The \n is the command to breakline and \t represents a tab. These characters are typically not visible, but they are there. Let me put all the useful escape sequences in a table for you:

Escape Sequence Meaning
\’ Single quote
\\ Backslash
\n Newline
\t Horizontal Tab

Let me show you a few more examples:

  1. In a previous example, I had to use both " and ' to print “You’re twenty years old.”. However, with the escaped version of ' things are simpler.

    print('You\'re twenty years old.') 
    You're twenty years old.
  2. If you want to print \, you need to ‘escape’ it. If you don’t… well, give it a try and see.

    print('A\\B\\C')
    A\B\C
  3. print('A\nB\nC')
    A
    B
    C

    Notice the linebreaks!

  4. print('A\tB\tC')
    A   B   C

    Notice the tabs!

7 Computers read = from Right to Left!

The way computers use = is quirky. Let me explain why.

Consider the code below:

x = 40
y = x + 2

How Python executes these instructions is as follows:

This means that the following will work in programming (but not math!).

y = 40
y = y + 2
print(y)

You will frequently see variables modified using this syntax. So, best get used to it.

Note: Python also allows the following syntax.

x = y = 10

8 Shorter and Cleaner Code

Let me now introduce some shorthand syntax4 related to the previous point that will make your code neater. This shorthand is used often so even if you do not want to use it, you still need to understand it.

Consider the following two sets of code; both have the same result.

y = 40
y = y + 2
y
y = 40
y += 2    # Same as y = y + 2
y
42
42

So, we can replace y = y + 2 with y += 2. Similar shorthand notation exists for subtraction, division and multiplication:

Long form Shorthand
Addition y = y+2 y += 2
Subtraction y = y-2 y -= 2
Multiplication y = y*2 y *= 2
Division y = y/2 y /= 2

9 Python can be a prima-donna.

When we do something Python doesn’t like or understand, it will often act like a prima-donna and throw a complaint with a looong error message. As with most complaints, scroll to the end to see the real problem.

If you had used Print() in the previous chapter, you would have already seen an error message. Fixing coding errors is called debugging. Most programmers spend a long time debugging. Further, the more debugging you do, the more comfortable you will be with thinking and programming. So, use every opportunity you have to practice debugging.

10 Best Practices for Scientific Computing

Now is an apt time to highlight some best practices you should always bear in mind. The following is an excerpt from Wilson et al. (2014). I have only given those points that apply to you now. I will bring up more as we progress on our journey.

  1. Write programs for people, not computers.
  2. Optimise software only after it works correctly.
  3. Document design and purpose, not mechanics.
  4. Collaborate.

If you don’t take care, your code can quickly become unfathomable to others and your future self. So, consciously produce easily understandable code (for example, using appropriate variable names). In addition, discussing your code with your friends (collaboration) is helpful because you will get immediate feedback if your code is indecipherable or if you have misunderstood a concept.

Another common pitfall novices succumb to is pursuing a perfect solution right from the get-go. Instead, it is better to get something (anything) working. You can then make things complicated and/or optimize your code.

Tip

Always start simple and get something working first before making it perfect.

11 Looking for help

You can get help/information about Python functions from within Python. However, I do not recommend it at this stage. Let me show you why:

help(print)
Help on built-in function print in module builtins:

print(*args, sep=' ', end='\n', file=None, flush=False)
    Prints the values to a stream, or to sys.stdout by default.
    
    sep
      string inserted between values, default a space.
    end
      string appended after the last value, default a newline.
    file
      a file-like object (stream); defaults to the current sys.stdout.
    flush
      whether to forcibly flush the stream.

The above is the documentation corresponding to the function print(). Unfortunately, unless you already have some experience, this documentation is not the friendliest. The internet (e.g. stack overflow, Google or ChatGPT) is the fastest way to get a question about programming answered.

Back to top

References

Wilson, Greg, D. A. Aruliah, C. Titus Brown, Neil P. Chue Hong, Matt Davis, Richard T. Guy, Steven H. D. Haddock, et al. 2014. “Best Practices for Scientific Computing.” PLOS Biology 12 (1): e1001745. https://doi.org/10.1371/journal.pbio.1001745.

Footnotes

  1. despite the English phrase↩︎

  2. E.g. with an OCR table of numbers.↩︎

  3. due to issues related to the precision of the IEEE 754 standard↩︎

  4. called augmented assignment↩︎