Cannot figure out why this code isn't looping a second time - python-3.x

This for loop is running once, but not running a second time.
I've put print() statements everywhere to confirm:
-round = 2, on the second pass.
-The loop comes up to the 'for' statement on the second pass, but the 'print' statement I put before "doChecks = True" didn't trigger.
-ClockCheck() is no factor; it fires perfectly first time, isn't called second time.
I've been up for ~20 hours and I figure I have to be missing something obvious. I'm going to sleep so I can re-attack fresh in the morning...hopefully it's obvious to someone else?
def scoreThisRound(answerKey, round):
global stopTime
global gameInProgress
userInput = [] #Initialize user input list
for i in range(round): #This is not starting a second loop!
doChecks = True
if clockCheck(): #If there is still time remaining
userInput.append(input(">")) #Get user input and add it to a list.
else:
print("ClockCheck Failed # ScorethisRound")
gameInProgress = False
doChecks = False
if doChecks == True:
for i in range(len(answerKey)):
if answerKey[i] == userInput[i]:
print("Good Answer!") #change this code to add time
stopTime += 1.5
else:
print("Bad Answer!") #change this code to subtract time
stopTime -= 3
Here is the output from the console:

Solved, and it was something obvious. My "if doChecks" statement was tabbed too far over; that's why it was running fine the first time (round = answers = user input), but second time the loop went (2 = 2 = 1), and threw the exception.
Lesson learned:
1) Sleep. It's important.
2) Need to get an IDE that shows tabs and spaces as something other than whitespace, which kinda blends together for me.
Thanks!

Related

Having a break within a loop and waiting for the person to continue

Hi i am running an experiment which has 120 trials. i want to add a break in the loop every 30 trials and wait for the participants to press a key when they are ready to continue. my code for the loop looks like this
start.draw()
win.flip()
event.waitKeys(keyList=['return'])
win.flip()
cross.draw()
win.flip()
event.waitKeys(keyList=['5'])
for stim in stroop:
colour.text = stim[0]
colour.color = stim[1]
colour.draw()
display_time = win.flip()
how can i add a break into this for loop?
Thank you!!
You can use enumerate to keep track of the number of iterations made:
for idx, stim in enumerate(stroop):
# The +1 makes it so we avoid asking the user's input on first iteration.
if (idx + 1) % 30 == 0:
event.waitKeys(keyList=['return'])
[...]
By the way, breaks in python refers to breaking out of the loop. What you want to do is rather "wait for user input".

Testing and accepting User Input in Python using a while loop

