yeref 0.24.81__py3-none-any.whl → 0.24.83__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
@@ -16393,7 +16393,6 @@ async def return_cohort_metrics(bot, PROJECT_USERNAME, EXTRA_D, BASE_P):
|
|
16393
16393
|
|
16394
16394
|
thumb = types.FSInputFile(os.path.join(EXTRA_D, "parse.jpg"))
|
16395
16395
|
await bot.send_document(chat_id=my_tid, document=types.FSInputFile(path), thumbnail=thumb)
|
16396
|
-
|
16397
16396
|
except Exception as e:
|
16398
16397
|
logger.info(log_ % str(e))
|
16399
16398
|
await asyncio.sleep(round(random.uniform(0, 1), 2))
|
@@ -16554,6 +16553,131 @@ async def return_retention_metrics(bot, PROJECT_USERNAME, EXTRA_D, BASE_P):
|
|
16554
16553
|
await asyncio.sleep(round(random.uniform(0, 1), 2))
|
16555
16554
|
|
16556
16555
|
|
16556
|
+
async def return_profit_and_loss_metrics(bot, PROJECT_USERNAME, EXTRA_D, BASE_P):
|
16557
|
+
try:
|
16558
|
+
sql = 'SELECT USER_LSTS FROM "USER"'
|
16559
|
+
data_users = await db_select_pg(sql, (), BASE_P)
|
16560
|
+
|
16561
|
+
months = ["2025-06", "2025-07", "2025-08", "2025-09"]
|
16562
|
+
data_users = []
|
16563
|
+
for _ in range(30):
|
16564
|
+
# дата входа
|
16565
|
+
entry_month = random.choice(months)
|
16566
|
+
entry_day = random.randint(1, 28)
|
16567
|
+
entry_date = f"{entry_month}-{entry_day:02}"
|
16568
|
+
entry_dt_obj = datetime.strptime(entry_date, '%Y-%m-%d')
|
16569
|
+
entry_dt = f"{entry_dt_obj.strftime('%d-%m-%Y')}_{datetime.now().strftime('%H-%M-%S')}"
|
16570
|
+
utm = random.choice(["/start", "/startapp"])
|
16571
|
+
|
16572
|
+
# месяцы от входа и дальше
|
16573
|
+
valid_months = [m for m in months if datetime.strptime(m + "-01", "%Y-%m-%d") >= entry_dt_obj.replace(day=1)]
|
16574
|
+
if not valid_months:
|
16575
|
+
valid_months = [entry_month]
|
16576
|
+
|
16577
|
+
user_mau = sorted(random.sample(valid_months, k=random.randint(1, len(valid_months))))
|
16578
|
+
user_dau_dates = set()
|
16579
|
+
txs, payments = [], []
|
16580
|
+
|
16581
|
+
# платеж
|
16582
|
+
if user_mau:
|
16583
|
+
pay_month = random.choice(user_mau)
|
16584
|
+
pay_day = random.randint(1, 28)
|
16585
|
+
pay_date = f"{pay_month}-{pay_day:02}"
|
16586
|
+
dt_pay = datetime.strptime(pay_date, "%Y-%m-%d")
|
16587
|
+
# if dt_pay >= entry_dt_obj:
|
16588
|
+
payments = [{
|
16589
|
+
"TYPE": random.choice(["don", "sub", "pst"]),
|
16590
|
+
"DT_START": f"{dt_pay.strftime('%d-%m-%Y')}_14-00-00",
|
16591
|
+
"DT_END": "0",
|
16592
|
+
"AMOUNT": str(random.randint(1, 10))
|
16593
|
+
}]
|
16594
|
+
user_dau_dates.add(pay_date)
|
16595
|
+
|
16596
|
+
# вход в приложение
|
16597
|
+
user_dau_dates.add(entry_date)
|
16598
|
+
for m in user_mau:
|
16599
|
+
day = random.randint(1, 28)
|
16600
|
+
visit = f"{m}-{day:02}"
|
16601
|
+
dt_visit = datetime.strptime(visit, "%Y-%m-%d")
|
16602
|
+
if dt_visit >= entry_dt_obj and random.random() < 0.7:
|
16603
|
+
user_dau_dates.add(visit)
|
16604
|
+
|
16605
|
+
# статусы (отток) с низкой вероятностью
|
16606
|
+
USER_STATUSES = []
|
16607
|
+
if random.random() < 0.2: # 10% шанс оттока
|
16608
|
+
churn_month = random.choice(valid_months)
|
16609
|
+
churn_day = random.randint(1, 28)
|
16610
|
+
churn_date = f"{churn_month}-{churn_day:02}"
|
16611
|
+
churn_ts = datetime.strptime(churn_date, "%Y-%m-%d").strftime("%d-%m-%Y") + "_23-59-59"
|
16612
|
+
USER_STATUSES = [{random.choice(["left", "kicked"]): churn_ts}]
|
16613
|
+
|
16614
|
+
user_dau = sorted(user_dau_dates)
|
16615
|
+
wallet = f"wallet{random.randint(1, 100)}" if txs else random.choice([f"wallet{random.randint(1, 100)}", ""])
|
16616
|
+
|
16617
|
+
data_users.append((
|
16618
|
+
random.randint(100000, 999999),
|
16619
|
+
json.dumps({"USER_WALLET": wallet, "USER_UTM": utm, "USER_DT": entry_dt}),
|
16620
|
+
json.dumps({"USER_DAU": user_dau, "USER_MAU": user_mau, "USER_TXS": txs,
|
16621
|
+
"USER_PAYMENTS": payments, "USER_STATUSES": USER_STATUSES})
|
16622
|
+
))
|
16623
|
+
print(f"gen {data_users=}")
|
16624
|
+
|
16625
|
+
metrics = defaultdict(lambda: {"sum_amount": 0.0})
|
16626
|
+
|
16627
|
+
for (USER_LSTS,) in data_users:
|
16628
|
+
USER_LSTS = json.loads(USER_LSTS or "{}")
|
16629
|
+
USER_PAYMENTS = USER_LSTS.get("USER_PAYMENTS", [])
|
16630
|
+
|
16631
|
+
for pay in USER_PAYMENTS:
|
16632
|
+
dt_p = datetime.strptime(pay.get("DT_START", ""), "%d-%m-%Y_%H-%M-%S")
|
16633
|
+
mo_p = dt_p.strftime("%Y-%m")
|
16634
|
+
amt = float(pay.get("AMOUNT", 0)) * 0.013
|
16635
|
+
metrics[mo_p]["sum_amount"] += amt
|
16636
|
+
|
16637
|
+
def fmt(x):
|
16638
|
+
return f"{x:.2f}".rstrip("0").rstrip(".")
|
16639
|
+
|
16640
|
+
months_sorted = sorted(metrics.keys())
|
16641
|
+
results = []
|
16642
|
+
|
16643
|
+
for mo in months_sorted:
|
16644
|
+
MRR = metrics[mo]["sum_amount"]
|
16645
|
+
COGS = 0.0
|
16646
|
+
GP = MRR - COGS
|
16647
|
+
OPEX = 4.5
|
16648
|
+
OP = GP - OPEX
|
16649
|
+
COMM = MRR * 0.3
|
16650
|
+
EXCH = MRR * 0.01
|
16651
|
+
NP = OP - COMM - EXCH
|
16652
|
+
|
16653
|
+
results.append([
|
16654
|
+
mo.upper()[5:] + "_" + mo[:4], # Format to "JUN_2024"
|
16655
|
+
fmt(MRR),
|
16656
|
+
fmt(COGS),
|
16657
|
+
fmt(GP),
|
16658
|
+
fmt(OPEX),
|
16659
|
+
fmt(OP),
|
16660
|
+
fmt(COMM),
|
16661
|
+
fmt(EXCH),
|
16662
|
+
fmt(NP)
|
16663
|
+
])
|
16664
|
+
|
16665
|
+
path = os.path.join(EXTRA_D, "4_profit_and_loss_metrics.csv")
|
16666
|
+
with open(path, "w", newline="", encoding="utf-8") as f:
|
16667
|
+
writer = csv.writer(f)
|
16668
|
+
writer.writerow([
|
16669
|
+
"Месяц", "Total MRR", "COGS", "Валовая прибыль",
|
16670
|
+
"OPEX", "Операционная прибыль", "Комиссия (30%)", "Обмен (1%)", "Чистая прибыль"
|
16671
|
+
])
|
16672
|
+
for row in results:
|
16673
|
+
writer.writerow(row)
|
16674
|
+
|
16675
|
+
thumb = types.FSInputFile(os.path.join(EXTRA_D, "parse.jpg"))
|
16676
|
+
await bot.send_document(chat_id=my_tid, document=types.FSInputFile(path), thumbnail=thumb)
|
16677
|
+
except Exception as e:
|
16678
|
+
logger.info(log_ % str(e))
|
16679
|
+
await asyncio.sleep(round(random.uniform(0, 1), 2))
|
16680
|
+
|
16557
16681
|
# endregion
|
16558
16682
|
|
16559
16683
|
|
@@ -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=nJ6rdm48zUuPL6BASNz2AIuXvl8roUZUKKzvT35c-34,1059485
|
5
|
+
yeref-0.24.83.dist-info/METADATA,sha256=lgEfz7ThZG23_FKSDxgODYeQ2IP4zt2IO1nmSswMR1o,119
|
6
|
+
yeref-0.24.83.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
7
|
+
yeref-0.24.83.dist-info/top_level.txt,sha256=yCQKchWHbfV-3OuQPYRdi2loypD-nmbDJbtt3OuKKkY,6
|
8
|
+
yeref-0.24.83.dist-info/RECORD,,
|
yeref-0.24.81.dist-info/RECORD
DELETED
@@ -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=sgMrikx-YvtjWBcqRUbOeaLfQBv1VdGwKW5sv_wB_Bs,1054158
|
5
|
-
yeref-0.24.81.dist-info/METADATA,sha256=XUNjT5Tqo26_s0vgpOrskCz_uCGAThY3cSJ_T7WaOOc,119
|
6
|
-
yeref-0.24.81.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
7
|
-
yeref-0.24.81.dist-info/top_level.txt,sha256=yCQKchWHbfV-3OuQPYRdi2loypD-nmbDJbtt3OuKKkY,6
|
8
|
-
yeref-0.24.81.dist-info/RECORD,,
|
File without changes
|
File without changes
|