timeit

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

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

Решение на Аритметични изрази от Божидар Карааргиров

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

Към профила на Божидар Карааргиров

Резултати

  • 6 точки от тестове
  • 0 бонус точки
  • 6 точки общо
  • 11 успешни тест(а)
  • 8 неуспешни тест(а)

Код

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
import collections


class ArithmeticsBase:
    def __add__(self, other):
        return Expression((self,
                           BinaryOperator("+", type(self.value).__add__),
                           other))

    def __sub__(self, other):
        return Expression((self,
                           BinaryOperator("-", type(self.value).__sub__),
                           other))

    def __mul__(self, other):
        return Expression((self,
                           BinaryOperator("*", type(self.value).__mul__),
                           other))

    def __truediv__(self, other):
        return Expression((self,
                           BinaryOperator("/", type(self.value).__truediv__),
                           other))


class Constant(ArithmeticsBase):
    def __init__(self, value):
        self.__setattr__('value', value)

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

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


class Variable(Constant):
    def __init__(self, value):
        self.__name = value
        self.__setattr__('value', 0)

    def __str__(self):
        return self.__name.__str__()

    def evaluate(self, **kwargs):
        # variables can have only 1 "variable"
        return kwargs[self.__name]


class BinaryOperator:
    def __init__(self, name, func):
        self.__name = name
        self.__operation = func

    def __str__(self):
        return self.__name.__str__()

    def apply(self, left, right):
        return self.__operation(left, right)


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

    def evaluate(self, **arguments):
        return Expression.apply(self.expression, arguments)

    def __str__(self):
        return Expression.expression_to_string(self.expression)

    @staticmethod
    def expression_to_string(expression):
        if isinstance(expression, collections.Iterable) is False:
            return str(expression)

        current_repr = "("
        for item in expression:
            if isinstance(item, collections.Iterable):
                current_repr += Expression.expression_to_string(item)
            elif type(item) is BinaryOperator:
                current_repr = current_repr + " " + str(item) + " "
            else:
                current_repr += str(item)

        current_repr += ")"
        return current_repr

    @staticmethod
    def apply(expression_structure, kwargs):
        if isinstance(expression_structure, collections.Iterable) is False:
            return expression_structure.evaluate(**kwargs)

        value = None
        current_operation = None

        for item in expression_structure:
            if current_operation is not None:
                value = current_operation.apply(value,
                                                Expression.apply(item, kwargs))
                current_operation = None
            elif type(item) is BinaryOperator:
                current_operation = item
            else:
                value = Expression.apply(item, kwargs)

        return value


def create_constant(value):
    return Constant(value)


def create_variable(name):
    return Variable(name)


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


def create_expression(expression_structure):
    return Expression(expression_structure)


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

EEEEEE.........EE..
======================================================================
ERROR: test_constant_and_right_hand_side_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_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_left_hand_side_literal_and_constant (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: unsupported operand type(s) for +: 'int' and 'Constant'

======================================================================
ERROR: test_left_hand_side_literal_and_variable (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: unsupported operand type(s) for +: 'int' and 'Variable'

======================================================================
ERROR: test_string_conversion_with_literals (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: unsupported operand type(s) for *: 'int' and 'Variable'

======================================================================
ERROR: test_variable_and_right_hand_side_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_arithmetics (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
AttributeError: 'Expression' object has no attribute 'value'

======================================================================
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.140s

FAILED (errors=8)

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

Божидар обнови решението на 20.03.2016 21:00 (преди над 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
import collections


class ArithmeticsBase:
    def __add__(self, other):
        return Expression((self,
                           BinaryOperator("+", type(self.value).__add__),
                           other))

    def __sub__(self, other):
        return Expression((self,
                           BinaryOperator("-", type(self.value).__sub__),
                           other))

    def __mul__(self, other):
        return Expression((self,
                           BinaryOperator("*", type(self.value).__mul__),
                           other))

    def __truediv__(self, other):
        return Expression((self,
                           BinaryOperator("/", type(self.value).__truediv__),
                           other))


class Constant(ArithmeticsBase):
    def __init__(self, value):
        self.__setattr__('value', value)

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

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


class Variable(Constant):
    def __init__(self, value):
        self.__name = value
        self.__setattr__('value', 0)

    def __str__(self):
        return self.__name.__str__()

    def evaluate(self, **kwargs):
        # variables can have only 1 "variable"
        return kwargs[self.__name]


class BinaryOperator:
    def __init__(self, name, func):
        self.__name = name
        self.__operation = func

    def __str__(self):
        return self.__name.__str__()

    def apply(self, left, right):
        return self.__operation(left, right)


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

    def evaluate(self, **arguments):
        return Expression.apply(self.expression, arguments)

    def __str__(self):
        return Expression.expression_to_string(self.expression)

    @staticmethod
    def expression_to_string(expression):
        if isinstance(expression, collections.Iterable) is False:
            return str(expression)

        current_repr = "("
        for item in expression:
            if isinstance(item, collections.Iterable):
                current_repr += Expression.expression_to_string(item)
            elif type(item) is BinaryOperator:
                current_repr = current_repr + " " + str(item) + " "
            else:
                current_repr += str(item)

        current_repr += ")"
        return current_repr

    @staticmethod
    def apply(expression_structure, kwargs):
        if isinstance(expression_structure, collections.Iterable) is False:
            return expression_structure.evaluate(**kwargs)

        value = None
        current_operation = None

        for item in expression_structure:
            if current_operation is not None:
                value = current_operation.apply(value,
                                                Expression.apply(item, kwargs))
                current_operation = None
            elif type(item) is BinaryOperator:
                current_operation = item
            else:
                value = Expression.apply(item, kwargs)

        return value


def create_constant(value):
    return Constant(value)


def create_variable(name):
    return Variable(name)


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


def create_expression(expression_structure):
    return Expression(expression_structure)


  • Липсват ти доста оператори за предефиниране :)
  • Никога не предпочитай self.__setattr__('value', value) пред self.value = value, освен ако някаква крайност не го налага.
  • Предпочитай str(x) пред x.__str__().
  • expression_to_string и apply са твърде сложни. Опрости ги.