My plan to fight Trump

I am not writing this to brag about how amazing I am. I am writing this because I am scared and sad and I want to do everything I can to stop Trump from hurting people. And writing lists has always helped curb my anxiety.

I also want to try and recruit others, especially my friends within the tech industry, to come up with their own plans and share them. I urge you to think about and enumerate what you are going to do. Your plan is allowed to change, but having one, at least for me, means you’re more likely to follow through.

To that end, I ask that you please consider sharing this post.

This is bad. This is a worst-case scenario. This is proto-fascism well on its way to fascism. Have you heard that Hitler Trump might continue to hold large rallies? Have you noticed that in addition to all three branches of government, the GOP controls nearly 2/3 of state governments, the amount needed to amend the constitution? I can’t even begin to talk about how bad this is because I won’t be able to stop, and this article will never get to its point. I trust you, reader, to have your own understanding of how bad this is.

I feel sick. I have had, for the past few days, a dark vortex of despair spinning in the pit of my stomach and the back of my mind. I feel anxious, I feel powerless, I feel totally ripped off.

I also understand that this is how oppressed peoples feel, like, a lot the time.

Many people will find themselves abused by the government and its actors, and stripped of their voices. Women, undocumented immigrants, people of color, LGBTQ folks. They are humans and they have worth. They matter. I will fight for them.

I know that my personal social network, and the tech industry, has no lack of individuals who look and think a lot like me: highly privileged, usually white, fairly liberal men with high incomes and few financial obligations. Let’s step up.

Here’s my plan.

  • I will donate $75 a month each to Planned Parenthood, the ACLU, the EFF, MSF (aka Doctors Without Borders), and the SPLC. That’s $375 a month, a significant, but far from huge chunk of my post-tax income of about $4000 a month. I will remain very comfortable. I may decide to up my contributions.
  • If my post-tax income increases as a result of Trump’s tax cuts, I will spend all of the gains on charitable organizations. This especially I urge you to do.
  • I will volunteer with organizations directly help people. I haven’t yet decided which organization, but I am considering either Big Brothers Big Sisters (a youth mentoring program) or Lines for Life (a suicide prevention hotline).
  • I will continue to strive to be an effective ally. This is a complicated and never-ending goal, but, for example, I will try to put myself between Trumpist abusers and their victims if I witness it. I will offer compassion and material help to those around me who need it.
  • I will contact Democratic congresspeople and ask them to obstruct the GOP.
  • I will continue to not eat meat and try to spread a culture of vegetarianism. I originally became a vegetarian out of compassion for animals, but concerns for the environment have become my strongest internal motivator. The environment will suffer greatly under Trump as he attempts to dismantle the EPA, and eating meat is, plain and simple, really awful for the environment.
    • Many of my liberal friends laugh at the idea of giving up meat, but please consider cutting back, like by only eating meat on weekends or holidays.
  • I will continue to avoid using my car, partially an act of protest against our endless oil wars. This is possible because I live in Portland, OR, which has very decent non-car transport infrastructure. I tend to bike everywhere.

As all this happens, I will continue to be imperfect and make mistakes. I will fall short. I will love myself in spite of that. I will treat myself well, and I will do my best to surround myself with people I love. I will treat them well.

In addition,

Here’s what I will not to do, and what I think you should consider also not doing.

