Skip to content

Commit d907341

Browse files
committed
Various Python notes and code snippets for the PCPP1 exam
1 parent 4e37a4b commit d907341

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+1951
-28
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ cython_debug/
165165
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
166166
# and can be added to the global gitignore or merged into this file. For a more nuclear
167167
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
168-
#.idea/
168+
.idea/
169169

170170
# PyPI configuration file
171171
.pypirc

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# PCPP1™ – Certified Professional Python Programmer Level 1
1+
# PCPP1™ – Certified Professional Python Programmer
22
(Exam [PCPP-32-10x](https://pythoninstitute.org/pcpp1-exam-syllabus))
33

44
![PCPP1-Badge](https://images.credly.com/images/37e26478-d80c-43e8-80eb-ec492f3a26c1/image.png)

advanced-oop.md

Lines changed: 413 additions & 11 deletions
Large diffs are not rendered by default.

coding-conventions.md

Lines changed: 110 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,59 @@
11
## Coding Conventions, Best Practices, and Standardisation
22
[PEP-8 naming conventions](https://peps.python.org/pep-0008/#naming-conventions)
3+
4+
PEP-8 guidelines are a set of rules for formatting Python code to enhance readability and maintainability.
5+
6+
:wink: If you are starting a new project, it is recommended to use [PEP-8](https://peps.python.org/pep-0008/) as a guide for writing Python code.
7+
38
* :x: Avoid using lowercase `l`, uppercase `O`, and uppercase `I` as variable names, since they can be confused with the digits `1` and `0`.
4-
* Modules - Modules should have short, all-lowercase names. Underscores can be used in the module name if it improves readability.
9+
* Modules - Modules should have short, all-lowercase names. Underscores can be used in the module name if it improves readability, e.g. `cron_locker`
510
* Packages - Package names should also have short all-lowercase, although underscores are discouraged.
611
* Classes - Class names should normally use the CapWords convention, e.g. `UserMetadata`
7-
* Exceptions - exceptions should be classes, so should follow the class naming convention. Use the `Error` suffix on exception names.
12+
* Exceptions - exceptions should be classes, so should follow the class naming convention. Use the `Error` suffix on exception names, e.g. `UserNotFoundError`, `InvalidInputError`.
813
* Functions - Function names should be lowercase, with words separated by underscores as necessary to improve readability.
914
* Variables - Variable names follow the same convention as function names.
1015
* Function and Method arguments - Always use `self` for the first argument to instance methods and `cls` for the first argument to class methods.
1116
* Constants - Constants are usually defined on a module level and written in all capital letters with underscores separating words, e.g. `BUCKET_NAME` and `THRESHOLD`.
1217

18+
Avoid extraneous whitespace in the following situations:
19+
* Immediately inside parentheses, brackets, or braces.
20+
```python
21+
# No extra spaces
22+
letsgo(info[1], {level: 2})
23+
# Extra spaces
24+
letsgo( info[ 1 ], { level: 2 } )
25+
```
26+
* Immediately before the open parenthesis that starts and indexing or slicing.
27+
```python
28+
# No extra spaces
29+
developer = {'name': 'crmpicco', 'language': 'Python'}
30+
info = developer['name']
31+
# Extra spaces
32+
info = developer[ 'name' ]
33+
```
34+
* More than one space around an assignment (or other) operator to align it with another.
35+
```python
36+
# No extra spaces
37+
aws = 1
38+
gcp = 2
39+
microsoft_azure = 3
40+
# Extra spaces
41+
aws = 1
42+
gcp = 2
43+
microsoft_azure = 3
44+
```
45+
1346
### Maximum Line Length
1447
* :seven::two: characters for docstrings and comments
1548
* :seven::nine: characters for code
1649

1750
The restricted line length originates from the early days of computing when terminals were limited to 80 characters per line. This convention is still followed in Python to ensure code readability across different editors and environments.
1851

52+
### Trailing commas
53+
Trailing commas are mandatory when making a tuple of one element, even although they appear redundant.
54+
```python
55+
towns = ('Mauchline',)
56+
```
1957
### Comparisons
2058
Use `is` or `is not` when comparing to `None`. From a performance perspective, `is` is faster than `==` because it checks for object identity rather than value equality.
2159
```python
@@ -31,6 +69,34 @@ if the_champ is not None:
3169
### Types
3270
#### Informational
3371
Informational PEPs describe a Python design issue, or provide general guidelines or information to the Python community. Some examples of informational PEPs are [PEP-20](https://peps.python.org/pep-0020/) (The Zen of Python), and [PEP-257](https://peps.python.org/pep-0257/) (Docstring conventions).
72+
73+
:information_source: You can view the PEP-20 aphorisms by running the following command from the REPL:
74+
```python
75+
Python 3.13.4 (main, Jun 3 2025, 15:34:24) [Clang 17.0.0 (clang-1700.0.13.3)] on darwin
76+
Type "help", "copyright", "credits" or "license" for more information.
77+
>>> import this
78+
The Zen of Python, by Tim Peters
79+
80+
Beautiful is better than ugly.
81+
Explicit is better than implicit.
82+
Simple is better than complex.
83+
Complex is better than complicated.
84+
Flat is better than nested.
85+
Sparse is better than dense.
86+
Readability counts.
87+
Special cases aren't special enough to break the rules.
88+
Although practicality beats purity.
89+
Errors should never pass silently.
90+
Unless explicitly silenced.
91+
In the face of ambiguity, refuse the temptation to guess.
92+
There should be one-- and preferably only one --obvious way to do it.
93+
Although that way may not be obvious at first unless you're Dutch.
94+
Now is better than never.
95+
Although never is often better than *right* now.
96+
If the implementation is hard to explain, it's a bad idea.
97+
If the implementation is easy to explain, it may be a good idea.
98+
Namespaces are one honking great idea -- let's do more of those!
99+
```
34100
#### Standards Track
35101
Standards Track PEPs describes a new feature or implementation in Python. They include a specification and a rationale for the change. An examples of Standards Track PEPs is [PEP-621](https://peps.python.org/pep-0621/).
36102

@@ -42,7 +108,13 @@ A short summary and description of the technical issue being addressed.
42108
#### Open Issues
43109
Ideas related to the PEP that are not yet resolved. This section is optional.
44110

111+
## Comments
112+
* Comments should be written in English
113+
* Comments that contradict the code are worse than no comments at all
114+
* Inline comments should start with a `#` and a single space and should be written on the same line as your statements
115+
45116
## [Docstrings](https://peps.python.org/pep-0257/)
117+
* String literals that occur as the first statement in a module, function, class or method definition.
46118
* For one-liner docstrings, the closing `"""` should be on the same line
47119
* The `"""` that ends a multiline docstring should be on a line by itself. For consistency, always use triple double quotes around docstrings.
48120
```python
@@ -58,7 +130,11 @@ comment = 'He said, "Hello Hello!"' # :white_check_mark: No need for backslash
58130
```
59131

60132
### Type variables
61-
Type variables, from the [typing](https://docs.python.org/3/library/typing.html) module, are used to define generic types in Python. They do not exist at runtime and are implicitly established by [PEP-484](https://peps.python.org/pep-0484/). They allow you to create functions and classes that can work with different types while maintaining type safety. Type variable names should typically use CamelCase (CapWords), for example:
133+
Type variables, from the [typing](https://docs.python.org/3/library/typing.html) module, are used to define generic types in Python.
134+
* :no_entry_sign: Do **not** exist at runtime and are implicitly established by [PEP-484](https://peps.python.org/pep-0484/).
135+
* Type annotations provide optional metadata used for static type checking and help IDEs with autocompletion.
136+
* They allow you to create functions and classes that can work with different types while maintaining type safety.
137+
* Type variable names should typically use CamelCase (CapWords), for example:
62138
#### Single-letter type variable
63139
```python
64140
from typing import TypeVar
@@ -77,3 +153,34 @@ def get_user(user_id: UserId):
77153
"""Retrieve a user by their ID."""
78154
pass
79155
```
156+
### Context Managers
157+
`with` statements - used to wrap the execution of a block with methods defined by a context manager. It ensures that resources are properly managed, such as closing files or releasing locks.
158+
159+
To make a class usable with a `with` statement, you need to implement the `__enter__()` and `__exit__()` methods.
160+
161+
* `__enter__()` - called when the block is entered
162+
* `__exit__()` - called when the block is exited. Always called even if an exception occurs inside the `with` block. This allows context managers to clean up resources.
163+
164+
```python
165+
class APIConnection:
166+
def __enter__(self):
167+
print("Connection opened")
168+
return self
169+
170+
def __exit__(self, exc_type, exc_value, exc_traceback):
171+
print("Connection closed")
172+
173+
with APIConnection() as connection:
174+
print("Using connection")
175+
```
176+
177+
`self` - refers to the instance of the class within the context manager. It allows you to access instance variables and methods.
178+
It is **not** a keyword and is only a naming convention.
179+
180+
If you return `True` from `__exit__()`, it suppresses the exception, meaning it won't be propagated outside the `with` block. This can be useful if you want to handle exceptions within the context manager itself.
181+
182+
:warning: **GOTCHA!** Never use mutable objects like lists or dicts as default arguments. The alternative is to use `None` and handle it inside the function. Default arguments are evaluated only once at the time the function is defined, not every time it is called.
183+
184+
:x: `def add_item(lst=[]):`
185+
186+
:white_check_mark: `def add_item(lst=None):`

examples/.DS_Store

6 KB
Binary file not shown.

examples/q105.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import tkinter as tk
2+
3+
root = tk.Tk()
4+
root.geometry("200x200")
5+
6+
label = tk.Label(
7+
root,
8+
text='Hello, World!',
9+
fg='white',
10+
bg='black',
11+
width=10,
12+
height=10,
13+
anchor='center',
14+
justify='left' )
15+
label.pack()
16+
17+
root.mainloop()

examples/q114.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# This code will raise error
2+
"""
3+
import json
4+
x = {"apple","banana","cherry"}
5+
y = json.dumps(x)
6+
print(y)
7+
"""
8+
# it will raise: TypeError: Object of type set is not JSON serializable
9+
10+
# This code will not raise error
11+
12+
import json
13+
print(json.dumps({"name": "John", "age": 30}))
14+
print(json.dumps(["apple", "bananas"]))
15+
print(json.dumps(42))
16+
17+
#Output will be:
18+
19+
#{"name": "John", "age": 30}
20+
#["apple", "bananas"]
21+
#42

examples/q117.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
class File:
2+
def __init__(self, fname):
3+
if fname.endswith('.docx'):
4+
self.language = 'Microsoft Word'
5+
elif fname.endswith('.pdf'):
6+
self.language = 'PDF Document'
7+
else:
8+
self.info = None
9+
10+
files = [
11+
File('script.docx'),
12+
File('win.py'),
13+
File('data.pdf'),
14+
File('login.docx'),
15+
]
16+
for file in files:
17+
if hasattr(file, 'language'):
18+
print(file.language)

examples/q119.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class Person:
2+
def display(self):
3+
print("Person called")
4+
5+
class Father(Person):
6+
def display(self):
7+
print("Father called")
8+
9+
class Mother(Person):
10+
def display(self):
11+
print("Mother called")
12+
13+
class Child(Mother, Person): # Mother should be before Person in inheritance
14+
pass
15+
16+
child_obj = Child()
17+
child_obj.display()

examples/q120.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
def html(func):
2+
def wrapper(*args, **kwargs):
3+
print("<html>")
4+
func(*args, **kwargs)
5+
print("</html>")
6+
return wrapper
7+
8+
def body(func):
9+
def wrapper(*args, **kwargs):
10+
print("<body>")
11+
func(*args, **kwargs)
12+
print("</body>")
13+
return wrapper
14+
15+
@html
16+
@body
17+
def text_printer(text):
18+
print(text)
19+
20+
text_printer("This is my text")

0 commit comments

Comments
 (0)