python function skipping around - python

My intent is to read a list from a file, pick a random number from that list and remove it, then resave the list. Sometimes the function works fine, sometimes not.
choices=[]
with open("C:\\choices.txt", "r") as f:
for line in f:
choices.append(int(line.strip()))
if len(choices)==0:
choices=[0,1,2,3,4,5]
num=rdm.randint(0,5)
def chooseline(myList, myNum):
print("before if num= "+str(myNum))
if not myNum in myList:
myNum=rdm.randint(0,5)
chooseline(myList,myNum)
print("In NOT-IF num= "+str(myNum))#<-- Need to move before chooseline to print. ok
else:
myNum=myList.pop(myList.index(myNum))
print("in Else num= "+str(myNum))
print("end num= "+str(myNum))
return myNum
newnum= chooseline(choices,num)
with open("C:\\choices.txt", "w") as f:
for e in choices:
f.write(str(e) +"\n")
As long as the random number is in the list the function returns as expected, but if the first number is not on the list, it seems to loop back.
runfile('...')
before if num= 0
in Else num= 0
end num= 0
runfile('...')
before if num= 2
in Else num= 2
end num= 2
runfile('...')
before if num= 2 #ok not in list
before if num= 0 #ok chooses new number, but not in list
before if num= 4 # chose 4, in list
in Else num= 4 # as expected
end num= 4 #<----- expect to stop here and return 4
In NOT-IF num= 4
end num= 4 #
In NOT-IF num= 0
end num= 0

There is an easier and more efficient approach ...
import random
lines = []
with open('choices.txt', 'r') as file:
for line in file:
lines.append(int(line.rstrip()))
file.close()
with open('choices.txt', 'w') as file:
if len(lines) > 1:
number = lines[random.randint(0, len(lines) - 1)]
for line in lines:
if line != number:
file.write(f'{line}\n')
file.close()

Example without the recursion as mentioned in the comments:
import random
choices = []
with open("choices.txt", "r") as f:
for line in f:
choices.append(int(line.strip()))
if len(choices) == 0:
choices = [0, 1, 2, 3, 4, 5]
num = random.randint(0, 5)
def choose_num_in_list(max_attempts=100):
chosen_number = -1
attempts = 0
while chosen_number == -1 and attempts < max_attempts:
candiate_number = random.randint(0, 5)
attempts = attempts + 1
if candiate_number in choices:
chosen_number = candiate_number
return chosen_number
newnum = choose_num_in_list()
if(newnum != -1):
choices.pop(choices.index(newnum))
print(f"Removed {str(newnum)} from the list")
else:
print("Failed to remove a number from the list")
with open("choices.txt", "w") as f:
for e in choices:
f.write(str(e) + "\n")

Related

I'm getting IndexError: list index out of range when I know the index is within range

