Calculate bacteria number program in python - python-3.x

Bacteria B replicates itself each 2 minutes, write a program that asks users to enter two numbers: the initial B bacteria number and a period of time (in minutes). Calculate and print out the total number of B bacteria after this period.
How to do. I did like below but the result is wrong. Because bateria replicates itself each 2 minutes then I multiply it with time.
b = int(input('How many B Bacterias are there? '))
t = int(input('How much time will we waits (minutes)? '))
r = b * 2 * t
print ('After',t,'minutes(s) we would have',r,'B Bacterias')
See the image here

You have b bacterias at the t time like this:
t b
0 b
1 b
2 b * 2
3 b * 2
4 b * 4
5 b * 4
6 b * 8
7 b * 8
8 b * 16
and so on.
So your formula is r = b * 2 ** math.floor(t/2) and the code will be:
import math
b = int(input('How many B Bacterias are there? '))
t = int(input('How much time will we waits (minutes)? '))
r = b * 2 ** math.floor(t/2)
print ('After',t,'minutes(s) we would have',r,'B Bacterias')

Your function to calculate the number of bacteria is wrong, this is a textbook example of an exponential function.
should be r = b * 2 ** (t/2)
You need to take the time t and divide it by the division time of 2 minutes to get the number of divisions that occurred.
By raising 2 to this number you get the total offspring of one bacterial cell and this multiplied by the initial number of bacteria is your answer

Related

Is there a way to sort a list so that rows with the same value in one column are evenly distributed?

