Python: Returning array values from a function - python

I'm trying to understand how to use functions properly. In this code, I want to return 2 arrays for pupil names and percentage scores. However I am unable to return the array variables from the first function.
I've tried using different ways of defining the arrays (with and without brackets, both globally and locally)
This is the relevant section of code for the program
#function to ask user to input name and score
def GetInput():
for counter in range(0,10):
names[counter] = input("Please enter the student's name: ")
valid = False
while valid == False:
percentages[counter] = int(input("Please enter the student's score %: "))
if percentages[counter] < 0 or percentages[counter] > 100:
print("Please enter a valid % [0-100]")
else:
valid = True
return names, percentages
name, mark = GetInput()
I'm expecting to be asked to enter the values for both arrays.
I'm instead getting:
Traceback (most recent call last):
File "H:/py/H/marks.py", line 35, in <module>
name, mark = GetInput()
File "H:/py/H/marks.py", line 7, in GetInput
names[counter] = input("Please enter the student's name: ")
NameError: global name 'names' is not defined

You need to use dictionary instead of list if your want to use key-value pairs. furthermore you need to return the values outside of for loop. You can try the following code.
Code:
def GetInput():
names = {} # Needs to declare your dict
percentages = {} # Needs to declare your dict
for counter in range(0, 3):
names[counter] = input("Please enter the student's name: ")
valid = False
while valid == False:
percentages[counter] = int(input("Please enter the student's score %: "))
if percentages[counter] < 0 or percentages[counter] > 100:
print("Please enter a valid % [0-100]")
else:
valid = True
return names, percentages # Return outside of for loop.
name, mark = GetInput()
print(name)
print(mark)
Output:
>>> python3 test.py
Please enter the student's name: bob
Please enter the student's score %: 20
Please enter the student's name: ann
Please enter the student's score %: 30
Please enter the student's name: joe
Please enter the student's score %: 40
{0: 'bob', 1: 'ann', 2: 'joe'}
{0: 20, 1: 30, 2: 40}
If you want to create a common dictionary which contains the students' name and percentages, you can try the following implementation:
Code:
def GetInput():
students = {}
for _ in range(0, 3):
student_name = input("Please enter the student's name: ")
valid = False
while not valid:
student_percentages = int(input("Please enter the student's score %: "))
if student_percentages < 0 or student_percentages > 100:
print("Please enter a valid % [0-100]")
continue
valid = True
students[student_name] = student_percentages
return students
students = GetInput()
print(students)
Output:
>>> python3 test.py
Please enter the student's name: ann
Please enter the student's score %: 20
Please enter the student's name: bob
Please enter the student's score %: 30
Please enter the student's name: joe
Please enter the student's score %: 40
{'ann': 20, 'bob': 30, 'joe': 40}

You forgot to set the names and percentages as empty dictionaries so you can use them. Also the "return" should be outside of the for loop.:
def GetInput():
names={}
percentages={}
for counter in range(0,10):
names[counter] = input("Please enter the student's name: ")
valid = False
while valid == False:
percentages[counter] = int(input("Please enter the student's score %: "))
if percentages[counter] < 0 or percentages[counter] > 100:
print("Please enter a valid % [0-100]")
else:
valid = True
return names, percentages
name, mark = GetInput()

Probably this may help to you.
#function to ask user to input name and score
def GetInput():
names=[]
percentages=[]
for counter in range(0,3):
names.append(input("Please enter the student's name: "))
valid = False
while valid == False:
percentages.append(int(input("Please enter the student's score %: ")))
if percentages[counter] < 0 or percentages[counter] > 100:
print("Please enter a valid % [0-100]")
else:
valid = True
return names, percentages
name, mark = GetInput()
print(name,mark)

