Challenge 7 Megathread

For any and all questions relating to challenge 7. :point_down:

For a tutorial on how to use Jupyter Notebook, we put together this video:

Still have questions? Read all the FAQs here.

Is this too cheeky?
import pandas as pd
def sortDF(table):
return table.sort_values("weight")

df = sortDF(pd.DataFrame(user_boxes))

16 Likes

Whoops, were we supposed to learn how to bubble sort??
I just turned it into a list then sorted the list.

def sort_boxes(weight_box_dict: dict) -> list:

better_boxes = [[box_name, weight] for box_name, weight in zip(weight_box_dict["box_name"], weight_box_dict["weight"])]

return sorted(better_boxes, key = lambda box: box[1])

Is this really inefficient?

2 Likes

Thought I’d try a recursive solution as a bonus! Here’s my approach:

def sort(a):
    if len(a['weight']) == 1:
        return [a['box_name'][0]]
    
    min_index = 0
    
    for i in range(len(a['weight'])):
        if a['weight'][i] < a['weight'][min_index]:
            min_index = i
            
    box = a['box_name'][min_index]      
    a['weight'].pop(min_index)
    a['box_name'].pop(min_index)
    return [box] + sort(a)
    
print(sort(user_boxes))
5 Likes

Ended up exploring the function toolset for dicts:

import collections

def sort_box_asc(weight, name):
    converted_dictionary = dict(zip(weight, name))
    sorted_dictionary = collections.OrderedDict(sorted(converted_dictionary.items()))
    for x, y in sorted_dictionary.items():
        print (y)
        
sort_box_asc(user_boxes['weight'], user_boxes['box_name'])
5 Likes

:exploding_head: i feel like i took the longest possible route after seeing this

3 Likes

I might need to read more on python…I’m used to java’s verbosity. Here’s my long quicksort implementation

box_dictionary = {
    2 : 'box2',
    4 : 'box1',
    13 : 'box6',
    14 : 'box5',
    18 : 'box3',
    21 : 'box4'
}

def partition(arr, low, high): 
    i = (low-1)         # index of smaller element 
    pivot = arr[high]     # pivot 
  
    for j in range(low, high): 
  
        # If current element is smaller than or 
        # equal to pivot 
        if arr[j] <= pivot: 
  
            # increment index of smaller element 
            i = i+1
            arr[i], arr[j] = arr[j], arr[i] 
  
    arr[i+1], arr[high] = arr[high], arr[i+1] 
    return (i+1)


def quickSort(arr, low, high): 
    if len(arr) == 1: 
        return arr 
    if low < high: 
  
        # pi is partitioning index, arr[p] is now 
        # at right place 
        pi = partition(arr, low, high) 
  
        # Separately sort elements before 
        # partition and after partition 
        quickSort(arr, low, pi-1) 
        quickSort(arr, pi+1, high) 

weight_list = user_boxes['weight']
quickSort(weight_list,0,len(weight_list)-1)
for i in range(len(weight_list)):
    print(box_dictionary[weight_list[i]])

Having learned python has map last time:

def open_boxes(dict_box):
def helper(row):
return [row[0], row[1]]
thing = list(map(helper, zip(dict_box[‘weight’],dict_box[‘box_name’])))
thing.sort()
print(thing)

open_boxes(user_boxes)

1 Like

Nice to see a ton of variety in the posts here. Lots of ways to skin this cat! I kept mine simple.

def swap_position(rangeA, lowpos, hipos):
    temp = rangeA[lowpos]
    rangeA[lowpos] = rangeA[hipos]
    rangeA[hipos] = temp
    
listlen = len(user_boxes['weight'])
for i in range(listlen):
    for j in range(listlen-i):
        if (user_boxes['weight'][i] > user_boxes['weight'][listlen-1-j]):
            swap_position(user_boxes['weight'], i, listlen-1-j)
            swap_position(user_boxes['box_name'], i, listlen-1-j)
print (user_boxes['box_name'])

So far my answer is given below:

user_boxes = {'weight': [4,2,18,21,14,13],
              'box_name': ['box1','box2', 'box3', 'box4', 'box5', 'box6']
             }
def open_box_order(lst):
	       l = lst['weight']
	       b = lst['box_name']
	       for i in range(len(l)):
		      for j in range(i + 1, len(l)):
			      if l[i] > l[j]:
				       l[i], l[j] = l[j], l[i]
				       b[i], b[j] = b[j], b[I]
open_box_order(user_boxes)
print(user_boxes)
6 Likes

Well since everyone else is showing how they skinned this cat, here’s mine.

def sortWeight(box):
    w = box['weight']
    bn = box['box_name']
    for i in range(len(w)):
        for j in range(len(w) - 1):
            if w [j] > w [j+1]:
                w[j], w[j+1] = w[j+1], w[j]
                bn[j], bn[j+1] = bn[j+1], bn[j]
    return print(bn)

sortWeight(user_boxes)
2 Likes

OK so I feel like my answer is not that elegant but I couldn’t remember how recursion works! I wanted the solution without running the function more than once.

 def sortem(dict):
    weights = dict['weight']
    names = dict['box_name']
    ordered = []            # box order
    ow = []                 # weight order
    for i in range(len(weights)):
        if ow == []:
            ow.append(weights[i])
            ordered.append(names[i])
        elif weights[i] > max(ow):
            ow.append(weights[i])
            ordered.append(names[i])
        elif weights[i] < min(ow):
            ow.insert(0, weights[i])
            ordered.insert(0, names[i])
        else:
            for j in range(len(ow)):
                if weights[i] < ow[j]:
                    ow.insert(j, weights[i])
                    ordered.insert(j, names[i])
                    break
    return ordered

Separately, I defined a min and max function. Obviously, they were not meant for values outside this dataset and I could have imported a module but I wanted to do it all without external assistance:

def min(list):
  smallest = 100
  for i in range(len(list)):
    if list[i] < smallest:
      smallest = list[i]
  return smallest


def max(list):
    largest = 0
    for i in range(len(list)):
        if list[i] > largest:
            largest = list[i]
    return largest

Other than learning how to declare and call a bubble sort function, what would be the purpose of calling a function only once in the program?

2 Likes

I know it wasn’t the proper way to do it for the challenge but the result was the same so here it is:

weight_list = [4,2,18,21,14,13]
print(sorted(weight_list))

I’m still getting the hang of this so I am still figuring out other ways to do it that are more accurate to the challenge but just thought I’d through it out there.

2 Likes

Nice;
Mine is this:
def sortBoxes(df):
result = []
temp = {}
weight = df[‘weight’]
box_name = df[‘box_name’]
for i in range(len(weight)):
temp[weight[i]] = box_name[i]
weight.sort()
for i in range(len(weight)):
result.append(temp[weight[i]])
return result
sortBoxes(user_boxes)

1 Like

why write your own sorting function when something already exists that does the job if the data is better organized:

better_dict = {"box1": 4, "box2": 2, "box3": 18, "box4": 21, "box5": 14, "box6": 13}
print(sorted(better_dict, key=better_dict.get))

not that teaching people how to write a function is a bad idea, but teaching them to write a sorting function when every language out there already has many of these built in is not the best example…

4 Likes

Is it just me or is this a horrible use of a dictionary? Two lists that you must cross-reference?
A more logical use would be user_boxes = {“box1” : 4, “box2” : 2, “box3” : 18, etc. }

In fact, this is making the exercise much harder - I’m having to keep a record of the index of the box weights instead of sorting the actually weights/boxes, an extra complication.

6 Likes

In a real scenario I would have used pandas to create a table, as in the challenge description, sorted by that. But I rarely write functions at the moment and wanted to practice.
Here’s my function description:
Zip the two lists together and use list() to create a list of tuples. Sort the list of tuples by element 0 (default) and print element 1.

  def open_box(user_boxes):
        ordered_by_weight = sorted(list(zip(user_boxes['weight'],user_boxes['box_name'])))
        for weight, box in ordered_by_weight:
            print(box)
2 Likes