Don't know how to call classes in python using if function - python

So I am making a program in which it reads a .txt file and runs different classes; I made it so it opens the file and stores the text in a decision string, Using if decision == "wincode" or "lostcode" I want it to run a specific class like:
class wonToss():
wininput = input("Do you want to choose: ")
def outChoice():
print("no error")
def inChoice():
print("No error")
if wininput == "Indoor":
inChoice()
elif wininput == "Outdoor":
outChoice()
I put the "No error" for testing to see if it works
class lostToss():
def botChoose():
print("Bot is choosing between Indoor and Outdoor.")
print(".")
time.sleep(0.25)
print("..")
time.sleep(0.25)
print("...")
time.sleep(0.25)
print("")
choices = ['Indoor', 'Outdoor']
botting = random.choice(choices)
print(f"And the bot chose: {botting}")
time.sleep(2)
botChoose()
And this is the second class. So now, I want it to check the code and class the specific class.
This is the check code:
f=open("TossDecision.ch", "r")
if f.mode == 'r':
decision = f.read()
if decision == "jhe78r2dbgv67t2yhdb7vgr":
print("")
wonToss()
elif decision == "jhe78rnxshwdn7wgh89u3cn":
print("")
lostToss()
else:
print("Toss Decision changed! Re-run the PlayGame file.")
exit()
But the problem is,
When I run the program it just shows:
Do you want to choose (Indoor) or (Outdoor)?: Indoor
Bot is choosing between Indoor and Outdoor.
.
..
...
And the bot chose: Indoor
It calls both the classes. Currently its set to loss. It still calls wonToss() Can anyone help fix this

Sorry, but you are using classes totally wrong.
Please read on Object-oriented programming.
A class is a blueprint for an object.
In most times, you instantiate an object of the class, and work with it. Like this:
class Mything:
def InChoice(self):
print("No errror indoors")
def OutChoice(self):
print("No error outdoors")
def ask_choice(self):
wininput = input("Do you want to choose: ")
if wininput == "Indoor":
self.InChoice()
elif wininput == "Outdoor":
self.OutChoice()
Then in your program you do:
choice_object=Mything()
choice_object.ask_choice()

Related

Running a function inside of an if statement

