A problem in 15/15


#1

I can't figure out what's the problem in my code. I'll be glad for help. Here it is:

def median(old_list):
new_list = sorted(old_list)
for i in old_list:
if len(old_list) == 1:
return new_list[0]
elif len(old_list) % 2 > 0:
return new_list[(len(new_list) % 2) +1]
elif len(old_list) % 2 == 0:
return new_list[len(new_list) % 2] + new_list[len(new_list) % 2 - 1] / 2.0

the mistake is: "Oops, try again. median([4, 5, 5, 4]) returned 6.5 instead of 4.5"


#2

@omerbs110 tak a look at your code below with comment on pitfalls

def median(old_list):
    
    new_list = sorted(old_list)
    #the for loop here really has no purpose
    #in your code
    #==========================
    #get rid of it and re-indent
    #==========================
    for i in old_list:
        if len(old_list) == 1:
            return new_list[0]
        elif len(old_list) % 2 > 0:
            #you wrote new_list[(len(new_list) %2)]
            #but thats incorrect becuse this will
            #always return the value at index 1
            #rather you must use '/' operator
            return new_list[(len(new_list) / 2)]
        elif len(old_list) % 2 == 0:
            #you were using the '%' operator here too which is wrong
            #also you need to remember BEDMAS
            #meaning you have to wrap everything in  a bracket
            #befor dividing by 2.0
            return (new_list[len(new_list) /2] + new_list[len(new_list) / 2 - 1]) / 2.0
        
print median([4,5,5,4])

#3

I took a different approach on this. Getting the flow of data from intake to return of median values was the aim for myself. To pseudocode it out, its as follows:

OPEN PROGRAM

Take in num[] list

Sort num[] list

Pass Sorted List to New List[]

Get the index length of New List[]

Assign a variable to New List index list / 2

If(index list Modulus 2 is NOT equal to 0):

return the value of NewList[variable]

else:

Return the value of (NewList[variable] + NewList[variable]-1)//2.0

CLOSE PROGRAM

My solution programatically looks like this:

input = int(raw_input("Please input your median number range now"))

median_num = [(input)]

def median(median_num):    
    median_index = 0
    x_num = []
    x_num = sorted(median_num)    
    median_index = len(x_num)
    m = median_index//2
    
    if median_index % 2 != 0:
        median_result = x_num[m]
    else:
        median_result = (x_num[m] + x_num[m-1])/2.0
    return median_result

#4

Thats good you can modify it to this

def median(median_num):    
    #median_index = 0
    #x_num = []
    x_num = sorted(median_num)    
    median_index = len(x_num)
    m = median_index//2
    
    if median_index % 2 != 0:
        median_result = x_num[m]
    else:
        median_result = (x_num[m] + x_num[m-1])/2.0
    return median_result

but I am trying to understand your logic here


#5

@rydan, To answer your question on logic, I'm taking in a number string, (strongly) parsing it and passing it to a list. I am not hard coding a number sequence in a list in my approach. Any suggestions for a better approach in Python?


#6

remember the median_num here

has nothing to do with the variable defined before
if your aim was to generate a list of random numbers you can try this

def median(median_num):    
    #median_index = 0
    #x_num = []
    x_num = sorted(median_num)    
    median_index = len(x_num)
    m = median_index//2
    
    #Add this little placeholder
    #if the list is empty
    #=========================
    if not median_num:
        return None
    #=========================
    
    if median_index % 2 != 0:
        median_result = x_num[m]
    else:
        median_result = (x_num[m] + x_num[m-1])/2.0
    return median_result


import random
input = raw_input("Please input your median number range now")
input = int(input) if input.isdigit() else 0
median_num = random.sample(range(input), input)
#or
#median_num = random.shuffle(range(input))
print median(median_num)

#7

Hi Rydan
Thanks for the heads up on the code. I love the use of Random in your code but it was not my intention to produce a list of random numbers. It was my intention to produce a list from the int object from raw_input and bring it into the function for sorting. I tested this in the editor and it now brings it in but does not produce the desired output. Take a look at my code, any ideas?

