How to simplify my elif code in python - python

I am viswa. I prepared a simple code using elif command.
I will share the code and condition... it is working. but I am looking for simplified program. if anything available for the same result
inputs names are= 'AEX_ABC','AEX_XXX','AEX_YYY','CAI_XXX','CAI_YYY'....etc.,
output should be AEX_1,AEX_2,AEX_3,CAI_1,CAI_2,....
program:
name=(<user input>)
AEX,CAI,CAR,CCA,CEL,CLM,CRE,ECH,FAV,FRE,GMP,INS,ROU,TAR,TAV,UAV,VEH,ERROR=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
name=part._name.split('_')
if name[0]=='AEX':
AEX+=1
i=AEX
elif name[0]=='CAI':
CAI+=1
i=CAI
elif name[0]=='CAR':
CAR+=1
i=CAR
elif name[0]=='CCA':
CAR+=1
i=CCA
elif name[0]=='CEL':
CEL+=1
i=CEL
elif name[0]=='CLM':
CLM+=1
i=CLM
elif name[0]=='CRE':
CRE+=1
i=CRE
elif name[0]=='ECH':
ECH+=1
i=ECH
elif name[0]=='FAV':
FAV+=1
i=FAV
elif name[0]=='FRE':
FRE+=1
i=FRE
elif name[0]=='GMP':
GMP+=1
i=GMP
elif name[0]=='INS':
INS+=1
i=INS
elif name[0]=='ROU':
ROU+=1
i=ROU
elif name[0]=='TAR':
TAR+=1
i=TAR
elif name[0]=='TAV':
TAV+=1
i=TAV
elif name[0]=='UAV':
UAV+=1
i=UAV
elif name[0]=='VEH':
VEH+=1
i=VEH
else:
ERROR+=1
i='error'+str(ERROR)
output=name[0]+i
print(output)

You can replace this with a dictionary lookup.
stock_indices={<all stock indices:0>}
error=0
try:
stock_indices[input[0]]+=1
except KeyError:
error+=1

As Jesse Bakker says, this is a job for a dictionary. Whenever you find yourself creating a whole bunch of variable names to track a group of related items you should probably be using a dictionary instead. You can use a dict literal to initialize the dictionary, but when all of the items have the same initial value it's convenient to use the dict.fromkeys class method, as shown below.
To keep the code lines short I've split the keys string into two strings: Python will automatically join adjacent string literals, but we need to wrap the expression with parentheses so that the parser knows that it continues over more than one line.
keys = ('AEX,CAI,CAR,CCA,CEL,CLM,CRE,ECH,FAV,FRE,'
'GMP,INS,ROU,TAR,TAV,UAV,VEH,ERROR'.split(','))
stock_indices = dict.fromkeys(keys, 0)
def update_stock(name):
key = name.partition('_')[0]
if key not in stock_indices:
key = 'ERROR'
val = stock_indices[key] + 1
stock_indices[key] = val
return key, val
# Test
test = (
'AEX_ABC',
'AEX_XXX',
'AEX_YYY',
'BAD_ZZZ',
'CAI_XXX',
'CAI_YYY',
)
for name in test:
key, val = update_stock(name)
print('{0}_{1}'.format(key, val))
output
AEX_1
AEX_2
AEX_3
ERROR_1
CAI_1
CAI_2

Related

How do I take a dictionary from one function and use it in another in python?

