siat 3.2.32__py3-none-any.whl → 3.2.37__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.
siat/common.py CHANGED
@@ -3946,5 +3946,49 @@ def sort_list_by_len(alist,reverse=False):
3946
3946
 
3947
3947
  return alist_sorted
3948
3948
  #==============================================================================
3949
+ if __name__=='__main__':
3950
+ data=security_trend("AAPL")
3951
+ search_mode=True
3952
+
3953
+ show_df(data,search_mode=False)
3954
+ show_df(data,search_mode=True)
3955
+
3956
+ def show_df(data,search_mode=False):
3957
+ """
3958
+ 功能:在Jupyter中查看dataframe,并可下载成Excel
3959
+ """
3960
+ df=data.copy()
3961
+
3962
+ import pandas as pd
3963
+ import datetime
3964
+ from itables import init_notebook_mode, show
3965
+ init_notebook_mode(all_interactive=True)
3966
+
3967
+ if not search_mode:
3968
+ show(df, buttons=["copyHtml5", "csvHtml5", "excelHtml5"])
3969
+ else:
3970
+ #需要所有日期字段都是datetime格式,有错误,不能用
3971
+ columns = df.columns
3972
+ # 判断哪些字段是日期,并转换
3973
+ date_columns=[]
3974
+ for col in columns:
3975
+ if 'date' in col.lower() or '日期' in col:
3976
+ try:
3977
+ df[col]=df[col].apply(lambda x: pd.to_datetime(x))
3978
+ date_columns=date_columns+[col]
3979
+ except:
3980
+ continue
3981
+
3982
+ firstCol=list(df)[0]
3983
+ firstValue=df[firstCol].values[0]
3984
+
3985
+ show(df,
3986
+ layout={"tool":"searchBuilder"},
3987
+ searchBuilder={"preDefined":{
3988
+ "criteria":[{"data":firstCol,"condition":"=","value":firstValue}]
3989
+ }})
3990
+
3991
+ return
3992
+
3949
3993
  #==============================================================================
3950
3994
  #==============================================================================
siat/luchy_draw.py CHANGED
@@ -33,7 +33,7 @@ def current_dir(printout=True):
33
33
  current_path = os.getcwd()
34
34
 
35
35
  if printout:
36
- print(f"[当前工作路径] {current_path}")
36
+ print(f"[Current path] {current_path}")
37
37
 
38
38
  return current_path
39
39
 
@@ -69,6 +69,9 @@ if __name__=='__main__':
69
69
  typewriter(text,text_color='red',text_size=12,delay=1)
70
70
 
71
71
  def typewriter(text,text_color='blue',text_size=12,delay=3):
72
+ """
73
+ 功能:居中显示带颜色的大字体
74
+ """
72
75
  from IPython.display import display_html
73
76
 
74
77
  time.sleep(delay)
@@ -80,16 +83,20 @@ def typewriter(text,text_color='blue',text_size=12,delay=3):
80
83
 
81
84
  #==============================================================================
82
85
 
83
- def pickle_write(df,pickle_path):
86
+ def pickle_write(df,pickle_path,overlap_confirm=True):
84
87
 
85
88
  ok2go=True
86
89
 
87
- prompt="File "+pickle_path+" already exists, overwrite it? [yes/no]"
88
- file_exist=existing(pickle_path)
89
- if file_exist:
90
- yes=read_yes_no(prompt, default=None)
91
- if not yes:
92
- ok2go=False
90
+ if overlap_confirm:
91
+ cur_dir=current_dir(printout=False)
92
+
93
+ prompt=pickle_path+" already exists in "+cur_dir+", overwrite it?"
94
+ file_exist=existing(pickle_path)
95
+ if file_exist:
96
+ #是否覆盖已经存在的文件
97
+ yes=read_yes_no(prompt, default=None)
98
+ if not yes:
99
+ ok2go=False
93
100
 
94
101
  if ok2go:
95
102
  with open(pickle_path, 'wb') as pickle_file:
@@ -118,29 +125,47 @@ if __name__=='__main__':
118
125
  def lucky_draw_header_create(course,file_path, \
119
126
  skiprows=1,column='Name',draw_limit=2, \
120
127
  absent_limit=2,pass_limit=2):
128
+ """
129
+ 功能:创建随机点名头文件,存储随机点名的参数信息
130
+ """
121
131
 
122
- pickle_path=course+" header.pkl"
132
+ pickle_path=course+" detail.pkl"
133
+ header_path=course+" header.pkl"
134
+ cur_dir=current_dir(printout=False)
123
135
 
