Уведомления

Группа в Telegram: @pythonsu

#1 Окт. 30, 2011 11:37:08

Brony
От:
Зарегистрирован: 2011-06-21
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

Первая программа, калькулятор, в стиле ООП

Переписал. Лучше?

#! /usr/bin/python

'''Calculator in object oriented style.
For start GUI or Console use the run method of the object.
Install Tkinter for use GUI.
'''

try:
from Tkinter import \
Tk, Frame, Entry, Button, \
END, TOP, LEFT, RIGHT
except ImportError:
print 'For GUI Tkinter needed'

class Logic:

def __init__(self):
self.result = ''
self.binary_operation = ''
self.first_number_string = ''
self.second_number_string = ''
self.negative_number = False

self.switch = {'.': self.dot,
'=': self.calculate, 'c': self.reset,
'/': lambda: self.operation('/'),
'-': lambda: self.operation('-'),
'*': lambda: self.operation('*'),
'+': lambda: self.operation('+'),
'0': lambda: self.combination('0'),
'1': lambda: self.combination('1'),
'2': lambda: self.combination('2'),
'3': lambda: self.combination('3'),
'4': lambda: self.combination('4'),
'5': lambda: self.combination('5'),
'6': lambda: self.combination('6'),
'7': lambda: self.combination('7'),
'8': lambda: self.combination('8'),
'9': lambda: self.combination('9')}

def write(self, char):
if char in self.switch:
self.switch[char]()

def combination(self, digit):
'''Combination the number from digits'''
if self.negative_number:
# This number is negative
digit = '-' + digit
self.negative_number = False
if self.result:
# Old result is not needed
self.result = ''
self.first_number_string += digit
self.show(self.first_number_string)

def operation(self, char):
'''Arithmetic operations'''
if self.result:
# Use the result of the previous calculation
self.first_number_string = self.result
self.result = ''
if self.first_number_string:
if self.second_number_string:
# Continue to enter numbers
self.calculate()
self.first_number_string = self.result
self.result = ''
self.second_number_string = self.first_number_string
self.first_number_string = ''
self.binary_operation = char
self.show(self.binary_operation)
elif char == '-':
# We remember that the number is less than zero
self.negative_number = True
self.show('-')

def calculate(self):
if self.first_number_string \
and self.second_number_string and self.binary_operation:
if '.' in self.second_number_string:
number = float(self.second_number_string)
else:
number = int(self.second_number_string)
if '.' in self.first_number_string:
number2 = float(self.first_number_string)
else:
number2 = int(self.first_number_string)

if self.binary_operation == '+':
result = number + number2
elif self.binary_operation == '-':
result = number - number2
elif self.binary_operation == '/':
try:
result = float(number) / number2
except ZeroDivisionError:
result = 'ERROR division by zero'
elif self.binary_operation == '*':
result = number * number2

self.first_number_string = ''
self.second_number_string = ''
self.binary_operation = ''
# Save result
self.result = str(result)
self.show(self.result)
if self.result == 'ERROR division by zero':
self.result = ''

def reset(self):
self.result = ''
self.binary_operation = ''
self.first_number_string = ''
self.second_number_string = ''
self.negative_number = False
self.show('0')

def dot(self):
if self.first_number_string == '':
# Forgot to enter a zero before '.'
self.combination('0.')
elif '.' in self.first_number_string:
# Repeated, incorrect entry '.'
pass
else:
self.combination('.')

def show(self, value):
raise NotImplementedError


class GUI(Logic):

def __init__(self, title='My calc',
width_root=160, height_root=170,
width_numb_btn=1, width_math_btn=2):

Logic.__init__(self)

self.root = Tk()
self.root.title(title)
self.root.maxsize(width = width_root, height = height_root)
self.root.minsize(width = width_root, height = height_root)

frame = Frame(self.root)
frame_ent = Frame(self.root)
frame_math = Frame(self.root)

