Spaces:
Runtime error
Runtime error
neoai-kterasawa commited on
Commit ·
e656870
1
Parent(s): 7131f8d
modelのpyファイルを分ける
Browse files
src/func.py
CHANGED
|
@@ -1,9 +1,9 @@
|
|
| 1 |
-
from src.model.
|
| 2 |
|
| 3 |
|
| 4 |
-
def calculate(budget: int, raw_text: str) -> tuple[str,
|
| 5 |
choices = Choices.from_text(raw_text)
|
| 6 |
-
choices_with_bet =
|
| 7 |
|
| 8 |
summary_markdown = choices_with_bet.to_summary_markdwown()
|
| 9 |
table = choices_with_bet.to_table()
|
|
|
|
| 1 |
+
from src.model.choice import Choices, ChoicesWithBet, ChoiceWithBetTable
|
| 2 |
|
| 3 |
|
| 4 |
+
def calculate(budget: int, raw_text: str) -> tuple[str, ChoiceWithBetTable]:
|
| 5 |
choices = Choices.from_text(raw_text)
|
| 6 |
+
choices_with_bet = ChoicesWithBet.from_choices(choices, budget)
|
| 7 |
|
| 8 |
summary_markdown = choices_with_bet.to_summary_markdwown()
|
| 9 |
table = choices_with_bet.to_table()
|
src/model/choice/__init__.py
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from .choice import Choice
|
| 2 |
+
from .choice_with_bet import ChoiceWithBet
|
| 3 |
+
from .choices import Choices
|
| 4 |
+
from .choices_with_bet import ChoicesWithBet, ChoiceWithBetTable
|
| 5 |
+
|
| 6 |
+
__all__ = ["Choice", "ChoiceWithBet", "Choices", "ChoicesWithBet", "ChoiceWithBetTable"]
|
src/model/choice/choice.py
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from pydantic import BaseModel, StrictFloat, StrictStr
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
class Choice(BaseModel):
|
| 5 |
+
name: StrictStr
|
| 6 |
+
odds: StrictFloat
|
src/model/choice/choice_with_bet.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from pydantic import StrictInt, computed_field
|
| 2 |
+
|
| 3 |
+
from .choice import Choice
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
class ChoiceWithBet(Choice):
|
| 7 |
+
bet_amount: StrictInt
|
| 8 |
+
|
| 9 |
+
@computed_field # type: ignore
|
| 10 |
+
@property
|
| 11 |
+
def pay_back(self) -> int:
|
| 12 |
+
return int(self.bet_amount * self.odds)
|
| 13 |
+
|
| 14 |
+
@computed_field # type: ignore
|
| 15 |
+
@property
|
| 16 |
+
def profit(self) -> int:
|
| 17 |
+
return self.pay_back - self.bet_amount
|
src/model/{choices.py → choice/choices.py}
RENAMED
|
@@ -1,29 +1,11 @@
|
|
| 1 |
import re
|
| 2 |
from typing import Final
|
| 3 |
|
| 4 |
-
from pydantic import
|
| 5 |
-
computed_field, field_validator)
|
| 6 |
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
class Choice(BaseModel):
|
| 11 |
-
name: StrictStr
|
| 12 |
-
odds: StrictFloat
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
class ChoiceWithBet(Choice):
|
| 16 |
-
bet_amount: StrictInt
|
| 17 |
|
| 18 |
-
|
| 19 |
-
@property
|
| 20 |
-
def pay_back(self) -> int:
|
| 21 |
-
return int(self.bet_amount * self.odds)
|
| 22 |
-
|
| 23 |
-
@computed_field # type: ignore
|
| 24 |
-
@property
|
| 25 |
-
def profit(self) -> int:
|
| 26 |
-
return self.pay_back - self.bet_amount
|
| 27 |
|
| 28 |
|
| 29 |
class Choices(RootModel[list[Choice]]):
|
|
@@ -36,22 +18,6 @@ class Choices(RootModel[list[Choice]]):
|
|
| 36 |
raise ValueError("買い目が1つもありません")
|
| 37 |
return choices
|
| 38 |
|
| 39 |
-
def to_choices_with_bet(self, budget: int) -> "ChoicesWithBet":
|
| 40 |
-
inverse_ratios_sum = sum(1 / choice.odds for choice in self.root)
|
| 41 |
-
|
| 42 |
-
choice_with_bet_list: list[ChoiceWithBet] = []
|
| 43 |
-
for chice in self.root:
|
| 44 |
-
weight = (1 / chice.odds) / inverse_ratios_sum
|
| 45 |
-
choice_with_bet_list.append(
|
| 46 |
-
ChoiceWithBet(
|
| 47 |
-
name=chice.name,
|
| 48 |
-
odds=chice.odds,
|
| 49 |
-
bet_amount=max(int(weight * budget / 100) * 100, 100),
|
| 50 |
-
)
|
| 51 |
-
)
|
| 52 |
-
|
| 53 |
-
return ChoicesWithBet(root=choice_with_bet_list)
|
| 54 |
-
|
| 55 |
@classmethod
|
| 56 |
def from_text(cls, text: str) -> "Choices":
|
| 57 |
FIRST_KEYS: Final[list[str]] = [
|
|
@@ -118,40 +84,3 @@ class Choices(RootModel[list[Choice]]):
|
|
| 118 |
)
|
| 119 |
)
|
| 120 |
return cls(root=choice_list)
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
class ChoicesWithBet(RootModel[list[ChoiceWithBet]]):
|
| 124 |
-
root: list[ChoiceWithBet]
|
| 125 |
-
|
| 126 |
-
def to_summary_markdwown(self) -> str:
|
| 127 |
-
return (
|
| 128 |
-
f"**点数**: {len(self.root)} 点<br>"
|
| 129 |
-
f"**購入額**: ¥ {self.total_bet_amount:,}<br>"
|
| 130 |
-
f"**回収率**: {self.average_pay_back / self.total_bet_amount:.0%}"
|
| 131 |
-
)
|
| 132 |
-
|
| 133 |
-
def to_table(self) -> list[list]:
|
| 134 |
-
return [
|
| 135 |
-
[
|
| 136 |
-
choice.name,
|
| 137 |
-
choice.odds,
|
| 138 |
-
choice.bet_amount,
|
| 139 |
-
choice.pay_back,
|
| 140 |
-
]
|
| 141 |
-
for choice in self.root
|
| 142 |
-
]
|
| 143 |
-
|
| 144 |
-
@computed_field # type: ignore
|
| 145 |
-
@property
|
| 146 |
-
def total_bet_amount(self) -> int:
|
| 147 |
-
return sum(choice.bet_amount for choice in self.root)
|
| 148 |
-
|
| 149 |
-
@computed_field # type: ignore
|
| 150 |
-
@property
|
| 151 |
-
def average_pay_back(self) -> float:
|
| 152 |
-
return sum(choice.pay_back for choice in self.root) / len(self.root)
|
| 153 |
-
|
| 154 |
-
@computed_field # type: ignore # type: ignore
|
| 155 |
-
@property
|
| 156 |
-
def average_profit(self) -> float:
|
| 157 |
-
return sum(choice.profit for choice in self.root) / len(self.root)
|
|
|
|
| 1 |
import re
|
| 2 |
from typing import Final
|
| 3 |
|
| 4 |
+
from pydantic import RootModel, field_validator
|
|
|
|
| 5 |
|
| 6 |
+
from .choice import Choice
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
|
| 8 |
+
NUMBER_JOINER: Final[str] = "-"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
|
| 10 |
|
| 11 |
class Choices(RootModel[list[Choice]]):
|
|
|
|
| 18 |
raise ValueError("買い目が1つもありません")
|
| 19 |
return choices
|
| 20 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
@classmethod
|
| 22 |
def from_text(cls, text: str) -> "Choices":
|
| 23 |
FIRST_KEYS: Final[list[str]] = [
|
|
|
|
| 84 |
)
|
| 85 |
)
|
| 86 |
return cls(root=choice_list)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/model/choice/choices_with_bet.py
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from pydantic import RootModel, computed_field
|
| 2 |
+
|
| 3 |
+
from .choice_with_bet import ChoiceWithBet
|
| 4 |
+
from .choices import Choices
|
| 5 |
+
|
| 6 |
+
ChoiceWithBetTable = list[tuple[str, float, int, int]]
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
class ChoicesWithBet(RootModel[list[ChoiceWithBet]]):
|
| 10 |
+
root: list[ChoiceWithBet]
|
| 11 |
+
|
| 12 |
+
@classmethod
|
| 13 |
+
def from_choices(cls, choices: Choices, budget: int) -> "ChoicesWithBet":
|
| 14 |
+
inverse_ratios_sum = sum(1 / choice.odds for choice in choices.root) # 標準化用
|
| 15 |
+
|
| 16 |
+
choice_with_bet_list: list[ChoiceWithBet] = []
|
| 17 |
+
for chice in choices.root:
|
| 18 |
+
weight = (1 / chice.odds) / inverse_ratios_sum
|
| 19 |
+
choice_with_bet_list.append(
|
| 20 |
+
ChoiceWithBet(
|
| 21 |
+
name=chice.name,
|
| 22 |
+
odds=chice.odds,
|
| 23 |
+
bet_amount=max(int(weight * budget / 100) * 100, 100),
|
| 24 |
+
)
|
| 25 |
+
)
|
| 26 |
+
return cls(root=choice_with_bet_list)
|
| 27 |
+
|
| 28 |
+
def to_summary_markdwown(self) -> str:
|
| 29 |
+
return (
|
| 30 |
+
f"**点数**: {len(self.root)}点<br>"
|
| 31 |
+
f"**購入/払戻**: ¥{self.total_bet_amount:,} → ¥{int(self.average_pay_back):,} ({int(self.average_profit):+,})<br>"
|
| 32 |
+
f"**回収率**: {self.average_pay_back / self.total_bet_amount:.0%}"
|
| 33 |
+
)
|
| 34 |
+
|
| 35 |
+
def to_table(self) -> ChoiceWithBetTable:
|
| 36 |
+
return [
|
| 37 |
+
(
|
| 38 |
+
choice.name,
|
| 39 |
+
choice.odds,
|
| 40 |
+
choice.bet_amount,
|
| 41 |
+
choice.pay_back,
|
| 42 |
+
)
|
| 43 |
+
for choice in self.root
|
| 44 |
+
]
|
| 45 |
+
|
| 46 |
+
@computed_field # type: ignore
|
| 47 |
+
@property
|
| 48 |
+
def total_bet_amount(self) -> int:
|
| 49 |
+
return sum(choice.bet_amount for choice in self.root)
|
| 50 |
+
|
| 51 |
+
@computed_field # type: ignore
|
| 52 |
+
@property
|
| 53 |
+
def average_pay_back(self) -> float:
|
| 54 |
+
_average_pay_back: float = sum(choice.pay_back for choice in self.root) / len(
|
| 55 |
+
self.root
|
| 56 |
+
)
|
| 57 |
+
return _average_pay_back
|
| 58 |
+
|
| 59 |
+
@computed_field # type: ignore
|
| 60 |
+
@property
|
| 61 |
+
def average_profit(self) -> float:
|
| 62 |
+
return self.average_pay_back - self.total_bet_amount
|