Sunday, July 30, 2017

0020 - Cleaning House (Explicit Content)

So I obviously haven't posted in a long while, and I figured, "Hey, why not do it while I have a minute free today?"

I've been working on cleaning up my house lately. I've had projects that I've been wanting to work on for, I don't know... the last 6 and a half years or so. A friend came to breakfast a few months ago and lit a fire under my ass to get started on that, and I had a new roommate move in last week, so I've been getting some help with motivation, as well as just an extra hand to keep things moving.

The first project (which is now complete for the most part) was tearing all of the carpet out of the house. There are still two closets left (I'll probably take care of those tonight), but aside from those, I've done the den, the music room, the hallway, and all three bedrooms. The next project will be sanding the stucco crap off of the walls in the kitchen because I hate it and want it gone. I *may* start painting the rest of the house while doing the sanding in there because I have a feeling it will be mundane and take a while.

I also came to the realization a few weeks ago that I needed a new dresser because my clothes wouldn't all fit in the dresser/closet at once. After thinking about this problem, it struck me that the problem wasn't a lack of storage space, but a surplus of clothing. Thursday morning, while I was waiting for my roommate to text me that he had a U-Haul to move his furniture over, a visitor stopped by my house with a pink bag for a clothing drive for the HOPE for Domestic Violence shelter. I took that as a sign, and, on Friday night, I bagged up 3 and a half bags of clothes for them, which were picked up Saturday afternoon. So hooray! I got rid of a lot of clothes that I didn't wear/I didn't like/didn't fit, plus I got to feel good about myself for helping someone else. The downside? I threw in all my work clothes.

*gasp*

In addition to cleaning my physical house, I've also been working on cleaning myself up as a person. Not as in giving up vices (because I like some of my vices, and I'm lazy and lack the willpower to get rid of all of them), but as in making myself into a more presentable person.

I've started going to a new barber shop where a man known as "Razor Rob" has been "guiding" my hair and beard into something besides a frizzy mess. He has convinced me (using terms such as "professional" and "fuckable" in relation to how I *should* look) that I should take better care of my personal grooming and appearance. As a result, I have finally stopped using body wash or bar soap to wash my hair (I'm even using conditioner...it makes my hair feel nice), and I even comb my hair and beard at least once a day. On top of all of that, I've even started playing with beard oil and pomade, though my experiments so far make me look like a small child combs my hair...

After a few months of being Razor Rob'd, I decided to go get some new dress shirts last weekend. For those not in the know, this was the first time I've ever gone clothes shopping by myself (I always had my mom and/or my ex-wife with me before). I met a very nice lady at JC Penney's named Sherry, and she measured my neck and arms, had me try on a few different styles of dress shirts (I honestly didn't know there were different styles of dress shirts...) then found two for me. I told her I would be back to rebuild my wardrobe from the ground up.

That brings me back to throwing out my work clothes. After the bags were gone (so I would not be able to go pull the clothes back out and pretend like nothing happened), I went to JCP and was outfitted with 4 new shirts and 2 new pairs of pants. I also learned that there are different "fits" of pants. All that "New Year, New Me" crap? I'm making that shit happen. Hell, I even went back and deleted some of my blog posts that consisted primarily of me bitching about how poorly I thought my life was going because I'm not dwelling on that shit any more. It's time to stop being pissy about the past and start being optimistic about the future.

Part of my "transitional period" as I'm calling it has also been to try out new things, go to new places, and stop being a boring schmuck sitting at home, playing video games, and wondering why cool things never happen to me. I finally visited New York, I caught up with college friends, I've tried new bars and restaurants around town, tried new recipes (and made up a few)...and it's been a blast. I've been kicking myself for not starting this sooner, but now I'm turning that frustration into a fervor to get caught up. I'm tired of being jealous of everyone else living life while I keep myself shackled to the belief that I can't do the same damn thing. I'm doing it, and I'm gonna keep doing it, because screw it: I want to.

Thursday, August 4, 2016

0019 - Small Wins

Some days at work, everything sucks for everyone. We can tell when we have those days because Keith comes over to the cubicles to see me, Richard, and Todd, and he says, "Today sucks. We need a win. Does anybody have a win?"

At that point, the size of the win doesn't matter: we could have had a support call that went abnormally well, or maybe we figured out a solution to why a textbox wasn't posting back correctly. Even something small counts and helps lift our spirits, probably more than it should. On the occasion that we don't have any sort of win (and no, getting out of bed or waking up alive don't count, though sometimes they should...), we take solace in the fact that everybody's day has sucked, so we share our biggest frustrations in as humorous a way as possible and all laugh at each other's (and our own) misery.

I've started using this practice in my personal life, too. Whenever I'm feeling particularly down, or feel like everything sucks, I try to think of a win I had that day. Maybe a friend texted me just to see how I was doing or to invite me to do something fun. Maybe I caught every green light on my way home from work. Either way, I've started focusing more on the wins, however small, than the losses, however big, every day. This is kind of a new perspective for me; I've always tended a bit more toward the pessimistic side of things, so the whole positive outlook thing felt foreign at best and silly at worst.

Aside from the small wins (like how there was very little traffic on the way home and I caught all but 3 green lights), I've also had a few bigger wins in the last few weeks that have kind of helped me keep that positive mindset more constant:

