Here is my python code it has few issues. The buttons for adding removing columns, rows are missing. The Variable Viewer should have a column near variable names with their data types, which user should be able to change manualy ( thus, conversion of data types shall be also implemented)  "import sys
from PySide6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
                               QHBoxLayout, QTableWidget, QTableWidgetItem, QLabel, QSpinBox,
                               QPushButton, QTabWidget, QGroupBox, QMenuBar, QMenu, QFileDialog,
                               QMessageBox, QDockWidget, QSplitter, QComboBox, QFrame, QStackedWidget,
                               QLineEdit, QFormLayout, QListWidget, QListWidgetItem, QCheckBox, QHeaderView,
                               QToolBar, QStatusBar, QStyle, QInputDialog)
from PySide6.QtCore import Qt, QPropertyAnimation, QEasingCurve, Signal, QObject, QSize
from PySide6.QtGui import QFont, QColor, QPalette
import pandas as pd
import numpy as np


class ModernStyle:
    """Class to handle application-wide styling"""

    PRIMARY_COLOR = "#2196F3"
    SECONDARY_COLOR = "#FFC107"
    BACKGROUND_COLOR = "#FFFFFF"
    ACCENT_COLOR = "#E91E63"

    @staticmethod
    def get_stylesheet():
        return """
        QMainWindow {
            background-color: #F5F5F5;
        }

        QTableWidget {
            background-color: white;
            alternate-background-color: #F5F5F5;
            selection-background-color: #2196F3;
            selection-color: white;
            border: 1px solid #E0E0E0;
            border-radius: 4px;
        }

        QTableWidget::item {
            padding: 5px;
        }

        QPushButton {
            background-color: #2196F3;
            color: white;
            border: none;
            padding: 8px 15px;
            border-radius: 4px;
            min-width: 80px;
        }

        QPushButton:hover {
            background-color: #1976D2;
        }

        QPushButton:pressed {
            background-color: #0D47A1;
        }

        QGroupBox {
            font-weight: bold;
            border: 1px solid #E0E0E0;
            border-radius: 4px;
            margin-top: 1ex;
            padding: 10px;
            background-color: white;
        }

        QGroupBox::title {
            subcontrol-origin: margin;
            left: 10px;
            padding: 0 3px;
        }

        QComboBox {
            padding: 5px;
            border: 1px solid #E0E0E0;
            border-radius: 4px;
            min-width: 100px;
        }

        QLineEdit {
            padding: 5px;
            border: 1px solid #E0E0E0;
            border-radius: 4px;
        }

        QTabWidget::pane {
            border: 1px solid #E0E0E0;
            border-radius: 4px;
        }

        QTabBar::tab {
            background-color: #F5F5F5;
            padding: 8px 15px;
            margin-right: 2px;
        }

        QTabBar::tab:selected {
            background-color: #2196F3;
            color: white;
        }
        """

    @staticmethod
    def get_compact_stylesheet():
        return """
        QPushButton {
            padding: 3px 8px;
            min-width: 60px;
            max-height: 24px;
        }

        QGroupBox {
            padding: 5px;
            margin-top: 0.5ex;
        }

        QComboBox {
            padding: 3px;
            min-width: 80px;
            max-height: 24px;
        }

        QLineEdit {
            padding: 3px;
            max-height: 24px;
        }
        """