Edit: changing code as the issue came up first somewhere else in my code
I'm trying to figure out how to use my dictionary from one function in another one and the other answers on here haven't helped.
The overall goal is to print the key and value just entered into the dictionary named contacts but contacts can only be defined inside init_phonebook
def init_phonebook():
contacts = {}
while True:
choice = print_menu()
if choice == 1:
list_contacts(contacts)
elif choice == 2:
add_contact(contacts)
elif choice == 3:
find_contact(contacts)
elif choice == 4:
edit_contact(contacts)
elif choice == 5:
delete_contact(contacts)
elif choice == 6:
delete_all(contacts)
elif choice == 7:
thanks()
Down here the issue is that .keys and .values don't work as it's not recognizing contacts as a dictionary. I've tried changing the parameter to something else but it doesn't work that way either.
def add_contact(contacts):
phone_number = input('Please enter a phone number: ')
name = input('What would you like to save the name as?: ')
if name in contacts:
print('This contact already exists in your phonebook')
elif name not in contacts:
contacts[name] = phone_number
print('Contact successfully saved')
print('Your updated phonebook is shown below')
for c in contacts:
print('{} --> {}'.format(contacts.keys(c), contacts.values(c)))
print()
the error message I get is:
File "c:\Users\myname\Desktop\VS Code Projects\contact_list.py", line 54, in add_contact
print('{} --> {}'.format(contacts.keys(c), contacts.values(c)))
TypeError: dict.keys() takes no arguments (1 given)
The problem is not how you go about passing the dictionary to these other functions.The error actually arising within your add_contact() function, due to how you are trying to iterate through the dictionary key-val pairs:
for c in contacts:
print('{} --> {}'.format(contacts.keys(c), contacts.values(c)))
It seems you want to iterate through the contacts. contact.keys() does not let you access/index a key, this method returns all of the keys in a dict. contact.values does not let you access/index a value, it returns all of the values in the dict. When you call "for c in contacts", c represents a key. So here are two alternative ways to iterate through:
Properly indexing on the contacts dict using the key c:
for c in contacts:
print('{} --> {}'.format(c, contacts[c]))
By iterating through both the key and value pairs:
for key,value in contacts.items():
print('{} --> {}'.format(key, value))
If confused about a type in Python, I recommend referring to the documentation!
dict.keys() and dict.values() both return arrays that can be indexed but accepts no inputs when called.
But in your case, since you are looping over the dictionary, each iteration stores the key in c. In your case that will be the name associated with the contact.
So you already have the key stored in c on each iteration. What you need next is to use the key to get the value like so dict[key] or dict.get(key).
Alternatively, you can loop over both keys and values simultaneously like so:
for name, phone_number in contacts:
print("{} ==> {}".format(name, phone_number))
I am altering your original code as follows:
def add_contact(contacts):
phone_number = input('Please enter a phone number: ')
name = input('What would you like to save the name as?: ')
if name in contacts:
print('This contact already exists in your phonebook')
else: #You seem to have only two options so no need for elif
contacts[name] = phone_number
print('Contact successfully saved')
print('Your updated phonebook is shown below')
for c in contacts: #c will hold name in each iteration
print('{} --> {}'.format(c, contacts[c]))

How do I find if a value is present in a value list in dictionary?

So here is the question. I am trying to find if a particular value is part of a value list in a dictionary. when I tried using .values(), it wouldn't work. Here is the code. The part indicated does not go into the if statement.
company_dict = dict()
while True:
command = input()
if command == 'End':
break
(employer,id_worker) = command.split(' -> ')
if id_worker in company_dict.values(): # THIS
continue # PART
else:
if employer not in company_dict:
company_dict[employer] = []
company_dict[employer].append(id_worker)
And here is how I have managed to solve it, but it is extremely inefficient:
while True:
flag = 0
command = input()
if command == 'End':
break
(employer,id_worker) = command.split(' -> ')
for key,values in company_dict.items():
for i in values:
if id_worker == i and employer == key:
flag = 1
if flag == 1:
continue
else:
if employer not in company_dict:
company_dict[employer] = []
company_dict[employer].append(id_worker)
This will print 'True' if the key exists in the dictionary. It's basically the same as what you had and it should work fine, check to see if it prints 'True'
company_dict = dict()
while True:
command = input("employer -> worker_id")
if command.lower() == 'end':
break
employer, id_worker = command.split(' -> ')
if id_worker in company_dict.values():
print(True)
continue
else:
if not company_dict.get(employer, false):
company_dict[employer] = [worker_id]
You could break from the for loop if you find a match, and then use an else after the for loop to mean execute some code if the for loop reached the end without break.
while True:
command = input()
if command == 'End':
break
(employer,id_worker) = command.split(' -> ')
for key,values in company_dict.items():
if employer == key and id_worker in values:
break
else:
if employer not in company_dict:
company_dict[employer] = []
company_dict[employer].append(id_worker)
This will be more efficient than what you have, because you stop searching after the first match -- both due to the break from the explicit loop and the fact that the expression id_worker in values will stop iterating on the first match. (Here the use of in for inclusion testing also avoids using an explicit loop for the iteration over values, so may be a bit faster for that reason also.)

