How do I subtract a number with an if-statement? - python

This is my code:
import sys
import click
def Seats():
global seats
seats = 168
print("\nThe current seating capacity is {}\n".format(seats))
def Restart():
while True:
restart = click.confirm('\nWould you like to subtract 1 from seats?',
default=True)
if restart == True:
x = seats - 1
Seats()
elif restart == False:
print("\nOk, see you next time!\n")
sys.exit()
Seats()
Restart()
I want to ask the user "Would you like to subtract 1 from seats?" and then subtract one from seats variable and then repeat until the users inputs no.

As pointed in the comments, the main problem in your code is here:
def Seats():
global seats
seats = 168
print("\nThe current seating capacity is {}\n".format(seats))
Whenever and wherever you call the function Seats in your code, the value of seats is redefined because seats = 168 gets executed.
With the problem pointed out, I tried to edit your code maintaining the same structure in order to try to show you how to fix the problem, but changed my mind. The code, despite small, has an unnecessarily complex logic and a far from clean syntax. You are a beginner, so there is no problem with that! It is just that, because of that, I thought that showing you another way to implement this algorithm would be more valuable. Here it goes:
import click
seats = 168
while seats > 0:
subtract_seat = click.confirm('\nWould you like to subtract 1 from seats?', default = True)
if subtract_seat:
seats -= 1
print("\nThe current seating capacity is {}\n".format(seats))
else:
break
print("\nOk, see you next time!\n")
Do not need to import the sys library. You are not using it
while seats > 0 avoids subtracting seats when there are no more seats left and is also the main loop used to interact with the user
The else clause will automatically take care if the first condition is not met
There is absolutely no need for functions or global variables in your code. They might be needed if you insert this code in a bigger context, but keep simplicity in mind
#AshidoBestGirl

To get things to work you have to declare seats to be a global variable in the Restart() function and stop resetting it in the Seats() function. It doesn't have to be declared in the version of the Seats() function below because it no longer tries to set or change its value.
To subtract a number from a variable and store the result back into the variable, you need to either do variable = variable - number or use the more succinct variable -= number statement.
Also, when you want to terminate the while loop in Restart() and let it "fall of the end" and return, all you need to do is break out of the while True loop.
Here's your code with those changes:
import click
seats = 168 # Initialize global variable.
def Seats():
print("\nThe current seating capacity is {}\n".format(seats))
def Restart():
global seats
while True:
restart = click.confirm('\nWould you like to subtract 1 from seats?',
default=True)
if restart:
seats -= 1
Seats()
else:
print("\nOk, see you next time!\n")
break
Seats()
Restart()

Related

Can I make a print statement run before a module I imported?

