timeit

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

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

Решение на Аритметични изрази от Ивета Чампоева

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

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

Резултати

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

Код

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
def normalize(value):
    if not isinstance(value, (Constant, Variable, Expression)):
        return Constant(value)
    else:
        return value


class Arithmetic:
    def __init__(self, value):
        self. value = value

    def __add__(self, value):
        value = normalize(value)
        plus = create_operator('+', lambda larg, rarg: larg + rarg)
        return create_expression((self, plus, value))

    def __radd__(self, value):
        value = normalize(value)
        plus = create_operator('+', lambda larg, rarg: larg + rarg)
        return create_expression((value, plus, self))

    def __sub__(self, value):
        value = normalize(value)
        minus = create_operator('-', lambda larg, rarg: larg - rarg)
        return create_expression((self, minus, value))

    def __rsub__(self, value):
        value = normalize(value)
        minus = create_operator('-', lambda larg, rarg: larg - rarg)
        return create_expression((value, minus, self))

    def __mul__(self, value):
        value = normalize(value)
        times = create_operator('*', lambda larg, rarg: larg * rarg)
        return create_expression((self, times, value))

    def __rmul__(self, value):
        value = normalize(value)
        times = create_operator('*', lambda larg, rarg: larg * rarg)
        return create_expression((value, times, self))

    def __truediv__(self, value):
        value = normalize(value)
        div = create_operator('/', lambda larg, rarg: larg / rarg)
        return create_expression((self, div, value))

    def __rtruediv__(self, value):
        value = normalize(value)
        div = create_operator('/', lambda larg, rarg: larg / rarg)
        return create_expression((value, div, self))

    def __getitem__(self, index):
        if isinstance(self, Expression):
            return self.expression_structure[index]


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

    @property
    def variable_names(self):
        return ()

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

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


def create_constant(value):
    return Constant(value)


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

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

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

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


def create_variable(name):
    return Variable(name)


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

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


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


def tuple_to_expression(element):
        if isinstance(element, tuple):
            return Expression(element)
        else:
            return element


class Expression(Arithmetic):
    def __init__(self, expression_structure):
        self.expression_structure = expression_structure

    @property
    def variable_names(self):
        left = tuple_to_expression(self.expression_structure[0])
        right = tuple_to_expression(self.expression_structure[2])
        return tuple(set(left.variable_names + right.variable_names))

    def __str__(self):
        left = tuple_to_expression(self.expression_structure[0])
        operator = self.expression_structure[1]
        right = tuple_to_expression(self.expression_structure[2])
        return '(' + str(left) + ' ' + str(operator) + ' ' + \
               str(right) + ')'

    def evaluate(self, **args):
        left = tuple_to_expression(self.expression_structure[0])
        operator = self.expression_structure[1]
        right = tuple_to_expression(self.expression_structure[2])
        return operator.function(left.evaluate(**args),
                                 right.evaluate(**args))


def create_expression(expression_structure):
    return Expression(expression_structure)

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

.E..............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
AttributeError: 'int' object has no attribute 'evaluate'

======================================================================
ERROR: test_variables_and_constants_extra_operators (test.TestNativeOperators)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/data/rails/pyfmi-2016/releases/20160307095126/lib/language/python/runner.py", line 67, in thread
    raise result
TypeError: unsupported operand type(s) for ** or pow(): 'Variable' and 'Variable'

----------------------------------------------------------------------
Ran 19 tests in 0.151s

FAILED (errors=2)

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

