Tuesday, August 21, 2018

Python Intro: First Steps

Python First Steps

Python First Steps

Keywords

Every programming language has a set of special predefined words that can only be used for statements in the programming language. In python they are:

and del from not while
as elif global or with
assert else if pass yield
break except import print False
class exec in raise None
continue finally is return True
def for lambda try  

This and following posts will deal with an important subset of these keywords. I will cover enough so the reader will be able to learn the rest on their own after they are comfortable writing simple programs.

Hello World (first Keyword: print)

Python has a large following and more importantly seems to be a language of choice for Artificial Intellegence and Big Data applications. Python is a scripting language and interpreter. I like to start by using thing in a unix shell environment.

save the following to hello.py:

#!/path-to-python/bin/python

print('Hello World!')

When the program is run using the python command:

$ python hello.py
Hello World!
$

Not very much but it's a start. Python is considered a functional language. This means that most of the work is done in functional blocks. There is a whole lot of theory behind why using a functional language is an important programming paridigm, but that is beyond the scope of this introduction. It will "flavor" how programs are structured. But you shouldn't need very much experience with the theory of functional programming to become a useful python programmer.

Function syntax

A more useful program would be one to find the squareroot of a number. So lets create our own function to do just that. I have transcribed part of the python grammar into a pseudogrammar to help show how functions are structured in python.

function_definition = 'def' <function_name> '('parameter_list')' ':' single_stm |
                      'def' <function_name> '('parameter_list')' ':' 
                          indented_statements

The first thing a function definition must have is the word 'def' to start. This is followed by a function name, a list of parameters we expect to be passed in. Finally it is completed by any number of indented statements. To simplify this lets use the math library function call as the guts of our function definition (later in this article I provide a way to actually calculate the square root). I use the comment symbol # to provide in-program explanations of new python commands and functions

#!/path-to-python/bin/python

# For now cheat and use the python math library to make the function work
# Python uses an import state to bring in libraries of functions
import math

# define a new function called squareroot taking 1 parameter x
def squareroot(x):
  return math.sqrt(x)

# The above function definition the return statement goes with the function
# due to the indentation level. If the return statement were even with the def

# the input statement displays a prompt and accepts user text.
# the text needs to be converted to a number, python provides a float() function
# and an int() function to convert text to numbers
X = float(input('Enter value: '))
print(squareroot(X))
$ python sqrt.py
Enter value: 25
5.0
$

Keywords covered so far

The keywords covered just in the preceding program are highlighted in red:

and del from not while
as elif global or with
assert else if pass yield
break except import print False
class exec in raise None
continue finally is return True
def for lambda try  

If - Else statment

Now there is a problem with this simple program. If a negative number is entered the program fails with error messages:

$ python sqrt.py
Enter value: -25
Traceback (most recent call last):
  File "sqrt.py", line 8, in <module>
    print(squareroot(X)) 
  File "sqrt.py", line 5, in squareroot
    return math.sqrt(x)
ValueError: math domain error

The math.sqrt function doesn't calculate negative square roots it is undefined as a negative root would generate an imaginary number. You can catch this problem in the program using an if-statement.

if statment syntax

The grammar text below tries to show how the actual program statement might be structured. It is verbose on purpose.

if_stm = ('if' test_expression ':' single_stm |           # | line symbol means or (one or the other but not both)
         'if' test_expression ':' 
             indented_statments)                          # parenthesis are used to group a section of the grammar to be done first
         ['else' ':' (single_stm | indented_statements)]  # square brackets means optional or 0 or 1 of the statements in the brackets

Lets shorten the grammar syntax up to the version with the else statement. Understand that in the if portion I am trying to give you a sense of how the statements will look structurally with indentation and newlines. Once you compare the syntax and the actual statments I think you will see that the following is an equivalent syntax definition that saves on space:

if_stm = 'if' test_expression ':' (single_stm | indented_statments) # if statment start
         ['else' ':' (single_stm | indented_statements)]            # optional else clause

In the above syntax statements you must interpret yourself that the indented statements if used would would follow underneath the 'if' keyword and testexpression part of the statement Again square brakets around a syntax specification mean that it is optional. You may place a clause there or you may leave it out. This is 0 or 1 statements.

import math

def squareroot(x):
  if x >= 0:
    return math.sqrt(x)
  else:
    print(x,' does not have a real square root')
    return 0

X = float(input('Enter value: '))
print(squareroot(X))
$ python sqrt.py
Enter value: -25
-25.0  does not have a real square root
0
$

Compound If statement

Some of the most difficult to read programs are ones with complex compound if - then - else statements. In python this is an if - else statement, the then is implied. In this case we will solve the quadratic equation

\[ax^2 + bx + c = 0\] which you should remember is solved by the following formula: \[x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}\]

# solve quadratic equation ax^2 + bx + c = 0
# accept a,b,c from the user
#
# Program: quadratic.py
#
import math

# Function definitions:
def quadratic(a,b,c):
  if (a==0) and (b==0):
    print('The equation is degenerate')
  else:
    if a == 0:
      print('the only root is ', -c/b)
    else:
       if c == 0:
         print('the roots are ', (-b/a),' and 0')
       else:
         re = -b / (2 * a)
         discriminant =  (b*b) - 4 * a * c
         im = math.sqrt(abs(discriminant))/(2*a)
         if discriminant >= 0:
           print('the roots are ', re+im, ' and ', re - im)
         else:
           print('the roots are complex: ', re,' + j',im,' and ', re, '- j',im)

