0

I've created a code that allows a user to view the average score of the values that are in the file. In Example the Text File would look like the following:

Text File For Class 1: it is similar for each text file ; 2 and 3. just different names and values

Matt 2
Sid 4
Jhon 3
Harry 6

There are 3 classes altogether in which the user is prompted to choose which class they want to preview.

Code:

def main_menu():
        print ("\n         Main Menu        ")
        print ("1.Average Score of class = 'avg'")

main_menu()

option = input("option [avg]: ")
option_class = input("class: ")
one = "1.txt"
two = "2.txt"
three = "3.txt"
if option.lower() == 'avg' and option_class == '1':
    with open(one) as f:
        the_list = [int(l.strip().split()[-1]) for l in f]

        b = sum(the_list)
        length = len(the_list)
        avg = float(b) / length if length else 0
        print ("Average of Class is: ", avg)

if option.lower() == 'avg' and option_class == '2':
    with open(two) as f:
        the_list = [int(l.strip().split()[-1]) for l in f]

        b = sum(the_list)
        length = len(the_list)
        avg = float(b) / length if length else 0
        print ("Average of Class is: ", avg)

if option.lower() == 'avg' and option_class == '3':
    with open(three) as f:
        the_list = [int(l.strip().split()[-1]) for l in f]

        b = sum(the_list)
        length = len(the_list)
        avg = float(b) / length if length else 0
        print ("Average of Class is: ", avg)

Question If i wanted to Keep Repeating the code above so that the user can keep using it until they want to exit. so, is it possible to put the code into a while loop and only stop the code if the user wants to, i.e the user is prompted if they want to choose another option and class. NB: there will be other options such as alphabetical order however right now i only want to know how to do it for the average section.

1
  • 6
    I think this is the perfect time for you to learn how to write a proper function. Commented Oct 31, 2015 at 16:09

3 Answers 3

1

Best thing you can do is to make a loop for user input and write a function for listing the file.

def main_menu():
    print ("\n         Main Menu        ")
    print ("1.Average Score of class = 'avg'")

main_menu()

option = ""
options = ["1", "2", "3"]

one = "1.txt"
two = "2.txt"
three = "3.txt"

def read_text_file(file): # standalone function for viewing files to reduce duplicate code
    file += ".txt"
    with open(file) as f:
            the_list = [int(l.strip().split()[-1]) for l in f]

            b = sum(the_list)
            length = len(the_list)
            avg = float(b) / length if length else 0
            print ("Average of Class is: ", avg)

while True:

    option = input("option [avg]: ").lower()
    if option == "exit":
        break # checks if user want to exit a program
    else:
        option_class = input("class: ")

        if option == 'avg' and option_class in options:
            read_text_file(option_class)

        else:
            print("nothing to show, asking again")

print("end of program")
Sign up to request clarification or add additional context in comments.

Comments

0

As I mentioned in the comment section, you should leverage the power of functions here. By breaking down your components to manageable pieces, you actually afford yourself readability and flexibility. See code below, where I have two functions, one for averages and one for totals.

def get_class_average(class_number):

    filename = "{0}.txt".format(class_number)
    try:
        with open(filename) as f:
            the_list = [int(l.strip().split()[-1]) for l in f]
            b = sum(the_list)
            length = len(the_list)
            avg = float(b) / length if length else 0
            return avg
    except:
        print "No file with that name found."


def get_class_total(class_number):

    filename = "{0}.txt".format(class_number)
    try:
        with open(filename) as f:
            the_list = [int(l.strip().split()[-1]) for l in f]
            b = sum(the_list)
            return b
    except:
        print "No file with that name found."


def check_class_number(string_input):

    try:
        int(string_input)
        return True
    except ValueError:
        return False

if __name__ == "__main__":

    while True:

        input_val = raw_input(
            "Enter class number (enter 'exit' to quit program): ")
        if input_val == 'exit':
            break

        if check_class_number(input_val):  # If it's a valid class number.
            method = raw_input("Enter method: ")
            if method == 'avg':
                avg = get_class_average(int(input_val))
                print "The average of Class {0} is {1}".format(input_val, avg)
            elif method == 'sum':
                total = get_class_total(int(input_val))
                print "The total of Class {0} is {1}".format(input_val, total)
        else:
            print "That is not a valid class number."
            continue

Sample run:

enter image description here

The really fun part here is that you can even refactor get_class_average and get_class_total to be a single function that checks if the passed in method is avg or sum and returns the respective values from there (this is easily doable since you have practically the same lines of code for both functions, get_class_average just has an extra division involved).

Have fun.

Comments

0

Yes, you can just put your code within a while-loop and prompt the user for input:

def main_menu():
        print ("\n         Main Menu        ")
        print ("1.Average Score of class = 'avg'")
# End main_menu()

one = "1.txt"
two = "2.txt"
three = "3.txt"

keepGoing = True
while(keepGoing):
        main_menu()

        option = input("option [avg]: ")
        option_class = input("class: ")
        if option.lower() == 'avg' and option_class == '1':
            with open(one) as f:
                the_list = [int(l.strip().split()[-1]) for l in f]

                b = sum(the_list)
                length = len(the_list)
                avg = float(b) / length if length else 0
                print ("Average of Class is: ", avg)

        if option.lower() == 'avg' and option_class == '2':
            with open(two) as f:
                the_list = [int(l.strip().split()[-1]) for l in f]

                b = sum(the_list)
                length = len(the_list)
                avg = float(b) / length if length else 0
                print ("Average of Class is: ", avg)

        if option.lower() == 'avg' and option_class == '3':
            with open(three) as f:
                the_list = [int(l.strip().split()[-1]) for l in f]

                b = sum(the_list)
                length = len(the_list)
                avg = float(b) / length if length else 0
                print ("Average of Class is: ", avg)

        # Prompt user for input on whether they want to continue or not:

        while(True):
                keepGoingStr = input("Would you like to continue? (Y/N)\n>>> ").lower()
                if(keepGoingStr[0] == 'y'):
                        # Keep going
                        keepGoing = True
                        break
                elif(keepGoingStr[0] == 'n')
                        # Stop
                        keepGoing = False
                        break
                else:
                        print("Sorry, your input did not make sense.\nPlease enter either Y or N for yes or no.")
                # end if
        # end while - keep going input

# End While(keepGoing)

As mentioned in the comments, though, you should consider breaking up your code into functions.

1 Comment

You should consider removing duplicite code using a separate function for viewing the files like I did in my answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.