frame_numb = Frame(frame)
frame_numb2 = Frame(frame)
frame_numb3 = Frame(frame)
frame_numb4 = Frame(frame)

self.entry = Entry(frame_ent)
self.entry.insert(END, '0')

self.entry.pack(side = TOP)

frame_ent.pack(side = TOP)
frame.pack(side = LEFT)
frame_math.pack(side = RIGHT)

frame_numb.pack(side = TOP)
frame_numb2.pack(side = TOP)
frame_numb3.pack(side = TOP)
frame_numb4.pack(side = TOP)

Button(frame_ent, text = 'C', width = width_math_btn,
command = lambda: self.write('c')).pack(side = RIGHT)

Button(frame_numb, text = '7', width = width_numb_btn,
command = lambda: self.write('7')).pack(side = LEFT)
Button(frame_numb, text = '8', width = width_numb_btn,
command = lambda: self.write('8')).pack(side = LEFT)
Button(frame_numb, text = '9', width = width_numb_btn,
command = lambda: self.write('9')).pack(side = LEFT)

Button(frame_numb2, text = '4', width = width_numb_btn,
command = lambda: self.write('4')).pack(side = LEFT)
Button(frame_numb2, text = '5', width = width_numb_btn,
command = lambda: self.write('5')).pack(side = LEFT)
Button(frame_numb2, text = '6', width = width_numb_btn,
command = lambda: self.write('6')).pack(side = LEFT)

Button(frame_numb3, text = '1', width = width_numb_btn,
command = lambda: self.write('1')).pack(side = LEFT)
Button(frame_numb3, text = '2', width = width_numb_btn,
command = lambda: self.write('2')).pack(side = LEFT)
Button(frame_numb3, text = '3', width = width_numb_btn,
command = lambda: self.write('3')).pack(side = LEFT)

Button(frame_numb4, text = '0', width = width_numb_btn,
command = lambda: self.write('0')).pack(side = LEFT)
Button(frame_numb4, text = '.', width = width_numb_btn,
command = lambda: self.write('.')).pack(side = LEFT)
Button(frame_numb4, text = '=', width = width_numb_btn,
command = lambda: self.write('=')).pack(side = LEFT)

Button(frame_math, text = '+', width = width_math_btn,
command = lambda: self.write('+')).pack(side = TOP)
Button(frame_math, text = '-', width = width_math_btn,
command = lambda: self.write('-')).pack(side = TOP)
Button(frame_math, text = '/', width = width_math_btn,
command = lambda: self.write('/')).pack(side = TOP)
Button(frame_math, text = '*', width = width_math_btn,
command = lambda: self.write('*')).pack(side = TOP)

def show(self, value):
self.entry.delete(first = 0, last = END)
self.entry.insert(END, value)

def run(self):
'''Run a GUI calculator'''
self.root.mainloop()

class Console(Logic):

def __init__(self):
Logic.__init__(self)
self.show_result = False

def run(self):
'''Run a console calculator'''
print '[c] reset, [q] quit, [=] result'
while True:
for char in raw_input('calc>'):
if char == 'q':
raise SystemExit('Quit')
elif char == '=':
self.show_result = True
self.write(char)

def show(self, value):
if self.show_result:
self.show_result = False
print value


if __name__ == '__main__':
if 'g' in raw_input('GUI or console? ([g] or [c])?\n'):
GUI().run()
else:
Console().run()
Ed
лямбду можно заменить на partial из functools
Чем partial лучше лямбды, в этом случае?
Ed
Вы же все равно юзаете eval
Лень заставила меня использовать eval. Исправился.



Офлайн

#2 Окт. 30, 2011 20:05:30

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

Первая программа, калькулятор, в стиле ООП

Ага, лучше. Только я по-прежнему считаю, что наследовать UI от логики как-то не очень. Это разные вещи, так что лучше объект UI передавать в объект, который логику реализует. И код будет понятнее.



Офлайн

#3 Ноя. 1, 2011 13:19:17

Brony
От:
Зарегистрирован: 2011-06-21
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

