Python 101
Table of content
- 1.0 - Installing Python
- 2.0 - Python
- 3.0 - Functions
- 4.0 - User inputs
- 5.0 - String operations
- 6.0 -
listandtuple - 7.0 - Dictionary
- 8.0 - Conditions using
if,elif, andelse - 9.0 -
whileandforloops - 10.0 - Error Handling
- 11.0 - File handling
- 12.0 - Modules and libraries
- 13.0 - X Comprehensions
- 14.0 - Lambda functions
- 15.0 - Decorators
- 16.0 - Classes
So, it seems that you want to learn Python? Alright.
This is a quick Python introduction where i’ll cover most basic thing from installation to how to program in Python.
1.0 - Installing Python #
Go to python.org then find any suitable recent version for your operating system. I use Ubuntu 22.04, and Python already installed with python 3.10 by default. But i use Python3.11
Now, after installing, let’s try how to use Python.
2.0 - Python #
Python is easy to learn. Now create a file named python_file.py
a = 50
We just created variable a with 50 as the value.
Now, we also need to know comments, what is it? It’s a way to tell programmers, and readers and also perhaps tools to understand what we’re doing.
# This is a comment, prefixed with a #.
# Comments will be ignored by the interpreter.
“Now, how do we print the variable?”
a = 50
print(a) # Output: 50
Just like calling a function in math, if you remember the f(x), it’s pretty much like that.
“How do we execute our code?”
python3 python_file.py
The output should be like the example
50
2.1 - Data Types #
There are many datatypes such as list, tuple, dict, set, str, int, float, bool, etc.
example_string = "Hello, World"
example_int = 50
example_float = 2.5
example_bool = True # a False can also be used
example_tuple = (1, 2)
example_list = [1, 2]
example_dict = {'a': 50},
example_set = {50}
In the next section, i’ll be explaining what’s tuple, list, dict, and set means.
2.2 - Advanced Data Types #
listis a data type to create collections of types mutably (you can change the content)tupleis as same withlisthowever it’s immutable which means you cannot edit it once you declare it.dictis a key-value pair, works like dictionary when you want to search specific word and its defininition.setis a mathematic set.stris a collection of characters just like"hello, world"intis a integer. A number without a.floatis a real number or in a sense, a decimal number.boolis boolean, a state of true and false, 1 and 0.
3.0 - Functions #
def add_numbers(x, y):
result = x + y
return result
# Calling the function
sum = add_numbers(3, 5)
print(sum)
That’s the thing, add_numbers is a procedure or a ‘recipe’ that requires arguments (or ingredients) x and y and voila, there’s the result. One more example of function is like a vending machine. It requires some money and your input to tell which item do you want. The machine will give you the item once the money and item has been declared (told or given).
Then, when you call the function (add_numbers) with 3 and 5, you get 8 as the output.
So, functions are like the building blocks of your code, making it easier to manage and reuse your code.
4.0 - User inputs #
Inputs are fun.
a = input("Tell me what's inside your mind: ")
print("You're thinking of", a)
Let’s run
python3 python_file.py
Tell me what's inside your mind: Nothing
You're thinking of Nothing
That should do the trick, isn’t it? Now you know what input means.
4.1 - Casting input from string to other data types. #
You can’t just immediately do input('number') - 2, this would crash. However, there’s a way to do it.
There’s a function or callable from the data type names such as list(), tuple(), set(), dict(), int(), str(), float(), etc.
And, when you see like name(), that means it’s callable or behave like functions.
And thus, when you do int(input('number: ')) - 2 will work, unless if you add non digit characters.
# Let's assume we have an input
a = "12a"
b = "12"
print(int(a) - 1) # Error
print(int(b) - 1) # 11
It’s pretty much clear, 'a' is not a digit thus cause the int(a) to crash.
5.0 - String operations #
String can be manipulated but it’ll be ‘cloned’, string is immutable but we can clone and edit. Confused?
a = "Hello, World!"
print(a.title()) # Output: Hello, World!
print(a.upper()) # Output: HELLO, WORLD!
print(a.lower()) # Output: hello, world!
There’s 3 things going on.
a.title(), .title() is a method of a string that create a new string from the base one to be titled.
From str.title:
str.title = title(self, /)
Return a version of the string where each word is titlecased. More specifically, words start with uppercased characters and all remaining cased characters have lower case.
The same goes with .upper and .lower, however .upper replaces all lowercase characters to be uppercased and vice versa.
5.1 - .split, .strip, .rstrip #
.split is a string method to split up string from a certain characters. Let’s look at this example:
a = "a,b,c,d" # Note that this is comma separated
# We can use a.split to split up the string
b = a.split(',')
print(b) # b is a list, so it returns: ['a', 'b', 'c', 'd']
Then, .strip and .rstrip is just stripping whitespaces or ' ', \t, \n, etc.
a = '\n \tHello, World!\n\t '
print(a.strip().rstrip()) # Output: Hello, World
If you try to remove .strip().rstrip() part, you will have different result.
5.2 - .find, .replace #
Splitting and stripping is fun, but .find and .replace are more fun.
a = "Hello, World!"
print(a.find('H')) # Output: 0
And the reason why the output is 0 is because of index. Index starts at 0.
H e l l o , W o r l d !
0 1 2 3 4 5 6 7 8 9 10 11 12
So then:
print(a[0]) # Output: H
In summary, .find finds index of a character of a string.
Let’s move on to .replace. .replace is a method to replace matching substring with other one.
a = "Hello, World!"
print(a.replace("World", "Python")) # Output: Hello, Python!
That’s it.
6.0 - list and tuple #
Just like at 2.2 number 1 and 2, list is a mutable collections while tuple is immutable collections.
This way, we can have read-write and read-only operations.
Both list and tuple works with index.
a = [1, 2, 3, 4, 5]
b = (1, 2, 3, 4, 5)
print(a[0], b[1]) # Output: 1 2
Pretty much self-explanatory.
We can also use some methods to do meaningfull stuff like sorting and reversing.
For sorting on list:
a = [5, 2, 3, 4, 1]
a.sort()
print(a)
For sorting on tuple:
b = (1, 2, 3, 4, 5)
print(sorted(b)) # However, sorted() returns list
We can also reverse using [::-1], it might be not self-explanatory but [::-1] is a slicing, i.e, a way to tell that we are slicing through. Slice has start, stop, and step argument. [::-1] means we set start to default, end to default, and step to be -1.
If step is a negative number, start and end is reversed.
a = [1, 2, 3, 4, 5]
sliced = slice(step=-1) # equivalent to [::-1]
print(a[::-1]) # [5, 4, 3, 2, 1]
print(a[sliced]) # [5, 4, 3, 2, 1]
There’s also a param reverse on .sort for list and reversed also available
a = [1, 2, 3, 4, 5]
b = [1, 2, 3, 4, 5]
a.sort(reverse=True)
print(a) # [5, 4, 3, 2, 1]
print(tuple(reversed(b))) # (5, 4, 3, 2, 1)
The reason we wrap reversed with tuple is to cast reversed instance to tuple since reversed returns type reversed.
7.0 - Dictionary #
dict is a key-value pair collection.
person = {
"name": "Agus Sandal",
"age": 17
}
The first element, has a key of "name", and its value is "Agus Sandal". The way we access it with the key.
person = {
"name": "Agus Sandal",
"age": 17
}
print(person['name']) # Agus Sandal
The same goes to "age". It’s also possible to use integer as a key, but in some cases, we should use list instead.
a = {
5: 'a'
}
print(a[5]) # a
8.0 - Conditions using if, elif, and else #
Using conditions like if, elif, and else make your program to be conditional. In a way.
if 5 == 5:
print("5 equals to 5")
else: # Only executed if above if-keyword and elif-keyword are not executed due to false condition
print("5 not equals to 5")
if 2 == 5:
print("2 equals to 5")
elif 2 == 2:
print("2 not equals to 5 and 2 equals to 2")
else:
print("2 is not equals to either 5 and 2.")
Yep, like that. There’s also and and or keyword, which are also conditional.
if 2 == 5 or 2 == 2:
print("Either 2 == 5, or 2 == 2")
or will return true if any of the 2 conditions returns True, in this case False, True. or will not work if the condition evaluated to False, False.
However, and denotes that the 2 conditions MUST be true.
if 2 == 2 and 5 == 5:
print("2 == 2 and 5 == 5")
If you want to negate the condition, use not. not denotes that the condition will be reversed, from True to False and False to True
if not 2 == 3:
print("2 is not equals to 3")
The example is equivalent to 2 != 3
9.0 - while and for loops #
Now, we’re heading to loops. We should learn 4 new keywords, while, for, break, and continue.
Let’s head into the code
condition = 5 == 5
while condition:
# If the conition is True, this block is executed
print("5 == 5")
break # This means, we are done with the loop.
The example is equalivent to:
condition = 5 == 5
if condition:
print("5 == 5")
Now that we’re talking, the loop like while will always execute until the condition is evaluated to False or until break statement is reached.
start = 0
while start <= 10: # Walk from 0 to 10.
print(start)
start += 1 # Increment so that the loop will eventually done
Just like that, and we must make sure that the while loop will eventually done or we will have a loop hell in which we have to kill the program to stop it. (Usually using Interrupt or Ctrl+C)
Now, continue is a signal that tells the loop to skip the block execution. This is useful if you want to skip on certain condition.
start = 0
while start <= 10:
if start == 5:
start += 1
continue
print(start)
start += 1
The continue on if start == 5 denotes that we are skipping if start is equals to 5, but before that we must increment it by 1 so that it doesn’t enter yet another loop hell where if start == 5 always execute since start doesn’t get changed. In other word, stuck at 5.
10.0 - Error Handling #
Ever found errors? we can opt-in to silent them and even raise them from being silenced.
Let’s use common errors on input
try:
print(int(input('number: ')))
except ValueError:
print("Value was not an integer.")
We just prevent error raised from int(). This is particularly useful if you don’t want user to pass in bad inputs. You can try to squeeze in all errors appropriately if you find one, but make sure you handle them correctly and accordingly, if you didn’t, you might found yet another hour of debugging.
Now, let us use raise to raise an error or re-raise an error.
raise Exception("Hello, World") # We compose an error from Exception then raise it
The code is intentionally gives us error, it’s the expected behavior because we intend so.
try:
1/0
except DivisionByZeroError as exc:
raise ValueError("How the 0 just pop?") from None
The code surpress DivisionByZeroError error and raise ValueError, the from None tells that it came from nothing or it doesn’t have any error origins. However, if we slightly change the last bit into: raise ValueError("How the 0 just pop?") from exc, the new error is now originated from DivisionByZeroError.
11.0 - File handling #
DO NOT USE BARE open() IF THE CODE CANNOT CERTAIN WHEN THE FILE IS CLOSED
How bold am I? Well, there’s a reason. Let’s now dive in before why i tell you about not using bare open()
We can read/write file, using open() however, if we didn’t close it, there might be some nasty stuff that can happen. This and this can answer the question.
How to open file:
with open("filename.txt", 'w') as file:
file.write("Hello, World!")
Here’s how it works: The with statement starts with open(...), and the file is assigned to the variable file using as. Importantly, the with block ensures that the file is automatically closed, even if an error occurs. This is achieved through the use of a context manager, which defines __enter__ and __exit__ methods. Learn more about context managers here.
After we write the file, here’s how we read the file:
with open("filename.txt") as file:
data = file.read()
print(data)
That’s it, pretty much straight forward and error-safe. Though, i don’t want to show the unsafe way.
12.0 - Modules and libraries #
There are stuff that people build, and you can use them without copy and pasting. This is called importing.
Let’s get started
import os
from os import name
from os import urandom as xrand
This example uses 3 different kind of importing. The first line imports a builtin module named os. The second line imports a variable name from module os. The third line is the same as second line but the variable urandom is renamed as xrand.
Now that’s how we import, but let’s get real.
Inside module.py:
def function():
pass # pass statement does nothing, it's a placeholder for a empty block
x = 50
Inside python_file.py:
import module as mod
from module import function
from module import x as z
print(mod.x) # Output: 50
print(z) # Output: 50
function()
mod.function()
Execute that.
13.0 - X Comprehensions #
The ‘X’ means anything, but in this context, it means list comprehensions, generator comprehensions, dictionary comprehensions, and set comprehensions.
a = [number for number in range(10) if number % 2 == 0]
Here, we’re creating a list a that contains even numbers from 0 to 9. It uses a special notation called a ‘list comprehension’ to do this efficiently. The number for number in range(10) part means we’re considering numbers from 0 to 9 one by one. if number % 2 == 0 checks if a number is even (divisible by 2), and if it is, it’s added to the list a.
You can also do something more with X comprehensions:
a = [(number,number+1) for number in range(10) if number % 2 == 0]
In the example, a is a list containing a tuple of even number then odd number. Let’s print the first elements
print(a[0]) # Output: (0, 1)
Like that.
From there, you can also use a dict comprehension to create a dictionary from for-loop.
numbers = {number: number % 2 for number in range(0, 10)}
We create a dict that has keys from 0 to 9 with the value is denoting whether they are True or False (in this case, even or odd)
We can use inline if-else to make it really shows even or odd.
numbers = {number: 'even' if number % 2 else 'odd' for number in range(0, 10)}
Voila! When we print numbers[0] it’ll print out 'even'.
The inline if-else has a syntax of: value-true if condition else value-false
14.0 - Lambda functions #
Sometimes, declaring function is too much, then we have anonymous function named lambda.
add_numbers = lambda a, b: a+b
sum = add_numbers(5, 3)
print(sum) # Output: 8
The example is the same as previous function example. This is extremely useful in case of using map, filter, and reduce.
Using map():
numbers = [1, 2, 3, 4, 5]
# Using map to double each number using lambda
doubled_numbers = list(map(lambda x: x * 2, numbers))
print(doubled_numbers) # Output: [2, 4, 6, 8, 10]
Using filter():
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Using filter to get even numbers using lambda
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers) # Output: [2, 4, 6, 8, 10]
Using reduce():
from functools import reduce
numbers = [1, 2, 3, 4, 5]
# Using reduce to find the product of all numbers using lambda
product = reduce(lambda x, y: x * y, numbers)
print(product) # Output: 120 (1 * 2 * 3 * 4 * 5)
15.0 - Decorators #
Decorators are extensions to callables. In a sense, wrapping a function within a function. This may modify what the function will behave.
# Define a decorator function
def my_decorator(func):
def wrapper():
print("Something is happening before the function is called.")
func() # Call the original function
print("Something is happening after the function is called.")
return wrapper
# Apply the decorator to a function
@my_decorator
def say_hello():
print("Hello!")
# Call the decorated function
say_hello()
In this example, we define a decorator function my_decorator, which takes a function func as an argument. Inside the my_decorator, there’s a nested function wrapper that adds behavior before and after calling the original function func. Finally, the decorator returns the wrapper function.
We then apply the my_decorator to the say_hello function using the @ symbol. When we call say_hello(), it actually calls the wrapper function, which adds the extra behavior defined in the decorator.
Output:
Something is happening before the function is called.
Hello!
Something is happening after the function is called.
16.0 - Classes #
Class or classes is a blueprint of creating a object. str() is actually a class str. the str() called str.__init__() in which a class constructor.
class Person:
def __init__(self, name, age): # Self is a our current object
self.name = name
self.age = age
# argument `self` is required on every method unless if you use
# @staticmethod decorator
def say(self):
print(f"Hello, my name is {self.name} and my age is {self.age}")
# We only pass 2 arguments. The argument `self` is automatically assigned.
agus = Person("Agus", 17)
bambang = Person("Bambang", 17)
agus.say()
bambang.say()
Output:
Hello, my name is Agus and my age is 17
Hello, my name is Bambang and my age is 17
Furthermore, it become more extremely complex.
And, here’s the Python documentation you need to learn.
Now, that covers of this long page of Python 101, covering 16 sections.