Python Forum
How to work with list - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: How to work with list (/thread-39167.html)



How to work with list - kafka_trial - Jan-12-2023

Hi all,
I am new to Python. I am doing an application. the application takes 20 names of individuals then prompts user to input out of 20 individual who came first, second, third..... twentieth.
According to the ranking then points allocated for every individual for the first place 100, second 95, third 90... so on.

However, I am finding to very difficult to allocate the points as not sure how to find out who came first and second. The code is below.

Any help will be apricated.

names=[]

history=[]
maths=[]

for i in range(0,20):
    nam=input("Please enter the name of competitor ")
    names.append(nam)
order=["first","second","third","fourth","fifth","sixth","seventh","eighth","ninth","tenth","eleventh","twelfth",
       "thirteenth","fourteenth","fifteenth","sixteenth","seventeenth","eighteenth","nineteenth","twentieth"]

for i in range (0,20):
    print("Please enter the name of the individual who came ",order[i],"in History Quiz ")
    a=input()
    history.append(a)

for i in range (0,20):
    print("Please enter the name of the individual who came ",order[i],"in Maths Quiz ")
    a=input()
    maths.append(a)


if names[0]==history[0]:
    print(names[0])
elif names[1]==history[0]:
    print(names[1])
elif names[2]==history[0]:
    print(names[2])
elif names[3]==history[0]:
    print(names[3])
elif names[4]==history[0]:
    print(names[4])
elif names[5]==history[0]:
    print(names[5])
elif names[6]==history[0]:
    print(names[6])
elif names[7]==history[0]:
    print(names[7])
elif names[8]==history[0]:
    print(names[8])
elif names[9]==history[0]:
    print(names[9])
elif names[10]==history[0]:
    print(names[10])
elif names[11]==history[0]:
    print(names[11])
elif names[12]==history[0]:
    print(names[12])
elif names[13]==history[0]:
    print(names[13])
elif names[14]==history[0]:
    print(names[14])
elif names[15]==history[0]:
    print(names[15])
elif names[16]==history[0]:
    print(names[16])
elif names[17]==history[0]:
    print(names[17])
elif names[18]==history[0]:
    print(names[18])
else:
    print(names[19])


if names[0]==maths[0]:
    print(names[0])
elif names[1]==maths[0]:
    print(names[1])
elif names[2]==maths[0]:
    print(names[2])
elif names[3]==maths[0]:
    print(names[3])
elif names[4]==maths[0]:
    print(names[4])
elif names[5]==maths[0]:
    print(names[5])
elif names[6]==maths[0]:
    print(names[6])
elif names[7]==maths[0]:
    print(names[7])
elif names[8]==maths[0]:
    print(names[8])
elif names[9]==maths[0]:
    print(names[9])
elif names[10]==maths[0]:
    print(names[10])
elif names[11]==maths[0]:
    print(names[11])
elif names[12]==maths[0]:
    print(names[12])
elif names[13]==maths[0]:
    print(names[13])
elif names[14]==maths[0]:
    print(names[14])
elif names[15]==maths[0]:
    print(names[15])
elif names[16]==maths[0]:
    print(names[16])
elif names[17]==maths[0]:
    print(names[17])
elif names[18]==maths[0]:
    print(names[18])
else:
    print(names[19])
    



RE: How to work with list - rob101 - Jan-12-2023

First, I'd move the order list (as I've done below) so that it's easier to see the logic flow. You can loop through the names and positions, remembering that a list object is ordered: you know who came first, second, third... because that's the order in which the names have been entered.

This should get you back on track, but it's not a full solution; I'll leave that to you, so that you can learn from it.

names = []
history = []
maths = []
order = ["first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eighth", "ninth", "tenth", "eleventh", "twelfth",
         "thirteenth", "fourteenth", "fifteenth", "sixteenth", "seventeenth", "eighteenth", "nineteenth", "twentieth"]

for i in range (0,20):
    print("Please enter the name of the individual who came ",order[i],"in History Quiz ")
    a=input()
    history.append(a)
 
for i in range (0,20):
    print("Please enter the name of the individual who came ",order[i],"in Maths Quiz ")
    a=input()
    maths.append(a)

# history
for name in names:
    for position in enumerate(history):
        if name == position[1]:
            print(f"{name} came {order[position[0]]} in history")
Any questions, simply ask.

Edit to add:

You may find that a dictionary would be of use; the key being 'first', 'second', 'third'... and the value being the points:
'first': 100
'second': 95
'third': 90
...
Do you understand how a dictionary works and how it could be of use here?


RE: How to work with list - deanhystad - Jan-12-2023

