Autosave: 2025-03-26 17:50:46

This commit is contained in:
thomasabishop 2025-03-26 17:50:46 +00:00
parent a2b65df7a4
commit 994a3feea8
847 changed files with 443 additions and 7 deletions

View file

@ -0,0 +1,74 @@
---
tags: [literature]
created: Tuesday, March 25, 2025
---
# _Code Craft: The Practice Of Writing Excellent Code_
## Clarity not brevity
> Readability is the best single criterion of program quality: If a program is
> easy to read, it is probably a good program; if it is hard to read, it
> probably isn't good. -- _The Elements of Programming Style_ (Kernighan and
> Plaugher, 1978)
Whenever you can choose between concise (but potentially confusing) code and
clear (but potentially tedious) code, use code that reads as intended, even if
its less elegant.
## Initialise all variables at their points of declaration
The uninitialized value may turn into a problem further down the line.
## Declare variables as late as possible
Place the variable as close as possible to its use. This prevents it from
confusing other parts of the code. It also clarifies the code using the
variable. You dont have to hunt around to find the variables type and
initialization; a nearby declaration makes it obvious.
## Naming
- Choose names from the perspective of an inexperienced reader, not from your
internal, knowledgeable perspective.
- If you cant come up with a good name, then you might need to change your
design. Its an indication that something might be wrong.
- Use clear names even if they are long. It doesnt matter that a name is long
if its meaning is unambiguous.
- Avoid redundant words in names. Specifically, avoid these words in type names:
_class_, _data_, _object_, and _type_.
## Self-documenting code
This can be achieved with good naming alone if you are clever about it. It
doesn't necessarily require automated tools or excessive commentary.
### Scope
- With smaller, more specific scope we can name things in a more intuitive and
expressive way. For example `Tree.countApples()`, `Tree.hasApples` rather than
`Tree.countApplesInTree()`.
### Good presentation
- Make the “normal” path through your code obvious. Error cases should not
confuse the normal flow of execution. Your if-then-else constructs should be
ordered _consistently_ (i.e., always place the “normal” case before the
“error” case, or vice versa).
- _One function, one action_. Make that your mantra.
- Public information should come first, since this is what the class user needs
to see. Put the **private implementation details at the end**, since they are
less important to most readers.
### Comments
- Explain _why_ not _how_. Your comments should not describe how the program
works. You can see that by reading the code. The code is the definitive
description of how the code works. You should instead focus on describing why
something is written the way it is or what the next block of statements
ultimately achieves.

View file

@ -0,0 +1,57 @@
---
tags: [python]
created: Sunday, March 16, 2025
---
# Constructing paths in Python
Rather than hard-coding paths it's better to use path construction operators.
In the past this was done with `os.path` but a more modern library is `pathlib`.
```python
import os
import pathlib
from pathlib import Path
```
I'll show both, side by side.
## Get directory of the current script
```py
SCRIPT_DIR = Path(__file__).parent.absolute()
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file))
```
## Get the user home directory
```py
HOME_DIR = Path.home
HOME_DIR = os.environ.get("HOME")
```
## Construct a path from $HOME
```py
HOME_DIR = Path.home
HOME_DIR = os.environ.get("HOME")
SUB_DIR = HOME_DIR / "repos" / "systems-obscure" / "src"
SUB_DIR = os.path.join(HOME_DIR, "repos", "systems-obscure", "src")
```
## Access root directories
It's less straightforward to access directories that are not children of
`$HOME`.
For instance to access mounted drives:
```py
EXT_HD = Path("/media/samsung-T3")
EXT_HD_DIR = EXT_HD / "music"
EXT_HD = "/media/samsung-T3"
EXT_HD_DIR = os.path.join(EXT_HD, "music")
```

View file