CW: Discussion of things Donald Trump has done, like, allegedly, child rape.

  • Act like we are faced with a normal GOP presidency. He is an (alleged) child rapist, overt racist and misogynist, con-man, (alleged) rapist, braggadocios pussy-grabber, lying sociopathic wannabe autocrat, and (alleged, but come on) rapist. This is not normal, and it is not okay. He was helped into office by a coalition of white supremacists, a spineless GOP, a corrupt FBI director, and Vladimir Putin. Many of his electoral gains were made possible by SCOTUS’s gutting of the Voting Rights Act, and the subsequent widespread voter suppression. And though he won the electoral college, Trump lost the popular vote by around 2 million votes.
    • Let me repeat: This is not normal.
  • Pretend that he didn’t win the presidency. I don’t see denial of his ascendency as productive.
  • Hunt for a silver lining in a Trump presidency and firm GOP control of all three houses of government. This is just 100% bad.
    • Other good things happened on election day, though, like our first Latina senator, or the ouster of Joe Arpaio. About fucking time.
    • But these do not diminish the badness of Trump.
    • Specifically, I swear to god if I hear one more person say “I can’t wait for all the great protest music that comes out of this” I’m gonna flip.
  • Fail to recognize the central role of misogyny in Clinton’s (electoral) loss.
  • Give Trump the benefit of the doubt and offer appeasement, as some tech folks are already doing. Words are actions. Trump has already caused a huge amount of damage by mainstreaming our nation’s hip new rebranded white supremacy movement, the Alt Right. Already you’ve heard on social media of attacks on women and minorities by emboldened Trumpists, of swastikas drawn in school bathrooms, of queer folks beaten. There is no need to wait for his damaging legislation to oppose him. Trump does not have good intentions, and I wish him the worst.
    • Even if he doesn’t want to repeal Obamacare anymore, he will almost certainly ruin it. Anything he touches will turn to shit. Because he is a Shit Midas.
  • Fantasize about how Bernie Sanders would have beat Trump.
  • Blame Trump on Clinton.
    • Trump is  the fault of Donald Trump, the GOP, Russia, the FBI, and, by and large, white people.
  • Fawn over the working class whites who elected Trump, and discuss how the Democrats need to win their racist hearts and minds back over. They are not the future of our democracy.
  • Complain about protesters ruining my commute.
  • Cling to the safety blanket of my privilege. As a wealthy (for my age) white man with a foreign passport living in Portland, I among the safest in Trump’s America. I could put on blinders and hide from this terror, but I will not do that. I will stay informed, stay awake (woke, right?), and stay active in the fight against him for the next four years.

Once again, please share. Stay safe. Love is real.

Vincent, 11/12/2016

Advertisements

Leave a comment

Filed under Uncategorized

No Man’s Sky birthday problem

Demo here. Code here.

My birthday is coming up in a couple days, so what better way to celebrate than by implementing a birthday problem calculator in JavaScript?

Don’t answer. I know the answer.

I actually started down this path after reading about how a pair of No Man’s Sky players have already found each other in-game, which was supposed to be nearly impossible. In fact, it’s happened a bunch. I suspect that the developers have underestimated a version of birthday problem. That’s the thing you might have heard about in elementary school, where a surprisingly small group of people will likely have a pair of individuals with the same birthday.

I’m not the only one to come to have this idea, as this comment by reddit user madbadanddangerous shows.

I’ve heard that there are about a billion planets a player can start out on (out of some quintillions of total planets). And the game has sold at least a couple hundred thousand copies, so let’s assume 150,000 players.

Aaaaand my calculator cannot handle those numbers. It just freezes, and I think it might be one of those heat death of the universe length calculations.

UPDATE: I added and approximating calculator. It’ll work for huge numbers.

Aside: factorials shouldn’t be terribly complex calculations, so I think the computer just gets bogged down with trying to handle massive numbers. If you have a fix to this problem, please submit a PR!

Check out this less accurate but actually functional calculator to get a sense of the probability. Going with 1,000,000,000 planets and 150,000 players yields a ~99.998% chance that at least 2 people will start on the same planet. Seems a little high, but that’s the math!

Technical Summary

This was a small project, so there’s not much of a postmortem! It took me maybe 3 or 4 hours to write, which is 2 hours more than I expected. Which sounds about right.

I find the probability with  1 - (d!/((d-n)!) * d^n) , where d is number of days, and n is number of people, from this Wolfram Mathworld article. Wikipedia indicates that there are some ways of approximating the value faster. I might try that.

Much of the time was spent setting up Math.js after realizing that even the standard case with 365 days overflows JS’s integer type. I am surprised to find that Math.js’s factorial function doesn’t cache its calculations, which means repeated calculations aren’t efficient.

Still, factorials shouldn’t have O(n!) time complexity or anything. I think the sluggishness comes from managing the huge numbers involved. A billion factorial is flipping huge.

Another chunk of the time was spent googling how to interact with the DOM without JQuery. Turns out it’s possible, who woulda thought?

Anyways, there you go. The Birthday Problem. No Man’s Sky. Hash collisions.

1 Comment

Filed under code, Uncategorized

Reusable behavior in Ruby objects

Though my Forest project is still in its infancy (a mere 150 commits in), I have spent a great deal of my time wrestling with objects and the bridges between them. The hardest parts of the design are yet to come, like when animals begin interacting with (attacking? eating?) each other. But I’ve made a few major design choices so far.

Note: this article ends up kind of being a recapitulation of David Copeland’s very well-written and informative Re-use in OO, but I come to a different conclusion.

In particular, I’ve come to final (I think!) decision on how objects obtain shared behaviors.

