kempfa
Posts: 8
Joined: Wed Nov 22, 2017 8:57 pm

Random.Choice and while loop

Thu Dec 07, 2017 5:54 pm

Hello,

in the attached code I add a loop which selects a bottle from a list of bottles. This selection should be saved in a file and checked the next time you run it. If the new selection should be the same as the one saved in the file, then the loop should run until the contents are not the same.
The selection from the next run should then be saved in the file.

The program runs so far, a selection is made, the contents of the file are read and displayed. Finally, the selection is also saved in the file and replaced by the new one the next time it is run.

However, I have a problem with the part when the selected bottle is the same as the previous one.

I'm still at the beginning of programming in Python, maybe you can give me a tip or tell me what I'm doing wrong.

Thank you in advance!

bottle.py is an empty file the beginning, just for saving der choosen bottle of the last run.

Code: Select all

import random
import time

##Select which bottle to take
selectbottle = random.choice(["1","2","3","4"])
bottle = open('/home/pi/Scripts/bottle.py','r')
formerbottle = bottle.readlines()
bottle.close()
print(selectbottle)
print(formerbottle)
time.sleep(0.5)
	
while True:
    if selectbottle == formerbottle:
        print("equal")

    if not selectbottle == formerbottle:
        f = open('/home/pi/Scripts/bottle.py','w')
        f.write(selectbottle)
        f.close()
        break
    break
    time.sleep(0.5)

User avatar
davidcoton
Posts: 5027
Joined: Mon Sep 01, 2014 2:37 pm
Location: Cambridge, UK
Contact: Website

Re: Random.Choice and while loop

Thu Dec 07, 2017 6:01 pm

If I've got it right, the problem is the second break statement.
The first one is right: exist the "while true" loop when the new bottle is different.
But the second one is executed outside the "if not" code, so it exits even when the bottles are equal.
Just delete the second break line, without changing the indentation of any other lines.

(Sorry if that's wrong, my Python is a little rusty right now.)
Signature retired

kempfa
Posts: 8
Joined: Wed Nov 22, 2017 8:57 pm

Re: Random.Choice and while loop

Fri Dec 08, 2017 7:13 am

Hi,

first of all, thank you for your help. I tried it, but it doesn't work. When I delete the second break it prints "Equal" all over the display.

If selectbootle is the same as formerbottle then a new random. choice shall be performed again until selectbootle is not equal to formerbottle.

Then the selected bottle should be displayed and the result written to the file. The second part of while True already works, it's reading out the contents of the file and writing it to the variable formerbottle. Only the first part of the while True loop doesn't work right.

Thx!

User avatar
Paeryn
Posts: 2966
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: Random.Choice and while loop

Fri Dec 08, 2017 8:52 am

Your while True: bit as it stands is totally superfluous (the loop, not the contents of the loop) as the code inside the while loop will be executed once and once only (apart from the time.sleep(0.5) at the end of the loop which will never be executed since the break on the line immediately above it terminates the loop there and then).

In your description you said
kempfa wrote:If selectbootle is the same as formerbottle then a new random. choice shall be performed again until selectbootle is not equal to formerbottle.
But in your code the only time you make that choice (and the only time you read the file) is right at the start before the while loop, so if you do go around the loop a second time you will get the exact same result as you did the first time.
She who travels light — forgot something.

jbudd
Posts: 1409
Joined: Mon Dec 16, 2013 10:23 am

Re: Random.Choice and while loop

Fri Dec 08, 2017 9:02 am

Code: Select all

#!/usr/bin/env python

import random
import time

##Select which bottle to take
selectbottle = random.choice(['1','2','3','4'])
bottle = open('/home/pi/bottle.py','r')
formerbottle = bottle.readline()
bottle.close()
print(selectbottle)
print(formerbottle)
time.sleep(0.5)

while True:
    if selectbottle == formerbottle:
        print("equal")
        selectbottle = random.choice(['1','2','3','4'])
        print(selectbottle)
        print(formerbottle)

    if not selectbottle == formerbottle:
        f = open('/home/pi/bottle.py','w')
        f.write(selectbottle)
        f.close()
        break
    time.sleep(0.5)
You should only break from the loop when the values are different - the second "break" is an error.
If the values are the same, you need to make another random choice within the While loop
It only worked for me when I changed readlines() to readline()

Also I removed the "/Scripts" from pathnames since I don't have that directory on my Pi

jbudd
Posts: 1409
Joined: Mon Dec 16, 2013 10:23 am

Re: Random.Choice and while loop

Fri Dec 08, 2017 9:16 am

This is better:

Code: Select all

#!/usr/bin/env python

import random
import time

bottle = open('/home/pi/bottle.py','r')
formerbottle = bottle.readline()
bottle.close()

while True:
    ##Select which bottle to take
    selectbottle = random.choice(['1','2','3','4'])
    print(selectbottle)
    print(formerbottle)

    if selectbottle == formerbottle:
        print("equal")

    if not selectbottle == formerbottle:
        f = open('/home/pi/bottle.py','w')
        f.write(selectbottle)
        f.close()
        break

    time.sleep(0.5)

User avatar
davidcoton
Posts: 5027
Joined: Mon Sep 01, 2014 2:37 pm
Location: Cambridge, UK
Contact: Website

Re: Random.Choice and while loop

Fri Dec 08, 2017 4:22 pm

jbudd wrote:
Fri Dec 08, 2017 9:16 am
This is better: ...
Yes, that should work. Now we can clean up the logic (just one condition, at the expense of erepeating the random.choice line), the naming of variables (meaningful and consistent style), and the diagnostic prints (so we know what is being printed):

Code: Select all

#!/usr/bin/env python

import random
import time

bottlefile = open('/home/pi/bottle.py','r')
formerbottle = bottlefile.readline()
bottlefile.close()
print("Previously: ", formerbottle)

selectbottle = random.choice(['1','2','3','4'])
print("This time:", selectbottle)
while selectbottle == formerbottle:
    print("equal")
    #Re-select which bottle to take
    selectbottle = random.choice(['1','2','3','4'])
    print("This time:", selectbottle)
    time.sleep(0.5)
   
bottlefile = open('/home/pi/bottle.py','w')
bottlefile.write(selectbottle)
bottlefile.close()
I'm sure the Python purists can do better! There is certainly room for more comments (on each "paragraph" of code, for example).
Interesting extensions:
  • Add a "dictionary" of bottle descriptions, with options to extend or amend it. Show description not number of bottle.
  • Add stock levels, do not select out of stock bottles.
  • Allow user to reject a selection, then make another.
(Tested on Python 3.6.0 on Windows 10 64bit)
Signature retired

Return to “Beginners”