Allocate the points when the names are entered. Don't put them in a list.

You are starting out with the wrong structure. You should use a dictionary to keep track of student scores. The dictionay keys would be the student names. The student scores would be the dictionary values. With a dictionary you can look up the student's scores by using their name.
students = {}
while True:
    if name := input('Enter student name (or blank to end list): '):
        students[name] = [0, 0]
    else:
        break

for student, scores in students.items():
    print(f'{student:20} {scores[0]:5} {scores[1]:5}')
Output:
Enter student name (or blank to end list): A Enter student name (or blank to end list): B Enter student name (or blank to end list): C Enter student name (or blank to end list): A 0 0 B 0 0 C 0 0
Now you have a structure that has the student name associated with their scores (currently zero's). Next we need to enter their scores. Instead of making a list, ask for the student with the highest score, get that student from the dictionary and add the score to the student's scores. Math scores will be scores[0].
students = {}
while True:
    if name := input('Enter student name (or blank to end list): '):
        students[name] = [0, 0]
    else:
        break

suffix = {1: 'st', 2: 'nd', 3:'rd'}
score = 100
for i in range(1, len(students)+1):
    name = input(f'Student with {i}{suffix.get(i, "th")} score in Math: ')
    students[name][0] = score
    score -= 5

for student, scores in students.items():
    print(f'{student:20} {scores[0]:5} {scores[1]:5}')
Output:
Enter student name (or blank to end list): A Enter student name (or blank to end list): B Enter student name (or blank to end list): C Enter student name (or blank to end list): D Enter student name (or blank to end list): Student with 1st score in Math: A Student with 2nd score in Math: B Student with 3rd score in Math: C Student with 4th score in Math: D A 100 0 B 95 0 C 90 0 D 85 0
Now you could repeat the same code for entering the History scores. And you could add a score to the students scores and copy the block of code to add a Language score and do the same to add an Arts score and so on. Or you could identify early on that there is a repeated pattern that can be exploited to eliminate duplicate code and make the program easier to modify.
classes = {'Math': 0, 'History': 1}
students = {}
while True:
    if name := input('Enter student name (or blank to end list): '):
        students[name] = [0] * len(classes)
    else:
        break

suffix = {1: 'st', 2: 'nd', 3:'rd'}
for class_name, class_index in classes.items():
    score = 100
    for i in range(1, len(students)+1):
        name = input(f'Student with {i}{suffix.get(i, "th")} score in {class_name}: ')
        students[name][class_index] = score
        score -= 5

for student, scores in students.items():
    print(f'{student:20}', *[f'{s:5}' for s in scores])
Output:
Enter student name (or blank to end list): A Enter student name (or blank to end list): B Enter student name (or blank to end list): Student with 1st score in Math: A Student with 2nd score in Math: B Student with 1st score in History: B Student with 2nd score in History: A A 100 95 B 95 100

The same solution implemented using lists. See how much better a dictionary works?
count = 3
names=[''] * count
history=[0] * count
maths=[0] * count

for i in range(0, count):
    names[i] = input("Please enter the name of competitor ")

suffix = {0: 'st', 1: 'nd', 2: 'rd'}
score = 100
for i in range(0, count):
    name = input(f'Who came {i+1}{suffix.get(i)} in History Quiz: ')
    history[names.index(name)] = score
    score -= 5
 
score = 100
for i in range(0, count):
    name = input(f'Who came {i+1}{suffix.get(i)} in Math Quiz: ')
    maths[names.index(name)] = score
    score -= 5

for i in range(count):
    print(names[i], history[i], maths[i])
Output:
Please enter the name of competitor A Please enter the name of competitor B Please enter the name of competitor C Who came 1st in History Quiz: A Who came 2nd in History Quiz: B Who came 3rd in History Quiz: C Who came 1st in Math Quiz: C Who came 2nd in Math Quiz: B Who came 3rd in Math Quiz: A A 100 90 B 95 95 C 90 100



RE: How to work with list - kafka_trial - Jan-16-2023

This is very useful. Thank you.

Just one more question. How I would add the points for maths and history for each learners.

For example, let's say that Student John came fourth math which is 35 points and John came first in history which is 50 points. How could add these points.

Thanks.

PS: No, I don't know anything about dictionary yet. Sad But I will learn asap.

(Jan-12-2023, 03:22 PM)rob101 Wrote: First, I'd move the order list (as I've done below) so that it's easier to see the logic flow. You can loop through the names and positions, remembering that a list object is ordered: you know who came first, second, third... because that's the order in which the names have been entered.

