pm21-dragon/lectures/lecture-02/1 - Scopes, Types, etc.ipynb
2024-10-25 08:05:31 +02:00

174 KiB
Executable file

None <html> <head> </head>

Review

One key idea in programming is a variable. A variable is a name that refers to a value. It lets us reference the value, even if we do not know what it is. We can assign to variables in Python using the = symbol.

Even though we are still working with simple code, we have already learned two key ideas of programming that let us build more complex systems through modularity.

The first is functions. We learned that code is organized in blocks.

The second idea is scope.

We also learned about exceptions.

In [1]:
x = 0

def foo(a):
    return a

z = foo(x)
In [2]:
x = 0

def foo(x):
    y = 100/x
    print(x)
    print(y)
    return y

y = 32
z = foo(y)
print(x)
print(y)
32
3.125
0
32

Coding style

It is great if your code runs successfully! However, you are likely to want to run it again. (And even if not, it is good to practice "Doin' It Right".) Therefore, it is good to optimize it for readability and reuse. There is certainly a sense of style in software coding. It's good to develop your own sense of good style.

There is more one way to write correct code. (In fact, there are infinitely many ways.)

Depending on the programming language, and often depending on the project or environment, there are standard, "idiomatic" ways of doing things. You should prefer those - they make your code easier to read for others - and also yourself in the future.

It is useful to spend time refining code so that it looks simple and, ideally, is simple. Of course this is not always possible.

One stylistic rule that holds pretty much in every programming language is the principle "Don't Repeat Yourself" (DRY). If you need to change something, ideally you will only need to change it in one place in your code. Another way of saying this is that there should only be a "single source of truth".

The python package "black" is commonly used linter for making code style changes to an idiomatic format.