class VariableViewer(QWidget):
    variableChanged = Signal(int, str, str)

    def __init__(self, data_table):
        super().__init__()
        self.data_table = data_table
        self.setup_ui()

    def setup_ui(self):
        layout = QVBoxLayout(self)
        layout.setSpacing(5)  # Reduce spacing
        layout.setContentsMargins(5, 5, 5, 5)  # Reduce margins

        # Variable list group
        variable_list_group = QGroupBox("Variables")
        variable_list_layout = QVBoxLayout()
        variable_list_layout.setSpacing(3)
        variable_list_layout.setContentsMargins(5, 5, 5, 5)
        self.variable_list = QListWidget()
        self.variable_list.setMaximumHeight(150)  # Limit height
        variable_list_layout.addWidget(self.variable_list)
        variable_list_group.setLayout(variable_list_layout)
        layout.addWidget(variable_list_group)

        # Connect signals
        self.variable_list.itemDoubleClicked.connect(self.edit_variable_name)
        self.variable_list.currentRowChanged.connect(self.update_variable_details)

        # Add some spacing and margins
        layout.setContentsMargins(10, 10, 10, 10)
        layout.setSpacing(10)

        # Style the lists and buttons
        self.variable_list.setAlternatingRowColors(True)
        self.variable_list.setStyleSheet("""
            QListWidget {
                border: 1px solid #E0E0E0;
                border-radius: 4px;
            }
        """)

    def load_variables(self):
        self.variable_list.clear()
        for column in range(self.data_table.columnCount()):
            item = QListWidgetItem(self.data_table.horizontalHeaderItem(column).text())
            item.setData(Qt.UserRole, "Numeric" if self.data_table.horizontalHeaderItem(column).text().isdigit() else "String")
            self.variable_list.addItem(item)

    def update_variable_details(self, row):
        if row >= 0:
            header_item = self.data_table.horizontalHeaderItem(row)
            self.variable_list.item(row).setText(header_item.text())
            self.variable_list.item(row).setData(Qt.UserRole, "Numeric" if header_item.text().isdigit() else "String")

    def edit_variable_name(self, item):
        row = self.variable_list.row(item)
        new_name, ok = QInputDialog.getText(self, "Edit Variable Name", "New Name:", text=item.text())
        if ok and new_name:
            item.setText(new_name)
            self.variableChanged.emit(row, new_name, item.data(Qt.UserRole))

    def change_variable_type(self, item):
        row = self.variable_list.row(item)
        current_type = item.data(Qt.UserRole)
        type_dialog = QInputDialog()
        type_dialog.setComboBoxItems(["Numeric", "String"])
        type_dialog.setWindowTitle("Change Variable Type")
        type_dialog.setLabelText("New Type:")
        type_dialog.setTextValue(current_type)
        ok = type_dialog.exec()
        if ok:
            new_type = type_dialog.textValue()
            item.setData(Qt.UserRole, new_type)
            self.variableChanged.emit(row, item.text(), new_type)


