I am running a small unittest to check the roman number converter. Here is my code :-
class RomConverter(object):
def __init__(self):
self.digital_mapping = {"M":1000, "D":500, "C":100, "L":50, "X":10, "V":5, "I":1}
def convert(self, rom_num):
value = 0
for char in rom_num:
val += self.digital_mapping[char]
return value
import unittest
class RomConverterTest(unittest.TestCase):
def settingUp(self):
print ("Creating a new RomConverter...")
self.cvt = RomConverter()
def tearDown(self):
print ("Destroying the RomConverter...")
self.cvt = None
def test_empty_num(self):
self.assertTrue(self.cvt.convert("") == 0)
self.assertFalse(self.cvt.convert("") > 0)
def test_no_rom_num(self):
self.assertRaises(TypeError,self.cvt.convert, None)
if __name__ == "__main__":
unittest.main()
But I am getting this message when I run the code :-
Traceback (most recent call last):
File "receipe2 - Copy.py", line 31, in test_empty_roman_numeral
self.assertTrue(self.cvt.convert_to_decimal("") == 0)
AssertionError: False is not true
I see two problems in your code.
First def settingUp(self): should be def setUp(self):
And the return of def convert(self, rom_num): is indented to much. In result the method does not return 0 incase of an empty string.
Here is a working version:
class RomConverter(object):
def __init__(self):
self.digital_mapping = {"M":1000, "D":500, "C":100, "L":50, "X":10, "V":5, "I":1}
def convert(self, rom_num):
value = 0
for char in rom_num:
value += self.digital_mapping[char]
return value
import unittest
class RomConverterTest(unittest.TestCase):
def setUp(self):
print ("Creating a new RomConverter...")
self.cvt = RomConverter()
def tearDown(self):
print ("Destroying the RomConverter...")
self.cvt = None
def test_empty_num(self):
self.assertTrue(self.cvt.convert("") == 0)
self.assertFalse(self.cvt.convert("") > 0)
def test_no_rom_num(self):
self.assertRaises(TypeError,self.cvt.convert, None)
if __name__ == "__main__":
unittest.main()
Related
so the program that I am trying to make accepts only a valid month and year between 2018-2050 but pycharm crushes with the message "Process finished with exit code -1073740791 (0xC0000409)" and I know in which line it does that, but I dont know how to fix it, here is the code I am using and the error appers in the last elif when ok is clicked. I have tried reinstalling python and pycharm, as suggested in other posts but nothing happens.
import sys
from PyQt5.QtWidgets import (QVBoxLayout,QHBoxLayout,QPushButton,
QLineEdit,QApplication,QLabel,QCheckBox,QWidget)
class Window(QWidget):
def __init__(self):
super().__init__()
self.init_ui()
def accepted(month, year):
conf = True
try:
int(month)
int(year)
except ValueError:
conf = False
if conf:
if (int(month) > 12 or int(month) < 1) or (int(year) < 2019 or
int(year) > 2050):
conf = False
return conf
def init_ui(self):
self.btn1=QPushButton('OK')
self.btn2=QPushButton('Clear')
self.btn3=QPushButton('Cancel')
self.txt1=QLabel('Month input')
self.txt2=QLabel('Year Input')
self.b1=QLineEdit()
self.b2=QLineEdit()
h_box1: QHBoxLayout=QHBoxLayout()
h_box1.addWidget(self.txt1)
h_box1.addWidget(self.b1)
h_box2 = QHBoxLayout()
h_box2.addWidget(self.txt2)
h_box2.addWidget(self.b2)
h_box3=QHBoxLayout()
h_box3.addWidget(self.btn1)
h_box3.addWidget(self.btn2)
h_box3.addWidget(self.btn3)
layout=QVBoxLayout()
layout.addLayout(h_box1)
layout.addLayout(h_box2)
layout.addLayout(h_box3)
self.setLayout(layout)
self.setWindowTitle('Calendar Manager')
self.show()
self.btn1.clicked.connect(self.buttons)
self.btn2.clicked.connect(self.buttons)
self.btn3.clicked.connect(self.buttons)
def buttons(self):
clicked=self.sender()
if clicked.text() == 'Clear':
self.b1.clear()
self.b2.clear()
elif clicked.text() == 'Cancel':
sys.exit()
elif clicked.text() == 'OK':
if not accepted(self.b1.text(),self.b2.text()):
self.b1.clear()
self.b2.clear()
else:
pass
app=QApplication(sys.argv)
a_window=Window()
sys.exit(app.exec_())
So the problem is the self in two instances, first as an argument in def accepted and secondly the self.accepted when I call it.
As you mentioned, the problem is with function accepted. If you intended it to be a class method, it should have been defined as:
def accepted(self, month, year):
....
You don't use 'self' in the method, so it could be turned into a static method:
#staticmethod
def accepted(month, year):
....
I am using pool.imap_unordered to apply a function over different txt files saved locally.
Is it possible to capture the exception and pass?
If my code runs into an exception, it blocks the entire loop.
pool = Pool(processes=15)
results = {}
files = glob.glob('{}/10K_files/*.txt'.format(path_input))
for key, output in tqdm(pool.imap_unordered(process_file, files),total=len(files)):
results[key] = output
I've tried something like this:
pool = Pool(processes=15)
results = {}
files = glob.glob('{}/10K_files/*.txt'.format(path_input))
try:
for key, output in tqdm(pool.imap_unordered(process_file, files), total=len(files)):
results[key] = output
except:
print("error")
but then I want to resume the loop from where I started.
Thanks!
You could catch the exception in process_file and return it. Then test for whether the return value is an exception. Here is an example:
import os
import traceback
import multiprocessing as mp
def main():
work_items = [i for i in range(20)]
pool = mp.Pool()
for result in pool.imap_unordered(process_file_exc, work_items):
if isinstance(result, Exception):
print("Got exception: {}".format(result))
else:
print("Got OK result: {}".format(result))
def process_file_exc(work_item):
try:
return process_file(work_item)
except Exception as ex:
return Exception("Err on item {}".format(work_item)
+ os.linesep + traceback.format_exc())
def process_file(work_item):
if work_item == 9:
# this will raise ZeroDivisionError exception
return work_item / 0
return "{} * 2 == {}".format(work_item, work_item * 2)
if __name__ == '__main__':
main()
I apologize for my bad English.
I need your help. I just bring strategy design pattern, I have understood the pattern with a simple example, but the implementation in my project is very confusing for me, maybe you can help me.
I have for example these two classes:
from tkinter import *
from app.interface.settings import New_Font
from app.controller.interface_elements.button_controller import Button_controller
from app.controller.interface_elements.close_button_controller import Close_button_controller
class New_Button:
def __init__(self, insert_button_in_frame, text, width, position_X, position_Y, background_color, foreground_color, close_button_parameter):
self._number_types = {int, float}
self.set_frame (insert_button_in_frame)
self.set_text (text)
self.set_width (width)
self.set_position (position_X, position_Y)
self.set_color (background_color, foreground_color)
self.set_close_button_parameter (close_button_parameter)
if self.get_text() == 'Abbrechen':
self.controller = Close_button_controller(self.get_close_button_parameter())
else:
self.controller = Button_controller()
self.create_button ()
def create_button(self):
self.set_button(Button(self.get_frame(),
text=self.get_text(),
bg=self.get_background_color(),
fg=self.get_foreground_color(),
width=self.get_width(),
font=New_Font().get_defaultfont(),
command=lambda :self.controller.main_method()))
self.get_button().place(x=self.get_position_X(),
y=self.get_position_Y())
def set_button(self, button):
self._button = button
def get_button(self):
return self._button
def set_frame(self, insert_button_in_frame):
if type(insert_button_in_frame) == Frame:
self._frame = insert_button_in_frame
else: raise TypeError
def get_frame(self):
return self._frame
def set_text(self, text):
if type(text) == str:
self._text = text
else: raise TypeError()
def get_text(self):
return self._text
def set_width(self, width):
if type(width) in self._number_types:
self._width = width
else: raise TypeError
def get_width(self):
return self._width
def set_position(self, position_X , position_Y):
if type(position_X) in self._number_types and type(position_Y) in self._number_types:
self._position_X = position_X
self._position_Y = position_Y
else: raise TypeError
def get_position_X(self):
return self._position_X
def get_position_Y(self):
return self._position_Y
def set_color(self, background_color, foreground_color):
if type(background_color) == str and type(foreground_color) == str:
self._background_color = background_color
self._foreground_color = foreground_color
else: raise TypeError
def get_background_color(self):
return self._background_color
def get_foreground_color(self):
return self._foreground_color
def set_controller(self, controller):
self._controller = controller
def get_controller(self):
return self._controller
def set_info(self, search_for):
self._info = self.get_button().cget(search_for)
def get_info(self):
return self._info
def set_close_button_parameter(self, close_button_parameter):
self._close_button_parameter = close_button_parameter
def get_close_button_parameter(self):
return self._close_button_parameter
and
from app.gui.top_frame import *
from app.interface.settings import New_Font
from app.controller.interface_elements.radiobutton_controller import Radiobutton_controller
class New_Radiobutton:
def __init__(self, frame_to_insert_radiobutton, radiobutton_label, button_horizontal_position, button_vertical_position, radiobutton_group, radiobutton_value, crawled_radiobuttons):
self._number_types = {int, float}
self._allowed_group_types = {int, float, str}
self._values = {1,3,5}
self._disable = {3,4,5,6}
self.set_frame_to_insert_radiobutton (frame_to_insert_radiobutton)
self.set_radiobutton_label (radiobutton_label)
self.set_position (button_horizontal_position, button_vertical_position)
self.set_radiobutton_group (radiobutton_group)
self.set_radiobutton_value (radiobutton_value)
self.create_radiobutton()
self._radiobutton_controller = Radiobutton_controller(crawled_radiobuttons)
self.set_first_radiobutton_of_a_group()
def create_radiobutton(self):
self.set_radiobutton(Radiobutton(self.get_frame_to_insert_radiobutton(),
text=self.get_radiobutton_label(),
variable=self.get_radiobutton_group(),
value=self.get_radiobutton_value(),
font=New_Font().get_defaultfont(),
command= lambda : self._radiobutton_controller.main_method()))
self.get_radiobutton().place(x=self.get_button_horizontal_position(),
y=self.get_button_vertical_position())
def set_first_radiobutton_of_a_group(self):
if self.get_radiobutton_value() in self._values:
self.get_radiobutton().invoke()
if self.get_radiobutton_value() in self._disable:
self.get_radiobutton().config(state=DISABLED)
def get_frame_to_insert_radiobutton(self):
return self._frame_to_insert_radiobutton
def set_frame_to_insert_radiobutton(self, frame_to_insert_radiobutton):
if type(frame_to_insert_radiobutton) == tkinter.Frame:
self._frame_to_insert_radiobutton = frame_to_insert_radiobutton
else: raise TypeError(frame_to_insert_radiobutton +
' frame_to_insert_radiobutton i not from type tkinter.Frame')
def get_radiobutton_label(self):
return self._radiobutton_label
def set_radiobutton_label(self, radiobutton_label):
if type(radiobutton_label) == str:
self._radiobutton_label = radiobutton_label
else: raise TypeError(radiobutton_label +
' radiobutton_label is not from type string')
def get_button_horizontal_position(self):
return self._button_horizontal_position
def get_button_vertical_position(self):
return self._button_vertical_position
def set_position(self, button_horizontal_position, button_vertical_position):
if type(button_horizontal_position) and type(button_vertical_position) in self._number_types:
self._button_horizontal_position = button_horizontal_position
self._button_vertical_position = button_vertical_position
else: raise TypeError(button_horizontal_position + ' ' + button_vertical_position +
' button_horizontal_position or button_vertical_position or both is/are not from type number')
def get_radiobutton_group(self):
return self._radiobutton_group
def set_radiobutton_group(self, radiobutton_group):
if type(radiobutton_group) in self._allowed_group_types:
self._radiobutton_group = radiobutton_group
else: raise TypeError(radiobutton_group +
' radiobutton_group is not from type int/float or string')
def get_radiobutton_value(self):
return self._radiobutton_value
def set_radiobutton_value(self, radiobutton_value):
if type(radiobutton_value) in self._number_types:
self._radiobutton_value = radiobutton_value
else: raise TypeError(radiobutton_value +
'radiobutton_value is not from type number')
def get_radiobutton_controller(self, radiobutton_controller):
return self.get_radiobutton().cget(radiobutton_controller)
def set_radiobutton(self, radiobutton):
self._radiobutton = radiobutton
def get_radiobutton(self):
return self._radiobutton
both classes need 90% the same methods and I have 2 other methods where it is. how do I start encapsulating the changeable now? because the button, no matter if radio, checkbox or button, is only created with the create method
thank you for your help
I got distracted and ended up writing a test framework in python. I'm struggling with a particular problem that this throws up.
During my assertion, I want to throw an exception as a way of bubbling a problem up to the run_test() method without requiring the user to have any knowledge of the framework. The problem is that when I do that, it seems that the try/catch block is not honoured.
Here is a cut down version of my fledgling framework:
# test_framework.py
import inspect
import module_containing_tests
class AssertionException(Exception):
def __init__(self, message):
self.message = message
def __str__(self):
return self.message
def run_test(test_name, test_method):
try:
print(">", test_name)
test_method()
print("Passed")
except AssertionException as error:
print("Failed")
print(str(error))
def assert_true(conditional):
if not conditional:
raise AssertionException("Expected True. Was False")
def test(func):
func.is_test = True
return func
members = inspect.getmembers(module_containing_tests)
for member in members:
if "is_test" in dir(member[1]) and not member[0] == "module_containing_tests":
run_test(member[0], member[1])
The module containing the tests will look like this:
# module_containing_tests.py
from test_framework import *
#test
def passing_test():
assert_true(1 + 2 == 3)
#test
def failing_test():
assert_true(1 + 2 == 5)
The output has all the exception stack tracing in it and it also halts the execution
λ python test_framework.py
> failing_test
Traceback (most recent call last):
File "test_framework.py", line 29, in <module>
run_test(member[0], member[1])
File "test_framework.py", line 13, in run_test
test_method()
File "C:\Git\simpy-test\module_containing_tests.py", line 9, in failing_test
assert_true(1 + 2 == 5)
File "C:\Git\simpy-test\test_framework.py", line 20, in assert_true
raise AssertionException("Expected True. Was False")
test_framework.AssertionException: Expected True. Was False
What I want is something like this:
λ python test_framework.py
> failing_test
Expected True. Was False
Failed
> passing_test
Passed
I think the issue is partly in the circular reference between the two files that might mess up with the visibility of the methods (as somehow explained here) and partly, maybe, in the approach. If you think about how many other testing framework work, you often have 3 elements, the unit to test, the testing framework and a test runner.
So if we try to split everythig folllowing that logic you end up having:
test_framework.py
# test_framework.py
class AssertionException(Exception):
pass
def test(f):
f.is_test = True
return f
def assert_true(conditional):
if not conditional:
raise AssertionException("Expected True. Was False")
test_runner.py
# test_runner.py
import inspect
import unit_test
from test_framework import AssertionException
def run_test(test_name, test_method):
try:
print(">", test_name)
test_method()
print("Passed")
except AssertionException as error:
print("Failed with AssertionException: " + str(error))
except Exception as error:
print("Failed with Exception: " + str(error))
if __name__ == "__main__":
members = inspect.getmembers(unit_test)
for member in members:
if "is_test" in dir(member[1]):
run_test(member[0], member[1])
unit_test.py
# unit_test.py
from test_framework import *
#test
def a_passing_test():
assert_true(1 + 2 == 3)
#test
def z_failing_test():
assert_true(1 + 2 == 5)
With this setup the circular dependency is removed and all the visibility context are respected and the output/behaviour is the expected one.
I hope it helps.
Not sure this is what you want but this works.
Copied from here Hide traceback unless a debug flag is set
Output:
$ ./test_framework.py
> a_passing_test
Passed
> z_failing_test
test_framework.AssertionException: Expected True. Was False
First file:
#!/usr/bin/env python3
#test_framework.py
import inspect
import module_containing_tests
import sys
class AssertionException(Exception):
def __init__(self, message):
self.message = message
def __str__(self):
return self.message
def run_test(test_name, test_method):
try:
print(">", test_name)
test_method()
print("Passed")
except AssertionException as error:
print("Failed")
print(str(error))
def assert_true(conditional):
if not conditional:
raise AssertionException("Expected True. Was False")
def test(func):
func.is_test = True
return func
sys.tracebacklimit=0
members = inspect.getmembers(module_containing_tests)
for member in members:
if "is_test" in dir(member[1]) and not member[0] == "module_containing_tests":
run_test(member[0], member[1])
second file:
#!/usr/bin/env python3
#module_containing_tests.py
from test_framework import *
#test
def a_passing_test():
assert_true(1 + 2 == 3)
#test
def z_failing_test():
assert_true(1 + 2 == 5)
Having trouble with Built-in Exception: ModuleNotFoundError. I see nothing wrong with this solution, but am getting an Error. Checked out the docs but couldn't figure it out
folder structure
app
__init__.py
logic.py
test
__init__.py
test_logic.py
this error comes when i try to run the file from the command line directly --python test/test_logic.py
(tdd) D:\code\Outcome-15>coverage run test/test_logic.py
Traceback (most recent call last):
File "test/test_logic.py", line 3, in <module>
from app.logic import FizzBuzz
ModuleNotFoundError: No module named 'app'
logic.py
class FizzBuzz:
def fizz_buzz_service(self, num):
number_types = (int, float, complex)
if isinstance(num, number_types):
if num % 5 == 0 and num % 3 == 0:
return 'FizzBuzz'
elif num % 5 == 0:
return 'Buzz'
elif num % 3 == 0:
return 'Fizz'
else:
return num
else:
raise ValueError
test_logic.py
import unittest
from app.logic import FizzBuzz
class FizzBuzzServiceTestCases(unittest.TestCase):
"""
docstring for FizzBuzzServiceTestCases goes here!
"""
def setUp(self):
"""
Create an instance of fizz_buzz_service
"""
self.fizzbuzz = FizzBuzz()
def test_it_returns_a_number(self):
"""
Test for the default behavior of returning a number if not divisible by 3, 5 or both
"""
self.assertEqual(7, self.fizzbuzz.fizz_buzz_service(7))
def test_should_return_Fizz(self):
self.assertEqual("Fizz", self.fizzbuzz.fizz_buzz_service(3))
def test_should_return_Buzz(self):
self.assertEqual('Buzz', self.fizzbuzz.fizz_buzz_service(5))
def test_should_return_FizzBuzz(self):
self.assertEqual('FizzBuzz', self.fizzbuzz.fizz_buzz_service(15))
def test_should_return_error_message_if_arg_not_number(self):
with self.assertRaises(ValueError):
self.fizzbuzz.fizz_buzz_service('five')
if __name__ == '__main__':
unittest.main()