yeref 0.24.65__py3-none-any.whl → 0.24.67__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
@@ -16235,13 +16235,11 @@ async def return_unit_metrics(bot, PROJECT_USERNAME, EXTRA_D, BASE_P):
16235
16235
 
16236
16236
  async def return_cohort_metrics(bot, PROJECT_USERNAME, EXTRA_D, BASE_P):
16237
16237
  try:
16238
- # Получаем всех пользователей
16239
16238
  sql = 'SELECT USER_TID, USER_VARS, USER_LSTS FROM "USER"'
16240
16239
  data_users = await db_select_pg(sql, (), BASE_P)
16241
16240
 
16242
- # Собираем для каждого пользователя: месяц входа и набор месяцев активности
16243
- cohorts = defaultdict(set) # cohort_month -> set(USER_TID)
16244
- activity_months = defaultdict(set) # USER_TID -> set месяцов, в которые был DAU
16241
+ cohorts = defaultdict(set)
16242
+ activity_months = defaultdict(set)
16245
16243
 
16246
16244
  months = ["2025-06", "2025-07", "2025-08", "2025-09"]
16247
16245
  data_users = []
@@ -16313,11 +16311,12 @@ async def return_cohort_metrics(bot, PROJECT_USERNAME, EXTRA_D, BASE_P):
16313
16311
  USER_DT = USER_VARS.get("USER_DT", "")
16314
16312
  USER_DAU = USER_LSTS.get("USER_DAU", [])
16315
16313
 
16316
- # вычисляем месяц входа
16314
+ if not USER_DT:
16315
+ continue
16316
+
16317
16317
  entry_mo = datetime.strptime(USER_DT, "%d-%m-%Y_%H-%M-%S").strftime("%Y-%m")
16318
16318
  cohorts[entry_mo].add(USER_TID)
16319
16319
 
16320
- # сохраняем месяцы активности
16321
16320
  for day_str in USER_DAU:
16322
16321
  try:
16323
16322
  mo = datetime.strptime(day_str, "%Y-%m-%d").strftime("%Y-%m")
@@ -16325,10 +16324,8 @@ async def return_cohort_metrics(bot, PROJECT_USERNAME, EXTRA_D, BASE_P):
16325
16324
  except:
16326
16325
  pass
16327
16326
 
16328
- # Список уникальных месяцев cohort, отсортированный
16329
16327
  cohort_months = sorted(cohorts.keys())
16330
16328
 
16331
- # Функция для прибавления месяцев
16332
16329
  def add_months(mo_str, n):
16333
16330
  y, m = map(int, mo_str.split("-"))
16334
16331
  total = m + n
@@ -16337,32 +16334,23 @@ async def return_cohort_metrics(bot, PROJECT_USERNAME, EXTRA_D, BASE_P):
16337
16334
  return f"{new_y:04d}-{new_m:02d}"
16338
16335
 
16339
16336
  num_cohorts = len(cohort_months)
16340
-
16341
- # Формируем таблицу: строки M1..M{num_cohorts}
16342
16337
  table = []
16343
16338
  header = ["Месяц/Когорта"]
16344
- # Добавляем в заголовок каждый cohort + его размер
16345
16339
  for mo in cohort_months:
16346
16340
  header.append(f"{mo} ({len(cohorts[mo])})")
16347
16341
  header.append("∑")
16348
16342
  table.append(header)
16349
16343
 
16350
- # Для каждой строки-месяца кортаций
16344
+ # Собираем саму таблицу
16351
16345
  for i in range(num_cohorts):
16352
16346
  row = [f"M{i+1}"]
16353
16347
  row_sum = 0
16354
- for j, cohort_mo in enumerate(cohort_months):
16355
- # вычисляем целевой месяц = cohort_mo + i месяцев
16348
+ for cohort_mo in cohort_months:
16356
16349
  target_mo = add_months(cohort_mo, i)
16357
16350
  if i == 0:
16358
- # M1 = размер когорты
16359
16351
  val = len(cohorts[cohort_mo])
16360
16352
  else:
16361
- # считаем, сколько пользователей из когорты были активны в target_mo
16362
- cnt = 0
16363
- for uid in cohorts[cohort_mo]:
16364
- if target_mo in activity_months.get(uid, set()):
16365
- cnt += 1
16353
+ cnt = sum(1 for uid in cohorts[cohort_mo] if target_mo in activity_months.get(uid, set()))
16366
16354
  val = cnt
16367
16355
  if val:
16368
16356
  row.append(str(val))
@@ -16372,14 +16360,39 @@ async def return_cohort_metrics(bot, PROJECT_USERNAME, EXTRA_D, BASE_P):
16372
16360
  row.append(str(row_sum))
16373
16361
  table.append(row)
16374
16362
 
16363
+ # Считаем общий отток по всем когортам
16364
+ total_lost = 0
16365
+ total_start = 0
16366
+ for cohort_mo in cohort_months:
16367
+ counts = []
16368
+ for i in range(num_cohorts):
16369
+ target_mo = add_months(cohort_mo, i)
16370
+ if i == 0:
16371
+ count = len(cohorts[cohort_mo])
16372
+ else:
16373
+ count = sum(1 for uid in cohorts[cohort_mo] if target_mo in activity_months.get(uid, set()))
16374
+ counts.append(count)
16375
+ for k in range(len(counts) - 1):
16376
+ start_cnt = counts[k]
16377
+ next_cnt = counts[k + 1]
16378
+ if start_cnt > 0:
16379
+ lost = start_cnt - next_cnt
16380
+ total_lost += lost
16381
+ total_start += start_cnt
16382
+
16383
+ avg_churn = (total_lost / total_start * 100) if total_start else 0
16384
+
16375
16385
  path = os.path.join(EXTRA_D, "3_cohort_metrics.csv")
16376
16386
  with open(path, "w", newline="", encoding="utf-8") as f:
16377
16387
  writer = csv.writer(f)
16378
16388
  for r in table:
16379
16389
  writer.writerow(r)
16390
+ writer.writerow([])
16391
+ writer.writerow([f"Avg monthly cohort churn: {avg_churn:.2f}%"])
16380
16392
 
16381
16393
  thumb = types.FSInputFile(os.path.join(EXTRA_D, "parse.jpg"))
16382
16394
  await bot.send_document(chat_id=my_tid, document=types.FSInputFile(path), thumbnail=thumb)
16395
+
16383
16396
  except Exception as e:
16384
16397
  logger.info(log_ % str(e))
16385
16398
  await asyncio.sleep(round(random.uniform(0, 1), 2))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: yeref
3
- Version: 0.24.65
3
+ Version: 0.24.67
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=rVaQc_Ol1gmoBs8HxywCSu--0yxBYRZzgDiNAp6MGE8,1052940
5
+ yeref-0.24.67.dist-info/METADATA,sha256=0Knh7gq-jz47tplBHpMdEYsEPZogwk3Wf1Bg6BXAQrA,119
6
+ yeref-0.24.67.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
7
+ yeref-0.24.67.dist-info/top_level.txt,sha256=yCQKchWHbfV-3OuQPYRdi2loypD-nmbDJbtt3OuKKkY,6
8
+ yeref-0.24.67.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=fze5I1x5ZD0D4OgYpK1sv-bDgu2RXtMGPhDwjiwBa64,1053049
5
- yeref-0.24.65.dist-info/METADATA,sha256=Q5AZlJwo8T2kw62j1kSn8eFMPG3O6DBs7KoKHmLDWYo,119
6
- yeref-0.24.65.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
7
- yeref-0.24.65.dist-info/top_level.txt,sha256=yCQKchWHbfV-3OuQPYRdi2loypD-nmbDJbtt3OuKKkY,6
8
- yeref-0.24.65.dist-info/RECORD,,