1import unittest
2
3import solution
4
5
6class TestSanity(unittest.TestCase):
7 """Check if all of the classes are present."""
8
9 def test_concrete(self):
10 self.assertIn('Concrete', dir(solution), 'Убеди се, че класът "Concrete" е наличен с точно това име.')
11 self.assertTrue(isinstance(solution.Concrete, type), 'Убеди се, че "Concrete" е клас.')
12
13 def test_brick(self):
14 self.assertIn('Brick', dir(solution), 'Убеди се, че класът "Brick" е наличен с точно това име.')
15 self.assertTrue(isinstance(solution.Brick, type), 'Убеди се, че "Brick" е клас.')
16
17 def test_stone(self):
18 self.assertIn('Stone', dir(solution), 'Убеди се, че класът "Stone" е наличен с точно това име.')
19 self.assertTrue(isinstance(solution.Stone, type), 'Убеди се, че "Stone" е клас.')
20
21 def test_wood(self):
22 self.assertIn('Wood', dir(solution), 'Убеди се, че класът "Wood" е наличен с точно това име.')
23 self.assertTrue(isinstance(solution.Wood, type), 'Убеди се, че "Wood" е клас.')
24
25 def test_steel(self):
26 self.assertIn('Steel', dir(solution), 'Убеди се, че класът "Steel" е наличен с точно това име.')
27 self.assertTrue(isinstance(solution.Steel, type), 'Убеди се, че "Steel" е клас.')
28
29 def test_factory(self):
30 self.assertIn('Factory', dir(solution), 'Убеди се, че класът "Factory" е наличен с точно това име.')
31 self.assertTrue(isinstance(solution.Factory, type), 'Убеди се, че "Factory" е клас.')
32
33
34if __name__ == '__main__':
35 unittest.main()
1import unittest
2from importlib import reload
3
4import solution
5
6
7class TestMaterials(unittest.TestCase):
8 """Test the material classes."""
9
10 def test_materials(self):
11 """Test the material classes instances and properties."""
12 # Material 1
13 self.assertAlmostEqual(solution.Concrete(2500).volume, 1.0, places=1)
14 self.assertAlmostEqual(solution.Concrete(3750).volume, 1.5, places=1)
15 # Material 2
16 self.assertAlmostEqual(solution.Brick(2000).volume, 1.0, places=1)
17 self.assertAlmostEqual(solution.Brick(3000).volume, 1.5, places=1)
18 # Material 3
19 self.assertAlmostEqual(solution.Stone(1600).volume, 1.0, places=1)
20 self.assertAlmostEqual(solution.Stone(2400).volume, 1.5, places=1)
21 # Material 4
22 self.assertAlmostEqual(solution.Wood(600).volume, 1.0, places=1)
23 self.assertAlmostEqual(solution.Wood(900).volume, 1.5, places=1)
24 # Material 5
25 self.assertAlmostEqual(solution.Steel(7700).volume, 1.0, places=1)
26 self.assertAlmostEqual(solution.Steel(11550).volume, 1.5, places=1)
27
28
29class TestFactory(unittest.TestCase):
30 """Test the factory class."""
31
32 def setUp(self):
33 """Create isntances to be used by test cases."""
34 self.factory1 = solution.Factory()
35 self.factory2 = solution.Factory()
36
37 def tearDown(self):
38 """Reload the Factory class."""
39 del self.factory1
40 del self.factory2
41 reload(solution)
42
43 def test_bad_input(self):
44 """Test calling a factory using bad input."""
45 # Calling with no arguments
46 with self.assertRaises(ValueError):
47 self.factory1()
48 # Calling with mixed arguments
49 brick = solution.Brick(2000)
50 with self.assertRaises(ValueError):
51 self.factory1(brick, Brick=1)
52 # Calling with invalid name for an argument
53 with self.assertRaises(ValueError):
54 self.factory1(NotExisting=1)
55
56 def test_named_arguments(self):
57 """Test calling a factory using named arguments."""
58 # Calling with single argument
59 result = self.factory1(Concrete=1)
60 self.assertIs(type(result), tuple)
61 self.assertIs(type(result[0]), solution.Concrete)
62 # Calling with multiple arguments
63 result = self.factory1(Concrete=1, Brick=2, Stone=3, Wood=4, Steel=5)
64 self.assertIs(type(result), tuple)
65 self.assertIs(type(result[0]), solution.Concrete)
66 self.assertIs(type(result[1]), solution.Brick)
67 self.assertIs(type(result[2]), solution.Stone)
68 self.assertIs(type(result[3]), solution.Wood)
69 self.assertIs(type(result[4]), solution.Steel)
70 self.assertAlmostEqual(result[0].volume, 0.0004, places=4)
71 self.assertAlmostEqual(result[1].volume, 0.0010, places=4)
72 self.assertAlmostEqual(result[2].volume, 0.0019, places=4)
73 self.assertAlmostEqual(result[3].volume, 0.0067, places=4)
74 self.assertAlmostEqual(result[4].volume, 0.00065, places=5)
75
76 def test_positional_arguments_single_argument(self):
77 """Test calling a factory using a sigle positional argument."""
78 concrete1, = self.factory1(Concrete=5000)
79 concrete2 = self.factory1(concrete1)
80 self.assertIs(type(concrete2), solution.Concrete)
81 self.assertEqual(concrete2.volume, 2.0)
82 # Ensure the material cannot be used again
83 with self.assertRaises(AssertionError):
84 self.factory1(concrete1)
85
86 def test_positional_arguments_multiple_argument_from_initial_set(self):
87 """Test calling a factory using multiple positional arguments.
88
89 Only using the original 5 materials.
90 """
91 wood, concrete, brick = self.factory1(Wood=1200, Concrete=5000,
92 Brick=4000)
93 result = self.factory1(wood, brick, concrete)
94 self.assertEqual(result.__class__.__name__, 'Brick_Concrete_Wood')
95 self.assertEqual(result.volume, 6.0) # Density=1700, mass=10200
96 # Ensure the new class expects mass and calculates correct volume
97 brick_concrete_wood = type(result)(1700)
98 self.assertEqual(brick_concrete_wood.volume, 1.0)
99 # Ensure the materials cannot be reused
100 steel, = self.factory1(Steel=1)
101 with self.assertRaises(AssertionError):
102 self.factory1(wood, steel)
103 steel, = self.factory1(Steel=1)
104 with self.assertRaises(AssertionError):
105 self.factory1(concrete, steel)
106 steel, = self.factory1(Steel=1)
107 with self.assertRaises(AssertionError):
108 self.factory1(brick, steel)
109 # Ensure that attempting to create an alloy with only one
110 # expended material does not affect the other ones
111 wood, concrete, brick = self.factory1(Wood=9001, Concrete=5000,
112 Brick=1200)
113 _ = self.factory1(brick)
114 with self.assertRaises(AssertionError):
115 _ = self.factory1(wood, concrete, brick) # Brick is expended
116 concrete_wood = self.factory1(concrete, wood)
117
118 def test_positional_arguments_multiple_argument_with_dynamics(self):
119 """Test calling a factory using multiple positional arguments.
120
121 Using dynamicaly created classes.
122 """
123 materials = self.factory1(Stone=1600, Concrete=5000, Brick=4000)
124 brick_concrete_stone = self.factory1(*materials)
125 self.assertAlmostEqual(brick_concrete_stone.volume, 5.2131, places=4)
126 steel, wood = self.factory1(Steel=7700, Wood=1200)
127 mega_material = self.factory1(steel, brick_concrete_stone, wood)
128 self.assertEqual(mega_material.__class__.__name__,
129 'Brick_Concrete_Steel_Stone_Wood')
130 self.assertAlmostEqual(mega_material.volume, 6.77, places=2) # mass=19500, density=2880
131
132 def test_positional_arguments_singletons(self):
133 """Test dynamically created classes uniqueness."""
134 materials1 = self.factory1(Wood=1200, Concrete=5000, Brick=4000)
135 brick_concrete_wood1 = self.factory1(*materials1)
136 materials2 = self.factory1(Wood=1, Concrete=2, Brick=3)
137 brick_concrete_wood2 = self.factory1(*materials2)
138 self.assertIs(type(brick_concrete_wood1), type(brick_concrete_wood2))
139
140 def test_named_arguments_with_dynamically_created_classes(self):
141 """Test dynamically created classes uniqueness."""
142 materials = self.factory1(Wood=1200, Concrete=5000, Brick=4000,
143 Steel=7700, Stone=1600)
144 result1 = self.factory1(*materials)
145 result2, = self.factory1(Brick_Concrete_Steel_Stone_Wood=2)
146 self.assertEqual(result1.__class__.__name__,
147 'Brick_Concrete_Steel_Stone_Wood')
148 self.assertIs(type(result1), type(result2))
149
150 def test_materials_between_factories(self):
151 """Test materials sharing."""
152 # Test sharing a new class
153 materials = self.factory1(Wood=1200, Concrete=5000, Brick=4000,
154 Steel=7700, Stone=1600)
155 result1 = self.factory1(*materials)
156 result2, = self.factory2(Brick_Concrete_Steel_Stone_Wood=2)
157 self.assertIs(type(result1), type(result2))
158 # Test sharing reusing status
159 wood, = self.factory1(Wood=1200)
160 self.factory1(wood)
161 with self.assertRaises(AssertionError):
162 self.factory2(wood)
163
164 def test_can_build(self):
165 """Test can_build methods."""
166 # Create volume=2 from factory1, reusing materials to ensure
167 # the obsolete status is taken into account.
168 concrete, steel = self.factory1(Concrete=2500, Steel=7700)
169 # Create volume=4 from factory2, reusing materials to ensure
170 # the obsolete status is taken into account.
171 brick, wood = self.factory2(Wood=1200, Brick=4000)
172 brick_wood = self.factory2(brick, wood)
173 self.assertFalse(self.factory1.can_build(2.000001))
174 self.assertTrue(self.factory1.can_build(2.0))
175 self.assertFalse(self.factory2.can_build(4.0001))
176 self.assertTrue(self.factory2.can_build(4.0))
177 self.assertFalse(solution.Factory.can_build_together(6.0001))
178 self.assertTrue(self.factory2.can_build_together(6.0))
179
180
181if __name__ == '__main__':
182 unittest.main()
Ивана Димитрова
24.11.2024 18:30Здравейте.
Необходимо ли е да се правят валидации и проверки, когато подаваме число, отговарящо за масата на материал, в инициализатора и дали въобще подаваме число от тип int, и ако е int, трябва ли да проверяваме дали е положително?
| |
Стефан Шиваров
21.11.2024 14:41Ако от някое factory1 се пробваме да направим сплав от вече създаден от това factory1 материал и друг материал създаден от друго factory2, трябва ли да прибавяме нещо към обема за factory1?
Пример:
```py
factory1 = Factory()
brick1, wood1 = factory1(Brick=2000, Wood=1000)
factory2 = Factory()
steel2 = factory2(Steel=1000)
brick_steel = factory1(brick1, steel2)
```
В случая brick1 ще се води като преизползван материал за factory1, но steel2 не e използван от factory1. Да разбирам, че понеже steel2 е използван вече от друго фактори, то тогава и двата ги считам за преизползвани, следователно не променям сумата на volume за факторито? Тогава при сплавите няма смисъл да се добавя нищо към общия обем?
Нишка
| |
Павел Петков
21.11.2024 10:23```
factory2 = Factory()
brick2, wood2 = factory2(Brick=2000, Wood=1200)
print(brick2.volume) # 1.0
print(wood2.volume) # 2.0
brick_wood2 = factory2(brick2, wood2)
print(brick_wood2.volume) # 2.46
```
Заради този пример направих така че да се форматира отговора до 2 десетичен знак, защото реалният отговор е 2.4615384615384617.
Написах го като коментар, че не съм сигурен дали трябва, тоест този print трябва да изкара 2.4615384615384617 или 2.46 или няма значение, защото използваме self.assertAlmostEqual, и ако ползвам self.assertAlmostEqual трябва да кажа колко знака след десетичната запетая искам, защото в противен случай пак няма да работи коректно.
Нишка
| |
Ивайло Кънчев
21.11.2024 01:45Ако на фактори подадем един валиден и един невалиден обект, след хвърляне на грешка валидният обект си остава валиден, нали? И също така форматирането на обема до 2рия знак след запетайката ли трябва да е?
Нишка
| |
Йоан Байчев
21.11.2024 00:21Предвид уточнението, че инстанции на новосъздадените сплави могат да се създават само чрез обекта Factory и не са достъпни глобално, все още ли е валиден граничният случай за "Използване на материали между различни фабрики"?
Нишка
| |
Василена Станойска
20.11.2024 18:05Здравейте. Когато изчисляваме новата плътност, трябва ли да връщаме цяло число, или може да бъде и float?
Нишка | |
Николай Стоянов
20.11.2024 17:51Здравейте!
Когато създадем нова сплав, очаква ли се да можем да създадем инстанция от новия клас в глобалния scope или е приемливо това да става само от Factory обект?
Нишка
| |
Павел Петков
20.11.2024 15:36Направих лека промяна в тестовете, за да не прави проблеми при десетичните запетаи
```
import unittest
from fourth_homework import *
class BaseMaterialsTests(unittest.TestCase):
"""
in these tests expected_density is mass and all check if expected_density/mass == 1.0
also they test decimal places for volume
"""
def setUp(self) -> None:
self.factory = Factory()
def test_density_for_concrete(self):
expected_density = 2500
concrete, = self.factory(Concrete=expected_density)
self.assertEqual(concrete.volume, 1.0)
def test_density_for_brick(self):
expected_density = 2000
brick, = self.factory(Brick=expected_density)
self.assertEqual(brick.volume, 1.0)
def test_density_for_stone(self):
expected_density = 1600
stone, = self.factory(Stone=expected_density)
self.assertEqual(stone.volume, 1.0)
def test_density_for_wood(self):
expected_density = 600
wood, = self.factory(Wood=expected_density)
self.assertEqual(wood.volume, 1.0)
def test_density_for_steel(self):
expected_density = 7700
steel, = self.factory(Steel=expected_density)
self.assertEqual(steel.volume, 1.0)
def test_for_volume_decimal_places_if_one_decimal_places(self):
expected_density = 7700 * 7
steel, = self.factory(Steel=expected_density)
self.assertEqual(steel.volume, 7.0)
self.assertIsInstance(steel.volume, float)
def test_for_volume_decimal_places_if_more_than_places_up(self):
# от задачата разбирам че просто трябва резултата да се форматира до 2рия знак
# ако не е така да ме поправи някой :)
# 4453/7700 = 0.5783116883116883 => 0.58
expected_density = 4453
steel, = self.factory(Steel=expected_density)
self.assertEqual(steel.volume, 0.5783116883116883)
self.assertIsInstance(steel.volume, float)
def test_for_volume_decimal_places_if_more_than_places_down(self):
# 4453/600 = 7.421666666666667 => 7.42
expected_density = 4453
steel, = self.factory(Wood=expected_density)
self.assertAlmostEqual(steel.volume, 7.42, places=2)
self.assertIsInstance(steel.volume, float)
class FactoryTests(unittest.TestCase):
def setUp(self):
self.factory1 = Factory()
self.factory2 = Factory()
self.wood1, self.steel1, self.brick1, self.stone1, self.concrete1 = self.factory1(Wood=5, Steel=15, Brick=60,
Stone=300, Concrete=20)
self.wood2, self.steel2, self.brick2, self.stone2, self.concrete2 = self.factory2(Wood=5, Steel=30, Brick=300,
Stone=600, Concrete=2000)
def test_factory_invalid_call_with_empy_call(self):
with self.assertRaises(ValueError):
self.factory1()
def test_factory_invalid_call_with_args_and_kwargs(self):
with self.assertRaises(ValueError):
self.factory1(self.wood1, Wood=5)
def test_factory_return_type(self):
self.assertIsInstance(self.factory2(Wood=66), tuple)
def test_two_factories_with_same_passed_arguments_produce_different_objects_of_same_type(self):
self.assertEqual(type(self.wood1), type(self.wood2))
self.assertEqual(self.wood1.volume, self.wood2.volume)
self.assertNotEqual(self.wood1, self.wood2)
def test_factory_call_with_kwargs_with_not_existing_class(self):
with self.assertRaises(ValueError):
self.factory1(Baba=1)
def test_volume_for_all_instances_returned_from_factory_call_kwargs(self):
wood, steel, stone = self.factory1(Wood=600, Steel=100, Stone=3200)
self.assertAlmostEqual(wood.volume, 1.0, )
self.assertAlmostEqual(steel.volume, 0.012987012987012988)
self.assertAlmostEqual(stone.volume, 2.0)
def test_for_recreating_already_existing_dynamic_class(self):
wooden_steel = self.factory1(self.wood1, self.steel1)
self.assertEqual(wooden_steel.__class__.__name__, "Steel_Wood")
another_wooden_steel = self.factory1(self.wood2, self.steel2)
self.assertEqual(type(wooden_steel), type(another_wooden_steel))
def test_for_reusing_same_materials_for_creation(self):
self.factory1(self.wood1, self.steel2)
with self.assertRaises(AssertionError):
self.factory1(self.wood1)
def test_new_generated_class_name_is_sorted_in_ascending_order(self):
result = self.factory1(self.wood1, self.steel1, self.brick1)
self.assertEqual(result.__class__.__name__, "Brick_Steel_Wood")
result = self.factory1(self.stone1, self.steel2, self.wood2, )
self.assertEqual(result.__class__.__name__, "Steel_Stone_Wood")
def test_new_generated_class_name_is_sorted_in_ascending_order2(self):
result = self.factory1(self.wood1, self.steel2, self.stone2, self.brick1, self.concrete1)
self.assertEqual(result.__class__.__name__, "Brick_Concrete_Steel_Stone_Wood")
def test_volume_and_density_for_dynamically_created_materials(self):
# density = (2500 + 7700 + 600) / 3 = 3600.
# mass = 5 + 30 + 2000 = 2035
# volume = 2035 / 3600 = 0.5652777777777778 = 0.57
result = self.factory1(self.wood1, self.steel2, self.concrete2)
self.assertAlmostEqual(result.volume, 0.5652777777777778)
def test_different_factories_called_with_same_kwargs_return_materials_of_same_type(self):
steel_stone = self.factory1(Stone=1, Steel=1)
another_steel_stone = self.factory2(Steel=1, Stone=1)
self.assertEqual(type(steel_stone), type(another_steel_stone))
def test_one_factory_use_material_and_another_tries_to_use_it_and_fails(self):
steel_stone = self.factory1(self.steel2, self.stone1)
self.factory1(steel_stone)
with self.assertRaises(AssertionError):
self.factory2(self.wood1, steel_stone)
def test_build_method_returns_true_for_greater_than_volume(self):
factory = Factory()
factory(Brick(2500))
self.assertTrue(factory.can_build(1))
def test_build_method_returns_true_for_equal_volume(self):
factory = Factory()
factory(Brick(2000))
self.assertTrue(factory.can_build(1))
def test_build_method_returns_false(self):
factory = Factory()
factory(Brick(1500))
self.assertFalse(factory.can_build(1))
def test_build_method_with_many_materials_returns_false(self):
factory1 = Factory()
brick1, wood1 = factory1(Brick=2000, Wood=1200)
brick_wood1 = factory1(brick1, wood1)
self.assertEqual(factory1.can_build(3), False)
def test_build_method_with_many_materials_returns_true(self):
# density = (2000+ 600+7700) / 3 = 3433.3333333333335
# mass = 2000 + 1000 + 70000 = 73000
# volume = 73000 / 3433.3333333333335 = 21.262135922330096 = 21.2
factory1 = Factory()
brick1, wood1, steel = factory1(Brick=2000, Wood=1000, Steel=70000)
factory1(brick1, wood1, steel)
self.assertTrue(factory1.can_build(21.26))
self.assertEqual(factory1.can_build(21.27), False)
def test_string_after_combination(self):
result1 = self.factory1(self.wood1, self.brick1)
result2 = self.factory2(self.concrete2, self.stone1)
result = self.factory1(result1, result2)
self.assertEqual(result.__class__.__name__, "Brick_Concrete_Stone_Wood")
if __name__ == "__main__":
unittest.main()
```
Нишка
|
Нишка
24.11.2024 18:42