Here’s the problem, in the most general sense: both Wolf and Rabbit should be able to change their location. They should be able to move. The code for movement should be shared.

Module mixins are not the way

My initial solution was to include a Movable module in both Wolf and Rabbit. This is the solution for which Copeland advocates. I walked pretty far down this path, and even found solutions to some of my problems, like that private methods defined in the included module are accessible to every other included module and the parent class. I wrote a blog post about my solution, but I mention at the bottom a remaining qualm: there’s nothing preventing a module from calling another module’s public method, as in this gist. They can do so easily and inexplicitly.

I envisioned a bleak future for my project, with included modules calling each other willy nilly, in all directions, forming intractable dependencies. This problem could be worked around by carefully maintaining unidirectional dependencies, but it would be ad-hoc and easy to break, unensured against by nature of the construct.

So I asked for help. My friends Devon and Forrest, fellow Dev Bootcamp grads (RACCOONS!), helped out. Forrest showed me the Copeland article, and Devon illustrated a technique of sharing behavior through composition.

A few acceptable solutions

Decorating objects to #move! through composition

What I’m going with is Devon’s suggestion. It has the benefit of ensuring that dependencies are explicit and travel in one direction. Additionally, instances only gain these abilities when you want them, rather than having always-on, and thus abusable, abilities.

This is an implementation of the decorator pattern, where Movable is the decorator. I was actually already using decorators in my code to create presenters (with view-specific logic), but I didn’t at first make the connection that it could be used to share behavior.

class Movable < SimpleDelegator
  def move!; ...; end
end

wolf = Wolf.new
movable_wolf = Movable.new(wolf)
movable_wolf.move!

Data, Context, Integration (DCI)

Jim Gay discusses DCI in-depth here, and I don’t understand it totally. Anyhow, it relies on modules extending objects as needed, rather than mixed into the class’s definition itself.

Note that usage is very similar to the previous solution.

module Movable
  def move!; ...; end
end

wolf = Wolf.new
wolf.extend(Movable)
wolf.move!

Duck typing your way to movement

Another composition / duck-typing solution is as follows, where the actual moving is delegated to another object or module. This is a partial solution.

I don’t like this path as much; I intuitively think that an object should be in charge of its own movement. I could envisage plenty of cases when it would be preferable, however, like if there was a Map object in charge of collision detection. You’d have to be vigilant in preventing the Map from becoming a God Object, though.

As stated, this is a partial solution. It doesn’t solve the problem of how to ensure a Wolf is a Movable in the first place. One could do that through extension or composition, as in the above two examples. It just changes where the #move! method lives, and implies that movement is the responsibility of a third object.

I like how “movable” makes semantic sense, though. And duck typing is just fun.

module Mover
  def self.move!(movable); ...; end
end

Mover.move!(a_movable_wolf)

Unsurprisingly

There’s more than one way to do it.

Module mixin on its own, my naive approach, seems totally untenable. It is multiple inheritance, as demonstrated by the fact that included modules are listed in a class’s .ancestors method. And inheritance can be a mess to begin with, without dependencies being able to go in all directions.

Please let me know if I you’ve got corrections or feedback! For example, I’d love to hear more examples of when the last code example is appropriate. I feel like it’s more useful than I am realizing.

Leave a comment

Filed under code, Uncategorized

Creating practically private methods in mixed-in Ruby modules

Module injection in Ruby is cool. It allows you to flexibly compose an object’s behavior (those it’s not composition; it’s multiple inheritance), while still leveraging the data/code coupling power of objects. However, it comes with its own set of complications.

A particular module might want to reduce its namespace footprint by exposing a small interface and hiding implementation functions. Take a look at the code in this gist. Both modules define an aptly-named private_method, but once they’re both included in the class, the second private method overwrites the first.

Ruby’s private keyword does not do what I want here, as methods defined within it share a namespace with all other included methods. You do not want a module’s private methods to have to compete for namespace, as no other parts of your code should even know they exist! This is a strong dependency.

There is an easy, common solution, but I have to admit that it feels hacky, and is certainly not semantic. By which I mean, this solution would never occur to me. But here: effectively private methods can be hidden within classes or modules defined within your original module, like in this gist. The idea is summarized as follows:

module MyFirstModule
  def first_public_method(my_string)
    return "#{my_string} #{PrivateMethods.private_method}"
  end

  module PrivateMethods
    def self.private_method
      1
    end
  end
end

This module can be included in your model classes, and Bob’s your uncle! The module exposes a public interface which makes use of private methods which truly do not effect anything else. It’s not too complicated, but don’t you agree that it’s a bit gross?

