I am working on a project where I have to generate a puzzle based on the users input. I would ask the user how many words they will want to include in the puzzle and will also ask for the word. However, the puzzle must work with 4-9 words and each word must be at least 9 letters long. I already wrote some code to start off with since I'm doing it in pieces (I'm new to python) but my code does not stop asking the user for more words, it just keeps asking. If the user says they want only 4 words, and once they enter the 4 words, it should stop there but my code still keeps asking for more words. Any guidance is appreciated! I have 2 python files. one named "main.py" and the other one named "puzzler.py" in my main.py I have this code:
import puzzler
changeable_grid = list()
ways = 0
word_list = []
# TODO:
# 1A. ask user to input how many words they wanna work with
def ask_num_words() -> int:
global num_of_words
while True:
try:
num_of_words = int(input('How many words would you want to work with: '))
except ValueError as e:
print(e)
if puzzler.MIN_WORD <= num_of_words <= puzzler.MAX_WORD:
break
else:
print('Sorry words can only be between {} and {}'.format(puzzler.MIN_WORD, puzzler.MAX_WORD))
print('')
continue
return num_of_words
# 1B. ask user to input the words for the puzzle
def ask_for_words(amt_of_words: int) -> list:
global word
while True:
try:
for i in range(amt_of_words):
word = input('Please enter the word: ')
word_length = len(word)
if puzzler.MIN_WORD_LENGTH >= word_length or word_length >= puzzler.MAX_WORD_LENGTH:
print('The word must be be between {} and {} in length'.format(puzzler.MIN_WORD_LENGTH,
puzzler.MAX_WORD_LENGTH))
print('')
word = input('Re-enter the word again:')
word_length = len(word)
word_list.append(word)
except ValueError as e:
print(e)
print(word_list)
return word_list
if __name__ == "__main__":
amt_of_words = ask_num_words()
ask_for_words(amt_of_words
)
In my puzzler.py file so far I only have this code:
MAX_WORD = 9
MIN_WORD = 4
MAX_WORD_LENGTH = 9
MIN_WORD_LENGTH = 1
You use "while True:" when you want something to happen forever.I think you should just take it out from ask_for_words.
Related
I'm trying to count how many times each letter appears in the string and then display it in a list eg.
The word "hello" would be:
{h:1, e:1, l:2, o:2}
This is my code.
text = input()
dict = {}
for k in range(len(text)):
if text[k] in dict:
count +=1
dict.update({text[k]:count})
else:
count=1
dict.update({text[k]:count})
print(dict)
The code works on smaller words but not for words that are >10
Can someone please point out what is wrong or what I am missing.
You can use the following code to count letter frequencies:
d = {}
for letter in text:
d[letter] = d.get(letter, 0) + 1
print(d)
I've changed your code around a bit that seems to work:
trans = {}
def letterCounter(num):
for ch in num.lower():
if ch in trans.keys():
trans[ch] += 1;
else:
trans[ch] = 1;
print('Counts letters shown in the input:')
for x in sorted(trans):
print(f"Letter \"{x}\": {trans[x]}")
try:
usr = input('Please insert your input & press ENTER to count its letters: ')
letterCounter(usr)
except ValueError:
print('Input must contain a word or sentence')
I know this is a little bit different than what you asked for, but this seems to work very well, and I used www.cologic.dev to do it. It uses code completion to help you learn and code more efficiently.
Im very new on python, actually, Im not even a programer, Im a doctor :), and as a way to practice I decided to wright my hangman version.
After some research I couldnt find any way to use the module "random" to return a word with an especific length. As a solution, I wrote a routine in which it trys a random word till it found the right lenght. It worked for the game, but Im sure its a bad solution and of course it affects the performance. So, may someone give me a better solution? Thanks.
There is my code:
import random
def get_palavra():
palavras_testadas = 0
num_letras = int(input("Choose the number of letters: "))
while True:
try:
palavra = random.choice(open("wordlist.txt").read().split())
escolhida = palavra
teste = len(list(palavra))
if teste == num_letras:
return escolhida
else:
palavras_testadas += 1
if palavras_testadas == 100: # in large wordlists this number must be higher
print("Unfortunatly theres is no words with {} letters...".format(num_letras))
break
else:
continue
except ValueError:
pass
forca = get_palavra()
print(forca)
You may
read the file once and store the content
remove the newline \n char fom each line, because it count as a character
to avoid making choice on lines that hasn't the good length, filter first to keep the possible ones
if the good_len_lines list has no element you directly know you can stop, no need to do a hundred picks
else, pick a word in the good_length ones
def get_palavra():
with open("wordlist.txt") as fic: # 1.
lines = [line.rstrip() for line in fic.readlines()] # 2.
num_letras = int(input("Choose the number of letters: "))
good_len_lines = [line for line in lines if len(line) == num_letras] # 3.
if not good_len_lines: # 4.
print("Unfortunatly theres is no words with {} letters...".format(num_letras))
return None
return random.choice(good_len_lines) # 5.
Here is a working example:
def random_word(num_letras):
all_words = []
with open('wordlist.txt') as file:
lines = [ line for line in file.read().split('\n') if line ]
for line in lines:
all_words += [word for word in line.split() if word]
words = [ word for word in all_words if len(word) == num_letras ]
if words:
return random.choice(words)
I want to assign word, translation, and notes to one index in the list, but I keep getting errors. I want to go increment the index each time it goes through the loop, assigning the variables to the same index. I'm new to Python so any help is appreciated. I want to be able to search for the words later so if there is a better way to do so please explain it.
num = 0
listOfWords = [[] for i in range(3)]
def WriteToFile():
word = ""
while word != "quit":
word = input(str("Enter the word: "))
if word != "quit":
listOfWords[num][num][num].append(word,translation,notes)
num += 1
else:
break
I think you're complicating yourself a bit much. You can append any number of lists to a listOfWords, and thus get the data structure you need.
Here's what I would, though I assume you define translation and notes elsewhere, I also input them:
listOfWords = []
word = ""
while word != "quit":
word = input(str("Enter the word: "))
if word != "quit":
translation = input(str("Enter the translation: "))
notes = input(str("Enter the notes: "))
listOfWords.append([word, translation, notes])
print(listOfWords)
Output:
Enter the word: Hola
Enter the translation: Hello
Enter the notes: greeting
Enter the word: Perro
Enter the translation: Dog
Enter the notes: animal
Enter the word: quit
[['Hola', 'Hello', 'greeting'], ['Perro', 'Dog', 'animal']]
I'm trying to set a memory word game where the program reads a text file with 10 words. The program reads the file and creates a list of 9 out of the words .pop() the last word no.10. The words are randomly shuffled and then displayed again with a 2nd list of the same words randomly shuffled with the last word .pop() and the 1st removed is replacing the word (removed / substituted) - hope that sort of explains it.
I an having an issue regarding feeding back the right response whenter code hereen the user guesses the correct answer (it nots) everything else appears to be working.
import time
from random import shuffle
file =open('Words.txt', 'r')
word_list = file.readlines()
word_list [0:9]
shuffle(word_list)
extra_word=(word_list.pop())
print (extra_word)#substitute word for 2nd question (delete this line)
print '...............'
print (word_list)
print ('wait and now see the new list')
time.sleep(3)
print ('new lists')
word_list [0:9]
shuffle(word_list)
newExtra_word=(word_list.pop())
print (newExtra_word)#replace word for 1st question (delete this line)
word_list.insert(9,extra_word)# replace word
print (word_list)
This code above works fine (for what i want it to do..) The section below however:
#ALLOW FOR 3 GUESSES
user_answer = (raw_input('can you guess the replaced word: ')).lower()
count = 0
while count <=1:
if user_answer == newExtra_word:
print("well done")
break
else:
user_answer = (raw_input('please guess again: ')).lower()
count+=1
else:
print ('Fail, the answer is' + extra_word)
The code does allow for three guesses, but will not accept the removed list item. Does anyone have any ideas why?
Well, because your code above DOESN'T work the way you want it to.
file = open('Words.txt', 'r')
word_list = file.readlines()
# you should do file.close() here
word_list[0:9]
That last line doesn't actually do anything. It returns the first 10 elements in word_list but you never assign them to anything, so it's essentially a NOP. Instead do
word_list = word_list[0:9] # now you've removed the extras.
Probably better is to shuffle first so you have a truly random set of 10. Why 10? Why are we restricting the data? Oh well, okay...
# skipping down a good ways
word_list.insert(9, extra_word) # replace word
Why are we doing this? I don't really understand what this operation is supposed to do.
As for allowing three guesses:
count = 0
while count < 3:
user_answer = raw_input("Can you guess the replaced word: ").lower()
count += 1
if user_answer == newExtra_word:
print("well done")
break
else:
print("Sorry, the answer is " + extra_word)
Wait, did you catch that? You're checking the user input against newExtra_word then you're reporting the correct answer as extra_word. Are you sure your code logic works?
What it SOUNDS like you want to do is this:
with open("Words.txt") as inf:
word_list = [next(inf).strip().lower() for _ in range(11)]
# pull the first _11_ lines from Words.txt, because we're
# going to pop one of them.
word_going_in = word_list.pop()
random.shuffle(word_list)
print ' '.join(word_list)
random.shuffle(word_list)
word_coming_out = word_list.pop()
# I could do word_list.pop(random.randint(0,9)) but this
# maintains your implementation
word_list.append(word_going_in)
random.shuffle(word_list)
count = 0
while count < 3:
user_input = raw_input("Which word got replaced? ").lower()
count += 1
if user_input == word_coming_out:
print "Well done"
break
else:
print "You lose"
Im working on a word game. The purpose for the user is to guess a 5 letter word in 5 attempts. The user can know the first letter. And if he doesn't get the word correct, but if he has a letter in the correct place he gets to know this.
This is my code:
import random
list_of_words = ["apple","table", "words", "beers", "plural", "hands"]
word = random.choice(list_of_words)
attempts = 5
for attempt in range(attempts):
if attempt == 0:
tempList = list(word[0] + ("." * 4))
print("The first letter of the word we are looking for: %s" % "".join(tempList))
answer = raw_input("What is the word we are looking for?:")
if len(answer) != 5:
print ('Please enter a 5 letter word')
Else:
if answer != word:
wordlist = list(word)
answerlist = list(answer)
for i in range(min(len(wordlist), len(answerlist))):
if wordlist[i] == answerlist[i]:
tempList[i] = wordlist[i]
print(tempList)
else:
print("correct, you have guessed the word in:", attempt, "attempts")
if answer != word:
print("Sorry maximum number of tries, the word is: %s" % word)
I have two questions about this code:
The first one is a small problem: If the user gives a 6 or 4 letter word it will still print the word. While I'd rather have it that the word is just ignored and the attempt isnt used..
If a letter is given correct (and also the first letter) it doesnt become a standard part of the feedback. Trying to get this with temp but of yet its not working great.
Any suggestions to clean up my code are also appreciated!
Thanks for your attention
I made some changes in your code, now it's working according to your specification. I also wrote a couple of explaining comments in it:
import random
list_of_words = ["apple", "table", "words", "beers", "plural", "hands"]
word = random.choice(list_of_words)
# changed the loop to a 'while', because i don't want to count the invalid length answers
# and wanted to exit the loop, when the user guessed correctly
attempts = 5
attempt = 0
correct = False
while attempt < attempts and not correct:
if attempt == 0:
# i stored a working copy of the initial hint (ex: "w....")
# i'll use this to store the previously correctrly guessed letters
tempList = list(word[0] + ("." * 4))
print("The first letter of the word we are looking for: %s" % "".join(tempList))
answer = raw_input("What is the word we are looking for?:")
if len(answer) != 5:
print("Please enter a 5 letter word")
else:
if answer != word:
# i simplified this loop to comparing the wordlist and answerlist and update templist accordingly
wordlist = list(word)
answerlist = list(answer)
for i in range(min(len(wordlist), len(answerlist))):
if wordlist[i] == answerlist[i]:
tempList[i] = wordlist[i]
print(tempList)
else:
correct = True
print("Correct, you have guessed the word in %s attempts" % (attempt + 1))
attempt += 1
if answer != word:
# also i used string formatting on your prints, so is prints as a string, and not as a tuple.
print("Sorry maximum number of tries, the word is: %s" % word)
There are several problems with the code.
Just 1 for now. I notice in the sample output you are entering five letter words (beeds and bread) and it still prints out Please enter a 5 letter word.
These two lines:
if len(answer) != 4:
print ('Please enter a 5 letter word')
Surely this should be:
if len(answer) != 5:
print ('Please enter a 5 letter word')
continue
This would catch an invalid input and go round the loop again.
Answering your specific questions:
You will need to have a for loop around your input, keeping the user in that loop until they enter a word of appropriate length
If you move guessed letters to the correct places, it is trivial to win by guessing "abcde" then "fghij", etc. You need to think carefully about what your rules will be; you could have a separate list of "letters in the guess that are in the answer but in the wrong place" and show the user this.
To keep the display version with all previously-guessed characters, keep a list of the display characters: display = ["." for letter in answer], and update this as you go.
Other problems you have:
Too much hard-coding of word length (especially as len("plural") != 5); you should rewrite your code to use the length of the word (this makes it more flexible).
You only tell the user they've won if they guess the whole answer. What if they get to it with overlapping letters? You could test as if all(letter != "." for letter in display): to see if they have got to the answer that way.
Your list comprehension [i for i in answer if answer in word] is never assigned to anything.