batch24-28 1.2.2__tar.gz → 1.2.4__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.
Files changed (23) hide show
  1. {batch24_28-1.2.2/src/batch24_28.egg-info → batch24_28-1.2.4}/PKG-INFO +46 -4
  2. batch24_28-1.2.2/PKG-INFO → batch24_28-1.2.4/README.md +36 -10
  3. batch24_28-1.2.4/pyproject.toml +21 -0
  4. {batch24_28-1.2.2 → batch24_28-1.2.4}/src/batch24_28/__init__.py +4 -2
  5. batch24_28-1.2.4/src/batch24_28/reporter.py +18 -0
  6. batch24_28-1.2.4/src/batch24_28/vision.py +187 -0
  7. batch24_28-1.2.4/src/batch24_28/watcher.py +40 -0
  8. batch24_28-1.2.2/README.md → batch24_28-1.2.4/src/batch24_28.egg-info/PKG-INFO +53 -2
  9. {batch24_28-1.2.2 → batch24_28-1.2.4}/src/batch24_28.egg-info/SOURCES.txt +2 -0
  10. batch24_28-1.2.4/src/batch24_28.egg-info/requires.txt +9 -0
  11. batch24_28-1.2.2/pyproject.toml +0 -10
  12. batch24_28-1.2.2/src/batch24_28/watcher.py +0 -24
  13. batch24_28-1.2.2/src/batch24_28.egg-info/requires.txt +0 -2
  14. {batch24_28-1.2.2 → batch24_28-1.2.4}/setup.cfg +0 -0
  15. {batch24_28-1.2.2 → batch24_28-1.2.4}/src/batch24_28/art.py +0 -0
  16. {batch24_28-1.2.2 → batch24_28-1.2.4}/src/batch24_28/calculator.py +0 -0
  17. {batch24_28-1.2.2 → batch24_28-1.2.4}/src/batch24_28/chess_game.py +0 -0
  18. {batch24_28-1.2.2 → batch24_28-1.2.4}/src/batch24_28/from .py +0 -0
  19. {batch24_28-1.2.2 → batch24_28-1.2.4}/src/batch24_28/games.py +0 -0
  20. {batch24_28-1.2.2 → batch24_28-1.2.4}/src/batch24_28/monitor.py +0 -0
  21. {batch24_28-1.2.2 → batch24_28-1.2.4}/src/batch24_28/timers.py +0 -0
  22. {batch24_28-1.2.2 → batch24_28-1.2.4}/src/batch24_28.egg-info/dependency_links.txt +0 -0
  23. {batch24_28-1.2.2 → batch24_28-1.2.4}/src/batch24_28.egg-info/top_level.txt +0 -0
@@ -1,11 +1,18 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: batch24-28
3
- Version: 1.2.2
4
- Summary: A multi featured Python terminal
5
- Requires-Python: >=3.7
3
+ Version: 1.2.4
4
+ Summary: A multi featured Python terminal and vision toolkit
5
+ Requires-Python: >=3.12
6
6
  Description-Content-Type: text/markdown
7
7
  Requires-Dist: psutil
8
8
  Requires-Dist: watchdog
9
+ Requires-Dist: opencv-python
10
+ Requires-Dist: mediapipe==0.10.21
11
+ Requires-Dist: fer
12
+ Requires-Dist: tensorflow==2.17.0
13
+ Requires-Dist: protobuf==4.25.9
14
+ Requires-Dist: setuptools==81.0.0
15
+ Requires-Dist: python-chess
9
16
 
10
17
 
11
18
  # batch24-28
@@ -122,7 +129,20 @@ monitor_performance(threshold=80)
122
129
 
123
130
  ---
124
131
 
125
- ### 8. System Performance Sentinel
132
+ ### 8. System Information Reporter
133
+
134
+ Generates a comprehensive snapshot of system hardware and environment status.
135
+
136
+ ```python
137
+ from batch24_28 import generate_system_report
138
+
139
+ # Generate report to a file
140
+ generate_system_report("system_report.txt")
141
+ ```
142
+
143
+ ---
144
+
145
+ ### 9. System Performance Sentinel
126
146
 
127
147
  Monitor a directory for file system changes (created, modified, or deleted).
128
148
 
@@ -132,3 +152,25 @@ from batch24_28 import start_file_watcher
132
152
  # Watch the current directory
133
153
  start_file_watcher(path=".")
134
154
  ```
155
+
156
+ ---
157
+
158
+ ### 10. Computer Vision & Emotion Analysis Toolkit
159
+
160
+ An interactive computer vision pipeline powered by MediaPipe hand-tracking and deep learning emotion recognition. Includes virtual mid-air drawing (Air Canvas) and facial expression tracking via webcam, static images, or video files.
161
+
162
+ ```python
163
+ from batch24_28 import VisionAnalyzer
164
+
165
+ analyzer = VisionAnalyzer()
166
+
167
+ # Option A: Run live Air Canvas and Emotion detection via webcam
168
+ analyzer.run_air_canvas(run_draw=True, run_emotion=True)
169
+
170
+ # Option B: Analyze facial expression from a static image file
171
+ emotion, score, img = analyzer.analyze_image_file("path_to_image.jpg")
172
+ print(f"Detected: {emotion} ({int(score * 100)}%)")
173
+
174
+ # Option C: Stream and analyze a video file for expressions
175
+ analyzer.analyze_video_file("path_to_video.mp4")
176
+ ```
@@ -1,12 +1,3 @@
1
- Metadata-Version: 2.4
2
- Name: batch24-28
3
- Version: 1.2.2
4
- Summary: A multi featured Python terminal
5
- Requires-Python: >=3.7
6
- Description-Content-Type: text/markdown
7
- Requires-Dist: psutil
8
- Requires-Dist: watchdog
9
-
10
1
 
11
2
  # batch24-28
12
3
 
@@ -122,7 +113,20 @@ monitor_performance(threshold=80)
122
113
 
123
114
  ---
124
115
 
125
- ### 8. System Performance Sentinel
116
+ ### 8. System Information Reporter
117
+
118
+ Generates a comprehensive snapshot of system hardware and environment status.
119
+
120
+ ```python
121
+ from batch24_28 import generate_system_report
122
+
123
+ # Generate report to a file
124
+ generate_system_report("system_report.txt")
125
+ ```
126
+
127
+ ---
128
+
129
+ ### 9. System Performance Sentinel
126
130
 
127
131
  Monitor a directory for file system changes (created, modified, or deleted).
128
132
 
@@ -132,3 +136,25 @@ from batch24_28 import start_file_watcher
132
136
  # Watch the current directory
133
137
  start_file_watcher(path=".")
134
138
  ```
139
+
140
+ ---
141
+
142
+ ### 10. Computer Vision & Emotion Analysis Toolkit
143
+
144
+ An interactive computer vision pipeline powered by MediaPipe hand-tracking and deep learning emotion recognition. Includes virtual mid-air drawing (Air Canvas) and facial expression tracking via webcam, static images, or video files.
145
+
146
+ ```python
147
+ from batch24_28 import VisionAnalyzer
148
+
149
+ analyzer = VisionAnalyzer()
150
+
151
+ # Option A: Run live Air Canvas and Emotion detection via webcam
152
+ analyzer.run_air_canvas(run_draw=True, run_emotion=True)
153
+
154
+ # Option B: Analyze facial expression from a static image file
155
+ emotion, score, img = analyzer.analyze_image_file("path_to_image.jpg")
156
+ print(f"Detected: {emotion} ({int(score * 100)}%)")
157
+
158
+ # Option C: Stream and analyze a video file for expressions
159
+ analyzer.analyze_video_file("path_to_video.mp4")
160
+ ```
@@ -0,0 +1,21 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "batch24-28"
7
+ version = "1.2.4"
8
+ description = "A multi featured Python terminal and vision toolkit"
9
+ readme = "README.md"
10
+ requires-python = ">=3.12"
11
+ dependencies = [
12
+ "psutil",
13
+ "watchdog",
14
+ "opencv-python",
15
+ "mediapipe==0.10.21",
16
+ "fer",
17
+ "tensorflow==2.17.0",
18
+ "protobuf==4.25.9",
19
+ "setuptools==81.0.0",
20
+ "python-chess"
21
+ ]
@@ -1,4 +1,4 @@
1
- __version__ = "1.2.2"
1
+ __version__ = "1.2.4"
2
2
 
