neurostats-API 0.0.23b2__py3-none-any.whl → 0.0.24.post1__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.
@@ -1,4 +1,4 @@
1
- __version__='0.0.23b2'
1
+ __version__='0.0.24.post1'
2
2
 
3
3
  from .fetchers import (
4
4
  BalanceSheetFetcher,
@@ -19,32 +19,43 @@ class BalanceSheetFetcher(StatsFetcher):
19
19
  "us_stats": self.process_data_us
20
20
  }
21
21
 
22
+ self.return_keys = [
23
+ 'balance_sheet', 'total_asset', 'current_asset', 'non_current_asset',
24
+ 'current_debt', 'non_current_debt', 'equity', 'balance_sheet_all', 'balance_sheet_YoY'
25
+ ]
26
+
22
27
  def prepare_query(self):
23
28
  pipeline = super().prepare_query()
24
29
 
25
- pipeline = pipeline + [
26
- {
27
- "$unwind": "$seasonal_data" # 展開 seasonal_data 陣列
28
- },
29
- {
30
- "$project": {
31
- "_id": 0,
32
- "ticker": 1,
33
- "company_name": 1,
34
- "year": "$seasonal_data.year",
35
- "season": "$seasonal_data.season",
36
- "balance_sheet": {
37
- "$ifNull": ["$seasonal_data.balance_sheet", []]
38
- } # 避免 null
39
- }
40
- },
41
- {
42
- "$sort": {
43
- "year": -1,
44
- "season": -1
30
+ name_map = {
31
+ "twse_stats": "balance_sheet",
32
+ "us_stats": "balance_sheet"
33
+ }
34
+
35
+
36
+ chart_name = name_map.get(self.collection_name, "balance_sheet")
37
+
38
+ append_pipeline = [
39
+ {
40
+ "$project": {
41
+ "_id": 0,
42
+ "ticker": 1,
43
+ "company_name": 1,
44
+ "seasonal_data": {
45
+ "$map": {
46
+ "input": {"$ifNull": ["$seasonal_data", []]},
47
+ "as": "season",
48
+ "in": {
49
+ "year": "$$season.year",
50
+ "season": "$$season.season",
51
+ "data": {"$ifNull": [f"$$season.{chart_name}", []]}
52
+ }
53
+ }
45
54
  }
46
55
  }
47
- ]
56
+ }
57
+ ]
58
+ pipeline = pipeline + append_pipeline
48
59
 
49
60
  return pipeline
50
61
 
@@ -53,6 +64,7 @@ class BalanceSheetFetcher(StatsFetcher):
53
64
 
54
65
  def query_data(self):
55
66
  fetched_data = self.collect_data()
67
+ fetched_data = fetched_data[0]
56
68
 
57
69
  process_fn = self.process_function_map[self.collection_name]
58
70
  processed_data = process_fn(fetched_data)
@@ -72,14 +84,19 @@ class BalanceSheetFetcher(StatsFetcher):
72
84
 
73
85
  return_dict = {
74
86
  "ticker": self.ticker,
75
- "company_name": fetched_data[-1]['company_name']
87
+ "company_name": fetched_data['company_name']
76
88
  }
77
89
  table_dict = {}
78
90
 
91
+ seasonal_data = fetched_data.get('seasonal_data')
92
+ if not seasonal_data:
93
+ return_dict.update(self._get_empty_structure())
94
+ return return_dict
95
+
79
96
  # 將value與percentage跟著年分季度一筆筆取出
80
- for data in fetched_data:
97
+ for data in seasonal_data:
81
98
  year, season, balance_sheet = data['year'], data['season'], data[
82
- 'balance_sheet']
99
+ 'data']
83
100
  time_index = f"{year}Q{season}"
84
101
 
85
102
  new_balance_sheet = dict()
@@ -96,35 +113,37 @@ class BalanceSheetFetcher(StatsFetcher):
96
113
  old_balance_sheet = old_balance_sheet.loc[:, target_season_col]
97
114
  old_balance_sheet = StatsProcessor.expand_value_percentage(old_balance_sheet)
98
115
 
116
+ # 處理QoQ版BalanceSheet
99
117
  for time_index, data_dict in table_dict.items():
100
118
  new_balance_sheet = self.flatten_dict(
101
- balance_sheet,
119
+ data_dict,
102
120
  indexes = index_names,
103
121
  target_keys=["value", "percentage"]
104
122
  )
105
123
 
106
124
  table_dict[time_index] = new_balance_sheet
107
125
 
108
- total_table = pd.DataFrame.from_dict(table_dict)
109
- value_index = total_table.index.str.endswith("_value")
110
- total_table.loc[value_index, :] = (
111
- total_table.loc[value_index, :].apply(
112
- lambda x: StatsProcessor.cal_non_percentage(x, postfix="元"),
113
- axis=0
126
+ total_table = pd.DataFrame.from_dict(table_dict).T
127
+ value_index = total_table.columns.str.endswith("_value")
128
+ value_cols = total_table.loc[:, value_index].columns
129
+ total_table[value_cols] = (
130
+ total_table[value_cols].map(
131
+ lambda x: StatsProcessor.cal_non_percentage(x, postfix="千元"),
114
132
  )
115
133
  )
116
134
 
117
- percenrage_index = total_table.index.str.endswith(
135
+ percentage_index = total_table.columns.str.endswith(
118
136
  "_percentage"
119
137
  )
120
- total_table.loc[percenrage_index, :] = (
121
- total_table.loc[percenrage_index, :].apply(
138
+ percentage_cols = total_table.loc[:, percentage_index].columns
139
+ total_table[percentage_cols] = (
140
+ total_table[percentage_cols].map(
122
141
  lambda x: StatsProcessor.
123
142
  cal_non_percentage(x, to_str=True, postfix="%"),
124
- axis=0
125
143
  )
126
144
  )
127
145
 
146
+ total_table = total_table.T
128
147
  target_season_columns = total_table.columns.str.endswith(
129
148
  f"Q{target_season}"
130
149
  )
@@ -140,7 +159,6 @@ class BalanceSheetFetcher(StatsFetcher):
140
159
  )
141
160
  break
142
161
  except Exception as e:
143
- print(f"error : {str(e)}")
144
162
  continue
145
163
 
146
164
  return_dict.update(
@@ -155,24 +173,30 @@ class BalanceSheetFetcher(StatsFetcher):
155
173
  def process_data_us(self, fetched_data):
156
174
  return_dict = {
157
175
  "ticker": self.ticker,
158
- "company_name": fetched_data[-1]['company_name']
176
+ "company_name": fetched_data['company_name']
159
177
  }
178
+ table_dict = {}
160
179
 
161
180
  table_dict = dict()
162
181
 
163
- for data in fetched_data:
182
+ for data in fetched_data['seasonal_data']:
164
183
  year, season, balance_sheet = data['year'], data['season'], data[
165
- 'balance_sheet']
184
+ 'data']
166
185
  table_dict[f"{year}Q{season}"] = balance_sheet
167
186
 
168
187
  table_dict = pd.DataFrame.from_dict(table_dict)
169
188
 
170
189
  return_dict["balance_sheet"] = table_dict
171
190
 
172
- latest_season = fetched_data[0]['season']
191
+ latest_season = fetched_data['seasonal_data'][0]['season']
173
192
  target_season_columns = table_dict.columns.str.endswith(
174
193
  f"Q{latest_season}"
175
194
  )
176
195
  table_dict_YoY = table_dict.loc[:, target_season_columns]
177
196
  return_dict["balance_sheet_YoY"] = table_dict_YoY
178
197
  return return_dict
198
+
199
+ def _get_empty_structure(self):
200
+ return {
201
+ key: pd.DataFrame(columns= pd.Index([], name = 'date')) for key in self.return_keys
202
+ }
@@ -97,8 +97,12 @@ class BaseTEJFetcher(abc.ABC):
97
97
  }
98
98
  )
99
99
 
100
- # return 得到最新日期或None
101
- return latest_data.get('last_update', {}).get("latest_data_date", None)
100
+ if (latest_data):
101
+ # return 得到最新日期或None
102
+ return latest_data.get('last_update', {}).get("latest_data_date", None)
103
+
104
+ else:
105
+ return None
102
106
 
103
107
  def process_value(self, value):
104
108
  if isinstance(value, str) and "%" in value:
@@ -18,6 +18,8 @@ class CashFlowFetcher(StatsFetcher):
18
18
  "twse_stats": self.process_data_twse,
19
19
  "us_stats": self.process_data_us
20
20
  }
21
+
22
+ self.return_keys = ['cash_flow', 'CASHO', 'CASHI', 'CASHF', 'cash_flow_all', 'cash_flow_YoY']
21
23
 
22
24
  def prepare_query(self):
23
25
  pipeline = super().prepare_query()
@@ -31,28 +33,25 @@ class CashFlowFetcher(StatsFetcher):
31
33
  chart_name = name_map.get(self.collection_name, "cash_flow")
32
34
 
33
35
  append_pipeline = [
34
- {
35
- "$unwind": "$seasonal_data" # 展開 seasonal_data 陣列
36
- },
37
- {
38
- "$project": {
39
- "_id": 0,
40
- "ticker": 1,
41
- "company_name": 1,
42
- "year": "$seasonal_data.year",
43
- "season": "$seasonal_data.season",
44
- "cash_flow": {
45
- "$ifNull": [f"$seasonal_data.{chart_name}", []]
46
- } # 避免 null
47
- }
48
- },
49
- {
50
- "$sort": {
51
- "year": -1,
52
- "season": -1
36
+ {
37
+ "$project": {
38
+ "_id": 0,
39
+ "ticker": 1,
40
+ "company_name": 1,
41
+ "seasonal_data": {
42
+ "$map": {
43
+ "input": {"$ifNull": ["$seasonal_data", []]},
44
+ "as": "season",
45
+ "in": {
46
+ "year": "$$season.year",
47
+ "season": "$$season.season",
48
+ "data": {"$ifNull": [f"$$season.{chart_name}", []]}
49
+ }
50
+ }
53
51
  }
54
52
  }
55
- ]
53
+ }
54
+ ]
56
55
 
57
56
  pipeline = pipeline + append_pipeline
58
57
 
@@ -63,6 +62,7 @@ class CashFlowFetcher(StatsFetcher):
63
62
 
64
63
  def query_data(self):
65
64
  fetched_data = self.collect_data()
65
+ fetched_data = fetched_data[0]
66
66
 
67
67
  process_fn = self.process_function_map.get(self.collection_name, self.process_data_us)
68
68
  return process_fn(fetched_data)
@@ -78,27 +78,36 @@ class CashFlowFetcher(StatsFetcher):
78
78
  index_names = []
79
79
  column_names = []
80
80
 
81
- table_dict = dict()
82
- CASHO_dict = dict()
83
- CASHI_dict = dict()
84
- CASHF_dict = dict()
81
+ table_dict = {}
82
+ CASHO_dict = {}
83
+ CASHI_dict = {}
84
+ CASHF_dict = {}
85
85
 
86
86
  # 處理cash_flow 比例
87
87
  checkpoints = ["營業活動之現金流量-間接法", "投資活動之現金流量", "籌資活動之現金流量", "匯率變動對現金及約當現金之影響"]
88
88
  main_cash_flows = [
89
- "營業活動之淨現金流入(流出)", "投資活動之淨現金流入(流出)", "籌資活動之淨現金流入(流出)", None
89
+ "營業活動之淨現金流入(流出)", "投資活動之淨現金流入(流出)", "籌資活動之淨現金流入(流出)", "其他"
90
90
  ] # 主要的比例對象
91
91
  partial_cash_flows = [CASHO_dict, CASHI_dict, CASHF_dict, dict()]
92
92
 
93
93
  # 作法: dictionary中也有checkpoints,如果出現了就換下一個index去計算
94
94
 
95
- for data in fetched_data:
96
- year, season, cash_flow = data['year'], data['season'], data['cash_flow']
95
+ return_dict = {
96
+ "ticker": self.ticker,
97
+ "company_name": fetched_data['company_name']
98
+ }
99
+ seasonal_data = fetched_data.get('seasonal_data')
100
+ if not seasonal_data:
101
+ return_dict.update(self._get_empty_structure())
102
+ return return_dict
103
+
104
+ for data in seasonal_data:
105
+ year, season, cash_flow = data['year'], data['season'], data['data']
97
106
 
98
107
  time_index = f"{year}Q{season}"
99
108
 
100
- main_cash_flow_name = None
101
- partial_cash_flow = None
109
+ main_cash_flow_name = ""
110
+ partial_cash_flow = {}
102
111
  next_checkpoint = 0
103
112
 
104
113
  temp_dict = {}
@@ -110,34 +119,34 @@ class CashFlowFetcher(StatsFetcher):
110
119
  partial_cash_flow = partial_cash_flows[next_checkpoint]
111
120
  partial_cash_flow[time_index] = {}
112
121
  next_checkpoint += 1
122
+
123
+ if main_cash_flow_name: # 有取得cash flow name再進行接下來的計算percentage
124
+ if (isinstance(cash_flow_value, dict)):
125
+ value = cash_flow_value.get('value', None)
126
+ else:
127
+ value = cash_flow_value
113
128
 
114
- if (isinstance(cash_flow_value, dict)):
115
- value = cash_flow_value.get('value', None)
116
- else:
117
- value = cash_flow_value
118
-
119
-
120
- main_value = cash_flow.get(main_cash_flow_name, None)
121
- if (isinstance(main_value, dict)):
122
- main_value = main_value.get('value', None)
123
- else:
124
- pass
125
-
126
- try:
127
- ratio = np.round(
128
- (value / main_value) * 100, 2
129
- )
130
- ratio = f"{ratio}%"
131
- except:
132
- ratio = None
133
-
134
- value = StatsProcessor.cal_non_percentage(value, postfix="千元")
135
- temp_dict[index_name] = {
136
- "value" : value,
137
- "percentage": ratio
138
- }
139
-
140
- partial_cash_flow[time_index][index_name] = temp_dict[index_name]
129
+ # 處理cashflow percentage部分(取2位 + 接%)
130
+ main_value = cash_flow.get(main_cash_flow_name, None)
131
+ if (isinstance(main_value, dict)):
132
+ main_value = main_value.get('value', None)
133
+ else:
134
+ pass
135
+
136
+ try:
137
+ ratio = np.round(
138
+ (value / main_value) * 100, 2
139
+ )
140
+ ratio = f"{ratio}%"
141
+ except:
142
+ ratio = None
143
+
144
+ value = StatsProcessor.cal_non_percentage(value, postfix="千元")
145
+ temp_dict[index_name] = {
146
+ "value" : value,
147
+ "percentage": ratio
148
+ }
149
+ partial_cash_flow[time_index][index_name] = temp_dict[index_name]
141
150
 
142
151
  table_dict[time_index] = temp_dict
143
152
  index_names += list(cash_flow.keys())
@@ -157,35 +166,42 @@ class CashFlowFetcher(StatsFetcher):
157
166
  CASHF_table = pd.DataFrame(CASHF_dict)
158
167
  CASHF_table = StatsProcessor.expand_value_percentage(CASHF_table)
159
168
 
160
- for time_index in table_dict.keys():
161
- table_dict[time_index] = self.flatten_dict(table_dict[time_index], index_names, target_keys=['value', 'percentage'])
162
- cash_flow_flatten = pd.DataFrame.from_dict(table_dict)
169
+ # 回傳歷來格式
170
+ target_season = seasonal_data[0]['season']
163
171
 
164
- target_season = fetched_data[0]['season']
165
- target_season_column = cash_flow_flatten.columns.str.endswith(f"Q{target_season}")
172
+ cash_flow_flatten, cash_flow_flatten_YoY = self.flatten_twse(
173
+ table_dict, target_season, index_names
174
+ )
166
175
 
167
- return_dict = {
168
- "ticker": self.ticker,
169
- "company_name": fetched_data[-1]['company_name'],
176
+ return_dict.update({
170
177
  "cash_flow": cash_flow_table_stats,
171
178
  "CASHO": CASHO_table,
172
179
  "CASHI": CASHI_table,
173
180
  "CASHF": CASHF_table,
174
181
  "cash_flow_all": cash_flow_flatten,
175
- "cash_flow_YoY": cash_flow_flatten.loc[:, target_season_column]
176
- }
182
+ "cash_flow_YoY": cash_flow_flatten_YoY
183
+ })
177
184
  return return_dict
185
+
186
+ def flatten_twse(self, data_dict: dict, target_season: int, index_names: list):
187
+ for time_index in data_dict.keys():
188
+ data_dict[time_index] = self.flatten_dict(data_dict[time_index], index_names, target_keys=['value', 'percentage'])
189
+ cash_flow_flatten = pd.DataFrame.from_dict(data_dict)
190
+
191
+ target_season_column = cash_flow_flatten.columns.str.endswith(f"Q{target_season}")
192
+
193
+ return cash_flow_flatten, cash_flow_flatten.loc[:, target_season_column]
178
194
 
179
195
  def process_data_us(self, fetched_data):
180
196
 
181
197
  table_dict = {
182
- f"{data['year']}Q{data['season']}": data['cash_flow']
183
- for data in fetched_data
198
+ f"{data['year']}Q{data['season']}": data['data']
199
+ for data in fetched_data['seasonal_data']
184
200
  }
185
201
 
186
202
  cash_flow_df = pd.DataFrame.from_dict(table_dict)
187
203
 
188
- latest_season = fetched_data[0]['season']
204
+ latest_season = fetched_data['seasonal_data'][0]['season']
189
205
  target_season_columns = cash_flow_df.columns.str.endswith(
190
206
  f"Q{latest_season}"
191
207
  )
@@ -193,8 +209,13 @@ class CashFlowFetcher(StatsFetcher):
193
209
 
194
210
  return_dict = {
195
211
  "ticker": self.ticker,
196
- "company_name": fetched_data[-1]['company_name'],
212
+ "company_name": fetched_data['company_name'],
197
213
  "cash_flow": cash_flow_df,
198
214
  "cash_flow_YoY": cash_flow_df_YoY
199
215
  }
200
216
  return return_dict
217
+
218
+ def _get_empty_structure(self):
219
+ return {
220
+ key: pd.DataFrame(columns= pd.Index([], name = 'date')) for key in self.return_keys
221
+ }
@@ -196,7 +196,7 @@ class FinanceOverviewProcessor(StatsProcessor):
196
196
  finance_dict['EBIT'] = StatsProcessor.cal_non_percentage(EBIT)
197
197
  except (KeyError, ZeroDivisionError, TypeError) as e:
198
198
  finance_dict['EBIT'] = None
199
- print(f"Error calculating EBIT: {e}")
199
+ # print(f"Error calculating EBIT: {e}")
200
200
 
201
201
  @classmethod
202
202
  def cal_fcf(cls, finance_dict):
@@ -210,7 +210,7 @@ class FinanceOverviewProcessor(StatsProcessor):
210
210
  finance_dict["fcf"] = StatsProcessor.cal_non_percentage(fcf)
211
211
  except (KeyError, ZeroDivisionError, TypeError) as e:
212
212
  finance_dict['fcf'] = None
213
- print(f"Error calculating FCF: {e}")
213
+ # print(f"Error calculating FCF: {e}")
214
214
 
215
215
  @classmethod
216
216
  def cal_interest_bearing_debt(cls, finance_dict):
@@ -242,7 +242,7 @@ class FinanceOverviewProcessor(StatsProcessor):
242
242
  finance_dict['eps'])
243
243
  except (KeyError, ZeroDivisionError, TypeError) as e:
244
244
  finance_dict['share_outstanding'] = None
245
- print(f"share_outstanding failed because of {str(e)}")
245
+ # print(f"share_outstanding failed because of {str(e)}")
246
246
 
247
247
  @classmethod
248
248
  def cal_revenue_per_share(cls, finance_dict):
@@ -258,7 +258,7 @@ class FinanceOverviewProcessor(StatsProcessor):
258
258
  revenue_per_share, False)
259
259
  except (KeyError, ZeroDivisionError, TypeError) as e:
260
260
  finance_dict['revenue_per_share'] = None
261
- print(f"revenue_per_share failed because of {str(e)}")
261
+ # print(f"revenue_per_share failed because of {str(e)}")
262
262
 
263
263
  @classmethod
264
264
  def cal_gross_per_share(cls, finance_dict):
@@ -283,7 +283,7 @@ class FinanceOverviewProcessor(StatsProcessor):
283
283
 
284
284
  except (KeyError, ZeroDivisionError, TypeError) as e:
285
285
  finance_dict['gross_per_share'] = None
286
- print(f"gross_per_share failed because of {str(e)}")
286
+ # print(f"gross_per_share failed because of {str(e)}")
287
287
 
288
288
  @classmethod
289
289
  def cal_operating_income_per_share(cls, finance_dict):
@@ -299,7 +299,7 @@ class FinanceOverviewProcessor(StatsProcessor):
299
299
  operating_income_per_share)
