CS1302 Introduction to Computer Programming
How can different functions work on the same variable?
What happens with global declarations removed?
count = count + 1count += 1Hint:
Functions with global variables are dependent.
With global variables,
To ensure functional independence, define pure functions which
Can we call a function without specifying all its arguments?
Can we set start=1 as a default parameter instead of stop=5?
Can we set multiple default parameter?
Can we define a function using the function itself?
What does the function compute?
Why recursion instead of iteration?
Say you would like to do check if a number is divisible by the numbers 2, 3, 5 and 7. Normally, you would write something like
Remember that the modulo operator \(\%\) takes the reminder of the division of number \(n\) by the numbers 2, 3, 5, and 7.
How do we avoid copy-pasting the same logic (code duplication) to decrease redundancy?
Further simplification:
Functions in Python are objects, just like the previous types you have studied (strings, integers). Thus, we can treat it like data.
Lambda expressions are simple, anonymous functions to simplify function calls.
Sometimes also referred to as nested functions
Break down functions into smaller components in a function
Application of passing functions as arguments to other functions
Break down functions into smaller components in a function
Let us get back to our previous example:
Python supports object oriented programming (OOP). As previously mentioned, each Python object has a type, or class.
An object is an instance of a class.
With OOP, we combine data and methods.
Before we go deeper into objects, let us look back at some of the general ideas and ways to express and use objects.
In general, a method call will have the following syntax:
object
method name
parameter list
(
)
.
object
period (dot)
method name
parameter list
: expression that represents object
: associates object expression with method
to be called
: name of method to execute
: comma-separated list of method's parameters
always required even if there are no parameters
similar to parameter list for a function call
Python strings are objects. They provide the perfect example of combining data and methods.
course_name = "cs1302"
print("Welcome to the {} course, hope you like it so far!"
.format(course_name.upper()))
# Output: Welcome to the CS1302 course, hope you like it so far!String contains the data "cs1302" and has the upper() method
Optional:
For more string methods, check out https://docs.python.org/3/library/string.html
Sometimes, we might want to read data from a file or save the results of our program execution into a file. We can achieve this with Python's standard library.
# Reading a file named file.txt
f = open("file.txt") # Equivalent of open("file.txt", "r")
for line in f:
print(line.strip())
f.close()There are several different modes for opening a file, specified in the second argument of the open function
Works with classes which provide initialization (open) and finalization (close) protocols. These protocols are defined for objects using the built-in __enter__and __exit__methods.
object-creation
object
:
with
as
block
with
object-creation
as
object
block
: reserved word, begins the statement
: attempts to create an object, only executes
function in block if creation successful
: reserved word, binds object created by object-
creation expression to a variable
: binding for object created by object-creation
: contains code which can use the previously
bounded object
object-creation
object
:
with
as
block
Formal name of file objects is \(TextIOWrapper\), found in the built-in \(io\) module. No import statement is required since the functions from \(io\) module are exposed by default.
open
filename
open mode
,
)
(
Returns a file (\(TextWrapperIO\)) object. Supported open modes are:
- 'r' for reading, default when no open
mode is specified
- 'w' for writing
- 'a' for appending data to file
*appending = adding data to end of file
When a file has been opened with 'w' or 'a', we can write to it with a file object's \(write\) method.
Usually, we have to call the \(close\) method to close the file.
with open("my_diary.txt", "w") as f:
# Note that \n represents a newline operator
f.write("I am currently attending\n")
f.write("The CS1302 course\n")
print(f.read())
for line in f:
print(line.strip())
With context managers, we can automatically close the file after all function inside the block executes:
Provided by the \(Fraction\) class from the \(fractions\) module
Modelling rational numbers (numbers as ratio of two integers) with a numerator and denominator.
Python reserves some special names for some methods.
For instance, the \(Fraction\) class provides an __add__ method. This function is invoked when we add two fractions. The + operator is an example of syntactic sugar for the __add__ method.
Other special methods which Python provides:
- __mul__, multiplication: f.__mul__(g) is equivalent to f * g
- __eq__, relational quality: f.__eq__(g) is equivalent to f == g
- __gt__, greater than: f.__gt__(g) is equivalent to f > g
- __sub__, subtraction: f.__sub__(g) is equivalent to f - g
- __neg__, unary minus: f.__neg__() is equivalent to -f
Let's apply these concepts to what you have learned from previous lectures in the next slide!
A variable is a name that labels an object. We have treated a variable as if it represents the object. For example, given the following statement:
We often refer to the object \(frac1\). In fact, this \(frac1\) "object" is the \(Fraction\) object representing the rational number \(\frac{1}{2}\).
To better understand objects, let us have a deeper look.
A variable is a name that labels an object. We have treated a variable as if it represents the object. For example, given the following statement:
We often refer to the object \(frac1\). In fact, this \(frac1\) "object" is the \(Fraction\) object representing the rational number \(\frac{1}{2}\).
To better understand objects, let us have a deeper look.
This aliasing behavior might be a problem. Let's say we created two class variables c1 and c2.
Why is this so?
The following statement:
f = Fraction(2, 3)
Creates a Fraction object representing the rational number \(\frac{2}{3}\) and assigns the variable f to the object. By doing so, the Python interpreter reserves some computer memory to hold the object and initializes the objects as such:
f.numerator = 2
f.denominator = 3
If we reassign the statement in the previous slide to be:
f = None
Where None is a special type which represents no object, the Fraction object previously created is now effectively abandoned and is unused for the remainder of the program's execution. In other words, it is now garbage.
Garbage is memory allocated by a program which is no longer accessible by the program. Python's interpreter is able to automatically do garbage collection using a reference counting garbage collector.
Let us look at the visualization below: