CoolFace
Apppublic

Coder19/interview_system

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
monitor.py173 linesDownload Raw Back to services
1import time2from typing import List, Dict, Optional3import numpy as np4from datetime import datetime5 6class InterviewMonitor:7    def __init__(self):8        self.typing_patterns: List[Dict] = []9        self.response_times: List[float] = []10        self.suspicious_activities: List[Dict] = []11        self.last_activity_time = time.time()12        13    def reset(self):14        """Reset all monitoring data"""15        self.typing_patterns = []16        self.response_times = []17        self.suspicious_activities = []18        self.last_activity_time = time.time()19 20    def record_response_time(self, response_text: str) -> Optional[Dict]:21        """Monitor response time and length to detect potential cheating"""22        current_time = time.time()23        response_time = current_time - self.last_activity_time24        self.last_activity_time = current_time25        26        # Calculate words per minute27        words = len(response_text.split())28        wpm = (words / response_time) * 60 if response_time > 0 else float('inf')29        30        self.response_times.append(response_time)31        32        suspicious_activity = None33        34        # Check for unusually fast responses (more than 100 WPM)35        if wpm > 100:36            suspicious_activity = {37                'type': 'fast_response',38                'details': f'Unusually fast response: {wpm:.0f} words per minute',39                'severity': 'medium',40                'timestamp': datetime.now().isoformat()41            }42            43        # Check for very long responses that came too quickly44        if words > 50 and response_time < 10:45            suspicious_activity = {46                'type': 'potential_copypaste',47                'details': f'Long response ({words} words) in very short time ({response_time:.1f}s)',48                'severity': 'high',49                'timestamp': datetime.now().isoformat()50            }51            52        if suspicious_activity:53            self.suspicious_activities.append(suspicious_activity)54            55        return suspicious_activity56 57    def analyze_typing_pattern(self, keystrokes: List[Dict]) -> Optional[Dict]:58        """Analyze typing patterns to detect copy-paste or unusual input patterns"""59        if not keystrokes:60            return None61            62        # Calculate time between keystrokes63        intervals = []64        for i in range(1, len(keystrokes)):65            interval = keystrokes[i]['timestamp'] - keystrokes[i-1]['timestamp']66            intervals.append(interval)67            68        if not intervals:69            return None70            71        # Detect sudden bursts of text (potential copy-paste)72        avg_interval = np.mean(intervals)73        std_interval = np.std(intervals)74        75        suspicious_activity = None76        77        if any(interval > avg_interval + 3 * std_interval for interval in intervals):78            suspicious_activity = {79                'type': 'irregular_typing',80                'details': 'Detected irregular typing pattern, possible copy-paste',81                'severity': 'medium',82                'timestamp': datetime.now().isoformat()83            }84            self.suspicious_activities.append(suspicious_activity)85            86        return suspicious_activity87 88    def analyze_video_frame(self, frame_data: Dict) -> Optional[Dict]:89        """Analyze video frame to detect suspicious behavior"""90        suspicious_activity = None91        92        # Check if eyes are looking away from camera93        if frame_data.get('looking_away', False):94            suspicious_activity = {95                'type': 'looking_away',96                'details': 'Candidate frequently looking away from camera',97                'severity': 'low',98                'timestamp': datetime.now().isoformat()99            }100            101        # Check if multiple faces detected102        if frame_data.get('face_count', 1) > 1:103            suspicious_activity = {104                'type': 'multiple_faces',105                'details': f"Detected {frame_data['face_count']} faces in frame",106                'severity': 'high',107                'timestamp': datetime.now().isoformat()108            }109            110        if suspicious_activity:111            self.suspicious_activities.append(suspicious_activity)112            113        return suspicious_activity114 115    def analyze_audio(self, audio_data: Dict) -> Optional[Dict]:116        """Analyze audio to detect potential prompting or background voices"""117        suspicious_activity = None118        119        # Check for multiple voices120        if audio_data.get('voice_count', 1) > 1:121            suspicious_activity = {122                'type': 'multiple_voices',123                'details': 'Detected multiple voices in audio',124                'severity': 'high',125                'timestamp': datetime.now().isoformat()126            }127            128        # Check for background conversation129        if audio_data.get('background_speech', False):130            suspicious_activity = {131                'type': 'background_speech',132                'details': 'Detected background conversation',133                'severity': 'medium',134                'timestamp': datetime.now().isoformat()135            }136            137        if suspicious_activity:138            self.suspicious_activities.append(suspicious_activity)139            140        return suspicious_activity141 142    def get_cheating_report(self) -> Dict:143        """Generate a report of all suspicious activities"""144        severity_counts = {145            'high': len([a for a in self.suspicious_activities if a['severity'] == 'high']),146            'medium': len([a for a in self.suspicious_activities if a['severity'] == 'medium']),147            'low': len([a for a in self.suspicious_activities if a['severity'] == 'low'])148        }149        150        return {151            'total_suspicious_activities': len(self.suspicious_activities),152            'severity_breakdown': severity_counts,153            'activities': self.suspicious_activities,154            'average_response_time': np.mean(self.response_times) if self.response_times else 0,155            'recommendation': self._generate_recommendation(severity_counts)156        }157        158    def _generate_recommendation(self, severity_counts: Dict) -> str:159        """Generate a recommendation based on suspicious activities"""160        total_weighted_score = (161            severity_counts['high'] * 3 +162            severity_counts['medium'] * 2 +163            severity_counts['low'] * 1164        )165        166        if total_weighted_score == 0:167            return "No suspicious activities detected. Interview appears to be conducted fairly."168        elif total_weighted_score < 3:169            return "Minor suspicious activities detected. Manual review recommended."170        elif total_weighted_score < 6:171            return "Multiple suspicious activities detected. Close review strongly recommended."172        else:173            return "Significant suspicious activities detected. Interview validity questionable."