class TimeSeriesApp(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Time Series Analysis Tool")
        self.resize(1200, 800)

        # Set the application style
        self.setStyleSheet(ModernStyle.get_stylesheet() + ModernStyle.get_compact_stylesheet())

        self.data = pd.DataFrame()
        self.setup_ui()

    def setup_ui(self):
        self.create_menu_bar()

        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        main_layout = QVBoxLayout(central_widget)

        tab_widget = QTabWidget()
        main_layout.addWidget(tab_widget)

        # Data View Tab
        data_tab = self.setup_data_tab()
        tab_widget.addTab(data_tab, "Data Editor")

        # Analysis Tab
        analysis_tab = self.setup_analysis_tab()
        tab_widget.addTab(analysis_tab, "Analysis")

        # Add a toolbar
        toolbar = self.addToolBar("Main Toolbar")
        toolbar.setMovable(False)

        # Add toolbar actions with icons
        new_action = toolbar.addAction("New")
        new_action.setIcon(self.style().standardIcon(QStyle.SP_FileIcon))
        new_action.triggered.connect(self.new_file)

        open_action = toolbar.addAction("Open")
        open_action.setIcon(self.style().standardIcon(QStyle.SP_DialogOpenButton))
        open_action.triggered.connect(self.open_file)

        save_action = toolbar.addAction("Save")
        save_action.setIcon(self.style().standardIcon(QStyle.SP_DialogSaveButton))
        save_action.triggered.connect(self.save_file)

        # Add status bar
        self.statusBar().showMessage("Ready")

        # Enhance the tab widget
        tab_widget.setDocumentMode(True)
        tab_widget.setTabPosition(QTabWidget.North)

        # Add icons to tabs
        tab_widget.setTabIcon(0, self.style().standardIcon(QStyle.SP_FileDialogDetailedView))
        tab_widget.setTabIcon(1, self.style().standardIcon(QStyle.SP_CommandLink))

    def create_menu_bar(self):
        menubar = self.menuBar()

        file_menu = menubar.addMenu("File")
        new_action = file_menu.addAction("New")
        new_action.triggered.connect(self.new_file)
        open_action = file_menu.addAction("Open")
        open_action.triggered.connect(self.open_file)
        save_action = file_menu.addAction("Save")
        save_action.triggered.connect(self.save_file)
        file_menu.addSeparator()
        exit_action = file_menu.addAction("Exit")
        exit_action.triggered.connect(self.close)

        edit_menu = menubar.addMenu("Edit")
        edit_menu.addAction("Copy")
        edit_menu.addAction("Paste")
        edit_menu.addAction("Clear All")

        help_menu = menubar.addMenu("Help")
        help_menu.addAction("Documentation")
        help_menu.addAction("About")

    def setup_data_tab(self):
        data_tab = QWidget()
        data_layout = QVBoxLayout(data_tab)
        data_layout.setSpacing(5)
        data_layout.setContentsMargins(5, 5, 5, 5)

        # Toolbar for data manipulation
        data_toolbar = QToolBar()
        data_toolbar.setIconSize(QSize(16, 16))  # Smaller icons

        add_row_btn = QPushButton()
        add_row_btn.setIcon(self.style().standardIcon(QStyle.SP_FileDialogNewFolder))
        add_row_btn.setToolTip("Add new row")
        add_row_btn.setMaximumWidth(30)
        add_row_btn.clicked.connect(self.add_row)

        delete_row_btn = QPushButton()
        delete_row_btn.setIcon(self.style().standardIcon(QStyle.SP_DialogCloseButton))
        delete_row_btn.setToolTip("Delete selected row")
        delete_row_btn.setMaximumWidth(30)
        delete_row_btn.clicked.connect(self.delete_row)

        add_column_btn = QPushButton()
        add_column_btn.setIcon(self.style().standardIcon(QStyle.SP_FileDialogNewFolder))
        add_column_btn.setToolTip("Add new column")
        add_column_btn.setMaximumWidth(30)
        add_column_btn.clicked.connect(self.add_column)

        data_toolbar.addWidget(add_row_btn)
        data_toolbar.addWidget(delete_row_btn)
        data_toolbar.addWidget(add_column_btn)
        data_layout.addWidget(data_toolbar)

        # Main splitter with adjusted sizes
        self.data_table = QTableWidget()
        self.data_table.setColumnCount(3)
        self.data_table.setHorizontalHeaderLabels(['Time', 'Variable 1', 'Variable 2'])
        self.data_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

        self.variable_viewer = VariableViewer(self.data_table)
        self.variable_viewer.variableChanged.connect(self.update_variable)

        splitter = QSplitter(Qt.Horizontal)
        splitter.addWidget(self.data_table)
        splitter.addWidget(self.variable_viewer)
        splitter.setStretchFactor(0, 2)  # Data table gets more space
        splitter.setStretchFactor(1, 1)  # Variable viewer gets less space
        data_layout.addWidget(splitter)

        return data_tab

    def setup_analysis_tab(self):
        analysis_tab = QWidget()
        analysis_layout = QHBoxLayout(analysis_tab)
        analysis_layout.setSpacing(5)
        analysis_layout.setContentsMargins(5, 5, 5, 5)

        # Left side: Plot and controls
        left_panel = QVBoxLayout()

        # Method selection in a compact group
        method_group = QGroupBox("Analysis Method")
        method_layout = QVBoxLayout()
        method_layout.setSpacing(3)
        self.method_combo = QComboBox()
        self.method_combo.setMaximumWidth(200)
        self.method_combo.addItems(
            ["Optimal Time Delay Analysis", "Optimal Embedding Dimension", "Convergent Cross Mapping"])
        self.method_combo.currentIndexChanged.connect(self.update_method_parameters)
        method_layout.addWidget(self.method_combo)
        method_group.setLayout(method_layout)
        left_panel.addWidget(method_group)

        # Plot area
        self.plot_label = QLabel("Plot will appear here")
        self.plot_label.setStyleSheet("background-color: #f0f0f0; border: 1px solid #ccc;")
        self.plot_label.setMinimumSize(400, 300)
        self.plot_label.setAlignment(Qt.AlignCenter)
        left_panel.addWidget(self.plot_label)

        analysis_layout.addLayout(left_panel)

        # Right side: Parameters and results
        right_panel = QVBoxLayout()

        # Parameters in a scrollable area
        params_group = QGroupBox("Parameters")
        self.params_frame = QFrame()
        self.params_frame.setFrameShape(QFrame.StyledPanel)
        self.params_frame.setMaximumWidth(250)
        self.params_layout = QVBoxLayout(self.params_frame)
        params_layout = QVBoxLayout()
        params_layout.addWidget(self.params_frame)
        params_group.setLayout(params_layout)
        right_panel.addWidget(params_group)

        # Results table
        results_group = QGroupBox("Results")
        results_layout = QVBoxLayout()
        self.results_table = QTableWidget()
        self.results_table.setMaximumHeight(200)
        results_layout.addWidget(self.results_table)
        results_group.setLayout(results_layout)
        right_panel.addWidget(results_group)

        analysis_layout.addLayout(right_panel)

        return analysis_tab

    def update_method_parameters(self):
        for i in reversed(range(self.params_layout.count())):
            self.params_layout.itemAt(i).widget().setParent(None)

        method = self.method_combo.currentText()
        if method == "Optimal Time Delay Analysis":
            self.add_parameter("Parameter 1", 0, 100)
            self.add_parameter("Parameter 2", 0, 100)
        elif method == "Optimal Embedding Dimension":
            self.add_parameter("Parameter A", 0, 100)
            self.add_parameter("Parameter B", 0, 100)
        elif method == "Convergent Cross Mapping":
            self.add_parameter("Parameter X", 0, 100)
            self.add_parameter("Parameter Y", 0, 100)

    def add_parameter(self, name, min_value, max_value):
        layout = QHBoxLayout()
        layout.addWidget(QLabel(name))
        spinbox = QSpinBox()
        spinbox.setRange(min_value, max_value)
        layout.addWidget(spinbox)
        self.params_layout.addLayout(layout)

    def update_variable(self, row, new_name, new_type):
        self.data_table.setHorizontalHeaderItem(row, QTableWidgetItem(new_name))

    def add_row(self):
        current_rows = self.data_table.rowCount()
        self.data_table.insertRow(current_rows)
        self.variable_viewer.load_variables()
        self.statusBar().showMessage("Row added", 2000)

    def delete_row(self):
        current_row = self.data_table.currentRow()
        if current_row >= 0:
            self.data_table.removeRow(current_row)
            self.variable_viewer.load_variables()
            self.statusBar().showMessage("Row deleted", 2000)

    def add_column(self):
        current_cols = self.data_table.columnCount()
        self.data_table.setColumnCount(current_cols + 1)
        self.data_table.setHorizontalHeaderItem(
            current_cols,
            QTableWidgetItem(f"Variable {current_cols}")
        )
        self.variable_viewer.load_variables()
        self.statusBar().showMessage("Column added", 2000)

    def new_file(self):
        self.data_table.clearContents()
        self.data_table.setRowCount(0)
        self.variable_viewer.load_variables()

    def open_file(self):
        filename, _ = QFileDialog.getOpenFileName(
            self,
            "Open Data File",
            "",
            "CSV Files (*.csv);;All Files (*)"
        )
        if filename:
            try:
                data = pd.read_csv(filename)
                self.load_data_to_table(data)
                self.variable_viewer.load_variables()
            except Exception as e:
                QMessageBox.critical(self, "Error", f"Could not open file: {str(e)}")

    def save_file(self):
        filename, _ = QFileDialog.getSaveFileName(
            self,
            "Save Data File",
            "",
            "CSV Files (*.csv);;All Files (*)"
        )
        if filename:
            try:
                data = self.get_data_from_table()
                data.to_csv(filename, index=False)
            except Exception as e:
                QMessageBox.critical(self, "Error", f"Could not save file: {str(e)}")

    def load_data_to_table(self, data):
        self.data_table.setRowCount(len(data))
        self.data_table.setColumnCount(len(data.columns))
        self.data_table.setHorizontalHeaderLabels(data.columns)

        for i in range(len(data)):
            for j in range(len(data.columns)):
                self.data_table.setItem(
                    i, j,
                    QTableWidgetItem(str(data.iloc[i, j]))
                )

    def get_data_from_table(self):
        rows = self.data_table.rowCount()
        cols = self.data_table.columnCount()
        data = []

        headers = []
        for j in range(cols):
            header = self.data_table.horizontalHeaderItem(j)
            headers.append(header.text() if header else f"Column {j}")

        for i in range(rows):
            row_data = []
            for j in range(cols):
                item = self.data_table.item(i, j)
                row_data.append(item.text() if item else "")
            data.append(row_data)

        return pd.DataFrame(data, columns=headers)

    def placeholder_action(self, action_name):
        self.results_label.setText(f"{action_name} placeholder - To be implemented")


def main():
    app = QApplication(sys.argv)

    # Set application-wide font
    font = QFont("Segoe UI", 9)
    app.setFont(font)

    # Enable high DPI scaling
    app.setAttribute(Qt.AA_EnableHighDpiScaling, True)
    app.setAttribute(Qt.AA_UseHighDpiPixmaps, True)

    window = TimeSeriesApp()
    window.show()
    sys.exit(app.exec())


if __name__ == "__main__":
    main()"