“Chapter 2. Essential Building Blocks of Computer Programs” in “Introduction to Computer Programming with Python”
Chapter 2 Essential Building Blocks of Computer Programs
This chapter introduces the fundamental elements and building blocks of computer programs in the Python language. These fundamental building blocks include the words, keywords, and reserved words that can be used in Python programs. You will also learn the primary data types and data models, the operators, and some built-in functions that can be applied to the data and data models in Python, as well as some important statements or sentences that can be used to instruct computers.
Learning Objectives
After completing this chapter, you should be able to
- • make and use names correctly to identify various items in your Python programs.
- • use different types of data and data models correctly.
- • use the proper operators for different types of data and data models.
- • correctly compose expressions using variables, data, operators, and the built-in functions of Python.
- • write an assignment statement to assign values to variables.
- • write augmented assignment statements.
- • write input statements correctly to get input from users.
- • write correct statements using print.
2.1 Primary Constructs of Computer Programs in Python
Computer programs tell computers how to complete specific tasks. These specific tasks may be as small as what you would do on a calculator or as big as mission control for space exploration. Believe it or not, computer programs for all these different tasks are composed of the same types of statements on the same types of primary data. The difference is in how the data are structured and how the statements are organized. In computing, the study of the first “how” is the subject of data structures, whereas the study of the second “how” is the subject of algorithms. In computing, there are dedicated courses providing in-depth coverage on data structures and algorithms. While studying introductory computer programming, keep in mind the importance of data and algorithms in solving problems and try to identify the data involved and describe the algorithms needed to solve a problem using the methods introduced in 1.7.
Vocabulary of the Programming Language
Vocabulary is the foundation of any language. In computer languages, identifiers are an important part of the vocabulary used to write computer programs. As in all programming languages, identifiers in Python are used to identify variables, functions and methods, classes, objects, and modules. They are called identifiers because, for computers, the only purpose of these names is to identify specific locations of computer memory that hold or can be used to hold specific data or code blocks.
Figure 2-1 illustrates how a variable named “grade” is identified as the memory location that holds the integer 98. Please note that we use 98 in the diagram for illustration purposes, although, in fact, both data and program codes are stored as sequences of binary (0s and 1s).
Figure 2-1: The variable “grade” and its memory location
Although an identifier in computer programs does not need to be meaningful to humans, it must be unique in a given context, which is often called namespace. In Python, a namespace is a mapping from names to objects and is implemented as a Python dictionary.
In a program, different identifiers may be used to refer to the same memory location and hold the same data or program code, as shown in Figure 2-2. This is accomplished through the following Python code:
In [ ]: |
|
Out [ ]: | John |
To check what x and y hold, we use the print statement as follows:
In [ ]: |
|
Out [ ]: | x holds John, y holds John |
Figure 2-2: X and Y point to the same memory location
If we change one identifier to refer to something else, the value referred to by the other identifier will remain the same, as shown in Figure 2-3. This is done with the following code:
In [ ]: |
|
Out [ ]: | x holds Smith, y holds John |
Figure 2-3: Now X and Y point to different memory locations
Please note that in the examples above and other examples in the remainder of the textbook, the box behind In [ ] represents a code cell in Jupyter Notebook, whereas everything behind Out [ ] is the output from the code contained in the code cell when you press Shift+Enter or click the play button.
Rules of Naming Identifiers
In addition to uniqueness, identifiers used in Python programs must be named according to the following rules:
- 1. An identifier can be a combination of letters (a–z, or A–Z), numbers (0–9), and underscores (_).
- 2. It must begin with a letter (a–z or A–Z) or underscore (_).
- 3. In Python, identifiers are case-sensitive, so x and X are different identifiers.
- 4. Identifiers can be of any length.
- 5. User-defined identifiers cannot be the same as words reserved by the Python language.
According to these rules, the following are legitimate user-defined identifiers in Python:
AB, zf, cd, hz, d_2, c5E, falling, to_be
Whereas the following are not:
1d, d/, f-, g.d
In Python, identifiers shown in Table 2-1 are reserved and hence called reserved words or keywords, with predefined special meaning in the language, which means that you must not use them to name your variables, functions/methods, classes, or modules.
Reserved word | Special meaning | Reserved word | Special meaning |
---|---|---|---|
and | logical and | if | conditional statement |
as | used together with import and with to create new alia | import | to import modules |
assert | to make an assertion for handling possible errors | in | membership test |
break | to get out of some code blocks such as during iteration | is | identity test |
class | to define class | lambda | to create a lambda function |
continue | to omit the rest of the code block and continue the loop | not | logic negation |
def | to define functions | or | logical or |
del | to delete an object | pass | to pass the code block |
elif | used together with if to create a conditional statement | to output | |
else | used together with if to create a conditional statement | raise | to raise an exception intentionally |
except | used together with try to handle errors | return | to return values from a function in function definition |
exec | to execute some dynamically generated code in a string or object | try | used for exception handling |
finally | used together with try and except to handle errors | while | to make loop/iteration statements |
for | to create a loop | with | to introduce context for a code block |
from | used together with import | yield | used in place of return, to turn a function into a generator |
global | to access a global variable from inside of a function |
In addition to the reserved words in Table 2-1, you should also avoid using names that have been used by Python for built-in types and built-in functions, classes, and modules. These names are collectively called built-in names. It is grammatically fine to use built-in names as user-defined identifiers, but using them may cause confusion.
Furthermore, Python also uses the underscore _ as an identifier for a very special variable to hold the result of the last evaluation when Python is running in interactive mode, as shown in the following example:
>>> sum ([1,2,3,4,5,6])
21
>>> sum (list(range(1000)))
499500
>>> _
499500
>>> |
This use of _ as a special variable can also be seen in Jupyter Notebook, as shown in the following example:
In [ ]: |
|
Out [ ]: | 729 |
In [ ]: |
|
Out [ ]: | 729 |
When Python is not running in interactive mode, _ has no predefined meaning, however. Even within Jupyter Notebook, the value of _ is often unpredictable unless explicitly assigned.
Syntactically, the special variable _ can be used in the same way as others, especially when the value is to be thrown away and not used, as shown below:
In [ ]: |
|
Out [ ]: | 2^10 = 1024 |
Python Naming Conventions
Although identifiers used in Python programs don’t have to be meaningful to humans, you should always try to use more meaningful identifiers in your programs because it is not only easy for you to tell what the identifiers are used for but also easier for other programmers to understand your programs when you work in a team or want to share your code with others.
For the same reason, you should also follow common practices and widely accepted coding conventions when programming. In terms of composing identifiers these conventions include:
- 1. Lower case identifiers are usually used for variables and function names.
- 2. Capitalized identifiers are used for class names.
- 3. Upper case identifiers are used for constants, such as PI = 3.1415926, E = 2.7182, and so on.
- 4. When an identifier has multiple words, the underscore _ is used to separate the words. So we use your_name instead of yourname, use to_be instead of tobe. Some programmers prefer not to use an underscore, but to capitalize each word, except for the first word, when an identifier is used as a variable or the name of a function or method.
Along with the programming technologies, these practices and conventions have developed over the years and may further evolve in the future. A good Python programmer should follow the developments and trends of the Python programming community.
Names with Leading and/or Trailing Underscores
As mentioned above, identifiers for variables, function/method names, and class names may begin and/or end with a single underscore, double underscores, or even triple underscores, and those names may have special meanings.
When a name has both leading and trailing double underscores, such as __init__, it is called a dunder (double-underscore) name. Some dunder names have been given special meanings in Python Virtual Machine (PVM) or a Python interpreter. They are either reserved as special variables holding special data or as special function/method names.
The following are some special dunder names used as special values or special variables holding special data.
__main__
Used as a special value. When a Python program/script file runs as the main program other than a module, the special variable __name__ will be assigned special value __main__.
__name__
Used as a special variable in a Python program to hold special value indicating how the program file is called or used. If the program file is used as the main program, __name__ will hold __main__. If it is used as a module, __name__ will hold the name of the module.
__package__
Used as a special variable to hold the package’s name if a module imported is a package. Otherwise, __package__ will hold an empty string.
__spec__
Used as a special variable to hold the module specification used when the module is imported. If the Python program file is not used as a module, it will hold the special value None.
__path__
Used as a special variable to hold the path to the module in a package. If the module is not within a package, __path__ is not defined.
__file__
Used as a special variable to hold the name of a Python program file.
__cached__
A special variable often used together with the special variable __file__, referring to a precompiled bytecode. If the precompiled bytecode is not from a program file, __file__ is not defined.
__loader__
Used as a special variable to hold the object that loads or imports the module so that you would know who is using the module.
__doc__
Used as a special variable to hold the documentation of a module or Python program if it is used as the main program, documentation of a class, or function or method of a class.
Dunder names used for special functions and methods will be discussed in Chapter 6 and Chapter 7.
Rules of Scope Resolution for Identifiers
Big programs for complicated applications often use hundreds or even thousands of identifiers to name variables, functions, classes, and other objects. When so many names are used, it is unavoidable that some names will be used more than once. How can we ensure in a program that each name can be mapped to an object without confusion and ambiguity? The answer is to follow the LEGB rule, in which L, E, G, and B refer to different scopes from small to big: L is for local, referring to the inside of a function or class; E is for enclosed, referring to the inside of a function enclosing another function; G is for global, referring to the space outside of all classes and function in a Python program file; and B is for built-in, referring to all the names defined within Python’s built-in module. The relationships of LEGB scopes are illustrated in Figure 2-4.
Figure 2-4: LEGB rules for scope resolution for names
The illustration above should be viewed in reference to a name used within a function or class. To resolve the name or to link it to a specific object, apply the following LEGB rules:
- 1. Look at the names defined locally (L) within the function/method or class. If not defined, proceed to the next rule.
- 2. Check whether the name has been defined in the enclosure (E) function (note that enclosures are not often used, so this is just for discussion right now). If not, proceed to the next rule.
- 3. Check whether it has been defined globally (G).
- 4. Check whether it is a built-in (B) name of Python.
The following sample shows how matching local and global names are resolved:
In [ ]: |
|
Out [ ]: | What is your name: Kevin local name is Kevin Global name is John |
You may have noted in the example above that variable l_name is defined both locally in definition of the function display_names() and globally. When it is used within the function, its local definition is used; variable g_name, on the other hand, is only defined globally, and when it is used within the function, it is resolved to its global definition.
In addition to the LEGB rules, please keep in mind the following:
- 1. A local name defined in a function will not be seen anywhere outside the function.
- 2. A local name defined in a class can be seen outside the class or its objects if the name is not a private member of the class, with an explicit reference to the name with dot notation. For example, a name X defined in class C can be accessed using C.X, or O.X if O is an object of C.
- 3. A name Nx globally defined in a Python script file named M1.py can be seen inside another Python script file by either importing the name explicitly from M or by importing M1 as a whole and using dot notation M1.Nx to access Nx.
Simple Data Types
Computers solve problems and accomplish various tasks by processing information. This information is represented in the form of data. It is important to know what data we can use or process and what operations we can apply to different types of data. In Python, there are simple data types and compound data types. The latter are also called models of data.
Simple data types include numbers, strings, and Boolean values. Numbers are used to represent numerical information, strings are used to represent literal information, and Boolean values are used to represent the result of tests, either True or False.
In Python, numbers can be signed integers, float numbers, and complex numbers. They all can be values of variables, as we shall see in the next section.
Although a string can be used conveniently as simple data, it has all the properties and supported operations of a compound data type. As such, it will be discussed in full detail later in this section.
Signed Integers (int)
Signed integers in Python are …−2, −1, 0, 1, 2…, as examples. In Python 3, signed integers can be of arbitrary size, at least theoretically, as long as computer memory is not exhausted. In implementation, however, the biggest integer is defined by sys.maxsize, a variable named maxsize in a module called sys, which specifies the maximum number of bytes that can be used to represent an integer number. The notation of sys.maxsize here means maxsize, defined in module sys.
Operations on integer numbers include the following:
- addition (x + y)
- subtraction (x − y)
- multiplication (x * y)
- division (x / y)
- negation (−x)
- exponentiation (x ** y)
- modular (x % y)
- integer division (x // y)
You should be able to use the above operations, which you should already be familiar with, as well as the following bitwise operations you may never have heard about:
- bitwise or (x | y)
>>> 1 | 4
5
- bitwise exclusive or, often called XOR (x ^ y)
>>> 1 ^ 2
3
- bitwise and (x & y)
>>> 1 & 5
1
- shifted left (x << n)
>>> 2 << 3
16
- shifted right (x >> n)
>>> 256 >> 5
8
- invert (~x)
>>> ~128
-129
The following are a few more samples from the Python interactive shell that show how these operators are used:
>>> 12 + 23
35
>>> 35 - 12
23
>>> -123
-123
>>> 123 * 567
69741
>>> 69741/123 # the result is a real or float-point number
567.0
>>> 69741//123 # get the quotient of two integers
567
>>> 69741%12 # operation % will get the remainder
9
The next few examples are about bitwise operations. The first two operations on the first line show the binary form of the two numbers. In Python, you can have two or multiple statements on a single line, but you are not encouraged to do so.
>>> bin(123); bin(567) # how to have two or more statements on one line
'0b1111011'
'0b1000110111'
>>> bin(123 | 567) # it will be 0001111011 | 1000110111
'0b1001111111'
>>> bin(123 ^ 567) # it will be 0001111011 ^ 1000110111
'0b1001001100'
>>> bin(123 & 567) # it will be 0001111011 & 1000110111
'0b110011'
>>> bin(123 << 5) # it will be 1111011 << 5
'0b111101100000'
>>> bin(123 >> 5) # it will be 1111011 >> 5
'0b11'
>>> bin(~123)
'-0b1111100'
There are also many built-in functions available for operations on integers. All the built-in functions of Python will be discussed in detail below.
In addition, the following methods are also available to use for operations on integer objects.
n.bit_length()
This returns the number of necessary bits representing the integer in binary, excluding the sign and leading zeros.
>>> n = -29
>>> print(f'Binary string of {n} is {bin(n)}')
binary string of -29 is -0b11101
>>> print(f'# of significant bits of {bin(n)} is {n.bit_length()}')
# of significant bits of -0b11101 is 5
n.to_bytes(length, byteorder, *, signed=False)
This returns an array of bytes representing an integer, where length is the length of bytes used to represent the number. byteorder can take Big-Endian or Little-Endian byte order, depending on whether higher-order bytes (also called most significant) bytes come first or lower-order bytes come first, and an optional signed argument is used to tell whether 2’s complement should be used to represent the integer.
>>> n = 256
>>> n.to_bytes(2, byteorder = 'big') # big means higher bytes first
b'\x01\x00'
Recall that modern computers use 2’s complements to represent negative numbers. So if the integer n is negative while signed remains False, an OverflowError will be raised, as shown below:
>>> n = -23567
>>> n.to_bytes(3, 'big')
OverflowError Traceback (most recent call last)
<ipython-input-4-66989275e22d> in <module>
1 n = -23567
----> 2 n.to_bytes(3, 'big')
OverflowError: can't convert negative int to unsigned
So a correct call of the method would be
>>> n = -23567
>>> n.to_bytes(3, 'big', signed = True)
b'\xff\xa3\xf1'
int.from_bytes(bytes, byteorder, *, signed = False)
This classmethod returns the integer represented by the given array of bytes.
>>> n = 256
>>> bin(n)
'0b100000000'
>>> # convert '0b100000000' in Big Endian to int
>>> int.from_bytes(n.to_bytes(2, byteorder = 'big'), 'big')
256
>>> # convert '0b100000000' in Little Endian to int
>>> n.from_bytes(n.to_bytes(2, byteorder = 'big'), 'little')
1
Note that when two bytes are used to represent integer 256, 0b100000000 will be expanded to 00000001 00000000. In Big Endian, it represents 256, but in Little Endian, 00000001 becomes the less significant byte, while 00000000 becomes the most significant byte, and the corresponding number for 256 becomes 00000000 00000001.
For more advanced operations on integers, there are some special modules such as the standard math module, math; the free open-source mathematics software system SAGE; (https://www.sagemath.org/); SymPy (https://www.sympy.org/en/index.html); and, for operations in number theory, eulerlib (https://pypi.org/project/eulerlib/).
Float (float)
Float numbers are numbers with decimals, in the form of 12.5 in decimal notation or 1.25e1 in scientific notation, for example. Operations on float numbers include addition (+), subtraction (−), multiplication (*), division (/), and exponentiation (**), as shown below:
In [ ]: |
|
Out [ ]: | x = 8762.31728619258 |
In the example above, the equal sign (=) is an assignment operator in Python (and almost all other programming languages as well). We will explain all operators fully later in this section.
Python can handle very big integers and floating-point numbers. When a number is too big, it becomes difficult to count and check for accuracy. To solve that problem, Python allows using the underscore to separate the numbers, in the similar way that accounting and finance use a comma. The following is an example:
>>> 123_456_789_987.56+234_456_678_789
357913468776.56
Using an underscore to separate the digits has made it much easier to tell how big the number is.
r.as_integer_ratio()
This returns a pair of integers whose ratio is exactly equal to the original float r and with a positive denominator. It will raise OverflowError on infinities and a ValueError on NaNs.
>>> r.as_integer_ratio()
(7093169413108531, 562949953421312)
r.is_integer()
This returns True if r is finite with integral value, and False otherwise.
>>> r.is_integer()
False
r.hex()
This returns a representation of a floating-point number as a hexadecimal string. For finite floating-point numbers, this representation will always include a leading 0x and a trailing p and exponent.
>>> r.hex()
'0x1.9333333333333p+3'
float.fromhex(s)
This returns the float represented by a hexadecimal string s. The string s may have leading and trailing whitespace.
>>> float.fromhex('0x1.9333333333333p+3')
12.6
Boolean (bool)
Boolean data have only two values: True and False. They are used to represent the result of a test or an evaluation of logical expressions, as we will see. Technically, Python does not need a special Boolean data type, since it treats 0 and None as Boolean False, and treats everything else as Boolean True, as shown below:
In [ ]: |
|
Out [ ]: | b = None Print this out when b is None! |
However, having a Boolean data type with two Boolean values of True and False does clearly remind Python programmers, especially beginners, that there are special types of data and expressions called Boolean data and Boolean expressions.
Complex (complex)
If you have never heard about complex numbers, quickly search the internet for complex numbers and read some articles or watch some videos.
Briefly, a complex number is a representation of a point on a plane with X and Y axes that take the form of x + yj, in which x and y are float numbers that represent and define the location of a point on the plane. Examples of complex numbers are 1 + 1j, 3 − 6j, 2.5 − 8.9j, and so on.
The same operations on float numbers can also be applied to complex numbers, as shown below:
In [ ]: |
|
Out [ ]: | (3.5 + 6.7j) + (12.3 - 23.9j) = (15.8 - 17.2j) (3.5 + 6.7j) - (12.3 - 23.9j) = (-8.8 + 30.599999999999998j) (3.5 + 6.7j) * (12.3 - 23.9j) = (203.18 - 1.2399999999999807j) (3.5 + 6.7j) / (12.3 - 23.9j) = (-0.16204844290657439 + 0.229840830449827j) |
Compound Data Types
In previous sections, we saw data in pieces. Sometimes it is more convenient, more effective, and even necessary to use some data together to represent certain kinds of information. Examples are when we refer to the days of the week, months of the year, and so on. Courses in universities are often identified using compound data, a tuple made of a course number and course title or name.
In Python, compound data types provide means of structuring data. They are also referred to as data structures.
Compound data types in Python can be categorized into sequence and nonsequence data types. Items in sequence compound data are ordered and indexed. Sequence compound data types include string, list, and tuple. Items in a nonsequence compound data are not ordered. Nonsequence compound data include set and dictionary.
String (str)
Sequences are a group of data in order, and a string is a good example of a sequence.
Like numbers, strings are very important in all programming languages. It is hard to imagine what a number means without its context. For that reason, in most programming languages, strings are also considered a primary data type in terms of their importance and the role that they play.
In Python, strings are sequences of characters, symbols, and numbers enclosed in a pair of double quotation marks or a pair of single quotation marks. Table 2-2 is a list of ASCII characters that can be used in strings. The following are some examples of strings:
In [ ]: |
|
Out [ ]: | s1 = this is my first string in double quotes s2 = string in single quotes |
When a string is too long and needs to span more than one line, a pair of triple quotation marks can be used, as shown in the following example:
In [ ]: |
|
Out [ ]: | long_string = ASCII stands for American Standard Code for Information Interchange. Computers can only understand numbers, so an ASCII code is the numerical representation of a character such as "a" or "@" or an action of some sort. ASCII was developed a long time ago and now the nonprinting characters are rarely used for their original purpose. Below is the ASCII character table. The first 32 characters are nonprinting characters. ASCII was designed for use with teletypes and so the descriptions in ASCII are somewhat obscure. If someone says they want your CV in ASCII format, all this means is they want "plain" text with no formatting such as tabs, bold or underscoring—the raw format that any computer can understand. This is usually so they can easily import the file into their own applications without issues. Notepad.exe creates ASCII text, and MS Word lets you save a file as "text only." |
This can be very useful in cases such as when you want to print out instructions for users to use with an application you developed.
Otherwise, you would need to use backslash at the end of each line except the last one to escape the invisible newline ASCII character, as shown below:
In [ ]: |
|
Out [ ]: | s0 = Demo only. This string is not too long to be put on one line. |
This is OK if the string only spans across two or three lines. It will look clumsy if the string spans across a dozen lines.
In the example above, we use backslash \ to escape or cancel the invisible newline ASCII character. In Python and almost all programming languages, some characters have special meanings, or we may want to assign special meaning to a character. To include such a character in a string, you need to use a backslash to escape from its original meaning. The following are some examples:
In [ ]: |
|
Out [ ]: | This string will be put on two lines This string will add a tab - a big space |
In the examples above, putting a backslash in front of n assigns the combination \n a special meaning, which is to add a new line to the string; putting a backslash in front of t assigns the combination \t a special meaning, which is to add a tab (a number of whitespaces) to the string. The next example uses backslash to escape the quotation from its original meaning defined in Python.
In [ ]: |
|
Out [ ]: | This is "President" quoted |
Dec | Char | Dec | Char | Dec | Char | Dec | Char |
---|---|---|---|---|---|---|---|
0 | NUL (null) | 32 | SPACE | 64 | @ | 96 | ` |
1 | SOH (start of heading) | 33 | ! | 65 | A | 97 | a |
2 | STX (start of text) | 34 | " | 66 | B | 98 | b |
3 | ETX (end of text) | 35 | # | 67 | C | 99 | c |
4 | EOT (end of transmission) | 36 | $ | 68 | D | 100 | d |
5 | ENQ (enquiry) | 37 | % | 69 | E | 101 | e |
6 | ACK (acknowledge) | 38 | & | 70 | F | 102 | f |
7 | BEL (bell) | 39 | ' | 71 | G | 103 | g |
8 | BS (backspace) | 40 | ( | 72 | v | 104 | h |
9 | TAB (horizontal tab) | 41 | ) | 73 | I | 105 | i |
10 | LF (NL line feed, new line) | 42 | * | 74 | J | 106 | j |
11 | VT (vertical tab) | 43 | + | 75 | K | 107 | k |
12 | FF (NP form feed, new page) | 44 | , | 76 | L | 108 | l |
13 | CR (carriage return) | 45 | - | 77 | M | 109 | m |
14 | SO (shift out) | 46 | . | 78 | N | 110 | n |
15 | SI (shift in) | 47 | / | 79 | O | 111 | o |
16 | DLE (data link escape) | 48 | 0 | 80 | P | 112 | p |
17 | DC1 (device control 1) | 49 | 1 | 81 | Q | 113 | q |
18 | DC2 (device control 2) | 50 | 2 | 82 | R | 114 | r |
19 | DC3 (device control 3) | 51 | 3 | 83 | S | 115 | s |
20 | DC4 (device control 4) | 52 | 4 | 84 | T | 116 | t |
21 | NAK (negative acknowledge) | 53 | 5 | 85 | U | 117 | u |
22 | SYN (synchronous idle) | 54 | 6 | 86 | V | 118 | v |
23 | ETB (end of trans. block) | 55 | 7 | 87 | W | 119 | w |
24 | CAN (cancel) | 56 | 8 | 88 | X | 120 | x |
25 | EM (end of medium) | 57 | 9 | 89 | Y | 121 | y |
26 | SUB (substitute) | 58 | : | 90 | Z | 122 | z |
27 | ESC (escape) | 59 | ; | 91 | [ | 123 | { |
28 | FS (file separator) | 60 | < | 92 | \ | 124 | | |
29 | GS (group separator) | 61 | = | 93 | ] | 125 | } |
30 | RS (record separator) | 62 | > | 94 | ^ | 126 | ~ |
31 | US (unit separator) | 63 | ? | 95 | _ | 127 | DEL |
These 128 ASCII characters, including both printable and unprintable ones, are defined for communication in English between humans and machines. There is an extended set of ASCII characters defined for communication in other Western languages such as German, French, and others.
To enable communication between human and machines in languages such as Chinese, Unicode was designed. Details about Unicode can be found at https://unicode.org/. For information on how Unicode is used in Python, read the article at https://docs.python.org/3/howto/unicode.html.
In earlier versions of Python, if you want to use a non-ASCII character encoded in Unicode in a string, you need to know the code, assuming it is NNNN, and use escape sequence \uNNNN within the string to represent the non-ASCII character. You can also use built-in function chr(M) to get a one-character string encoded in Unicode, where M is code of the character in the Unicode table. The reverse built-in function order(Unicode character) is used to get the code of the Unicode character in the Unicode table.
In Python 3.0, however, the default encoding of Python programs was changed to UTF-8, which includes Unicode, so you can simply include any Unicode character in a string and PVM will recognize and handle it correctly, as shown in the following example:
In [ ]: |
|
Out [ ]: | 秦时明月汉时关 can be directly included in a string though you can still use chr(31206) for 秦, chr(27721) for 汉 |
When representing strings, some prefixes or flags can be put in front of the opening quotation mark. These flags are also called prefixes, used before the opening quote of a string. These prefixes are listed in Table 2-3 with their meaning and some coding samples.
Flag | What it does | Code sample in Jupyter Notebook |
---|---|---|
F, f | F/f for formatting. Causes the evaluation of expressions enclosed within {}. | In:
Out: Your name is John. |
R, r | R/r for raw string. Nothing in the string is evaluated, not even \". | In:
Out: Your name is \t {name} \" |
U, u | U/u for Unicode, indicating Unicode literals in a string. It has no effect in Python 3 since Python 3’s default coding is UTF-8, which includes Unicode. | In:
Out: 秦时明月汉时关:秦时明月汉时关 |
B, b | B/b for byte. Literals in the string become byte literals, and anything outside of ASCII table must be escaped with backslash. | In:
Out: b"2005-05-26-10458.68" |
List
List is a very useful compound data type built into Python. A list of elements, which can be different types of data, is enclosed in square brackets. The following are some examples of lists:
[1, 2, 3, 4, 5]
['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
In Python, an element in a list can be any type of data or object, to use a more common computer-science term. So an element can be a list too, such as,
[[1,2,3],[4, 5, 6]]
Assume that
week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
The term week[0] refers to the first element of the list, and week[1] refers to the second element of the list, where 0 and 1 are called index. An index can be negative as well, meaning an item counted from the end of the list. For example, week[-1] will be Sunday, the first item from the end; week[-2] will be Saturday, the second item from the end.
To get a sublist of a list L we use notation L[s: e], where s is the starting point in the list, e is the ending point within the list, and the sublist will include all items from s till e but excluding the item at e. For example, to get all weekdays from the list week, we use week[0,5], as shown below:
In [ ]: |
|
Out [ ]: | ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'] |
Negative indexing becomes convenient when a list, or any sequence, is too long to count from the beginning. In the example above, it is much easier to count from the end to find out that the weekdays stop right before Saturday, whose index is −2, as shown below:
In [ ]: |
|
Out [ ]: | ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'] |
Within the notation of L[s:e], s or e or both may be missing. When s is missed, it means the sublist is indexed from the beginning of the list; when e is missed, it means the sublist is indexed from the end of the list. So week[:] will include all the items of the list week, as shown below:
In [ ]: |
|
Out [ ]: | ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] |
Multiple lists can be joined together with operator +. Assume we have the following two lists:
weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
weekend = ['Saturday', 'Sunday']
We can then combine weekdays and weekend into one list and assign the new list to week using operator +, as shown below:
In [ ]: |
|
Out [ ]: | ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] |
A copy of a list can be easily made by sublisting all its members, as shown below:
week0 = week[:]
We can create a list from a string using the built-in function list():
In [ ]: |
|
Out [ ]: | ['H', 'o', 'w', ' ', 'a', 'r', 'e', ' ', 'y', 'o', 'u', '?'] |
We can also create a list using the built-in function list() and range():
In [ ]: |
|
Out [ ]: | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] [10, 11, 12, 13, 14, 15, 16, 17, 18, 19] |
We can use the built-in function len() to find out how many elements are in the list:
In [ ]: |
|
Out [ ]: | 4 |
Tuple
Tuple is another type of sequence, but members of a tuple are enclosed in parentheses. The following are some sample tuples:
(12, 35)
('Canada', 'Ottawa')
('China', 'Beijing')
You can create a tuple from a list by using the tuple() function. For example,
tpl = tuple(week)
This will create a tuple, as shown below:
('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday')
Similarly, you can create a list from a tuple, as shown below:
week = list(tpl)
Members of a tuple can be accessed in the same way as lists because the members are also indexed. For example, tpl[0] refers to Monday.
Moreover, most of the operations used on lists can be applied to tuples, except those that make changes to the member items, because tuples are immutable.
Why are tuples immutable? You may consider it like this: A tuple is used to represent a specific object, such as a point on a line, or even a shape. If any member of the tuple is changed, it will refer to a different object. This is the same for numbers and strings, which are also immutable. If you change any digit of a number, or any character of a string, the number or string will be different.
Set
In Python, a set is a collection of elements or objects enclosed in a pair of curly brackets. Like sets in mathematics, members in a set are unordered and unindexed. The following are two examples of sets:
grades = {'A', 'A+', 'A−', 'B', 'B+', 'B−', 'C', 'C+', 'C−', 'D', 'D+', 'D−'}
My_friends = {'John', 'Jack', 'Jim', 'Jerry', 'Jeromy'}
You can use built-in function set() to build a set from a list or tuple:
week_set = set(('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'))
Built-in functions set(), list(), tuple(), float(), int(), str() are also called constructors or converters, because they are used to construct or convert to one respective type of data from another type.
You can use membership operator in to test if an object is a member of a set. For example,
'John' in My_friends
will give you a True value because John is a member of set My_friends constructed above.
You can use built-in function len() to get the size of a set—that is, how many members are in the set. So len(grades) will be 12.
Dictionary
In Python, a dictionary is a collection of comma-separated key-value pairs enclosed in curly brackets and separated by a colon :. The members of a dictionary are unordered and unindexed. The following is an example:
In [ ]: |
|
Out [ ]: | Monday of {'Mon': 'Monday', 'Tue': 'Tuesday', 'Wed': 'Wednesday', 'Thu': 'Thursday', 'Fri': 'Friday'} |
Because the keys are used to retrieve the values, each key must be unique within a dictionary. For example, we use Weekday['Mon'] to retrieve its corresponding value, Monday.
In this case, you can also use integer numbers as keys, as shown below:
In [ ]: |
|
Out [ ]: | Monday of {1: 'Monday', 2: 'Tuesday', 3: 'Wednesday', 4: 'Thursday', 5: 'Friday'} |
Object
Although you can code almost any application in Python without object-oriented thinking, you should be aware that Python fully supports object-oriented programming. In fact, Python treats everything as an object, including classes, functions, and modules. For example, numbers are treated as objects in the following statements:
In [ ]: |
|
Out [ ]: | 0x1.2cccccccccccdp+1 5 |
There are some special types of objects in Python, as shown in Table 2-4.
Name | Meaning | Example of usage |
---|---|---|
type | Because in Python everything is an object, so are classes, whose class is type, which is again an object as well as a special object. | It has no real usage in programming but is rather a philosophical and ideological concept. |
None | An object representing “no value.” It is the only object of data type NoneType. For a logical expression, None is the same as 0, null, empty string, and False. | In:
Out: There is no value |
file | A file object can be created by calling the file() or open() methods, which allow us to use, access, and manipulate all accessible files. | f = open("resume.xml", "r") |
function | In Python, functions are first-class objects and can be passed as arguments in another function call. | sort(method, data_list) |
module | A special type of object that all modules belong to. | It is more a philosophical and ideological concept. |
class | A type of all classes. | It is more a philosophical and ideological concept. |
class Instance | An individual object of a given class. | It is more a philosophical and ideological concept. |
method | A method of a given class. | It is more a philosophical and ideological concept. |
code | A code object is the internal representation of a piece of runnable Python code. | It is used in internal Python program running. |
frame | A table containing all the local variables. | It is used in function calling. |
traceback | A special object for exception handling. | It provides an interface to extract, format, and print stack traces of Python programs, especially when an exception is raised. |
ellipsis | A single object called ellipsis, a built-in name in Python 3. | It is rarely used except in slicing. |
Variables and Constants
Data values, variables, and constants are important constructs of any programming language. We have presented all standard simple or primary data types and compound data types and their values in the previous section. In the following section, we will study variables and constants.
Variables
A variable is a name that identifies a location in computer memory to store data. A variable must conform to the rules of naming discussed earlier in this section, and it also must not be used for other purposes within the same context of the program. For example, you cannot use reserved words or keywords as variables.
An important operation on a variable is to assign a value to it or put a value into the memory location identified by the variable. In Python, this is done by using the assignment operator =.
For example, the following statement assigns COMP 218 to the variable course, assigns Smith to the variable student, and assigns 99 to the variable grade:
In [ ]: |
|
Out [ ]: | course is COMP 218, student is Smith, grade is 99 |
Unlike other programming languages, in Python, there is no need to declare its type before a variable is introduced and used in your program for the first time. Its type is determined by the value assigned to it. In the above example, the type of grade is integer, because 99 is an integer.
In [ ]: |
|
Out [ ]: | int |
You may convert the value of a variable into another type using specific built-in functions, such as int(), float(), str(), etc.
In [ ]: |
|
Out [ ]: | 90 |
Please note that in Jupyter Notebook, if you need a new cell, simply click the plus sign button under the notebook menu.
Please also note that the type of variable area is the same as the type of variable pi, but not of variable r. We can check what type the result will be when a different arithmetic operator is applied to a pair of numbers of the same or different types, as shown in Tables 2-5a and 2-5b:
+, -, * | integer | float | complex |
integer | integer | float | complex |
float | float | float | complex |
complex | complex | complex | complex |
/ | integer | float | complex |
integer | float | float | complex |
float | float | float | complex |
complex | complex | complex | complex |
The following coding example in Jupyter Notebook confirms that the result will be a complex number when an integer is divided by a complex number:
In [ ]: |
|
Out [ ]: | (0.1573546180159635-0.2394526795895097j) <class 'complex'> |
You may copy and modify the code above to check other combinations in Jupyter Notebook.
Built-In Constants
We have seen some values of various data types. Some values have special meanings in Python. We call them constants. The following table lists all the constants you may see and use when programming with Python.
Constant name | Meaning | Code sample in Python interactive mode |
---|---|---|
True | Logical true |
|
False | Logical false |
|
None | No value assigned |
|
Ellipsis | Same as …, often used in slicing multiple dimensional arrays |
|
__debug__ | Contains True if Python is started without the -O option |
|
quit | Contains information displayed when Python quits and terminates |
|
exit | Contains information displayed when Python quits and terminates |
|
copyright | Contains copyright information |
|
credits | Contains credit information |
|
license | Contains licensing information |
|
__name__ | When a Python file is started, some special variables are initialized with specific values, and __name__ is one such variable. This variable will have value __main__ if the Python file is started as the main program; otherwise, it will contain the module name or the function or class name if that is imported from the module. |
|
More information about these constants can be found at https://docs.python.org/3/library/constants.html.
Operators
As we learned in previous sections, data are used to represent information, while variables and constants are used to refer to data stored in computer memory. In the following sections, we will learn about operators and built-in functions that can be used to process and manipulate data.
Arithmetic Operators
Arithmetic operators are used on numbers. These operators are well-known. Table 2-7 provides a list of these operators, their meaning, and code samples you may take and practise in Python interactive mode. Please copy only the expressions or statements behind >>>, which is the Python prompt for your input.
Operator | Operation | Code samples in Python interactive mode |
---|---|---|
+ | Add two operands or unary plus + operator can be redefined in a class for its objects defining __add__ |
|
− | Subtract right operand from the left or unary minus |
|
* | Multiply two operands |
|
/ | Divide left operand by the right one (always results into float) |
|
// | Floor division—division that results into integer number by omitting all the decimals |
|
% | Modulus—remainder of the division of left operand by the right |
|
** | Exponent—left operand raised to the power of right |
|
When two or more of these arithmetic operators are used in an expression, the precedence rules you learned in high school or university math courses apply. In brief, the precedence rules for all the operators are as follows:
- 1. Exponent operation (*) has the highest precedence.
- 2. Unary negation (−) is the next.
- 3. Multiplication (*), division (/), floor division (//), and modulus operation (%) have the same precedence and will be evaluated next unary negation.
- 4. Addition (+) and subtraction (−) are next, with the same precedence.
- 5. Comparison operators are next, with the same precedence.
- 6. The three logical operators (not, and, or) are next, with not having the highest precedence among the three, followed by and, then or.
- 7. When operators with equal precedence are present, the expression will be evaluated from left to right, hence left association.
- 8. Parentheses can be used to change the order of evaluation.
The following are some examples of how expressions are evaluated.
>>> 12 + 3 * 21
75
In the expression 12 + 3 * 21, because * has higher precedence than +, 3 * 21 is evaluated first to get 63, and then 12 + 63 is evaluated to get 75.
>>> ((23 + 32) // 6 - 5 * 7 / 10) * 2 ** 3
44.0
In this example, because ** has the highest precedence, 2 ** 3 is evaluated first, to get
((23 + 32) // 6 - 5 * 7 / 10) * 8
In this intermediate result, because of parentheses, we will need to evaluate ((23 + 32) // 6 − 5 * 7 / 10) first, and in this subexpression, because of parentheses, 23 + 32 will be evaluated first to get 55//6 − 5 * 7 /10. According to the precedence rules, this subexpression will be evaluated to 9 − 35 / 10, and then 9 − 3.5 = 5.5. Then the expression above will be
5.5 * 8
which is evaluated to be 44.0.
Comparison Operators
Comparison operators are used to compare two objects. It is easy to understand how they work on numbers and even strings. When a comparison is applied to lists or tuples, the comparison will be applied to pairs of items, one from each list or tuple, and the final result is True if there are more Trues; otherwise it will be False, as shown in the example below:
In [ ]: |
|
Out [ ]: | True |
Table 2-8 explains all the comparison operators, with samples.
Operator | Operation | Code sample in Python interactive mode |
---|---|---|
> | Greater than—True if left operand is greater than the right |
|
< | Less than—True if left operand is less than the right |
|
== | Equal to—True if both operands are equal |
|
!= | Not equal to—True if operands are not equal |
|
>= | Greater than or equal to—True if left operand is greater than or equal to the right |
|
<= | Less than or equal to—True if left operand is less than or equal to the right |
|
Logical Operators
Logical operators are used to form logical expressions. Any expression whose value is a Boolean True or False is a logical expression. These will include expressions made of comparison operators discussed above. Table 2-9 summarize the details of these logical variables.
Operator | Meaning | Code sample in Python interactive mode |
---|---|---|
and | A and B True if both A and B are true |
|
or | A or B True if either A or B is true |
|
not | not A True if A is false |
|
Logical expressions are often used in if and while statements, and it is important to ensure that the logical expressions used in your programs are correctly written. Otherwise, catastrophic results may occur in some real applications. Common errors in writing logical expressions include:
- 1. Using > instead of <, or using < instead of >
- 2. Using >= instead of >, or using > instead >=
- 3. Using <= instead of <, or using < instead <=
For example, suppose you are writing a program to control the furnace at home, and you want to heat the home to 25 degrees Celsius. The code for this should be
if t < 25 : heating()
However, if instead you wrote,
if t > 25 : heating()
the consequence would be either the home will not heat at all (if the initial temperature is below 25 when the program starts) or it will overheat (if the initial temperature is greater than 25).
Bitwise Operators
We know that data in computer memory are represented as sequences of bits, which are either 1 or 0. Bitwise operators are used to operate bit sequences bit by bit. These bitwise operations may look strange to you, but you will appreciate these operations when you need them. Table 2-10 provides a summary of bitwise operators. Please note that built-in function bin() converts data into their binary equivalents and returns a string of their binary expressions, with a leading 0b.
Operator | Meaning | Code sample in Python interactive mode |
---|---|---|
& | Bitwise and |
|
| | Bitwise or |
|
~ | Bitwise not |
|
^ | Bitwise XOR |
|
>> | Bitwise right shift |
|
<< | Bitwise left shift |
|
Assignment Operators
In Python, and all programming languages, the assignment operation is one of the most important operations because assignment operations store data in variables for later use.
In previous sections, we have seen many examples of using the assignment operator =, the equal sign. However, Python provides many augmented assignment operators. Table 2-11 lists all the assignment operators you can use in your Python programs.
Operator | Operation | Code samples in Python interactive mode |
---|---|---|
x = e | Expression e is evaluated, and the value is assigned to variable x. Note that in Python and in previous code samples, assignments can be made to more than one variable with one statement. |
|
x += e | Expression x + e is evaluated, and the value is assigned to variable x. x = x + e |
|
x = e | Expression x − e is evaluated, and the value is assigned to variable x. x = x − e |
|
x *= e | Expression x * e is evaluated, and the value is assigned to variable x. x = x * e |
|
x /= e | Expression x / e is evaluated, and the value is assigned to variable x. x = x / e |
|
x %= e | Expression x % e is evaluated, and the value is assigned to variable x. x = x % e |
|
x //= e | Expression x // e is evaluated, and the value is assigned to variable x. x = x // e |
|
x **= e | Expression x ** e is evaluated, and the value is assigned to variable x. x = x ** e |
|
x &= e | Expression x & e is evaluated, and the value is assigned to variable x. x = x & e |
|
x |= e | Expression x | e is evaluated, and the value is assigned to variable x. x = x | e |
|
x ^= e | Expression x ^ e is evaluated, and the value is assigned to variable x. x = x ^ e |
|
x >>= e | Expression x >> e is evaluated, and the value is assigned to variable x. x = x >> e |
|
x <<= e | Expression x << e is evaluated, and the value is assigned to variable x. x = x << e |
|
Identity Operators
Identity operators are used to test if two operands, usually two identifiers, are identical, which in most implementations of Python means that they are referring to the same memory block of the computer. The examples Table 2-12 tell you more about this. Note that in the example, the built-in function id(o) is used to get the id of object o.
Operator | Meaning | Example |
---|---|---|
is | True if the operands are identical (refer to the same object) Note that 3 and 2 + 1 have the same id, and so does 6 // 2, but not 6 / 2 because 6 / 2 = 3.0, which is different from 3. | >>> x = list(range(3)) >>> y = list(range(3)) >>> x, y ([0, 1, 2], [0, 1, 2]) >>> id(x), id(y) (10049456, 10049016) >>> x is y False >>> id(3) 258398416 >>> id(2 + 1) 258398416 |
is not | True if the operands are not identical (do not refer to the same object). Note that when assigning variable y to variable x, the operation points x to the same memory block y is pointing to (so that the two have the id) and shares the same memory block. However, when a new assignment is made to x or y, the two will have different ids, unless they both hold the same integer or string. | >>> x = list(range(3)) >>> x = y >>> id(x), id(y) (10049016, 10049016) >>> x is y True >>> y = list(range(3)) >>> id(x),id(y) (10090256, 10090336) >>> x, y ([0, 1, 2], [0, 1, 2]) >>> x is not y True |
Sequence Operators
In 2.1, we learned that sequences include strings, lists, and tuples because elements in strings, lists, and tuples are ordered and indexed. Sets and dictionaries are not sequences because elements in dictionaries and sets are not ordered, or not in sequence.
Sequence operators are made available for operations on strings, lists and tuples, as shown in Table 2-13.
Operator | Operation | Code sample in Python interactive mode |
---|---|---|
* | Repeat a sequence such as string, list or tuple multiple times |
|
+ | Join two sequences |
|
[n] | Slice out a single member of the sequence |
|
[n:m] | Slice a sequence start from n to m. |
|
Membership Operator
Membership operators are used to test whether an element is a member of a sequence. There are three membership operators in Python, and two of them are shown in Table 2-14.
Operator | Operation | Code sample in Python interactive mode |
---|---|---|
v in s | True if value v is found in sequence s |
|
v not in s | Checks whether value/variable is not found in the sequence |
|
The third membership operator is used to access members of objects, modules, or packages. It is the dot (.) operator. The example in Table 2-15 shows how to access a function in module math.
Operator | Operation | Code sample in Python interactive mode |
---|---|---|
p.q | q is a member of p where p and q refer to an object (variable, constant, function or method name), package, or module name |
|
Built-In Functions
As with operators, built-in functions are also important in processing and testing data in programs. As the name implies, built-in functions are built into Python Virtual Machine (PVM). A built-in function can be used directly without importing any module or noting what it belongs to.
Built-in functions, and functions or methods in general, can be put into two categories. One is based on the data they return, whereas the other is based on the operations performed, although sometimes the returned data from a built-in function in the second category may still be useful in subsequent executions of the program.
We will first explain built-in functions in the first category, followed by built-in functions in the second category. To best understand these functions, read through these built-in functions and test the sample code in a Python interactive shell or Jupyter Notebook.
abs(x)
This returns the absolute value of x, which can be any number.
>>> abs(-99)
99
>>> abs(-b110010) # a binary number
50
>>> abs(-0o32560) # an octal number
13680
>>> abs(0xdef21a) # a hexadecimal(16) number
13610970
int(s, base = 10)
This converts a number s in a specific base to an integer in base-10. The default base is 10. If the base is explicitly given, s must be a string containing a legitimate literal for the base.
>>> int(19.9)
19
>>> int("22", 8) # in the quote must be a legitimate literal for base-8
18
>>> int('0x123', base = 16) # a number in base-16
291
pow(x, p)
This returns the value of x to the power of p.
>>> pow(2.9, 12.8)
829266.980472172
float(s)
This converts s to float. s can be a number, or a string of numbers.
>>> float('18.23')
18.23
>>> float(19)
19.0
max(iterable, *[, default = obj, key = func])
max(arg1, arg2, *args, *[, key = func])
These find and return the biggest element from an iterable such as a list, tuple or string, or from two or more arguments. The default keyword-only argument specifies what will be returned if the iterable is empty. The key keyword-only argument specifies how the maximum is defined if it is out of the ordinary.
>>> max(2, 1, 5, 65, 89) # variable-length list of arguments
89
>>> max("this") # the given sequence is a string
't'
>>> max((2, 3, 5, 1, 78)) # numbers in a tuple
78
>>> max([2, 3, 5, 1, 78]) # numbers in a list
78
min(iterable, *[, default = obj, key = func])
min(arg1, arg2, *args, *[, key = func])
These find and return the smallest number from an iterable such as a list, tuple or string, or from two or more arguments. The default keyword-only argument specifies what will be returned if the iterable is empty. The key keyword-only argument specifies how the minimum is defined if it is out of the ordinary.
>>> min(6, 5, 8, 3, 2)
2
>>> min([2, 3, 5, 1, 78]) # numbers in a list
>>> min([], default = 0) # 0 will be returned because the list is empty
0
round(f)
This rounds number f to the closest integer and returns the integer.
>>> round(3.1415926)
3
ord(c)
This finds and returns the order of a character, as a single char string, in the ASCII table.
>>> ord('c')
99
sum(…)
This calculates and returns the sum of numbers in a list, a tuple, or a range() call.
>>> sum([23, 56, 67, 12, 89])
247
>>> sum((23, 56, 67, 12, 89))
247
>>> sum(range(88))
3828
set(s)
This converts a set from a list or tuple.
>>> set([23, 56, 67, 12, 89])
{23, 56, 67, 12, 89}
dict()
dict(iterable)
dict(a = v,…)
These convert an empty dictionary, construct a dictionary from the iterable of (k, v) tuples, and from key=value pairs, respectively.
>>> dict()
{}
>>> dict([(1,'Turing'), (2,'Bool'), (3,'Babbage'), (4,'Neumann'), (5,'Knuth')])
{1: 'Turing', 2: 'Bool', 3: 'Babbage', 4: 'Neumann', 5: 'Knuth'}
>>> dict(a = 1, b = 2, c = 3)
{'a': 1, 'b': 2, 'c': 3}
bin(n)
This converts a number to its binary equivalence as a string.
>>> bin(98)
'0b1100010'
hex(n)
This converts a number to its hex equivalence as a string.
>>> hex(19)
'0x13'
oct(n)
This converts a number to its oct equivalence as a string.
>>> oct(28)
'0o34'
bool(o)
This converts o to Boolean True or False. In Python, 0, '', and None are equivalent to False, everything else is equivalent to True.
>>> bool(1)
True
>>> bool('school')
True
>>> bool(0)
False
tuple(s)
This constructs a tuple from a list, a string, or range() call.
>>> tuple("this is tuple")
('t', 'h', 'i', 's', ' ', 'i', 's', ' ', 't', 'u', 'p', 'l', 'e')
len(s)
This returns the length of a sequence.
>>> len(my_tuple)
13
>>> len("I like Python so much!")
22
list(s)
This constructs a list from a sequence or range() call.
>>> list(range(5))
[0, 1, 2, 3, 4]
range(start, stop, step)
This returns a sequence of numbers starting from 0 by default, ending right before stop and increasing by one step by default.
>>> list(range(1, 9, 2))
[1, 3, 5, 7]
complex(a, b)
This constructs a complex number from a pair of numbers and returns the complex number.
>>> complex(1, 8)
1 + 8j
hash(s)
This generates a hash for a given string s and returns the hash. One use is for transmitting and saving passwords.
>>> hash("Python is a great language for programming")
6145305589036905122
divmod(a, b)
This returns a tuple of the quotient and the remainder of one integer or float number divided by another integer or float number.
>>> divmod(23, 5)
(4, 3)
str(x)
This converts object x literally to a string and returns the converted string.
>>> str([23, 56, 67, 12, 89])
'[23, 56, 67, 12, 89]'
chr(n)
This returns the character n with its code in the Unicode table. Note that 0 <= n <= 0x10ffff as a legitimate code.
>>> chr(90)
'Z'
>>> chr(99)
'c'
type(o)
type(C, bases, dict)
type(o) returns the data type of object o, whereas type(C, bases, dict) will create a new type/class whose name is C and whose base classes are in bases, which is a tuple, and the dictionary defines the attributes of the new class, with assigned values. This gives programmers a way to dynamically define classes.
>>> type(list(range(9)))
<class 'list'>
In [ ]: |
|
Out [ ]: | x.a = 1, x.b = 3 x.a = 23, x.b = 35 |
all(iterable)
This returns True if all the elements of iterable are true.
>>> all(range(9))
False
>>> all(range(1,9))
True
any(iterable)
This returns True if any of the arguments true.
>>> any(range(9))
True
>>> any([0,0,0,0])
False
dir()
dir(o)
dir() returns a list of names in the current namespace. dir(o) returns a list of the attributes of object o.
>>> dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']
>>> dir(math)
['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc']
next(it)
This returns the next element of an iterable such as list, string, tuple, and so on.
>>> l=iter(list(range(3,99)))
>>> next(l)
3
>>> next(l)
4
ascii(o)
This returns a string containing a printable ASCII representation of an object.
>>> ascii(math)
"< module 'math' (built-in)>"
>>> ascii(int)
"<class 'int'>"
id(o)
This returns object o’s “identity,” which is a unique integer within a given context, usually the address of the object in memory.
>>> i = 10
>>> id(i) # return the id of variable i
263313728
>>> i *= 98
>>> id(i) # id is different, but still the same i
2809440
sorted(s)
This returns a new sorted list of elements in iterable s.
>>> il = [12, 0, 9, 32, 8, 5, 3, 99] # il is a list of integers
>>> sorted(il) # default is to sort in ascending order
[0, 3, 5, 8, 9, 12, 32, 99]
>>> sorted(il, reverse = 1) # sorted in descending order
[99, 32, 12, 9, 8, 5, 3, 0]
reversed(s)
This returns a reversed iterator.
>>> il = [0, 3, 5, 8, 9, 12, 32, 99]
>>> list(reversed(il))
[99, 32, 12, 9, 8, 5, 3, 0]
>>> list(reversed(range(9))) # range(9) return a sequence of 0,1,…9
[8, 7, 6, 5, 4, 3, 2, 1, 0]
enumerate(s, start = 0)
This returns a list of tuples from a sequence in which the elements are counted and each element is paired with its count to form a tuple.
>>> list(enumerate("this is")) # default value for optional argument start is 0
[(0, 't'), (1, 'h'), (2, '€'), (3, 's'), (4, ' '), (5, '€'), (6, 's')]
>>> list(enumerate("this is", 2)) # now counting start from 2
[(2, 't'), (3, 'h'), (4, '€'), (5, 's'), (6, ' '), (7, '€'), (8, 's')]
>>>
eval(s, globals = None, locals = None, /)
This evaluates the expression in s as a string or a compiled Python code in s and returns the value. Global and local namespaces can be specified for the expression or code object using the keyword arguments.
>>> eval("1 / (1 + (1 / math.e) ** 12)")
0.9999938558253978
exec(s)
This executes the statement in string s and provides a way to dynamically execute the Python code.
>>> exec("print('Hello World!')")
Hello World!
In [ ]: |
|
Out [ ]: | 12167 |
zip(*iterables)
This returns a list of tuples by taking one element from each of the iterables to make a tuple until reaching the end of the shortest iterable, and then returning the tuple. In Python, *p notation means p takes multiple arguments. In this case, multiple iterables such as lists, tuples, or strings are expected.
>>> grade_n = [50, 70, 80, 90, 100]
>>> grade_c = ['F', 'D', 'C','B', 'A']
>>> list(zip(grade_n, grade_c))
[(50, 'F'), (70, 'D'), (80, 'C'), (90, 'B'), (100, 'A')]
In [ ]: |
|
Out [ ]: | (32, ' ') (33, '!') (34, '"') (35, '#') (36, '$') (37, '%') (38, '&') (39, "'")(40, '(') (41, ')') (42, '*') (43, '+') (44, ',') (45, '-') (46, '.') (47, '/') (48, '0') (49, '1') (50, '2') (51, '3') (52, '4') (53, '5') (54, '6') (55, '7') (56, '8') (57, '9') (58, ':') (59, ';') (60, '<') (61, '=') (62, '>') (63, '?') (64, '@') (65, 'A') (66, 'B') (67, 'C') (68, 'D') (69, 'E') (70, 'F') (71, 'G') (72, 'H') (73, 'I') (74, 'J') (75, 'K') (76, 'L') (77, 'M') (78, 'N') (79, 'O') (80, 'P') (81, 'Q') (82, 'R') (83, 'S') (84, 'T') (85, 'U') (86, 'V') (87, 'W') (88, 'X') (89, 'Y') (90, 'Z') (91, '[') (92, '\\') (93, ']') (94, '^') (95, '_') (96, '`') |
The code sample above prints a portion of ASCII table showing the codes from 32 to 96 and their corresponding characters. It is only to show how zip function is used. There is a much simpler way to print such a table using just one for loop.
map(f, *iterables)
This applies function f to every item of an iterable and returns the resulted iterator.
>>> import math
>>> list(map(math.sqrt, range(17))
[0.0, 1.0, 1.4142135623730951, 1.7320508075688772, 2.0, 2.23606797749979, 2.449489742783178]
>>> list(map(sum, ([1, 2, 3], [4, 5, 6], [7, 8, 9, 10])))
[6, 15, 34]
getattr(o, attr)
This returns the value of object o’s attribute attr, the same as o.attr.
>>> getattr(math, 'sqrt')
<built-in function sqrt>
>>> getattr(math, 'e')
2.718281828459045
hasattr(o, attr)
This tests if object o has attribute attr and returns True if it does.
>>> hasattr(math, 'e')
True
>>> hasattr(math, 'sqrt')
True
>>> hasattr(math, 'power')
False
setattr(o, a, v)
This sets or adds an attribute a to object o and assigns value v to the attribute.
>>> class Student: # defining a class named Student. By convention, class names should be capitalized
…pass # this defines a class without any attribute
…
>>> s1 = Student() # create an instance of Student
>>> setattr(s1, 'name', 'John') # add an attribute called name, and assign 'John' to it
>>> s1.name
'John'
>>> hasattr(s1, 'name')
True
delattr(o, a)
This deletes attribute a from object o.
>>> delattr(s1, 'name') # delete attribute name from object s1
>>> hasattr(s1, 'name') # check if s1 has attribute name
False
isinstance(o, c)
This returns True if o is an instance of class c or a subclass of c.
>>> class Student:
…pass
…
>>> s1 = Student()
>>> isinstance(s1, Student)
True
issubclass(c, C)
This returns True if class c is a subclass of C.
>>> class Graduate(student):
…pass
…
>>> issubclass(Graduate, Student)
True
repr(o)
This returns a string representation of object o.
>>> repr(Graduate)
"<class "__main__.graduate'>'
filter(f, iterator)
This returns an iterator containing only the elements of the iterable for which the function returns true.
>>> def even(n):
…return not n%2 # return True if n can be divided by 2
…
>>> list(filter(even, range(9))) # odd numbers will be taken out
[0, 2, 4, 6, 8]
callable(o)
This returns True if o is a callable object such as a defined function.
>>> callable(even) # it will return True since even is defined
True
locals()
This updates and returns a dictionary of local names/symbols.
>>> locals()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'math': <module 'math' (built-in)>, 'l': <list_iterator object at 0x00370230>, 'student': <class '__main__.student'>, 's1': <__main__.student object at 0x00CE3DB0>, 'graduate': <class '__main__.graduate'>, 'even': <function even at 0x0029F7C8>}
vars()
vars(o)
vars() returns the same as locals(), whereas vars(o) returns the _dict_ attribute of object o.
>>> setattr(s1, 'name', 'John')
>>> vars(s1)
{'name': 'John'}
globals()
This updates and returns a dictionary of global names/symbols in the current scope.
>>> globals()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'math': <module 'math' (built-in)>, 'student': <class '__main__.student'>, 's1': <__main__.student object at 0x00CE3DB0>, 'graduate': <class '__main__.graduate'>, 'even': <function even at 0x0029F7C8>}
bytearray([source[, encoding[, errors]]])
This returns a bytearray object which is an array of the given bytes.
>>> s = "Hello Python lover!"
>>> barry = bytearray(s, 'utf-8')
>>> print(barry)
bytearray(b'Hello Python lover!')
bytes([source[, encoding[, errors]]])
>>> bs = bytes(s, 'utf-8')
>>> print(bs)
b'Hello Python lover!'
breakpoint(*args, **kws)
This function break the program and takes it into debug mode, calls sys.breakpointhook(), and passes a list of arguments (args) and a list of keyword arguments (**kws) to the system function.
@classmethod
The at sign @ is called a decorator in Python. This particular decorator is used to declare a method as class method, which receives the class as its first argument.
# define a class Person
class Person:
# define a class attribute
species = "human"
# define an instance method
def __init__(self, name, age):
self.name = name
self.age = age
# define a class method using the @classmethod decorator
@classmethod
def from_birth_year(cls, name, birth_year):
# calculate the age from the birth year
age = 2023 - birth_year
# return a new instance of Person with the given name and age
return cls(name, age)
# create an instance of Person using the class method
p1 = Person.from_birth_year("Alice", 1995)
# print the instance attributes
print(p1.name) # output: Alice
print(p1.age) # output: 28
print(p1.species) # output: human
The code above was taken from a code cell in Jupyter Notebook. The output is as follows when you hit the Ctrl+Enter key to run the code:
Alice
28
Human
compile(source, filename, mode, flags = 0, dont_inherit = False, optimize = −1)
This is used to compile the source into a code that can be executed using eval() or exec().
format(value[, format_spec])
This is used to convert a value to a “formatted” representation, as controlled by format_spec.
>>> print("Modern computers have over {h:3d} years of history".format(h = 80))
Modern computers have over 80 years of history
frozenset([iterable])
This returns a new frozenset object, with the option to display it with elements taken from an iterable. frozenset is also a built-in class.
>>> l = list(range(10))
>>> print(frozenset(l))
frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}) # {…} is a set
help([object])
This invokes the built-in help system on the object.
>>> help(frozenset)
Using help on class frozenset in module builtins displays the following:
class frozenset(object)
| frozenset() -> empty frozenset object
| frozenset(iterable) -> frozenset object
|
| Build an immutable unordered collection of unique elements.
|….
input([prompt])
This is used to read a line from input, convert it to a string with trailing newline characters stripped, and return the string. The optional prompt argument will be displayed without a trailing newline character so that the cursor will just wait at the end of the prompt for input.
>>> s = input("please give me an integer:")
please give me an integer:
iter(object[, sentinel])
This returns an iterator object. If the second argument doesn’t exist, the first argument must be a collection object.
>>> for c in range(6): print(next(l))
…
P
y
t
h
o
n
memoryview(obj)
This returns a “memory view” object of obj. Note that obj must be a bytes-like object.
>>> mv = memoryview(b"Hello Python Lover")
>>> print(mv)
<memory at 0x000001B932AD4A00>
object
This returns a new featureless object, a base for all classes.
>>> O = object
>>> print(O)
<class 'object'>
open(file, mode = 'r', buffering = −1, encoding = None, errors = None, newline = None, closefd = True, opener = None)
This opens the file in the desired mode and returns a corresponding file object. The default mode is read.
>>> f = open('scoresheet.txt', 'w')
The example opens a file named scoresheet.txt for writing and assigns the handle to f.
print(*objects, sep = ' ', end = '\n', file = sys.stdout, flush = False)
This prints objects to the text stream file, separated by separator and followed by end. sep, end, file, and flush, if present, must be given as keyword arguments.
>>> print("Hello Python Lover!")
Hello Python Lover!
property(fget = None, fset = None, fdel = None, doc = None)
This returns a property attribute. fget, sfet, and fdel take functions for getting, setting, and deleting an attribute value.
slice(stop)
slice(start, stop[, step])
These return a slice object representing the set of indices specified by range(start, stop, step).
>>> s = "Hello Python Lover!"
>>> slicing = slice(3) # slicing the first 3 items out of an object
>>> print(s[slicing]) # this will take the first three characters from the s
Hel
@staticmethod
This function decorator is used to declare a method as static. A static method can be called on the class or an instance.
In [ ]: |
|
Out [ ]: | 13/256 is 0.04905660377358491 |
super([type[, object-or-type]])
This returns a proxy object that delegates method calls to a parent or sibling type class. It is used for accessing inherited methods that have been overridden in a class.
In [ ]: |
|
Out [ ]: | <super: <class 'FTool'>, NULL> |
The superclass is NULL because FTool is not a subclass of any class except object, which doesn’t count.
Expressions
Expressions are important program constructs. An expression is made up of data items, variables, constants, and function calls joined by proper operators. The precedencies of the operators are as follows:
- 1. Within arithmetic operators, other operators take precedence over addition and subtraction.
- 2. Arithmetic operators take precedence over comparison operators.
- 3. Membership operators, identity operators, and comparison operators take precedence over logic operators.
- 4. Among logic operators, the order of precedence, from high to low, is not > and > or.
Expressions are used almost everywhere in a program and will be evaluated to a value or object in a general term. According to the type of the value or object from evaluation, an expression can be any of the following.
Arithmetic Expressions
An arithmetic expression’s value is always one of the following: an integer, float, or complex. An arithmetic expression can be made of data, variables, function calls, and arithmetic operators. When mixed data types appeared in an expression, the value type of the expression will be the most general data type. For example, the value of 3 + 5.6 will be a float number.
String Expressions
The string expression’s value is a string. String expressions are made of strings, string operators, functions and methods that return a string.
Boolean Expressions
The Boolean expression’s value is either True or False. Boolean expressions can be made of data, comparison operators, and logical operators. Note that although Python has True and False defined as logical true and false, it treats 0, None, empty string, empty list, empty tuple, set, and dictionary as False and treats everything else as True.
Other Expressions
The values of some expressions may be a list, tuple, set, dictionary or even a complex object. For example, some functions and methods can return a list or an object of a user-defined class, and the operator + can be used to combine two strings or lists together.
The following are some examples of expressions in Python:
12 + 35.6 - 36 * 3 + x # integer and float numbers can be mixed
235 + x ** k # 235 plus x to the power of k
2 < j and j in list_x # 2 is less than j and j is a member of list x
Expressions are often used on the right-side of an assignment operator, such as
total = a1 + a2 + a3
i *= j + 2 # the same as i = i * (j + 2)
2.2 Higher-Level Constructs of Python Programs
The constructs you learned in section 2.1 are small and meant to be used as parts of bigger ones. The big constructs of programs are called statements, which give explicit instructions to computers to act upon.
Structure of Python Programs
Before diving into the details of writing statements in Python, this section will first look at the general structure of a Python program and the coding style widely agreed upon among the Python community, which will make it so the programs that you write are readable to others.
For a simple application, a single Python file (with py as its extension) may be enough to contain all the program code needed to implement the application; for a more complex application, however, several or even hundreds of Python files may be needed. Of these files, there will be only one Python file defining the starting point of the program that implements the application, while all other files are used as modules to be imported into the main Python file, either directly or indirectly. So essentially, the relationships of all the Python files used for an application can be depicted as a tree in which the root is the main Python file.
The modules used directly or indirectly by the main Python program may be from the standard libraries installed with Python or from those installed later using the conda or pip command as needed.
Regarding coding style, see PEP 8: Style Guide for Python Code (https://pep8.org/), which describes in great detail how Python code should be written. Read it thoroughly and review it whenever you are unsure. Below are the highlights:
- 1. A Python program/script file should begin with a docstring as the main documentation of the program file, stating the application and functionality of the program, as well as the author and revision history.
- 2. In a script file, use double blank lines to separate the actual program code from the documentation section at the beginning of the file.
- 3. Also use double blank lines to separate top-level function and class definitions.
- 4. Use a single blank line to surround the definition of a method in a class definition.
Figure 2-5: Illustration of the structure of files for a Python application
- 5. Pay attention to indentation, especially when an expression, a simple statement, or the header of a compound statement is too long and needs to cross multiple lines.
- a. When an expression or a statement needs a closing brace, bracket, or parenthesis mark to complete it, there is no need to escape (\) newline at the end of an unfinished line.
- b. When a string needs to cross multiple lines, newline must be escaped by putting a backslash at the end of each unfinished line.
- c. The four-space rule is optional. The next line can be started wherever it makes more sense, such as in the column next to the opening delimiter.
In addition to the rules of coding, it’s important to maintain a consistent coding style and to make sure that the programs not only are easy to read and understand but also look neat and nice.
Documentation and Comments
As mentioned above, some lines of documentation, called docstring, are needed at the very beginning of each Python script/program file to state the purpose and functionality of the program, who made it and when, and notes for you and others who may read the program.
The following sample program calculates the area of a circle for a given radius. It shows how docstring is used in the program file.
|
|
|
|
|
|
| |
|
|
|
|
|
|
|
|
|
|
| |
| |
|
|
|
|
|
|
|
Please note the triple quotation marks on line 1 and line 9. The triple quotation marks on line 1 mark the start of the docstring, whereas the triple quotation marks on line 10 mark the end of the docstring. The quotation marks can be single or double, but they must be the same. You can also add docstrings for functions, classes, class methods, or other code blocks in the program as needed, but the opening triple quotation marks and ending triple quotation marks must be indented the same amount as the code block. You will see how this should be done in later chapters, with examples.
Please also note the comments starting with a # at the end of lines 13, 14, and 15. They are called end-of-line comments or block notes. An end-of-line comment is usually used to explain what the code on the line does. Everything behind the # mark on that line is ignored by Python Virtual Machine (PVM) and intended for only humans to read. An end-of-line comment can also be started at the beginning of a line.
The difference between docstrings and end-of-line comments is that docstrings are formal documentation of the program or module and are accessible through the built-in help() function, with the _doc_ variable automatically attached to each module, function, class and method, whereas end-of-line comments are not. As well, utility tools such as pydoc are available for generating formal documentation for a program or module from the docstrings within each Python file. The revised version of program circle.py is shown below, in which we defined a function named area, with docstrings added to the function and the program.
|
|
|
|
|
|
| |
|
|
|
|
| |
|
|
|
|
|
|
|
|
|
|
| |
|
|
|
|
|
|
|
|
| |
|
|
|
|
| |
|
|
The following are some general rules for program documentation:
- 1. A docstring should also be written for every function, class, and public method right after the header of the definition. Docstrings must be indented the same amount as the suite of function or class definition.
- 2. Limit the maximum line length to 79 or 72 characters if the line is part of a docstring.
- 3. Use inline comments whenever necessary.
- 4. Some code may need more than one line of comments, which makes it a block comment. A block comment should be written right before the code and indented to the same level as the code below.
Simple Statements
Normally, a simple statement is contained within a single logical line, though Python allows several simple statements to appear on one line separated by semicolons. There will be examples of this later.
Expression Statement
Simply put, expression statements in Python programs are just expressions in mathematical terms. Any expression can be used as a statement, and PVM will evaluate every expression statement, but the result is only displayed in Python interactive mode, as shown in the following code sample in the Python Shell:
Code sample in Python interactive mode | |
---|---|
| |
|
|
|
|
|
|
|
|
|
|
| |
|
So if you are using Python in interactive mode, you can simply type expressions without using the print statement to see the result of the calculation, just like a powerful calculator.
We can also have expression statements in Jupyter Notebook, but when there are several expression statements in the same cell, it will only show the result of the last expression, as shown in the following example:
In [ ]: |
|
Out [ ]: | 706.5 |
We mentioned earlier in this subsection that you can also put several simple statements on the same line, but you must separate them with semicolons. This is shown in the following examples:
Code sample in Python interactive mode | |
---|---|
| |
|
|
|
|
|
|
|
|
| |
| |
|
The expression statement above can also be given in Jupyter Notebook, as shown below. In Jupyter Notebook, however, you have to press Shift+Enter or click the play button to run the scripts in an active cell:
In [ ]: |
|
Out [ ]: | 706.5 |
Again, in Jupyter Notebook, even if multiple expression statements are on the same line, only the result of the last expression statement will be displayed.
Assignment Statement
The assignment statement is one of the most important statements and is used most often in programs because it is a common requirement to keep the result of computing or information processing in the computer memory for future uses. It does so by assigning the result to a variable.
In section 2.1, we saw a list of assignment operators. Formally, an assignment statement is made of a variable on the left and an expression on the right of an assignment operator, either = or an augmented one such as +=. We have already seen some examples of assignment statements before, but the following code sample includes a few more examples:
In [ ]: |
|
Out [ ]: | diameter = 15; radius = 7.5; circumference = 47.1; area is 176.625 |
Augmented Assignment
In programming, we often take the value of a variable, perform an operation on it, then put the result back to the variable. That is when augmented assignment comes into play.
In section 2.1, we saw several augmented assignment operators. In general, for an assignment in the form of
x = x <operator> v
the augmented assignment can be used in the following form:
x <operator>= v
The following are some examples of augmented assignments:
In [ ]: |
|
Out [ ]: | y is 10; n is 5 y is 50; n is 5 y is 7.142857142857143; n is 7 |
To understand these augmented assignment statements, we need to consider the memory location referred to by a variable, such as y with respect to time. Take y *= n as an example. At time t0 before the actual assignment starts, the value of y (data stored in the memory referred to by y, which is 10 at time t0) is taken out, and multiplied by n, whose value is 5 at time t0; then time t1—the result, which is 50 (from 10 * 5)—is stored in the memory location referred to by variable y.
Multiple Assignments
Also, for convenience and efficiency, you can assign values to multiple variables in a single assignment statement. There are several ways of doing multiple assignments, as shown in the following examples:
In [ ]: |
|
Out [ ]: | x = 1; y = [2, 3, 5, 6]; z = 7 |
In the last example above, *l, *y tells PVM that variable l and y can take a variable-length list of values.
Conditional Assignments
Additionally, in Python, you may even assign different values to a variable under different conditions, as shown in the following example:
Code sample in Python interactive mode | |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
As you will see throughout the text, there are many fancy ways of making statements in Python, and that’s why Python is a very powerful language. Indeed, the full power of a programming language can only be materialized by the best programmers.
Annotated Assignment Statement
We know that variables in Python are dynamically typed. Sometimes, however, it is nice to indicate what type of data is expected for a variable. In Python, this is done by annotating the variable using a colon followed by the name of the data type, as shown in the following example:
marks: float = 86.5 # variable marks will hold a float number
However, Python will not complain if other types of data are assigned, as shown below:
>>> marks: float = "Python"
>>> marks
'Python'
>>>
To annotate the type of value returned from a function, you need to use -> followed by the data type, right before the colon, as shown in the following example:
In [ ]: |
|
Out [ ]: | pass |
In this example, marks:float determines that a float number is expected for marks when calling the function, and -> str dictates that a string is to be returned.
It must be made clear that the actual type of a variable is still determined by the value it holds, and annotation added to a variable or function doesn’t really change the type of the variable or the value returned from a function. So annotations are more for programmers as reminders.
print Statement
The print statement is another one of the most important statements. It is used to output (to a terminal by default) so that a program can tell human users the result of calculations or information processing, the value of an object, or the status of the program. The following are some examples of print statements:
In [ ]: |
|
Out [ ]: | this is my first print statement. it will take about 3 hours to drive from Edmonton to Calgary |
The print statement can evaluate multiple arguments and print out the values. If the arguments are all constant strings, there will be no need to separate them into multiple arguments. Separate arguments are needed only when some arguments are expressions, like the round(300/110) in the above example. If you do not like separations, introduced in release 3.0, Python provides a neat way to include expressions all in a single pair of quotation marks, as shown in the following example:
In [ ]: |
|
Out [ ]: | it will take about 3 hours to drive from Edmonton to Calgary |
Please note the f—which is a flag or prefix—before the opening quotation mark and the curly brackets around the expression. Without the f flag, everything will be taken literally as part of the string, without evaluation.
If you want one portion of the string to be put on one line and the other portion on the next line, you may insert \n between the two portions in the string, as below:
In [ ]: |
|
Out [ ]: | it will take about 3 hours to drive from Edmonton to Calgary |
In addition to \n, other escape sequences that we discussed previously may also be included in a string.
There may be times that you want to include an escape sequence such as \n in a string as is. To achieve that effect, you either use the r flag before the opening double quotation mark or use another backslash \ before the escape sequence to cancel the first backslash (escape), as shown in the following example:
In [ ]: |
|
Out [ ]: | there will be no escape \n to newline there will be no escape \n to newline |
Without the r flag, the sentence will be printed on two lines, as shown in the following example:
In [ ]: |
|
Out [ ]: | there will be no escape to newline |
Normally, a \n (newline) will be automatically appended to the output from each print statement by default, so that the output from the next print statement will print on a new line. If you want the output from a print statement to end with something else rather than a new line, you may use the end keyword argument to specify how the output should be ended. In the following example, output from the first print statement will be ended with a whitespace, so that outputs from the two print statements will be on the same line:
In [ ]: |
|
Out [ ]: | this is my first print statement. it will take about 3 hours to drive from Edmonton to Calgary |
Formally, a print statement may take the following form when used:
print(value0, value1, value2,…, sep=' ', end = '\n', file = sys.stdout, flush = False)
where value0, value1,… are values to be printed to a file stream; optional keyword argument sep defines what is used to separate value0, value1,…; optional keyword argument end tells how the output from the print statement should end; optional keyword argument file defines what file stream the output should be printed on; and optional keyword argument flush tells how the output should be flushed. The meanings and purposes of these optional keyword arguments are explained in Table 2-16.
Keyword argument | Values that can be taken | Default value |
---|---|---|
sep | it takes a string as its argument and inserts it between values | a space |
end | it also takes a string as argument but appends it to the last value of the output stream | a new line |
file | it is a file handle such as that returned by an open statement | sys.stdout |
flush | it takes a Boolean value (True or False) indicating whether to forcibly flush the output stream | False |
Please note that a program may need to output different types of data not only correctly but also nicely. In 5.1, we will learn how to construct well-formulated strings from various types of data.
input Statement
The input statement is another important one you must learn and use correctly and effectively. Contrary to the print statement, the input statement is used to get information from users through the keyboard, as shown in the following example in Jupyter Notebook:
In [ ]: |
|
Out [ ]: | Please tell me your age: 39 Now I know your age is 39 |
Please note that everything taken from users through the input statement is treated as a string. If you are expecting a number, such as an integer, you must convert the string into its respective data type, as shown in the following example:
In [ ]: |
|
Out [ ]: | Please tell me your age: 39 In 50 years, your age will be 89 |
As you may have guessed already, the input statement takes one argument as a prompt to tell users what to do and what the program is expecting from the user.
If you want to provide more detailed instructions in the prompt to the user, you may use the triple quotation marks to include multiple lines of instruction as prompt:
In [ ]: |
|
Out [ ]: | Your choices A: to get average the mark M: to get the mean of all marks H: to get the highest mark L: to get the lowest mark Q: to exit the program Please select___ |
As you can see, this can be a good way to make a menu for some terminal-based applications.
assert Statement
The assert statement is used to test if a condition is true in a program. It may take one of two forms, as shown in Table 2-17.
Syntax | Meaning |
---|---|
assert <condition> | if <condition> is false, the program will stop and raise AssertionError if <condition> is True, the program will run ahead |
assert <condition>, <error message> | if <condition> is false, the program will stop and raise AssertionError, along with <error message> |
The assertion statement is very useful in debugging your programs, because it can be used to check the value of a variable or a certain condition of the program. If the condition is not met as expected, the program would stop and let you check what’s going on, as shown in the following examples:
In [ ]: |
|
Out [ ]: | Average of incomes is 65810.2 ---------------------------------- AssertionError Traceback (most recent call last) <ipython-input-2-201cb13363c6> in <module> 6 print("Average of incomes is",average_incomes(incomes)) 7 incomes = [] -- 8 print("Average of incomes is","average_incomes(incomes)) <ipython-input-2-201cb13363c6> in average_incomes(incomes) 1 def average_incomes(incomes): -- 2 assert len(incomes) != 0, "Error: there must be at least one income" 3 return sum(incomes)/len(incomes) 4 5 incomes = [35892, 13487, 56852, 135278, 87542] AssertionError: Error: there must be at least one income |
pass Statement
As the name implies, this statement does nothing. It is used as a placeholder in places where you don’t have the actual code yet. As an example, assume you have the class Student in your design for a project, but the implementation details of the class, except the name, are yet to be worked out. You can use the pass statement to hold the place of the details, as shown below:
In [ ]: |
|
With the pass statement in place, this piece of code can run as part of a big program without raising an exception.
Note that a pass statement won’t let you get out of a loop. You will need to use the break statement to get out of a loop.
del Statement
This statement is used to delete an object. Because Python treats everything as an object, you can use this statement to delete everything you’ve defined.
In [ ]: |
|
Out [ ]: | grade = 99 ---------------------------------- NameError Traceback (most recent call last) <ipython-input-9-2b1bea6f987e> in <module> 3 4 del grade -- 5 print(f"grade = {grade}") NameError: name 'grade' is not defined |
Deleting an object will free up the memory locations occupied by the object. Computer memory is a precious resource in computing. Python objects, even objects of built-in data types—such as list, tuple, set, and dictionary—can take up a great deal of memory. Deleting the objects that are no longer used will free up memory and make it available for other objects and other applications.
return Statement
The return statement is one of the most important statements in Python (and some other languages as well). It is used to return a value from a function—a very important construct of all programs. The following is an example:
In [ ]: |
|
Out [ ]: | The cube of 23 is 12167 |
This function simply takes a number and returns n to the power of 3.
Please note that in Python, the return statement doesn’t have parentheses around the value to be returned. Even if you want to return multiple values from a function, you only need to use commas to separate the values behind the return keyword. The return statement will automatically pack all the values in a tuple and then return them.
In the following example, we define a function of a modular operation but return the quotient and the remainder at the same time:
In [ ]: |
|
Out [ ]: | (2, 1) |
open Statement
The open statement is used to open a file for writing, reading, appending, or updating (reading and writing). The following is an example:
f = open("c:\\workbench\\myprimes.txt", 'r')
This opens the file specified by c:\\workbench\\myprimes.txt and creates a file object ready for reading. Reading is the default mode when you open a file without the second argument. Hence the following statement does the same as the above statement:
f = open("c:\\workbench\\myprimes.txt")
To open a file for writing, w is used for the second argument:
f = open("c:\\workbench\\myprimes.txt", 'w')
When a file is opened for writing, the old data will be overwritten if there is already data in the file. To keep the old data and append new data to the file, use a for the second argument instead:
f = open("c:\\workbench\\myprimes.txt", 'a')
If you want to create a file only if the file doesn’t exist, use x for the second argument, to mean exclusive creation of the file:
f = open("c:\\workbench\\myprimes.txt", 'x')
This would avoid accidentally overwriting a file.
By default, data written to a file opened with w, a, or x is text. The data on a file can also be in binary format. To explicitly indicate whether data on a file are or should be text or binary, you can use t or b with r, w, a, or x, as shown in the following examples:
f3 = open("c:\\workbench\\mykey.dat", 'bw')
f5 = open("c:\\workbench\\mykey.dat", 'br')
yield Statement
The yield statement is used in place of the return statement in some special circumstances when defining a function. When the yield statement is used in defining a function, the function becomes a generator in Python terms, as shown in the following example:
In [ ]: |
|
Out [ ]: | type of object odd_numbers is <class 'generator'> 1 3 5 7 9 11 13 15 17 19 21 23 |
When we say a function becomes a generator, we mean that an object of the generator class is returned from the function.
What is a generator object? For now, you may consider it a dynamic list whose members are generated and used dynamically on the fly, without using a big bunch of memory to store the whole list. The following is an example of a generator:
Object_generator = (x ** 3 for x in range(13))
If we run
for i in Object_generator:
print(i)
we will see the following members:
- 0, 1, 8, 27, 64, 125, 216, 343, 512, 729, 1000, 1331, 1728,
However, if we try to get the length of the generator object with the following statement:
print(f"{len(object_generator)}")
we will get the following error:
TypeError: object of type 'generator' has no len()
This confirms that an object of type generator has no length.
raise Statement
When some errors occur in a Python program, exceptions will be automatically raised and the program will stop running, unless the exception is handled with the try-except statement. Such errors include operations deemed illegal by Python. In some cases, an exception needs to be explicitly applied when a certain condition is met. In the previous section, we saw how an exception can be raised with the assert statement. In the following example, we show how to raise an exception with the raise statement.
In [ ]: |
|
Out [ ]: | Tell me a mark: -12 ---------------------------------- Exception Traceback (most recent call last) <ipython-input-13-f4aa3f6c4326> in <module> 3 mark = int(input("Tell me a mark:")) 4 if mark < 0: -- 5 raise Exception("No negative mark is accepted!") 6 total += mark 7 print(f'average mark is {total / 39}') Exception: No negative mark is accepted! |
This piece of code is used to calculate the average marks of 39 students, but it considers a negative mark unacceptable and will raise an exception.
break Statement
The break statement is used to get out of a loop and continue to the next statement. Here is an example:
In [ ]: |
|
Out [ ]: | 0 1 2 3 4 5 6 7 8 get out of the loop when i = 8 |
continue Statement
The continue statement is used within a loop code block to continue to the next iteration of the loop and ignore the rest of the code block. This statement can be very useful if you don’t want to run some statements when some condition is met.
import Statement
The import statement is used to import modules into a program file or a specific class within the module. The following is an example of how to import the standard math module into the program:
In [ ]: |
|
Out [ ]: | 98 ** 3 = 941192.0 |
global Statement
A global statement simply declares, within a code block such as function or class, that some identifiers/names such as variables should be treated as globally writable. Without a global statement, a variable defined outside of a function or class may be read, but writing to the variable will raise an exception, as shown in the following examples:
In [ ]: |
|
Out [ ]: | ---------------------------------- UnboundLocalError Traceback (most recent call last) <ipython-input-36-7f10379e5fb0> in <module> 6 return gravity 7 -- 8 print(g_force(99999)) <ipython-input-36-7f10379e5fb0> in g_force(m) 3 4 def changed_gravity(m): -- 5 gravity = gravity * (r_earth/(r_earth+m))**2 6 return gravity 7 UnboundLocalError: local variable 'gravity' referenced before assignment |
In the code above, gravity is first introduced outside the function definition. It became a global variable by the rule of naming scopes. Inside the definition of function changed_gravity, the name was defined again by putting it on the left side of the assignment, but only locally by default, according to the rules. However, this local variable is used on the right side of the same assignment statement. That is how the exception has occurred.
Since what we actually want is to use the globally defined variable gravity on both sides of the assignment statement within the function definition, we need to explicitly declare that, as shown in the following example revised from above:
In [ ]: |
|
Out [ ]: | gravity at 99999 metres above sea level is 9.506238807104731 or 9.506238807104731 |
As you can see, the value of global variable gravity has now been changed within the function.
nonlocal Statement
We have seen global variables and local variables, and how global variables are accessible globally, whereas local variables are only accessible within a local scope such as a function. There is something between global and local called nonlocal. The nonlocal statement can be used to declare a list of variables that are not local but refer to variables defined in the nearest enclosing scope but excluding global variables. This may happen when defining a function within another function, as shown in the following example:
In [ ]: |
|
Out [ ]: | inner log: Something has happened. Something else has happened as well. outer log: Something has happened. Something else has happened as well. |
help Statement
The help statement is used to invoke a helping system and is often used in Python interactive mode to get help on modules, statements, functions, or methods.
Code sample in Python interactive mode | |
---|---|
|
|
|
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Compound Statements
In the previous section, we studied individual statements that can be used in programming with Python. In this section, we study compound statements and ways to make various compound statements in Python.
In Python, a compound statement consists of at least one clause, and each clause is made of a header and a suite, or code block. A header starts with a keyword such as if, for, while, class, def, try, else, except, finally, and so on and ends with a colon :, as described below:
- <header>:
- <code block>
What can be on the header line depends on the keyword leading the header. You will learn more about this in the following chapters.
Code Blocks
In programs, some statements are grouped and run in sequence as a unit or a suite. We call such a group of statements a code block.
Unlike C, C++, Java, and some other languages that use curly brackets to make code blocks, Python uses indentation to form code blocks. In Python, a program can have multiple code blocks, and code blocks can be nested with proper indentation. Statements intended to be in the same code block must use the same indentation. The following is an example:
Code sample | |
---|---|
|
|
| |
|
|
|
|
|
|
| |
|
|
The sample program above has two simple statements on lines 1 and 7, and one compound statement on lines 3 to 5. The header of the compound statement begins with the keyword while, and its suite is a code block that consists of two simple statements. Because statements on lines 1, 3, and 7 are in the same code block, they must be indented the same, whereas statements on lines 4 and 5 must be further indented to form a code block as a suite for the while compound statement.
Rules of Indentation
To ensure that your programs are properly indented, follow the following rules:
- 1. The first line of code of a program must start at the very first column of line, though there can be some blank lines before the first line of code, for better readability, if you like.
- 2. All lines of code in the same code block must be indented the same.
- 3. The suite of a compound statement must be indented further than the header of the compound statement.
- 4. All code blocks that are at the same level must use the same indentation.
- 5. All lines of code in the same suite must use the same indentation.
Rules of Spacing
The rules of spacing are about how to space out words within a line of script or code and how to space lines of scripts. Some of the rules must be followed, while other rules are for readability or are merely convention among Python programmers:
- 1. There must be at least one space between two words.
- 2. As a convention, there should be only one space between two words.
- 3. Also as a convention, there should be one space before each operator and one space behind each operator in an expression. So x>y should be written as x > y.
- 4. For better readability, there should be no space between a unary negation operator (−) and the term it negates. So - x should be written as -x.
- 5. Also for readability, in a function call, there should be no space between a function name and the list of parameters. So abs (y) should be written as abs(y).
- 6. The same goes for definitions of functions. There should be no space between the function name and the list of arguments.
- 7. There should be no blank lines between lines of simple statements if they are intended to be in the same code block.
- 8. For better readability, there should be a blank line between simple statement(s) and compound statements if they are in the same code block, as shown in the following sample code:
Code sample | |
---|---|
|
|
| |
|
|
|
|
|
|
| |
|
|
|
Please note the blank line between line 1 and line 3, as well as between lines 5 and 7.
if Statement
An if statement is used to run a block of statements under a condition. The header of an if statement begins with the keyword if, followed by a logical expression of a condition, and then a colon, as shown below:
if <condition>:
<suite or code block>
Figure 2-6: Flowchart of an if statement
Here is an example:
Code sample | |
---|---|
|
|
| |
|
|
|
|
|
Note that although Python allows the suite to be on the same line as the header, as shown in the following sample, for readability, that is not preferable.
if mark >= 0: print(f"The mark is {mark}.") # allowed but not preferred
if-else Statement
In the example above, the if statement can only make one selection. To do something in particular if the condition is not met, the else clause can be added. The syntax of if-else statement is shown below, and the corresponding flowchart is shown in Figure 2-7.
if <condition>:
<code block 1>
else:
<code block 2>
Figure 2-7: Flowchart of the if-else statement
The code sample shown above can be rewritten as follows by adding an else clause:
Code sample | |
---|---|
|
|
| |
|
|
|
|
|
|
|
|
|
if-elif Statement
The if-else statement can only handle double selections. How can we handle multiple selections in Python? For example, in addition to telling whether a mark is legitimate or not, we may also want to convert the percentage mark to a letter grade. In Python, that can be done with an if-elif or if-elif-else statement. The syntax of the if-elif statement is shown below:
if <condition 1>:
< suite 1 >
elif <condition 2>:
< suite 2 >
elif <condition 3>:
< suite 3 >
…
Figure 2-8: Flowchart of the if-elif-elif-…
The code that can tell the letter grade from a percentage grade is shown below:
Code sample | |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if-elif-else Statement
An else clause can be added to the end of an if-elif statement in case something special needs to be done if all the conditions are not met.
while Statement
The while statement is used to run a block of code repeatedly as long as a given condition is met. The syntax of the statement is as follows:
while <condition>:
< a suite >
Figure 2-9: Flowchart of an if-elif-…elif-else statement
The following is an example:
Code sample | |
---|---|
|
|
| |
|
|
|
|
|
|
The loop is ended when not (I <= 10). The while statement is more advantageous when used to form a loop if we only know when the loop should end, as shown in the following word-guessing program:
Code sample | |
---|---|
|
|
| |
|
|
|
|
| |
|
|
|
|
for Statement
A for statement provides another way to form a loop and is best for when the loop runs through an iterable, such as a list, a tuple, a string, a generator, a set, or even a dictionary. The syntax of the for statement is as follows:
for <iteration variable(s)> in <iterable>:
< a suite >
Note that there can be more than one iteration variable if needed, but it is more common to have only one iteration variable.
The following is an example:
Code sample: for statement with a string | |
---|---|
|
|
|
|
|
|
|
|
|
|
| |
| |
|
|
|
Code sample: for statement with a set | |
---|---|
|
|
|
|
|
|
|
Code sample: for statement with a dictionary | |
---|---|
|
|
|
|
|
|
|
def Statement
The def statement is used to define new functions or methods if defined within a class definition. The syntax of def statement is as follows:
def <function_name>(<list of arguments>):
< code block >
where function_name should be a unique identifier within the current scope, and the list of arguments can be empty. The details of defining and using functions will be presented in Chapter 6. For now, you need only be concerned with the definition of a simple function so that you know how the def statement is used. The function is to calculate a given number x to the power of 10, and return x*x*x*x*x*x*x*x*x*x:
In [ ]: |
|
Out [ ]: | 2 to the power of 10 = 1024 |
class Statement
The class statement is used to define new classes. The syntax of defining a new class that only inherits from the base class (object) is as follows:
Class class_name:
< suite >
or
Class class_name(object):
< suite >
To define a new class that inherits from classes other than object, the syntax is as follows:
Class Class_name(<list of base classes>):
< suite >
try-except Statement
The try-except statement is used to handle errors and exceptions, especially when certain errors are expected. The following are some common types of errors that you may encounter in your programs:
ArithmeticError | FileExistsError | LookupError |
FloatingPointError | FileNotFoundError | IndexError |
OverflowError | InterruptedError | KeyError |
ZeroDivisionError | IsADirectoryError | MemoryError |
AssertionError | NotADirectoryError | NameError |
AttributeError | PermissionError | UnboundLocalError |
BufferError | ProcessLookupError | BrokenPipeError |
EOFError | TimeoutError | ConnectionAbortedError |
ImportError | ReferenceError | ConnectionRefusedError |
ModuleNotFoundError | RuntimeError | ConnectionResetError |
Refer to https://docs.python.org/3/library/exceptions.html for a detailed discussion about the exceptions and error types defined in Python.
The following is an example showing how to handle errors from user input that use 0 for the denominator.
Code sample: for statement with dictionary | |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
The details of error and exception handling in programs will be discussed in Chapter 4.
with Statement
The with statement is used to provide a context for the execution of a code block. The mechanism is a bit complex, but the following may provide some help. Remember that the with statement works only on objects that have special methods __enter__() and __exit__() implemented in accordance with Python context management protocol (PEP 343). For the mechanisms behind the with statement, read https://effbot.org/zone/python-with-statement.htm or search the internet for more details.
The general syntax of the with statement is as follows:
With <expression of object> as < variable referring to the object>:
<suite>
where the value of <expression of the object> will be an object on which the context management protocol has been implemented and the <variable referring to the resulted object> will often be used in the suite. A good and common example of using the with statement is dealing files, which, when opened, are objects with context management protocol implemented. The following is an example:
Code sample: with statement | |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Chapter Summary
- • Vocabulary is important for any language, and even more important for computer languages, because computers will not understand your programs at all if you have used the wrong vocabulary.
- • For programming languages, including Python, vocabulary includes various types of data, operators, built-in functions, reserved words (including keywords), and variables identified by user-defined names (also called identifiers).
- • Identifiers must begin with a letter or underscore in the ASCII table, then be followed by letters, digits, and/or an underscore.
- • Identifiers in Python are case-sensitive, which means that A1 and a1 are two different identifiers.
- • Within the Python community, there are conventions for how identifiers should be made and used for identifying different things in Python programs.
- • Simple data types include integer numbers, float numbers, Boolean numbers, and complex numbers.
- • Complex numbers are represented as a + bj or a − bj, where a and b are integers or float numbers.
- • Compound data are made of other data that can be of two types: simple or compound.
- • A string is a sequence of characters within a pair of single or double quotation marks.
- • Some special characters in a string must be represented using an escape sequence, such as \n for newline, \t for tab, and \\ for a backslash, and so on.
- • In a string, all characters are indexed starting from 0, so that each individual character can be accessed using its index.
- • There are many functions available to manipulate strings.
- • There are three ways of formatting strings: using placeholders, using the format method, and using the f prefix before a string. The last one is preferred.
- • A list is a sequence of data within a pair of square brackets.
- • Members of a list are also indexed, and each individual member can be accessed through its index.
- • A tuple is a sequence of data within a pair of parentheses.
- • Members of a tuple are also indexed, and each individual member can also be accessed through its index.
- • While individual members of a list can be deleted or changed, individual members in a tuple cannot be deleted or changed.
- • A set is a collection of data within a pair of curly braces.
- • Members in a set are not indexed, so individual members in a set cannot be accessed through the index.
- • A dictionary is a collection of key-value pairs within a pair of curly braces.
- • Keys are used to access the values of a dictionary.
- • In Python, everything can be treated as an object.
Exercises
- 1. Indicate which of the following are not legitimate Python identifiers to name variables, functions/methods, and classes, and explain why.
This | 3da | My_name | for | i9 | vote |
$s | _sum_ | cLearance | method | lists | t5# |
- 2. Write a single statement to complete each of the following tasks:
- a. Read an integer from user into variable k.
- b. Print a multiple-line mailing label with your name and home address, including the postal code.
- c. Print the area of a circle with a radius of 13.
- d. Assign the cube of 23 to variable x.
- e. Print the square of 12, 25, and 56, respectively, on one line.
- 3. Evaluate the following expressions
- a. 23 + 16 / 2
- b. round(78.3)
- c. pow(2,3) + 5
- d. sum([1,3,5,7,9])/13
- e. bin(9)
- f. divmod(13, 5)
- g. int(38.6)//7
- h. (3.5 + 6.7j) + (5.3 + 12.9j)
- i. 'Well' * 3 + '!'
- 4. Mentally run the following code blocks and state what each code block will display.
- a. x = 5
- y = 6
- print(x + y)
- b. m = 5
- k = 3
- print(f’{m}**{k} = {m**k}’)
- c. m, k = 35, 12
- m //= k
- print(m)
- d. m, k = 35, 12
- m %= k
- print(m)
Projects
- 1. Write a program to read a float number from the user into variable s, then calculate and print the area of a square with s as the length of its side.
- 2. Write a program to read two numbers and calculate the product of the two numbers.
- 3. A parking lot charges $2.50 per hour. Write a program to read the number of hours a vehicle has parked, then calculate and print the total to be paid for parking.
- 4. The arithmetic mean of several numbers is the sum of all these numbers divided by the number of these numbers. For this project, write a program that will generate three numbers from users and calculate and display the arithmetic mean of these three numbers.
- 5. A cube has 6 faces and 12 edges, all of the same length. Write a program that takes a number from the user as the length of an edge and calculate and display the total surface area of the cube.
We use cookies to analyze our traffic. Please decide if you are willing to accept cookies from our website. You can change this setting anytime in Privacy Settings.