Well... I'm taking a Python course, and I'm going to document a bit my journey. At first I'll probably write less ( because easy ) but who knows if I end up writing more! For now, just an explanation of the course little exercises I've been doing, you can see all of them in this repository. 
Lots of love!
Classes:
Beginner:
- DAY 01 - Working with Variables in Python to Manage Data. - 10 April 2023
- DAY 02 - Understanding Data Types and How to Manipulate Strings. - 10 April 2023
- DAY 03 - Control Flow and Logical Operators. - 10 April 2023
- DAY 04 - Randomisation and Python Lists. - 11 April 2023
- DAY 05 - Python Loops. - 11 April 2023
- DAY 06 - Python Functions & Karel. - 13 April 2023
- DAY 07 - Hangman. - 13 April 2023
- DAY 08 - Function Parameters & Caesar Cipher. 14 April 2023
- DAY 09 - Dictionaries, Nesting and the Secret Auction. 14 April 2023
- DAY 10 - Functions with Outputs 17 April 2023
- DAY 11 - The Blackjack Capstone Project 20 April 2023
- DAY 12 - Scope and Number Guessing Game 20 April 2023
- DAY 13 - Debugging: How to Find and Fix errors in your code 21 April 2023
- DAY 14 - Higher Lower Game Project 21 April 2023
Intermediate:
- DAY 15 - Local Development, Environment Setup & The Coffee Machine 23 April 2023
- DAY 16 - Object Oriented Programming (OOP) 24 April 2023
- DAY 17 - The Quiz Project & the Benefits of OOP 25 April 2023
- DAY 18 - Turtle & the Graphical User Interface (GUI) 28 April 2023
- DAY 19 - Instances, State and Higher Order Functions 1 May 2023
- DAY 20 - Build the Snake Game Part 1 : Animation & Coordinates 4 May 2023
- DAY 21 - Build the Snake Game Part 2 : Inheritance & List Slicing 8 May 2023
- DAY 22 - Build Pong: The Famous Arcade Game 8 May 2023
- DAY 23 - The Turtle Crossing Capstone Project
- DAY 24 - Files, Directories and Paths
- ...
Generate a Band Name with the user's city and pet name.
Write a program that adds the digits in a 2 digit number. 
Modifyed to work for more than 2 digit numbers.
Write a program that calculates the Body Mass Index (BMI) form a user's weight and height. 
The BMI is calculated by dividing the person's weight (kg) by the square of their height (m).
Create a program using maths and f-Strings that tell us how many days, weeks and months we have left if we live up to 90 years old. 
1 year = 365 days, 52 weeks and 12 months
Calculate the tip based on the total bill, the tip percentage and how many people are going to pay.
Write a program that works out wether if a given number is odd or even. 
Even numbers can be divided by 2 with no remainder.
Upgrade of the las BMI Calculator. 
It should tell the interpretation of their BMI based on the value: 
 
Less than 18.5 --- Underweight 
18.5 - 25 -------- Normal weight 
25 - 30 ---------- Overweight 
30 - 35 ---------- Obese 
Over 35 ---------- Clinically Obese 
Write a program that works out wether if a given year is a leap year. 
A normal year has 365 days, leap years have 366 vith an extra day in February. 
'On every year that is evenly divisible by 4, except if that year is divisible by 100, unless it is also divisible by 400.'
Congratulations! You've got a job at Python Pizza. Your fist job is to build an automatic pizza order program. 
Based on the user's order, work out their final bill.
Write a program that tests the compatibility between two people. 
Take both people's name and check for the number of times the letters in the word TRUE occurs. Then, check for the number of times the letters in the word LOVE occurs. Combine these numbers to make a who digit number. 
 
Less than 10 or more than 90 --- 'You go together like coke and mentos' 
Between 40 and 50 --- 'You are alright together'
Create a 'Choose your own adventure' Game using this flowchart: 
Treasure Island Flowchart
Write a virtual coin toss program. It will randomly tell the user 'Heads' or 'Tails'.
Write a program which will select a random name from a list. The person selected will have to play for everybody's food bill.
Write a program which will mark a spot with an x. The map is made of 3 rows of blank squares. 
The program should allow you to enter the position of the treasure using a twi digit system. The first digit is the horizontal column number and the second is the vertical number. 
 