import math
input = int(raw_input("Please input your median number range now "))
median_num = [(input)]

def median(median_num):
    x_num = sorted(median_num)
    median_index = len(x_num)
    m = median_index//2

    if median_index % 2 != 0:
        median_result = x_num[m]
    else:
        median_result = (x_num[m] + x_num[m-1])/2.0
    return median_result
print median(median_num)

Should I be using getitem?


#8

This is what I did

def median(sequence):
sequence = sorted(list(sequence))
size = len(sequence)
if size % 2 == 0:
return(float(sequence[(size//2)]) + float(sequence[((size//2)-1)] ))/2
else:
return float(sequence[(size//2)])


#9

I am nowhere near adept at this, but try changing your third line to a variable that you don't use in your code for ease of debugging. I would then tell it to print both variables to test them. i.e. - print input and print num_list

My guess is that your median_num as defined by the raw input is not a list that will work in such a way. When I run those steps, I get that int() is not able to handle multiple number inputs at a time and then when you convert it to a list, it is seen as one index in the list. You need to convert it to a list in a different manner, potentially using .split() and appending your list.

Hope you figure it out!


#10

I looked at it again and figured it out. Couple of things:
a) Raw_Input wrapped in Int() will give you one int number, not many individual numbers
b) You need to as Rydan says get one list variable and use it all the way through
c) Be sure to iterate the str raw_input BUT don't forget to convert it to int using map()
d) Be sure to use floor division properly with float

Here is my final code for the problem noting my attempt that passed muster at Code Academy was far from correct.

import math
input = raw_input("Please input your median number range now ")
median_num = [] #Establish List for processing iteratively. Input len() = 1 otherwise
for i in input:
    median_num += i
print median_num

def median(median_num):
    median_num = map(int, median_num)#Converts str list to int list
    sorted(median_num, key = int)
    print median_num #TEST CODE - PROVE THE LIST IS SORTED
    median_index = len(median_num)
    print median_index #TEST CODE - PROVE THE LEN() RESULT IS ACCURATE
    m = median_index//2

    if median_index % 2 != 0:
        median_result = median_num[m]
    else:
        median_result = int((median_num[m] + median_num[m-1]))/2.0
    return median_result
print median(median_num)

Thanks guys for challenging me to continue debugging this and come out with a proper coding solution for this.


#11

I haven't ever tried this - does it do the same as splitting the raw_input data?

Also, I would think you might want to run a raw_input loop and have them hit enter after every number. When they type "done" have the while loop stop running. This could make it so that the UI is a bit smoother and you don't get people entering things in different ways. i.e. - 1 2 3 4 5 vs 1, 2, 3, 4, 5

def list_create():
    median_num = []
    input = raw_input("What is your first number? When done, hit enter."
    median_num.append(input)
    while str(input).lower() != "done": 
         input = raw_input("What is the next number? If no more numbers, type Done"}
         median_num.append(input)

That was really quick, sloppy coding and definitely needs work, but you get the idea. You can then run this function inside of your median function to have it be a pretty smooth thing.


#12

@tbhesswebber

for i in input:
median_num += i

In general terms, yes. It iterates over the input in the default data type it is entered in (str) and inputs each string (number) into the list median_num. Note raw_input does not interpret the data type so what is inputted will be stored as such in the raw_data variable. In Python 3, input() (updated data type) does interpret data types, which I think is troublesome. I would prefer to input the date type in what ever it is (e.g. int syntax: int(raw_data("input data here")) | default str syntax: raw_data("input data here")

Your idea on iterating from an input stream is doable, but you have not parsed the input from from str to int median_num = map(int, median_num) and you make it very tedious having to return each time something is entered. Better in my view to use my coding approach where the for loop iterates over single input and appends each element to median_num before it is then parsed in the function. You make a good point about wrapping the list input unto a function. Its a good idea.