Python Forum
Nested while loop problem + turtle - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Nested while loop problem + turtle (/thread-19602.html)



Nested while loop problem + turtle - DreamingInsanity - Jul-06-2019

Here's a bit of info. I am creating a simple program (for now) that takes an image, makes it black and white, then using turtle, draws it on the screen.

from PIL import Image 
from turtle import *

image_path = "image.png"
loaded_image = None
x, y, old_x = 0, 0, 0

def convert_img():
    image_file = Image.open(image_path)
    image_file = image_file.convert('L')
    image_file.save('bw_image.png')

def get_pix_col(pixels, x, y):
    return pixels[x,y]
    
def draw(img, pixels):
    global old_x, x ,y
    while x < img.size[0]:
        while y < img.size[1]:
            pendown()
            brightness = get_pix_col(pixels, x, y)
            color(brightness, brightness, brightness)
            if(x == old_x):
                goto((-img.size[0]/2) + x, (-img.size[1]/2) + y)
            else:
                penup()
                goto((-img.size[0]/2) + x, (-img.size[1]/2) + y)
            old_x = x
            y += 1
        x += 1
    done()

def main():
    convert_img()
    loaded_image = Image.open('bw_image.png')
    pix = loaded_image.load()
    canvas_setup(loaded_image)
    draw(loaded_image, pix)

def canvas_setup(img):
    colormode(255)
    setup(img.size[0], img.size[1])
    bgcolor(0, 0, 0)
    speed(10)
    penup()
    setposition(-img.size[0], -img.size[1])
    
main()
The first problem with this is the nested while loops. They should go:
Output:
x,y: 0,0 0,1 0,2 0,3 0,4 ...
until 'y' reaches, 562 in the case of my image. But it is whatever the 'y' size of the image is.
When y is this the output becomes:
Output:
1,0 1,1 1,2 ...
over and over until 'x' is equal to the x size of the image (1000 in my case).
However the problem is, 'x' never increments, it always is 0. There's got to be a simple fix but I can't find it. The only reason I am not using a nested for loop is so that I can increment 'x' and 'y' with different values.

The other problem is how can I speed up the turtle? I am already using 'speed(10)' but it is still very slow when drawing. If I can speed it up a lot that would be nice!

Thanks,
Dream


RE: Nested while loop problem + turtle - ichabod801 - Jul-06-2019

You need to reset y to 0. When x is 0 and y reaches img.size[1], the inner loop ends. Then x is incremented, and it checks the inner loop's condition again. But since you didn't reset y, it skips the loop and increments x again, until the outer loop is done. So when you increment x, reset y.


RE: Nested while loop problem + turtle - DreamingInsanity - Jul-06-2019

(Jul-06-2019, 11:27 AM)ichabod801 Wrote: You need to reset y to 0. When x is 0 and y reaches img.size[1], the inner loop ends. Then x is incremented, and it checks the inner loop's condition again. But since you didn't reset y, it skips the loop and increments x again, until the outer loop is done. So when you increment x, reset y.

Ohhh right. I forgot about that!

Thanks.


RE: Nested while loop problem + turtle - DreamingInsanity - Jul-06-2019

As for speeding it up - I now have this:
from PIL import Image 
from turtle import *

image_path = "image.png"
loaded_image = None
x, y, old_x = 0, 0, 0

def convert_img():
    image_file = Image.open(image_path)
    image_file = image_file.convert('L')
    image_file.save('bw_image.png')

def get_pix_col(pixels, x, y):
    return pixels[x,y]
    
def draw(img, pixels):
    global old_x, x ,y
    while x < img.size[0]:
        while y < img.size[1]:
            pendown()
            brightness = get_pix_col(pixels, x, y)
            color(brightness, brightness, brightness)
            if(x == old_x):
                goto((-img.size[0]/2) + x, (img.size[1]/2) - y)
            else:
                penup()
                goto((-img.size[0]/2) + x, (img.size[1]/2) - y)
            old_x = x
            y += 1
        update()
        x += 1
        y = 0
    done()

def main():
    convert_img()
    loaded_image = Image.open('bw_image.png')
    pix = loaded_image.load()
    canvas_setup(loaded_image)
    draw(loaded_image, pix)

def canvas_setup(img):
    colormode(255)
    setup(img.size[0], img.size[1])
    bgcolor(0, 0, 0)
    tracer(0, 0)
    speed("fastest")
    penup()
    setposition(-img.size[0] / 2, img.size[1] / 2)
    
main()
All it does now is update the screen only once one line of the x has been completed. The auto screen refresh was disabled.
It is considerably faster than before, however, even with my image (1000x563) It still takes over 5 mins to draw it on the canvas.
What else can I do to speed it up?

EDIT: explanation