adds libraries
This commit is contained in:
parent
7347594700
commit
81fb6551e0
|
@ -85,12 +85,16 @@ 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`.
|
||||
First `c#` then `c` then `c++` and last but not least `javascript`.
|
||||
|
||||
### c#
|
||||
|
||||
```c#
|
||||
Console.WriteLine("Hello World!");
|
||||
```
|
||||
|
||||
### c
|
||||
|
||||
```c
|
||||
#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
|
||||
alert( 'Hello, world!' );
|
||||
```
|
||||
|
@ -375,6 +394,8 @@ True
|
|||
|
||||
Your first challenge!
|
||||
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.
|
||||
|
||||
```bash
|
||||
|
@ -683,6 +704,8 @@ Think of some calculations such as the Celsius to Fahrenheit converter and creat
|
|||
# Coding challenge - Pretty Print
|
||||
|
||||
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.
|
||||
|
||||
```
|
||||
|
@ -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.
|
||||
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.
|
||||
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>
|
||||
<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
|
||||
|
||||
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))
|
||||
```
|
||||
|
||||
|
@ -808,17 +833,242 @@ Take your time to ask me about them, or use online documentation and keep some n
|
|||
|
||||
# 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?
|
||||
|
||||
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__"`?
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
|
|
Loading…
Reference in New Issue