I am a beginner to python and coding in general and I was wondering how I can make a print statement run before a module I imported. I am making a number guessing game and in my main file where I combine all the modules, I have a general function for running all the code together. It would be best if I show my code so you guys will have a better understanding of what I am dealing with:
import random
import lvl1
import time
level1 = lvl1.Level_1_activated()
# This is the main file combining everything together to make this game playable
introduction = """
Hello and welcome to NumGuess by Sava. Here is a little bit about the game:
The game works by having 3 levels, each where you must pick a number between a range of
1-10 (level 1), 1-20 (level 2), and 1-50 (level 3).
You are given 5 attempts in the first level, 10 in the second level, and 20 in the final one.
You can also access a hint by typing ‘hint’. You win the game by picking the right number in each level.
You lose the game when you run out of tries. You can get a free bonus with 5 extra tries if you type ‘hlp’.
"""
def start_game(time, lvl1):
print(introduction)
level1
start_game(time, lvl1)
This is just the code for the main module, I have the code for lvl1 (which is the first level of my 'game'), and I have a class which has all the functions which then take part in the while loop. I will also show that file:
import random
import time
# I will fist make variables for the time breaks. S is for short, M is for medium and L is for long
S = 0.2
M = 0.7
L = 1.1
class Level_1_activated():
def get_name(self):
# This function simply asks the name of the player
name = input("Before we start, what is your name? ")
time.sleep(S)
print("You said your name was: " + name)
def try_again(self):
# This asks the player if they want to try again, and shows the progress of the level
answer = (input("Do you want to try again? "))
time.sleep(M)
if answer == "yes":
print("Alright!, well I am going to guess that you want to play again")
time.sleep(M)
print("You have used up: " + str(tries) + " Of your tries. Remember, when you use 5 tries without getting the correct number, the game ends")
# Return statement for if the player wants to play again
return True
else:
print("Thank you for playing the game, I hope you have better luck next time")
# This is the return statement that stops the while loop
return False
def find_rand_num(self, random):
# This is the core of the level, where the player just chooses numbers between 1 and 10
time.sleep(S)
print("The computer is choosing a random number between 1 and 10... beep beep boop")
time.sleep(L)
# The list of numbers for the level that the player is on at the moment
num_list = [1,10]
number = random.choice(num_list)
ques = (input("guess your number, since this is the first level you need to choose a number between 1 and 10 "))
print(ques)
if ques == str(number):
time.sleep(S)
print("Congratulations! You got the number correct!")
# Yet another return statement for the while loop
return "Found"
elif input != number:
time.sleep(M)
print("Oops, you got the number wrong")
# This variable is fairly self-explanatory; it is what controls how many itterations there are in the while loop
tries = 1
while tries < 6:
if tries < 2:
Level_1_activated().get_name()
res = Level_1_activated().find_rand_num(random)
if res == "Found":
break
checker = Level_1_activated().try_again()
if checker is False:
break
tries += 1
If you go back to this function in the main file:
def start_game(time, lvl1):
print(introduction)
level1
I intentionally put the print statement before the module to make it run first, and I have tried different approaches to this and still can't seem to get a grasp on what I'm doing wrong here. Thank you for taking the time to read the code and I would be very grateful if any of you have a possible solution to this.
there are number of thing you can do, one is encapsulate your code into functions that only run when you ask for it
lvl1
... #all the previous code
def run_game():
tries = 1
while tries < 6:
...
tries += 1
you can also make a distinction between being executed directly vs being imported, to do that is simple, you include the following check (usually at the end of the file)
if __name__ == "__main__":
#if true it mean that you're executing this module directly, otherwise it was imported
#and you include here whatever you want that happens when you execute the module directly but not when is imported, like for example running a game
run_game()
__name__ is a special variable and python will assigned the value "__main__" if executed directly, otherwise it will be the name of the file, like "lvl1" for example
And in your main you can import it and do stuff like
import lvl1
...
def start_game():
print(introduction)
lvl1.run_game()

How to get rid of the global variables

