@mtf/

Dimensional Analysis Challenge

Python

https://discuss.codecademy.com/t/dimensional-analysis-challenge-proposal/428806

fork
loading
Files
  • main.py
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# @alexcraig proof of concept
def seperate(a):
    """ splits into unit and power dict """

    # make into array
    a = [u.split(" ** ") for u in a.split(" * ")]

    # turn array into dict
    a = dict([u[0]] + [int(u[1])] if len(u) == 2 else u + [1] for u in a)
        
    return a

def calculateUnits(a, b):
    """ calculates units of a * b """

    # split into dictionaries of units and powers
    a, b = seperate(a), seperate(b)

    # combine dictionaries
    c = {x: a.get(x,0) + b.get(x,0) for x in set(a).union(b)}
    
    # rebuild output
    out = [k + " ** " + str(v) if v >= 2 else k for (k, v) in c.items() if v]
    out = " * ".join(out)
    return out

print(calculateUnits("kg * m * s ** 0", "N * s ** 2 * kg ** -1 * m ** -1"))
# end of submission

class Fibonacci:

    def __init__(self):
        self.store = {0: 0, 1: 1}
        self.counter = 0

    def fibonacci(self, n):
        self.counter += 1

        if n in self.store.keys():
            return self.store[n]
        
        else:
            result = self.fibonacci(n-1) + self.fibonacci(n-2)
            self.store[n] = result
            return result

# @ionatan contribution
from collections import namedtuple, Counter
from functools import reduce
from itertools import groupby
from operator import itemgetter, attrgetter
from pprint import pprint

Term = namedtuple('Term', ['unit', 'constant'], defaults=[1])


def multiply(a, b):
    return reduce(add, [
        [Term(unit=(aa.unit + bb.unit), constant=(aa.constant * bb.constant))]
        for aa in a
        for bb in b
    ])


def divide(a, b):
    def negate(counter):
        return Counter({k: -v for k, v in counter.items()})

    return multiply(
        a,
        [Term(unit=negate(x.unit), constant=1/x.constant) for x in b]
    )


def subtract(a, b):
    return add(
        a,
        [Term(unit=bb.unit, constant=-bb.constant) for bb in b]
    )

def add(a, b):
    def group(it, key=None):
        'strict (non-lazy) version of itertools.groupby'
        return [[*vals] for _, vals in groupby(it, key=key)]

    def term_sort_key(term):
        return sorted(term.unit.items(), key=itemgetter(0))

    termgroups = group(
        sorted(a + b, key=term_sort_key),
        key=attrgetter('unit')
    )
    # sheesh, I can't set local vars in python list comps?
    return [t for t in [
        Term(ts[0].unit, sum(t.constant for t in ts))
        for ts in termgroups
    ] if t.constant != 0]

pprint(multiply(
    [
        Term(Counter({'a': 1, 'b': 1}), 3),
        Term(Counter({'c': 1, 'd': 1}), 2),
    ],
    [
        Term(Counter({'a': 1, 'b': 1}), 3),
        Term(Counter({'c': 1, 'd': 1}), 2),
    ],
))
# end of submission

# new submission of @ionatan
from collections import Counter
from functools import reduce
from operator import itemgetter
from pprint import pprint


class Expr(Counter):
    pass


class Unit(Counter):
    def __hash__(self):
        return hash(tuple(sorted(self.items(), key=itemgetter(0))))


def multiply(a, b):
    return reduce(add, [
        Expr({Unit(a_unit + b_unit): a_const * b_const})
        for a_unit, a_const in a.items()
        for b_unit, b_const in b.items()
    ])


def divide(a, b):
    return multiply(
        a,
        Expr({unit: 1/const for unit, const in b.items()})
    )


def negate(counter):
    return Expr({k: -v for k, v in counter.items()})


def subtract(a, b):
    return add(a, negate(b))


def add(a, b):
    return Expr(a + b)


pprint(multiply(
    Expr({
        Unit({'a': 1, 'b': 1}): 3,
        Unit({'c': 1, 'd': 1}): 2,
    }),
    Expr({
        Unit({'a': 1, 'b': 1}): 3,
        Unit({'c': 1, 'd': 1}): 2,
    }),
))