I was working on a blockchain project. Nothing wrong seemed to come of it, until I added the mining function. Then it spit out two errors that it was missing positional argument. the first was the main function on line 45, and the second one was that if name is main function. which makes since. It had to do with the mining function. The code is a bit lengthy and hard to understand so I am keeping the necessary parts.
from hashlib import sha3_512
##some hashing stuff
class Block():
## the variables thrown into the function
def __init__(self, txdata, number):
#initialize function.
# More hashing stuff
class blockchain:
difficulty = 4
def __init__(self, chain=[]):
#Initialize function. Sets up the blockchain
def add(self,Block):
#lables adding stuff to the chain
def mine(self,Block):
try:
block.prev = self.chain[-1].get('hash')
except IndexError:
pass
while True:
if Block.hash()[:blockchain.difficulty] == "0"*blockchain.difficulty:
self.add(Block)
break
else:
Block.nonce +=1
def main():
blockchain()
bchain = ["Nice day stack overflow", "Once again I need help with my bad code"]
Num = 0
for txdata in bchain:
Num += 1
blockchain.mine(Block(Block.txdata, Num)) #the error popped up here. I don't get it. I tried fiddling around with it, nothing.
if __name__ == '__main__':
main()
Can you help me solve this error. It could ruin the entire project if not fixed.
Error
Traceback(most recent call last)
File "blockchain.py", line 47 in <module>
main()
File "blockchain.py", line 45, in main()
blockchain.mine(Block(Block.txdata, Num))
Type error: mine missing one positional argument: Block
You need to keep hold of the instance of blockchain().
def main():
b = blockchain() # keep hold of the instance in b
bchain = ["Nice day stack overflow", "Once again I need help with my bad code"]
Num = 0
for txdata in bchain:
Num += 1
b.mine(Block(Block.txdata, Num)) # Use the instance here
if __name__ == '__main__':
main()
Related
I am trying to import the following module into the below code but I keep getting
comput()
TypeError: comput() missing 2 required positional arguments: 'r' and 'h'
I have tried some varying solutions and watched some videos but I can't figure this one out, any ideas?
def comput(r, h):
if h <= 40:
p = r * h
else:
p = r * 40 + (r * 1.5 * ( h - 40))
return p
comput()
import program5_1_module
def main():
pay()
pay()
pay()
def pay():
name = input('Enter employee name: ')
rate = float(input(f'Enter hourly rate for {name}: '))
hours = float(input(f'Enter hours for {name} this week: '))
pay = comput(rate, hours)
print(f'Pay for {name} is ${pay:,.2f}')
main()
Python executes all module-level code when importing another code.
In your first code, comput() raises TypeError because you are calling function with 2 parameters but you gave no argument.
In your second code, you import program5_1_module(I think this is name of your first code?), and python executes all code in program5_1_module, which includes comput()
Solution:
Remove comput() (9th line of your first code, because it makes error)
If you want to test calling comput() in first code then wrap it using if __name__ == "__main__", like if __name__ == "__main__": comput(a, b).
if __name__ == "__main__" informs python interpreter that this should not be executed when importing
really sorry if someone has asked this before, i just couldn't find what i was looking for, I'm new to coding and aren't sure why i cant get 'matrice2x2mult' function to be called within 'runcalc'. However i suspect it is to do with me calling the function 'runcalc' at the bottom. Any help will be greatly appreciated. Once again sorry.
-I get the error message:
Traceback (most recent call last):
File "FILE_PATH", line 42, in <module>
query.runcalc(q)
File "FILE_PATH", line 19, in runcalc
matrice2x2mult()
NameError: name 'matrice2x2mult' is not defined
import time
class calculator():
def __init__(self, method):
self.method = method
def matrice2x2mult():
print("Matrix 1:")
a = input("a:")
b = input("b:")
c = input("c:")
d = input("d:")
print(f"({a} {b})\n({c} {d})")
def runcalc(self, method):
if self.method == "1":
print("yes")
matrice2x2mult()
elif self.method == "2":
pass
print ("welcome to matrice Calculator: \nEnter 'HELP' for help menu")
time.sleep(1)
q = input(r"What method is required:")
q = str(q)
help1 = False
while help1 == False:
if r"HELP" in str(q):
print("------help-menu------")
print("ENTER '1' FOR 2X2 MATRIX MULTIPLICATION")
print("ENTER '2' FOR A INVERSE OF A 2X2 MATRIX")
time.sleep(1)
q = str(input(r"What method is required:"))
break
else:
break
pass
query = calculator(q)
query.runcalc(q)```
[1]: https://i.stack.imgur.com/s6jud.png
Since matrice2x2mult is defined within calculator, and you're trying to access it via runcalc which is also defined within the same class, you need to use self.matrice2x2mult to access the function. The only way that using just matrice2x2mult would work is either if it was defined in global scope rather than just in that class, or if you did something like matrice2x2mult = self.matrice2x2mult which would be weird and not recommended.
i'm trying to solve the adventofcode riddles, but this year i decided to take the chance to learn a new programming language: Python.
Since i already have some knowledge about other OOP languages like Java and C++, i immediately created an "interface" system for the Solutions objects.
My project setup at the moment is like:
Project Setup
Now what i want is to dynamically output solutions through the main class, that basically has to call all .solve() method of each dayX.py class that is in the /solutions/ directory.
I think i'm next to do it but i get an error:
Traceback (most recent call last):
File "C:\Users\siste\j-workspace\adventofcode2020\main.py", line 16, in <module>
print(solution.solve())
TypeError: solve() missing 1 required positional argument: 'self'
Here are my files:
main.py
import os
def days():
classes = []
path = "C:\\path"
for file in os.listdir(path):
if(file.startswith("day")) :
classes.append(str(file.replace(".py", "")))
return classes
if __name__ == '__main__':
for day in days() :
solution = getattr(__import__(str("solutions." + day)), day.replace("d", "D"))
print(solution.solve())
solution.py
path = "C:\\path\\inputs\\day{}.txt"
class Solution:
def __init__(self, dayNumber):
self.dayNumber = dayNumber
self.inputPath = path.format(self.dayNumber)
def part1(self):
pass
def part2(self):
pass
def solve(self):
return ("Day {} Solutions: \n\tPart1: {}\n\tPart2: {}"
.format(self.dayNumber, self.part1(), self.part2()))
day1.py
import fileinput
from solutions.solution import Solution
class Day1(Solution):
def __init__(self):
super().__init__(1)
def part1(self):
return "sol"
def part2(self):
return "sol2"
When you're using the getattr on the imported module, you're getting the class definition. Methods are only callable on class instances, otherwise they throw the error you're seeing:
class A:
def a(self):
pass
A.a() // Will throw "TypeError: a() missing 1 required positional argument: 'self'"
A().a() // OK
Changing the __main__ part this way should solve the issue:
if __name__ == '__main__':
for day in days() :
day_class = getattr(__import__(str("solutions." + day)), day.replace("d", "D"))
day_instance = day_class()
print(day_instance.solve())
I am currently having an issue, as i am relatively new to python , it might be a very easy solution for others.
I want to pass a parameter between both functions 'eg1' and 'eg2', there is a common number the user will input (example:10) then 'eg1' will add 1 to it and 'eg2' will take the final value of 'eg1' and add 1 more to it, (example: 10 will become 11 then 12)
It is troubling me because this keeps popping up:
Traceback (most recent call last):
File "example.py", line 69, in <module>
eg2(a)
File "example.py", line 63, in eg2
b = a.d
AttributeError: 'int' object has no attribute 'd'
I can't seem to find my mistake.
class Helper:pass
a = Helper()
def one(a):
d = a
d += 1
print d
def two(a):
b = a.d
b += 1
print b
print
print ("Please enter a number.")
a = int(input('>> ')
print
one(a)
print
two(a)
Reference for parameter passing:
Python definition function parameter passing
'Print' with nothing means to leave an empty line, for me
I messed up the title, fixed.
Since you are already using a class, you can pass the number you want to increment twice as an instance attribute, and call your increment functions on that attribute. This will avoid passing the updated value after calling one in the method two
Calling one and then two makes sure that two is working on the updated value after calling one.
class Helper:
# Pass num as parameter
def __init__(self, num):
self.num = num
# Increment num
def one(self):
self.num += 1
# Increment num
def two(self):
self.num += 1
h = Helper(10)
h.one()
print(h.num) # 11
h.two()
print(h.num) # 12
Based on your comments, here's one way to get the result. I am using python3:
class Helper:
d = None
cl = Helper()
def one(a):
cl.d = a
cl.d += 1
return cl.d
def two():
cl.d += 1
return cl.d
print ("Please enter a number.")
a = int(input('>> '))
print(one(a))
print(two())
I am trying to write a decorator that adds verbose logging to a function via a decorator (a method would be nice too, but I haven't tried that yet). The motivation behind this is that patching in a one-line add_logs decorator call into a box in production is much easier (and safer) than adding 100 debug lines.
Ex:
def hey(name):
print("Hi " + name)
t = 1 + 1
if t > 6:
t = t + 1
print("I was bigger")
else:
print("I was not.")
print("t = ", t)
return t
I'd like to make a decorator that will transform this into code that does this:
def hey(name):
print("line 1")
print("Hi " + name)
print("line 2")
t = 1 + 1
print("line 3")
if t > 6:
print("line 4")
t = t + 1
print("line 5")
print("I was bigger")
else:
print("line 6")
print("I was not.")
print("line 7")
print("t = ", t)
print("line 8")
return t
What I've got so far:
import inspect, ast
import itertools
import imp
def log_maker():
line_num = 1
while True:
yield ast.parse('print("line {line_num}")'.format(line_num=line_num)).body[0]
line_num = line_num + 1
def add_logs(function):
def dummy_function(*args, **kwargs):
pass
lines = inspect.getsourcelines(function)
code = "".join(lines[0][1:])
ast_tree = ast.parse(code)
body = ast_tree.body[0].body
#I realize this doesn't do exactly what I want.
#(It doesn't add debug lines inside the if statement)
#Once I get it almost working, I will rewrite this
#to use something like node visitors
body = list(itertools.chain(*zip(log_maker(), body)))
ast_tree.body[0].body = body
fix_line_nums(ast_tree)
code = compile(ast_tree,"<string>", mode='exec')
dummy_function.__code__ = code
return dummy_function
def fix_line_nums(node):
if hasattr(node, "body"):
for index, child in enumerate(node.body):
if hasattr(child, "lineno"):
if index == 0:
if hasattr(node, "lineno"):
child.lineno = node.lineno + 1
else:
# Hopefully this only happens if the parent is a module...
child.lineno = 1
else:
child.lineno = node.body[index - 1].lineno + 1
fix_line_nums(child)
#add_logs
def hey(name):
print("Hi " + name)
t = 1 + 1
if t > 6:
t = t + 1
print("I was bigger")
else:
print("I was not.")
print("t = ", t)
return t
if __name__ == "__main__":
print(hey("mark"))
print(hey)
This produces this error:
Traceback (most recent call last):
File "so.py", line 76, in <module>
print(hey("mark"))
TypeError: <module>() takes no arguments (1 given)
which makes sense because compile creates a module and of course modules are not callables. I've tried a hundred different ways of making this work at this point but can't come up with a working solution. Any recommendations? Am I going about this the wrong way?
(I haven't been able to find a tutorial for the ast module that actually modifies code at runtime like this. A pointer to such a tutorial would be helpful as well)
Note: I am presently testing this on CPython 3.2, but a 2.6/3.3_and_up solution would be appreciated. Currently the behavior is the same on 2.7 and 3.3.
When you compile the source, you get a code object representing a module, not a function. Substituting this code object into an existing function won't work, because it's not a function code object, it's a module code object. It's still a code object, though, not a real module, you so can't just do hey.hey to get the function from it.
Instead, as described in this answer, you need to use exec to execute the module's code, store the resulting objects in a dictionary, and extract the one you want. What you could do, roughly, is:
code = compile(ast_tree,"<string>", mode='exec')
mod = {}
exec(code, mod)
Now mod['hey'] is the modified function. You could reassign the global hey to this, or replace its code object.
I am not sure if what you're doing with the AST is exactly right, but you will need to do the above at any rate, and if there are problems in the AST manipulation, doing this will get you to a point where you can start to debug them.
It looks like you're trying to hackily implement a trace function. Can I suggest using sys.settrace to accomplish that in a more reusable fashion?
import sys
def trace(f):
_counter = [0] #in py3, we can use `nonlocal`, but this is compatible with py2
def _tracer(frame, event, arg):
if event == 'line':
_counter[0] += 1
print('line {}'.format(_counter[0]))
elif event == 'return': #we're done here, reset the counter
_counter[0] = 0
return _tracer
def _inner(*args, **kwargs):
try:
sys.settrace(_tracer)
f(*args, **kwargs)
finally:
sys.settrace(None)
return _inner
#trace
def hey(name):
print("Hi " + name)
t = 1 + 1
if t > 6:
t = t + 1
print("I was bigger")
else:
print("I was not.")
print("t = ", t)
return t
hey('bob')
Output:
$ python3 test.py
line 1
Hi bob
line 2
line 3
line 4
I was not.
line 5
t = 2
line 6
Note that the semantics of this are slightly different than in your implementation; the if branches not exercised by your code, for example, are not counted.
This ends up being less fragile - you're not actually modifying the code of the functions you're decorating - and has extra utility. The trace function gives you access to the frame object before executing each line of code, so you're free to log locals/globals (or do some dodgy injection stuff, if you're so inclined).
When you call inspect.getsource() with a decorated function, you also get the decorator, which, in your case, gets called recursively (just twice, and the second time it produces an OSError).
You can use this workaround to remove #add_logs line from the source:
lines = inspect.getsourcelines(function)
code = "".join(lines[0][1:])
EDIT:
It looks like your problem is that your dummy_function doesn't take arguments:
>>> print(dummy_function.__code__.co_argcount)
0
>>> print(dummy_function.__code__.co_varnames)
()
Whereas your original function does:
>>> print(hey.__code__.co_argcount)
1
>>> print(hey.__code__.co_varnames)
('name')
EDIT:
You're right about the code object being returned as a module. As pointed in another answer, you have to execute the this object and then, assign the resulting function (identifiable by function.__name__) to dummy_function.
Like so:
code = compile(ast_tree,"<string>", mode='exec')
mod = {}
exec(code, mod)
dummy_function = mod[function.__name__]
return dummy_function
Then:
>>> print(hey('you'))
line 1
Hi you
line 2
line 3
I was not.
line 4
t = 2
line 5
2