| Floating Point Arithmetic | ||||||||
|
floats carry imprecision such imprecisioncan cause bugs print(.1 + .2 == .3) # Falseuse the math.isclose function can specify relative or absolute tolerance to use in comparison helps account for small inaccuracies when comparing floats import math
print(math.isclose(.1 + .2, .3)) # True
print(math.isclose(.1 + .2, .3, rel_tol=1e-9)) # True
print(math.isclose(.1 + .2, .3, abs_tol=1e-9)) # True
import decimal
print(decimal.Decimal('.1') + decimal.Decimal('.2') == decimal.Decimal('.3')) # True
use the decimal.Decimal('value') convert floats to decimals print(decimal.Decimal(.1) + decimal.Decimal(.2) == decimal.Decimal(.3)) # True |
||||||||
| Mutable Variables as Arguments | ||||||||
|
using mutable default arguments in functions can lead to unexpected behavior default argument is only evaluated once when the function is defined, not each time the function is called mutable value is shared among instances the list my_list is shared across all calls to add_to_list def add_to_list(value, my_list=[]):
my_list.append(value)
return my_list
print(add_to_list(1)) # [1]
print(add_to_list(2)) # [1, 2], not [2]
to avoid unwanted accumulation of values use None as the default value
def add_to_list(value, my_list=None):
if my_list is None:
my_list = []
my_list.append(value)
return my_list
print(add_to_list(1)) # [1]
print(add_to_list(2)) # [2]
each call to add_to_list gets a new list if one is not provided
|
||||||||
| Structural Pattern Matching | ||||||||
|
a common error is trying to match values and types below an instance is compared with a type match 10: # value
case int: # type
print("It's an int")
case _:
print("It's something else!")
# It's something else!
using int() correctly identifies the value as being of the int type
match 10:
case int():
print("It's an int")
case _:
print("It's something else!")
# It's an int
use float(), list() and dict() for other types
|