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)
Related
I've got an auto completion function that listen on key. There is an edge case in which the given list to complete from is way too long. So I want to limit the output of possible options and ask the user whether he wants to see the whole amount of possibilities.
Let's say I have this completion function and my_list has about 4000 items.
import readline
my_list = [...]
def completer(text, state):
options = [x for x in my_list if x.startswith(text)]
if state < len(options):
return options[state]
else:
return None
readline.parse_and_bind("tab: complete")
readline.set_completer(completer)
while True:
ans = input("Please select one from the list above: ")
if ans == 'exit':
break
print(ans)
I tried to put the condition inside of def completer() like
def completer(text, state):
options = [x for x in my_list if x.startswith(text)]
if state < len(options):
if len(options) > 50:
question = input(f"Do you want to see all {len(options)} possibilities? ")
if question.lower(0) == "y":
return options[state]
else:
return None
else:
return options[state]
else:
return None
Unfortunately this doesn't work, because there is no way calling the input() function inside the input() function. Do you guys got an idea how to implement this?
My code for binary search function in a list returns true for a value in the list, but returns None (instead of false) for values not in the list.
Can someone please explain me what I'm doing wrong?
The program is:
def searchlist(x,alist):
end=int(len(alist)-1)
mid=int(len(alist)/2)
while len(alist)>2:
if x==alist[mid] or x==alist[0] or x==alist[end] :
return("true")
break
elif x>alist[mid]:
alist=alist[mid:]
mid=int(len(alist)/2)
end=int(len(alist)-1)
elif x<alist[mid]:
alist=alist[:mid]
mid=int(len(alist)/2)
end=int(len(alist)-1)
else:
return("false")
aList=[2,3,5,7,9,12,14,23,34,45,67,89,101]
xnum=int(input("enter a number:"))
searchlist(xnum,aList)
print(searchlist(xnum,aList))
You get None when your function does not return a value. This happens because the while loop terminates without going into the "else" branch.
A better practice would be to return True (not the string, but the Boolean value) when you find the value in the list, and return False after the loop.
Your while loop cannot catch the else statement. you don't need that else. try this :
def searchlist(x,alist):
end=int(len(alist)-1)
mid=int(len(alist)/2)
result = False
while len(alist)>2:
if x==alist[mid] or x==alist[0] or x==alist[end] :
result = True
elif x>alist[mid]:
alist=alist[mid:]
mid=int(len(alist)/2)
end=int(len(alist)-1)
elif x<alist[mid]:
alist=alist[:mid]
mid=int(len(alist)/2)
end=int(len(alist)-1)
return result
aList=[2,3,5,7,5,67,89,101]
xnum=int(input("enter a number:"))
print(searchlist(xnum,aList))
I have function AB which has 1 parameter, and AB has a bunch of loops and I have a counter which keeps track of how much it loops. It (must) returns an either True or False answer.
I have a second function called AC which calls upon 2 instances of AB with different things for the parameters and compares them like so
if (AB(option1) == True and AB(option2) == False):
result = "Option1 Wins"
elif (AB(option1) == False and AB(option2) == True):
result = "Option2 Wins"
if (AB(option1) == True and AB(option2) == True):
result = ??
however if both cases are 'True', I need to know which case reached 'True' first, so this means I would need to know how many times it loops (i need to know the value of the counter variable)
How can I access the variable?
I was thinking of making a helper function to access it but I'm not sure if that's possible/how to do that
You can return more than one value from a function in python:
def AB(param):
return True, 1
val = AB(1) # it will be (True,1), so it's a set
val, val1 = AB(2) # val = True, val1 = 1
So in your code you should check AB(param)[0] to check True, if you want to keep only one return value (you should get them in different variables).
But your code is wrong, since you are calling AB() each time you are checking the output, which will execute all the loops and, eventually, could bring an unexpected response for the same input. You should get the output from AB() for each param before, and then check them in your if block.
Zero evaluates to False and non-zero evaluates to True:
If AB fails it returns 0 otherwise it returns the amount of loops:
def AB(param):
if failed:
return 0
else:
return counter
Usage:
if AB(option1) and not AB(option2):
result = "Option1 Wins"
elif not AB(option1) and AB(option2):
result = "Option2 Wins"
elif AB(option1) < AB(option2):
result = "Option1 Wins"
else:
result = "Option2 Wins"
OOP solution: Create a class with this methods as member function and the counter variable as a member variable. Now you can check that value from anywhere for any object of that class.
Also in your code, no need to invoke AB multiple times.
o1 = AB(option1)
o2 = AB(option2)
if o1 and not o2:
result = "Option1 Wins"
elif not o1 and o2):
result = "Option2 Wins"
elif o1 and o2:
result = ??
An object oriented solution might look like following (code not tested)
class solver(object, option):
reached = 0
option = option
status = False
def AB(self):
# implementation. use self.option and update self.reached and self.status
opt1 = solver(option1)
opt2 = solver(option2)
o1 = opt1.AB()
o2 = opt2.AB()
if o1.status and not o2.status:
result = "Option1 Wins"
elif not o1.status and o2.status):
result = "Option2 Wins"
elif o1 and o2:
if o1.reached < o2.reached:
# o1 reached first
You can use global variables to store values of the counters. See http://www.diveintopython.net/html_processing/locals_and_globals.html for more details.
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
OK, so I've been trying this for about 2 hours now and I can't seem to figure it out. I think I tried almost every possible algorithm combination and it still isn't working. Here it goes:
I'm trying to validate keyboard input in Python based on two condition (ordered by priority):
Check if input is integer
Check if input is vertex (class method for checking if the number given can be found as a key in a dictionary)
Here's the code:
def checkVertex(self, x):
ok = 0
for key in self.__inv:
if key == x:
ok += 1
break
for key in self.__outv:
if key == x:
ok += 1
break
if ok == 2:
return True
return False
def checkInt(number):
if number.isdigit() is False:
return False
return True
def readVertex(msg, graf): <-- this is the issue
"""
msg - string message
graf - Graph() class instance initialised somewhere
invalid_input - string error message
"""
vertex = raw_input(msg)
while checkInt(vertex) is False:
print invalid_input
vertex = raw_input(msg)
if checkInt(vertex) is True:
vertex = int(vertex)
if graf.checkVertex(vertex) is True: <-- this bloody line is not working right
return vertex
else:
continue
return int(vertex)
source = readVertex("Give source vertex (by number): ", G)
dest = readVertex("Give destination vertex (by number): ", G)
cost = int(raw_input("Give cost: "))
print G.addEdge(source, dest, cost)
The problem that I'm getting is that the first condition works, so if I input a letter it will print an error, but if I input a number and that number isn't in the keys of the dictionary it will still return it.
So graf.checkVertex(vertex) always returns True in the above code even though I know for a fact that it works because I've tried the function with the same input in the shell and it returned False.
Let me give you an example, let's say I have this dict:
{0: [], 1: [], 2: [], 3: [], 4: []}
Screen recording of example:
Your validation only runs while checkInt(vertex) is False: - if it is a valid integer the first time, you never check the rest. It's not that graf.checkVertex(vertex) doesn't work; it's never called. Instead, try:
def readVertex(msg, graf, invalid_input):
"""
msg - string message
graf - Graph() class instance initialised somewhere
invalid_input - string error message
"""
while True:
vertex = raw_input(msg)
if checkInt(vertex) and graf.checkVertex(int(vertex)):
return int(vertex)
print invalid_input
or
def readVertex(msg, graf, invalid_input):
"""
msg - string message
graf - Graph() class instance initialised somewhere
invalid_input - string error message
"""
while True:
try:
vertex = int(raw_input(msg))
except ValueError:
print invalid_input
else:
if graf.checkVertex(vertex):
return vertex
print invalid_input