if name in namelist:
# not evaluated yet
pass
else:
# statementsDaily Notes: 2025-12-13
daily
ML Notes
Brief Interlude on Python
- For debugging/testing, using
python -ias inpython3 -i helloworld.pyis helpful because it runs the program and then enters the interactive shell afterwards.- This is helpful when I define a function and then experiment with this defined function
- Also helpful when I use exception handling
- Use
snake_casefor multiple word variable names instead of camelCase- Prefer lowercase
- Use leading
_for “private” or internal names. This is helpful because it reduces accidental use outside a module/class. Not real access control.- E.g.,
def _internal_helper from module import *will skip underscored names
- E.g.,
- You can add placeholders for statements to be added later with a
passsuch as below:
- You have to close files after opening and using them, like as follows:
f = open('foo.txt','r')
# Use f
f.close()- You can achieve the same purpose using
withand it automatically closes:
with open('foo.txt', 'r') as f:
# automatically closes afterwards
# for line-by-line reads
for line in f:
# Process the line
# for reading the entire file into a strong
data = f.read()
# for writing into a file
f.write('some text\n')Exception Handling
- Exception Handling: This is how Python deals with things going wrong. Errors are “exceptions”
- Wrap risky code in
tryblocks - With proper exception handling, if an error/exception occurs, control jumps to an
exceptblock. - Without an
exceptblock, any runtime error can crash our script. - With an
exceptblock:- Long-running programs stay alive after isolated failures
- Friendly error messages instead of tracebacks
- Differentiate between expected issues (aka user error) and bugs
- Importantly, the name must match the type of error you’re trying to catch (e.g.,
ValueError,ZeroDivisionError) - Exceptions have associated values that can be passed to variables (e.g.,
except ValueError as e) - Also,
finallycan be used for cleanup and for code that must run whether or not an exception occurs- Also useful for managing resources (esp. files)
try:
result = divide(num, denom)
except ZeroDivisionError:
print("Can't divide by zero—please try again.")
except ValueError as e: # can catch different kinds of exceptions, and prints the associated value
print("Value error—please try again.", e)
else:
print("Result:", result)
finally:
cleanup_resources()- Here’s something I wrote, which also includes an
f-stringthat allows me to drop values into the string with {…}
def portfolio_cost(file_name):
total_cost = 0.0
with open(file_name, 'r') as f:
for line in f:
fields = line.split()
try:
number_shares = float(fields[1])
purchase_price = float(fields[2])
total_cost += number_shares * purchase_price
except ValueError as e:
print(f"Couldn't parse: {line.strip()}")
print("Reason: ", e)
return total_costObjects
- All of the basic data types (strings, integers, lists, etc.) are Objects, therefore they involve “methods” to carry out operations
- You make your own Objects as follows (with their own methods):
class Player:
def __init__(self, name, age):
self.name = name
self.age = age
self.health = 100
def move(self, points):
self.health -= points__init__method initializes a new instance and is important for storing data attributes- By convention, the method is called on
selfandselfis defined as the first argument- The actual name is unimportant. Just know that the object is always passed as the first argument.
- Just conventional Python style to call it
self
import module as mimports a module (a namespace) that are the (global) variables and functions defined inmodule.py- Everything defined with global scope can be called as
m.method() from module import functionallows you to import certain functions from a module and put them into local scope. No need to use the module prefixmodule.function()from module import *allows you to import all functions. Don’t use this often in practice because it impacts readability.
- Everything defined with global scope can be called as
Data Structures
- Three options for data structures:
- tuples
- dictionaries
- classes (user-defined)
- Tuples are a collection of values (e.g.,
s = (GOOG, 10, 300.20)).- Can be used like an array (
quantity = s[1]) - Can be unpacked into separate variables (
name, quantity, price = s). - Immutable (
s[1] = 1throws aTypeError)
- Can be used like an array (
- Dictionaries are an unordered collection of key-value pairs (e.g., s = {‘name’: GOOG, …})
- Use the key values to access (
google_price = s[price]) - Can be modified (
s[price] = 320.20)
- Use the key values to access (
- User-Defined Classes as defined above provide the nice clean syntax we know and love (e.g.,
s.name). - Some “advanced” variants that are worth knowing:
- Slots: Saves memory
- Dataclasses: Reduces coding
- Named Tuples: Immutability/Tuple behavior
- Why are Slots so great?
__slots__are useful as a performance optimization because Python typically creates a__dict__for the attributes of every instance of an object.- These per-instance dictionaries allow you to add arbitary attributes at runtime, but have high memory overhead.
- In exchange for enumerating the attributes your instances will ever need in advance, a fixed slot layout saves the memory overhead of per-instance dictionaries.
- This is especially useful when you have many objects.
class Player:
__slots__('name', 'age', 'health')
def __init__(self, name, age):
self.name = name
self.age = age
self.health = 100- Why are Dataclasses so great?
- It’s just easier… it helps make boilerplate-free classes.
- Python auto-generates helpers like
__init__ - You do need to annotate the types (even if it’s just
Any)
from dataclasses import dataclass
@dataclass
class Player:
name: str
age: int
health: int- Why are Named Tuples so great?
- Dataclasses with guaranteed immutability.
- The most important feature is Immutability, which allows you to safely use them as dict keys
- Other features for tuples (indexing, etc.) are useful here too.
import typing
class Player(typing.NamedTuple):
name: str
age: int
health: intPersonal Notes
- I’m feeling a lot of anxiety to start “doing” rather than just consuming information, step by step, from a textbook. I’ve been coding more aggressively as a result.
- A reminder to myself on how learning via a textbook should feel:
- like pieces of a puzzle retroactively coming together
- like previous experiences making far more sense in context
- like seeing in the light what I once grasped around for in the dark
- I’m trying to avoid tutorial hell by building until I get stuck, and grasping around for the necessary context as I go.