@ -0,0 +1,84 @@
---
tags: [python]
created: Sunday, March 16, 2025
---
# Using a context manager in Python
For certain process that have a start and an end state such as opening and
closing a file or connecting and disconnecting from a database, instead of
having dedicated open/close, connect/disconnect handling, you can use a Context
Manager as a form of "syntactic sugar".
By using a Context Manager you can use a more Pythonic construction of e.g:
```py
with open('/file-path') as file:
... # handle file operation
```
```py
with open DatabaseService() as connection:
... # do database stuff
```
When you use this approach it is an abstraction over `try...finally`. Meaning
the clean-up `finally` operation will run automatically without you having to
explicitly handle it.
Some common processes such as file handling have the Context Manager built-in
and you don't have to explicitly provision it.
Other processes may lend themselves to `with` syntax but you have to do the
configuration yourself.
One such example is creating a database accessor. Below I have done this by
using `__enter__` and `__exit__` methods on a database class:
```py
class DatabaseService:
def __init__(self, db_name, db_path):
self.db_name = db_name
self.db_path = db_path
self.connection: Optional[sqlite3.Connection] = None
def connect(self) -> Optional[sqlite3.Connection]:
if self.connection is not None:
return self.connection
try:
if not os.path.exists(self.db_path):
os.makedirs(self.db_path)
print("INFO Created database directory")
self.connection = sqlite3.connect(f"{self.db_path}/{self.db_name}.db")
self.connection.execute("PRAGMA foreign_keys = ON")
return self.connection
except Exception as e:
raise Exception(f"ERROR Problem connecting to database: {e}")
def disconnect(self) -> None:
try:
if self.connection is not None:
self.connection.close()
self.connection = None
except Exception as e:
raise Exception(f"ERROR Problem disconnecting from database: {e}")
def __enter__(self) -> sqlite3.Connection:
connection = self.connect()
if connection is None:
raise RuntimeError("Failed to establish database connection")
return connection
def __exit__(self) -> None:
self.disconnect()
```
Then I can use it like so:
```py
with DatabaseService() as connection:
cursor = connection.cursor()
cursor.execute(...)
```

View file

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

View file