3
3
  from .timers import start_countdown, start_stopwatch, run_interactive_timer
4
4
  from .art import print_hello
@@ -6,4 +6,6 @@ from .calculator import AdvancedCalculator
6
6
  from .games import RockPaperScissors
7
7
  from .chess_game import TerminalChess
8
8
  from .watcher import start_file_watcher
9
- from .monitor import monitor_performance
9
+ from .monitor import monitor_performance
10
+ from .reporter import generate_system_report
11
+ from .vision import VisionAnalyzer
@@ -0,0 +1,18 @@
1
+ import platform
2
+ import psutil
3
+ import datetime
4
+
5
+ def generate_system_report(filename="system_report.txt"):
6
+ """Generates a text report of the current system status."""
7
+ report = [
8
+ f"--- System Report ({datetime.datetime.now()}) ---",
9
+ f"OS: {platform.system()} {platform.release()}",
10
+ f"Processor: {platform.processor()}",
11
+ f"RAM: {round(psutil.virtual_memory().total / (1024**3), 2)} GB",
12
+ f"CPU Usage: {psutil.cpu_percent(interval=1)}%",
13
+ f"Disk Usage: {psutil.disk_usage('/').percent}%"
14
+ ]
15
+
16
+ with open(filename, "w") as f:
17
+ f.write("\n".join(report))
18
+ print(f"[*] Report saved to {filename}")
@@ -0,0 +1,187 @@
1
+ import cv2
2
+ import math
3
+ import time
4
+ import os
5
+
6
+ class VisionAnalyzer:
7
+ def __init__(self):
8
+ self.colors = {
9
+ "BLUE": (255, 0, 0),
10
+ "GREEN": (0, 255, 0),
11
+ "RED": (0, 0, 255),
12
+ "YELLOW": (0, 255, 255)
13
+ }
14
+
15
+ def analyze_image_file(self, img_path):
16
+ """Analyzes facial emotion from a static image file."""
17
+ from fer.fer import FER
18
+ if not os.path.exists(img_path):
19
+ raise FileNotFoundError(f"Image not found at: {img_path}")
20
+
21
+ detector = FER(mtcnn=False)
22
+ img = cv2.imread(img_path)
23
+ dominant_emotion, score = detector.top_emotion(img)
24
+
25
+ if dominant_emotion is None:
26
+ dominant_emotion = "Neutral"
27
+ score = 0.0
28
+
29
+ return dominant_emotion, score, img
30
+
31
+ def analyze_video_file(self, vid_path):
32
+ """Streams and analyzes facial emotion from a video file."""
33
+ from fer.fer import FER
34
+ if not os.path.exists(vid_path):
35
+ raise FileNotFoundError(f"Video not found at: {vid_path}")
36
+
37
+ detector = FER(mtcnn=False)
38
+ cap = cv2.VideoCapture(vid_path)
39
+
40
+ while cap.isOpened():
41
+ success, frame = cap.read()
42
+ if not success:
43
+ break
44
+
45
+ dominant_emotion, score = detector.top_emotion(frame)
46
+ if dominant_emotion is None:
47
+ dominant_emotion = "Neutral"
48
+ score = 0.0
49
+
50
+ expression_text = f"Emotion: {dominant_emotion.capitalize()} ({int(score * 100)}%)"
51
+ cv2.putText(frame, expression_text, (30, 40), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 255), 2)
52
+
53
+ cv2.imshow('Video Emotion Analysis', frame)
54
+ if cv2.waitKey(25) & 0xFF == ord('q'):
55
+ break
56
+
57
+ cap.release()
58
+ cv2.destroyAllWindows()
59
+
60
+ def run_air_canvas(self, run_draw=True, run_emotion=True):
61
+ """Runs the live webcam pipeline for Air Canvas and/or Emotion Detection."""
62
+ from fer.fer import FER
63
+ import mediapipe as mp
64
+
65
+ emotion_detector = FER(mtcnn=False) if run_emotion else None
66
+ mp_hands = mp.solutions.hands if run_draw else None
67
+ mp_drawing = mp.solutions.drawing_utils if run_draw else None
68
+
69
+ strokes = []
70
+ current_stroke = []
71
+ cap = cv2.VideoCapture(0)
72
+
73
+ PINCH_THRESHOLD = 42
74
+ ERASER_RADIUS = 35
75
+ is_drawing = False
76
+ tool_mode = "DRAW"
77
+ current_color_name = "GREEN"
78
+ current_color = self.colors[current_color_name]
79
+
80
+ save_message_timer = 0
81
+ prev_ix, prev_iy = 0, 0
82
+ smoothing_factor = 0.5
83
+
84
+ hands_obj = mp_hands.Hands(min_detection_confidence=0.75, min_tracking_confidence=0.75) if run_draw else None
85
+
86
+ try:
87
+ while cap.isOpened():
88
+ success, frame = cap.read()
89
+ if not success:
90
+ continue
91
+
92
+ frame = cv2.flip(frame, 1)
93
+ h, w, _ = frame.shape
94
+ rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
95
+
96
+ expression_text = ""
97
+ expression_color = (200, 200, 200)
98
+
99
+ if run_emotion and emotion_detector:
100
+ dominant_emotion, score = emotion_detector.top_emotion(frame)
101
+ if dominant_emotion is None:
102
+ dominant_emotion = "Neutral"
103
+ score = 0.0
104
+ expression_text = f"Emotion: {dominant_emotion.capitalize()} ({int(score * 100)}%)"
105
+ expression_color = (0, 255, 255) if dominant_emotion == "happy" else (200, 200, 200)
106
+
107
+ if run_draw:
108
+ box_width, box_height, box_y = 90, 40, 15
109
+ palette_x = 50
110
+
111
+ for name, col in self.colors.items():
112
+ thickness = 3 if current_color_name == name and tool_mode == "DRAW" else 1
113
+ cv2.rectangle(frame, (palette_x, box_y), (palette_x + box_width, box_y + box_height), col, -1)
114
+ cv2.rectangle(frame, (palette_x, box_y), (palette_x + box_width, box_y + box_height), (255, 255, 255), thickness)
115
+ cv2.putText(frame, name, (palette_x + 10, box_y + 26), cv2.FONT_HERSHEY_SIMPLEX, 0.45, (255, 255, 255), 1)
116
+ palette_x += 105
117
+
118
+ mode_text = f"MODE: DRAW | Color: {current_color_name} ('e' to Erase)" if tool_mode == "DRAW" else "MODE: ERASER ('e' to Draw)"
119
+ mode_color = current_color if tool_mode == "DRAW" else (0, 165, 255)
120
+
121
+ hand_results = hands_obj.process(rgb_frame)
122
+ if hand_results.multi_hand_landmarks:
123
+ for hand_landmarks in hand_results.multi_hand_landmarks:
124
+ mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)
125
+ thumb_tip = hand_landmarks.landmark[4]
126
+ index_tip = hand_landmarks.landmark[8]
127
+
128
+ raw_ix, raw_iy = int(index_tip.x * w), int(index_tip.y * h)
129
+ tx, ty = int(thumb_tip.x * w), int(thumb_tip.y * h)
130
+
131
+ ix = int(prev_ix * smoothing_factor + raw_ix * (1 - smoothing_factor))
132
+ iy = int(prev_iy * smoothing_factor + raw_iy * (1 - smoothing_factor))
133
+ prev_ix, prev_iy = ix, iy
134
+
135
+ distance = math.hypot(ix - tx, iy - ty)
136
+
137
+ if iy < box_y + box_height + 10:
138
+ p_x = 50
139
+ for name in self.colors.keys():
140
+ if p_x <= ix <= p_x + box_width:
141
+ current_color_name = name
142
+ current_color = self.colors[name]
143
+ tool_mode = "DRAW"
144
+ p_x += 105
145
+ else:
146
+ if tool_mode == "DRAW":
147
+ if distance < PINCH_THRESHOLD:
148
+ cv2.circle(frame, (ix, iy), 10, current_color, -1)
149
+ if not is_drawing:
150
+ is_drawing = True
151
+ current_stroke = []
152
+ strokes.append((current_stroke, current_color))
153
+ current_stroke.append((ix, iy))
154
+ else:
155
+ cv2.circle(frame, (ix, iy), 8, (0, 0, 255), -1)
156
+ is_drawing = False
157
+ elif tool_mode == "ERASER":
158
+ cv2.circle(frame, (ix, iy), ERASER_RADIUS, (0, 165, 255), 2)
159
+ if distance < PINCH_THRESHOLD:
160
+ cv2.circle(frame, (ix, iy), ERASER_RADIUS, (0, 165, 255), -1)
161
+ for stroke_pts, _ in strokes:
162
+ stroke_pts[:] = [pt for pt in stroke_pts if math.hypot(pt[0] - ix, pt[1] - iy) > ERASER_RADIUS]
163
+ strokes = [s for s in strokes if len(s[0]) > 0]
164
+ else:
165
+ is_drawing = False
166
+
167
+ for stroke_pts, col in strokes:
168
+ for i in range(1, len(stroke_pts)):
169
+ cv2.line(frame, stroke_pts[i - 1], stroke_pts[i], col, 4)
170
+
171
+ if run_emotion:
172
+ cv2.putText(frame, expression_text, (w - 380, 40), cv2.FONT_HERSHEY_SIMPLEX, 0.6, expression_color, 2)
173
+
174
+ cv2.imshow('Batch24-28 Vision Pipeline', frame)
175
+
176
+ key = cv2.waitKey(1) & 0xFF
177
+ if key == ord('q'):
178
+ break
179
+ elif key == ord('c') and run_draw:
180
+ strokes.clear()
181
+ elif key == ord('e') and run_draw:
182
+ tool_mode = "ERASER" if tool_mode == "DRAW" else "DRAW"
183
+ finally:
184
+ if hands_obj:
185
+ hands_obj.close()
186
+ cap.release()
187
+ cv2.destroyAllWindows()
@@ -0,0 +1,40 @@
1
+ import tkinter as tk
2
+ from tkinter import filedialog
3
+ import shutil
4
+ import os
5
+ import time
6
+ from watchdog.observers import Observer
7
+ from watchdog.events import FileSystemEventHandler
8
+
9
+ def choose_save_location(original_filename):
10
+ root = tk.Tk()
11
+ root.withdraw()
12
+ file_path = filedialog.asksaveasfilename(
13
+ defaultextension=".txt",
14
+ initialfile=original_filename,
15
+ title="Select where to save the backup"
16
+ )
17
+ root.destroy()
18
+ return file_path
19
+
20
+ class ChangeHandler(FileSystemEventHandler):
21
+ def on_modified(self, event):
22
+ if not event.is_directory:
23
+ print(f"[!] Change detected: {event.src_path}")
24
+ target_path = choose_save_location(os.path.basename(event.src_path))
25
+ if target_path:
26
+ shutil.copy2(event.src_path, target_path)
27
+ print(f"[*] File saved to: {target_path}")
28
+
29
+ def start_file_watcher(path="."):
30
+ event_handler = ChangeHandler()
31
+ observer = Observer()
32
+ observer.schedule(event_handler, path, recursive=False)
33
+ observer.start()
34
+ print(f"[*] Watching directory: {path}")
35
+ try:
36
+ while True:
37
+ time.sleep(1)
38
+ except KeyboardInterrupt:
39
+ observer.stop()
40
+ observer.join()
@@ -1,3 +1,19 @@
1
+ Metadata-Version: 2.4
2
+ Name: batch24-28
3
+ Version: 1.2.4
4
+ Summary: A multi featured Python terminal and vision toolkit
5
+ Requires-Python: >=3.12
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: psutil
8
+ Requires-Dist: watchdog
9
+ Requires-Dist: opencv-python
10
+ Requires-Dist: mediapipe==0.10.21
11
+ Requires-Dist: fer
12
+ Requires-Dist: tensorflow==2.17.0
13
+ Requires-Dist: protobuf==4.25.9
14
+ Requires-Dist: setuptools==81.0.0
15
+ Requires-Dist: python-chess
16
+
1
17
 