Hoping to sort (below left) by sector but distribute evenly (below right):
Name
Sector.
Name.
Sector
A
1
A
1
B
1
E
2
C
1
H
3
D
4
D
4
E
2
B
1
F
2
F
2
G
2
J
3
H
3
I
4
I
4
C
1
J
3
G
2
Real data is 70+ rows with 4 sectors.
I've worked around it manually but would love to figure out how to do it with a formula in excel.
Here's a more complete (and hopefully more accurate) idea - the carouselOrder is the column I'd like to generate via a formula.
guestID
guestSector
carouselOrder
1
1
1
2
1
5
3
1
9
4
1
13
5
2
2
6
2
6
7
2
10
8
2
14
9
3
3
10
3
7
11
3
11
12
2
18
13
1
17
14
1
20
15
1
23
16
2
21
17
2
24
18
2
27
19
1
26
20
1
29
21
1
30
22
1
31
23
3
15
24
3
19
25
3
22
26
3
25
27
3
28
28
1
32
29
4
4
30
4
8
31
4
12
32
4
16
When using Office 365 you can use the following in D2: =MOD(SEQUENCE(COUNTA(A2:A11),,0),4)+1
This create the repetitive counter of the sectors 1 to 4 to the total count of rows in your data.
In C2 use the following:
=BYROW(D2#,LAMBDA(x,
INDEX(
FILTER($A$2:$A$11,$B$2:$B$11=x),
SUM(--(D$2:x=x)))))
This filters the Names that equal the sector of mentioned row and indexes it to show only the result where the row in the filter result equals the count of the same sector (D2#) up to current row.
Let's try the following approach that doesn't require to create a helper column. I would like to explain first the logic to build the recurrence, then the excel formula that builds such recurrence.
If we sort the input data Name and Sector. by Sector. in ascending order, the new positions of the Name values (letters) can be calculated as follow (Table 1):
Name
Sector.Sorted
Position
A
1
1+4*0=1
B
1
1+4*1=5
C
1
1+4*2=9
E
2
2+4*0=2
F
2
2+4*1=6
G
2
2*4*2=10
H
3
3+4*0=3
J
3
3+4*1=7
D
4
4+4*0=4
I
4
4+4*1=8
The new positions of Name (letters) follows this pattern (Formula 1):
position = Sector.Sorted + groupSize * factor
where groupSize is 4 in our case and factor counts how many times the same Sector.Sorted value is repeated, starting from 0. Think about Sector.Sorted as groups, where each set of repeated values represents a group: 1,2,3 and 4.
If we are able to build the Position values we can sort Name, based on the new positions via SORTBY(array, by_array1) function. Check SORTBY documentation for more information how this function works.
Here is the formula to get the Name sorted in cell E2:
=LET(groupSize, 4, sorted, SORT(A2:B11,2), sName,
INDEX(sorted,,1),sSector, INDEX(sorted,,2),
seq0, SEQUENCE(ROWS(sSector),,0), mapResult,
MAP(sSector, seq0, LAMBDA(a,b, IF(b=0, "SAME",
IF(a=INDEX(sSector,b), "SAME", "NEW")))), factor,
SCAN(-1,mapResult, LAMBDA(aa,c,IF(c="SAME", aa+1,0))),
pos,MAP(sSector, factor, LAMBDA(m,n, m + groupSize*n)),
SORTBY(sName,pos)
)
Here is the output:
Explanation
The name sorted represents the input data sorted by Sector. in ascending order, i.e.: SORT(A2:B11,2). The names sName and sSector represent each column of sorted.
To identify each group we need the following sequence (seq0) starting from 0, i.e. SEQUENCE(ROWS(sSector),,0).
Now we need to identify when a new group starts. We use MAP function for that and the result is represented by the name mapResult:
MAP(sSector, seq0, LAMBDA(a,b, IF(b=0, "SAME",
IF(a=INDEX(sSector,b), "SAME", "NEW"))))
The logic is the following: If we are at the beginning of the sequence (first value of seq0), then returns SAME otherwise we check current value of sSector (a) against the previous one represented by INDEX(sSector,b) if they are the same, then we are in the same group, otherwise a new group started.
The intermediate result of mapResult is:
Name
Sector Sorted
mapResult
A
1
SAME
B
1
SAME
C
1
SAME
E
2
NEW
F
2
SAME
G
2
SAME
H
3
NEW
J
3
SAME
D
4
NEW
I
4
SAME
The first two columns are shown just for illustrative purpose, but mapResult only returns the last column.
Now we just need to create the counter based on every time we find NEW. In order to do that we use SCAN function and the result is stored under the name factor. This value represents the factor we use to multiply by 4 within each group (see Table 1):
SCAN(-1,mapResult, LAMBDA(aa,c,IF(c="SAME", aa+1,0)))
The accumulator starts in -1, because the counter starts with 0. Every time we find SAME, it increments by 1 the previous value. When it finds NEW (not equal to SAME), the accumulator is reset to 0.
Here is the intermediate result of factor:
Name
Sector Sorted
mapResult
factor
A
1
SAME
0
B
1
SAME
1
C
1
SAME
2
E
2
NEW
0
F
2
SAME
1
G
2
SAME
2
H
3
NEW
0
J
3
SAME
1
D
4
NEW
0
I
4
SAME
1
The first three columns are shown for illustrative purpose.
Now we have all the elements to build our pattern for the new positions represented with the name pos:
MAP(sSector, factor, LAMBDA(m,n, m + groupSize*n))
where m represents each element of Sector.Sorted and factor the previous calculated values. As you can see the formula in Excel represents the generic formula (Formula 1 see above). The intermediate result will be:
Name
Sector Sorted
mapResult
factor
pos
A
1
SAME
0
1
B
1
SAME
1
5
C
1
SAME
2
9
E
2
NEW
0
2
F
2
SAME
1
6
G
2
SAME
2
10
H
3
NEW
0
3
J
3
SAME
1
7
D
4
NEW
0
4
I
4
SAME
1
8
The previous columns are shown just for illustrative purpose. Now we have the new positions, so we are ready to sort based on the new positions for Name via:
SORTBY(sName,pos)
Update
The first MAP can be removed creating an array as input for SCAN that has the information of sSector and the index position to be used for finding the previous element. SCAN only allows a single array as input argument, so we can combine both information in a new array. This is the formula can be used instead:
=LET(groupSize, 4, sorted, SORT(A2:B11,2), sName,
INDEX(sorted,,1),sSector, INDEX(sorted,,2),
factor, SCAN(-1,sSector&"-"&SEQUENCE(ROWS(sSector),,0),
LAMBDA(aa,b, LET(s, TEXTSPLIT(b,"-"),item, INDEX(s,,1),
idx, INDEX(s,,2), IF(aa=-1, 0, IF(1*item=INDEX(sSector, idx), aa+1,0))))),
pos,MAP(sSector, factor, LAMBDA(m,n, m + groupSize*n)),
SORTBY(sName,pos)
)
We use inside of SCAN a LET function to calculate all required elements for doing the comparison as part of the calculation of the corresponding LAMBDA function. We extract the item and the idx position used to find previous element of sSector via:
1*item=INDEX(sSector, idx)
we are able to compare each element of sSector with previous one, starting from the second element of sSector. We multiply item by 1, because TEXTSPLIT converts the result to text, otherwise the comparison will fail.

Fibonacci numbers program

Im trying to write a program that displays the FIBONACCI NUMBERS, however, the numbers don't print out correctly and are always one number too high for what the Fibonacci number is meant to be, can anyone understand why?
This is the code i have:
a, b = 0, 1
while b < 1000:
print(b, '', end='')
a, b = b, a + b
(have to use those 4 lines of code)
And this is the output I get
1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
and this is the output im looking for
0
1
2
4
7
12
20
33
54
the program should also start at 0 not 1
Try printing a instead of b. a and b are the first two terms of the sequence, so if you want to print the first term you have to print a.
To get your desired output, instead of the usual fibbonacci sequence, you'll also need to increase b by one, every iteration:
a, b = b, (a + b + 1)
Printing 'a' instead of 'b' will solve your problem.
Try this code this would solve your problem.
a, b = 0, 1
while b < 1000:
print(a, '', end='')
a, b = b, a + b
while i traced your code i got,
1st iter : a=0,b=1
2nd iter : a=1,b=1
3rd iter : a=1,b=2
4th iter : a=2,b=3
5th iter : a=3,b=5
and continues..

How do I get my python function to properly apply an IF-ELIF-ELSE statements correctly to all rows in my pandas dataframe?

I am trying to calculate the CGPA of a number of students. The idea here is that each student takes N courses (in this case, N = 3). Every course has its course load which is an integer and can range from 1 to 6. At the end of the semester, the CGPA is calculated based on the unit load of all the courses taken by each student and the grades obtained.
I am trying to do this using a for statement to loop through the entire dataset a row at a time and then an if suite to determine the number of units to assign to each student according to the grade scored. The problem here is that the code works but it doesn't follow through. So if the first student in the dataframe had an A in course1, the code gives him 15units and all other students also get 15units irregardless of if they score a D or an F.
I really want to know what I am doing wrong and how I can fix it. I would also appreciate it if you can suggest smarter ways of accomplishing this task. Thanks.
I have added breaks in the first course section but I am afraid the code is still not generalizing well.
A = 5; B = 4; C = 3; D = 2; E = 1; F = 0;
course1_cl = 3; course2_cl = 3; course3_cl = 3
def calculate_CGPA(dataframe, a, b, c, d):
for row in dataframe[d]:
if dataframe[a].any()=='A':
dataframe['units'] = A * course1_cl
break
elif dataframe[a].any()=='B':
dataframe['units'] = B * course1_cl
break
elif dataframe[a].any()=='C':
dataframe['units'] = C * course1_cl
break
elif dataframe[a].any()=='D':
dataframe['units'] = D * course1_cl
break
elif dataframe[a].any()=='E':
dataframe[units] = E * course1_cl
else:
dataframe[units]= 0
print("Done generating units for: "+ format(a))
for row in dataframe[d]:
if dataframe[b].any()=='A':
dataframe['units2']=A * course2_cl
elif dataframe[b].any()=='B':
dataframe['units2'] = B*course2_cl
elif dataframe[b].any()=='C':
dataframe['units2'] = C*course2_cl
elif dataframe[b].any()=='D':
dataframe['units2'] = D*course2_cl
elif dataframe[b].any()=='E':
dataframe['units2'] = E*course2_cl
else:
dataframe['units2'] = 0
print("Done generating units for: "+format(b))
for row in dataframe[d]:
if dataframe[c].any()=='A':
dataframe['units3']= A * course3_cl
elif dataframe[c].any()=='B':
dataframe['units3'] = B*course3_cl
elif dataframe[c].any()=='C':
dataframe['units3'] = C*course3_cl
elif dataframe[c].any()=='D':
dataframe['units3'] = D*course3_cl
elif dataframe[c].any()=='E':
dataframe['units3'] = E*course3_cl
else:
dataframe['units3'] = 0
print("Done generating units for: "+format(c))
df['CGPA'] = (dataframe['units'] + dataframe['units2'] + dataframe['units3'])/(course1_cl + course2_cl + course3_cl)
The resulting dataframe should have 4 newly added columns: One units column for each of the three courses and a CGPA column as seen below. The values in the units and CGPA columns should change dynamically based on the grades scored by the individual.
S/N,Name,ExamNo,Course1,Course2,Course3,Units,Units2,Units3,CGPA
1,Mary Beth,A1,A,A,B,15,15,12,4.67
2,Elizabeth Fowler,A2,B,A,A,12,15,15,4.67
3,Bright Thompson,A12,C,C,B,9,9,12,3.33
4,Jack Daniels,A24,C,E,C,9,3,9,2.33
5,Ciroc Brute,A31,A,B,C,15,12,9,4.0
I do not know how complicated you actual data is but for your sample data you do not need the if statements:
from io import StringIO
# sample data
s = """S/N,Name,ExamNo,Course1,Course2,Course3
1,Mary Beth,A1,A,A,B
2,Elizabeth Fowler,A2,B,A,A
3,Bright Thompson,A12,C,C,B
4,Jack Daniels,A24,C,E,C
5,Ciroc Brute,A31,A,B,C"""
df = pd.read_csv(StringIO(s))
# create a dict
d = {'A':5, 'B':4, 'C':3, 'D':2, 'E':1, 'F':0}
# replace the letter grade with number and assign it to units cols
df[['Units', 'Units2', 'Units3']] = df[['Course1','Course2','Course3']].replace(d) * 3
# calc CGPA with sum div 3
df['CGPA'] = df[['Course1','Course2','Course3']].replace(d).sum(1) / 3
S/N Name ExamNo Course1 Course2 Course3 Units Units2 Units3 \
0 1 Mary Beth A1 A A B 15 15 12
1 2 Elizabeth Fowler A2 B A A 12 15 15
2 3 Bright Thompson A12 C C B 9 9 12
3 4 Jack Daniels A24 C E C 9 3 9
4 5 Ciroc Brute A31 A B C 15 12 9
CGPA
0 4.666667
1 4.666667
2 3.333333
3 2.333333
4 4.000000

Why does Excel average gives different result?

Here's the table:
Should not they have the same result mathematically? (the average score of the per column and per row average)
The missing cells mean that your cells aren't all weighted evenly.
For example, row 11 has only two cells 82.67 and 90. So for your row average for row 11 they are weighted much more heavily than in your column averages where they are 1/13 and 1/14 of a column instead of 1/2 of a row.
Try filling up all the empty cells with 0 and the averages should match.
Taking a more extreme version of Ruslan Karaev's example:
5 5 5 | 5
1 | 1 Average of Average of Rows = (5 + 1 + 0) / 3 = 2
0 | 0
-----
2 5 5
Average of Average of Columns = (2 + 5 + 5) / 3 = 4
Yes, for example, the following two expressions:
/ a + b X + Y \ / a + X b + Y \
( ----- + ----- ) ( ----- + ----- )
\ 2 2 / \ 2 2 /
------------------- -------------------
2 2
are indeed mathematically equivalent, both coming out to be (a + b + X + Y) / 4.
However, short of having enough sufficient precision to store values, you may find that rounding errors accumulate differently depending on the order of operations.
You can see this sort of effect in a much simpler example if you assume a 3-digit precision and divide one by three, then multiply the result of that by three again:
1 / 3 -> 0.333, 0.333 x 3 -> 0.999
Contrast that with doing the operations in the oppisite order:
1 x 3 = 3, 3 / 1 = 1

Random effects, glmer, nested design

I have the following question:
I am analyzing the number of seed capsules between different genotypes (A,B and C)
I have 4 replicates for each genotype and in each of these replicates, I have 8 plants. Here is an example of the data:
Genotype Replicate_ID Plant_ID Seed_capsules
A 1 1 6
A 1 2 10
A 1 3 15
B 2 1 100
B 2 2 40
B 2 3 63
C 3 1 80
C 3 2 90
C 3 3 100
I used the glmer on the data but I am not sure whether my random is the replicate_ID or the plant_ID or both. Here is an example of what I tried so far:
freplicate_ID <- factor(newdata$replicate_ID)
fplant_ID <- factor(newdata$plant_ID)
m5 <- glmer(seed_capsules ~ pop_ID + (1| freplicate_ID /fplant_ID), family=poisson,data = data)
Further, How do I obtain the diagnostic plots for such a model? How do I compare between the genotypes? Do I need to run lsmeans on the model? Like this for example:
lsmeans(m5,pairwise ~ pop_ID, data=newdata) .
I thank you in advance for your help.
best,
Anna

Resources