This doesn’t solve every problem of module injection, but it allows you to reduce surface area and make necessary dependencies more obvious. I’m currently trying to figure out how to prevent modules from being so easily able to call and depend on each other in inexplicit, unobvious ways. Like in this gist.

Leave a comment

Filed under Uncategorized

RESTful API design and implementation

Recently, while building the forest’s API and finding myself running into problems I’d never imagined would need to be solved, I realized that I know very little API design.

This implies I’ve learned some, and simply have a better view of the field than I did. This article (which concerns both design and implementation) discusses the things I have learned and contended with.

I’ve been reading https://geemus.gitbooks.io/http-api-design/content/en/, and studying a couple different APIs (e.g. GitHub, which is my favorite) to see how it’s done.

Anyways.

Versioning

APIs need to be versioned so that the developer can easily release new work. The two major schemes to expose different API versions: through request headers, and through the URI.

The header solution is the “most correct”, partially because it keeps URIs as an explicit and clean reference to a particular resource. Properly, the API version doesn’t have any bearing on the resource the client is trying to access, and thus doesn’t belong in the uniform resource identifier. That’s a sound argument.

However, several major players do use “api/v1/resource”, the improper and less technically RESTful method. And I’m doing it, too.

It’s easier for development. I don’t have to use curl or Postman to see what my responses look like. I can just visit localhost in browser. I also believe it’s a less opaque technique, and the only argument against it is an appeal to authority.

Here’s a good StackOverflow answer explaining why I’m wrong.

I agree that URIs should be permalinks, but a major API version change is likely going to introduce breaking changes. API consumers are going to have to change how they request the resource in any case. I’m much happier keeping the version totally in sight.

URIs dependent on params, not IDs

I want clear, beautiful URIs. Locations are best known by their Cartesian coordinates, not their IDs. Any Rails developer already knows that this is somewhat of a pain. Although custom routes are fairly trivial in Rails, these schemes can very quickly and easily get out of hand if not managed properly; such is Rails’ dependence on naming conventions.

I went through a couple thoughts on this, like for example /locations/x/1/y/2, but I eventually settled on a query string: locations?x=1&y=2

I found a couple of people discussing whether query strings are RESTful on StackOverflow. It would seem that there’s no reason for them not to be; REST merely asks that resources have unique endpoints.

Of course, dictating to Rails that I want every location’s URI to use the query string rather than an ID meant clobbering DMM’s opinions.

Here’s some of the weirder stuff I had to do to get this scheme to work:

JSON layouts

That bullshit concerning rails-api and JBuilder that I already wrote about.

It makes no sense that this isn’t built into rails-api. The main draw of Rails is that it’s opinionated, and thus does a bunch of heavy lifting for the developer at the cost of flexibility.

There’s a bunch of stupid rails-api stuff I’ve complained about on Twitter.

HATEOAS

This is a large topic that dictates much of the forest’s design. It’s taken a lot of work, and I barely have it in place. HATEOAS is an aspect of REST that most APIs do not bother with; developers (not unreasonably) expect consumers to rely on separate documentation to get around. GitHub is my model API because they actually do implement it, and they implement it well.

I would love some back-end framework that makes this easier, like Rails makes every other common task easier. That’s a niche I would have expected rails-api to fill. Yes I’m bitter.

HATEOAS breaks down into a few sub-issues.

  1. Return relative or absolute URIs?
  2. Where should actions be in the response? All at the top level in one list or object, or some actions per object?
  3. What do action routes look like?

So, 1), I’m going with relative, rather than absolute, URIs. A couple of the reasons for this are, unfortunately, because Rails makes it easier to use relative URIs. URL helpers like url_for and [resource]_url return relative URIs by default. Additionally, RSpec makes it hard to get(absolute_url), so I’d have to add a bunch more boilerplate to the tests.

Here is a good discussion on paths on StackOverflow.

Github uses absolute URIs for action routes. They say it’s so the client doesn’t have to construct the URI themselves. Fair enough; it does take a little work for the client to construct URIs with the scheme I’m using. However, they would probably only need to implement that solution once in that project. I don’t expect it to be too onerous.

2) Right now, actions in the API response are presented like this:

location: 
  actions: {...},
  objects: [{
    kind: wolf,
    actions: {...}
  }]

Actions are stored in location.actionsand in location.objects[i].actions. They are organized according to what the object the action is on, but as a result are scattered throughout the JSON.