This is implemented by using two lists. (Not suggested for keeping records. Better use dictionary as done below.)
counter = 10
def GetInput():
names = []
percentage = []
for i in range(counter):
names.append(input("Please enter the student's name: "))
valid = False
while not(valid):
try:
percent = int(input("Please enter the student's score between 0 and 100%: "))
if percent >= 0 and percent <= 100:
percentage.append(percent)
valid = True
break
else:
continue
except ValueError:
print("\nEnter valid marks!!!")
continue
valid = True
return names, percentage
students, marks = GetInput()
The following is implemented by using dictionary, and for this, you do not need the variable counter.
def GetInput():
records = dict()
for i in range(counter):
name = input("Please enter the student's name: ")
valid = False
while not(valid):
try:
percent = int(input("Please enter the student's score between 0 and 100%: "))
if percent >= 0 and percent <= 100:
#percentage.append(percent)
valid = True
break
else:
continue
except ValueError:
print("\nEnter valid marks!!!")
continue
valid = True
records[name] = percent
return records
record = GetInput()
Change the value of counter to how many records you want. This takes care of marks to be between 0 and 100 (included) and to be integer. Its better if you implement it with dictionary.

Wouldn't it be better to have name and percentage in one dict?
#function to ask user to input name and score
def GetInput():
name_percentage = {}
for counter in range(0,10):
name = input("Please enter the student's name: ")
valid = False
while not valid:
percentage = int(input("Please enter the student's score %: "))
if percentage < 0 or percentage > 100:
print("Please enter a valid % [0-100]")
else:
valid = True
name_percentage[name] = percentage
return name_percentage
name_percentage = GetInput()
print(name_percentage)

Related

I have defined the variable but python still shows error

This progam was working fine before i used data validation(the while loops) but now i get the following error -
average_grade = (grade1 + grade2) / 2
NameError: name 'grade2' is not defined
This error was not happening before , I have just started programming so i am quite confused
valid = False
while valid==False:
grade1 = float( input("Enter the grade1: ") )
if grade1 <0 or grade1 > 10:
print('Please enter a grade between 0 and 10')
continue
else:
valid = True
while valid==False:
grade2 = float(input("Enter the grade2: "))
if grade2 < 0 or grade2 > 10:
print('Please enter a grade between 0 and 10')
continue
else:
valid = True
while valid == False:
absences = int(input("Enter the number of absences: "))
if type(absences)!=int:
print("Number of absences can only be an integer value")
continue
else:
valid = True
while valid == False:
total_classes = int(input("Enter the total number of classes: "))
if type(total_classes)!=int:
print("Total number of classes can only be an integer value")
continue
else:
valid = True
average_grade = (grade1 + grade2) / 2
attendance = ((total_classes - absences) / total_classes)*100
print(average_grade)
print("Your attendance is :", attendance , "%")
if(average_grade>=6):
if(attendance>=0.8):
print("YOU HAVE PASSED")
else:
print("You have failed as your attendance is less than 80%")
elif(attendance>=0.8):
print("You have failed due to average grade being lower than 6")
else:
print("You have failed due to average grade being lower than 6 and attendance lower than 80%")
The problem is that you're never resetting the value of valid, so once you set valid = True in the first while loop, none of the other loops will execute (because the loop condition will be false).
You don't need the valid variable in any case; instead of having a
conditional loop expression with a flag, just break out of the loop
when you receive a valid value:
while True:
grade1 = float( input("Enter the grade1: ") )
if grade1 <0 or grade1 > 10:
print('Please enter a grade between 0 and 10')
continue
else:
break
while True:
grade2 = float(input("Enter the grade2: "))
if grade2 < 0 or grade2 > 10:
print('Please enter a grade between 0 and 10')
continue
else:
break
while True:
absences = int(input("Enter the number of absences: "))
if type(absences)!=int:
print("Number of absences can only be an integer value")
continue
else:
break
while True:
total_classes = int(input("Enter the total number of classes: "))
if type(total_classes)!=int:
print("Total number of classes can only be an integer value")
continue
else:
break
Unrelated to your question, but when you have a boolean variable you
don't need to compare it explicitly to False (or True); you can
use the value of the variable itself as the condition:
while somevar == False:
You can just write:
while not somevar:

