كيف لا تضيع مرور الوقت في العمل على الكمبيوتر. تطبيق لرصد العمل والحفاظ على الإحصائيات





أعمل مدرسًا في حديقة كوانتوريوم لتكنولوجيا الأطفال. خلال فترة العزلة الذاتية ، تحولنا ، مثل أي شخص آخر ، إلى التعلم عن بعد. ونظرًا لحقيقة أن الأطفال بدأوا يقضون وقتًا أطول على الكمبيوتر ، قررت الإدارة تقصير الساعة الأكاديمية وأخذ فترات راحة بين العمل - للحفاظ على بصرهم. لقد كتبنا تطبيقًا يحسب الوقت الذي يقضيه الكمبيوتر ، ويحافظ على الإحصاءات في Excel - مفيد للآباء ، ويعطي تنبيهًا مسموعًا عندما يحين وقت الراحة.



سيكون التطبيق مفيدًا لأولئك الذين ضاعوا وقتًا في العمل على الكمبيوتر الشخصي ويريدون قيادة أنفسهم في الإطار الزمني أو تتبع أي جزء من الحياة ضاع في الفضاء الرقمي.



ربط المستودع



تحت قطع تحليل مفصل.



لإنشاء برنامج ، تحتاج إلى حل المهام التالية:



  • web ( mtcnn);
  • ( time)
  • excel ( openpyxl);
  • ;
  • .


web



نظرنا في خيار تتبع التواجد على الكمبيوتر عن طريق حركة فأرة الكمبيوتر ، ربما يكون ذلك أسهل وستظل كاميرا الويب مجانية ، ولكن بعد ذلك لن نتمكن من مراعاة مشاهدة البرامج التلفزيونية أو مقاطع فيديو youtube ، إلى جانب أن استخدام التعرف على الوجه أكثر إثارة للاهتمام.



لاكتشاف الوجه ، نستخدم بنية mtcnn. رأس يقع في أي زاوية ، مرتديًا نظارات ، في ظروف الإضاءة السيئة ، حتى لو لم يكن الوجه في الإطار تمامًا أو مغطى باليد ، فإن الشبكة العصبية تعمل بشكل صحيح. لن نبنيها بمفردنا ، بل سنقوم بتوصيل المكتبة التي تحمل الاسم نفسه ، مما سيحل مشكلتنا باستخدام بضعة أسطر من التعليمات البرمجية.



في البداية ، تم استخدام طريقة فيولا جونز. الدقة أسوأ بكثير من دقة mtcnn ، يقوم المعالج بتحميل نفس الشيء.











لنأخذ ناتج النتيجة إلى دالة منفصلة ، هناك حاجة فقط لمعرفة كيفية عمل التعرف.



import cv2
import os
from mtcnn.mtcnn import MTCNN


def show_face_frame():
    if faces:
        bounding_box = faces[0]['box']
        keypoints = faces[0]['keypoints']
        cv2.rectangle(img,
                      (bounding_box[0], bounding_box[1]),
                      (bounding_box[0] + bounding_box[2], 
                      bounding_box[1] + bounding_box[3]),
                      (0, 0, 255),
                      2)
        cv2.circle(img, (keypoints['left_eye']), 3, (0, 0, 255), 2)
        cv2.circle(img, (keypoints['right_eye']), 2, (0, 0, 255), 2)
        cv2.circle(img, (keypoints['nose']), 3, (0, 0, 255), 2)
        cv2.circle(img, (keypoints['mouth_left']), 3, (0, 0, 255), 2)
        cv2.circle(img, (keypoints['mouth_right']), 3, (0, 0, 255), 2)
    cv2.imshow('frame', img)

cap = cv2.VideoCapture(0)
detector = MTCNN()

while cap.isOpened():
        _, img = cap.read()
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        faces = detector.detect_faces(img)
        show_face_frame()
        cv2.waitKey(300)

cap.release()
cv2.destroyAllWindows()


تأخير كبير cv2.waitKey (300) حتى لا يتم تحميل المعالج. تؤدي معالجة 3-4 إطارات في الثانية إلى تحميل i3-8145U بمعدل 15٪.



