Kpenciler commited on
Commit
1058ca8
1 Parent(s): c36b8c2

Upload 5 files

Browse files
Files changed (5) hide show
  1. app.py +35 -0
  2. app_gradio.py +35 -0
  3. app_streamlit.py +27 -0
  4. requirements.txt +3 -0
  5. utils.py +107 -0
app.py ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from utils import get_calculated_df, get_info, text2oddslist
3
+
4
+
5
+ def calculate(amount, text):
6
+ df = get_calculated_df(amount, text2oddslist(text))
7
+ info = get_info(df)
8
+
9
+ # dfの整形
10
+ display_cols = ["odds", "buy", "refound"]
11
+ if df["name"].map(lambda name: name != "").any():
12
+ display_cols = ["name"] + display_cols
13
+
14
+ # markdownの整形
15
+ md_string = (
16
+ f"**購入額:** ¥ **{info['sum']:,}**<br>"
17
+ f"**点数:** **{info['num_kind']}** 点<br>"
18
+ f"**払戻:** ¥ **{info['refound_mean']:,}** (**{info['profit_mean']:+,}** (**{info['rate_min']:+.0%}**))<br>"
19
+ "---"
20
+ )
21
+
22
+ return md_string, df[["index"] + display_cols]
23
+
24
+
25
+ amount_input = gr.Number(value=3000, label="amount")
26
+ text_input = gr.Textbox(label="text")
27
+ markdown_output = gr.Markdown()
28
+ df_output = gr.Dataframe(type="pandas")
29
+ iface = gr.Interface(
30
+ fn=calculate,
31
+ inputs=[amount_input, text_input],
32
+ outputs=[markdown_output, df_output],
33
+ )
34
+
35
+ iface.launch()
app_gradio.py ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from utils import get_calculated_df, get_info, text2oddslist
3
+
4
+
5
+ def calculate(amount, text):
6
+ df = get_calculated_df(amount, text2oddslist(text))
7
+ info = get_info(df)
8
+
9
+ # dfの整形
10
+ display_cols = ["odds", "buy", "refound"]
11
+ if df["name"].map(lambda name: name != "").any():
12
+ display_cols = ["name"] + display_cols
13
+
14
+ # markdownの整形
15
+ md_string = (
16
+ f"**購入額:** ¥ **{info['sum']:,}**<br>"
17
+ f"**点数:** **{info['num_kind']}** 点<br>"
18
+ f"**払戻:** ¥ **{info['refound_mean']:,}** (**{info['profit_mean']:+,}** (**{info['rate_min']:+.0%}**))<br>"
19
+ "---"
20
+ )
21
+
22
+ return md_string, df[["index"] + display_cols]
23
+
24
+
25
+ amount_input = gr.Number(value=3000, label="amount")
26
+ text_input = gr.Textbox(label="text")
27
+ markdown_output = gr.Markdown()
28
+ df_output = gr.Dataframe(type="pandas")
29
+ iface = gr.Interface(
30
+ fn=calculate,
31
+ inputs=[amount_input, text_input],
32
+ outputs=[markdown_output, df_output],
33
+ )
34
+
35
+ iface.launch()
app_streamlit.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from utils import get_calculated_df, get_info, text2oddslist
3
+
4
+ amount: int = int(st.number_input("amount", min_value=100, value=3000, step=100))
5
+ text: str = st.text_area("text", "")
6
+ # ボタンを作る
7
+ st.button("calculate")
8
+ if text:
9
+ df = get_calculated_df(amount, text2oddslist(text))
10
+ # dataframeを綺麗に出力する
11
+ info = get_info(df)
12
+ col1, col2 = st.columns(2)
13
+ with col1:
14
+ st.markdown(f"#### 購入額: ¥ **{info['sum']:,}**")
15
+ st.markdown(f"#### 点 数: **{info['num_kind']}** 点")
16
+ with col2:
17
+ st.metric(
18
+ label="払戻",
19
+ value=f"¥ {info['refound_mean']:,}",
20
+ delta=f"{info['profit_mean']:+,}({info['rate_min']:.0%})",
21
+ )
22
+ st.markdown("---")
23
+ # dfの表示
24
+ display_cols = ["odds", "buy", "refound"]
25
+ if df["name"].map(lambda name: name != "").any():
26
+ display_cols = ["name"] + display_cols
27
+ st.dataframe(df[display_cols])
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ pandas==2.1.0
2
+ streamlit==1.26.0
3
+ gradio==3.44.3
utils.py ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import math
2
+ from typing import TypedDict
3
+
4
+ import pandas as pd
5
+
6
+
7
+ # Typing -----------------------------------------------------------------------
8
+ class OddsInfo(TypedDict):
9
+ index: str
10
+ name: str
11
+ odds: float
12
+
13
+
14
+ OdddsList = list[OddsInfo]
15
+
16
+
17
+ class Info(TypedDict):
18
+ sum: int
19
+ num_kind: int
20
+ refound_mean: int
21
+ profit_mean: int
22
+ rate_min: float
23
+ rate_max: float
24
+ rate_mean: float
25
+
26
+
27
+ # text -> odds_list ------------------------------------------------------------
28
+ def _text2oddslist_pc(text: str) -> OdddsList:
29
+ odds_list: OdddsList = []
30
+ tmp_list: list[str] = []
31
+ lines: list[str] = text.split("\n")
32
+ for text in lines:
33
+ if "." in text:
34
+ odds_list.append(
35
+ {
36
+ "index": "-".join(tmp_list),
37
+ "name": "",
38
+ "odds": float(text),
39
+ }
40
+ )
41
+ tmp_list = []
42
+ else:
43
+ if text.strip():
44
+ tmp_list.append(text.strip())
45
+ return odds_list
46
+
47
+
48
+ def _text2oddslist_mobile(text: str) -> OdddsList:
49
+ odds_list: OdddsList = []
50
+ lines: list[str] = text.split("\n")
51
+ if "選択" in lines:
52
+ lines = lines[lines.index("選択") + 1 :]
53
+ if "すべてを選択" in lines:
54
+ lines = lines[: lines.index("すべてを選択")]
55
+ for i in range(len(lines) // 3):
56
+ # oddsが1つ目にある
57
+ if "." in lines[3 * i + 1]:
58
+ idx_odds = 1
59
+ idx_name = 2
60
+ else:
61
+ idx_odds = 2
62
+ idx_name = 1
63
+
64
+ odds_list.append(
65
+ {
66
+ "index": "-".join(lines[3 * i].split()),
67
+ "name": "-".join(lines[3 * i + idx_name].split()),
68
+ "odds": float(lines[3 * i + idx_odds]),
69
+ }
70
+ )
71
+ return odds_list
72
+
73
+
74
+ def text2oddslist(text: str) -> OdddsList:
75
+ # pcの時
76
+ if set("".join(text.split())) <= set("0123456789.-"):
77
+ odds_list = _text2oddslist_pc(text)
78
+ # moduleの時
79
+ else:
80
+ odds_list = _text2oddslist_mobile(text)
81
+ return odds_list
82
+
83
+
84
+ # odds_list -> df ---------------------------------------------------------------
85
+ def get_calculated_df(amount: int, odds_list: OdddsList) -> pd.DataFrame:
86
+ df = pd.DataFrame(odds_list)
87
+ df["weight"] = (1 / df["odds"]) / (1 / df["odds"]).sum()
88
+ df["buy"] = (df["weight"] * amount / 100).map(
89
+ lambda x: max(math.floor(x) * 100, 100)
90
+ )
91
+ df["refound"] = (df["buy"] * df["odds"]).astype(int)
92
+ df["profit"] = df["refound"] - amount
93
+ df = df
94
+ return df
95
+
96
+
97
+ def get_info(df: pd.DataFrame) -> Info:
98
+ info: Info = {
99
+ "sum": df["buy"].sum(),
100
+ "num_kind": df.shape[0],
101
+ "refound_mean": int(df["refound"].mean()),
102
+ "profit_mean": int(df["profit"].mean()),
103
+ "rate_min": df["refound"].min() / df["buy"].sum(),
104
+ "rate_max": df["refound"].max() / df["buy"].sum(),
105
+ "rate_mean": df["refound"].mean() / df["buy"].sum(),
106
+ }
107
+ return info