Первая программа, калькулятор, в стиле ООП

Ed
Только я по-прежнему считаю, что наследовать UI от логики как-то не очень. Это разные вещи, так что лучше объект UI передавать в объект, который логику реализует. И код будет понятнее.
Честно говоря смутно понимаю о чем это вы, но переписал. Как я понял разговор о прямом вызове метода write класса Logic?
class Logic:

def __init__(self):
# Some code
pass

def write(self, char):
self.go(char)

class Console(Logic):

def __init__(self):
Logic.__init__(self)

def write(self, char):
Logic.write(self, char)
Весь код:
#! /usr/bin/python

'''Calculator in object oriented style.
For start GUI or Console use the run method of the object.
Install Tkinter for use GUI.
'''

from functools import partial as send
try:
from Tkinter import \
Tk, Frame, Entry, Button, \
END, TOP, LEFT, RIGHT
except ImportError:
print 'For GUI Tkinter needed'


class Logic:

def __init__(self):
self.result = ''
self.binary_operation = ''
self.first_number_string = ''
self.second_number_string = ''
self.negative_number = False

operation = [(char, send(self.operation, char)) for char in '+-*/']
operation += [('.', self.dot), ('=', self.calculate), ('c', self.reset)]

numbers = [(str(num), send(self.combination, str(num)))
for num in range(10)]

self.switch = dict(numbers + operation)

def write(self, char):
if char in self.switch:
self.switch[char]()

def combination(self, digit):
'''Combination the number from digits'''
if self.negative_number:
# This number is negative
digit = '-' + digit
self.negative_number = False
if self.result:
# Old result is not needed
self.result = ''
self.first_number_string += digit
self.show(self.first_number_string)

def operation(self, char):
'''Arithmetic operations'''
if self.result:
# Use the result of the previous calculation
self.first_number_string = self.result
self.result = ''
if self.first_number_string:
if self.second_number_string:
# Continue to enter numbers
self.calculate()
self.first_number_string = self.result
self.result = ''
self.second_number_string = self.first_number_string
self.first_number_string = ''
self.binary_operation = char
self.show(self.binary_operation)
elif char == '-':
# We remember that the number is less than zero
self.negative_number = True
self.show('-')

def calculate(self):
if self.first_number_string \
and self.second_number_string and self.binary_operation:
if '.' in self.second_number_string:
number = float(self.second_number_string)
else:
number = int(self.second_number_string)
if '.' in self.first_number_string:
number2 = float(self.first_number_string)
else:
number2 = int(self.first_number_string)

if self.binary_operation == '+':
result = number + number2
elif self.binary_operation == '-':
result = number - number2
elif self.binary_operation == '/':
try:
result = float(number) / number2
except ZeroDivisionError:
result = 'ERROR division by zero'
elif self.binary_operation == '*':
result = number * number2

self.first_number_string = ''
self.second_number_string = ''
self.binary_operation = ''
# Save result
self.result = str(result)
self.show(self.result)
if self.result == 'ERROR division by zero':
self.result = ''

def reset(self):
self.result = ''
self.binary_operation = ''
self.first_number_string = ''
self.second_number_string = ''
self.negative_number = False
self.show('0')

def dot(self):
if self.first_number_string == '':
# Forgot to enter a zero before '.'
self.combination('0.')
elif '.' in self.first_number_string:
# Repeated, incorrect entry '.'
pass
else:
self.combination('.')

def show(self, value):
raise NotImplementedError


class GUI(Logic):

def __init__(self, title='My calc',
width_root=160, height_root=170,
width_numb_btn=1, width_math_btn=2):

Logic.__init__(self)

self.root = Tk()
self.root.title(title)
self.root.maxsize(width = width_root, height = height_root)
self.root.minsize(width = width_root, height = height_root)

frame = Frame(self.root)
frame_ent = Frame(self.root)
frame_math = Frame(self.root)

