Python program - Help pairing elements together without using a dictionary - python

I"m studying for my Intro Python class and I have a proficiency exam tomorrow. In the sample problem, it asks:
"Write a program in Python to list the students who are members of the most
frequent major (assume there is only one most frequently occurring major). Your program should ask the user to input the number of students to be entered, and then ask for the name and major (you don’t know which majors will be entered ahead of time) for each of those students, on separate lines. The most frequent of the majors should be determined, and the names of the students from the most frequently occurring major should then be displayed (in any order you wish). In the following example, the user is inputting data.
How many students? 5
Enter Student Name
sue
enter major
CS
Enter Student Name
bob
enter major
PE
Enter Student Name
tom
enter major
CS
Enter Student Name
jack
enter major
CS
Enter Student Name
mary
enter major
MTH
Most Frequent Major is: CS
sue
tom
jack
So, I started to write my program, but unfortunately I'm stuck. I figured out a complicated method of gathering the majors together and finding sorting them. With that, it's easy to display the most frequent major. However, I can't seem to figure out how to assign the name values to each major. I know a dictionary cannot be used because they are immutable. Given my code, what function can I use to assign each name to a major?
num_students = int(input("enter the number of students: "))
counter = 0
major_list = []
name_list = []
while counter < num_students:
name = input("Enter Student Name: ")
name_list.append(name)
major = input("enter major: ").upper
major_list.append(major)
counter += 1
major_counter = {}
for word in major_list:
if word in major_counter:
major_counter[word] += 1
else:
major_counter[word] = 1
popular_majors = sorted(major_counter, key = major_counter.get, reverse = True)
top_major = popular_majors[0]
print("Most Frequent Mjaor is: ", top_major)
input("Press Enter to exit")
I'm really hung up on this one. Thank you so much for your help!

I your goal is to pair two elements together without dictionaries. I would:
>>> array = []
Create an array.
>>> array.append(["name","major"])
Then create a sub array with your two values
print array
[['name', 'major']]
See how there is a array within a array?
array.append(["tom","CS"])
print array
How add your stuff!
[['name', 'major'], ['tom', 'CS']]
And here is our end result!

Your task is to display a list of the students in the most frequent major. Your code does not keep track of the student names, but you need to if you are to include them in the output.
A dictionary of lists is a good way to go. As you have done, use the major as the key but, instead of counting the number of students, add each student to a list. Once you have completed collecting the user's input, you can find the most common major and print out its students. Something like this:
major_students = {}
for major, student in zip(major_list, name_list):
if major not in major_students:
major_students[major] = []
major_students[major].append(student)
In the above I have retained your method of collecting the user input into two lists which I then zipped together for processing. It's better though if you insert the user's input directly into the major_students dict as it is entered:
major_students = {}
for i in range(num_students):
name = input("Enter Student Name: ")
major = input("enter major: ").upper()
major_students[major] = major_students.get(major, []) + [name]
This results in a dictionary with the major as key and a list of students as values. Next, finding the major with the most students can be done by sorting the dictionary items using the length of the student list:
major, students = sorted(major_students.items(), key=lambda x: len(x[1]), reverse=True)[0]
print("Most Frequent Major is {} with {} students: {}".format(major, len(students), ', '.join(students)))

Related

how to write a program that using lists for calculating GPA of students in python

