Principles of Programming - Class Notes
Table of Contents
We want to evalute alll the source blocks:
You can download this file here. Then open it in Pycharm, you will get the option to download the extension Org4Idea. Install it and restart Pycharm. Now you can open the file in Pycharm and you will see the file formatted much better.
1. Data Types
1.1. Integers
An integer is a whole number, positive or negative, with no fractional part. In python integers are represented by the int class. The int class has the following methods:
__add__(self, other)__
: returns the sum of self and other__sub__(self, other)__
: returns the difference of self and other__mul__(self, other)__
: returns the product of self and other__floordiv__(self, other)__
: returns the quotient of self and other__mod__(self, other)__
: returns the remainder of self and other__pow__(self, other)__
: returns the power of self and other__abs__(self)__
: returns the absolute value of self__neg__(self)__
: returns the negative value of self__pos__(self)__
: returns the positive value of self
How do we use integers in python?
a = 5 b = 2 print(a.__add__(b)) print(a+b)
7 7
1.2. Floating Point Numbers
A floating point number is a number with a fractional part. In python floating point numbers are represented by the float class. The float class has the following methods:
__add__(self, other)__
: returns the sum of self and other__sub__(self, other)__
: returns the difference of self and other__mul__(self, other)__
: returns the product of self and other__floordiv__(self, other)__
: returns the quotient of self and other__mod__(self, other)__
: returns the remainder of self and other__pow__(self, other)__
: returns the power of self and other__abs__(self)__
: returns the absolute value of self__neg__(self)__
: returns the negative value of self__pos__(self)__
: returns the positive value of self
The difference between the int and float classes is that the float class has the following methods:
__truediv__(self, other)__
: returns the quotient of self and other__round__(self, ndigits)__
: returns the rounded value of self to ndigits decimal places__floor__(self)__
: returns the floor value of self__ceil__(self)__
: returns the ceiling value of self
How do we use floating point numbers in python?
a = 5.0 b = 2.0 c = 2.5128596 print(a.__truediv__(b)) print(a/b) print(c.__round__(3))
2.5 2.5 2.513
1.3. Strings
A string is a sequence of characters. In python strings are represented by the str class. The str class has the following methods:
__add__(self, other)__
: returns the concatenation of self and other__mul__(self, other)__
: returns the product of self and other__len__(self)__
: returns the length of self__getitem__(self, key)__
: returns the character at index key of self__setitem__(self, key, value)__
: sets the character at index key of self to value__delitem__(self, key)__
: deletes the character at index key of self__contains__(self, item)__
: returns True if item is in self, False otherwise__iter__(self)__
: returns an iterator over self__reversed__(self)__
: returns a reversed iterator over self__eq__(self, other)__
: returns True if self and other are equal, False otherwise__ne__(self, other)__
: returns True if self and other are not equal, False otherwise__lt__(self, other)__
: returns True if self is less than other, False otherwise__le__(self, other)__
: returns True if self is less than or equal to other, False otherwise__gt__(self, other)__
: returns True if self is greater than other, False otherwise__ge__(self, other)__
: returns True if self is greater than or equal to other, False otherwise__hash__(self)__
: returns the hash value of self__str__(self)__
: returns the string representation of self__repr__(self)__
: returns the string representation of self__format__(self, format_spec)__
: returns the formatted string representation of self
How do we use strings in python? We can use single quotes or double quotes to represent strings.
a = 'Hello' b = "World" # here are some examples of string methods print(a.__add__(b)) print(a.__hash__()) print(a.__len__()) print(a.__getitem__(1)) print(b.__contains__('l'))
HelloWorld 4549127709763905501 5 e True
1.4. Booleans
A boolean is a value that can be either True or False. In python booleans are represented by the bool class. The bool class has the following methods:
__and__(self, other)__
: returns the logical and of self and other__or__(self, other)__
: returns the logical or of self and other__xor__(self, other)__
: returns the logical xor of self and other__eq__(self, other)__
: returns True if self and other are equal, False otherwise__ne__(self, other)__
: returns True if self and other are not equal, False otherwise__hash__(self)__
: returns the hash value of self__str__(self)__
: returns the string representation of self__repr__(self)__
: returns the string representation of self
How do we use booleans in python?
a = True b = False print(a.__and__(b)) print(a.__or__(b)) print(a.__xor__(b)) print(a.__hash__())
False True True 1
Another way we can use booleans in python is by using the following operators:
and
: returns the logical and of two valuesor
: returns the logical or of two valuesnot
: returns the logical not of a value
Examples:
a = True b = False print(a and b) print(a or b) print(not a)
False True False
We will also introduce more in coming sections.
2. Flow Control Statements
2.1. Conditional Statements
Conditional statements are used to control the flow of execution of a program. In python conditional statements are represented by the if, elif, and else statements. The syntax of the if statement is as follows:
if condition: # do something print('Hello')
If we need to use multiple conditions we can use the elif statement. The syntax of the elif statement is as follows:
if condition1: # do something print('Hello') elif condition2: # do something print('World')
If none of the conditions are met we can use the else statement. The syntax of the else statement is as follows:
if condition1: # do something print('Hello') elif condition2: # do something print('World') else: # do something print('!')
2.2. Loops
Loops are used to repeat a block of code. In python loops are represented by the for and while statements. The syntax of the for statement is as follows:
for i in range(10): # do something print(i)
0 1 2 3 4 5 6 7 8 9
We can also make looks more interesting by using the following syntax:
someList = [x for x in range(10)] print(someList)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
We call this a list comprehension. We can also use list comprehensions to create lists of lists. The general syntax of a list comprehension is as follows:
[[expression] for item in iterable if condition]
2.2.1. While
The syntax of the while statement is as follows:
i = 0 while i < 10: # do something print(i) i += 1
0 1 2 3 4 5 6 7 8 9
2.3. Break and Continue
The break statement is used to exit a loop. The continue statement is used to skip the current iteration of a loop. The syntax of the break statement is as follows:
for i in range(10): if i == 5: break print(i)
0 1 2 3 4
The syntax of the continue statement is as follows:
for i in range(10): if i == 5: continue print(i)
0 1 2 3 4 6 7 8 9
We can see that the number 5 is not printed because we used the continue statement to skip the current iteration of the loop.
3. Logic
3.1. Truth Value Testing
In python we can test the truth value of an object. The following values are considered false:
None
False
zero of any numeric type
any empty sequence, for example, '', (), []
any empty mapping, for example, {}
All other values are considered true. For example:
True
non-zero numbers
non-empty strings
non-empty lists
non-empty tuples
non-empty dictionaries
We can use the following functions to test the truth value of an object:
bool()
: returns the truth value of an objectall()
: returns True if all elements of an iterable are true (or if the iterable is empty)any()
: returns True if any element of an iterable is true. If the iterable is empty, returns False
3.2. Identity Operators
The identity operators are used to compare the memory locations of two objects. The identity operators are:
is
: returns True if the operands are identical (refer to the same object)is not
: returns True if the operands are not identical (do not refer to the same object)
Examples:
a = 5 b = 5 print(a is b) print(a is not b)
True False
3.3. Membership Operators
The membership operators are used to test whether a value or variable is found in a sequence. The membership operators are:
in
: returns True if a sequence with the specified value is present in the objectnot in
: returns True if a sequence with the specified value is not present in the object
Examples:
a = [1, 2, 3, 4, 5] print(1 in a) print(6 in a) print(1 not in a) print(6 not in a)
True False False True
3.4. Bitwise Operators
Bitwise operators are used to compare (binary) numbers. The bitwise operators are:
&
: binary and|
: binary or~
: binary xor~
: binary ones complement<<
: binary left shift>>
: binary right shift
Examples:
a = 60 b = 13 print(a & b) print(a | b) print(a ^ b) print(~a) print(a << 2) print(a >> 2)
12 61 49 -61 240 15
We probably won't use bitwise operators very often, but it's good to know they exist.
4. Scope and Constants
4.1. Scope
Scope, is the area of a program where an object or name may be accessible. In python there are two types of scope:
global
: a name that is defined outside of a functionlocal
: a name that is defined inside a function
We can access a global variable inside a function by using the global
keyword. The syntax of the global
keyword is as follows: global variableName
. For example:
a = 5 def myFunction(): global a a = 10 print(a) myFunction() print(a)
10 10
4.2. Constants
Constants are variables whose value cannot be changed. In python constants are usually defined in all capital letters. For example: PI
, E
, G
.
PI = 3.14 E = 2.71 G = 9.81 print(PI) print(E) print(G)
3.14 2.71 9.81
What if we try to modify a constant? Let's try it:
PI = 3.14 PI = 3.15 print(PI)
3.15
We can see that we can modify a constant. This is because python does not have a constant type. We can use the const
module to define constants. Python uses constants more as a semantic convention than a language feature. The const
module is not part of the standard library, so we need to install it. We can install the const
module using the pip
command:
5. Functions
A function is a block of code which only runs when it is called. You can pass data, known as parameters, into a function. A function can return data as a result. In python a function is defined using the def
keyword. The syntax of a function is as follows:
def myFunction(): print("Hello World")
We can call the function by using the function name followed by parenthesis. For example:
myFunction()
Hello World
5.1. Arguments
Information can be passed into functions as arguments. Arguments are specified after the function name, inside the parentheses. You can add as many arguments as you want, just separate them with a comma. The following example has a function with one argument ( name
). When the function is called, we pass along a first name, which is used inside the function to print the full name:
def myFunction(name): print(name + " Smith") myFunction("John") myFunction("Jane") myFunction("Joe")
John Smith Jane Smith Joe Smith
We can also use default arguments. Default arguments are used when we call the function without arguments. For example:
def myFunction(name = "John"): print(name + " Smith") myFunction() myFunction("Jane") myFunction("Joe")
John Smith Jane Smith Joe Smith
These might also be called optional arguments.
5.2. Return Types
To let a function return a value, use the return
statement:
def myFunction(x): return 5 * x print(myFunction(3)) print(myFunction(5)) print(myFunction(9))
15 25 45
That is not the only way to get some data from a function, we can make use of yield
statements. The yield
statement is used to define a generator, which is covered in the next sections.
5.3. Recursion
Python also accepts function recursion, which means a defined function can call itself. Recursion is a common mathematical and programming concept. It means that a function calls itself. This has the benefit of meaning that you can loop through data to reach a result. The developer should be very careful with recursion as it can be quite easy to slip into writing a function which never terminates, or one that uses excess amounts of memory or processor power. However, when written correctly recursion can be a very efficient and mathematically-elegant approach to programming.
Example:
def fib(n): if n <= 1: return n else: return(fib(n-1) + fib(n-2)) print(fib(7))
13
Be careful, python has a default recursion limit of 1000. If you need to increase the recursion limit, you can use the sys.setrecursionlimit()
method. But this probably means you are doing something wrong.
6. Lists
Probably the best datatype in python is the list
. A list is a collection which is ordered and changeable. In python lists are written with square brackets. For example: myList = [1, 2, 3]
. We can access the items of a list by referring to the index number. For example:
myList = ["apple", "banana", "cherry"] print(myList[1])
banana
We can also use negative indexing. Negative indexing means beginning from the end, -1 refers to the last item, -2 refers to the second last item etc. For example:
myList = ["apple", "banana", "cherry"] print(myList[-1])
cherry
Some important list methods are:
append()
: adds an element at the end of the listclear()
: removes all the elements from the listcopy()
: returns a copy of the listcount()
: returns the number of elements with the specified value. Ex:myList.count("apple")
extend()
: add the elements of a list (or any iterable), to the end of the current list. Ex:myList.extend(myList2)
index()
: returns the index of the first element with the specified valueinsert()
: adds an element at the specified position. Ex:myList.insert(2, "orange")
pop()
: removes the element at the specified position. This also returns the removed element. Ex:myList.pop(1)
remove()
: removes the first item with the specified value. Ex:myList.remove("banana")
reverse()
: reverses the order of the listsort()
: sorts the list
6.1. List Comprehension
This is really what makes python so powerful. List comprehension is an elegant way to define and create lists based on existing lists. For example:
myList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] newList = [x for x in myList if x % 2 == 0] print(newList)
[2, 4, 6, 8, 10]
This, is frankly amazing. We can also use if
and else
statements in list comprehension.
Here is a table of some examples when using list comprehension:
Bad Python | Good Python |
---|---|
myList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] newList = [] for x in myList: if x % 2 == 0: newList.append(x) print(newList) | myList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] newList = [x for x in myList if x % 2 == 0] print(newList) |
final = []source = np.random.randint(0, 100, 100)for x in source: if x < 0.5: final.append(x)print(final) | source = np.random.randint(0, 100, 100)final = [x for x in source if x < 0.5]print(final) |