yeref 0.24.66__tar.gz → 0.24.68__tar.gz

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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: yeref
3
- Version: 0.24.66
3
+ Version: 0.24.68
4
4
  Summary: desc-f
5
5
  Author: john smith
6
6
  Dynamic: author
@@ -2,7 +2,7 @@ from setuptools import setup
2
2
 
3
3
  setup(
4
4
  name='yeref',
5
- version='0.24.66',
5
+ version='0.24.68',
6
6
  description='desc-f',
7
7
  author='john smith',
8
8
  packages=['yeref'],
@@ -16238,6 +16238,71 @@ async def return_cohort_metrics(bot, PROJECT_USERNAME, EXTRA_D, BASE_P):
16238
16238
  sql = 'SELECT USER_TID, USER_VARS, USER_LSTS FROM "USER"'
16239
16239
  data_users = await db_select_pg(sql, (), BASE_P)
16240
16240
 
16241
+ months = ["2025-06", "2025-07", "2025-08", "2025-09"]
16242
+ data_users = []
16243
+ for _ in range(20):
16244
+ # дата входа
16245
+ entry_month = random.choice(months)
16246
+ entry_day = random.randint(1, 28)
16247
+ entry_date = f"{entry_month}-{entry_day:02}"
16248
+ entry_dt_obj = datetime.strptime(entry_date, '%Y-%m-%d')
16249
+ entry_dt = f"{entry_dt_obj.strftime('%d-%m-%Y')}_{datetime.now().strftime('%H-%M-%S')}"
16250
+ utm = random.choice(["/start", "/startapp"])
16251
+
16252
+ # месяцы от входа и дальше
16253
+ valid_months = [m for m in months if datetime.strptime(m + "-01", "%Y-%m-%d") >= entry_dt_obj.replace(day=1)]
16254
+ if not valid_months:
16255
+ valid_months = [entry_month]
16256
+
16257
+ user_mau = sorted(random.sample(valid_months, k=random.randint(1, len(valid_months))))
16258
+ user_dau_dates = set()
16259
+ txs, payments = [], []
16260
+
16261
+ # платеж
16262
+ if user_mau:
16263
+ pay_month = random.choice(user_mau)
16264
+ pay_day = random.randint(1, 28)
16265
+ pay_date = f"{pay_month}-{pay_day:02}"
16266
+ dt_pay = datetime.strptime(pay_date, "%Y-%m-%d")
16267
+ # if dt_pay >= entry_dt_obj:
16268
+ payments = [{
16269
+ "TYPE": random.choice(["don", "sub", "pst"]),
16270
+ "DT_START": f"{dt_pay.strftime('%d-%m-%Y')}_14-00-00",
16271
+ "DT_END": "0",
16272
+ "AMOUNT": str(random.randint(1, 10))
16273
+ }]
16274
+ user_dau_dates.add(pay_date)
16275
+
16276
+ # вход в приложение
16277
+ user_dau_dates.add(entry_date)
16278
+ for m in user_mau:
16279
+ day = random.randint(1, 28)
16280
+ visit = f"{m}-{day:02}"
16281
+ dt_visit = datetime.strptime(visit, "%Y-%m-%d")
16282
+ if dt_visit >= entry_dt_obj and random.random() < 0.7:
16283
+ user_dau_dates.add(visit)
16284
+
16285
+ # статусы (отток) с низкой вероятностью
16286
+ USER_STATUSES = []
16287
+ if random.random() < 0.2: # 10% шанс оттока
16288
+ churn_month = random.choice(valid_months)
16289
+ churn_day = random.randint(1, 28)
16290
+ churn_date = f"{churn_month}-{churn_day:02}"
16291
+ churn_ts = datetime.strptime(churn_date, "%Y-%m-%d").strftime("%d-%m-%Y") + "_23-59-59"
16292
+ USER_STATUSES = [{random.choice(["left", "kicked"]): churn_ts}]
16293
+
16294
+ user_dau = sorted(user_dau_dates)
16295
+ wallet = f"wallet{random.randint(1, 100)}" if txs else random.choice([f"wallet{random.randint(1, 100)}", ""])
16296
+
16297
+ data_users.append((
16298
+ random.randint(100000, 999999),
16299
+ json.dumps({"USER_WALLET": wallet, "USER_UTM": utm, "USER_DT": entry_dt}),
16300
+ json.dumps({"USER_DAU": user_dau, "USER_MAU": user_mau, "USER_TXS": txs,
16301
+ "USER_PAYMENTS": payments, "USER_STATUSES": USER_STATUSES})
16302
+ ))
16303
+ print(f"gen {data_users=}")
16304
+
16305
+
16241
16306
  cohorts = defaultdict(set)
16242
16307
  activity_months = defaultdict(set)
16243
16308
 
@@ -16261,6 +16326,7 @@ async def return_cohort_metrics(bot, PROJECT_USERNAME, EXTRA_D, BASE_P):
16261
16326
  pass
16262
16327
 
16263
16328
  cohort_months = sorted(cohorts.keys())
16329
+ num_months = len(cohort_months)
16264
16330
 
16265
16331
  def add_months(mo_str, n):
16266
16332
  y, m = map(int, mo_str.split("-"))
@@ -16269,7 +16335,7 @@ async def return_cohort_metrics(bot, PROJECT_USERNAME, EXTRA_D, BASE_P):
16269
16335
  new_m = (total - 1) % 12 + 1
16270
16336
  return f"{new_y:04d}-{new_m:02d}"
16271
16337
 
16272
- num_cohorts = len(cohort_months)
16338
+ # Собираем таблицу посменно по календарным месяцам
16273
16339
  table = []
16274
16340
  header = ["Месяц/Когорта"]
16275
16341
  for mo in cohort_months:
@@ -16277,40 +16343,44 @@ async def return_cohort_metrics(bot, PROJECT_USERNAME, EXTRA_D, BASE_P):
16277
16343
  header.append("∑")
16278
16344
  table.append(header)
16279
16345
 
16280
- # Собираем саму таблицу
16281
- for i in range(num_cohorts):
16346
+ # Матрица для подсчёта retention (counts[i][j] = активных из когорты j в календарном месяце i)
16347
+ counts = [[0] * num_months for _ in range(num_months)]
16348
+ for i in range(num_months):
16349
+ calendar_mo = cohort_months[i]
16282
16350
  row = [f"M{i+1}"]
16283
16351
  row_sum = 0
16284
- for cohort_mo in cohort_months:
16285
- target_mo = add_months(cohort_mo, i)
16286
- if i == 0:
16352
+
16353
+ for j in range(num_months):
16354
+ if j > i:
16355
+ row.append("")
16356
+ continue
16357
+
16358
+ cohort_mo = cohort_months[j]
16359
+ if i == j:
16360
+ # первый месяц когорты
16287
16361
  val = len(cohorts[cohort_mo])
16288
16362
  else:
16289
- cnt = sum(1 for uid in cohorts[cohort_mo] if target_mo in activity_months.get(uid, set()))
16290
- val = cnt
16363
+ # считаем, сколько из когорты j активны в календарном месяце i
16364
+ val = sum(1 for uid in cohorts[cohort_mo] if calendar_mo in activity_months.get(uid, set()))
16365
+
16366
+ counts[i][j] = val
16291
16367
  if val:
16292
16368
  row.append(str(val))
16293
16369
  row_sum += val
16294
16370
  else:
16295
16371
  row.append("")
16372
+
16296
16373
  row.append(str(row_sum))
16297
16374
  table.append(row)
16298
16375
 
16299
- # Считаем общий отток по всем когортам
16376
+ # Считаем средний ежемесячный churn
16300
16377
  total_lost = 0
16301
16378
  total_start = 0
16302
- for cohort_mo in cohort_months:
16303
- counts = []
16304
- for i in range(num_cohorts):
16305
- target_mo = add_months(cohort_mo, i)
16306
- if i == 0:
16307
- count = len(cohorts[cohort_mo])
16308
- else:
16309
- count = sum(1 for uid in cohorts[cohort_mo] if target_mo in activity_months.get(uid, set()))
16310
- counts.append(count)
16311
- for k in range(len(counts) - 1):
16312
- start_cnt = counts[k]
16313
- next_cnt = counts[k + 1]
16379
+ for j in range(num_months):
16380
+ # для каждой когорты собираем по календарным месяцам
16381
+ for i in range(j, num_months - 1):
16382
+ start_cnt = counts[i][j]
16383
+ next_cnt = counts[i + 1][j]
16314
16384
  if start_cnt > 0:
16315
16385
  lost = start_cnt - next_cnt
16316
16386
  total_lost += lost
@@ -16334,6 +16404,7 @@ async def return_cohort_metrics(bot, PROJECT_USERNAME, EXTRA_D, BASE_P):
16334
16404
  await asyncio.sleep(round(random.uniform(0, 1), 2))
16335
16405
 
16336
16406
 
16407
+
16337
16408
  async def return_retention_metrics(bot, PROJECT_USERNAME, EXTRA_D, BASE_P):
16338
16409
  try:
16339
16410
  sql = 'SELECT USER_TID, USER_VARS, USER_LSTS FROM "USER"'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: yeref
3
- Version: 0.24.66
3
+ Version: 0.24.68
4
4
  Summary: desc-f
5
5
  Author: john smith
6
6
  Dynamic: author
File without changes
File without changes
File without changes
File without changes
File without changes