I'm getting the IndexError on line 50 (the sixth line of checkForDisallowedCharacters while j < len(resultSet[i]):)
I get this error when I input '***er', 't', and 'canpilru' into the console when prompted
Using my print statements I've found that this error occurs when the resultSet array has a length of 141, and when i is 0
resultSet[0] is 'paper' and it clearly exists
If anyone can explain why this is throwing an error I would be very grateful
import csv
import os
import sys
def buildDictionary():
dictionary = []
with open("./wordle-helper/wordle-dictionary.csv", newline='') as csvfile:
spamreader = csv.reader(csvfile, delimiter='\t')
for row in spamreader:
dictionary.append(row)
for i in range(len(dictionary)):
dictionary[i] = dictionary[i][0].lower()
return dictionary
def buildTestWordComposition(testWord):
testWordComposition = []
for i in range(len(testWord)):
if testWord[i] == "*":
testWordComposition.append(i)
return testWordComposition
def buildThreshold(testWord):
threshold = 0
for character in testWord:
if character != "*":
threshold += 1
return threshold
def checkForSoftMatches(dictionary, testWord, threshold):
resultSet = []
for word in dictionary:
testThreshold = 0
for i in range(5):
if testWord[i] == "*":
continue
elif testWord[i] == word[i]:
testThreshold += 1
if testThreshold == threshold:
resultSet.append(word)
return resultSet
def checkForDisallowedCharacters(resultSet, disallowedCharacters):
i = 0
while i < len(resultSet):
print(len(resultSet), i, resultSet[i][0])
j = 0
while j < len(resultSet[i]):
for character in disallowedCharacters:
if resultSet[i][j] == character:
try:
resultSet.remove(resultSet[i])
finally:
i -= 1
j = -1
break
j += 1
i += 1
if i < 0:
i = 0
elif i >= len(resultSet):
break
return resultSet
def checkForRequiredCharacters(resultSetNoDisallowedCharacters, requiredCharacters, testWordComposition):
resultSetChecked = []
threshold = len(requiredCharacters)
m = 0
resultSetCheckedLength = 0
while m < len(resultSetNoDisallowedCharacters):
compareToThreshold = 0
for aCharacter in requiredCharacters:
for number in testWordComposition:
if resultSetNoDisallowedCharacters[m][number] == aCharacter:
compareToThreshold += 1
break
if len(resultSetChecked) != resultSetCheckedLength:
break
if compareToThreshold == threshold:
resultSetChecked.append(resultSetNoDisallowedCharacters[m])
resultSetCheckedLength = len(resultSetChecked)
m += 1
return resultSetChecked
def wordleHelper(testWord, requiredCharacters=[], disallowedCharacters=[]):
dictionary = buildDictionary()
testWordComposition = buildTestWordComposition(testWord)
threshold = buildThreshold(testWord)
resultSet = checkForSoftMatches(dictionary, testWord, threshold)
resultSetNoDisallowedCharacters = checkForDisallowedCharacters(resultSet, disallowedCharacters)
resultSetChecked = checkForRequiredCharacters(resultSetNoDisallowedCharacters, requiredCharacters, testWordComposition)
if not resultSetChecked:
return resultSetNoDisallowedCharacters
return resultSetChecked
def printWordleHelper(testWord, requiredCharacters=[], disallowedCharacters=[]):
print("All possible words are listed below\n\n-----------------------------------------------\n")
for word in wordleHelper(testWord, requiredCharacters, disallowedCharacters):
print(word)
def handlePersistentCharacters(disallowedCharactersComplete):
willDisallowedCharactersPersist = input("Would you like to continue using your previous list of grey letters? (y/n): ")
if willDisallowedCharactersPersist == "y":
return disallowedCharactersComplete
elif willDisallowedCharactersPersist == "n":
return []
else:
print("Please enter a valid character")
handlePersistentCharacters(disallowedCharactersComplete)
def clearConsole():
if sys.platform.startswith('linux') or sys.platform.startswith('darwin'):
os.system('clear')
elif sys.platform.startswith('win'):
os.system('cls')
def buildParsed(unparsed):
parsed = []
for letter in unparsed:
parsed.append(letter)
return parsed
def handleUserContinue(disallowedCharactersComplete):
willUserContinue = input("Would you like to use World Helper (tm) again? (y/n): ")
if willUserContinue == "n":
sys.exit()
persistentDisallowedCharacters = handlePersistentCharacters(disallowedCharactersComplete)
if willUserContinue == "y":
promptUser(persistentDisallowedCharacters)
def promptUser(persistentDisallowedCharacters=[]):
clearConsole()
testWord = input("Please enter your Wordle guess in the form of *la*t where 'l', 'a', and 't' are the green letters from your guess, and the '*'s are yellow or grey letters from your guess: ")
requiredCharacters = input("Please enter your letters in yellow here in the form of 'abcxyz' (do not enter letters which are already in your Wordle guess string): ")
disallowedCharacters = input("Please enter your letters in grey here (in the form of 'abcxyz'): ")
requiredCharactersParsed = buildParsed(requiredCharacters)
disallowedCharactersParsed = buildParsed(disallowedCharacters)
disallowedCharactersComplete = persistentDisallowedCharacters + disallowedCharactersParsed
printWordleHelper(testWord, requiredCharactersParsed, disallowedCharactersComplete)
handleUserContinue(disallowedCharactersComplete)
promptUser()

Run program but nothing comes out

