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
def create_constant(value):
    return Constant(value)


def create_variable(name):
    return Variable(name)


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


def create_expression(expression_structure):
    return Expression(expression_structure)


class MathTerm:
    def create_plus_operator(self):
        return create_operator('+', lambda lhs, rhs: lhs + rhs)

    def create_minus_operator(self):
        return create_operator('-', lambda lhs, rhs: lhs - rhs)

    def create_times_operator(self):
        return create_operator('*', lambda lhs, rhs: lhs * rhs)

    def create_by_operator(self):
        return create_operator('/', lambda lhs, rhs: lhs / rhs)

    def __mul__(self, other):
        return Expression((self, self.create_times_operator(), other))

    def __add__(self, other):
        return Expression((self, self.create_plus_operator(), other))

    def __sub__(self, other):
        return Expression((self, self.create_minus_operator(), other))

    def __truediv__(self, other):
        return Expression((self, self.create_by_operator(), other))

    def __rsub__(self, other):
        return Expression((other, self.create_minus_operator(), self))

    def __rtruediv__(self, other):
        return Expression((other, self.create_by_operator(), self))

    def __rmul__(self, other):
        return Expression((other, self.create_times_operator(), self))

    def __radd__(self, other):
        return Expression((other, self.create_plus_operator(), self))


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

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

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


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

    def __str__(self):
        return self.name

    def evaluate(self, **args):
        for key, value in args.items():
            if key == self.name:
                return value


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

    def __str__(self):
        return self.symbol


class Expression(MathTerm):
    def __init__(self, expression_structure):
        self.expression_structure = expression_structure
        self.variable_names = self.extract_variable_names()

    def __str__(self):
        components_str = [self.expression_component_str(c) for c
                          in self.expression_structure]
        return "{}{}{}".format('(', ' '.join(components_str), ')')

    def expression_component_str(self, component):
        if not hasattr(component, '__iter__'):
            return str(component)
        else:
            compound_component_str = [self.expression_component_str(c) for c
                                      in component]
            return "{}{}{}".format('(', ' '.join(compound_component_str), ')')

    def extract_variable_names(self):
        variables = []
        for component in self.expression_structure:
            if self.variables_from_component(component) is not None:
                variables.append(self.variables_from_component(component))
        return self.flatten(variables)

    def variables_from_component(self, component):
        if isinstance(component, Variable):
            return component.name
        elif isinstance(component, Expression):
            return [self.variables_from_component(c) for c
                    in component.expression_structure
                    if self.variables_from_component(c) is not None]

    def flatten(self, to_flatten):
        if to_flatten == []:
            return to_flatten
        if isinstance(to_flatten[0], list):
            return self.flatten(to_flatten[0]) + self.flatten(to_flatten[1:])
        return to_flatten[:1] + self.flatten(to_flatten[1:])

    def evaluate(self, **variables):
        self_to_str = str(self)

        for key, value in variables.items():
            self_to_str = self_to_str.replace(key, str(value))

        return eval(self_to_str)

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

................E..
======================================================================
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.125s

FAILED (errors=1)

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

