Løsningsforslag 10

Oppgave 1
from math import sqrt

def pearson_corr(xs,ys):
    xs_mean = sum(xs)/len(xs)
    ys_mean = sum(ys)/len(ys)

    xs_diffs = [ x - xs_mean for x in xs ]
    ys_diffs = [ y - ys_mean for y in ys ]
    
    num = sum( x*y for x,y in zip(xs_diffs, ys_diffs) )

    dx2 = sum(x**2 for x in xs_diffs)
    dy2 = sum(y**2 for y in ys_diffs)
    denom = sqrt(dx2 * dy2)

    return num/denom

#uten inline loops.
def pearson_corr(x, y):
    n = len(x)

    # gjennomsnitt 
    mean_x = sum(x) / n
    mean_y = sum(y) / n

    #beregner teller og nevner
    numerator = 0
    denominator_x = 0
    denominator_y = 0

    for i in range(n):
        #teller
        numerator += (x[i] - mean_x) * (y[i] - mean_y)
        
        #nevner venstre side
        denominator_x += (x[i] - mean_x) ** 2
        
        #nevner høyre side
        denominator_y += (y[i] - mean_y) ** 2

    # deler nevner på teller
    corr = numerator / (denominator_x ** 0.5 * denominator_y ** 0.5)

    return corr
Oppgave 2
#DEL A
def make_stats(matches):
    teams = {} # dict of dicts: name -> {GF, GA, GD, PT}
    for name_A, name_B, score_A, score_B in matches:
        if name_A not in teams:
            teams[name_A] = {'GF':0, 'GA':0, 'GD':0, 'PT':0}
        if name_B not in teams:
            teams[name_B] = {'GF':0, 'GA':0, 'GD':0, 'PT':0}
        
        if score_A > score_B:
            teams[name_A]['PT'] += 3
        elif score_B > score_A:
            teams[name_B]['PT'] += 3
        else:
            teams[name_A]['PT'] += 1
            teams[name_B]['PT'] += 1

        teams[name_A]['GF'] += score_A
        teams[name_B]['GF'] += score_B
              
        teams[name_A]['GA'] += score_B
        teams[name_B]['GA'] += score_A        
        
        teams[name_A]['GD'] += score_A - score_B
        teams[name_B]['GD'] += score_B - score_A

    return teams


#DEL B
def compare(matches, data, a, b):
    for crit in ['PT','GD','GF']:
        if data[a][crit] > data[b][crit]:
            #print(a,b,crit)
            return 1
        elif data[a][crit] < data[b][crit]:
            #print(b,a,crit)
            return -1
    # find match
    for nx, ny, x, y in matches:
        if nx == b and ny == a:
            nx,ny = ny,nx
            x,y = y,x
        if nx == a and ny == b:
            #print(a,b,f'{x}:{y}')
            if x > y:
                return 1
            elif y > x:
                return -1
            print("LOTTERY",a,b)
            return 0
Oppgave 3

def meal_list(fridge, ingredient_list):
    """
    1. set up a tally that counts the ingredients you do have for a given 
       meal in your fridge
    2. _for each_ ingredient in a meal
    3. check _if_ that ingredient is in your fridge
    4. _add_ to tally of ingredients for a given meal that are in your fridge
    5. once you have looped through the ingredient list, 
       check _if_ your count tally matches the number of items in the ingredient list
    """
    count = 0
    for ingredient in ingredient_list:
        if ingredient in fridge:
            count += 1
    return count == len(ingredient_list)
    
    # if you really want it on one line, this works, too:
    # return sum(i in fridge for i in ingredient_list) == len(ingredient_list)



def meal_options(fridge, meals):
    """
    1. _for each_ tuple pair in meals
    2. run meal_list()
    3. _if_ function evaluates to true, then add to a new list of meals that are possible to make
    """
    meal_options_ls = []
    for meal in meals:
        if meal_list(fridge, meal[1]): 
            meal_options_ls.append(meal[0])
    return meal_options_ls


def to_buy(fridge, ingredient_list):
    shopping = []
    for ingredient in ingredient_list:
        if ingredient not in fridge:
            shopping.append(ingredient)
    return shopping
Oppgave 4
from math import log

# no error check required
a = int(input("Factor A: "))
b = int(input("Factor B: "))

# keep original input for printout later
in_a, in_b = a, b

if a > b:
    a, b = b, a

maxbinary = int(log(a, 2))

# using reverse order, since we start with the biggest binary
reverse_table = reversed([(2**n, b * 2**n) for n in range(maxbinary+1)])


# output strings
output = []
# marked numbers (for use in the + lines later)
a_list, b_list = [], []

# pick out the Xs
for bin, bfact in reverse_table:
    if bin <= a:
        tag = 'X'
        a -= bin
        a_list.append(bin)
        b_list.append(bfact)
    else:
        tag = ' '
    output.append(f'{tag} {bin:4d} {bfact:4d}')

# reverse all lists back to increasing
for l in (a_list, b_list, output):
    l[:] = reversed(l)
    
divider = "=" * 25

print(divider)

print('\n'.join(output))

print(divider)

print(' + '.join(map(str, a_list)), '=', sum(a_list))
print(' + '.join(map(str, b_list)), '=', sum(b_list))

print(divider)

print(f'{in_a} * {in_b} = {in_a * in_b}')
Oppgave 5
"""A function for justifying the margins of a text so that
they are straight.
"""


def line_w_whitespace(words, len_w_one_space, line_len):
    """Add whitespace evenly to a list of words to return
    a string of given length.

    words: a list of strings
    len_w_one_space: an integer, combined length of words
    with one space between
    line_len: an integer, length of output string
    """
    extra_spaces = line_len - len_w_one_space

    positions = len(words) - 1

    equal_spaces = extra_spaces // positions + 1
    remaining_spaces = extra_spaces % positions

    for i in range(remaining_spaces):
        words[-(i % positions + 2)] += " "

    return (" " * equal_spaces).join(words)


def justify(text, line_len):
    """Justify margins of a text to be straight with lines
    of given length.

    text: a string, the text to be justified
    line_len: an integer, the length of the output lines
    """
    words = text.split()

    if not words:
        return ""

    current_line = words[:1]
    current_len = len(current_line[0])
    justified_text = ""

    for w in words[1:]:
        word_len = len(w)
        if current_len + word_len + 1 <= line_len:
            current_line.append(w)
            current_len += word_len + 1
        else:
            justified_text += (
                line_w_whitespace(current_line, current_len, line_len) + "\n"
            )
            current_line = [w]
            current_len = word_len

    justified_text += " ".join(current_line)

    return justified_text



text = """Alice was beginning to get very tired of sitting by her sister
        on the bank, and of having nothing to do: once or twice she had peeped
        into the book her sister was reading, but it had no pictures
        or conversations in it, 'and what is the use
        of a book,' thought Alice 'without pictures or conversation?'"""

print(justify(text, 60))