300
300
  except (KeyError, ZeroDivisionError, TypeError) as e:
301
301
  finance_dict['operating_income_per_share'] = None
302
- print(f"operating_income_per_share failed because of {str(e)}")
302
+ # print(f"operating_income_per_share failed because of {str(e)}")
303
303
 
304
304
  @classmethod
305
305
  def cal_operating_cash_flow_per_share(cls, finance_dict):
@@ -331,7 +331,7 @@ class FinanceOverviewProcessor(StatsProcessor):
331
331
  fcf_per_share)
332
332
  except (KeyError, ZeroDivisionError, TypeError) as e:
333
333
  finance_dict['fcf_per_share'] = None
334
- print(f"fcf_per_share failed because of {str(e)}")
334
+ # print(f"fcf_per_share failed because of {str(e)}")
335
335
 
336
336
  # 盈利能力
337
337
 
@@ -375,7 +375,7 @@ class FinanceOverviewProcessor(StatsProcessor):
375
375
  gross_over_asset)
376
376
  except (KeyError, ZeroDivisionError, TypeError) as e:
377
377
  finance_dict['gross_over_asset'] = None
378
- print(f"營業毛利/總資產 failed because of {str(e)}")
378
+ # print(f"營業毛利/總資產 failed because of {str(e)}")
379
379
 