Python if elif and loops

I wrote this for my beginner class and I don't know how to get the NAME of the SECOND STUDENT with the 2nd highest score. After testing it, I believe the code works for the first student.
I think what I need is to store the highest score in to variable high_score and then the next highest in to second_score and then compare the third score to both the highest and second score. But I am confused on how to get the name of the second highest scoring student.
num_students = int(input("enter number of students: "))
high_score = 0
high_name = ""
second_name = ""
second_score = 0
for i in range(1,num_students + 1):
if num_students < 2:
break
if num_students >= 2:
name = input("enter student name: ")
score = int(input("enter student score: "))
if score > second_score:
if score > high_score:
second_score = high_score
high_score = score
high_name = name
elif score < high_score:
second_score = score
second_name = name
print()
print("Top Two Students")
print()
print(high_name,"'s score is", high_score)
print(second_name,"'s score is", second_score)
In addition to Gary02127's solution, I'd like to point out a few other improvements:
You should move if num_students < 2 outside of your loop. It would be enough to check the condition once after the user inputted the number of students.
You could also write for i in range(num_students). It doesn't matter if the range starts with 0 or 1 since you are not using i.
Also, if you are not using a variable, you could use _ (throwaway variable) instead. See more about for _ in range(num_students) here: What is the purpose of the single underscore "_" variable in Python?.
Instead of:
if score > second_score:
if score > high_score:
# ...
else:
# ...
You could also write:
if high_score < score:
# ...
elif second_score < score:
# ...
Here is a verbose solution considering suggested improvements:
num_students = int(input("Enter number of students: "))
if num_students < 2:
exit()
highest_name = None
highest_grade = 0
second_highest_name = None
second_highest_grade = 0
for _ in range(num_students):
name = input("Enter student's name: ")
grade = int(input("Enter student's score: "))
if highest_grade < grade:
second_highest_name = highest_name
second_highest_grade = highest_grade
highest_name = name
highest_grade = grade
elif second_highest_grade < grade:
second_highest_name = name
second_highest_grade = grade
print(highest_name, highest_grade) # highest grade
print(second_highest_name, second_highest_grade) # second highest grade
You could also use a list and sorted() (built-in function):
from operator import itemgetter
num_students = int(input("Enter number of students: "))
if num_students < 2:
exit()
grades = []
for _ in range(num_students):
name = input("Enter student's name: ")
grade = int(input("Enter student's score: "))
grades.append((name, grade))
grades = sorted(grades, key=itemgetter(1), reverse=True)
print(grades[0]) # highest grade
print(grades[1]) # second highest grade
You could also use a specialized list such as SortedList (requires external package):
from sortedcontainers import SortedList
num_students = int(input("Enter number of students: "))
if num_students < 2:
exit()
grades = SortedList(key=lambda record: -record[1])
for _ in range(num_students):
name = input("Enter student's name: ")
grade = int(input("Enter student's score: "))
grades.add((name, grade))
print(grades[0]) # highest grade
print(grades[1]) # second highest grade
Notes:
Difference between sorted() and str.sort(). sorted() creates a new sorted list whereas str.sort() modifies the current list.
itemgetter(1) is equals to lambda record: record[1].
You can install SortedList with: pip install sortedcontainers.
Here's a solution based on my previous comments to your original post.
num_students = int(input("enter number of students: "))
high_score = 0
high_name = ""
second_name = ""
second_score = 0
for i in range(1,num_students + 1):
if num_students < 2:
break
# if num_students >= 2: # don't need this "if" after previous "break"
name = input("enter student name: ")
score = int(input("enter student score: "))
if score > second_score:
if score > high_score:
second_score = high_score
second_name = high_name # NEW
high_score = score
high_name = name
else: # simplified to just a plain "else:"
second_score = score
second_name = name
print()
print("Top Two Students")
print()
print(high_name,"'s score is", high_score)
print(second_name,"'s score is", second_score)
Notice that simplifying that last "elif ...:" to a simple "else:" also solves a simple bug where entering the current high score again can be ignored and not captured. If you were to run your code as is and use input values "100 80 100", you would find the 2nd high score set to 80 instead of 100.
You can simply store the details in a list. And use list.sort() to sort the values according to the score.
Here is the working code:
num_students = int(input("Enter number of students: "))
scores = []
if num_students < 2:
print('Number of students less than 2')
exit()
for i in range(num_students):
name = input("Enter student's name: ")
score = int(input("Enter student's score: "))
scores.append([name, score])
scores.sort(key=lambda details: details[1], reverse=True)
print("Top Two Students")
print()
print(f"{scores[0][0]}'s score is {scores[0][1]}")
print(f"{scores[1][0]}'s score is {scores[1][1]}")

