Compare commits
No commits in common. "main" and "master" have entirely different histories.
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
.venv/
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
.vs/
|
||||||
|
reports/*.txt
|
||||||
|
*.backup.json
|
||||||
1
requirements.txt
Normal file
1
requirements.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
# Нет внешних зависимостей, только стандартная библиотека
|
||||||
6
транзакции интернет банка/.gitignore
vendored
Normal file
6
транзакции интернет банка/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
.venv/
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
.vs/
|
||||||
|
*.user
|
||||||
|
*.suo
|
||||||
417
транзакции интернет банка/bank_transactions.py
Normal file
417
транзакции интернет банка/bank_transactions.py
Normal file
@ -0,0 +1,417 @@
|
|||||||
|
import json
|
||||||
|
import sys
|
||||||
|
from datetime import datetime
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
|
|
||||||
|
def zagruzit_tranzaktsii(filepath):
|
||||||
|
transaktsii = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(filepath, 'r', encoding='utf-8') as f:
|
||||||
|
for num, line in enumerate(f, 1):
|
||||||
|
line = line.strip()
|
||||||
|
if not line:
|
||||||
|
continue
|
||||||
|
|
||||||
|
parts = line.split('|')
|
||||||
|
|
||||||
|
if len(parts) != 7:
|
||||||
|
print(f'Ошибка в строке {num}: ожидается 7 полей, найдено {len(parts)}. Строка: {line[:50]}...', file=sys.stderr)
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
transaktsiya = {
|
||||||
|
'transaction_id': parts[0].strip(),
|
||||||
|
'user_id': int(parts[1].strip()),
|
||||||
|
'amount': float(parts[2].strip()),
|
||||||
|
'category': parts[3].strip(),
|
||||||
|
'timestamp': parts[4].strip(),
|
||||||
|
'is_fraud': parts[5].strip().lower() == 'true',
|
||||||
|
'card_last_digits': parts[6].strip()
|
||||||
|
}
|
||||||
|
transaktsii.append(transaktsiya)
|
||||||
|
except ValueError as e:
|
||||||
|
print(f'Ошибка в строке {num}: неверный тип данных - {e}', file=sys.stderr)
|
||||||
|
continue
|
||||||
|
|
||||||
|
except FileNotFoundError:
|
||||||
|
print(f'Файл {filepath} не найден', file=sys.stderr)
|
||||||
|
return []
|
||||||
|
except Exception as e:
|
||||||
|
print(f'Ошибка при чтении файла: {e}', file=sys.stderr)
|
||||||
|
return []
|
||||||
|
|
||||||
|
return transaktsii
|
||||||
|
|
||||||
|
|
||||||
|
def filtr_po_kategorii(transaktsii, kategorii):
|
||||||
|
resultat = []
|
||||||
|
kategorii_nizhnij = [kat.lower() for kat in kategorii]
|
||||||
|
|
||||||
|
for t in transaktsii:
|
||||||
|
if t.get('category', '').lower() in kategorii_nizhnij:
|
||||||
|
resultat.append(t)
|
||||||
|
return resultat
|
||||||
|
|
||||||
|
|
||||||
|
def filtr_po_summe(transaktsii, min_summa, max_summa):
|
||||||
|
otfiltrovannye = []
|
||||||
|
for t in transaktsii:
|
||||||
|
summa = t.get('amount', 0)
|
||||||
|
if min_summa <= summa <= max_summa:
|
||||||
|
otfiltrovannye.append(t)
|
||||||
|
return otfiltrovannye
|
||||||
|
|
||||||
|
|
||||||
|
def filtr_moshennicheskih(transaktsii):
|
||||||
|
moshenniki = []
|
||||||
|
for t in transaktsii:
|
||||||
|
if t.get('is_fraud') == True:
|
||||||
|
moshenniki.append(t)
|
||||||
|
|
||||||
|
#сорт по убыванию суммы
|
||||||
|
moshenniki.sort(key=lambda x: x.get('amount', 0), reverse=True)
|
||||||
|
return moshenniki
|
||||||
|
|
||||||
|
|
||||||
|
def rassch_traty_po_kategoriyam(transaktsii, id_polzovatelya):
|
||||||
|
traty = {}
|
||||||
|
|
||||||
|
for t in transaktsii:
|
||||||
|
if t.get('user_id') == id_polzovatelya and t.get('is_fraud') == False:
|
||||||
|
kat = t.get('category', 'Другое')
|
||||||
|
summa = t.get('amount', 0)
|
||||||
|
|
||||||
|
if kat in traty:
|
||||||
|
traty[kat] += summa
|
||||||
|
else:
|
||||||
|
traty[kat] = summa
|
||||||
|
|
||||||
|
return traty
|
||||||
|
|
||||||
|
|
||||||
|
def top_kategorii(transaktsii, n):
|
||||||
|
summy_kategorij = {}
|
||||||
|
|
||||||
|
for t in transaktsii:
|
||||||
|
kat = t.get('category', 'Другое')
|
||||||
|
summa = t.get('amount', 0)
|
||||||
|
|
||||||
|
if kat in summy_kategorij:
|
||||||
|
summy_kategorij[kat] += summa
|
||||||
|
else:
|
||||||
|
summy_kategorij[kat] = summa
|
||||||
|
|
||||||
|
#список пар сортировк
|
||||||
|
elementy = list(summy_kategorij.items())
|
||||||
|
elementy.sort(key=lambda x: x[1], reverse=True)
|
||||||
|
|
||||||
|
return elementy[:n]
|
||||||
|
|
||||||
|
|
||||||
|
def obnaruzhit_podozritelnye(transaktsii, id_polzovatelya, porog):
|
||||||
|
traty_polzovatelya = []
|
||||||
|
for t in transaktsii:
|
||||||
|
if t.get('user_id') == id_polzovatelya and t.get('is_fraud') == False:
|
||||||
|
traty_polzovatelya.append(t)
|
||||||
|
|
||||||
|
if len(traty_polzovatelya) < 3:
|
||||||
|
return []
|
||||||
|
|
||||||
|
vsego = 0
|
||||||
|
for t in traty_polzovatelya:
|
||||||
|
vsego += t.get('amount', 0)
|
||||||
|
srednyaya = vsego / len(traty_polzovatelya)
|
||||||
|
|
||||||
|
porogovoe_znachenie = srednyaya * porog
|
||||||
|
podozritelnye = []
|
||||||
|
for t in traty_polzovatelya:
|
||||||
|
if t.get('amount', 0) > porogovoe_znachenie:
|
||||||
|
podozritelnye.append(t)
|
||||||
|
|
||||||
|
# убыван суммы
|
||||||
|
podozritelnye.sort(key=lambda x: x.get('amount', 0), reverse=True)
|
||||||
|
return podozritelnye
|
||||||
|
|
||||||
|
|
||||||
|
def gruppirovat_po_dnyam(transaktsii):
|
||||||
|
dni = {}
|
||||||
|
|
||||||
|
for t in transaktsii:
|
||||||
|
|
||||||
|
ts = t.get('timestamp', '')
|
||||||
|
if ts:
|
||||||
|
data = ts.split()[0]
|
||||||
|
else:
|
||||||
|
data = '1970-01-01'
|
||||||
|
|
||||||
|
summa = t.get('amount', 0)
|
||||||
|
|
||||||
|
if data not in dni:
|
||||||
|
dni[data] = {
|
||||||
|
'total_amount': 0.0,
|
||||||
|
'transaction_count': 0,
|
||||||
|
'avg_amount': 0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
dni[data]['total_amount'] += summa
|
||||||
|
dni[data]['transaction_count'] += 1
|
||||||
|
|
||||||
|
# среднее дня
|
||||||
|
for data in dni:
|
||||||
|
kolvo = dni[data]['transaction_count']
|
||||||
|
if kolvo > 0:
|
||||||
|
dni[data]['avg_amount'] = dni[data]['total_amount'] / kolvo
|
||||||
|
|
||||||
|
return dni
|
||||||
|
|
||||||
|
|
||||||
|
def gruppirovat_po_polzovatelyam(transaktsii):
|
||||||
|
polzovateli = {}
|
||||||
|
|
||||||
|
for t in transaktsii:
|
||||||
|
uid = t.get('user_id')
|
||||||
|
if uid is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if uid not in polzovateli:
|
||||||
|
polzovateli[uid] = []
|
||||||
|
|
||||||
|
polzovateli[uid].append(t)
|
||||||
|
|
||||||
|
# сорт по времени
|
||||||
|
for uid in polzovateli:
|
||||||
|
polzovateli[uid].sort(key=lambda x: x.get('timestamp', '1970-01-01 00:00:00'))
|
||||||
|
|
||||||
|
return polzovateli
|
||||||
|
|
||||||
|
|
||||||
|
def sozdat_otchet(transaktsii, output_file):
|
||||||
|
try:
|
||||||
|
vsego_tranzaktsij = len(transaktsii)
|
||||||
|
vsego_summa = 0
|
||||||
|
moshen_tranzaktsij = 0
|
||||||
|
moshen_summa = 0
|
||||||
|
|
||||||
|
for t in transaktsii:
|
||||||
|
summa = t.get('amount', 0)
|
||||||
|
vsego_summa += summa
|
||||||
|
|
||||||
|
if t.get('is_fraud'):
|
||||||
|
moshen_tranzaktsij += 1
|
||||||
|
moshen_summa += summa
|
||||||
|
|
||||||
|
obych_tranzaktsij = vsego_tranzaktsij - moshen_tranzaktsij
|
||||||
|
obych_summa = vsego_summa - moshen_summa
|
||||||
|
|
||||||
|
top_kategorij = top_kategorii(transaktsii, 5)
|
||||||
|
|
||||||
|
kolvo_po_polzovatelyam = {}
|
||||||
|
for t in transaktsii:
|
||||||
|
uid = t.get('user_id')
|
||||||
|
if uid:
|
||||||
|
kolvo_po_polzovatelyam[uid] = kolvo_po_polzovatelyam.get(uid, 0) + 1
|
||||||
|
|
||||||
|
top_polzovateli = sorted(kolvo_po_polzovatelyam.items(), key=lambda x: x[1], reverse=True)[:3]
|
||||||
|
|
||||||
|
unikalnye_polzovateli = len(set([t.get('user_id') for t in transaktsii if t.get('user_id')]))
|
||||||
|
|
||||||
|
po_dnyam = gruppirovat_po_dnyam(transaktsii)
|
||||||
|
pervye_7_dnej = dict(list(po_dnyam.items())[:7])
|
||||||
|
|
||||||
|
otchet = []
|
||||||
|
otchet.append('=' * 60)
|
||||||
|
otchet.append('ФИНАНСОВЫЙ ОТЧЕТ')
|
||||||
|
otchet.append('=' * 60)
|
||||||
|
otchet.append('')
|
||||||
|
otchet.append(f'Всего транзакций: {vsego_tranzaktsij}')
|
||||||
|
otchet.append(f'Общая сумма: {vsego_summa:,.2f} руб.')
|
||||||
|
otchet.append('')
|
||||||
|
otchet.append('Обычные транзакции:')
|
||||||
|
otchet.append(f' Количество: {obych_tranzaktsij}')
|
||||||
|
otchet.append(f' Сумма: {obych_summa:,.2f} руб.')
|
||||||
|
otchet.append('')
|
||||||
|
otchet.append('Мошеннические транзакции:')
|
||||||
|
otchet.append(f' Количество: {moshen_tranzaktsij}')
|
||||||
|
otchet.append(f' Сумма: {moshen_summa:,.2f} руб.')
|
||||||
|
otchet.append('')
|
||||||
|
otchet.append('ТОП-5 КАТЕГОРИЙ ПО ТРАТАМ:')
|
||||||
|
|
||||||
|
for i, (kat, summa) in enumerate(top_kategorij, 1):
|
||||||
|
otchet.append(f' {i}. {kat}: {summa:,.2f} руб.')
|
||||||
|
|
||||||
|
otchet.append('')
|
||||||
|
otchet.append('ТОП-3 ПОЛЬЗОВАТЕЛЯ ПО КОЛИЧЕСТВУ ТРАНЗАКЦИЙ:')
|
||||||
|
|
||||||
|
for i, (uid, kol) in enumerate(top_polzovateli, 1):
|
||||||
|
otchet.append(f' {i}. Пользователь {uid}: {kol} транзакций')
|
||||||
|
|
||||||
|
otchet.append('')
|
||||||
|
otchet.append(f'Уникальных пользователей: {unikalnye_polzovateli}')
|
||||||
|
otchet.append('')
|
||||||
|
otchet.append('СТАТИСТИКА ПО ДНЯМ (первые 7 дней):')
|
||||||
|
|
||||||
|
for data in sorted(pervye_7_dnej.keys()):
|
||||||
|
stat = pervye_7_dnej[data]
|
||||||
|
otchet.append(f' {data}:')
|
||||||
|
otchet.append(f' Сумма: {stat["total_amount"]:,.2f} руб.')
|
||||||
|
otchet.append(f' Кол-во: {stat["transaction_count"]}')
|
||||||
|
otchet.append(f' Средний чек: {stat["avg_amount"]:,.2f} руб.')
|
||||||
|
|
||||||
|
otchet.append('')
|
||||||
|
otchet.append('=' * 60)
|
||||||
|
|
||||||
|
# сохран
|
||||||
|
with open(output_file, 'w', encoding='utf-8') as f:
|
||||||
|
f.write('\n'.join(otchet))
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f'Ошибка при сохранении отчета: {e}', file=sys.stderr)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print('Запуск программы анализа транзакций...')
|
||||||
|
print('-' * 50)
|
||||||
|
|
||||||
|
transaktsii = zagruzit_tranzaktsii('data.txt')
|
||||||
|
|
||||||
|
if not transaktsii:
|
||||||
|
print('Не удалось загрузить транзакции. Программа завершена.')
|
||||||
|
print('\nФайл data.txt должен содержать строки в формате:')
|
||||||
|
print('ID_транзакции|ID_пользователя|Сумма|Категория|Время|is_fraud|Последние_4_цифры')
|
||||||
|
print('Пример:')
|
||||||
|
print('tx001|1|1500.50|Продукты|2024-01-15 10:30:00|False|1234')
|
||||||
|
return
|
||||||
|
|
||||||
|
print(f'Загружено транзакций: {len(transaktsii)}')
|
||||||
|
|
||||||
|
kategorii = ['Продукты', 'Кафе', 'Транспорт']
|
||||||
|
otfiltrovannye_po_kat = filtr_po_kategorii(transaktsii, kategorii)
|
||||||
|
print(f'После фильтрации по категориям {kategorii}: {len(otfiltrovannye_po_kat)} транзакций')
|
||||||
|
|
||||||
|
otfiltrovannye_po_summe = filtr_po_summe(otfiltrovannye_po_kat, 500, 5000)
|
||||||
|
print(f'После фильтрации по сумме (500-5000 руб.): {len(otfiltrovannye_po_summe)} транзакций')
|
||||||
|
|
||||||
|
moshenniki = filtr_moshennicheskih(transaktsii)
|
||||||
|
summa_moshennikov = sum(t.get('amount', 0) for t in moshenniki)
|
||||||
|
|
||||||
|
print(f'\nМошеннических транзакций: {len(moshenniki)}')
|
||||||
|
print(f'Общая сумма мошеннических транзакций: {summa_moshennikov:,.2f} руб.')
|
||||||
|
|
||||||
|
if moshenniki:
|
||||||
|
print('\nТоп-3 мошеннических транзакции по сумме:')
|
||||||
|
for i, t in enumerate(moshenniki[:3], 1):
|
||||||
|
print(f' {i}. ID: {t["transaction_id"]}, Сумма: {t["amount"]} руб., Категория: {t["category"]}')
|
||||||
|
|
||||||
|
if transaktsii:
|
||||||
|
primernyj_polzovatel = transaktsii[0].get('user_id')
|
||||||
|
|
||||||
|
raskhody = rassch_traty_po_kategoriyam(transaktsii, primernyj_polzovatel)
|
||||||
|
print(f'\nРасходы пользователя {primernyj_polzovatel} по категориям:')
|
||||||
|
if raskhody:
|
||||||
|
for kat, summa in raskhody.items():
|
||||||
|
print(f' {kat}: {summa:,.2f} руб.')
|
||||||
|
else:
|
||||||
|
print(' Нет расходов (или все транзакции мошеннические)')
|
||||||
|
|
||||||
|
podozritelnye = obnaruzhit_podozritelnye(transaktsii, primernyj_polzovatel, 1.5)
|
||||||
|
print(f'\nПодозрительно крупные транзакции пользователя {primernyj_polzovatel} (среднее * 1.5):')
|
||||||
|
if podozritelnye:
|
||||||
|
for t in podozritelnye:
|
||||||
|
print(f' {t["timestamp"]}: {t["amount"]} руб. - {t["category"]}')
|
||||||
|
else:
|
||||||
|
print(' Не найдено')
|
||||||
|
|
||||||
|
print('\n' + '=' * 50)
|
||||||
|
print('АГРЕГИРОВАННАЯ СТАТИСТИКА')
|
||||||
|
print('=' * 50)
|
||||||
|
|
||||||
|
top_kat = top_kategorii(transaktsii, 5)
|
||||||
|
print('\nТоп-5 категорий по сумме трат:')
|
||||||
|
for i, (kat, summa) in enumerate(top_kat, 1):
|
||||||
|
print(f' {i}. {kat}: {summa:,.2f} руб.')
|
||||||
|
|
||||||
|
po_dnyam = gruppirovat_po_dnyam(transaktsii)
|
||||||
|
print('\nСтатистика за первые 3 дня:')
|
||||||
|
for i, (data, stat) in enumerate(list(po_dnyam.items())[:3]):
|
||||||
|
print(f' {data}:')
|
||||||
|
print(f' Сумма: {stat["total_amount"]:,.2f} руб.')
|
||||||
|
print(f' Кол-во: {stat["transaction_count"]}')
|
||||||
|
print(f' Средний чек: {stat["avg_amount"]:,.2f} руб.')
|
||||||
|
|
||||||
|
polzovateli_s_tranzaktsiyami = gruppirovat_po_polzovatelyam(transaktsii)
|
||||||
|
kolvo_po_polz = [(uid, len(txs)) for uid, txs in polzovateli_s_tranzaktsiyami.items()]
|
||||||
|
kolvo_po_polz.sort(key=lambda x: x[1], reverse=True)
|
||||||
|
|
||||||
|
print('\nТоп-5 пользователей по количеству транзакций:')
|
||||||
|
for i, (uid, kol) in enumerate(kolvo_po_polz[:5], 1):
|
||||||
|
print(f' {i}. Пользователь {uid}: {kol} транзакций')
|
||||||
|
|
||||||
|
print('\n' + '=' * 50)
|
||||||
|
uspekh = sozdat_otchet(transaktsii, 'financial_report.txt')
|
||||||
|
|
||||||
|
if uspekh:
|
||||||
|
print('Отчет успешно сохранен в файл financial_report.txt')
|
||||||
|
else:
|
||||||
|
print('Ошибка при сохранении отчета')
|
||||||
|
|
||||||
|
print('\n' + '=' * 50)
|
||||||
|
print('ДОПОЛНИТЕЛЬНЫЙ АНАЛИЗ')
|
||||||
|
print('=' * 50)
|
||||||
|
|
||||||
|
moshenniki_po_polz = defaultdict(float)
|
||||||
|
for t in moshenniki:
|
||||||
|
moshenniki_po_polz[t.get('user_id')] += t.get('amount', 0)
|
||||||
|
|
||||||
|
if moshenniki_po_polz:
|
||||||
|
top_moshennik = max(moshenniki_po_polz.items(), key=lambda x: x[1])
|
||||||
|
print(f'\nПользователь с максимальной суммой мошеннических транзакций:')
|
||||||
|
print(f' ID: {top_moshennik[0]}, Сумма: {top_moshennik[1]:,.2f} руб.')
|
||||||
|
|
||||||
|
if po_dnyam:
|
||||||
|
samyy_nagruzhennyy_den = max(po_dnyam.items(), key=lambda x: x[1]['transaction_count'])
|
||||||
|
print(f'\nДень с наибольшим количеством транзакций:')
|
||||||
|
print(f' {samyy_nagruzhennyy_den[0]}: {samyy_nagruzhennyy_den[1]["transaction_count"]} транзакций')
|
||||||
|
|
||||||
|
statistika_po_dnyam_nedeli = defaultdict(lambda: {'vsego': 0, 'kolvo': 0})
|
||||||
|
for t in transaktsii:
|
||||||
|
ts = t.get('timestamp')
|
||||||
|
if ts:
|
||||||
|
try:
|
||||||
|
dt = datetime.strptime(ts.split()[0], '%Y-%m-%d')
|
||||||
|
den_nedeli = dt.strftime('%A')
|
||||||
|
summa = t.get('amount', 0)
|
||||||
|
statistika_po_dnyam_nedeli[den_nedeli]['vsego'] += summa
|
||||||
|
statistika_po_dnyam_nedeli[den_nedeli]['kolvo'] += 1
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if statistika_po_dnyam_nedeli:
|
||||||
|
print('\nСредний чек по дням недели:')
|
||||||
|
poryadok_dnej = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
|
||||||
|
russkie_dni = {
|
||||||
|
'Monday': 'Понедельник',
|
||||||
|
'Tuesday': 'Вторник',
|
||||||
|
'Wednesday': 'Среда',
|
||||||
|
'Thursday': 'Четверг',
|
||||||
|
'Friday': 'Пятница',
|
||||||
|
'Saturday': 'Суббота',
|
||||||
|
'Sunday': 'Воскресенье'
|
||||||
|
}
|
||||||
|
|
||||||
|
for eng_den in poryadok_dnej:
|
||||||
|
if eng_den in statistika_po_dnyam_nedeli:
|
||||||
|
stat = statistika_po_dnyam_nedeli[eng_den]
|
||||||
|
sredniy = stat['vsego'] / stat['kolvo'] if stat['kolvo'] > 0 else 0
|
||||||
|
print(f' {russkie_dni[eng_den]}: {sredniy:,.2f} руб. ({stat["kolvo"]} транзакций)')
|
||||||
|
|
||||||
|
print('\n' + '=' * 50)
|
||||||
|
print('Программа завершена!')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
3
транзакции интернет банка/data.txt
Normal file
3
транзакции интернет банка/data.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
tx001|1|1500.50|Продукты|2024-01-15 10:30:00|False|1234
|
||||||
|
tx002|1|250.00|Кафе|2024-01-15 12:45:00|False|1234
|
||||||
|
tx003|2|5000.00|Электроника|2024-01-15 15:20:00|True|5678
|
||||||
7
транзакции интернет банка/data/report.txt
Normal file
7
транзакции интернет банка/data/report.txt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
=== Отчёт по отзывам ===
|
||||||
|
Общее количество отзывов: 0
|
||||||
|
Средний рейтинг: 0.0
|
||||||
|
|
||||||
|
Топ слов:
|
||||||
|
|
||||||
|
Пользователи:
|
||||||
218
транзакции интернет банка/data/transactions.json
Normal file
218
транзакции интернет банка/data/transactions.json
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"transaction_id": "TXN001",
|
||||||
|
"user_id": 1,
|
||||||
|
"amount": 1250.5,
|
||||||
|
"category": "Products",
|
||||||
|
"timestamp": "2024-01-15 10:30:00",
|
||||||
|
"is_fraud": false,
|
||||||
|
"card_last_digits": "1234"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"transaction_id": "TXN002",
|
||||||
|
"user_id": 1,
|
||||||
|
"amount": 3500.0,
|
||||||
|
"category": "Cafe",
|
||||||
|
"timestamp": "2024-01-15 19:45:00",
|
||||||
|
"is_fraud": false,
|
||||||
|
"card_last_digits": "1234"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"transaction_id": "TXN003",
|
||||||
|
"user_id": 1,
|
||||||
|
"amount": 450.0,
|
||||||
|
"category": "Transport",
|
||||||
|
"timestamp": "2024-01-16 08:15:00",
|
||||||
|
"is_fraud": false,
|
||||||
|
"card_last_digits": "1234"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"transaction_id": "TXN004",
|
||||||
|
"user_id": 1,
|
||||||
|
"amount": 5600.0,
|
||||||
|
"category": "Entertainment",
|
||||||
|
"timestamp": "2024-01-16 20:30:00",
|
||||||
|
"is_fraud": false,
|
||||||
|
"card_last_digits": "1234"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"transaction_id": "TXN005",
|
||||||
|
"user_id": 1,
|
||||||
|
"amount": 2800.0,
|
||||||
|
"category": "Products",
|
||||||
|
"timestamp": "2024-01-17 14:20:00",
|
||||||
|
"is_fraud": false,
|
||||||
|
"card_last_digits": "1234"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"transaction_id": "TXN006",
|
||||||
|
"user_id": 1,
|
||||||
|
"amount": 12500.0,
|
||||||
|
"category": "Entertainment",
|
||||||
|
"timestamp": "2024-01-18 22:00:00",
|
||||||
|
"is_fraud": false,
|
||||||
|
"card_last_digits": "1234"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"transaction_id": "TXN007",
|
||||||
|
"user_id": 2,
|
||||||
|
"amount": 3500.0,
|
||||||
|
"category": "Products",
|
||||||
|
"timestamp": "2024-01-15 12:00:00",
|
||||||
|
"is_fraud": false,
|
||||||
|
"card_last_digits": "5678"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"transaction_id": "TXN008",
|
||||||
|
"user_id": 2,
|
||||||
|
"amount": 15000.0,
|
||||||
|
"category": "Transfers",
|
||||||
|
"timestamp": "2024-01-15 22:15:00",
|
||||||
|
"is_fraud": true,
|
||||||
|
"card_last_digits": "5678"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"transaction_id": "TXN009",
|
||||||
|
"user_id": 2,
|
||||||
|
"amount": 45000.0,
|
||||||
|
"category": "Transfers",
|
||||||
|
"timestamp": "2024-01-16 23:30:00",
|
||||||
|
"is_fraud": true,
|
||||||
|
"card_last_digits": "5678"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"transaction_id": "TXN010",
|
||||||
|
"user_id": 2,
|
||||||
|
"amount": 2800.0,
|
||||||
|
"category": "Cafe",
|
||||||
|
"timestamp": "2024-01-17 13:00:00",
|
||||||
|
"is_fraud": false,
|
||||||
|
"card_last_digits": "5678"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"transaction_id": "TXN011",
|
||||||
|
"user_id": 2,
|
||||||
|
"amount": 32000.0,
|
||||||
|
"category": "Cash Withdrawal",
|
||||||
|
"timestamp": "2024-01-18 09:45:00",
|
||||||
|
"is_fraud": true,
|
||||||
|
"card_last_digits": "5678"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"transaction_id": "TXN012",
|
||||||
|
"user_id": 3,
|
||||||
|
"amount": 800.0,
|
||||||
|
"category": "Transport",
|
||||||
|
"timestamp": "2024-01-15 09:00:00",
|
||||||
|
"is_fraud": false,
|
||||||
|
"card_last_digits": "9012"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"transaction_id": "TXN013",
|
||||||
|
"user_id": 3,
|
||||||
|
"amount": 1200.0,
|
||||||
|
"category": "Products",
|
||||||
|
"timestamp": "2024-01-15 17:30:00",
|
||||||
|
"is_fraud": false,
|
||||||
|
"card_last_digits": "9012"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"transaction_id": "TXN014",
|
||||||
|
"user_id": 3,
|
||||||
|
"amount": 4500.0,
|
||||||
|
"category": "Cafe",
|
||||||
|
"timestamp": "2024-01-16 20:00:00",
|
||||||
|
"is_fraud": false,
|
||||||
|
"card_last_digits": "9012"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"transaction_id": "TXN015",
|
||||||
|
"user_id": 3,
|
||||||
|
"amount": 2300.0,
|
||||||
|
"category": "Products",
|
||||||
|
"timestamp": "2024-01-16 11:15:00",
|
||||||
|
"is_fraud": false,
|
||||||
|
"card_last_digits": "9012"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"transaction_id": "TXN016",
|
||||||
|
"user_id": 3,
|
||||||
|
"amount": 6800.0,
|
||||||
|
"category": "Entertainment",
|
||||||
|
"timestamp": "2024-01-17 21:30:00",
|
||||||
|
"is_fraud": false,
|
||||||
|
"card_last_digits": "9012"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"transaction_id": "TXN017",
|
||||||
|
"user_id": 3,
|
||||||
|
"amount": 950.0,
|
||||||
|
"category": "Transport",
|
||||||
|
"timestamp": "2024-01-18 08:45:00",
|
||||||
|
"is_fraud": false,
|
||||||
|
"card_last_digits": "9012"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"transaction_id": "TXN018",
|
||||||
|
"user_id": 4,
|
||||||
|
"amount": 5800.0,
|
||||||
|
"category": "Utilities",
|
||||||
|
"timestamp": "2024-01-15 14:20:00",
|
||||||
|
"is_fraud": false,
|
||||||
|
"card_last_digits": "3456"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"transaction_id": "TXN019",
|
||||||
|
"user_id": 4,
|
||||||
|
"amount": 4200.0,
|
||||||
|
"category": "Products",
|
||||||
|
"timestamp": "2024-01-16 16:45:00",
|
||||||
|
"is_fraud": false,
|
||||||
|
"card_last_digits": "3456"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"transaction_id": "TXN020",
|
||||||
|
"user_id": 4,
|
||||||
|
"amount": 18500.0,
|
||||||
|
"category": "Transfers",
|
||||||
|
"timestamp": "2024-01-17 11:30:00",
|
||||||
|
"is_fraud": false,
|
||||||
|
"card_last_digits": "3456"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"transaction_id": "TXN021",
|
||||||
|
"user_id": 5,
|
||||||
|
"amount": 3200.0,
|
||||||
|
"category": "Cafe",
|
||||||
|
"timestamp": "2024-01-15 12:30:00",
|
||||||
|
"is_fraud": false,
|
||||||
|
"card_last_digits": "7890"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"transaction_id": "TXN022",
|
||||||
|
"user_id": 5,
|
||||||
|
"amount": 1500.0,
|
||||||
|
"category": "Transport",
|
||||||
|
"timestamp": "2024-01-16 18:20:00",
|
||||||
|
"is_fraud": false,
|
||||||
|
"card_last_digits": "7890"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"transaction_id": "TXN023",
|
||||||
|
"user_id": 5,
|
||||||
|
"amount": 4700.0,
|
||||||
|
"category": "Products",
|
||||||
|
"timestamp": "2024-01-17 09:15:00",
|
||||||
|
"is_fraud": false,
|
||||||
|
"card_last_digits": "7890"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"transaction_id": "TXN024",
|
||||||
|
"user_id": 1,
|
||||||
|
"amount": 28500.0,
|
||||||
|
"category": "Transfers",
|
||||||
|
"timestamp": "2024-01-19 03:00:00",
|
||||||
|
"is_fraud": true,
|
||||||
|
"card_last_digits": "1234"
|
||||||
|
}
|
||||||
|
]
|
||||||
33
транзакции интернет банка/financial_report.txt
Normal file
33
транзакции интернет банка/financial_report.txt
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
============================================================
|
||||||
|
ФИНАНСОВЫЙ ОТЧЕТ
|
||||||
|
============================================================
|
||||||
|
|
||||||
|
Всего транзакций: 3
|
||||||
|
Общая сумма: 6,750.50 руб.
|
||||||
|
|
||||||
|
Обычные транзакции:
|
||||||
|
Количество: 2
|
||||||
|
Сумма: 1,750.50 руб.
|
||||||
|
|
||||||
|
Мошеннические транзакции:
|
||||||
|
Количество: 1
|
||||||
|
Сумма: 5,000.00 руб.
|
||||||
|
|
||||||
|
ТОП-5 КАТЕГОРИЙ ПО ТРАТАМ:
|
||||||
|
1. Электроника: 5,000.00 руб.
|
||||||
|
2. Продукты: 1,500.50 руб.
|
||||||
|
3. Кафе: 250.00 руб.
|
||||||
|
|
||||||
|
ТОП-3 ПОЛЬЗОВАТЕЛЯ ПО КОЛИЧЕСТВУ ТРАНЗАКЦИЙ:
|
||||||
|
1. Пользователь 1: 2 транзакций
|
||||||
|
2. Пользователь 2: 1 транзакций
|
||||||
|
|
||||||
|
Уникальных пользователей: 2
|
||||||
|
|
||||||
|
СТАТИСТИКА ПО ДНЯМ (первые 7 дней):
|
||||||
|
2024-01-15:
|
||||||
|
Сумма: 6,750.50 руб.
|
||||||
|
Кол-во: 3
|
||||||
|
Средний чек: 2,250.17 руб.
|
||||||
|
|
||||||
|
============================================================
|
||||||
19
транзакции интернет банка/report.txt
Normal file
19
транзакции интернет банка/report.txt
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
=== Отчёт по отзывам ===
|
||||||
|
Общее количество отзывов: 7
|
||||||
|
Средний рейтинг: 3.43
|
||||||
|
|
||||||
|
Топ слов:
|
||||||
|
- покупкой: 2
|
||||||
|
- рекомендую: 2
|
||||||
|
- есть: 2
|
||||||
|
- за: 2
|
||||||
|
- отличный: 1
|
||||||
|
|
||||||
|
Пользователи:
|
||||||
|
- Анна
|
||||||
|
- Дмитрий
|
||||||
|
- Елена
|
||||||
|
- Ирина
|
||||||
|
- Михаил
|
||||||
|
- Ольга
|
||||||
|
- Сергей
|
||||||
52
транзакции интернет банка/reports/financial_report.txt
Normal file
52
транзакции интернет банка/reports/financial_report.txt
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
============================================================
|
||||||
|
ФИНАНСОВЫЙ ОТЧЕТ
|
||||||
|
============================================================
|
||||||
|
|
||||||
|
Всего транзакций: 24
|
||||||
|
Общая сумма: 207,350.50 руб.
|
||||||
|
|
||||||
|
Обычные транзакции:
|
||||||
|
Количество: 20
|
||||||
|
Сумма: 86,850.50 руб.
|
||||||
|
|
||||||
|
Мошеннические транзакции:
|
||||||
|
Количество: 4
|
||||||
|
Сумма: 120,500.00 руб.
|
||||||
|
|
||||||
|
ТОП-5 КАТЕГОРИЙ ПО ТРАТАМ:
|
||||||
|
1. Transfers: 107,000.00 руб.
|
||||||
|
2. Cash Withdrawal: 32,000.00 руб.
|
||||||
|
3. Entertainment: 24,900.00 руб.
|
||||||
|
4. Products: 19,950.50 руб.
|
||||||
|
5. Cafe: 14,000.00 руб.
|
||||||
|
|
||||||
|
ТОП-3 ПОЛЬЗОВАТЕЛЯ ПО КОЛИЧЕСТВУ ТРАНЗАКЦИЙ:
|
||||||
|
1. Пользователь 1: 7 транзакций
|
||||||
|
2. Пользователь 3: 6 транзакций
|
||||||
|
3. Пользователь 2: 5 транзакций
|
||||||
|
|
||||||
|
Уникальных пользователей: 5
|
||||||
|
|
||||||
|
СТАТИСТИКА ПО ДНЯМ (первые 7 дней):
|
||||||
|
2024-01-15:
|
||||||
|
Сумма: 34,250.50 руб.
|
||||||
|
Кол-во: 8
|
||||||
|
Средний чек: 4,281.31 руб.
|
||||||
|
2024-01-16:
|
||||||
|
Сумма: 63,550.00 руб.
|
||||||
|
Кол-во: 7
|
||||||
|
Средний чек: 9,078.57 руб.
|
||||||
|
2024-01-17:
|
||||||
|
Сумма: 35,600.00 руб.
|
||||||
|
Кол-во: 5
|
||||||
|
Средний чек: 7,120.00 руб.
|
||||||
|
2024-01-18:
|
||||||
|
Сумма: 45,450.00 руб.
|
||||||
|
Кол-во: 3
|
||||||
|
Средний чек: 15,150.00 руб.
|
||||||
|
2024-01-19:
|
||||||
|
Сумма: 28,500.00 руб.
|
||||||
|
Кол-во: 1
|
||||||
|
Средний чек: 28,500.00 руб.
|
||||||
|
|
||||||
|
============================================================
|
||||||
35
транзакции интернет банка/транзакции интернет банка.pyproj
Normal file
35
транзакции интернет банка/транзакции интернет банка.pyproj
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
<ProjectGuid>6efbf71d-f045-46ef-8006-9621f4cfde65</ProjectGuid>
|
||||||
|
<ProjectHome>.</ProjectHome>
|
||||||
|
<StartupFile>транзакции_интернет_банка.py</StartupFile>
|
||||||
|
<SearchPath>
|
||||||
|
</SearchPath>
|
||||||
|
<WorkingDirectory>.</WorkingDirectory>
|
||||||
|
<OutputPath>.</OutputPath>
|
||||||
|
<Name>транзакции интернет банка</Name>
|
||||||
|
<RootNamespace>транзакции интернет банка</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="транзакции_интернет_банка.py" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Python Tools\Microsoft.PythonTools.targets" />
|
||||||
|
<!-- Uncomment the CoreCompile target to enable the Build command in
|
||||||
|
Visual Studio and specify your pre- and post-build commands in
|
||||||
|
the BeforeBuild and AfterBuild targets below. -->
|
||||||
|
<!--<Target Name="CoreCompile" />-->
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
</Project>
|
||||||
23
транзакции интернет банка/транзакции интернет банка.sln
Normal file
23
транзакции интернет банка/транзакции интернет банка.sln
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.14.36518.9 d17.14
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "транзакции интернет банка", "транзакции интернет банка.pyproj", "{6EFBF71D-F045-46EF-8006-9621F4CFDE65}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{6EFBF71D-F045-46EF-8006-9621F4CFDE65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{6EFBF71D-F045-46EF-8006-9621F4CFDE65}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {280AB7AA-1880-4723-92BD-77A223A9F832}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
Loading…
Reference in New Issue
Block a user