diff --git a/ch03/any.py b/ch03/any.py new file mode 100644 index 0000000..bef25c5 --- /dev/null +++ b/ch03/any.py @@ -0,0 +1,13 @@ +items = [0, None, 0.0, True, 0, 7] # True and 7 evaluate to True + +found = False # this is called "flag" +for item in items: + print('scanning item', item) + if item: + found = True # we update the flag + break + +if found: # we inspect the flag + print('At least one item evaluates to True') +else: + print('All items evaluate to False') diff --git a/ch03/binary.2.py b/ch03/binary.2.py new file mode 100644 index 0000000..b2377d0 --- /dev/null +++ b/ch03/binary.2.py @@ -0,0 +1,8 @@ +n = 39 +remainders = [] +while n > 0: + n, remainder = divmod(n, 2) + remainders.append(remainder) + +remainders.reverse() +print(remainders) diff --git a/ch03/binary.py b/ch03/binary.py new file mode 100644 index 0000000..e42da20 --- /dev/null +++ b/ch03/binary.py @@ -0,0 +1,17 @@ +""" +6 / 2 = 3 (remainder: 0) +3 / 2 = 1 (remainder: 1) +1 / 2 = 0 (remainder: 1) +List of remainders: 0, 1, 1. +Reversed is 1, 1, 0, which is also the binary repres. of 6: 110 +""" + +n = 39 +remainders = [] +while n > 0: + remainder = n % 2 # remainder of division by 2 + remainders.append(remainder) # we keep track of remainders + n //= 2 # we divide n by 2 + +remainders.reverse() +print(remainders) diff --git a/ch03/compress.py b/ch03/compress.py new file mode 100644 index 0000000..d49d3c7 --- /dev/null +++ b/ch03/compress.py @@ -0,0 +1,12 @@ +from itertools import compress +data = range(10) +even_selector = [1, 0] * 10 +odd_selector = [0, 1] * 10 + +even_numbers = list(compress(data, even_selector)) +odd_numbers = list(compress(data, odd_selector)) + +print(odd_selector) +print(list(data)) +print(even_numbers) +print(odd_numbers) diff --git a/ch03/conditional.1.py b/ch03/conditional.1.py new file mode 100644 index 0000000..29dd5ed --- /dev/null +++ b/ch03/conditional.1.py @@ -0,0 +1,3 @@ +late = True +if late: + print('I need to call my manager!') diff --git a/ch03/conditional.2.py b/ch03/conditional.2.py new file mode 100644 index 0000000..30bebf9 --- /dev/null +++ b/ch03/conditional.2.py @@ -0,0 +1,5 @@ +late = False +if late: + print('I need to call my manager!') #1 +else: + print('no need to call my manager...') #2 diff --git a/ch03/coupons.dict.py b/ch03/coupons.dict.py new file mode 100644 index 0000000..cd98791 --- /dev/null +++ b/ch03/coupons.dict.py @@ -0,0 +1,19 @@ +customers = [ + dict(id=1, total=200, coupon_code='F20'), # F20: fixed, £20 + dict(id=2, total=150, coupon_code='P30'), # P30: percent, 30% + dict(id=3, total=100, coupon_code='P50'), # P50: percent, 50% + dict(id=4, total=110, coupon_code='F15'), # F15: fixed, £15 +] +discounts = { + 'F20': (0.0, 20.0), # each value is (percent, fixed) + 'P30': (0.3, 0.0), + 'P50': (0.5, 0.0), + 'F15': (0.0, 15.0), +} +for customer in customers: + code = customer['coupon_code'] + percent, fixed = discounts.get(code, (0.0, 0.0)) + customer['discount'] = percent * customer['total'] + fixed + +for customer in customers: + print(customer['id'], customer['total'], customer['discount']) diff --git a/ch03/coupons.py b/ch03/coupons.py new file mode 100644 index 0000000..eb7fd81 --- /dev/null +++ b/ch03/coupons.py @@ -0,0 +1,21 @@ +customers = [ + dict(id=1, total=200, coupon_code='F20'), # F20: fixed, £20 + dict(id=2, total=150, coupon_code='P30'), # P30: percent, 30% + dict(id=3, total=100, coupon_code='P50'), # P50: percent, 50% + dict(id=4, total=110, coupon_code='F15'), # F15: fixed, £15 +] +for customer in customers: + code = customer['coupon_code'] + if code == 'F20': + customer['discount'] = 20.0 + elif code == 'F15': + customer['discount'] = 15.0 + elif code == 'P30': + customer['discount'] = customer['total'] * 0.3 + elif code == 'P50': + customer['discount'] = customer['total'] * 0.5 + else: + customer['discount'] = 0.0 + +for customer in customers: + print(customer['id'], customer['total'], customer['discount']) diff --git a/ch03/discount.py b/ch03/discount.py new file mode 100644 index 0000000..25b2411 --- /dev/null +++ b/ch03/discount.py @@ -0,0 +1,17 @@ +from datetime import date, timedelta + +today = date.today() +tomorrow = today + timedelta(days=1) # today + 1 day is tomorrow +products = [ + {'sku': '1', 'expiration_date': today, 'price': 100.0}, + {'sku': '2', 'expiration_date': tomorrow, 'price': 50}, + {'sku': '3', 'expiration_date': today, 'price': 20}, +] + +for product in products: + if product['expiration_date'] != today: + continue + product['price'] *= 0.8 # equivalent to applying 20% discount + print( + 'Price for sku', product['sku'], + 'is now', product['price']) diff --git a/ch03/errorsalert.py b/ch03/errorsalert.py new file mode 100644 index 0000000..80a6358 --- /dev/null +++ b/ch03/errorsalert.py @@ -0,0 +1,18 @@ +# The send_email function is defined here to enable you to play with +# code, but of course it doesn't send an actual email. +def send_email(*a): + print (*a) + +alert_system = 'console' # other value can be 'email' +error_severity = 'critical' # other values: 'medium' or 'low' +error_message = 'OMG! Something terrible happened!' + +if alert_system == 'console': + print(error_message) #1 +elif alert_system == 'email': + if error_severity == 'critical': + send_email('admin@example.com', error_message) #2 + elif error_severity == 'medium': + send_email('support.1@example.com', error_message) #3 + else: + send_email('support.2@example.com', error_message) #4 diff --git a/ch03/for.else.py b/ch03/for.else.py new file mode 100644 index 0000000..41f2d01 --- /dev/null +++ b/ch03/for.else.py @@ -0,0 +1,11 @@ +class DriverException(Exception): + pass + + +people = [('James', 17), ('Kirk', 9), ('Lars', 13), ('Robert', 8)] +for person, age in people: + if age >= 18: + driver = (person, age) + break +else: + raise DriverException('Driver not found.') diff --git a/ch03/for.no.else.py b/ch03/for.no.else.py new file mode 100644 index 0000000..fd74bac --- /dev/null +++ b/ch03/for.no.else.py @@ -0,0 +1,13 @@ +class DriverException(Exception): + pass + + +people = [('James', 17), ('Kirk', 9), ('Lars', 13), ('Robert', 8)] +driver = None +for person, age in people: + if age >= 18: + driver = (person, age) + break + +if driver is None: + raise DriverException('Driver not found.') diff --git a/ch03/infinite.py b/ch03/infinite.py new file mode 100644 index 0000000..ede3107 --- /dev/null +++ b/ch03/infinite.py @@ -0,0 +1,8 @@ +from itertools import count + +for n in count(5, 3): + if n > 20: + break + print(n, end=', ') # instead of newline, comma and space + +print() diff --git a/ch03/menu.no.walrus.py b/ch03/menu.no.walrus.py new file mode 100644 index 0000000..536abf1 --- /dev/null +++ b/ch03/menu.no.walrus.py @@ -0,0 +1,13 @@ +flavors = ["pistachio", "malaga", "vanilla", "chocolate", "strawberry"] +prompt = "Choose your flavor: " + +print(flavors) + +while True: + choice = input(prompt) + if choice in flavors: + break + + print(f"Sorry, '{choice}' is not a valid option.") + +print(f"You chose '{choice}'.") diff --git a/ch03/menu.walrus.py b/ch03/menu.walrus.py new file mode 100644 index 0000000..8b1806e --- /dev/null +++ b/ch03/menu.walrus.py @@ -0,0 +1,9 @@ +flavors = ["pistachio", "malaga", "vanilla", "chocolate", "strawberry"] +prompt = "Choose your flavor: " + +print(flavors) + +while (choice := input(prompt)) not in flavors: + print(f"Sorry, '{choice}' is not a valid option.") + +print(f"You chose '{choice}'.") diff --git a/ch03/multiple.sequences.enumerate.py b/ch03/multiple.sequences.enumerate.py new file mode 100644 index 0000000..621e4ff --- /dev/null +++ b/ch03/multiple.sequences.enumerate.py @@ -0,0 +1,5 @@ +people = ['Nick', 'Rick', 'Roger', 'Syd'] +ages = [23, 24, 23, 21] +for position, person in enumerate(people): + age = ages[position] + print(person, age) diff --git a/ch03/multiple.sequences.explicit.py b/ch03/multiple.sequences.explicit.py new file mode 100644 index 0000000..b8e2aed --- /dev/null +++ b/ch03/multiple.sequences.explicit.py @@ -0,0 +1,5 @@ +people = ['Nick', 'Rick', 'Roger', 'Syd'] +ages = [23, 24, 23, 21] +instruments = ['Drums', 'Keyboards', 'Bass', 'Guitar'] +for person, age, instrument in zip(people, ages, instruments): + print(person, age, instrument) diff --git a/ch03/multiple.sequences.implicit.py b/ch03/multiple.sequences.implicit.py new file mode 100644 index 0000000..b1a3c91 --- /dev/null +++ b/ch03/multiple.sequences.implicit.py @@ -0,0 +1,6 @@ +people = ['Nick', 'Rick', 'Roger', 'Syd'] +ages = [23, 24, 23, 21] +instruments = ['Drums', 'Keyboards', 'Bass', 'Guitar'] +for data in zip(people, ages, instruments): + person, age, instrument = data + print(person, age, instrument) diff --git a/ch03/multiple.sequences.py b/ch03/multiple.sequences.py new file mode 100644 index 0000000..6bf71ed --- /dev/null +++ b/ch03/multiple.sequences.py @@ -0,0 +1,6 @@ +people = ['Nick', 'Rick', 'Roger', 'Syd'] +ages = [23, 24, 23, 21] +for position in range(len(people)): + person = people[position] + age = ages[position] + print(person, age) diff --git a/ch03/multiple.sequences.while.py b/ch03/multiple.sequences.while.py new file mode 100644 index 0000000..723fa9a --- /dev/null +++ b/ch03/multiple.sequences.while.py @@ -0,0 +1,8 @@ +people = ['Nick', 'Rick', 'Roger', 'Syd'] +ages = [23, 24, 23, 21] +position = 0 +while position < len(people): + person = people[position] + age = ages[position] + print(person, age) + position += 1 diff --git a/ch03/multiple.sequences.zip.py b/ch03/multiple.sequences.zip.py new file mode 100644 index 0000000..5b95b95 --- /dev/null +++ b/ch03/multiple.sequences.zip.py @@ -0,0 +1,4 @@ +people = ['Nick', 'Rick', 'Roger', 'Syd'] +ages = [23, 24, 23, 21] +for person, age in zip(people, ages): + print(person, age) diff --git a/ch03/permutations.py b/ch03/permutations.py new file mode 100644 index 0000000..95f1af8 --- /dev/null +++ b/ch03/permutations.py @@ -0,0 +1,2 @@ +from itertools import permutations +print(list(permutations('ABC'))) diff --git a/ch03/primes.else.py b/ch03/primes.else.py new file mode 100644 index 0000000..8263cad --- /dev/null +++ b/ch03/primes.else.py @@ -0,0 +1,10 @@ +primes = [] +upto = 100 +for n in range(2, upto + 1): + for divisor in range(2, n): + if n % divisor == 0: + break + else: + primes.append(n) + +print(primes) diff --git a/ch03/primes.py b/ch03/primes.py new file mode 100644 index 0000000..a0e3f5a --- /dev/null +++ b/ch03/primes.py @@ -0,0 +1,12 @@ +primes = [] # this will contain the primes in the end +upto = 100 # the limit, inclusive +for n in range(2, upto + 1): + is_prime = True # flag, new at each iteration of outer for + for divisor in range(2, n): + if n % divisor == 0: + is_prime = False + break + if is_prime: # check on flag + primes.append(n) + +print(primes) diff --git a/ch03/range.py b/ch03/range.py new file mode 100644 index 0000000..ef5ada2 --- /dev/null +++ b/ch03/range.py @@ -0,0 +1,6 @@ +>>> list(range(10)) # one value: from 0 to value (excluded) +[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] +>>> list(range(3, 8)) # two values: from start to stop (excluded) +[3, 4, 5, 6, 7] +>>> list(range(-10, 10, 4)) # three values: step is added +[-10, -6, -2, 2, 6] diff --git a/ch03/simple.for.2.py b/ch03/simple.for.2.py new file mode 100644 index 0000000..5882226 --- /dev/null +++ b/ch03/simple.for.2.py @@ -0,0 +1,4 @@ +surnames = ['Rivest', 'Shamir', 'Adleman'] +for position in range(len(surnames)): + print(position, surnames[position]) + # print(surnames[position][0], end='') # try swapping prints diff --git a/ch03/simple.for.3.py b/ch03/simple.for.3.py new file mode 100644 index 0000000..f3333fc --- /dev/null +++ b/ch03/simple.for.3.py @@ -0,0 +1,3 @@ +surnames = ['Rivest', 'Shamir', 'Adleman'] +for surname in surnames: + print(surname) diff --git a/ch03/simple.for.4.py b/ch03/simple.for.4.py new file mode 100644 index 0000000..4b9b74a --- /dev/null +++ b/ch03/simple.for.4.py @@ -0,0 +1,3 @@ +surnames = ['Rivest', 'Shamir', 'Adleman'] +for position, surname in enumerate(surnames): + print(position, surname) diff --git a/ch03/simple.for.py b/ch03/simple.for.py new file mode 100644 index 0000000..9a9ccdf --- /dev/null +++ b/ch03/simple.for.py @@ -0,0 +1,7 @@ +for number in [0, 1, 2, 3, 4]: + print(number) + + +# equivalent using range +for number in range(5): + print(number) diff --git a/ch03/switch.js b/ch03/switch.js new file mode 100644 index 0000000..038cae7 --- /dev/null +++ b/ch03/switch.js @@ -0,0 +1,18 @@ +switch (day_number) { + case 1: + case 2: + case 3: + case 4: + case 5: + day = "Weekday"; + break; + case 6: + day = "Saturday"; + break; + case 0: + day = "Sunday"; + break; + default: + day = ""; + alert(day_number + ' is not a valid day number.') +} diff --git a/ch03/switch.py b/ch03/switch.py new file mode 100644 index 0000000..34b49fe --- /dev/null +++ b/ch03/switch.py @@ -0,0 +1,11 @@ +# this code is not supposed to be run +if 1 <= day_number <= 5: + day = 'Weekday' +elif day_number == 6: + day = 'Saturday' +elif day_number == 0: + day = 'Sunday' +else: + day = '' + raise ValueError( + str(day_number) + ' is not a valid day number.') diff --git a/ch03/taxes.py b/ch03/taxes.py new file mode 100644 index 0000000..30d82b6 --- /dev/null +++ b/ch03/taxes.py @@ -0,0 +1,11 @@ +income = 15000 +if income < 10000: + tax_coefficient = 0.0 #1 +elif income < 30000: + tax_coefficient = 0.2 #2 +elif income < 100000: + tax_coefficient = 0.35 #3 +else: + tax_coefficient = 0.45 #4 + +print(f'You will pay: ${income * tax_coefficient} in taxes') diff --git a/ch03/ternary.py b/ch03/ternary.py new file mode 100644 index 0000000..1a7e796 --- /dev/null +++ b/ch03/ternary.py @@ -0,0 +1,12 @@ +order_total = 247 # GBP + +# classic if/else form +if order_total > 100: + discount = 25 # GBP +else: + discount = 0 # GBP +print(order_total, discount) + +# ternary operator +discount = 25 if order_total > 100 else 0 +print(order_total, discount) diff --git a/ch03/walrus.if.py b/ch03/walrus.if.py new file mode 100644 index 0000000..83adfd8 --- /dev/null +++ b/ch03/walrus.if.py @@ -0,0 +1,12 @@ +value = 42 +modulus = 11 + +# Without assignment expression: +remainder = value % modulus +if remainder: + print(f"Not divisible! The remainder is {remainder}.") + + +# Rewritten with assignment expression: +if remainder := value % modulus: + print(f"Not divisible! The remainder is {remainder}.")