Explanation
I am currently writing a code that simulates a game of hangman, but cheats by attempting to evade the player's guesses by changing the word. The class and methods are defined in hangman.py, while play_hangman.py calls the instance of Hangman and the play method (cannot be changed per the instructions of the assignment).
Problem
In the play method, I received the following error: "
TypeError: askForWordLength() takes 1 positional argument but 2 were given "
I know that this means I am giving too many arguments into the call of the method, but I am unsure of how to change it. I have tried rewriting the 5th line of the following code multiple times to fix this error, but it does not cease:
Specific Section of Code*
def play(self):
MODE = 1
openSession = 1
while(openSession == 1):
word_length = self.askForWordLength(self.words)
num_guesses = self.askForNumOfGuesses()
wordStatus = self.wordStatus(word_length)
letters_already_guessed = []
print()
gameOver = 0
while (gameOver == 0):
if (MODE == 1):
self.printCountOfRemainingWords(self.remainingWords)
self.printGameStats(self.remainingWords. letters_already_guessed,
self.num_guesses, self.wordStatus)
guess = self.askPlayerForGuess(letters_already_guessed)
letters_already_guessed.append(guess)
num_guesses -= 1
remainingWords = self.retrieveRemainingWords(guess, self.remainingWords,
num_guesses, word_length)
wordStatus = self.wordStatus(remainingWords[0], letters_already_guessed)
print()
if (guess in wordStatus):
num_guesses += 1
if ('-' not in wordStatus):
game_over = 1
print('Congratulations! You won!')
print('Your word was: ' + wordStatus)
if (num_guesses == 0 and game_over == 0):
game_over = 1
print('Haha! You Lose')
print('Your word was: ' + remainingWords[0])
print('Thanks for playing Hangman!')
ENTIRE CODE
hangman.py
import re
class Hangman:
# hangman self method
def hangman(self):
self.hangman = Hangman() # object of the Hangman class
def words(self):
with open('dictionary.txt') as file: # opens dictionary text file
file_lines = file.read().splitlines() # reads and splits each line
all_words = [] # empty list to contain all words
valid_words = [] # empty list to contain all valid words
for word in file_lines: # traverses all words in the file lines
if len(word) >= 3: # accepts word if it has at least 3 letters
all_words.append(word) # appends accepted word to list
# list of all invalid characters in python
CHARACTERS = ["~", "`", "!", "#", "#", "$", "%", "^", "&", "*", "(",
")", "-", "_", "=", "+", "[", "]", "{", "}", "|", "\","
"", "'", "?", "/", ">", ".", "<", ",", "", ";", ":"]
for i in CHARACTERS: # traverse list of invalids
for word in all_words:
if i not in word: # if invalid character is not in word
valid_words.append(word) # accept and append to list
return valid_words # return list of valid words
def askForWordLength(self, valid_words):
word_lengths = [] # empty list for possible word lengths
for word in valid_words: # traverse list of valid words
length = word.__len__() # record length of current word
if (length not in word_lengths):
word_lengths.append(length) # accept and append to list
word_lengths.sort()
# inform user of possible word lengths
print('The available word lengths are: ' + str(word_lengths[0]) + '-'
+ str(word_lengths[-1]))
print()
# have user choose from possible word lengths
while(1):
try:
length = int(input('Please enter the word length you want: '))
if (length in word_lengths):
return length
except ValueError:
print('Your input is invalid!. Please use a valid input!')
print()
def askForNumberOfGuesses(self):
while(1):
try:
num_guesses = int(input('Enter number of guesses you want: '))
if (num_guesses >= 3):
return num_guesses
except ValueError:
print('Your input is invalid!. Please use a valid input!')
print()
def wordStatus(self, length):
status = '-'
for i in range(0, length):
status += '-'
return
def remainingWords(self, file_lines, length):
words = []
for word in file_lines:
if (word.__len__() == length):
words.append(word)
return words
def printGameStats(self, letters_guessed, status, num_guesses):
print('Game Status: ' + str(status))
print()
print('Attempted Guesses' + str(letters_guessed))
print('Remaining Guesses' + str(num_guesses))
def askPlayerForGuess(self, letters_guessed):
letter = str(input('Guess a letter: ')).lower()
pattern = re.compile("^[a-z]{1}$")
invalid_guess = letter in letters_guessed or re.match(pattern, letter) == None
if (invalid_guess):
while (1):
print()
if (re.match(pattern, letter) == None):
print('Invalid guess. Please enter a correct character!')
if (letter in letters_guessed):
print('\nYou already guessed that letter' + letter)
letter = str(input('Please guess a letter: '))
valid_guess = letter not in letters_guessed and re.match(pattern, letter) != None
if (valid_guess):
return letter
return letter
def retrieveWordStatus(self, word_family, letters_already_guessed):
status = ''
for letter in word_family:
if (letter in letters_already_guessed):
status += letter
else:
status += '-'
return status
def retrieveRemainingWords(self, guess, num_guesses, remaining_words,
wordStatus, guesses_num, word_length,
createWordFamiliesDict,
findHighestCountWordFamily,
generateListOfWords):
word_families = createWordFamiliesDict(remaining_words, guess)
family_return = wordStatus(word_length)
avoid_guess = num_guesses == 0 and family_return in word_families
if (avoid_guess):
family_return = wordStatus(word_length)
else:
family_return = findHighestCountWordFamily(word_families)
words = generateListOfWords(remaining_words, guess, family_return)
return words
def createWordFamiliesDict(self, remainingWords, guess):
wordFamilies = dict()
for word in remainingWords:
status = ''
for letter in word:
if (letter == guess):
status += guess
else:
status += '-'
if (status not in wordFamilies):
wordFamilies[status] = 1
else:
wordFamilies[status] = wordFamilies[status] + 1
return wordFamilies
def generateListOfWords(self, remainingWords, guess, familyToReturn):
words = []
for word in remainingWords:
word_family = ''
for letter in word:
if (letter == guess):
word_family += guess
else:
word_family += '-'
if (word_family == familyToReturn):
words.append(word)
return words
def findHighestCountWordFamily(self, wordFamilies):
familyToReturn = ''
maxCount = 0
for word_family in wordFamilies:
if wordFamilies[word_family] > maxCount:
maxCount = wordFamilies[word_family]
familyToReturn = word_family
return familyToReturn
def printCountOfRemainingWords(self, remainingWords):
show_remain_words = str(input('Want to view the remaining words?: '))
if (show_remain_words == 'yes'):
print('Remaining words: ' + str(len(remainingWords)))
else:
print()
def play(self, askForWordLength, askForNumberOfGuesses, remainingWords,
words, wordStatus, printCountOfRemainingWords, printGameStats,
askPlayerForGuess, retrieveRemainingWords):
MODE = 1
openSession = 1
while (openSession == 1):
word_length = askForWordLength(words)
num_guesses = askForNumberOfGuesses()
wordStatus = wordStatus(word_length)
letters_already_guessed = []
print()
game_over = 0
while (game_over == 0):
if (MODE == 1):
printCountOfRemainingWords(remainingWords)
printGameStats(remainingWords, letters_already_guessed,
num_guesses, wordStatus)
guess = askPlayerForGuess(letters_already_guessed)
letters_already_guessed.append(guess)
num_guesses -= 1
remainingWords = retrieveRemainingWords(guess, remainingWords,
num_guesses, word_length)
wordStatus = wordStatus(remainingWords[0], letters_already_guessed)
print()
if (guess in wordStatus):
num_guesses += 1
if ('-' not in wordStatus):
game_over = 1
print('Congratulations! You won!')
print('Your word was: ' + wordStatus)
if (num_guesses == 0 and game_over == 0):
game_over = 1
print('Haha! You Lose')
print('Your word was: ' + remainingWords[0])
print('Thanks for playing Hangman!')```
It looks like you don't understand how classes work or there is a piece of code not shown here. When you define a method in a class, the first argument always refers to the object on which the method operates, which is conventionally called self. Any subsequent arguments are defined how you want. Usually, you don't need to pass the first self argument because it is passed according to the object you use. Any remaining arguments are your responsibility though.
For example:
class Student:
def __init__(self, name, age):
# Initializer (Commonly called Constructor in other languages)
# This is the first method that will run when you create an object and
# it runs automatically (You don't need to call it).
# This is where you'd initialize the state of the object, for example:
# Create a student with name and age.
# name and age are regular parameters of the __init__ method. We'd like
# to save them as attributes of our student object which is represented
# by self.
self.name = name
self.age = age
# Maybe we'd like to save a list of grades too
self.grades = []
def add_grade(self, grade):
# self is our object, and grade is the parameter
self.grades.append(grade)
def get_average(self):
# If we don't need additional parameters, we don't have to, but self is
# mandatory
return sum(self.grades) / len(self.grades)
def print_status(self):
# Note I am calling get_average() and I don't specify self. It's determined automatically.
print("Name:", self.name)
print("Age:", self.age)
print("Average:", self.get_average())
# We created the class, but we need to create some objects to use it.
s1 = Student("Dan", 15)
s2 = Student("Maya", 14)
# Note we only pass the custom parameters we specified which are `grade`
# self is determined by the object we are using (s1 or s2)
s1.add_grade(81)
s1.add_grade(86)
s2.add_grade(89)
s2.add_grade(93)
s1.print_status()
s2.print_status()
I hope this example helps you understand how methods work. In your code, I don't understand why you pass the methods as arguments of the play method and I don't see where you call this method or where you even create a Hangman object, so I can't help further.
def read_input(random_words):
word = choose_random_words()
rand = random.randrange(0, 3)
letter = find_row_letter(word[rand])
print(rand)
user_input = timed_input("Input: %s " % letter)
return user_input
This function chooses a random word out of a list. This Word is then linked to a letter of the alphabet. You can see the timed_input as a normal input, as it is not important for my question.
def handle_input(random_words):
letter = read_input(random_words)
word =
print(letter)
if word == letter:
print("Correct")
else:
print("False")
In this function I want to compare if the user input from function read_input is the same as the chosen word from the same function.
Make read_input return the word too
def read_input(random_words):
word = choose_random_words()
rand = random.randrange(0, 3)
letter = find_row_letter(word[rand])
user_input = timed_input("Input: %s " % letter)
return user_input, word
def handle_input(random_words):
letter, word = read_input(random_words)
What you can do is declare the word variable to be global:
def read_input(random_words):
global word
word = choose_random_words()
rand = random.randrange(0, 3)
letter = find_row_letter(word[rand])
print(rand)
user_input = timed_input("Input: %s " % letter)
return user_input
That allows you to access the word variable from anywhere.
I'm writing a hangman game and found a code online for replacing blank spaces with the letters after a correct guess was made but it unfortunately produces a 'NoneType' error
I'm not sure how to correct it and I haven't been able to apply other answers I've found online to the code to fix it
word_list = ['around','august','branch','bright','castle','change','across']
tries = 0
word = random.choice(word_list)
print(word)
blank = print ("_ "*len(word))
while tries < 7:
guess = input("Enter a letter: ")
blank = list(blank)
for k in range(0, len(word)) or []:
if guess == word[k]:
blank[k] = guess
print (''.join(blank))
You are storing the return of print and not the value in print into blank
Try this :
import random
word_list = ['around','august','branch','bright','castle','change','across']
tries = 0
word = random.choice(word_list)
print(word)
blank = "_ "*len(word) #storing what you want in variable
print(blank) #print the variable
while tries < 7:
guess = input("Enter a letter: ")
blank = list(blank) #here you do list() on the variable and not the return of print >> OK
for k in range(0, len(word)) or []:
if guess == word[k]:
blank[k] = guess
print (''.join(blank))
Hey guys so I have my program working to a certain extent. My program is suppose to check if there is an "A" in the user input and if done so it will swap that "A" with the next letter.
Here are the examples:
"tan" = "TNA"
"abracadabra" = "BARCADABARA"
"whoa" = "WHOA"
"aardvark" = "ARADVRAK"
"eggs" = "EGGS"
"a" = "A"
In my case this is what works and doesn't work:
Works:
tan to TNA
Doesn't work:
abracadabra = BARCADABAR
whoa = WHO
aardvark = ARADVRA
eggs = EGG
a =
a just equals nothing.
What I'm getting at is that the last character isn't printing and I'm not sure how to do so.
def scrambleWord(userInput):
count = 0
Word_ = ""
firstLetter_ = ""
secondLetter_ = ""
while count < len(userInput):
if count+1 >=len(userInput):
break #copy last character
firstLetter_ = userInput[count] #assigning first letter
secondLetter_ = userInput[count+1] #assigning next letter
if firstLetter_ == 'A' and secondLetter_ != 'A':
Word_ += (secondLetter_ + firstLetter_) #Swap then add both letters
count+=1
else:
Word_+=firstLetter_
count+=1
return Word_
def main():
userInput = input("Enter a word: ")
finish = scrambleWord(userInput.upper())
print(finish)
main()
Probably because you are just breaking without writing the userinput[count] into the word.
if count+1 >=len(userInput):
Word_ += userInput[count]
break #copy last character
This should help
This function will search for anagrams in a list from a .txt file, I want to be able to check for anagrams and return all anagrams of the word that I input, and if it's not an anagram it will return the input, when I do it in the code below, it iterates through the for loop then ignores my first if statement and heads directly to my else statement. How can I fix this?
def find_in_dict():
input_word = input("Enter input string)")
sorted_word = ''.join(sorted(input_word.strip()))
a_word = ''.join((input_word.strip()))
word_file = open("filename", "r")
word_list = {}
for text in word_file:
simple_text = ''.join(sorted(text.strip()))
word_list.update({text.strip(): simple_text})
alist = []
for key, val in word_list.items():
if val == sorted_word:
alist.append(key)
return alist
else:
return "No words can be formed from:" + a_word
you are making a return statement in the if and else branch, that will break the for (because return invoked inside a function do exactly that, interrupt the execution and return the value) , so, don't do that, just ask if the word is equal, and in the end, check if there is none occurrences (empty list)
for text in word_file:
simple_text = ''.join(sorted(text.strip()))
word_list.update({text.strip(): simple_text})
alist = []
for key, val in word_list.items():
if val == sorted_word:
alist.append(key)
if alist == []: print("No words can be formed from: " + a_word)