380
380
  @classmethod
381
381
  def cal_roce(cls, finance_dict):
@@ -392,7 +392,7 @@ class FinanceOverviewProcessor(StatsProcessor):
392
392
 
393
393
  except (KeyError, ZeroDivisionError, TypeError) as e:
394
394
  finance_dict['roce'] = None
395
- print(f"ROCE failed because of {str(e)}")
395
+ # print(f"ROCE failed because of {str(e)}")
396
396
 
397
397
  @classmethod
398
398
  def cal_gross_profit_marginal(cls, finance_dict):
@@ -408,7 +408,7 @@ class FinanceOverviewProcessor(StatsProcessor):
408
408
  gross_profit_margin)
409
409
  except Exception as e:
410
410
  finance_dict['gross_profit_margin'] = None
411
- print(f"gross_profit_margin failed because of {str(e)}")
411
+ # print(f"gross_profit_margin failed because of {str(e)}")
412
412
 
413
413
  @classmethod
414
414
  def cal_operation_profit_rate(cls, finance_dict):
@@ -425,7 +425,7 @@ class FinanceOverviewProcessor(StatsProcessor):
425
425
  operation_profit_rate)
426
426
  except (KeyError, ZeroDivisionError, TypeError) as e:
427
427
  finance_dict["operation_profit_rate"] = None