frame_numb = Frame(frame)
frame_numb2 = Frame(frame)
frame_numb3 = Frame(frame)
frame_numb4 = Frame(frame)

self.entry = Entry(frame_ent)
self.entry.insert(END, '0')

self.entry.pack(side = TOP)

frame_ent.pack(side = TOP)
frame.pack(side = LEFT)
frame_math.pack(side = RIGHT)

frame_numb.pack(side = TOP)
frame_numb2.pack(side = TOP)
frame_numb3.pack(side = TOP)
frame_numb4.pack(side = TOP)

Button(frame_ent, text = 'C', width = width_math_btn,
command = lambda: self.write('c')).pack(side = RIGHT)

for char in '789':
Button(frame_numb, text = char, width = width_numb_btn,
command = send(self.write, char)).pack(side = LEFT)
for char in '456':
Button(frame_numb2, text = char, width = width_numb_btn,
command = send(self.write, char)).pack(side = LEFT)
for char in '123':
Button(frame_numb3, text = char, width = width_numb_btn,
command = send(self.write, char)).pack(side = LEFT)
for char in '0.=':
Button(frame_numb4, text = char, width = width_numb_btn,
command = send(self.write, char)).pack(side = LEFT)

for char in '+-/*':
Button(frame_math, text = char, width = width_math_btn,
command = send(self.write, char)).pack(side = TOP)

def show(self, value):
self.entry.delete(first = 0, last = END)
self.entry.insert(END, value)

def write(self, char):
Logic.write(self, char)

def run(self):
'''Run a GUI calculator'''
self.root.mainloop()


class Console(Logic):

def __init__(self):
Logic.__init__(self)
self.show_result = False

def run(self):
'''Run a console calculator'''
print '[c] reset, [q] quit, [=] result'
while True:
for char in raw_input('calc>'):
if char == 'q':
raise SystemExit('Quit')
elif char == '=':
self.show_result = True
self.write(char)

def write(self, char):
Logic.write(self, char)

def show(self, value):
if self.show_result:
self.show_result = False
print value


if __name__ == '__main__':
if 'g' in raw_input('GUI or console? ([g] or [c])?\n'):
GUI().run()
else:
Console().run()



Офлайн

#4 Ноя. 1, 2011 14:41:56

Soteric
От:
Зарегистрирован: 2010-09-19
Сообщения: 352
Репутация: +  20  -
Профиль   Отправить e-mail  

Первая программа, калькулятор, в стиле ООП

Здесь не требуется наследование. Т.е. вот так:

class Calculator():
def plus(a, b):
return a + b

class GUI():
def __init__(calculator)
self.Calculator = calculator

def onPlusPressed():
a = getA()
b = getB()
result = self.Calculator.plus(a, b)

if __name__ == '__main__':
calculator = Calculator()
gui = GUI(calculator)



Офлайн

#5 Ноя. 2, 2011 11:06:34

Brony
От:
Зарегистрирован: 2011-06-21
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

Первая программа, калькулятор, в стиле ООП

Ed
Если есть желание разделять UI и логику, то по-моему лучше это делать не путем наследования класса с логикой от класса с UI. Даже с точки зрения здравого смысла это, кхм, вызывает вопросы. Попробуйте вместо наследования просто передавать объект UI в качестве параметра в конструктор вашего калькулятора.
Soteric
Здесь не требуется наследование
Переделал. Правильно?
#! /usr/bin/python

'''Calculator in object oriented style.
For start GUI or Console use the run method of the object.
Install Tkinter for use GUI.
'''

from functools import partial as send
try:
from Tkinter import \
Tk, Frame, Entry, Button, \
END, TOP, LEFT, RIGHT
except ImportError:
print 'For GUI Tkinter needed'


class Logic:

def __init__(self):
self.result = ''
self.buffer = ''
self.binary_operation = ''
self.first_number_string = ''
self.second_number_string = ''
self.negative_number = False

operation = [('.', self.dot), ('=', self.calculate), ('c', self.reset)]
operation += [(command, send(self.operation, command))
for command in '+-*/']

