Why is turtle lightening pixels? - python

My program for creating a Mandelbrot set has a bug: whenever the pen changes colors, and every 42nd pixel after that, is lighter. This is, rather coincidentally, a mandelbug (yes, I just learned that term), as it is inconsistent for many pixels near an "edge" (it might actually be blurred between the color it's supposed to be and the color the last, or next, pixel is supposed to be), but it's always the 42nd pixel after that one until the next color change. I am using OSX 10.6.8, PYTHON 2.7. When I wrote this program at school, it worked perfectly (Windows), and then I sent it to myself, and worked on it a little more (mostly just making the sample size and therefore image larger), and ran it, I got this bug. EDIT: My bad, I forgot to mention that this only happens with my Mandelbrot program, the few other turtle programs I have at home are fine.
Parts of screenshots (so that you don't have to wait forever while the program runs to see what I'm talking about):
From my first version from home:
From the current version (sideways):
Heres the code:
import turtle
import math
turtle.speed(0)
def benoit(onelen):
turtle.left(90)
for x in range(-2*onelen, onelen):
turtle.up()
turtle.goto(x, int(-1.5*onelen)-1)
turtle.down()
for y in range(int(-1.5*onelen)-1, int(1.5*onelen)-1):
z = complex(0,0)
c = complex(x*1.0/onelen,y*1.0/onelen)
for k in range(20):
z = z*z+c
if abs(z) > 2:
g = .2 + .8*(20-k)/20
break
if k == 19:
g = 0
turtle.pencolor(0,g,0)
turtle.forward(1)
benoit(250)
x = raw_input("Press Enter to Exityadayadayada")
EDIT: A fix has been suggested by DSM, who likes this bug. However, I have no experience editing Python source code, and all the underscores are making me nervous. Can someone tell me specifically what to edit and/or how?

Wow. I think this is one of my favourite bugs ever, and believe it or not, the fact that the number happens to be 42 is actually relevant! Well, peripherally, anyhow..
In turtle.py:
def _goto(self, end):
"""Move the pen to the point end, thereby drawing a line
if pen is down. All other methodes for turtle movement depend
on this one.
[...]
###### vererbung!!!!!!!!!!!!!!!!!!!!!!
self._position = end
if self._creatingPoly:
self._poly.append(end)
if len(self.currentLine) > 42: # 42! answer to the ultimate question
# of life, the universe and everything
self._newLine()
self._update() #count=True)
So the problem comes about when it decides to break a line, apparently for performance reasons:
def _newLine(self, usePos=True):
"""Closes current line item and starts a new one.
Remark: if current line became too long, animation
performance (via _drawline) slowed down considerably.
"""
I was able to "fix" the bug by bumping up the linenumber limit and/or scattering self._pencolor references in places that didn't have any. But you're not crazy, anyway, and it's not really anything that you're doing. :-)

Can i offer a suggestion?
i tried your code and it was taking forever to run which you are aware of but what you may not be aware of is the tracer function... i simply put at the beginning of your code:
wn=turtle.Screen()
wn.tracer(10000)
that also eliminates the need for the speed(0) function :)
Try that and run it again, i did and it rendered the whole image in 62 seconds, i timed it by importing the time module by putting this code at the beginning:
import time
st=time.time()
and this code at the end:
print time.time()-st
Well done by the way, Ive just made my own thats a lot slower and lower quality then yours but was using an array of the square shape and stamping to each location i wanted in the array lol, but will be trying to improve it in the future as i only found out turtle existed less then a week ago.
One last thing, if you type:
from turtle import *
instead of "import turtle" you dont need to put turtle at the beginning of every function call :) same thing goes for every other module.
Ive included the pic of your fractal that took 62 seconds to render on my machine thats not even that powerfulYour code run on my weak machine.
I hope all this helps you greatly. also youll notice i dont have that light line problem, not sure if you fixed that issue in the original code up top?

Related

What modules should I use to make my grid swap letters as intended?

I have a crossword puzzle project. I have a puzzle and a random letter generator for every time I press run. Here is the code,
import random
import string
for x in range(4):
for y in range(4):
print( '['+random.choice(string.ascii_letters)+']',end='' )
print()
This results in the following output
[O][E][R][i]
[g][c][C][J]
[D][M][Z][X]
[y][A][M][Q] (letters are randomly generated)
I want to take it to the next level by implementing code which will swap the places of two blocks in the grid which are either exactly above, below, to the left or to the right of each other. Furthermore, I want this to be done only through touch, not any commands
Through research I have learnt that some modules could be used such as the Kivy module or the touch module but I'm not entirely sure. Can anyone please suggest what should I check to get started on this?

Using recursion in pygame

I'm new to python and programming in general and am working on a final project for a python centric class. One of the requirements that I cant seem to figure out how to make work is to integrate recursion into our code in order to show a working knowledge. I've worked up a simple "bullet hell" style game using pygame.
My goal is that when contact is made between a bullet and an enemy, that a series of bullet sets will be launched from the player position as a sort of short-term modifier.
This code runs in the main loop whenever a bullet hits an enemy:
for i in reversed(range(len(bullets))):
for j in reversed(range(len(enemies))):
if bullets[i].collided(enemies[j].rect):
del enemies[j]
del bullets[I]
s.global_score += 100
more_bullets(10)
#print("Hit!")
#print(s.global_score)
break
The "more_bullets" function is the focus of my recursion, and calls this:
def more_bullets(n):
if(n > 0):
spawnx = sq.rect.x+10 + sq.rect.width/2 - 10
b = Square(s.red, spawnx,sq.rect.y, 10,30)
b.direction = 'N'
b.player_speed = 10
bullets.append(b)
spawnx = sq.rect.x-10 + sq.rect.width/2 - 10
b = Square(s.red, spawnx,sq.rect.y, 10,30)
b.direction = 'N'
b.player_speed = 10
bullets.append(b)
pygame.display.update()
more_bullets(n-1)
print(f"Fired x {n}")
The outcome currently is that my debug does print 10 times making me think that the recursion is functioning correctly, however only one set of bullets is firing when the collision occurs. I'm thinking that all 10 bullets are firing faster than I can register it and just stacking on the screen.
Is there an easy-to-use function that might slow down the firing of the bullets? or have messed up something more fundamentally here?
I'm thinking that all 10 bullets are firing faster than I can register it and just stacking on the screen.
You're correct.
I don't believe there's an "easy way" to do what you're asking the way you think. The recursion is immediate, meaning that the function runs 10 times right away when it's called. For it to send out a burst of staggered bullets, you'd need some kind of timer or queue or something along those lines that runs alongside your main loop, and recursion isn't really a natural fit for that. The same will go for any kind of game logic function that plays out over a period of time.
This isn't what's being asked, but here's an idea of what you could do, even though it's kind of a redundant use of recursion: add a parameter to that function that dictates the angle the bullet is being shot. Then, add a little bit to that parameter on every recursive call. That way an arc of bullets will be shot at the same time.

Using onscreen.click() in turtle but only works at the end of the programme

This is the programme I wrote but I'm not sure what's wrong:-
import turtle
import random
bob = turtle.Turtle()
screen = turtle.Screen()
def coord(x,y):
print(x,y)
turtle.onscreenclick(None)
turtle.onscreenclick(coord)
turtle.listen()
print('hello')
turtle.done()
The programme works fine except that the print('hello') part happens first, followed by the on screen event. How do I make the onscreen event occur first before the rest of my programme?
You can simply make the rest of your code part of the coord function:
def coord():
print(x,y)
turtle.onscreenclick(None)
print("Hello")
# The rest of your program goes here.
However, a few things to note:
This isn't an amazing elegant solution, especially if you intend to set up other events further into your code. It can become quite hard to keep track of.
It's imperative that you remove the event binding (in this case the binding of coord to onscreenclick) as soon as it's been used, otherwise you could end up with multiple instances of the same code running at once if someone double-clicked the screen, for example. In your case you've already done this (with turtle.onscreenclick(None)), but it is something to keep in mind.
If you choose to go this route, don't forget to rename the coord function something more representative of what that section of your code will do.

Python Turtle Graphics - Bring A Turtle To The Front

I have two turtles in my program. An animation happened where they collide together, but I would like one turtle to be on top of the other like this:
So, my question is - how can I make this happen - is there a simple line of code such as: turtle.front(), if not what is it?
I discuss this briefly in my response to Make one turtle object always above another where the rule of thumb for this simple situation is:
last to arrive is on top
Since Python turtle doesn't optimize away zero motion, a simple approach is to move the turtle you want on top by a zero amount:
import turtle
def tofront(t):
t.forward(0)
gold = turtle.Turtle("square")
gold.turtlesize(5)
gold.color("gold")
gold.setx(-10)
blue = turtle.Turtle("square")
blue.turtlesize(5)
blue.color("blue")
blue.setx(10)
turtle.onscreenclick(lambda x, y: tofront(gold))
turtle.done()
The blue turtle overlaps the gold one. Click anywhere and the situation will be reversed.
Although #Bally's solution works, my issue with it is that it creates a new turtle everytime you adjust the layering. And these turtles don't go away. Watch turtle.turtles() grow. Even my solution leaves footprints in the turtle undo buffer but I have to believe it consumes less resources.
Just add this to turtle.py file
def tofront(self, tobring):
newfront = tobring.clone()
tobring.ht()
return newfront
works correct,
so method - sould return you new clone of turtle, on the top of all other turtles.
parameter tobring - it's your current turtle (the one you want to bring to front)
you can use this def in your program or put it into turtle.py file
if so, don't forget to add it to list of commands, - _tg_turtle_functions
_tg_turtle_functions = ['back', 'backward', 'begin_fill', 'begin_poly', 'bk',
'circle', 'clear', 'clearstamp', 'clearstamps', 'clone', 'tofront', 'color',
I did it after clone command
Hope this will help you

Adding a countdown timer in python

I'll admit, i am a newbie with python, but here is my issue.
the version is 2.6.5 (i know i'ts an old version but there's reasons to this) and livewires is used
Bascially this game has a bunch of colored balloons in which you need to click them to make them disappear. Adjacent balloons of the same color disappear along with the clicked balloon. Once the balloons are cleared it moves on to the next level.
I need to create a timer on the top right of my screen. This timer needs to countdown in seconds (from 30 might be a good start.) However no matter what i try, either the timer does not display or the numbers are overlap eachother. I would like to know how to do this, as it has been driving me up the wall as of late.
...Of course it also needs to end the game if it reaches zero and add more time if the level is complete...
But for now i just want to focus on displaying the timer and having it count down to zero on screen.
class Timer(games.Sprite):
""" countdown timer """
def __init__(self):
timer_message = games.Text(
value = 30,
size = 50,
color = red,
x = 600,
y = 30
)
def start(self):
while self.timer_message.value != 0:
time.sleep(1)
self.timer_message.value -= 1
game.screen.add(timer_message)
Alright. I fixed the "compressing balloons table" (accidentally deleted the self_update lol) problem, but now it is saying that "global name timer_message is not defined"... despite the fact that it says timer_message = games.Text
I would paste the whole code, but i can't get the indentation right (this is my first time using this website.)
So, I understand it's been some time and if you don't need an answer anymore that's alright.
For now it's hard to answer your question in general because I don't understand the structure of the rest of your code or how you're displaying graphics. However, I can tell you while you're getting the
global name timer_message is not defined
error. It's because when you define timer_message within the __init__ function you are defining it within the local scope of the function but not for the class. In order to make it accessible to the class you need to assign to self.timer_message.
This is a consequence of how python imitates object oriented programming, but making this change should address your immediate error.

Categories

Resources