Modified to be a find the treasure game, with limited attempts to find it.
Create a Rock Paper Scissors Game.
Write a program that calculates the average student height from a list of heights.
Write a program that calculates the highest score from a list of scores. Not allowed to use the min() max() functions.
Write a program that calculates the sum of all the even numbers from 1 to 100, including both.
Write a program that automatically prints the solution to the FizzBuzz game. 
- Your program should print each number from 1 to 100 in turn.
- When the number is divisible by 3 the instead of the number, it should print 'Fizz'.
- When the number is divisible by 5. then instead of the number, it should print 'Buzz'.
- When the number is divisible by both 3 and 5 then instead of the number, it should print 'FizzBuzz'.
Write a Random Password Generator with the amount of letters, symbols and numbers chosen by the user. 
In this project I learnt about the existence of random.sample( sequence, k ) that uses the items of a sequence ( list , string, ... ) and a length to generate a randomized result.
import random
list = [1, 2, 3, 4, 5] 
random.sample( list , 3 ) 
# E.g. Output : [2, 3, 5]In this case, I used it to randomize the position of the characters of the password:
''.join( random.sample( password, len( password ) ) )Challenge:
Reeborg's World - Hurdle 1 
Reeborg has entered a hurdles race. Make him run the course, following the path shown. 
My solution:
def jump():
  move()
  turn(1)
  turn(3)
  turn(3)
  turn(1, False)
def turn(num, m = True ):
    for n in range(0,num):
        turn_left()
    if m :
        move()
for n in range(0, 6):
    jump()Challenge:
Reeborg's World - Hurdle 3 
Reeborg has entered a hurdle race. Make him run the course, following the path shown.
The position and number of hurdles changes each time this world is reloaded. 
My solution:
def jump():
    turn(1)
    turn(3)
    turn(3)
    turn(1, False)
    
def turn(num, m = True ):
    for n in range(0,num):
        turn_left()
    if m :
        move()
    
while not at_goal():
    while front_is_clear() and not at_goal():
        move()
    else:
        jump()Challenge:
Reeborg's World - Hurdle 4 
Reeborg has entered a hurdle race. Make him run the course, following the path shown.
The position, the height and the number of hurdles changes each time this world is reloaded. 
My solution:
def jump():
    turn(1)
    turn(3)
    turn(3)
    turn(1, False)
    
def turn(num, m = True ):
    for n in range(0,num):
        turn_left()
    if m :
        if( not wall_on_right() ) : move()
        while wall_on_right() and front_is_clear():
            move()
    
while not at_goal():
    while front_is_clear() and not at_goal():
        move()
    else:
        if not at_goal() : jump()
else:
    done()Challenge:
Reeborg's World - Maze 
Reeborg was exploring a dark maze and the battery in its flashlight ran out. 
Write a program using an if/elif/else statement so Reeborg can find the exit. The secret is to have Reeborg follow along the right edge of the maze, turning right if it can, going straight ahead if it can’t turn right, or turning left as a last resort. 
It took me more than I'd like to admit because I started with a completely wrong mindset about how to complete it... I had to sit back and really figure out how everything should work. 
I's funny because there is a place in the maze that would make the robot go on a loop, making a square. I fixed this making it so the robot can only turn right two times in a row. 
My solution:
def lookNorth():
    while not is_facing_north():
        turn_left()
def lookRight():
    for n in range(0, 3):
        turn_left()
        
count = 0
def detectWalls():
    global count
    
    if right_is_clear() and count <= 1:
        count += 1
        lookRight()
    elif not right_is_clear() and not front_is_clear():
        turn_left()
        count = 0
    else:
        count = 0
        
lookNorth()        
while not at_goal():
    detectWalls()
    if front_is_clear() : move()
else:
    done()Create a hangman game.
- Picking Random Words and Checking Answers.
- Replacing Blanks with Guesses.
- Checking if the Playes has Won.
- Keeping Track of the Player's Lives.
- Improving the User Experience.
You are painting a wall, the instructions on the paint says that 1 can of paint can cover 5 square meters of wall. 
Given a random size of the wall, calculate how many cans of paint you'll need to buy. 
 
