I am trying to write a Python turtle program that draws a Spirograph and I keep getting this error:
Traceback (most recent call last):
File "C:\Users\matt\Downloads\spirograph.py", line 36, in <module>
main()
File "C:\Users\matt\Downloads\spirograph.py", line 16, in main
spirograph(R,r,p,x,y)
File "C:\Users\matt\Downloads\spirograph.py", line 27, in spirograph
spirograph(p-1, x,y)
TypeError: spirograph() missing 2 required positional arguments: 'x' and 'y'
>>>
This is the code:
from turtle import *
from math import *
def main():
p= int(input("enter p"))
R=100
r=4
t=2*pi
x= (R-r)*cos(t)-(r+p)*cos((R-r)/r*t)
y= (R-r)*sin(t)-(r+p)*sin((R-r)/r*t)
spirograph(R,r,p,x,y)
def spirograph(R,r,p,x,y):
R=100
r=4
t=2*pi
x= (R-r)*cos(t)-(r+p)*cos((R-r)/r*t)
y= (R-r)*sin(t)-(r+p)*sin((R-r)/r*t)
while p<100 and p>10:
goto(x,y)
spirograph(p-1, x,y)
if p<10 or p>100:
print("invalid p value, enter value between 10 nd 100")
input("hit enter to quite")
bye()
main()
I know this maybe has a simple solution but I really can't figure out what I am doing wrong, this was an exercise in my computer science 1 class and I have no idea how to fix the error.
The last line of the traceback tells you where the problem is:
File "C:\Users\matt\Downloads\spirograph.py", line 27, in spirograph
spirograph(p-1, x,y) # <--- this is the problem line
TypeError: spirograph() missing 2 required positional arguments: 'x' and 'y'
In your code, the spirograph() function takes 5 arguments: def spirograph(R,r,p,x,y), which are R, r, p, x, y. In the line highlighted in the error message, you are only passing in three arguments p-1, x, y, and since this doesn't match what the function is expecting, Python raises an error.
I also noticed that you are overwriting some of the arguments in the body of the function:
def spirograph(R,r,p,x,y):
R=100 # this will cancel out whatever the user passes in as `R`
r=4 # same here for the value of `r`
t=2*pi
Here is a simple example of what is happening:
>>> def example(a, b, c=100):
... a = 1 # notice here I am assigning 'a'
... b = 2 # and here the value of 'b' is being overwritten
... # The value of c is set to 100 by default
... print(a,b,c)
...
>>> example(4,5) # Here I am passing in 4 for a, and 5 for b
(1, 2, 100) # but notice its not taking any effect
>>> example(9,10,11) # Here I am passing in a value for c
(1, 2, 11)
Since you always want to keep this values as the default, you can either remove these arguments from your function's signature:
def spirograph(p,x,y):
# ... the rest of your code
Or, you can give them some defaults:
def spirograph(p,x,y,R=100,r=4):
# ... the rest of your code
As this is an assigment, the rest is up to you.
The error tells you that you're using too few arguments to call spirograph
Change this code:
while p<100 and p>10:
goto(x,y)
spirograph(R,r, p-1, x,y) # pass on the missing R and r
You're not using these arguments though, but you still have to give them to the function to call it.
Related
I've implemented a fibonacci Measurement algorithm with 2 parameter n and p.
I got this issue,
TypeError Traceback (most recent call last)
<ipython-input-19-295638b26e62> in <module>
2 N = 10
3 # [F(n,p) for n in range(N)]
----> 4 print(F(10,1))
<ipython-input-12-fda62c8ec9a6> in F(n, p)
6 elif n <= p+1:
7 return n
----> 8 return F(n-1) + F(n-p-1)
TypeError: F() missing 1 required positional argument: 'p'
I have input 2 parameters n =10, p = 1, but still having this problem "missing 1 required argument". Does anyone know why and solution for this or any suggestion would be appreciated!
There could be two potential issues.
You're calling a function, F, that doesn't seem to be defined in the snippet you've attached. You might want to change it to fibonacci_of if it is supposed to call itself recursively. In addition, since the fibonacci_of accepts two parameters, you would need to call it with two arguments
If F is already defined elsewhere, it is supposed to accept more than one argument. You could check its function definition and see the parameter requirements. See attached examples.
def square(a): # Requires single parameter.
return a ** 2
def add(a, b): # Requires two parameters.
return a + b
I'm not so good with python and I keep getting this error:
TypeError: demand_curve() missing 1 required positional argument: 'pb'
And this is my code:
P,c,Q,y,pb,N,X,pf,t=sp.symbols('P c Q y pb N X pf t')
def demand_curve(c,Q,y,pb):
demand = (c.log(Q)-(-4.507+(0.841*y)+(0.2775*pb)))/(-0.397)
return demand
Q_num = np.linspace(0,100,100)
fig,ax=plt.subplots()
ax.set_ylabel('P')
ax.set_xlabel('E')
ax.plot(demand_curve(Q_num, 50, 2), Q_num,label='E (a=100,b=2)')
#legend:
ax.legend(loc='upper right', frameon=False)
ax.set(xlim=(0,100))
ax.set(ylim=(0,60))
I don't really understand what is the problem, can someone help me?
When you declare your function you do this :
def demand_curve(c,Q,y,pb):
...
So you have four parameters c, Q, y and pb, later in the code you call it using :
demand_curve(Q_num, 50, 2)
So in the way you call it you have
c = Q_num
Q = 50
y = 2
pb = Nothing at all
And python don't like this so you should provide and additional value when you call this function or provide a default value for the last parameter for example :
def demand_curve(c,Q,y,pb = "a default value"):
...
You are not passing all the arguments value when you call you function "demand_curve". Your function "demand_curve(c,Q,y,pb)" required 4 positional arguments but you give only 3 at "demand_curve(Q_num, 50, 2)".
So I have a Point class which basically consists of X and Y coordinates, and I want to create a Rectangle class that is constructed from a point at its top left corner, its width and its height.
My idea is to pass the Point object as a parameter so the Rectangle class constructor will create its own Point attribute with the argument's x and y values, which should be returned as a tuple and assigned to the new object, but it's not working.
This is my code:
class Point:
def __init__(self, init_x, init_y):
self.x = init_x
self.y = init_y
def get_point(self):
return(self.x, self.y)
class Rectangle:
def __init__(self,point,height,width):
self.top_left = Point(point.get_point())
my_point = Point(1,2)
my_rectangle = Rectangle(my_point,2,2)
print(my_rectangle.top_left)
And this is the error message:
Traceback (most recent call last):
File "/Users/mac/Desktop/programming/python/rectangle.py", line 70, in <module>
my_rectangle = Rectangle(my_point,2,2)
File "/Users/mac/Desktop/programming/python/rectangle.py", line 67, in __init__
self.top_left = Point(point.get_point())
TypeError: __init__() missing 1 required positional argument: 'init_y'
Why is it not passing the two values as a tuple? Is there a way to do what I'm trying to do?
You need to unpack the tuple using the * unpacking syntax:
self.top_left = Point(*point.get_point())
Otherwise, the tuple returned by get_point will be treated as only one argument:
>>> def func(a, b):
... return a, b
...
>>> func((1, 2))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: func() missing 1 required positional argument: 'b'
>>> func(*(1, 2))
(1, 2)
>>>
You are already passing a Point object here
my_rectangle = Rectangle(my_point,2,2)
so you don't have to create another Point like this
self.top_left = Point(point.get_point())
Simply do
self.top_left = point
The actual error is due to the fact that, Point class accepts two parameters in its __init__, but you are passing only one value, as a tuple.
Point(point.get_point())
Instead, you should be passing the values of x and y, by unpacking the tuple, like this
self.top_left = Point(*point.get_point())
First of all, I'm super new to python and I actually search for my problem but the examples were to heavy to understand.
Here is my homework; I need a function which takes two functions as an argument and returns if the results of the two functions are same or not? Basically, it will give either TRUE of FALSE.
For that I wrote:
def f(x,y,z):
k=x(*z)
l=y(*z)
return k == l
The previos code I wrote for single function was working but when I modified it for two function as above, it gives an error as following :
import math
>>> f(math.sqrt,math.cos,5)
Traceback (most recent call last):
File "<pyshell#56>", line 1, in <module>
f(math.sqrt,math.cos,5)
File "D:/Users/karabulut-ug/Desktop/yalanmakinesi.py", line 2, in f
k=x(*z)
TypeError: sqrt() argument after * must be a sequence
>>>
I could not figured it out since the error giving function is normally does not take a sequence. So I dont think it makes a sense :) Any help is appreciated.. Thanks :)
z is just a single number, but the * argument expansion syntax requires that you pass in a sequence (like a list, tuple or str, for example).
Either remove the * (and make your function work for just single arguments), or use *z in the function signature to make z a tuple of 0 or more captured arguments:
def f(x, y, z):
k = x(z)
l = y(z)
return k == l
or
def f(x, y, *z):
k = x(*z)
l = y(*z)
return k == l
The latter now works for functions with more than one argument too:
f(math.pow, math.log, 10, 10)
If you added a **kw argument to the signature, then keyword arguments could be handled too:
def f(x, y, *args, **kwargs):
k = x(*args, **kwargs)
l = y(*args, **kwargs)
return k == l
Here I renamed z to args to better reflect its purpose.
The syntax *z invokes argument unpacking on z. When z is just an integer, there is no iterator behavior defined, and so you see this error. Try:
>>> f(math.sqrt, math.cos, [5])
You need to remove the *. Its for unpacking. So:
def f(x,y,z):
k=x(z)
l=y(z)
return k == l
You use the * operator when you want to pass in an iterable object, like a list or tuple as something thats split up. So, for example:
a = [1,2,3,4,5]
So, for an arbitrary function, f:
f(*a) = f(1,2,3,4,5)
I'm trying to build a python class that parses a string and if it matches a regex that looks
like a function call attempt to call that function on the class, passing in any parameters.
For example a string like "foo("a", 20")" would translate to something like self.foo("a", 20).
Here is the code that I have so far..
class FooTranslate(object):
def create_string(self, letter, size):
return letter*size
def run_function(self, func_str):
match = re.match("([\w_]+)\((|[\W\d\w\,]+)\)", func_str)
if match == None:
print "Couldn't match a regex!"
return False
else:
func, fargs = match.groups()
try:
if fargs == "":
return self.__getattribute__(func)()
else:
return self.__getattribute__(func)(eval(fargs))
except AttributeError, e:
print "Invalid function call: %s" % (func)
return False
This code works in the basic cases...
In [1018]: foot = FooTranslate()
In [1019]: foot.run_function("foo()")
Foo!
In [1020]: foot.run_function("bar(2)")
FooFoo
However in the case of using 2 argument functions:
In [1021]: foot.run_function("create_string('a', 2)")
in run_function(self, func_str)
24 return self.__getattribute__(func)()
25 else:
---> 26 return self.__getattribute__(func)(eval(fargs))
27 except AttributeError, e:
28 print "Invalid function call: %s" % (func)
TypeError: create_string() takes exactly 3 arguments (2 given)
The reason why is that the eval() call returns fargs as a tuple, which create_string()
takes as only a single argument. Any idea how I can pass a variable number of arguments
through to a function call? Or have a better alternative way to do this?
You can use the * operator to explode a tuple into separate arguments to a function. For example:
def f(a, b, c):
print a, b, c
If I call f(...) like this:
f((1,2,3))
I get an error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() takes exactly 3 arguments (1 given)
But if I call it like this:
f(*(1,2,3))
I get:
1 2 3
The * operator will even work if the function takes a variable number of arguments. For example, given the following function:
def f2(a, b, *args):
print a, b,
for x in args:
print x,
print
If I call f2(*(1,2,3,4,5)) it prints:
1 2 3 4 5