<jupyter_start><jupyter_text>`app.py` While `main_window.py`'s responsibility is to **define the graphics user interface**, `app.py`'s responsibility is to **define the functionalities of the GUI**. This is achieved by doing 2 things:1. Defining `functions` to accomplish certain actions2. Connecting `Widget` actions to these `functions`For example, if we want the `Update Window Button` to plot the stock prices in the GUI's canvas. We will have to create a `function` that plots the graph into the canvas and then connect the `Update Window Button` to this `function`.However, before doing so, `app.py` must first know the `Widget names` defined in `main_window.py`. For example, the `Update Window Button` is actually named: `updateWindowButton`. This name is defined on the previous section, when `main_window.ui` was designed using `Qt Designer` and the `objectName` is specified inside the Property Editor!This is why, on the previous step, it is **recommended** to name the `Widgets` **accordingly!**This section of the report will go through the 3 steps of developing `app.py` + 1 optional step to compile `app.exe`, as summarized in the graphics below.![app.py development process](asset/img/app-process.png)  Inheriting `Widgets` from `main_window.py`  The goal of this section is to ensure that `app.py` is **runnable without any error** and shows the **exact same** GUI as if previewing `main_window.ui`.![app.py running correctly](asset/img/gui.png)This result shows that `app.py` has successfully inherited all the properties of `main_window.py`, which includes all the `Widgets` defined when `main_window.ui` was created! These `Widgets` include `updateWindowButton`, `SMA1Checkbox`, `filePathEdit`, etc...To achieve this, simply start from the generic starter code for all `PyQt5` application and then add the following:1. Import `matplotlib`, `PyQt5` and the GUI's Widget class called `UI_Form` from `main_window`2. Pass `QWidget` and `UI_Form` as argument to `Main` class to specify inheritance from `QWidget` and `UI_Form` class3. Call the superclass' (`UI_Form`) initializing function and setup function4. Finally, after the inherited GUI has been initialized, it is still possible to add other `Widgets` programmatically as wellThis is exactly shown in the code below, running them should result in the image shown above:<jupyter_code>import sys
from pathlib import Path
from datetime import datetime

# Step 1
# standard matplotlib import statements
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

# import matplotlib backend for Qt5
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar

# standard PyQt5 import statements
from PyQt5 import QtCore as qtc
from PyQt5 import QtWidgets as qtw

# importing the class to be inherited from
from main_window import Ui_Form

# importing StockData processing module
from stock_data import StockData

class Main(qtw.QWidget, Ui_Form): # Step 2
    def __init__(self):
        # Step 3
        # calling Ui_Form's initializing and setup function
        super().__init__()
        self.setupUi(self)
        self.setWindowTitle("Stock Chart & Moving Average Application")

        # Step 4
        # sets up figure to plot on, instantiates canvas and toolbar
        self.figure, self.ax = plt.subplots()
        self.canvas = FigureCanvas(self.figure)
        self.toolbar = NavigationToolbar(self.canvas, self)

        # attaches the toolbar and canvas to the canvas layout
        self.canvasLayout.addWidget(self.toolbar)
        self.canvasLayout.addWidget(self.canvas)
        
        # sets up a scroll area to display GUI statuses
        self.scrollWidget = qtw.QWidget()
        self.scrollLayout = qtw.QVBoxLayout()
        self.scrollWidget.setLayout(self.scrollLayout)
        self.scrollArea.setWidget(self.scrollWidget)
    
    def function(self):
        # define new functions to do each new actions this way
        pass

if __name__ == "__main__":
    app = qtw.QApplication([])
    main = Main()
    main.show()
    sys.exit(app.exec_())<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.07736389684813753, 'fraction_numerical': 0.0054918815663801334, 'mean_word_length': 4.275818639798489, 'pattern_counts': {'":': 1, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '441230', 'license': 'MIT', 'n_tokens_mistral': 1161, 'n_tokens_neox': 1125, 'n_words': 485, 'path': 'report/app.ipynb', 'repo_name': 'heavensward-argentlux/StockChartApplication', 'size': '4188'}