-
Notifications
You must be signed in to change notification settings - Fork 24
/
Copy pathtest.py
125 lines (106 loc) · 3.02 KB
/
test.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
from enum import IntEnum
from typing import Dict, Optional
from pydantic import BaseModel
from core.model.base import PCallRet
class MarketTransCode(IntEnum):
"""
market transaction codes
"""
BUY_PRODUCT = 1001
MODIFY_PRICE = 1002
class Product(BaseModel):
"""
product model
"""
pid: int
name: str
origin: str
price: float
num: int = 0
profit: float = 0.0
class Sex(IntEnum):
"""
sex enum
"""
FEMALE = 0
MALE = 1
class Customer(BaseModel):
"""
customer model
"""
cid: int
name: str
sex: Sex
city: str = ''
balance: float = 0.0
products: Dict[int, int] = {} # { pid: num }
@classmethod
def female(cls, **kwargs):
return Customer(sex=Sex.FEMALE, **kwargs)
@classmethod
def male(cls, **kwargs):
return Customer(sex=Sex.MALE, **kwargs)
class Market(BaseModel):
"""
market instance
"""
products: Dict[int, Product] = {}
customers: Dict[int, Customer] = {}
def add_product(self, product: Product) -> None:
"""
add a product
:param product: product instance
:return: None
"""
assert product.pid not in self.products.keys()
self.products[product.pid] = product
def add_customer(self, customer: Customer) -> None:
"""
add a customer
:param customer: customer instance
:return: None
"""
assert customer.cid not in self.customers.keys()
self.customers[customer.cid] = customer
def get_product(self, pid: int) -> Optional[Product]:
"""
get product by pid
:param pid: product id
:return: optional product instance
"""
return self.products.get(pid)
def get_customer(self, cid: int) -> Optional[Customer]:
"""
get customer by cid
:param cid: customer id
:return: optional customer instance
"""
return self.customers.get(cid)
def handle_transaction(self, cid: int, pid: int, num: int) -> PCallRet:
"""
handle transaction
:param cid: customer id
:param pid: product id
:param num: number of products
:return: ok (if transaction is successful), err (error message)
"""
if num <= 0:
return False, 'invalid trade num %d' % num
customer = self.get_customer(cid)
if not customer:
return False, 'no customer with id %d' % cid
product = self.get_product(pid)
if not product:
return False, 'no product with id %d' % pid
if product.num < num:
return False, 'insufficient products'
exchange = product.price * num
if customer.balance < exchange:
return False, 'insufficient balance'
if pid not in customer.products.keys():
customer.products[pid] = 0
customer.products[pid] += num
product.num -= num
product.profit += exchange
customer.balance -= exchange
return True, ''