Python Crash Course
This crash course uses Python 3 because Python 2 has been dead since 2020. The difference between Python 3 and 2 syntax is slightly different, but I don't want to go into that here. This course allows you to learn Python without experience or to warm up your Python skills.
Just like Ruby, Python's syntax is also simple. Python inspired Ruby's syntax because Python is older than Ruby. But, Python is not dead yet. Python is a multipurpose programming language and has a large community. Python touches almost every aspect of software. It could be for the back end of the web with its famous framework, Django. It could be for the back end of desktop applications, video games, or the Internet of Things (IoT). The most popular Python use case today is Data Science. One more thing, Python is also popular in competitive programming.
Whatever game you want to play with Python, you need to master its syntax first, don't skip the basics.
Installation
pyenv
We need Python version management for local development because each project has its own version of Python. I recommend pyenv. You can follow the installation instructions there. I think the instruction is clear enough.
You can add the Python path to the system if you can't set the Python by command. Here is the location, ~/.pyenv/versions/x.x.x/bin
. ∼
is home. Replace x.x.x
with your installed Python version.
Pipenv
It is better to isolate the environment because each project has its versions of Python and packages. That is called a virtual environment. I recommend Pipenv. My reason is it works well with pyenv. You can open the website to look at other reasons why Pipenv and the installation instructions.
The pipenv
command is not found? You should add ∼/.local/bin
to your system path.
Variables
number = 9
decimal = 9.99
hello1 = "Hello!"
hello2 = 'Hello!'
is_active = false
not_is_active = !is_active
String
print("Hello {}!".format("John Doe")) # Hello John Doe!
print("Hello {name}!".format(name="John Doe")) # Hello John Doe!
print("Hello {name}!".format("John Doe")) # KeyError
print(1 + " + " + 1 + " = " + 2) # TypeError
print("1" + " + " + '1' + " = " + str(2)) # 1 + 1 = 2
print("Paragraph 1\nParagraph 2\nParagraph 3")
print('Paragraph 1\nParagraph 2\nParagraph 3')
print("Paragraph 1\\nParagraph 2\\nParagraph 3") # Paragraph 1\nParagraph 2\nParagraph 3
print("Paragraph 1\nParagraph 2\nParagraph 3') # SyntaxError
print("h" in "hello") # True
print('o' in 'HELLO') # False
hello = "hello"
for c in hello:
print(c)
for i in range(len(hello)):
print(hello[i])
+
is to concat strings. Types except a string need to be converted to a string withstr()
.\
is to espace characters. Put double\
(\\
) to print\
.- You can use
in
to check if a string is a substring, it will return a boolean, or to iterate over string values. String is similar to Array, or we could say that they are the same.
Operations
Arithmetic
print(1 + 1) # 2
print(2 - 1) # 1
print(2 / 1) # 1
print(2 * 2) # 4
print(2 ** 3) # 8
print(8 // 3) # 2
print(4 % 2) # 0
Bitwise
print(~7) # -8
print(5 & 3) # 1
print(5 | 3) # 7
print(5 ^ 3) # 6
print(4 >> 1) # 2
print(4 << 1) # 8
and / or
print(True and False) # False
print(True or False) # True
Control
if score >= 100:
print("Perfect!")
elif score >= 80:
print("Good!")
elif score >= 70:
print("Okay.")
else:
print("Sad...")
print("Passed" if score >= 70 else "Not qualified!")
if score >= 70: print("Congratulations!")
Match
match score:
case "A":
print("Very good!")
case "B":
print("Good!")
case default:
print("Not qualified!")
There is a match
syntax in Python 3 (>= 3.10). It is just like the switch
in other programming languages. Before 3.10, people prefer to use a dictionary to do the trick.
Try and Except
try:
print(1 / 0)
except:
print("sorry, there is an error")
We can use try
and except
to handle errors or exceptions. It is like Try and Catch in other programming languages like Java and PHP.
try:
print(1 / 1)
except ZeroDivisionError as e:
print("cannot be divided by zero")
print(e)
except (NameError, ValueError):
print("did you miss something?")
except:
print("sorry, there is an error")
else:
print("yes, no error!")
finally:
print("ah, finally...")
- The
except
can handle multiple errors and store the error message in a variable. - The
else
will be executed if there is no error. - The
finally
always will be executed at the end.
Looping
for i in range(1, 4):
print(i) # 123
for i in [1, 2, 3]:
print(i) # 123
i = 1
while i < 4:
print(i) # 123
i += 1
i = 1
while True:
if i > 3:
break
print(i) # 123
i += 1
for i in range(1, 9):
if i % 2 == 1:
continue
print(i)
List
numbers = [1, 2, 3, 4, 5]
unrestricted = [1, 2.3, True, "Hello", 'World!']
numbers.append(6)
unrestricted += [6]
print(numbers[-1])
print(unrestricted[-3:-1])
- The
append
is to append an element to the list. There are a lot of other methods of List such asinsert()
,pop()
,remove()
,count()
, etc. You could try them by yourself. - The
+
operator can combine lists too. - In Python, we can index by negative numbers. It starts from the right.
Sorting
numbers = [3, 4, 1, 5, 2]
numbers.sort() # [1, 2, 3, 4, 5]
numbers.sort(reverse=True) # [5, 4, 3, 2, 1]
Dictionary
map = {
"a": 1,
"b": 2,
"c": 3
}
set = {
1: True,
2: False,
3: True
}
print(map["a"]) # 1
print(set.get(1)) # True
print(set.pop(2)) # False
print(set) # {1: True, 3: True}
print(map.keys()) # dict_keys(['a', 'b', 'c'])
print(map.values()) # dict_values([1, 2, 3])
print(map.items()) # dict_items([('a', 1), ('b', 2), ('c', 3)])
map.update(set)
print(map) # {'a': 1, 'b': 2, 'c': 3, 1: True, 3: True}
- We can access the value of the dictionary by using
[]
orget()
. - In
items()
, you can see that it returned the list of tuples. Tuple is a mutable list. - To combine dictionaries, use
update()
.
Method
def power(number, value):
return number ** value
print(power(2, 3)) # 8
print(power(value=3, number=2)) # 8
Arguments
def sum(*args):
result = 0
for number in args:
result += number
return result
def my_print(**kwargs):
print(kwargs)
print(sum(1, 2, 3)) # 6
my_print(a=1, b=2, c=3) # {'a': 1, 'b': 2, 'c': 3}
With an asterisk (*
), we can pass several arguments. An asterisk (*
) will make a list. Double asterisks (**
) will make a dictionary.
Lambda
power = lambda number, value : number ** value
print(power(2, 3)) # 8
Hm, Lambda is about a function in one line.
Built-Ins
There are built-in methods in Python, such as len()
to get the length of the list, zip()
to combine lists and make them an object, etc. Ever wonder how to get available built-in methods in Python? print(dir(__builtins__))
to get them. Here is the result of Python 3.12.4. It showed all of the error types too.
['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BaseExceptionGroup', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EncodingWarning', 'EnvironmentError', 'Exception', 'ExceptionGroup', 'False', 'FileExistsError', 'FileNotFoundError', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError', 'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'ModuleNotFoundError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError', 'RecursionError', 'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning', 'StopAsyncIteration', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError', '__build_class__', '__debug__', '__doc__', '__import__', '__loader__', '__name__', '__package__', '__spec__', 'abs', 'aiter', 'all', 'anext', 'any', 'ascii', 'bin', 'bool', 'breakpoint', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']
Special Methods
class Number:
def __init__(self, value):
self.value = value
def __repr__(self):
return str(self.value)
def __add__(self, value):
self.value += value
def __sub__(self, value):
self.value -= value
def __mul__(self, value):
self.value *= value
def __truediv__(self, value):
self.value /= value
number = Number(9)
number + 1
number - 2
number * 3
number / 4
print(number)
There are built-in methods with double underscores (double at the start and double at the end) in Python. From the example above, we can see that the representation of __add__
is +
, __sub__
is -
, __mul__
is *
, and __truediv__
is /
. You can visit https://docs.python.org/3/reference/datamodel.html#special-method-names to list all available special methods, especially in Python 3.
Strict
class Number:
def __init__(self, value: int):
self.value = value
def __repr__(self) -> str:
return str(self.value)
def __add__(self, value: int):
self.value += value
def __sub__(self, value: int):
self.value -= value
def __mul__(self, value: int):
self.value *= value
def __truediv__(self, value: int):
self.value /= value
number = Number(9)
number + 1
number - 2
number * 3
number / 4
print(number)
We can be strict in Python 3. We can set the data types on arguments and returns, but they are optional, just like PHP 8 and TypeScript. You can visit https://docs.python.org/3/library/stdtypes.html to list all available data types.
unittest
import unittest
import number
class TestNumber(unittest.TestCase):
def test_repr(self):
num = number.Number(9)
self.assertEqual(repr(num), "9")
def test_add(self):
num = number.Number(9)
num + 1
self.assertEqual(repr(num), "10")
def test_sub(self):
num = number.Number(9)
num - 1
self.assertEqual(repr(num), "8")
def test_mul(self):
num = number.Number(9)
num * 3
self.assertEqual(repr(num), "27")
def test_truediv(self):
num = number.Number(9)
num / 3
self.assertEqual(repr(num), "3.0")
unittest.main()
Let's write a unit test for the example above. You can save the script from the example above as number.py
and this unit test script as number_test.py
, then run python number_test.py
to execute it.
- We imported
unittest
, the unit test library, andnumber
, the module or class we wanted to test. - All test steps are methods that start with
test_
. - What results did you want to assert?
- Execute the test classes by using
unittest.main()
.
You can visit https://docs.python.org/3/library/unittest.html for more details.
Object-Oriented Programming
from abc import ABC, abstractmethod
class Animal(ABC):
def __init__(self, name, feets, has_paws):
self._name = name
self._feets = feets
self._has_paws = has_paws
@property
def name(self):
return self._name
@name.setter
def name(self, name):
self._name = name
@name.deleter
def name(self):
del self._name
@property
def feets(self):
return self._feets
@feets.setter
def feets(self, feets):
self._feets = feets
@feets.deleter
def feets(self):
del self._feets
@property
def has_paws(self):
return self._has_paws
@has_paws.setter
def has_paws(self, has_paws):
self._has_paws = has_paws
@has_paws.deleter
def has_paws(self):
del self._has_paws
@abstractmethod
def print(self):
print("{} has {} feets".format(self._name, self._feets))
if self._has_paws:
print("{} has paws.".format(self._name))
class Monster(Animal):
def __init__(self, name, feets, has_paws, abilities):
super().__init__(name, feets, has_paws)
self._abilities = abilities
def print(self):
print("{} is a monster!!!".format(self._name))
print("{} has:".format(self._name))
for ability in self._abilities:
print("- {}".format(ability))
monster = Monster("Dragon", 4, True, ["Nuclear blast", "Ice smoke"])
monster.print()
ABC
is an Abstract Base Class. It is a way to create an interface in Python. As we can see, the@abstractmethod
is on theprint()
method. That means the children ofAnimal
should define theprint()
method.- The
__init__
is to define the constructor. - There are 3 access modifiers in Python; default/public, protected, and private. Protected starts with an underscore (
_
). Private starts with double underscores (__
). - The
@property
decorator is the best way to define getter, setter, and deleter. So, we don't need to call the methods, but they become a property. Eg;print(monster.name); monster.name = "..."; del monster.name
Multiple Inheritance
...
class Legend:
def __init__(self, story):
self.__story = story
def tale(self):
print("Here is the story...")
print(self.__story)
class Monster(Animal, Legend):
def __init__(self, name, feets, has_paws, abilities, story):
super().__init__(name, feets, has_paws)
Legend.__init__(self, story)
self._abilities = abilities
def print(self):
print("{} is a monster!!!".format(self._name))
print("{} has:".format(self._name))
for ability in self._abilities:
print("- {}".format(ability))
monster = Monster("Dragon", 4, True, ["Nuclear blast", "Ice smoke"], "One day...")
monster.print()
monster.tale()
Python supports multiple inheritance. That means one class can have multiple parents. As we can see in the example above, the first parent of Monster
is Animal
, that's why super()
is for Animal
. To call other parents, we need to call their class names instead of super()
.
Related Articles
- Ruby Crash Course
- Object-Oriented Programming in C++
- Python for Data Science and Machine Learning Bootcamp
- PyTorch Scholarship Challenge from Facebook
- C/C++ Crash Course