timeit

Програмиране с Python

Курс във Факултета по Математика и Информатика към СУ

Решение на Аритметични изрази от Светомир Стоименов

Обратно към всички решения

Към профила на Светомир Стоименов

Резултати

  • 9 точки от тестове
  • 0 бонус точки
  • 9 точки общо
  • 18 успешни тест(а)
  • 1 неуспешни тест(а)

Код

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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
class Operator:
    def __init__(self, symbol, func):
        self.symbol = symbol
        self.func = func

    def __call__(self, x, y):
        return self.func(x, y)

    def __str__(self):
        return self.symbol


class Operators:
    plus = Operator('+', lambda lhs, rhs: lhs + rhs)
    minus = Operator('-', lambda lhs, rhs: lhs - rhs)
    times = Operator('*', lambda lhs, rhs: lhs * rhs)
    divide = Operator('/', lambda lhs, rhs: lhs / rhs)
    floor_divide = Operator('//', lambda lhs, rhs: lhs // rhs)
    modulo = Operator('%', lambda lhs, rhs: lhs % rhs)
    power = Operator('**', lambda lhs, rhs: lhs ** rhs)
    left_shift = Operator('<<', lambda lhs, rhs: lhs << rhs)
    right_shift = Operator('>>', lambda lhs, rhs: lhs >> rhs)
    bit_xor = Operator('^', lambda lhs, rhs: lhs ^ rhs)
    bit_or = Operator('|', lambda lhs, rhs: lhs | rhs)
    bit_and = Operator('&', lambda lhs, rhs: lhs & rhs)
    div_mod = Operator('divmod?', divmod)


def to_evaluatable(item):
    if isinstance(item, Evaluatable):
        return item
    return create_constant(item)


class Evaluatable:
    def __add__(self, other):
        return Expression(self, Operators.plus, to_evaluatable(other))

    def __radd__(self, other):
        return to_evaluatable(other) + self

    def __mul__(self, other):
        return Expression(self, Operators.times, to_evaluatable(other))

    def __rmul__(self, other):
        return to_evaluatable(other) * self

    def __sub__(self, other):
        return Expression(self, Operators.minus, to_evaluatable(other))

    def __rsub__(self, other):
        return to_evaluatable(other) - self

    def __truediv__(self, other):
        return Expression(self, Operators.divide, to_evaluatable(other))

    def __rtruediv__(self, other):
        return to_evaluatable(other) / self

    def __floordiv__(self, other):
        return Expression(self, Operators.floor_divide, to_evaluatable(other))

    def __rfloordiv__(self, other):
        return to_evaluatable(other) // self

    def __mod__(self, other):
        return Expression(self, Operators.modulo, to_evaluatable(other))

    def __rmod__(self, other):
        return to_evaluatable(other) % self

    def __pow__(self, other):
        return Expression(self, Operators.power, to_evaluatable(other))

    def __rpow__(self, other):
        return to_evaluatable(other) ** self

    def __lshift__(self, other):
        return Expression(self, Operators.left_shift, to_evaluatable(other))

    def __rlshift__(self, other):
        return to_evaluatable(other) << self

    def __rshift__(self, other):
        return Expression(self, Operators.right_shift, to_evaluatable(other))

    def __rrshift__(self, other):
        return to_evaluatable(other) >> self

    def __and__(self, other):
        return Expression(self, Operators.bit_and, to_evaluatable(other))

    def __rand__(self, other):
        return to_evaluatable(other) & self

    def __or__(self, other):
        return Expression(self, Operators.bit_or, to_evaluatable(other))

    def __ror__(self, other):
        return to_evaluatable(other) | self

    def __xor__(self, other):
        return Expression(self, Operators.bit_xor, to_evaluatable(other))

    def __rxor__(self, other):
        return to_evaluatable(other) ^ self

    def __divmod__(self, other):
        return Expression(self, Operators.div_mod, to_evaluatable(other))

    def __rdivmod__(self, other):
        return divmod(to_evaluatable(other), self)


class Variable(Evaluatable):
    def __init__(self, name):
        self.name = name

    def evaluate(self, **kwargs):
        return kwargs[self.name]

    @property
    def variable_names(self):
        return tuple(self.name)

    def __str__(self):
        return self.name


class Constant(Evaluatable):
    def __init__(self, value):
        self.value = value

    def evaluate(self, **kwargs):
        return self.value

    @property
    def variable_names(self):
        return tuple()

    def __str__(self):
        return str(self.value)


class Expression(Evaluatable):
    def __init__(self, left, operator, right):
        self.left = left
        self.operator = operator
        self.right = right

    @property
    def variable_names(self):
        return tuple(set(self.left.variable_names + self.right.variable_names))

    def evaluate(self, **kwargs):
        left_kwargs = {k: kwargs[k] for k in self.left.variable_names}
        right_kwargs = {k: kwargs[k] for k in self.right.variable_names}
        left_val = self.left.evaluate(**left_kwargs)
        right_val = self.right.evaluate(**right_kwargs)
        return self.operator(left_val, right_val)

    def __str__(self):
        left = str(self.left)
        operator = str(self.operator)
        right = str(self.right)
        return '({} {} {})'.format(left, operator, right)


def create_expression(expression_structure):
    if isinstance(expression_structure, (Evaluatable, Operator)):
        return expression_structure
    left = create_expression(expression_structure[0])
    operator = create_expression(expression_structure[1])
    right = create_expression(expression_structure[2])
    return Expression(left, operator, right)


def create_variable(name):
    return Variable(name)


def create_operator(symbol, function):
    return Operator(symbol, function)


def create_constant(value):
    return Constant(value)

Лог от изпълнението

.E.................
======================================================================
ERROR: test_create_expression_with_literal (test.TestArithmeticsWithLiterals)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/data/rails/pyfmi-2016/releases/20160307095126/lib/language/python/runner.py", line 67, in thread
    raise result
TypeError: 'int' object is not subscriptable

----------------------------------------------------------------------
Ran 19 tests in 0.115s

FAILED (errors=1)

История (3 версии и 1 коментар)

Светомир обнови решението на 17.03.2016 19:54 (преди над 1 година)

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
class Evaluatable:
    def evaluate(**kwargs):
        return 42

    def __add__(self, other):
        if not isinstance(other, Evaluatable):
            other = create_constant(other)
        plus = create_operator('+', lambda lhs, rhs: lhs + rhs)
        return Expression(self, plus, other)

    def __radd__(self, other):
        return (self + other).inverted()

    def __mul__(self, other):
        if not isinstance(other, Evaluatable):
            other = create_constant(other)
        times = create_operator('*', lambda lhs, rhs: lhs * rhs)
        return Expression(self, times, other)

    def __rmul__(self, other):
        return (self * other).inverted()

    def __sub__(self, other):
        if not isinstance(other, Evaluatable):
            other = create_constant(other)
        minus = create_operator('-', lambda lhs, rhs: lhs - rhs)
        return Expression(self, minus, other)

    def __rsub__(self, other):
        return (self - other).inverted()

    def __truediv__(self, other):
        if not isinstance(other, Evaluatable):
            other = create_constant(other)
        divide = create_operator('/', lambda lhs, rhs: lhs / rhs)
        return Expression(self, divide, other)

    def __rtruediv__(self, other):
        return (self / other).inverted()


class Operator:
    def __init__(self, symbol, func):
        self.symbol = symbol
        self.func = func

    def __call__(self, x, y):
        return self.func(x, y)

    def __str__(self):
        return self.symbol


class Variable(Evaluatable):
    def __init__(self, name):
        self.name = name

    def evaluate(self, **kwargs):
        return kwargs[self.name]

    @property
    def variable_names(self):
        return tuple(self.name)

    def __str__(self):
        return self.name


class Constant(Evaluatable):
    def __init__(self, value):
        self.value = value

    def evaluate(self, **kwargs):
        return self.value

    @property
    def variable_names(self):
        return tuple()

    def __str__(self):
        return str(self.value)


class Expression(Evaluatable):
    def __init__(self, left, operator, right):
        self.left = left
        self.operator = operator
        self.right = right

    @property
    def variable_names(self):
        return tuple(set(self.left.variable_names+self.right.variable_names))

    def evaluate(self, **kwargs):
        left_kwargs = {k: kwargs[k] for k in self.left.variable_names}
        right_kwargs = {k: kwargs[k] for k in self.right.variable_names}
        left_val = self.left.evaluate(**left_kwargs)
        right_val = self.right.evaluate(**right_kwargs)
        return self.operator(left_val, right_val)

    def __str__(self):
        left = str(self.left)
        op = str(self.operator)
        right = str(self.right)
        return '({} {} {})'.format(left, op, right)

    def inverted(self):
        return Expression(self.right, self.operator, self.left)


def create_expression(expression_structure):
    if isinstance(expression_structure, Evaluatable):
        return expression_structure
    if isinstance(expression_structure, Operator):
        return expression_structure
    left = create_expression(expression_structure[0])
    operator = create_expression(expression_structure[1])
    right = create_expression(expression_structure[2])
    return Expression(left, operator, right)


def create_variable(name):
    return Variable(name)


def create_operator(symbol, function):
    return Operator(symbol, function)


def create_constant(value):
    return Constant(value)
  • if not isinstance(other, Evaluatable): го повтаряш за всеки оператор. Измисли начин да избегнеш това повторение на код.
  • Първите два if-а в create_expression водят до един и същи резултат. Обедини ги в едно условие.
  • Идеята с метода inverted е почти толкова хитра колкото имплементацията на evaluate метода в Evaluatable :D

Светомир обнови решението на 20.03.2016 12:26 (преди над 1 година)

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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
class Operator:
    def __init__(self, symbol, func):
        self.symbol = symbol
        self.func = func

    def __call__(self, x, y):
        return self.func(x, y)

    def __str__(self):
        return self.symbol


class Operators:
    plus = Operator('+', lambda lhs, rhs: lhs + rhs)
    minus = Operator('-', lambda lhs, rhs: lhs - rhs)
    times = Operator('*', lambda lhs, rhs: lhs * rhs)
    divide = Operator('/', lambda lhs, rhs: lhs / rhs)
    floor_divide = Operator('//', lambda lhs, rhs: lhs // rhs)
    modulo = Operator('%', lambda lhs, rhs: lhs % rhs)
    power = Operator('**', lambda lhs, rhs: lhs ** rhs)
    left_shift = Operator('<<', lambda lhs, rhs: lhs << rhs)
    right_shift = Operator('>>', lambda lhs, rhs: lhs >> rhs)
    bit_xor = Operator('^', lambda lhs, rhs: lhs ^ rhs)
    bit_or = Operator('|', lambda lhs, rhs: lhs | rhs)
    bit_and = Operator('&', lambda lhs, rhs: lhs & rhs)


def to_evaluatable(item):
    if isinstance(item, Evaluatable):
        return item
    return create_constant(item)


class Evaluatable:
    def __add__(self, other):
        return Expression(self, Operators.plus, to_evaluatable(other))

    def __radd__(self, other):
        return to_evaluatable(other) + self

    def __mul__(self, other):
        return Expression(self, Operators.times, to_evaluatable(other))

    def __rmul__(self, other):
        return to_evaluatable(other) * self

    def __sub__(self, other):
        return Expression(self, Operators.minus, to_evaluatable(other))

    def __rsub__(self, other):
        return to_evaluatable(other) - self

    def __truediv__(self, other):
        return Expression(self, Operators.divide, to_evaluatable(other))

    def __rtruediv__(self, other):
        return to_evaluatable(other) / self

    def __floordiv__(self, other):
        return Expression(self, Operators.floor_divide, to_evaluatable(other))

    def __rfloordiv__(self, other):
        return to_evaluatable(other) // self

    def __mod__(self, other):
        return Expression(self, Operators.modulo, to_evaluatable(other))

    def __rmod__(self, other):
        return to_evaluatable(other) % self

    def __pow__(self, other):
        return Expression(self, Operators.power, to_evaluatable(other))

    def __rpow__(self, other):
        return to_evaluatable(other) ** self

    def __lshift__(self, other):
        return Expression(self, Operators.left_shift, to_evaluatable(other))

    def __rlshift__(self, other):
        return to_evaluatable(other) << self

    def __rshift__(self, other):
        return Expression(self, Operators.right_shift, to_evaluatable(other))

    def __rrshift__(self, other):
        return to_evaluatable(other) >> self

    def __and__(self, other):
        return Expression(self, Operators.bit_and, to_evaluatable(other))

    def __rand__(self, other):
        return to_evaluatable(other) & self

    def __or__(self, other):
        return Expression(self, Operators.bit_or, to_evaluatable(other))

    def __ror__(self, other):
        return to_evaluatable(other) | self

    def __xor__(self, other):
        return Expression(self, Operators.bit_xor, to_evaluatable(other))

    def __rxor__(self, other):
        return to_evaluatable(other) ^ self


class Variable(Evaluatable):
    def __init__(self, name):
        self.name = name

    def evaluate(self, **kwargs):
        return kwargs[self.name]

    @property
    def variable_names(self):
        return tuple(self.name)

    def __str__(self):
        return self.name


class Constant(Evaluatable):
    def __init__(self, value):
        self.value = value

    def evaluate(self, **kwargs):
        return self.value

    @property
    def variable_names(self):
        return tuple()

    def __str__(self):
        return str(self.value)


class Expression(Evaluatable):
    def __init__(self, left, operator, right):
        self.left = left
        self.operator = operator
        self.right = right

    @property
    def variable_names(self):
        return tuple(set(self.left.variable_names + self.right.variable_names))

    def evaluate(self, **kwargs):
        left_kwargs = {k: kwargs[k] for k in self.left.variable_names}
        right_kwargs = {k: kwargs[k] for k in self.right.variable_names}
        left_val = self.left.evaluate(**left_kwargs)
        right_val = self.right.evaluate(**right_kwargs)
        return self.operator(left_val, right_val)

    def __str__(self):
        left = str(self.left)
        operator = str(self.operator)
        right = str(self.right)
        return '({} {} {})'.format(left, operator, right)


def create_expression(expression_structure):
    if isinstance(expression_structure, (Evaluatable, Operator)):
        return expression_structure
    left = create_expression(expression_structure[0])
    operator = create_expression(expression_structure[1])
    right = create_expression(expression_structure[2])
    return Expression(left, operator, right)


def create_variable(name):
    return Variable(name)


def create_operator(symbol, function):
    return Operator(symbol, function)


def create_constant(value):
    return Constant(value)

Светомир обнови решението на 21.03.2016 16:06 (преди над 1 година)

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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
class Operator:
    def __init__(self, symbol, func):
        self.symbol = symbol
        self.func = func

    def __call__(self, x, y):
        return self.func(x, y)

    def __str__(self):
        return self.symbol


class Operators:
    plus = Operator('+', lambda lhs, rhs: lhs + rhs)
    minus = Operator('-', lambda lhs, rhs: lhs - rhs)
    times = Operator('*', lambda lhs, rhs: lhs * rhs)
    divide = Operator('/', lambda lhs, rhs: lhs / rhs)
    floor_divide = Operator('//', lambda lhs, rhs: lhs // rhs)
    modulo = Operator('%', lambda lhs, rhs: lhs % rhs)
    power = Operator('**', lambda lhs, rhs: lhs ** rhs)
    left_shift = Operator('<<', lambda lhs, rhs: lhs << rhs)
    right_shift = Operator('>>', lambda lhs, rhs: lhs >> rhs)
    bit_xor = Operator('^', lambda lhs, rhs: lhs ^ rhs)
    bit_or = Operator('|', lambda lhs, rhs: lhs | rhs)
    bit_and = Operator('&', lambda lhs, rhs: lhs & rhs)
    div_mod = Operator('divmod?', divmod)


def to_evaluatable(item):
    if isinstance(item, Evaluatable):
        return item
    return create_constant(item)


class Evaluatable:
    def __add__(self, other):
        return Expression(self, Operators.plus, to_evaluatable(other))

    def __radd__(self, other):
        return to_evaluatable(other) + self

    def __mul__(self, other):
        return Expression(self, Operators.times, to_evaluatable(other))

    def __rmul__(self, other):
        return to_evaluatable(other) * self

    def __sub__(self, other):
        return Expression(self, Operators.minus, to_evaluatable(other))

    def __rsub__(self, other):
        return to_evaluatable(other) - self

    def __truediv__(self, other):
        return Expression(self, Operators.divide, to_evaluatable(other))

    def __rtruediv__(self, other):
        return to_evaluatable(other) / self

    def __floordiv__(self, other):
        return Expression(self, Operators.floor_divide, to_evaluatable(other))

    def __rfloordiv__(self, other):
        return to_evaluatable(other) // self

    def __mod__(self, other):
        return Expression(self, Operators.modulo, to_evaluatable(other))

    def __rmod__(self, other):
        return to_evaluatable(other) % self

    def __pow__(self, other):
        return Expression(self, Operators.power, to_evaluatable(other))

    def __rpow__(self, other):
        return to_evaluatable(other) ** self

    def __lshift__(self, other):
        return Expression(self, Operators.left_shift, to_evaluatable(other))

    def __rlshift__(self, other):
        return to_evaluatable(other) << self

    def __rshift__(self, other):
        return Expression(self, Operators.right_shift, to_evaluatable(other))

    def __rrshift__(self, other):
        return to_evaluatable(other) >> self

    def __and__(self, other):
        return Expression(self, Operators.bit_and, to_evaluatable(other))

    def __rand__(self, other):
        return to_evaluatable(other) & self

    def __or__(self, other):
        return Expression(self, Operators.bit_or, to_evaluatable(other))

    def __ror__(self, other):
        return to_evaluatable(other) | self

    def __xor__(self, other):
        return Expression(self, Operators.bit_xor, to_evaluatable(other))

    def __rxor__(self, other):
        return to_evaluatable(other) ^ self

    def __divmod__(self, other):
        return Expression(self, Operators.div_mod, to_evaluatable(other))

    def __rdivmod__(self, other):
        return divmod(to_evaluatable(other), self)


class Variable(Evaluatable):
    def __init__(self, name):
        self.name = name

    def evaluate(self, **kwargs):
        return kwargs[self.name]

    @property
    def variable_names(self):
        return tuple(self.name)

    def __str__(self):
        return self.name


class Constant(Evaluatable):
    def __init__(self, value):
        self.value = value

    def evaluate(self, **kwargs):
        return self.value

    @property
    def variable_names(self):
        return tuple()

    def __str__(self):
        return str(self.value)


class Expression(Evaluatable):
    def __init__(self, left, operator, right):
        self.left = left
        self.operator = operator
        self.right = right

    @property
    def variable_names(self):
        return tuple(set(self.left.variable_names + self.right.variable_names))

    def evaluate(self, **kwargs):
        left_kwargs = {k: kwargs[k] for k in self.left.variable_names}
        right_kwargs = {k: kwargs[k] for k in self.right.variable_names}
        left_val = self.left.evaluate(**left_kwargs)
        right_val = self.right.evaluate(**right_kwargs)
        return self.operator(left_val, right_val)

    def __str__(self):
        left = str(self.left)
        operator = str(self.operator)
        right = str(self.right)
        return '({} {} {})'.format(left, operator, right)


def create_expression(expression_structure):
    if isinstance(expression_structure, (Evaluatable, Operator)):
        return expression_structure
    left = create_expression(expression_structure[0])
    operator = create_expression(expression_structure[1])
    right = create_expression(expression_structure[2])
    return Expression(left, operator, right)


def create_variable(name):
    return Variable(name)


def create_operator(symbol, function):
    return Operator(symbol, function)


def create_constant(value):
    return Constant(value)