how to make a calculator 10


I want to try another way to make a website for the Calculator, the last one is not beautiful yet. I test Streamlit which lets me build web applications with almost no extra code.


preview

These are the tests I have by the end of the chapter

  1import random
  2import streamlit.testing.v1
  3import tests.test_calculator
  4import unittest
  5
  6
  7class TestStreamlitCalculator(unittest.TestCase):
  8
  9    def setUp(self):
 10        self.tester = streamlit.testing.v1.AppTest.from_file(
 11            'src/streamlit_calculator.py'
 12        )
 13        self.tester.run()
 14
 15    def test_streamlit_calculator_title(self):
 16        self.assertEqual(self.tester.title[0].value, 'Calculator')
 17
 18    def test_streamlit_calculator_display(self):
 19        self.assertEqual(
 20            self.tester.main.children[1].type,
 21            'flex_container'
 22        )
 23
 24    def test_streamlit_calculator_columns(self):
 25        self.assertEqual(len(self.tester.columns), 4)
 26        self.assertEqual(
 27            self.tester.columns[0].button('<-').label,
 28            '<-'
 29        )
 30        self.assertEqual(
 31            self.tester.columns[0].button('7').label,
 32            '7'
 33        )
 34        self.assertEqual(
 35            self.tester.columns[0].button('4').label,
 36            '4'
 37        )
 38        self.assertEqual(
 39            self.tester.columns[0].button('1').label,
 40            '1'
 41        )
 42        self.assertEqual(
 43            self.tester.columns[0].button('+/-').label,
 44            '+/-'
 45        )
 46        self.assertEqual(
 47            self.tester.columns[1].button('C').label,
 48            'C'
 49        )
 50        self.assertEqual(
 51            self.tester.columns[1].button('8').label,
 52            '8'
 53        )
 54        self.assertEqual(
 55            self.tester.columns[1].button('5').label,
 56            '5'
 57        )
 58        self.assertEqual(
 59            self.tester.columns[1].button('2').label,
 60            '2'
 61        )
 62        self.assertEqual(
 63            self.tester.columns[1].button('0').label,
 64            '0'
 65        )
 66
 67        self.assertEqual(
 68            self.tester.columns[2].button('AC').label,
 69            'AC'
 70        )
 71        self.assertEqual(
 72            self.tester.columns[2].button('9').label,
 73            '9'
 74        )
 75        self.assertEqual(
 76            self.tester.columns[2].button('6').label,
 77            '6'
 78        )
 79        self.assertEqual(
 80            self.tester.columns[2].button('3').label,
 81            '3'
 82        )
 83        self.assertEqual(
 84            self.tester.columns[2].button('.').label,
 85            '.'
 86        )
 87
 88        self.assertEqual(
 89            self.tester.columns[3].button('/').label,
 90            '/'
 91        )
 92        self.assertEqual(
 93            self.tester.columns[3].button('X').label,
 94            'X'
 95        )
 96        self.assertEqual(
 97            self.tester.columns[3].button('-').label,
 98            r'\-'
 99        )