numbers = [(str(number), send(self.combination, str(number)))
for number in range(10)]

self.switch = dict(numbers + operation)

def write(self, char):
if char in self.switch:
self.switch[char]()

def combination(self, digit):
'''Combination the number from digits'''
if self.negative_number:
# This number is negative
digit = '-' + digit
self.negative_number = False
if self.result:
# Old result is not needed
self.result = ''
self.first_number_string += digit
self.buffer = self.first_number_string

def operation(self, char):
'''Arithmetic operations'''
if self.result:
# Use the result of the previous calculation
self.first_number_string = self.result
self.result = ''
if self.first_number_string:
if self.second_number_string:
# Continue to enter numbers
self.calculate()
self.first_number_string = self.result
self.result = ''
self.second_number_string = self.first_number_string
self.first_number_string = ''
self.binary_operation = char
self.buffer = self.binary_operation
elif char == '-':
# We remember that the number is less than zero
self.negative_number = True
self.buffer = '-'

def calculate(self):
if self.first_number_string \
and self.second_number_string and self.binary_operation:
if '.' in self.second_number_string:
number = float(self.second_number_string)
else:
number = int(self.second_number_string)
if '.' in self.first_number_string:
number2 = float(self.first_number_string)
else:
number2 = int(self.first_number_string)

if self.binary_operation == '+':
result = number + number2
elif self.binary_operation == '-':
result = number - number2
elif self.binary_operation == '/':
try:
result = float(number) / number2
except ZeroDivisionError:
result = 'ERROR division by zero'
elif self.binary_operation == '*':
result = number * number2

self.first_number_string = ''
self.second_number_string = ''
self.binary_operation = ''
# Save result
self.result = str(result)
self.buffer = self.result
if self.result == 'ERROR division by zero':
self.result = ''

def reset(self):
self.result = ''
self.binary_operation = ''
self.first_number_string = ''
self.second_number_string = ''
self.negative_number = False
self.buffer = '0'

def dot(self):
if self.first_number_string == '':
# Forgot to enter a zero before '.'
self.combination('0.')
elif '.' in self.first_number_string:
# Repeated, incorrect entry '.'
pass
else:
self.combination('.')

def get_buffer(self):
'''The result is the last action'''
return self.buffer


class GUI:

def __init__(self, title='My calc',
width_root=160, height_root=170,
width_number_button=1, width_math_button=2):

self.logic = Logic()

self.root = Tk()
self.root.title(title)
self.root.maxsize(width = width_root, height = height_root)
self.root.minsize(width = width_root, height = height_root)

frame = Frame(self.root)
frame_entry = Frame(self.root)
frame_math = Frame(self.root)

frame_numbers = Frame(frame)
frame_numbers2 = Frame(frame)
frame_numbers3 = Frame(frame)
frame_numbers4 = Frame(frame)

self.entry = Entry(frame_entry)
self.entry.insert(END, '0')

self.entry.pack(side = TOP)

frame_entry.pack(side = TOP)
frame.pack(side = LEFT)
frame_math.pack(side = RIGHT)

frame_numbers.pack(side = TOP)
frame_numbers2.pack(side = TOP)
frame_numbers3.pack(side = TOP)
frame_numbers4.pack(side = TOP)

Button(frame_entry, text = 'C', width = width_math_button,
command = send(self.write, 'c')).pack(side = RIGHT)

for char in '789':
Button(frame_numbers, text = char, width = width_number_button,
command = send(self.write, char)).pack(side = LEFT)
for char in '456':
Button(frame_numbers2, text = char, width = width_number_button,
command = send(self.write, char)).pack(side = LEFT)
for char in '123':
Button(frame_numbers3, text = char, width = width_number_button,
command = send(self.write, char)).pack(side = LEFT)
for char in '0.=':
Button(frame_numbers4, text = char, width = width_number_button,
command = send(self.write, char)).pack(side = LEFT)