2
18
  # batch24-28
3
19
 
@@ -113,7 +129,20 @@ monitor_performance(threshold=80)
113
129
 
114
130
  ---
115
131
 
116
- ### 8. System Performance Sentinel
132
+ ### 8. System Information Reporter
133
+
134
+ Generates a comprehensive snapshot of system hardware and environment status.
135
+
136
+ ```python
137
+ from batch24_28 import generate_system_report
138
+
139
+ # Generate report to a file
140
+ generate_system_report("system_report.txt")
141
+ ```
142
+
143
+ ---
144
+
145
+ ### 9. System Performance Sentinel
117
146
 
118
147
  Monitor a directory for file system changes (created, modified, or deleted).
119
148
 
@@ -122,4 +151,26 @@ from batch24_28 import start_file_watcher
122
151
 
123
152
  # Watch the current directory
124
153
  start_file_watcher(path=".")
125
- ```
154
+ ```
155
+
156
+ ---
157
+
158
+ ### 10. Computer Vision & Emotion Analysis Toolkit
159
+
160
+ An interactive computer vision pipeline powered by MediaPipe hand-tracking and deep learning emotion recognition. Includes virtual mid-air drawing (Air Canvas) and facial expression tracking via webcam, static images, or video files.
161
+
162
+ ```python
163
+ from batch24_28 import VisionAnalyzer
164
+
165
+ analyzer = VisionAnalyzer()
166
+
167
+ # Option A: Run live Air Canvas and Emotion detection via webcam
168
+ analyzer.run_air_canvas(run_draw=True, run_emotion=True)
169
+
170
+ # Option B: Analyze facial expression from a static image file
171
+ emotion, score, img = analyzer.analyze_image_file("path_to_image.jpg")
172
+ print(f"Detected: {emotion} ({int(score * 100)}%)")
173
+
174
+ # Option C: Stream and analyze a video file for expressions
175
+ analyzer.analyze_video_file("path_to_video.mp4")
176
+ ```
@@ -7,7 +7,9 @@ src/batch24_28/chess_game.py
7
7
  src/batch24_28/from .py
