import math
deff():
print("This is a user-defined function")
return42
print("Some basic types in Python:")
print(type(2)) # int
print(type(2.2)) # float
print(type(2 < 2.2)) # bool (boolean)
print(type(type(42))) # type
print("#####################################################")
print("And some other types we may see later in the course...")
print(type("2.2")) # str (string or text)
print(type([1,2,3])) # list
print(type((1,2,3))) # tuple
print(type({1,2})) # set
print(type({1:42})) # dict (dictionary or map)
print(type(2+3j)) # complex (complex number)
print(type(f)) # A function is also a value!
Some Builtin Constants
print("Some builtin constants:")
print(True)
print(False)
print(None)
print("And some more constants in the math module:")
import math
print(math.pi)
print(math.e)
print("Precedence:")
print(2+3*4) # prints 14, not 20
print(5+4%3) # prints 6, not 0 (% has same precedence as *, /, and //)
print(2**3*4) # prints 32, not 4096 (** has higher precedence than *, /, //, and %)
print()
print("Associativity:")
print(5-4-3) # prints -2, not 4 (- associates left-to-right)
print(4**3**2) # prints 262144, not 4096 (** associates right-to-left)
print("The problem....")
d1 = 0.1 + 0.1 + 0.1
d2 = 0.3
print(d1 == d2) # False (never use == with floats!)
print()
print("The solution...")
epsilon = 10**-10
print(abs(d2 - d1) < epsilon) # True!
print()
print("Once again, using a useful helper function, almostEqual:")
defalmostEqual(d1, d2):
epsilon = 10**-10return (abs(d2 - d1) < epsilon)
d1 = 0.1 + 0.1 + 0.1
d2 = 0.3
print(d1 == d2) # still False, of course
print(almostEqual(d1, d2)) # True, and now packaged in a handy reusable function!
Short-Circuit Evaluation
defyes():returnTruedefno():returnFalsedefcrash():return1/0# crashes!
print(no() and crash()) # Works!
print(crash() and no()) # Crashes!print (yes() and crash()) # Never runs (due to crash), but would also crash (without short-circuiting)
Once again, using the "or" operator:
defyes():returnTruedefno():returnFalsedefcrash():return1/0# crashes!
print(yes() or crash()) # Works!
print(crash() or yes()) # Crashes!
print(no() or crash()) # Never runs (due to crash), but would also crash (without short-circuiting)
Yet another example:
defisPositive(n):
result = (n > 0)
print("isPositive(",n,") =", result)
return result
defisEven(n):
result = (n % 2 == 0)
print("isEven(",n,") =", result)
return result
print("Test 1: isEven(-4) and isPositive(-4))")
print(isEven(-4) and isPositive(-4)) # Calls both functions
print("----------")
print("Test 2: isEven(-3) and isPositive(-3)")
print(isEven(-3) and isPositive(-3)) # Calls only one function!
type vs isinstance
# Both type and isinstance can be used to type-check# In general, (isinstance(x, T)) will be more robust than (type(x) == T)
print(type("abc") == str)
print(isinstance("abc", str))
# We'll see better reasons for this when we cover OOP + inheritance later# in the course. For now, here is one reason: say you wanted to check# if a value is any kind of number (int, float, complex, etc). # You could do:defisNumber(x):return ((type(x) == int) or
(type(x) == float)) # are we sure this is ALL kinds of numbers?
print(isNumber(1), isNumber(1.1), isNumber(1+2j), isNumber("wow"))
# But this is cleaner, and works for all kinds of numbers, including# complex numbers for example:import numbers
defisNumber(x):return isinstance(x, numbers.Number) # works for any kind of number
print(isNumber(1), isNumber(1.1), isNumber(1+2j), isNumber("wow"))