patternpythonMinor
Simple four function calculator in python
Viewed 0 times
simplefourfunctionpythoncalculator
Problem
I just finished my first Python GUI project, a simple four function calculator. I think I've tested it pretty thoroughly. I'm learning python and OOP, so any critiques would be welcome.
In general, I was wondering if there is a more automated way to generate the number buttons and their actions - it was a lot of copy and paste, while only changing a single character and the name of the function.
```
import sys
from PyQt4 import QtGui, QtCore
class Calc(QtGui.QMainWindow):
def __init__(self):
super(Calc,self).__init__()
self.setGeometry(50,50,220,300)
self.setWindowTitle('PyCalc')
self.setWindowIcon(QtGui.QIcon('favicon.png'))
self.string = ''
self.home()
def home(self):
self.lcd = QtGui.QLCDNumber(self)
self.lcd.setDigitCount(8)
self.lcd.move(20,20)
self.lcd.resize(125,50)
btn1 = QtGui.QPushButton('1', self) # first argument is the text
btn1.clicked.connect(self.button1) # note the lack of parens on method
btn1.resize(50,50) # sizeHint - automatic sizing
btn1.move(10,180) # x and y location
btn2 = QtGui.QPushButton('2', self)
btn2.clicked.connect(self.button2)
btn2.resize(50,50)
btn2.move(60,180)
btn3 = QtGui.QPushButton('3', self)
btn3.clicked.connect(self.button3)
btn3.resize(50,50)
btn3.move(110,180)
btn4 = QtGui.QPushButton('4', self)
btn4.clicked.connect(self.button4)
btn4.resize(50,50)
btn4.move(10,130)
btn5 = QtGui.QPushButton('5', self)
btn5.clicked.connect(self.button5)
btn5.resize(50,50)
btn5.move(60,130)
btn6 = QtGui.QPushButton('6', self)
btn6.clicked.connect(self.button6)
btn6.resize(50,50)
btn6.move(110,130)
btn7 = QtGui.QPushButton('7', self)
btn7.clicked.connect(self.button7)
btn7.resize(50,50)
In general, I was wondering if there is a more automated way to generate the number buttons and their actions - it was a lot of copy and paste, while only changing a single character and the name of the function.
```
import sys
from PyQt4 import QtGui, QtCore
class Calc(QtGui.QMainWindow):
def __init__(self):
super(Calc,self).__init__()
self.setGeometry(50,50,220,300)
self.setWindowTitle('PyCalc')
self.setWindowIcon(QtGui.QIcon('favicon.png'))
self.string = ''
self.home()
def home(self):
self.lcd = QtGui.QLCDNumber(self)
self.lcd.setDigitCount(8)
self.lcd.move(20,20)
self.lcd.resize(125,50)
btn1 = QtGui.QPushButton('1', self) # first argument is the text
btn1.clicked.connect(self.button1) # note the lack of parens on method
btn1.resize(50,50) # sizeHint - automatic sizing
btn1.move(10,180) # x and y location
btn2 = QtGui.QPushButton('2', self)
btn2.clicked.connect(self.button2)
btn2.resize(50,50)
btn2.move(60,180)
btn3 = QtGui.QPushButton('3', self)
btn3.clicked.connect(self.button3)
btn3.resize(50,50)
btn3.move(110,180)
btn4 = QtGui.QPushButton('4', self)
btn4.clicked.connect(self.button4)
btn4.resize(50,50)
btn4.move(10,130)
btn5 = QtGui.QPushButton('5', self)
btn5.clicked.connect(self.button5)
btn5.resize(50,50)
btn5.move(60,130)
btn6 = QtGui.QPushButton('6', self)
btn6.clicked.connect(self.button6)
btn6.resize(50,50)
btn6.move(110,130)
btn7 = QtGui.QPushButton('7', self)
btn7.clicked.connect(self.button7)
btn7.resize(50,50)
Solution
def button0(self):
self.string += '0'
self.lcd.display(self.string)
def button1(self):
self.string += '1'
self.lcd.display(self.string)All of these numbers to 9 seem to do the same thing (append to the string and then display the updated number on the LCD). I think you should be able to use a single function that takes an argument to update your numbers.
btn1 = QtGui.QPushButton('1', self) # first argument is the text
btn1.clicked.connect(self.button1) # note the lack of parens on method
btn1.resize(50,50) # sizeHint - automatic sizing
btn1.move(10,180) # x and y location
btn2 = QtGui.QPushButton('2', self)
btn2.clicked.connect(self.button2)
btn2.resize(50,50)
btn2.move(60,180)If you don't want to repeat all of this code, you should be able to put the different number button objects inside of a collection (i.e., a list).
number_buttons = []
for x in range(1, 10):
# update your calculations for x and y for move here
button = QtGui.QPushButton(str(x), self)
button.clicked.connect(number_button_action(x))
button.resize(50, 50)
button.move(x, y)
number_buttons.append(button)You can refer to the button objects after using
number_buttons[num - 1]. For the repeating operation buttons you should similarly be able to put the values inside of a tuple.
operations = (('.', self.decimal), ('=', self.plus), ('-', self.minus), ...)In the tuple, we're pairing the symbol for the operation and the specific function for the operation together. You can iterate through the operations tuple and create a button for each of the 2-tuples.
All of your button sizes are the same, so again all of you should need to change around is how you're calculating the x and y for your move operation (seems to go in a predictable pattern).
Code Snippets
def button0(self):
self.string += '0'
self.lcd.display(self.string)
def button1(self):
self.string += '1'
self.lcd.display(self.string)btn1 = QtGui.QPushButton('1', self) # first argument is the text
btn1.clicked.connect(self.button1) # note the lack of parens on method
btn1.resize(50,50) # sizeHint - automatic sizing
btn1.move(10,180) # x and y location
btn2 = QtGui.QPushButton('2', self)
btn2.clicked.connect(self.button2)
btn2.resize(50,50)
btn2.move(60,180)number_buttons = []
for x in range(1, 10):
# update your calculations for x and y for move here
button = QtGui.QPushButton(str(x), self)
button.clicked.connect(number_button_action(x))
button.resize(50, 50)
button.move(x, y)
number_buttons.append(button)operations = (('.', self.decimal), ('=', self.plus), ('-', self.minus), ...)Context
StackExchange Code Review Q#146186, answer score: 2
Revisions (0)
No revisions yet.