8
8
  src/batch24_28/games.py
9
9
  src/batch24_28/monitor.py
10
+ src/batch24_28/reporter.py
10
11
  src/batch24_28/timers.py
12
+ src/batch24_28/vision.py
11
13
  src/batch24_28/watcher.py
12
14
  src/batch24_28.egg-info/PKG-INFO
13
15
  src/batch24_28.egg-info/SOURCES.txt
@@ -0,0 +1,9 @@
1
+ psutil
2
+ watchdog
3
+ opencv-python
4
+ mediapipe==0.10.21
5
+ fer
6
+ tensorflow==2.17.0
7
+ protobuf==4.25.9
8
+ setuptools==81.0.0
9
+ python-chess
@@ -1,10 +0,0 @@
1
- [project]
2
- name = "batch24-28"
3
- version = "1.2.2"
4
- description = "A multi featured Python terminal"
5
- readme = "README.md"
6
- requires-python = ">=3.7"
7
- dependencies = [
8
- "psutil",
9
- "watchdog",
10
- ]
@@ -1,24 +0,0 @@
1
- import time
2
- from watchdog.observers import Observer
3
- from watchdog.events import FileSystemEventHandler
4
-
5
- class ChangeHandler(FileSystemEventHandler):
6
- def on_modified(self, event):
7
- if not event.is_directory:
8
- print(f"\n[!] Change detected: {event.src_path}")
9
- # Add your custom logic here (e.g., auto-backup, alert, etc.)
10
-
11
- def start_file_watcher(path="."):
12
- """Starts a watcher that monitors a directory for changes."""
13
- print(f"[*] Watching directory: {path}")
14
- event_handler = ChangeHandler()
15
- observer = Observer()
16
- observer.schedule(event_handler, path, recursive=False)
17
- observer.start()
18
- try:
19
- while True:
20
- time.sleep(1)
21
- except KeyboardInterrupt:
22
- observer.stop()
23
- print("\n[*] Watcher stopped.")
24
- observer.join()
@@ -1,2 +0,0 @@
1
- psutil
2
- watchdog
File without changes