100        self.assertEqual(
101            self.tester.columns[3].button('+').label,
102            r'\+'
103        )
104        self.assertEqual(
105            self.tester.columns[3].button('=').label,
106            '='
107        )
108
109    def test_streamlit_session_state(self):
110        expectation = '0'
111        for _ in range(0, 10):
112            number = random.choice('0123456789')
113            (
114                self.tester.button(number)
115                .click().run()
116            )
117            if expectation == '0':
118                expectation = number
119            else:
120                expectation += number
121        self.assertEqual(
122            self.tester.session_state['number'],
123            expectation
124        )
125
126    def test_streamlit_calculator_w_decimals(self):
127        for button in ('0.23.5.6.7.8.9'):
128            (
129                self.tester.button(button)
130                .click().run()
131            )
132        self.assertEqual(
133            self.tester.session_state['number'],
134            '.2356789'
135        )
136
137    def test_streamlit_calculator_w_plus_minus(self):
138        number = '963.0258741'
139        for button in number:
140            (
141                self.tester.button(button)
142                .click().run()
143            )
144        self.tester.button('+/-').click().run()
145        self.assertEqual(
146            self.tester.session_state['number'],
147            f'-{number}'
148        )
149
150        self.tester.session_state['number'] = '0'
151        number = '-963.0258741'
152        for button in number:
153            (
154                self.tester.button(button)
155                .click().run()
156            )
157
158        self.tester.button('+/-').click().run()
159        self.assertEqual(
160            self.tester.session_state['number'],
161            number[1:]
162        )
163
164    def test_streamlit_calculator_reset_state(self):
165        numbers = '123456789'
166        number = random.choice(numbers)
167        self.tester.button(number).click().run()
168        self.assertEqual(
169            self.tester.session_state['number'],
170            number
171        )
172        self.tester.button('C').click().run()
173        self.assertEqual(
174            self.tester.session_state['number'],
175            '0'
176        )
177
178        number = random.choice(numbers)
179        self.tester.button(number).click().run()
180        self.assertEqual(
181            self.tester.session_state['number'],
182            number
183        )
184        self.tester.button('AC').click().run()
185        self.assertEqual(
186            self.tester.session_state['number'],
187            '0'
188        )
189
190    @unittest.skip
191    def test_streamlit_calculator_operations(self):
192        # first_number = '1'
193        first_number = tests.test_calculator.a_random_number()
194        first_number = str(first_number)
195        second_number = '2'
196
197        for character in first_number:
198            if character == '-':
199                self.tester.button('+/-').click().run()
200            else:
201                self.tester.button(character).click().run()
202        self.tester.button('+').click().run()
203        self.assertEqual(
204            self.tester.session_state['first_number'],
205            first_number
206        )
207
208        self.tester.button(second_number).click().run()
209        self.tester.button('=').click().run()
210        self.assertEqual(
211            self.tester.session_state['second_number'],
212            second_number
213        )
214
215        self.assertEqual(
216            self.tester.session_state['number'],
217            str(float(first_number) + float(second_number))
218        )
219
220
221# Exceptions seen
222# NameError
223# AttributeError
224# AssertionError
225# SyntaxError
226# KeyError
227# streamlit.errors.StreamlitDuplicateElementKey
228# TypeError
  1import random
  2import streamlit.testing.v1
  3import tests.test_calculator
  4import unittest
  5
  6
  7class TestStreamlitCalculator(unittest.TestCase):
  8
  9    def setUp(self):
 10        self.tester = streamlit.testing.v1.AppTest.from_file(
 11            'src/streamlit_calculator.py'
 12        )
 13        self.tester.run()
 14
 15    def test_streamlit_calculator_title(self):
 16        self.assertEqual(self.tester.title[0].value, 'Calculator')
 17
 18    def test_streamlit_calculator_display(self):
 19        self.assertEqual(
 20            self.tester.main.children[1].type,
 21            'flex_container'
 22        )
 23
 24    def test_streamlit_calculator_columns(self):
 25        self.assertEqual(len(self.tester.columns), 4)
 26        self.assertEqual(
 27            self.tester.columns[0].button('<-').label,
 28            '<-'
 29        )
 30        self.assertEqual(
 31            self.tester.columns[0].button('7').label,
 32            '7'
 33        )
 34        self.assertEqual(
 35            self.tester.columns[0].button('4').label,
 36            '4'
 37        )
 38        self.assertEqual(
 39            self.tester.columns[0].button('1').label,
 40            '1'
 41        )
 42        self.assertEqual(
 43            self.tester.columns[0].button('+/-').label,
 44            '+/-'
 45        )
 46        self.assertEqual(
 47            self.tester.columns[1].button('C').label,
 48            'C'
 49        )
 50        self.assertEqual(
 51            self.tester.columns[1].button('8').label,
 52            '8'
 53        )
 54        self.assertEqual(
 55            self.tester.columns[1].button('5').label,
 56            '5'
 57        )
 58        self.assertEqual(
 59            self.tester.columns[1].button('2').label,
 60            '2'
 61        )
 62        self.assertEqual(
 63            self.tester.columns[1].button('0').label,
 64            '0'
 65        )
 66
 67        self.assertEqual(
 68            self.tester.columns[2].button('AC').label,
 69            'AC'
 70        )
 71        self.assertEqual(
 72            self.tester.columns[2].button('9').label,
 73            '9'
 74        )
 75        self.assertEqual(
 76            self.tester.columns[2].button('6').label,
 77            '6'
 78        )
 79        self.assertEqual(
 80            self.tester.columns[2].button('3').label,
 81            '3'
 82        )
 83        self.assertEqual(
 84            self.tester.columns[2].button('.').label,
 85            '.'
 86        )
 87
 88        self.assertEqual(
 89            self.tester.columns[3].button('/').label,
 90            '/'
 91        )
 92        self.assertEqual(
 93            self.tester.columns[3].button('X').label,
 94            'X'
 95        )
 96        self.assertEqual(
 97            self.tester.columns[3].button('-').label,
 98            r'\-'
 99        )