Understanding True/False evaluations in the context of Python dictionaries

I am working through the EdEx 6.00.2x course online and am struggling with one portion of my code:
newResistances = copy.deepcopy(self.resistances)
for drugs in self.resistances:
resistancePicker = random.random()
if self.resistances[drugs] == True:
if resistancePicker < self.mutProb:
print self.mutProb
newResistances[drugs] = False
elif self.resistances[drugs] == False:
if resistancePicker < self.mutProb:
print self.mutProb
newResistances[drugs] = True
print newResistances
return ResistantVirus(self.maxBirthProb, self.clearProb, newResistances, self.mutProb)
self.resistances is a dictionary containing drug name keys, and True or False values {'a':True,'b':True}. My problem is that only the first element of the dictionary seems to be evaluated and changed in the newResistances dictionary. Please let me know if this question is too vague/needs more context.
This is because your return is the wrong location. If you move it to line up with the for, you will see the code iterate through all keys.
I have also updated the code to remove constructs like if predicate==True since you could just do if predicate: instead.
Here's how the code should look:
for drugs in self.resistances:
resistancePicker = random.random()
if self.resistances[drugs]:
if resistancePicker < self.mutProb:
print self.mutProb
newResistances[drugs] = False
elif not self.resistances[drugs]: # or else:
if resistancePicker < self.mutProb:
print self.mutProb
newResistances[drugs] = True
print newResistances
return ResistantVirus(self.maxBirthProb, self.clearProb, newResistances, self.mutProb)

Python Nested If

hey im making a simple little grocery list on Python. I know it's not the most eloquent... but I am just learning the syntax right now. I want to get into learning Django.
list = []
def makeList():
listing = True
while listing:
addTo = raw_input("Add to list: ")
if addTo == 'q':
listing = False
else:
list.append(addTo)
def checkList():
if check in list:
print "Yay there is " + check + " here"
else:
print "No you have not added that..."
addAnother = raw_input("Would you like to add it? ")
if str.lower(addAnother) == "yes":
list.append(check)
elif str.lower(addAnother) == "no":
print "Okay then here is your list."
print list
else:
print check
makeList()
check = raw_input("What item: ")
checkList()
I know its pretty complex and hard to understand O_o... but you can see that the nested if statement is not registering when you run it.
What is making it do this? I think that's the best way to ask this.
I've rewritten it a bit to make it cleaner and more Pythonic;
def get_list(prompt, halt):
lst = []
while True:
item = raw_input(prompt)
if item == halt:
return lst
else:
lst.append(item)
def check_list(lst, item):
if item in lst:
print('Yay there is {} here'.format(item))
return True
else:
print('No you have not added {}'.format(item))
return False
def get_yesno(prompt):
while True:
yesno = raw_input(prompt).lower()
if yesno in {'y', 'yes'}:
return True
elif yesno in {'n', 'no'}:
return False
def main():
mylist = get_list('Add to list:', 'q')
check = raw_input('Look for item:')
if not check_list(mylist, check):
if get_yesno('Would you like to add it?'):
mylist.append(check)
print(mylist)
if __name__=="__main__":
main()
Some style tips:
Don't use list as a variable name; it's a built-in function, and you don't want to overwrite it.
Global variables are almost always a bad idea; passing data around explicitly makes it much easier to figure out where bad data is coming from, and makes functions more reusable.
camelCase is generally denigrated; use_underscores for function names instead.
You probably intended to keep going rather than break when you append the new item (or at least print something to indicate success), but the nested if statement works just fine, appends the thing to the list as specified and then the function and program terminate.

int() argument must be a string or a number