number of cans = ( wall height * wall width ) / coverage per can  
Prime numbers are numbers that can only be divided by itself and 1. 
You need to write a function that checks wether if the number passed into it is a prime number or not. 
In this case I made a little library with the different answers to if it was or not a prime number, so I could use them multiple times but change it only once if necessary. 
answers = {
    'it_is'     : 'It\'s a prime number.',
    'it_is_not' : 'It\'s NOT a prime number.'
}The Caesar Cipher ( or Caesar Code ) is a monoalphabetic substitution cipher, where each letter is replace by another located a little further. This shift distance is based on an offset. 
In the course project, you have to know the offset to decode the message, but I wanted to be able to decript the message either way. For that, I just checked all possible offsets that can be made in the alphabet. 
for n in range( 0 , len( alphabet )):
  caesar( direction , text , n )You have access to a database of student_scores in the format of a dictionary. The keys of the dictionary are the names of the students, and the values are their exam scores. 
Write a program that converts their scores to grades. By the end of the program, you should have a dictionary called student_grades with the same structure as the other. 
Coding criteria: 
- Scores 91 - 100 : 'Outstanding'
- Scores 81 - 90 : 'Exceeds Expectations'
- Scores 71 - 80 : 'Acceptable'
- Scores 70 or lower : 'Fail'
Write a program that adds to a travel_log. Write a function to add or modify this travel_log to add the name of the country, how many times you've visited it, and which cities. 
I've added the posibility to check the complete Travel Log, or just one country.
A firs-price sealed-bid auction (FPSBA) or Blind Aucion is a type of aution in wich all bidders simultaneously submit sealed bids, so that no other bidder knows the bid of any other participant. 
Using the Leap Year project code, change the function so that instead of printint 'Leap year' or 'Not leap year' it returns True or False. 
Then, create a function called days_in_month( year , month ) that will use its paremeters to work out the days in the month, and return that as the output.
Make a calculator. In the project she said to ask three questions, the first number, the operator, and then the second number. I wanted to be able to write the operation itself, and that gave me the problem of... ¿What if I want to write a complicated operation that has more than two numbers? And of course I have to follow the order so multiply and so on goes first, then sum and subtraction, etc. 
After thinking a bit, I created a while loop to run until I have my result, first, I check all the multiplication, division, etc. and substitute the values used in the list for the result of the calculation. When I finish that, I check for all the other operations until I get just one value, my result.
while len(numbers) > 1:
        for i, n in enumerate( numbers ):
            if n == '*' or n == '/' or n == '%' or n == '^' or n == 'x':
                numbers[i] = calculate( float(numbers[i - 1]), n , float(numbers[i + 1]) )
                numbers.pop( i + 1 )
                numbers.pop( i - 1 )
        else:
            for i, n in enumerate( numbers ):
                if n == '+' or n == '-':
                    numbers[i] = calculate( float(numbers[i - 1]), n , float(numbers[i + 1]) )
                    numbers.pop( i + 1 )
                    numbers.pop( i - 1 )Also, I learnt about the operator module, that exports a set of efficient functions corresponding to each Python operator. operator.add( a , b ) its equivalent to the expression a + b. 
