openfund-core 0.0.3__py3-none-any.whl → 1.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. core/Exchange.py +276 -0
  2. core/main.py +23 -0
  3. core/smc/SMCBase.py +130 -0
  4. core/smc/SMCFVG.py +86 -0
  5. core/smc/SMCLiquidity.py +7 -0
  6. core/smc/SMCOrderBlock.py +288 -0
  7. core/smc/SMCPDArray.py +77 -0
  8. core/smc/SMCStruct.py +290 -0
  9. core/smc/__init__.py +0 -0
  10. core/utils/OPTools.py +30 -0
  11. openfund_core-1.0.1.dist-info/METADATA +48 -0
  12. openfund_core-1.0.1.dist-info/RECORD +15 -0
  13. {openfund_core-0.0.3.dist-info → openfund_core-1.0.1.dist-info}/WHEEL +1 -1
  14. openfund_core-1.0.1.dist-info/entry_points.txt +3 -0
  15. openfund/core/__init__.py +0 -14
  16. openfund/core/api_tools/__init__.py +0 -16
  17. openfund/core/api_tools/binance_futures_tools.py +0 -23
  18. openfund/core/api_tools/binance_tools.py +0 -26
  19. openfund/core/api_tools/enums.py +0 -539
  20. openfund/core/base_collector.py +0 -72
  21. openfund/core/base_tool.py +0 -58
  22. openfund/core/factory.py +0 -97
  23. openfund/core/openfund_old/continuous_klines.py +0 -153
  24. openfund/core/openfund_old/depth.py +0 -92
  25. openfund/core/openfund_old/historical_trades.py +0 -123
  26. openfund/core/openfund_old/index_info.py +0 -67
  27. openfund/core/openfund_old/index_price_kline.py +0 -118
  28. openfund/core/openfund_old/klines.py +0 -95
  29. openfund/core/openfund_old/klines_qrr.py +0 -103
  30. openfund/core/openfund_old/mark_price.py +0 -121
  31. openfund/core/openfund_old/mark_price_klines.py +0 -122
  32. openfund/core/openfund_old/ticker_24hr_price_change.py +0 -99
  33. openfund/core/pyopenfund.py +0 -85
  34. openfund/core/services/um_futures_collector.py +0 -142
  35. openfund/core/sycu_exam/__init__.py +0 -1
  36. openfund/core/sycu_exam/exam.py +0 -19
  37. openfund/core/sycu_exam/random_grade_cplus.py +0 -440
  38. openfund/core/sycu_exam/random_grade_web.py +0 -404
  39. openfund/core/utils/time_tools.py +0 -25
  40. openfund_core-0.0.3.dist-info/LICENSE +0 -201
  41. openfund_core-0.0.3.dist-info/METADATA +0 -67
  42. openfund_core-0.0.3.dist-info/RECORD +0 -30
  43. {openfund/core/openfund_old → core}/__init__.py +0 -0
