class Budget:
def __init__(self):
self.wants_perc = 0
self.wants_amt = 0
self.wants_left = 0
self.needs_perc = 0
self.needs_amt = 0
self.needs_left = 0
self.food_perc = 0
self.food_amt = 0
self.food_left = 0
while True:
try:
self.monthly_income = float(input("Enter your monthly income after taxes: "))
break
except ValueError:
print("Invalid Input : Please enter a number")
continue
while True:
print("Enter desired percentage of income spent for each category (do not include %): ")
try:
self.wants_perc = float(input("Wants: "))
self.needs_perc = float(input("Needs: "))
self.food_perc = float(input("Food: "))
if self.wants_perc + self.needs_perc + self.food_perc not in range(95, 105):
print("Invalid Input : Must add to 100%")
continue
else:
break
except ValueError:
print("Invalid Input : Please enter a number")
continue
def deposit(self):
dep_loc = input("Where would you like to deposit? ")
while True:
try:
if dep_loc.lower() == "wants":
self.wdep_amt = float(input("Deposit amount: "))
self.wants()
break
elif dep_loc.lower() == "needs":
self.ndep_amt = float(input("Deposit amount: "))
self.needs()
break
elif dep_loc.lower() == "food":
self.fdep_amt = float(input("Deposit amount: "))
self.food()
break
else:
print("Invalid Input")
break
except ValueError:
print("Invalid Input : Please enter a number")
continue
def wants(self):
self.wants_max = (self.wants_perc / 100) * self.monthly_income
self.wants_amt += self.wdep_amt
self.wants_left = self.wants_max - self.wants_amt
print(f"Amount spent on wants: ${self.wants_amt} \nAmount left to spend: ${round(self.wants_left,2)}")
def needs(self):
self.needs_max = (self.needs_perc / 100) * self.monthly_income
self.needs_amt += self.ndep_amt
self.needs_left = self.needs_max - self.needs_amt
print(f"Amount spent on needs: ${self.needs_amt} \nAmount left to spend: ${round(self.needs_left,2)}")
def food(self):
self.food_max = (self.food_perc / 100) * self.monthly_income
self.food_amt += self.fdep_amt
self.food_left = self.food_max - self.food_amt
print(f"Amount spent on food: ${self.food_amt} \nAmount left to spend: ${round(self.food_left,2)}")
wyatt = Budget()
while True:
wyatt.deposit()
I know this is a very general question, but is it possible to reduce the amount of repeated code I use? I feel like there has to be a way to use one general variable in a loop for each of the categories. My three functions that use the food, wants, and needs variables are all the exact same besides the names. I thought of getting user input and adding it to a list and indexing that list to get each category, but I couldn't fully figure it out. This may be too broad for stack overflow and if it is I apologize. Thanks!
In general there is no mechanism for reducing the amount of code - if there was, it would already be part of the language. Making a dictionary instead of member variables doesn't really help, because all it will do is replace your 9 member variables with 9 dictionary items.
However, there is an opportunity for factoring out repeated operations. Your instinct is correct that repeated blocks of code are a sign of poor design. I would suggest you start with a class structure something like this:
class BudgetItem:
def __init__(self, name):
self.name = name
self.perc = 0
self.amt = 0
self.left = 0
def get_perc(self):
self.perc = float(input(f"{self.name}: "))
class Budget:
def __init__(self, monthly_income):
self.monthly_income = monthly_income
self.wants = BudgetItem("Wants")
self.needs = BudgetItem("Needs")
self.food = BudgetItem("Food")
self.all_items = (self.wants, self.needs, self.food)
def gather_percentages(self):
print("Enter desired percentage of income"
" spent for each category (do not include %): ")
for b in self.all_items:
b.get_perc()
if 95.0 <= sum(b.perc for b in self.all_items) <= 105.0:
print("Precentages must sum to 100")
# etc.
Create a separate class to represent a budget category, since the logic for each is identical. Add methods to the little class to capture that logic. Now re-write your main class in terms of those three individual items. I won't take the time to refactor your whole program, but I hope you get the idea. You should end up with a much shorter program and no significant repeated logic.
One other thing: I think that putting an "input" statement in a class constructor is a terrible idea. Constructors should not contain complicated loops or extended logic. I would put it outside the class and pass the data into the class as arguments, or as method calls.
so, I'm getting a NameError on npc.name(and I imagine it will arise in all subsequent class method-linked variables I'm trying to redefine), also, I have an IndexError arising earlier.
I'll explain in more detail,but first, my code.
This is my full code, beware:
# import pickle
import pickle
npcs_pickle_file = 'NPCatt.pk'
npc_count = 200
class NPC:
def __init__(self, name="", occupation="", weakness="", need="", desire="", enemy="",
rumor="", secret="", passion="", redeeming_quality="",damning_quality="", happy="",
occ_desire="", occ_complication="", pc_opinion="", accomplishment="", magical_gear="",
political_influence="", resource="", intel="", research=""):
# Attributes
self.name = name
self.occupation = occupation
self.weakness = weakness
self.need = need
self.desire = desire
self.enemy = enemy
self.rumor = rumor
self.secret = secret
self.passion = passion
self.redeeming_quality = redeeming_quality
self.damning_quality=damning_quality
self.happy = happy
self.occ_desire = occ_desire
self.occ_complication = occ_complication
self.pc_opinion = pc_opinion
self.accomplishment = accomplishment
self.magical_gear = magical_gear
self.political_influence = political_influence
self.resource = resource
self.intel = intel
self.research = research
def __str__(self):
npc_output = "####NPC SUMMARY####\n"
for att, val in self.__dict__.items():
if val:
npc_output += (f"{att} = {val}\n")
return npc_output
# open a pickle file
# load your data back to memory when you need it
try:
with open(npcs_pickle_file, 'rb') as fi:
npcs = pickle.load(fi)
except FileNotFoundError as fne:
#file doesnt exist prob first time running so create a dict with the 170 npc id's
npcs = {id: None for id in range(npc_count)}
#select an NPC to modify / create
npc_id = None
while not npc_id:
try:
npc_id = int(input(f"Enter the id number of the NPC you wish to modify: "))
except ValueError as ve:
print("You must provide a numerical id")
if npc_id < 0 or npc_id >= npc_count:
npc_id = None
print(f"you must provide a value between 0 and {npc_count}")
if npcs[npc_id]:
npc = npcs[npc_id]
print(npc)
modify = input("This NPC already exists, do you want to continue and change them? (y/n): ")
if modify.lower() == "y":
name = input("Enter name of NPC: ")
occupation = input("Enter NPC occupation: ")
weakness= input("Enter Weakness: ")
need= input("Enter Need: ")
desire= input("Enter Desire: ")
enemy= input("Enter Enemy: ")
rumor= input("Enter Rumor: ")
secret= input("Enter Secret: ")
passion= input("Enter Passion: ")
redeeming_quality=input("Enter Redeeming Quality: ")
damning_quality=input("Enter Damning Quality: ")
happy= input("Enter, is this NPC happy?: ")
occ_desire= input("Enter an Occupational Desire: ")
occ_complication= input("Enter an Occupational Complication: ")
pc_opinion= input("Enter this NPC's disposition toward the PCs: ")
accomplishment= input("Enter an Accomplishment: ")
magical_gear= input("Enter Magical Gear: ")
political_influence=input("Enter Political Influence: ")
resource= input("Enter Resource Level: ")
intel= input("Enter Intel Tier: ")
research= input("Enter Research: ")
npc.name = name
npc.occupation = occupation
npc.weakness = weakness
npc.need = need
npc.desire= desire
npc.enemy= enemy
npc.rumor= rumor
npc.secret= secret
npc.passion= passion
npc.redeeming_quality= redeeming_quality
npc.damning_quality= damning_quality
npc.happy= happy
npc.occ_desire=occ_desire
npc.occ_complication=occ_complication
npc.pc_opinion=pc_opinion
npc.accomplishment=accomplishment
npc.magical_gear=magical_gear
npc.political_influence=political_influence
npc.resource=resource
npc.intel=intel
npc.research=research
else:
npcs[npc_id] = NPC(name=npc.name, occupation=npc.occupation,weakness=npc.weakness,need=npc.need,desire=npc.desire,\
enemy=npc.enemy,rumor=npc.rumor,secret=npc.secret,passion=npc.passion,redeeming_quality=npc.redeeming_quality,\
damning_quality=npc.damning_quality,happy=npc.happy,occ_desire=npc.occ_desire,\
occ_complication=npc.occ_complication\
,pc_opinion=npc.pc_opinion,accomplishment=npc.accomplishment,\
magical_gear=npc.magical_gear,political_influence=npc.political_influence,resource=npc.resource,\
intel=npc.intel,research=npc.research)
else:
name = input("Enter name of NPC: ")
occupation = input("Enter NPC occupation: ")
weakness= input("Enter Weakness: ")
need= input("Enter Need: ")
desire= input("Enter Desire: ")
enemy= input("Enter Enemy: ")
rumor= input("Enter Rumor: ")
secret= input("Enter Secret: ")
passion= input("Enter Passion: ")
redeeming_quality=input("Enter Redeeming Quality: ")
damning_quality=input("Enter Damning Quality: ")
happy= input("Enter, is this NPC happy?: ")
occ_desire= input("Enter an Occupational Desire: ")
occ_complication= input("Enter an Occupational Complication: ")
pc_opinion= input("Enter this NPC's disposition toward the PCs: ")
accomplishment= input("Enter an Accomplishment: ")
magical_gear= input("Enter Magical Gear: ")
political_influence=input("Enter Political Influence: ")
resource= input("Enter Resource Level: ")
intel= input("Enter Intel Tier: ")
research= input("Enter Research: ")
npc.name = name
npc.occupation = occupation
npc.weakness = weakness
npc.need = need
npc.desire= desire
npc.enemy= enemy
npc.rumor= rumor
npc.secret= secret
npc.passion= passion
npc.redeeming_quality= redeeming_quality
npc.damning_quality= damning_quality
npc.happy= happy
npc.occ_desire=occ_desire
npc.occ_complication=occ_complication
npc.pc_opinion=pc_opinion
npc.accomplishment=accomplishment
npc.magical_gear=magical_gear
npc.political_influence=political_influence
npc.resource=resource
npc.intel=intel
npc.research=research
with open(npcs_pickle_file, 'wb') as fi:
# dump your data into the file
pickle.dump(npcs, fi)
I'm a noob so the code structure was provided as an answer on my only other question so far on the site. I've expanded it for my purposes.
The thing is, the NPC indexed as [1], has been stored perfectly, shows up as needed, and is modifiable.
But when defining new NPCs, I get first an IndexError for new Indexable NPCs, which I caught with a
try: #the code for when the NPC has been previously defined
except IndexError:#the code on the last else block, for new indexes
in order to check whether the rest of the code worked,
and a NameError arises on the last else block where I define each attribute as
self.att=att
now, my best guess is that it has to do with local vs global variable definitions, but I have no idea how to solve either error.
Thank you if you read all the way through, and I'm sorry.
Please help, if you can and want to.
Your IndexError issue comes from unpickling a file created by the previous version of your script. If this file contains valuable data, just rename it for the moment, and once you'll get you script working and stable enough, it will be time to write a migration script to get your old data back. Else, well, just ditch it xD
wrt/ the NameError, it's in the last else block: you are trying to set attributes on a npc variable that is indeed not defined at this point - it's only defined in the if block:
if npcs[npc_id]:
npc = npcs[npc_id]
# way too much code here
else:
# repeated code here
# and here's the issue:
npc.something = something
You already noticed that "mashing together pieces of code without understanding them doesn't always work", which is a good start (at least you're aware of it, so there's still hope xD), now here's another enlightenment for you: "trying to understand messy code is hard". That's why good code structure is important. Also, short functions that only (or mostly) depend on their arguments are easier to understand (and test !) than long scripts with lots of conditionals and code blocks that depends on some variable being (or not) defined some 20+ lines away.
I usually don't do this, but it seems that in this case, you may benefit from seeing what a decently structured code looks like. It's far from perfect and could benefit from some improvements (like, when editing an existing npc, letting the user specify which attributes he wants to change instead of asking them to retype everything) but well, that's your job, not mine ;-)
import pickle
# coding conventions: pseudo-constants should be ALL_UPPER
NPCS_PICKLE_FILE = 'NPCatt.pk'
NPC_COUNT = 200
# coding convention: class names should be CamelCase
class Npc:
def __init__(self, name="", occupation="", weakness="", need="", desire="", enemy="",
rumor="", secret="", passion="", redeeming_quality="",damning_quality="", happy="",
occ_desire="", occ_complication="", pc_opinion="", accomplishment="", magical_gear="",
political_influence="", resource="", intel="", research=""):
# Attributes
self.name = name
self.occupation = occupation
self.weakness = weakness
self.need = need
self.desire = desire
self.enemy = enemy
self.rumor = rumor
self.secret = secret
self.passion = passion
self.redeeming_quality = redeeming_quality
self.damning_quality = damning_quality
self.happy = happy
self.occ_desire = occ_desire
self.occ_complication = occ_complication
self.pc_opinion = pc_opinion
self.accomplishment = accomplishment
self.magical_gear = magical_gear
self.political_influence = political_influence
self.resource = resource
self.intel = intel
self.research = research
def update(self, **values):
for key, val in values.items():
# make sure we're only accepted known attributes
if not hasattr(self, key):
raise AttributeError("Npc object has no attribute '{}'".format(key))
setattr(self, key, val)
def __str__(self):
# in Python, string concatenation is better done by
# building a list and joining it afterward
npc_output = ["####NPC SUMMARY####"]
for att, val in self.__dict__.items():
if val:
npc_output.append(f"{att} = {val}")
npc_output.append("") # so we have a last newline
return "\n".join(npc_output)
class InvalidDataFile(ValueError):
pass
def load_npcs_from_file():
with open(NPCS_PICKLE_FILE, 'rb') as fi:
try:
npcs = pickle.load(fi)
except EOFError as e:
raise InvalidDataFile(
"looks like {} is empy - expected a dict, got {}".format(NPCS_PICKLE_FILE, e)
)
# make sure we don't have incorrect data from
# the previous version where what was pickled was a list
if not isinstance(npcs, dict):
raise InvalidDataFile(
"looks like {} is obsolete or corrupted - expected a dict, got {}".format(NPCS_PICKLE_FILE, ncps)
)
# make sure we ALWAYS have `NPC_COUNT` npcs whatever
# (ie: in case the pickle didn't have as many entries as expected)
missing = NPC_COUNT - len(npcs)
if missing > 0:
for id in range(NPC_COUNT):
ncps.setdefault(id, None)
return npcs
def init_npcs():
return {id: None for id in range(NPC_COUNT)}
def load_npcs():
try:
return load_npcs_from_file()
except (FileNotFoundError, InvalidDataFile) as e:
# so you know what's happening...
print("got {} when trying to load npcs from file - creating a new dataset".format(e))
return init_npcs()
def save_npcs(npcs):
with open(NPCS_PICKLE_FILE, 'wb') as fi:
# dump your data into the file
pickle.dump(npcs, fi)
def get_npc_values():
# factor out common stuff
# XXX you definitly want to validate user inputs
values = {}
values["name"] = input("Enter name of NPC: ")
values["occupation"] = input("Enter NPC occupation: ")
values["weakness"] = input("Enter Weakness: ")
values["need"] = input("Enter Need: ")
values["desire"] = input("Enter Desire: ")
values["enemy"] = input("Enter Enemy: ")
values["rumor"] = input("Enter Rumor: ")
values["secret"] = input("Enter Secret: ")
values["passion"] = input("Enter Passion: ")
values["redeeming_quality"] = input("Enter Redeeming Quality: ")
values["damning_quality"] = input("Enter Damning Quality: ")
values["happy"] = input("Enter, is this NPC happy?: ")
values["occ_desire"] = input("Enter an Occupational Desire: ")
values["occ_complication"] = input("Enter an Occupational Complication: ")
values["pc_opinion"] = input("Enter this NPC's disposition toward the PCs: ")
values["accomplishment"] = input("Enter an Accomplishment: ")
values["magical_gear"] = input("Enter Magical Gear: ")
values["political_influence"] = input("Enter Political Influence: ")
values["resource"] = input("Enter Resource Level: ")
values["intel"] = input("Enter Intel Tier: ")
values["research"] = input("Enter Research: ")
return values
def update_npc(npc):
new_values = get_npc_values()
npc.update(**new_values)
def create_npc():
values = get_npc_values()
return Npc(**values)
def get_npc_id():
#select an NPC to modify / create
npc_id = None
while npc_id is None:
try:
npc_id = int(input(f"Enter the id number of the NPC you wish to modify: "))
except ValueError as ve:
print("You must provide a numerical id")
if npc_id < 0 or npc_id >= NPC_COUNT:
npc_id = None
print(f"you must provide a value between 0 and {NPC_COUNT}")
return npc_id
def edit_npc(npcs):
npc_id = get_npc_id()
# this should be safe now... theoretically at least
npc = npcs[npc_id]
if npc is None:
ok = input("This NPC doesn't exist yet, do you want to create it (y/n): ")
if ok.strip().lower() == 'y':
npcs[npc_id] = create_npc()
# let the caller know something was changed
return True
else:
ok = input("This NPC already exists, do you want to continue and change them? (y/n): ")
if ok.strip().lower() == "y":
update_npc(npc)
# let the caller know something was changed
return True
# let the caller know nothing was changed
return False
def show_npcs(npcs):
for id, npc in npcs.items():
print("{} : {}".format(id, npc))
print("") # add a blank line
def get_next_action():
while True:
print("what do you want to do ?")
print("S - show existing npcs")
print("E - edit a npc")
print("Q - quit")
action = input(">> ").strip().upper()
if action not in "SEQ":
print("sorry, I don't undertand '{}'".format(action))
return action
def main():
npcs = load_npcs()
while True:
nb_valids = len([_ for _ in npcs.values() if _])
print("we have {} valid npcs".format(nb_valids))
action = get_next_action()
if action == "Q":
break
elif action == "E":
if edit_npc(npcs):
print("saving data")
save_npcs(npcs)
elif action == "S":
show_npcs(npcs)
if __name__ == "__main__":
main()
basically i have made 4 question list and answer list the first one works fine but the next few don't work and come up with a error sometimes the first question is displayed but not the others
this is the tool and my code https://repl.it/#alandtic/final
Traceback (most recent call last):
File "main.py", line 155, in
print(question_list2[random_int])
IndexError: list index out of range
top_index=top_index-1
after deleting a question, you should atleast decrease top index.
# -*- coding: utf-8 -*-
"""
Created on Fri Jun 14 10:38:13 2019
#author: jainil
"""
import random
print("\033[0;37;40m\n")
print("welcome to soldier to WW1")
print(
"If you are ready to die for your country then you must learn all the parts of a WW1 soldier. but first maggot answers a few personal questions. ")
first_name = input("What is your first name? ")
middle_name = input("what is your middle name? ")
last_name = input("what is your last name? ")
full_name = (first_name + " " + middle_name + " " + last_name)
print("Is this your correct name? " + full_name)
yes_or_no = input("Y/N ")
if yes_or_no == ("N"):
print("program will give you chance to renter name in do not mess up again this is your LAST chance")
first_name = input("What is your first name? ")
middle_name = input("what is your middle name? ")
last_name = input("what is your last name? ")
full_name = (first_name + " " + middle_name + " " + last_name)
print("this is your NAME NOW " + full_name)
print("before we get to the training base do you want basic info on how it works. ")
TRAINING = input("Y/N ")
if TRAINING == ("Y"):
print(
" welcome to basic training let’s go over basic need to know info? A typical day starts with Reveille (a bugle or trumpet call to wake the soldiers and call them to duty) at 5.30 a.m. After tidying up and cleaning your quarters and having a brew, at 6.30 recruits will parade for an hour and a half to work on your fitness. After breakfast at 8, the morning was spent drilling on the parade square, learning, for instance, to march, form fours and about turn . Between 12.15 and 2 p.m. troops men took lunch before returning for more drill in the afternoon until 4.15. The unlucky image you might be working parties the rafter, but otherwise recruits are off duty, although you might have to spend time cleaning kit and shining boots. In large garrison towns like Aldershot, you can have leisure facilities in the shape of the ‘Smith-Dorrien Soldiers’ Home’, with a billiards room, a library, recreation rooms, private baths and a buffet. ")
i_am_gay = input("are you ready for the test Y/N")
if i_am_gay == ("Y"):
import random
question_list = []
question_list.append("what time do you wake up? ")
question_list.append("what do you do at 6:30? ")
question_list.append("what is at Aldershot? ")
question_list.append("what time do you have lunch? ")
question_list.append("Do you need to go to bed at a specific time? ")
answer_list = []
answer_list.append("5:30")
answer_list.append("parade")
answer_list.append("Leasure")
answer_list.append("12:15")
answer_list.append("No")
top_index = 4
correct = 0
for i in range(0, 5):
random_int = random.randint(0, top_index)
print(question_list[random_int])
user_answer = input("enter your answer: ")
if user_answer == answer_list[random_int]:
print("\033[1;32;40m good job \n")
print("\033[0;37;40m\n")
correct = correct + 1
else:
print("\033[1;31;40m incorrect \n")
print("\033[0;37;40m \n")
del question_list[random_int]
del answer_list[random_int]
top_index=top_index-1
print("you scored " + str(
correct) + " out of 5 based on this you will receive a rank all scores are collected to give you a final rank at the end of our testing. ")
import os
import time
time.sleep(10)
os.system('clear')
print(
"The next step of your training is to chose a group to learn more about and train in all with different types ways to train. first is infantry (multiple choice questions) second is planing (tactics questions) and finally is marine (fill in the blank)")
form = input("please select which one you want 1/2/3 ")
if form == ("1"):
form = input("you have selected infantry is this correct if yes enter Y1 if no then put in your teams number")
if form == ("Y1"):
print(
"first step is to train you on the role of infantry. your main mission is to be a ground troop this includes but is not limited to. building trenches, fighting off front lines and attack the enemies trenches.")
print(
"now that your training is complete time for your first quiz this will be multiple choice and will be the main for your rank. ")
question_list1 = []
question_list1.append(
"which one of these is not your job? A: build trench B: act as a spy C: fight on the front lines D: follow orders ")
question_list1.append("who is your boss? A: the furrier B: privates C: civilians D: a lieutenant ")
question_list1.append("which weaponry is better for long range A:50 cow B: mp5 C: benelli M3 D: Barret M82 ")
question_list1.append(
"which is not a rank? A: master first sergeant B: command segment major C: corporeal: D: private ")
answer_list1 = []
answer_list1.append("B")
answer_list1.append("D")
answer_list1.append("D")
answer_list1.append("A")
top_index1 = 3
correct = 0
for i in range(0, 4):
random1_int = random.randint(0, top_index1)
print(question_list1[random1_int])
user_answer1 = input("enter [A] [B] [C] [D] : ")
if user_answer == answer_list1[random1_int]:
print("\033[1;32;40m good job \n")
print("\033[0;37;40m\n")
correct = correct + 2
else:
print("\033[1;31;40m incorrect \n")
print("\033[0;37;40m \n")
del question_list1[random1_int]
del answer_list1[random1_int]
top_index1 = top_index1 - 1
if form == ("2"):
form = input("you have selected planing is this correct if yes enter Y2 if no then put in your teams number")
if form == ("Y2"):
print(
"first step is to train you on the role of a planer. you need to give tips and info to your troops based on you skills. ")
print(
"now that your training is complete time for your first quiz this will be a tactics question and will be the main determination for your rank. ")
question_list2 = []
question_list2.append(
"side X has a large compound with 12 men and side + has the element of surprise and 3 elite troops ")
question_list2.append("side X has 3 troops and the high ground side + has 13 troops but is on the low ground ")
answer_list2 = []
answer_list2.append("x")
answer_list2.append("+")
top_index2 = 1
correct = 0
for i in range(0, 2):
random_int = random.randint(0, top_index2)
print(question_list2[random_int])
user_answer2 = input("which side has the advantage x or +? ")
if user_answer2 == answer_list2[random_int]:
print("\033[1;32;40m good job \n")
print("\033[0;37;40m\n")
correct = correct + 4
else:
print("\033[1;31;40m incorrect \n")
print("\033[0;37;40m \n")
del question_list2[random_int]
del answer_list2[random_int]
top_index2 = top_index2 - 1
if form == ("3"):
form = input("you have selected marine is this correct if yes enter Y3 if no then put in your teams number")
if form == ("Y3"):
print(
"first step is to train you on the role of a marine. you need to give tips and info to your troops based on you skills. ")
print(
"now that your training is complete time for your first quiz this will be fill in the blanks and will be the main determination for your rank. ")
question_list3 = []
question_list3.append(" the marines are ___ based operatives ")
question_list3.append(" for under water travel marines use _____ ")
question_list3.append(" the average marine trains for _ weeks ")
answer_list3 = []
answer_list3.append("sea")
answer_list3.append("submarines")
answer_list3.append("13")
top_index3 = 2
correct = 0
for i in range(0, 3):
random_inte = random.randint(0, top_index3)
print(question_list3[random_inte])
user_answer3 = input("fill in the blank with the correct word ")
if user_answer3 == answer_list3[random_inte]:
print("\033[1;32;40m good job \n")
print("\033[0;37;40m\n")
correct = correct + 3
else:
print("\033[1;31;40m incorrect \n")
print("\033[0;37;40m \n")
del question_list3[random_inte]
del answer_list3[random_inte]
top_index3 = top_index3 - 1
time.sleep(10)
os.system('clear')
print(
"congratulations on your finishing of the course i will now give you a rank based on your score from e1(private) to e9(major) ")
if correct == (1):
print("e1 i would say not bad but that should be a lie")
elif correct == (2):
print("e1 i would say not bad but that should be a lie")
elif correct == (3):
print("e2 not worthless but not good")
elif correct == (4):
print("e2 not worthless but not good")
elif correct == (5):
print("e3 now i will make a man out of you")
elif correct == (6):
print("e3 now i will make a man out of you")
elif correct == (7):
print("e4 seems like front lines will be wasted on you")
elif correct == (8):
print("e5 good job mr wane")
elif correct == (9):
print("e6 no front line for you")
elif correct == (10):
print("e7 steve rogers would be proud")
elif correct == (11):
print("e8 welcome to the order")
elif correct == (12):
print("e9 no jokes you did very good my superior")
elif correct == (13):
print("you have no rank you scored 100% my bet is your cheater shame on you. ")
elif correct == (14):
print("this is a marine exclusive rank i added because i was lazy tbh. ")
you have not updated top index even,
Can anyone help me see what's going wrong in this? I'm getting an error at the end: "NameError: name 'age' is not defined". I'm just getting into Python and programming in general, and don't see what to change to fix it.
import random
def greeting():
print("Hi there, welcome to the world's simplest tv suggestion program!")
print("")
def get_birth_year():
birth_year = 0
birth_year = (input("Please enter your year of birth: "))
is_valid = is_year_valid(birth_year)
while not is_valid:
birth_year = input("Please enter a four digit year of birth: ")
is_valid = is_year_valid(birth_year)
birth_year = int(birth_year)
return birth_year
def is_year_valid(birth_year):
try:
birth_year = int(birth_year)
is_valid = True
except ValueError:
is_valid = False
return is_valid
def calculate_age(birth_year):
age = 0
age = 2018 - birth_year
return age
def show_rec_output(age):
print("Based on your age, a good Netflix show for you to watch would be:")
adult = ["Master of None", "Unbreakable Kimmy Schmidt", "Black Mirror", "Godless",
"Dear White People", "Grace and Frankie", "Jessica Jones"]
all_ages = ["The Crown", "The Great British Bake Off", "Jessica Jones",
"Sherlock", "A Series of Unfortunate Events", "Big Mouth"]
if age >= 18:
print(random.choice(adult))
else:
print(random.choice(all_ages))
def another_rec():
second_rec = ""
second_rec = (input("Would you like another recommendation Y/N: "))
while second_rec == str("Y"):
show_rec_output(age)
second_rec = (input("Would you like another recommendation? Y/N: "))
else:
print("Go make some popcorn!")
def main_module():
greeting()
birth_year = get_birth_year()
age = calculate_age(birth_year)
show_rec_output(age)
another_rec()
main_module()
The assignment I'm trying to complete requires one piece of input, one piece of output, two loops, input validation, and everything in modules.
The problem is here:
def another_rec():
second_rec = ""
second_rec = (input("Would you like another recommendation Y/N: "))
while second_rec == str("Y"):
show_rec_output(age)
You don't have age here, but you're trying to use it anyway.
To fix it, you want to do the exact same thing you do with show_rec_output. First, add an age parameter to the another_rec function:
def another_rec(age):
… and then, pass the value in from main_module:
show_rec_output(age)
another_rec(age)
My goal is to have a small program which checks if a customer is approved for a bank loan. It requires the customer to earn > 30k per year and to have atleast 2 years of experience on his/her current job. The values are get via user input. I implemented regexs to validate the input to be only digits without any strigns or negatives, nor 0.
But the 3rd function asses_customer is always executing the else part. I think everytime the parameters are either None, either 0
here's the source code:
import sys
import re
import logging
import self as self
class loan_qualifier():
# This program determines whether a bank customer
# qualifies for a loan.
def __init__(self): #creates object
pass
def main():
salary_check()
work_exp_check()
asses_customer(salary = 0, years_on_job = 0)
def salary_check():
input_counter = 0 # local variable
# Get the customer's annual salary.
salary = raw_input('Enter your annual salary: ')
salary = re.match(r"(?<![-.])\b[1-9][0-9]*\b", salary)
while not salary:
salary = raw_input('Wrong value. Enter again: ')
salary = re.match(r"(?<![-.])\b[1-9][0-9]*\b", salary)
input_counter += 1
if input_counter >= 6:
print ("No more tries! No loan!")
sys.exit(0)
else:
return salary
def work_exp_check():
input_counter = 0 #local variable to this function
# Get the number of years on the current job.
years_on_job = raw_input('Enter the number of ' +
'years on your current job: ')
years_on_job = re.match(r"(?<![-.])\b[1-9][0-9]*\b", years_on_job)
while not years_on_job:
years_on_job = raw_input('Wrong work experience. Enter again: ')
years_on_job = re.match(r"(?<![-.])\b[1-9][0-9]*\b", years_on_job)
input_counter += 1
if input_counter >= 6:
print ("No more tries! No loan!")
sys.exit(0)
else:
return years_on_job
def asses_customer(salary, years_on_job):
# Determine whether the customer qualifies.
if salary >= 30000.0 or years_on_job >= 2:
print 'You qualify for the loan. '
else:
print 'You do not qualify for this loan. '
# Call main()
main()
You have stated:
It requires the customer to earn > 30k per year and to have at least 2 years of experience on his/her current job.
We can write some simple statements that request a number and if a number is not given then ask for that number again.
The following code is a very simple approach to achieving that goal.
class Loan_Checker():
def __init__(self):
self.salary = 0
self.years_on_job = 0
self.request_salary()
self.request_years()
self.check_if_qualified()
def request_salary(self):
x = raw_input('Enter your annual salary: ')
try:
self.salary = int(x)
except:
print("Please enter a valid number")
self.request_salary()
def request_years(self):
x = raw_input('Enter the number of years on your current job: ')
try:
self.years_on_job = int(x)
except:
print("Please enter a valid number")
self.request_years()
def check_if_qualified(self):
if self.salary >= 30000 and self.years_on_job >= 2:
print 'You qualify for the loan. '
else:
print 'You do not qualify for this loan. '
Loan_Checker()
You have a few errors in your code, and I've refactored it to use the class structure you seemed to want to imply.
import sys
import re
import logging
class loan_qualifier():
# This program determines whether a bank customer
# qualifies for a loan.
def __init__(self): #creates object
self.salary = self.salary_check()
self.years_on_job = self.work_exp_check()
def salary_check(self):
input_counter = 0 # local variable
# Get the customer's annual salary.
salary = None
while salary is None:
if input_counter >= 6:
print ("No more tries! No loan!")
sys.exit(0)
elif input_counter >= 1:
print ("Invalid salary.")
salary = raw_input('Enter your salary: ')
salary = re.match(r"(?<![-.])\b[1-9][0-9]*\b", salary).group(0)
input_counter += 1
# broke out of loop, so valid salary
return salary
def work_exp_check(self):
input_counter = 0 #local variable to this function
# Get the number of years on the current job.
years_on_job = None
while years_on_job is None:
if input_counter >= 6:
print ("No more tries! No loan!")
sys.exit(0)
elif input_counter >= 1:
print ("Invalid year amount")
years_on_job = raw_input('Enter the number of years at your current job: ')
years_on_job = re.match(r"(?<![-.])\b[1-9][0-9]*\b", years_on_job).group(0)
input_counter += 1
# broke out of loop, so valid years_on_job
return years_on_job
def assess_customer(self):
# Determine whether the customer qualifies.
if int(self.salary) >= 30000.0 and int(self.years_on_job) >= 2:
print 'You qualify for the loan. '
else:
print 'You do not qualify for this loan. '
if __name__ == "__main__":
lq = loan_qualifier()
lq.assess_customer()
Some of the errors fixed include the way you were calling assess_customer initially (you were assigning 0's to both values in the function call), as well as the spelling of assess :p. Your condition in assess_customer should also have been an and instead of an or (you wanted both conditions to be true for them to qualify, not for either condition to be true).
You actually don't even really need to do the:
self.salary = self.salary_check()
self.years_on_job = self.work_exp_check()
lines. You could just directly assign the class variables in the functions (i.e. instead of returning, just set self.salary = blah in salary_check). That's kind of a personal choice thing though. I think this makes it clear.
Hopefully this is all clear to you. Let me know if you have any questions. The code can be called by simply typing python NAME_OF_YOUR_FILE.py.
Edit: I didn't realize how broken the salary and years checks were, the new code should fix them.
Edit: Fixed the regex results in this version. My bad.
In this fragment you pass third function always salary = 0 and years_on_job = 0
Try this way:
salary = salary_check()
years_on_job = work_exp_check()
asses_customer(salary, years_on_job)