428
- print(f"operation_profit failed because of {str(e)}")
428
+ # print(f"operation_profit failed because of {str(e)}")
429
429
 
430
430
  @classmethod
431
431
  def cal_operating_cash_flow_profit_rate(cls, finance_dict):
@@ -441,8 +441,8 @@ class FinanceOverviewProcessor(StatsProcessor):
441
441
  operating_cash_flow_profit_rate)
442
442
  except (KeyError, ZeroDivisionError, TypeError) as e:
443
443
  finance_dict["operating_cash_flow_profit_rate"] = None
444
- print(
445
- f"operating_cash_flow_profit_rate failed because of {str(e)}")
444
+ # print(
445
+ # f"operating_cash_flow_profit_rate failed because of {str(e)}")
446
446
 
447
447
 
448
448
  # 成長動能
@@ -466,7 +466,7 @@ class FinanceOverviewProcessor(StatsProcessor):
466
466
  dso, to_str=True, postfix="日")
467
467
  except Exception as e:
468
468
  finance_dict['dso'] = None
469
- print(f"Error calculating 應收帳款收現天數 because of {str(e)}")
469
+ # print(f"Error calculating 應收帳款收現天數 because of {str(e)}")
470
470
 
471
471
  @classmethod
472
472
  def cal_account_receive_over_revenue(cls, finance_dict):