# Begin Main Program:
a = float(input('a: '))
b = float(input('b: '))
c = float(input('c: '))
quadratic(a,b,c)
$ python quadratic.py
a: 0
b: 0
c: 7
The equation is degenerate
$ python quadratic.py
a: 0
b: 10
c: 2
the only root is  -0.2
$ python quadratic.py
a: 2
b: 3
c: 0
the roots are  -1.5  and 0
$ python quadratic.py
a: 1
b: 5
c: 6
the roots are  -2.0  and  -3.0
$ python quadratic.py
a: 1  
b: 1
c: 1
the roots are complex:  -0.5  + j 0.8660254037844386  and  -0.5 - j 0.8660254037844386
$

elsif statement

A companion keyword "elif" forms an else-if clause and helps flatten a compound if statement.

grammar syntax

if_stm = 'if' test_expression ':' (single_stm | indented_statments)         # must have this
         {'elif' test_expression ':' (single_stm | indented_statements)}    # curly braces mean 0 or more
         ['else' ':' (single_stm | indented_statements)]                    # square brackets optional part of statement

Here is the quadratic program now rewritten with the "elif" keyword (notice how it helps keep the indentation under control):

# solve quadratic equation ax^2 + bx + c = 0
# accept a,b,c from the user
#
# Program: quadratic.py
#
import math

# Function definitions:
def quadratic(a,b,c):
  if (a==0) and (b==0):
      print('The equation is degenerate')
  elif a == 0:
      print('the only root is ', -c/b)
  elif c == 0:
      print('the roots are ', (-b/a),' and 0')
  else:
      re = -b / (2 * a)
      discriminant =  (b*b) - 4 * a * c
      im = math.sqrt(abs(discriminant))/(2*a)
      if discriminant >= 0:
          print('the roots are ', re+im, ' and ', re - im)
      else:
          print('the roots are complex: ', re,' + j',im,' and ', re, '- j',im)

# Begin Main Program:
a = float(input('a: '))
b = float(input('b: '))
c = float(input('c: '))
quadratic(a,b,c)

Keywords covered so far

Here is the score card of keywords, the new ones are red with previous keywords covered only in Bold:

and del from not while
as elif global or with
assert else if pass yield
break except import print False
class exec in raise None
continue finally is return True
def for lambda try  

Loops: While loop, For loop

Now we will introduce the usage of for and while loops

for grammar syntax

for_stm = 'for' expression 'in' list ':' (single_stm | indented_statments)  # must have this
         ['else' ':' (single_stm | indented_statements)]                    # square brackets optional usage not shown below

while grammar syntax

while_stm = 'while' test_expression ':' (single_stm | indented_statments)   # must have this
         ['else' ':' (single_stm | indented_statements)]                    # square brackets optional usage not shown below

In the example below the for loop in the function divisors uses a python function called 'range'. Range returns a list of all integers beginning with the first argument and ending with the number just before the last argument. Now in Python3 range is an object. The object has been especially designed to work in a 'for' loop. These type of objects are called an Iterator. Iterators will give the 'for' loop the next item in the sequence of the underlying object. For now it's best to think of 'range' as returning a list. To see the underlying list that 'range' represents here is an example:

>>> list(range(2,10))
[2, 3, 4, 5, 6, 7, 8, 9]

Python makes use of lists as a built-in way to store data. Even though it's convenient to think of 'range' as a simple list, 'range' doesn't store all the values in memory. For example what if we wanted to loop 10,000,000 times. Why waste the memory with a list of 10,000,000 values when 'range' can calculate the next value when needed? You wouldn't, so range is set up to mimic a list in 'for' loops without pre-storing the entire list in memory.

# Program: divisor.py
# This loops through values 2, up to but not including the number, 
# and finds all divisors of the number
# No computer magic just loop through all values and test them with the 
# modulo operator (%) which returns 0 if the number is a divisor
def divisors(x):
  for divisor in range(2,x):  # this would work with list(range(2,x)) as well
    if (x % divisor)==0:
      print(divisor)

# Begin python program:
while True:          # begin repeat-until loop using while loop statement
  x = int(input('Input Integer: '))
  if x > 0:
    print('The divisors of ',x,' are: ')
    divisors(x)

  # break out of loop if the input is 0 or less
  if x <= 0:    # i.e. until x <= 0 
    break
  # otherwise return to the top of the while loop

Here is a quick session with the new program

$ python divisor.py
Input Integer: 12
The divisors of  12  are: 
2
3
4
6
Input Integer: 18
The divisors of  18  are: 
2
3
6
9
Input Integer: -1
$

Keywords covered so far

and del from not while
as elif global or with
assert else if pass yield
break except import print False
class exec in raise None
continue finally is return True
def for lambda try  

Conclusion

I selected a few short program examples from Peter Grogono's Programming in Pascal book and transcribed them into python. As you can see a significant portion of the keywords of python have now been covered. In the next installment I quickly show how to use the Python shell environment. It takes some small rewrites and all of the programs so far will run in the python shell command line.

References

  1. Grogono, Peter. Programming in Pascal. Adison-Wesley, 1984.
  2. “Welcome to Python.org.” The Python Tutorial, Python Software Foundation, 19 Aug. 2018, www.python.org/.

Author: Nasty Old Dog

Validate