Thanks to it, I can make a dynamic calculation without worrying about doing all the if's statements for all the individual operators.
import operator
ops = {
    '+' : operator.add,
    '-' : operator.sub,
    '*' : operator.mul,
    'x' : operator.mul,
    '/' : operator.truediv,
    '%' : operator.mod,
    '^' : operator.xor,
}
result = ops[ operation ]( first_number , second_number ) # operation = '+' or '-' or '*'...Write a Simplifyed Blackjack game. 
Blackjack House rules:
- The deck is unlimited in size.
- There are no jokers.
- The Jack/Queen/King all count as 10.
- The Ace can count as 11 or as 1.
-  Use the list cards = [11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]as a deck of cards.
- The cards in the list have equal probability of being drawn.
- Cards are not removed from the deck as they are drawn.
Make a game about guessing a random number bewteen 0 and 100. You have two levels, hard and easy, with 5 and 10 attempts to guess respectively. 
NAH
Make a game about guessing who has more followers on instagram from a made up list.
Program requirements: Coffee Machine Program Requirements
Three Hot Flavours:
| Espresso | Latte | Cappuccino | |
|---|---|---|---|
| Price | $1.50 | $2.50 | $3.00 | 
| Water | 50ml | 200ml | 250ml | 
| Coffee | 18g | 24g | 24g | 
| Milk | - | 150ml | 100ml | 
Manage Resources:
| Water | Coffee | Milk | 
|---|---|---|
| 300ml | 100g | 200ml | 
Coin Operated:
| Penny | Nickel | Dime | Quarter | 
|---|---|---|---|
| 1cent | 5cents | 10cents | 25cents | 
I really enjoyed this project, It had a lot more to it than the last ones. I added that, when you don't input enough money, instead of just giving it back and restarting everything, you can choose between adding more coins or just cancel the order and start again.
Also, I looked for ASCII Art on the internet of a coffee machine but couldn't find anything nice, so in the end I created my own which I'm actually really proud of.
    _____________________ _____
   |  _________________  | ___ ||   ______________________
   | | ___/     \__/\  | | ___ ||  |                      ||
   | |/_______________\| |     ||  | PRICE CHART:         ||
   |                     |  _  ||  |                      ||
   |   O || Espresso     | |_| ||  | Espresso   -> $ 1.50 ||
   |   O || Latte        |     ||  | Latte      -> $ 2.50 ||
   |   O || Capuccino    |  -o ||  | Cappuccino -> $ 3.00 ||
   |    _____________    |     ||  |______________________||
   |   Y    |___|    Y   |     ||   
   |   |   |     |   |   |     ||
   |  ||    \___/    ||  | ___ ||
   |   0_____________0   | ___ ||
   |_  _______________  _|_ _ _||
Same as before, but re-writting it with objects. 
I've made a Menu, MenuItem, CoffeeMaker and MoneyMachine classes, and each manage one part of the whole Coffee Machine. This way, the main code stays cleaner and more readable, and also, it is more modular and replicable.
In this project, I wanted to give a bit more of attention to commenting and typing, so that my code could be more readable and understandable. For this, I researched Commenting Best Practices and how to type variables, parameters and functions in Python.
def manage_money( self , total : float , cost : float ):
        """Adds the cost of the drink to the machine profit and gives back the change.
        :total: (float) Total of the payment.
        :cost: (float) Cost of the drink.
        """
        self.profit += cost
        change : float = round(total - cost, 2)
        print( f"\n    Here is your ${ change } in change." ) if not total == cost else ''Write a Quiz Game using the Open Trivia Database.
She takes the json given by the Open Trivia Database, copy it and transform it on the project, but I wanted to go a bit further and investigate how to use the Trivia API, how to recollect the data and actually let the user choose the difficulty of the Quiz.
import requests, json
def get_data( difficulty : str ):
    url = 'https://opentdb.com/api.php?amount=25&type=boolean&difficulty='
    res = requests.get( url + difficulty )
    data = json.loads( res.text )
    return data['results']Using the Python Turtle Module:
- Create Tim the Turtle:
tim = Turtle()
tim.shape('turtle')
tim.color('yellowgreen')- Create a screen:
screen = Screen()
screen.setup( WIDTH , HEIGHT )
screen.exitonclick()- Make him draw a square:
for _ in range(4):
    tim.forward( 100 )
    tim.right( 90 )- Make him draw a dashed line:
for _ in range(50):
    tim.fd( 10 )
    if tim.isdown() : tim.penup()
    else : tim.pendown()- Make him draw different shapes with random colors, one on top of the orher:
# triangle, square, pentagon, hexagon, heptagon, octagon, nonagon and decagon
for num in range( 3, MAX_SIDES + 1 ):
    tim.pencolor( tuple( random.choices(range(256), k=3) ) )
    for _ in range( num ):
        tim.fd( DEFAULT_SIDE_LENGTH )
        tim.rt( 360 / num )- Generate a random walk:
while True:
    r = random.randint(0, 250)
    g = random.randint(0, 250)
    b = 255
    tim.pencolor( r , g , b )
    tim.fd( 10 )
    tim.rt( random.choice([ 0, 90, 180, 270, 360 ]) )