What am I doing wrong?
valid = set(["Mon","Tue","Wed","Thu","Fri","Sat","Sun","All"])
value = input("Enter the day of interest or all for all days. Valid Values are Mon,Tue,Wed,Thu,Fri,Sat,Sun,All: ")
count = 0
while count <= 3:
if value in valid:
print("Awesome!! You chose {}".format(value.title()))
break
else:
count += 1
pass
print("Try Again")
else:
print("Too many errors. Read the instructions and come back again when ready!! :-| ")
exit()
So this works if I enter a valid value but if I test for a value outside the set, the else from the if loop ('Try Again') executes 3 times (setting the counter and then jumps to the else of the while loop.
I had wanted the input box to appear again and persist till either:
1. User entered the right value in 3 tries
2. Got a message and got booted out of the program returning them to command prompt.
Thanks in advance. Doing a tutorial project and completely stuck on this. Should I be using try/except? If so, would I still be able to set a counter?
You need to allow the user to enter input again. Place the input entering line below the Try again part.
print("Try Again")
value = input("Enter the day of interest or all for all days. Valid Values are Mon,Tue,Wed,Thu,Fri,Sat,Sun,All: ")
You also do not require the pass statement.
And please note that you're starting count from 0, that actually gives the user 4 chances, not 3. (Start with count=1)

Python3 - Advice on a while loop with range?

Good afternoon! I am relatively new to Python - and am working on an assignment for a class.
The goal of this code is to download a file, add a line of data to the file, then create a while loop that iterates through each line of data, and prints out the city name and the highest average temp from the data for that city.
My code is below - I have the output working, no problem. The only issue I am running into is an IndexError: list index out of range - at the end.
I have searched on StackOverflow - as well as digging into the range() function documentation online with Python. I think I just need to figure to the range() properly, and I'd be done with it.
If I take out the range, I get the same error - so I tried to change the for/in to - for city in mean_temps:
The result of that was that the output only showed 4 of the 7 cities - skipping every other city.
Any advice would be greatly appreciated!
here is my code - the screenshot link below shows output and the error as well:
!curl https://raw.githubusercontent.com/MicrosoftLearning/intropython/master/world_temp_mean.csv -o mean_temp.txt
mean_temps = open('mean_temp.txt', 'a+')
mean_temps.write("Rio de Janeiro,Brazil,30.0,18.0")
mean_temps.seek(0)
headings = mean_temps.readline().split(',')
print(headings)
while mean_temps:
range(len(city_temp))
for city in mean_temps:
city_temp = mean_temps.readline().split(',')
print(headings[0].capitalize(),"of", city_temp[0],headings[2], "is", city_temp[2], "Celsius")
mean_temps.close()
You have used a while loop, when you actually want to use a for loop. You have no condition on your while loop, therefore, it will evaluate to True, and run forever. You should use a for loop in the pattern
for x in x:
do stuff
In your case, you will want to use
for x in range(len(city_temp)):
for city in means_temp:
EDIT:
If you have to use a while loop, you could have variable, x, that is incremented by the while loop. The while loop could run while x is less than range(len(city_temp)).
A basic example is
text = "hi"
counter = 0
while counter < 10:
print(text)
counter += 1
EDIT 2:
You also said that they expected you to get out of a while loop. If you want a while loop to run forever unless a condition is met later, you can use the break command to stop a while or for loop.
I've been stuck with this as well with the index error. My original code was:
city_temp = mean_temp.readline().strip(" \n").split(",")
while city_temp:
print("City of",city_temp[0],headings[2],city_temp[2],"Celcius")
city_temp = mean_temp.readline().split(",")
So I read the line then, in the loop, print the line, create the list from reading the line and if the list is empty, or false, break. Problem is I was getting the same error as yourself and this is because city_temp is still true after reading the last line. If you add..
print(city_temp)
to your code you will see that city_temp returns as "" and even though it's an empty string the list has content so will return true. My best guess (and it is a guess) it looks for the split condition and returns back nothing which then populates the list as an empty string.
The solution I found was to readline into a string first (or at the end of the whole loop) before creating the list:
city_temp = mean_temp.readline()
while city_temp:
city_temp = city_temp.split(',')
print(headings[0].capitalize(),"of",city_temp[0],headings[2],"is",city_temp[2],"Celcius")
city_temp = mean_temp.readline()
This time city_temp is checked by the while loop as a string and now returns false. Hope this helps from someone else who struggled with this

PyEphem: How to test if an object is above the horizon?

I am writing a Python script that gives basic data for all the planets, the Sun and the Moon. My first function divides the planets between those that are above the horizon, and those that are not risen yet:
planets = {
'mercury': ephem.Mercury(),
'venus': ephem.Venus(),
'mars': ephem.Mars(),
'jupiter': ephem.Jupiter(),
'saturn': ephem.Saturn(),
'uranus': ephem.Uranus(),
'neptune': ephem.Neptune()
}
def findVisiblePlanets(obs):
visiblePlanets = dict()
notVisiblePlanets = dict()
for obj in planets:
planets[obj].compute(obs)
if planets[obj].alt > 0:
visiblePlanets[obj] = planets[obj]
else:
notVisiblePlanets[obj] = planets[obj]
return (visiblePlanets, notVisiblePlanets)
This works alright, the tuple I receive from findVisiblePlanets corresponds corresponds to the actual sky for the given 'obs'.
But in another function, I need to test the altitude of each planet. If it's above 0, the script displays 'setting at xxx', and if it's under 0, the script displays 'rising at xxx'. Here is the code:
if bodies[obj].alt > 0:
print(' Sets at', setTime.strftime('%H:%M:%S'), deltaSet)
else:
print(' Rises at', riseTime.strftime('%H:%M:%S'), deltaRise)
So I'm using the exact same condition, except that this time it doesn't work. I am sure I have the correct object behind bodies[obj], as the script displays name, magnitude, distance, etc. But for some reason, the altitude (.alt) is always below 0, so the script only displays the rising time.
I tried print(bodies[obj].alt), and I receive a negative figure in the form of '-0:00:07.8' (example). I tried using int(bodies[obj].alt) for the comparison but this ends up being a 0. How can I test if the altitude is negative? Am I missing something obvious here?
Thanks for your help.
I thinkk I had a similar problem once. How I understand it pyephem forwards the time of your observer, when you call nextrising() or nextsetting() on a object. It somehow looks, at which timepoint the object is above/below the horizont for the first time. if you then call the bodie.alt it will always be this little bit below/above horizon.
You have to store your observer time somehow and set it again after calculating setting/rising times.

Python itertools product start from certain

I have a very big product expected from a itertools.product.
for result in product(items, repeat=9):
# stuff
It takes a lot of time, and I am searching for a way to start from a certain item because I won't be able to do it on one run.
I could do the following:
gen = product(items, repeat=9):
for temp in gen:
if temp == DESIRED_VALUE:
break
for result in gen:
# stuff
But it will take a lot of time, almost the same as if I was just restarting the program. So, is there a way to "skip ahead" without wasting the time on iterating the whole thing?
Although I have serious concerns about brute-forcing a passsword in the first place, I can offer an answer.
You can use islice to skip a certain number of steps in iteration. This means that you would need to keep track of how many attempts you have done so far to know where to resume later.
START_VALUE = 200
all_combos = itertools.product(letters,repeat=9)
#start at START_VALUE and stop at None (the end)
combos = itertools.islice(all_combos,START_VALUE,None)
for i,password in enumerate(combos,start=START_VALUE):
...
note that this will only work for values below sys.maxsize.
You can also calculate the index of a given password with the same formula to convert bases:
def check_value(password):
pos = len(letters)
value = 0
for i,c in enumerate(reversed(password)):
value+= (pos**i) * letters.index(c)
return value
>>> check_value("aaaacbdaa")
29802532

Resources