Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Running the same program until condition satisfied

I am trying to create a small program that searches a folder of images, chooses one, checks its size and finishes if the chosen image is at least 5KB. If it is not then I need it to loop back to the choosing step (and then the size check, and so on..)

I am using functions for the choosing and the size-check but when I try to use them in a while loop I get all sorts of indentation errors and now I’m very confused. I’ve commented the section where I was using the function, but really I guess I want the whole thing to loop back, to the comment at the top..
Here’s my code –

#CHOOSE POINT
def chosen():
    random.choice(os.listdir(r"/Users/me/p1/images"))

def size():
    os.path.getsize(r"/Users/me/p1/images/"+chosen)

thresh = 5000
while size < thresh:
    print(chosen + " is too small")
    # loop back to CHOOSE POINT
else:
    print(chosen + " is at least 5KB")

Am I thinking about this all wrong? Will using the function in my while-loop do what I want? What’s the best way to achieve what I’m trying to do? I’m quite new to this and getting very confused.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

The first thing to realise is that code like this:

def chosen():
    random.choice(os.listdir(r"/Users/me/p1/images"))

is only the definition of a function. It only runs each time you actually call it, with chosen().

Secondly, random.choice() will make a random choice from the list provided (although it’s fairly inefficient to keep reading that from disk every time you call it, and it’s unclear why you’d pick one at random, but that’s OK), but since you don’t actually return the value, the function isn’t very useful. A choice is made and then discarded. Instead you probably wanted:

def chosen():
    return random.choice(os.listdir(r"/Users/me/p1/images"))

Thirdly, this function definition:

def size():
    os.path.getsize(r"/Users/me/p1/images/"+chosen)

It tries to use chosen, but that’s just the name of a function you previously defined. You probably want get the size of an actual file that was chosen, which the function needs to be provided with as a parameter:

def size(fn):
    return os.path.getsize(r"/Users/me/p1/images/"+fn)

Now to use those functions:

file_size = 0
threshold = 5000
while file_size < threshold:
    a_file = chosen()
    file_size = size(a_file)
    if file_size < threshold:
        print(a_file + " is too small")
    else:
        print(a_file + " is at least 5KB")
print('Done')

The variable file_size is initialised to 0, to make sure the loop starts. The loop will keep going until the condition is met at the start.

Every time, chosen() is executed, the returned value is remembers as the variable a_file, which you can then use in the rest of the code to refer back to.

It then gets passed to size(), to obtain a size and finally, the test is performed to print the right message.

A more efficient way to achieve the same:

threshold = 5000
while True:
    a_file = chosen()
    file_size = size(a_file)
    if file_size < threshold:
        print(a_file + " is too small")
    else:
        break
print(a_file + " is at least 5KB")

The break just exits the while loop which would keep going forever since it tests for True. This avoid testing the same thing twice.

So, you’d end up with:

import random
import os


def chosen():
    return random.choice(os.listdir(r"/Users/me/p1/images/"))


def size(fn):
    return os.path.getsize(r"/Users/me/p1/images/"+fn)


threshold = 5000
while True:
    a_file = chosen()
    file_size = size(a_file)
    if file_size < threshold:
        print(a_file + " is too small")
    else:
        break
print(a_file + " is at least 5KB")
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading