Python secret santa-ish draw - python

Sometimes it works fine, sometimes throws an error. Cannot figure it out. No matter how many inputs.
Thats the error. Is it the order of the code or something else?
give_gift.remove(reciever)
ValueError: list.remove(x): x not in list
Code:
import random
import os
import time
random.seed()
buy_gift = []
give_gift = []
names = True
print('Add name, then press ENTER. To finish type "end".')
while names is True:
name = input()
if name == "end":
if len(buy_gift) < 2:
print("Go play with your own gift. Goodbye!")
print()
os.system("PAUSE")
quit()
else:
names = False
else:
buy_gift.append(name)
give_gift.append(name)
exchange = len(give_gift)
os.system("cls")
time.sleep(1)
print("Drawing pairs...")
print()
time.sleep(1)
while exchange > 0:
giver = random.choice(buy_gift)
reciever = random.choice(give_gift)
while giver == reciever:
reciever = random.choice(buy_gift)
print(giver,"buys gift for",reciever)
time.sleep(0.25)
buy_gift.remove(giver)
give_gift.remove(reciever)
exchange -= 1
print()
os.system("PAUSE")

There is an issue with this line:
while giver == reciever:
reciever = random.choice(buy_gift)
It should be:
reciever = random.choice(give_gift)

Related

Randomize questions from web API and print out wrong answer

