I have been using Python for a very long time.

Whenever you start a new Python project, always start with a Virtual Environment.

I really need to develop the habit of using virtual environments. Here is the command:

pip freeze | xargs pip uninstall -y


Python under the hood

Code Style Python Script

Why python is so good

  • syntax (no need to declare types upfront)
  • Automatic memory management,
  • libraries (scipy, numpy, pytorch)
  • community support is amazing

Structure Your Project

Check out how this folder is structured.

Testing Your Code


Virtual Environments

Random Tips

Use .extend() instead of .append() if you want to “append” an array to another array.

Python Design

After taking CS247, I have SUCH a stronger mastery of Object-Oriented Programming. Now, I am actually curious about how does OOP actually work in Python? How do types work in Python?


Ahh, so python is ALWAYS dynamically typed. And this is why you don’t even need to declare any function as virtual, since it will NEVER use the static type.

Some new things

In Python, a private member can be defined by using a prefix __ (double underscore). So, in the private modifier’s case, we cannot access the attribute, Learned this at Ericsson

phaseOffsetTableObj.__offsetList  # this will return has no attribute

From Andrej Karpathy, so much I am learning from him:

# For classes, you can overwrite + and -, internally in python:
a + b  # a.__add__(b) is called under the hood
# Another example
5 + 6 # (5).__add__(6) 
# However, this returns an ERROR
int(5).__add__(float(6)) # NotImplemented Error, since int doesn't know how to add onto floats,
float(5).__add__(int(6)) # But this works!!
# Also, this is so interesting, I never thought about this
a + 2 # a.__add__(2) WORKS
2 + a # 2.__add__(a) DOESN'T WORK, unless you implement __radd__(self, other)
# so below works because #__radd__ is implemented when for the float values
5 + 11.0 

the __call__ method

class Neuron:
	def __call__(self, x):
n = Neuron(2)
n(x) # calls __call__

the zip function is actually super useful. Just in lecture 2 I am learning about using this function to print out the bigrams: With the zip, if any of the two inputs is shorter, it just stops, which is why this works.

for w in words:
	for ch1, ch2 in zip(w, w[1:]):
		print(ch1, ch2)

list(string) behaves differently than I thought. Say w = "emma", then list(w) == ['e', 'm', 'm', 'a']


Python is a really good scripting language, but the more I use Python for OOP, the more I dislike it. There is not strict typing, they do introduce the type thingy like this since like Python 3.8 (I believe?), but that doesn’t provide any optimization.

a: int = 5

Python is still fundamentally dynamically typed for everything, which makes it pretty slow and annoying and easy to make mistakes.

With C++, I already know all the types ahead of time, makes it easier to scale. George Hotz talked about this on a Lex Fridman podcast.

Scope Resolution

if __name__ == '__main__':
    x = 1
print x

python vs. sudo python

Ran into this super weird issue, where I need sudo permissions, but don’t want packages to install at the sudo level.

Intended target:


Target if you use sudo