Search code examples
pythonmathlogic

Calculating Quartiles Python


I'm having an issue with my code where I can't seem to calculate q1 and q3. The user inputs a list of numbers, and it's supposed to give you a data summary, however, I cannot seem to calculate the first and third quartiles. I will input 1,2,3,4,5,6, and I will get q1 = 2 and q3 = 5, which is correct, then I'll input 1,2,3,4,5,6,7,8,9,10, then get q1 = 2, q3 = 7, which is incorrect. Thanks for the help.

def quartiles(user_input):
    user_input.sort()
    length = len(user_input)

    # Initialize Values
    if length % 2 == 0:
        section_one = user_input[:(length // 2)]
        section_three = user_input[(length // 2):]
    else:
        section_one = user_input[:(length // 2)]
        section_three = user_input[(length // 2) + 1:]
    one_length = len(section_one)
    three_length = len(section_three)

    # Calculate Quartiles
    if one_length % 2 == 0:
        q1 = (section_one[one_length // 2 - 1] + section_one[one_length // 2]) / 2
    else:
        q1 = section_one[one_length // 2]

    if three_length % 2 == 0:
        q3 = (section_three[three_length // 2 - 1] + section_three[three_length // 2]) / 2
    else:
        q3 = section_three[three_length // 2]

    return q1, q3

  q1, q3 = quartiles(user_input)
  print("First Quartile:", q1)
  time.sleep(0.05)
  print("Third Quartile:", q3)

Solution

  • In testing out your code, I needed to attempt to determine how your list was being inputted, and my best educated guess was that you were entering in a list of numbers and then splitting the entered values similar to this.

    user_input = list(input("Enter list: ").split(","))    # Comes in as a list of strings
    

    If that is indeed the case, then the subsequent list is a list of string values and not integer values, and so will behave a bit differently in your function. Indeed, when I tested out that input method, I was able to replicate the unexpected behavior you got.

    craig@Vera:~/Python_Programs/Quartiles$ python3 Quartile.py 
    Enter list: 1,2,3,4,5,6
    The list: ['1', '2', '3', '4', '5', '6']
    First Quartile: 2
    Third Quartile: 5
    craig@Vera:~/Python_Programs/Quartiles$ python3 Quartile.py 
    Enter list: 1,2,3,4,5,6,7,8,9,10
    The list: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
    First Quartile: 2
    Third Quartile: 7
    

    Note for illustration purposes, I added a line of code in the test version of your code to print out the list that was produced.

    Most likely, what needs to be done is once the list has been initially built from the user input, it than needs to be converted from string values to integer values. With that, following is a refactored version of your code.

    import time
    
    def quartiles(user_input):
    
        user_input.sort()
        length = len(user_input)
    
        # Initialize Values
        if length % 2 == 0:
            section_one = user_input[:(length // 2)]
            section_three = user_input[(length // 2):]
        else:
            section_one = user_input[:(length // 2)]
            section_three = user_input[(length // 2) + 1:]
        one_length = len(section_one)
        three_length = len(section_three)
    
        # Calculate Quartiles
        if one_length % 2 == 0:
            q1 = (section_one[one_length // 2 - 1] + section_one[one_length // 2]) / 2
        else:
            q1 = section_one[one_length // 2]
    
        if three_length % 2 == 0:
            q3 = (section_three[three_length // 2 - 1] + section_three[three_length // 2]) / 2
        else:
            q3 = section_three[three_length // 2]
    
        return q1, q3
    
    entry_input = list(input("Enter list: ").split(","))    # Comes in as a list of strings
    
    user_input = []                                         # Initialize the user_input list
    
    for i in entry_input:
        user_input.append(int(i))                           # Converting each list entry to an integer
    
    print("The list:", user_input)
    
    q1, q3 = quartiles(user_input)
    print("First Quartile:", q1)
    time.sleep(0.05)
    print("Third Quartile:", q3)
    

    Following are the test output results utilizing your two list examples.

    craig@Vera:~/Python_Programs/Quartiles$ python3 Quartile.py 
    Enter list: 1,2,3,4,5,6
    The list: [1, 2, 3, 4, 5, 6]
    First Quartile: 2
    Third Quartile: 5
    craig@Vera:~/Python_Programs/Quartiles$ python3 Quartile.py 
    Enter list: 1,2,3,4,5,6,7,8,9,10
    The list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    First Quartile: 3
    Third Quartile: 8
    

    Give that a try to see if it addresses your requirements. The take-away from this is be careful how string values are evaluated as opposed to integer values.