Print list1 with list2 python - python-3.x

I dont know how to search this code in internet so I ask here
My code :
# This code is in Tes.py
n = [str]*3
x = [int]*3
MyLib.name(n)
MyLib.number(x)
MyLib.Result(n,x)
# This code in MyLib.py with 3 def
def name(data) :
for i in range (3) :
n[i] = str(input("Enter Name : ")
def number(data) :
for s in range (3) :
x[i] = int(input("Enter Number : ")
def result(data1,data2) :
for i in data1 :
for i in data2 :
print("Your Name",n,"Your Number",x)
examples :
input 1 : Jack
Rino
Gust
input 2 : 1232
1541
2021
output what I want : Your Name Jack Your Number 1232
Your Name Rino Your Number 1541
Your Name Gust Your Number 2021
output that i got : Your Name Jack Your Number 1232
Your Name Jack Your Number 1541
Your Name Jack Your Number 2021
Your Name Rino Your Number 1232
Your Name Rino Your Number 1541
Your Name Rino Your Number 2021
Your Name Gust Your Number 1232
Your Name Gust Your Number 1541
Your Name Gust Your Number 2021
How to get output like what I want, I want to search it in the google but I dont know what I must type.

Is this what you mean?
for i in range(min(len(n), len(x))):
print("Your Name",n[i],"Your Number",x[i])

total = 3
n = [str]*total
x = [int]*total
for i in range (total):
n[i] = str(input("Enter Name : "))
for i in range (total):
x[i] = int(input("Enter Number : "))
for i in range (total):
print("Your Name",n[i],"Your Number",x[i])
If you give this code the input you mentioned, it will show the desired result. As you wrote two loops,
for i in n :
for i in x :
your print will be triggered 3*3 = 9 times! You just need one single loop, since at the both input you are taking same number of inputs (3 names and 3 numbers!). Even I would say why do you need 3 loops? why not just this:
total = 3
n = [str]*total
x = [int]*total
for i in range (total):
n[i] = str(input("Enter Name : "))
x[i] = int(input("Enter Number : "))
print("Your Name",n[i],"Your Number",x[i])

Related

Why do I get duplicate output when using a for loop over a list?

Hello I have problem looping when printing data in a list.
def inputScore(scor) :
for i in range(len(scor)) :
scor[i] = int(input("Enter Score Number : "))
def Display(scr) :
for i in scr:
if i >= 86 and i <= 100 :
x = "A"
elif i >= 70 and i < 86 :
x = "B"
elif i >= 60 and i < 70 :
x = "C"
elif i >= 50 and i < 60 :
x = "D"
elif i >= 0 and i < 50 :
x = "E"
else :
print("Invalid Score")
for i in range(0,3) : # If I remove this code "for..", it will error "IndexError: list index out of range"
print("Score Number",scr[i],"Letter Grades", x)
def main () :
scor = [int]*3
inputScore(scor)
Display(scor)
main()
Example:
# Input :
85
60
40
# Output that I want :
Score Number 85 Letter Grades A
Score Number 60 Letter Grades C
Score Number 40 Letter Grades E
# Output that I got :
Score Number 85 Letter Grades A
Score Number 60 Letter Grades A
Score Number 40 Letter Grades A
Score Number 85 Letter Grades C
Score Number 60 Letter Grades C
Score Number 40 Letter Grades C
Score Number 85 Letter Grades E
Score Number 60 Letter Grades E
Score Number 40 Letter Grades E
There are 3 looping for Letter Grades (A = 3 times, C = 3 times and E = 3 times), I tried to give for i in range(0,3) for stop looping but it doesn't work, Letter Grades always prints 9 times with 3 A, 3 C, and 3 E. How to solve it and make it output like in the example above?
The inner for loop is unnecessary. The outer for loop already iterates through the scores. In each iteration, i is a score, not an index -- to get an index, you use range. Therefore, there's no need to index the scr list at all -- you would print i itself rather than scr[i].
Also, with the current code, the grade for 85 would be B rather than A. Perhaps you need to adjust the bounds for the A and B grades.
Another issue is that for an invalid score, it would still attempt the final print. This would fail if an invalid score occurred as the first score (since x wouldn't be defined). If an invalid score occurred as a subsequent score, the print would show you the grade for the previous score, which you don't want. You can get around this by setting x to be the empty string at the start of each iteration and checking if it has a non-empty value before doing the final print of the grade.
The following code resolves the issues discussed:
def inputScore(scor):
for i in range(len(scor)):
scor[i] = int(input("Enter Score Number: "))
def display(scr):
for i in scr:
x = ""
if i >= 85 and i <= 100:
x = "A"
elif i >= 70 and i < 85:
x = "B"
elif i >= 60 and i < 70:
x = "C"
elif i >= 50 and i < 60:
x = "D"
elif i >= 0 and i < 50:
x = "E"
else:
print("Invalid Score")
if x:
print("Score Number:", i, "Letter Grade:", x)
def main():
scor = [int] * 3
inputScore(scor)
display(scor)
main()

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

python: breaking age group by average number of friends

i have a dataframe of with 4 attributes, it can be seen blow.
what i wanted to do it that take the name and age of a person and count the number of friends he has. then of two ppl have the same age with different names, take the average number of friends for that age group. final divide the age range into age group and then take the average. this is how i tried.
#loc the attribute or features of interest
friends = df.iloc[:,3]
ages = df.iloc[:,2]
# default of dictionary with age as key and value as a list of friends
dictionary_age_friends = defaultdict(list)
# populating the dictionary with key age and values friend
for i,j in zip(ages,friends):
dictionary_age_friends[i].append(j)
print("first dict")
print(dictionary_age_friends)
#second dictionary, the same age is collected and the number of friends is added
set_dict ={}
for x in dictionary_age_friends:
list_friends =[]
for y in dictionary_age_friends[x]:
list_friends.append(y)
set_list_len = len(list_friends) # assign a friend with a number 1
set_dict[x] = set_list_len
print(set_dict)
# set_dict ={}
# for x in dictionary_age_friends:
# print("inside the loop")
# lis_1 =[]
# for y in dictionary_age_friends[x]:
# lis_1.append(y)
# set_list = lis_1
# set_list = [1 for x in set_list] # assign a friend with a number 1
# set_dict[x] = sum(set_list)
# a dictionary that assign the age range into age-groups
second_dict = defaultdict(list)
for i,j in set_dict.items():
if i in range(16,20):
i = 'teens_youthAdult'
second_dict[i].append(j)
elif i in range(20,40):
i ="Adult"
second_dict[i].append(j)
elif i in range(40,60):
i ="MiddleAge"
second_dict[i].append(j)
elif i in range(60,72):
i = "old"
second_dict[i].append(j)
print(second_dict)
print("final dict stared")
new_dic ={}
for key,value in second_dict.items():
if key == 'teens_youthAdult':
new_dic[key] = round((sum(value)/len(value)),2)
elif key =='Adult':
new_dic[key] = round((sum(value)/len(value)),2)
elif key =='MiddleAge' :
new_dic[key] = round((sum(value)/len(value)),2)
else:
new_dic[key] = round((sum(value)/len(value)),2)
new_dic
end_time = datetime.datetime.now()
print(end_time-start_time)
print(new_dic)
some of the feedback i got is: 1, no need to build a list if u want just to count number of friends.
2, two ppl with the same age, 18. One has 4 friends, the other 3. the current code conclude that there are 7 average friends.
3, the code is not correct and optimal.
any suggestions or help? thanks indavance for all suggestion or helps?
I haven't understood names of attributes and you haven't mention by which age groups you need to split your data. In my answer I'll treat the data as if the attributes were:
index, name, age, friend
To find amount of friends by name, I would suggest you to use groupby.
input:
groups = df.groupby([df.iloc[:,0],df.iloc[:,1]]) # grouping by name(0), age(1)
amount_of_friends_df = groups.size() # gathering amount of friends for a person
print(amount_of_friends_df)
output:
name age
EUNK 25 1
FBFM 26 1
MYYD 30 1
OBBF 28 2
RJCW 25 1
RQTI 21 1
VLIP 16 1
ZCWQ 18 1
ZMQE 27 1
To find amount of friends by age you also can use groups
input:
groups = df.groupby([df.iloc[:,1]]) # groups by age(1)
age_friends = groups.size()
age_friends=age_friends.reset_index()
age_friends.columns=(['age','amount_of_friends'])
print(age_friends)
output:
age amount_of_friends
0 16 1
1 18 1
2 21 1
3 25 2
4 26 1
5 27 1
6 28 2
7 30 1
To calculate average amount of friends per age group you can use categories and groupby.
input:
mean_by_age_group_df = age_friends.groupby(pd.cut(age_friends.age,[20,40,60,72]))\
.agg({'amount_of_friends':'mean'})
print(mean_by_age_group_df)
pd.cut returns caregorical series which we use to group data. Afterwards we use agg function to aggregate groups in dataframe.
output:
amount_of_friends
age
(20, 40] 1.333333
(40, 60] NaN
(60, 72] NaN

Print sorted data under a heading in python 3.7

I want to sort data in a txt file that has the following format:
name number1 number2 number3 number4
nick 3 2 66 40
Anna 3 1 33 19
kathrine 4 4 100 258
based on fourth column (number3) but it doesn't seem to work when number3 is three digits number.
The program simply asks three times for a name. Each name enters numbers other than 0
and prints the name, how many numbers given (number1), how many of them are greater than 10 (number2), percentage of them (number 3) and the sum of all numbers given(number4).
I would like also to print data aligned under each heading.The headings doesn't need to be stored
in the file.
The code is the following
def how_to_sort_a_file():
from operator import itemgetter
with open('myfile2.txt') as f:
lines = [line.split(' ') for line in f]
output = open('myfile2(sorted).txt', 'w')
for line in sorted(lines,key=itemgetter(3), reverse=True):
output.write(' '.join(line))
output.close()
print('')
with open('myfile2(sorted).txt') as f:
##prints an empty line between lines
for line in f:
print(line)
##end function
##################################################################
##################
## main program ##
##################
file=open('myfile2.txt', 'w')
file.close()
for i in range(3):
name=input('insert your name: ')
number=int(input('insert number, 0 to terminate: '))
given_numbers=0
numbers_greater_10=0
Sum=0
while number!=0:
Sum=Sum+number
given_numbers=given_numbers+1
if number>10:
numbers_greater_10=numbers_greater_10+1
number=int(input('insert number, 0 to terminate: '))
percentage=int((numbers_greater_10)*100/given_numbers)
with open('myfile2.txt', 'a') as saveFile:
saveFile.write(name +' '+str(given_numbers)+' '+str(numbers_greater_10)+' '+ str(percentage)+' '+ str(Sum)+"\n")
how_to_sort_a_file()
I'm totally inexperienced with Python and i would appreciate any help.
Thanks a lot.
You can try doing this using Python's library pandas:
Read the text file into a dataframe like below:
In [1397]: df = pd.read_fwf('myfile2.txt')
In [1398]: df
Out[1398]:
name number1 number2 number3 number4
0 nick 3 2 66 40
1 Anna 3 1 33 19
2 kathrine 4 4 100 258
Now, you can simple sort on the column number3 in an ascending order:
In [1401]: df = df.sort_values('number3')
In [1402]: df
Out[1402]:
name number1 number2 number3 number4
1 Anna 3 1 33 19
0 nick 3 2 66 40
2 kathrine 4 4 100 258
You can see above that the rows are sorted by number3. Now, simply write this to a text file:
In [1403]: df.to_csv('my_output.txt', index=False)
mayankp#mayank:~/Desktop$ cat my_output.txt
name,number1,number2,number3,number4
Anna,3,1,33,19
nick,3,2,66,40
kathrine,4,4,100,258
The good part about this is that you don't have to write complex code for parsing the file.

Print right-justified list of binary numbers

Here is the code to convert a decimal number number to binary (DectoBin), and to print a list of all binary numbers from 1 to number (print_formatted) :
def DectoBin(number):
j=1
binary = 0
while (number != 0):
reminder = number % 2
number= int(number / 2)
binary= binary + reminder * j
j *= 10
return(binary)
def print_formatted(number):
for j in range(1, number + 1):
bin1 = DectoBin(j)
print(bin1, end='\n')
Output I get :
1
10
11
100
101
110
111
1111
Output I want (right-justified list of binary numbers) :
1
10
11
100
101
110
111
1000
See PEP 498 which introduces Literal String Interpolation. You can use it to right justify your print out:
def DectoBin(number):
j=1
binary = 0
while (number != 0):
reminder = number % 2
number= int(number / 2)
binary= binary + reminder * j
j *= 10
return(binary)
for i in range(16):
print (f'{DectoBin(i):>5}')
which produces the following output:
0
1
10
11
100
101
110
111
1000
1001
1010
1011
1100
1101
1110
Define print_formatted function as following. This ensures that the binary numbers are correctly right justified with the right number of spaces before each number :
import math
def print_formatted(number):
max_bits = math.ceil(math.log2(number + 1))
for j in range(1, number + 1):
bin1 = str(DectoBin(j)).rjust(max_bits)
print(bin1, end='\n')
max_bits is the number of bits used to represent number, and rjust is used to right justify the string in a string of length max_bits.

Resources