In [ ]:
arbitrary_string = "Mike's Hello World"
In [ ]:
len(arbitrary_string) # You can type len() around anything that is a squence of things (strings, lists, etc.)
In [ ]:
20 # Typing a number itself with just print it back at you, same as a string.
In [ ]:
type(20) # In case you're wondering, the type of a real number is int.
In [ ]:
type(20.1) # But the type of a number with a decimal is float.
In [ ]:
a = 0 # When manipulating numeric data-types, they get "copied" as wholly seperate (tiny) objects in memory.
b = a
a = 1
print('b is still %s. That means b must have been a COPY of a.' % b)
In [ ]:
type(a), type(b)
In [ ]:
a = 0.5 # The rules about copying values in situations like this is true for either int's or floats.
b = a
a = 1.5
print('b is still %s. That means b must have been a COPY of a.' % b)
In [ ]:
a = ["I'm", 'missing', 'my', 'pop'] # Attempts to "copy" lists actually make references to original list in memory.
b = a
a.pop()
print("%s pop from the list, so b must reference the same in-memory list as a. It's NOT A COPY." % b)
In [ ]:
type(a), type(b) # It may not be immediately obvious, but a and be are references to the same list in memory.
In [ ]:
a = ["I'm", 'not', 'missing', 'my', 'pop'] # Use the .copy() method of lists, or the slice api to copy.
b = a.copy()
c = a[:]
a.pop()
print("%s so the b-list must have been an in-memory copy (duplicate) of the original list." % b)
print("%s so the c-list is likewise an in-memory copy (duplicate) of the original list." % c)
print("%s mind beause under Python, I can finally understand passing values by refrence vs. value." % a)
In [ ]:
a = ['three', 'two', 'one'] # Attempts to "copy" lists actually make references to original list in memory.
b = a
In [ ]:
a.pop(0)
In [ ]:
b.pop(0)
In [ ]:
a.pop(0)
In [ ]:
b.pop(0) # (error intentional)
In [ ]:
try:
b.pop(0)
except:
print('BOOM') # You can always make Python scripts keep running by trapping an error.
In [ ]:
try:
b.pop(0)
except Exception as e:
print(e) # You can display the Exception error message.
In [ ]:
try:
b.pop(0)
except Exception as e:
print(type(e).__name__) # Figuring out the name of the current Exception for later trapping is a wart on Python.
In [ ]:
try:
b.pop(0)
except IndexError:
print("Ah ha, I caught that specific error!") # But once you do figure it out, trapping errors can be very explicit.
In [ ]:
try:
b.add(1)
except IndexError:
print("Ah ha, I caught that specific error!")
except Exception as e:
catch_me = type(e).__name__
print("You now have to capture: %s" % catch_me) # See each untrapped exception name as it first occurs.
In [ ]:
print(e) # However, that "e" error object doesn't get outside its except-scope.
In [ ]:
if False:
new_var = 1
else:
new_var = 2 # In this case (unlike in a "try"), the variable new_var is ALWAYS defined. Scope can be funny.
print(new_var)
In [ ]:
starting_value = 1
if False:
starting_value = 2 # For good readability, declare variables outside if-statements, overriding obvious defaults.
print(starting_value)