I have 5 columns ( NO = index of vehicle / LEADER = index of the vehicle of the front / SEC = instant in seconds / X = position of the vehicle)
Some vehicles stop ( X stay the same for a while) and I want to get the exact time it starts to move again. Then, calculate the difference between their instant and their respective 'leader' vehicle.
I made a code but it has so many bugs
OBS: Some vehicles never stop or stop,but never return to move. I want to remove them too.
Here's my code:
dados = pd.read_excel('teste-reaction_001.xlsx')
n=dados["NO"].unique()
final=np.zeros(1)
for i in n:
botao = 0
array_aux=dados[dados["NO"] == i ]["X"]
df = pd.DataFrame(array_aux)
aux=df.diff().to_numpy()
count1 = 0
aux1 = []
for j in aux:
if j == 0:
botao = 1
elif j != 0 and botao == 1:
aux1=np.where(aux==j)[0]
aux1=aux1[np.where(aux1>=count1)[0]]
break
else :
botao = 0
count1 = count1 + 1
aux2=dados["SEC"][dados[dados["NO"]==i]["SEC"].index[aux1]].values[0]
final=np.append(final,aux2)
tr=np.zeros(1)
for i in n:
aux=dados[dados["NO"] == i ]["LEADER"].unique()[0]
aux1=np.where(dados["NO"].unique()==i)[0]
aux2=np.where(dados["NO"].unique()==aux)[0]
if aux2>-1:
aux3=final[int(aux1)]-final[aux2]
else:
aux3 = "s"
tr=np.append(tr,aux3)
columns = ["N", "TR"]
tabela = np.array([dados["NO"].unique(), tr[1:]])
res = pd.DataFrame(data=tabela.T,index=np.arange(len(tabela.T)), columns=columns)
After testing pokers hands x amount of times, I need to print a table with the title of the hand (full house, flush, etc.), the number of times each of them occurred, the percentage of times they occurred, expected percentage, and difference between the two. It won't let me run it with more than 2 iterations.
Here is what I have:
def is_pair(hand):
Yes = 0
for card in hand:
count = 0
for i in hand:
if (card['value']) == (i['value']):
count += 1
if count == 2:
Yes = 1
if Yes == 0:
return False
else:
if is_full_house(hand) is True:
return False
elif is_2_pair(hand) is True:
return False
elif is_3_of_a_kind(hand) is True:
return False
elif is_4_of_a_kind(hand) is True:
return False
else:
return True
def is_2_pair(hand):
Yes = 0
for card in hand:
count = 0
for i in hand:
if card['value'] == i['value']:
count += 1
if count == 2:
Yes += 1
if Yes == 4:
if is_4_of_a_kind(hand) is True:
return False
elif is_full_house(hand) is True:
return False
else:
return True
else:
return False
def is_3_of_a_kind(hand):
Yes = 0
for card in hand:
count = 0
for i in hand:
if card['value'] == i['value']:
count += 1
if count == 3:
Yes = 1
if Yes == 0:
return False
else:
if is_full_house(hand) is True:
return False
else:
return True
def is_4_of_a_kind(hand):
Yes = 0
for card in hand:
count = 0
for i in hand:
if card['value'] == i['value']:
count += 1
if count == 4:
Yes = 1
if Yes == 0:
return False
else:
return True
def is_full_house(hand):
Yes = 0
if is_3_of_a_kind(hand) is True:
Yes += 1
else:
return False
if is_pair(hand) is True:
Yes += 1
else:
return False
if Yes == 2:
return True
else:
return False
def is_flush(hand):
Yes = 0
for card in hand:
count = 0
for i in hand:
if card['suit'] == i['suit']:
count += 1
if count == 5:
Yes = 1
if Yes == 0:
return False
else:
return True
def is_straight(hand):
list = []
for card in hand:
list.append(card['value'])
list.sort()
if is_pair(hand) is True:
return False
elif is_2_pair(hand) is True:
return False
elif is_3_of_a_kind(hand) is True:
return False
elif is_4_of_a_kind(hand) is True:
return False
elif is_full_house(hand) is True:
return False
elif list[4] - list [0] == 4:
return True
else:
return False
def is_high_card(hand):
if (is_pair(hand) is False) and (is_2_pair(hand) is False) and (is_3_of_a_kind(hand) is False) and (is_4_of_a_kind(hand) is False) and (is_flush(hand) is False) and (is_full_house(hand) is False) and (is_straight(hand) is False) and (is_straight_flush(hand) is False):
return True
else:
return False
def is_straight_flush(hand):
if (is_straight(hand) is True) and (is_flush(hand) is True):
return True
else:
return False
def main():
deck = build_deck()
shuffle(deck)
hand = deck[:5]
return hand
def tests():
hand = main()
if is_straight_flush(hand) is True:
return('Straight flush')
elif is_4_of_a_kind(hand) is True:
return('Four of a kind')
elif is_full_house(hand) is True:
return('Full house')
elif is_flush(hand) is True:
return('Flush')
elif is_straight(hand) is True:
return('Straight')
elif is_3_of_a_kind(hand) is True:
return('Three of a kind')
elif is_2_pair(hand) is True:
return('Two pairs')
elif is_pair(hand) is True:
return('One pair')
elif is_high_card(hand) is True:
return('High card')
def main2():
iterations = int(input("How many hands would you like to test? "))
hands = ['Straight flush', 'Four of a kind', 'Full house', 'Flush', 'Straight', 'Three of a kind', 'Two pair', 'One pair', 'High card']
sf_expected = round(40/2598960*100, 4)
fok_expected = round(624/2598960*100, 4)
fh_expected = round(3744/2598960*100, 4)
f_expected = round(5108/2598960*100, 4)
s_expected = round(10200/2598960*100, 4)
tok_expected = round(54912/2598960*100, 4)
tp_expected = round(123552/2598960*100, 4)
op_expected = round(1098240/2598960*100, 4)
hc_expected = round(1302540/2598960*100, 4)
sf_freq = 0
fok_freq = 0
fh_freq = 0
f_freq = 0
s_freq = 0
tok_freq = 0
tp_freq = 0
op_freq = 0
hc_freq = 0
for i in range(iterations):
tests()
if (tests() == 'Straight flush'):
sf_freq += 1
if (tests() == 'Four of a kind'):
fok_freq += 1
if (tests() == 'Full house'):
fh_freq += 1
if (tests() == 'Flush'):
f_freq += 1
if (tests() == 'Straight'):
s_freq += 1
if (tests() == 'Three of a kind'):
tok_freq += 1
if (tests() == 'Two pair'):
tp_freq += 1
if (tests() == 'One pair'):
op_freq += 1
if (tests() == 'High card'):
hc_freq += 1
occurences = [sf_freq, fok_freq, fh_freq, f_freq, s_freq, tok_freq, tp_freq, op_freq, hc_freq]
expected = [sf_expected, fok_expected, fh_expected, f_expected, s_expected, tok_expected, tp_expected, op_expected, hc_expected]
percent = [sf_freq/iterations * 100, fok_freq/iterations * 100, fh_freq/iterations * 100, f_freq/iterations * 100, s_freq/iterations * 100, tok_freq/iterations * 100, tp_freq/iterations * 100, op_freq/iterations * 100, hc_freq/iterations * 100]
difference = [sf_freq/iterations * 100 - sf_expected, fok_freq/iterations * 100 - fok_expected, fh_freq/iterations * 100 - fh_expected, f_freq/iterations * 100 - f_expected, s_freq/iterations * 100 - s_expected, tok_freq/iterations * 100 - tok_expected, tp_freq/iterations * 100 - tp_expected, op_freq/iterations * 100 - op_expected, hc_freq/iterations * 100 - hc_expected]
print("{:<15} {:<15} {:<15} {:<15} {:>15}".format('Hand', 'Occurences','Percent', 'Expected', 'Difference'))
all = [['Straight flush', sf_freq, sf_freq/iterations * 100, sf_expected, sf_freq/iterations * 100 - sf_expected],
['Four of a kind', fok_freq, fok_freq/iterations * 100, fok_expected, fok_freq/iterations * 100 - fok_expected],
['Full house', fh_freq, fh_freq/iterations * 100, fh_expected, fh_freq/iterations * 100 - fh_expected],
['Flush', f_freq, f_freq/iterations * 100, f_expected, f_freq/iterations * 100 - f_expected],
['Straight', s_freq, s_freq/iterations * 100, s_expected, s_freq/iterations * 100 - s_expected],
['Three of a kind', tok_freq, tok_freq/iterations * 100, tok_expected, tok_freq/iterations * 100 - tok_expected],
['Two pair', tp_freq, tp_freq/iterations * 100, tp_expected, tp_freq/iterations * 100 - tp_expected],
['One pair', op_freq, op_freq/iterations * 100, op_expected, op_freq/iterations * 100 - op_expected],
['High card', hc_freq, hc_freq/iterations * 100, hc_expected, hc_freq/iterations * 100 - hc_expected]]
for list in all:
hands, occurences, percent, expected, difference = list
print("{:<15} {:<15} {:<15} {:<15} {:>15}".format(hands, occurences, percent, expected, difference))
main2()
It's a little unclear why you aren't getting any output, which seems to be the implication of your question. Is your code raising an exception?
It looks to me like the problem is with results. This appears to be a standard Python list (containing a collection of integers). Calling something like results/iterations would normally result in something like TypeError: unsupported operand type(s) for /: 'list' and 'int'.
Lists are not intended to support operations that apply to all their elements, but it's also unclear that's what you intended to achieve with this. Your format string specifies that results/iterations * 100 should be rendered in a space 10 characters wide and centered.
I believe you perhaps wanted to iterate through the individual values of hands, results, and expected, producing a set of rows to form a table. In that case I propose the following in place of your second print statement:
for hand, freq, expectation in zip(hands, results, expected):
percent = 100 * freq / iterations
print(f"{hand:^10}{freq:^10}{percent:^10}{expectation:^10}{percent-expectation:^10}")
I have used the somewhat friendlier f-string formatting, but if you have python <3.6 feel free to revert.
In general, the pandas data analysis library is a good fit for this kind of problem, since you can simply put your data in a pandas DataFrame and print it. However I appreciate that you may want to do this in base Python.
While I'm at it, I fear you have another error. You haven't told us what tests() does, but it looks like instead of calling it once per iteration and processing the result you call it many times.
Let me help you tidy your code and make it more maintainable, fixing this issue in the process.
hands = ['Straight flush', 'Four of a kind', 'Full house', 'Flush', 'Straight', 'Three of a kind', 'Two pair', 'One pair', 'High card']
results = {hand: 0 for hand in hands}
denom = 2598960 / 100
expected = [int(40/denom), int(624/denom), int(3744/denom), int(5108/2598960*100), int(10200/denom), int(54912/denom), int(123552/denom), int(1098240/denom), int(1302540/denom)]
for i in range(iterations):
hand = tests()
results[hand] += 1
By using a dictionary to store the results and using the hand name as the key to look up the result for that hand we improve the code.
You would then use results.values() to retrieve the list of results you had before.
I have also put your repeated code into a variable. If you ever had to change it, you now only have to change it in one place, making mistakes much less likely.
I have two codes which should perform the same thing but in the first, I am not getting the result but in the second one I am getting output
if (Method == "EMM" ):
if ((Loan_Obligation/12)+EMI) !=0:
DSCR_Post = EBITDA_EMM/((Loan_Obligation/12)+EMI)
else:
0
elif (Method != "EMM" ):
if ((Loan_Obligation/12)+EMI) !=0:
DSCR_Post = EBITDA/((Loan_Obligation/12)+EMI)
else:
0
and other one is:
if (Method == "EMM"):
DSCR_Post = EBITDA_EMM/((Loan_Obligation/12)+EMI) if ((Loan_Obligation/12)+EMI) !=0 else 0
else:
DSCR_Post = EBITDA/((Loan_Obligation/12)+EMI) if ((Loan_Obligation/12)+EMI) !=0 else 0
print('DSCR_Post:',DSCR_Post)
Can someone help me what is the difference between the two codes
In your first code snippet, you are not assigning the 0 to DSCR_Post as you do in the second. Modify as follows:
if Method == "EMM" :
if (Loan_Obligation / 12) + EMI !=0:
DSCR_Post = EBITDA_EMM / ((Loan_Obligation / 12) + EMI)
else:
DSCR_Post = 0 # the 0 has to be assigned!
else: # you do not need a condition here! It can either be equal or not, no third state possible.
if (Loan_Obligation / 12) + EMI !=0:
DSCR_Post = EBITDA / ((Loan_Obligation / 12) + EMI)
else:
DSCR_Post = 0
print('DSCR_Post:',DSCR_Post)
Which can be simplified to the following:
ebid = EBITDA_EMM if Method == "EMM" else EBITDA
DSCR_Post = 0 # 0 will be overwritten if ...
if (Loan_Obligation / 12) + EMI != 0:
DSCR_Post = ebid / ((Loan_Obligation / 12) + EMI)
print('DSCR_Post:',DSCR_Post)
At the moment, I managed to code, successfully, a simulation for a work that I need to do. However, I'm fairly new to python. And so, I'm now in the process of making the simulation more efficient.
For instance:
if random.random() < mm:
z = numpy.random.choice(pat)
if random.random() < 0.5:
if random.random() < mut:
if maleadult[z][0] == 0:
malejuv[y][x][0] = 1
elif maleadult[z][0] == 1:
malejuv[y][x][0] = 0
else:
malejuv[y][x][0] = maleadult[z][0]
else:
if random.random() < mut:
if femaleadult[z][0] == 0:
malejuv[y][x][0] = 1
elif femaleadult[z][0] == 1:
malejuv[y][x][0] = 0
else:
malejuv[y][x][0] = femaleadult[z][0]
if random.random() < 0.5:
if random.random() < mut:
if maleadult[z][1] == 0:
malejuv[y][x][1] = 1
elif maleadult[z][1] == 1:
malejuv[y][x][1] = 0
else:
malejuv[y][x][1] = maleadult[z][1]
else:
if random.random() < mut:
if femaleadult[z][1] == 0:
malejuv[y][x][1] = 1
elif femaleadult[z][1] == 1:
malejuv[y][x][1] = 0
else:
malejuv[y][x][1] = femaleadult[z][0]
where:
mm - male dispersal,
mf - female dispersal,
mut - mutations,
pat - patch,
maleadult - adult male,
femaleadult - adult female,
malejuv - juvenile male,
femalejuv - juvenile female.
As you can see, the code is big. And this is only for males and when they disperse. The rest of the code is very similar. These are standard genetic and demographic processes - but I feel like this can be improved. I feel like these processes are simple enough, so maybe code as big as this is not necessary.
Does anyone have any ideas to shorten this and, by consequence, making it more efficient?
Your example does not have any loops but it looks like it could be simplified by one:
if random.random() < mm:
z = numpy.random.choice(pat)
for i in range(2):
if random.random() < 0.5:
if random.random() < mut:
if maleadult[z][i] == 0:
malejuv[y][x][i] = 1
elif maleadult[z][i] == 1:
malejuv[y][x][i] = 0
else:
malejuv[y][x][i] = maleadult[z][i]
else:
if random.random() < mut:
if femaleadult[z][i] == 0:
malejuv[y][x][i] = 1
elif femaleadult[z][i] == 1:
malejuv[y][x][i] = 0
else:
malejuv[y][x][i] = femaleadult[z][i]
It is also possible to pass a mutable object as reference to a function which can modify it, which allows further reduction of almost redundant code. I've added some data to test it:
#!python3
#coding=utf-8
import random
maleadult = [[["male adult"], ["another male adult"], ]]
femaleadult = [[["female adult"], ["another female adult"], ]]
malejuv = [[[["male juv"],["another male juv"]]]]
mut = 0.5
mm = 1.0
x = 0
y = 0
z = 0
def some_logic(a, j):
""" does something """
if random.random() < mut:
if a[z][i] == 0:
j[y][x][i] = 1
elif a[z][i] == 1:
j[y][x][i] = 0
# added!
else:
j[y][x][i] = 0
else:
j[y][x][i] = a[z][i]
if random.random() < mm:
z = 0 #numpy.random.choice(pat)
for i in range(2):
print(i)
if random.random() < 0.5:
some_logic(maleadult, malejuv)
else:
some_logic(femaleadult, malejuv)
print(maleadult)
print(malejuv)
print(femaleadult)
I am asked to binary search a list of names and if these names start with a particular letter, for example A, then I am to print that name.
I can complete this task by doing much more simple code such as
for i in list:
if i[0] == "A":
print(i)
but instead I am asked to use a binary search and I'm struggling to understand the process behind it. We are given base code which can output the position a given string. My problem is not knowing what to edit so that I can achieve the desired outcome
name_list = ["Adolphus of Helborne", "Aldric Foxe", "Amanita Maleficant", "Aphra the Vicious", "Arachne the Gruesome", "Astarte Hellebore", "Brutus the Gruesome", "Cain of Avernus"]
def bin_search(list, item):
low_b = 0
up_b = len(list) - 1
found = False
while low_b <= up_b and found == False:
midPos = ((low_b + up_b) // 2)
if list[midPos] < item:
low_b = midPos + 1
elif list[midPos] > item:
up_b = midPos - 1
else:
found = True
if found:
print("The name is at positon " + str(midPos))
return midPos
else:
print("The name was not in the list.")
Desired outcome
bin_search(name_list,"A")
Prints all the names starting with A (Adolphus of HelBorne, Aldric Foxe .... etc)
EDIT:
I was just doing some guess and check and found out how to do it. This is the solution code
def bin_search(list, item):
low_b = 0
up_b = len(list) - 1
true_list = []
count = 100
while low_b <= up_b and count > 0:
midPos = ((low_b + up_b) // 2)
if list[midPos][0] == item:
true_list.append(list[midPos])
list.remove(list[midPos])
count -= 1
elif list[midPos] < item:
low_b = midPos + 1
count -= 1
else:
up_b = midPos - 1
count -= 1
print(true_list)
Not too sure if this is what you want as it seems inefficient... as you mention it seems a lot more intuitive to just iterate over the entire list but using binary search i found here i have:
def binary_search(seq, t):
min = 0
max = len(seq) - 1
while True:
if max < min:
return -1
m = (min + max) // 2
if seq[m][0] < t:
min = m + 1
elif seq[m][0] > t:
max = m - 1
else:
return m
index=0
while True:
index=binary_search(name_list,"A")
if index!=-1:
print(name_list[index])
else:
break
del name_list[index]
Output i get:
Aphra the Vicious
Arachne the Gruesome
Amanita Maleficant
Astarte Hellebore
Aldric Foxe
Adolphus of Helborne
You just need to found one item starting with the letter, then you need to identify the range. This approach should be fast and memory efficient.
def binary_search(list,item):
low_b = 0
up_b = len(list) - 1
found = False
midPos = ((low_b + up_b) // 2)
if list[low_b][0]==item:
midPos=low_b
found=True
elif list[up_b][0]==item:
midPos = up_b
found=True
while True:
if found:
break;
if list[low_b][0]>item:
break
if list[up_b][0]<item:
break
if up_b<low_b:
break;
midPos = ((low_b + up_b) // 2)
if list[midPos][0] < item:
low_b = midPos + 1
elif list[midPos] > item:
up_b = midPos - 1
else:
found = True
break
if found:
while True:
if midPos>0:
if list[midPos][0]==item:
midPos=midPos-1
continue
break;
while True:
if midPos<len(list):
if list[midPos][0]==item:
print list[midPos]
midPos=midPos+1
continue
break
else:
print("The name was not in the list.")
the output is
>>> binary_search(name_list,"A")
Adolphus of Helborne
Aldric Foxe
Amanita Maleficant
Aphra the Vicious
Arachne the Gruesome
Astarte Hellebore