Baby Language Lab Scripts
A collection of data processing tools.
 All Classes Namespaces Files Functions Variables Pages
check2.py
Go to the documentation of this file.
1 ## @package data_structs.check2
2 
3 from data_structs.base_objects import DBObject
4 from db.bll_database import DBConstants
5 from data_structs.test2 import Test2
6 from datetime import datetime
7 
8 import pickle
9 
10 ## This class represents one trial's worth of data for the reliability2 app.
12  ## Constructor
13  # @param self
14  # @param csv_filename (string) path to the csv file that will be used - blocks will be picked from this file and presented to the user (see parsers.csv_parser for a list of the columns that must be present. In addition to those, we also need "environment" and "activity" columns.)
15  # @param wav_foldername (string) path to a folder containing all the wav files that correspond to blocks that could be picked from the csv file
16  # @param activities (list) list of strings, one for each activity that will be run (within each environment). E.g. ['mealtime', 'playtime', ...]
17  # @param environments (list) list of strings, one for each environment that will be run. E.g ['home', 'daycare centre', ...]
18  # @param blocks_per_activity (int) the number of 5 minute blocks that will be picked for each activity (blocks will be picked for each activity, separately for each environment)
19  # @param completed (string=None) timestamp string representing the date/time when this check2 was completed. Is None if it has not yet been completed by the user.
20  # @param created (string=None) timestamp string representing the date/time when this check2 was created by the user. This is assigned by the database in the insert() method. So if the check2 is not in the DB, this may be None.
21  # @param modified (string=None) timestamp string representing the last time this check2 was modified by the user. For example, the last time the progress in the application was saved when working on this check. This is assigned by the DB. It will be None if the check2 has never been saved in an incomplete trial. It is possible for check2s to be completed, but not modified (if the user goes through the whole trial without saving/quitting).
22  # @param test2s (list=[]) a list of all the Test2 data structure objects for this trial. Each Test2 object represents (and contains all the data for) the input for a single block that the user has completed.
23  # @param test2_index (int=0) the index we are currently sitting at in the test2 list (previous param). This information is used to restore the state of the app to where the user left off, when a saved check2 is loaded back up.
24  # @param db_id (int=None) the primary key value of this check2 in the check2 database table. In general, code should not set this. It's set from db_select(), and upon db_insert(). Will be None if object is not yet in the DB.
25  def __init__(
26  self,
27  csv_filename,
28  wav_foldername,
29  activities, #array
30  environments, #array
31  blocks_per_activity,
32  completed=None, #timestamp
33  created=None, #timestamp
34  modified=None, #timestamp
35  test2s=[], #array of Test2 objects
36  test2_index=0, #index of the test2 to display in the UI
37  db_id=None
38  ):
39 
40  super(Check2, self).__init__()
41 
42  self.csv_filename = csv_filename
43  self.wav_foldername = wav_foldername
44  self.activities = activities
45  self.environments = environments
46  self.blocks_per_activity = blocks_per_activity
47  self.completed = completed
48  self.created = created
49  self.modified = modified
50  self.test2s = test2s
51  self.test2_index = test2_index
52  self.db_id = db_id
53 
54  ## Overwrites the completed timestamp (both in the DB and the object attribute for this instance) with the current date/time.
55  # @param self
56  # @param db (BLLDatabase) a database object
57  def update_completed(self, db):
58  #allow the DB to set the timestamp value
59  self._update_timestamp(db, 'completed')
60  #then re-select it and update the instance attribute
61  self.completed = db.select('checks2', ['datetime(completed,\'localtime\')'], 'id=?', [self.db_id])
62 
63  ## Overwrites the modified timestamp (both in the DB and the object attribute for this instance) with the current date/time.
64  # @param self
65  # @param db (BLLDatabase) a database object
66  def update_modified(self, db):
67  #allow the DB to set the timestamp value
68  self._update_timestamp(db, 'modified')
69  #select it back and update the instance attribute
70  self.modified = db.select('checks2', ['datetime(modified,\'localtime\')'], 'id=?', [self.db_id])
71 
72  ## Updates the test2_index value in the database. It is set to the current value for this instance. If the instance is not already in the dd, an exception is raised.
73  # @param self
74  # @param db (BLLDatabase) a database object
75  def update_test2_index(self, db):
76  if self.db_id != None:
77  db.update('checks2', ['test2_index'], 'id=?', [self.test2_index, self.db_id])
78  else:
79  raise Exception('Cannot update test2_index on Check2 instance that is not in the databse.')
80 
81  ## Performs a db update of a timestamp column, setting it to the date/time at the point this method is executed. If this instance is not already in the db, an exception is raised.
82  # @param self
83  # @param db (BLLDatabase) a database object
84  # @param col (string) name of the timestamp column from the checks2 database table to update.
85  def _update_timestamp(self, db, col):
86  if self.db_id != None:
87  db.update_timestamp_col('checks2', col, 'id=?', [self.db_id])
88  else:
89  raise Exception('Cannot update timestamp because Check2 instance is not in the database.')
90 
91  ## See superclass description.
92  # If any of this instance's test2 objects are not yet in the DB, this method will insert them as well.
93  def db_insert(self, db):
94  super(Check2, self).db_insert(db)
95 
96  cols = 'csv_file wav_folder activities environments blocks_per_activity completed test2_index'.split() #omit the 'modified' and 'created' columns - they will default to current timestamp
97 
98  #pickle the lists of activities and environments (convert them to a format in which we can just store the object instance in the database), as they are of variable length.
99  row = [self.csv_filename, self.wav_foldername, pickle.dumps(self.activities), pickle.dumps(self.environments), self.blocks_per_activity, self.completed, self.test2_index]
100 
101  #grab the last inserted id and use it to assign this object's db_id
102  last_ids = db.insert('checks2', cols, [row])
103  self.db_id = last_ids[0]
104 
105  #re-select and update this instance's timestamp attributes (these are always assigned by the DB)
106  checks2_rows = db.select('checks2', ["datetime(created,'localtime')", "datetime(modified,'localtime')"], 'id=?', [str(self.db_id)])
107  self.created = datetime.strptime(checks2_rows[0][0], DBConstants.DB_DATETIME_FMT)
108  self.modified = datetime.strptime(checks2_rows[0][1], DBConstants.DB_DATETIME_FMT)
109 
110  #ensure that all of this check2's test2 objects are in the DB
111  if self.test2s:
112  for t in self.test2s:
113  if t.db_id == None:
114  t.db_insert(db)
115 
116  ## See superclass description.
117  def db_delete(self, db):
118  super(Check2, self).db_delete(db)
119 
120  #this will cascade and remove all corresponding test2 rows
121  num_rows = db.delete('checks2', 'id=?', [self.db_id])
122  if num_rows == 1:
123  self.db_id = None
124 
125  return num_rows
126 
127  ## See superclass description.
128  @staticmethod
129  def db_select(db, ids=[]):
130  DBObject.db_select(db, ids)
131 
132  #build the SQL where clause using the ids passed in
133  where_cond = DBObject._build_where_cond_from_ids(ids)
134 
135  #do the select to retrieve the a list of raw data
136  rows = db.select('checks2', 'csv_file wav_folder activities environments blocks_per_activity datetime(completed,\'localtime\') datetime(created,\'localtime\') datetime(modified,\'localtime\') test2_index id'.split(), where_cond)
137 
138  #create Check2 objects from the selected data and return them
139  check2_list = []
140  for cur_row in rows:
141  #each check2 has zero or more Test2s, which can be retrieved using this static method
142  test2s = Test2.db_select_by_check2(db, cur_row[9])
143 
144  check2 = Check2(
145  cur_row[0],
146  cur_row[1],
147  #un-pickle the lists of activities and environments (the loads() call will return an instance of a list)
148  pickle.loads(cur_row[2]),
149  pickle.loads(cur_row[3]),
150  cur_row[4],
151  cur_row[5],
152  cur_row[6],
153  cur_row[7],
154  test2s,
155  cur_row[8],
156  cur_row[9]
157  )
158 
159  check2_list.append(check2)
160 
161  return check2_list