- Make a Sphirograph:
for _ in range(100):
    
    r = random.randint(0, 250)
    g = random.randint(0, 250)
    b = 255
    tim.pencolor( r , g , b )
    tim.circle(LEN_CIRCLES)
    tim.rt( 360 / LEN_CIRCLES )Make a 'Hirst' Dot painting, getting the pallete from one of his paintings using colorgram.py.
Create a Etch-A-Sketch Game App.
| w | a | s | d | c | 
|---|---|---|---|---|
| forward | rotate left | backward | rotate right | clear screen | 
Make a turtle race, in which the user can bet with Turtle will win.
I created a list to save all the snake's body segments. Each segment is a different turtle placed so that it appears a snake.
START_BODY_LENGTH : int = 3
SEGMENT_SIZE      : int = 20
snake_body = []
for i in range( START_BODY_LENGTH ):
      segment = Turtle('square')
      segment.penup()
      segment.color('white')
      segment.setx( - SEGMENT_SIZE * i )
      snake_body.append(segment)For this part, I had to use s.tracer(0), which basically stops the screen from updating, so I can update it later manually, because if not, you would see each segment moving one by one, and the result wanted was to move all the body at once, so I wanted to update it the moment all the segments has already moved. To slow down the movement and make it playable, I used time.sleep(0.1).
s.tracer(0) 
game_is_on = True
while game_is_on:
    s.update()
    time.sleep(0.1)
    for num in range( len( snake_body ) - 1 , 0 , -1 ):
            x_cor = snake_body[ num - 1 ].xcor()
            y_cor = snake_body[ num - 1 ].ycor()
            snake_body[ num ].goto( x_cor , y_cor )
    snake_body[0].forward( SPEED )I then moved all this parts into another file with a Snake class in it, so it could manage everything the snake does and how it is created.
class Snake:
    snake_body = []
    def __init__( self ):
        self.create_snake()
        self.head = self.snake_body[0]
    def create_snake( self ):
        for i in range( START_BODY_LENGTH ):
            segment = Turtle('square')
            segment.penup()
            segment.color('white')
            segment.setx( - SEGMENT_SIZE * i )
            self.snake_body.append(segment)
    def move( self ):
        for num in range( len( self.snake_body ) - 1 , 0 , -1 ):
            x_cor = self.snake_body[ num - 1 ].xcor()
            y_cor = self.snake_body[ num - 1 ].ycor()
            self.snake_body[ num ].goto( x_cor , y_cor )
        self.head.forward( SPEED )Finally, I started managing the user input, for this, I used s.listen() to focus on the window, and s.onkey() to get the user's movement imput. 
s.listen()
s.onkey( snake.up    , 'Up'   )
s.onkey( snake.down  , 'Down' )
s.onkey( snake.left  , 'Left' )
s.onkey( snake.right , 'Right')Then, in the Snake class, I made four methods for each movement, having in mind that the snake could not completely change directions, just turn.
RIGHT = 0
UP    = 90
LEFT  = 180
DOWN  = 270
def up( self ):
    if self.head.heading() != DOWN:
        self.head.setheading( UP )
def down( self ):
    if self.head.heading() != UP:
        self.head.setheading( DOWN )
def left( self ):
    if self.head.heading() != RIGHT:
        self.head.setheading( LEFT )
def right( self ):
    if self.head.heading() != LEFT:
        self.head.setheading( RIGHT )def detect_food_collision( self ):
    # Detect collision with food
    if self.snake.head.distance( self.food ) < 15:
        self.food.refresh()
        self.snake.extend()
        self.scoreboard.increase_score()def detect_wall_collision( self ):
    # Detect collision with wall
    if self.snake.head.xcor() > 290 or self.snake.head.xcor() < -290 or self.snake.head.ycor() > 290 or self.snake.head.ycor() < -290:
        self.scoreboard.game_over()
        self.game_is_on = False
        self.game_over()def detect_self_collision( self ):
    # Detect collision with tail
    for segment in self.snake.snake_body[1:]:
        if self.snake.head.distance( segment ) < 5:
            self.scoreboard.game_over()
            self.game_is_on = False
            self.game_over()I also made a little menu, where you can either start the game or close it. You can also restart the game if you fail, and it keeps track of your best score in the game.
Make a Pong Game. This time, I couldn't bother to make a menu because I want to advance faster...
I might do this in the future, too many similar projects, and I want to advance.














































