# Session 2 : Setup & Python basics In this session we will make sure that everyone can run Python on their devices and then do a quite fast-paced run-through over the code pieces below, to explain the basic Python (and programming) concepts. As this might be a lot in a very short amount of time for people who are new not only to Python but to coding in general, please also take at the Python Bascis resources on our [](references.md) page. Especially the w3schools [Python Tutorial](https://www.w3schools.com/python/default.asp) might be a good first starting point, if you are still puzzled about some of the concepts after our quick run-through. There are three recordings in which I talk you through the following code snippets (and the setup initially, with some remarks about code editors): * [Setup & Basics 1](https://base.uni-ak.ac.at/cloud/index.php/s/9Zz9nr6T8HgZ7KY) (~51min, 163MB) * [Basics 2](https://base.uni-ak.ac.at/cloud/index.php/s/kMyGpR6DL8geNQA) (~33min, 100MB) * [Basics 3](https://base.uni-ak.ac.at/cloud/index.php/s/5i2aKtZkbwwcmEq) (~50min, 156MB) ## Setup If you already have Python set up and also have an editor/IDE you like to work with, then you are ready to go. If not, the easiest way to start ist to install [Thonny](https://thonny.org), which is a beginner friendly IDE (itself written in Python). Thonny was developed by the University of Tartu specifically for the context of teaching and learning Python. Thonny is not only an editor/IDE, it also brings a full Python 3 installation with it, as well as a version of pip - the package installer for Python. So with Thonny you have everything you need to get started, and we will use this as a reference tool throughout the course. ## Python basics crash course I Here's the code we'll run through and work in this session: ### basic.py ```python ''' This is a multi-line comment at the beginning of this Python script. Its aim is to introduce you to the most basic concepts in Python. We'll walk through this live in the course. If you look at this in advance and everything here makes perfect sense to you, and you could recreate it yourself from scratch, feel free to skip the first hour of our Setup & Python basics session. ''' # also a comment, only a single line comment # althought it is followed by just another one # no machine code will be executed up to (down) here # but now, let's define some variables my_boolean = True my_boolean = False # well, now we've overwritten the content my_boolean = 'Not a boolean at all, but a string now!' my_boolean = True or False # ahm ... what's that? # let's check and print the content to the console print(my_boolean) print('How can we explain that?') my_explanation = 'Well, True or False is always ' + str(my_boolean) print(my_explanation) # combine printing and evaluation print('But True and False is always', True and False) # Let's get some user input print() # do an empty line first user_name = input('Hey! What\'s your name? ') print(f'Hi {user_name}, nice to talk to you.\n') # using a format string and adding an empty line at the end # before we can do more awesome stuff we need some better ideas # of what types we can use here my_string1 = 'Well, we already know this one' my_string2 = "Double-quotes are also fine" my_string3 = '' my_string4 = 'The last one was an empty string. Still a string!' my_multiline_string = '''This string starts here, but spans several lines. Quite convenient.''' my_tedious_multiline_string = 'This string starts here,\n' my_tedious_multiline_string += 'but spans several lines.\n' my_tedious_multiline_string += 'Quite inconvenient doing it this way.' print(my_multiline_string) print(my_tedious_multiline_string, '\n') print('So' + 'yes,' + 'strings' + 'can' + 'be' + 'concatenated!') # whats up with the spaces? # ok, we got strings, what about numbers and calculations? my_int = 42 my_float = 42.0000000000001 my_float2 = 42.0 print(f'The type of {my_int} is {type(my_int)}.') print(f'The type of {my_float2} is {type(my_float2)}.') # let's do some calculations print(5 * (12-8) + -15) print(98 + (59872 / (13*8)) * -51) print(72 % 8) # this is the modulo operation print(73 % 8) # it returns the remainder of a division # we can even "multiply" strings print('The essence is ' + 'bla' * 3) # now, comparing things is a very boolean thing to do print('2 == 2? ', 2 == 2) print('2 == 3? ', 2 == 3) print('2 < 3? ', 2 < 3) print('2 <= 2? ', 2 <= 2) print('42 > 0? ', 42 > 0) print('"lala" == "lala"', "lala" == "lala") # comparing can be fun, IF you can do something with it user_guess = input(f'Hey {user_name}, give me a number: ') if user_guess == '42': print('Awesome, it seems there is nothing else left to lear for you') user_guess = input(f'Gimme another one: ') if user_guess == '42': print('Sneaky you, you are really intent on being stuck here, are you?') else: print('Sorry, your number is just wrong!') user_guess = input(f'Only one more: ') if user_guess == '42': print('This is getting boring: ') elif user_name == 'jackie': print(f'Well {user_name}, whatever you say seems to be the right thing.') else: print('Not it! Well, maybe another time') # so here we actually compared strings, not really numbers (as in int) # but as we already have 100 lines of code here, let's try it out before we continue with basic2.py ``` As a file: [](snippets/basic.py) ### basic2.py ```python # as we are getting into error handling now, let's define a DEMO var DEMO = True try: print(23 + '23') except Exception as err: if DEMO: print("Ugh, there was an error. But never mind, we'll just continue") else: raise err print(str(23) + '23') print(23 + int(23)) # Ok, so type conversion is an important thing. Let's try that with our # number guesser guess = input('Hey user, gimme a number: ') # You might get an error here, depending on your input try: if int(guess) == 42: print('Correct!') else: print('Not it!') except: print("Ugh, there was an error. But never mind, we'll just continue") # Errors sometimes seem ugly and annoying, # but really, don't be a snob, they can be your friends # Turn off the DEMO mode and see what you get. # Try to fix the code one way or another. # Now which of the following produce an error? try: print(12 + 12) print('12' + '12') print('12' + 12) print('12 + 12') print(2 * 5) print('2' * '5') print('2' * 5) print('2 * 5') except: if DEMO: print("Ugh, there was an error. But never mind, we'll just continue") else: raise err # we've already seen type conversion, here some more examples: variable_1 = 12 variable_2 = '12' str(variable_1) int(variable_2) float(variable_2) # now we can actually check the user input more properly guess = input('Hey user, gimme a number again: ') try: guess = int(guess) except: print("Come on, why can't you give me a number?") else: if guess > 10000: print("That's quite a large number") else: print('Nothing special about this number') # This does not handle ALL numbers. Can you fix it? print('\nAnd now for something completely different!\n') print('A side note on string formatting:') name = 'jackie' day = 'Thursday' # simple string concatenation, as we already know it formatted = 'Hello ' + name + ', what a ' + day + '!' print(formatted) # the old style - good to know but please don't use it formatted = 'Hello %s, what a %s!' % (name, day) print(formatted) # the new style formatted = 'Hello {}, what a {}!'.format(name, day) print(formatted) # f-strings : the best, since Python 3.6 formatted = f'Hello {name}, what a {day}!' print(formatted) # Still, everything is so boringly determined here. Let's add some randomness # and use some standard library features from random import randint from datetime import datetime number = randint(0, 5) now = datetime.now() weekday = now.weekday() print('Today, right now, this moment is', now.strftime('%A, %Y-%m-%d %H:%M')) if abs(weekday - number) == 0: print('Wow! This is a perfect day!') elif abs(weekday - number) <= 2: print('A day as every other.') else: print('This day really sucks!') # check out https://www.w3schools.com/python/python_datetime.asp # for more things you can do with dates # enough for now. try to get this script running. play around with it. # in DEMO and outside DEMO mode. fix the errors. and then ready yourself # for part 3 ``` As a file: [](snippets/basic2.py) ### basic3.py ```python # before we venture into machine land, we really should talk about # lists, dicts, loops and functions item = True my_list = ['contains', 5, 'different', 'items like', item] my_tuple = ('contains', 4, 'immutable', 'things') my_list_from_tuple = list(my_tuple) + ['now mutable!'] # lists can be concatenated too print(my_list_from_tuple, len(my_list_from_tuple)) # let's correct the number of items then my_list_from_tuple[1] = len(my_list_from_tuple) print(my_list_from_tuple) # lists are indexed starting with 0. and they can be sliced print(my_list[2:4]) print(my_list[2:]) print(my_list[:3]) print(my_list[1:2]) # isn't this a bit silly, as we could just use my_list[1] then? print(my_list[1]) # hm ... see the difference? # lists can be extended print('extending my_list') my_list.append('something') my_list.extend([1, 2, 3]) my_list.insert(2, '(number is actually incorrect)') print(my_list) # and we can update single or multiple items print('updating my_list') my_list[1] = len(my_list) # we've already seen this above my_list[2:5] = ['(now correct)', 'very different', 'items'] my_list[7:] = [42, 10] # this replaces part of the list with another (shorter) list print(my_list) # and we can also specifically delete items print('deleting from my_list') my_list.remove(10) popped_item = my_list.pop(4) print(f'popped_item: {popped_item} ; the list now looks like: {my_list}') del my_list[1] print(my_list) my_list.clear() print(my_list) #del my_list print(my_list) # well, this should throw an error, becaus the list is gone now # so remove the last line, before you move on to explore dictionaries # and take a look at those many other aweseom list methods: # https://www.w3schools.com/python/python_lists_methods.asp my_dict = {'name': 'jackie', 'xp': 42, 'zombie': True} # after such a speed run, what did you expect? print(my_dict) print(my_dict['name']) # dicts contain key:value pairs. the values can also be dicts my_dict = { 'name': 'jackie', 'data': { 'xp': 42, 'zombie': True, # machine braaaaaains! }, } print(my_dict) print(my_dict['data']) print(type(my_dict['data'])) print(my_dict['data']['zombie']) print(my_dict.get('name')) # a different way to access print(my_dict.get('something')) # because my_dict['something'] would through an error print('\nsome more ways to access dict keys and values:') print(my_dict.values()) print(my_dict.keys()) print(my_dict.items()) print('\nadding and changing dict items') my_dict['name'] = 'mafalda' my_dict['data']['zombie'] = False my_dict['a_new_key'] = 'a new value' # adding something is easy as that print(my_dict) # but we can update (change/add) several key-value-pairs at once too my_dict.update({'name': None, 'data': 'useless', 'hidden_gem': True}) print(my_dict) print('\ndeleting works similar to lists') popped_item = my_dict.pop('a_new_key') print(f'popped_item: {popped_item} ; the dict now looks like: {my_dict}') del my_dict['hidden_gem'] print(my_dict) my_dict.clear() print(my_dict) #del my_dict print(my_dict) # well, this is same as with lists, same as with everything actually. # if you delete it, it's gone. so fix this before you continue. # also check out all of those dictionary methods: # https://www.w3schools.com/python/python_dictionaries_methods.asp print('\nOk, now, finally it is time to do some looping') print("We'll loop through lists and dicts just for the fun of it") my_list = ['contains', 5, 'different', 'items', True, 0.0, 1.234, False, None, {}, [], ''] for item in my_list: print('We now can do stuff with', item) if type(item) == str: print(f'This item is a string and of {len(item)} length.\n') elif type(item) == int: print('This item is an int:', item, '\n') else: output = 'This item appears to be something else.' if item: output += ' It looks like to be a truthy one.' else: output += ' Totally falsy of course.' print(output + '\n') # here our loop ends print('Looping through dicts works quite similarly') my_dict = {'name': 'jackie', 'xp': 42, 'zombie': True, 'data': {'some': 'thing'}} for key in my_dict: print('Currently at key', key, 'which has the value', my_dict[key]) # but sometimes it is more convenient to get the key and value as separate variables in the loop for key, value in my_dict.items(): print(f'In this loop we can access {key} and directly get {value}.') if type(value) == dict: print('A dict in a dict?!? Are you nuts? I wont look at this any further.') else: print('Boring') # and because those loops actually work with all iterables we can also do this for n in range(23): print(n) else: print('imagine all the possibilities!') # whait, what?!? # yep, that's a thing too, you can use an else after a for loop # look it up: https://www.w3schools.com/python/python_for_loops.asp print(''' You've made it to the end! I think this is enough for today. Get some fresh air. Take a deep breath. Think about happy things. Try not to become a robot until next Thursday. Then we collect the missing pieces to become ... ah, create universal discrete state machines. ''') from time import sleep sleep(4) print('\n\nOh...') sleep(3) print('by the way,') sleep(3) print('did you know this?\n') sleep(2) import this ``` As a file: [](snippets/basic3.py)