adds libraries

This commit is contained in:
waldek 2021-11-02 10:33:03 +01:00
parent 7347594700
commit 81fb6551e0
1 changed files with 255 additions and 5 deletions

View File

@ -85,12 +85,16 @@ print("Hello World!")
``` ```
Just for reference below are a few helloworld programs in different languages. Just for reference below are a few helloworld programs in different languages.
First `c#` then `c` and last but not least `javascript`. First `c#` then `c` then `c++` and last but not least `javascript`.
### c#
```c# ```c#
Console.WriteLine("Hello World!"); Console.WriteLine("Hello World!");
``` ```
### c
```c ```c
#include <stdio.h> #include <stdio.h>
@ -100,6 +104,21 @@ int main() {
} }
``` ```
### c++
```c++
// Your First C++ Program
#include <iostream>
int main() {
std::cout << "Hello World!";
return 0;
}
```
### javascript
```javascript ```javascript
alert( 'Hello, world!' ); alert( 'Hello, world!' );
``` ```
@ -375,6 +394,8 @@ True
Your first challenge! Your first challenge!
I would like you to write a program that converts Celsius to Fahrenheit. I would like you to write a program that converts Celsius to Fahrenheit.
You should do this in a **new** python file.
I suggest you call it `c_to_f.py` or something that makes sense to you.
The result of this program *could* be as follows. The result of this program *could* be as follows.
```bash ```bash
@ -683,6 +704,8 @@ Think of some calculations such as the Celsius to Fahrenheit converter and creat
# Coding challenge - Pretty Print # Coding challenge - Pretty Print
Can you write me a function that decorates a name or message with a *pretty* character. Can you write me a function that decorates a name or message with a *pretty* character.
You should do this in a **new** python file.
I suggest you call it `pretty_frame.py` or something that makes sense to you.
Kind of like the two examples below. Kind of like the two examples below.
``` ```
@ -776,6 +799,8 @@ Also think about how you can *break* this program!
That being said, we all die and we all live in a country with a life expectancy. That being said, we all die and we all live in a country with a life expectancy.
The [Belgian](https://www.healthybelgium.be/en/health-status/life-expectancy-and-quality-of-life/life-expectancy) life expectancy for a man is about 80 years so if you know your birthday, which you should, you can calculate your theoretical death day. The [Belgian](https://www.healthybelgium.be/en/health-status/life-expectancy-and-quality-of-life/life-expectancy) life expectancy for a man is about 80 years so if you know your birthday, which you should, you can calculate your theoretical death day.
Plus, you can calculate the percentage of your life that remains. Plus, you can calculate the percentage of your life that remains.
You should do this in a **new** python file.
I suggest you call it `memento_mori.py` or something that makes sense to you.
<details> <details>
<summary>Spoiler warning</summary> <summary>Spoiler warning</summary>
@ -797,7 +822,7 @@ days_to_live = memento_mori - datetime.datetime.now().date()
percentage = (days_to_live.days / life_expectancy_days) * 100 percentage = (days_to_live.days / life_expectancy_days) * 100
print("your theoretical death day is:", memento_mori) print("your theoretical death day is:", memento_mori)
print("that's", days_to_live.days, "left to live") print("that's", days_to_live.days, "days left to live")
print("which means you have {:.2f}% left to live...".format(percentage)) print("which means you have {:.2f}% left to live...".format(percentage))
``` ```
@ -808,17 +833,242 @@ Take your time to ask me about them, or use online documentation and keep some n
# Writing your first library # Writing your first library
TODO import pretty print and digital dice Up until now have coded our own functions and usage of these functions.
We've seen there is no need to always write everything from scratch as we can *reuse* existing code by importing libraries and calling it's functions.
But what are those libraries actually?
## What are libraries? Consider the following mini script.
It imports `datetime` and calls the `now` function to print the date and time.
A pretty basic clock.
```python3
import datetime
timestamp = datetime.datetime.now()
print("It is: {}".format(timestamp))
```
When you put your cursor on the `now` part of the function call, you can press **CTRL-b** to go to the **declaration** of said function.
You can also right click on the `now` part and see all possible *actions* you can perform on this function.
This opens up a **second tab** in your editor window with a `datetime.py` file in it.
In this file your cursor should have jumped to the following code.
```python3
@classmethod
def now(cls, tz=None):
"Construct a datetime from time.time() and optional time zone info."
t = _time.time()
return cls.fromtimestamp(t, tz)
```
What does this look like?
It looks like python code no?
Well, it is!
Libraries are often *just* other python files we load into our program.
So if they are just python files we *should* be able to write our own libraries no?
🏃 Try it
---
Import some libraries and go peak at some function declarations.
A big part of code writing is *navigating* a codebase written by other people.
Properly understanding how to navigate is essential!
## How do we write libraries? ## How do we write libraries?
Let's go back to our `pretty_print` function.
I have code along these lines.
```python3
def pretty_print(msg, decorator="#"):
line_len = len(msg) + (len(decorator) * 2) + 2
print(decorator * line_len)
print("{} {} {}".format(decorator, msg, decorator))
print(decorator * line_len)
pretty_print("Wouter")
pretty_print("Python rules!")
pretty_print("Alice", "-")
```
I'll **create a new python file** and name it `helper_functions.py`.
In this file I rewrite (don't copy paste, you need the practice) my function.
As I'm rewriting my function I'll also need some test calls to my function.
Done!
Now in a **second new python file** I'll name `my_program.py` I'll `import` the `helper_fucntions.py` file.
Note the syntax drops the `.py` extension!
```python3
import helper_functions
print("I'm a program")
helper_functions.pretty_print("hello world!")
```
If we now **run** the `my_program.py` file we get the following output.
```
##########
# Wouter #
##########
#################
# Python rules! #
#################
---------
- Alice -
---------
I'm a program
################
# hello world! #
################
```
OK, it *kind* of works, the function get's called from within the `my_program.py` file but the test calls from the `helper_functions.py` file are messing up my execution.
Luckily there is a way to tell python to only run certain code when a file should be seen as program and not a library.
Sounds complicated but it's logically very simple.
## What is `__name__ == "__main__"`? ## What is `__name__ == "__main__"`?
Remember on the first day when I showed you how python is self documenting via `print.__doc__`?
Well, there are [more](https://stackoverflow.com/questions/20340815/built-in-magic-variable-names-attributes) *magical attributes* than just the `__doc__` one!
There is one called `__name__` which is used for the exact purpose we're trying to achieve.
Go back to the `helper_functions.py` file and comment out the test calls and add the line that print's the `__name__` variable.
```python3
def pretty_print(msg, decorator="#"):
line_len = len(msg) + (len(decorator) * 2) + 2
print(decorator * line_len)
print("{} {} {}".format(decorator, msg, decorator))
print(decorator * line_len)
print("I'm a library")
print("my name is: {}".format(__name__))
# pretty_print("Wouter")
# pretty_print("Python rules!")
# pretty_print("Alice", "-")
```
Do the same in the `my_program.py` file so it look similar to the code below.
```python3
import helper_functions
print("I'm a program")
print("my name is: {}".format(__name__))
helper_functions.pretty_print("hello world!")
```
If you now run the `helper_functions.py` file you should get output similar to this.
```
I'm a library
my name is: __main__
```
But when you run the `my_program.py` you should get something like this.
```
I'm a library
my name is: helper_functions
I'm a program
my name is: __main__
################
# hello world! #
################
```
This shows that the `__name__` variable changes according to how a script is called and this behavior can be used to our advantage!
We can *evaluate* the value behind `__name__` and change execution accordingly.
Evaluating and changing execution screams **conditional logic** no?
So in the library we add the following.
```python3
def pretty_print(msg, decorator="#"):
line_len = len(msg) + (len(decorator) * 2) + 2
print(decorator * line_len)
print("{} {} {}".format(decorator, msg, decorator))
print(decorator * line_len)
if __name__ == "__main__":
pretty_print("Wouter")
pretty_print("Python rules!")
pretty_print("Alice", "-")
```
Only when the library is executed as a program, for example when we're testing out out functions, the condition is met to allow execution of our calls.
Problem sorted!
Executing our main program now gives the expected output.
```
I'm a program
my name is: __main__
################
# hello world! #
################
```
## Anatomy of a program ## Anatomy of a program
TODO imports, functions, execution While it's still very early in your coding career I *really* want to insist on good practices from the start as it will help you make sense of it all.
A well written script or program is divided into **three** sections.
1. We collect external tools from libraries, either from the standard library or of our own making.
2. We write the specific tools we need for our program to run.
3. We call a combination of **external** and **specific** tools which constitutes our program logic.
A mock-up program that follows these rules could look like this.
Notice how it's easy to read?
```python3
import random
import datetime
def first_function():
pass
def second_function():
pass
def third_function():
pass
def fourth_function():
pass
if __name__ == "__main__":
print("today it's: {}".format(datetime.datetime.now()))
choice = random.randint(0, 100)
if choice < 50:
first_function()
elif choice > 90:
second_function()
elif choice == 55:
third_function()
else:
fourth_function()
```
🏃 Try it
---
Go online and look for some scripts and programs that interest you.
See if you can assess whether the code follows the pattern I outlined.
There are a couple of things you should definitely read up on.
* The [zen](https://www.python.org/dev/peps/pep-0020/) of python.
* What is [pythonic](https://stackoverflow.com/questions/25011078/what-does-pythonic-mean)?
* Coding [style](https://docs.python-guide.org/writing/style/)
# While loop # While loop