I have very little to show for what I got done today, but I think it is made up for by what I learnt as a result! I started the day by trying to figure out the problem from yesterday — as far as I could understand, I was using the same dictionary in two places, but getting different words in the two spots. I tried using different dictionaries, changing how I stored the data, and how I wrote my function, but I was no closer to understanding what the problem was. I concluded that it was probably some little thing that I wasn’t picking up because I wasn’t familiar enough with the existing codebase. When Adam sent me this file, I basically learnt enough of what was happening (and how) to be able to add in what I needed, but I didn’t entirely follow the details of what all the structures were for, and how they were being created. As such, to familiarize myself with the program, I started writing the program over in a different file, cleaning up things and optimizing for my data labelling wherever I could. This was probably a good idea anyway — the way I added onto the code is far from ideal, and I put strange functions in strange places. An overhaul is hopefully going to make it cleaner.
Unfortunately, this led to the problem that I struggled with for hours. I named the new program “copy.py” and started coding. Compiling caused a snag I hadn’t seen before; matplotlib couldn’t load, because it couldn’t import pyparsing, a module it needs to run. This confused me because I had definitely run the program mere hours ago, and so must have had pyparsing. I therefore spent ages searching for pyparsing, installing pyparsing, moving files around, etc. When none of this worked, I asked Prof Medero for help, and the problem turned out to have nothing to do with pyparsing. By naming my file “copy.py”, I had confused Python into thinking this was the copy module it needed to import into pyparsing, whicih was what caused the whole problem. After fixing this I went back to the same process, and so far I think it’s been helpful. I have a much better grasp of where all the data is coming from, how it’s being treated and where it’s being stored. Hopefully the program will be done tomorrow, with all the functionality I want!
My plans for what to do today changed a little bit from what I had anticipated. First, I finished off the function I was working on last week — having each word’s “acceleration delta” calculated and stored somewhere. Instead of simply giving each word one of two labels (“faster” and “slower”) as I had planned, I instead used the following approach: for each whole word, look at the acceleration while that word was being read. Compare this acceleration value to the accelerations immediately before and immediately after (since we take readings every 0.2 seconds, this was easy enough to find). Then classify the word as one of the following:
- If the acceleration at that word (accel) is larger in value than both the one before it and the one after it, call it a “spike”
- If accel is smaller than both before and after, call it a “dip”
- If accel is smaller than the one before, but larger than the one after, then it is on a “decreasing” trend
- The opposite of the one above is on an “increasing” trend
This wasn’t too bad to do, so then I thought it would be worthwhile to see on the graph whether my function is actually doing something useful, so I thought I could add the word type (one of the four things above) to each data point in the plot. This should be straightforward, since I already have labels. Trying to implement this led me to a problem I spent the whole day on. Every attempt to make this work gave me assorted errors, and in fixing them for hours I ended up figuring out that the acceleration/words in one function were totally different from the acceleration/words in another. I have no idea why this is happening and have been trying to fix it since I realized that this was the problem. So far, my *guess* is that one function is only storing the acceleration/words for one text, while the other is storing them for all seven texts — i.e. one person’s trial. I have yet to prove this and have a suspicion that I will have to rework a lot of the program to figure out what the problem is. No obvious place shows two different sources being used, so I may just need to understand the control flow better. This is probably more than enough to occupy me for a while.
After much fiddling, much tweaking, and a whole lot of commenting, the bbb, black bar bug, is still not fixed, and even worse, the solution I thought I had turned out to be faulty. Prof. Medero recommended I use a static analyzer tool, prebuilt into XCode to try to find memory leaks, but this tool gave me no errors with my code, which was as I expected. In my own tests, I created a new project and stripped it down to just a VC transition and a scrollview on one of the VCs, and this still produced the bbb. I then spent a ton of time trying to convert the infrastructure of the scrolling label from a double subview of a uilabel and scrollview to a single instantiation of a text view. However UITextView is truly awful to work with. All of its functions are hallmarks of obj C, and all the functions which I needed to use have been deprecated in the current XCode implementation. The problem is that I can’t resize the text view, ever, because it resizes its vertical, not its horizontal, even if you explicitly limit its number of lines. Moreover, when you do limit lines and then ask for a horizontal increase, it does it, but also adds characters above itself in its frame. Basically, it doesn’t like being used for horizontal purpose, which is what we need. So that is out of the question. I tried using a UITextField, but this behaved in the exact same way as the UILabel. At the end of the day I tried just instantiating a bare bones scrollview with constituent label in the MVC, without any calls to creating the scrolling label, and this worked, without ever bringing up the bbb. This gives me hope, because it means there is something which is wrong in the scrolling label, I just need to find it.
Most of my day today was spent struggling with numpy. I have to use both the existing data compiled about our text — for instance, in the program as Adam gave it to me, there is already a mapping between time elapsed and acceleration, between acceleration and words on screen, and so on — and the existing features of numpy to try and come up with some useful data analysis. From Prof Medero’s email, a couple of things seemed easily doable, so I looked at those first. For instance, it didn’t take too long to figure out the average word length of the text, although this is currently computed in a pretty awkward spot in the code, so I should probably fix that soon. After this I also computed the standard deviation of the word length, but at the moment haven’t done anything useful with these numbers.
I then set bout finding the average acceleration corresponding to each word. This is now stored in a dictionary as part of the class I was working with (DataAnalyzer), and this should tell us something about how people interact with that word. To be honest it is not very useful information, as I realized after I looked at the numbers in the dictionary. The raw number out of context doesn’t tell you whether the reader slowed down, sped up or just stayed constant at that particular word. This means that those numbers make an interesting indication of the reader’s speed and interaction with the text, but don’t give us information to compare across people.
To fix this, I then thought I could create a similar dictionary which maps each word to either “faster” or “slower” — an average indication of whether people slow down or speed up when they see that particular word. This is what I am in the middle of doing right now, and will hopefully complete next week. This is complicated only because I need both the time data and the acceleration data to be linked to the words, so I just started manually doing this now. I thought “faster” and “slower” are more useful than numbers, because as I said above, raw numbers are not incredibly helpful. Hopefully this pans out next week.
Well, after testing tons of configurations of code today, commenting out this line, setting that object to nil, rewriting that function etc. etc., I think I know how to fix the black bars bug; rewrite the whole thing. My reasons for this: no amount of switching, flipping, refactoring or commenting changed the behavior. BUT, turning the iPad off and then on again increased the number of cycles until failure to 5, instead of 4. This means the problem is NOT in the code, but something is just… happening? Anyway, I then ran two tests. I had a feeling the problem might be rooted in UITransitionViews, private undocumented subclasses of the UIView, which Apple uses as backend for all segue transitions. I thought this because my program was creating a view, but they would not disappear upon segue, which, though it had no impact on memory or cpu, may have some consequence somewhere that I couldn’t see. I made a new program to test this theory, just a simple view cycling program, and in that the transition views disappeared after use. But then I found a way to make them disappear in my code, and the problem persisted… So that test was helpful, but unconclusive. I then made a new program and copied the central part of the problem/my code into it, that being the options view controller transitioning to a main view controller containing a scrolling label, and the problem WAS NOT PRESENT. That means that the core functionality of my code does not cause the bug, if indeed it is my code that causes the problem. Therefore, I am going to rewrite all of my code into a new project, refactoring and making things pretty along the way, and see if that fixes it. To be fair, the black bars bug is fairly inconsequential, because we will end up using a much smaller font, so the cycle limit will be around 25 or so, but at this point I just want to fix it. At that point I can convert to swift 2.0. Thats my goal for the immediate future.
Today featured a lot of good, a lot of bad, and a whole lot more bad, all centered around the mysterious black bars. Essentially all my work today was focused on finding what I call the “Black Bar Bug” occurs, and the conclusion is: I have no idea. Its not a memory issue, because I monitored memory, and added in random calls to increase usage, but still never exceeded any limits. Its not a CPU issue, because I checked the logs on each of the activated threads, consolidated actions to just thread 1, stop accelerometer functioning and more, and still never went over 7% cpu usage. I debugged through to find the uiwindow in which I was situated, and the simulator tells me I am in the correct view controller, even though the screen remains obstinately on the OVC. I tested on the other iPad, and the same phenomena occurred, BUT AFTER 5 CYCLES, NOT 4. WHAT. On the computer simulator IT NEVER OCCURS. So I am so confused. I don’t know what could be causing it, except for something in the iPad itself. Wait, I just had an idea. I think it might be because one of the threads stalls up on the UITransitionView. This would cause the memory limit on the simulator to not be updated until the CPU became “unstuck”. I can’t test right now, but will tomorrow… Sorry for the shorter post, but today was literally all debugging this thing.
We spent a decent amount of the morning preparing for and presenting at the CS Open House. We didn’t do too much by way of decoration, but printed out most of our data so far to give an idea of what kind of analysis we would be carrying out. The Open House itself was interesting, as it was nice to get non-CS people taking an interest in our work. We got a reasonable number of sign-ups for the next study, especially if we aim for it to be similar in scale to the one we just finished conducting. It really helped me polish the pitch for our project, just as I had done during the study.
Beyond this, I wanted to spend some time doing something useful with the data from our first study, but I’m not sure what we want to do with it. I hope this is something we address soon!
What I actually ended up doing was working with the data presentation. I did successfully use the module mpldatacursor to get our graphs to have labels on them. Now, when you click on a point, it displays its coordinates and the word that corresponds to that data reading:
This turned out to be more straightforward than I thought, but it took a long time to understand all the code behind mpldatacursor. This done, I asked Adam what else would be useful and he pointed out that right now, the “word” at each point is really a subword, and it might be more helpful to see the entirety of the word it corresponds to. I spent some time working on this, and have it basically done; I just need to find a succinct way of stripping the string of punctuation that can be turned on and off, because I can imagine that sometimes punctuation would be useful. This shouldn’t take too long, so hopefully I will find something else useful to do tomorrow.