from collections.abc import Collection import pandas as pd from config.models import Participant, Screen from setup import db_engine, session screen_status = {0: "off", 1: "on", 2: "locked", 3: "unlocked"} def get_screen_data(usernames: Collection) -> pd.DataFrame: """ Read the data from the screen table and return it in a dataframe. Parameters ---------- usernames: Collection A list of usernames to put into the WHERE condition. Returns ------- df_screen: pd.DataFrame A dataframe of screen data. """ query_screen = ( session.query(Screen, Participant.username) .filter(Participant.id == Screen.participant_id) .filter(Participant.username.in_(usernames)) ) with db_engine.connect() as connection: df_screen = pd.read_sql(query_screen.statement, connection) return df_screen def identify_screen_sequence(df_screen: pd.DataFrame) -> pd.DataFrame: # TODO Implement a method that identifies "interesting" sequences of screen statuses. # The main one are: # - OFF -> ON -> unlocked (a true phone unlock) # - OFF -> ON -> OFF/locked (no unlocking, i.e. a screen status check) # Consider that screen data is sometimes unreliable as shown in expl_screen.ipynb: # "I have also seen # off -> on -> unlocked (with 2 - locked missing) # and # off -> locked -> on -> off -> locked (*again*)." # Either clean the data beforehand or deal with these inconsistencies in this function. pass def time_screen_sequence(df_screen: pd.DataFrame) -> pd.DataFrame: # TODO Use the results of indentify_screen_sequence to calculate time statistics related to transitions. # For example, from the two main sequences outlined above, the time of "real" phone usage can be calculated, # i.e. how long the screen was unlocked. # Another example might be the average time between screen unlocks and/or screen status checks. pass