watchdog (для отслеживания изменений в папке), os, time, logging и др. import time
import os
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
class RansomwareHandler(FileSystemEventHandler):
def __init__(self):
self.modified_files = set()
self.deleted_files = set()
def on_modified(self, event):
if not event.is_directory:
self.modified_files.add(event.src_path)
print("Modified:", event.src_path)
def on_deleted(self, event):
if not event.is_directory:
self.deleted_files.add(event.src_path)
print("Deleted:", event.src_path)
def monitor(path_to_watch, check_interval=10):
event_handler = RansomwareHandler()
observer = Observer()
observer.schedule(event_handler, path=path_to_watch, recursive=True)
observer.start()
try:
while True:
time.sleep(check_interval)
# Простая логика: если за интервал изменилось или удалилось слишком много файлов
if len(event_handler.modified_files) > 100 or len(event_handler.deleted_files) > 10:
print("Warning: Potential ransomware activity detected!")
# Можно логировать события
event_handler.modified_files.clear()
event_handler.deleted_files.clear()
except KeyboardInterrupt:
observer.stop()
observer.join()
if name == "__main__":
path = "/path/to/watch"
monitor(path, check_interval=10)
🟢 Мониторит указанную директорию на события изменения и удаления файлов🟢 Логирует эти события в консоль и файл (например ransomware_detection.log)🟢 Периодически проверяется, если много изменений/удалений — вывод предупреждения о потенциальной атаке
#скрипты
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤2🔥2
glasbey🟢 Можно создавать палитры с произвольным количеством цветов: glasbey.create_palette(palette_size=15) — и цвета будут стараться быть максимально отличимыми визуально.🟢 Можно расширять существующие палитры, или “с нуля” задавать seed цвета, чтобы новая палитра дополняла прежнюю (чтобы цвета не пересекались сильно).🟢 Поддержка ограничений: можно задавать границы яркости, хромности (chroma), чтобы цвета не были слишком яркими или слишком блеклыми.🟢 Можно создавать “блочные” палитры — когда есть иерархии категорий, вложенные группы.🟢 Легко использовать в связке с matplotlib / seaborn и др. визуализациями — просто генерируешь цвета и передаёшь библиотеке визуализации.
pip install glasbey
#библиотеки
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4👍4
Forwarded from Python_Scripts
CompressImages.py — скрипт для пакетной обработки изображений: сжатия и изменения размераPIL (Pillow), os, sys, argparse — используется для обработки изображения и работы с файловой системой. CompressImages.py — утилита, которую запускаешь в папке с изображениями (или указываешь исходную папку), скрипт изменяет размер изображений до заданных лимитов (максимальная ширина/высота), сжимает качество (JPEG или др.), переименовывает по шаблону, и сохраняет в output-папку. Полезно, когда надо оптимизировать папки с фотографиями, иконками, медиа-контентом. import os
import sys
from PIL import Image
from argparse import ArgumentParser
def process_images(input_dir, output_dir, max_width, max_height, quality=70, rename_template=None):
os.makedirs(output_dir, exist_ok=True)
count = 0
for fname in os.listdir(input_dir):
if fname.lower().endswith(('.jpg', '.jpeg', '.png')):
path = os.path.join(input_dir, fname)
img = Image.open(path)
# изменение размера с сохранением пропорций
img.thumbnail((max_width, max_height))
base_name, ext = os.path.splitext(fname)
if rename_template:
out_name = rename_template.replace("{count}", str(count)) + ext
else:
out_name = fname
out_path = os.path.join(output_dir, out_name)
img.save(out_path, quality=quality)
print(f"Saved: {out_path}")
count += 1
def main():
parser = ArgumentParser()
parser.add_argument("input_dir")
parser.add_argument("output_dir")
parser.add_argument("--max_width", type=int, default=800)
parser.add_argument("--max_height", type=int, default=600)
parser.add_argument("--quality", type=int, default=70)
parser.add_argument("--rename", help="template, e.g. img_{count}")
args = parser.parse_args()
process_images(args.input_dir, args.output_dir, args.max_width, args.max_height, args.quality, args.rename)
if name == "__main__":
main()
🟢 Идёт по всем изображениям в папке с разрешениями .jpg, .jpeg, .png🟢 Изменяет их размер до заданных максимальных ширины/высоты, сохраняя пропорции🟢 Сжимает качество (для JPG например), чтобы уменьшить размер файлов🟢 Опционально переименовывает файлы по шаблону с номером🟢 Сохраняет всё в выходную папку, чтобы не перезаписывать оригиналы
#скрипты
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8❤6
py-irt🟢 Масштабируемость — работает с большими наборами данных, использует PyTorch и Pyro под капотом для ускорения вычислений.🟢 Байесовский подход — поддерживает обучение с априорными распределениями и вывод параметров через стохастические методы.🟢 GPU-поддержка — если данные большие, можно ускорить обучение.🟢 Чистый API — удобно интегрировать в образовательные платформы или аналитические пайплайны.
pip install py-irt
#библиотеки
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3🔥2
qrcode, Pillow import qrcode
import sys
def make_qr(data, output_file="qrcode.png", version=1, box_size=10, border=4):
qr = qrcode.QRCode(
version=version,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=box_size,
border=border,
)
qr.add_data(data)
qr.make(fit=True)
img = qr.make_image(fill_color="black", back_color="white")
img.save(output_file)
print(f"QR saved to {output_file}")
if name == "__main__":
if len(sys.argv) < 2:
print("Usage: python qr_gen.py <text_or_url>")
sys.exit(1)
data = sys.argv[1]
make_qr(data)
🟢 Принимает строку (URL, текст и т.д.)
🟢 Генерирует QR-код с заданными параметрами (размер, граница)
🟢 Сохраняет в файл (PNG)
🟢 Можно встроить в GUI или веб-интерфейс
#скрипты
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥2❤1
nixnet🟢 Поддержка CAN и LIN — взаимодействие с сетями транспортных сообщений через NI-XNET оборудование🟢 Возможность читать кадры, сигналы, преобразовывать данные между физическим и представлением (unit conversion)🟢 Использует API NI-XNET / NI hardware — фактически “Python на железо” решение🟢 Поддержка Windows и взаимодействие с runtime NI-XNET
pip install nixnet
#библиотеки
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4👍3
Рост в эпоху AI: иллюзия лёгких побед? 🏆
AI обещает доступность знаний, быстрый запуск продуктов и удешевление выхода на рынок.
➡️ Но на деле этот рынок превращается в конвейер клонов Ctrl+C Ctrl+V
Любой, кто копает глубже и понимает пользователя лучше других, навсегда останется вне конкуренции.
В канале Продукт и рост мы разбираем:
🔵 как строить продукты, которые защищены от копирования,
🔵 какие механики продвижения реально работают в 2025-м,
🔵 и почему рост — это единственное настоящее оружие в эпоху AI.
Список жизненно важной информации для твоего продукта в закрепе канала🖇
Переходи:
👉🏻 https://t.me/+ykiXdap13NZiZjYy
AI обещает доступность знаний, быстрый запуск продуктов и удешевление выхода на рынок.
Любой, кто копает глубже и понимает пользователя лучше других, навсегда останется вне конкуренции.
В канале Продукт и рост мы разбираем:
Список жизненно важной информации для твоего продукта в закрепе канала
Переходи:
👉🏻 https://t.me/+ykiXdap13NZiZjYy
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3❤2🔥1
class ChainedDicts(dict):
def __init__(self, *dicts):
self.dicts = dicts
self.base = {}
def __getitem__(self, item):
if item in self.base:
return self.base[item]
elif item not in self.dicts[0]:
raise KeyError
for internal_dict in self.dicts:
if item in internal_dict:
item = internal_dict[item]
else:
return item
return item
def __setitem__(self, key, value):
self.base[key] = value
def __delitem__(self, key):
if key in self.base:
del self.base[key]
if key in self.dicts[0]:
del self.dicts[0][key]
# Пример использования из Gist:
d = ChainedDicts({1: 2, 3: 4}, {4: 5, 6: 8})
print(d[1])
print(d[3])
🟢 Конструирует словарь, объединяющий несколько уровней словарей🟢 При чтении ключа: сначала смотрит base (локальные переопределения), потом “цепочку” словарей🟢 При записи: всегда записывает в base🟢 При удалении: удаляет из base или из первого словаря, если там🟢 Позволяет иметь “умный” конфиг: “дефолт + overrides + runtime”
#скрипты
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4👍4
Каналы с Junior IT вакансиями
и стажировками
Подписывайся и забирай свой оффер
1. Стажировки и вакансии по России и миру
2. IT вакансии по СНГ
3. IT стажировки по СНГ
4. ИИ-ассистент для автооткликов
5. IT стажировки и волонтерства
6. IT стажировки в топовых компаниях мира
7. Удалённые IT вакансии и стажировки
8. Python вакансии и стажировки
9. БИГТЕХ вакансии и стажировки
10. Design вакансии и стажировки
11. QA вакансии и стажировки
12. Junior вакансии и стажировки
13. Frontend вакансии и вопросы собесов
14. Вакансии и стажировки для аналитиков
15. Вакансии в русских стартапах за границей
16. Вакансии и стажировки для DevOps
17. Вакансии, которых нет на ХХ.РУ
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
GraSPy🟢 Поддерживает различные статистические методы для графов: распределения степеней, алгоритмы сравнения графов, random graph models.🟢 API совместим с привычным стилем библиотек Python для работы с данными / машинным обучением: интеграция в пайплайны исследовательской работы.🟢 Визуализация и инструменты анализа графов внутри библиотеки.🟢 Открытый исходный код, лицензия Apache 2.0.
pip install graspy
#библиотеки
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3👍2❤1
argparse, subprocess (для вызова ffmpeg), time и др.import argparse
import subprocess
def autocut(input_files, output, silent_speed=10, silent_threshold=600, denoise=False):
for input_vid in input_files:
cmd = ["ffmpeg", "-i", input_vid]
# добавляется фильтр, который ускоряет silent части
vfilt = f"silencedetect=n={silent_threshold}dB"
# здесь опции ускорения, убирание шума и т.д.
# пример:
cmd.extend([
"-vf", vfilt,
"-filter_complex", f"[0:v]setpts=PTS/ {silent_speed}[v]",
"-map", "[v]", "-map", "0:a",
output or f"{input_vid}_faster.mp4"
])
if denoise:
cmd.extend(["-af", "arnndn"])
print("Running:", " ".join(cmd))
subprocess.run(cmd, check=True)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Speed up silent parts in videos.")
parser.add_argument("--input", nargs='+', required=True, help="Input video files *.mp4")
parser.add_argument("--output", help="Output filename or directory")
parser.add_argument("--silent-speed", type=int, default=10, help="How much to speed up silent parts")
parser.add_argument("--silent-threshold", type=int, default=600, help="What is considered silent (threshold in milliseconds/sound level)")
parser.add_argument("--denoise", action="store_true", help="Remove background noise using ffmpeg model")
args = parser.parse_args()
autocut(args.input, args.output, args.silent_speed, args.silent_threshold, args.denoise)
🟢 Определяет “тихие” участки видео, используя порог громкости / шумов🟢 Автоматически ускоряет эти участки, чтобы сократить общее время просмотра видео🟢 Опционально удаляет шум или фоновые звуки (denoise) при помощи фильтров ffmpeg🟢 Сохраняет модифицированное видео с суффиксом или в указанное место
#скрипты
Please open Telegram to view this post
VIEW IN TELEGRAM
1❤9👍4🔥3
nico-sc-sp🟢 Аннотация типов клеток: библиотека помогает метить клетки по данным транскриптомики.🟢 Выявление взаимодействий ниш: определение, какие типы клеток близко соседствуют и как они влияют друг на друга.🟢 Ковариационный анализ: нахождение взаимозависимостей между наборами генов у взаимодействующих клеток.🟢 Интеграция с популярными библиотеками: зависит от scanpy, pandas, numpy, pygraphviz и др.
pip install nico-sc-sp
#библиотеки
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5🔥3
requests, BeautifulSoup / lxml — для HTTP-запросов и парсинга HTML страниц. import requests
from bs4 import BeautifulSoup
import os
def download_slideshare(slide_url, output_dir="slides"):
os.makedirs(output_dir, exist_ok=True)
resp = requests.get(slide_url)
soup = BeautifulSoup(resp.text, "html.parser")
# найти контейнер со слайдами, получить ссылки на изображения слайдов
img_tags = soup.select("img.slide_image") # пример селектора
for idx, img in enumerate(img_tags):
img_url = img.get("data-full") or img.get("src")
if not img_url:
continue
ext = img_url.split('.')[-1]
fname = f"slide_{idx}.{ext}"
path = os.path.join(output_dir, fname)
r = requests.get(img_url)
with open(path, "wb") as f:
f.write(r.content)
print("Downloaded:", fname)
if __name__ == "__main__":
url = "https://www.slideshare.net/some-presentation"
download_slideshare(url)
🟢 Загружает HTML страницы Slideshare🟢 Парсит HTML и извлекает ссылки на изображения слайдов🟢 Скачивает каждый слайд как картинку🟢 Сохраняет всё в указанную папку, нумеруя слайды
#скрипты
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6🔥3
— Ты уволен
— Почему?
— Мы оплатили GPT-5, ты больше не нужен.
Вы тоже в ах@е с такого расклада? Учился лет 5, потом столько же батрачил за копейки ради опыта — чтобы тебя заменила еб@чая железяка.
А теперь задумайтесь: нейронки развиваются с бешеной скоростью. Поэтому сейчас как никогда нужны спецы для их обучения.
Чтобы в кратчайшие сроки выйти на уровень элиты и стать топом в сфере — подпишитесь на канал @devsp. Его автор раскрывает неочевидные секреты: как в 3 месяца уместить 6 лет обучения, достойно пройти любое собеседование и что делать, чтобы лучшие компании дрались за вас.
А временами подкидывает крутые вакансии и лайфхаки, после которых вас с руками оторвут даже без опыта.
Это всё равно что встретить Нео и войти в 10% тех, кто сломал систему. Подписывайтесь: @devsp
— Почему?
— Мы оплатили GPT-5, ты больше не нужен.
Вы тоже в ах@е с такого расклада? Учился лет 5, потом столько же батрачил за копейки ради опыта — чтобы тебя заменила еб@чая железяка.
А теперь задумайтесь: нейронки развиваются с бешеной скоростью. Поэтому сейчас как никогда нужны спецы для их обучения.
Чтобы в кратчайшие сроки выйти на уровень элиты и стать топом в сфере — подпишитесь на канал @devsp. Его автор раскрывает неочевидные секреты: как в 3 месяца уместить 6 лет обучения, достойно пройти любое собеседование и что делать, чтобы лучшие компании дрались за вас.
А временами подкидывает крутые вакансии и лайфхаки, после которых вас с руками оторвут даже без опыта.
Это всё равно что встретить Нео и войти в 10% тех, кто сломал систему. Подписывайтесь: @devsp
1😁13❤1
AnomalousLib🟢 Поддержка Python 3.12.10 или новее.🟢 Позволяет генерировать данные с различными типами аномальной диффузии (subdiffusion, superdiffusion и др.).🟢 Встроенные методы статистического анализа (оценка показателей, сравнение моделей) + инференс моделей.🟢 С визуализацией: возможность строить графики траекторий, распределений, оценки отклонения от нормальной диффузии.
pip install anomalouslib
#библиотеки
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2👍2
This media is not supported in your browser
VIEW IN TELEGRAM
Подойдёт и новичкам, и тем, кто уже работает с JS и React
На канале Интенсивный JavaScript действующий тимлид и опытный разработчик помогает изучить фронтенд на практических задачах, которые интересно кодить
С 18 октября стартует бесплтаное обучение, где он на практике поможет разобраться во фронтенде: новикам в HTML/CSS и JavaScript, а тем, кто с опытом — React, TypeScript, Next.js
Всего сделаете три проекта:
Обучение подойдёт, даже если у вас нет опыта в программировании — всё объясняют так, чтобы поняла даже ваша бабуля
Если опыт есть — будет проще. Сможете набить руку на React, TS, Next
Что будет кроме уроков:
— пошаговый план изучения всего, что нужно современному фронтендеру
— способы поиска заказов на фрилансе с помощью ИИ
— разыграет годовой доступ к крутому ИИ
— расскажет, как взять первый заказ на фрилансе, если на биржах не получается
Подписывайтесь, чтобы участвовать, осталось 39 мест
Учиться самостоятельно можно бесконечно, если не знать, куда копать. На интенсиве сократите время на поиск информации и получите пошаговый план от разработчика, который нанимает новичков в команду
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
pytrends, flask, openai, requests и др. — взаимодействие с Google Trends API, веб-интерфейс, генерация текста. Нишевый инструмент для маркетологов / предпринимателей: ты вводишь ключевые слова или темы, скрипт берёт тренды из Google Trends, комбинирует их с моделями GPT, и генерирует идеи нишевых подкатегорий, потенциально прибыльных тем или продукты.
👨💻 Пример кода (упрощённая логика):
from pytrends.request import TrendReq
from flask import Flask, request, jsonify
import openai
pytrend = TrendReq()
app = Flask(__name__)
@app.route("/niche", methods=["POST"])
def find_niche():
data = request.json
keywords = data.get("keywords") # список ключевых слов
trends = []
for kw in keywords:
pytrend.build_payload([kw], timeframe="today 12-m")
interest = pytrend.interest_over_time()
trends.append((kw, interest.mean()))
# строим запрос в GPT, чтобы предложил нишевые идеи на основе трендов
prompt = f"Given these keywords and their trends: {trends}, suggest niche ideas."
resp = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[{"role":"user", "content":prompt}]
)
ideas = resp.choices[0].message.content
return jsonify({"ideas": ideas, "trends": trends})
if name == "__main__":
app.run(port=5000)
🟢 Берёт тренды по ключевым словам из Google Trends (pytrends)🟢 Анализирует средние интересы или тренды роста🟢 Отправляет данные + ключевые слова в модель GPT🟢 Получает от GPT идеи ниш, подкатегорий или направлений🟢 Возвращает JSON с предложениями и трендами
#скрипты
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤3🔥1😁1
argparse, subprocess, pathlib, fnmatch, uuid, shutil, os, re — всё стандартное.#!/usr/bin/env python3
"""
gitingest.py - Turn any Git repository into a prompt-friendly text and copy to clipboard.
Usage:
python gitingest.py <URL/LOCAL_FOLDER> [options]
Options:
--exclude PATTERN Patterns to exclude (can be used multiple times)
--max-size SIZE Include files under SIZE kb (default: 50kb)
Examples:
python gitingest.py https://github.com/user/repo
python gitingest.py ./local-folder --exclude "*.log" --exclude "tests/*" --max-size 100
"""
import os
import sys
import subprocess
import tempfile
import shutil
import argparse
from pathlib import Path
from fnmatch import fnmatch
import uuid
import re
def clone_repo_if_needed(repo_path_or_url, tmp_dir):
# если передана URL — клонировать, иначе использовать локальный путь
pass
def collect_files(base_path, max_size_kb, exclude_patterns):
# пройтись по базе, собрать пути файлов, которые
# — меньше max_size
# — не соответствуют exclude_patterns
pass
def read_files(paths):
# читать файлы, возможно ограничивать общую длину, фильтры по расширениям
pass
def main():
# парсинг аргументов, клонирование, сбор файлов, вывод в консоль / буфер
pass
🟢 Принимает на вход путь к репозиторию либо URL🟢 Опции: --exclude шаблоны файлов / директорий, --max-size чтобы игнорировать большие файлы🟢 Сбирает содержимое подходящих файлов🟢 Генерирует текстовый вывод — может копировать в clipboard или просто печатать🟢 Удобное для подготовки данных перед аналитикой, обзором репо, работе с AI, чтобы “загрузить” код без лишнего мусора
#скрипты
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4👍3❤1
opencv-python, numpy, click, ffmpegИспользует алгоритмы анализа яркости, цвета и движения для определения точек смены сцен.
from scenedetect import detect, ContentDetector, split_video_ffmpeg
scene_list = detect('input.mp4', ContentDetector())
split_video_ffmpeg('input.mp4', scene_list)
🟢 Анализирует видео и определяет, где происходит смена сцены🟢 Разделяет видео на отдельные файлы по найденным сценам🟢 Поддерживает экспорт списка сцен в CSV, HTML и EDL🟢 Работает как через CLI, так и через Python API
#скрипты
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6👍5
Pillow, numpy, argparse🟠 Загружает изображение любого поддерживаемого формата🟠 Конвертирует в градации серого🟠 Делит изображение на сетку и заменяет среднюю яркость каждой ячейки ASCII‑символом (@, #, . и пр.)🟠 Сохраняет ASCII-арт в файл или выводит на экран🟠 Включает CLI‑интерфейс для настройки ширины и дискреты яркости.
python ascii_art.py --input image.jpg --width 80 --output ascii.txt --detailed
import os
import argparse
from PIL import Image
import numpy as np
GSCALE_SIMPLE = "@%#*+=-:. "
GSCALE_EXTENDED = "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~i!lI;:,\"^`'. "
def avg_brightness(tile):
return np.array(tile).mean()
def image_to_ascii(image_path, cols=80, more_levels=False):
image = Image.open(image_path).convert('L')
W, H = image.size
scale = 0.43 # поправка на соотношение символов в терминале
w = W / cols
h = w / scale
rows = int(H / h)
print(f"[ASCII] Рисунок: cols={cols}, rows={rows}")
ascii_img = []
gs = GSCALE_EXTENDED if more_levels else GSCALE_SIMPLE
levels = len(gs)
for row in range(rows):
y1 = int(row * h)
y2 = int((row + 1) * h) if row < rows - 1 else H
line = ""
for col in range(cols):
x1 = int(col * w)
x2 = int((col + 1) * w) if col < cols - 1 else W
tile = image.crop((x1, y1, x2, y2))
brightness = avg_brightness(tile)
idx = int(brightness * (levels - 1) / 255)
line += gs[idx]
ascii_img.append(line)
return ascii_img
def main():
parser = argparse.ArgumentParser(description="ASCII Art Image Converter")
parser.add_argument('--input', required=True, help='Путь к изображению')
parser.add_argument('--width', '-w', type=int, default=80, help='Ширина в символах')
parser.add_argument('--output', '-o', help='Выходной .txt файл (по умолчанию — stdout)')
parser.add_argument('--detailed', action='store_true',
help='Использовать мелкую градацию (GSCALE_EXTENDED)')
args = parser.parse_args()
art = image_to_ascii(args.input, cols=args.width, more_levels=args.detailed)
if args.output:
with open(args.output, 'w', encoding='utf-8') as f:
f.write('\n'.join(art))
print(f"✅ Сохранено в {args.output}")
else:
print()
print('\n'.join(art))
if __name__ == "__main__":
main()
pip install pillow numpy
#скрипты
Please open Telegram to view this post
VIEW IN TELEGRAM
1❤8👍4🔥1
time, csv, datetime, argparseКаждую заданную минуту спрашивает (CLI), чем вы заняты.
Записывает метку времени и описание задачи в CSV.
В конце дня автоматически выводит краткую таблицу: сколько времени ушло на каждую задачу.
Полезно, чтобы увидеть, куда уходит время, и перестать терять минуты зря.
python time_tracker.py --interval 60 --output time_log.csv
import time
import csv
from datetime import datetime
import argparse
from collections import Counter
def track(interval, output):
with open(output, 'a', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
while True:
now = datetime.now()
task = input(f"[{now.strftime('%H:%M')}] Что вы сейчас делаете? ")
writer.writerow([now.isoformat(), task])
if task.lower() in ('выход', 'exit', 'quit'):
break
time.sleep(interval * 60)
def summarize(output):
tasks = []
with open(output, newline='', encoding='utf-8') as f:
for row in csv.reader(f):
if len(row) >= 2:
tasks.append(row[1])
counts = Counter(tasks)
print("⏳ Итоги дня:")
for task, cnt in counts.items():
print(f"{task[:30]:30} — {cnt} отметок")
if __name__ == '__main__':
parser = argparse.ArgumentParser("Hourly Time Tracker")
parser.add_argument("--interval", type=int, default=60, help="Интервал опроса (в минутах)")
parser.add_argument("--output", default="time_log.csv", help="CSV файл для логов")
parser.add_argument("--summary", action="store_true", help="Показать итог за день и выйти")
args = parser.parse_args()
if args.summary:
summarize(args.output)
else:
track(args.interval, args.output)
#скрипты
Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥8❤4👍2