for char in '+-/*':
Button(frame_math, text = char, width = width_math_button,
command = send(self.write, char)).pack(side = TOP)

def show(self, value):
self.entry.delete(first = 0, last = END)
self.entry.insert(END, value)

def write(self, char):
self.logic.write(char)
self.show(self.logic.get_buffer())

def run(self):
'''Run a GUI calculator'''
self.root.mainloop()


class Console:

def __init__(self):
self.logic = Logic()

def run(self):
'''Run a console calculator'''
print '[c] reset, [q] quit, [=] result'
while True:
for char in raw_input('calc>'):
if char == 'q':
raise SystemExit('Quit')
elif char == '=':
self.write(char)
print self.logic.get_buffer()
else:
self.write(char)

def write(self, char):
self.logic.write(char)


if __name__ == '__main__':
if 'g' in raw_input('GUI or console? ([g] or [c])?\n'):
GUI().run()
else:
Console().run()
Если я все правильно понял - это называется композиция. Но особых преимуществ перед наследованием не вижу. Как в первом, так и во втором варианте есть повторное использование кода класса Logic, классы вызывают только методы. В чем суть?
Ed
лямбду можно заменить на partial из functools
Чем partial лучше лямбды?
Ed
В сторону MVC смотрели?
Нет, никогда не сталкивался. Правильно ли я понял шаблон MVC?
#! /usr/bin/python

'''Calculator in object oriented style.
For start GUI or Console use the run method of the object.
Install Tkinter for use GUI.
'''

from functools import partial as send
try:
from Tkinter import \
Tk, Frame, Entry, Button, \
END, TOP, LEFT, RIGHT
except ImportError:
print 'For GUI Tkinter needed'


class Logic:

def __init__(self):
self.result = ''
self.buffer = ''
self.binary_operation = ''
self.first_number_string = ''
self.second_number_string = ''
self.negative_number = False

operation = [('.', self.dot), ('=', self.calculate), ('c', self.reset)]
operation += [(command, send(self.operation, command))
for command in '+-*/']

numbers = [(str(number), send(self.combination, str(number)))
for number in range(10)]

self.switch = dict(numbers + operation)

def write(self, char):
if char in self.switch:
self.switch[char]()

def combination(self, digit):
'''Combination the number from digits'''
if self.negative_number:
# This number is negative
digit = '-' + digit
self.negative_number = False
if self.result:
# Old result is not needed
self.result = ''
self.first_number_string += digit
self.buffer = self.first_number_string

def operation(self, char):
'''Arithmetic operations'''
if self.result:
# Use the result of the previous calculation
self.first_number_string = self.result
self.result = ''
if self.first_number_string:
if self.second_number_string:
# Continue to enter numbers
self.calculate()
self.first_number_string = self.result
self.result = ''
self.second_number_string = self.first_number_string
self.first_number_string = ''
self.binary_operation = char
self.buffer = self.binary_operation
elif char == '-':
# We remember that the number is less than zero
self.negative_number = True
self.buffer = '-'

def calculate(self):
if self.first_number_string \
and self.second_number_string and self.binary_operation:
if '.' in self.second_number_string:
number = float(self.second_number_string)
else:
number = int(self.second_number_string)
if '.' in self.first_number_string:
number2 = float(self.first_number_string)
else:
number2 = int(self.first_number_string)

if self.binary_operation == '+':
result = number + number2
elif self.binary_operation == '-':
result = number - number2
elif self.binary_operation == '/':
try:
result = float(number) / number2
except ZeroDivisionError:
result = 'ERROR division by zero'
elif self.binary_operation == '*':
result = number * number2

self.first_number_string = ''
self.second_number_string = ''
self.binary_operation = ''
# Save result
self.result = str(result)
self.buffer = self.result
if self.result == 'ERROR division by zero':
self.result = ''

def reset(self):
self.result = ''
self.binary_operation = ''
self.first_number_string = ''
self.second_number_string = ''
self.negative_number = False
self.buffer = '0'

