CS50 Introduction to Programming with Python: Problem with Check50 in PSet4 - python

I'm taking CS50 Introduction to Programming with Python. I have problem with PSet4 (Little Professor). I don't have any problem while running, but when check50 running it keeps giving this error: "Little Professor accepts valid level timed out while waiting for program to exit." While I’m manually running the program, it accepts any level value lower than 4. But the check50 says otherwise. Here is my code:
import random
def main():
try:
level = input("Level: ")
first, second = get_level(level)
game_on(first, second, 0, 2, 0, level)
except WrongInputError:
main()
def get_level(x):
try:
x = int(x)
if 0 < x < 4:
first = generate_integer(x)
second = generate_integer(x)
return first, second
else:
raise WrongInputError
except ValueError:
raise WrongInputError
class WrongInputError(Exception):
"""You entered something wrong, try again """
def generate_integer(level):
if level == 1:
integer = random.randrange(10)
return integer
elif level == 2:
x = str(random.randrange(1, 10))
y = str(random.randrange(10))
integer = int(x + y)
return integer
elif level == 3:
x = str(random.randrange(1, 10))
y = str(random.randrange(10))
z = str(random.randrange(10))
integer = int(x + y + z)
return integer
def game_on(x , y, count, lives, score, level):
game_set = [x, y]
try:
if count < 10:
calculation = int(input(f"{x} + {y} = "))
count += 1
if calculation == sum(game_set):
score +=1
first, second = get_level(level)
game_on(first, second, count, 3, score, level)
elif calculation == sum(game_set):
print("EEE")
if lives > 0:
lives -= 1
count -= 1
game_on(x, y, count, lives, score, level)
elif lives == 0:
print(f"{x} + {y} = {sum(game_set)}")
first, second = get_level(level)
game_on(first, second, count, 2, score, level)
else:
print(f"Score: {score}")
except ValueError:
print("EEE")
if lives > 0:
lives -= 1
game_on(x, y, count, lives, score, level)
elif lives == 0:
print(f"{x} + {y} = {sum(game_set)}")
first, second = get_level(level)
game_on(first, second, count, 2, score, level)
if __name__ == "__main__":
main()
main()

import sys
import random
def main():
num = get_level()
errors = 1
score = 0
for i in range(10):
x = generate_integer(num)
for j in range(1):
y = generate_integer(num)
answer = x + y
equation = input(f"{x} + {y} = ")
if int(equation) == answer:
score += 1
while int(equation) != answer:
errors += 1
print("EEE")
equation = input(f"{x} + {y} = ")
if errors >= 3:
print(answer)
sys.exit("Score: " + str(score))
print("Score: " + str(score))
# prompt for level and reprompt if needed
def get_level():
levelChoice = input("Level: ")
if levelChoice.isalpha() or int(levelChoice) <= 0 or int(levelChoice) > 3:
input("Level: ")
else:
levelChoice = int(levelChoice)
for i in [1,2,3]:
if levelChoice == i:
return levelChoice
# generate int from level choice
def generate_integer(level):
try:
if level == 1:
return random.randint(0, 9)
elif level == 2:
return random.randint(10, 99)
elif level == 3:
return random.randint(100, 999)
except:
raise ValueError
if __name__ == "__main__":
main()

Related

Why am I not breaking out of a try loop with a break statement?

