RunestoneInteractive / fopp

Foundations of Python Programming
https://runestone.academy/runestone/static/fopp/index.html
38 stars 120 forks source link

Activity 2 of Project 11: float compare of the test result #301

Closed leefurong closed 4 years ago

leefurong commented 4 years ago

Describe the bug It seems Activity 2 of Project 11 don't support float differences. image

To Reproduce Steps to reproduce the behavior:

  1. Go to 'Project 11

  2. Scroll to Activity 2: (Calculate the total usage percentage ...)

  3. Paste the code


# your code here
def append_lists(list_of_list, list_of_data):
    for i, data in enumerate(list_of_data):
        if len(list_of_list)<=i:
            list_of_list.append([])
        list_of_list[i].append(data)

def split_multi_line(s):
    return list(map(lambda x: x.split(','), s.split('\n')))

def get_data(filename, ignore_heading):
    print("get_data")
    s = open(filename).read()
    print("read s")
    rows = split_multi_line(s)[1:]
    print("splitted")
    data_lists = []
    for row in rows:
        append_lists(data_lists, row)
    print("finished")
    return data_lists

def is_sorted(seq, by):
    for i in range(0, len(seq), 2):
        if not by(seq[i], seq[i+1]):
            print(seq[i], seq[i+1])
            return False
    return True

# is_decreasing = partial(is_sorted, by=(lambda a,b: a>=b))
def is_decreasing(seq):
    return is_sorted(seq, lambda a,b: a>=b)

(ranks, words, parts, freqs, dispersions) =get_data("words5000.csv", True)

top_10_by_dict = []
bottom_10_by_dict = []

def adjust(seq, keep_head):
    seq.sort(key=lambda x: x["freq"], reverse=True)
    while len(seq)>10:
        i = keep_head and 10 or 0
        seq.pop(i)

for word, freq in zip(words, map(int, freqs)):
    should_add_top = len(top_10_by_dict)<10 or freq>top_10_by_dict[9]['freq']
    should_add_bottom = len(bottom_10_by_dict)<10 or freq<bottom_10_by_dict[0]['freq']
    if should_add_top:
        top_10_by_dict.append({"word": word, "freq": freq})
        adjust(top_10_by_dict, True)
    if should_add_bottom:
        bottom_10_by_dict.append({"word": word, "freq": freq})
        adjust(bottom_10_by_dict, False)

total = sum(map(int, freqs))
print(total)
top_10 = sum(list(map(lambda d: int(d["freq"]), top_10_by_dict)))/float(total)
bottom_10 = sum(list(map(lambda d: int(d["freq"]),  bottom_10_by_dict)))/float(total)

print(top_10)
print(bottom_10)
  1. Click "Save & Run"
  2. See error: bottom_10 passed, but top_10 failed.

Expected behavior top_10 should pass, because the difference is very small. You might see the notes like this:

Expected 0.276829737262 to equal 0.276

Screenshots

image

Desktop (please complete the following information):

Javascript Console Not related.

leefurong commented 4 years ago

I misunderstood the Quiz. In fact we don't need to sort the data by frequency. Just use the order from the raw data is OK. Eventually I passed the Quiz via the following code.


# your code here
def append_lists(list_of_list, list_of_data):
    for i, data in enumerate(list_of_data):
        if len(list_of_list)<=i:
            list_of_list.append([])
        list_of_list[i].append(data)

def split_multi_line(s):
    return list(map(lambda x: x.split(','), s.split('\n')))

def get_data(filename, ignore_heading):
    print("get_data")
    s = open(filename).read()
    print("read s")
    rows = split_multi_line(s)[1:]
    print("splitted")
    data_lists = []
    for row in rows:
        append_lists(data_lists, row)
    print("finished")
    return data_lists

def is_sorted(seq, by):
    for i in range(0, len(seq), 2):
        if not by(seq[i], seq[i+1]):
            print(seq[i], seq[i+1])
            return False
    return True

(ranks, words, parts, freqs, dispersions) =get_data("words5000.csv", True)

total = sum(map(int, freqs))
print(total)
top_10 = sum(map(int,freqs[:10]))/float(total)
bottom_10 = sum(map(int,freqs[-10:]))/float(total)

print(top_10)
print(bottom_10)