Wie "sauber" ist mein Code programmiert? Was kann man verbessern?
Verfasst: Donnerstag 14. Januar 2021, 15:54
Hallo,
ich habe mit PyQt5 eine kleine GUI programmiert auf der ich mit der Maus eine Zahl schreiben kann, welche dann von einem Convolutional Neural Network klassifiziert wird. Ich habe kein wirkliches Problem damit und es funktioniert alles genauso wie es soll. Ich wollte den Code hier aber einfach mal posten und fragen, ob ein erfahrener Programmierer drüber schauen kann. Es ist kein super großes oder komplexes Programm, aber mich interessiert einfach wie "sauber" der Code programmiert ist bzw. was ich wirklich unbedingt ändern oder für zukünftige Projekte anders angehen sollte. Vielleicht hat ja jemand Zeit und Lust kurz drüberzuschauen und mir ein paar Tipps zu geben. Ich hab das Programm auf 4 Module aufgeteilt.
Eine Sache die mich auch etwas verwundert ist, dass ich mir mit Pyinstaller eine .exe Datei generieren habe, welche über 600 MB groß geworden ist. Das kommt mir doch sehr viel vor für so ein kleines Programm. Woran kann das liegen?
main.py
mainwindow.py
MyCanvas.py
model.py
ich habe mit PyQt5 eine kleine GUI programmiert auf der ich mit der Maus eine Zahl schreiben kann, welche dann von einem Convolutional Neural Network klassifiziert wird. Ich habe kein wirkliches Problem damit und es funktioniert alles genauso wie es soll. Ich wollte den Code hier aber einfach mal posten und fragen, ob ein erfahrener Programmierer drüber schauen kann. Es ist kein super großes oder komplexes Programm, aber mich interessiert einfach wie "sauber" der Code programmiert ist bzw. was ich wirklich unbedingt ändern oder für zukünftige Projekte anders angehen sollte. Vielleicht hat ja jemand Zeit und Lust kurz drüberzuschauen und mir ein paar Tipps zu geben. Ich hab das Programm auf 4 Module aufgeteilt.
Eine Sache die mich auch etwas verwundert ist, dass ich mir mit Pyinstaller eine .exe Datei generieren habe, welche über 600 MB groß geworden ist. Das kommt mir doch sehr viel vor für so ein kleines Programm. Woran kann das liegen?
main.py
Code: Alles auswählen
import sys
from PyQt5.QtWidgets import QMessageBox, QMainWindow, QApplication
from mainwindow import Ui_MainWindow
from model_check import Predictor
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.Classify.clicked.connect(self.classification)
self.ui.Clear.clicked.connect(self.ui.Drawfield.clear)
self.model = Predictor()
def classification(self):
self.number = self.ui.Drawfield.get_number()
self.prediction = self.model.number_prediction(self.number)
msg = QMessageBox()
msg.setWindowTitle("Classification")
msg.setText("The written number was classified as %s" % (self.prediction))
msg.setDetailedText("This prediction was made by a previously trained convolutional neural network.\nIt was trained on the MNIST Dataset with a extensive data augmentation to make sure that the classification works properly.")
msg.exec_()
def main():
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())
if __name__ == "__main__":
main()
Code: Alles auswählen
from PyQt5 import QtCore, QtGui, QtWidgets
from Mycanvas import Canvas
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(578, 677)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.Drawfield = Canvas(self.centralwidget)
self.Drawfield.setMinimumSize(QtCore.QSize(560, 560))
self.Drawfield.setMaximumSize(QtCore.QSize(560, 560))
self.Drawfield.setCursor(QtGui.QCursor(QtCore.Qt.CrossCursor))
self.Drawfield.setMouseTracking(True)
self.Drawfield.setTabletTracking(True)
self.Drawfield.setObjectName("Drawfield")
self.gridLayout.addWidget(self.Drawfield, 2, 0, 1, 1)
self.Clear = QtWidgets.QPushButton(self.centralwidget)
self.Clear.setObjectName("Clear")
self.gridLayout.addWidget(self.Clear, 0, 0, 1, 1)
self.Classify = QtWidgets.QPushButton(self.centralwidget)
self.Classify.setObjectName("Classify")
self.gridLayout.addWidget(self.Classify, 1, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 578, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.Clear.setText(_translate("MainWindow", "Clear"))
self.Classify.setText(_translate("MainWindow", "Classify"))
Code: Alles auswählen
from PyQt5.QtWidgets import QWidget
from PyQt5.QtGui import QImage, QPainter, QPen
from PyQt5.QtCore import Qt, QPoint
import numpy as np
class Canvas(QWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.image = QImage(560, 560, QImage.Format_RGB32)
self.image.fill(Qt.white)
self.drawing = False
self.brushSize = 56
self.brushColor = Qt.black
self.lastPoint = QPoint()
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.drawing = True
self.lastPoint = event.pos()
def mouseMoveEvent(self, event):
if(event.buttons() & Qt.LeftButton) & self.drawing:
painter = QPainter(self.image)
painter.setPen(QPen(self.brushColor, self.brushSize, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
painter.drawLine(self.lastPoint, event.pos())
self.lastPoint = event.pos()
self.update()
def mouseReleaseEvent(self, event):
if event.button() == Qt.LeftButton:
self.drawing = False
def paintEvent(self, event):
canvasPainter = QPainter(self)
canvasPainter.drawImage(self.rect(),self.image, self.image.rect())
def get_number(self):
image = self.convertQImageToMat(self.image)
gray = self.rgb2gray(image)
new_img = np.full((28,28), 0)
for i in range(0, 560, 20):
new_img[int(i/20)] = gray[i][0::20]
return(new_img)
def convertQImageToMat(self, incomingImage):
incomingImage = incomingImage.convertToFormat(4)
width = incomingImage.width()
height = incomingImage.height()
ptr = incomingImage.bits()
ptr.setsize(incomingImage.byteCount())
image_array = np.array(ptr).reshape(height, width, 4)
return(image_array)
def rgb2gray(self, rgb):
gray = np.round(np.dot(rgb[...,:3], [0.1144, 0.587, 0.2989]))
return(gray)
def clear(self):
self.image.fill(Qt.white)
self.update()
Code: Alles auswählen
from keras.models import load_model
import numpy as np
class Predictor():
def __init__(self):
self.model = load_model('model.h5')
def img_prep(self, image):
new_image = 255 - image
new_image = new_image.reshape(1, new_image.shape[0], new_image.shape[1], 1)
return(new_image)
def number_prediction(self, image):
x_test = self.img_prep(image)
prediction = np.argmax(self.model.predict(x_test))
return(prediction)