I could also have a big ol’ hash or list at the top level simply labelled actions which would contain every action possible at that moment. It would be very easy to find, and namespacing actions within could help organize them.

My main concern here isn’t whether one thing is more correct that the other. I’m struggling with what solution would be easiest for the API consumer.

In terms of development from the API maintainer’s perspective, the current setup is easiest. So that’s that. If it turns out to be awful from the consumer perspective, I’ll look into changing it.

3) And what should actions look like? Specifically, let’s say hello to a wolf. Is that:

  • /wolves/1/action/say-hello
  • /wolves/1/say-hello
  • /wolves/1?action=say-hello

I’m pretty sure I’m gonna go with the second option, although if the forest ever has nested resources, it could get to be a problem. The solution is to say “no nested resources!”, but that seems pretty limiting. We’ll see!

Well

Designing and building this API has taught me so much that I didn’t know I didn’t know. It’s been so much fun! Because my collaborators (looks like Ryan‘s on board!) and I are basically the only people consuming the API, I have a pretty good idea of what the client’s needs are. Having to deeply consider both sides has given the process a lot of helpful direction.

Leave a comment

Filed under code, Uncategorized

What I learned from a React code challenge

I’m currently on hold with the Oregon Employment Department, and as a result don’t feel that I have the focus to design and implement some extra features. I’ll write a blog post instead!

An employer emailed me and asked me to complete a code challenge: create a simple to-do list in React. You can see the todo list I built here. I would have liked to style it a bit just to show off my design and CSS chops, but I focused on implementing features and ran out of time.

I’ve written todo lists in React before, but I always followed a tutorial. In this case, I kept honest and wrote everything from scratch. Without someone guiding me, it took longer than I expected, but I learned an awful lot more! I found myself really enjoying this challenge.

I probably made some beginner mistakes, and implemented some anti-patterns. If you notice any in my code, I’d love to know about them.

So.

Step one was to find a React and Webpack boilerplate. I was googling around, and found plenty of super-complex, production-ready solutions. They transpiled ES6 or 7, and included hot module reloading, local dev servers, deployment scripts, and test helpers. I didn’t want any of those. I wanted something that would use Webpack to build all my JSX modules into one JS file that I could include in some basic index file I could open in my browser. So I Googled “react webpack barebones boilerplate”.

This very simple template is one of the first things to come up, which is surprising because it simply doesn’t work. Among other things, you need to include and use the React-dom module to render things to the DOM these days.

So I forked it, fixed it, and PR’d it. We’ll see if the maintainer accepts it, but now I could move forward with the challenge!

And like 70% of my time has been looking up and remembering syntax. I’ve written a fair amount of React and JSX, but I’ve written far more Ember and Angular. Generally, the “data down, actions up” philosophy makes plenty of sense. I think you can get a good sense of my workflow and thought process by looking at my commit history.

One of my first steps was realizing that React’s getInitialState() function unintuitively (to me) sets a component’s initial state.

Another important realization was that a component’s render() function is called every time the DOM is updated. For a while, I assumed it was called only once in a component’s life, but the fact that it is frequently called means that work done and defined within it is essentially dynamic.

And finally, I had to re-learn how to send actions up through the component hierarchy. I’m not using a Flux implementation here, so there’s no dispatcher involved. If an action at a low-level needs to change something higher-up, it needs to somehow invoke a function its parent passed down to it through props.

Instead of calling a prop function directly from the render, I found that delegating to a locally-defined dispatcher function (I’m not sure what the proper terminology is here) solved a lot of problems. That is to say, instead of this:

render: function() {<button onClick={this.props.addThingie}></button>}

do this:

render: function() {<button onClick={this.handleClick}></button>},
handleClick: function(e) {this.props.addThingie()}

Not only is this prettier, but it gives you more flexibility. Instead of the addThingie() function only getting access to the click event (and thus its target and its value), you can pass addThingie() anything you’d like. Possibly something from the child’s state, or something that is computed within handleClick(). You can also do more work within handleClick(), such event.preventDefault().

In my code sample, I haven’t gotten the time to implement todo editing yet, but I am now confident that I could do so! Before this code challenge, I wouldn’t have had that confidence. That’s pretty cool.

Leave a comment

Filed under Uncategorized

The Jacket.

This is just a little anecdote about a hackathon I went to in 2015. There isn’t some big declaration at the end, but if there is a thesis or moral, it’s this:

Fun is tremendously important to me.

And maybe:

Do scary things.

