Why is this code raising an AssertionError? - python-3.x

This is the code.
# mean_var_std.py
def calculate(list):
try:
if len(list) < 9:
raise ValueError
else:
return 0
except ValueError:
print("List must contain nine numbers.")
This is the test.
import unittest
import mean_var_std
# the test case
class UnitTests(unittest.TestCase):
def test_calculate_with_few_digits(self):
self.assertRaisesRegex(ValueError, "List must contain nine numbers.", mean_var_std.calculate, [2,6,2,8,4,0,1,])
if __name__ == "__main__":
unittest.main()
When I run it, I get the following output:
F
======================================================================
FAIL: test_calculate_with_few_digits (test_module.UnitTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/runner/fcc-mean-var-std-2/test_module.py", line 8, in test_calculate_with_few_digits
self.assertRaisesRegex(ValueError, "List must contain nine numbers.", mean_var_std.calculate, [2,6,2,8,4,0,1,])
AssertionError: ValueError not raised by calculate
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (failures=1)
The output says that the code isn't raising a ValueError, but from the code we can clearly see that the code raises a ValueError. Why is my code still failing the unittest?

It's because you catch the ValueError before the test can receive it.
Remove the try catch and it should work
# mean_var_std.py
def calculate(list):
if len(list) < 9:
print("List must contain nine numbers.")
raise ValueError
else:
return 0

Related

logging usability in python

I am implementing a simple logger in python.Find my code below, Sometimes it runs fine,at times I get ValueError at self.log('INFO','Append operation successful.')
Where am I doing wrong? I am new to python and have also referred to the doc. Unable to understand the inconsistency, also I am using python 3.9, tried using force parameter too. It is also not logging the level, like Critical, Info or Error.
import logging as logger
class data:
def __init__(self, filename,filetype,filesize,date):
self.filename=filename
self.filetype=filetype
self.filesize=filesize
self.date=date
def log(self,logtype,msg):
logger.basicConfig(filename="datalog.log",level=logger.INFO,force=True,format='%(asctime)s %(message)s')
if logtype == "INFO":
logger.info(msg)
elif logtype == "ERROR":
logger.ERROR(msg)
elif logtype == "CRITICAL":
logger.CRITICAL(msg)
else:
logger.info(msg)
def openFile(self):
try:
filename=self.filename+self.filetype
f=open(filename,'w+')
f.write("Hello, Lets learn OOPs in Python")
f.close()
self.log('INFO','Write operation successful.')
except Exception as e:
self.log('ERROR','Writing operation failed.')
def appendFile(self):
try:
f=open(self.filename+self.filetype,'a')
f.write("Appending some extra content")
f.close()
self.log('INFO','Append operation successful.')
except Exception as e:
self.log('ERROR','Append operation failed.')
sample = data('sample','.txt','1Mb','2021-08-20')
sample.appendFile()
sample.openFile()
Error:
ValueError: Unrecognised argument(s): force
During handling of the above exception, another exception occurred:
TypeError Traceback (most recent call last)
<ipython-input-1-e095529812fd> in log(self, logtype, msg)
12 logger.info(msg)
13 elif logtype == "ERROR":
---> 14 logger.ERROR(msg)
15 elif logtype == "CRITICAL":
16 logger.CRITICAL(msg)
TypeError: 'int' object is not callable
The force option to basicConfig is only available in Python 3.8+. Check your Python version.
Also, it's probably not a good idea to force reconfigure the logging system on each and every log event. Just configure it once, at the main entry point of your application.

how to set global variable with subdirectorys

how can i set a global variable, from a other file from other directory?
I would like to take the variable aaid into test.py and
the variable bbid from test.py print in test2.py
Structure:
d:\test\main.py
d:\test\a\test.py
d:\test\b\test2.py
main.py:
# import relevant files
import sys, os, subprocess
while (True):
# The menu
print("MENU")
print(" 1. Librarian")
try:
choice = int(input("Select who you are (choose a number): "))
except ValueError:
print("you have not entered a numerical input! \nplease enter a number")
# Librarian choice
if choice == 1:
while (True):
# Handling Value Error
try:
aaid = input("\nID? :")
except ValueError:
print("Error! Please enter a numerical input")
else:
os.chdir("a/")
subprocess.call('python test.py', shell=True)
break
test.py
print(aaid)
bbid = x500
test2.py
print(bbid)
error:
Traceback (most recent call last):
File "test.py", line 2, in <module>
print(aaid)
NameError: name 'aaid' is not defined
python 3.8.2 on windows 10

How to Create a Custom Error Handling Class Without Writing Error Handling into Functions

I'm trying to create a class that does nothing but handle error. Use the classes methods when calling functions so that the methods from the error handling class stop the execution of the function if user input is bad.
class Error(Exception):
pass
class UserError(Error):
def handle_even(number):
try: number % 2 == 0
except: raise UserError.handle_even('error: odd number\n')
def handle_odd(number):
try: number % 2 != 0
except: raise UserError.handle_odd('error: even number\n')
def take_even(number):
print(number) #if user input is bad, this shouldn't execute
def take_odd(number):
print(number) #if user input is bad, this shouldn't execute
take_even(UserError.handle_even(5)) # I expect this to print 'error: odd number'
take_odd(UserError.handle_odd(4)) # I expect this to print 'error: even number'
So, the output I want is:
error: odd number
error: even number
However, the output I get instead is:
None
None
The try block won't generate an exception because an expression evaluation was true/false, also your odd/even checking logic was wrong.
class Error(Exception):
pass
class UserError(Error):
#classmethod
def handle_even(cls, number):
if number % 2 != 0:
raise Error('error: odd number\n')
return number
#classmethod
def handle_odd(cls, number):
if number % 2 == 0:
raise Error('error: even number\n')
return number
def take_even(number):
print(number) # if user input is bad, this won't execute
def take_odd(number):
print(number) # if user input is bad, this won't execute
# This will raise an 'Error' exception (error: odd number)
take_even(UserError.handle_even(5))
# This will raise an 'Error' exception (error: even number)
take_odd(UserError.handle_odd(4))
You could handle these specific Error exceptions like so:
try:
take_even(UserError.handle_even(5))
except Error as e:
print(e) # print 'error: odd number'
try:
take_odd(UserError.handle_odd(4))
except Error as e:
print(e) # print 'error: even number'
Edit:
Changing the methods as class methods per #NathanVÄ“rzemnieks recommendation.

Having trouble with Built-in Exception: ModuleNotFoundError

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()

Python 3 - reading files, counting, and filtering text

I am working on a code in Python 3 with the following prompt:
Exercise 2: Write a program to prompt for a file name, and then read through the file and look for lines of the form: X-DSPAM-Confidence:0.8475. When you encounter a line that starts with X-DSPAM-Confidence: pull apart the line to extract the floating-point number on the line. Count these lines and then compute the total of the spam confidence values from these lines. When you reach the end of the file, print out the average spam confidence.
I have started writing my code (below), but keep getting the following error message from Python:
Traceback (most recent call last):
File "spam_lines_in_file.py", line 14, in <module>
for line in fhand:
NameError: name 'fhand' is not defined
0587388179:ch_07_files juliecruz$
I'm confused because I have defined the variable 'fhand'. Any help from the experts?
count = 0
sum = 0
user = input('Please enter a file name')
try:
fhand = open(user)
except:
print("Not a valid file")
for line in fhand:
line = line.rstrip()
if line.startswith('X-DSPAM-Confidence:'):
print(lines)
count += 1
colon_position = int(line.find(":"))
extract = line[colon_position+1:]
number_extract = float(extract)
sum += number_extract
print("Extracted lines", count)
print("Sum of confidence values", sum)
print("Average of confidence values", sum/count)
Your problem is that fhand is only assigned a value if no exceptions occur.
You wrote:
try:
fhand = open(user)
except:
print("Not a valid file")
So in the case of an exception, fhand is not assigned a value. Which means that when you try to iterate over it, Python throws a NameError as it was never defined.
Maybe what you want is to terminate in the case of an exception? For example:
import sys
try:
fhand = open(user)
except:
print("Not a valid file")
sys.exit()
Or assign a default value to fhand?
import sys
try:
fhand = open(user)
except:
print("Not a valid file")
fhand = 'Default content'
The most likely reason is that, if a error occurs during opening the file, then a warning message is shown "Not a valid file", but processing then continues.
In that case fhand would not be assigned a value, and there would be a NameError
You probably want a loop that repeatedly asks for a filename, and only breaks out when the file has been opened successfully.
while True:
name = input("filename ... ")
try:
fhand = open(name)
except OSerror: # only catch OS errors, not everything.
print("not a valid file")
else:
break
fhand is a file object
try:
fhand = open(user)
except:
print("Not a valid file")
You can not do the following on a file object.
for line in fhand:
You would need to do this:
for line in fhand.readlines():
This isn't a problem for you yet, but it will be soon.
Your real problem is this:
When this code
try:
fhand = open(user)
throws an exception, the fhand variable doesn't get created, so you'd need to exit in the except block.
try:
fhand = open(user)
except:
print("Not a valid file")
sys.exit(1)
There is a mistake in line 11 :) - change to "line"
print(lines)

Resources