I have a program that is supposed to show all classes in the external .txt file when the user presses "V", and is supposed to allow the user to lookup a specific class based off of its course code (EX. user types csce101 and it will print "Introduction to computer concepts"). However, I can't get the V and L functions to work properly. As it sits currently, the V function is only working because I called a break... but after it prints all the classes, it asks the user for a course code when it is not supposed to. That is what the L function is supposed to do. I am unsure on how to call a function inside of an if/elif loop. The function name just comes up as undefined. Is it possible with the way I have the code setup?
Python Code:
while True:
command = input("(V)iew, (L)ookup, or (Q)uit: ")
if command == "v":
break
elif command == "l":
print(f"{code}")
elif command == "q":
print("Goodbye!")
quit()
else:
print("Invalid command")
def getCourses():
courses = {}
with open("assignments/assignment-19/courses.txt") as file:
for line in file:
data = line.split(':')
code = data[0].strip()
className = data[1].strip()
courses[code] = className
return courses
def getDescription(courseList):
code = input("Enter course code: ").strip().lower()
if code in courseList:
print(f"{courseList[code]}")
else:
print(f"Sorry {code} is not in our system")
courseList = getCourses()
for classes in courseList:
print(f"{classes}: {courseList[classes]}")
getDescription(courseList)
.txt file contents
csce101: Introduction to Computer Concepts
csce102: General Applications Programming
csce145: Algorithmic Design 1
csce146: Algorithmic Design 2
csce190: Computing in the Modern World
csce201: Introduction to Computer Security
csce204: Program Design and Development
csce205: Business Applications Programming
Some general observations:
Functions, like any other object, need to be defined before they are
referenced/used. You aren't violating this, but you will be if you
fill in the rest of your while-loop. Ideally, you'll want a main
entry point for your program, so that it's clear in what order things
are being executed, and your functions are guaranteed to be defined
by the time flow-of-execution reaches the lines on which your functions are called.
It would make sense to define one function for each corresponding
command type (except for quit). You were on the right track here.
A couple questionable/redundant instances of f-strings (f"{code}" almost certainly doesn't do what you think it should.)
Prefer snake_case over camelCase when writing Python source code.
Your V command will terminate the loop (and the program)
prematurely. What if the user wants to print all courses, then a
description?
Here are my suggestions incarnate:
def get_courses():
courses = {}
with open("assignments/assignment-19/courses.txt", "r") as file:
for line in file:
data = line.split(":")
code = data[0].strip()
class_name = data[1].strip()
courses[code] = class_name
return courses
def display_courses(courses):
for key, value in courses.items():
print(f"{key}: {value}")
def display_description(courses):
code = input("Enter course code: ").strip().lower()
if code in courses:
print(courses[code])
else:
print(f"Sorry, \"{code}\" is not in our system.")
def main():
courses = get_courses()
while True:
command = input("(V)iew, (L)ookup or (Q)uit: ").lower()
if command == "v":
display_courses(courses)
elif command == "l":
display_description(courses)
elif commany == "q":
print("Goodbye!")
break
else:
print("Invalid command.")
# 'main' ends here
main()

Why am I getting "NameError" from input()?

I am new and trying to create a simple "guess the number game":
import random
class Randgame :
def __init__(self):
pass
def restart(self):
response = input("Type Yes To Play Again!").lower()
if response == "yes":
self.play()
else:
print("Thanks for playing!")
pass
def play(self):
guess = int(input("What's your guess?"))
num = random.randint(0, 10)
if guess == num:
print("Correct!")
else:
print("Nope!")
self.restart()
fun = Randgame()
fun.play()
All is well until I get to the restart() method. If I type "yes" into the console I get this response:
NameError: name 'yes' is not defined
I cannot figure this out to save my life and I don't know what to look up. Please help!
In Python 2, getting input as plain text is done via raw_input instead of input. Python 3 changed the name of the function to input. The Python 2 version of input does eval(raw_input(prompt)), so it is trying to actually access a variable called yes, when you just want to get the string "yes".
Python 2 Docs

While statement ignoring function

I am very new to using classes and creating functions within it. I have been trying to write a bit more elegant code to the point where the only line to be 'executed' is 1 line, 'o.pag' in this case.
However, my pag function is just not working out. To my eyes, though I've made several variations of the same and even tried to turn it into an series of 'if' statements, gets stuck on "Would you like to play again'?.
Here the problematic but:
def pag(self):
o.game()
o.q()
while p_again == 'yes':
o.game()
o.q(). <<<<<<THIS IS WANT WONT EXECUTE AFTER TYPING 'YES'
if p_again != 'yes':
break
Here is the complete code sample. I am wondering if I caused the problem myself by trying to put everything into functions. Any help would be greatly appreciated.
import random
a = random.randint(1, 9)
#a = 4
again = ''
y = 'yes'
n = 'no'
g= 0
p_again = ''
class olv(object):
def glogic(self):
if g > a:
print('You guessed too HIGH.')
elif g < a:
print('You guessed too LOW.')
else:
print(g)
def game(self):
global g
while g != a:
g = int(input('Guess a number between 1 and 9! '))
o.glogic()
if g == a:
print('Wow, you guessed it.')
def q(self):
global p_again
p_again = str(input('Would you like to play again? '))
def pag(self):
o.game()
o.q()
while p_again == 'yes':
o.game()
o.q()
if p_again != 'yes':
break
o = olv()
o.pag()
you need to put in inside function not out side the function.
code should look like this.
def pag(self):
o.game()
o.q()
while p_again == 'yes':
o.game()
o.q(). <<<<<<THIS IS WANT WONT EXECUTE AFTER TYPING 'YES'
if p_again != 'yes':
break
I believed that this guessing game can run without using classes. From your code, it shows that your basics towards classes is not familiar enough.
You can try to make this guessing game without using classes first. Then you can try to implement the game using classes.
Here is an example of using classes for this game:
import random
p_again = ""
class olv:
def __init__(self):
self.answer = random.randint(1, 9)
self.guess = 0
def game(self):
while self.guess != self.answer:
self.guess = int(input('Guess a number between 1 and 9: '))
if self.guess > self.answer:
print('You guessed too HIGH.')
elif self.guess < self.answer:
print('You guessed too LOW.')
elif self.guess == self.answer:
print("Wow, you guessed it")
else:
print("You should guess between 1 and 9")
while True:
o = olv()
o.game()
p_again = str(input('Would you like to play again? ')).lower()
if p_again != "yes":
break
As pointed out in the comments, you have most of the code logic in there; however there is some confusion about OOP. One great thing to learn is to abandon (at least mostly) global variables, and use classes so that they can keep state of things. Another great suggestion I have is to use meaningful names, for variables and methods.
Now, it is a bit difficult to comment on each line of your code, so I took the liberty to rewrite it a bit. Keep in mind, there are dozen ways to do the same thing, so mine is not the best, nor (hopefully) the worse. I'll add comments to the code:
import random
class Game(object):
# First, let's use meaningful names
def __init__(self):
# Being a class, we can have an init method, and we can use it to initialize
# some variables that we will use to maintain "state". This means, we will give
# the class the job to remember what these values are during the course of the
# program, instead of storing them as global variables
#
# These variables are accessible by ALL methods in the class, using `self.`
self.value_to_guess = -1 # Note: we make value_to_guess and user_input different on purpose
self.user_input = 0 # so that play_game can loop without too much extra code
self.continue_play = True
def game_logic(self):
# This method is in charge of the game logic, which is "compare the values and print something"
# In your original code you did it for only two cases (>, <); it would be a good idea to also
# consolidate the case of equality
if self.user_input > self.value_to_guess:
print('You guessed too HIGH.')
elif self.user_input < self.value_to_guess:
print('You guessed too LOW.')
else:
print('Wow, you guessed it.')
def game_play(self):
# This method is in charge of the game play, making sure that a new random value is
# set at the beginning of a cycle, and that the user is asked every time for a value,
# until the user guesses. Every time, `game_logic` is called so that it will print the
# appropriate message on screen
#
self.value_to_guess = random.randint(1, 9)
while self.value_to_guess != self.user_input:
self.user_input = int(input('Guess a number between 1 and 9! '))
self.game_logic()
def question(self):
# This method will ask the user the question, and return the answered string straight out
return str(input('Would you like to play again? '))
def play(self):
# This method in charge of running games+questions, until the user stops answering 'yes'
self.game_play()
while self.question() == 'yes':
self.game_play()
if __name__ == '__main__':
my_game = Game() # Create a new Game object
my_game.play() # Ask the game object `my_game` to start playing
It's a lot of code, but I hope all the comments will help.
Just what you asked for
The problem manifests like this:
You play the game until you guessed the right number. Note that g == a now.
The asks "Do you want to play again?"
game() is called
But since g == a, game() will immediately quit
So, what's the problem? Well, for a new game, a needs to get a new random value.
Other stuff to make you a better programmer
To me it looks like you're typing in a poor text editor. You use short variable names. If you use an IDE which is made for Python, you'll get code completion and you can have better names that actually express what things are. a could be answer, g could be guess etc. Try JetBrains PyCharm. They have a community edition which is already great.
To me, glogic() is incomplete. The "Wow you guessed it" part is in game(). How about
def glogic(self):
if g > a:
print('You guessed too HIGH.')
elif g < a:
print('You guessed too LOW.')
else:
print('Wow, you guessed it.')
The code depends on global variables. Since you already have a class, all the variables could be included there. Please read about def __init__(self) and member variables like self.answer etc.
In q(), you convert the user input into a string. That's unnecessary, because it is already a string.
In pag(), code is duplicate. The logic to execute o.game() and then o.q() is coded twice. If you set p_again = "yes" initially, you can get rid of that duplication.
It seems n, y and again are unused.
To make user input a bit more robust, you could .lower() the input just in case the user enters some captital letters.
Same for numbers: if the user enters a letter, the code will fail with a ValueError. Use try: ... except ValueError: ... to make the game more robust.
I could rewrite the whole code for you, but I think it's worth doing that yourself.

How to allow users to assign a instances or something that can work the same way?

What I am trying to do is to make an app so, while the user is using the app he can add an instance for a class.
To be more specific, I am trying to make a rating app for the workers but, I need to make the user to be able to add a worker to the app which I want to be treated as an instance in the backend code which has a class called worker.
and here is the code to understand what I am trying to say more.
class worker:
"""
This class is responsible for any worker been rated.
INPUT: name of rated worker
OUTPUT: the rating
"""
def __init__(self, name):
self.name = name
def rate(self):
rating = input(f"What is your rating for {self.name}")
#open a file and append the rating to it.
rat_stor = open(f"{self.name}rating_storage", "a+")
rat_stor.write(rating + ",")
rat_stor.close()
#open a file and read it.
rat_stor = open(f"{self.name}rating_storage", "r")
rat_stor_read = rat_stor.read()
rat_stor.close()
#I have the all the ratings as a list.
lis_rat = rat_stor_read.split(",")
#going to be used as a filter for non-numerical values
int_lis = []
for i in lis_rat:
#if the string can be converted to an integer then, add it to int_lis
try:
int_lis.append(int(i))
except:
pass
rates_sum = sum(int_lis)
rates_amount = len(int_lis)
self.result = rates_sum / rates_amount
def __str__(self):
return self.name + str(round(self.result,1))
You need to design a user interface for your program - if you want a windowed application then you could either use tkinter (built in to python) or you could find a package that does the job you want (installable using pip). Or you could make a web app with a package such as django. If this isn't a commercial application then the simplest option is to just make a command line application (using print and input)
For a windowed/graphical application: you need to consider what process the user should go through to add a worker/submit a rating. Presumably some data needs to be inputted (their name, etc.) The package you choose will allow you to build an interface for this.
Edit:
A command line app that illustrates how you might make a menu system, Allows you to create/rate workers. Error handling is very limited and workers are not saved to disk so they will be lost when the program is closed. I recommend looking into a module called pickle for saving data to disk - much more powerful that manually writing to a file. This example is written for Python version >3. For Python 2 you will need to use raw_input() instead of input
# --- file name: manageworkers.py ---
class Worker: #I'm using this in place of your class for simplicity
def __init__(self):
self.name = ""
self.ratings = []
def rate(self):
#Normally code that takes user input should be with the rest of the code for the menu. Have put this here to stay consistent with your code.
print("What is your rating for {}?".format(self.name))
self.ratings.append(input(">"))
print("Rating saved!")
workers = []
def mainMenu():
while True:
print("Please select an option:")
print("\t1) Add a worker")
print("\t2) Rate a worker")
print("\t3) View worker ratings")
print("\t4) Exit")
while True:
choice = int(input(">")) #Will break if you don't enter a valid number
if choice == 1:
addWorker()
break
elif choice == 2:
rateWorker()
break
elif choice == 3:
viewRatings()
break
elif choice == 4:
return
else:
print("Invalid selection - please try again")
def addWorker():
global workers
newWorker = Worker() #This is where the instance is created
print("What is the name of the worker?")
newWorker.name = input(">")
workers.append(newWorker) #Keep the worker somewhere so we can use it later
print("Worker Saved!")
def chooseWorker():
global workers
if len(workers) == 0:
print("There are no workers.")
return
#Let's print a menu
print("Please select a worker:")
for n, w in enumerate(workers):
print("\t{}) {}".format(n+1, w.name)) #Add one to n so numbering starts at 1
#Now we need to work out what the user entered
while True:
selection = int(input(">")) - 1 #Take the one away again so array indexing starts at 0. Will break if you don't enter a number.
if selection >= 0 and selection < len(workers):
return workers[selection]
break
else:
print("Invalid selection, please try again.")
def rateWorker():
workerToRate = chooseWorker()
if workerToRate != None:
workerToRate.rate()
def viewRatings():
workerToView = chooseWorker()
if workerToView != None:
if len(workerToView.ratings) == 0:
print("Worker has no ratings.")
else:
print("Ratings for {}:".format(workerToView.name))
for rating in workerToView.ratings:
print("\t{}".format(rating))
if __name__ == "__main__":
mainMenu()

My display menu repeats multiple times when an input is entered

I'm practice classes and inheritance in a program idea that I came up with myself. Basically Im making an arcade game menu simulator that can play two modes, single player and multiplayer. Every time I enter a choice, either 1 or 2, the menu displays a couple times and then it proceeds to accept the input, I only want the menu to be displayed once. Heres my code:
# Suppose you are at an arcade and you and your friend want to play a multiplayer game that requires UI.
# Make the game ask for the users name and age to see if they can play, make the program so that it can add a friend.
# If any of the players are under the age of 18, they are not allowed to play, otherwise proceed.
# **EXTRA CREDIT** --> Add a functionality which adds the players to a list until the list reaches 4 players, then stop adding to the list.
# arcade_game.py
import sys
# give the user a greeting
import self as self
lst = []
class menu:
def __init__(self, ready):
self.ready = ready
#display menu
#classmethod
def display_menu(self):
print("Pick from one of the choices below, type in the corressponding number")
print("1. single player \n"
"2. Multiplayer")
choice = int(input("Enter your choice here: "))
return choice
# ready or not function to see if the user is ready to play
def ready_or_not(self):
# see if user types 1 or 2 with try & except
try:
# ask user if they are ready
self.ready = int(input("Are you ready to play? Type 1 for yes, 2 for no"))
self.display_menu()
except ValueError:
print("You did not type 1 or 2, please try again!")
# add players class
class player(menu):
# add a default player to __init__(), **(since there has to be at least one player)**
def __init__(self, ready, player1):
super().__init__(ready)
self.player1 = player1
# single player method
def set_name(self):
self.player1 = input("Enter your name for single player mode")
print("Lets play! ", self.player1)
# multiplayer method
def set_names(self):
try:
self.player1 = input("Enter your name to begin")
lst.append(self.player1)
# add another player to continue
while len(lst) <= 4:
add = input("Add player here: ")
lst.append(add)
if len(lst) == 4:
print("Player limit reached!")
break;
except ValueError:
print("You didnt enter valid input, please try again")
# get the names of the players only if 1 is picked from display_menu() above, including player1
def check_choice(self):
if self.display_menu() == 1:
self.set_name()
elif self.display_menu() == 2:
self.set_names()
else:
print("Exiting....")
print("Goodbye!")
sys.exit(0)
m = menu("yes")
m.ready_or_not()
p = player("yes", "test")
p.check_choice()
ready_or_not calls self.display_menu():
def ready_or_not(self):
# see if user types 1 or 2 with try & except
try:
# ask user if they are ready
self.ready = int(input("Are you ready to play? Type 1 for yes, 2 for no"))
self.display_menu()
except ValueError:
print("You did not type 1 or 2, please try again!")
check_choice also calls self.display_menu() at least once, and twice if you type anything other than 1 the first time:
def check_choice(self):
if self.display_menu() == 1:
self.set_name()
elif self.display_menu() == 2:
self.set_names()
else:
print("Exiting....")
print("Goodbye!")
sys.exit(0)
Your top-level code calls ready_or_not() on one menu instance:
m = menu("yes")
m.ready_or_not()
… and check_choice() on another:
p = player("yes", "test")
p.check_choice()
So, your program displays the menu twice, and then a third time if you type anything but 1.
If you don't want the menu displayed two or three times, don't call the method two or three times.
If you want to display the menu only once and remember the choice, instead of displaying it two or three times, you need to use that self.ready attribute that you create in ready_or_not, instead of calling the method again.
However, that still isn't going to work as-is, because your class design is weird. You've made two separate instances, m and p, each of which has its own independent attributes. I'm not sure why player inherits from menu in the first place (or why display_menu is a #classmethod, or why it calls its parameter self rather than cls if it is one, and various other things), but, given that a player is a menu in your design, you probably just want a single player instance, like this:
p = player("yes", "test")
p.ready_or_not()
p.check_choice()
And then, you can change check_choice like this:
def check_choice(self):
if self.choice == 1:
self.set_name()
elif self.choice == 2:
self.set_names()
else:
print("Exiting....")
print("Goodbye!")
sys.exit(0)
Took me a while to figure out, but it seems like when you are done with display_menu() your calling ready_or_not() so you need to remove display_menu() from ready or not like this
# ready or not function to see if the user is ready to play
def ready_or_not(self):
# see if user types 1 or 2 with try & except
try:
# ask user if they are ready
self.ready = int(input("Are you ready to play? Type 1 for yes, 2 for no"))
# self.display_menu()
except ValueError:
print("You did not type 1 or 2, please try again!")
EDIT
looks like im late to the party

Categories

Resources