Ивета обнови решението на 20.03.2016 15:24 (преди над 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
def normalize(value):
    if not isinstance(value, (Constant, Variable, Expression)):
        return Constant(value)
    else:
        return value


class Arithmetic:
    def __init__(self, value):
        self. value = value

    def __add__(self, value):
        value = normalize(value)
        plus = create_operator('+', lambda larg, rarg: larg + rarg)
        return create_expression((self, plus, value))

    def __radd__(self, value):
        value = normalize(value)
        plus = create_operator('+', lambda larg, rarg: larg + rarg)
        return create_expression((value, plus, self))

    def __sub__(self, value):
        value = normalize(value)
        minus = create_operator('-', lambda larg, rarg: larg - rarg)
        return create_expression((self, minus, value))

    def __rsub__(self, value):
        value = normalize(value)
        minus = create_operator('-', lambda larg, rarg: larg - rarg)
        return create_expression((value, minus, self))

    def __mul__(self, value):
        value = normalize(value)
        times = create_operator('*', lambda larg, rarg: larg * rarg)
        return create_expression((self, times, value))

    def __rmul__(self, value):
        value = normalize(value)
        times = create_operator('*', lambda larg, rarg: larg * rarg)
        return create_expression((value, times, self))

    def __truediv__(self, value):
        value = normalize(value)
        div = create_operator('/', lambda larg, rarg: larg / rarg)
        return create_expression((self, div, value))

    def __rtruediv__(self, value):
        value = normalize(value)
        div = create_operator('/', lambda larg, rarg: larg / rarg)
        return create_expression((value, div, self))

    def __getitem__(self, index):
        if isinstance(self, Expression):
            return self.expression_structure[index]
        return self.value[index]


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

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

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


def create_constant(value):
    return Constant(value)


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

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

    def evaluate(self, **args):
        if self.name in args:
            return args[self.name]
        pass


def create_variable(name):
    return Variable(name)


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

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


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


class Expression(Arithmetic):
    def __init__(self, expression_structure):
        self.expression_structure = expression_structure

    @property
    def variable_names(self):
        container = []
        copy = self.expression_structure
        while isinstance(copy[0], (tuple, Expression)) or \
                isinstance(copy[2], (tuple, Expression)):
            if isinstance(copy[0], (tuple, Expression)) and \
               isinstance(copy[2], (tuple, Expression)):
                if isinstance(copy[0], tuple):
                    return tuple(set(Expression(copy[0]).variable_names +
                                     Expression(copy[2]).variable_names))
                else:
                    return tuple(set(copy[0].variable_names +
                                     copy[2].variable_names))
            if isinstance(copy[0], (tuple, Expression)):
                if type(copy[2]) == Variable:
                    container.append(copy[2].name)
                copy = copy[0]
            elif isinstance(copy[2], (tuple, Expression)):
                if type(copy[0]) == Variable:
                    container.append(copy[0].name)
                copy = copy[2]
        if type(copy[0]) == Variable:
            container.append(copy[0].name)
        if type(copy[2]) == Variable:
            container.append(copy[2].name)
        return tuple(set(container))

    def __str__(self):
        copy = self.expression_structure
        if type(copy[0]) == tuple and type(copy[2]) == tuple:
            return '(' + str(Expression(copy[0])) + ' ' + \
                   str(copy[1]) + ' ' + str(Expression(copy[2])) + ')'
        elif type(copy[0]) == tuple:
            return '(' + str(Expression(copy[0])) + ' ' + \
                   str(copy[1]) + ' ' + str(copy[2]) + ')'
        elif type(copy[2]) == tuple:
            return '(' + str(copy[0]) + ' ' + str(copy[1]) + ' ' + \
                   str(Expression(copy[2])) + ')'
        else:
            return '(' + str(copy[0]) + ' ' + str(copy[1]) + ' ' + \
                    str(copy[2]) + ')'

    def evaluate(self, **args):
        copy = self.expression_structure
        if type(copy[0]) == tuple and type(copy[2]) == tuple:
            return copy[1].function(Expression(copy[0]).evaluate(**args),
                                    Expression(copy[2]).evaluate(**args))
        elif type(copy[0]) == tuple:
            return copy[1].function(Expression(copy[0]).evaluate(**args),
                                    copy[2].evaluate(**args))
        elif type(copy[2]) == tuple:
            return copy[1].function(copy[0].evaluate(**args),
                                    Expression(copy[2]).evaluate(**args))
        else:
            return copy[1].function(copy[0].evaluate(**args),
                                    copy[2].evaluate(**args))


def create_expression(expression_structure):
    return Expression(expression_structure)
  • Можеш ли да преосмислиш normalize като декоратор, който да прилагаш на предефинираните оператори?
  • Проверката в evaluate на Variable не ти трябва, тъй като винаги ще подаваме необходимите аргументи.
  • Всички тези страшни вложени итерации и проверки на типове могат да се синтезират в няколко реда ползващи рекурсия и малко duck typing.

Ивета обнови решението на 21.03.2016 14:51 (преди над 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
def normalize(value):
    if not isinstance(value, (Constant, Variable, Expression)):
        return Constant(value)
    else:
        return value


class Arithmetic:
    def __init__(self, value):
        self. value = value

    def __add__(self, value):
        value = normalize(value)
        plus = create_operator('+', lambda larg, rarg: larg + rarg)
        return create_expression((self, plus, value))

    def __radd__(self, value):
        value = normalize(value)
        plus = create_operator('+', lambda larg, rarg: larg + rarg)
        return create_expression((value, plus, self))

    def __sub__(self, value):
        value = normalize(value)
        minus = create_operator('-', lambda larg, rarg: larg - rarg)
        return create_expression((self, minus, value))

    def __rsub__(self, value):
        value = normalize(value)
        minus = create_operator('-', lambda larg, rarg: larg - rarg)
        return create_expression((value, minus, self))

    def __mul__(self, value):
        value = normalize(value)
        times = create_operator('*', lambda larg, rarg: larg * rarg)
        return create_expression((self, times, value))

    def __rmul__(self, value):
        value = normalize(value)
        times = create_operator('*', lambda larg, rarg: larg * rarg)
        return create_expression((value, times, self))

    def __truediv__(self, value):
        value = normalize(value)
        div = create_operator('/', lambda larg, rarg: larg / rarg)
        return create_expression((self, div, value))

    def __rtruediv__(self, value):
        value = normalize(value)
        div = create_operator('/', lambda larg, rarg: larg / rarg)
        return create_expression((value, div, self))

    def __getitem__(self, index):
        if isinstance(self, Expression):
            return self.expression_structure[index]


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

    @property
    def variable_names(self):
        return ()

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

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


def create_constant(value):
    return Constant(value)


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

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

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

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


def create_variable(name):
    return Variable(name)


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

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


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


def tuple_to_expression(element):
        if isinstance(element, tuple):
            return Expression(element)
        else:
            return element


class Expression(Arithmetic):
    def __init__(self, expression_structure):
        self.expression_structure = expression_structure

    @property
    def variable_names(self):
        left = tuple_to_expression(self.expression_structure[0])
        right = tuple_to_expression(self.expression_structure[2])
        return tuple(set(left.variable_names + right.variable_names))

    def __str__(self):
        left = tuple_to_expression(self.expression_structure[0])
        operator = self.expression_structure[1]
        right = tuple_to_expression(self.expression_structure[2])
        return '(' + str(left) + ' ' + str(operator) + ' ' + \
               str(right) + ')'

    def evaluate(self, **args):
        left = tuple_to_expression(self.expression_structure[0])
        operator = self.expression_structure[1]
        right = tuple_to_expression(self.expression_structure[2])
        return operator.function(left.evaluate(**args),
                                 right.evaluate(**args))


def create_expression(expression_structure):
    return Expression(expression_structure)