I got an error. I did quick googling and it did not help me well.
I added the whole code, well kind of whole code. request from a user.
from derp_node import *
##############################################################################
# parse
##############################################################################
def parse(tokens, i = 0):
"""parse: tuple(String) * int -> (Node, int)
From an infix stream of tokens, and the current index into the
token stream, construct and return the tree, as a collection of Nodes,
that represent the expression.
NOTE: YOU ARE NOT ALLOWED TO MUTATE 'tokens' (e.g. pop())!!! YOU
MUST USE 'i' TO GET THE CURRENT TOKEN OUT OF 'tokens'
"""
if tokens == []:
raise TypeError("Error: Empty List.")
elif tokens[int(i)] == '*':
tokens.remove(int(i))
return mkMultiplyNode(parse(tokens), parse(tokens))
elif tokens[int(i)] == '//':
tokens.remove(int(i))
return mkDivideNode(parse(tokens), parse(tokens))
elif tokens[int(i)] == '+':
tokens.remove(int(i))
return mkAddNode(parse(tokens), parse(tokens))
elif tokens[int(i)] == '-':
tokens.remove(int(i))
return mkSubtractNode(parse(tokens), parse(tokens))
elif tokens[int(i)].isdigit():
return mkLiteralNode(tokens.remove(int(i)))
elif not tokens[int(i)].isdigit():
return mkVariableNode(tokens.remove(int(i)))
else:
raise TypeError("Error: Invalid Input")
##############################################################################
# main
##############################################################################
def main():
"""main: None -> None
The main program prompts for the symbol table file, and a prefix
expression. It produces the infix expression, and the integer result of
evaluating the expression"""
print("Hello Herp, welcome to Derp v1.0 :)")
inFile = input("Herp, enter symbol table file: ")
symTbl = {}
for line in open(inFile):
i = line.split()
symTbl[i[0]] = int(i[1])
print("Derping the symbol table (variable name => integer value)...")
for variable in sorted(symTbl):
print(variable + " => " + str(symTbl[variable]))
# STUDENT: CONSTRUCT AND DISPLAY THE SYMBOL TABLE HERE
print("Herp, enter prefix expressions, e.g.: + 10 20 (RETURN to quit)...")
# input loop prompts for prefix expressions and produces infix version
# along with its evaluation
while True:
prefixExp = input("derp> ")
if prefixExp == "":
break
# STUDENT: GENERATE A LIST OF TOKENS FROM THE PREFIX EXPRESSION
prefixLst = prefixExp.split()
# STUDENT: CALL parse WITH THE LIST OF TOKENS AND SAVE THE ROOT OF
# THE PARSE TREE.
tokens = []
parseLst = parse(prefixLst, tokens)
# STUDENT: GENERATE THE INFIX EXPRESSION BY CALLING infix AND SAVING
# THE STRING
infixLst = infix(parseLst)
print("Derping the infix expression:")
# STUDENT: EVALUTE THE PARSE TREE BY CALLING evaluate AND SAVING THE
# INTEGER RESULT
print("Derping the evaluation:")
print("Goodbye Herp :(")
if __name__ == "__main__":
main()
The error I received is:
File "derpNew.py", line 31, in parse
if tokens[int(i)] == '*':
TypeError: int() argument must be a string or a number, not 'list'
If I remove the int() from the variable i, then I would get this error: TypeError: list indices must be integers, not list
Am I suppose to convert the list to tuple? Any help would be great. Thank you.
If you guys are curious how I am calling the parse. I put this under main function.
tokens = []
parseLst = parse(tokens, i)
EDIT:
The loop:
while True:
prefixExp = input("derp> ")
if prefixExp == "":
break
prefixLst = prefixExp.split()
tokens = []
parseLst = parse(tokens, i)
parseLst = parse(tokens, i) - this line doesn't make sense unless you define i. If you want to pass default i=0, then just leave it out: parseLst = parse(tokens).
EDIT: After the whole code has been pasted, there is some (apparently irrelevant) i defined before, which is why there was no NameError.
The passed variable i is a list, that's why the errors! Would need more info on the arguments being passed to help you more!
List indices work like this
>>> my_list = [1, 2, 3, 4, 5]
>>> for index in range(5):
... print my_list[i]
1
2
3
4
5
>>> my_list[3]
4
What are you passing to the method parse(...) as second parameter? If it's a list, it shouldn't. You may want to change the value you are passing to parse.
You may also want to check if tokens is an empty list, before the other ifs, or it will cause another error.
if tokens == []:
raise TypeError("Error: Empty List.")
elif tokens[int(i)] == '*':
tokens.remove(int(i))
return mkMultiplyNode(parse(tokens), parse(tokens))
return mkSubtractNode(parse(tokens), parse(tokens))
elif tokens[int(i)].isdigit():
return mkLiteralNode(tokens.remove(int(i)))
elif not tokens[int(i)].isdigit():
return mkVariableNode(tokens.remove(int(i)))
else:
raise TypeError("Error: Invalid Input")

Categories