Introduction to Python
Python is a high-level interpreted programming language focused on general-purpose programming and code readability. It is also known for having the most simplistic Hello, world! program.
print("Hello, world!")
We recommend following the official Python documentation to learn more about the language. This manual serves as a guide to the most relevant concepts needed to work on the assignments. We expect you to be able to put together programming knowledge gained from other languages and the provided resources to fully master Python.
Being an interpreted language, Python deals with blocks of code through indentation. Therefore, the interpreter is very picky about code style. Each new instruction must be indented perfectly with the others. Different levels of indentation may affect control flow. We recommend using a code formatter, usually provided with most code editors to regularly format your files.
Variables
Python is dynamically type-checked, which means that variables don't need to obey a fixed type. This paradigm gives the language a lot of flexibility but could come at the cost of complexity and difficulty in debugging.
# An example of a variable changing type in the same runtime context
my_var = "hello"
print(type(my_var)) # output: <class 'str'>
my_var = 10
print(type(my_var)) # output: <class 'int'>
To avoid this complexity, especially in debugging, Python provides a type hint feature, allowing us to specify the type of each variable. Type hints won't prevent the code above from being executed but will generate warnings inside your code editor, letting you know that something went wrong. We want to avoid situations in which variables change types in most cases, proving type hints to be extremely useful. Another benefit of this feature is intellisense: by providing the variable type, the code editor will be able to complete your instructions.
my_var: str = "hello"
print(type(my_var)) # output: <class 'str'>
# Warning: Type "Literal[10]" is not assignable to declared type "str"
my_var = 10
# No warning, works fine
my_var = "world"
Control flow
By design, Python does not have an entry point to execution via a main
function like other programming languages. You can start writing instructions from the first line, and the interpreter will execute them one by one. However, we still find value in following the main
function pattern to starting execution.
def main() -> None:
print("Hello, world!")
if __name__ == "__main__":
main()
We will expand upon the meaning of if __name__ == "__main__"
in the Modules section. For now, you may take this syntax for granted in writing your programs. The def main() -> None:
represents the main
function's signature; it takes no parameters and returns None
(i.e., nothing, void).
Branches are handled in Python as expected using if
statements. However, we do not need parentheses around any control flow statements, and the logical operators &&
, ||
, !
are replaced by and
, or
, not
respectively.
some_var: str = "hi"
is_cool: bool = False
my_number: float = 3.14
if some_var == "hi" or my_number != 2.71 and not is_cool:
print("python conditions")
Similarly, loops can be created using the while
and for
keywords. However, for
loops slightly differ in syntax from other languages by requiring an iterator for execution. The most basic iterator is a range
iterator.
for i in range(10):
print(i)
Functions
Defining functions is easily done with the def
keyword. Functions may take any number of parameters and return exactly one value.
# Example function definition. Make sure to include types in your function signature.
def sum(first: int, second: int) -> int:
return first + second
Functions may raise exceptions for control flow, terminating execution and returning to the caller. This behavior is particularly useful for handling edge cases. We can check if a function encountered an error using a try
... except
block.
The Python standard library is notorious for handling control flow based on exceptions. Always make sure to read the documentation of the function you are using and handle the exceptions accordingly.
def divide(first: int, second: int) -> float:
if second == 0:
raise ValueError("Can't divide by zero")
return first / second
try:
divide(1, 0)
except ValueError as e:
print("An error occurred:", e)
Documentation is usually provided in the form of docstrings. It is recommended to document most of your function behavior, usage, exceptions, and parameters in the docstring rather than using comments.
# Docstring example. Code editors can parse docstrings into
# nicely formatted documentation.
def multiply(first: int, second: int) -> int:
"""
Multiply two numbers
:param first: The first number
:param second: The second number
:return: The result of the multiplication
"""
return first * second
Last updated