Reputation: 59
I have a small loop for turtle to turn at 90 degrees after meeting the corner of the square. The first loop is fine but Python seem to forget to check condition at the next loop.
I start to draw at
t.setpos(-300,300)
This work fine for the first loop:
for i in range(4):
t.forward(600)
print(t.pos())
if t.pos() > (300,300):
t.right(90)
elif t.pos() > (300,-300):
t.right(90)
elif t.pos() > (-300, -300):
t.right(90)
elif t.pos() > (-300,300):
t.right(90)
But when I increase range()
to 5, the code forgets to check the elif t.pos() > (-300,300):
to t.right(90)
but instead Python continues to draw t.forward(600)
to this position:
(-300.00,900.00)
for i in range(5):
t.forward(600)
print(t.pos())
if t.pos() > (300,300):
t.right(90)
elif t.pos() > (300,-300):
t.right(90)
elif t.pos() > (-300, -300):
t.right(90)
elif t.pos() > (-300,300):
t.right(90)
Any idea why Python forgets to check a condition like this? Somehow I feel like I did wrong somewhere.
Upvotes: 1
Views: 118
Reputation: 41872
The seemingly easy fix is this comparision is backward:
elif t.pos() > (-300, 300):
it should be:
elif t.pos() < (-300, 300):
The reason you don't see it in the range(4)
case is the loop quits before ever executing it. In the range(5)
case it finally executes and the inverted comparision causes the failure.
However, there are significant problems with this code which will show up as you build upon it. Although your debugging print(t.pos())
statement shows:
(300.00,300.00)
(300.00,-300.00)
(-300.00,-300.00)
(-300.00,300.00)
(-300.00,900.00)
What's really happening is:
(300.0, 300.0)
(300.00000000000006, -300.0)
(-299.99999999999994, -300.00000000000006)
(-300.00000000000006, 299.99999999999994)
(-300.00000000000017, 900.0)
The reason you don't see this, is because t.pos()
doesn't return a generic tuple
, it returns a specialization of tuple
called Vec2D
which has it's own repr()
method which masks the floating point fuzziness, by only showing two digits of precision:
def __repr__(self):
return "(%.2f,%.2f)" % self
You might expect your clauses to fire in order, but they don't:
Position: (300.0, 300.0)
trips the second clause: elif t.pos() > (300,-300):
position: (300.00000000000006, -300.0)
trips the first clause: if t.pos() > (300,300):
position: (-299.99999999999994, -300.00000000000006)
trips the third clause: elif t.pos() > (-300, -300):
and positions:
(-300.00000000000006, 299.99999999999994)
(-300.00000000000017, 900.0)
don't trip any of the clauses. Add some print()
statements to convince yourself of this.
Upvotes: 1
Reputation: 59
Here is my solution, it might not be efficient but it work, somehow...
if myturtle[count].xcor() > 300 and myturtle[count].heading() == 0:
myturtle[count].right(90)
if myturtle[count].ycor() < -300 and myturtle[count].heading() == 270:
myturtle[count].right(90)
if myturtle[count].xcor() < -300 and myturtle[count].heading() ==180:
myturtle[count].right(90)
if myturtle[count].ycor() > 300 and myturtle[count].heading() == 90:
myturtle[count].right(90)
Upvotes: 1