@@ -498,7 +498,7 @@ class FinanceOverviewProcessor(StatsProcessor):
498
498
  dpo, to_str=True, postfix="日")
499
499
  except (KeyError, ZeroDivisionError, TypeError) as e:
500
500
  finance_dict["dpo"] = None
501
- print(f"應付帳款週轉天數 failed because of {str(e)}")
501
+ # print(f"應付帳款週轉天數 failed because of {str(e)}")
502
502
 
503
503
  @classmethod
504
504
  def cal_inventories_cycle_ratio(cls, finance_dict):
@@ -515,7 +515,7 @@ class FinanceOverviewProcessor(StatsProcessor):
515
515
  inventories_cycle_ratio)
516
516
  except (KeyError, ZeroDivisionError, TypeError) as e:
517
517
  finance_dict["inventories_cycle_ratio"] = None
518
- print(f"Error calculating 存貨周轉率 because of {str(e)}")
518
+ # print(f"Error calculating 存貨周轉率 because of {str(e)}")
519
519
 
520
520
  @classmethod
521
521
  def cal_dio(cls, finance_dict):
@@ -531,7 +531,7 @@ class FinanceOverviewProcessor(StatsProcessor):
531
531
  dio, to_str=True, postfix="日")
532
532
  except (KeyError, ZeroDivisionError, TypeError) as e:
533
533
  finance_dict["dio"] = None
534
- print(f"Error calculating 存貨週轉天數 because of {str(e)}")
534
+ # print(f"Error calculating 存貨週轉天數 because of {str(e)}")
535
535
 
536
536
  @classmethod
537
537
  def cal_inventories_revenue_ratio(cls, finance_dict):
@@ -548,7 +548,7 @@ class FinanceOverviewProcessor(StatsProcessor):
548
548
  inventories_revenue_ratio)
549
549
  except (KeyError, ZeroDivisionError, TypeError) as e:
550
550
  finance_dict["inventories_revenue_ratio"] = None
551
- print(f"Error calculating 存貨佔營收比率 because of {str(e)}")
551
+ # print(f"Error calculating 存貨佔營收比率 because of {str(e)}")
552
552
 
553
553
  @classmethod
554
554
  def cal_cash_of_conversion_cycle(cls, finance_dict):
@@ -609,7 +609,7 @@ class FinanceOverviewProcessor(StatsProcessor):
609
609
  current_ratio)
610
610
  except (KeyError, ZeroDivisionError, TypeError) as e:
611
611
  finance_dict['current_ratio'] = None
612
- print(f"Error calculating current ratio: {e}")
612
+ # print(f"Error calculating current ratio: {e}")
613
613
 
