Skip to content

Commit e4313cb

Browse files
authored
Add files via upload
1 parent 55affe6 commit e4313cb

File tree

3 files changed

+220
-0
lines changed

3 files changed

+220
-0
lines changed

LLM API Price Comperator.ico

77.1 KB
Binary file not shown.

LLM API Price Comperator.py

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
import sys
2+
import requests
3+
from PyQt5.QtWidgets import (
4+
QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
5+
QPushButton, QLabel, QLineEdit, QComboBox, QCheckBox, QMessageBox, QGridLayout,
6+
QScrollArea, QFrame
7+
)
8+
from PyQt5.QtGui import QIcon
9+
from PyQt5.QtCore import Qt
10+
11+
def validate_float(text):
12+
try:
13+
if text:
14+
text = text.replace('。', '.')
15+
float(text)
16+
return True
17+
return False
18+
except ValueError:
19+
return False
20+
21+
class NumericLineEdit(QLineEdit):
22+
def __init__(self, placeholder_text='', parent=None):
23+
super().__init__(parent)
24+
self.setPlaceholderText(placeholder_text)
25+
26+
def focusOutEvent(self, event):
27+
text = self.text()
28+
if text and not validate_float(text):
29+
QMessageBox.warning(self, "输入错误", "请输入有效的数字。")
30+
self.clear()
31+
super().focusOutEvent(event)
32+
33+
class LLMComparisonTool(QMainWindow):
34+
def __init__(self):
35+
super().__init__()
36+
self.setWindowTitle("LLM API价格比较器")
37+
self.setWindowIcon(QIcon("D:\\Price\\LLM API Price Comperator.ico")) # Set the window icon
38+
self.setGeometry(100, 100, 1200, 350) # Adjust window size
39+
self.exchange_rate = 1.0
40+
self.initUI()
41+
self.get_exchange_rate()
42+
43+
def initUI(self):
44+
self.central_widget = QWidget()
45+
self.setCentralWidget(self.central_widget)
46+
self.layout = QVBoxLayout()
47+
self.central_widget.setLayout(self.layout)
48+
49+
self.exchange_rate_layout = QHBoxLayout()
50+
self.exchange_rate_label = QLabel("当前汇率(USD/CNY): 获取中...")
51+
self.refresh_rate_button = QPushButton("刷新汇率")
52+
self.refresh_rate_button.clicked.connect(self.get_exchange_rate)
53+
self.exchange_rate_layout.addWidget(self.exchange_rate_label)
54+
self.exchange_rate_layout.addWidget(self.refresh_rate_button)
55+
self.layout.addLayout(self.exchange_rate_layout)
56+
57+
self.token_input_layout = QHBoxLayout()
58+
self.token_input = NumericLineEdit("输入Token数")
59+
self.token_output = NumericLineEdit("输出Token数")
60+
self.token_input_layout.addWidget(QLabel("输入Token数:"))
61+
self.token_input_layout.addWidget(self.token_input)
62+
self.token_input_layout.addWidget(QLabel("输出Token数:"))
63+
self.token_input_layout.addWidget(self.token_output)
64+
self.layout.addLayout(self.token_input_layout)
65+
66+
self.scroll_area = QScrollArea()
67+
self.scroll_area.setWidgetResizable(True)
68+
self.scroll_frame = QFrame()
69+
self.scroll_area.setWidget(self.scroll_frame)
70+
self.layout.addWidget(self.scroll_area)
71+
72+
self.providers_grid = QGridLayout(self.scroll_frame)
73+
headers = ["服务商名称", "充值金额 (仅数字)", "充值货币", "到账余额 (仅数字)", "输入价格 (仅数字)", "输出价格 (仅数字)", "不区分输入输出", "Token单位", "操作"]
74+
for i, header in enumerate(headers):
75+
self.providers_grid.addWidget(QLabel(header), 0, i)
76+
77+
self.add_provider_button = QPushButton("添加更多服务商")
78+
self.add_provider_button.clicked.connect(self.add_provider_row)
79+
self.layout.addWidget(self.add_provider_button)
80+
81+
self.result_label = QLabel("费用排名(由低至高):")
82+
self.result_list = QLabel("")
83+
self.layout.addWidget(self.result_label)
84+
self.layout.addWidget(self.result_list)
85+
86+
self.calculate_button = QPushButton("计算成本")
87+
self.calculate_button.clicked.connect(self.calculate_costs)
88+
self.layout.addWidget(self.calculate_button)
89+
90+
self.clear_button = QPushButton("清除所有数据")
91+
self.clear_button.clicked.connect(self.clear_all_data)
92+
self.layout.addWidget(self.clear_button)
93+
94+
self.github_link = QLabel('<a href="https://github.com/CookSleep/LLM-API-Price-Comperator">GitHub @CookSleep</a>')
95+
self.github_link.setOpenExternalLinks(True)
96+
self.github_link.setAlignment(Qt.AlignCenter)
97+
self.layout.addWidget(self.github_link)
98+
99+
self.clear_all_data() # Initially setup with two default rows
100+
101+
def add_provider_row(self):
102+
index = self.providers_grid.rowCount()
103+
provider_name = QLineEdit()
104+
recharge_amount = NumericLineEdit("仅数字")
105+
currency_combo = QComboBox()
106+
currency_combo.addItems(["CNY", "USD"])
107+
balance = NumericLineEdit("仅数字")
108+
input_price = NumericLineEdit("仅数字")
109+
output_price = NumericLineEdit("仅数字")
110+
input_output_checkbox = QCheckBox()
111+
token_unit_combo = QComboBox()
112+
token_unit_combo.addItems(["1K token", "1M token"])
113+
delete_button = QPushButton("删除")
114+
delete_button.clicked.connect(lambda: self.delete_provider_row(index))
115+
116+
row_widgets = [provider_name, recharge_amount, currency_combo, balance, input_price, output_price, input_output_checkbox, token_unit_combo, delete_button]
117+
for i, widget in enumerate(row_widgets):
118+
self.providers_grid.addWidget(widget, index, i)
119+
120+
def delete_provider_row(self, index):
121+
for j in range(9):
122+
item = self.providers_grid.itemAtPosition(index, j)
123+
if item:
124+
widget = item.widget()
125+
if widget:
126+
widget.deleteLater()
127+
128+
def clear_all_data(self):
129+
for i in reversed(range(1, self.providers_grid.rowCount())):
130+
self.delete_provider_row(i)
131+
self.token_input.clear()
132+
self.token_output.clear()
133+
for _ in range(2):
134+
self.add_provider_row()
135+
136+
def get_exchange_rate(self):
137+
try:
138+
response = requests.get('https://api.exchangerate-api.com/v4/latest/USD')
139+
data = response.json()
140+
self.exchange_rate = data['rates']['CNY']
141+
self.exchange_rate_label.setText(f"当前汇率(USD/CNY): {self.exchange_rate:.4f}")
142+
except Exception as e:
143+
QMessageBox.warning(self, "网络错误", "无法获取汇率,请检查网络连接后重试。")
144+
self.exchange_rate_label.setText("当前汇率(USD/CNY): 获取失败")
145+
146+
def calculate_costs(self):
147+
results = []
148+
input_tokens = float(self.token_input.text()) if self.token_input.text() else 0
149+
output_tokens = float(self.token_output.text()) if self.token_output.text() else 0
150+
151+
for i in range(1, self.providers_grid.rowCount()):
152+
try:
153+
provider_name = self.providers_grid.itemAtPosition(i, 0).widget().text()
154+
recharge_amount = float(self.providers_grid.itemAtPosition(i, 1).widget().text())
155+
currency = self.providers_grid.itemAtPosition(i, 2).widget().currentText()
156+
balance = float(self.providers_grid.itemAtPosition(i, 3).widget().text())
157+
input_price = float(self.providers_grid.itemAtPosition(i, 4).widget().text())
158+
output_price = float(self.providers_grid.itemAtPosition(i, 5).widget().text()) if not self.providers_grid.itemAtPosition(i, 6).widget().isChecked() else input_price
159+
tokens_per_unit = {'1K token': 1000, '1M token': 1000000}[self.providers_grid.itemAtPosition(i, 7).widget().currentText()]
160+
161+
if currency == "USD":
162+
recharge_amount *= self.exchange_rate
163+
164+
cost_per_token_input = (recharge_amount / balance) * input_price / tokens_per_unit
165+
cost_per_token_output = (recharge_amount / balance) * output_price / tokens_per_unit
166+
total_cost_cny = cost_per_token_input * input_tokens + cost_per_token_output * output_tokens
167+
total_cost_usd = total_cost_cny / self.exchange_rate
168+
results.append((provider_name, total_cost_cny, total_cost_usd))
169+
except ValueError:
170+
QMessageBox.warning(self, "错误", f"请检查第{i}行的数据输入。")
171+
return
172+
173+
results.sort(key=lambda x: x[1])
174+
result_text = "\n".join([f"{name}: {cny_cost:.4f} RMB / {usd_cost:.4f} USD" for name, cny_cost, usd_cost in results])
175+
self.result_list.setText(result_text)
176+
177+
if __name__ == "__main__":
178+
app = QApplication(sys.argv)
179+
mainWin = LLMComparisonTool()
180+
mainWin.show()
181+
sys.exit(app.exec_())

LLM API Price Comperator.spec

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# -*- mode: python ; coding: utf-8 -*-
2+
3+
4+
a = Analysis(
5+
['LLM API Price Comperator.py'],
6+
pathex=[],
7+
binaries=[],
8+
datas=[],
9+
hiddenimports=[],
10+
hookspath=[],
11+
hooksconfig={},
12+
runtime_hooks=[],
13+
excludes=[],
14+
noarchive=False,
15+
optimize=0,
16+
)
17+
pyz = PYZ(a.pure)
18+
19+
exe = EXE(
20+
pyz,
21+
a.scripts,
22+
a.binaries,
23+
a.datas,
24+
[],
25+
name='LLM API Price Comperator',
26+
debug=False,
27+
bootloader_ignore_signals=False,
28+
strip=False,
29+
upx=True,
30+
upx_exclude=[],
31+
runtime_tmpdir=None,
32+
console=False,
33+
disable_windowed_traceback=False,
34+
argv_emulation=False,
35+
target_arch=None,
36+
codesign_identity=None,
37+
entitlements_file=None,
38+
icon=['D:\\Price\\LLM API Price Comperator.ico'],
39+
)

0 commit comments

Comments
 (0)