I am building a Hangman game. The code that I wrote prints the 'updated target word' multiple times if a letter occurs multiple times.
Example: the target word is 'celebrate'. If I guess e then it prints
*e******
*e*e****
*e*e***e
I would like to avoid printing the first two printouts and only print the third and most updated version.
import random
import re
word_list = ["fireboard", "identical", "chocolate", "christmas", "beautiful", "happiness", "wednesday", "challenge", "celebrate"]
random_pick = random.choice(word_list)
random_pick_a = re.sub("[a-z]","*", random_pick)
random_pick_list_a = list(random_pick_a)
print(random_pick)
count = 0
def main_function():
global count
while count <= 9:
user_input = str(input("type a letter:"))
for i, c in enumerate(random_pick):
if c == user_input.casefold():
random_pick_list_a[i] = user_input.casefold()
random_pick_list_b = ''.join(random_pick_list_a)
print(random_pick_list_b)
if random_pick_list_b == random_pick:
print("done")
exit()
else:
continue
else:
if user_input.casefold() not in random_pick:
count = count+1
print(count)
if count == 10:
print("sorry")
exit()
main_function()
Disclaimer: I am in my first weeks of coding!
No need to str() the input(), it's already a string. So strip str(input("type a letter:")) to input("type a letter:").
No need in
else:
continue
it will continue even without it. Don't use globals, just move your count into main_function().
Don't do if count == 10, you're already doing it in while count <= 9.
As for your question - move the block
print(random_pick_list_b)
if random_pick_list_b == random_pick:
print("done")
exit()
out of the for-loop. So the whole thing would look like this:
def main_function():
count = 0
while count <= 4:
user_input = input("type a letter:")
for i, c in enumerate(random_pick):
if c == user_input.casefold():
random_pick_list_a[i] = user_input.casefold()
random_pick_list_b = ''.join(random_pick_list_a)
print(random_pick_list_b)
if random_pick_list_b == random_pick:
print("done")
exit()
else:
if user_input.casefold() not in random_pick:
count = count+1
print(count)
print("sorry")
You have:
print(random_pick_list_b)
Inside the for loop that is checking each character for the chosen letter. So, it prints out random_pick_list_b every time it finds a match.
Move it to right after the for loop if you want to do it one time when the checking is complete.
I would do this check once before the for loop.
Related
import math
import random
a = math.floor((random.random())*100)
if a%10 != 00:
c = math.floor(a/10)
a = a - c*10
#to make sure the number isnt over 10
attempts = int(input("enter num of attempts"))
att = attempts
for i in range(0,attempts+1,1):
tr = int(input("try"))
att = att -1
if tr == a:
print("good")
break;
else:
print("no,try again", "you got",att,"more attempts")
if att == 0:
print("game over,the num was", (a))
the game has random num between 0-10 and you need to insert num of attempst, and then guess what number is it, and you got the amount of attempst you have insert to try guessing the num.
You can replace the for loop by a while loop.
This way you have more control, you can use a found boolean and loop while it is False.
Note also that you have to increment i by yourself.
I printed the messages (win/lost) outside of the loop.
It makes the loop code more readable.
I also used randint() to choose the random number to guess.
It does all the work without further computation and is also part of the random module.
from random import randint
a = randint(1, 10)
attempts = int(input("enter num of attempts"))
att = attempts
found = False
i = 0
while i < attempts and not found:
i += 1
att -= 1
tr = int(input("try"))
if tr == a:
found = True
elif att > 0:
print("no,try again", "you got", att, "more attempts")
if found:
print("good")
else:
print("game over,the num was", (a))
I am trying to make a random word/phrase generator that is like the one that bitwarden has (in python3). But the issue I am running into and need some help with is the addition of 1 number at the end of 1 of the words that is shown.
Something like this Referee-Outrank-Cymbal-Cupping-Cresting-Fiber7-Expensive-Myth-Unveiling-Grasp-Badland-Epiphany-Simplify-Munchkin-Pastrami-Spiffy-Gladly-Skeptic-Retouch-Buckskin
What is very important here is that the number is "random" and the word it is attached to is "random".
Code I have written so far:
Word list I am using is https://svnweb.freebsd.org/csrg/share/dict/words?view=co&content-type=text/plain but without ' in any of the words.
#pycryptodome==3.15.0
from Crypto.Random import random
import beaupy
import os
def clear():
os.system('clear||cls')
def main():
while True:
try:
number = int(beaupy.prompt("How many words?: "))
except ValueError as e:
print(f'Oops! Something went wrong.\nError: {e}\n\n')
input('Press "enter" to continue...')
clear()
continue
if number > 20 or number < 3:
print("20 words is the maximum number of words you can use. And 5 words is the minimum.\n\n")
input('Press "enter" to continue...')
clear()
else:
break
cwd = os.getcwd()
word_path = f"{cwd}/words.txt"
with open(word_path, 'r') as fh:
words = fh.read().lower()
word_list = words.splitlines() #list of words
sep = beaupy.prompt('Line separator? (leave empty for default "-"): ')
if sep == '' or sep == ',':
sep = '-'
#Returns True or False. Basically Yes or No?
if beaupy.confirm("Capitalize?"):
"""Make list of words with the first letter capitalized."""
c_lst = []
for i in word_list:
c_lst.append(i.title())
capital_words = f'{sep}'.join(random.choice(c_lst) for _ in range(number))
else:
default_words = f'{sep}'.join(random.choice(word_list) for _ in range(number))
if beaupy.confirm("Number?"):
rn_num = random.randint(0, 9) # <-- Get a random number to be used with only 1 of the words defined in capital_words or default_words below.
#I don't know what to do here... but I need to have a version with the number and one without. (default)
if __name__ == '__main__':
clear()
main()
I am not exactly familiar with string manipulation and searching for answers online just isn't giving me any help with the very specific thing I'm trying to do. All I want is for 1 word in the resulting string to have a "random" number attached to it.
I don't know if I need to re order my code and have it be done a different way. I am having such a headache with this. Any help would be great.
Edit#1
Additional and unrelated note, If anyone knows of a better word list to use, please let me know!
If I am understanding correctly, here is a solution:
#Returns True or False. Basically Yes or No?
capital_words = ''
default_words = ''
if beaupy.confirm("Capitalize?"):
"""Make list of words with the first letter capitalized."""
c_lst = []
for i in word_list:
c_lst.append(i.title())
capital_words = f'{sep}'.join(random.choice(c_lst) for _ in range(number))
else:
default_words = f'{sep}'.join(random.choice(word_list) for _ in range(number))
if beaupy.confirm("Number?"):
rn_num = random.randint(0, 9) # <-- Get a random number to be used with only 1 of the words defined in capital_words or default_words below.
#I don't know what to do here... but I need to have a version with the number and one without. (default)
word_index = random.randint(0, number - 1) # Get random index that is in the word list
if default_words != '':
word_with_number = default_words.split(sep)
else:
word_with_number = capital_words.split(sep)
word_with_number[word_index] = word_with_number[word_index] + str(rn_num)
word_with_number = sep.join(word_with_number)
print(word_with_number)
if default_words != '':
print(default_words)
else:
print(capital_words)
OUTPUT:
detroit-elide-windbag-purge-tort-mortician-codex7-annex-fairy-suntanning
detroit-elide-windbag-purge-tort-mortician-codex-annex-fairy-suntanning
With some help from AnonymousFrog. I was able to get my code working.
The following is the now working code.
from Crypto.Random import random
import beaupy
import os
def clear():
os.system('clear||cls')
def main():
while True:
try:
number = int(beaupy.prompt("How many words?: "))
except ValueError as e:
print(f'Oops! Something went wrong.\nError: {e}\n\n')
input('Press "enter" to continue...')
clear()
continue
if number > 20 or number < 3:
print("20 words is the maximum number of words you can use. And 5 words is the minimum.\n\n")
input('Press "enter" to continue...')
clear()
else:
break
cwd = os.getcwd()
word_path = f"{cwd}/words.txt"
with open(word_path, 'r') as fh:
words = fh.read().lower()
word_list = words.splitlines() #list of words
sep = beaupy.prompt('Line separator? (leave empty for default "-"): ')
if sep == '' or sep == ',':
sep = '-'
#Returns True or False. Basically Yes or No?
capital_words = ''
default_words = ''
if beaupy.confirm("Capitalize?"):
"""Make list of words with the first letter capitalized."""
c_lst = []
for i in word_list:
if len(i) < 3 or len(i) > 9:
pass
else:
c_lst.append(i.title())
cap = True
capital_words = f'{sep}'.join(random.choice(c_lst) for _ in range(number))
else:
cap = False
default_words = f'{sep}'.join(random.choice(word_list) for _ in range(number))
if beaupy.confirm("Number?"):
num = True
rn_num = random.randint(0, 9) # <-- Get a random number to be used with only 1 of the words defined in capital_words or default_words below.
word_index = random.randint(0, number - 1) # Get random index that is in the word list
if default_words != '':
word_with_number = default_words.split(sep)
else:
word_with_number = capital_words.split(sep)
word_with_number[word_index] = word_with_number[word_index] + str(rn_num)
word_with_number = sep.join(word_with_number)
else:
num = False
if cap == True and num == False:
print(capital_words)
if cap == False and num == False:
print(default_words)
if num == True:
print(word_with_number)
Thanks for the help!
(if anyone knows of a better word list to use, feel free to let me know)
I was instructed to have a user input at least 8 words into a list and then perform various manipulations to the data within the list. One of the manipulations it asks me to do is to create a loop that makes every other letter in the strings capitalized (hElLo WoRlD.) For better readability, I left out the other manipulations that I have done to the code.
import sys
def main():
words = []
wordCount = 0
userWord = input("Enter at least 8 words or 'bye' to leave the program: ").split(' ')
while True:
if len(userWord)<8:
print("Please print at least 8 words, try again.")
sys.exit()
elif wordCount >= 8 and userWord[wordCount] != 'bye':
words.append(userWord[wordCount])
wordCount = wordCount + 1
else:
break
every_other (userWord)
def every_other(words):
words6 = words.copy()
st = ""
for i in range(len(words6)):
if (i%2) == 0:
st += words6[i].upper()
else:
st += words6[i]
print ('This is your list with every other letter capitalized: ', words6)
return st
main()
I am not getting any error messages but the code doesn't seem to be running starting at def every_other.
You'll have to print the function every_other as it returns a string:
import sys
def main():
words = []
wordCount = 0
userWord = input("Enter at least 8 words or 'bye' to leave the program: ").split(' ')
while True:
if len(userWord)<8:
print("Please print at least 8 words, try again.")
sys.exit()
elif wordCount >= 8 and userWord[wordCount] != 'bye':
words.append(userWord[wordCount])
wordCount = wordCount + 1
else:
break
print('This is your list with every other letter capitalized: ', every_other(userWord))
def every_other(words):
words6 = words.copy()
st = ""
for i in range(len(words6)):
if (i%2) == 0:
st += words6[i].upper()
else:
st += words6[i]
return st
#print ('This is your list with every other letter capitalized: ', words6) # This will never run as the function has already returned
main()
If you want to capitalize every second character:
import sys
def main():
words = []
wordCount = 0
userWord = input("Enter at least 8 words or 'bye' to leave the program: ").split(' ')
while True:
if len(userWord)<8:
print("Please print at least 8 words, try again.")
sys.exit()
elif wordCount >= 8 and userWord[wordCount] != 'bye':
words.append(userWord[wordCount])
wordCount = wordCount + 1
else:
break
print('This is your list with every other letter capitalized: ', every_other(userWord))
def every_other(words):
st = ""
new_st = ""
for w in words:
st+=w
print(str(st))
for count, val in enumerate(st):
if (count % 2) == 0:
val = val.upper()
new_st+=val
return new_st
main()
secret_word = "python"
correct_word = "yo"
count = 0
for i in secret_word:
if i in correct_word:
print(i,end=" ")
else:
print('_',end=" ")
so the outcome of the code will look like this _ y _ _ o _
my question is how i can i get the same output by using while loop instead of using For loop. i know i have to use index to iterate over each character but when i tried i failed . so any help?
while count < len(secret_word):
if correct_word [count]in secret_word[count]:
print(correct_word,end=" ")
else:
print("_",end=" ")
count = count + 1
Thanks
You can do this:
secret_word = "python"
correct_word = "yo"
count = 0
while count < len(secret_word):
print(secret_word[count] if secret_word[count] in correct_word else '_', end=" ")
count += 1
Another way to use while is to simulate a pop of the first character. The while loop terminates when the 'truthiness' of a string becomes false with no more characters to process:
secret_word = "python"
correct_word = "yo"
while secret_word:
ch=secret_word[0]
secret_word=secret_word[1:]
if ch in correct_word:
print(ch,end=" ")
else:
print('_',end=" ")
Or, you can actually use a list with a LH pop:
secret_list=list(secret_word)
while secret_list:
ch=secret_list.pop(0)
if ch in correct_word:
print(ch,end=" ")
else:
print('_',end=" ")
Here is a simple, way of writing your program with a while loop instead of a for loop. The code breaks out of an infinite loop when appropriate.
def main():
secret_word = 'python'
correct_word = 'yo'
iterator = iter(secret_word)
sentinel = object()
while True:
item = next(iterator, sentinel)
if item is sentinel:
break
print(item if item in correct_word else '_', end=' ')
if __name__ == '__main__':
main()
It uses logic similar to how the for loop is implemented internally. Alternatively, the example could have used exception handling instead.
I am trying to use a while statement like so:
o = 0
while o == 0:
try:
n = int(raw_input("Which number do you want to begin with?"))
o = 1
except:
o = 0
print "Please use a valid number."
However, when I try to use variable n later, it gives me the "local variable 'n' referenced before assignment' UnboundLocalError. That means that n cannot be recognized as a variable in the def I am using, because it only exists in the while statement? Is this possible?
The whole code:
import time
from sys import argv
import os
os.system("cls")
print "Welcome to Number counter 2.0!"
a = True
def program():
global a
if a == False:
os.system("cls")
o = 0
while o == 0:
try:
n = int(raw_input("Which number do you want to begin with?"))
o = 1
except:
o = 0
print "Please use a valid number."
if n == "/historyKeep false":
if a == False:
print "Command historyKeep is already set to false."
else:
a = False
print "Command set successfully."
elif n == "/historyKeep true":
if a == True:
print "Command historyKeep is already set to true."
else:
a = True
print "Command set successfully."
if n == "/historyKeep false":
n = raw_input("Which number do you want to begin with?")
elif n == "/historyKeep true":
n = raw_input("Which number do you want to begin with?")
d = raw_input("How many seconds between each number?")
d = int(d)
total_s = n * d
while n > 0:
print n
time.sleep(d)
n = n - 1
print "Done in", total_s, "seconds in total!"
end_q = raw_input("Exit or retry? (e/r)")
if end_q == "e":
os.system("cls")
print "Exiting."
time.sleep(0.5)
os.system("cls")
print "Exiting.."
time.sleep(0.5)
os.system("cls")
print "Exiting..."
time.sleep(0.5)
os.system("cls")
exit(0)
elif end_q == "r":
program()
program()
You set a = True at the beginning. You then test if a == False and only set n if it is. But then you test n == "/history.... n has not been set at this point.
You need to make sure n is assigned before you use it. It is not enough to just mention it in a branch that is not taken.
n is not defined in the scope that you are trying to use it to fix this define it outside of the while loop and the if statement the while loop is in:
global a
n = 0
Then when you ask the user for what number to start with, that value will replace 0, and you should be good to go. Also instead of declaring global a, why not just make a an input argument for the program() function?
Just to make sure, declare n outside of the loop first:
n = None
while True:
try:
n = int(raw_input("Text..."))
break
except:
print("Please enter a valid number!")
Note: Usually, you would use break to exit a loop. This is because your method requires an extra variable, which uses more memory (not much, but if you keep doing it, it will stack up).