def dot(self):
if self.first_number_string == '':
# Forgot to enter a zero before '.'
self.combination('0.')
elif '.' in self.first_number_string:
# Repeated, incorrect entry '.'
pass
else:
self.combination('.')

def get_buffer(self):
'''The result is the last action'''
return self.buffer


class GUI:

def __init__(self, controller, title='My calc',
width_root=160, height_root=170,
width_number_button=1, width_math_button=2):

self.controller = controller

self.root = Tk()
self.root.title(title)
self.root.maxsize(width = width_root, height = height_root)
self.root.minsize(width = width_root, height = height_root)

frame = Frame(self.root)
frame_entry = Frame(self.root)
frame_math = Frame(self.root)

frame_numbers = Frame(frame)
frame_numbers2 = Frame(frame)
frame_numbers3 = Frame(frame)
frame_numbers4 = Frame(frame)

self.entry = Entry(frame_entry)
self.entry.insert(END, '0')

self.entry.pack(side = TOP)

frame_entry.pack(side = TOP)
frame.pack(side = LEFT)
frame_math.pack(side = RIGHT)

frame_numbers.pack(side = TOP)
frame_numbers2.pack(side = TOP)
frame_numbers3.pack(side = TOP)
frame_numbers4.pack(side = TOP)

Button(frame_entry, text = 'C', width = width_math_button,
command = send(self.write, 'c')).pack(side = RIGHT)

for char in '789':
Button(frame_numbers, text = char, width = width_number_button,
command = send(self.write, char)).pack(side = LEFT)
for char in '456':
Button(frame_numbers2, text = char, width = width_number_button,
command = send(self.write, char)).pack(side = LEFT)
for char in '123':
Button(frame_numbers3, text = char, width = width_number_button,
command = send(self.write, char)).pack(side = LEFT)
for char in '0.=':
Button(frame_numbers4, text = char, width = width_number_button,
command = send(self.write, char)).pack(side = LEFT)

for char in '+-/*':
Button(frame_math, text = char, width = width_math_button,
command = send(self.write, char)).pack(side = TOP)

def show(self, value):
self.entry.delete(first = 0, last = END)
self.entry.insert(END, value)

def write(self, char):
self.controller.write(char)
self.controller.show()

def run(self):
'''Run a GUI calculator'''
self.root.mainloop()


class Console:

def __init__(self, controller):
self.controller = controller

def run(self):
'''Run a console calculator'''
print '[c] reset, [q] quit, [=] result'
while True:
for char in raw_input('calc>'):
if char == 'q':
raise SystemExit('Quit')
elif char == '=':
self.controller.write(char)
self.controller.show()
else:
self.controller.write(char)

def write(self, char):
self.controller.write(char)

def show(self, value):
print value


class Controller:
'''Model-view-controller'''
def __init__(self):
self.logic = Logic()
if 'g' in raw_input('GUI or console? ([g] or [c])?\n'):
self.user_interface = GUI(self)
else:
self.user_interface = Console(self)

def write(self, char):
self.logic.write(char)

def show(self):
self.user_interface.show(self.logic.get_buffer())

def run(self):
self.user_interface.run()

if __name__ == '__main__':
Controller().run()



Отредактировано (Ноя. 2, 2011 11:07:40)

Офлайн

#6 Ноя. 2, 2011 22:09:17

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

Первая программа, калькулятор, в стиле ООП

Я вообще намекал на что-то типа такого:

class Calculator():
def __init__(self, gui)
self.gui = gui

def operation(self, char):
'''Arithmetic operations'''
...
self.memr += self.numb + char
self.gui.show(self.numb + char)
...
class GUI():

def show(self, value):
self.entry.delete(first = 0, last = END)
self.entry.insert(END, value)
...

if __name__ == '__main__':
gui = GUI()
calculator = Calculator(gui)
Собственно я и писал о передаче объекта gui в объект, реализующий логику.

Про MVC пока забудьте. Это я не подумав спросил, сорри.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version