This should get you back on track, but it's not a full solution; I'll leave that to you, so that you can learn from it.

names = []
history = []
maths = []
order = ["first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eighth", "ninth", "tenth", "eleventh", "twelfth",
         "thirteenth", "fourteenth", "fifteenth", "sixteenth", "seventeenth", "eighteenth", "nineteenth", "twentieth"]

for i in range (0,20):
    print("Please enter the name of the individual who came ",order[i],"in History Quiz ")
    a=input()
    history.append(a)
 
for i in range (0,20):
    print("Please enter the name of the individual who came ",order[i],"in Maths Quiz ")
    a=input()
    maths.append(a)

# history
for name in names:
    for position in enumerate(history):
        if name == position[1]:
            print(f"{name} came {order[position[0]]} in history")
Any questions, simply ask.

Edit to add:

You may find that a dictionary would be of use; the key being 'first', 'second', 'third'... and the value being the points:
'first': 100
'second': 95
'third': 90
...
Do you understand how a dictionary works and how it could be of use here?



RE: How to work with list - rob101 - Jan-17-2023

(Jan-16-2023, 11:39 AM)kafka_trial Wrote: This is very useful. Thank you.

Just one more question. How I would add the points for maths and history for each learners.

For example, let's say that Student John came fourth math which is 35 points and John came first in history which is 50 points. How could add these points.

Thanks.

PS: No, I don't know anything about dictionary yet. Sad But I will learn asap.

You're welcome.

A Python dictionary is a very useful data construct, for which your use case could be:

order = {"first": 100,
         "second": 95,
         "third": 90,
         "fourth": 85,
         "fifth": 80
         }
... and so on, but do you need that kind of thing? Why do you need that way of displaying the rankings?

I'd also like to better understand the points system, as it seems to be complicated. As an example, in your first post you said "... first place 100, second 95, third 90... so on.", but now you post "... let's say that Student John came fourth math which is 35 points and John came first in history which is 50 points."

A consistent scoring system would make the coding much simpler. For example, if there's always a 5 point separation between placements, then each place could be calculated by simply subtracting 5 points from 100 for each place. That would then make it quite easy to allocate points to each candidate, based on the position in the list:

# the data as entered, for example
math = ['Paul', 'Ringo', 'John', 'George']
history = ['George', 'Ringo', 'John', 'Paul']
totals = []

name = 1
score = 0

for position, names in enumerate(math):
    math[position] = 100 - 5 * position, names
math.sort(reverse=True)

for position, names in enumerate(history):
    history[position] = 100 - 5 * position, names
history.sort(reverse=True)

print("Results for math:")
for scores in math:
    print(f"{scores[name]}: {scores[score]}")

print()
print("Results for history:")
for scores in history:
    print(f"{scores[name]}: {scores[score]}")

for h_score in history:
    for m_score in math:
        if h_score[name] == m_score[name]:
            totals.append((h_score[score] + m_score[score], h_score[name]))
totals.sort(reverse=True)

print()
print("Totals:")
for scores in totals:
    print(f"{scores[name]}: {scores[score]}")
Output:
Results for math: Paul: 100 Ringo: 95 John: 90 George: 85 Results for history: George: 100 Ringo: 95 John: 90 Paul: 85 Totals: Ringo: 190 Paul: 185 George: 185 John: 180



RE: How to work with list - kafka_trial - Jan-23-2023

Thanks for that. Good stuff.

Just for my own sanity: why do I get the following message:

Error:
Traceback (most recent call last): File "C:/Users/mustafa.turus/OneDrive - Capital City College Group/Desktop/sirrrrr.py", line 24, in <module> total[i]=history[i]+maths[i] IndexError: list assignment index out of range
count = 3
names=[''] * count
history=[0] * count
maths=[0] * count
total=[]
 
for i in range(0, count):
    names[i] = input("Please enter the name of competitor ")
 
suffix = {0: 'st', 1: 'nd', 2: 'rd'}
score = 100
for i in range(0, count):
    name = input(f'Who came {i+1}{suffix.get(i)} in History Quiz: ')
    history[names.index(name)] = score
    score -= 5
  
score = 100
for i in range(0, count):
    name = input(f'Who came {i+1}{suffix.get(i)} in Math Quiz: ')
    maths[names.index(name)] = score
    score -= 5
 
for i in range(0,count):
    total[i]=history[i]+maths[i]
print(total)
(Jan-17-2023, 05:25 PM)rob101 Wrote:
(Jan-16-2023, 11:39 AM)kafka_trial Wrote: This is very useful. Thank you.