I tried to run this program but it seems time only exit code 0.
if __name__ == '__main__':
import random
f = open("quiz.csv", 'r')
Counter =0
Content = f.read()
Colist = Content.split("\n")
qlist=[]
calist=[]
adict={}
alist=[]
c=0
for i in Colist:
if i:
if (Counter%5 ==0):
if(Counter!= 0):
x = alist[0]
random.shuffle(alist)
calist.append(alist.index(x))
c+=1
alist=[]
qlist.append(i)
else:
alist.append(i)
Counter+=1
x = alist[0]
random.shuffle(alist)
adict[c]= alist
calist.append(alist.index(x))
congo =["Goodjob!","awesome!","correct"]
cnt = 0
for i in range(len(qlist)):
print("\n question", i + 1)
print("-------")
print(qlist[i])
for j in range (len(adict[1])):
print(j+1, "->", adict[i][j])
ch = int(input("enter your choice: "))
if ((ch-1)==calist[i]):
random.shuffle(congo)
print(congo[0])
cnt+=1
else:
print("sry you chose the wrong option! the correct option is",calist[i]+1)
#print("\n End of quiz ! your score is", round(cnt/len(qlist)*100,2))
Can some one tell me what's wrong with this code? It's a school project which I need submit within 2 days time. Please give me some advice on this as I'm stuck at this stage for a long period of time.
Your loop is not correct. You're not saving the first question. I would skip reading and splitting the file, and just let the standard file do it.
counter = 0
qlist = []
alist = []
for line in open("quiz.csv"):
if line:
if counter % 5 == 0:
qlist.append( line )
alist.append( [] )
else:
alist[-1].append( line )
if counter % 5 == 4:
x = alist[-1][0]
random.shuffle(alist[-1])
calist.append(alist[-1].index(x))
counter += 1
Now you have qlist as the list of questions, alist as a list of lists, where entry [i] has the answers that map to question i, and calist has the index of the right answer.
Note that for this change to work, you must delete your "open", your "read", and your "split".

How to find the number of times that 2 follows 3 in a list

If I have a number 13245. What I need is to return how many times 2 follows behind number 3.
def thirtyTwos(n):
lst=(map(int,str(n)))
count=0
i=0
j=1
while i<len(lst):
while j<len(lst):
if lst[i]==3>lst[j]==2:
count+=1
j+=1
j=i+1
i+=1
return count
But it turns wrong on some numbers. What should I do now?
This appears to work:
def count_32(number):
number = str(number)
prev_char = ""
count = 0
for char in number:
if char == "2" and prev_char == "3":
count += 1
prev_char = char
return count
for x in [13245, 2345, 32432, 3323232]:
print(x, count_32(x))
Output:
13245 1
2345 0
32432 2
3323232 3
An approach using regex:
import re
def count_32(number):
if not isinstance(number, str):
number = str(number)
return len(re.findall('32', number))

Annotating adjacent values in a list

