yeref 0.25.4__py3-none-any.whl → 0.25.6__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.
yeref/yeref.py CHANGED
@@ -16097,7 +16097,7 @@ async def calc_metrics(bot, PROJECT_USERNAME, dataroom_folder_id, EXTRA_D, BASE_
16097
16097
  offset += len(tbl['rows'])
16098
16098
 
16099
16099
  # 5.3) Оставляем минимум 2 пустые строки перед следующей таблицей
16100
- offset += 2
16100
+ offset += 3
16101
16101
 
16102
16102
  # 6) Выполняем единый batchUpdate для всех data_requests
16103
16103
  write_body = {
@@ -16309,14 +16309,14 @@ async def return_unit_metrics(bot, data_users, EXTRA_D):
16309
16309
  results.append({
16310
16310
  "MO": mo,
16311
16311
  "N": str(N),
16312
- "MRR": str(mrr_fmt).replace('.', ','),
16313
- "ARPU": str(fmt(ARPU)).replace('.', ','),
16314
- "ARR": str(fmt(ARR)).replace('.', ','),
16315
- "ChurnR": str(fmt(ChurnR)).replace('.', ','),
16316
- "LTV1": str(fmt(LTV1)).replace('.', ','),
16317
- "LTV2": str(fmt(LTV2)).replace('.', ','),
16318
- "CMGR": str(fmt(CMGR)).replace('.', ','),
16319
- "CAC": str("").replace('.', ',')
16312
+ "MRR": mrr_fmt,
16313
+ "ARPU": fmt(ARPU),
16314
+ "ARR": fmt(ARR),
16315
+ "ChurnR": fmt(ChurnR),
16316
+ "LTV1": fmt(LTV1),
16317
+ "LTV2": fmt(LTV2),
16318
+ "CMGR": fmt(CMGR),
16319
+ "CAC": ""
16320
16320
  })
16321
16321
 
16322
16322
  f_name = os.path.join(EXTRA_D, "2_unit_metrics.csv")
@@ -16325,8 +16325,16 @@ async def return_unit_metrics(bot, data_users, EXTRA_D):
16325
16325
  writer.writerow(["MO", "N", "MRR", "ARPU", "ARR", "ChurnR", "LTV1", "LTV2", "CMGR", "CAC"])
16326
16326
  for row in results:
16327
16327
  writer.writerow([
16328
- row["MO"], row["N"], row["MRR"], row["ARPU"], row["ARR"],
16329
- row["ChurnR"], row["LTV1"], row["LTV2"], row["CMGR"], row["CAC"]
16328
+ row["MO"],
16329
+ str(row["N"]).replace('.', ','),
16330
+ str(row["MRR"]).replace('.', ','),
16331
+ str(row["ARPU"]).replace('.', ','),
16332
+ str(row["ARR"]).replace('.', ','),
16333
+ str(row["ChurnR"]).replace('.', ','),
16334
+ str(row["LTV1"]).replace('.', ','),
16335
+ str(row["LTV2"]).replace('.', ','),
16336
+ str(row["CMGR"]).replace('.', ','),
16337
+ str(row["CAC"]).replace('.', ',')
16330
16338
  ])
16331
16339
 
16332
16340
  cmgr_vals = [float(r["CMGR"]) for r in results if r["CMGR"] != ""]
@@ -16334,7 +16342,7 @@ async def return_unit_metrics(bot, data_users, EXTRA_D):
16334
16342
  factors = [1 + v for v in cmgr_vals]
16335
16343
  avg = math.prod(factors) ** (1 / len(factors))
16336
16344
  writer.writerow([])
16337
- writer.writerow([f"Rev ~ ×{round(avg, 2)} monthly"])
16345
+ writer.writerow([f"Rev ~ ×{round(avg, 2)} monthly".replace('.', ',')])
16338
16346
 
16339
16347
  result = f_name
16340
16348
  thumb = types.FSInputFile(os.path.join(EXTRA_D, "parse.jpg"))
@@ -16429,7 +16437,7 @@ async def return_cohort_metrics(bot, data_users, EXTRA_D):
16429
16437
  for r in table:
16430
16438
  writer.writerow(r)
16431
16439
  writer.writerow([])
16432
- writer.writerow([f"Churn ~ ×{avg_churn:.2f} monthly"])
16440
+ writer.writerow([f"Churn ~ ×{avg_churn:.2f} monthly".replace('.', ',')])
16433
16441
 
16434
16442
  result = f_name
16435
16443
  thumb = types.FSInputFile(os.path.join(EXTRA_D, "parse.jpg"))
@@ -16503,12 +16511,12 @@ async def return_retention_metrics(bot, data_users, EXTRA_D):
16503
16511
  else:
16504
16512
  rev = rev_by_cohort[c].get(offset, 0.0)
16505
16513
  if rev > 0:
16506
- cell = f"{rev:.1f}"
16514
+ cell = f"{rev:.1f}".replace('.', ',')
16507
16515
  row.append(cell)
16508
16516
  row_sum += rev
16509
16517
  else:
16510
- row.append("0.0")
16511
- row.append(f"{row_sum:.1f}")
16518
+ row.append("0,0")
16519
+ row.append(f"{row_sum:.1f}".replace('.', ','))
16512
16520
  writer.writerow(row)
16513
16521
 
16514
16522
  factors = []
@@ -16521,7 +16529,7 @@ async def return_retention_metrics(bot, data_users, EXTRA_D):
16521
16529
  avg_multiplier = math.prod(factors) ** (1 / len(factors)) if factors else 1.0
16522
16530
 
16523
16531
  writer.writerow([])
16524
- writer.writerow([f"NRR ~ ×{avg_multiplier:.2f} monthly"])
16532
+ writer.writerow([f"NRR ~ ×{avg_multiplier:.2f} monthly".replace('.', ',')])
16525
16533
 
16526
16534
  result = f_name
16527
16535
  thumb = types.FSInputFile(os.path.join(EXTRA_D, "parse.jpg"))
@@ -16538,6 +16546,7 @@ async def return_profit_and_loss_metrics(bot, data_users, EXTRA_D):
16538
16546
  try:
16539
16547
  metrics = defaultdict(lambda: {"sum_amount": 0.0})
16540
16548
 
16549
+ # Собираем данные по месяцам
16541
16550
  for USER_TID, USER_VARS, USER_LSTS in data_users:
16542
16551
  USER_LSTS = json.loads(USER_LSTS or "{}")
16543
16552
  USER_PAYMENTS = USER_LSTS.get("USER_PAYMENTS", [])
@@ -16548,12 +16557,14 @@ async def return_profit_and_loss_metrics(bot, data_users, EXTRA_D):
16548
16557
  amt = float(pay.get("AMOUNT", 0)) * 0.013
16549
16558
  metrics[mo_p]["sum_amount"] += amt
16550
16559
 
16560
+ # Функция форматирования с запятой
16551
16561
  def fmt(x):
16552
- return f"{x:.2f}".rstrip("0").rstrip(".") if x is not None else ""
16562
+ return f"{x:.2f}".rstrip("0").rstrip(".").replace(".", ",") if x is not None else ""
16553
16563
 
16554
16564
  # Сортируем месяцы
16555
16565
  months_sorted = sorted(metrics.keys())
16556
16566
  results = []
16567
+ np_values = []
16557
16568
 
16558
16569
  for mo in months_sorted:
16559
16570
  MRR = metrics[mo]["sum_amount"]
@@ -16562,12 +16573,12 @@ async def return_profit_and_loss_metrics(bot, data_users, EXTRA_D):
16562
16573
  OPEX = 4.5
16563
16574
  OP = GP - OPEX
16564
16575
 
16565
- # из OP сначала вычитаем 30%, затем из результата вычитаем 1%
16566
- after_comm = OP * 0.70 # остаётся после 30% комиссии
16567
- after_fiat = after_comm * 0.99 # остаётся после ещё 1% на обмен
16568
- COMM = OP - after_comm # сама комиссия (30% от OP)
16569
- EXCH = after_comm - after_fiat # сама часть обмена (1% от остатка после комиссии)
16570
- NP = after_fiat # чистая прибыль
16576
+ # комиссия 30% и обмен 1%
16577
+ after_comm = OP * 0.70
16578
+ after_fiat = after_comm * 0.99
16579
+ COMM = OP - after_comm
16580
+ EXCH = after_comm - after_fiat
16581
+ NP = after_fiat
16571
16582
 
16572
16583
  results.append([
16573
16584
  mo,
@@ -16580,16 +16591,27 @@ async def return_profit_and_loss_metrics(bot, data_users, EXTRA_D):
16580
16591
  fmt(EXCH),
16581
16592
  fmt(NP)
16582
16593
  ])
16594
+ np_values.append(NP)
16595
+
16596
+ # Вычисляем средний NP (если есть хотя бы одно значение)
16597
+ avg_np = sum(np_values) / len(np_values) if np_values else 0.0
16598
+ avg_np_str = fmt(avg_np)
16583
16599
 
16584
16600
  f_name = os.path.join(EXTRA_D, "5_profit_and_loss_metrics.csv")
16585
16601
  with open(f_name, "w", newline="", encoding="utf-8") as f:
16586
16602
  writer = csv.writer(f)
16603
+ # Заголовок
16587
16604
  writer.writerow([
16588
16605
  "Mo", "MRR", "COGS", "Gross Profit",
16589
16606
  "OPEX", "Operating Profit", "Comission (30%)", "Fiat (1%)", "Net Profit"
16590
16607
  ])
16608
+ # Строки по месяцам
16591
16609
  for row in results:
16592
16610
  writer.writerow(row)
16611
+ # Пустая строка перед средним
16612
+ writer.writerow([])
16613
+ # Строка со средним Net Profit
16614
+ writer.writerow([f"Average Net Profit: {avg_np_str}"])
16593
16615
 
16594
16616
  result = f_name
16595
16617
  thumb = types.FSInputFile(os.path.join(EXTRA_D, "parse.jpg"))
@@ -16599,6 +16621,7 @@ async def return_profit_and_loss_metrics(bot, data_users, EXTRA_D):
16599
16621
  await asyncio.sleep(round(random.uniform(0, 1), 2))
16600
16622
  finally:
16601
16623
  return result
16624
+
16602
16625
  # endregion
16603
16626
 
16604
16627
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: yeref
3
- Version: 0.25.4
3
+ Version: 0.25.6
4
4
  Summary: desc-f
5
5
  Author: john smith
6
6
  Dynamic: author
@@ -0,0 +1,8 @@
1
+ yeref/__init__.py,sha256=Qpv3o6Xa78VdLcsSRmctGtpnYE9btpAkCekgGhgJyXM,49
2
+ yeref/l_.py,sha256=LMX_olmJwq-tgoALJCnhV_fGrL_i_43yBLkLIcEVqGo,1176743
3
+ yeref/tonweb.js,sha256=Jf6aFOQ1OIY4q7fINYz-m5LsI3seMus124M5SYYZmtE,443659
4
+ yeref/yeref.py,sha256=8Ow6asK12jj3noAAUVtCKwq-txpj_ks_w-L-IQKqaZA,1056443
5
+ yeref-0.25.6.dist-info/METADATA,sha256=bsrMXHVBgRzsBy8TBIwOSrV1PA13MYOgpYrFdb4BfPY,118
6
+ yeref-0.25.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
7
+ yeref-0.25.6.dist-info/top_level.txt,sha256=yCQKchWHbfV-3OuQPYRdi2loypD-nmbDJbtt3OuKKkY,6
8
+ yeref-0.25.6.dist-info/RECORD,,
@@ -1,8 +0,0 @@
1
- yeref/__init__.py,sha256=Qpv3o6Xa78VdLcsSRmctGtpnYE9btpAkCekgGhgJyXM,49
2
- yeref/l_.py,sha256=LMX_olmJwq-tgoALJCnhV_fGrL_i_43yBLkLIcEVqGo,1176743
3
- yeref/tonweb.js,sha256=Jf6aFOQ1OIY4q7fINYz-m5LsI3seMus124M5SYYZmtE,443659
4
- yeref/yeref.py,sha256=TB7u0uxv8RGRRLfQ6iaeFS-Ng2YuhOx0JDo1n7om6gs,1055802
5
- yeref-0.25.4.dist-info/METADATA,sha256=ecy4S3CjeJWmItaFH2Zc2IC7hgTSPR3TSVFtZqsUi_4,118
6
- yeref-0.25.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
7
- yeref-0.25.4.dist-info/top_level.txt,sha256=yCQKchWHbfV-3OuQPYRdi2loypD-nmbDJbtt3OuKKkY,6
8
- yeref-0.25.4.dist-info/RECORD,,
File without changes