notes

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

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:
Mlatex/designing/DesigningDataIntensiveApplications.tex | 2--
Alatex/fluent-python/FluentPython.tex | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alatex/fluent-python/python-code/doubly-linked-list.py | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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])