@@ -1,85 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import logging
4
- import os
5
- import sys
6
-
7
- from typing import TYPE_CHECKING
8
-
9
- from pathlib import Path
10
-
11
- from platformdirs import user_cache_path
12
- from platformdirs import user_config_path
13
- from platformdirs import user_data_path
14
- from platformdirs import user_log_path
15
- from apscheduler.schedulers.background import BackgroundScheduler
16
-
17
- if TYPE_CHECKING:
18
- from poetry.poetry import Poetry
19
- from openfund.core.factory import Factory
20
-
21
- logger = logging.getLogger(__name__)
22
- _APP_NAME = "pyopenfund"
23
-
24
-
25
- class Openfund:
26
- def __init__(self, poetry: Openfund) -> None:
27
- self._poetry: Poetry = poetry
28
- self._schedule: BackgroundScheduler = None
29
-
30
- @property
31
- def poetry(self) -> Poetry:
32
- from pathlib import Path
33
-
34
- if self._poetry is not None:
35
- return self._poetry
36
-
37
- project_path = Path.cwd()
38
-
39
- self._poetry = Factory().create_poetry(
40
- cwd=project_path,
41
- )
42
-
43
- return self._poetry
44
-
45
- @property
46
- def dataDir(self) -> Path:
47
- # openfund_home = os.getenv("OPENFUND_HOME")
48
- # if openfund_home:
49
- # return Path(openfund_home).expanduser()
50
- return Path(
51
- os.getenv("OPENFUND_DATA_DIR")
52
- or user_data_path(_APP_NAME, appauthor=False, roaming=True)
53
- ).joinpath("data")
54
-
55
- @property
56
- def cacheDir(self) -> Path:
57
- return Path(
58
- os.getenv("OPENFUND_CACHE_DIR")
59
- or user_cache_path(_APP_NAME, appauthor=False)
60
- )
61
-
62
- @property
63
- def configDir(self) -> Path:
64
-
65
- return Path(
66
- os.getenv("OPENFUND_CONFIG_DIR")
67
- or user_config_path(_APP_NAME, appauthor=False, roaming=True)
68
- ).joinpath("config")
69
-
70
- @property
71
- def logDir(self) -> Path:
72
-
73
- return Path(
74
- os.getenv("OPENFUND_LOG_DIR")
75
- or user_log_path(_APP_NAME, appauthor=False, roaming=True)
76
- )
77
-
78
- @property
79
- def scheduler(self) -> BackgroundScheduler:
80
- if self._schedule is None:
81
- self._schedule = BackgroundScheduler(
82
- timezone="MST",
83
- )
84
-
85
- return self._schedule
@@ -1,142 +0,0 @@
1
- from __future__ import annotations
2
-
3
-
4
- import logging
5
- import time
6
- from pathlib import Path
7
-
8
- from openfund.core.api_tools.enums import KlineInterval
9
- from openfund.core.base_tool import Tool as BaseTool
10
- from openfund.core.api_tools.binance_futures_tools import BinanceUMFuturesTool
11
- from openfund.core.base_collector import Collector as BaseCollector
12
-
13
- from openfund.core.utils.time_tools import TimeTools
14
-
15
- logger = logging.getLogger(__name__)
16
-
17
-
18
- class KLinesCollector(BaseCollector):
19
- def __init__(
20
- self,
21
- hisSwitch: int = 0,
22
- hisDateTime: int = 0,
23
- pool: list = None,
24
- interval: int = 5,
25
- client: BaseTool = None,
26
- ) -> None:
27
- super().__init__()
28
- self._pool = pool
29
- if self._pool is None:
30
- self._pool = ["BTCUSDT", "ETHUSDT"]
31
- logger.debug("+++++++++++++++ KLinesCollector init +++++++++++++ ")
32
-
33
- self._interval = interval
34
- self._hisSwitch = hisSwitch
35
- self._hisDateTime = hisDateTime
36
- self._dataDir = self.openfund.dataDir
37
- self._client = client
38
- if self._client is None:
39
- self._client = BinanceUMFuturesTool().umclient
40
- # self._job = None
41
-
42
- def collect(self) -> None:
43
-
44
- for symbol in self._pool:
45
- logger.debug("{} symbol 开始 ++++++++++++++++++++++++++++ ".format(symbol))
46
- latestRecords = 1 # 采集最近一次的记录数量
47
- records = 0 # 累计记录数
48
- queryCount = 0 # 执行次数
49
- nextEndTime = 0
50
- params = {"limit": 1000}
51
- while latestRecords != 0: # 循环读取,直到记录为空
52
- queryCount += 1
53
- if nextEndTime != 0:
54
- params = {"limit": 1000, "endTime": nextEndTime}
55
-
56
- logger.debug("1、{}第{}次开始执行...".format(symbol, queryCount))
57
- listData = []
58
- try:
59
- listData = self._client.klines(
60
- symbol,
61
- KlineInterval.getByUnit(self._interval, "m"),
62
- **params,
63
- )
64
- except Exception as e:
65
- # print("Error:", e)
66
- logger.error(e)
67
- time.sleep(10)
68
- continue
69
-
70
- latestRecords = len(listData)
71
- data_file = Path(
72
- self._dataDir.joinpath("klines")
73
- .joinpath(symbol)
74
- .joinpath(
75
- "klines_{}.csv".format(
76
- KlineInterval.getByUnit(self._interval, "m")
77
- )
78
- )
79
- )
80
- self._write_to_csv(data_file, listData)
81
-
82
- if latestRecords > 0:
83
- nextEndTime = (
84
- # -1 不和close时间戳相同,避免重新拉取重复数据
85
- listData[0][0]
86
- - 1
87
- )
88
-
89
- logger.debug(
90
- "3、下次结束时间 %s %s"
91
- % (TimeTools.format_timestamp(nextEndTime), nextEndTime)
92
- )
93
-
94
- if self._hisSwitch == 0 or nextEndTime <= self._hisDateTime:
95
- break
96
- else:
97
- logger.debug("4、结束...")
98
-
99
- # time.sleep(0.1)
100
- records = latestRecords + records
101
- logger.info("5、{} 抓取数据 {} 条记录...".format(symbol, records))
102
- logger.debug("{} symbol --------------------------------- ".format(symbol))
103
-
104
- # def taskDetail(taskName: str):
105
- # currTime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
106
- # logger.debug(f"{taskName}-->", "currTime:", currTime)
107
-
108
- def start(self) -> int:
109
-
110
- # self.collect()
111
- self._job = self.openfund.scheduler.add_job(
112
- func=self.collect,
113
- trigger="interval",
114
- # minutes=self._interval,
115
- seconds=self._interval,
116
- id="um_futures_collector",
117
- )
118
-
119
- logger.debug("调度任务已启动,每%s分钟执行一次。", self._interval)
120
-
121
- return 0
122
-
123
-
124
- # if __name__ == "__main__":
125
- # from openfund.core.services.um_futures_collector import KLinesCollector
126
-
127
- # collector = KLinesCollector()
128
-
129
- # collector.start()
130
- # logger.debug(f"main collector.start() ===== ")
131
- # i = 0
132
- # while i < 10:
133
-
134
- # logger.debug("main i=%s ===== ", i)
135
- # if i == 2:
136
- # collector.pause()
137
- # if i == 4:
138
- # collector.resume()
139
- # if i == 8:
140
- # collector.stop()
141
- # time.sleep(5)
142
- # i += 1
@@ -1 +0,0 @@
1
- from .exam import *
@@ -1,19 +0,0 @@
1
- # sample.py
2
-
3
- # create a variable in the module
4
- sample_variable = "This is a string variable in the sample.py module"
5
-
6
-
7
- # A function in the module
8
- def say_hello(name):
9
- return f"Hello, {name} welcome to this simple module."
10
-
11
-
12
- # This is another function in the module
13
- def add(a, b):
14
- return f"{a} + {b} is = {a+b}"
15
-
16
-
17
- # print(sample_variable)
18
- # print(say_hello("小明"))
19
- # print(add(2, 3))
@@ -1,440 +0,0 @@
1
- #!/usr/bin/env python
2
- import csv
3
- import time
4
- import os
5
- import sys
6
- import random
7
-
8
- curPath = os.path.abspath(os.path.dirname(__file__))
9
- rootPath = os.path.split(curPath)[0]
10
- sys.path.append(rootPath)
11
-
12
- from datetime import datetime
13
- from libs.time_tools import format_timestamp, format_date, format_date_to
14
- from libs.file_tools import create_path
15
- from libs.prepare_env import get_path
16
- from libs.log_tools import Logger
17
-
18
- data_path, log_path = get_path()
19
-
20
- app = "random_grade"
21
- logger = Logger(app).get_log()
22
- c_name = "stu_23sk-1-java"
23
-
24
- sx_times = 1
25
- xz_times = 1
26
-
27
-
28
- def jieke_fun(row):
29
- jieke = 0
30
- cent1_1 = 5
31
- cent1_2 = 5
32
- if row[2] in ["A"]:
33
- cent2_1 = 10
34
- cent2_2 = cent(8, 9)
35
- cent2_3 = cent(8, 9)
36
- cent2_4 = cent(8, 9)
37
-
38
- cent3_1 = 5
39
- cent3_2 = 5
40
- cent3_3 = 5
41
- # cent3_4 = cent(3, 4)
42
-
43
- cent4_1 = 14
44
- cent5_1 = cent(8, 9)
45
- cent6_1 = 5
46
- cent6_2 = 5
47
- elif row[2] in ["B+"]:
48
- cent2_1 = cent(7, 8)
49
- cent2_2 = cent(7, 8)
50
- cent2_3 = cent(7, 8)
51
- cent2_4 = cent(7, 8)
52
-
53
- cent3_1 = 5
54
- cent3_2 = 5
55
- cent3_3 = 5
56
- # cent3_4 = cent(3, 4)
57
-
58
- cent4_1 = 12
59
- cent5_1 = cent(8, 9)
60
- cent6_1 = 5
61
- cent6_2 = 5
62
- elif row[2] in ["B"]:
63
- cent2_1 = cent(6, 7)
64
- cent2_2 = cent(6, 7)
65
- cent2_3 = cent(7, 8)
66
- cent2_4 = cent(7, 8)
67
-
68
- cent3_1 = 5
69
- cent3_2 = 4
70
- cent3_3 = 5
71
- # cent3_4 = cent(3, 4)
72
-
73
- cent4_1 = 11
74
- cent5_1 = cent(8, 9)
75
- cent6_1 = 5
76
- cent6_2 = 5
77
- elif row[2] in ["C+"]:
78
- cent2_1 = cent(7, 8)
79
- cent2_2 = cent(6, 7)
80
- cent2_3 = cent(6, 7)
81
- cent2_4 = cent(3, 4)
82
-
83
- cent3_1 = 5
84
- cent3_2 = 4
85
- cent3_3 = 4
86
- # cent3_4 = cent(2, 3)
87
-
88
- cent4_1 = 9
89
- cent5_1 = cent(6, 7)
90
- cent6_1 = 4
91
- cent6_2 = 4
92
- elif row[2] in ["C"]:
93
- cent2_1 = cent(7, 8)
94
- cent2_2 = cent(6, 7)
95
- cent2_3 = cent(6, 7)
96
- cent2_4 = cent(4, 5)
97
-
98
- cent3_1 = 3
99
- cent3_2 = 3
100
- cent3_3 = 3
101
- # cent3_4 = cent(2, 3)
102
-
103
- cent4_1 = 7
104
- cent5_1 = cent(6, 7)
105
- cent6_1 = 3
106
- cent6_2 = 3
107
- else:
108
- cent2_1 = cent(6, 7)
109
- cent2_2 = cent(6, 7)
110
- cent2_3 = cent(6, 7)
111
- cent2_4 = 0
112
-
113
- cent3_1 = 3
114
- cent3_2 = 3
115
- cent3_3 = 3
116
- # cent3_4 = cent(2, 3)
117
-
118
- cent4_1 = 5
119
- cent5_1 = cent(5, 6)
120
- cent6_1 = 3
121
- cent6_2 = 3
122
-
123
- jieke = (
124
- cent1_1
125
- + cent1_2
126
- + cent2_1
127
- + cent2_2
128
- + cent2_3
129
- + cent2_4
130
- + cent3_1
131
- + cent3_2
132
- + cent3_3
133
- # + cent3_4
134
- + cent4_1
135
- + cent5_1
136
- + cent6_1
137
- + cent6_2
138
- )
139
-
140
- cents = []
141
- cents.append(row[0])
142
- cents.append(row[1])
143
- cents.append(row[2])
144
- cents.append(row[3])
145
- cents.append(jieke)
146
- cents.append(cent1_1)
147
- cents.append(cent1_2)
148
- cents.append(cent2_1)
149
- cents.append(cent2_2)
150
- cents.append(cent2_3)
151
- cents.append(cent2_4)
152
- cents.append(cent3_1)
153
- cents.append(cent3_2)
154
- cents.append(cent3_3)
155
- # cents.append(cent3_4)
156
- cents.append(cent4_1)
157
- cents.append(cent5_1)
158
- cents.append(cent6_1)
159
- cents.append(cent6_2)
160
-
161
- return cents
162
-
163
-
164
- def xiaozu_fun(row):
165
- # 程序代码编写及附加信息(55分)
166
- xiaozu = 0
167
- cent1_1 = 10
168
- cent2_1 = 10
169
- # 小组给分
170
- if row[3] in ["A"]:
171
- cent3_1 = 10
172
- cent4_1 = 10
173
- cent5_1 = 26
174
- elif row[3] in ["B"]:
175
- cent3_1 = 8
176
- cent4_1 = 8
177
- cent5_1 = 23
178
- else:
179
- cent3_1 = 7
180
- cent4_1 = 7
181
- cent5_1 = 20
182
-
183
- if row[2] in ["A"]:
184
- cent6_1 = cent(9, 10)
185
- cent7_1 = cent(9, 10)
186
- cent8_1 = cent(8, 9)
187
-
188
- elif row[2] in ["B+"]:
189
- cent6_1 = cent(8, 9)
190
- cent7_1 = cent(8, 9)
191
- cent8_1 = cent(8, 9)
192
- elif row[2] in ["B"]:
193
- cent6_1 = cent(6, 8)
194
- cent7_1 = cent(6, 8)
195
- cent8_1 = cent(6, 8)
196
- elif row[2] in ["C+"]:
197
- cent6_1 = cent(5, 7)
198
- cent7_1 = cent(5, 7)
199
- cent8_1 = cent(5, 7)
200
- elif row[2] in ["C"]:
201
- cent6_1 = cent(4, 5)
202
- cent7_1 = cent(4, 5)
203
- cent8_1 = cent(4, 5)
204
- else:
205
- cent6_1 = cent(3, 4)
206
- cent7_1 = cent(3, 4)
207
- cent8_1 = cent(3, 4)
208
-
209
- xiaozu = (
210
- cent1_1 + cent2_1 + cent3_1 + cent4_1 + cent5_1 + cent6_1 + cent7_1 + cent8_1
211
- )
212
- cents = []
213
- cents.append(row[0])
214
- cents.append(row[1])
215
- cents.append(row[2])
216
- cents.append(row[3])
217
- cents.append(xiaozu)
218
- cents.append(cent1_1)
219
- cents.append(cent2_1)
220
- cents.append(cent3_1)
221
- cents.append(cent4_1)
222
- cents.append(cent5_1)
223
- cents.append(cent6_1)
224
- cents.append(cent7_1)
225
- cents.append(cent8_1)
226
- return cents
227
-
228
-
229
- def shixu_fun(row):
230
- shixun = 0
231
- cent1_1 = 10
232
- # cent1_2 = 5
233
- if row[2] in ["A"]:
234
- cent2_1 = 12
235
- cent2_2 = 15
236
- cent2_3 = 5
237
- cent2_4 = 15
238
- # cent2_5 = 10
239
- # cent2_6 = cent(10, 12)
240
- cent3_1 = 10
241
- cent4_1 = cent(13, 15)
242
- cent5_1 = 9
243
- elif row[2] in ["B+"]:
244
- cent2_1 = 12
245
- cent2_2 = 15
246
- cent2_3 = 5
247
- cent2_4 = cent(12, 14)
248
- # cent2_5 = 10
249
- # cent2_6 = cent(8, 10)
250
- cent3_1 = 10
251
- cent4_1 = cent(13, 15)
252
- cent5_1 = cent(7, 8)
253
- elif row[2] in ["B"]:
254
- cent2_1 = 12
255
- cent2_2 = 10
256
- cent2_3 = 5
257
- cent2_4 = cent(12, 14)
258
- # cent2_5 = 10
259
- # cent2_6 = cent(8, 10)
260
- cent3_1 = 10
261
- cent4_1 = cent(13, 15)
262
- cent5_1 = cent(7, 8)
263
- elif row[2] in ["C+"]:
264
- cent2_1 = 9
265
- cent2_2 = 10
266
- cent2_3 = 0
267
- cent2_4 = cent(12, 14)
268
- # cent2_5 = 10
269
- # cent2_6 = cent(8, 10)
270
- cent3_1 = 10
271
- cent4_1 = cent(12, 13)
272
- cent5_1 = cent(7, 8)
273
- elif row[2] in ["C"]:
274
- cent2_1 = 9
275
- cent2_2 = 5
276
- cent2_3 = 0
277
- cent2_4 = cent(12, 14)
278
- # cent2_5 = 10
279
- # cent2_6 = cent(8, 10)
280
- cent3_1 = 10
281
- cent4_1 = cent(10, 13)
282
- cent5_1 = cent(7, 8)
283
- else:
284
- cent2_1 = 6
285
- cent2_2 = 5
286
- cent2_3 = 0
287
- cent2_4 = cent(10, 12)
288
- # cent2_5 = 10
289
- # cent2_6 = cent(8, 10)
290
- cent3_1 = 10
291
- cent4_1 = cent(8, 10)
292
- cent5_1 = cent(7, 8)
293
-
294
- shixun = (
295
- cent1_1
296
- # + cent1_2
297
- + cent2_1
298
- + cent2_2
299
- + cent2_3
300
- + cent2_4
301
- # + cent2_5
302
- # + cent2_6
303
- + cent3_1
304
- + cent4_1
305
- + cent5_1
306
- )
307
- cents = []
308
- cents.append(row[0])
309
- cents.append(row[1])
310
- cents.append(row[2])
311
- cents.append(row[3])
312
- cents.append(shixun)
313
- cents.append(cent1_1)
314
- # cents.append(cent1_2)
315
- cents.append(cent2_1)
316
- cents.append(cent2_2)
317
- cents.append(cent2_3)
318
- cents.append(cent2_4)
319
- # cents.append(cent2_5)
320
- # cents.append(cent2_6)
321
- cents.append(cent3_1)
322
- cents.append(cent4_1)
323
- cents.append(cent5_1)
324
- # print(
325
- # row[1],
326
- # row[2],
327
- # shixun,
328
- # cent1_1,
329
- # cent1_2,
330
- # cent2_1,
331
- # cent2_2,
332
- # cent2_3,
333
- # cent2_4,
334
- # cent2_5,
335
- # cent2_6,
336
- # cent3_1,
337
- # cent4_1,
338
- # cent5_1,
339
- # sep=",",
340
- # )
341
-
342
- return cents
343
-
344
-
345
- def homework_fun(row):
346
- work = 0
347
-
348
- if row[2] in ["A"]:
349
- cent1_1 = 100
350
- cent1_2 = 90
351
- cent1_3 = 95
352
-
353
- elif row[2] in ["B+"]:
354
- cent1_1 = 90
355
- cent1_2 = 80
356
- cent1_3 = 85
357
- elif row[2] in ["B"]:
358
- cent1_1 = 85
359
- cent1_2 = 75
360
- cent1_3 = 80
361
- elif row[2] in ["C+"]:
362
- cent1_1 = 80
363
- cent1_2 = 70
364
- cent1_3 = 75
365
- elif row[2] in ["C"]:
366
- cent1_1 = 75
367
- cent1_2 = 65
368
- cent1_3 = 70
369
- else:
370
- cent1_1 = 70
371
- cent1_2 = 60
372
- cent1_3 = 65
373
-
374
- work = cent1_3
375
- cents = []
376
- cents.append(row[0])
377
- cents.append(row[1])
378
- cents.append(row[2])
379
- cents.append(row[3])
380
- cents.append(work)
381
- cents.append(cent1_1)
382
- cents.append(cent1_2)
383
- cents.append(cent1_3)
384
- return cents
385
-
386
-
387
- def cent(low, high):
388
- cent = random.randint(low, high)
389
- return cent
390
-
391
-
392
- def do():
393
- rows = []
394
- with open(
395
- "{0}/../grade/{1}.csv".format(data_path, c_name),
396
- "r",
397
- encoding="utf-8-sig",
398
- newline="",
399
- ) as file:
400
- reader = csv.reader(file)
401
- rows = [row for row in reader]
402
-
403
- cents = []
404
- for i in range(len(rows)):
405
- line = []
406
- for j1 in range(sx_times):
407
- shixun_cents = shixu_fun(rows[i])
408
- line.extend(shixun_cents)
409
-
410
- for j2 in range(xz_times):
411
- xiaozu_cents = xiaozu_fun(rows[i])
412
- line.extend(xiaozu_cents)
413
-
414
- jieke_cents = jieke_fun(rows[i])
415
- line.extend(jieke_cents)
416
-
417
- homework_cents = homework_fun(rows[i])
418
- line.extend(homework_cents)
419
-
420
- cents.append(line)
421
-
422
- with open(
423
- "{0}/../grade/{3}_{1}_{2}.csv".format(
424
- data_path,
425
- "gd",
426
- c_name,
427
- format_timestamp(datetime.now().timestamp() * 1000),
428
- ),
429
- "a",
430
- encoding="utf-8-sig",
431
- newline="",
432
- ) as file:
433
- writer = csv.writer(file)
434
- for row in cents:
435
- writer.writerow(row)
436
-
437
-
438
- if __name__ == "__main__":
439
- logger.info("random_grade Starting ...... ")
440
- do()