Previous: 03-IntroPython.html
**Q**: In hexadecimal, in Canada, why is 6 afraid of 7?
**A**: Because 7, 8, 9, A?
document.querySelector('video').playbackRate = 1.2
Extra reading 1:
* https://automatetheboringstuff.com/2e/chapter0/
* https://automatetheboringstuff.com/2e/chapter1/
* https://inventwithpython.com/invent4thed/chapter0.html
* https://inventwithpython.com/invent4thed/chapter1.html
* https://inventwithpython.com/invent4thed/chapter2.html
* http://scipy-lectures.org/intro/intro.html
* http://scipy-lectures.org/intro/language/python_language.html
* http://scipy-lectures.org/intro/language/first_steps.html
* http://scipy-lectures.org/intro/language/basic_types.html
* https://books.trinket.io/pfe/01-intro.html
* https://books.trinket.io/pfe/02-variables.html
* https://docs.python.org/3/library/constants.html
* https://docs.python.org/3/library/functions.html (built in python
functions, not how to write your own)
* https://docs.python.org/3/library/stdtypes.html
* https://www.python-course.eu/python3_variables.php
* https://www.python-course.eu/python3_operators.php
* https://www.learnpython.org/en/Variables_and_Types
* https://www.learnpython.org/en/Basic_Operators
* https://python.swaroopch.com/basics.html
* https://python.swaroopch.com/op_exp.html
* https://www.tutorialspoint.com/python3/python_basic_syntax.htm
* https://www.tutorialspoint.com/python3/python_variable_types.htm
* https://www.tutorialspoint.com/python3/python_numbers.htm
* https://www.tutorialspoint.com/python3/python_basic_operators.htm
How do we represent data in the computer?
https://en.wikipedia.org/wiki/Binary_number
Text encoding (above the numeric/binary layer):
Note: There are some non-numeric characters, like ‘’
Hidden characters exist invisibly at the end of lines, as tabs,
etc.
Watch out, because hidden characters differ by operating system, and can
break code (do your work in the class VM when we get there)!
Types of built-in “object” in Python3 include:
Numbers
Strings
Containers
Note: there can hypothetically be more types, but you would import them as extra modules.
Variable names are aliases assigned to objects.
04-ExpressionsTypes/00_variables.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
Variables
"""
# There are no declarations in python3, only assignments.
# Use lower_case_with_underscores for variable names.
some_var = 5
some_var # => 5
# Accessing a previously unassigned variable names is an error / exception.
# >>> print(some_unknown_var)
# If we ran the line above, it raises a NameError, learn to read errors!!!!
# NameError: name 'some_unknown_var' is not defined
my_string = "This is a string"
my_string = 'This is a string too with an " in it'
my_string2: str = (
"The : str part is optional, and for now is just a helpful note, called a type hint"
)
my_string3: str = "The thing below isn't a number, but a string"
my_string4: str = "4"
my_int: int = 4 # This is a real int
my_string = "We're re-using the above name (my_string) for a new object. Variables (labels) can be re-assigned to new objects"
# They can also be assigned to new objects of different type, but that's usualyl not good style.
my_string = 4
# Variables are just references to objects stored in memory
# These references are like numeric addresses
# The variable name does not have a type, but the object being referenced does.
myint: int = 7
print(type(myint))
print(id(myint))
print(myint)
myfloat: float = 7.0
print(type(myfloat))
print(id(myfloat))
print(myfloat)
myfloat = float(myint)
print(type(myfloat))
print(id(myfloat))
print(myfloat)
mystring = "hello"
print(type(mystring))
print(id(mystring))
print(mystring)
https://docs.python.org/3/reference/lexical_analysis.html#identifiers
* Variables can be named uppercase and lowercase letters A through Z,
the underscore _ and, except for the first character, the digits 0
through 9.
* Naming is case-sensitive, as it is in Linux.
* Starting with _ has special purpose (more to come later)
* The following identifiers are used as reserved words, or keywords of
the language, and cannot be used as ordinary identifiers. They must be
spelled exactly as written here:
~~~
False await else import pass
None break except in raise
True class finally is return
and continue for lambda try
as def from nonlocal while
assert del global not with
async elif if or yield
~~~
Name your variables using snake case, for example:
slithering_reptile
As a preview (more to come), name your classes using camel case, for
example:
DesertAnimal
How to get input from the user (during run-time of your
program)?
How to print output to the screen for the user during run-time?
04-ExpressionsTypes/01_input.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-
print("Type something in please:")
x: str = input()
print(x)
y: str = input("Type something in please:")
print(y)
Notes:
* Command line arguments are another way to get input from users, but
they only work before/at run-time, not during the actual run of the
program.
* Files are another way.
Example: http://inventwithpython.com/invent4thed/chapter4.html
You can just discard input (or take enter alone) by calling input()
without storing the result. Print by itself just prints a newline.
04-ExpressionsTypes/02_jokes.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-
print("What do you get when you cross a snowman with a vampire?")
input()
print("Frostbite!")
print()
print("What do dentists call an astronaut's cavity?")
input()
print("A black hole!")
print()
print("Knock knock.")
input()
print("Who's there?")
input()
print("Interrupting cow.")
input()
print("Interrupting cow wh", end="")
print("-MOO!")
https://en.wikipedia.org/wiki/Boolean_data_type
The best thing about a boolean is even if you are wrong, you are only off by a bit...
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Boolean values are special primitives
# Note: the capitalization
True # => True
False # => False
# They're actual objects
var = True
var = False
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# A special value indicating null
None
# None is an actual object.
var = None
https://realpython.com/null-in-python/
https://en.wikipedia.org/wiki/Integer
* An integer (from the Latin integer meaning “whole”) is a number that
can be written without a fractional component.
* The set of integers consists of:
* zero (0),
* the positive natural numbers (1, 2, 3, …), also called whole numbers
or counting numbers, and
* their additive inverses (the negative integers, i.e., -1, -2, -3,
…).
* In python, integers can be arbitrarily big (this is nice, especially
compare to other languages like C or C++ where you need to use a library
or write it yourself)!
https://en.wikipedia.org/wiki/Floating-point_arithmetic
* Floating-point arithmetic (FP) is arithmetic using formulaic
representation of real numbers as an approximation, so as to support a
trade-off between range and precision.
* For this reason, floating-point computation is often found in systems
which include very small and very large real numbers, which require fast
processing times.
* A number is, in general, represented approximately to a fixed number
of significant digits (the significand), and scaled using an exponent in
some fixed base.
* You may get slightly off answers, so watch out for things like x ==
2.0!
*
https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
* Floating point number example: 3.2
* Floating point literal number example: 4 / 5
An operator performs an action, e.g., the
+
in 4 + 5
An operand is operated upon, e.g., the 4
and 5
in 4 + 5
Operands and operators can be combined into
expressions, which themselves are evaluated and then
“return” objects.
04-ExpressionsTypes/03_numeric.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-
x = 4
print(type(x))
print(id(x))
print(x)
y = 4.0
print(type(y))
print(id(y))
print(y)
# If I type 7, what is the type of z???
z: str = input()
print(type(z))
print(id(z))
print(z)
# Type-hint comment, optional for now, but recommended
# Explicit is better than implicit!!
a: int = 4
b: float = 4.0
# Assignment statements
# An assignment statement assigns a variable with the value of an expression.
# [var] = [arithexpr]
# Left must be a variable, right an arithmetic expression.
# Below, the third statement assigns a with 2 times a's current value.
# If a was 4, the statement assigns a with 2 * 4, or 8.
print(a)
# variables can be re-assigned to themselves
a = 2 * a
# variables can be re-assigned to other values
b = (4 + 3) / 2
print(b)
Expressions produce (return) values upon evaluation.
04-ExpressionsTypes/04_loan.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Left must be a variable, right an arithmetic expression.
# Arithmetic operators: +, -, *, /, %
# An assignment statement’s right side can be an arithmetic expression:
# Ex: x = (3 * y) + (z / 2).
# This over-simplified program below computes the total cost of a loan,
# given the loan amount and interest.
loan_amount: float = float(input())
interest_rate: float = float(input())
total_cost: float = loan_amount + (loan_amount * interest_rate)
print(total_cost)
https://en.wikipedia.org/wiki/Division_(mathematics)#Of_integers
https://en.wikipedia.org/wiki/Division_(mathematics)#Of_real_numbers
++++++++++++++++++++
Cahoot-04.1
https://mst.instructure.com/courses/58101/quizzes/55317
04-ExpressionsTypes/05_convert_bad.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Integer versus float division
fahr: int = int(input())
# despite calling celc a float, it labels an int.
celc: float = (5 // 9) * (fahr - 32)
print(celc)
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Integer versus float division
fahr: float = float(input())
celc: float = (5.0 / 9.0) * (fahr - 32)
print(celc)
Note: Watch out for deprecated python2 code, where this // vs. / pattern is reversed.
Some implicit conversions are automatically performed:
04-ExpressionsTypes/07_conversions.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-
integer1: int = 3
print(type(integer1))
float1: float = 4.0
print(type(float1))
print(type(float1 + integer1)) # gives a float
print(type(float1 - integer1)) # gives a float
print(type(float1 * integer1)) # gives a float
print(type(float1 / integer1)) # gives a float
print(type(integer1 / float1)) # gives a float
print(type(float1 % integer1)) # gives a float
print(type(integer1 % float1)) # gives a float
print(type(float(integer1))) # gives a float
print(type(int(float1))) # gives an int, truncatitng decimal points
If conversion is from a floating-point type to an integer type, the value is truncated (the decimal part is removed).
++++++++++++++++++++
Cahoot-04.2
https://mst.instructure.com/courses/58101/quizzes/55318
https://en.wikipedia.org/wiki/Division_by_zero
Typically “undefined” and to be avoided!
#!/usr/bin/python3
# -*- coding: utf-8 -*-
print(5 / 0)
# produces an error in python
# >>> print(5/0)
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# ZeroDivisionError: division by zero
++++++++++++++++++++
Cahoot-04.3
https://mst.instructure.com/courses/58101/quizzes/55319
https://en.wikipedia.org/wiki/Modular_arithmetic
In mathematics, modular arithmetic is a system of arithmetic for
integers, where numbers “wrap around” upon reaching a certain value, the
modulus.
(11 + 4) % 12 = 3
mod The mod operator, %, works this way:
a mod b produces the remainder after a is divided by b.
4 % 7 is 4 (since 4 / 7 is 0 with remainder 4)
7 % 3 is 1 (since 7 / 3 is 2 with remainder 1)
27 % 3 is 0 (since 27 / 3 is 9 with remainder 0)
For a positive integer n, two numbers a and b are said to be
congruent modulo n, if their difference a - b is an integer multiple of
n (that is, if there is an integer k such that a − b = kn). This
congruence relation is typically considered when a and b are integers,
and is denoted:
\(a\equiv b \pmod {n}\)
The number n is called the modulus of the congruence.
The congruence relation may be rewritten as \(a=kn + b\)
\(a\equiv b \pmod {n}\)
asserts is that a and b have the same remainder when divided by n. That
is,
Example: \(38 \equiv 14 \pmod {12}\)
Example of mod 9:
mod and division by 10s to choose place
x = int(input())
tens_digit: int (x % 100) / 10 # assigns tens digit of x to variable tens_digit
When python evaluates mathematical expressions for their resulting value, the following defines order of precedence, where higher/earlier in the list takes precedence over lower/later:
()
Parentheses
**
Exponentiation (raise to the power)
~ + -
Complement, unary plus, and minus (method names for
the last two are +@ and -@)
* / % //
Multiply, divide, modulo, and floor division
+ -
Addition and subtraction
>> <<
Right and left bitwise shift
&
Bitwise ‘AND’
^ |
Bitwise exclusive OR' and regular
OR’
<= < > >=
Comparison operators
== !=
Equality operators (<> is like != in
python2)
= %= /= //= -= += *= **=
Assignment operators
is is not
Identity operators
in not in
Membership operators
not or and
Logical operators
However, you should use () even when you don’t need to.
Explicit is better than implicit!
++++++++++++++++++++
Cahoot-04.4
https://mst.instructure.com/courses/58101/quizzes/55320
A function is like a named block of code that can be “called” (a.k.a. executed) by referencing its name as follows:
function(arguments)
These are some pre-written importable functions in Python:
04-ExpressionsTypes/08_random.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# using someone else's code:
import random
# Built-in functions generate random numbers.
# Each call specifies a range and returns a new random number within that range.
print(random.randint(0, 5))
print(random.randint(0, 5))
print(random.randint(0, 5))
print()
# To enable reproducible programs,
# a programmer can set a seed,
# as in random.seed(7),
# prior to any calls to random.randint().
# Then, for any run of the program,
# the sequence of "random" numbers is always the same for that seed.
# If no seed is provided, Python3 uses the what as the seed,
# yielding the expected “randomness” for each run of the program?
random.seed(7)
print(random.randint(0, 5))
print(random.randint(0, 5))
print(random.randint(0, 5))
print()
random.seed(7)
print(random.randint(0, 5))
print(random.randint(0, 5))
print(random.randint(0, 5))
# Setting seed first is optional.
# Seed typically only set once, at start of program (if at all)
+++++ Lecture 1 ends here +++++
+++++ Lecture 2 starts here +++++
https://en.wikipedia.org/wiki/Caesar_cipher
The mod operation is important (and actually worth mastering)!
The Outer Wheel
* English alphabet of 26 letters
* Do we start at 0 or 1?
The Inner Wheel
The inner wheel is used to determine the number of shifts
Spin the Inner Wheel
For an animation, see:
https://inventwithpython.com/cipherwheel/
1. Take each letter from the plain-text and match it with the letter on
the outer wheel
2. Replace the letter with the corresponding letter on the inner
wheel
1. Take each letter from the cipher-text and match it with the letter on
the inner wheel
2. Replace the letter with the corresponding letter on the outer
wheel
This is the Caesar encoding: each letter gets a number, like ASCII, but
simpler.
There are two different bugs in the below programs, that only
occurs sometimes, related to one of the more confusing operators we’ve
covered above!
Can you find them??
04-ExpressionsTypes/09_keygen.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import random
print("Your randomly chosen Caesar cipher key is: ")
print(random.randint(0, 25))
print("\n Share securily with your communication partner, and don't tell anyone else\n")
Caesar encoding is similar to ASCII encoding, but
~~~
a is 0,
b is 1,
c is 2,
…
z is 25
~~~
The letters of “hi” in Caesar encoding are what?
Q: “hi” encrypted with a key of 1 is what?
A: “ij”
Q: “hi” encrypted with a key of 1 is what?
A: “jk”
04-ExpressionsTypes/10_encrypt.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-
print("You have to run this program, once for every character of your message")
key: int = int(input("\nEnter your Caesar key in numeric form (1-25): "))
encoded_char: int = int(
input(
"\nEnter Caesar encoded number corresponding to one character of your message:"
)
)
print("\nThe translation of your character is:")
# To encrypt:
print(encoded_char + key)
04-ExpressionsTypes/11_decrypt.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-
print("You have to run this program, once for every character of your message")
key: int = int(input("\nEnter your Caesar key in numeric form (1-25): "))
encoded_char: int = int(
input(
"\nEnter Caesar encoded number corresponding to one character of your message:"
)
)
print("\nThe translation of your character is:")
# To decrypt:
print(encoded_char - key)
Ask:
* Besides the 2 above intentional bugs, what are some missing features
with this version of the Caesar cipher?
* Are there any features you’d like for this to be more usable,
convenient, easy, or functional?
To be stepped through in the python3-spyder IDE and/or python3-pudb
debugger:
04-ExpressionsTypes/12_expressions.py
++++++++++++++++++++
Cahoot-04.5
https://mst.instructure.com/courses/58101/quizzes/55384
04-ExpressionsTypes/13_logic.py
++++++++++++++++++++
Cahoot-04.6
https://mst.instructure.com/courses/58101/quizzes/55385
04-ExpressionsTypes/14_string_literals.py
++++++++++++++++++++
Cahoot-04.7
https://mst.instructure.com/courses/58101/quizzes/55386
04-ExpressionsTypes/15_conversions.py
++++++++++++++++++++
Cahoot-04.8
https://mst.instructure.com/courses/58101/quizzes/55387
04-ExpressionsTypes/16_assignment.py
++++++++++++++++++++
Cahoot-04.9
https://mst.instructure.com/courses/58101/quizzes/55388
Next: 05-Branches.html