Glossary: determinism, dictionaries and dynamic types — DedSec Project
Glossary: determinism, dictionaries and dynamic types Determinism Concept in practice A deterministic computation produces the same observable result for the same inputs and relevant…
Determinism
Concept in practice
A deterministic computation produces the same observable result for the same inputs and relevant environment. Random seeds can help reproduce pseudo-random sequences, but do not control clocks, thread scheduling, filesystem ordering or changing external services.
Focused example
import random
first = random.Random(17).sample(range(100), 5)
second = random.Random(17).sample(range(100), 5)
assert first == second
Exercise and common pitfall
Remove the explicit seed and observe possible variation, then sort an unordered collection before comparing output. For tests with dates, inject a fixed clock instead of depending on the current time. Explain which dependencies still prevent complete reproducibility.
Reference: https://docs.python.org/3/library/random.html
Dictionary
Concept in practice
A dictionary associates unique keys with values and typically supports efficient lookup by key. In Python, keys must be hashable, and assigning to an existing key replaces its value. Lookup performance is usually good on average but not a contractual constant-time guarantee in all circumstances.
Focused example
totals = {}
for name in ['Ada', 'Grace', 'Ada']:
totals[name] = totals.get(name, 0) + 1
assert totals == {'Ada': 2, 'Grace': 1}
Exercise and common pitfall
Try using a list as a dictionary key and record the resulting TypeError. Compare d.get(k) with d[k] when a key is absent; distinguish legitimate missing data from a default zero.
Reference: https://docs.python.org/3/tutorial/datastructures.html#dictionaries
Dynamic typing
Concept in practice
In dynamically typed languages such as Python, values carry types and names may refer to different types over time. This is not the same as having no type rules; incorrect operations still raise errors at runtime. Optional static annotations can help tooling without converting Python into a statically enforced runtime.
Focused example
value = 3
value = 'three'
assert isinstance(value, str)
try:
_ = value + 1
except TypeError: pass
else: raise AssertionError('expected a type error')
Exercise and common pitfall
Design a function accepting unknown JSON and validate with isinstance before arithmetic. Compare its runtime behavior with a type-checker warning on value + 1; avoid treating type hints as automatic input validation.
Reference: https://docs.python.org/3/library/typing.html
Encapsulation
Meaning and constraints
Encapsulation places state and the operations that preserve its rules behind a deliberate interface. Python's leading underscore is a convention, not hard access control. Clients should call methods that preserve an invariant rather than mutating internal fields directly.
A concrete use
class Balance:
def __init__(self): self._cents = 0
def add(self, cents):
if type(cents) is not int or cents < 0: raise ValueError('invalid amount')
self._cents += cents
@property
def cents(self): return self._cents
b = Balance(); b.add(25); assert b.cents == 25
Challenge and misconception
Try add(-1) and add(True). Explain why direct assignment to _cents is still technically possible, so an API boundary must also enforce caller privileges where relevant.
Further reading: https://docs.python.org/3/tutorial/classes.html#private-variables