عد الوقت



لا يجب على البرنامج الكتابة إلى السجل في الحالات التالية:



  • جلس أمام الكمبيوتر لمدة 5 ثوانٍ للقيام بشيء ما ؛
  • خرجت لصب القهوة أو شد ساقي.


لحل هذه المشاكل ، يستخدم البرنامج ساعتي توقف time_here (يحسب الوقت عندما يكون الوجه في الإطار) و time_not_here (عندما لا يكون هناك وجه). يتم إعادة ضبط كلتا ساعتي التوقف عند إجراء إدخال في السجل. بالإضافة إلى ذلك ، يتم إعادة تعيين time_not_here في كل مرة يظهر فيها وجه في الإطار. يشير



المتغير min_time_here إلى الحد الأدنى من الوقت الذي يقضيه الكمبيوتر ، وبعد ذلك يستحق الكتابة في السجل. سيتم التسجيل بعد تشتيت انتباه الشخص عن الكمبيوتر لفترة أطول من الوقت المحدد في min_time_not_here .



في الكود أدناه ، يتم التسجيل إذا أمضيت 5 دقائق على الأقل على الكمبيوتر. لن يأخذ البرنامج في الحسبان حقيقة أنني مشتت لأقل من دقيقتين.



import cv2
import time
import os
from mtcnn.mtcnn import MTCNN

cap = cv2.VideoCapture(0)
path = os.path.abspath(__file__)[:-11]  #      

here, not_here = 0, 0  # 
time_here, time_not_here = 0, 0  #  
switch = True  #        
min_time_here = 300  #     ,     ( ) 
min_time_not_here = 120  #          ( )

detector = MTCNN()

try:
    while cap.isOpened():
        _, img = cap.read()
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        faces = detector.detect_faces(img)
       show_face_frame()
       audio_message(path, here)

        if faces and switch:
            not_here = 0
            switch = False
            if here == 0:
                here = time.time()
                print('     ' + time.strftime("%H:%M:%S", time.localtime(here)))
        elif not faces and not switch:
            not_here = time.time()
            switch = True

        if not_here != 0:
            time_not_here = time.time() - not_here
        if here != 0 and not switch:
            time_here = time.time() - here

        if time_here > min_time_here and time_not_here > min_time_not_here:  #        min_time_here
            write_excel(path, here)
            print('    ' + time.strftime('%H:%M:%S', time.gmtime(time.time() - here)))
            time_here, time_not_here = 0, 0
            here, not_here = 0, 0
        elif time_not_here > min_time_not_here and  time_here < min_time_here:  #      min_time_here,    
            print('  ')
            time_here, time_not_here = 0, 0
            here, not_here = 0, 0

        cv2.waitKey(300)
except KeyboardInterrupt:
    if time_here > min_time_here:  #        min_time_here
        write_excel(path, here)
    cap.release()
    cv2.destroyAllWindows()


إذا أراد المستخدم إيقاف تشغيل الكمبيوتر ، فأنت بحاجة أولاً إلى مقاطعة البرنامج (ctrl + c) وسيتم تسجيل وقت العمل الحالي. لهذا ، يتم استخدام معالج استثناء.



كتابة البيانات إلى مستند Excel



للعمل مع برنامج Excel ، سوف تساعد مكتبة openpyxl الرائعة في قراءة البيانات وكتابتها في نفس الوقت.



كل يوم يقوم البرنامج بإنشاء ورقة جديدة بالتاريخ الحالي.





في ورقة واحدة ، يتم تسجيل المعلومات اليومية ، في أي يوم تم قضاء الوقت على الكمبيوتر. تفتح







وظيفة write_excel المستند وتكتب البيانات وتغلقه على الفور.



لا يمكنك تعديل مستند من خلال openpyxl إذا كان مفتوحًا بالفعل من قبل المستخدم. تم إضافة استثناء لهذه الحالة.