124
136
  header_dict={'course':course,'file_path':file_path,'pickle_path':pickle_path, \
125
137
  'skiprows':skiprows,'column':column,'draw_limit':draw_limit, \
126
138
  'absent_limit':absent_limit,'pass_limit':pass_limit}
127
139
 
128
- pickle_write(header_dict,pickle_path)
140
+ pickle_write(header_dict,header_path)
141
+ print(header_path,"is created in",cur_dir)
129
142
 
130
143
  return
131
144
 
132
- def lucky_draw_header_modify(course,file_path="current", \
145
+ if __name__=='__main__':
146
+ course="SICS RUC24"
147
+
148
+ lucky_draw_header_modify(course,draw_limit=3)
149
+ pickle_read(pickle_path=course+' header.pkl')
150
+
151
+ def lucky_draw_header_modify(course,file_path="current",pickle_path="current", \
133
152
  skiprows="current",column="current",draw_limit="current", \
134
153
  absent_limit="current",pass_limit="current"):
135
154
 
136
- pickle_path=course+" header.pkl"
137
- header_dict=pickle_read(pickle_path)
155
+ header_path=course+" header.pkl"
156
+ header_dict=pickle_read(header_path)
157
+ cur_dir=current_dir(printout=False)
138
158
 
139
159
  if file_path !='current':
140
160
  header_dict['file_path']=file_path
141
161
  else:
142
162
  file_path=header_dict['file_path']
143
163
 
164
+ if pickle_path !='current':
165
+ header_dict['pickle_path']=pickle_path
166
+ else:
167
+ pickle_path=header_dict['pickle_path']
168
+
144
169
  if skiprows !='current':
145
170
  header_dict['skiprows']=skiprows
146
171
  else:
@@ -170,12 +195,255 @@ def lucky_draw_header_modify(course,file_path="current", \
170
195
  'skiprows':skiprows,'column':column,'draw_limit':draw_limit, \
171
196
  'absent_limit':absent_limit,'pass_limit':pass_limit}
172
197
 
173
- pickle_write(header_dict,pickle_path)
198
+ pickle_write(header_dict,pickle_path,overlap_confirm=False)
199
+ print(header_path,"is modified in",cur_dir)
200
+
201
+ return
202
+
203
+ #==============================================================================
204
+ if __name__=='__main__':
205
+ course="SICS RUC24"
206
+ lucky_draw_detail_create(course)
207
+ pickle_read(course+" detail.pkl")
208
+
209
+
210
+ def lucky_draw_detail_create(course):
211
+ """
212
+ 功能:创建随机点名明细文件,记录随机点名的过程
213
+ """
214
+ #读取参数信息
215
+ header_path=course+" header.pkl"
216
+ header_dict=pickle_read(header_path)
217
+ detail_path=header_dict['pickle_path']
218
+ cur_dir=current_dir(printout=False)
219
+
220
+ #读取学生名单
221
+ df = pd.read_excel(header_dict['file_path'],skiprows=header_dict['skiprows'])
222
+ df1=df[[header_dict['column']]].copy()
223
+
224
+ todaydt = str(datetime.date.today())
225
+ df1['Date']=todaydt
226
+ df1['Lucky']=0
227
+ df1['Absent']=0
228
+ df1['Pass']=0
229
+
230
+ #排序
231
+ df1.sort_values(by=[header_dict['column'],'Date','Lucky','Absent','Pass'],inplace=True)
232
+ df1.reset_index(drop=True,inplace=True)
233
+ df1.index=df1.index + 1
174
234
 
235
+ pickle_write(df1,detail_path)
236
+ print(detail_path,"is created in",cur_dir)
237
+
175
238
  return
176
239
 
240
+ if __name__=='__main__':
241
+ course="SICS RUC24"
242
+
243
+ lucky_draw_detail_add(course,name="Liu Chixin")
244
+ lucky_draw_detail_add(course,name=["Liu Chixin","Zhang San Feng","Li Si Ye"])
245
+
246
+ pickle_read(course+" detail.pkl")
177
247
 
178
248
 
249
+ def lucky_draw_detail_add(course,name):
250
+ """
251
+ 功能:在随机点名明细文件中增加一个名字,支持批量增加
252
+ """
253
+ #读取参数信息
254
+ header_path=course+" header.pkl"
255
+ header_dict=pickle_read(header_path)
256
+
257
+ #读取明细文件
258
+ detail_path=header_dict['pickle_path']
259
+ df=pickle_read(detail_path)
260
+
261
+ todaydt = str(datetime.date.today())
262
+
263
+ if isinstance(name,str):
264
+ name=[name]
265
+
266
+ added=False
267
+ for n in name:
268
+ #重名检查
269
+ if n in list(df[header_dict['column']]):
270
+ print(n,"is already in file, no need to add")
271
+ continue
272
+
273
+ #增加名单
274
+ added=True
275
+ row=pd.Series({header_dict['column']:n,'Date':todaydt,'Lucky':0,'Absent':0,'Pass':0})
276
+ try:
277
+ df=df.append(row,ignore_index=True)
278
+ except:
279
+ df=df._append(row,ignore_index=True)
280
+
281
+ print(n,"is added into file")
282
+
283
+ #写回明细文件
284
+ if added:
285
+ pickle_write(df,header_dict['pickle_path'],overlap_confirm=False)
286
+
287
+ return
288
+
289
+ #==============================================================================
290
+ if __name__=='__main__':
291
+ course="SICS RUC24"
292
+
293
+ lucky_draw_detail_remove(course,name="Liu Chixin")
294
+ lucky_draw_detail_remove(course,name=["Liu Chixin","Zhang San Feng","Li Si Ye"])
295
+ pickle_read(course+" detail.pkl")
296
+
297
+
298
+ def lucky_draw_detail_remove(course,name):
299
+ """
300
+ 功能:在随机点名明细文件中删除一个名字的所有记录,支持批量删除
301
+ """
302
+ #读取参数信息
303
+ header_path=course+" header.pkl"
304
+ header_dict=pickle_read(header_path)
305
+
306
+ #读取明细文件
307
+ detail_path=header_dict['pickle_path']
308
+ df=pickle_read(detail_path)
309
+
310
+ if isinstance(name,str):
311
+ name=[name]
312
+
313
+ found=False
314
+ for n in name:
315
+ #检查是否存在
316
+ if n not in list(df[header_dict['column']]):
317
+ print(n,"is not in file, no need to remove")
318
+ continue
319
+
320
+ found=True
321
+ #删除该名字的所有记录
322
+ to_drop = df[df[header_dict['column']] == n].index
323
+ df.drop(to_drop, inplace=True)
324
+
325
+ print(n,"is removed from file")
326
+
327
+ #写回明细文件
328
+ if found:
329
+ pickle_write(df,header_dict['pickle_path'],overlap_confirm=False)
330
+
331
+ return
332
+
333
+ #==============================================================================
334
+ if __name__=='__main__':
335
+ course="SICS RUC24"
336
+ lucky_color="blue"
337
+
338
+
339
+
340
+ def random_draw(course,lucky_color="blue"):
341
+ """
342
+ 随机点名,并记录
343
+ draw_limit:整个课程每人最多几次抽签机会
344
+ absent_limit:整个课程每人最多缺席几次,超过就丧失抽签资格
345
+ pass_limit:整个课程每人最多可以pass几次,超过就丧失抽签资格
346
+ """
347
+ #读取参数信息
348
+ header_path=course+" header.pkl"
349
+ header_dict=pickle_read(header_path)
350
+
351
+ #读取明细文件
352
+ detail_path=header_dict['pickle_path']
353
+ df=pickle_read(detail_path)
354
+
355
+ #点名名单
356
+ column=header_dict['column']
357
+ alist=list(set(list(df[column])))
358
+
359
+ found=False
360
+ todaydt = str(datetime.date.today())
361
+ draw_limit=header_dict['draw_limit']
362
+ absent_limit=header_dict['absent_limit']
363
+ pass_limit=header_dict['pass_limit']
364
+ column=header_dict['column']
365
+
366
+ prompt="*** Is the lucky person here on site?"
367
+ prompt2="*** Does the lucky person expect to pass?"
368
+ prompt3="*** Continue lucky draw?"
369
+
370
+ while True:
371
+ while True:
372
+ aname=random_select(alist)
373
+
374
+ adf=df[df[column]==aname]
375
+ atimes=adf['Lucky'].sum()
376
+ aonsite=adf['Absent'].sum()
377
+ apass=adf['Pass'].sum()
378
+
379
+ if atimes < draw_limit and aonsite <= absent_limit and apass < pass_limit:
380
+ #检查今日是否被抽中过
381
+ drew_today=False
382
+ try:
383
+ adf_today=adf[adf['Date']==todaydt]
384
+ if len(adf_today) > 0:
385
+ if adf_today['Lucky'].sum() > 0:
386
+ #有当日记录,且被抽中过(排除当日刚刚加入课程的情形)
387
+ drew_today=True
388
+ except: pass
389
+
390
+ if not drew_today:
391
+ found=True
392
+ break
393
+ else: continue
394
+ else:
395
+ continue
396
+
397
+ if not found:
398
+ #循环完毕,无合适人选
399
+ print("Congratulations! all person has been lucky for",draw_limit,"times")
400
+ else:
401
+ typewriter(text=aname,text_color=lucky_color,text_size=12,delay=1)
402
+
403
+ #是否到场
404
+ onsite=read_yes_no(prompt)
405
+ if onsite: absent=0
406
+ else: absent=1
407
+
408
+ #是否pass
409
+ onpass=False
410
+ bpass=0
411
+ if onsite:
412
+ onpass=read_yes_no(prompt2)
413
+ #是否pass
414
+ if onpass: bpass=1
415
+
416
+ #只要抽中,不论是否到场都记录
417
+ row=pd.Series({column:aname,'Date':todaydt,'Lucky':1,'Absent':absent,'Pass':bpass})
418
+ try:
419
+ df=df.append(row,ignore_index=True)
420
+ except:
421
+ df=df._append(row,ignore_index=True)
422
+
423
+ if onsite and not onpass:
424
+ proceed=read_yes_no(prompt3)
425
+ if not proceed:
426
+ #到场且不pass,结束本轮抽签
427
+ print("=== Lucky draw ends!")
428
+ break
429
+ else:
430
+ #未到场或pass,继续抽签
431
+ continue
432
+
433
+ df.sort_values(by=[column,'Date'],inplace=True)
434
+ pickle_write(df,detail_path,overlap_confirm=False)
435
+
436
+ return
437
+
438
+ #==============================================================================
439
+ #==============================================================================
440
+ if __name__=='__main__':
441
+ file_path="S:\北外工作-24春\小学期-人大\学生名单\student_list.xlsx"
442
+
443
+ draw_limit=2
444
+ absent_limit=2
445
+ pass_limit=2
446
+
179
447
 
180
448
  lucky_draw_initialize(file_path,skiprows=1,column='Name',pickle_path="student_list.pkl")
181
449
 
@@ -184,6 +452,7 @@ def lucky_draw_initialize(file_path,skiprows=1,column='Name',pickle_path="studen
184
452
  功能:读入带有指定路径的Excel文件file_path,跳过前skiprows行
185
453
  Excel文件结构:抽奖名单字段为'Name',字段位于第2行
186
454
  输出:存入pickle文件student_list.pkl
455
+ 废弃!!!
187
456
  """
188
457
 
189
458
  df = pd.read_excel(file_path,skiprows=skiprows)
@@ -206,19 +475,15 @@ def lucky_draw_initialize(file_path,skiprows=1,column='Name',pickle_path="studen
206
475
 
207
476
  #==============================================================================
208
477
  if __name__=='__main__':
209
- pickle_path="student_list.pkl"
478
+ pickle_path="SICS RUC24 detail.pkl"
210
479
 
211
480
  df=pickle_read(pickle_path)
212
481
 
213
- def pickle_read(pickle_path="student_list.pkl"):
482
+ def pickle_read(pickle_path):
214
483
  with open(pickle_path,'rb') as pickle_file:
215
484
  df = pickle.load(pickle_file)
216
485
  return df
217
486
 
218
- #==============================================================================
219
-
220
-
221
-
222
487
 
223
488
  #==============================================================================
224
489
  if __name__=='__main__':
@@ -272,6 +537,7 @@ def lucky_draw(draw_limit=2,absent_limit=2,column='Name',pickle_path="student_li
272
537
  """
273
538
  draw_limit=2:整个课程每人最多2次抽签机会
274
539
  absent_limit=2:整个课程每人最多缺席2次,超过就丧失抽签资格
540
+ 废弃!
275
541
  """
276
542
  df=pickle_read(pickle_path)
277
543
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: siat
3
- Version: 3.2.32
3
+ Version: 3.2.37
4
4
  Summary: Securities Investment Analysis Tools (siat)
5
5
  Home-page: https://pypi.org/project/siat/
6
6
  Author: Prof. WANG Dehong, International Business School, Beijing Foreign Studies University
@@ -31,6 +31,7 @@ Requires-Dist: prettytable
31
31
  Requires-Dist: graphviz
32
32
  Requires-Dist: luddite
33
33
  Requires-Dist: pendulum
34
+ Requires-Dist: itables
34
35
 
35
36
  # Welcome to the Magic World of siat
36
37
 
@@ -18,7 +18,7 @@ siat/capm_beta.py,sha256=cxXdRVBQBllhbfz1LeTJAIWvyRYhW54nhtNUXv4HwS0,29063
18
18
  siat/capm_beta2.py,sha256=07y3q4nJdkM-anpZepj4gK0gvTKj-BB0ppDDI5-TCcY,26904
19
19
  siat/capm_beta_test.py,sha256=ImR0c5mc4hIl714XmHztdl7qg8v1E2lycKyiqnFj6qs,1745
20
20
  siat/cmat_commons.py,sha256=Nj9Kf0alywaztVoMVeVVL_EZk5jRERJy8R8kBw88_Tg,38116
21
- siat/common.py,sha256=mw6fvy_RPc1hBCu_IERWmjknjoSwLHQzMqf0g5Gcfac,145721
21
+ siat/common.py,sha256=AaZYKbkeLYYRdsncZ3HDhTM6d0RSJbJX7nid6U6TMfo,147084
22
22
  siat/compare_cross.py,sha256=3iP9TH2h3w27F2ARZc7FjKcErYCzWRc-TPiymOyoVtw,24171
23
23
  siat/compare_cross_test.py,sha256=xra5XYmQGEtfIZL2h-GssdH2hLdFIhG3eoCrkDrL3gY,3473
24
24
  siat/concepts_iwencai.py,sha256=m1YEDtECRT6FqtzlKm91pt2I9d3Z_XoP59BtWdRdu8I,3061
@@ -65,7 +65,7 @@ siat/grafix_test.py,sha256=kXvcpLgQNO7wd30g_bWljLj5UH7bIVI0_dUtXbfiKR0,3150
65
65
  siat/holding_risk.py,sha256=G3wpaewAKF9CwEqRpr4khyuDu9SU2EGyQUHdk7cmHOA,30693
66
66
  siat/holding_risk_test.py,sha256=FRlw_9wFG98BYcg_cSj95HX5WZ1TvkGaOUdXD7-V86s,474
67
67
  siat/local_debug_test.py,sha256=CDAOffW1Rvs-TcNN5giWVvHMlch1w4dp-w5SIV9jXL0,3936
68
- siat/luchy_draw.py,sha256=VVOsPUxCaegFuY-cZ39ucyxRBYw6rp9DeyCNltiaoHE,11694
68
+ siat/luchy_draw.py,sha256=27YTkFPr91D_ndNbmoxeUUcsjbfGWoufKP1FcF1lCkY,20379
69
69
  siat/market_china.py,sha256=hKoTLUyHuzsuG2L3_IuLx_utTKqS-__mZ63wrElh65U,45943
70
70
  siat/markowitz.py,sha256=glHikhabFAF6Hb6df1pYfhkxid2IZXBYAVQng5wd9Wk,97526
71
71
  siat/markowitz2-20240620.py,sha256=irZAPnjaatFsKQmFRMENP-cO6bEUl2narYtkU5NKTWI,108019
@@ -138,7 +138,7 @@ siat/valuation.py,sha256=NKfeZMdDJOW42oLVHob6eSVBXUqlN1OCnnzwyGAst8c,48855
138
138
  siat/valuation_china.py,sha256=EkZQaVkoBjM0c4MCNbaX-bMnlG0e3FXeaWczZDnkptU,67784
139
139
  siat/valuation_market_china_test.py,sha256=gbJ0ioauuo4koTPH6WKUkqcXiQPafnbhU5eKJ6lpdLA,1571
140
140
  siat/var_model_validation.py,sha256=R0caWnuZarrRg9939hxh3vJIIpIyPfvelYmzFNZtPbo,14910
141
- siat-3.2.32.dist-info/METADATA,sha256=vwFwBHG51nUPwHwT69gPhlo1U2pyseJH2EFPxAypznE,7234
142
- siat-3.2.32.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
143
- siat-3.2.32.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
144
- siat-3.2.32.dist-info/RECORD,,
141
+ siat-3.2.37.dist-info/METADATA,sha256=UnwG90_i5hNJUS3gc7fHwrxRs2EJZJaZHqExVTLJgR0,7258
142
+ siat-3.2.37.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
143
+ siat-3.2.37.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
144
+ siat-3.2.37.dist-info/RECORD,,
File without changes