所以我的 python 程序本质上是一个投资界面,客户端显示图形元素,比如第一页是登录或注册页面,然后当用户的凭据针对使用 sqlite 数据库存储所述条目的服务器进行验证时。然后在成功登录后,用户将移至下一个页面,其中实例化了其他元素。我的问题是每次我登录或注册时,按下任一按钮都会冻结整个图形用户界面,我必须硬关闭它。我尝试使用存储 sql 数据库条目的 csv 文件,然后使用 pandas 读取所述 csv 以确认正确的条目,但无济于事。如果此功能不工作,我将无法继续进行。任何帮助深表感谢。多年来一直在尝试调试它。
使用连接到 sql 数据库的 csv 然后 pandas 从所述 csv 读取,不起作用,我注意到没有任何内容被保存但是当运行客户端时,它显示在终端发送然后继续显示在登录/注册中选择的凭据页面,但我猜服务器没有收到这些数据,因此无法存储它们。这是服务器和客户端代码。
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 Codes: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()