- Printing outputs
- Input Function
- Variables
- Dat Types
- Subscripting
- Integer (Whole Number)
- Float = Floating point number
- Boolean
- Type Conversion Functions (Type casting)
- Modulo Operator (
%) - Condituinal Statement (
if / else) - Nested
if / else if / elif/ else- Multiple if
- Logocal Operators
- Random Module
- Lists
- Tuple :
- constant :
- For Loop
- Function
- While Loop
- Slicing:
returnkeyword :- Debugging
if __name__ == '__main__'asyncandawait- The
splatorunpackingoperator (*): - Ternary Operator
print("Hello World!")Instead of writing multiple lines like
print("Hello World!")
print("Hello World!")
print("Hello World!")We could write
print("Hello World! \nHello World! \nHello World")
# Hello World
# Hello World
# Hello World# Hello Naz
# We could add an empty strng in between the words :
print("Hello" + " " + "Naz")
# or
print("Hello " + "Naz")
# Hello Naz
# or
print("Hello" + " Naz")
# Hello Nazinput("A prompt for the user")Example:
input("What is your name?")print("Hello " + input("What is your name?") + "!")Variable is somtheing that can be changed or varied.
name = input("What is your name?")
print(name)- String
- Integer
- Float
- Boolean
Pulling out a particular element from a string and the number between square brackets determines which character you're going to pull out
print("Hello"[0])
# H- Tip :
We can use
-and get the last character
print("Hello"[-1])
# oprint(123 + 456)
# 468For writing big numbers like 123,456,786 we use _ instead of ,
print(123_456_789)
# 123456789print(3.14159)
# 3.14159print(True)
print(False)int() Converts a value to an integer. If the input is a float, it truncates the decimal part (rounds towards zero). If the input is a string, it must represent a whole number.
print(int(55.222))
#55
print(int(55.9222))
#55float() Converts a value to a floating-point number. If the input is an integer, it adds a decimal part (e.g., 5 becomes 5.0). If the input is a string, it must represent a valid number (integer or decimal).
print(float(55.222))
# 55.222
print(float(55.9222))
# 55.9222round() is used to round a number to the nearest integer or to a specified number of decimal places.
print(round(55.222))
#55
print(round(55.9222))
#56It lets you add a second argument to specify how many decimal places to show for rounding is:
round(number, ndigits)
print(round(55.2255452 , 2))
# 55.23
print(round(55.9222 , 1))
# 56.9Simple Example: Cookies and Bags
Let's say you have 10 cookies and each bag holds 3 cookies.
You fill the first bag: You use 3 cookies. You have 7 left.
You fill the second bag: You use another 3 cookies. You have 4 left.
You fill the third bag: You use another 3 cookies. You have 1 left.
Can you fill another bag? No, because you only have 1 cookie left, and a bag needs 3.
So, the number of cookies left over is 1.
In Python, this would be:
10 % 3 which equals 1.
print(10 % 3) # Output: 1 (10 divided by 3 is 3 with a remainder of 1)
# 3 * 3 = 9 and 10 - 9 = 1
print(15 % 4) # Output: 3 (15 divided by 4 is 3 with a remainder of 3)
# 4 * 3 = 12 and 15 - 12 = 3
print(7 % 2) # Output: 1 (7 divided by 2 is 3 with a remainder of 1 - useful for checking odd/even)
# 2 * 3 = 6 and 7 - 6 = 1
print(20 % 5) # Output: 0 (20 divided by 5 is 4 with a remainder of 0)
# 5 * 4 = 0 and there is no remaining
print(5 % 20) # Output: 5 (5 divided by 20 is 0 with a remainder of 5)if condition:
do this
else:
do thisheight = int(input("How tall are you?\n"))
if height >= 120:
print("You can enter to ride the rollecoaster")
else:
print("sorry, you are short")Tip
= is for assignment
== is for checking equality
if condition:
if another condition:
do this
else:
do this
else:
do thisheight = int(input("How tall are you?"))
if height >= 120:
print("You can ride")
age = int(input("How old are you?"))
if age >= 18:
print("you have to pay 12$")
else:
print("you have to pay 7$")
else:
print("Sorry you are short")if condition1:
do A
elif conditio2:
do B
else:
do Thisheight = int(input("How tall are you?"))
# Prompt the user for their height and convert the input string to an integer.
# This variable will be used to determine initial ride eligibility.
height = int(input("How tall are you?\n")) # Added \n for better prompt display
# Check if the person meets the minimum height requirement for the ride.
if height >= 120:
# If tall enough, inform the user they can ride and proceed to age-based pricing.
print("You can ride")
# Prompt the user for their age and convert the input string to an integer.
# This variable will determine the specific ticket price.
age = int(input("How old are you?\n")) # Added \n for better prompt display
# Determine the ticket price based on age, using a clear tiered system.
# If age is 12 or younger, apply the child price.
if age <= 12:
print("You have to pay 5$")
# If age is 18 or older, apply the adult price.
# This 'elif' ensures that ages 13-17 are correctly skipped for this condition.
elif age >= 18:
print("You have to pay 12$")
# If none of the above conditions are met (i.e., age is between 13 and 17, inclusive),
# apply the 'teen' or 'standard' price.
else: # This implicitly covers ages > 12 and < 18 (i.e., 13, 14, 15, 16, 17)
print("You have to pay 7$")
# If the person does not meet the minimum height requirement,
# inform them they cannot ride.
else:
print("Sorry you are too short") if condition1:
do A
if condition2:
do B
if condition3:
do CA and B
# of both condictions are true = True
#if just one of them is true = False
C ord D
# if only either of them is true = True
# False or False = False
not EWhat is `module?
A module in Python is a very specific, low-level concept: it's literally a single .py file that contains Python code (functions, classes, variables). It's the most basic unit of code organization and reuse in Python.
The first thing that we need to do is to add import random.
link
random_number = random.randint(1, 99)
# random numbes between 1-99random_number_0_to_1 = random.random()
print(random_number_0_to_1)
# Generates a random number between 0-1variable = [item1, item2, item3]fruits = ["apple", "orange", "strawberry", "cherry"]
print(fruits[0])
# apple
print(fruits[-1])
# Gets the last one
# cherryHow to change a variable?
fruits = ["apple", "orange", "strawberry", "cherry"]
fruits[1] = "banana"
print(fruits)
# ['apple', 'banana', 'strawberry', 'cherry']How to add a new variable? (append() function)
fruits = ["apple", "orange", "strawberry", "cherry"]
fruits.append("banana")
print(fruits)
# ['apple', 'orange', 'strawberry', 'cherry', 'banana']How to add a list? (extend() function)
fruits = ["apple", "orange", "strawberry", "cherry"]
fruits.extend(["banana", "melon", "lemon"])
print(fruits)
# ['apple', 'orange', 'strawberry', 'cherry', 'banana', 'melon', 'lemon']Tuple is similar to a list
Tuple:
(1, 2, 3)
Lits:
[1, 2, 3]
The difference between a tuple and a list is that you can't change the value in a tuple like you can in a list.
You can't change the values in any way in a tuple. It is immutable.
Convertin a tuple into a list:
my_tuple = (1, 2, 3)
list(my_tuple)
#[1, 2, 3]In Python, the naming convention of using all capital letters (e.g., STARTING_POSITION, PI, MAX_SPEED) is a way for programmers to signal that a variable should be treated as a constant. However, unlike in some other programming languages, Python does not enforce this. You can technically change the value of STARTING_POSITION later in your code.
The main purpose of this naming convention is to improve code readability and inform other programmers that they should not modify the value. It's a way of saying, "Hey, this value is meant to stay the same throughout the program's execution, so please don't change it!"
for item in list_of_items:
# Do spmething to each itemExample:
fruits = ["apple", "strawberry", "melon"]
for fruit in fruits:
print(fruit)
# apple
# strawberry
# melon def name(args):
passExample :
def my_function():
print("Hello")
print("Bye")
my_function()
# Hello
# Byedef add(*args):
for n in args:
print(n)def add(*args):
sum = 0
for n in args:
sum += n
return sum
print(add(5, 4, 3, 2, 8, 1, 11))
# 34def display_name(*args):
for arg in args:
print(arg, end=" ")
display_name("Naz", "Ash", "III")
# Naz Ash IIIdef calculate(**kwargs):
print(type(kwargs))
calculate(add=3, multiply=6)
# <class 'dict'>def calculate(**kwargs):
for key, value in kwargs.items():
print(key, value)
calculate(add=3, multiply=6)
# add 3
# multiply 6def address(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
address(
street="123 Fake St.", pobox="P.O Box 777", city="Detroit", state="MI", zip="54321"
)
# street: 123 Fake St.
# pobox: P.O Box 777
# city: Detroit
# state: MI
# zip: 54321def address(*args, **kwargs):
for arg in args:
print(arg, end=" ")
print()
for key, value in kwargs.items():
print(f"{key}: {value}")
address(
"Naz",
"Ashrafi",
street="123 Fake St.",
pobox="P.O Box 777",
city="Detroit",
state="MI",
zip="54321",
)
# Naz Ashrafi
# street: 123 Fake St.
# pobox: P.O Box 777
# city: Detroit
# state: MI
# zip: 54321def calculate(**kwargs):
print(kwargs["add"])
print(kwargs["multiply"])
calculate(add=3, multiply=6)
# 3
# 6def calculate(n, **kwargs):
n += kwargs["add"]
n *= kwargs["multiply"]
print(n)
calculate(2, add=3, multiply=6)
# 30def address(*args, **kwargs):
for arg in args:
print(arg, end=" ")
print()
print(f"{kwargs.get("street")}")
print(f"{kwargs.get("city")}, {kwargs.get("state")}, {kwargs.get("zip")}")
address(
"Naz",
"Ashrafi",
street="123 Fake St.",
city="Detroit",
state="MI",
zip="54321",
)
# Naz Ashrafi
# 123 Fake St.
# Detroit, MI, 54321NOTE:
If we do this:
def address(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")It will get all of the arguments in kwargs but if we want to call some specific kwargs we use the get() method.
print(f"{kwargs.get("street")}")while something_is_true:
# Do something
# The loop will stop hen something becomes falseIt is designed to build a brand new list.
for loop
numbers = [1, 2, 3]
new_list = []
for n in numbers:
add_1 = n + 1
new_list.append(add_1)List comprehension
new_list = [new_item for item in list]numbers = [1, 2, 3]
new_list = [n + 1 for n in numbers]
# list ==> numbers
# item ==> n
# new_item ==> n + 1new_list = [number * 2 for number in range(1, 5)]new_list = [new_item for item in list if test]names = ["Max", "Ashley", "lexa", "Alex", "Roxy", "Alison"]
new_list = [name for name in names if name[0] == "A"]
print(new_list)
# ['Ashley', 'Alex', 'Alison']new_dict = {new_key:new_value for item in list}
new_dict = {new_key:new_value for (key, value) in dict.items()}
new_dict = {new_key:new_value for (key, value) in dict.items() if test}students = ["Alex", "Max", "Ashley", "Rachel", "Chad"]
scores = {name: random.randint(1, 100) for name in students}
print(scores)
# {'Alex': 85, 'Max': 44, 'Ashley': 88, 'Rachel': 11, 'Chad': 11}students = ["Alex", "Max", "Ashley", "Rachel", "Chad"]
scores = {
name: random.randint(1, 100) for name in students if random.randint(1, 100) > 80
}
print(scores)
passed_students = {name: score for (name, score) in scores.items() if score >= 60}
print(passed_students)
# {'Max': 39, 'Ashley': 25, 'Rachel': 18, 'Chad': 88}
# {'Chad': 88}In Python, if a function doesn't have a return statement, or if the return statement is reached without an explicit value (like just return), the function implicitly returns None.
Coding partner Imagine you send your robot helper 🤖 to go do a job.
If you tell the robot to "Go clean your room!" and it just does it, but you don't tell it to report anything back to you, the robot will just finish the job and then stand there quietly. That's like the function implicitly returning None. It did its job, but didn't give you a message or a toy back.
Now, if you tell the robot, "Go get me a snack!" and it comes back holding a cookie 🍪, that's like the function explicitly returning a value (the cookie).
So, if your function doesn't specifically give you something back with a return command, Python just assumes it gave you nothing important, which it calls None.
- The return statement's job in a function is precisely like reporting back and bringing you a value.
Think of it this way:
When you call a function, you're asking it to perform a task.
Once it's done with that task, the return statement is how the function gives you the result of its work, or simply a confirmation that it finished.
Without return, the function might do its job internally (like printing something), but it doesn't hand anything back to the part of the code that called it. If it doesn't explicitly hand anything back, Python automatically hands back None, which means "nothing special."
That's the primary purpose of return in a function: it fetches the value computed or determined within the function so you can use that value in the code that called the function.
It's like a messenger delivering a specific piece of information from the function's internal work back to the main operation.
when we dont use return in a function, we cant just call the function and expect to get an output but when we use return and if we call the fucntion, we'll get an output, right?
Here's a slightly more precise way to put it:
-
When a function does NOT use
return(orreturnis used without an argument):-
You can call the function to make it perform actions (like changing variables, printing things to the console, writing to files, etc.).
-
However, if you try to use the result of calling that function (e.g., assign it to a variable, or print it directly in an f-string like
print(f"Result: {my_function()}")), the result will be the special valueNone. This is Python's way of saying "this function completed its operations, but it didn't explicitly hand back any data."
-
-
When a function uses return with an argument (e.g.,
return 10,return"hello",return my_list):-
You can call the function to make it perform actions.
-
Crucially, the function will stop executing at the
returnstatement and will hand back the specific value you put afterreturn. -
You can then capture or use this returned value (e.g.,
result = my_function(), orprint(my_function())).
-
Analogy Recap:
-
No return: You tell a worker (function) to "Clean the car." They clean the car (perform actions), but they don't give you anything back. If you ask "What did you give me?", the answer is "Nothing" (Python's None).
-
With return: You tell a worker (function) to "Go fetch the keys." They go get the keys (perform actions) and then they hand you the keys (return keys). Now you have the keys to use.
Q: So one of the use case for function is to make some variable local and make them stop being global?
A: Yes, that's absolutely one of the core use cases and benefits of functions! 🎉
A primary reason to use a function is to create a local scope, which in turn allows you to define local variables* that are confined to that function. This prevents them from cluttering the global namespace and avoids potential naming conflicts with other parts of your code.
Think of it like this:
-
Without functions (all global): Every tool you use in your workshop is just sitting out on one big workbench. If you have two different projects, and both need a "hammer," it can get messy and confusing which "hammer" belongs to which project.
-
With functions (local scope): Each project gets its own designated toolbox. When you work on "Project A," you open its toolbox, and any "hammer" inside that box belongs only to Project A. Once you close Project A's toolbox, those specific tools are put away. This means "Project B" can also have its own "hammer" in its own toolbox, and they won't conflict.
So, by using functions, you effectively encapsulate variables. They only exist and are accessible while the function is running, and then they're cleaned up. This makes your code much cleaner, more organized, and less prone to unexpected bugs from variables accidentally interfering with each other.
- Describe the problem.
- Reproduce the bug:
It simply means make the problem happen again on purpose.
Imagine your game crashed. To fix it, you need to figure out exactly what you did before it crashed so you can make it crash again. Once you can make it crash every time, you can then try to find out why it's crashing. - Play computer
- Fix the errors (red underlines)
- Use
print() - Use a debugger :
pythontutor.
Thonny app.
async is short for asynchronous. It tells Python that a function can be run alongside other code, instead of having to wait for it to finish.
Imagine you're at a coffee shop. When you place your order, you don't just stand there staring at the barista until your coffee is done, right? You might go find a table, check your phone, or chat with a friend. async is like that. It lets your program place a "request" (like an API call that takes time) and then move on to do other things while it waits for the result. When the result is ready, the program comes back and continues from where it left off. This makes your program much more efficient. The await keyword is used to tell the program to wait for the result of an asynchronous task before moving on.
You can think of the async function as politely stepping aside to let other functions run, and then it picks up where it left off once the task it was waiting for is complete. This is the core of what makes your code efficient and responsive.
async and await work together. You can't use one without the other.
Think of it like this:
asyncis the label you put on a function to tell Python, "This function might have a part that needs to wait for something. It can step aside to let other code run while it waits."awaitis the specific instruction inside anasyncfunction that tells the program, "Okay, pause right here and wait for this one thing to finish. While you're waiting, go do something else."
You must define a function as async to be able to use the await keyword inside it. If you try to use `await in a regular function, you'll get an error. They are a team!
Let's say you have list of tuples and want to create a random shape size for turtle module:
SHAPE_SIZE = [(1,4),(1,5),(1,6)]
random_size = random.choice(SHAPE_SIZE)You can't just use the random_size for shapesize() because it accept a tuple.
self.shapesize(random_size)So we need to use the * (splat) operator.
self.shapesize(*random_size)
The asterisk * operator is the key to solving this. When you place a * in front of an iterable (like your random_size tuple), it unpacks the elements of that iterable and passes them to the function as separate, individual arguments.
By adding the * before random_size, you're telling Python to take the chosen tuple (e.g., (1, 4)) and pass its elements as shapesize(1, 4). This is what the shapesize() method expects and will allow your code to work correctly.
Ternary Syntax
The general format is:
value_if_true if condition else value_if_falseExample:
if self.ycor() > FINISH_LINE_Y:
return True
else:
return False # Ternary Form
return True if self.ycor() > FINISH_LINE_Y else False
# a simpler and more Pythonic way
return self.ycor() > FINISH_LINE_Y