@ -13,12 +13,16 @@ computer science.
<a href="https://thomasabishop.github.io/eolas/tags">View tags</a>
**Build ID:** 7aecb0c4-f9f9-4579-9564-8a4cb5e9c958
**Build ID:** 2abd5c63-27cc-420e-b0df-76bdd7f8acb1
**Published:** Fri 14 Mar 2025 17:01:53
**Published:** Wed 26 Mar 2025 17:50:41
### Recent edits
- [[Code_Craft_The_Practice_Of_Writing_Excellent_Code]]
- [[Constructing paths in Python]]
- [[File_operations_in_Python]]
- [[Using a context manager in Python]]
- [[USB-C]]
- [[USB protocols and connectors]]
- [[SSH]]
@ -35,13 +39,9 @@ computer science.
- [[Case_statements_in_Bash]]
- [[UFW_firewall_management]]
- [[Firewalls]]
- [[Disable_non-root_ssh_access]]
- [[Setup encrypted harddrive]]
- [[Disk_size_utilities]]
- [[Let's_Encrypt]]
### All notes (541)
### All notes (544)
- [[0716531c_rewilding_the_internet]]
- [[241fe1a3_the_Web_versus_modem_BBSs]]
@ -132,6 +132,7 @@ computer science.
- [[Classes]]
- [[Classes_in_Python]]
- [[Clock_signals]]
- [[Code_Craft_The_Practice_Of_Writing_Excellent_Code]]
- [[Command_pattern]]
- [[Commutative_Property_of_Addition_and_Multiplication]]
- [[Comparing_React_classes_to_hooks]]
@ -148,6 +149,7 @@ computer science.
- [[Conjunction_Introduction]]
- [[Connect_to_Mongo_database]]
- [[Connecting_a_frontend_to_a_Docker_backend]]
- [[Constructing paths in Python]]
- [[Containerization]]
- [[Controlled_components_in_React]]
- [[Corresponding_material_and_biconditional]]
@ -523,6 +525,7 @@ computer science.
- [[User_agent]]
- [[User_management_in_Linux]]
- [[User_management_on_AWS]]
- [[Using a context manager in Python]]
- [[Using_GraphQL_with_Node]]
- [[Using_SQLite_with_Python]]
- [[Using_arguments_with_Apollo_Client]]

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

View file

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

View file

Before

Width:  |  Height:  |  Size: 145 KiB

After

Width:  |  Height:  |  Size: 145 KiB

View file

Before

Width:  |  Height:  |  Size: 289 KiB

After

Width:  |  Height:  |  Size: 289 KiB

View file

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View file

Before

Width:  |  Height:  |  Size: 6.9 MiB

After

Width:  |  Height:  |  Size: 6.9 MiB

View file

Before

Width:  |  Height:  |  Size: 224 KiB

After

Width:  |  Height:  |  Size: 224 KiB

View file

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

View file

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 65 KiB

View file

Before

Width:  |  Height:  |  Size: 218 KiB

After

Width:  |  Height:  |  Size: 218 KiB

View file

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View file

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View file

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

View file

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View file

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View file

Before

Width:  |  Height:  |  Size: 132 KiB

After

Width:  |  Height:  |  Size: 132 KiB

View file

Before

Width:  |  Height:  |  Size: 175 KiB

After

Width:  |  Height:  |  Size: 175 KiB

View file

Before

Width:  |  Height:  |  Size: 204 KiB

After

Width:  |  Height:  |  Size: 204 KiB

View file

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 49 KiB

View file

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View file

Before

Width:  |  Height:  |  Size: 165 KiB

After

Width:  |  Height:  |  Size: 165 KiB

View file

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

View file

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

View file

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 91 KiB

View file

Before

Width:  |  Height:  |  Size: 133 KiB

After

Width:  |  Height:  |  Size: 133 KiB

View file

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View file

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 45 KiB

View file

Before

Width:  |  Height:  |  Size: 4 KiB

After

Width:  |  Height:  |  Size: 4 KiB

View file

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View file

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View file

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

View file

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 2 KiB

View file

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View file

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View file

Before

Width:  |  Height:  |  Size: 148 KiB

After

Width:  |  Height:  |  Size: 148 KiB

View file

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

View file

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View file

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

View file

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View file

Before

Width:  |  Height:  |  Size: 121 KiB

After

Width:  |  Height:  |  Size: 121 KiB

View file

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View file

Before

Width:  |  Height:  |  Size: 470 KiB

After

Width:  |  Height:  |  Size: 470 KiB

View file

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View file

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View file

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View file

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View file

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 59 KiB

View file

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View file

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View file

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View file

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 59 KiB

View file

Before

Width:  |  Height:  |  Size: 99 KiB

After

Width:  |  Height:  |  Size: 99 KiB

View file

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View file

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View file

Before

Width:  |  Height:  |  Size: 848 KiB

After

Width:  |  Height:  |  Size: 848 KiB

View file

Before

Width:  |  Height:  |  Size: 194 KiB

After

Width:  |  Height:  |  Size: 194 KiB

View file

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

View file

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View file

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 130 KiB

View file

Before

Width:  |  Height:  |  Size: 171 KiB

After

Width:  |  Height:  |  Size: 171 KiB

View file

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View file

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View file

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

View file

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View file

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 79 KiB

View file

Before

Width:  |  Height:  |  Size: 157 KiB

After

Width:  |  Height:  |  Size: 157 KiB

View file

Before

Width:  |  Height:  |  Size: 183 KiB

After

Width:  |  Height:  |  Size: 183 KiB

View file

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 72 KiB

View file

Before

Width:  |  Height:  |  Size: 153 KiB

After

Width:  |  Height:  |  Size: 153 KiB

View file

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

View file

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 87 KiB

View file

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 118 KiB

View file

Before

Width:  |  Height:  |  Size: 414 KiB

After

Width:  |  Height:  |  Size: 414 KiB

View file

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View file

Before

Width:  |  Height:  |  Size: 174 KiB

After

Width:  |  Height:  |  Size: 174 KiB

View file

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View file

Before

Width:  |  Height:  |  Size: 167 KiB

After

Width:  |  Height:  |  Size: 167 KiB

View file

Before

Width:  |  Height:  |  Size: 150 KiB

After

Width:  |  Height:  |  Size: 150 KiB

View file

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

View file

Before

Width:  |  Height:  |  Size: 140 KiB

After

Width:  |  Height:  |  Size: 140 KiB

View file

Before

Width:  |  Height:  |  Size: 190 KiB

After

Width:  |  Height:  |  Size: 190 KiB

View file

Before

Width:  |  Height:  |  Size: 374 KiB

After

Width:  |  Height:  |  Size: 374 KiB

View file

Before

Width:  |  Height:  |  Size: 9 KiB

After

Width:  |  Height:  |  Size: 9 KiB

View file

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 1.2 MiB

View file

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 76 KiB

View file

Before

Width:  |  Height:  |  Size: 448 KiB

After

Width:  |  Height:  |  Size: 448 KiB

View file

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 122 KiB

View file

Before

Width:  |  Height:  |  Size: 668 KiB

After

Width:  |  Height:  |  Size: 668 KiB

View file

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View file

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View file

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View file

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View file

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View file

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

View file

Before

Width:  |  Height:  |  Size: 108 KiB

After

Width:  |  Height:  |  Size: 108 KiB

View file

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

View file

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View file

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View file

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View file

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View file

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View file

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB

View file

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View file

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View file

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View file

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View file

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View file

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View file

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View file

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View file

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View file

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

View file

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View file

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View file

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

View file

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

View file

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 58 KiB

View file

Before

Width:  |  Height:  |  Size: 146 KiB

After

Width:  |  Height:  |  Size: 146 KiB

View file

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View file

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View file

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View file

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 63 KiB

View file

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 94 KiB

View file

@ -548,6 +548,7 @@ unlisted: true
- [[UFW_firewall_management]]
### literature
- [[Code_Craft_The_Practice_Of_Writing_Excellent_Code]]
- [[The_History_of_Computing_Swade]]
- [[Weaving_the_Web_Berners_Lee]]
### logic
@ -936,6 +937,7 @@ unlisted: true
- [[Classes_in_Python]]
- [[Compile_Python_app_to_single_executable]]
- [[Conditional_statements_in_Python]]
- [[Constructing paths in Python]]
- [[Dates_in_Python]]
- [[Dictionaries_in_Python]]
- [[Error_handling_in_Python]]
@ -969,6 +971,7 @@ unlisted: true
- [[Testing_Python_code]]
- [[Tuples_in_Python]]
- [[Type_hinting]]
- [[Using a context manager in Python]]
- [[Using_SQLite_with_Python]]
- [[With_open_in_Python]]
- [[Working_with_CSVs_in_Python]]

Binary file not shown.

View file

@ -0,0 +1,74 @@
---
tags: [literature]
created: Tuesday, March 25, 2025
---
# _Code Craft: The Practice Of Writing Excellent Code_
## Clarity not brevity
> Readability is the best single criterion of program quality: If a program is
> easy to read, it is probably a good program; if it is hard to read, it
> probably isn't good. -- _The Elements of Programming Style_ (Kernighan and
> Plaugher, 1978)
Whenever you can choose between concise (but potentially confusing) code and
clear (but potentially tedious) code, use code that reads as intended, even if
its less elegant.
## Initialise all variables at their points of declaration
The uninitialized value may turn into a problem further down the line.
## Declare variables as late as possible
Place the variable as close as possible to its use. This prevents it from
confusing other parts of the code. It also clarifies the code using the
variable. You dont have to hunt around to find the variables type and
initialization; a nearby declaration makes it obvious.
## Naming
- Choose names from the perspective of an inexperienced reader, not from your
internal, knowledgeable perspective.
- If you cant come up with a good name, then you might need to change your
design. Its an indication that something might be wrong.
- Use clear names even if they are long. It doesnt matter that a name is long
if its meaning is unambiguous.
- Avoid redundant words in names. Specifically, avoid these words in type names:
_class_, _data_, _object_, and _type_.
## Self-documenting code
This can be achieved with good naming alone if you are clever about it. It
doesn't necessarily require automated tools or excessive commentary.
### Scope
- With smaller, more specific scope we can name things in a more intuitive and
expressive way. For example `Tree.countApples()`, `Tree.hasApples` rather than
`Tree.countApplesInTree()`.
### Good presentation
- Make the “normal” path through your code obvious. Error cases should not
confuse the normal flow of execution. Your if-then-else constructs should be
ordered _consistently_ (i.e., always place the “normal” case before the
“error” case, or vice versa).
- _One function, one action_. Make that your mantra.
- Public information should come first, since this is what the class user needs
to see. Put the **private implementation details at the end**, since they are
less important to most readers.
### Comments
- Explain _why_ not _how_. Your comments should not describe how the program
works. You can see that by reading the code. The code is the definitive
description of how the code works. You should instead focus on describing why
something is written the way it is or what the next block of statements
ultimately achieves.

View file

@ -0,0 +1,57 @@
---
tags: [python]
created: Sunday, March 16, 2025
---
# Constructing paths in Python
Rather than hard-coding paths it's better to use path construction operators.
In the past this was done with `os.path` but a more modern library is `pathlib`.
```python
import os
import pathlib
from pathlib import Path
```
I'll show both, side by side.
## Get directory of the current script
```py
SCRIPT_DIR = Path(__file__).parent.absolute()
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file))
```
## Get the user home directory
```py
HOME_DIR = Path.home
HOME_DIR = os.environ.get("HOME")
```
## Construct a path from $HOME
```py
HOME_DIR = Path.home
HOME_DIR = os.environ.get("HOME")
SUB_DIR = HOME_DIR / "repos" / "systems-obscure" / "src"
SUB_DIR = os.path.join(HOME_DIR, "repos", "systems-obscure", "src")
```
## Access root directories
It's less straightforward to access directories that are not children of
`$HOME`.
For instance to access mounted drives:
```py
EXT_HD = Path("/media/samsung-T3")
EXT_HD_DIR = EXT_HD / "music"
EXT_HD = "/media/samsung-T3"
EXT_HD_DIR = os.path.join(EXT_HD, "music")
```

View file

@ -0,0 +1,84 @@
---
tags: [python]
created: Sunday, March 16, 2025
---
# Using a context manager in Python
For certain process that have a start and an end state such as opening and
closing a file or connecting and disconnecting from a database, instead of
having dedicated open/close, connect/disconnect handling, you can use a Context
Manager as a form of "syntactic sugar".
By using a Context Manager you can use a more Pythonic construction of e.g:
```py
with open('/file-path') as file:
... # handle file operation
```
```py
with open DatabaseService() as connection:
... # do database stuff
```
When you use this approach it is an abstraction over `try...finally`. Meaning
the clean-up `finally` operation will run automatically without you having to
explicitly handle it.
Some common processes such as file handling have the Context Manager built-in
and you don't have to explicitly provision it.
Other processes may lend themselves to `with` syntax but you have to do the
configuration yourself.
One such example is creating a database accessor. Below I have done this by
using `__enter__` and `__exit__` methods on a database class:
```py
class DatabaseService:
def __init__(self, db_name, db_path):
self.db_name = db_name
self.db_path = db_path
self.connection: Optional[sqlite3.Connection] = None
def connect(self) -> Optional[sqlite3.Connection]:
if self.connection is not None:
return self.connection
try:
if not os.path.exists(self.db_path):
os.makedirs(self.db_path)
print("INFO Created database directory")
self.connection = sqlite3.connect(f"{self.db_path}/{self.db_name}.db")
self.connection.execute("PRAGMA foreign_keys = ON")
return self.connection
except Exception as e:
raise Exception(f"ERROR Problem connecting to database: {e}")
def disconnect(self) -> None:
try:
if self.connection is not None:
self.connection.close()
self.connection = None
except Exception as e:
raise Exception(f"ERROR Problem disconnecting from database: {e}")
def __enter__(self) -> sqlite3.Connection:
connection = self.connect()
if connection is None:
raise RuntimeError("Failed to establish database connection")
return connection
def __exit__(self) -> None:
self.disconnect()
```
Then I can use it like so:
```py
with DatabaseService() as connection:
cursor = connection.cursor()
cursor.execute(...)
```