Алекс обнови решението на 18.03.2016 22:09 (преди над 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
def create_constant(value):
    return Constant(value)


def create_variable(name):
    return Variable(name)


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


def create_expression(expression_structure):
    return Expression(expression_structure)


def create_plus_operator():
    return create_operator('+', lambda lhs, rhs: lhs + rhs)


def create_minus_operator():
    return create_operator('-', lambda lhs, rhs: lhs - rhs)


def create_times_operator():
    return create_operator('*', lambda lhs, rhs: lhs * rhs)


def create_by_operator():
    return create_operator('/', lambda lhs, rhs: lhs / rhs)


class MathTerm:
    def __mul__(self, other):
        return Expression((self, create_times_operator(), other))

    def __add__(self, other):
        return Expression((self, create_plus_operator(), other))

    def __sub__(self, other):
        return Expression((self, create_minus_operator(), other))

    def __truediv__(self, other):
        return Expression((self, create_by_operator(), other))

    def __rsub__(self, other):
        return Expression((other, create_minus_operator(), self))

    def __rtruediv__(self, other):
        return Expression((other, create_by_operator(), self))

    def __rmul__(self, other):
        return Expression((other, create_times_operator(), self))

    def __radd__(self, other):
        return Expression((other, create_plus_operator(), self))


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

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

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


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

    def __str__(self):
        return self.name

    def evaluate(self, **args):
        for key, value in args.items():
            if key == self.name:
                return value


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

    def __str__(self):
        return self.symbol


class Expression(MathTerm):
    def __init__(self, expression_structure):
        self.expression_structure = expression_structure
        self.variable_names = self.extract_variable_names()

    def __str__(self):
        components_str = [self.expression_component_str(c) for c
                          in self.expression_structure]
        return '(' + ' '.join(components_str) + ')'

    def expression_component_str(self, component):
        if not hasattr(component, '__iter__'):
            return str(component)
        else:
            compound_component_str = [self.expression_component_str(c) for c
                                      in component]
            return '(' + ' '.join(compound_component_str) + ')'

    def extract_variable_names(self):
        variable_names = [self.variable_names_from_component(component)
                          for component in self.expression_structure
                          if self.variable_names_from_component(component)
                          is not None]
        return self.flatten(variable_names)

    def variable_names_from_component(self, component):
        if type(component) is Variable:
            return component.name
        elif type(component) is Expression:
            return [self.variable_names_from_component(c) for c
                    in component.expression_structure
                    if self.variable_names_from_component(c) is not None]

    def flatten(self, l):
        if l == []:
            return l
        if isinstance(l[0], list):
            return self.flatten(l[0]) + self.flatten(l[1:])
        return l[:1] + self.flatten(l[1:])

    def evaluate(self, **variables):
        self_to_str = str(self)

        for key, value in variables.items():
            self_to_str = self_to_str.replace(key, str(value))

        return eval(self_to_str)
  • Опитай се да минеш без eval().
  • create_x_operator функциите ти са само за вътрешно ползване и няма нужда да са функции в глобалния scope. В този ред на мисли, можеш да минеш и без тях като цяло.
  • l е лошо име за променлива.
  • Сравнявай типове с isinstance, вместо с type.
  • Предпочитай да използваш str.format() пред конкатениране на низове.
  • Когато един list comprehension стане на четири реда, предпочитай да го разбиеш до "нормален" for.

Алекс обнови решението на 20.03.2016 21:49 (преди над 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
def create_constant(value):
    return Constant(value)


def create_variable(name):
    return Variable(name)


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


def create_expression(expression_structure):
    return Expression(expression_structure)


class MathTerm:
    def create_plus_operator(self):
        return create_operator('+', lambda lhs, rhs: lhs + rhs)

    def create_minus_operator(self):
        return create_operator('-', lambda lhs, rhs: lhs - rhs)

    def create_times_operator(self):
        return create_operator('*', lambda lhs, rhs: lhs * rhs)

    def create_by_operator(self):
        return create_operator('/', lambda lhs, rhs: lhs / rhs)

    def __mul__(self, other):
        return Expression((self, self.create_times_operator(), other))

    def __add__(self, other):
        return Expression((self, self.create_plus_operator(), other))

    def __sub__(self, other):
        return Expression((self, self.create_minus_operator(), other))

    def __truediv__(self, other):
        return Expression((self, self.create_by_operator(), other))

    def __rsub__(self, other):
        return Expression((other, self.create_minus_operator(), self))

    def __rtruediv__(self, other):
        return Expression((other, self.create_by_operator(), self))

    def __rmul__(self, other):
        return Expression((other, self.create_times_operator(), self))

    def __radd__(self, other):
        return Expression((other, self.create_plus_operator(), self))


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

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

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


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

    def __str__(self):
        return self.name

    def evaluate(self, **args):
        for key, value in args.items():
            if key == self.name:
                return value


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

    def __str__(self):
        return self.symbol


class Expression(MathTerm):
    def __init__(self, expression_structure):
        self.expression_structure = expression_structure
        self.variable_names = self.extract_variable_names()

    def __str__(self):
        components_str = [self.expression_component_str(c) for c
                          in self.expression_structure]
        return "{}{}{}".format('(', ' '.join(components_str), ')')

    def expression_component_str(self, component):
        if not hasattr(component, '__iter__'):
            return str(component)
        else:
            compound_component_str = [self.expression_component_str(c) for c
                                      in component]
            return "{}{}{}".format('(', ' '.join(compound_component_str), ')')

    def extract_variable_names(self):
        variables = []
        for component in self.expression_structure:
            if self.variables_from_component(component) is not None:
                variables.append(self.variables_from_component(component))
        return self.flatten(variables)

    def variables_from_component(self, component):
        if isinstance(component, Variable):
            return component.name
        elif isinstance(component, Expression):
            return [self.variables_from_component(c) for c
                    in component.expression_structure
                    if self.variables_from_component(c) is not None]

    def flatten(self, to_flatten):
        if to_flatten == []:
            return to_flatten
        if isinstance(to_flatten[0], list):
            return self.flatten(to_flatten[0]) + self.flatten(to_flatten[1:])
        return to_flatten[:1] + self.flatten(to_flatten[1:])

    def evaluate(self, **variables):
        self_to_str = str(self)

        for key, value in variables.items():
            self_to_str = self_to_str.replace(key, str(value))

        return eval(self_to_str)