614
614
  @classmethod
615
615
  def cal_quick_ratio(cls, finance_dict):
@@ -625,7 +625,7 @@ class FinanceOverviewProcessor(StatsProcessor):
625
625
  quick_ratio)
626
626
  except (KeyError, ZeroDivisionError, TypeError) as e:
627
627
  finance_dict['quick_ratio'] = None
628
- print(f"Error calculating quick ratio: {e}")
628
+ # print(f"Error calculating quick ratio: {e}")
629
629
 
630
630
  @classmethod
631
631
  def cal_debt_to_equity_ratio(cls, finance_dict):
@@ -640,7 +640,7 @@ class FinanceOverviewProcessor(StatsProcessor):
640
640
  debt_to_equity_ratio)
641
641
  except (KeyError, ZeroDivisionError, TypeError) as e:
642
642
  finance_dict['debt_to_equity_ratio'] = None
643
- print(f"Error calculating debt to equity ratio: {e}")
643
+ # print(f"Error calculating debt to equity ratio: {e}")
644
644
 
645
645
  @classmethod
646
646
  def cal_net_debt_to_equity_ratio(cls, finance_dict):
@@ -657,7 +657,7 @@ class FinanceOverviewProcessor(StatsProcessor):
657
657
  net_debt_to_equity_ratio)