I signed up for a hardware hackathon (Hack to the Future, held by hackster.io and the super-great Adam Benzion) with my friend Stephen a while ago, just after graduating from Dev Bootcamp. It was a super uncomfortable position for us: not only were super green as developers, being barely able to cobble together a crappy CRUD app, but we were (and are) web developers. We knew next to nothing about hardware. It was terrifying.

I distinctly remember the first morning of the two-day hackathon. We were supposed to mill about and socialize. Stephen and I were so intimidated that we almost left without participating. We managed to dare each other into sticking it out for at least a little while. We had paid for entry, after all.

I talked to a few people, and was continuously made aware of the fact that I was inexperienced, out of my element, and that all my hardware ideas were stupid. I floated the idea of building a telescoping hat that could telescope up and down, partially joking. People let me know it was a stupid and out-of-place idea. I agreed and kept quiet, fuming.

Eventually, it came time for people to announce project ideas out loud; if someone was interested in your idea, they would come over to you and teams would form sort of organically. As it came time for me to yell out, I quickly edited my original thought:

“IT IS 2015, THE YEAR IN BACK TO THE FUTURE 2, AND WE STILL DON’T HAVE THOSE JACKETS WITH RETRACTABLE SLEEVES. THAT’S WHAT I WANT.”

I got laughs and applause, and then I got a team: Stephen; a computer science student (Martha) and an engineering student (Stephanie) from SFSU; and a couple pals (Ken and Tinic) with deep hardware prototyping experience (e.g. laser cutting and 3D modelling and printing). After that, I actually had to turn a couple people away. People were excited to build this stupid project of mine. I was gushing, proud, and terrified. Then we got to work.

Marty McSleeves was born.

Vincent wearing the jacket while Stephanie works on wiring it together

A lot of the time, I served as team mannequin.

It was magic. One of the team members donated a jacket. Martha and I did some sewing. We modelled and printed the spools and housing, spooled fishing line on them, sewed them into the jacket’s shoulders. I spent all night at Noisebridge in the Mission sewing washers into one of the sleeves! The servo motors (housed in components built by Ken and Tinic) were controlled by a Spark core, which exposes its internal methods as an easy-to-access web API. Those methods were written by Stephanie and Martha. Stephen wrote a web client using Node and Express, we deployed it on Azure, and Bob’s your uncle. More than once the spools got tangled and jammed, and some API calls were behaving erratically, but we had done it:

A jacket whose sleeves would go up and down based on a button you click in your browser, and I got to call myself “team lead” the whole time! And we made it in 48 hours! I am still stupidly proud of it.

You can see the Hackster project page here.

the 3D printed components in the jacket, and the servo motors they housed.

Servos with 3D-printed spools and their 3D-printed housing, which would later be sewn into the shoulders of the jacket.

Here’s a video of this janky, hacked-together thing in action.

I made friends, I had fun, and I learned a lot by doing something I was totally uncomfortable with. I think this was true for my teammates as well. It was a huge personal win.

Then came the judging.

Which, I dunno. I have very mixed feelings about judging in hackathons. Unless there’s a specific need for it, I tend to favor the approach of “the team that had the most fun won!”. But we had judges, and they had criteria.

We set up our table like it was a science fair, and I delivered our spiel. As it happens, when the judges saw our results, the jacket’s spools were jammed and we couldn’t demo. I hardly saw that as an issue. We showed them a video instead.

But the judges were obviously disappointed. They followed up by asking me what sort of market I foresaw for this kind of product.

I said this was for fun. Obviously no one would or should try to market this.

We got an honorable mention.

Almost every other team got a special sponsor prize with an actual reward. Almost every team also tried to create something useful or marketable. I somewhat bitterly suspect our mention was a consolation prize.

There is nothing wrong with creating a product that helps people or is profitable. Indeed, those are good things that we should usually strive for.

But this was a hackathon. I approached as a space in which to create without judgement, cut off from the demands of Silicon Valley. I was bummed! Oh well. By my criteria, we won by miles.

There are other hackathons out there with a philosophy closer to mine, e.g. the beautiful Stupid Shit No One Needs and Terrible Ideas “Hackathon”.

The Snackathon

And in a couple weeks, I’ll be self-hosting what I’m calling the Snackathon, a tiny little hackathon among friends with a similar idea. Maybe every single project will win an esoteric and customized prize. Maybe they will be snacks.

The primary goal is for it to be fun. Let me know if you’re interested!

I’m so stoked.

Leave a comment

Filed under Uncategorized