Browse files

Threw the old version up there for comparison. Posterity.

  • Loading branch information...
1 parent b9740da commit f5311e3bc49bb21fe01195370d04e6388f102b67 @josefski committed Apr 16, 2012
Showing with 723 additions and 0 deletions.
  1. +723 −0 oldobservatory.py
View
723 oldobservatory.py
@@ -0,0 +1,723 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#layouts generated by wxGlade 0.6.3 on Mon Apr 9 14:15:10 2012
+#wxGlade only did the layout! The rest of the code is mine!!!!
+
+#Author: Josef Hoffman (c) 2012
+
+import wx
+
+# begin wxGlade: extracode
+# end wxGlade
+
+import csv
+import time
+from time import strftime
+import os.path
+
+#Lots of lists in this program. Some of them are written to a css file, others are just a convenient place
+#to store certain integer values and reliably count events that occur across multiple iterations
+#of the same function.
+
+a = [] #time_event stores the integer "1" in this list every time it's called by the "TIME" button.
+ot = [] #First statement in time_event sticks the system time up here as an integer, the second if statement pops it and subtracts it from the current system time
+oft = [] #Oops, I repeated myself. Forgive me; I'm new at this. Does the same thing as ot, but for the next two if statements.
+OnTask = ['On Task' ] #gets written to css
+OffTask = ['Off Task' ]#to css
+off=[] #stores integer everytime off_task if statement is run, "length" counts how long it is and is used to return the integer to the user
+on=[] #same as above, only for the other if statement.
+ontotal=[] #store total number of events to place at bottom of txt file
+offtotal=[]
+
+#These lists stor all the values needed for the redirect and repetitive event counters.
+slf_rdr=["SELF"] #Writes to the csv file, also used to track number of redirects
+peer_rdr=["PEER"] #same functionality as above, different event
+tchr_rdr=["TEACHER"] #''
+rdr_peer=["REDIRECTED"] #''
+redirect_times=[] #stores the system time of each redirect
+redirect_interval=[] #stores the intervals between each redirect event
+interval_labels=[] #gives me labels 'self' 'teacher' 'peer' to help me label the intervals inside the csv file
+
+#These were a lot of fun to code.
+rpt1=[] #These store the name and system time for each user defined repeat event
+rpt2=[]
+rpt3=[]
+rpt1i=[] #These store the result of some basic subtraction that returns the intervals between each repeated event
+rpt2i=[]
+rpt3i=[]
+rpt1n=[] #store the system time for each user defined repeat event and the function subtracts it from the current system time to determine the intervals
+rpt2n=[]
+rpt3n=[]
+
+# I had wxGlade do most of the layout yak shaving for me. I must admit I'm impressed with the results.
+class Dialog1(wx.Dialog):
+ def __init__(self, *args, **kwds):
+ # begin wxGlade: Dialog1.__init__
+ kwds["style"] = wx.DEFAULT_DIALOG_STYLE
+ wx.Dialog.__init__(self, *args, **kwds)
+ self.welcome = wx.StaticText(self, -1, "Thank you for using FBA Machine. \nStart by entering the first and last \nnames of the student and then your name.")
+ self.first_name_txt = wx.TextCtrl(self, -1, "Enter Student First Name Here")
+ self.last_name_txt = wx.TextCtrl(self, -1, "Enter Student Last Name Here")
+ self.observer_first = wx.TextCtrl(self, -1, "Enter Your Name Here")
+ self.static_line_1 = wx.StaticLine(self, -1)
+ self.save_names = wx.Button(self, -1, "Fill Out Information Above, Then Press Here")
+ self.label_directions = wx.StaticText(self, -1, "The widget underneath this message\nis the task timer. Push the \"TIME\" button \nand see what happens.")
+ self.static_line_2 = wx.StaticLine(self, -1)
+ self.time_button = wx.Button(self, -1, "TIME")
+ self.notes_box = wx.TextCtrl(self, -1, "\n", style=wx.TE_MULTILINE|wx.TE_LINEWRAP|wx.TE_WORDWRAP)
+ self.save_quit = wx.Button(self, -1, "Save and Quit")
+ self.re_title = wx.StaticText(self, -1, "Record Repetitive Events")
+ self.re_txt_1 = wx.TextCtrl(self, -1, "Repetitive Event")
+ self.count_1 = wx.Button(self, -1, "Record")
+ self.re_txt_2 = wx.TextCtrl(self, -1, "Repetitive Event")
+ self.count_2 = wx.Button(self, -1, "Record")
+ self.re_txt_3 = wx.TextCtrl(self, -1, "Repetitive Event ")
+ self.count_3 = wx.Button(self, -1, "Record")
+ self.static_line_rep = wx.StaticLine(self, -1)
+ self.rd_title = wx.StaticText(self, -1, "Record Redirects")
+ self.slf_rd_btn = wx.Button(self, -1, "Self Redirect")
+ self.slf_rd_cnt = wx.StaticText(self, -1, "0")
+ self.pr_rd_btn = wx.Button(self, -1, "Peer Redirect")
+ self.pr_rd_cnt = wx.StaticText(self, -1, "0")
+ self.tch_rd_btn = wx.Button(self, -1, "Teacher Redirect")
+ self.tch_rd_cnt = wx.StaticText(self, -1, "0")
+ self.rd_pr_btn = wx.Button(self, -1, "Redirected Peer")
+ self.rd_pr_cnt = wx.StaticText(self, -1, "0")
+ self.hint = wx.StaticText(self, -1, "\nHINT: You can use\nTAB and SHIFT + TAB\nto navigate around\nthe application and \"ENTER\"\nto activate buttons.")
+ self.re_1_lbl = wx.StaticText(self, -1, "Repetive Event Count ")
+ self.cnt_1 = wx.StaticText(self, -1, "0")
+ self.re_2_lbl = wx.StaticText(self, -1, "Repetive Event Count")
+ self.cnt_2 = wx.StaticText(self, -1, "0")
+ self.re_3_lbl = wx.StaticText(self, -1, "Repetitive Event Count")
+ self.cnt_3 = wx.StaticText(self, -1, "0")
+ self.setting_events = wx.StaticText(self, -1, "Record Setting Events")
+ self.setting_get = wx.TextCtrl(self, -1, "", style=wx.TE_MULTILINE|wx.TE_LINEWRAP|wx.TE_WORDWRAP)
+ self.help = wx.Button(self, -1, "Read Me")
+ self.about = wx.Button(self, -1, "About")
+ self.Copyright = wx.StaticText(self, -1, "Josef Hoffman\n(C) 2012")
+ self.bitmap_1 = wx.StaticBitmap(self, -1, wx.Bitmap("/home/josef/Behavior-Observatory/gplv3-127x51.png", wx.BITMAP_TYPE_ANY))
+
+ self.__set_properties()
+ self.__do_layout()
+ # end wxGlade
+
+#Back to my code again. These keep the user from interacting with the application before they've told it where to save their files.
+ self.time_button.Enable(False)
+ self.save_quit.Enable(False)
+ self.slf_rd_btn.Enable(False)
+ self.tch_rd_btn.Enable(False)
+ self.pr_rd_btn.Enable(False)
+ self.rd_pr_btn.Enable(False)
+ self.count_1.Enable(False)
+ self.count_2.Enable(False)
+ self.count_3.Enable(False)
+
+#Binding all the buttons to a function.
+ self.Bind(wx.EVT_BUTTON, self.time_event, self.time_button)
+ self.Bind(wx.EVT_BUTTON, self.filefunc, self.save_quit)
+ self.Bind(wx.EVT_BUTTON, self.header, self.save_names)
+ self.Bind(wx.EVT_BUTTON, self.self_redirect, self.slf_rd_btn)
+ self.Bind(wx.EVT_BUTTON, self.peer_redirect, self.pr_rd_btn)
+ self.Bind(wx.EVT_BUTTON, self.teacher_redirect, self.tch_rd_btn)
+ self.Bind(wx.EVT_BUTTON, self.redirect_peer, self.rd_pr_btn)
+ self.Bind(wx.EVT_BUTTON, self.repeat_behavior_1, self.count_1)
+ self.Bind(wx.EVT_BUTTON, self.repeat_behavior_2, self.count_2)
+ self.Bind(wx.EVT_BUTTON, self.repeat_behavior_3, self.count_3)
+ self.Bind(wx.EVT_BUTTON, self.OnAboutBox, self.about)
+
+#More of the wxGlade free yak grooming service. My code starts again on line 222.
+ def __set_properties(self):
+ # begin wxGlade: Dialog1.__set_properties
+ self.SetTitle("Behavior Observatory")
+ self.first_name_txt.SetMinSize((250, 28))
+ self.last_name_txt.SetMinSize((250, 28))
+ self.observer_first.SetMinSize((200, 28))
+ self.time_button.SetMinSize((300, 30))
+ self.notes_box.SetMinSize((300, 150))
+ self.save_quit.SetMinSize((300, 30))
+ self.re_txt_1.SetMinSize((160, 28))
+ self.re_txt_2.SetMinSize((160, 28))
+ self.re_txt_3.SetMinSize((160, 28))
+ self.static_line_rep.SetMinSize((184, 3))
+ self.setting_events.SetFont(wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, "Cantarell"))
+ self.setting_get.SetMinSize((205, 150))
+ # end wxGlade
+
+ def __do_layout(self):
+ # begin wxGlade: Dialog1.__do_layout
+ sizer_main = wx.BoxSizer(wx.HORIZONTAL)
+ rpt_events_ct_sz = wx.BoxSizer(wx.VERTICAL)
+ sizer_1 = wx.BoxSizer(wx.HORIZONTAL)
+ rpt_events_sz = wx.BoxSizer(wx.VERTICAL)
+ rd_pr = wx.BoxSizer(wx.HORIZONTAL)
+ tch_rd = wx.BoxSizer(wx.HORIZONTAL)
+ pr_rd = wx.BoxSizer(wx.HORIZONTAL)
+ slf_rd = wx.BoxSizer(wx.HORIZONTAL)
+ sizer_left = wx.BoxSizer(wx.VERTICAL)
+ name_saver_sz = wx.BoxSizer(wx.HORIZONTAL)
+ observer_name_sz = wx.BoxSizer(wx.HORIZONTAL)
+ last_name_sz = wx.BoxSizer(wx.HORIZONTAL)
+ first_name_sz = wx.BoxSizer(wx.HORIZONTAL)
+ sizer_left.Add(self.welcome, 0, 0, 0)
+ first_name_sz.Add(self.first_name_txt, 0, 0, 0)
+ sizer_left.Add(first_name_sz, 1, 0, 0)
+ last_name_sz.Add(self.last_name_txt, 0, 0, 0)
+ sizer_left.Add(last_name_sz, 1, 0, 0)
+ observer_name_sz.Add(self.observer_first, 0, 0, 0)
+ sizer_left.Add(observer_name_sz, 1, wx.EXPAND, 0)
+ sizer_left.Add(self.static_line_1, 0, wx.EXPAND, 0)
+ name_saver_sz.Add(self.save_names, 0, 0, 0)
+ sizer_left.Add(name_saver_sz, 1, wx.EXPAND, 0)
+ sizer_left.Add(self.label_directions, 0, 0, 0)
+ sizer_left.Add(self.static_line_2, 0, wx.EXPAND, 0)
+ sizer_left.Add(self.time_button, 0, 0, 0)
+ sizer_left.Add(self.notes_box, 0, 0, 0)
+ sizer_left.Add(self.save_quit, 0, 0, 0)
+ sizer_main.Add(sizer_left, 0, wx.ALL, 3)
+ rpt_events_sz.Add(self.re_title, 0, 0, 0)
+ rpt_events_sz.Add(self.re_txt_1, 0, 0, 0)
+ rpt_events_sz.Add(self.count_1, 0, 0, 0)
+ rpt_events_sz.Add(self.re_txt_2, 0, 0, 0)
+ rpt_events_sz.Add(self.count_2, 0, 0, 0)
+ rpt_events_sz.Add(self.re_txt_3, 0, 0, 0)
+ rpt_events_sz.Add(self.count_3, 0, 0, 0)
+ rpt_events_sz.Add(self.static_line_rep, 0, wx.ALL|wx.EXPAND, 0)
+ rpt_events_sz.Add(self.rd_title, 0, 0, 0)
+ slf_rd.Add(self.slf_rd_btn, 0, 0, 0)
+ slf_rd.Add(self.slf_rd_cnt, 0, 0, 0)
+ rpt_events_sz.Add(slf_rd, 1, wx.EXPAND, 0)
+ pr_rd.Add(self.pr_rd_btn, 0, 0, 0)
+ pr_rd.Add(self.pr_rd_cnt, 0, 0, 0)
+ rpt_events_sz.Add(pr_rd, 1, wx.EXPAND, 0)
+ tch_rd.Add(self.tch_rd_btn, 0, 0, 0)
+ tch_rd.Add(self.tch_rd_cnt, 0, 0, 0)
+ rpt_events_sz.Add(tch_rd, 1, wx.EXPAND, 0)
+ rd_pr.Add(self.rd_pr_btn, 0, 0, 0)
+ rd_pr.Add(self.rd_pr_cnt, 0, 0, 0)
+ rpt_events_sz.Add(rd_pr, 1, wx.EXPAND, 0)
+ rpt_events_sz.Add(self.hint, 0, 0, 0)
+ sizer_main.Add(rpt_events_sz, 0, wx.ALL, 3)
+ rpt_events_ct_sz.Add(self.re_1_lbl, 0, 0, 0)
+ rpt_events_ct_sz.Add(self.cnt_1, 0, 0, 0)
+ rpt_events_ct_sz.Add(self.re_2_lbl, 0, 0, 0)
+ rpt_events_ct_sz.Add(self.cnt_2, 0, 0, 0)
+ rpt_events_ct_sz.Add(self.re_3_lbl, 0, 0, 0)
+ rpt_events_ct_sz.Add(self.cnt_3, 0, 0, 0)
+ rpt_events_ct_sz.Add((205, 20), 0, 0, 0)
+ rpt_events_ct_sz.Add(self.setting_events, 0, 0, 0)
+ rpt_events_ct_sz.Add(self.setting_get, 0, 0, 0)
+ rpt_events_ct_sz.Add(self.help, 0, 0, 0)
+ rpt_events_ct_sz.Add(self.about, 0, 0, 0)
+ rpt_events_ct_sz.Add((205, 30), 0, 0, 0)
+ sizer_1.Add(self.Copyright, 0, 0, 0)
+ sizer_1.Add(self.bitmap_1, 0, 0, 0)
+ rpt_events_ct_sz.Add(sizer_1, 1, wx.EXPAND, 0)
+ sizer_main.Add(rpt_events_ct_sz, 0, wx.ALL, 3)
+ self.SetSizer(sizer_main)
+ sizer_main.Fit(self)
+ self.Layout()
+ # end wxGlade
+
+
+# end of class Dialog1
+#Thank you wxGlade!
+
+#Opens a "save as" dialog
+ def header(self, event, **dialogOptions):
+ dialog = wx.DirDialog(self, **dialogOptions)
+ if dialog.ShowModal() == wx.ID_OK:
+ self.dirname = dialog.GetPath()
+ dialog.Destroy()
+ directory = self.dirname
+
+ #This is the header for the text file.
+ date_time = strftime("%Y-%m-%d %H:%M:%S")
+ first = self.first_name_txt.GetValue() #grabs user input from field, puts it in file.
+ last = self.last_name_txt.GetValue()
+ text_file = open("%s/%s_%s.txt" % (directory, first, last), "w") #Gotta remember to flip the '/' to '\' when porting between windows and linux
+ text_file.write("OBSERVATION REPORT FOR: %s %s " % (first, last))
+ text_file.write("%s" % (date_time))
+ observer = self.observer_first.GetValue()
+ text_file.write("\nObservation Performed By: %s" % observer)
+ text_file.write('\n')
+ text_file.write('----------------------------------------------------------------------------')
+ text_file.write('\n')
+ text_file.write('----------------------------------------------------------------------------')
+ text_file.write('\n')
+ text_file.write('\n')
+
+ #Now the program knows where to put its files. You may interact with it now.
+ self.time_button.Enable(True)
+ self.save_quit.Enable(True)
+ self.slf_rd_btn.Enable(True)
+ self.tch_rd_btn.Enable(True)
+ self.rd_pr_btn.Enable(True)
+ self.count_1.Enable(True)
+ self.count_2.Enable(True)
+ self.count_3.Enable(True)
+ self.pr_rd_btn.Enable(True)
+ self.last_name_txt.Enable(False)
+ self.first_name_txt.Enable(False)
+ self.save_names.Enable(False)
+ self.observer_first.Enable(False)
+
+ def time_event(self, event):
+ a.append(1) #Could be an integer, or whatever. It's just a way to record how many times this function has run.
+ countfinal = len(a) #Count the number of integers in the list
+ if countfinal > 3: #It's cyclical! I want it to start over each time. This also gives me the flexibility to adjust how things operate.
+ del a[0:]
+
+
+
+ if countfinal == 1:
+ on_start = time.time() #get system time
+ ot.append(on_start) #put it in a list
+ self.welcome.SetLabel("Timing On Task Event") #tell the user what's happening
+ self.label_directions.SetLabel("Timing On Task Event\nRecord Notes Below") #Tell them in bigger letters
+ self.SetBackgroundColour(wx.GREEN) #Make so it's REALLY obvious what's going on
+ self.Refresh() #Needed this for Windows.
+ on.append(1) #stick the integer "1" into a list for counting
+ size = 18 #How big I want the font
+ font = wx.Font(size, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL) #Linux doesn't care about all this explicit stuff, but Windows sure does.
+ self.label_directions.SetFont(font) #Make the font big
+ self.save_quit.Enable(False) #Don't want them exiting out early
+
+ if countfinal == 2: #This function is more complicated because it has to do file operations, or else we lose all our work.
+ on_stop = time.time() #get system time again
+ on_taskraw = on_stop - ot.pop() #subtract the system time from up the previous if statement
+ on_task = round(on_taskraw, 2) #Make it user friendly
+ OnTask.append(on_task) #Stick it in a list
+ ontotal.append(on_task) #Going to sum this one up when we're done. Looks like I repeated myself again.
+
+ self.SetBackgroundColour(wx.LIGHT_GREY) #Dear User: Nothing is happening.
+ self.Refresh() #I hate you Windows.
+ self.welcome.SetLabel("Timed On-Task Event") #You did?
+ size = 10
+ font = wx.Font(size, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
+ self.label_directions.SetFont(font)
+ self.label_directions.SetLabel("Click TIME to record off-task event")
+
+ notes = self.notes_box.GetValue()
+ first = self.first_name_txt.GetValue()
+ last = self.last_name_txt.GetValue()
+ directory = self.dirname #dirname is generated by the wx.DirDialog module. I confused myself with this one.
+ text_file = open("%s/%s_%s.txt" % (directory, first, last), "a")
+ length = len(on)
+ date_time = strftime("%H:%M:%S")
+ text_file.write("\n")
+ text_file.write("ON TASK EVENT#%s, Interval Time: %s sec, Time of Day: %s" % (length, on_task, date_time))
+ text_file.write('\n')
+ text_file.write("==>%s" % (notes))
+ text_file.write('\n')
+ text_file.write("-----------------------------------------------------------")
+ text_file.write('\n')
+ text_file.write("\nBEGIN OFF TASK RECORDING:\n")
+ self.notes_box.Clear()
+ self.save_quit.Enable(True)#You can stop and save here if you wish.
+
+ #Does the same thing again, just puts things in different places.
+ if countfinal == 3:
+ start_off = time.time()
+ oft.append(start_off)
+ self.SetBackgroundColour(wx.RED)
+ self.Refresh()
+ size = 18
+ font = wx.Font(size, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
+ self.label_directions.SetFont(font)
+ self.welcome.SetLabel("Timing Off Task Event")
+ self.label_directions.SetLabel("Timing off-task event\nRecord Notes Below")
+ off.append(1)
+ self.save_quit.Enable(False)
+
+ if countfinal == 4:
+ stop_off = time.time()
+ off_taskraw = stop_off - oft.pop()
+ off_task = round(off_taskraw, 2)
+ offtotal.append(off_task)
+ OffTask.append(off_task)
+ self.SetBackgroundColour(wx.LIGHT_GREY)
+ self.Refresh()
+ notes2 = self.notes_box.GetValue()
+ self.welcome.SetLabel("Timed Off-Task Event")
+ size = 10
+ font = wx.Font(size, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
+ self.label_directions.SetFont(font)
+ self.label_directions.SetLabel("Click TIME to record on-task event")
+ first = self.first_name_txt.GetValue()
+ last = self.last_name_txt.GetValue()
+ directory = self.dirname
+ text_file = open("%s/%s_%s.txt" % (directory, first, last), "a")
+ length = len(off)
+ date_time = strftime("%H:%M:%S")
+ text_file.write("\n")
+ text_file.write("OFF TASK EVENT#%s Interval Time: %s sec Time of Day: %s" % (length, off_task, date_time))
+ text_file.write('\n')
+ text_file.write("==>%s" % (notes2))
+ text_file.write('\n')
+ text_file.write('-----------------------------------------------------------')
+ text_file.write('\n')
+ text_file.write('\nBEGIN ON TASK RECORDING:\n')
+ self.notes_box.Clear()
+ self.save_quit.Enable(True)
+
+ def self_redirect(self, event): #Records the time a redirect happened in line with the on-task, off-task records and a tally summary appended to the bottom of the text file
+ redirect_times.insert(0,0) #Insert a "0" into place one so that m2 doesn't return an error the first time this function is called.
+ m1 = time.time() #Record system time
+ m2 = redirect_times.pop()
+ delta_raw = m1 - m2 #Get the interval between now and the last time this was called
+ redirect_times.append(m1)
+ delta = round(delta_raw, 2) #Make the user love you, not hate you.
+ redirect_interval.append(delta) #Yay! I got to use the word delta! I feel so smart and math-like!
+ interval_labels.append("self") #as in, 'self redirect.' I got myself REALLY confused here
+
+ self_tod = strftime("%H:%M:%S") #Record the time of day. Ugh, never put 'self' in the name of anything. This was hell.
+ slf_rdr.append(self_tod) #Put it in a list
+
+ #Now, get all the variables needed to open and append the right text file
+ first = self.first_name_txt.GetValue()
+ last = self.last_name_txt.GetValue()
+ directory = self.dirname
+ #Open it
+ text_file = open("%s/%s_%s.txt" % (directory, first, last), "a") #reverse the / to \ for Win.
+ #Add the human readable name of the event and the time of day to the text file
+ text_file.write("\nSELF REDIRECT: %s \n" % self_tod)
+ rd_cnt = len(slf_rdr) #Get a running length of the list
+ cnt = rd_cnt - 1 #subtract one because the label stuck in takes one slot
+ self.slf_rd_cnt.SetLabel("%s" % cnt) #Advance the counter that the user sees.
+
+ def peer_redirect(self, event): #Same thing as above
+ redirect_times.insert(0,0)
+ m1 = time.time()
+ m2 = redirect_times.pop()
+ delta_raw = m1 - m2
+ redirect_times.append(m1)
+ delta = round(delta_raw, 2)
+ redirect_interval.append(delta)
+ interval_labels.append("peer")
+
+ peer_tod = strftime("%H:%M:%S")
+ peer_rdr.append(peer_tod)
+ first = self.first_name_txt.GetValue()
+ last = self.last_name_txt.GetValue()
+ directory = self.dirname
+ text_file = open("%s/%s_%s.txt" % (directory, first, last), "a")
+ text_file.write("\nPEER REDIRECT: %s\n" % peer_tod)
+ peer_cnt = len(peer_rdr)
+ peer = peer_cnt - 1
+ self.pr_rd_cnt.SetLabel("%s" % peer)
+
+ def teacher_redirect(self, event):
+ redirect_times.insert(0,0)
+ m1 = time.time()
+ m2 = redirect_times.pop()
+ delta_raw = m1 - m2
+ redirect_times.append(m1)
+ delta = round(delta_raw, 2)
+ redirect_interval.append(delta)
+ interval_labels.append("teacher")
+
+ tch_tod = strftime("%H:%M:%S")
+ tchr_rdr.append(tch_tod)
+ first = self.first_name_txt.GetValue()
+ last = self.last_name_txt.GetValue()
+ directory = self.dirname
+ text_file = open("%s/%s_%s.txt" % (directory, first, last), "a")
+ text_file.write("\nTEACHER REDIRECT: %s\n" % tch_tod)
+ tch_cnt = len(tchr_rdr)
+ tch = tch_cnt - 1
+ self.tch_rd_cnt.SetLabel("%s" % tch)
+
+ def redirect_peer(self, event):# This function is not included in the intervals. It would wreck the data.
+ pr_tod = strftime("%H:%M:%S")
+ rdr_peer.append(pr_tod)
+ first = self.first_name_txt.GetValue()
+ last = self.last_name_txt.GetValue()
+ directory = self.dirname
+ text_file = open("%s/%s_%s.txt" % (directory, first, last), "a")
+ text_file.write("\nREDIRECTED PEER: %s\n" % pr_tod)
+ pr_cnt = len(rdr_peer)
+ pr = pr_cnt - 1
+ self.rd_pr_cnt.SetLabel("%s" % pr)
+
+ #The next three functions are user definable, meaning the observer assigns a value to each event.
+ #The intervals are recorded, but only between occurrences of the same event.
+ def repeat_behavior_1(self, event):
+ rpt1n.insert(0,0)
+ r1 = time.time()
+ r2 = rpt1n.pop()
+ delta_raw = r1 - r2
+ rpt1n.append(r1)
+ delta = round(delta_raw, 2) #Be nice
+ rpt1i.append(delta) #put the interval into a list
+ repeat_tod = strftime("%H:%M:%S") #Get time of day
+ repeat_value = self.re_txt_1.GetValue() #Retrieve the user defined value
+ self.re_txt_1.Enable(False) #Let's not have any unnecessary confusion
+
+ #This if statement inserts a label in the beginning of the list so the user knows what they're looking
+ #at when this is converted to csv
+ if len(rpt1) == 0:
+ rpt1.insert(0, repeat_value)
+
+ #These lines just write to the text file.
+ first = self.first_name_txt.GetValue()
+ last = self.last_name_txt.GetValue()
+ directory = self.dirname
+ text_file = open("%s/%s_%s.txt" % (directory, first, last), "a") #"a" is for append. Always append.
+ text_file.write("\n%s: %s\n" % (repeat_value, repeat_tod)) #Record the name of the event and the time of day in the text file.
+
+ rpt1.append(repeat_tod) #make a tally
+ rep1 = len(rpt1) - 1 #count the tallies, subtract one for the name
+ self.cnt_1.SetLabel("%s" % rep1) #set the label the user sees
+ self.re_1_lbl.SetLabel("%s" % repeat_value) #advance the counter
+
+
+ def repeat_behavior_2(self, event):
+ rpt2n.insert(0,0)
+ r1 = time.time()
+ r2 = rpt2n.pop()
+ delta_raw = r1 - r2
+ rpt2n.append(r1)
+ delta = round(delta_raw, 2)
+ rpt2i.append(delta)
+ repeat_tod = strftime("%H:%M:%S")
+ repeat_value = self.re_txt_2.GetValue()
+ self.re_txt_2.Enable(False)
+ if len(rpt2) == 0:
+ rpt2.insert(0, repeat_value)
+ first = self.first_name_txt.GetValue()
+ last = self.last_name_txt.GetValue()
+ directory = self.dirname
+ text_file = open("%s/%s_%s.txt" % (directory, first, last), "a")
+ text_file.write("\n%s: %s\n" % (repeat_value, repeat_tod))
+ rpt2.append(repeat_tod)
+ rep2 = len(rpt2) - 1
+ self.cnt_2.SetLabel("%s" % rep2)
+ self.re_2_lbl.SetLabel("%s" % repeat_value)
+
+ def repeat_behavior_3(self, event):
+ rpt3n.insert(0,0)
+ r1 = time.time()
+ r2 = rpt3n.pop()
+ delta_raw = r1 - r2
+ rpt3n.append(r1)
+ delta = round(delta_raw, 2)
+ rpt3i.append(delta)
+ repeat_tod = strftime("%H:%M:%S")
+ repeat_value = self.re_txt_3.GetValue()
+ self.re_txt_3.Enable(False)
+ if len(rpt3) == 0:
+ rpt3.insert(0, repeat_value)
+ first = self.first_name_txt.GetValue()
+ last = self.last_name_txt.GetValue()
+ directory = self.dirname
+ text_file = open("%s/%s_%s.txt" % (directory, first, last), "a")
+ text_file.write("\n%s: %s\n" % (repeat_value, repeat_tod))
+ rpt3.append(repeat_tod)
+ rep3 = len(rpt3) - 1
+ self.cnt_3.SetLabel("%s" % rep3)
+ self.re_3_lbl.SetLabel("%s" % repeat_value)
+
+
+
+ def filefunc(self, event): #Writes the contents of the task lists to the .csv file and appends all the summary information to the text file.
+ lenr = len(redirect_interval) #the three pre-defined redirect intervals
+ if lenr > 0: #The conditional is here in case the observer doesn't record redirects.
+ redirect_interval.pop(0) #The first value in the list is a giant number, because the number subtracted from it was 0
+ redirect_interval.insert(0, "Interval") # Label it for the spreadsheet
+
+ #These are the user defined event intervals
+ len1 = len(rpt1i)
+ len2 = len(rpt2i)
+ len3 = len(rpt3i)
+ #Getting the names of the events
+ repeat_value1 = self.re_txt_1.GetValue()
+ repeat_value2 = self.re_txt_2.GetValue()
+ repeat_value3 = self.re_txt_3.GetValue()
+
+ if len1 > 0:
+ rpt1i.pop(0) #Gets rid of the one big number at the beginning
+ rpt1i.insert(0, "%s Int" % repeat_value1)
+ if len2 > 0:
+ rpt2i.pop(0)
+ rpt2i.insert(0, "%s Int" % repeat_value2)
+ if len3 > 0:
+ rpt3i.pop(0)
+ rpt3i.insert(0, "%s Int" % repeat_value3)
+
+ firstname = self.first_name_txt.GetValue()
+ lastname = self.last_name_txt.GetValue()
+ directory = self.dirname
+
+ #Writes the csv file. Teachers should familiarize themselves with spreadsheets.
+ writefile = csv.writer(open('%s/%s_%s.csv' % (directory, firstname, lastname), 'wb'), delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL) #Reverse the / for Win or it gets mad.
+ empty_row = ("")
+ writefile.writerow(OnTask)
+ writefile.writerow(OffTask)
+ writefile.writerow(empty_row) #Again, treat the user with compassion. Make things readable.
+ writefile.writerow(interval_labels)
+ writefile.writerow(redirect_interval)
+ writefile.writerow(empty_row)
+ writefile.writerow(slf_rdr)
+ writefile.writerow(tchr_rdr)
+ writefile.writerow(peer_rdr)
+ writefile.writerow(rdr_peer)
+ writefile.writerow(empty_row)
+ writefile.writerow(rpt1)
+ writefile.writerow(rpt1i)
+ writefile.writerow(rpt2)
+ writefile.writerow(rpt2i)
+ writefile.writerow(rpt3)
+ writefile.writerow(rpt3i)
+
+
+
+ #Get more values that will be appended
+ final_notes = self.notes_box.GetValue()
+ first = self.first_name_txt.GetValue()
+ last = self.last_name_txt.GetValue()
+ observer = self.observer_first.GetValue()
+
+ #get a whole bunch of totals to write in
+ total_off = sum(offtotal)
+ total_on = sum(ontotal)
+ total_self = len(slf_rdr) #Get the number of self redirects that happened
+ total_peer = len(peer_rdr)
+ total_teacher = len(tchr_rdr)
+ total_redirect_peer = len(rdr_peer)
+ total_rpt1 = len(rpt1)
+ total_rpt2 = len(rpt2)
+ total_rpt3 = len(rpt3)
+
+ #These all get averages to include in the text write up. This is in case the user is too lazy to use a spreadsheet.
+ if lenr > 1: #Tells it not to do this function unless there are integers in the list to work with.
+ redirect_interval.pop(0)
+ average_interval = float(sum(redirect_interval) / len(redirect_interval))
+ average = round(average_interval, 2)
+
+ if len1 > 1:
+ rpt1i.pop(0)
+ avg = float(sum(rpt1i) / len(rpt1i))
+ event1i = round(avg, 2)
+ else:
+ event1i = 0
+ if len2 > 1:
+ rpt2i.pop(0)
+ avg2 = float(sum(rpt2i) / len(rpt2i))
+ event2i = round(avg2, 2)
+ else:
+ event2i = 0
+ if len3 > 1:
+ rpt3i.pop(0)
+ avg3 = float(sum(rpt3i) / len(rpt3i))
+ event3i = round(avg3, 2)
+ else:
+ event3i = 0
+
+ directory = self.dirname
+ text_file = open("%s/%s_%s.txt" % (directory, first, last), "a")
+ setting = self.setting_get.GetValue()
+ text_file.write("\nSETTING EVENTS: \n%s" % setting)
+ text_file.write('\n')
+ text_file.write('FINAL OBSERVATION NOTES:')
+ text_file.write('\n')
+ text_file.write('\n')
+ text_file.write('%s' % (final_notes))
+ text_file.write('\n')
+ text_file.write('\n')
+
+ #These if statements keep irrelevant information off the text report.
+ #They also gave me an excuse to use some boolean logic.
+
+ if total_on != 0:
+ text_file.write('Total time on task: %s' % (total_on))
+ text_file.write('\n')
+ if total_off != 0:
+ text_file.write('Total time off task: %s' % (total_off))
+ text_file.write('\n')
+ if total_self != 0:
+ text_file.write("Total Self Redirects: %s\n" % total_self) #Add that number to the bottom of the file
+ if total_peer !=0:
+ text_file.write("Total Peer Redirects: %s\n" % total_peer)
+ if total_teacher != 0:
+ text_file.write("Total Teacher Redirects: %s\n" % total_teacher)
+ if total_redirect_peer != 0:
+ text_file.write("Redirected a Peer: %s times.\n" % total_redirect_peer)
+
+ rpt1_1 = len(rpt1)
+ rpt1v = rpt1_1 - 1
+ rpt2v = len(rpt2) - 1
+ rpt3v = len(rpt3) - 1
+ if event1i != 0:
+ text_file.write("Total Number of %s: %s\n" % (repeat_value1, rpt1v))
+ text_file.write("Average time between %s: %s\n" % (repeat_value1, event1i))
+ if event2i != 0:
+ text_file.write("Total Number of %s: %s\n" % (repeat_value2, rpt2v))
+ text_file.write("Average time between %s: %s\n" % (repeat_value2, event2i))
+ if event3i != 0:
+ text_file.write("Total Number of %s: %s\n" % (repeat_value3, rpt3v))
+ text_file.write("Average time between %s: %s\n" % (repeat_value3, event3i))
+
+ if lenr > 1:
+ text_file.write("Average Time Between Redirects: %s sec\n" % average)
+ date_time = strftime("\n%Y-%m-%d %H:%M:%S") #Record the time we're done.
+ text_file.write("\nEND OF REPORT" '\n')
+ text_file.write("%s" % (date_time))
+ text_file.write("\n\n\n\nSIGNED:______________________________________\n")
+ text_file.write(" %s" % observer)
+ self.Close(True)
+ self.Destroy() #Don't just leave it running.
+
+
+ def OnAboutBox(self, e):
+
+ description = """FBA Machine is an application, written in Python,
+designed to make Time on Task and repetitive event observations more accurate
+and official looking. Its intended users are special educators and school psychologists.
+FBA Machine outputs to .csv and .txt so that the user will have access to the maximum number of
+programs in which to manipulate their data. It is recommended the .txt file
+be opened in either a word processor or text editor and that the .csv be
+opened in a spreadsheet editor.
+
+This software is intended to be freely distributed and should remain free for all to
+use and modify. It would be immoral for me to try to sell this considering I developed
+it entirely using free and open-source tools. I hope you'll find this application useful.
+And don't hold your breath waiting for this to be a smartphone app. You'd look awfully
+conspicuous poking away at your smart phone in a classroom, wouldn't you?
+"""
+
+ licence = """FBA Machine is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>."""
+
+
+ info = wx.AboutDialogInfo()
+
+
+ info.SetName('FBA Machine')
+ info.SetVersion('1.0')
+ info.SetDescription(description)
+ info.SetCopyright('(C) 2012 Josef Hoffman')
+ info.SetWebSite('http://www.puddletownindie.com')
+ info.SetLicence(licence)
+ info.AddDeveloper('Josef Hoffman')
+ info.AddDocWriter('Josef Hoffman')
+
+
+ wx.AboutBox(info)
+
+if __name__ == "__main__":
+ behavior_observation = wx.PySimpleApp(0)
+ wx.InitAllImageHandlers()
+ dialog_3 = Dialog1(None, -1, "")
+ behavior_observation.SetTopWindow(dialog_3)
+ dialog_3.Show()
+ behavior_observation.MainLoop()

0 comments on commit f5311e3

Please sign in to comment.