How can I print the report without the first in the list

I'm trying to display the names except the 'name' and trying to get the average of age without 'age' on the list and lastly get the average of the grade without the 'Grade'.
I have a problem I'm trying to print the names of the list without the first row in the list(['Name', 'Age', 'Grade']) without pop or removing them from the list.
studentDB = [['Name', 'Age', 'Grade'], ['Con', 20, 90.2],
['Juan', 45, 70.2], ['Jed', 39, 100.0]]
while True:
for i in range(len(studentDB)):
print(i, studentDB[i])
print("\n********** Hackathon ***********")
CRUD = """1- Add
2- Delete
3- Edit
4- Print Report
----------------
Enter a number: """
choice = float(input(CRUD))
if (choice == 1):
Name = input("Please Enter your Name: ")
Age = int(input("Please Enter your Age: "))
Grade = float(input("Please Enter your Grade: "))
studentDB.append([Name, Age, Grade])
print(studentDB)
elif (choice == 2):
Del = int(input("Please Enter the row you want to delete: "))
studentDB.pop(Del)
elif (choice == 3):
Del1 = int(input("Please Enter the row you want to delete: "))
Name1 = input("Please Enter your Name: ")
Age1 = int(input("Please Enter your Age: "))
Grade1 = float(input("Please Enter your Grade: "))
studentDB.pop(Del1)
studentDB.insert(Del1,[Name1, Age1, Grade1])
print(studentDB)
elif (choice == 4):
#here is the problem
for s in range(1, len(studentDB)):
print("")
print(f"There are in the {s} student table. The people included in the list are.")
else:
print("Invalid input")
Here is the output that I wanted to do
This is the online compiler: https://www.programiz.com/python-programming/online-compiler/
There can be many ways to solve this. One could be to use starting index in range and use slice while calculating average of age or grades.
from statistics import mean
while True:
# Use the start index in range.
for i in range(len(studentDB)):
print(i, studentDB[i])
print("\n********** Hackathon ***********")
CRUD = """1- Add
2- Delete
3- Edit
4- Print Report
----------------
Enter a number: """
choice = float(input(CRUD))
if (choice == 1):
Name = input("Please Enter your Name: ")
Age = int(input("Please Enter your Age: "))
Grade = float(input("Please Enter your Grade: "))
studentDB.append([Name, Age, Grade])
print(studentDB)
elif (choice == 2):
Del = int(input("Please Enter the row you want to delete: "))
studentDB.pop(Del)
elif (choice == 3):
Del1 = int(input("Please Enter the row you want to delete: "))
Name1 = input("Please Enter your Name: ")
Age1 = int(input("Please Enter your Age: "))
Grade1 = float(input("Please Enter your Grade: "))
studentDB.pop(Del1)
studentDB.insert(Del1,[Name1, Age1, Grade1])
print(studentDB)
elif (choice == 4):
#here is the problem
# Use slice to get the row from index 1 afterwards
print(f"There are in the {len(studentDB) - 1} records in the student table. The people included in the list are.")
print(",".join([student[0] for student in studentDB[1:]]))
average_age = mean([row[1] for row in studentDB[1:]])
average_grades = mean([row[2] for row in studentDB[1:]])
# Print average age and grades here
else:
print("Invalid input")```

Passing 'ValueError' & 'continue' in a function and call it

I am trying to check user inputs to ensure that:
1) It is a floating number
2) Floating number is not negative
I am trying to put above 2 checks into a function and call it after user has input into a variable.
However, I cant seem to put 'ValueError' & 'continue' in a function that I can call. Is this possible?
I have tried below code, but it repeats from the top when I key in 't' for salCredit, or any of the next few variables. The code will work if I were to repeat 'ValueError' & 'continue' for every variable. I'm just wondering if there is a shorter way of doing do?
def interestCalculator():
#User inputs required for calculation of interest earned.
while True:
try:
mul_AccBal = float(input("Enter your Account Balance: "))
#checkInputError(accBal)
salCredit = float(input("Enter your Salary: "))
#checkInputError(salCredit)
creditCard = float(input("Credit Card Spend (S$): "))
#checkInputError(creditCard)
except ValueError:
print("Please enter a valid number.")
continue
def checkInputError(userInput):
if userInput < 0:
print("Please enter a positive number.")
interestCalculator()
Expected results:
Scenario 1: if user inputs 't'
Enter your Account Balance: 5000
Enter your Salary: t
Please enter a valid number.
Enter your Salary: 500
Scenario 2: if user inputs negative number
Enter your Account Balance: 5000
Enter your Salary: -50
Please enter a valid number.
Enter your Salary: 500
Current results:
Scenario 1: if user inputs 't'
Enter your Account Balance: 5000
Enter your Salary: t
Please enter a valid number.
Enter your Account Balance:
Scenario 2: if user inputs negative number
Enter your Account Balance: 5000
Enter your Salary: -50
Please enter a positive number.
Credit Card Spend (S$):
You could create a function that continues prompting for input until a valid float is input
def get_float_input(prompt):
while True:
try:
user_input = float(input(prompt))
if user_input < 0:
print("Please enter a positive number.")
continue # start the while loop again
return user_input # return will break out of the while loop
except ValueError:
print("Please enter a valid number.")
mul_AccBal = get_float_input("Enter your Account Balance: ")
salCredit = get_float_input("Enter your Salary: ")
creditCard = get_float_input("Credit Card Spend (S$): ")
Try this:
def interestCalculator():
#User inputs required for calculation of interest earned.
while True:
invalid = True
while invalid:
try:
mul_AccBal = float(input("Enter your Account Balance: "))
invalid=checkInputError(salCredit)
except ValueError:
print("Please enter a valid number.")
continue
invalid = True
while invalid:
try:
salCredit = float(input("Enter your Salary: "))
invalid=checkInputError(salCredit)
except ValueError:
print("Please enter a valid number.")
continue
invalid = True
while invalid:
try:
creditCard = float(input("Credit Card Spend (S$): "))
invalid=checkInputError(salCredit)
except ValueError:
print("Please enter a valid number.")
continue
def checkInputError(userInput):
if userInput < 0:
print("Please enter a positive number.")
return True
return False
interestCalculator()
you need to break you while loop if all the input is successful (also note that the continue at the end of the while loop is unnecessary). and if you want to have a validation for every number separately, you could do something like this:
def get_float(message, retry_message="Please enter a valid number."):
while True:
try:
ret = float(input(message))
if ret >= 0:
return ret
else:
print(retry_message)
except ValueError:
print(retry_message)
def interestCalculator():
mul_AccBal = get_float("Enter your Account Balance: ")
salCredit = get_float("Enter your Salary: ")
creditCard = get_float("Credit Card Spend (S$): ")

Trying to call read/write functions

I am a beginner programmer learning python in my intro game development class. The current homework assignment is to create a function to read and write files. We have to do it also where we can use user input to find the file directory. The problem I'n currently having is that I can't figure out how to write the function to open and close the files. I'll post my code for any help. Thank you. I am only focused on Option 8 for the time being.
enter = 0
start = 0
Roger = ()
text_file = ()
line = open("read.txt", "r")
def read_file(line):
for line in text_file:
print(line)
return line
def close_file(text_file):
text_file.close()
return close_file
def update_score(scores, person, amount):
for score in scores:
if score[0].lower() == person.lower():
score[1] += amount
return scores
def update_score1(scores, person, amount):
for score in scores:
if score[0].lower() == person.lower():
score[1] -= amount
return scores
def addition(num1):
return num1 + num1
def square(num):
print("I'm in square")
return num * num
def display(message):
"""Display game instuctions"""
print(message)
def instructions():
"""Display game instuctions"""
print("Welcome to the world's greatest game")
def main():
str1 = ["Roger", 3456]
str2 = ["Justin", 2320]
str3 = ["Beth", 1422]
instructions()
scores = [str1, str2, str3]
start = input("Would you like to view the high score options? y/n ")
if start == "y":
print("""\
Hello! Welcome to the high scores!
Here are the current high score leaders!:
""")
print(scores)
print("""\n\
0 - Sort high scores
1 - Add high score
2 - Reverse the order
3 - Remove a score
4 - Square a number
5 - Add 2 numbers together
6 - Add to a score
7 - Subtract from a score
8 - Read a file
9 - Write to a file
""")
option = int(input("Please enter your selection "))
while option < 8:
print(scores)
if option == 0:
scores.sort()
print("These are the scores sorted alphabetically")
print(scores)
option = option = int(input("Please enter your selection"))
elif option == 1:
print(scores)
print("Please enter your name and score; After entering your name, hit the return key and enter your score")
name = input()
score = int(input())
entry = (name,score)
scores.append(entry)
print(scores)
option = option = int(input("Please enter your selection"))
elif option == 2:
print(scores)
scores.reverse()
print("\nHere are the scores reversed")
print(scores)
option = option = int(input("Please enter your selection"))
elif option == 3:
print(scores)
print("Please enter the high score you would like to remove. After typing the name, hit the return key and enter the score")
name1 = input()
score1 = int(input())
remove = (name1,score1)
scores.remove(remove)
print(scores)
option = option = int(input("Please enter your selection"))
elif option == 4:
val = int(input("Give me a number to square"))
sqd = square(val)
print(sqd)
option = option = int(input("Please enter your selection"))
elif option == 5:
val0 = int(input("Give me one number"))
val1 = int(input("Give me another number"))
addi = (val0 + val1)
print(addi)
option = option = int(input("Please enter your selection"))
elif option == 6:
print(scores)
sc0 = input("Please enter player whose score you would like to increase. ")
sc1 = int(input("Please enter the amount would would like to add to their score. "))
scores = update_score(scores, sc0, sc1)
print(scores)
option = option = int(input("Please enter your selection"))
elif option == 7:
sc2 = input("Please enter player whose score you would like to decrease. ")
sc3 = int(input("Please enter the amount you would like to subtract from their score. "))
scores = update_score1(scores, sc2, sc3)
print(scores)
while option <= 8:
if option == 8:
print (line)
text_file.close()
option = option = int(input("Please enter your selection"))
main()
Function to return a file's contents:
def read_file(filename):
return open(filename).read()
To write to a file:
def write_file(filename, toWrite):
file = open(filename, 'w')
file.write(toWrite)
file.close()
Example usage:
stuffInFile = read_file("myfile.txt")
write_file("myfile.txt", "I just wrote this to a file!")

Categories

Resources