1. If you're a friend of mine on Facebook, you will have noticed how, for the last few weeks, I've been using the Couch 2 5K (C25K) app to help me get into shape. For a little more backstory, on that: Richard and I have been talking for a few months about getting back into shape, working out, etc. That joker decided we should each make up a short list of fitness goals and share them with each other so we can hold each other accountable in working towards them. My goals are to be able to do chin-ups and pull-ups with minimal effort (a subjective measure) by August 31, run a 4 mile race by Thanksgiving (Turkey Trot), and to look like Captain America by June 1, 2017. So I've been working out a bit towards the goal of the chin-ups, and I've been running at least 3 times each week for the past 5 weeks (I had to do Week 1 of C25K twice). Every time I finish a run (especially the first day of each week's regimen) is a big win for me because it's a step towards several goals.

2. Also, if you're a friend of mine on Facebook, you will have noticed that I've now fostering a beautiful pit mix named Eva since July 19. She runs part of my C25K with me each day, as well as going on walks with me on off-days. When I'm home, she's my constant companion (except for when she sneaks away to eat food off the counter or pee on the floor or both). She's a sweet girl, and has helped get rid of the loneliness I was feeling most nights at home. I'm hoping to adopt her soon, so we'll see how that goes. Either way, though, the joy and companionship she's brought me since my last dogs left have been wonderful, and that has been a major win for me. She seems to enjoy the house better than the shelter, too, so I think it's a win for her as well.

3. Since May, I've been thinking of asking a particular girl out. She's smart, she's cool, she's cute, she loves animals, she's funny... that's a pretty intimidating combination. A few weeks ago, I finally made up my mind that I was going to ask, then spent two weeks analyzing, reanalyzing, overanalyzing, and psyching myself out. I convinced myself countless times not to do it, then countless times that I should. And I finally did. And she said yes, which actually surprised me. I was expecting more of the "Awww... that's so sweet!" like when a small child gives you a handful of grass for a present. But she didn't, and since I asked her Sunday, I've been analyzing, reanalyzing, overanalyzing, and psyching myself out about whatever step comes next, so at least that part of my personality hasn't changed... But this event was a few major wins for me: I took a step forward, I took a chance, and it worked out well. With any luck (and me behaving like a civilized human being, which is no small feat), this will lead to more wins down the line.

4. I've been opening up more to my friends and family. I like to stay private and still keep many, many things private, but I'm learning to be more vulnerable to the people I trust and care about. I share my wins and losses with them and either listen to what they have to say or accept their sympathies (which is even more difficult). I'm not sure how long I'll be doing this, but it seems to be going okay for now. I'd have to ask the people with whom I've been sharing whether I'm over-sharing and need to lay off some. But, hey! A win's a win, and this is a win.


So I'm going to keep on trucking and looking for wins wherever they may come. If you ever see me down, ask me if I've had any wins that day. I'll try to think of something!

Saturday, April 9, 2016

0016 - I'm Happy

For such a long time, when someone has asked me (typically in passing) how I am, how I'm feeling, or how I've been doing lately, I gave the same response that I'm sure most people give: "I'm doing fine. How are you?"

Mostly, I would do this out of courtesy, because I know that this random fellow employee at work who has never met me doesn't really want to hear what's actually going on in my life, especially not in very much detail. After all, that's why I have a blog, right?

[insert laugh track]

Speaking honestly, though, over the last few years, my answer should have been something more like, "Y'know, things could be better. I mean, there's nothing seriously wrong. I'm just not happy." When I did share that sentiment, whether with family or friends, I would usually say that I just wished I made more money at work, or that I'm just stressed about work and/or school, or that I'm just in a little bit of a funk at the moment because of X. However, it was always something deeper than that:

I wasn't happy because I felt like I didn't deserve to be happy.

Like (I assume) most people, I mainly remember and focus on the negative aspects of myself and my life, be it my weight, my appearance, choices I've made, actions I've taken, or whatever. I look back at mistakes I've made and people I've hurt and think to myself, "Someone who has done this doesn't deserve to be happy, so why should I be?" I refused to take into account my own strengths, the people I've helped, or the people who love me, because I felt like I was overstating them, wasn't sincere enough, or didn't deserve them, either, respectively.

And then came the divorce. I finally felt like I was getting what I deserved: pain, betrayal, disappointment, fear, anxiety, sleepless nights, and loneliness. That all sucked. It sucked to the point that I started to think that maybe that's what life was really supposed to be, and that I had just been living in some fantasy world up to that point.

And that's when my friends and family saved me. So many people have done so much for me over the past few months that I've come to realize how loved I truly am. I'm not going to remember or list everyone here, and this is in no particular order, but these are things that I want to say. This is my blog; you don't have to read it.


  1. Mom and Dad - from the night I drove out to their house in the middle of the night to tell them what was going on, they have wrapped me in their arms and shown me nothing but love and understanding. From when Mom held me while I cried, thinking that everything in my life up to that point had been nothing but sham after sham leading to overall failure to having dinner with Dad and Josh on my birthday, I've felt nothing but pure love.
  2. Jason and Josh - I get to be a bit more frank when I talk to my brothers, and they've never had a problem with me going off about one thing, or on and on about another. My brothers and I love each other, and being able to talk to them so freely and openly about anything and everything has been therapeutic at worst and freeing at best.
  3. Claudio - Claudio has been going through his own divorce for quite some time (and is finished now!) and his counsel, listening ear, and supporting shoulder have all been highly sought and greatly appreciated. It also helps that he appreciates Scotch and is willing to share it sometimes...
  4. Ben - Ben never had much to say about my situation, but he was always willing to listen and help me find ways to take my mind off of my problems and divert my energy into things that were actually beneficial for myself and others. Also, his general calm has helped me to find my own calm center even in the midst of some fairly trying times.
  5. Joe and Swanson - the two hosts of the Nerds Drinking podcast (listen if you like technology and/or alcohol) have also been great listeners and counselors through all of this mess. Whether it's encouraging me to stay strong or pushing me to get healthier and quit smoking (which I promise I will do one day), they've both always found a way to motivate me to better myself and my community, one step at a time.
  6. Brandon - I've known Brandon for almost 15 years. He and I have helped each other through very tough times before, and he has been there for me every step of the way. There's nothing I can say to express how profound of an impact he'd had on me even before this situation began, and he's stayed the course with me throughout it. Whether I needed a drink, a home-cooked meal, or just someone to sit and play video games with, he is always available when I need him.
  7. April - a newer friend, but seriously one of the closest friends I have. April is the one who finally beat it into my skull (figuratively, though she probably has been tempted to do it physically) that I don't deserve every bad thing that could ever happen to me. She is an incredible woman in her own right, but still has the time to listen to my BS with grace. I owe her more than I can ever express.
  8. Randy - my pastor, my brother, my friend. He's stayed up way too late way too many times dealing with me. When I called him in the middle of the afternoon, sobbing on the phone while driving through rush hour traffic, he was able to talk to me in a way I could understand and help me start seeing clearly (literally and metaphorically) again. 
As I said, there are many, many more, but most folks don't even want to read all of that, much less the rest of the 50 or so folks who have helped me in the last week. 

However, this is not strictly a "Thank You" card. My interactions with these (and other) people have resulted in something very strange for me: I'm happy. I'm emotionally healthy. I'm doing better psychologically than I have in years. I've gone from trying to find the light at the end of the tunnel to having to think back about what the tunnel was like, and it's because of all of you. I know that I can never repay the love and support that I've received from friends and family, and I also know that I would never need to pay you back anyway; that's what friends and family are all about!

But thank you. How am I? I'm great, I'm fantastic, and I'm surrounded by the best people anyone could ever hope for.

Thursday, February 4, 2016

0015 - Lessons Learned

Back in December, I took a day off of work just for myself. This is not a common occurrence: as a university student, I typically spend most of my vacation days on finals week each semester, with maybe another day or two each year taken off around a holiday weekend for a little extra length. That was pretty much what happened in December: I had final exams on a Wednesday and Thursday, so I took those days off. Instead of going back to work for a day, then having a weekend, I decided to take Friday off for a "recovery day." All that meant was that I got to finally go to a Memtech Geek Breakfast (http://www.meetup.com/memphis-technology-user-groups/events/228302623/) for once. So I went down to the breakfast and had a great time with some great folks before they went to work. Then I was alone again.

So I figured, "Hey, why not go by Central [Baptist School] and see if anyone's around?" For those of you not intimate with my life history, I went to CBS for K-12, and I still maintain good relationships with a few of the faculty remaining from my tenure there. So on my way home, I swung on by CBS and found that classes were still in session. As per usual, I spent most of the day hanging with Mr. Nelson, my HS math teacher. When he was unavailable, I went to chat with Mr. Henry, my 7th grade English teacher, who is now also teaching the HS computer classes. I mentioned to him that I was thinking about offering to teach a basic programming class at CBS next year (something I hadn't really thought about until that moment or so), and I asked him if he thought that any students would be interested in something like that. He smiled.

"Talk to Justin Gord."

After about 20 minutes, I finally tracked down Justin and asked him if he wanted to learn some basic programming techniques. He was fairly noncommittal, but we agreed to meet up sometime soon to further discuss the idea. Long story short, I've been meeting with Justin once or twice a week for about 4 hours per session for a month and a half now, drilling as much software development practice and computer science theory into his head as I can muster. For that time span, my semi-weekly meetings with Justin have been some of the brightest spots of my week.

Sitting here at home on a Thursday night, though, I've been thinking back about how our first few meetings went versus how they're going now, trying to spot areas on which we should focus, etc., when I realized how much I've learned through the teaching process:

1. Teaching >= Learning: I can't tell you how many people I've heard say, "The best way to learn something is to teach it." Probably somewhere around 4 or 5.
Naturally, I always assumed that this was referring to the time spent studying subject matter for lesson plan development, as well as analyzing material with which you're already intimately familiar for the express purpose of presenting said material in a way that your student(s) can understand it. However, that's only half of the picture. I learn more by having to answer Justin's questions than I do cramming before our meetings. The questions are usually as simple as "Why are we doing things this way?" or "How does that even work?" Usually it's not so much that I don't already know the information, but that, in the process of explaining it to someone wholly unfamiliar with the subject matter, I have been gaining a deeper understanding and a much greater appreciation for how and why some things just "work."

2. Kids are quick: I make no qualms about it - I threw Justin straight into the deep end and watched him flounder. Of course, I didn't let him drown, but I watched how he reacted to being confronted with something he had no clue about. He chipped away at it for a bit, and I gave him feedback on what he was doing. Each time I threw him in, though, I gave a little bit less feedback, and watched how quickly he was able to start solving problems for himself. Granted, he's still very new to this domain of knowledge, so a lot of the problems he has stem solely from a lack of experience (i.e. trying to reference a variable that is out of scope). However, he's starting to pick up on his common mistakes and is working to correct them. When I was a month and a half into programming, I could barely understand how human input was supposed to work. This kid's already building a frigging computer game, as well as making decent progress through Project Euler (https://projecteuler.net/). So, yeah, he's still got a long, long way to go, but he's trucking it down that road.

3. Computers are stupid: Justin's come up with a few clever solutions so far that just don't work with the tools we have. Sure, there may be some language out there that can do what he wants it to do, but for the most part, he's struggling against common knowledge in the software development field. Also, he doesn't like to have his "Why...?" questions answered, "Because that's how it is."
One thing I've focused on quite a bit through our sessions, though, is how stupid computers are. They don't think, they don't solve problems, they don't develop themselves. Whereas the human brain is constantly carrying on hundreds (if not thousands or millions) of processes each second, usually completely concurrently. Meanwhile, a computer processor can only handle one thing at a time.I think Justin is finally coming to grips with this.

4. Curricula suck: now, I'm not talking about planned lessons in general, but about the overarching curriculum path students have to follow in order to graduate. At the University of Memphis (http://www.memphis.edu/), you take the data structures classes, then move on to Discrete Math, Design and Analysis of Algorithms, Software Engineering, and Models of Computation. This is not necessarily a terrible thing, but it's designed to work for a majority of students, not each and every one individually. Working with Justin, though, we've jumped back and forth through the material from all of those courses. One session, we may start with some data structures, then get carried away when the topic morphs into something like the backracking algorithm. Because of it being a 1-on-1 relationship in the class, I'm able to adapt what we do based on exactly what problems he's having or what advice/data he needs to be able to take his next step.

5. Many of my classmates are idiots: When I first learned about a concept like OOP at U of M, I was already familiar with the idea (having been developing quite a bit before that time). When my classmates had trouble understanding exactly what was going on in the class, I chalked it up to inexperience, particularly when 20+ year olds were frustrated to the point of tears.
Meanwhile, Justin had a pretty good understanding of OOP within 20 minutes. Now, maybe the kid's just smart (and he is pretty smart), but this was when he could barely remember how to output text to the screen in Java ("System.out.print([text]);" or "System.out.println([text]);" for those listening at home). By our third meeting, I had decided that our goal in these lessons is that he will be bored out of his mind for at least 3 years at college.

6. "I don't know" just isn't acceptable: When preparing for job interviews, dealing with fellow employees/peers, and sitting in classes, I've had the concept of "It's okay to say, 'I don't know' if you don't know something" drilled into my head. In those situations, it is okay, especially if you follow it up with a good, old-fashioned, "...but I can find the answer for you."
When teaching, though, I've learned that saying, "I don't know" just doesn't cut it. Admitting that you don't have a piece of knowledge is fine, However, there is a better way to express that, something like: "That's a good question! Why don't we look into that?" and then guiding the student(s) to finding their own answers. Seems pretty common sense, right? Try telling that to college professors.


In conclusion, the last month and a half have had some very nice bright spots, like when Justin created his first classes without assistance, or when he figured his way through a fairly complex problem to develop a pretty clever algorithm to solve it. Every time I see the light bulb go off over his head gets me excited and pumps a little more enthusiasm into me. Also, if you're interested in hanging out with us sometime, hit me up on Twitter (@jawood2005) and we'll see when that can happen. Guest appearances by folks in the field are always appreciated, and if you just want to learn, then the more, the merrier. I'll let Justin teach you.

Tuesday, August 4, 2015

0011 - My Frustration...again

Just had to crank up my "Pick-me-up" playlist on Youtube. Just in case you're wondering, my playlist consists of 4 songs that loop forever. Feel free to listen to these as you read, or at your leisure:







Why am I playing my "Pick-me-up" playlist? If you can recall a previous blog post about "My Frustration," just know that I'm more frustrated right now than I have been at any point in this process. Granted, I'm 3 months into working on a problem that has consumed the greater portions of great men's lives before me. Those guys must have gone completely insane, because damn. This problem is stupid hard.

I just had my latest algorithm go up in smoke. Granted, I knew it wasn't complete, I knew it wasn't correct. I also knew that it was returning accurate results on large-sized graphs upwards of 90% of the time, which is pretty good. However, I finally admitted to myself tonight something that I've known for at least a week: at best, my algorithm is a decent heuristic, nothing more. It's like solving this problem is winning the World Cup, and I'm playing hopscotch while jumping rope. It makes no sense. I'm not even part of the game. I'm not even playing my game correctly. I feel like a dumbass.

So, since tonight is apparently full disclosure night, I'm going to share the BS algorithm I built because I'm brainless.

This algorithm will solve a majority of the graphs you throw at it, assuming that the graphs are formatted in a peculiar way: if two nodes are connected by an edge, it is represented in a 2-dimensional array with a 1; if they are not connected by an edge, it is represented as a 0; also, each node itself is represented with a 2. For example,

0 1 2 3 4 5 6 7 8 9
0 2 0 0 0 0 0 1 0 1 0
1 0 2 1 1 1 1 1 1 1 0
2 0 1 2 0 0 0 1 1 1 1
3 0 1 0 2 1 1 0 1 1 0
4 0 1 0 1 2 0 0 1 1 0
5 0 1 0 1 0 2 1 0 1 1
6 1 1 1 0 0 1 2 1 0 1
7 0 1 1 1 1 0 1 2 1 0
8 1 1 1 1 1 1 0 1 2 0
9 0 0 1 0 0 1 1 0 0 2

is a 10 node graph (nodes 0-9). You'll notice the diagonal line of 2's - these correspond to the nth column on the nth row, such as (0,0), (1,1), etc. So the first row represents the relationships of node 0. There is a 2 for 0, meaning that this is node 0. There are 0's for 1, 2, 3, 4, 5, 7, and 9, indicating that 0 is not connected to those numbers. There are 1's for 6 and 8, indicating that these two nodes are connected to node 0.

Okay, so that graph is used by the following algorithm (first few lines explain global variables):

gSize - integer that represents the number of nodes in the graph
best - integer that contains the largest independent set found thus far
g[][] - 2 dimensional integer array that contains the original graph (such as expressed above)
s[i][j] - 2 dimensional integer array that contains the optimal solution array for each node i; initialized with the original values of g[][]

IS():
    for i = 0 to gSize:
        while(true):
            temp = Weight(i)
            if temp < gSize:
                Switch(i, temp)
            else:
                break
         currBest = GetBest(i)
         if currBest > best:
             best = currBest

Weight(i):
    currBest = 0, currIndex = gSize
    for j = i to gSize:
        currWeight = 0
        if s[i][j] = 0:
            match = true
            for k = i to gSize:
                if s[i][k] == 0 && g[j][k] == 0:
                    currWeight++
                else if g[j][k] == 2:
                    currWeight++
                else if s[i][k] == 0 && g[j][k] == 1:
                    match = false
            if match == true:
                return j
        if currWeight > currBest && currWeight != 0:
            currBest = currWeight
            currIndex = j
        else if currWeight == currBest && currWeight != 0:
            first = 0, second = 0
            for k = i to gSize:
                if s[i][k] == 0 && g[currIndex][k] == 0:
                    for l = i to gSize:
                        if s[i][l] == 0 && g[currIndex][l] == 0 

                          && g[k][l] == 0:
                            first++
                if s[i][k] == 0 && g[j][k] == 0:
                    for l = i to gSize:
                        if s[i][l] == 0 && g[j][l] == 0 && g[k][l] == 0:
                            second++
            if second > first:
                currIndex = j
    return currIndex

Switch(i, j)
    s[i][j] = 2
    for k = 0 to gSize:
        if g[j][k] == 1:
            s[i][k] = 1

GetBest(i)
    currBest = 0
    for j = i to gSize:
        if s[i][j] == 2:
            currBest++
    return currBest


If you don't understand that, it's totally fine. It doesn't work anyway. If you do understand it, feel free to try to solve the graph I gave above with this algorithm. Here's a hint: you'll get a largest independent set of 3, while the correct answer is 4 because node 0 will connect with node 9 before the rest of them, while node 9 is actually not a part of the true largest set. In fact, my algorithm will come up with a largest independent set made up of nodes 0, 9, and 1 (picked in that order), whereas the actual largest independent set (as determined by me working it out by hand) is 0, 2, 4, and 5 (not necessarily picked in that order).

The problem is that I tried to simplify the selection process by weighting nodes based on similarity to the current node in question (in this algorithm, this would be node i). In so doing, I managed to actually solve a vast majority of the graphs that I tested. However, it was not perfect, so there were incorrect solutions.


So, how do I fix this? In short, I'm going to have to teach my computer to think, or at least to appear to be thinking. Backtracking, if you remember, has a worst-case time complexity of T(n) = O(2^n). I'm not taking that many steps when I work these out by hand, but I can't rightly explain to you my by hand method (which is part of the problem). The algorithm I outlined above has a time complexity of T(n) = O(n^5) (more or less...), which is much mo' bettah, but also doesn't get the right freaking answer.

So I'm creating a new class in my test app, opening up my steno pads, busting the dry erase markers back out, and listening to my Pick-me-up Playlist. Because I've got a lot of work to do.





Tuesday, June 30, 2015

0009 - Burnout (Explicit Content)

Burnout is a bitch. Anyone who has dealt with burnout knows this. However, folks who have seen others deal with burnout without having personal experience can often see it as whining and/or dealing with the consequences of getting in over your head. They're not wrong, but that oversimplification can lead to something that might be even more dangerous than burnout itself: bottling it all up.

Let's face it: people don't like being ridiculed. That's why I rarely write blog posts, I advertise new blog posts on Twitter exactly one (1) time, usually late at night so it will get lost in people's feeds, and I get nervous when I hit 5+ pageviews on a post (especially when people aren't commenting). It's because I just know deep down in my heart that someone is going to read my blog and think "This guy's an idiot and probably should never be loved and die alone."

Back to the topic...
When someone is feeling burnt out, they have limited options with limited results:
1. They can share how they're feeling and have people reach out to help them, which can (not always will) make the situation better
2. They can share how they're feeling and be ignored, which will make the situation worse
3. They can share how they're feeling and be ridiculed, which will make the situation much worse
4. They can keep it to themselves and have an altruistic person magically come along and make things better, which will make the situation better but pretty much will never happen
5. They can keep it to themselves and eventually regain the fire that got them started in the first place, which will, at least temporarily, make things better
6. They can keep it to themselves and eventually go postal and/or grind themselves down into nothing, which is pretty much the worst result

So, yeah. Burnout is a bitch. But what can we do about it?
In my endless wisdom and experience, I have concocted the following cockamamie scheme:

1. We, as a community, should learn to recognize burnout within our communities
We are all members of multiple communities, whether we realize it or not. It's not just the people you live around, the people you work around, your classmates, the church you attend, your group of friends, or the IRC channels you frequent, either. Members of your broad vocational field ("technology" in my case) and more specific fields (most likely plural; for me, they are "elevators," ".Net development," "logistics," "warehouse management," "analysis," etc. Do I personally manufacture elevators? No, but I'm a member of that vocational community.) are members of your communities. More than likely, you know people who have experience burnout in your community and know how your community was diminished because of the loss of that person's enthusiasm and abilities. What events or circumstances led up to that point? Were there any indications from the person that they were starting to feel burnt out? This can vary from community to community and from person to person, so there is no hard and fast rule for recognizing that this is happening. At best, when you hear someone talking about being overwhelmed, not having the energy to finish fairly normal tasks, and/or wanting to quit, move to a yurt on the side of the interstate, and raise goats and guineas, talk to them about that. Ask questions. Pry. Be a pain in the ass. Try to let them know, in your social misfit way, that you care about them and want them to be around for a while. Even if there's nothing that you can do (or that they will let you do), you will hopefully at least let them know that you care about them, which may help them open up later.

2. We, as people, should learn to recognize burnout within ourselves EARLY
I was raised by a father and a mother who sucked at recognizing burnout in themselves. Whenever something needed to be done at our church, my mom was doing it. Whenever there were new responsibilities that needed to be taken on at work, my dad was doing it. This resulted in ever-increasing amounts of stress for both of them and, finally, to burnout for both. What could and should have been fun, relaxing, and rewarding experiences for them became drudgery and extra stressors (on top of raising 3 boys, one of whom was me). When the weekend came around and it was time for them to relax, they kept right on working. This went on for years. Even after they were burnt out with involvement in various communities, they kept on taking on more responsibilities and pushing themselves farther than they should have ever gone.
So how can we recognize burnout in ourselves before we get to the breaking point? As before, there is no hard and fast rule. However, by asking ourselves a few questions, we might be able to figure it out. Why do you do what you do? If it's because it won't be done unless you do it, is this something that absolutely must be done? What would stop someone else from doing it? What will happen if it is not done? What are you not doing so that you can do this?

3. We, as people, should learn to say "No"
4. We, as a community, should learn to accept "No"
5. We, as a community of people, should learn to all pitch in
So how is my mom still alive and not 15 years dead with stress-related heart disease? It's a quick story: We moved to a new church. She was asked to help out with something and said "Yes" with a slightly pained look in her eyes. The person who had asked her could see that pain and told her "It's okay to say 'no' sometimes." My mom apologized and said, "No." She felt really terrible about it until things magically worked out (i.e. someone else who had some extra free time said "Yes"). It was liberating for her. It was liberating for me (I say "No" way too often, most likely).
But did you see what happened? A community member recognized that pain, knew that pain, and acknowledged that pain. When the option to say "No" was given, and my mother took it, the community accepted that answer graciously, and someone else within the community who was better equipped at that time took on the responsibility.
Granted, not all communities accept "No" for an answer. Not all communities (hell, probably most communities) do not know how to pitch in. As a result, a small group of people shoulders the burdens for entire communities, and we end up with burnout.

So, in short, to help avoid burnout, follow these easy steps:
People burning out:
Communities:

 Everyone:

Wednesday, June 10, 2015

0008 - My Frustration

Part of my childhood that won't die (likely for many, if not most, others) is my imagination. I like to daydream. I like to construct elaborate fantasies about potential futures, and plot ways to make those futures a reality.

Unfortunately, all of the plots I concoct center on one of a few highly improbable events:
    1. Winning the lottery (I don't play the lottery, so will never win)
    2. Finding some other source of massive income within a relatively short timeframe

As I've gotten older, my daydreams have reached less and less into the future as the window for one of these improbable events narrows each and every day. As such, I have plunged myself headfirst into the second event: finding a source of massive income. My current event? Solving the P vs. NP problem and proving that P = NP.

For those who are not familiar with this problem or are a little rusty on the particulars, here's a brief rundown with some heavy generalization:
The complexity of an algorithm can be judged by its worst case time complexity. Worst case time complexity is a measure of how long it will take to solve the given problem using the given algorithm as a product of the size of the problem.
For example, an algorithm may use a loop to add the numbers 1-N together, like so:

sum = 0
for i = 1 to N:
    sum = sum + i

This has a worst case time complexity of N (i.e. if N = 10, this will take 10 steps to complete)
If we wanted, instead, to add each number from 1 to N to each other N times, we could use the following algorithm:

sum = 0
for i = 1 to N
    for j = 1 to N
        sum = sum + i

This has a worst case time complexity of N^2, because it takes N steps N times. Both of these problems are called P problems, because they can be solved in deterministic polynomial time (i.e the worst case time complexity is N^X, where X is a finite number less than N).
If, however, we wanted to find the largest independent set of a graph using backtracking, our algorithm would have a worst case time complexity of 2^N.

Confused?

Okay, first off, a "graph" in this instance is referring to a set of nodes that are connected by edges:
A-B-C
In this graph, A, B, and C are the nodes, and edges connect A to B and B to C.
Another example:
A-B-C
  \  |
    D
In this graph, A, B, C, and D are the nodes, and edges connect A to B, A to D, B to C, and B to D.

Second, an "independent set" is a collection of 1 to N nodes that are not connected with edges. For our first graph, the independent sets are {A}, {B}, {C}, and {A,C}. In our second graph, the independent sets are {A}, {B}, {C}, {D}, {A,C}, and {C,D}. The largest independent set is the independent set containing the most nodes (for graph 1, it is {A,C}; for graph 2, it is either {A,C} or {C,D}).

To date, the best algorithm to solve for the largest independent set utilizes backtracking, which I don't want to talk about in this post. Essentially, it attempts to test every possible combination of nodes and has a worst case time complexity of 2^N (i.e. with a problem size of 3, it would take 8 steps; with a problem size of 4, it would take 16 steps; with a problem size of 10, it would take 1024 steps). This is called nondeterministic polynomial time, or NP.

Enough of that.
My goal, and what I've been working on in my spare time for almost a month now, is to prove that P = NP, meaning that problems that are contained in the NP class (such as determining the largest independent set of a graph) can be solved with an algorithm in the P class. Unfortunately, this is very difficult, and is starting to frustrate me.
This problem was formally stated in 1971, so it's something that nobody has proved in the last 44 years, though many, many intelligent people have tried. As such, I'm not being very hard on myself for not solving it yet. However, every time I work up an algorithm that seems to work, I'm missing one of two important points:
1. It's accurate (i.e. it always reaches the correct solution)
2. It's in the P class
So far, I can only get one or the other. The closest I've come (earlier this evening) is an NP algorithm that is 100% accurate that, when removing two simple loops (and thereby changing the algorithm to the P class), becomes accurate only for problem sizes < 5.

So, I've decided that, as of about an hour ago, I am going to completely scrap what I've done so far. I've been approaching and representing the problem in the same way that everyone else has. I'm reinventing the wheel over and over (of my accurate solutions, I have worst case time complexities of N!, 2^N, and N^N!; don't ask about that last one - I was drinking). Now I just have to figure out a novel approach to the problem, and that will hopefully yield better results.

Or I can buy a Powerball ticket. Either way works.

Edit: as for why solving this problem will give me massive income, please view the following links:
http://en.wikipedia.org/wiki/Millennium_Prize_Problems
http://en.wikipedia.org/wiki/Fields_Medal
http://en.wikipedia.org/wiki/Abel_Prize
etc.

Sunday, November 30, 2014

0007 - Prolog Adventure Game

I hate the Prolog language. Just going to get that out there to start this.

Anyway, I've finally finished the assignment given to my class a few weeks ago: take a text-based adventure/maze game that is written in Prolog, and modify the code so that different configurations can be used in the game. Also, this rewrite should include the capability of having a list of commands passed to the game for an "autopilot" type of deal.

Simple, right? No, because I hate Prolog because it is stupid and sucks and I'll probably play with it later and find out I secretly like it.

Anyway, I decided to add a few of the more interesting bits of code on here in case anyone ever wants to see it:

The "go" and "fileManager" clauses. The first "go" clause simply opens up the configuration file (a comma-delimited plaintext file), reads it into the List labeled "Data," and passes Data to the fileManager clause. The fileManager clause opens up a new stream for writing the results of the game, creates an atom whose value is set to the next file name, and calls the next go clause. This go clause reads in the commands from the file, then runs through them iteratively for each configuration. Once all of that ends, everything kicks back to fileManager, which sends the next file.

go :-
  csv_read_file('/home/jonathan/Desktop/Prolog/configurations.txt',Data),
  fileManager(Data).
 
fileManager(Data) :-
  open('/home/jonathan/Desktop/Prolog/commands_v1Results.txt',write,Stream1),
  File1='/home/jonathan/Desktop/Prolog/commands_v1',
  go(Data,Stream1,0,0,File1),
  open('/home/jonathan/Desktop/Prolog/commands_v2Results.txt',write,Stream2),
  File2='/home/jonathan/Desktop/Prolog/commands_v2',
  go(Data,Stream2,0,0,File2),
  open('/home/jonathan/Desktop/Prolog/commands_v3Results.txt',write,Stream3),
  File3='/home/jonathan/Desktop/Prolog/commands_v3',
  go(Data,Stream3,0,0,File3),
  open('/home/jonathan/Desktop/Prolog/commands_v4Results.txt',write,Stream4),
  File4='/home/jonathan/Desktop/Prolog/commands_v4',
  go(Data,Stream4,0,0,File4),
  open('/home/jonathan/Desktop/Prolog/commands_v5Results.txt',write,Stream5),
  File5='/home/jonathan/Desktop/Prolog/commands_v5',
  go(Data,Stream5,0,0,File5).
   
go([],_,_,_,_).

go([row(X,Y)|Data],Stream,M,S,File) :-
  retractall(at(_,_)), % clean up from previous runs
  area(X,Loc1),
  area(Y,Loc2),
  assert(at(you,valley)),
  assert(at(ogre,Loc1)),
  assert(at(treasure,Loc2)),
  open(File, read, Str),
  read_commands(Str, Commands),
  close(Str),
  report,
  S1 is S+1,
  main(Commands,Data,Stream,M,S1,File).
 
read_commands(Stream, []) :-
  at_end_of_stream(Stream).
   
read_commands(Stream, [X|L]) :-
  \+ at_end_of_stream(Stream),
  read(Stream, X),
  read_commands(Stream, L).


That's really the trickiest part of the code. Every other change mainly had to deal with writing to the Stream rather than the console (which may not have actually been a requirement for the assignment...).

Enjoy!

Monday, November 3, 2014

0006 - Sure, it's simple, but I like it

This semester, I'm in COMP 4040 (Programming Languages). The big assignments in this class are all pretty much the same thing: take a text-based adventure game originally written in Prolog (nifty language, but I don't care for writing in it), and translate it to other languages that we are learning about.

Well, the C++ translation was due last night at 11:59 pm. I finally gave up on trying to optimize it and turned in what I had at about 11:50, but that didn't sit well with me. Before I go down that road, I do want to fill you in on a few things about me that you may or may not already know:
1. I am a serial optimizer. I may write a quick and dirty piece of code to get a job done, but I can never let sleeping dogs lie: I have to eventually come back and clean it up, making it run faster, smoother, more error-free.
2. I'm finally learning C++. I tried picking it up when I was 12, but it was hard to find info, I had no idea what a compiler was, and the code looked scary, so I deemed it Too Hard and maintained that stance until this past summer. As such, I'm excited that I'm able to write some C++ now, and am finding it very fun.

So, since I am a serial optimizer, I'm just now learning C++, and I find C++ to be fun, I couldn't let the code I turned in last night just stay as it was. As such, I spent about 5-6 hours today trying to figure out ways to make it better.
The version I turned in last night could run from start to finish (automated tasks ftw!) in an average of .135 seconds. Since the other students I talked to had their running in just over 1.0 seconds, I originally felt pretty good about that. However, I knew there were a few things I could change to speed mine up, so I started tinkering...and tinkering...and tinkering. After trimming .01 seconds off of the run time (down to .125s), I decided that, surely, the code could be better optimized, and that I should be able to get the run time down to under 0.1 seconds.

Long story short, after another 5 hours of tinkering, I managed to get the run time down to an average of .057 seconds (less than half of the time when I started). Why am I so excited about this? Because I set an uncertain goal in a still largely unknown language, and accomplished what I set out to do. Also, because my friend Nathan said I was crazy and might have said that I couldn't pull it off (I don't listen well, so I just put words in people's mouths). So, if someone's interested in checking out what I did, leave a comment asking for the code (or ask me in person), and I'll send you the whole kit and caboodle (code, configuration files, etc.). After all, 345 lines is too much to have to read in this poorly formatted blog.

Friday, June 20, 2014

0005 - MIPS Mansion - Full Source Code

As I promised in an earlier post, here is the full source code for MIPS Mansion (minus the room files...deal with it!). Theoretically, if you can read and understand MIPS, you should be able to build your own room files without much trouble.

Just a brief recap...
MIPS Mansion was the final result of my group's project in COMP 3410 (Computer Organization and Assembler Language) at the University of Memphis in the Spring 2014 semester. The members of this group (dubbed "Team Puzzle" by our professor) were (in alphabetical order by last name):
1. Nathan Brandeburg
2. Joseph Ciskowski
3. Drew Stabenow
4. Daniel Wood
5. Jonathan Wood (Hey, that's me! Woohoo!)

It is a Zork-like text-based maze/adventure game written entirely in the MIPS Assembler language. To complete this project, we had to learn/figure out how to perform what are usually a few basic tasks:
1. File reading - in most high-level languages, file reading is a relatively simple task. In MIPS, it's not too bad, but parsing out the information from files can be a bit...tricky.
2. String concatenation - in most high-level languages, this is laughably simple. We had to use this to build dynamic filenames for each room and, while it was far more painful than we hoped it would be, being able to do this made MIPS Mansion a heck of a lot more impressive.
3. Dynamic input validation - depending on the "room" you are in within the mansion, different inputs might be valid, and each input will have a different result. As such, we had to be able to read in any and all possible inputs to verify whether the user's actual input is acceptable and, if so, what the result might be (usually just the number of the next room, but there were also some "unique" results as well).

One last note: we were only able to consistently get this code to compile and run using the Mars MIPS simulator in Linux Mint (tested in versions 14 and 16) and Windows 7. If any changes are made to the code (which they may be if I get bored), this post will be modified with the changes, and it will only be after they are confirmed in these operating systems.

So, with no further ado, I present the MIPS Mansion source code. Enjoy!

#################
# COMP 3410     #
# Final Project #
# MIPS Mansion  #
# Version 1.0.0 #
#################

# main/driver starts here
 .globl main
main:

# data segment
.data
buffer: .space 1200 # used to store room name, room description, and room input values
filepath: .asciiz "/home/jonathan/Desktop/Final Project/rooms/" # hard coded rooms directory
room: .asciiz "00/" # temporary storage point for current room number
readFile: .asciiz "n" # temporary storage point for current file to be read
filename: .space 70 # used to store the full file path/name for i/o
validInput: .space 32 # used to store valid input strings
userInput: .space 32 # used to store user input (surprise!)
nameHolder: .asciiz "n" # "name" # designates the name file
descHolder: .asciiz "d" # designates the description file
inputHolder: .asciiz "i" # designates the input file
delimiter: .asciiz "*" # used to mark the end of a valid input
pickup: .asciiz "You find a key!\n" # used in special inputs when a key is found
unlock: .asciiz "You use your key to unlock the door. The key breaks off in the door\nand, as you pass through, the door slams shut behind you, locked."
die: .asciiz "You see the last light from the candle flash off of the eye of the\nbeast that has been hunting you. The beast growls softly..."
live: .asciiz "You have somehow survived this nightmare, but who knows what lurks\naround the next corner...?"
special1: .asciiz "k" # if this special input result is received, you've picked up a key
special2: .asciiz "u" # if this special input result is received, you've used a key
special3: .asciiz "l" # if this special input result is received, you've lived through the nightmare
false: .byte 0 # just a false byte for verification
alreadyHave: .asciiz "\nYou've already picked up this key!\n" # message if a key is picked back up
doNotHave: .asciiz "\nYou need a key to do this!\n" # message if a key is needed
candleRemaining1: .asciiz "\nYou only have "
candleRemaining2: .asciiz " minutes left to escape...\n"
correctMove: .asciiz "\nThe candle burns a little more as you press forward.\n"
incorrectMove: .asciiz "\nYou can't do that. You're wasting time! The candle burns more\nas you try in vain...\n"

# text segment
.text

####################################################
# Reserved registers:
# $s0 = file descriptor
# $s1 = filename
# $s2 = filepath
# $s3 = room
# $s4 = readFile
# $s5 = new room number
# $s6 = key boolean
# $s7 = candle counter
####################################################

####################################################
# general room procedure
# configurable by room files: name, description, input
####################################################
li $s7, 31 # initial candle value load

BuildRoom:
jal GetName # get name for room
jal GetDescription # get description for room
jal GetInput # get input for room
jal ClearInputs # clear out previous rooms valid inputs
j PlayRoom # after the room is built, it is played

GetName:
move $t7, $ra # saving the return address so we can get back
jal ClearBuffer # clear the buffer so there is no data overlap
lb $t0, nameHolder # loading the file name for the 'name' file
la $t1, readFile # loading the address for the file name
sb $t0, ($t1) # storing the file name in the file name address
jal GetFilename # concatenate the file path/name
jal FileOpen # read the file into buffer space

# print room name
li $v0, 4 # get ready to print text
la $a0, buffer # load the address of the buffer space
syscall # print that buffer!
jal ClearBuffer # clear the buffer before the next file
jr $t7 # Get back!

# get description text
GetDescription:
move $t7, $ra # saving the return address so we can get back
lb $t0, descHolder # loading the file name for the 'description' file
la $t1, readFile # loading the address for the file name
sb $t0, ($t1) # storing the file name in the file name address
jal GetFilename # concatenate the file path/name
jal FileOpen # read the file into buffer space

# print room description
li $v0, 4 # get ready to print text
la $a0, buffer # load the address of the buffer space
syscall # print that buffer!
jal ClearBuffer # clear the buffer before the next file
jr $t7 # Get back!

# get input/result file and hold in buffer
GetInput:
move $t7, $ra # saving the return address so we can get back
lb $t0, inputHolder # loading the file name for the 'description' file
la $t1, readFile # loading the address for the file name
sb $t0, ($t1) # storing the file name in the file name address
jal GetFilename # concatenate the file path/name
jal FileOpen # read the file into buffer space
jr $t7 # Get back to where you once belonged!

# the actual playing part
PlayRoom:
# get room input
li $v0, 8 # open up for input
la $a0, userInput # going to read the input into the 'input' memory address
syscall # user input is now stored at 'userInput'

# validate room input (include special cases)
j ValidateInput

####################################################
# procedure to clear the buffer in between string
# loads/unloads (prevents data overlap)
####################################################
ClearBuffer:
la $t1, buffer # load the address of the buffer for clearing
li $t0, 0x00000000 # hex 0 (null), for clearing
addi $t2, $t1, 1196 # buffer is 1200 bytes long. Our null is a word. Do the math.
j Clear # clear it out!

Clear:
sw $t0, 0($t1) # store the null word in the address
addi $t1, $t1, 4 # move up a word in the space
ble $t1, $t2, Clear # if we're not past the end of the space, clear the new address
jr $ra # otherwise, get outta heah!

ClearInputs:
la $t1, validInput # load the address of the valid input string
li $t0, 0x00000000 # hex 0 (null), for clearing
addi $t2, $t1, 28 # valid input space is 32 bytes long. Our null is a word. Seriously, do the math.
j Clear # clear it out!

####################################################
# procedure to check input, provide feedback
####################################################
ValidateInput:
la $t0, validInput # valid input strings will be stored at $t0
la $t1, buffer # valid input string is now reachable at $t1
lb $t2, delimiter # setting $t2 to '*' to check end of input
j buildValid

buildValid:
# loop through, pulling out valid input bytes one by one, then comparing
lb $t3, ($t1) # load current byte from valid inputs into $t2
beq $t3, $t2, CheckInput # end of current input string, compare user input
beqz $t3, InvalidInput # if it reaches null, it's an invalid input
sb $t3, ($t0) # store the current byte and move on
addi $t0, $t0, 1 # increase address to store next byte of string
addi $t1, $t1, 1 # increase address to read next byte of buffer
j buildValid # loop

CheckInput:
# going to compare 'input' address to user input
li $t4, 0x0A # load hex value of new line (dec: 13) into $t4
sb $t4, ($t0) # store cr value as next byte in validInput
la $t4, userInput # current user input
la $t0, validInput # current valid input string
j InputChecker

InputChecker:
lb $t6, ($t4) # load current byte of user input
lb $t7, ($t0) # load current byte of valid input string
bne $t6, $t7, Invalidated # if bytes are not equal, call invalidated
beqz $t7, ValidInput # if bytes are equal and one of them is null, this is valid
# otherwise, increment and compare
addi $t4, $t4, 1 # move to next byte of user input
addi $t0, $t0, 1 # move to next byte of valid input string
j InputChecker

Invalidated:
addi $t1, $t1, 4 # move to beginning of next valid input string
la $t0, validInput # load addres for storing valid input string
j buildValid # build next valid input string

ValidInput:
# set $s5 to new room
la $s5, room # getting ready to write new room
addi $t1, $t1, 1 #moving to first character of new room number
lb $t4, ($t1) # loading first byte of new room number
subi $s7, $s7, 1 # decrement the candle by 1 'minute'
jal CheckSpecial # make sure that the input return value isn't a special case
sb $t4, ($s5) # storing first byte of new room number
addi $t1, $t1, 1 # moving to second character of new room number
addi $s5, $s5, 1 # moving to second room number character
lb $t4, ($t1) # loading second byte of new room number
sb $t4, ($s5) # storing second byte of new room number
li $v0, 4 # get ready to print some text
la $a0, correctMove # load address for the 'correct move' feedback
syscall # print it
j DispCandle # display the candle length

InvalidInput:
li $v0, 4 # get ready to print some text
la $a0, incorrectMove # load address for the 'incorrect move' feedback
syscall # print it
subi $s7, $s7, 2 # decrement the candle by 2 'minutes'
j DispCandle # display the candle length

DispCandle:
ble $s7, $0, Die # if the candle length is <= 0, you die
li $v0, 4 # get ready to print some text
la $a0, candleRemaining1 # load address for the intro to the candle text
syscall # print it
li $v0, 1 # get ready to print a number
addi $a0, $s7, 0 # load up the current candle length
syscall # print it
li $v0, 4 # get ready to print some text
la $a0, candleRemaining2 # load address for the conclusion of the candle text
syscall # print it
j BuildRoom # go build the room, knucklehead...

####################################################
# procedures to handle special input results
####################################################
# checks for special input results and handles them appropriately
CheckSpecial:
lb $t2, special1 # load byte to compare and see if a key is picked up
beq $t2, $t4, GetKey # if the return value byte = k, you get a key!
lb $t2, special2 # load byte to compare and see if a key is used
beq $t2, $t4, UseKey # if the return value byte = u, you need a key!
lb $t2, special3 # load byte to compare and see if the game is won
beq $t2, $t4, Live # if the return value byte = l, you survive!
jr $ra # no special input results; continue with the room number

# when an input result means you pick up a key
GetKey:
lb $t2, false # load the false byte up
bne $s6, $t2, HaveKey # if you have a key, you can't pick up a key
li $v0, 4 # get ready to print some text
la $a0, pickup # load the address for the key picked up feedback
syscall # print it
li $s6, 1 # key = true
addi $t1, $t1, 1 #moving to first character of new room number
lb $t4, ($t1) # loading first byte of new room number
jr $ra


# if you already have a key, you can't pick another one up
HaveKey:
li $v0, 4 # get ready to print a string
la $a0, alreadyHave # you already have the key, knucklehead!
syscall # print it
j DispCandle # go build the room

# when an input requires that you use a key
UseKey:
lb $t2, false # load the false byte
beq $s6, $t2, NoKey # if you don't have a key, you can't use it
li $v0, 4 # get ready to print some text
la $a0, unlock # load the address of the "you did it!" text
syscall # go print it
li $s6, 0 # get rid of the key

# changing room number
addi $t1, $t1, 1 # moving to first character of new room number
lb $t4, ($t1) # loading first byte of new room number
jr $ra

# check whether a key is in inventory
NoKey:
li $v0, 4 # get ready to print some text
la $a0, doNotHave # load the address of the "you need a key, dolt!" text
syscall # print it
j DispCandle # go build the room

# when your input wins the game
Live:
li $v0, 4 # get ready to print some text
la $a0, live # load the address of the "you survived!" text
syscall # print it
j End # Game over, man! Game over!

# when your candlie hits 0 (not necessarily special input)
Die:
li $v0, 4 # get ready to print some text
la $a0, die # load the "you dead, mofo!" text
syscall # print it
j End # Game over, man!, Game over!

####################################################
# procedure to concatenate filepath, room, and
# specified file to open for room configuration
####################################################
GetFilename:
la $s1, filename # will be writing bytes to filename
la $s2, filepath # loading generic filepath into $s2
la $s3, room # loading room number into $s3
la $s4, readFile # loading name of file to read into $s4
j ConcFilepath # start concatenating the file path

ConcFilepath: 
lb $t0, ($s2) # get character at address 
beqz $t0, ConcRoomNum # if the whole path is loaded in, get the room number, too
sb $t0, ($s1) # else store current character in the buffer 
addi $s2, $s2, 1 # filepath pointer points a position forward 
addi $s1, $s1, 1 # same for filename pointer 
j ConcFilepath # loop

# I hate code repetition, but this makes the app
# more flexible
ConcRoomNum:
lb $t0, ($s3) # get character at address
beqz $t0, ConcFile # if the whole room number is loaded in, get the room number, too
sb $t0, ($s1) # else, store the current character in the buffer
addi $s3, $s3, 1 # room pointer points a position forward
addi $s1, $s1, 1 # same for filename pointer
j ConcRoomNum # loop

ConcFile:
lb $t0, ($s4) # get character at address
beqz $t0, ReturnFile # if the whole file name is loaded in, return it
sb $t0, ($s1) # else, store the current character in the buffer
addi $s4, $s4, 1 # name pointer points a position forward
addi $s1, $s1, 1 # same for filename pointer
j ConcFile # loop

ReturnFile:
jr $ra # filepath is all written out, so return

####################################################
# procedure to open file specified in filename space
####################################################
FileOpen:
# open the file for reading
li $v0, 13 # system call code for opening a file
la $a0, filename # loading the file name
li $a1, 0 # loading said file for reading
li $a2, 0 # mode is ignored
syscall # opening the file (file descriptor returned in $v0)
move $s0, $v0 # save the file descriptor

# read from the file
li $v0, 14 # system call for reading from a file
move $a0, $s0 # file descriptor to read
la $a1, buffer # address of buffer to read into
li $a2, 1200 # max read of 1200 characters
syscall # reading from file into buffer

# close the file
li $v0, 16 # system call code for closing a file
move $a0, $s0 # file descriptor to close
syscall # close the file

jr $ra # file has been read into address 'buffer'

####################################################
# final exit code
####################################################
End:
li $v0, 10 # exiting the program
syscall # booyah!

0004 - Programmatically Running an SSRS Report Server Report in VB.Net (or other languages if you want to translate...)

This is just a solution to an interesting puzzle I recently encountered at work. Essentially had to combine 4 or 5 different solutions I found online as well as figuring out some of the eccentricities on my own. In the theme of this blog, I'm putting this here so that folks might be able to find the entire solution in one spot.

Note: you can change the code in step 6 to whichever language you're wanting to use. Also, you'll need to make sure you've imported everything you need (I think it's just System.SQL and System.Configuration, but there may be more...)