def write_excel(path_excel, time_start):
    wb = openpyxl.load_workbook(path_excel + r'\dnevnik.xlsx')
    today = time.strftime("%d.%m.%Y", time.localtime(time.time()))
    if today not in wb.sheetnames:  #        ,   
        wb.create_sheet(title=today)
        sheet = wb[today]
        sheet.column_dimensions['A'].width = 20
        sheet.column_dimensions['B'].width = 20
        sheet.column_dimensions['C'].width = 20
        sheet.column_dimensions['D'].width = 31
        sheet['A1'] = '   '
        sheet['B1'] = '   '
        sheet['C1'] = ' '
        sheet['D1'] = '  :'
        sheet['D2'] = '    :'
        sheet = wb[today]
        row = 2
        all_time = 0
    else:  #      
        sheet = wb[today]
        row = sheet['E1'].value  #    excel 
        all_time = sheet['E2'].value  #        
        all_time = all_time.split(':')
        all_time = int(all_time[0]) * 3600 + int(all_time[1]) * 60 + int(all_time[2])  #    
        row = row + 2  #      

    sheet['A' + str(row)] = time.strftime("%H:%M:%S", time.localtime(time_start))  #      
    sheet['C' + str(row)] = time.strftime("%H:%M:%S", time.localtime(time.time()))  #   - 
    seconds = time.time() - time_start  #      
    sheet['B' + str(row)] = time.strftime('%H:%M:%S', time.gmtime(seconds))
    sheet['E1'] = row - 1  #   
    all_time = all_time + seconds
    all_time = time.strftime('%H:%M:%S', time.gmtime(all_time))
    sheet['E2'] = all_time
    #   
    sheet_0 = wb.worksheets[0]
    sheet_0['A' + str(len(wb.sheetnames))] = today
    sheet_0['B' + str(len(wb.sheetnames))] = all_time
    while True:  #  
        try:
            wb.save(path_excel + r'\dnevnik.xlsx')
        except PermissionError:
            input('  excel     enter')
        else:
            break


تنبيه صوتي



من أجل التغيير ، قمنا بإنشاء 8 ملفات صوتية باستخدام آلة النطق ، والتي تعمل بشكل عشوائي بعد ساعة من العمل. حتى تأخذ استراحة ، لن تكون هناك تنبيهات صوتية متكررة.



def audio_message(path, here):
    if here == 0:
        pass
    elif time.strftime('%H:%M:%S', time.gmtime(time.time()-here)) == "01:00:00":
        wav = random.choice(os.listdir(path + r'\audio'))
        winsound.PlaySound(path + r'\audio\\' + wav, winsound.SND_FILENAME)


البرنامج النصي لبدء التشغيل عند تشغيل جهاز الكمبيوتر



لكي يتم تحميل البرنامج مع Windows ، يمكنك إنشاء ملف دفعي يقوم بتشغيل برنامج Python النصي. يجب أن يكون الملف الدفعي موجودًا في الدليل:



C: \ Users \٪ username٪ \ AppData \ Roaming \ Microsoft \ Windows \ Start Menu \ Programs \ Startup



نظرًا لأن الملف الدفعي والملف المصدر مخزنين في دلائل مختلفة ، فلا يمكنك استخدام os.getcwd ( ) لأنه سيعيد المسار إلى الملف الدفعي. نحن نستخدم os.path.abspath (__ file __) [: - 11]



UPD: ak545اقترح خيارًا أفضل os.path.dirname (os.path.abspath (__ file__))



في المستقبل



كنت أرغب في أن يتبع البرنامج وجهي ، وليس كل من يجلس على الكمبيوتر. لهذا الغرض ، سيتم استخدام FaceNet ، القادر على التعرف على الوجه.

هناك أيضًا خطط لتطوير عنصر واجهة مستخدم جميل بدلاً من وحدة تحكم سوداء قبيحة ، وعندما يتم إيقاف تشغيل الكمبيوتر ، يتم التسجيل تلقائيًا ، وليس باستخدام مقاطعة.

شكرآ لك على أهتمامك. إذا كانت لديك أسئلة ، فاكتب في التعليقات أو على https://www.linkedin.com/in/evg-voronov/



All Articles