I want to get 10 random questions from an web API with many questions, but I dont seem to get it to work. Right now im getting KeyError: 'prompt', but I dont know if the function is correct at all as I have been trying a few diffrent options.
Im also trying to print out in the end which questions you get wrong, but with no luck there either.
import random
import requests
from random import randint
url = ""
the_questions = requests.get(url).json()
print("------ Welcome to Python quiz ------")
def random_question():
data = the_questions['prompt']
random_index = randint(0, len(data)-1)
return data[random_index]['prompt']
def get_correct_answers(answers):
res = []
for ans in answers:
if ans['correct']:
res.append(ans['answer'])
return res
def get_numeric(prompt, max_value,):
while True:
try:
res = int(input(prompt))
except ValueError:
print("Answer only with a number!")
continue
if 0 < res < max_value:
break
else:
print("Invalid answer option!")
return res
def main():
score = 0
for questions in the_questions['questions']:
#print(questions['prompt'])
print(random_question())
for i, a in enumerate(questions['answers'], start=1):
print(f"[{i}] {a['answer']}")
user_answer = get_numeric("> ", len(questions['answers']) + 1)
if questions['answers'][user_answer - 1]['correct']:
score += 1
print(f"Right!")
else:
all_correct = ", ".join(get_correct_answers(questions['answers']))
print(f"Wrong, right is: {all_correct}")
print(f"You got {score} points of {len(the_questions['questions'])} possible!")
if __name__ == '__main__':
main()
Sample of the API
{"questions":[{"id":"1","prompt":"Which functions is used to write out text in the terminal?","answers":[{"answer":"print","correct":true},{"answer":"input","correct":false},{"answer":"import","correct":false},{"answer":"sys.exit","correct":false}]}
Error shows problem with key prompt and you use it only in random_question().
If you use print() to see values in variables random_question() then you will see that you need
data = the_questions['questions']
instead of
data = the_questions['prompt']
As for me name of variables are missleading. You should use name data for all information from API and later questions = data['questions'] could make sense.
EDIT:
My version with random.shuffle()
import random
#import requests
import json
def get_correct_answers(answers):
res = []
for ans in answers:
if ans['correct']:
res.append(ans['answer'])
return res
def get_numeric(prompt, max_value,):
while True:
try:
res = int(input(prompt))
except ValueError:
print("Answer only with a number!")
continue
if 0 < res < max_value:
break
else:
print("Invalid answer option!")
return res
def main():
print("------ Welcome to Python quiz ------")
#url = ""
#data = requests.get(url).json()
data = json.loads('''
{"questions":[
{"id":"1","prompt":"Which functions is used to write out text in the terminal?","answers":[{"answer":"print","correct":true},{"answer":"input","correct":false},{"answer":"import","correct":false},{"answer":"sys.exit","correct":false}]},
{"id":"2","prompt":"Which functions is used to read text from the terminal?","answers":[{"answer":"print","correct":false},{"answer":"input","correct":true},{"answer":"exec","correct":false},{"answer":"load","correct":false}]}
]}
''')
questions = data['questions']
random.shuffle(questions)
score = 0
for question in questions:
print(question['prompt'])
answers = question['answers']
for i, a in enumerate(question['answers'], 1):
print(f"[{i}] {a['answer']}")
user_answer = get_numeric("> ", len(answers)+1)
if answers[user_answer-1]['correct']:
score += 1
print(f"Right!")
else:
all_correct = ", ".join(get_correct_answers(answers))
print(f"Wrong, right is: {all_correct}")
print(f"You got {score} points of {len('questions')} possible!")
if __name__ == '__main__':
main()

Python: keyboard input and loop

I am trying to build a locker with Raspberry Pi. I have a code that when entering a correct CODE = '1234' with USB keyboard it opens a servo.
Basically it works, but need to loop it somehow so, if I put wrong PIN, I am asked again to put correct.
for event in dev.read_loop():
if event.type == ecodes.EV_KEY:
e = categorize(event)
if e.keystate == e.key_down:
klawisz = e.keycode[4:]
if klawisz != "ESC":
kod = (kod + klawisz)
print(kod)
else:
break
if kod == '1234':
for event in dev.read_loop():
if event.type == ecodes.EV_KEY:
d = categorize(event)
if d.keystate == d.key_down:
klawisz = d.keycode[4:]
if klawisz == "ESC":
print('ITS OPEN')
break
else:
break
else:
print('Wrong PIN')
I tried with while loop at the beginning, but it doesn't work :(
while kod == '1234'
Hope you could you guide me to correct solution, as I am still learning Python. Thanks.
You can use while loop to repeatedly perform some operations (reading users password in your example) if some condition stays true:
def read_password():
kod = ""
for event in dev.read_loop():
if event.type == ecodes.EV_KEY:
e = categorize(event)
if e.keystate == e.key_down:
klawisz = e.keycode[4:]
if klawisz != "ESC":
kod = (kod + klawisz)
print(kod)
else:
break
return kod
while read_password() != '1234':
print('Wrong PIN, try again')
In this case you're reading password as long as it doesn't match '1234'.
Use an infinite while loop and break out of it only if the code matches.
while True:
code = input('Enter code: ')
if code == '1234':
print('Code accepted.')
break
print('Wrong code, try again.')
You can easily add an additional security feature to reduce the amount of attempts per time.
import time
attempts = 0
while True:
code = input('Enter code: ')
if code == '1234':
print('Code accepted.')
break
print('Wrong code, try again.')
attempts = attempts + 1
if attempts > 9:
print('Too many failed attempts. Please wait.')
time.sleep(600)
attempts = 0
You can run all examples above on your regular computer to test them. They use Python's built-in input function. You use the RETURN key to finalize your input instead of the ESC key in your code. You said that you read the user input with a USB keyboard, so input might even work for you with your Raspberry Pi, too.

Escape Sequences in Python Not Working in CMD

import time
listy = ['timer','stopwatch']
def intro():
print("This is a program which contains useful tools")
print(listy)
def timer():
x = int(input("How long Seconds ?"))
while x > 0:
print(x)
time.sleep(1)
x -= 1
def stopwatch():
verif = input("Do you want to start y/n \n")
if verif == 'y':
x = 0
while True:
print(x, end = "\b"*5)
time.sleep(1)
x += 1
def main():
intro()
decider = input("Which Program?")
if decider.lower() == 'timer':
timer()
elif decider.lower() == 'stopwatch':
stopwatch()
main()
in this code i dont know why the \b escape sequence isnt working in cmd or in idle, can anyone explain why? Is it because of a logic error?
A flush may be required. How about...
print("{0}{1}".format("\b"*5, x), end="", flush=True)

Breaking a loop with input

I'm trying to make a an input timer on a question that gives the user 5 seconds to answer the question before deciding that no input is the same as the wrong answer, but no body wants to touch it with a 10ft pole, so I'm trying to go about it a different way and break a for loop with input?
Any one got suggestions?
import random
import operator
qLimit = 10
oqLimit = 10
score = 0
maxNum = 10
timeLimit = 0
otimeLimit = 5
import time
ops = {
'+':operator.add,
'-':operator.sub
}
def generateQuestion():
x = random.randint(1,maxNum)
y = random.randint(1,maxNum)
op = random.choice(list(ops.keys()))
a = ops.get(op)(x,y)
print("What is {} {} {}?\n".format(x, op, y))
return a
def askQuestion(a):
timeLimit = otimeLimit
for i in range(0,timeLimit):
guess = input("")
print (timeLimit - i)
time.sleep(1)
if timeLimit == 0:
try:
integer_input = int(guess)
except ValueError:
print('Please enter a valid number')
return
global score
if integer_input == a:
print("Correct!")
score += 1
else:
print("Wrong, the answer is",a)
while qLimit != 0:
askQuestion(generateQuestion())
qLimit -= 1
print ("You have", qLimit, "questions remaining")
print("Your score is",score)
if (qLimit == 0):
break
Adapting the example from the Python docs:
import signal
class OutOfTime(Exception):
"too slow"
def handler(signum, frame):
raise OutOfTime("no input received")
try:
# Set the signal handler and a 5-second alarm
signal.signal(signal.SIGALRM, handler)
signal.alarm(5)
ans = input('What is your favorite color? ')
signal.alarm(0)
except OutOfTime:
print('\nout of time! too slow!')
else:
print('%s, huh? Mine, too!' % ans)

Personal archive tool, looking for suggestions on improving the code

i've written a tool in python where you enter a title, content, then tags, and the entry is then saved in a pickle file. it was mainly designed for copy-paste functionality (you spot a piece of code you like on the net, copy it, and paste it into the program), not really for handwritten content, though it does that with no problem.
i mainly did it because i'm always scanning through my pdf files, books, or the net for some coding example of solution that i'd already seen before, and it just seemed logical to have something where you could just put the content in, give it a title and tags, and just look it up whenever you needed to.
i realize there are sites online that handle this ex. http://snippets.dzone.com, but i'm not always online when i code. i also admit that i didn't really look to see if anyone had written a desktop app, the project seemed like a fun thing to do so here i am.
it wasn't designed with millions of entries in mind, so i just use a pickle file to serialize the data instead of one of the database APIs. the query is also very basic, only title and tags and no ranking based on the query.
there is an issue that i can't figure out, when you are at the list of entries there's a try, except clause where it tries to catch a valid index (integer). if you enter an inavlid integer, it will ask you to enter a valid one, but it doesn't seem to be able to assign it to the variable. if you enter a valid integer straightaway, there are no problems and the entry will display.
anyway let me know what you guys think. this is coded for python3.
main file:
#!usr/bin/python
from archive_functions import Entry, choices, print_choice, entry_query
import os
def main():
choice = ''
while choice != "5":
os.system('clear')
print("Mo's Archive, please select an option")
print('====================')
print('1. Enter an entry')
print('2. Lookup an entry')
print('3. Display all entries')
print('4. Delete an entry')
print('5. Quit')
print('====================')
choice = input(':')
if choice == "1":
entry = Entry()
entry.get_data()
entry.save_data()
elif choice == "2":
queryset = input('Enter title or tag query: ')
result = entry_query('entry.pickle', queryset)
if result:
print_choice(result, choices(result))
else:
os.system('clear')
print('No Match! Please try another query')
pause = input('\npress [Enter] to continue...')
elif choice == "3":
queryset = 'all'
result = entry_query('entry.pickle', queryset)
if result:
print_choice(result, choices(result))
elif choice == "4":
queryset = input('Enter title or tag query: ')
result = entry_query('entry.pickle', queryset)
if result:
entry = result[choices(result)]
entry.del_data()
else:
os.system('clear')
print('No Match! Please try another query')
pause = input('\npress [Enter] to continue...')
elif choice == "5":
break
else:
input('please enter a valid choice...')
main()
if __name__ == "__main__":
main()
archive_functions.py:
#!/bin/usr/python
import sys
import pickle
import os
import re
class Entry():
def get_data(self):
self.title = input('enter a title: ')
print('enter the code, press ctrl-d to end: ')
self.code = sys.stdin.readlines()
self.tags = input('enter tags: ')
def save_data(self):
with open('entry.pickle', 'ab') as f:
pickle.dump(self, f)
def del_data(self):
with open('entry.pickle', 'rb') as f:
data_list = []
while True:
try:
entry = pickle.load(f)
if self.title == entry.title:
continue
data_list.append(entry)
except:
break
with open('entry.pickle', 'wb') as f:
pass
with open('entry.pickle', 'ab') as f:
for data in data_list:
data.save_data()
def entry_query(file, queryset):
'''returns a list of objects matching the query'''
result = []
try:
with open(file, 'rb') as f:
entry = pickle.load(f)
os.system('clear')
if queryset == "all":
while True:
try:
result.append(entry)
entry = pickle.load(f)
except:
return result
break
while True:
try:
if re.search(queryset, entry.title) or re.search(queryset, entry.tags):
result.append(entry)
entry = pickle.load(f)
else:
entry = pickle.load(f)
except:
return result
break
except:
print('no entries in file, please enter an entry first')
pause = input('\nPress [Enter] to continue...')
def choices(list_result):
'''takes a list of objects and returns the index of the selected object'''
os.system('clear')
index = 0
for entry in list_result:
print('{}. {}'.format(index, entry.title))
index += 1
try:
choice = int(input('\nEnter choice: '))
return choice
except:
pause = input('\nplease enter a valid choice')
choices(list_result)
def print_choice(list_result, choice):
'''takes a list of objects and an index and displays the index of the list'''
os.system('clear')
print('===================')
print(list_result[choice].title)
print('===================')
for line in list_result[choice].code:
print(line, end="")
print('\n\n')
back_to_choices(list_result)
def back_to_choices(list_result):
print('1. Back to entry list')
print('2. Back to Main Menu')
choice = input(':')
if choice == "1":
print_choice(list_result, choices(list_result))
elif choice == "2":
pass
else:
print('\nplease enter a valid choice')
back_to_choices(list_result)
In the else, you call the main function again recursively. Instead, I'd do something like choice == "0", which will just cause the while loop to request another entry. This avoids a pointless recursion.

Categories