100        self.assertEqual(
101            self.tester.columns[3].button('+').label,
102            r'\+'
103        )
104        self.assertEqual(
105            self.tester.columns[3].button('=').label,
106            '='
107        )
108
109    def test_streamlit_session_state(self):
110        expectation = '0'
111        for _ in range(0, 10):
112            number = random.choice('0123456789')
113            (
114                self.tester.button(number)
115                .click().run()
116            )
117            if expectation == '0':
118                expectation = number
119            else:
120                expectation += number
121        self.assertEqual(
122            self.tester.session_state['number'],
123            expectation
124        )
125
126    def test_streamlit_calculator_w_decimals(self):
127        for button in ('0.23.5.6.7.8.9'):
128            (
129                self.tester.button(button)
130                .click().run()
131            )
132        self.assertEqual(
133            self.tester.session_state['number'],
134            '.2356789'
135        )
136
137    def test_streamlit_calculator_w_plus_minus(self):
138        number = '963.0258741'
139        for button in number:
140            (
141                self.tester.button(button)
142                .click().run()
143            )
144        self.tester.button('+/-').click().run()
145        self.assertEqual(
146            self.tester.session_state['number'],
147            f'-{number}'
148        )
149
150        self.tester.session_state['number'] = '0'
151        number = '-963.0258741'
152        for button in number:
153            (
154                self.tester.button(button)
155                .click().run()
156            )
157
158        self.tester.button('+/-').click().run()
159        self.assertEqual(
160            self.tester.session_state['number'],
161            number[1:]
162        )
163
164    def test_streamlit_calculator_reset_state(self):
165        numbers = '123456789'
166        number = random.choice(numbers)
167        self.tester.button(number).click().run()
168        self.assertEqual(
169            self.tester.session_state['number'],
170            number
171        )
172        self.tester.button('C').click().run()
173        self.assertEqual(
174            self.tester.session_state['number'],
175            '0'
176        )
177
178        number = random.choice(numbers)
179        self.tester.button(number).click().run()
180        self.assertEqual(
181            self.tester.session_state['number'],
182            number
183        )
184        self.tester.button('AC').click().run()
185        self.assertEqual(
186            self.tester.session_state['number'],
187            '0'
188        )
189
190    @unittest.skip
191    def test_streamlit_calculator_operations(self):
192        # first_number = '1'
193        first_number = tests.test_calculator.a_random_number()
194        first_number = str(first_number)
195        second_number = '2'
196
197        for character in first_number:
198            if character == '-':
199                self.tester.button('+/-').click().run()
200            else:
201                self.tester.button(character).click().run()
202        self.tester.button('+').click().run()
203        self.assertEqual(
204            self.tester.session_state['first_number'],
205            first_number
206        )
207
208        self.tester.button(second_number).click().run()
209        self.tester.button('=').click().run()
210        self.assertEqual(
211            self.tester.session_state['second_number'],
212            second_number
213        )
214
215        self.assertEqual(
216            self.tester.session_state['number'],
217            str(float(first_number) + float(second_number))
218        )
219
220
221# Exceptions seen
222# NameError
223# AttributeError
224# AssertionError
225# SyntaxError
226# KeyError
227# streamlit.errors.StreamlitDuplicateElementKey
228# TypeError
  1import random
  2import streamlit.testing.v1
  3import tests.test_calculator
  4import unittest
  5
  6
  7class TestStreamlitCalculator(unittest.TestCase):
  8
  9    def press_button(self, key):
 10        self.tester.button(key).click().run()
 11
 12    def setUp(self):
 13        self.tester = streamlit.testing.v1.AppTest.from_file(
 14            'src/streamlit_calculator.py'
 15        )
 16        self.tester.run()
 17
 18    def test_streamlit_calculator_title(self):
 19        self.assertEqual(self.tester.title[0].value, 'Calculator')
 20
 21    def test_streamlit_calculator_display(self):
 22        display = (
 23            self.tester.main.children[1].proto
 24                .flex_container
 25        )
 26        self.assertEqual(display.gap_config.gap_size, 1)
 27        self.assertEqual(display.direction, 1)
 28        self.assertEqual(display.justify, 1)
 29        self.assertEqual(display.align, 1)
 30        self.assertTrue(display.border)
 31
 32    def test_streamlit_calculator_columns_and_buttons(self):
 33        self.assertEqual(len(self.tester.columns), 4)
 34
 35        for column, keys in (
 36            (0, ('<-', '7', '4', '1', '+/-')),
 37            (1, ('C', '8', '5', '2', '0')),
 38            (2, ('AC', '9', '6', '3', '.')),
 39            (3, ('/', 'X', r'\-', r'\+', '=')),
 40        ):
 41            for key in keys:
 42                with self.subTest(key=key):
 43                    self.assertEqual(
 44                        (
 45                            self.tester.columns[column]
 46                                .button(key)
 47                                .label
 48                        ),
 49                        key
 50                    )
 51
 52    def test_streamlit_calculator_operations_buttons(self):
 53        for key in ('/', 'X', r'\-', r'\+', '=', 'C', 'AC'):
 54            with self.subTest(key=key):
 55                self.assertEqual(
 56                    self.tester.button(key).proto.type,
 57                    'primary'
 58                )
 59
 60    def test_streamlit_session_state(self):
 61        numbers = '0123456789'
 62        self.assertEqual(self.tester.session_state['number'], '0')
 63
 64        expectation = random.choice(numbers)
 65        while expectation == '0':
 66            expectation = random.choice(numbers)
 67        else:
 68            self.press_button(expectation)
 69
 70        self.assertEqual(
 71            self.tester.session_state['number'], expectation
 72        )
 73
 74        for _ in range(0, len(numbers)):
 75            a_random_number = random.choice(numbers)
 76            self.press_button(a_random_number)
 77            expectation += a_random_number
 78
 79        self.assertEqual(
 80            self.tester.session_state['number'],
 81            expectation
 82        )
 83
 84    def test_streamlit_calculator_w_decimals(self):
 85        for key in ('0.23.5.6.7.89'):
 86            self.press_button(key)
 87
 88        self.assertEqual(
 89            self.tester.session_state['number'],
 90            '0.2356789'
 91        )
 92
 93    def test_streamlit_calculator_backspace(self):
 94        a_random_number = tests.test_calculator.a_random_number()
 95        while a_random_number < 0:
 96            a_random_number = tests.test_calculator.a_random_number()
 97        a_random_number = str(a_random_number)
 98
 99        for key in a_random_number:
100            self.press_button(key)
101        self.press_button('<-')
102
103        self.assertEqual(
104            self.tester.session_state['number'],
105            a_random_number[:-1]
106        )
107
108        self.press_button('<-')
109        self.assertEqual(
110            self.tester.session_state['number'],
111            a_random_number[:-2]
112        )
113
114    def test_streamlit_calculator_w_plus_minus(self):
115        a_number = '963.0258741'
116        for key in a_number:
117            self.press_button(key)
118        self.assertEqual(
119            self.tester.session_state['number'], a_number
120        )
121
122        self.press_button('+/-')
123        self.assertEqual(
124            self.tester.session_state['number'], f'-{a_number}'
125        )
126
127        self.press_button('+/-')
128        self.assertEqual(
129            self.tester.session_state['number'], a_number
130        )
131
132
133# Exceptions seen
134# NameError
135# AttributeError
136# AssertionError
137# SyntaxError
138# KeyError
139# streamlit.errors.StreamlitDuplicateElementKey
  1import random
  2import streamlit.testing.v1
  3import tests.test_calculator
  4import unittest
  5
  6
  7class TestStreamlitCalculator(unittest.TestCase):
  8
  9    def setUp(self):
 10        self.tester = streamlit.testing.v1.AppTest.from_file(
 11            'src/streamlit_calculator.py'
 12        )
 13        self.tester.run()
 14
 15    def test_streamlit_calculator_title(self):
 16        self.assertEqual(self.tester.title[0].value, 'Calculator')
 17
 18    def test_streamlit_calculator_display(self):
 19        self.assertEqual(
 20            self.tester.main.children[1].type,
 21            'flex_container'
 22        )
 23
 24    def test_streamlit_calculator_columns(self):
 25        self.assertEqual(len(self.tester.columns), 4)
 26        self.assertEqual(
 27            self.tester.columns[0].button('<-').label,
 28            '<-'
 29        )
 30        self.assertEqual(
 31            self.tester.columns[0].button('7').label,
 32            '7'
 33        )
 34        self.assertEqual(
 35            self.tester.columns[0].button('4').label,
 36            '4'
 37        )
 38        self.assertEqual(
 39            self.tester.columns[0].button('1').label,
 40            '1'
 41        )
 42        self.assertEqual(
 43            self.tester.columns[0].button('+/-').label,
 44            '+/-'
 45        )
 46        self.assertEqual(
 47            self.tester.columns[1].button('C').label,
 48            'C'
 49        )
 50        self.assertEqual(
 51            self.tester.columns[1].button('8').label,
 52            '8'
 53        )
 54        self.assertEqual(
 55            self.tester.columns[1].button('5').label,
 56            '5'
 57        )
 58        self.assertEqual(
 59            self.tester.columns[1].button('2').label,
 60            '2'
 61        )
 62        self.assertEqual(
 63            self.tester.columns[1].button('0').label,
 64            '0'
 65        )
 66
 67        self.assertEqual(
 68            self.tester.columns[2].button('AC').label,
 69            'AC'
 70        )
 71        self.assertEqual(
 72            self.tester.columns[2].button('9').label,
 73            '9'
 74        )
 75        self.assertEqual(
 76            self.tester.columns[2].button('6').label,
 77            '6'
 78        )
 79        self.assertEqual(
 80            self.tester.columns[2].button('3').label,
 81            '3'
 82        )
 83        self.assertEqual(
 84            self.tester.columns[2].button('.').label,
 85            '.'
 86        )
 87
 88        self.assertEqual(
 89            self.tester.columns[3].button('/').label,
 90            '/'
 91        )
 92        self.assertEqual(
 93            self.tester.columns[3].button('X').label,
 94            'X'
 95        )
 96        self.assertEqual(
 97            self.tester.columns[3].button('-').label,
 98            r'\-'
 99        )