Just one more question. How I would add the points for maths and history for each learners.

For example, let's say that Student John came fourth math which is 35 points and John came first in history which is 50 points. How could add these points.

Thanks.

PS: No, I don't know anything about dictionary yet. Sad But I will learn asap.

You're welcome.

A Python dictionary is a very useful data construct, for which your use case could be:

order = {"first": 100,
         "second": 95,
         "third": 90,
         "fourth": 85,
         "fifth": 80
         }
... and so on, but do you need that kind of thing? Why do you need that way of displaying the rankings?

I'd also like to better understand the points system, as it seems to be complicated. As an example, in your first post you said "... first place 100, second 95, third 90... so on.", but now you post "... let's say that Student John came fourth math which is 35 points and John came first in history which is 50 points."

A consistent scoring system would make the coding much simpler. For example, if there's always a 5 point separation between placements, then each place could be calculated by simply subtracting 5 points from 100 for each place. That would then make it quite easy to allocate points to each candidate, based on the position in the list:

# the data as entered, for example
math = ['Paul', 'Ringo', 'John', 'George']
history = ['George', 'Ringo', 'John', 'Paul']
totals = []

name = 1
score = 0

for position, names in enumerate(math):
    math[position] = 100 - 5 * position, names
math.sort(reverse=True)

for position, names in enumerate(history):
    history[position] = 100 - 5 * position, names
history.sort(reverse=True)

print("Results for math:")
for scores in math:
    print(f"{scores[name]}: {scores[score]}")

print()
print("Results for history:")
for scores in history:
    print(f"{scores[name]}: {scores[score]}")

for h_score in history:
    for m_score in math:
        if h_score[name] == m_score[name]:
            totals.append((h_score[score] + m_score[score], h_score[name]))
totals.sort(reverse=True)

print()
print("Totals:")
for scores in totals:
    print(f"{scores[name]}: {scores[score]}")
Output:
Results for math: Paul: 100 Ringo: 95 John: 90 George: 85 Results for history: George: 100 Ringo: 95 John: 90 Paul: 85 Totals: Ringo: 190 Paul: 185 George: 185 John: 180



RE: How to work with list - rob101 - Jan-23-2023

(Jan-23-2023, 04:21 PM)kafka_trial Wrote: Thanks for that. Good stuff.

Just for my own sanity: why do I get the following message:

No worries.

It's because total is an empty list object; you've appended nothing to that list.

Maybe you mean total.append(history[i] + maths[i])?


RE: How to work with list - deanhystad - Jan-23-2023

(Jan-23-2023, 04:21 PM)kafka_trial Wrote: why do I get the following message:

Error:
Traceback (most recent call last): File "C:/Users/mustafa.turus/OneDrive - Capital City College Group/Desktop/sirrrrr.py", line 24, in <module> total[i]=history[i]+maths[i] IndexError: list assignment index out of range
total = [] makes a list with no elements. total[0] indexes an element that doesn't exist, thus "index error".

Do not use reply unless referring to a previous post. Even then, edit the reply to only include the important parts. Here I only needed to reference the question and the error message, so I removed everything else from the reply. Think of what a mess it would be if I replied to your post, and you replied to mine, and I replied back to yours and the reply part of each post becomes huge, dwarfing the important additional content.


RE: How to work with list - jefsummers - Jan-24-2023

This is not meant to entirely answer your question, but rather to offer another option in the approach - more proof of concept.
When working with a set of related data, a Python class may be a useful construct. Dictionaries work great for paired data, but in this case you have a student name, rank, math and history scores.

The following defines a class that has those elements as well as a function that sums the math and history score. Recognize that there is no error checking for someone entering a score that is not an integer, etc, but again this is more showing the concept. I also have it just take 2 student entries. I get the rank by order of entry, which may not work but again, doing this to show another approach.

You access data and functions within a class using the dot (.)

class student:
    name = ''
    place = ''
    math = ''
    history = ''

    def total(self):
        return int(self.math)+int(self.history)

students = [] # List of the students, will fill with student objects

for count in range(2): # Loop to enter the student names and scores
    studlet = student()
    studlet.name = input('Enter Name ')
    studlet.place = count
    studlet.math = input('Enter Math Score ')
    studlet.history = input('Enter History Score ')
    students.append(studlet) # Append the student object to the list of students

for student in students: # Loop to display the student object data
    print(student.name, student.place, student.math, student.history, student.total())
Output:
Enter Name John Enter Math Score 42 Enter History Score 38 Enter Name Mary Enter Math Score 45 Enter History Score 30 John 0 42 38 80 Mary 1 45 30 75