Introduction To Python
Introduction To Python
The purpose of this lab is to familiarize you with this term's lab system and to diagnose your programming
ability and facility with Python. This course uses Python for all of its labs, and you will be called on to
understand the functioning of large systems, as well as to write significant pieces of code yourself. While
coding is not, in itself, a focus of this class, artificial intelligence is a hard subject full of subtleties. As such,
it is important that you be able to focus on the problems you are solving, rather than the mechanical code
necessary to implement the solution.
Python resources
Python: There are a number of versions of Python available. This course will use standard Python from
http://www.python.org/. If you are running Python on your own computer, you should download and
install latest version (Currently Python 3.7.4) from http://www.python.org/download/ .
Many other languages require a lot more structure in their simplest programs, but in Python this single
line, which prints a short message, is sufficient. A very informative example of Python’s syntax which does
(almost) exactly the same thing:
A hash (#) denotes the start of a comment. The interpreter will ignore everything that follows the hash
until the end of the line.
In many languages we need to use a special character to mark the end of each instruction – usually a
semicolon. Python uses ends of lines to determine where instructions end (except in some special cases
when the last symbol on the line lets Python know that the instruction will span multiple lines). We may
optionally use semicolons – this is something we might want to do if we want to put more than one
instruction on a line (but that is usually bad style):
Python is a dynamically (and not statically) typed language. That means that we don’t have to specify a
type for a variable when we create it – we can use the same variable to store values of different types.
However, Python is also strongly typed – at any given time, a variable has a definite type. If we try to
perform operations on variables which have incompatible types (for example, if we try to add a number
to a string), Python will exit with a type error instead of trying to guess what we mean.
Python has large collection of built-in functions that operate on different kinds of data to produce all kinds
of results. One function is called type, and it returns the type of any object.
1.1.3.1 Numbers:
The interpreter acts as a simple calculator: you can type an expression at it and it will write the value.
Expression syntax is straightforward: the operators +, -, * and / work just like in most other languages.
The equal sign (=) is used to assign a value to a variable. Afterwards, no result is displayed before the next
interactive prompt:
In interactive mode, the last printed expression is assigned to the variable _. This means that when you
are using Python as a desk calculator, it is somewhat easier to continue calculations, for example:
1.1.3.2 Strings
A string is a sequence of characters. Python can also manipulate strings, which can be expressed in several
ways. They can be enclosed in single quotes ('...') or double quotes ("...") with the same result. \ can be
used to escape quotes. In the interpreter, the output string is enclosed in quotes and special characters
are escaped with backslashes.
Some common escape sequences:
Sometimes we may need to define string literals which contain many backslashes – escaping all of them
can be tedious. We can avoid this by using Python’s raw string notation. By adding an r before the opening
quote of the string, we indicate that the contents of the string are exactly what we have written, and that
backslashes have no special meaning. For example:
Strings can be concatenated (glued together) with the + operator, and repeated with *:
Strings can be indexed (subscripted), with the first character having index 0. There is no separate character
type; a character is simply a string of size one:
1.1.4 Files
Although the print function prints to the console by default, we can also use it to write to a file. Here is
a simple example:
In the with statement the file myfile.txt is opened for writing and assigned to the variable myfile.
Inside the with block, Hello! followed by a newline is written to the file. The w character passed to
open indicates that the file should be opened for writing. The with statement automatically closes the
file at the end of the block, even if an error occurs inside the block.
Unlike print, the write method does not add a newline to the string which is written.
We can read data from a file by opening it for reading and using the file’s read method:
This reads the contents of the file into the variable data. Note that this time we have passed r to the
open function. This indicates that the file should be opened for reading.
There can be zero or more elif parts, and the else part is optional. The keyword ‘elif’ is short for
‘else if’, and is useful to avoid excessive indentation. An if … elif … elif … sequence is a substitute for
the switch or case statements found in other languages.
The interpreter will treat all the statements inside the indented block as one statement – it will process
all the instruction in the block before moving on to the next instruction. This allows us to specify multiple
instructions to be executed when the condition is met.
If you do need to iterate over a sequence of numbers, the built-in function range () comes in handy.
It generates arithmetic progressions:
The given end point is never part of the generated sequence; range(10) generates 10 values, the legal
indices for items of a sequence of length 10. It is possible to let the range start at another number, or to
specify a different increment (even negative; sometimes this is called the ‘step’):
We use the def statement to indicate the start of a function definition. The next part of the definition is
the function name, in this case print_a_message, followed by round brackets (the definitions of any
parameters that the function takes will go in between them) and a colon. Thereafter, everything that is
indented by one level is the body of the function.
We can create a function that writes the Fibonacci series to an arbitrary boundary:
A function definition introduces the function name in the current symbol table. The value of the function
name has a type that is recognized by the interpreter as a user-defined function. This value can be
assigned to another name which can then also be used as a function. This serves as a general renaming
mechanism:
• giving only the mandatory argument: ask_ok('Do you really want to quit?')
• giving one of the optional arguments: ask_ok('OK to overwrite the file?', 2)
• or even giving all arguments: ask_ok('OK to overwrite the file?', 2, 'Come
on, only yes or no!')
This example also introduces the in keyword. This tests whether or not a sequence contains a certain
value.
In Python, there can only be one function with a particular name defined in the scope – if you define
another function with the same name, you will overwrite the first function. You must call this function
with the correct number of parameters, otherwise you will get an error. Sometimes there is a good reason
to want to have two versions of the same function with different sets of parameters. You can achieve
something similar to this by making some parameters optional. To make a parameter optional, we need
to supply a default value for it. Optional parameters must come after all the required parameters in the
function definition:
When we call the function, we can leave the optional parameter out – if we do, the default value will be
used. If we include the parameter, our value will override the default value.
1.3.2 Lambdas
We have already seen that when we want to use a number or a string in our program we can either write
it as a literal in the place where we want to use it or use a variable that we have already defined in our
code. For example, print("Hello!") prints the literal string "Hello!", which we haven’t stored in
a variable anywhere, but print(message) prints whatever string is stored in the variable message.
We have also seen that we can store a function in a variable, just like any other object, by referring to it
by its name (but not calling it). Is there such a thing as a function literal? Can we define a function on the
fly when we want to pass it as a parameter or assign it to a variable, just like we did with the string
"Hello!"?
The answer is yes, but only for very simple functions. We can use the lambda keyword to define
anonymous, one-line functions inline in our code:
Lambdas can take parameters – they are written between the lambda keyword and the colon, without
brackets. A lambda function may only contain a single expression, and the result of evaluating this
expression is implicitly returned from the function (we don’t use the return keyword):
1.4 Class Definitions:
A class serves as the primary means for abstraction in object-oriented programming. In Python, every
piece of data is represented as an instance of some class. A class provides a set of behaviors in the form
of member functions (also known as methods), with implementations that are common to all instances
of that class. A class also serves as a blueprint for its instances, effectively determining the way that state
information for each instance is represented in the form of attributes (also known as fields, instance
variables, or data members).
As a first example, we will define a CreditCard class. The instances defined by the CreditCard class
provide a simple model for traditional credit cards. They have identifying information about the customer,
bank, account number, credit limit, and current balance. The class restricts charges that would cause a
card’s balance to go over its spending limit, but it does not charge interest or late payments.
The construct begins with the keyword, class, followed by the name of the class, a colon, and then an
indented block of code that serves as the body of the class. The body includes definitions for all methods
of the class. These methods are defined as functions, yet with a special parameter, named self, that
serves to identify the particular instance upon which a member is invoked.
By convention, names of members of a class (both data members and member functions) that start with
a single underscore character (e.g., _secret) are assumed to be nonpublic and should not be relied
upon.
Syntactically, self identifies the instance upon which a method is invoked. For example, assume that a
user of our class has a variable, my_card, that identifies an instance of the CreditCard class. When
the user calls my_card.get_balance( ), identifier self, within the definition of the get_balance
method, refers to the card known as my_card by the caller. The expression, self._balance refers
to an instance variable, named _balance, stored as part of that particular credit card’s state.
1.4.2 The Constructor
A user can create an instance of the CreditCard class using a syntax as:
cc = CreditCard( John Doe, 1st Bank , 5391 0375 9387 5309 , 1000)
Internally, this results in a call to the specially named _ _init_ _ method that serves as the constructor
of the class. Its primary responsibility is to establish the state of a newly created credit card object with
appropriate instance variables. By the conventions, a single leading underscore in the name of a data
member, such as _balance, implies that it is intended as nonpublic. Users of a class should not directly
access such members.
Many classes like to create objects with instances customized to a specific initial state. Therefore a class
may define a special method named _ _init_ _(), like this:
We will demonstrate some basic usage of the CreditCard class, inserting three cards into a list named
wallet. We use loops to make some charges and payments, and use various accessors to print results
to the console. These tests are enclosed within a conditional, if _ _name == ‘_ _main_ _’:, so
that they can be embedded in the source code with the class definition.
1.4.3 Class and Instance Variables
Generally speaking, instance variables are for data unique to each instance and class variables are for
attributes and methods shared by all instances of the class: