upgrade this GUI to the best of your abilities to ensure a practical en effective program. Adjust the process flow logic and redesign the GUI making text boxes display vertical instead of horizontal so they are next to each other and not stacked on top making it hard to read. import sys
import re
import threading
import io
import contextlib
from PyQt6.QtCore import QObject, QThread, pyqtSignal, Qt, QTimer
from PyQt6.QtWidgets import (
    QApplication, QWidget, QVBoxLayout, QLabel, QLineEdit,
    QPushButton, QSlider, QTextEdit, QProgressBar, QMessageBox
)
from gradio_client import Client

class Worker(QObject):
    finished = pyqtSignal()
    result_ready = pyqtSignal(str, str)
    execution_result = pyqtSignal(str)
    save_code_finished = pyqtSignal()

    def __init__(self, client, inputs, top_p, temperature, retries=5):
        super().__init__()
        self.client = client
        self.inputs = inputs
        self.top_p = top_p
        self.temperature = temperature
        self.retries = retries
        self.api_call_count = 0  # Initialize the API call counter

    def run(self):
        try_count = 0
        while try_count < self.retries:
            try:
                self.api_call_count += 1  # Increment API call counter
                result = self.client.predict(
                    inputs=self.inputs,
                    top_p=self.top_p,
                    temperature=self.temperature,
                    chat_counter=self.api_call_count,
                    chatbot=[],
                    api_name="/predict"
                )

                response_text = result[0][0][1]
                code = self.extract_code(response_text)

                self.result_ready.emit(response_text, code)

                exec_output = self.execute_code(code)
                self.execution_result.emit(exec_output)

                if "error" not in exec_output.lower():
                    break  
            except Exception as e:
                self.result_ready.emit(f"Error: {str(e)}", "")
                self.execution_result.emit(f"Execution error: {str(e)}")

            try_count += 1

        self.finished.emit()

    def extract_code(self, text):
        pattern = r'```python(.*?)```'
        matches = re.findall(pattern, text, re.DOTALL)
        if matches:
            return "\n".join(match.strip() for match in matches)
        else:
            return "No code found."

    def execute_code(self, code):
        if code == "No code found.":
            return "No code to execute."

        try:
            output = io.StringIO()
            with contextlib.redirect_stdout(output):
                exec(code, globals())
            return output.getvalue() if output.getvalue() else "Code executed without output."
        except Exception as e:
            return f"Execution error: {str(e)}"

    def save_code(self, filename, code):
        try:
            with open(filename, 'w') as f:
                f.write(code)
            self.save_code_finished.emit()
        except Exception as e:
            return f"Failed to save code: {str(e)}"


class ChatGPTApp(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("ChatGPT API Interface")
        self.resize(800, 600)

        self.client = Client("yuntian-deng/ChatGPT")
        self.initUI()
        self.api_call_counter = 0  # Initialize the API call counter displayed in GUI

    def initUI(self):
        layout = QVBoxLayout()

        self.input_field = QLineEdit(self)
        self.input_field.setPlaceholderText("Type your message here...")
        layout.addWidget(self.input_field)

        self.top_p_slider = QSlider(Qt.Orientation.Horizontal)
        self.top_p_slider.setRange(0, 100)
        self.top_p_slider.setValue(100)
        layout.addWidget(QLabel("Top-p (nucleus sampling):"))
        layout.addWidget(self.top_p_slider)

        self.temperature_slider = QSlider(Qt.Orientation.Horizontal)
        self.temperature_slider.setRange(0, 100)
        self.temperature_slider.setValue(100)
        layout.addWidget(QLabel("Temperature:"))
        layout.addWidget(self.temperature_slider)

        self.filename_field = QLineEdit(self)
        self.filename_field.setPlaceholderText("Enter filename to save code (e.g., output.py)")
        layout.addWidget(self.filename_field)

        self.predict_button = QPushButton("Predict", self)
        self.predict_button.clicked.connect(self.start_prediction_thread)
        layout.addWidget(self.predict_button)

        self.save_execute_button = QPushButton("Save and Execute Code", self)
        self.save_execute_button.clicked.connect(self.save_and_execute_code)
        layout.addWidget(self.save_execute_button)

        self.response_area = QTextEdit(self)
        self.response_area.setReadOnly(True)
        layout.addWidget(QLabel("Response:"))
        layout.addWidget(self.response_area)

        self.code_area = QTextEdit(self)
        self.code_area.setReadOnly(True)
        layout.addWidget(QLabel("Extracted Code:"))
        layout.addWidget(self.code_area)

        self.execution_area = QTextEdit(self)
        self.execution_area.setReadOnly(True)
        layout.addWidget(QLabel("Execution Result:"))
        layout.addWidget(self.execution_area)

        self.debug_console = QTextEdit(self)
        self.debug_console.setReadOnly(True)
        layout.addWidget(QLabel("Debug Console:"))
        layout.addWidget(self.debug_console)

        self.api_counter_label = QLabel("API Call Count: 0")
        layout.addWidget(self.api_counter_label)

        self.progress_bar = QProgressBar(self)
        self.progress_bar.setRange(0, 0)
        layout.addWidget(self.progress_bar)
        
        self.flashing_lights_label = QLabel("Processing...")
        layout.addWidget(self.flashing_lights_label)
        self.flashing_lights_timer = QTimer()
        self.flashing_lights_timer.timeout.connect(self.toggle_flashing_lights)
        self.flashing_lights_timer.start(500)

        self.setLayout(layout)

    def toggle_flashing_lights(self):
        current_color = self.flashing_lights_label.styleSheet()
        if current_color == "color: red;":
            self.flashing_lights_label.setStyleSheet("color: black;")
        else:
            self.flashing_lights_label.setStyleSheet("color: red;")

    def start_prediction_thread(self):
        inputs = self.input_field.text()
        
        # Do not proceed if inputs are empty
        if not inputs.strip():
            QMessageBox.warning(self, "Warning", "Please enter a message before predicting.")
            return

        top_p = self.top_p_slider.value() / 100.0
        temperature = self.temperature_slider.value() / 100.0

        self.thread = QThread()
        self.worker = Worker(self.client, inputs, top_p, temperature)

        self.worker.moveToThread(self.thread)

        self.thread.started.connect(self.worker.run)
        self.worker.finished.connect(self.thread.quit)
        self.worker.finished.connect(self.worker.deleteLater)
        self.thread.finished.connect(self.thread.deleteLater)
        self.worker.result_ready.connect(self.update_ui)
        self.worker.execution_result.connect(self.update_execution_result)

        self.progress_bar.setValue(0)
        self.progress_bar.setRange(0, 0)
        self.flashing_lights_timer.start()
        self.thread.start()

        # Increment the API call counter in the GUI
        self.api_call_counter += 1
        self.api_counter_label.setText(f"API Call Count: {self.api_call_counter}")

    def save_and_execute_code(self):
        code = self.code_area.toPlainText()
        filename = self.filename_field.text()
        
        if not filename:
            QMessageBox.warning(self, "Warning", "Please enter a filename to save the code.")
            return
        
        self.thread = QThread()
        self.worker = Worker(self.client, '', 0, 0)  # Dummy input, no prediction here
        self.worker.moveToThread(self.thread)

        self.thread.started.connect(lambda: self.worker.save_code(filename, code))
        self.worker.save_code_finished.connect(self.on_code_saved)

        self.thread.finished.connect(self.thread.deleteLater)
        self.worker.finished.connect(self.worker.deleteLater)

        self.thread.start()

    def on_code_saved(self):
        QMessageBox.information(self, "Success", "Code saved successfully!")

    def update_ui(self, response_text, code):
        self.response_area.setPlainText(response_text)
        self.code_area.setPlainText(code)
        self.debug_console.append(f"New code received:\n{code}\n")
        self.progress_bar.setRange(0, 1)
        self.flashing_lights_timer.stop()

    def update_execution_result(self, execution_result):
        self.execution_area.setPlainText(execution_result)
        self.debug_console.append(f"Execution result:\n{execution_result}\n")
        self.progress_bar.setRange(0, 1)
        self.flashing_lights_timer.stop()

    def reset_textbox(self):
        self.input_field.clear()
        self.response_area.clear()
        self.code_area.clear()
        self.execution_area.clear()
        self.debug_console.clear()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = ChatGPTApp()
    window.show()
    sys.exit(app.exec())