100        self.assertEqual(
101            self.tester.columns[3].button('+').label,
102            r'\+'
103        )
104        self.assertEqual(
105            self.tester.columns[3].button('=').label,
106            '='
107        )
108
109    def test_streamlit_session_state(self):
110        expectation = '0'
111        for _ in range(0, 10):
112            number = random.choice('0123456789')
113            (
114                self.tester.button(number)
115                .click().run()
116            )
117            if expectation == '0':
118                expectation = number
119            else:
120                expectation += number
121        self.assertEqual(
122            self.tester.session_state['number'],
123            expectation
124        )
125
126    def test_streamlit_calculator_w_decimals(self):
127        for button in ('0.23.5.6.7.8.9'):
128            (
129                self.tester.button(button)
130                .click().run()
131            )
132        self.assertEqual(
133            self.tester.session_state['number'],
134            '.2356789'
135        )
136
137    def test_streamlit_calculator_w_plus_minus(self):
138        number = '963.0258741'
139        for button in number:
140            (
141                self.tester.button(button)
142                .click().run()
143            )
144        self.tester.button('+/-').click().run()
145        self.assertEqual(
146            self.tester.session_state['number'],
147            f'-{number}'
148        )
149
150        self.tester.session_state['number'] = '0'
151        number = '-963.0258741'
152        for button in number:
153            (
154                self.tester.button(button)
155                .click().run()
156            )
157
158        self.tester.button('+/-').click().run()
159        self.assertEqual(
160            self.tester.session_state['number'],
161            number[1:]
162        )
163
164    def test_streamlit_calculator_reset_state(self):
165        numbers = '123456789'
166        number = random.choice(numbers)
167        self.tester.button(number).click().run()
168        self.assertEqual(
169            self.tester.session_state['number'],
170            number
171        )
172        self.tester.button('C').click().run()
173        self.assertEqual(
174            self.tester.session_state['number'],
175            '0'
176        )
177
178        number = random.choice(numbers)
179        self.tester.button(number).click().run()
180        self.assertEqual(
181            self.tester.session_state['number'],
182            number
183        )
184        self.tester.button('AC').click().run()
185        self.assertEqual(
186            self.tester.session_state['number'],
187            '0'
188        )
189
190    @unittest.skip
191    def test_streamlit_calculator_operations(self):
192        # first_number = '1'
193        first_number = tests.test_calculator.a_random_number()
194        first_number = str(first_number)
195        second_number = '2'
196
197        for character in first_number:
198            if character == '-':
199                self.tester.button('+/-').click().run()
200            else:
201                self.tester.button(character).click().run()
202        self.tester.button('+').click().run()
203        self.assertEqual(
204            self.tester.session_state['first_number'],
205            first_number
206        )
207
208        self.tester.button(second_number).click().run()
209        self.tester.button('=').click().run()
210        self.assertEqual(
211            self.tester.session_state['second_number'],
212            second_number
213        )
214
215        self.assertEqual(
216            self.tester.session_state['number'],
217            str(float(first_number) + float(second_number))
218        )
219
220
221# Exceptions seen
222# NameError
223# AttributeError
224# AssertionError
225# SyntaxError
226# KeyError
227# streamlit.errors.StreamlitDuplicateElementKey
228# TypeError

what is next?

start with how to make a calculator 10: part 1