I have to write a program in python that user inputs 3 majors and then he inputs students for each major with their classes and their scores for each class and then my program should calculate each student's GPA and then prints the best and worst student according to their GPA.
I was thinking to a program that is has 3 major lists and each list has another list inside of it for students and each student list has another two lists inside of it for classes and scores! But it seems impossible because for writing it I don't know user's inputs so I can not call the student name.
I mean if I had this list:
Math = [Jack[], Max[], Sarah[]]
I could easily use Jack[] but when I don't know users inputs so I can not write the program this way!
Any idea?
Don't know if this is late, but maybe you could work with dictionaries:
majors = {}
for i in range(3):
major = input('Insert a major\n')
majors[major] = {}
print("To terminate type 'end'\n")
for major in majors:
student = ""
while student != "end":
student = input('Insert a student for major {}\n'.format(major))
if student != "end":
majors[major][student] = {}
stud_class = ""
while stud_class != "end":
stud_class = input('Insert a class for student {}\n'.format(student))
if stud_class != "end":
grade = input('Insert grade\n')
majors[major][student][stud_class] = grade
print(majors)
# Example throwing inside some random bunch of data, just so you can get the feeling
>> {'Math': {'Laura': {'IT': '10', 'English': '8'}, 'Marco': {'Spanish': '4'}}, 'English': {'Jen': {'IT': '9'}}, 'Spanish': {}}
Of course you'll have to add validation on user input because things could easily go wrong.
Also majors are fixed in number, but the students and classes for each students aren't. A simple solution to stop the input could be: when the user enters "end" you discard that input and pass to the next thing.
Hope this helps!

Add more values in a list at once in Python