658
658
  except (KeyError, ZeroDivisionError, TypeError) as e:
659
659
  finance_dict['net_debt_to_equity_ratio'] = None
660
- print(f"Error calculating net debt to equity ratio: {e}")
660
+ # print(f"Error calculating net debt to equity ratio: {e}")
661
661
 
662
662
  @classmethod
663
663
  def cal_interest_coverage_ratio(cls, finance_dict):
@@ -672,7 +672,7 @@ class FinanceOverviewProcessor(StatsProcessor):
672
672
  interest_coverage_ratio, to_str=True, postfix="倍")
673
673
  except (KeyError, ZeroDivisionError, TypeError) as e:
674
674
  finance_dict['interest_coverage_ratio'] = None
675
- print(f"Error calculating interest coverage ratio: {e}")
675
+ # print(f"Error calculating interest coverage ratio: {e}")
676
676
 
677
677
  @classmethod
678
678
  def cal_debt_to_operating_cash_flow(cls, finance_dict):
@@ -687,7 +687,7 @@ class FinanceOverviewProcessor(StatsProcessor):
687
687
  debt_to_operating_cash_flow)
688
688
  except (KeyError, ZeroDivisionError, TypeError) as e:
689
689
  finance_dict['debt_to_operating_cash_flow'] = None
690
- print(f"Error calculating debt to operating cash flow: {e}")
690
+ # print(f"Error calculating debt to operating cash flow: {e}")
691
691
 
692
692
  @classmethod
693
693
  def cal_debt_to_free_cash_flow(cls, finance_dict):
@@ -702,7 +702,7 @@ class FinanceOverviewProcessor(StatsProcessor):
702
702
  debt_to_free_cash_flow)
703
703
  except (KeyError, ZeroDivisionError, TypeError) as e:
704
704
  finance_dict['debt_to_free_cash_flow'] = None
705
- print(f"Error calculating debt to free cash flow: {e}")
705
+ # print(f"Error calculating debt to free cash flow: {e}")
706
706
 
707
707
  @classmethod
708
708
  def cal_cash_flow_ratio(cls, finance_dict):
@@ -716,4 +716,4 @@ class FinanceOverviewProcessor(StatsProcessor):
716
716
  cash_flow_ratio)
717
717
  except (KeyError, ZeroDivisionError, TypeError) as e:
718
718
  finance_dict['cash_flow_ratio'] = None
719
- print(f"Error calculating cash flow ratio: {e}")
719
+ # print(f"Error calculating cash flow ratio: {e}")