< prev 19 Dec 2017 to 14 Nov 2014 next >

Posts tagged 'victory'

  • Organization, Part 2

    We came back from a brief trip to Orlando with over 700 new photos in tow. I dutifully uploaded them to Photos.app1, and realized that it's almost impossible to find anything.

    In fairness, Apple does have some automated tooling to make looking for specific photos easier. Faces, events, and upload groups make finding a specific event and flipping through photos for projects or just recollection simple, but there are some flaws. It's not clear to me if they got rid of the feature to flip through all unnamed faces or if I just can't find it—either way, it reflects poorly on Apple2, and is just another marker of their trend toward entropy.

    So I'm sitting at my computer, looking at over 16,000 photos, trying to make sense of them. What ends up working, and what I spent Sunday evening doing, is making a smart album that only selects files that don't belong to an album, then triaging. As I observe natural collections of files, a taxonomy emerges: some things are vacations or events (happening in a constrained time and place), some are of people (e.g. my wife, or the cat), and the remainder have conceptual boundaries, for the most part.

    Beyond normal tourism, the way I use my camera is to capture moments of interest ("memories"), interesting locations ("explorations"), or to record information where writing would be too slow (e.g. snapping a photo of a serial number, recording damage to the apartment). Triaging gave me the opportunity to filter some obvious duds/outdated information (I don't need to know the model number of my refrigerator two apartments ago), and to realize that this specific taxonomy predates this current push.

    Notably, when I would upload photos to Facebook in the past, the only way I could get a handle on them (and find them in the future) is to split along similar axes.

    I'm going to have some trouble making sure I'm not repeating myself here, but the broad purposes of organization are as follows:

    1. Finding trends in existing material
    2. Relocating specific material later on
    3. Reminding yourself what exists
    4. Extracting specific information (e.g. the date an event happened)
    5. Finding a general case of a specific collection

    The overall goal, of course, is to do productive work, so we need to impose just enough order on the system to allow it to work for us.

    Contrast a search engine. You might search for some restaurant in general (general case), or a particular restaurant (specific information). You might want to look for where restaurants cluster so you can go to an area with a lot of options, where you can search in person (finding trends). You might want to recall the name of that little place you visited two years ago (relocating information), or you might want to find that area you used to go all the time (reminding yourself what exists).

    I've noticed that Google has become good at a subset of these and bad at the rest. Notably, Google is pretty good at finding general information, but if you're looking for something you know exists and the information is a bit stale (e.g. hasn't been reposted or updated in a couple years), or if the search term you're using is specific but close enough to a more common term that it auto-corrects to something else, you might struggle to find "your thing." I just experienced this situation when looking for a specific comic that used to appear on reddit all the time3.

    This is where local caches come into play. I have layers and layers of data that I've been trying to keep organized; photos are just one. The app-centered model is a bit odd for some of the uses I have in mind. Case in point: sometimes (as mentioned above) the easiest way to quickly record something for later consumption/digestion is to take a screenshot of text. But this ends with a nightmare taxonomy, as follows.

    • When I just take a screenshot, that ends up in my photo stream and can be triaged quickly (it's hard to mistake a page of text for a photo of a person, even at thumbnail level). I have both a phone and a tablet, so I have to keep track of two separate streams.
    • Further, I have computers, and those screenshots go straight to desktop, so I have to deliberately aggregate them somewhere so that I can find what I'm looking for quickly.
    • Sometimes I use the "highlight" function in my eReader4, and those notes are stored… in my eReader, I guess? There's probably some way to setup a workflow to move those notes somewhere useful, but keep in mind the ultimate goal is to have stuff available for later use, so too much overhead defeats the purpose5.
    • Sometimes I copy relevant text to a note, or one of several note taking apps, and if the text becomes unsearchable some day (altogether too many pages go missing, either taken down, lost, or changed beyond recognition), then the source won't be available for contextualization.
    • And, most pathologically of all, sometimes I hand-write notes.

    So, sorting through fodder is a matter of paging through screenshots, photos in my library, text files, and scraps of paper, trying to find some specific thing.

    I don't think there's a need to solve this case in particular, but it's worth highlighting what a struggle it can be, and which has relevance to real-world scenarios6. It's not worth solving fully, but I want to have at least a first-pass handle on it so that I have a chance of finding something that I at one time thought worth remembering.

    Remember, the purpose of all this is to make things do work for you. If you spend so much time organizing that you never address any projects, you haven't won.

    A final note, and justification for the "victory" tag: a bunch of files that I thought I'd misplaced, containing a lot of business ideas and so forth, were actually filed away on my NAS.

    1. One day I'll need to talk about how hard Apple's app naming conventions have made googling for tech support… 

    2. I checked some help docs; seems it was possibly an inadvertent removal in High Sierra. 

    3. In fact, for reasons I can't quite determine, Google has gotten much worse at finding all comics, even when I would have sworn that the same search terms would yield the results I seek not even a year ago. I'm not sure if this is a result of a change in Google or the pages themselves. 

    4. Marvin, an iOS app that allows you to make clippings of text without any of the asinine copyright hurdles that the kindle inflicts on you. 

    5. Spending a day figuring this workflow out when I only read at most a book a week, and can easily recall that the thing I saw was in a book, seems rather pointless. On the other hand… for the sake of just having fodder available to inspire writing, it might be in my interest. 

    6. Off the top of my head, legal discovery. 

  • CSSris and spinning wheels

    One of our cohort has a job offer! Neat.

    I spent the past two (and a half) days getting up late and working later. I got nervous that I have absolutely nothing to show with regards to portfolio work and decided to do some mini-side projects that I thought would be good examples for my portfolio.

    The first of these was cleaning up Rails Lite, which I'm pretty happy with. When we were doing it in class, I was frustrated because of how fragmented the lessons were, but once I consolidated my code a little bit everything made perfect sense. When controller instances inherit from the ControllerBase class, they gain all the powers that it has, including auto-routing and rendering of default templates… it's actually quite clear, and quite neat how it all works. The inheritance tree is also much clearer, now, so I can see that parsing of input parameters and session management happens in quite the sensible manner. It's truly improved my understanding of how Rails works.

    One neat side-effect: When I told Tommy that I wanted to include Rails Lite in my portfolio because it made more sense to me, he and I talked for a bit about how rails is organized and it piqued my interest about the project codebase. So I started reading through the source on github, and ended up identifying a bug in the source that will prevent the current cohort from being able to complete the assignment on that class day. (Long story short: the way the project is designed, it will work with version 4.1.x but not version 4.2.) It was interesting to be able to dive into the code like that and know what I was looking for, and I feel more capable for it.

    Late Thursday, I started in on a project that I knew I wanted to do: modifying my Snake (game) code to instead implement Tetris. Besides being (I believe) the better game, it was something that I think could set me apart a bit on my portfolio, and it was fun to see JavaScript in a different light now that I'm more versed in the language. I've finished it up now, for the most part, after quite a bit of late-night logic-checking (pieces no longer get stuck in the sidewalls! Yay!) and I'm quite happy to say that I can be proud of my code in a way that I wasn't for Snake. It is my project and it works well and looks like what I envisioned when starting out, more or less.

    Curiously, I got the code 90% right straight out of the box when doing the initial implementation. I started it up without the rendering code, and after making a small fix (ensuring that the IIFE was starting correctly), I could step through the game logic and see little boolean pieces falling like they should. It was pretty empowering to have that be the case; writing (mostly) bug-free code with few syntactic errors is a powerful feeling.

    I added both projects to my resume, which has been cleaned up a bit, and I'm feeling (almost) ready to go full-in on the job hunt. I know I'm late to the game, but that's quite alright. This break has done me well, and if I can do that with as much determination as I've been able to muster the past two-three days, I should be fine.


    Now that we don't have to blog, I can blog whenever I want—which also means blogging in the middle of the day when I've found some solution to a particularly knotty annoyance and am taking a break from whatever.

    I'll try to keep this quick, and I still don't have it how I want it.

    Sign-in is handled through a modal (using a library that is just okay…). When the app first starts, it tries fetching the currentUser model (asynchronously, of course). Meanwhile, it tries to route to whichever route was input, and if the user isn't signed in (which he won't be, because we're still waiting on a server response), it redirects to the sign-in window, which has an initializer that tells it to destroy itself when it receives a 'signIn' event over the Backbone.Radio eventsChannel.

    Meanwhile, the modal animates, and only adds its keybindings once the animation is finished. But the 'signIn' event is received in the middle of the animation, which means that the view is destroy()ed before it has attached its keybindings… which it does after the fact.

    Long story short, when a signed-in user refreshes the page, the sign-in modal installs listeners that get uninstalled before they're installed, and the next time the user hits "enter" the modal executes a "submit" event on empty text fields.

    I got around it by having an onShow callback that checks to see if we're signed in, and ONCE THAT CHECK HAPPENS, install the 'signIn' event listener. If that check fails (we've signed in during the 100ms that the animation has as default) then we uninstall ourselves.

    Gah. JavaScript, why you hurt so much?

  • Week 1 Day 4 - Applied telepathy

    Today's partner: Michael C. (since there are two)

    I think I adapt to things within three days. Today just felt normal, like what I should be doing with my life. I know it's going to get much harder before we finish, and I keep pushing things onto the stack to go into more depth on over the weekend—but there is already plenty to keep me busy. Life's going to be tough enough on its own, and I should probably be getting up early Saturday morning and diving right in. I may have to work remotely to get away from distractions (although this hasn't been as big a problem as I might have thought - Facebook and reddit just aren't very interesting to me now that I have a stack of things to think about).

    I am still not getting enough sleep, and it doesn't seem to actually affect my engagement or 'awareness' during the day. It's an awesome feeling.

    The highlights of the day were working with procs and, again, the big projects toward the end of the day. We were wrestling with understanding how to write our own versions of a couple Enumerable class methods (my_each, my_select, etc) but the breakthrough on this matter came when we tried to express the same things in "normal" ruby code and then translated that work into our functions.

    For instance, normally, to double all elements in an array, you might write

    array.map { |i| i * 2 }

    When defining your own function to receive that proc, you can start with something done in the standard ruby function calls:

    def my_map(&prc)
      result = []
      self.each do |item|
        result << prc.call(item)

    Simply replace "each" with "my_each" and you've basically re-created standard ruby functionality. I assume that, even if it's not now written this way, at some point the ruby "standard library" looked something like this (albeit with more error handling).

    My partner mentioned at the beginning of the day that he didn't really understand why you'd use procs, and within a half hour we both got it.

    The work on recursion was solid practice. The first example took ten minutes, the second five, and each one after was simply an exercise in analyzing the higher-level problem. Satisfying, and excellent practice/pedagogy, but nothing earth-shattering. :)

    make_change, the recursive method for taking a list of coin values (for instance, in the US, 25, 10, 5, and 1 for quarters, dimes, nickels, and pennies) as well as an amount that you're trying to target and yielding the list of coins you'd return in order to make the target amount with the minimum number of coins, was easy, then absolutely maddening. We managed to describe the core logic within a half hour - about one line every 90 seconds, go figure - and then took another half hour in order to track down a crazy edge-case bug that was killing most of our results.

    Constance looked at our code for a good ten minutes before we nailed down what was actually going wrong. We had a specific test case that broke the method quickly, a bunch of ghetto debug statements (p for the win!) and basically total awareness about the state of the internal variables, and we still struggled to find what was causing this failure.

    It turned out that there was a loop condition that this edge case was falling through, returning nil when our calling function was expecting an array. It was such a specific edge case that I should have seen earlier, but I kept looking in the wrong places for this, and the doubt caused by that sort of weakened my learning. I spent five minutes doubting each level of my knowledge, until finally I was doubting whether < actually means "less than". I'll definitely need more practice overall, and to develop more facility with debugger… and I've gained some specific respect for the challenges software maintainers face every day.

    WordChainer, today's "capstone", was a blast. The spec was thorough, and my partner and I basically spent fifteen minutes reading sections of it to one another and getting code into the editor. What a delight a properly detailed spec is! Too bad I'll probably never see one again in my life, unless I write it myself! ;)

    It took us about two hours to get a very respectable and pretty clean class for this portion, overshooting the end of class by a half hour. Remarkably, by the last hour, I wasn't sure which one of us was actually driving or navigating. Michael and I were basically on a single wavelength, and passing the keyboard back and forth was mostly a formality.

< prev 19 Dec 2017 to 14 Nov 2014 next >