My code for now works as desired where the user can input a level 1-3 depending on how hard they would like it to be (1-3 being the amount of digits the numbers will have in the math equation), and then must solve math equations. Those math equations will output EEE if the answer is incorrect and everything works as planned if you correctly answer the question as it exits the function and adds one total_correct_answers variable at the bottom, then will prompt you with another equation. However, if you input an incorrect answer and then a correct answer, you will just be prompted with the same question over and over again without the try loop being truly broken out of and total_correct_answers not being incremented positively by 1. The incrementation block of code is at lines 61-65, and the equation code is lines 30-49.
import random
def main():
ten_questions()
def get_level():
while True:
try:
level_input = int(input("Level: "))
if level_input in [1,2,3]:
return level_input
except:
pass
def integer_generator(level):
if level == 1:
x = random.randint(0,9)
y = random.randint(0,9)
elif level == 2:
x = random.randint(10, 99)
y = random.randint(10, 99)
else:
x = random.randint(100, 999)
y = random.randint(100, 999)
return x, y
def question_generator(x, y):
real_answer = x + y
wrong_counter = 0
while True:
try:
answer_given = input(str(x) + " + " + str(y) + " = ")
if int(answer_given) == real_answer:
if wrong_counter == 0:
return True
elif int(answer_given) == real_answer and wrong_counter != 0:
break
else:
while wrong_counter < 2:
print("EEE")
wrong_counter +=1
break
else:
print(str(x) + " + " + str(y) + " = " + str(real_answer))
print("False, that was last attempt")
break
except:
print("EEE")
pass
def ten_questions():
num_of_questions = 0
total_correct_answers = 1
my_level = get_level()
correct_answers = question_generator(*integer_generator(my_level))
while num_of_questions <= 8:
question_generator(*integer_generator(my_level))
num_of_questions +=1
if correct_answers == True:
total_correct_answers +=1
print("Score: " + str(total_correct_answers))
if __name__ == "__main__":
main()
Because of your line 36:
if int(answer_given) == real_answer: happens when someone answers correctly, wether they are right or wrong. So it enters the if, and then faces if wrong_counter == 0: which discards wrong answers. So just replace those two lines with if int(answer_given) == real_answer and wrong_counter == 0: and you are good to go.

TypeErr: Object "int" is not callable

I tried to make a "typing game" and at first, it worked out pretty nice. But when I translated my code to English (variable names, class names, function names etc.) it gave me the warning "Object int is not callable". How can I solve this?
Here's my code:
import time
import random
import sys
class Player():
def __init__(self, name, health = 5, energy = 10):
self.name = name
self.health = health
self.energy = energy
self.hit = 0
def inf(self):
print("Health: ", self.health, "\nEnergy: ", self.energy, "\nName: ", self.name)
def attack(self, opponent):
print("Attacking")
time.sleep(.300)
for i in range(3):
print(".", end=" ", flush=True)
x = self.randomAttack()
if x == 0:
print("Nobody attacks.")
elif x == 1:
print("{} hits {} !".format(name, opponentName))
self.hit(opponent)
opponent.health -= 1
elif x == 2:
print("{} hits {}!".format(opponentName, name))
opponent.hit(self)
self.health -= 1
def randomAttack(self):
return random.randint(0, 2)
def hit(self, hit):
hit.hitVariable += 1
hit.energy -= 1
if (hit.hitVariable % 5) == 0:
hit.health -= 1
if hit.health < 1:
hit.energy = 0
print('{} won the game!'.format(self.name))
self.exit()
#classmethod
def exit(cls):
sys.exit()
def run(self):
print("Running...")
time.sleep(.300)
print("Opponent catch you!")
#######################################################
print("Welcome!\n----------")
name = input("What's your name?\n>>>")
opponentName = input("What's your opponent's name?\n>>>")
you = Player(name)
opponent = Player(opponentName)
print("Commands: \nAttack: a\nRun: r\nInformation: i\nExit: e")
while True:
x = input(">>>")
if x == "a":
you.attack(opponent)
elif x == "r":
you.run()
elif x == "i":
you.inf()
elif x == "e":
Player.exit()
break
else:
print("Command not found!")
continue
It gives me the error at line 24 (self.hit(opponent)).
Your hit function is the problem. You have member and a function with the same name. Change one of them.
Also rename the hit argument of the hit(). You call it via self.hit(opponent) so I would rename it to def hit(self, opponent):.
def __init__(self, name, health = 5, energy = 10):
self.hit = 0
def hit(self, hit):
hit.hitVariable += 1
hit.energy -= 1
if (hit.hitVariable % 5) == 0:
hit.health -= 1
if hit.health < 1:
hit.energy = 0
print('{} won the game!'.format(self.name))
self.exit()

Mastermind Python coding

