classes: tests and solutions
classes tests
the code from person/tests/test_person.py from classes
1import datetime
2import random
3import src.person
4import unittest
5
6
7def choose(*choices):
8 return random.choice(choices)
9
10
11def this_year():
12 return datetime.datetime.now().year
13
14
15def random_year_of_birth():
16 return random.randint(
17 this_year()-120, this_year()
18 )
19
20
21def get_age(year_of_birth):
22 return this_year() - year_of_birth
23
24
25class TestPerson(unittest.TestCase):
26
27 RANDOM_NAMES = (
28 'jane', 'joe', 'john', 'person',
29 'doe', 'smith', 'blow', 'public',
30 )
31
32 def setUp(self):
33 self.random_year_of_birth = random_year_of_birth()
34 self.random_new_year_of_birth = random_year_of_birth()
35 self.original_age = get_age(self.random_year_of_birth)
36 self.new_age = get_age(self.random_new_year_of_birth)
37 self.random_first_name = choose(*self.RANDOM_NAMES)
38 self.random_last_name = choose(*self.RANDOM_NAMES)
39 self.random_sex = choose('M', 'F')
40 self.random_factory_person = src.person.factory(
41 first_name=self.random_first_name,
42 last_name=self.random_last_name,
43 sex=self.random_sex,
44 year_of_birth=self.random_year_of_birth,
45 )
46 self.random_classy_person = src.person.Person(
47 first_name=self.random_first_name,
48 last_name=self.random_last_name,
49 sex=self.random_sex,
50 year_of_birth=self.random_year_of_birth,
51 )
52
53 def test_factory_takes_keyword_arguments(self):
54 self.assertEqual(
55 src.person.factory(
56 first_name=self.random_first_name,
57 last_name=self.random_last_name,
58 sex=self.random_sex,
59 year_of_birth=self.random_year_of_birth,
60 ),
61 self.random_factory_person
62 )
63
64 def test_factory_w_default_arguments(self):
65 self.assertEqual(
66 src.person.factory(
67 first_name=self.random_first_name,
68 year_of_birth=self.random_year_of_birth,
69 ),
70 dict(
71 first_name=self.random_first_name,
72 last_name='doe',
73 sex='M',
74 age=self.original_age,
75 )
76 )
77
78 def expected_greeting(self):
79 return (
80 f'Hi, my name is {self.random_first_name} '
81 f'{self.random_last_name} '
82 f'and I am {self.original_age}'
83 )
84
85 def test_factory_person_greeting(self):
86 self.assertEqual(
87 src.person.hello(self.random_factory_person),
88 self.expected_greeting()
89 )
90
91 def test_classy_person_greeting(self):
92 self.assertEqual(
93 self.random_classy_person.hello(),
94 self.expected_greeting()
95 )
96
97 def test_update_factory_person_year_of_birth(self):
98 self.assertEqual(
99 self.random_factory_person.get('age'),
100 self.original_age
101 )
102
103 with self.assertRaises(KeyError):
104 self.random_factory_person['year_of_birth']
105 self.assertEqual(
106 self.random_factory_person.setdefault(
107 'year_of_birth', self.random_new_year_of_birth
108 ),
109 self.random_new_year_of_birth
110 )
111 self.assertEqual(
112 self.random_factory_person.get('age'),
113 self.original_age
114 )
115
116 self.assertEqual(
117 src.person.update_year_of_birth(
118 self.random_factory_person,
119 self.random_new_year_of_birth
120 ),
121 dict(
122 first_name=self.random_first_name,
123 last_name=self.random_last_name,
124 sex=self.random_sex,
125 age=self.new_age
126 )
127 )
128
129 def test_update_classy_person_year_of_birth(self):
130 self.assertEqual(
131 self.random_classy_person.get_age(),
132 self.original_age
133 )
134
135 self.random_classy_person.year_of_birth = self.random_new_year_of_birth
136 self.assertEqual(
137 self.random_classy_person.get_age(),
138 self.new_age
139 )
140
141
142# Exceptions seen
143# AssertionError
144# NameError
145# AttributeError
146# TypeError
147# SyntaxError
classes solutions
the solutions in person/src/person.py from classes
1import datetime
2
3
4def this_year():
5 return datetime.datetime.today().year
6
7
8def factory(
9 first_name, year_of_birth,
10 last_name='doe', sex='M',
11 ):
12 return {
13 'first_name': first_name,
14 'last_name': last_name,
15 'sex': sex,
16 'age': this_year() - year_of_birth,
17 }
18
19
20def hello(person):
21 return (
22 f'Hi, my name is {person.get("first_name")} '
23 f'{person.get("last_name")} '
24 f'and I am {person.get("age")}'
25 )
26
27
28def update_year_of_birth(person, new_year_of_birth):
29 return factory(
30 first_name=person.get('first_name'),
31 last_name=person.get('last_name'),
32 sex=person.get('sex'),
33 year_of_birth=new_year_of_birth
34 )
35
36
37class Person:
38
39 def __init__(
40 self, first_name, last_name=None,
41 year_of_birth=None, sex=None,
42 ):
43 self.first_name = first_name
44 self.last_name = last_name
45 self.year_of_birth = year_of_birth
46 return None
47
48 def hello(self):
49 return (
50 f'Hi, my name is {self.first_name} '
51 f'{self.last_name} and I am {self.get_age()}'
52 )
53
54 def get_age(self):
55 return this_year() - self.year_of_birth
inheritance tests
the code from person/tests/test_classes.py from inheritance
1import unittest
2import src.classes
3import src.person
4
5
6class TestClasses(unittest.TestCase):
7
8 def test_making_a_class_w_pass(self):
9 self.assertIsInstance(src.classes.WPass(), object)
10
11 def test_making_a_class_w_parentheses(self):
12 self.assertIsInstance(src.classes.WParentheses(), object)
13
14 def test_making_a_class_w_object(self):
15 self.assertIsInstance(src.classes.WObject(), object)
16
17 def test_attributes_and_methods_of_objects(self):
18 self.assertEqual(
19 dir(object),
20 [
21 '__class__',
22 '__delattr__',
23 '__dir__',
24 '__doc__',
25 '__eq__',
26 '__format__',
27 '__ge__',
28 '__getattribute__',
29 '__getstate__',
30 '__gt__',
31 '__hash__',
32 '__init__',
33 '__init_subclass__',
34 '__le__',
35 '__lt__',
36 '__ne__',
37 '__new__',
38 '__reduce__',
39 '__reduce_ex__',
40 '__repr__',
41 '__setattr__',
42 '__sizeof__',
43 '__str__',
44 '__subclasshook__'
45 ]
46 )
47
48 def test_making_classes_w_inheritance(self):
49 self.assertIsInstance(
50 src.classes.Doe('doe'),
51 src.person.Person
52 )
53 self.assertEqual(
54 dir(src.classes.Doe),
55 dir(src.person.Person)
56 )
57
58 def test_family_ties(self):
59 doe = src.classes.Doe('doe')
60 jane = src.classes.Doe('jane')
61 john = src.classes.Doe('john')
62 mary = src.classes.Smith('mary')
63 joe = src.classes.Blow('joe')
64 baby = src.classes.Baby('baby')
65 lil = src.classes.Lil('lil')
66
67 self.assertEqual(doe.last_name, 'doe')
68 self.assertEqual(jane.last_name, 'doe')
69 self.assertEqual(john.last_name, 'doe')
70 self.assertEqual(mary.last_name, 'smith')
71 self.assertEqual(joe.last_name, 'blow')
72 self.assertEqual(baby.last_name, 'blow')
73 self.assertEqual(lil.last_name, 'doe')
74
75
76# Exceptions seen
77# AssertionError
inheritance solutions
the solutions in person/src/classes.py from inheritance
1import src.person
2
3
4class WPass:
5
6 pass
7
8
9class WParentheses():
10
11 pass
12
13
14class WObject(object):
15
16 pass
17
18
19class Doe(src.person.Person):
20
21 def __init__(self, first_name, last_name='doe'):
22 super().__init__(first_name, last_name)
23
24
25class Smith(src.person.Person):
26
27 def __init__(self, first_name, last_name='smith'):
28 super().__init__(first_name, last_name)
29
30
31class Blow(src.person.Person):
32
33 def __init__(self, first_name, last_name='blow'):
34 super().__init__(first_name, last_name)
35
36
37class Baby(Blow, Doe): pass
38
39
40class Lil(Doe, Smith): pass
booleans 4: tests
the code from booleans/tests/test_booleans.py from booleans 4: inheritance
1import unittest
2
3
4class TestBooleans(unittest.TestCase):
5
6 def test_what_is_false(self):
7 self.assertIsInstance(False, (bool, int))
8 self.assertNotIsInstance(False, float)
9 for false_item in (
10 False,
11 None, bool(None),
12 0, 0.0, bool(0), bool(0.0),
13 str(), bool(str()),
14 tuple(), bool(tuple()),
15 list(), bool(list()),
16 set(), bool(set()),
17 dict(), bool(dict()),
18 ):
19 with self.subTest(item=false_item):
20 self.assertFalse(false_item)
21
22 def test_what_is_true(self):
23 self.assertIsInstance(True, (bool, int))
24 self.assertNotIsInstance(True, float)
25
26 for true_item in (
27 True,
28 -1, bool(-1), 1, bool(1),
29 -0.1, bool(-0.1), 0.1, bool(0.1),
30 "text", bool("text"),
31 ((1, 2, 3, 'n')), bool((1, 2, 3, 'n')),
32 [1, 2, 3, 'n'], bool([1, 2, 3, 'n']),
33 {1, 2, 3, 'n'}, bool({1, 2, 3, 'n'}),
34 {'key': 'value'}, bool({'key': 'value'}),
35 ):
36 with self.subTest(item=true_item):
37 self.assertTrue(true_item)
38
39 def test_the_value_of_false(self):
40 self.assertEqual(False+1, 1)
41 self.assertEqual(False-1, -1)
42 self.assertEqual(False*1, 0)
43 with self.assertRaises(ZeroDivisionError):
44 1 / False
45
46 def test_the_value_of_true(self):
47 self.assertEqual(True+1, 2)
48 self.assertEqual(True-1, 0)
49 self.assertEqual(True*1, 1)
50 self.assertEqual(True/1, 1)
51
52 def test_if_bool_is_an_int(self):
53 self.assertNotIsInstance(bool, int)
54
55
56# NOTES
57# a dictionary with things is True
58# a set with things is True
59# a list with things is True
60# a tuple with things is True
61# a string with things is True
62# positive and negative numbers are True
63# True is True
64# True is not false
65# True is a boolean
66# True is an integer
67# True is not a float
68# True is 1
69# the empty dictionary is False
70# the empty set is False
71# the empty list is False
72# the empty tuple is False
73# the empty string is False
74# 0 is False
75# None is False
76# False is False
77# False is not true
78# False is a boolean
79# False is an integer
80# False is not a float
81# False is 0
82
83
84# Exceptions seen
85# AssertionError
how to make a calculator 8: tests
the code from calculator/tests/test_calculator.py from how to make a calculator 8
1import random
2import src.calculator
3import unittest
4
5
6def a_random_number():
7 return random.triangular(-1000.0, 1000.0)
8
9
10class TestCalculator(unittest.TestCase):
11
12 @staticmethod
13 def get_division_result(x, y):
14 try:
15 return x / y
16 except ZeroDivisionError:
17 return 'brmph?! I cannot divide by 0. Try again...'
18
19 def setUp(self):
20 self.random_first_number = a_random_number()
21 self.random_second_number = a_random_number()
22
23 x = self.random_first_number
24 y = self.random_second_number
25
26 self.calculator_tests = {
27 'add': x+y,
28 'subtract': x-y,
29 'multiply': x*y,
30 'divide': self.get_division_result(x, y)
31 }
32
33 def test_calculator_w_list_items(self):
34 # two_numbers = [
35 # self.random_first_number,
36 # self.random_second_number
37 # ]
38 a_dictionary = {
39 'x': self.random_first_number,
40 'y': self.random_second_number
41 }
42 two_numbers = list(a_dictionary.values())
43
44 for operation in self.calculator_tests:
45 with self.subTest(operation=operation):
46 self.assertEqual(
47 src.calculator.__getattribute__(operation)(
48 *two_numbers
49 ),
50 self.calculator_tests[operation]
51 )
52
53 self.assertEqual(
54 src.calculator.add(
55 two_numbers[0],
56 two_numbers[1]
57 ),
58 self.random_first_number+self.random_second_number
59 )
60 self.assertEqual(
61 src.calculator.divide(
62 two_numbers[-2],
63 two_numbers[-1]
64 ),
65 self.random_first_number/self.random_second_number
66 )
67 self.assertEqual(
68 src.calculator.multiply(
69 two_numbers[1],
70 two_numbers[-1]
71 ),
72 self.random_second_number*self.random_second_number
73 )
74 self.assertEqual(
75 src.calculator.subtract(
76 two_numbers[-2],
77 two_numbers[0]
78 ),
79 self.random_first_number-self.random_first_number
80 )
81
82 def test_calculator_w_dictionary_items(self):
83 two_numbers = {
84 'first_input': self.random_first_number,
85 'second_input': self.random_second_number,
86 }
87
88 for operation in self.calculator_tests:
89 with self.subTest(operation=operation):
90 self.assertEqual(
91 src.calculator.__getattribute__(operation)(
92 **two_numbers
93 ),
94 self.calculator_tests[operation]
95 )
96
97 self.assertEqual(
98 src.calculator.add(
99 two_numbers['first_input'],
100 two_numbers['second_input']
101 ),
102 self.random_first_number+self.random_second_number
103 )
104 self.assertEqual(
105 src.calculator.divide(
106 two_numbers['first_input'],
107 two_numbers['second_input']
108 ),
109 self.random_first_number/self.random_second_number
110 )
111 self.assertEqual(
112 src.calculator.multiply(
113 two_numbers['second_input'],
114 two_numbers['second_input']
115 ),
116 self.random_second_number*self.random_second_number
117 )
118 self.assertEqual(
119 src.calculator.subtract(
120 two_numbers['first_input'],
121 two_numbers['first_input']
122 ),
123 self.random_first_number-self.random_first_number
124 )
125
126 def test_calculator_raises_type_error_when_given_more_than_two_inputs(self):
127 for operation in self.calculator_tests:
128 with (
129 self.subTest(operation=operation),
130 self.assertRaises(TypeError),
131 ):
132 src.calculator.__getattribute__(operation)(
133 [0, 1, 2]
134 )
135
136 def test_calculator_sends_message_when_input_is_not_a_number(self):
137 for bad_input in (
138 None,
139 True, False,
140 str(), 'text',
141 tuple(), (0, 1, 2, 'n'),
142 list(), [0, 1, 2, 'n'],
143 set(), {0, 1, 2, 'n'},
144 dict(), {'key': 'value'},
145 ):
146 for operation in self.calculator_tests:
147 with self.subTest(
148 operation=operation,
149 bad_input=bad_input,
150 ):
151 self.assertEqual(
152 src.calculator.__getattribute__(operation)(
153 bad_input, a_random_number()
154 ),
155 'brmph?! Numbers only. Try again...'
156 )
157
158 def test_calculator_functions(self):
159 for operation in self.calculator_tests:
160 with self.subTest(operation=operation):
161 self.assertEqual(
162 src.calculator.__getattribute__(operation)(
163 self.random_first_number,
164 self.random_second_number
165 ),
166 self.calculator_tests[operation]
167 )
168
169
170# Exceptions seen
171# AssertionError
172# NameError
173# AttributeError
174# TypeError
175# KeyError
how to make a calculator 8: solutions
the solutions in calculator/src/calculator.py from how to make a calculator 8
1def check_input(function):
2 def wrapper(first_input, second_input):
3 if isinstance(
4 first_input,
5 (dict, set, list, tuple, str, bool)
6 ) or first_input is None:
7 return 'brmph?! Numbers only. Try again...'
8 return function(first_input, second_input)
9 return wrapper
10
11
12@check_input
13def add(first_input, second_input):
14 return first_input + second_input
15
16
17@check_input
18def divide(first_input, second_input):
19 return first_input / second_input
20
21
22@check_input
23def multiply(first_input, second_input):
24 return first_input * second_input
25
26
27@check_input
28def subtract(first_input, second_input):
29 return first_input - second_input