Mar-21-2023, 03:18 AM
So my python program is essentially an investment interface where the client displays the graphical elements like the first page is the login or signup page and then when the credentials of the user are verified against the server which uses an sqlite database to store said entries. Then upon successful login, the user moves on to the next page where there are other elements instantiated. My question is each time I login or signup, a press of either buttons just end up freezing the whole gui and I have to hardclose it. I have tried with a csv file which stores the sql database entries and then use pandas to read said csv to acknowledge proper entry but to no avail. I cannot proceed further without this feature working. Any help is much appreciated. Been trying to debug this for ages now.
Used csv connected to sql database then pandas to read from said csv, does not work and I noticed that nothing was being saved but when running the client, it displays in the terminal sending then proceeds to show the credentials chosen in the login/signup page but I guess the server does not receive these data and as such cannot store them. Here are the server and client codes.
Server codes:
Used csv connected to sql database then pandas to read from said csv, does not work and I noticed that nothing was being saved but when running the client, it displays in the terminal sending then proceeds to show the credentials chosen in the login/signup page but I guess the server does not receive these data and as such cannot store them. Here are the server and client codes.
Server codes:
import sqlite3 from sqlite3 import Error import socket import threading import pandas as pd import yfinance as yf import os class Database: def __init__(self): self.conn = self.create_connection() def create_connection(self): conn = None try: conn = sqlite3.connect('clients.db') print(f'successful connection with sqlite version {sqlite3.version}') except Error as e: print(e) return conn def create_table(self, create_table_sql): try: c = self.conn.cursor() c.execute(create_table_sql) except Error as e: print(e) def setup_database(self): sql_create_user_table = """CREATE TABLE IF NOT EXISTS clients ( client_id VARCHAR(20) NOT NULL PRIMARY KEY, password VARCHAR(255) NOT NULL, age INT, initial_investment FLOAT, investment_type VARCHAR(255) );""" self.create_table(sql_create_user_table) def create_user(self, user): sql = '''INSERT INTO clients(client_id, password, age, initial_investment, investment_type) VALUES(?,?,?,?,?)''' cur = self.conn.cursor() cur.execute(sql, user) self.conn.commit() return cur.lastrowid def get_all_users(self): cur = self.conn.cursor() cur.execute("SELECT * FROM clients") return cur.fetchall() def user_exists(self, client_id, password): cur = self.conn.cursor() cur.execute("SELECT * FROM clients WHERE client_id = ? AND password = ?", (client_id, password)) return len(cur.fetchall()) > 0 def export_to_csv(self, filename): df = pd.read_sql_query("SELECT * FROM clients", self.conn) df.to_csv(filename, index=False) def import_from_csv(self, filename): df = pd.read_csv(filename) df.to_sql('clients', self.conn, if_exists='replace', index=False) class AssetManager: @staticmethod def get_asset_prices(): assets = ['ETH-USD', 'DOGE-USD', 'BTC-USD', 'GC=F', 'SI=F'] prices = yf.download(assets, start='2023-03-18', end='2023-03-19')['Close'] return prices.iloc[-1].to_dict() class Server: def __init__(self, database, asset_manager): self.database = database self.asset_manager = asset_manager def handle_client(self, client_socket): while True: data = client_socket.recv(1024).decode("utf-8") if not data: break print(f"Received data: {data}") request_type, *request_data = data.split("|") if request_type == "signup": client_id, password, age, initial_investment, investment_type = request_data print(f"Signup data: {client_id}, {password}, {age}, {initial_investment}, {investment_type}") if not self.database.user_exists(client_id, password): self.database.create_user((client_id, password, age, initial_investment, investment_type)) response = "signup_success|Account created successfully." else: response = "signup_failure|Account with this ID and password already exists." elif request_type == "login": client_id, password = request_data if self.database.user_exists(client_id, password): response = "login_success|Login successful." else: response = "login_failure|Invalid ID or password." elif request_type == "view_portfolio": asset_prices = self.asset_manager.get_asset_prices() response = "view_portfolio|" for asset, price in asset_prices.items(): response += f"{asset}: {price}\n" all_users = self.database.get_all_users() response += "\nList of connected users:\n" for user in all_users: response += f"{user[0]}: {user[1]}\n" if request_type in ["signup", "login"]: if "success" in response: self.database.export_to_csv('clients.csv') client_socket.sendall(response.encode("utf-8")) def start(self): if not os.path.exists('clients.csv'): self.database.export_to_csv('clients.csv') self.database.import_from_csv('clients.csv') server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(('localhost', 5000)) server.listen(5) server.settimeout(5) print("Server started. Waiting for connections...") while True: try: client, address = server.accept() client.settimeout(5) # Set the timeout for the new socket print(f"Connection from {address} has been established.") client_thread = threading.Thread(target=self.handle_client, args=(client,)) client_thread.start() except socket.timeout: print("No new connection received. Continuing to wait...") def main(): db = Database() db.setup_database() am = AssetManager() server = Server(db, am) try: server.start() except KeyboardInterrupt: print("Server stopped. Exporting data to 'clients.csv'...") db.export_to_csv('clients.csv') print("Data exported successfully.") if __name__ == "__main__": main() Client: import socket from tkinter import * from tkinter import messagebox from tkinter import simpledialog import yfinance as yf import matplotlib.pyplot as plt class Investment_Interface_App: def __init__(self, root): self.root = root self.root.title("Investment_Interface_App") self.root.geometry("400x400") self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.client_socket.connect(('localhost', 5000)) self.client_socket.settimeout(5) self.login_signup_frame = Frame(self.root) self.login_signup_frame.pack(fill=BOTH, expand=True) self.create_login_signup_frame() def send_request(self, request): client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_socket.connect(('localhost', 5000)) client_socket.sendall(request.encode("utf-8")) response = client_socket.recv(4096).decode("utf-8") client_socket.close() response_type, *response_data = response.split("|") if response_type == "signup_success": messagebox.showinfo("Success", response_data[0]) elif response_type == "signup_failure": messagebox.showerror("Error", response_data[0]) elif response_type == "login_success": messagebox.showinfo("Success", response_data[0]) # Add any additional actions to perform upon successful login elif response_type == "login_failure": messagebox.showerror("Error", response_data[0]) else: messagebox.showerror("Error", "Unknown response type.") return response.split("|") def login(self): self.client_id = self.client_id_entry.get() self.password = self.password_entry.get() if not self.client_id or not self.password: messagebox.showerror("Error", "Please fill in both fields.") return data = f"login|{self.client_id}|{self.password}" response = self.send_request(data) if response is None: return response_status, response_message = response.split("|", 1) if response_status == "login_success": # Proceed to the next page print("Logged in successfully") else: # Show an error message print(f"Login failed: {response_message}") def signup(self): self.client_id = self.client_id_entry.get() self.password = self.password_entry.get() self.age = self.age_entry.get() self.initial_investment = self.initial_investment_entry.get() selected_investment_types = [] for index in self.investment_type_listbox.curselection(): selected_investment_types.append(self.investment_type_listbox.get(index)) self.investment_type = ','.join(selected_investment_types) if not self.client_id or not self.password or not self.age or not self.initial_investment or not self.investment_type: messagebox.showerror("Error", "Please fill in all fields.") return if not (18 <= int(self.age) <= 100): messagebox.showerror("Error", "Age must be between 18 and 100.") return data = f"signup|{self.client_id}|{self.password}|{self.age}|{self.initial_investment}|{self.investment_type}" response = self.send_request(data) if response is None: return if "|" in response: response_status, response_message = response.split("|", 1) if response_status == "success": messagebox.showinfo("Success", response_message) else: messagebox.showerror("Error", response_message) else: messagebox.showerror("Error", f"Unexpected server response: {response}") def create_login_signup_frame(self): Label(self.login_signup_frame, text="ClientID").grid(row=0, column=0, sticky=W) self.client_id_entry = Entry(self.login_signup_frame) self.client_id_entry.grid(row=0, column=1) Label(self.login_signup_frame, text="Password").grid(row=1, column=0, sticky=W) self.password_entry = Entry(self.login_signup_frame, show="*") self.password_entry.grid(row=1,column=1) self.extra_fields = [] self.mode = StringVar() self.mode.set("login") self.mode_button = Button(self.login_signup_frame, text="Switch to Sign Up", command=self.toggle_mode) self.action_button = Button(self.login_signup_frame, text="Login", command=self.login_or_signup) self.mode_button.grid(row=5, column=0, padx=10, pady=10) self.action_button.grid(row=5, column=1, padx=10, pady=10) def toggle_mode(self): if self.mode.get() == "login": self.mode.set("signup") self.mode_button.config(text="Switch to Login") self.action_button.config(text="Sign Up") self.create_signup_frame() else: self.mode.set("login") self.mode_button.config(text="Switch to Sign Up") self.action_button.config(text="Login") self.remove_signup_frame() def create_signup_frame(self): age_label = Label(self.login_signup_frame, text="Age") age_label.grid(row=3, column=0, sticky=W) self.age_entry = Entry(self.login_signup_frame) self.age_entry.grid(row=3, column=1) initial_investment_label = Label(self.login_signup_frame, text="Initial Investment") initial_investment_label.grid(row=4, column=0, sticky=W) self.initial_investment_entry = Entry(self.login_signup_frame) self.initial_investment_entry.grid(row=4, column=1) investment_type_label = Label(self.login_signup_frame, text="Investment Type") investment_type_label.grid(row=5, column=0, sticky=W) self.investment_type_listbox = Listbox(self.login_signup_frame, selectmode=MULTIPLE) self.investment_type_listbox.grid(row=5, column=1) for item in ["Ethereum", "Bitcoin", "DogeCoin", "Gold", "Silver"]: self.investment_type_listbox.insert(END, item) self.extra_fields.extend([age_label, self.age_entry, initial_investment_label, self.initial_investment_entry, investment_type_label, self.investment_type_listbox]) self.mode_button.grid(row=6, column=0, padx=10, pady=10) self.action_button.grid(row=6, column=1, padx=10, pady=10) def remove_signup_frame(self): for field in self.extra_fields: field.grid_remove() self.extra_fields.clear() def login_or_signup(self): client_id = self.client_id_entry.get() password = self.password_entry.get() if self.mode.get() == "signup": age = self.age_entry.get() initial_investment = self.initial_investment_entry.get() investment_type = "|".join([self.investment_type_listbox.get(idx) for idx in self.investment_type_listbox.curselection()]) request = f"signup|{client_id}|{password}|{age}|{initial_investment}|{investment_type}" else: request = f"login|{client_id}|{password}" self.send_request(request) def create_account_frame(self): self.account_frame = Frame(self.root) self.account_frame.pack(fill=BOTH, expand=True) self.open_account_button = Button(self.account_frame, text="Open An Account", command=self.open_account) self.open_account_button.pack(pady=10) def open_account(self): self.account_frame.pack_forget() self.create_options_frame() def create_options_frame(self): self.options_frame = Frame(self.root) self.options_frame.pack(fill=BOTH, expand=True) self.invest_now_button = Button(self.options_frame, text="Invest Now", command=self.invest_now) self.invest_now_button.pack(pady=10) self.portfolio_viewing_button = Button(self.options_frame, text="Portfolio Viewing", command=self.view_portfolio) self.portfolio_viewing_button.pack(pady=10) self.pay_in_out_button = Button(self.options_frame, text="Pay In/Withdraw", command=self.pay_in_out) self.pay_in_out_button.pack(pady=10) def invest_now(self): self.options_frame.pack_forget() self.invest_now_frame = Frame(self.root) self.invest_now_frame.pack(fill=BOTH, expand=True) Label(self.invest_now_frame, text="Investment").grid(row=0, column=0, sticky=W) self.investment_choice = StringVar() self.investment_menu = OptionMenu(self.invest_now_frame, self.investment_choice, *["Ethereum", "LiteCoin", "DogeCoin", "Shiba Inu", "Binance Coin", "Gold", "Silver"]) self.investment_menu.grid(row=0, column=1) Label(self.invest_now_frame, text="Quantity").grid(row=1, column=0, sticky=W) self.quantity_entry = Entry(self.invest_now_frame) self.quantity_entry.grid(row=1, column=1) self.calculate_button = Button(self.invest_now_frame, text="Calculate Value", command=self.calculate_value) self.calculate_button.grid(row=2, column=1, pady=10) def calculate_value(self): investment = self.investment_choice.get() quantity = float(self.quantity_entry.get()) data = f"get_current_price|{investment}" response = self.send_request(data) if response is None: return current_price = float(response) value = current_price * quantity messagebox.showinfo("Investment Value", f"The value of {quantity} {investment} is ${value:.2f}") def get_latest_prices(self, investment_types): ticker_symbols = { "Gold": "GC=F", "Silver": "SI=F", "Ethereum": "ETH-USD", "Bitcoin": "BTC-USD", "DogeCoin": "DOGE-USD" } prices = {} for investment in investment_types: ticker = yf.Ticker(ticker_symbols[investment]) latest_price = ticker.info["regularMarketPrice"] prices[investment] = latest_price return prices def view_portfolio(self): data = f"view_portfolio|{self.client_id}" response = self.send_request(data) if response is None: return if response.startswith("success"): portfolio = response[8:] investment_types = portfolio.split(",") # Get the latest prices latest_prices = self.get_latest_prices(investment_types) # Calculate the value of each investment type quantities = [1, 2, 3] # Replace this with the actual quantities of the investments values = [quantities[i] * latest_prices[investment] for i, investment in `your text`enumerate(investment_types)] # Generate a bar chart plt.bar(investment_types, values) plt.xlabel("Investment Types") plt.ylabel("Value") plt.title("Portfolio") plt.show() messagebox.showinfo("Portfolio", f"Your portfolio: {portfolio}") else: messagebox.showerror("Error", "Failed to fetch portfolio.") def pay_in_out(self): self.options_frame.pack_forget() self.pay_in_out_frame = Frame(self.root) self.pay_in_out_frame.pack(fill=BOTH, expand=True) self.pay_in_button = Button(self.pay_in_out_frame, text="Pay In", command=self.pay_in) self.pay_in_button.pack(pady=10) self.withdraw_button = Button(self.pay_in_out_frame, text="Withdraw", command=self.withdraw) self.withdraw_button.pack(pady=10) def pay_in(self): amount = simpledialog.askfloat("Pay In", "Enter the amount to pay in:", parent=self.root, minvalue=0) if amount is None: return data = f"pay_in|{amount}" response = self.send_request(data) if response is None: return if response == "success": messagebox.showinfo("Success", f"${amount:.2f} has been successfully added to your account.") else: messagebox.showerror("Error", "Failed to pay in.") def withdraw(self): amount = simpledialog.askfloat("Withdraw", "Enter the amount to withdraw:", parent=self.root, minvalue=0) if amount is None: return data = f"withdraw|{amount}" response = self.send_request(data) if response is None: return if response == "success": messagebox.showinfo("Success", f"${amount:.2f} has been successfully withdrawn from your account.") else: messagebox.showerror("Error", "Failed to withdraw.") if __name__ == "__main__": root = Tk() app = Investment_Interface_App(root) root.mainloop()