Ok I have a feeling that this is a simple simple issue but I have been staring at this code for about 10 hours now.
The issue I am having is in mastermind is that once I get it to recognize that I have the correct colors in the right spot I can get it to display the right spots with X and the wrong spots with O. I need to be able to convert that so instead of X and O I need it to tell the user that he/she has 2 blacks and one white
For example: The secret code is RGYB The user enters RGOY so then Python relays "You have 2 blacks(The R and G spots) and one 1 White (The Y because it's the right color just in the wrong index) As of right now I got it to display X for the right color in the right spot and anything else it is an O
I will post what I have been working with now but today I am at my wit's end
https://pastebin.com/HKK0T7bQ
if correctColor != "XXXX":
for i in range(4):
if guess[i] == tempCode[i]:
correctColor += "X"
if guess[i] != tempCode[i] in tempCode:
correctColor += "O"
print (correctColor + "\n")
if correctColor == "XXXX":
if attempts == 1:
print ("You think you are sweet because you got it right on the first try? Play me again!")
else:
print ("Well done... You needed " + str(attempts) + " attempts to guess.")
game = False
A few comments
X and O
you use X and 0 to denote the success, it will be easier and faster to use a list or tuple or booleans for this, that way you can use sum() to count how many colors and locations were correct. Then whether you represent that with X and O or red and white pins is a matter for later
compartmentalization
Your game logic (guess input, input validation, do you want to continue, etc) is mixed with the comparison logic, so it would be best to separate the different functions of your program into different methods.
This is an fineexample to introduce object oriented programming, but is so simple it doesn't need OO, but it can help. What you need is a method which takes a series of colours and compares it to another series of colours
Standard library
Python has a very extended standard library, so a lot of stuff you want to do probably already exists
Correct colours
to count the number of letters which occur in 2 strings, you can use collections.Counter
guess = "RGOY "
solution = "RGYB"
a = collections.Counter(guess)
b = collections.Counter(solution)
a & b
Counter({'G': 1, 'R': 1, 'Y': 1})
correct_colours = sum((a & b).values())
3
So the user guessed 3 colours correctly
Correct locations
can be solved with an easy list comprehension
[g == s for g, s in zip(guess, solution)]
[True, True, False, False]
sum(g == s for g, s in zip(guess, solution))
2
so the used put 2 colours on the correct location
This is a MasterMind I made in Python. Hope you like it and it helped you! :)
import random
import time
from tkinter import *
def select_level():
global level
level = level_selector.get()
root.destroy()
root = Tk()
level_selector = Scale(root, from_=1, to=3, tickinterval=1)
level_selector.set(0)
level_selector.pack()
Button(root, text="Select a difficulty level", command=select_level).pack()
mainloop()
cpc_1_digit = 0
cpc_2_digit = 0
cpc_3_digit = 0
cpc_4_digit = 0
p_1_digit = 0
p_2_digit = 0
p_3_digit = 0
p_4_digit = 0
correct_correct = 0
correct_wrong = 0
chances = 0
if level == 1:
chances = 15
elif level == 2:
chances = 10
else:
chances = 7
cpc_1_digit = random.randint(0, 9)
while cpc_2_digit == cpc_1_digit or cpc_2_digit == cpc_3_digit or cpc_2_digit ==
cpc_4_digit:
cpc_2_digit = random.randint(0, 9)
while cpc_3_digit == cpc_1_digit or cpc_3_digit == cpc_2_digit or cpc_3_digit ==
cpc_4_digit:
cpc_3_digit = random.randint(0, 9)
while cpc_4_digit == cpc_1_digit or cpc_4_digit == cpc_2_digit or cpc_4_digit ==
cpc_3_digit:
cpc_4_digit = random.randint(0, 9)
while chances > 0:
correct_correct = 0
correct_wrong = 0
answer = input("Enter a four-digit number with different digits (e.g 1476): ")
p_1_digit = int(answer[0])
p_2_digit = int(answer[1])
p_3_digit = int(answer[2])
p_4_digit = int(answer[3])
if p_1_digit == cpc_1_digit:
correct_correct = int(correct_correct) + 1
elif p_1_digit == cpc_2_digit or p_1_digit == cpc_3_digit or p_1_digit ==
cpc_4_digit:
correct_wrong = int(correct_wrong) + 1
else:
pass
if p_2_digit == cpc_2_digit:
correct_correct = correct_correct + 1
elif p_2_digit == cpc_1_digit or p_2_digit == cpc_3_digit or p_2_digit ==
cpc_4_digit:
correct_wrong = int(correct_wrong) + 1
else:
pass
if p_3_digit == cpc_3_digit:
correct_correct = int(correct_correct) + 1
elif p_3_digit == cpc_1_digit or p_3_digit == cpc_2_digit or p_3_digit ==
cpc_4_digit:
correct_wrong = int(correct_wrong) + 1
else:
pass
if p_4_digit == cpc_4_digit:
correct_correct = int(correct_correct) + 1
elif p_4_digit == cpc_1_digit or p_4_digit == cpc_3_digit or p_4_digit ==
cpc_2_digit:
correct_wrong = int(correct_wrong) + 1
else:
pass
print("")
if int(correct_correct) == 4:
print("Congratsulations! You found the computer's number!")
break
elif int(correct_wrong) > 0 or int(correct_correct) >= 1 and int(correct_correct)
< 4:
print("You got " + str(correct_correct) + " correct digit(s) in the correct
place, and " + str(correct_wrong) + " correct digit(s) but in wrong place.")
elif int(correct_correct) == 0 and int(correct_wrong) == 0:
print("You didn't guess any number, try again!")
else:
raise Exception("CheckError: line 69, something went wrong with the
comparings.")
exit()
print("")
chances = chances - 1
if chances == 0:
print("You lost... The secret number was " + str(cpc_1_digit) + str(cpc_2_digit)
+ str(cpc_3_digit) + str(cpc_4_digit) + ". Try again by rerunning the program.")
time.sleep(4)

While loop not breaking under logical circumstances

I am making a code to simulate a dice and do other stuff, but there is a while loop which isn't breaking and I don't know why.
import random
import math
#infinite loop
while True:
while True:
a = 0
#input amount of dice
att_die = raw_input('Attacking dice: ')
def_die = raw_input('Defending dice: ')
#att
#if NaN
if str(att_die).isdigit() == False:
print('NaN')
#if not NaN
else:
a += 1
#def
#if NaN
if str(def_die).isdigit() == False:
print('NaN')
#if not NaN
else:
a +=1
if a == 2:
break
if att_die >= def_die:
no = def_die
else:
no = att_die
print (no)
x = 0
while x <= no:
att_loss = 0
def_loss = 0
roll_att = random.randint(1,6)
roll_def = random.randint(1,6)
if roll_att <= roll_def:
att_loss += 1
elif roll_att == roll_def:
att_loss += 1
else:
def_loss += 1
x += 1
print(x)
print('Att: -' + str(att_loss) + '\nDef: -' + str(def_loss))
everything works up until the last while loop, which just continuously outputs the value of x increasing.
Any help on how to fix this would be appreciated.
Thanks in advance
no is a str, not an int. x is an int. In Python2, ints are always compare less than strs:
In [187]: 9999 < '1'
Out[187]: True
The solution is to convert the str no into an int:
no = int(no)
In [188]: 9999 < int('1')
Out[188]: False
Note that in Python3, comparing an int with a str raises a TypeError, which will save many a programmer from this pitfall.
Here's a refactored version:
import random
import math
DIE_SIDES = 6
WINNING_ATTACK_ODDS = 0.5 * (DIE_SIDES - 1) / DIE_SIDES
def get_int(prompt):
while True:
try:
return int(raw_input(prompt))
except ValueError:
pass
def attack():
"""
Does the attacker win?
"""
return random.random() < WINNING_ATTACK_ODDS
def main():
while True:
att_die = get_int("Attacking dice: ")
def_die = get_int("Defending dice: ")
rolls = min(att_die, def_die)
def_loss = sum(attack() for _ in range(rolls))
att_loss = rolls - def_loss
print("Att: -{}\nDef: -{}".format(att_loss, def_loss))
if __name__=="__main__":
main()

Connecting and changing .txt-values to/from a mainfunction

I'm trying to create a class with private attributes (the attributevalues are imported from a .txt-file) the user should be able to change the values of the attribute. The list looks like this:
Rats
Berta/2/4/3/0
Oscar/5/0/3/2
John/-1/-6/-5/-9
My question is; where does my messy code go wrong? What am I missing? I've been searching the web for answers for a few days now.
#The class
class Rat(object):
"""Defines my class"""
def __init__(self, rat_name, sleep, joy, full, happiness):
self.__rat_name = rat_name
self.__sleep = sleep
self.__joy = joy
self.__full = full
self.__happiness = happiness
def setfull(self, value, absolute = False):
"""Gives the full attribute a value"""
try:
value = int(value)
if absolute:
self.__full = value
else:
self.__full += value
return True
except ValueError:
return False
def getfull(self):
"""Gives a fullvalue"""
return self.__full
def setfull(self, x):
x = int(x)
"""acess to the full attribute"""
self.__full = x
def sethappiness(self, value, absolute = False):
"""Gives the happiness attribute a value"""
try:
value = int(value)
if absolute:
self.__happiness = value
else:
self.__happiness += value
return True
except ValueError:
return False
def gethappiness(self):
"""Gives happiness value"""
return self.__happiness
def sethappiness(self, x):
"""access to the happiness attribute"""
x = int(x)
self.__happiness = x
def setsleep(self, value, absolute = False):
"""Gives the sleep attribute a value"""
try:
value = int(value)
if absolute:
self.__sleep = value
else:
self.__sleep += value
return True
except ValueError:
return False
def getsleep(self):
"""Gives a sleep value"""
return self.__sleep
def setsleep(self, x):
"""access to the sleep attribute"""
x = int(x)
self.__sleep = x
def setjoy(self, value, absolute = False):
"""Gives a value to the joy attribute"""
try:
value = int(value)
if absolute:
self.__joy = value
else:
self.__joy += value
return True
except ValueError:
return False
def getjoy(self):
"""Gives a joy value"""
return self.__joy
def setjoy(self, x):
"""access to the joy attribute"""
x = int(x)
self.__joy = x
# main menu functions
def cheese(self):
"""Feeds the pet"""
print("- Mmmm cheese!")
self.__full += 3
self.__sleep += 1
self.__joy += 1
return self.__full, self.__sleep, self.__joy
def play(self):
"""Plays with the rat"""
print("- Oh, I'm having fun!")
self.__full -= 2
self.__sleep += 2
self.__joy += 4
self.__happiness += 2
return self.__full, self.__sleep, self.__joy, self.__happiness
def tosleep(self):
"""Let the rat sleep"""
print("Zzzzzzz")
self.__sleep -= 7
self.__joy += 1
return self.__sleep, self.__joy
def trap(self):
"""A mousetrap"""
if self.__full > 5:
print("The rat is to full to be fooled by a simple mousetrap")
else:
print("The rat escaped with a broken tail!")
self.__joy -= 2
self.__happiness -=2
return self.__full, self.__sleep, self.__joy, self.__happiness
def __str__(self):
"""Returns a string that describes the mood of the rat"""
mood =self.rat_name + " är: "
if self.__joy > 5:
mood += "Glad, "
else:
mood += "Pissed, "
if self.__full > 8:
mood += "overfed, "
elif self.__full > 0:
mood += "full, "
elif self.__full < -5:
mood += "starving, "
else:
mood += "craving cheese and "
if self.__sleep > 7:
mood += "very tired and "
elif self.__sleep > 0:
mood += "sleepy and "
else:
mood += "well rested and "
if self.__happiness > 7:
mood += "SUPER HAPPY!"
elif self.__happiness > 0:
mood += "quite happy!"
else:
mood += "unhappy..."
return mood
# The list
def listan():
"""Opens and sorts the list"""
infil = open("ratlist.txt", "r")
infil.readline
rats = []
for row in infil:
lista = row.split("/")
print(lista)
ratname = lista[0]
ratsleep = int(lista[1])
ratjoy = int(lista[2])
ratfull = int(lista[3])
rathappiness = int(lista[4].strip())
t = Rat(ratname, ratsleep, ratjoy, ratfull, rathappiness)
rats.append(t)
print("Finished")
return rats
# the main menu
def main():
"""The menu"""
ratzinger = listan()
choice = None
while choice != "1":
print \
("""
The ratkeeper
1 - Buy a cat
2 - Listen to your rat
3 - Let the rat sleep
4 - Give the rat cheese
5 - Prepare a mousetrap
6 - Play with the rat
7 - Change the values of your rat
8 - Know the name of my rat
""")
choice = input("I want to: ")
if val == "1":
print(rat_name, "was tortured and eaten, bye.")
elif val == "2":
print(ratzinger)
elif val == "3":
ratzinger.tosleep()
elif val == "4":
ratzinger.cheese()
elif val == "5":
ratzinger.trap()
elif val == "6":
ratzinger.play()
elif val == "7":
print()
elif val == "8":
print()
else:
print("Choose a number between one and eight!")
main()
input()
In addition to the answer above: double underscores in Python do not imply that the marked attribute is private. Double underscores apply name mangling and are used to avoid naming-collisions. If you mean "private" then you should use a single underscore.

Categories

Resources