I don't want to use the global-variable, but how do I make this without them?
(I have more functions and so on, so this isn't all)
Players turn. I use the global-variable to make sure the turns are switching, tried some other sulotion however the turns didn't switch...
#Check if the shot hit any computerships
def player_hit_check():
global players_turn
shot = player_shot()
check_if_hit = set(computer_ships) & set(player_turn_shot)
if(check_if_hit == set()):
print("You missed! Switching turns...")
time.sleep(3)
players_turn = 1
else:
print(f"YOU MADE A BIG BANG ON ",player_turn_shot,"!")
computer_ships.remove(shot)
all_player_hits.append(shot)
Computers turn
#Check if the computers shot hit any player ships
def computer_hit_check():
global computers_turn
computer_random_shot = computer_shot()
check_if_hit = set(player_ships) & set(computer_turn_shot)
if(check_if_hit == set()):
print("Computer missed! It's now your turn.")
time.sleep(3)
computers_turn = 1
else:
print(f"COMPUTER MADE A BIG BANG ON ",computer_turn_shot,"!")
player_ships.remove(computer_random_shot)
all_computer_hits.append(computer_random_shot)
The game it self
#Runs the game
while True:
#Players turn
players_turn = 0
while players_turn < 1:
print('\n'.join('\t'.join(row) for row in board.values()))
print("Playerships:",player_ships)
print("Computerships:",computer_ships)
print("You have shot on",all_player_shots,"and has knocked out these ships:",all_player_hits)
print("The computer has shot at these coordinates",all_computer_shots,"and has knocked out these ships:",all_computer_hits)
player_hit_check()
#Computers turn
computers_turn = 0
while computers_turn < 1:
computer_hit_check()
In your case you don't need global variables at all. Your program is not using them to carry information back and forth.
In your case you just need to get information back from your functions. So in the case of player_hit_check():
def player_hit_check():
shot = player_shot()
check_if_hit = set(computer_ships) & set(player_turn_shot)
if(check_if_hit == set()):
print("You missed! Switching turns...")
time.sleep(3)
return 1
else:
print(f"YOU MADE A BIG BANG ON ",player_turn_shot,"!")
computer_ships.remove(shot)
all_player_hits.append(shot)
return 0
And the call site would be like this:
while True:
#Players turn
players_turn = 0
while players_turn < 1:
# prints elided ...
players_turn = player_hit_check()
The problem with global variables is, that they fly around in an unstructured manner.
There are several approaches to solve global variables
One first step to get rid of global variables is to use singletons (https://en.wikipedia.org/wiki/Singleton_pattern). This will bundle similar values into one class. So the values are more structured and easier to track.
Use classes. If the global value is used in an environment that can be associated to a single responsibility, it can be productive to bundle all functions in a class and make the global variable to a class variable or property of the class
Pass it through. In many programs there is the need of settings class or state class. Put everything in there that defines the current state or starting state of the program and pass it through your code. The downside of passing is, that this classes tend to become almighty classes that appear in every constructor.
There are certainly more approaches how to get rid of global variables, but this are some common strategies.

Modifying a dictionary inside of an if statement

I've been trying to make a basic text game in Python, and I'm using dictionaries to contain the player's information. I want to make it so that when a player's health reaches 0, the code will stop running. I've had trouble making that happen. My dictionary, which is at the beginning of my code, looks like this:
playerAtt = {}
playerAtt["Weapon"] = "Baseball bat"
playerAtt["Party"] = "Empty"
playerAtt["Health"] = 15
playerAtt["Cash"] = "$100"
print(playerAtt)
if playerAtt['Health'] <= 0:
exit()
The bottom section is what I wrote to try and make the code stop running when the player's health reached zero, but it doesn't seem to work. In one path of my game, your health gets set to zero and the game is supposed to end, but the program continues to run:
townChoice = raw_input("You met a traveler in the town. 'Yo. I'm Bob. Let's be friends.' Will you invite him to your party? Y/N\n")
if townChoice == 'y' or townChoice == 'Y':
print("That kind traveler was not such a kind traveler. He stabbed you with a machete. RIP " + Name + '.')
playerAtt['Health'] == 0
When you reach this part of the game, all it does is print the message, and moves on to the next decision. In this situation, I could just manually end the program by doing exit() under the print command, but there are circumstances where the player only loses a fraction of their health, and they would eventually reach zero. Sorry if this is a stupid question, I've only been working on Python for a few days.
You have two "=" when you set the player's health to 0
I had put 2 == instead of 1 = when defining
playerAtt["Health"].
Also, I needed to make sure it was constantly checking if the player's health was zero, so I used a while loop. I used
while playerAtt["Health"] = 0:
deathmsg()
exit()
to fix it. deathMsg was a function I made to display a random death message, for more information.

Assigning a value to a objects created at run time (python)

I am trying to use a while loop to create object to populate a list of a user defined type until a certain condition is met. I want to assign a value to each object based on the number of iterations the loop has completed. For example:
class WalkingPeeps:
def___init___(self):
self.location = 0
def leftAt(self,time):
self.tleft = time
def changePos(self):
self.location += random.choice([1, -1])
objectList =[]
location_reached = False
time = 0
while not location_reached
objectList.append(WalkingPeeps())
for x in objectList:
x.tleft = time
if x.location == 20:
location_reached = True
time+=1
print("Person left at: ",x.tleft)
print("Person arrived at: ", time)
However, when it runs, it just set the time the object was created to one less than when the person reached 20. Any pointers? Hints? Thanks in advance.
In python, loops do not define their own scope. When you write
for x in objectList: ...
There variable x is created. At each step in the loop, the variable is updated. When the loop ends, the variable is not destroyed. Therefore, when you print x.tleft, you're printing the time on the last x, which by definition is 20, since you break the loop only when x.tleft == 20.
Furthermore, since you loop over every single element at each phase and update its time, you're setting each elements time to the most reccent time. Therefore, all elements have time == 20, when you terminate. What you mean, I believe, is to only update the last element
What I think you want to print, to check that your loop is working is,
for obj in objectList:
print( obj.tleft )
You would then see the expected behaviour
You also have many errors, including some syntax errors and some that make the code enter an infinite loop. This is the version I worked with, in good faith (try and make sure that the the only bugs in your code are the one's you're asking about!)
class WalkingPeeps: pass # None of the methods were relevant
objectList =[]
location_reached = False
time =0
while not location_reached:
objectList.append(WalkingPeeps())
x = objectList[-1]
x.tleft = time
# you need to check tleft, not location; location is never set
if x.tleft == 20:
location_reached = True
time+=1
print("Person left at: ",x.tleft)
print("Person arrived at: ", time)
for person in objectList: print(person.tleft)
A far more readable and concise version of this code would be:
class WalkingPerson:
def __init__(self,time=0):
self.time=time
objectList = [WalkingPerson(t) for t in range(20)]

How do you make python read a random value it printed and insert it into an array?

I have written a small coin flipping program for Home work Python, it will choose one of two values; Heads or Tails at random and print them, the loop iterates 10 times then stops. As I understand it the only way to count the number of repetitions of some words is to place the words in an array or a split variable string and then run a pre-written cnt. Click Here to see that discussion.
I need to know how you get Python to take the random value it produced and then save it into an array according to the number of iterations of the for loop(in this case x number of iterations).
Here is the variable name and the two options:
coin = ["Heads", "Tails"]
Here is the code for the coin flipper core:
#Flipping core :)
def flipit(random, flip, time, comment, repeat):
time.sleep(1)
print("It begins...")
print("\n")
for x in range(0, 10):
print("Flip number", x + 1)
print(random.choice(comment))
time.sleep(1)
print(random.choice(coin),"\n")
time.sleep(2)
print("\n")
from collections import Counter
counting = []
cnt = Counter(counting)
cnt
print("Type startup(time) to begin flipping coins again")
If you do feel like refining the code please do if you have the time, but all I need is a method that I can put into the overall program that will make it run properly.
Please don't worry about the random comment, that was for a bit of fun.
I have pasted the whole program on PasteBin, Click Here for that.
Thank you for reading this and my gratitude to those who respond or even fix it.
Edit:
Just for reference I am a bit of a newbie to Python, I know some things but not even half of what the people who answer this will know.
Solution:
I have managed to make Python "read" the random value using a per-iteration if statement in my for loop, using if statements I have added 1 to the respective variable according to the random.choice.
Here is the flip core code:
def flipit(random, time, comment, headcount, tailcount, side):
time.sleep(1)
print("It begins...")
print("\n")
for x in range(0, 10):
print("Flip number", x + 1)
side = random.choice(coin) # get the random choice
print(random.choice(comment))
time.sleep(1)
print(side) # print it
if side == "Heads":
headcount += 1
else:
tailcount += 1
time.sleep(2)
print("\n")
print("You got", headcount, "heads and", tailcount, "tails!")
print("Type start() to begin flipping coins again")
resetheadtail()
resetheadtail() is the new function I have added to reset the variables at the end of the program running.
For the full code click Here!
Thanks all who helped, and those who persevered with my newbieness :)
#comment necessary for edit, please ignore
I think what you want to do is:
flip = random.choice(coin) # get the random choice
print(flip) # print it
counting.append(flip) # add it to the list to keep track
Note that you will need to move counting = [] to before your for loop.

Categories

Resources