Python Pickle Problem - Output not matching with Hackerrank - python-3.x

I’m trying to solve the below question on Hackerrank.
It is working on Pycharm IDE but on Hackerrank the output is not matching with the expected output given. Below is the Code I used
import os
import builtins
import pickle
import sys
sys.tracebacklimit = 0
import traceback
import io
from logging import Logger
safe_builtins = {
'range',
'complex',
'set',
'frozenset'
}
class RestrictedUnpickler(pickle.Unpickler):
def find_class(self, module, name):
# Only allow safe classes from builtins.
if module == "builtins" and name in safe_builtins:
return getattr(builtins, name)
# Forbid everything else.
raise pickle.UnpicklingError("global '%s.%s' is forbidden" %
(module, name))
def restricted_loads(s):
"""Helper function analogous to pickle.loads()."""
return RestrictedUnpickler(io.BytesIO(s)).load()
def func1(a):
try:
x = restricted_loads(pickle.dumps(a))
return a
except pickle.UnpicklingError:
s = traceback.format_exc()
return s
def func2(s):
try:
x = restricted_loads(pickle.dumps(slice(0, 8, 3)))
return s[x]
except pickle.UnpicklingError:
s = traceback.format_exc()
return s
if __name__ == "__main__":
a = range(int(input()))
b = func1(a)
print(b)
y = tuple(input())
z = func2(y)
print(z)
Expected Output:
range(0, 50):
Traceback (most recent call last):
_pickle.UnpicklingError: global 'builtins.slice' is forbidden
Actual Output:
range(0, 50):
_pickle.UnpicklingError: global 'builtins.slice' is forbidden
Question: Why does the output not match in hackerrank when the code seems to be correct?

This is an acceptable answer for Hackerrank. I included sys.stdout.write("Traceback (most recent call last):\n") since we declared the traceback=0 initially and pickle.UnpicklingError class doesn't have a traceback message. Try the below code for Hacker rank.
def func2(s):
try:
x = restricted_loads(pickle.dumps(slice(0, 8, 3)))
return s[x]
except pickle.UnpicklingError as e :
sys.stdout.write("Traceback (most recent call last):\n")
s = traceback.format_exc()
return s
PS: This is just an acceptable answer for Hackerrank. I just made simple modifications according to the output needs. This might not be a good practice everywhere. And I dont have full knowledge of it either.
import os
import builtins
import pickle
import sys
sys.tracebacklimit=0
import traceback
import io
from logging import Logger
safe_builtins = {
'range',
'complex',
'set',
'frozenset'
}
class RestrictedUnpickler(pickle.Unpickler):
def find_class(self, module, name):
# Only allow safe classes from builtins.
if module == "builtins" and name in safe_builtins:
return getattr(builtins, name)
# Forbid everything else.
raise pickle.UnpicklingError("global '%s.%s' is forbidden" %
(module, name))
def restricted_loads(s):
"""Helper function analogous to pickle.loads()."""
return RestrictedUnpickler(io.BytesIO(s)).load()
def func1(a):
try:
x = restricted_loads(pickle.dumps(a))
return a
except pickle.UnpicklingError:
s = traceback.format_exc()
return s
def func2(s):
try:
x = restricted_loads(pickle.dumps(slice(0, 8, 3)))
return s[x]
except pickle.UnpicklingError as e :
sys.stdout.write("Traceback (most recent call last):\n")
s = traceback.format_exc()
return s
if __name__ == "__main__":
a = range(int(input()))
b = func1(a)
print(b)
y = tuple(input())
z = func2(y)
print(z)

Related

Getting unexpected NoneType error in Python

While trying to create a minimal, reproducible example for another problem in Python 3.7.3, I ran into a NoneType Error that I wasn't expecting.
Main program:
import worker
def multiply_worker_value(arguments):
current_Worker = arguments[0]
multiplier = arguments[1]
new_worker = current_Worker.change_value(multiplier)
return new_worker
current_worker = worker.Worker()
print("Printing value:")
print(current_worker.get_value()[0])
while(current_worker.get_value()[0] < 10):
paramList = [current_worker,2]
current_worker = multiply_worker_value(paramList)
print(current_worker.get_value()[0])
Worker class:
import numpy
class Worker():
def __init__(self):
self.values = numpy.random.rand(10)
def change_value(self,multiplier):
self.values = numpy.sum(self.values*multiplier)
def get_value(self):
return self.values
When this is run, I get:
Printing value:
0.10619190084595542
Traceback (most recent call last):
File "F:\Visual Studio\repos\Projects2020\tests\concurrent_test\concurrent_test\main.py", line 14, in <module>
while(current_worker.get_value()[0] < 10):
AttributeError: 'NoneType' object has no attribute 'get_value'
Press any key to continue . . .
and I am not sure why this is happening.
Inside the while loop, your current_worker gets overwritten with None:
current_worker = multiply_worker_value(paramList)
this calls:
new_worker = current_Worker.change_value(multiplier)
Your Worker.change_value method does not have a return statement, so it implicitly returns None.
Then, in the second iteration of your loop, your code tries to call get_value on None, which fails.

Error when trying to communicate in Python

I want two scripts to communicate in python. I want them to know if the others have failed.
Doing what you see in the picture I have some questions. When I run rob2.py I automatically run rob1.py, why is this?
rob1.py
import simpy
import time
from rob2 import brok2
class Moving:
def __init__(self, env):
self.env = env
"""What does self.prov do?"""
self.prov = env.process(self.work())
self.broken = False
if self.broken == False:
global brok1
brok1 = 0
else:
brok1 = 0
#print(brok1)
def work(self):
while True:
yield env.timeout(20)
if brok2 == 1:
print("Robot 2 is not broken")
else:
print("Robot 2 is broken")
env= simpy.Environment()
moving = Moving(env)
env.run(until = 60)
rob2.py
import simpy
import time
from rob1 import brok1
class Placing:
def __init__(self, env):
self.env = env
"""What does self.prov do?"""
self.prov = env.process(self.work())
self.broken = False
if self.broken == False:
global brok2
brok2=1
else:
brok2 = 0
def work(self):
while True:
yield env.timeout(20)
time.sleep(5)
if brok1 == 1:
print("Robot 1 is not broken")
else:
print("Robot 1 is broken")
env= simpy.Environment()
placing = Placing(env)
env.run(until = 60)
And what have I done wrong when I get this message trying to run the scripts?
Traceback (most recent call last):
File "rob2.py", line 3, in <module>
from rob1 import brok1
File "/Users/erik/Python/python/rob1.py", line 3, in <module>
from rob2 import brok2
File "/Users/erik/Python/python/rob2.py", line 3, in <module>
from rob1 import brok1
ImportError: cannot import name 'brok1'
I came across some posts about zeroMQ, is that the way to go here?
The ImportError exception is thrown because Python detects a circular import loop: in one of your files you import the other one, which itself imports the first one, which import the second one and so on.
You will need to reorganize your code to avoid that.
Most (all?) programming languages will not like a circular import one way or another.

How can I catch an exception thrown in a function that I'm calling dynamically?

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)

self.assertTrue throwing traceback error in Python 3.x unittesting

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

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

Resources