TopNotchNote
Notes that matter
installation via terminal
sudo apt install python3 python3-pip| https://www.python.org/downloads/ | installs Python 3 and pip on Ubuntu |'py_inst1'
Good habits of python programming
Here are some comments:
- Always add if __name__ == "__main__": to your scripts to allow or prevent parts of code from being run when the modules are imported.
- Always define the main() function in your scripts to encapsulate the main logic and improve code organization (and combine it with the previous item).
- Keep your functions small and focused on a single task to enhance readability and maintainability.
- define type annotations for variables, function parameters, and return types to improve code clarity and help with static analysis. For example: number: int = 10. Example for function: def greet(name: str) -> str:.
- Use list comprehensions and generator expressions for concise and efficient data processing. Example: squares = [x**2 for x in range(10)].
- Trailing comma is optional in python, but it is a good practice to add it in multi-line collections (lists, tuples, dictionaries, sets) and function arguments. This makes adding new elements easier and reduces the chances of syntax errors. Example: my_list = [ 1, 2, 3, ]
- Always have documentation string for each function/classes/modules. For functions, return parameters, and the return type if exists. For Class talk about methods and variable, and for modules list important funcstions, and classes. Example: def myFunction(arg1, arg2=None): """myFunction(arg1, arg2=None) --> Doesn't really do anything special. Parameters: arg1: the first argument. Whatever you feel like passing. arg2: the second argument. Defaults to None. Whatever makes you happy. """ print(arg1, arg2) def main(): print(myFunction.__doc__) Note that you can access the documentation for each function/module with __doc__. For example print(collections.__doc__). Refer to https://peps.python.org/pep-0257
- https://peps.python.org/
- closures - # Nested functions create inner scopes. These are called closures: def multiplier_maker(factor): def multiply(num): return num * factor return multiply doubler = multiplier_maker(2) tripler = multiplier_maker(3) print(doubler(10)) print(doubler(15)) print(tripler(10))
tips
- functions are first class objects, that means they can be passed as args to other functions.
type(funcName()): prints the return type of the function
- help(funcs): prints the help output
- Calling a function without () returns the reference to that func, but with () returns the returns.
- Decorator: is a callable that takes another function as an argument and extending the behavior of that function without explicitly modifying that function.
- Decorator can access and modify input arguments and the return values.
- The super() function is used to give access to methods and properties of a parent or sibling class. The super() function returns an object that represents the parent class.
- Magic methods: a set of methods that python automatically associates with each class. We can override this methods to customize the methods.
- Any object is considered boolean true, unless it has a link or has some special values that make it false (None/Flase/Numeric zero values (0,0.0,0j/Decimal(0)/Fraction(0,x)/Empty sequences/collections: '', (),[],{}/empty sets and ranges: set(), range(0)). And also if you override the value of __bool__ to false, or __len__ to 0 in a class.
- To check the boolean value of something in python: bool(x).
- walrus operator in python is the assignment expression that helps to write concise code. For example:
thestr = input("value? ")
while thestr != "exit":
print(thestr)
thestr = input("value? ")
TO
while (thestr := input("value? ")) != "exit":
print(thestr)
Another example, to reduce function calls:
values = [12, 0, 10, 5, 9, 18, 41, 23, 30, 16, 18, 9, 18, 22]
val_data = {
"length": (l := len(values)),
"total": (s := sum(values)),
"average": s / l
}
- you can change, separator and ending of print statement:
values=["one", "two", "three", "four", "five"]
print(*values)
# use the 'sep' argument to control the separator between values:
print(*values, sep=' -- ')
# use the 'end' argument to control the line ending characters
# let's auto-print the current line number along with each item
for i in range(0, len(values)):
print(values[i], end=f" [line: {str(i+1)}]\n")
you can also use print to print in file:
newfile = open("output.txt","w")
print(*values, sep=' -- ', file=newfile, flush=True)
newfile.close()
- pretty print (link to help: https://docs.python.org/3/library/pprint.html)
--- iterators:
- i = iter(list), next(i)
- enumerate:
days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
for i, m in enumerate(days, start=1):
print(i, m)
- use zip to combine sequences, if the lists are not equal in size, it stops when the short list ends :
for m in zip(days, daysFr):
print(m)
- zip_longest, fills the values of shorter list:
import itertools
# use zip_longest
seq1 = ["A","B","C","D","E","F"]
seq2 = [1, 2, 3, 4]
seq3 = "xyz"
result = itertools.zip_longest(seq1, seq2, seq3, fillvalue="-")
print("Result: ")
for item in result:
print(item)
Result:
('A', 1, 'x')
('B', 2, 'y')
('C', 3, 'z')
('D', 4, '-')
('E', '-', '-')
('F', '-', '-')
- function has lib called itertools: https://docs.python.org/3/library/itertools.html
# cycle iterator can be used to cycle over a collection infinitely - as long as you call next, it iterates
names = ["Joe", "Jane", "Jim"]
cycler = itertools.cycle(names)
print(next(cycler))
print(next(cycler))
print(next(cycler))
print(next(cycler))
# use count to create a simple counter - as long as you call next, it iterates
counter = itertools.count(100, 10)
print(next(counter))
print(next(counter))
print(next(counter))
##
vals = [10,20,30,40,50,40,30]
acc = itertools.accumulate(vals, max)
print(list(acc))
- chain
# chain() creates a single iterable from multiple
x = itertools.chain("ABCD", "1234")
print(list(x))
s1 = "ABCDEFG"
s2 = [1,2,3,4,5]
s3 = ['$','%','@','&']
result = itertools.chain.from_iterable([s1,s2,s3])
print(list(result))
related topics
Python Optimization — making this code faster once it's correct.
Debugging: gdb, pdb & a General Method — pdb and other debugging tools for when this code misbehaves.
Claude API for Developers — the language most Claude API integrations are written in.
PyTorch Notes — applying these Python fundamentals to PyTorch specifically.
Debugging: gdb, pdb & a General Method — pdb and other debugging tools for when this code misbehaves.
Claude API for Developers — the language most Claude API integrations are written in.
PyTorch Notes — applying these Python fundamentals to PyTorch specifically.