commit 892a36c5647d8be6cf5f6663a4bbfe4067c6c88b
parent d4332493dafa7398afca298c663fc6f3b31234c6
Author: Andrew Laack <andrew@laack.co>
Date: Mon, 14 Jul 2025 13:18:49 -0500
Started reading python design patterns book
Diffstat:
3 files changed, 145 insertions(+), 2 deletions(-)
diff --git a/latex/designing/DesigningDataIntensiveApplications.tex b/latex/designing/DesigningDataIntensiveApplications.tex
@@ -166,8 +166,6 @@ The property graph model, as implemented by Neo4j, Titan, and InfiniteGraph, eac
As we see, this is a directed graph and each object (edges and vertices) contains its own collection of properties and identifier. Conceptually, this can be implemented by a SQL database where we have a table for vertices and a table for edges, each of which contains respective columns for attributes of said records, presuming we have a json datatype, which is supported in PostgreSQL.
-
-
\subsubsection{Triple-Store Model}
The triple-store model, as implemented by Datomic, AllegroGraph, and others,
diff --git a/latex/fluent-python/FluentPython.tex b/latex/fluent-python/FluentPython.tex
@@ -0,0 +1,89 @@
+\documentclass[12pt, letterpaper]{article}
+\usepackage{xcolor}
+
+\setlength{\parindent}{0pt}
+\setlength{\parskip}{.5em}
+
+\usepackage{enumitem}
+\usepackage{graphicx}
+\usepackage{listings}
+\usepackage{caption}
+\usepackage{tcolorbox}
+\usepackage{datetime}
+\usepackage{amsfonts}
+\usepackage{amsmath}
+\usepackage{geometry}
+\geometry{verbose,tmargin=1in,bmargin=1in,lmargin=1in,rmargin=1in}
+\usepackage{amssymb}
+\usepackage{amsthm,stmaryrd}
+\usepackage[all]{xy}
+
+\newenvironment{definition}{
+ \begin{quote}
+ \textbf{Definition:}
+ }{
+ \end{quote}
+}
+
+
+\newenvironment{explanation}{
+ \begin{quote}
+ \textbf{Explanation:}
+ }{
+ \end{quote}
+}
+
+\newenvironment{example}{
+ \begin{quote}
+ \textbf{Example:}
+ }{
+ \end{quote}
+}
+
+\lstnewenvironment{code}{
+ \textbf{Code:}
+ \lstset{
+ basicstyle=\ttfamily,
+ columns=fullflexible,
+ breaklines=true
+ }
+}{
+}
+
+
+\begin{document}
+
+\noindent{\large \textbf{Fluent Python}}
+
+\noindent Notes by Andrew Laack
+
+\tableofcontents
+
+\section{Python Data Model}
+
+\subsection{Special Methods}
+
+Special methods are methods that take a general input object. These are things like \textbf{len()} and \textbf{str()}. When defining these special methods, we define them with method names that start and end with double underscores.
+
+We implement these special methods when we want objects to support fundamental constructs. These include:
+
+\begin{enumerate}
+ \item Collections
+ \item Attribute Access
+ \item Iteration (and async)
+ \item Operator Overloading
+ \item Function and Method Invocation
+ \item String Representation and Formatting
+ \item Asynchronous With \textbf{await}
+ \item Object Creation/Destruction
+ \item Managed Contexts Using \textbf{with} or \textbf{async with}
+\end{enumerate}
+
+These are also referred to as \textbf{magic methods}.
+
+
+\subsection{Named Tuples}
+
+To use named tuples we import \textbf{collections} and use \textbf{collections.namedtuple()}. Named tuples are a common approach for creating a struct analog in cases where there isn't a need to define associated functions. These are key-value pairs where keys are hashed, and, unlike with dictionaries, we can use indexes on them. A limitation of named tuples is they are immutable, but there is an update analog called \textbf{\_replace} which deletes a record and creates a new one.
+
+\end{document}
diff --git a/latex/fluent-python/python-code/doubly-linked-list.py b/latex/fluent-python/python-code/doubly-linked-list.py
@@ -0,0 +1,56 @@
+class DoublyLinkedList:
+ class Node:
+ def __init__(self, val, left=None, right=None):
+ self.val = val
+ self.left = left
+ self.right = right
+
+ def __init__(self, ls):
+
+ cp_ls = ls.copy()
+
+ for index, ele in enumerate(cp_ls):
+
+ cp_ls[index] = self.Node(ele)
+
+ if index != 0:
+ cp_ls[index].left = cp_ls[index - 1]
+
+ for index, ele in enumerate(cp_ls):
+ if index != len(cp_ls) - 1:
+ ele.right = cp_ls[index + 1]
+
+ self.head = cp_ls[0]
+ self.tail = cp_ls[-1]
+ self.length = len(ls)
+
+ def __getitem__(self, position):
+
+ while position < 0:
+ position += len(self)
+
+ if position > self.length // 2:
+ current = self.tail
+ for _ in range(0, position - self.length):
+ current = current.left
+ return current.val
+ else:
+ current = self.head
+ for _ in range(0, position):
+ current = current.right
+ return current.val
+
+ def __len__(self):
+ return self.length
+
+
+
+if __name__ == "__main__":
+ nums = [10, 487, 123908, 7120398]
+ ls = DoublyLinkedList(nums)
+
+ for i in range(0, len(ls)):
+ print(ls[i])
+
+ print(ls[-1])
+ print(ls[-2])