Style suggestions

  • In general: simplify
  • Remove irrelevant code (e.g. plt.show;)
  • Remove irrelevant comments (e.g. # YOUR CODE HERE)

Types

Every value in Python has a type. You don't usually see the types written, but it is critically important to understand what types are used in code you are working on. Python checks exactly how something is typed and, according to strict rules, decides what type the value will have. For example, these will all be different types:

10
10.0
'10'

Types of types

So far, we have mostly worked with whole numbers called integers - in python, an int. We briefly saw None and some strings. You may have also seen floating point numbers (float in python).

Let's practice with some of these types.

Playing with types

In [3]:
10
Out[3]:
10
In [4]:
type(10)
Out[4]:
int
In [5]:
10.0
Out[5]:
10.0
In [6]:
type(10.0)
Out[6]:
float
In [7]:
x = 10
type(x)
Out[7]:
int
In [8]:
type("10")
Out[8]:
str
In [9]:
type('10')
Out[9]:
str
In [10]:
my_string = "Hello, My name is Angela Merkel"
In [11]:
my_string = "übersetzen"
In [12]:
Übersetzung = "translation"
In [13]:
print(my_string)
übersetzen
In [14]:
my_string = 'the data is like this: "gcatcccggg"'
print(my_string)
the data is like this: "gcatcccggg"
In [15]:
my_string = "the data is like this: "gcatcccggg""
print(my_string)
  Cell In[15], line 1
    my_string = "the data is like this: "gcatcccggg""
                                         ^
SyntaxError: invalid syntax
In [16]:
my_string = "the data is like this: \"gcatcccggg\""
print(my_string)
the data is like this: "gcatcccggg"
In [17]:
my_string = "the data is like this: \\gcatcccggg\""
print(my_string)
the data is like this: \gcatcccggg"
In [18]:
my_string = 'the data is like this: \'gcatcccggg\''
print(my_string)
the data is like this: 'gcatcccggg'
In [19]:
my_string = 'the data is like this: 'gcatcccggg''
print(my_string)
  Cell In[19], line 1
    my_string = 'the data is like this: 'gcatcccggg''
                                         ^
SyntaxError: invalid syntax
In [20]:
my_string = "the data is like this: 'gcatcccggg'"
print(my_string)
the data is like this: 'gcatcccggg'
In [21]:
my_string = "the data is like this: \\ 'gcatcccggg'"
print(my_string)
the data is like this: \ 'gcatcccggg'
In [22]:
x=10
In [23]:
print(x)
10
In [24]:
1234
Out[24]:
1234
In [25]:
def myprint(x):
    print(x)
    return 32
In [26]:
myprint("hello")
hello
Out[26]:
32
In [27]:
myprint("hello");
hello
In [28]:
10
Out[28]:
10
In [29]:
# In Jupyter, `_` is a special variable, which means the output value of the previously run cell.
y=_
In [30]:
y
Out[30]:
10
In [31]:
x=x+1
In [32]:
print(x)
11
In [33]:
z=x=x+1
In [34]:
z
Out[34]:
12
In [35]:
x
Out[35]:
12

None type

The None type is used when there is no value. It is actually very common in Python. For example a function which does not return anything actually returns the value None.

In [36]:
x=None
print(x)
None
In [37]:
x=None
type(x)
Out[37]:
NoneType
In [38]:
None
In [39]:
10
Out[39]:
10
In [40]:
x=print(10)
print(x)
10
None
In [41]:
x
In [42]:
x=10
In [43]:
x
Out[43]:
10

Operators

Many of the most commonly used operations (like addition) could be written as function calls, but instead have special symbols (like +).

In [44]:
3+4
Out[44]:
7
In [45]:
int.__add__(3,4)
Out[45]:
7
In [46]:
"abc" + "def"
Out[46]:
'abcdef'
In [ ]:
str.__add__("abc", "def")

Complex expressions

Often we write expressions in which multiple operations happen in one line of code

In [48]:
4 * 3 + 2
Out[48]:
14
In [49]:
2 + 4 * 3
Out[49]:
14
In [50]:
x = 4 * 3 + 2
In [51]:
x
Out[51]:
14
In [52]:
x = x * 2
In [53]:
x
Out[53]:
28
In [54]:
y=4*3+2
y
Out[54]:
14
In [55]:
tmp = 4*3
y = tmp+2
y
Out[55]:
14
In [56]:
tmp = 'my super import data'

y=4*(3+2)
In [57]:
y
Out[57]:
20
In [58]:
tmp
Out[58]:
'my super import data'
In [61]:
tmp2 = 'my super import data'

tmp=3+2
tmp2 = 4*tmp
y = tmp2
In [62]:
tmp2
Out[62]:
20
In [63]:
print(y)
20
In [64]:
print(4*3+2)
14

list type

list construction

In [65]:
x = [1,2,2,2,2,2,"three", 4.0]
print(x)
[1, 2, 2, 2, 2, 2, 'three', 4.0]
In [66]:
x=list()
print(x)
[]
In [67]:
x=[1,2,3,4]
print(x)
[1, 2, 3, 4]
In [71]:
x=[]
print(x)

x.append(1)
print(x)

x.append(2)
print(x)

x.append(3)
print(x)

z = x.append(4)
print(x)

print(z)
[]
[1]
[1, 2]
[1, 2, 3]
[1, 2, 3, 4]
None
In [72]:
x=["red","green","blue"]
print(x)
['red', 'green', 'blue']
In [73]:
x=["red", 101, "green", 202, "blue", 303]
print(x)
['red', 101, 'green', 202, 'blue', 303]
In [74]:
x=["red", 101, "green", 202, "blue", 303, [1,2,3], 'lkasjdf"laskdjfj']
print(x)
['red', 101, 'green', 202, 'blue', 303, [1, 2, 3], 'lkasjdf"laskdjfj']

list indexing

In [75]:
x=["red","green","blue"]
x[0]
Out[75]:
'red'
In [76]:
x=["red","green","blue"]
x[1]
Out[76]:
'green'
In [77]:
x=["red","green","blue"]
x[2]
Out[77]:
'blue'
In [78]:
x=["red","green","blue"]
x[-1]
Out[78]:
'blue'
In [79]:
x=["red","orange","yellow","green","blue","indigo","violet"]
x[-1]
Out[79]:
'violet'
In [80]:
x=["red","orange","yellow","green","blue","indigo","violet"]
x[-3]
Out[80]:
'blue'
In [81]:
x
Out[81]:
['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']
In [82]:
y=2
x[y]
Out[82]:
'yellow'
In [83]:
x['hello']
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[83], line 1
----> 1 x['hello']

TypeError: list indices must be integers or slices, not str
In [84]:
x[1.23]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[84], line 1
----> 1 x[1.23]

TypeError: list indices must be integers or slices, not float

getting index of item in list

In [85]:
x=["red","orange","yellow","green","blue","indigo","violet"]
x.index("blue")
Out[85]:
4
In [86]:
x.index(321)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[86], line 1
----> 1 x.index(321)

ValueError: 321 is not in list

setting an item in a list

In [87]:
x
Out[87]:
['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']
In [88]:
x[3]=3
In [89]:
x
Out[89]:
['red', 'orange', 'yellow', 3, 'blue', 'indigo', 'violet']

list slicing

In [90]:
x=["red","orange","yellow","green","blue","indigo","violet"]
x[0:3]
Out[90]:
['red', 'orange', 'yellow']
In [91]:
x[3]
Out[91]:
'green'
In [92]:
x[:3]
Out[92]:
['red', 'orange', 'yellow']
In [93]:
x=["red","orange","yellow","green","blue","indigo","violet"]
x[None:3]
Out[93]:
['red', 'orange', 'yellow']
In [94]:
x[0:3]
Out[94]:
['red', 'orange', 'yellow']
In [95]:
x=["red","orange","yellow","green","blue","indigo","violet"]
x[3:]
Out[95]:
['green', 'blue', 'indigo', 'violet']
In [96]:
x=["red","orange","yellow","green","blue","indigo","violet"]
x[3:None]
Out[96]:
['green', 'blue', 'indigo', 'violet']
In [97]:
x=["red","orange","yellow","green","blue","indigo","violet"]
x[3:-1]
Out[97]:
['green', 'blue', 'indigo']

tuples

tuple construction

In [98]:
x = (1,2,3,4)
print(type(x))
print(x)
<class 'tuple'>
(1, 2, 3, 4)
In [99]:
x = ()
print(type(x))
print(x)
<class 'tuple'>
()
In [100]:
x = (1,)
print(type(x))
print(x)
<class 'tuple'>
(1,)
In [101]:
x = (1)
print(type(x))
print(x)
<class 'int'>
1
In [104]:
x = 1,
print(type(x))
print(x)
<class 'tuple'>
(1,)
In [105]:
x = 1,2,3
print(type(x))
print(x)
<class 'tuple'>
(1, 2, 3)
In [106]:
x = 1
print(type(x))
print(x)
<class 'int'>
1
In [107]:
x = tuple()
print(type(x))
print(x)
<class 'tuple'>
()
In [108]:
x = tuple([1])
print(type(x))
print(x)
<class 'tuple'>
(1,)
In [114]:
x = tuple([1,2,3,4])
print(type(x))
print(x)
<class 'tuple'>
(1, 2, 3, 4)
In [115]:
x = tuple(1,2,3,4)
print(type(x))
print(x)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[115], line 1
----> 1 x = tuple(1,2,3,4)
      2 print(type(x))
      3 print(x)

TypeError: tuple expected at most 1 argument, got 4
In [116]:
tmp = [1]
print(type(tmp))
x = tuple(tmp)
print(type(x))
print(x)
<class 'list'>
<class 'tuple'>
(1,)

tuple indexing and slicing

In [117]:
x=("red","orange","yellow","green","blue","indigo","violet")
x[2]
Out[117]:
'yellow'
In [118]:
x=("red","orange","yellow","green","blue","indigo","violet")
x[-1]
Out[118]:
'violet'
In [119]:
x=("red","orange","yellow","green","blue","indigo","violet")
x[-3]
Out[119]:
'blue'
In [120]:
x=("red","orange","yellow","green","blue","indigo","violet")
x[0:3]
Out[120]:
('red', 'orange', 'yellow')
In [121]:
x[:3]
Out[121]:
('red', 'orange', 'yellow')

lists are mutable, tuples are not

In [122]:
x=["red","orange","yellow","green","blue","indigo","violet"]
print(x)
x[3]=3
print(x)
['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']
['red', 'orange', 'yellow', 3, 'blue', 'indigo', 'violet']
In [123]:
x=("red","orange","yellow","green","blue","indigo","violet")
print(x)
x[3]=3
print(x)
('red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[123], line 3
      1 x=("red","orange","yellow","green","blue","indigo","violet")
      2 print(x)
----> 3 x[3]=3
      4 print(x)

TypeError: 'tuple' object does not support item assignment

passing mutable lists to functions

In [125]:
def modify_arg(a,b):
    a.append(b)
    # Notice that there is no return here!
    # So, this function has an important "side effect",
    # but the output is None.
    
x = [1,2,3]
y = modify_arg(x, 4)
x
print(y)
None
In [126]:
x
Out[126]:
[1, 2, 3, 4]

variables can be names pointing to an object in memory

In [127]:
x=["red","orange","yellow","green","blue","indigo","violet"]
y=x
print(x)
y[3]=3
print(y)
['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']
['red', 'orange', 'yellow', 3, 'blue', 'indigo', 'violet']
In [128]:
print(x)
['red', 'orange', 'yellow', 3, 'blue', 'indigo', 'violet']
In [129]:
x=0
y=x
print(x)
y=3
print(x)
print(y)
0
0
3
In [130]:
# View the previous example and then this one in pythontutor.com
x=["red","orange","yellow","green","blue","indigo","violet"]
y=x.copy()
print(x)
y[3]=3
print(y)
['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']
['red', 'orange', 'yellow', 3, 'blue', 'indigo', 'violet']
In [131]:
print(x)
['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']

Plotting

In [132]:
import matplotlib.pyplot as plt
In [138]:
x=[1,2,3,0,4,1]
y=[0,4,0,3,3,0]
plt.plot(x,y,"go-");
In [141]:
x=[1,2,3,0,4,1]
y=[0,4,0,3,3,0]
plt.plot(x,y);
In [142]:
y=[0,4,0,3,3,0]
plt.plot(y);

Cheatsheet for much more matplotlib: https://twitter.com/dr_shlee/status/1282772480046891010

Boolean (bool) type

Python's bool type can take one of two values: True or False. It is used to test a condition, such as in an if statement.

In [144]:
x = 1
y = x > 0
y
Out[144]:
True
In [145]:
type(y)
Out[145]:
bool
In [148]:
x = -1

if x > 0:
    print("x is positive")
    x = 10

x
Out[148]:
-1
In [149]:
x>0
Out[149]:
False
In [150]:
type(x>0)
Out[150]:
bool
In [153]:
x = 1

if x > 0:
    y = 20
    print("x is positive")
    print("x is still positive")
else:
    y = 40
    print("x is negative")
    print("x is still negative")
    
print("out of the blocks")
print(y)
x is positive
x is still positive
out of the blocks
20

Equality testing

Equality and comparisons

Comparison operators: ==, >, >=, <, <=, !=

These operators take two arguments (left and right hand side) and return a boolean.

In [154]:
3 > 4
Out[154]:
False
In [155]:
3 == 4
Out[155]:
False
In [156]:
2+2 == 4
Out[156]:
True
In [157]:
2+(2 == 4)
Out[157]:
2
In [158]:
2+(False)
Out[158]:
2
In [159]:
2+False
Out[159]:
2

Coercion

explicit coersion

In [160]:
x = "10"
In [161]:
x
Out[161]:
'10'
In [162]:
type(x)
Out[162]:
str
In [163]:
x+32
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[163], line 1
----> 1 x+32

TypeError: can only concatenate str (not "int") to str
In [164]:
x = int(x)
In [165]:
x
Out[165]:
10
In [166]:
type(x)
Out[166]:
int
In [167]:
x+32
Out[167]:
42
In [168]:
bool(0)
Out[168]:
False
In [169]:
bool(1)
Out[169]:
True
In [170]:
bool("")
Out[170]:
False
In [171]:
bool(" ")
Out[171]:
True
In [172]:
bool(None)
Out[172]:
False
In [173]:
bool("False")
Out[173]:
True
In [174]:
bool(False)
Out[174]:
False
In [175]:
str(False)
Out[175]:
'False'
In [176]:
bool(str(False))
Out[176]:
True
In [178]:
int(False)
Out[178]:
0
In [177]:
int('False')
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[177], line 1
----> 1 int('False')

ValueError: invalid literal for int() with base 10: 'False'
In [179]:
int(bool('False'))
Out[179]:
1
In [180]:
int(False)
Out[180]:
0
In [181]:
int(True)
Out[181]:
1

implicit coersion

In [182]:
if 10:
    print("10 is an integer, not a boolean. Why is this not an error?")
10 is an integer, not a boolean. Why is this not an error?
In [183]:
if 0:
    print("why doesn't this print?")
In [184]:
x = "False"
if x:
    print("hello")
hello
In [185]:
x = ""
if x:
    print("hello")

Python's assert

In [186]:
assert True
In [187]:
assert False
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
Cell In[187], line 1
----> 1 assert False

AssertionError: 
In [188]:
bool(1)==True
Out[188]:
True
In [189]:
assert bool(1)==True
In [190]:
assert bool(0)==True
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
Cell In[190], line 1
----> 1 assert bool(0)==True

AssertionError: 
In [191]:
assert bool(0)==True, "When I wrote this function, I assumed this would be otherwise."
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
Cell In[191], line 1
----> 1 assert bool(0)==True, "When I wrote this function, I assumed this would be otherwise."

AssertionError: When I wrote this function, I assumed this would be otherwise.

Blocks and control flow

In [192]:
if True:
    print("statement 1")
    print("statement 2")
    print("statement 3")
statement 1
statement 2
statement 3
In [194]:
a = 1
b = -2

if a==1:
    if b>0:
        print("a is one and b is positive")
    else:
        print("here")
        print("a is one")
else:
    print("a is not one")
here
a is one
In [195]:
a = 1
b = -0.0

if a==1:
    if b>0:
        print("a is one and b is positive")
    elif b<0:
        print("a is one and b is negative")
    else:
        print("a is one")
        print("b is zero")
else:
    print("a is not one")
a is one
b is zero
In [196]:
b
Out[196]:
-0.0
</html>