I'm a beginner in Python and I'm trying to solve this problem.
I'm trying to write a code where you can put your name and the amount that you want to donate.
The thing is, deppending on the amount of the donation you can have more chances to be the winner.
Eg. If you donate $10 (1 chance), $20(2 chances), $30(3 chances).
My biggest problem is because I can't figure out how to solve this problem when the person insert $30 its name goes to the list 3 times and so on. I tried to use "for..inrange():" but without any sucess. Can someone explain me how to do this?
from random import shuffle
from random import choice
list = []
while True:
name = str(input('Write your name: '))
donation = float(input('Enter the amount you want to donate.: $ '))
list.append(name)
print('You donated $ {}. Thank you {} for you donation!'.format(donation, name))
print('=-'*25)
print('[1] YES')
print('[2] NO')
answer = int(input('Would you like to make another donation? '))
if answer == 1:
continue
else:
shuffle(list)
winner = choice(list)
break
print('The winner was: {}' .format(winner))
First do not use the name of a built-in type as a (meaningless) variable name. Change list to entry_list.
For the particular problem
compute the quantity of chances;
make a list of the person's name that many times;
extend the entry list with that list of repeated name.
Code:
entry_list = []
while ...
...
chances = int(donation) // 10
entry_list.extend( [name] * chances )
An alternative to adding another loop with additional control flow, you can use list.extend() with a list expression:
num_chances = donation // 10
chances = [name] * num_chances
all_chances.extend(chances)
Note that list is a built-in python identifier, and it's not a good idea to overwrite it. I've used all_chances instead.
Rather than adding extra names to the list to represent the higher chance, you could use the donations as weights in the random.choices function:
from random import choices
names, donations = [], []
while True:
names.append(input('Write your name: '))
donations.append(float(input('Enter the amount you want to donate.: $')))
print(f'You donated ${donations[-1]}. Thank you {names[-1]} for your donation!')
print('=-'*25)
print('[1] YES')
print('[2] NO')
if input('Would you like to make another donation? ') != '1':
break
winner = choices(names, donations)[0]
print(f'The winner was: {winner}')
This allows for non-integer donations to be counted fairly -- e.g. if Bob donates $0.25 and Fred donates $0.50, the drawing will still work in a reasonable way. It also allows very large donations to be handled without tanking the performance of the program -- if you have one list entry per dollar donated, what happens if Elon donates $20B and Jeff donates $30B? (The answer is that your fan spins really fast for a while and then the program crashes because you can't create a list with 50 billion elements -- but this is not a problem if you simply have a list of two elements with large int values.)
Note that shuffle is not necessary if you're using random.choices (or random.choice for that matter) because those functions will already make a random selection from the list.
You can use a for loop to append the name to the list more than one time :
for i in range(donation//10):
list.append(name)
This code should do the job. Please follow good naming conventions as pointed out by others. I have changed the list variable to donations as it is forbidden to use keywords as variables.
I have included the name in donations int(name) // 10 times using the extend function as pointed out by others. You may change the number of times as you wish.
from random import shuffle
from random import choice
donations = []
makeDonation = True
winner = "Unknown"
while makeDonation:
name = str(input('Write your name: '))
donation = float(input('Enter the amount you want to donate.: $ '))
donations.extend([name for i in range ( int(donation) // 10)])
print('You donated $ {}. Thank you {} for you donation!'.format(donation, name))
print('=-'*25)
print('[1] YES')
print('[2] NO')
answer = int(input('Would you like to make another donation? '))
if answer == 2:
makeDonation = False
shuffle(donations)
winner = choice(donations)
print('The winner was: {}' .format(winner))

Is there an easier way to input multiple names and store them accordingly? [duplicate]

This question already has answers here:
More Pythonic Way to Run a Process X Times [closed]
(5 answers)
Closed 2 years ago.
1st: So i was told to make a code that can store the names of students who have asked to go on a trip up to the maximum number allowed ( 45 students max).
2nd: i must also input and store whether each student has paid.
3rd: enable printouts to be produced to show which students have not paid.
so as of now, im still at the 1st stage. here's my code, i decided to use the dictionary command:
d = {}
d [input("have the student paid?: ")]=input("enter 1st name: ")
d [input("have the student paid?: ")]= input("enter 2nd name: ")
d [input("have the student paid?: ")]= input("enter 3rd name: ")
d [input("have the student paid?: ")]= input("enter 4th name: ")
d [input("have the student paid?: ")]= input("enter 5th name: ")
It worked perfectly fine.
But is there any other way on how to input the names and assign the name correctly to which students have/ have not paid.
Is there any method of doing it instead of writing it one by one, because i need to write 45 of those.
This not my complete answer for the 1st question
I also need extra help for my 2nd and 3rd question please.
Have you tried using a for loop?
Also, your dictionary should be the other way around. You have a dictionary of 'Paid?' (which can be either yes or no) to a student's name. However, when you try to print the dictionary, it will have only two members: yes and no, with only two names. That's because you are overwriting the last respective value.
Try something like this:
students = {} # declare a 'students' dictionary
for i in range(45): # this loop will be executed 45 times (from 0 to 44)
student_name = input('Enter the student\'s name: ') # get the student's name
input_student_has_paid = input('Has the student paid? Y/N: ') # only accept Y or N as an answer to avoid inconsistencies
if input_student_has_paid.lower() in ['y', 'yes']: # accept either 'y' or 'yes' (case insensitive because of .lower()
student_has_paid = True
else:
student_has_paid = False
students[student_name] = student_has_paid # this will be, for example, d['rafael'] = False since I have not paid
print(students)
More about dictionaries.
you can use a for loop for the first part:
d = {}
for number in range(45):
d[input("have the student paid?: ")] = input(f'enter student {number} name: ')
The most pythonic and least readable way to do it is the following:
number_of_students = 45
d = {input("Student name: ") : (True if input("Has paid: ").lower() in "yes" else False) for _ in range(number_of_students)}
Note that the first prompt will be "Has paid" and the second one "Student name", so it's reversed but the same way OP stated it. Also note the prompt "Has paid" will give True for the following answers: "y", "e", "s", "ye", "es", "yes" with all combinations of lowercase and uppercase letters.

How to iterate through all values in a dictionary when the key is a variable?

students = {}
grade_collect = False
id_collect = True
while id_collect == True:
ID = input(str('What is your student ID?'))
students[ID] = {}
students[ID]['Name'] = input(str('What is the student\'s name?'))
decision = input('Would you like to enter another student? (y/n)')
if decision == 'y':
continue
else:
number = input('How many assignments were given?')
id_collect = False
grade_collect = True
break
while grade_collect == True:
for x in range(int(number)):
x = input('Please enter the scores for ' + students[ID]['Name'])
print(x)
I am trying to write a program that stores Student IDs, Names, grades, and scores that are inputted by the user; and eventually printing out the average scores for each student.
Because I have the keys for the dictionary as a variable 'ID' I cannot figure out how to get the program to prompt for the grades of more than one student; it just repeats itself. In the first part of my code, I can get the dictionary to store all of the names and IDs, but when I need to go through the students by their IDs to ask the user what the grades on each assignment are, it only asks the most recent student ID in the dictionary.
I hope this is clear, thanks for any help.
Edit for clarification: By 'when the key is a variable' I meant that the variable ID is the key to each value.
ex.
{'1245': {'Name': 'Connor'}, '6789': {'Name': 'Josh'}}
The IDs aren't hard-coded, they are user input so they are a variable in the code itself. That is the part that is confusing me. Sorry for the confusion.
Since you have already created a dictionary of students ID, you technically do not need another while loop. You can simply do the following to grab each users score.
for id in students:
score = input("Please enter the scores for " + students[id]["Name"])
students[id]["Score"] = score
If there are multiple assignments, then another while-loop would be appropriate.
You can loop over all IDs using:
for id in students:
#now in each iteration, 'id' points to one of the IDs in the keys
#whatever you want to do with students[id]...
try:
for s in list(students):
students[s]
Edited to better address the question.

Editing lists in a dictionary Python 3.7

I am trying to print out a dictionary that shows a students ID, Name and Grades so it looks like this "ID:{'Name': 'Students Name', Grades[Grade1, Grade2, Grade3....]. When I am doing this and print out the dictionary it will only print our the grade for the last assignment for each student dictionary. For example if student 1 got a 30 on the last assignment and student 2 got a 40 on the last assignment. The output is:
enter code here
1:{'Name': 'Student 1', 'Grades': [30, 40]}
2:{'Name': 'Student 2', 'Grades': [30, 40]}
My original problem was everyscore for every student was in the dictionary, I thought I fixed this by emptying the Grades list in the loop after the grades go in. But now i have this problem. Im not quite sure what the problem is and Im going to try and work on it but any help would be appreciated. MY code is below.
enter code here
students = {}
grades = []
while True:
blank = {}
student_name = input("What is the student's name? ")
student_id = input("What is the student's ID number? ")
blank['Name'] = student_name
blank['Grades'] = grades
students[student_id] = blank
y_or_n = input("Would you like to enter another student? Yes or No ")
if y_or_n == "Yes":
continue
else:
break
homework_assignments = int(input("How many homework assignments were
given? "))
for i in students.keys():
print("Please enter the grades for {}".format(students[i]['Name']))
for j in range (1, homework_assignments + 1):
grade = int(input("What was the grade for homework {}?".format(j)))
grades.append(grade)
for i in students.keys():
students[i]['Grades'] = grades
grade = []
for key in students.keys():
print("{}:{}".format(key, students[key]))
When you callstudents['Grades'] = grades you are modifying the same dictionary while iterating through it's keys. The correct code should be students[i]['Grades'] = grades since you have declared the Grades as a nested structure of students above. There is another mistake, you are using the varibale i as an index to iterate through the assignments as well as the students, which results in i being incremented in an unexpected manner. Try the following snippet.
for i in students.keys():
print("Please enter the grades for {}".format(students[i]['Name']))
for j in range (1, homework_assignments + 1):
grade = int(input("What was the grade for homework {}? ".format(i)))
if grade < 0 or grade > 100:
print("Grades need to be between 0 - 100")
grades.append(grade)
students[i]['Grades'] = grades
Some things I have noticed:
Your checking of invalid grades does nothing, the grade will still be added incorrectly. To fix this, you need to make sure that the grade is not added if it is outside that range, and that you repeat that i'th iteration.
This is not really accomplish-able with a for loop in your current structure, maybe a while loop would suit it better.
I also noticed you have used the variable i for two of your loops, which means that it is getting overwritten and causing confusing things to happen.
There are a whole host of logical errors towards the bottom and I think it would help you if you printed out the students dictionary before you print it to see its structure.
From my perspective I see has keys that are the student's ID numbers, with corresponding values of their name and this grades list. It also has a key that is 'Grades' which holds the same grades list.
The reason you are seeing all of the grades is because of a small detail about how python handles lists. The problem you are seeing is related to assignment and copying - you want to copy the contents at that point and then empty it after you are done assigning so the next student has an empty list. What you are currently doing is assigning the list which is effectively making every grade list point to the same list.
I'd personally like to stray away from literally writing the code for you, but if you have further questions just comment them and I will guide you through it.

Categories