I have been writing a small code to have my turtle (t) drawing a star. I need to stay within the general perimeters of the code I have, but I would like someone to take a look and see what is going wrong. I am a new programmer, so bear with me.
import turtle
def drawStar(n, l):
"""Get turtle t to draw a star with n sides at l length"""
for i in range(n):
t.forward(l)
t.left(36)
t.forward(l)
t.left(36)
drawStar(5, 100)
wn.exitonclick()
It says that the problem is on line 6 (drawStar(5, 100))
Besides the syntax error discussed, you have a logic error. Consider your t.left(36) statement, or later t.left(144) statement. The angle passed is actually a function of n and making it a constant as you have means this routine only works for one value of n. Consider:
drawStar(7, 100)
You don't get a seven pointed star, just some portion of a (duplicated) five pointed star. Which is not what your docstring claims about n. If we instead do:
import turtle
def drawStar(n, l):
"""Get turtle to draw a star with n sides of l length"""
for _ in range(n):
turtle.forward(l)
turtle.left(2 * 360 / n) # calculate the angle
drawStar(7, 100)
turtle.exitonclick()
We can still get our five pointed star if we want but we can also get a seven pointed star:
Unfortunately, this logic only works for odd values of n. Even values give us back regular polygons of n / 2 sides. We need a different formula to generate stars with an even number of points...
The issue that t is undefined. If t is supposed to invoke some method in from the turtle module directly, use:
import turtle as t
Related
I need to draw a shape using recursion and turtle graphics.
I'm more of a looper and rarely ever use recursion, so some help here with this would be nice. Not even sure where to start.
The shape just needs to be cool looking.
Oh man! What a fun problem :)
As you are a self-proclaimed 'looper', I would think about recursion just as you would looping.
In a for loop, you execute the body of the loop until the for loop condition is satisfied. Now, recursion is very similar. You keep calling the function until the parameters of the function no longer hit a recursive case. They hit a base case instead which then returns a value that the recursion can then build up on.
So thinking about recursion this way, let's think about how to draw a square. You need to first identify what parts of the code get repeated (i.e. what would be in the body of a for loop trying to do the same thing). Then, identify when you want this repetition to stop (i.e. how do I know when a for loop exits).
While drawing a square, I can think of two major things that get repeated at least 4 times. The turtle goes forward a certain number of steps and the turtle turns 90 degrees (or 270 degrees depending on orientation). So this would be something we detail in our recursive case.
Now, let's think about the base case. Well, we know that a square has 4 sides, so after the turtle draws four sides, we want it to stop.
Lastly, let's think about the function declaration and how these two pieces, the recursive case and the base case, play into it. A function declaration may take the following form (in Python):
def draw_square_recursive(turn_deg=90, side_len, sides=4):
"""
Function draws a square with turtle graphics recursively
:param turn_deg: an int, the number of degrees a turtle should turn
:param side_len: an int, the length of a side of the square
:param sides: an int, the number of sides in our square
"""
turn_deg and side_len will be important for our recursive case as they define how a turtle should turn and how far it should 'walk'. sides is an interesting parameter and one we can use to dictate whether to continue recurring or stop. If we subtract 1 from sides every time we draw a side, we will know that we need to stop recurring when sides == 0, a base case!
Thus, whenever we call our function to recur again, we will call it as, draw_square_recursive(side_len, sides-1):
Overall, the structure of the function would look like:
def draw_square_recursive(turn_deg=90, side_len, sides=4):
"""
Function draws a square with turtle graphics recursively
:param turn_deg: an int, the number of degrees a turtle should turn
:param side_len: an int, the length of a side of the square
:param sides: an int, the number of sides in our square
"""
if sides == 0:
# base case!
else:
# recursive case!
Note that this function named draw_square_recursive but it can be much more generalized to other shapes. Do you see how?
Sorry if this was a long winded answer! Hope it helps ;p
Without any parametrization, here a beginning:
import time
from turtle import *
def recurse(n):
if n>0:
left(10)
forward(5)
recurse(n-1)
recurse(20)
time.sleep(5)
When you create recursive function, you need to have a stop criterion that effectively guaranties your program will exit at some point.
More editorial than answer, but recursion like this:
def recurse(n):
if n>0:
left(10)
forward(5)
recurse(n-1)
which is better written as iteration:
for n in range(2):
left(10)
forward(5)
is similar to folks who ask, "How can I count the number of elements in a list using recursion?" Ditto drawing a square using recursion.
I understand the goal is to learn about recursion, but what seems to get lost is that there are times where recursion makes wonderful things happen and times where it just slows down your program. Fractals are an opportunity to so something of wonder with recursion:
import sys
from turtle import Turtle, Screen
def hilbert_curve(n, turtle, angle=90):
if n <= 0:
return
turtle.left(angle)
hilbert_curve(n - 1, turtle, -angle)
turtle.forward(1)
turtle.right(angle)
hilbert_curve(n - 1, turtle, angle)
turtle.forward(1)
hilbert_curve(n - 1, turtle, angle)
turtle.right(angle)
turtle.forward(1)
hilbert_curve(n - 1, turtle, -angle)
turtle.left(angle)
depth = int(sys.argv[1])
size = 2 ** depth
screen = Screen()
screen.setworldcoordinates(0, 0, size, size)
yertle = Turtle('turtle')
yertle.speed('fastest')
yertle.penup()
yertle.goto(0.5, 0.5)
yertle.pendown()
hilbert_curve(depth, yertle)
yertle.hideturtle()
screen.exitonclick()
USAGE
% python3 hilbert.py 5
(PARTIAL) OUTPUT
I'm not picking on the other answers, I'm suggesting you think big (or at least beyond "just needs to be cool looking".)
I really need help as I am stuck at the begining of the code.
I am asked to create a function to investigate the exponential distribution on histogram. The function is x = −log(1−y)/λ. λ is a constant and I referred to that as lamdr in the code and simply gave it 10. I gave N (the number of random numbers) 10 and ran the code yet the results and the generated random numbers gave me totally different results; below you can find the code, I don't know what went wrong, hope you guys can help me!! (I use python 2)
import random
import math
N = raw_input('How many random numbers you request?: ')
N = int(N)
lamdr = raw_input('Enter a value:')
lamdr = int(lamdr)
def exprand(lamdr):
y = []
for i in range(N):
y.append(random.uniform(0,1))
return y
y = exprand(lamdr)
print 'Randomly generated numbers:', (y)
x = []
for w in y:
x.append((math.log((1 - w) / lamdr)) * -1)
print 'Results:', x
After viewing the code you provided, it looks like you have the pieces you need but you're not putting them together.
You were asked to write function exprand(lambdr) using the specified formula. Python already provides a function called random.expovariate(lambd) for generating exponentials, but what the heck, we can still make our own. Your formula requires a "random" value for y which has a uniform distribution between zero and one. The documentation for the random module tells us that random.random() will give us a uniform(0,1) distribution. So all we have to do is replace y in the formula with that function call, and we're in business:
def exprand(lambdr):
return -math.log(1.0 - random.random()) / lambdr
An historical note: Mathematically, if y has a uniform(0,1) distribution, then so does 1-y. Implementations of the algorithm dating back to the 1950's would often leverage this fact to simplify the calculation to -math.log(random.random()) / lambdr. Mathematically this gives distributionally correct results since P{X = c} = 0 for any continuous random variable X and constant c, but computationally it will blow up in Python for the 1 in 264 occurrence where you get a zero from random.random(). One historical basis for doing this was that when computers were many orders of magnitude slower than now, ditching the one additional arithmetic operation was considered worth the minuscule risk. Another was that Prime Modulus Multiplicative PRNGs, which were popular at the time, never yield a zero. These days it's primarily of historical interest, and an interesting example of where math and computing sometimes diverge.
Back to the problem at hand. Now you just have to call that function N times and store the results somewhere. Likely candidates to do so are loops or list comprehensions. Here's an example of the latter:
abuncha_exponentials = [exprand(0.2) for _ in range(5)]
That will create a list of 5 exponentials with λ=0.2. Replace 0.2 and 5 with suitable values provided by the user, and you're in business. Print the list, make a histogram, use it as input to something else...
Replacing exporand with expovariate in the list comprehension should produce equivalent results using Python's built-in exponential generator. That's the beauty of functions as an abstraction, once somebody writes them you can just use them to your heart's content.
Note that because of the use of randomness, this will give different results every time you run it unless you "seed" the random generator to the same value each time.
WHat #pjs wrote is true to a point. While statement mathematically, if y has a uniform(0,1) distribution, so does 1-y appears to be correct, proposal to replace code with -math.log(random.random()) / lambdr is just wrong. Why? Because Python random module provide U(0,1) in the range [0,1) (as mentioned here), thus making such replacement non-equivalent.
In more layman term, if your U(0,1) is actually generating numbers in the [0,1) range, then code
import random
def exprand(lambda):
return -math.log(1.0 - random.random()) / lambda
is correct, but code
import random
def exprand(lambda):
return -math.log(random.random()) / lambda
is wrong, it will sometimes generate NaN/exception, as log(0) will be called
I wrote the code for an assignment which completes the task required. Which is to draw the shape of a polygon from user input and draw the amount of shapes per side number specified. The only problem is after the shape is drawn the arrow just keeps tracing through in an infinite loop. I tried using break at the end but it did not work.
from turtle import *
def polygon(n, length):
Screen()
shape('turtle')
mode('logo')
n = input ("Enter number of sides ")
print ("you entered ", n)
length = input("Enter the length of sides ")
print ("you entered ", length)
n=int(n)
length=int(length)
for side in range(n):
forward(length)
right(360/n)
while side in range(n):
right(360/n)
for side in range(n):
forward(length)
right(360/n)
What I have so far will technically work for the assignment, however the infinite loop at the end is annoying me.
The main problem is that the while loop goes for an infinite amount of time.
#This is infinite loop because 'side' iterator is ALWAYS in the sequence returned from range function
while side in range(n):
Also, with the current structure
of your code the function does nothing and only wastes space (you probably call it from the shell which is
understandable). There's a few more redundancies that we can get ride of too. Lets design your script so that the turtle's
polygons can be controlled from the function you created. Hopefully you'll see how powerful the turtle module
can be when utilized with recursion and a proper use of functions.
Lets look at the declarion of your polygon function 1st. The reason I feel your script should revolve around your
polygon function aside from the natural convience of functions is because of the parameters you included in the script.
Although they are not needed (here atleast) per the implied design of your script, the inclusion of them implies A: You
intended for this function to control the turtle, or B: You don't quite understand how functions/parameters work. To
offer more of a learning experience we should definitely focus this script around that function in either case.
def polygon(n,length): #<--- get ride of 'n' & 'length' parameters
def polygon(n=None,length=None): #<---These are defualt values if you wish to go with that direction
def polygon(): #<---This is the declaration I'll follow for aiding your script
Get rid of the paramaters for now. We'll bring them back in a nested function later. Next we're going to add the rest
of the script to the polygon function. Because your n and length variable collect input, it renders the parameters
for the polygon function useless. It's not an either or scenerio, with some control flow you can have both if you
wanted. Before we add the script to our polygon function I'd like to point out how you declared the variables twice, the
second time you converted them to integers. Python allows us to nest them in a int() function the 1st time we declare
them.
n = input("Enter num ")
n = int(n) #<---instead of these 1st 2 lines, do the 3rd line below.
n = int(input("Enter num: ")) #<--1 line of code that is equally as readable as 2.
After modifying both the n & length variables, lets add everything into our polygon function (except the while loop,
get rid of everything involved with that). Notice that the Screen,shape, and mode functions have been moved below the
variable declarions. This is so the turtle window does not jump in front of the user while they're inputing information
into the program.
def polygon():
n = int(input("Enter number of sides: "))
print("You entered %d sides.\n"%(n))
length = int(input("Enter length of sides: "))
print("Your sides are %d pixels long.\n"%(length))
Screen()
shape('turtle')
mode('logo')
Now that we have a clean and readable function lets handle our business with creating polygons. For this we'll use
a nested function that utilizes both recursion and parameters. We'll call it 'looper'. The reason being is that your
assignment is to make an equal amount of polygons that there are sides (in otherwords, num of polygons == n). looper will
achieve that for us. 1st it will take in the variables established in polygon as parameters. Then we'll use your previous
for loop inside.
def looper(n,length,loops=n): #notice the 'loops=n' default parameter, this allows to keep track of it recursively
if (loops > 0): #As long as loops is greater than zero this functin will repeat itself as many times as 'n'
for side in range(n):
forward(length)
right(360/n)
penup()
#penup after the forloop so that the turtle will not draw while searching for next polygon space
setposition(xcor()+length,ycor()+length) #xcor() and ycor() return the current position of the turtle
#notice that we add it to the length of of our sides, this is how the turtle will space out the polys.
#I would even experiment with things like setposition(xcor()+(length*2),ycor()+(length*2))
pendown() #after turtle find the position we we use pendown() to prepare to draw again
loops -= 1 #this decrements the loops parameter so that the functin will not call itself infinitely
#(stack overflow)
looper(n,length,loops) #recursively call our looper function again
return #I personally always return the end of recursive functions to be safe, this may be redundant
Essentially recursion is when a function calls itself within itself repeatedly to perform a task. To make sure that it
eventually ends we tell the program: "Only draw polygons if there are any loops" furthermore after the functions performs
it's duties we tell it "subtract loops by 1" to make sure that the loops will eventually be zero. This and the return
statement (a rough equivalent to what you were referring to as 'break') will assure us that we do not perfom tasks
an infinite amount of times. The last step in this code is to make sure that you actually call the polygon function
so your code will run AND to also call looper(n,length) and the end of your polygon function for the same reason.
Your code should look something like this:
from turtle import *
def polygon():
n = int(input("Enter number of sides: "))
print("You entered %d sides.\n"%(n))
length = int(input("Enter length of sides: "))
print("Your sides are %d pixels long.\n"%(length))
Screen()
shape('turtle')
mode('logo')
def looper(n,length,loops=n):
if (loops > 0):
for side in range(n):
forward(length)
right(360/n)
penup()
setposition(xcor()+length,ycor()+length)
pendown()
loops -= 1
looper(n,length,loops)
return
looper(n,length)
polygon()
I pretty much did the assignment for you, but if you learned a thing or two then my goal is achieved. I hope I helped any!
I'm trying to create a game in which 100 rocks are scattered through a large series of coordinates randomly. The problem is that sometimes the rocks may overlap each other. The solution I came up with was to check if the rocks overlap each other, and if they do, create new randomly generate coordinates for the rock again and again until it collides with nothing. I'm not entirely sure how to do this; I've tried detecting collision between the rock and the rock list, but all that ends up happening is that it thinks that it collides with itself and always returns as True. The __init__ function generates the coordinates with random.randint(-2500,2500). When the rocks are created in the for loop, each rock is added to the list. In the update function it checks for rectangular collision between the rocks. How can I fix this? Thanks, an answer would be much appreciated. Ask me if you need more information.
Well, I guess there are a few ways you can approach this problem:
1) The first would be the one you already used, you would check for collisions each time you generate a rock and if a collision exist you would regenerate a position for the given rock
2) The second one would be to slice your "field" into rectangles of the size of the rock, just like a tilemap, therefore creating a list of possible positions, something like this:
possible_positions = [(i, j) for i in range(x_size_field//x_size_rock) for j in range(y_size_field//y_size_rock)]
for i in range(n_of_rocks):
rock_pos = random.choice(possible_positions)
possible_positions.remove(rock_pos)
But this approach would implicate in a given set of possible positions that make a "uniform" rock distribution
3) So if its really necessary to make put the rocks on absolute random positions you could create a list of possible positions like the following:
possible_positions = [[(i, j) for j in range(y_size_field-y_size_rock)] for i in range(x_size_field-x_size_rock)]
for i in range(n_of_rocks):
# X and Y represente positions on the list not on the field
x = random.randint(0, len(possible_positions))
y = random.randint(0, len(possible_positions[x]))
# The rock positions
rock_pos = possible_positions[x][y]
# Now we remove the positions on the region of the new rock
for i in range(x,x+x_size_rock):
possible_positions[i] = possible_positions[i][0:y] + possible_positions[i][y+y_size_rock:-1]
if [] in possible_positions:
possible_positions.remove([])
Of course this code may generate errors (its a rather simple code) and it needs some optimizations, but i think you may get the general ideia from this.
Sorry about my english
I'm going through Think Python and I've reached recursion which is turning to be a great pain to understand for me.
There's this exercise, number 5, that shows me this piece of code:
def draw(t, length, n):
if n == 0:
return
angle = 50 #sets angle
fd(t, length*n) #make a turtle() "t" go forward length*n pixels while drawing
lt(t, angle) #makes turtle "t" turn left on itself "angle" (50) degrees
draw(t, length, n-1) #1st call
rt(t, 2*angle) #makes turtle "t" turn right "2*angle" (100) degrees
draw(t, length, n-1) #2nd call
lt(t, angle) #makes turtle "t" turn left "angle" (50) degrees
bk(t, length*n) #makes turtle "t" go backwards length*n pixels
And asks me to think of what it does and then run it. I ran it and I had trouble understanding why it does what it does.
It is a much more complex case of recursion that the ones the books presented for explaining this device and I cannot understand it.
Lets make n for example 2 in order to understand a simple instance of this problem:
What I can make out is that the code calls itself until n=0 up to the first call consecutively, then returns the control to n=1 and makes the remaining lines of code from call 1 to call 2. It makes the second call with n=0 and returns but I cannot understand what instance of the function it returns the control of the program.
I'd be glad if someone could point me in the right direction as how to think this kind of recursive code by myself, how can I make use of it (when a for statement wouldn't quite make it) and a way to schematize the way it works (with some sort of diagram, for example?).
I have this:
function called with n=2
function called with n=1
function called with n=0; returns to:
function called with n=1 makes the 2nd call to the function with n=0
function called with n=0; returns to where?
??????
As you can see it is quite impractical for, let's say, a function call with n = 7.
A function always returns directly to its caller. Your recursive function does some work, calls itself, then when the call returns, does some more work, then calls itself another time, then when that returns, does some final work, before the function ends and itself returns:
work
call
work
call
work
return
That is, unless n == 0 is true, then the function immediately returtns. Every recursive call subtracts 1 from n so as long as n was positive to start with, your recursion ends at some point.
Recursion is simply the act of running the same function again, so you can substitute each call in the above 'diagram' with the same jobs being executed. Lets do this once:
n = 2
work
n = 1
work
call
work
call
work
work
n = 1
work
call
work
call
work
return
work
return
I've added in the value for n, provided we start with n = 2. Of course, once you get down to n = 0, the call immediately returns; we can fill that in too:
n = 2
work
n = 1
work
n = 0
return
work
n = 0
return
work
return
work
n = 1
work
n = 0
return
work
n = 0
return
work
return
work
return
Now we have the full call tree for your recursive function, for n = 2. For higher values of n, just keep indenting and filling in the work - call - work - call - work - return lines anywhere there is a call line for the previous level, and you can build a full call tree for any recursive function.
So I've met the same issue to understand this exercice and i think there is nothing better than a schema or a picture to easily understand it , so here is my explanation for the first iteration of the code (using this same logic you'll understand the rest of the code easily) :