It's supposed to be a roll of dice (random) then adjacent values (runs) are supposed to be in ( ). One challenge is using the current - 1 with the 0 index (think I got that resolved by using range(len(dieRun) -1). But another challenge is using 'current + 1' as it tends to 'out of range' errors.
One thought I have is to maybe build a function to compare the values for adjacents? Then use whatever return I get from that to reference a variable, then use that variable in a formatted Print of the dieRun? But, I don't see how that would be better as then I'd still have to figure out how to place that variable as a "(" or ")" with the print(dieRun) list.
Still a newb.
def main():
from random import randint
counter = 0
inRun = 0
dieRun = []
while counter < 20:
roll = randint(0,6)
dieRun.append(roll)
counter = counter +1
index = 0
counter = 0
value = 0
inRun == False
print(dieRun) # just to see what I'm working with
while counter < len(dieRun):
for i in range(0, len(dieRun)-1):
if dieRun[i] != dieRun[i-1]:
print(")" , end= "")
inRun = False
counter = counter + 1
if dieRun[i] == dieRun[i+1]:
inRun = True
print("(")
counter = counter + 1
print(dieRun[i])
if inRun:
print("(")
if inRun :
print(")", end="")
main()
if you want the output like: 1(3 3) 4 5 (6 6 6) 2 1 3 (2 2) 1 (4 4) 5 6 1 2
from random import randint
dieRun = []
for i in range(20):
roll = randint(0,6)
dieRun.append(roll)
inRun = False
print(dieRun)
for i, n in enumerate(dieRun):
if i < len(dieRun)-1:
if not inRun:
if n == dieRun[i+1]:
print('(', n,' ', end='')
inRun = True
else:
print(n,' ', end='')
else:
if n != dieRun[i+1]:
print(n, ')',' ', end='')
inRun = False
else:
print(n,' ', end='')
else:
if dieRun[i-1] == n:
print(n, ')')
else:
print(n)
just a thought, hope it help.
Just a quick fix, I have commented in the code.
For the inline print, you have provided the solution 'print(")" , end= "")', but I don't know why you didn't make it for every print().
if dieRun[i] != dieRun[i-1]: # will check the first number with last number
dieRun[0] != dieRun[-1]: # [-1] is the last item in the list
if dieRun[i] == dieRun[i+1]: # will index out of length
dieRun[len(..)-1] != dieRun[len(..)]: # [len(..)] wil be out of range
Since the head and tail of the list will always cause problem, I just chopped them off from the for loop, and do it manually.
There must be some cleaner solution:
from random import randint
counter = 0
inRun = 0
dieRun = []
while counter < 20:
roll = randint(0,6)
dieRun.append(roll)
counter = counter +1
index = 0
counter = 0
value = 0
inRun == False
print(dieRun)
# while counter < len(dieRun): # while loop is redundant with the for loop
print('(', dieRun[0],' ', end='') # print the first number manually
for i in range(1, len(dieRun)-1):
if dieRun[i] != dieRun[i-1]:
print(")(" , end= "") # change ")" to ")("
inRun = False
counter = counter + 1
"""
these are redundant, just like if True, don't need elif not True
# if dieRun[i] == dieRun[i+1]:
# inRun == True
# print("(", end='')
# counter = counter + 1
"""
print(dieRun[i],' ', end='')
print(dieRun[-1],')', end='') # print the last number manually

Is there a command for exiting and re-entering a script?

Sorry for the other post, it had an error.
My simplified code:
#test
import json
x = {}
x['x'] = {'y': 1, 'z': 0}
with open('x.json', 'w') as f:
json.dump(x, f)
and
#test2
import json
f = open('x.json')
x = json.load(f)
while x['x']['y'] > 0:
x['x']['z'] = x['x']['z'] + 1
x['x']['y'] = x['x']['y'] - 1
if x['x']['y'] == 0:
print(x['x']['z'])
n = input("Number: ")
while n.isdigit() == False:
print("Not a number")
n = input("Number: ")
if n.isdigit() == True:
x['x']['y'] = int(n)
with open('x.json', 'w') as f:
json.dump(x, f)
I have two codes so I don't overwrite the numbers of test2 with test
This is already kinda what I want, but my output for n = 4 and n = 5 is:
1
Number: 4
5
Number: 5
10
Number:
And so on...
But instead, I want the code to Exit completely and then start it again without me doing it manually. Kinda like:
1
Number: 4
Code restarts
5
Number: 5
Code restarts
5
Number: 10
and so on. Thank you :-)
If I understood you correctly , You will have to create two separate scripts
test1.py
#test
import json
import os
x = {}
x['x'] = {'y': 1, 'z': 0}
with open('x.json', 'w') as f:
json.dump(x, f)
os.system('python test2.py') # this line will run the second script
test2.py
import json
f = open('x.json')
x = json.load(f)
while x['x']['y'] > 0:
x['x']['z'] = x['x']['z'] + 1
x['x']['y'] = x['x']['y'] - 1
if x['x']['y'] == 0:
print(x['x']['z'])
n = input("Number: ")
while n.isdigit() == False:
print("Not a number")
n = input("Number: ")
if n.isdigit() == True:
x['x']['y'] = int(n)
with open('x.json', 'w') as f:
json.dump(x, f)

Categories

Resources