591 lines
18 KiB
Markdown
591 lines
18 KiB
Markdown
# What we'll learn
|
|
|
|
You'll learn **three** things at the same time so don't get discouraged if it feels a bit much at the start.
|
|
Everybody's issues will be in these three different domains and at the beginning it can be difficult to differentiate between them.
|
|
Keep this in mind, everybody has to go through this stage and the *click* comes at different times for different people but everybody clicks at some point!
|
|
The three new things you'll learn:
|
|
|
|
1. the **concepts** of programming, most notably Object Orientated Programming (OOP)
|
|
2. the **syntax** of one particular language, in our case Python3
|
|
3. the **tools** needed to start programming in our language of choice
|
|
|
|
Within each of these topics there are *subtopics* but there are not bottomless!
|
|
Below is a small overview of how I would subdivide them.
|
|
|
|
## Concepts
|
|
|
|
The subtopics behind the concept of programming can be sliced (in no particular order) as follows:
|
|
|
|
* objects or **OOP** (Object Orientated Programming)
|
|
* abstraction
|
|
* encapsulation
|
|
* inheritance
|
|
* polymorphism
|
|
* variables (which are **not** *boxes* in python3)
|
|
* conditional logic
|
|
* functions
|
|
* loops
|
|
|
|
The concept behind these topics are the same in most languages, it's just *how* you write them that is different.
|
|
This *how* is part of the **syntax** of the language.
|
|
|
|
## Syntax
|
|
|
|
> In computer science, the syntax of a computer language is the set of rules that defines the combinations of symbols that are considered to be correctly structured statements or expressions in that language.
|
|
> This applies both to programming languages, where the document represents source code, and to markup languages, where the document represents data.
|
|
> The syntax of a language defines its surface form.[1] Text-based computer languages are based on sequences of characters,
|
|
|
|
The quote above is taken shamelessly from [wikipedia](https://en.wikipedia.org/wiki/Syntax_(programming_languages)).
|
|
|
|
## Tools
|
|
|
|
### Writing code
|
|
|
|
Scripts are text files, plain and simple.
|
|
So in order to **write** a Python3 script all we need is a text editor.
|
|
Nano, vim, notepad++ all do a good job of editing plain text files but some make it *easier* than others.
|
|
You've noticed that vim colors the code of a shell script no?
|
|
One of the many features of an [IDE](https://en.wikipedia.org/wiki/Integrated_development_environment) is *syntax highlighting*.
|
|
It colors things such as [keywords](https://realpython.com/python-keywords/) which makes our life so much nicer when writing code.
|
|
We'll come back to these features in a bit.
|
|
|
|
### Running code
|
|
|
|
In order to **run** Python3 code you need the Python3 interpreter.
|
|
This is because when you **execute** your script, the interpreter will **read and execute** each line of the text file **line by line**.
|
|
|
|
Most people who want to write and run Python3 code, or any language for that matter, will install an Integrated Development Environment to do so.
|
|
There are no *rules* as to what has to be included for a program to qualify as an IDE but in my opinion they should include:
|
|
|
|
* syntax highlighting
|
|
* autocomplete
|
|
* *goto* commands such as goto definition, goto declaration, goto references
|
|
* automatic *pair* opening and closing
|
|
* builtin help navigation
|
|
|
|
There is a plethora of IDE's available and you can't really make a *wrong* choice here, but to make the overall learning curve a bit less steep we'll start out with a user friendly IDE, [pycharm](https://www.jetbrains.com/help/pycharm/installation-guide.html).
|
|
|
|
# The python3 shell
|
|
|
|
TODO animated overview of the shell and the world of OOP
|
|
|
|
# Installing pycharm
|
|
|
|
TODO
|
|
|
|
# Your first project
|
|
|
|
In almost any language you'll find a *helloworld* program.
|
|
It serves to illustrate a *very* basic working script or program to showcase the syntax.
|
|
In python a helloworld is done as such.
|
|
|
|
```python3
|
|
print("Hello World!")
|
|
```
|
|
|
|
Just for reference below are a few helloworld programs in different languages.
|
|
First `c#` then `c` and last but not least `javascript`.
|
|
|
|
```c#
|
|
Console.WriteLine("Hello World!");
|
|
```
|
|
|
|
```c
|
|
#include <stdio.h>
|
|
|
|
int main() {
|
|
printf("Hello World!");
|
|
return 0;
|
|
}
|
|
```
|
|
|
|
```javascript
|
|
alert( 'Hello, world!' );
|
|
```
|
|
|
|
## How to execute
|
|
|
|
* within pycharm
|
|
* from the command line
|
|
|
|
## Simple printing
|
|
|
|
The most basic printing can be done by calling the `print` function.
|
|
In python a call is symbolized by the `()`.
|
|
In practice this becomes as follows.
|
|
|
|
```python3
|
|
print("hello world")
|
|
print("my name is Wouter")
|
|
print("I'm", 35, "years old")
|
|
```
|
|
|
|
🏃 Try it
|
|
---
|
|
|
|
Try printing different lines and with combinations of different object types such as `int`, `float` and `str`.
|
|
What happens if you *add* (`+`) values to one another?
|
|
|
|
|
|
We can also print the objects referenced by variables.
|
|
A simple example:
|
|
|
|
```python3
|
|
name = "Wouter"
|
|
age = "35"
|
|
|
|
print("Hello, my name is", name, "and I'm", age, "years old.")
|
|
```
|
|
|
|
While it works perfectly well it's not super *readable*.
|
|
We can improve the readability by using either string replacement or string formatting.
|
|
My personal preference is string formatting.
|
|
|
|
🏃 Try it
|
|
---
|
|
|
|
Have a look at both ways illustrated below and try them out.
|
|
|
|
|
|
## String replacement
|
|
|
|
```python3
|
|
name = "Wouter"
|
|
age = "35"
|
|
|
|
print(f"Hello, my name is {name} and I'm {age} years old.")
|
|
```
|
|
|
|
## String formatting
|
|
|
|
```python3
|
|
name = "Wouter"
|
|
age = "35"
|
|
|
|
print("Hello, my name is {} and I'm {} years old.".format(name, age))
|
|
```
|
|
|
|
## Some links to read up
|
|
|
|
* [realpython string formatting](https://realpython.com/python-string-formatting/)
|
|
|
|
# Taking input
|
|
|
|
The first **builtin function** we saw is `print` which can be used to signal messages to the user.
|
|
But how can we **get** some information from the user?
|
|
This is done with the `input` function.
|
|
If we open up a python shell we can observe it's behaviour.
|
|
|
|
```python3
|
|
>>> input()
|
|
hello world
|
|
'hello world'
|
|
>>>
|
|
```
|
|
|
|
It seems to echo back what we type on the empty line.
|
|
If we take this idea and add it to a script the behaviour changes slightly.
|
|
The [prompt](https://en.wikipedia.org/wiki/Command-line_interface#Command_prompt) appears but when we hit `enter` the text is not printed.
|
|
This is one of the slight nuances between running scripts and using the shell.
|
|
The shell is more *verbose* and will explicitly tell you what a function returns, unless it doesn't return anything.
|
|
|
|
## Some functions are blocking
|
|
|
|
When we call `print` the function is executed immediately and the python interpreter continues with the next line.
|
|
The `input` function is slightly different.
|
|
It is called a **blocking** function.
|
|
When a blocking function is called the program is *waiting* for some action.
|
|
Once the condition is met, the program continues.
|
|
It's important to be aware of this but don't overthink it.
|
|
We'll get back to this behaviour later.
|
|
|
|
## Functions can return something
|
|
|
|
So, functions can **return** something but how can we *use* the returned objects?
|
|
This is where **variables** come in handy.
|
|
The `input` function will **always** return an object of type `str`.
|
|
If we want to use this object later in our code we need to add a *post-it* to it so we can reference it later.
|
|
Remember that the object is created by the function call, and we add the reference after the object's creation.
|
|
|
|
```python3
|
|
print("What is your name? ")
|
|
answer = input()
|
|
print("Well hello", answer, "!")
|
|
```
|
|
|
|
**When looking at the code block above did you notice the *empty space* I added after my question?
|
|
Can you tell me why I did that?**
|
|
|
|
🏃 Try it
|
|
---
|
|
|
|
Try playing around with the `input` function and incorporate the different ways to print with it.
|
|
Ask multiple questions and combine the answers to print on one line.
|
|
|
|
## Functions can take arguments
|
|
|
|
Some, if not most, functions will take one or more arguments when calling them.
|
|
This might sound complicated but you've already done this!
|
|
The `print` function takes *a-message-to-print* as an argument, or even multiple ones as you probably noticed when playing around.
|
|
|
|
The `input` function *can* take arguments but as we've seen does not *require* an argument.
|
|
When looking at the documentation we can discover **what** the function does, how to **call** the function and what it **returns**.
|
|
|
|
⛑ **CTRL-q opens the documentation in pycharm**
|
|
|
|
```
|
|
Help on built-in function input in module builtins:
|
|
|
|
input(prompt=None, /)
|
|
Read a string from standard input. The trailing newline is stripped.
|
|
|
|
The prompt string, if given, is printed to standard output without a
|
|
trailing newline before reading input.
|
|
|
|
If the user hits EOF (*nix: Ctrl-D, Windows: Ctrl-Z+Return), raise EOFError.
|
|
On *nix systems, readline is used if available.
|
|
```
|
|
|
|
We can add one **argument** inside the `input` call which serves as a prompt.
|
|
Now which `type` should the object we pass to `input` be?
|
|
The most logical type would be a `str` that represents the *question* to ask the user no?
|
|
Let's try it out.
|
|
|
|
```python3
|
|
answer = input("What is your name?")
|
|
print("Well hello {}!".format(answer))
|
|
```
|
|
|
|
🏃 Try it
|
|
---
|
|
|
|
Modify the questions you asked before so they have a proper prompt via the `input` function.
|
|
Ask multiple questions and combine the answers to print on one line with different `print` formatting.
|
|
|
|
# Taking input and evaluation
|
|
|
|
We can do a lot more with the input from users than just print it back out.
|
|
It can be used to make logical choices based on the return **value**.
|
|
This is a lot easier than you think.
|
|
Imagine you ask me my age.
|
|
When I respond with *35* you'll think to yourself *"that's old!"*.
|
|
If I would be younger then *30* you would think I'm young.
|
|
We can implement this logic in python with easy to read syntax.
|
|
First we'll take a python **shell** to experiment a bit.
|
|
|
|
```python3
|
|
>>> 35 > 30
|
|
True
|
|
>>> 25 > 30
|
|
False
|
|
>>> 30 > 30
|
|
False
|
|
>>> 30 >= 30
|
|
True
|
|
>>>
|
|
```
|
|
|
|
The `True` and `False` you see are also objects but of the type `bool`.
|
|
If you want to read up a bit more on boolean logic I can advise you [this](https://en.wikipedia.org/wiki/Boolean_algebra) page and also [this](https://realpython.com/lessons/boolean-logic/).
|
|
This boolean logic open the door towards **conditional logic**.
|
|
|
|
## Conditional logic
|
|
|
|
Let's convert the quote below to logical statements.
|
|
|
|
> If you are younger than 27 you are still young so if you're older than 27 you're considered old, but if you are 27 on the dot your life might be at [risk](https://en.wikipedia.org/wiki/27_Club)!
|
|
|
|
```python3
|
|
age = 35
|
|
if age < 27:
|
|
print("you are still very young, enjoy it!")
|
|
elif age > 27:
|
|
print("watch out for those hips oldie...")
|
|
else:
|
|
print("you are at a dangerous crossroad in life!")
|
|
```
|
|
|
|
## Class string methods
|
|
|
|
Let's take the logic above and implement it in a real program.
|
|
I would like the program to ask the user for his/her name and age.
|
|
After both questions are asked I would like the program to show a personalized message to the user.
|
|
The code below is functional but requires quite a bit of explaining!
|
|
|
|
```python3
|
|
name = input("What is you name?")
|
|
age = input("What is you age?")
|
|
|
|
if age.isdigit():
|
|
age = int(age)
|
|
else:
|
|
print("{} is not a valid age".format(age))
|
|
exit(1)
|
|
|
|
if age < 27:
|
|
print("My god {}, you are still very young, enjoy it!".format(name))
|
|
elif age > 27:
|
|
print("Wow {}! Watch out for those hips oldie...".format(name))
|
|
else:
|
|
print("{}, you are at a dangerous crossroad in life!".format(name.capitalize()))
|
|
```
|
|
|
|
An object of the type `str` has multiple **methods** that can be applied on itself.
|
|
It might not have been obvious but the *string formatting* via `"hello {}".format("world")` we did above is exactly this.
|
|
We **call** the `.format` **method** on a `str` object.
|
|
Strings have a handful of methods we can call.
|
|
Pycharm lists these methods when you type `.` after a string.
|
|
In the **shell** we can visualize this as well.
|
|
For those of you not familiar with shells have a look at [tab completion](https://en.wikipedia.org/wiki/Command-line_completion).
|
|
|
|
```python3
|
|
>>> name = "wouter"
|
|
>>> name.
|
|
name.capitalize( name.format( name.isidentifier( name.ljust( name.rfind( name.startswith(
|
|
name.casefold( name.format_map( name.islower( name.lower( name.rindex( name.strip(
|
|
name.center( name.index( name.isnumeric( name.lstrip( name.rjust( name.swapcase(
|
|
name.count( name.isalnum( name.isprintable( name.maketrans( name.rpartition( name.title(
|
|
name.encode( name.isalpha( name.isspace( name.partition( name.rsplit( name.translate(
|
|
name.endswith( name.isascii( name.istitle( name.removeprefix( name.rstrip( name.upper(
|
|
name.expandtabs( name.isdecimal( name.isupper( name.removesuffix( name.split( name.zfill(
|
|
name.find( name.isdigit( name.join( name.replace( name.splitlines(
|
|
>>> name.capitalize()
|
|
'Wouter'
|
|
>>> name.isd
|
|
name.isdecimal( name.isdigit(
|
|
>>> name.isdigit()
|
|
False
|
|
>>> age = "35"
|
|
>>> age.isdigit()
|
|
True
|
|
>>>
|
|
```
|
|
|
|
⛑ **Remember CTRL-q opens the documentation in Pycharm and don't forget to actually use it!**
|
|
|
|
# Coding challenge - Celsius to Fahrenheit converter
|
|
|
|
Your first challenge!
|
|
I would like you to write a program that converts celcius to farenheit.
|
|
The result of this program *could* be as follows.
|
|
|
|
```bash
|
|
➜ ~ git:(master) ✗ python3 ex_celcius_to_farenheit.py
|
|
What's the temperature?30
|
|
30°C equals 86.0°F
|
|
Go turn off the heating!
|
|
➜ ~ git:(master) ✗ python3 ex_celcius_to_farenheit.py
|
|
What's the temperature?4
|
|
4°C equals 39.2°F
|
|
Brrrr, that's cold!
|
|
➜ ~ git:(master) ✗ python3 ex_celcius_to_farenheit.py
|
|
What's the temperature?blabla
|
|
I can't understand you...
|
|
➜ ~ git:(master) ✗
|
|
```
|
|
|
|
<details>
|
|
<summary>Spoiler warning</summary>
|
|
|
|
```python3
|
|
result = input("What's the temperature?")
|
|
|
|
if result.isdigit():
|
|
celsius = int(result)
|
|
else:
|
|
print("I can't understand you...")
|
|
exit(1)
|
|
|
|
farenheit = celsius * (9/5) + 32
|
|
|
|
print("{}°C equals {}°F".format(celsius, farenheit))
|
|
|
|
if celsius < 15:
|
|
print("Brrrr, that's cold!")
|
|
else:
|
|
print("Go turn off the heating!")
|
|
|
|
```
|
|
|
|
</details>
|
|
|
|
# A text based adventure game
|
|
|
|
We can use conditional logic to create quite elaborate decision processes.
|
|
Let's build a mini text based adventure game.
|
|
Granted it's not a *tripple A* game but it will train your `if` and `else` skills plus it will highlight some issues we'll overcome in the next section.
|
|
Consider the diagram below.
|
|
|
|
![adventure game](./assets/text_based_adventure_game.png)
|
|
|
|
```python3
|
|
answer = input("You're at a cross section. Do you go left or right?")
|
|
if answer.startswith("l"):
|
|
answer = input("Down this hall you encounter a bear. Do you fight it?")
|
|
if answer.startswith("y"):
|
|
print("The bear counter attack! He kills you")
|
|
print("game over!")
|
|
exit(0)
|
|
elif answer.startswith("n"):
|
|
print("It's a friendly bear! He transforms into a wizard!")
|
|
answer = input("The wizard asks you if you know the meaning of life?")
|
|
if answer == "42":
|
|
print("He knods approuvingly and upgrades you to wizard status!")
|
|
print("You win!")
|
|
exit(0)
|
|
else:
|
|
print("He shakes his head in disbelief. You fool!")
|
|
print("game over!")
|
|
else:
|
|
print("that's not a valid choice...")
|
|
print("game over!")
|
|
exit(0)
|
|
elif answer.startswith("r"):
|
|
answer = input("Down this hall you find some mushrooms. Do you eat them?")
|
|
if answer.startswith("n"):
|
|
print("You starve to dead...")
|
|
print("game over!")
|
|
exit(0)
|
|
elif answer.startswith("y"):
|
|
print("A wizard apprears out of thin air!")
|
|
answer = input("The wizard asks you if you know the meaning of life?")
|
|
if answer == "42":
|
|
print("He knods approuvingly and upgrades you to wizard status!")
|
|
print("You win!")
|
|
exit(0)
|
|
else:
|
|
print("He shakes his head in disbelief. You fool!")
|
|
print("game over!")
|
|
else:
|
|
print("that's not a valid choice...")
|
|
print("game over!")
|
|
exit(0)
|
|
pass
|
|
else:
|
|
print("game over!")
|
|
exit(0)
|
|
```
|
|
|
|
# Creating your own functions
|
|
|
|
## Functions that *do* something
|
|
|
|
TODO recipe with variable flavor (chocolate, vanilla, ...)
|
|
TODO pretty_print
|
|
|
|
## Variable scope
|
|
|
|
## Functions that *return* something
|
|
|
|
TODO basic math functions
|
|
|
|
# Using the standard library
|
|
|
|
TODO import random exercise (digital dice)
|
|
TODO import datetime exercise (will it be Sunday)
|
|
TODO simple ROT13 cryptography with multiple libs
|
|
|
|
# Coding challenge - Memento Mori calculator
|
|
|
|
# Writing your first library
|
|
|
|
TODO import pretty print and digital dice
|
|
|
|
## What are libraries?
|
|
|
|
## How do we write libraries?
|
|
|
|
## What is `__name__ == "__main__"`?
|
|
|
|
## Anatomy of a program
|
|
|
|
TODO imports, functions, execution
|
|
|
|
# While loop
|
|
|
|
TODO guess the number exercise
|
|
|
|
# Lists
|
|
|
|
## Creating lists
|
|
|
|
## Picking elements
|
|
|
|
## Slicing lists
|
|
|
|
# For loop
|
|
|
|
TODO say hello to my friends exercise
|
|
|
|
# Coding challenge - Cheerleader chant
|
|
|
|
TODO nested for loop exercise
|
|
|
|
# Handling files
|
|
|
|
## Reading from a file
|
|
|
|
## Writing to a file
|
|
|
|
## csv, JSON and yaml
|
|
|
|
## pickle
|
|
|
|
# Coding challenge - Login generator
|
|
|
|
TODO write a login generator as a library with a cli as program
|
|
BONUS argparse, save to file, read from file
|
|
|
|
# Dictionaries as data containers
|
|
|
|
TODO adapt the login generator to output a dict
|
|
|
|
# Creating our own classes
|
|
|
|
## Class examples
|
|
|
|
TODO simple animal or vehicle exercise
|
|
TODO task manager
|
|
|
|
## Class inheritance
|
|
|
|
TODO shapes and surfaces
|
|
TODO superhero game
|
|
|
|
## Improve the login generator
|
|
|
|
TODO convert the login generator to a class
|
|
|
|
# Infinite programs
|
|
|
|
* insist on the nature of scripts we did up until now
|
|
|
|
## Logic breakdown of a simple game
|
|
|
|
TODO hangman exercise
|
|
|
|
## Trivial pursuit multiple choice game
|
|
|
|
TODO [db](https://opentdb.com/api_config.php)
|
|
|
|
### Introduction to the `requests` library
|
|
|
|
## Threading
|
|
|
|
TODO add a countdown timer to the multiple choice game
|
|
|
|
# GUI programming
|
|
|
|
## wxpython helloworld
|
|
|
|
## wxpython guess the number
|
|
|
|
## MVC design pattern
|
|
|
|
# Coding challenge - Login generator with GUI
|
|
|
|
# Coding challenge - Trivial pursuit with GUI
|
|
|
|
# Introduction to the `logging` library
|
|
|