Improving Comedy by Imitating Nathaniel

My cousin Nathaniel (called ‘Nano,’ since that’s how he pronounces his name) has Down Syndrome. He is charismatic, exuberant, affectionate, and driven by a desire for attention. In other words, he’s exactly like a comedian.

Comedy genius

As I’ve been formally studying comedy, reading about the structure of jokes, I think back to some of Nano’s performances: he has an intuitive understanding of basic joke structure. For instance, here’s his favorite joke:

That’s Kaiser. No, I am just kidding. That’s Schaeffer.

Here, “That’s Kaiser” is the premise. It’s a false premise, which establishes the expectation that the person he has identified is Kaiser. “That’s Schaeffer” is the punchline – he reveals the truth that the person he’s pointing to isn’t actually me, but rather my brother. And of course we need the sentence in between them for narrative purposes, because otherwise we’re just making two contradictory statements, one after the other.

He iterated on that joke, too. He punched it up by simply calling people by the wrong name, and then laughing. Instead of telling a joke for the sake of the whole room, he did crowd work with an individual, which serves to really engage that one audience member so that they’ll laugh more and bring up the energy of the whole room.

I don’t mean that Nano is doing this on purpose. He’s genuine, raw, and necessarily improvised, which means that his performances are really authentic and conversational. Sometimes this means that he can lose the audience, or that we might go too long between laugh points and get bored. But we can consciously consider the differences between when his antics make us laugh, versus when we’re annoyed with our family member, and use that information as either a pattern to follow or an antipattern to avoid in our own comedy.

Nano also has a tape recorder, which he’ll use to record the audio of things he likes on YouTube, or just to record himself talking. He’ll play it back, and just listen to previous monologues he’s delivered over and over, intercut with this constantly-expanding YouTube-driven mix tape. It’s common advice that you should record every set, listen to it, and consciously consider how to improve. I actually think there’s value in even the type of undirected listening Nano does – he’s not taking notes and tweaking his jokes, he’s just re-listening. When we do that, it helps subconsciously remind us what the order of the routine was last time; if we spoke imperfectly, it also constantly reminds us of the thing we missed, and helps us avoid repeating the same mistake the next time we do that bit.

So be kind and energetic; be direct in your joke structure, with punchlines as close as is practical to the setup; consider your audience feedback; and record and listen to your sets. Really target Nano’s methods. You’ll be glad you did!

 

Getting Started in Stand-up Comedy

Stand-up comedy seems to be undergoing an ongoing resurgence in popularity. Part of this is probably Netflix’s appetite for low-cost content: stand-up is even cheaper to produce than reality TV. The variety of new content delivery channels like YouTube also means that barriers to entry are lower than ever for new performers, and stand-up is easy to bootstrap. Finally, I moved to San Francisco from Montana recently, which means that now I live in a place where there are a bunch of stand-up comedy venues, so maybe it’s always been this popular and I just now noticed.

Kaiser at Edinburgh Castle Showcase

 

Many of us watch comedy in part because we’d really like to perform. We’ve all told jokes that our friends have laughed at, and the glamorous lifestyle enjoyed by luminaries like Louis CK and Bill Cosby is appealing. Like lottery tickets, cryptocurrency speculation, and startup equity, a successful comedy career promises fame, fortune, and a lifetime of enduring prestige. Unfortunately, it can be hard to figure out how to go from casually watching specials on your couch to actually telling jokes in front of an audience. I’ve been doing this for over two months now, and so I decided to write this guide to help you stop dreaming and start doing.

Step 0: Take a class (optional)

A lot of people think comedy classes are a waste of time and money. I respect their incorrect opinions, which is why I wrote “(optional)” up there and made this step 0 instead of step 1.

The funniest people I know didn’t take classes to start, and that includes the people who teach the classes I waste my time and money on. The funniest people I know also spent a long, frustrating time getting to the point where their material was strong and their delivery was funny.

Taking a class doesn’t immediately short-circuit the need to put in the time writing, re-writing, and practicing new material. But it does hold you accountable to work on your jokes every week, and it comes with a built-in framework to get started. Furthermore, your classmates will be a more forgiving and engaged audience than any you’re likely to encounter elsewhere. Finally, many of those same classmates will be out there trying to do comedy themselves, which means they’ll invite you to quality open mics and shows.

I take a weekly class at the SF Comedy College, which I highly recommend if you’re local.

Step 1: Write and practice some jokes

This is a stock photo from energepic.com which I am using to represent ‘writing’

This seems obvious. It’s not. Some people come out to do comedy and they don’t have jokes. They have stories, which might have a sensible chuckle somewhere at the end, but are otherwise sad, rambling, and hard to follow. Depending on the performer that can still be engaging enough that the budding comedian will keep trying it.

Sometimes, people will come out there without any jokes and just try to come up with them on the fly. That’s no good either. Those people are me. I do that. Don’t do that. It’s a huge waste of everyone’s time.

Look: jokes have punchlines and tags and laugh points. I’m not telling you how to design jokes, or opining on the nature of humor. I’m just suggesting, gently, that you tell jokes as part of your comedy routine.

It’s also important that you practice the jokes before you go on stage to tell them. You don’t have to memorize the funny bit about your cat eating your gluten-free quinoa like it’s Hamlet’s soliloquy, but standing up there and reading verbatim off your phone can be really frustrating and it creates distance between you and the audience. I’ve done that, too.

Step 2: Find an open mic and tell your jokes

This is me again. I don’t have a bunch of pictures of other comedians I can just use for this.

Tell your jokes to other people. Tell your coworkers. Tell Lyft and Uber drivers. Corner your neighbors in the elevator. Once you feel confident that you’ve hit upon something funny, find an open mic in your neighborhood and try it out! Depending on the audience, your delivery, the quality of the material, and any number of other factors, the people there might not laugh at it. Other comedians often don’t laugh even at jokes we think are really good. Sometimes we’ll shake hands afterwards and say “good job,” which is genuine.

Most open mics will let you go up for about five minutes. Some will let you have four minutes, and give you more time if you buy a drink. Sometimes, especially if there aren’t too many people signed up, the host will let you go for nine or ten minutes, until you run out of material. In any case, they’ll flash a light at you to let you know you should wrap it up – it’ll probably be the face of a cell phone or a smart watch, but it might be an actual flashlight. Usually, the light means you have one minute left. Once you see the light, wrap up your set and get off the stage. It might not seem like a big deal to you, but for professional gigs, “running the light” (going over time) can seriously mess with other people’s schedules. Get into good habits now. Once you get the light, finish up your current joke and say goodnight.

The jokes that are the best are usually the jokes that get laughs, and you keep those around and try to iterate on them – in software development, we talk about A/B testing, or the multi-armed bandit approach. That’s what we’re doing here. If you’re a psychology student, think about performing operant conditioning on yourself and your set, training your jokes to be good via the stimulus of audience reactions.

If people don’t laugh – and they won’t, not as much as you expect or hope – that’s okay too! If it was easy, if you could just come out and be like a combination of Dave Chappelle and the ghost of Richard Pryor after writing jokes for half an hour, there’d be no reason to do it. Keep practicing, keep writing, and keep attending open mics.

Step 3: Be a regular at your favorite open mic

TK Moyer, @tkmoyer88 on social media, host of my favorite open mic

If you remember only one thing from this post, make it this one. If you go to different open mics all over the city you’ll see a whole lot of new faces, hear a whole lot of new jokes, and you and they will blend forgettably into each other’s backgrounds. If you pick one open mic and make it your church, though, it opens up the possibility of building a real mutually beneficial promotional relationship with the venue. The other regulars at the same place will have seen you before, which encourages you to try new material frequently so they don’t get bored. It also means that the other regulars will grow to like you, which means that your performance will be more engaging, and you’ll get better feedback.

Furthermore, if you get to the point where you’re feeling confident enough that you want to invite your friends and coworkers to come watch you, having a consistent time and place at which you do comedy means that they’re more likely to be able to attend in the future. If your schedule constantly changes, it’s harder to bring an entourage with you, which means it’s harder for the venue to care since you’re not bringing in people who will buy drinks.

I got really lucky with this strategy. The first open mic I went to was Edinburgh Castle Pub, which is a short walk from my apartment. The host, TK Moyer, is a high-energy showman and a great comic, which makes it easier to bring other comedians and audience members back again and again. Really this whole blog post is just an ad for the Edinburgh Castle open mic, which happens every Monday at 8 pm at 950 Geary in San Francisco. 

Step 4: Keep going

It’s hard. Comedy is hard. You get funnier as you keep working at it. You get funnier faster if you work at it consciously, considering the rhythm of the setups and punchlines and tags instead of just going at it haphazardly. But regardless of how quickly or slowly you improve, you have to put in the time.

 

Wrapping Text and Making Memes

Play with the meme generator here.

The project I’m moving to on Monday is written using a different tech stack than what I’ve done previously. Instead of a web service in Spark or Play, this is a world-facing web app written in Spring Boot. I’m decently comfortable with Spring for dependency injection, so jumping in isn’t too terribly weird. I chopped up their tutorials on form submission and handling uploads and built a feature-poor meme generator.

Captioning images on the server side is a task for ImageMagick, or at least it used to be. I found Im4Java, a Java wrapper last updated in 2012, and hacked together a service method to write some text on the image:

It’s not my favorite code I’ve ever written. The wrapper library is fighting an uphill battle because you’re literally just putting a string together and then executing it as a system command, and that makes it difficult to get useful feedback. You have to call those property methods on the operation object in the correct order, since they’re just concatenating the string together. It’s frustrating. But it kinda sorta worked, and the rest of the application did some file storage and form handling stuff, and it served the purpose of “play with Spring Boot.”

Unfortunately, I didn’t have the means to compute how big the text was going to end up being on the resulting image.

download

When I showed this to my friend Chase Maier, he pointed out that this is a much easier task using an HTML5 Canvas – splat the image onto the canvas, draw your text, and do whatever you want with it. Now, “play with canvas again” doesn’t count for the “play with Spring Boot” part, but we’ll still be able to do our persistence in Spring Boot later.

The full source is here, but let’s focus on the js method that’s doing the equivalent of my java code above:

It’s not that the equivalent js code is much more compact than the Java code was – the important thing is that it’s easier for me to measure the width of the lines for the sake of wrapping:

The results are much prettier:

download-1

Fractal Simplex Noise for Procedural Terrain Generation

Noise is great for procedural generation. Rather than just turning a pixel on or off in a vacuum, we apply a random gradient function over the entire output space, and so each pixel is close to its neighbors. If we interpret the output of Perlin noise as being a brightness value for each pixel, for instance, we get something like this, depending on the scale of our function:

perlinnoise2d1x2x

Like a freeze frame of the static you’d get on an old tube TV tuned to a channel that didn’t exist, kind of.

We can re-scale the noise function’s input so that the gradient bounces back and forth more or less quickly between values. Simplex noise at a very small scale looks like this:

static

Now, neither of the above are particularly believable terrain, at least not on their own. In the past, I’d tried generating terrain by taking relatively course noise, and summing it with some deterministic function, like the distance from the center of the output space, or the distance from the edges. That worked okay, but resulted in very circular or very square islands, with a high peak in the center.

A better approach, at least for rapid development, is to re-scale our noise function so that we have relatively course noise responsible for the general outline of the world, and finer and finer noise functions added to it to create some excitement around the edges.

We can supply whatever value we’d like for the number of iterations – I think 5 is about right, but if you want your terrain to be more chaotic and for your daring adventurer to have less walking between mountains or bodies of water, you can reduce it.

The ‘tectonics’ function is my name for actually grabbing the noise for this iteration and adding the value to a given pixel:

That “maxElevationBeforeRescaling” variable is determined based on how many iterations we’re going to perform:

Running the code above (with the height and width supplied, and something to paint in an html5 canvas) we can get some pretty clouds:

clouds

That’s much nicer than the original static. WIth colors, we can make it clear:

And ultimately we get a pretty convincing distinction between land and water:

islands

You can hit kaiserleib.github.io/islands and refresh to get different coastlines, or view the complete source at github.com/kaiserleib/islands.

The thing that’s most impressive to me about this approach is how compact it is, given how nice the output is. With 50 or so lines of code (assuming we take the Simplex noise function as a given) we get a reasonably believable world, complete with elevation data. The generation process doesn’t mesh at all with real geology, but it’s compatible with algorithms for rainfall and erosion and biome placement and you can get a realistic-looking world out of it.

Now, it’s not terribly runtime-efficient. You have to compute Simplex noise five times for each pixel, which adds up fast. But it’s a comprehensible approach.

Selectively Disable-able Java CSRF Filters in Play! 2.5

I’ve written a little bit about CSRF (Cross-Site Request Forgery) protection before. Play provides strong CSRF protection out of the box, which is one of the things I like about the framework. To enable across-the-board CSRF protection, you create the following file, at app/filters/Filters.java:

Then enable the CSRF filter in application.conf:

And add a dependency for filters to build.sbt:

This will apply Play’s default, strong CSRF protection to every request which contains any cookies in the header.

In some cases, though, it’s important to be able to let cross-site requests happen for some (but not all) requests. In this case, ‘forgery’ is a misnomer, because we want the user to be able to make a request from our world-facing app, hit a microservice (for, say, authentication), and see results rather than being unceremoniously kicked out by an error message.

The most straightforward way to do that is with a blacklist: instead of you add an @RequireCSRFCheck annotation to all the form post methods which require CSRF filtering, and an @AddCSRFToken annotation to the action methods which generate those forms. This is tedious if you have many methods which require CSRF filtering and few that don’t. It’s also error-prone, and any oversight results in your security failing open rather than closed, which is not what we want.

Fortunately, although it’s not quite as straightforward, we do still have the ability to selectively disable a global CSRF filter, with just a little work. Moreover, we can do it in Java!

Steve Chaloner provides an excellent answer on StackOverflow detailing how to decorate Play’s routes file with comments to disable CSRF on a per-action basis. At SoFi, we like annotations, so we did it a little bit differently.

First, define an annotation:

We’ll use this annotation on any action method we don’t want to protect against CSRF.

Having defined the annotation, we then define a custom CSRF filter, which will replace the CSRFFilter in Filters.java. Save it as app/filters/AnnotationDisablableCSRFFilter.java:

The important distinction between my solution here and Steve’s solution from the stackoverflow answer is that we’re grabbing the class and method to which the request was made, then inspecting it for the presence of our @DisableCSRFCheck annotation.

Having implemented our custom filter, we then update the constructor of Filters.java, replacing the default CSRFFilter with our AnnotationDisablableCSRFFilter:

Whereupon we can go through and apply the @DisableCSRFCheck annotation to the action methods we wish to open to cross-site requests.

Play 2.5: java.lang.NoClassDefFoundError: play/mvc/Results$Status

Upgrading one of our apps from Play 2.3 to Play 2.5, I got the following:

This is maddening, in part because I’m able to hit many of the routes in the application just fine; only some of them barf. When they do, there’s no way to set a breakpoint: the JVM shuts down before hitting any of our code.

Ultimately, the issue is that we have a library that bundles the older version of Play. Migrating the library to 2.5 should solve the issue, but it’s not abundantly clear what the problem was based on the stack trace.

For this particular library, the Play dependency makes sense – we’re dealing with Play’s request and response objects using Play’s API, and it’s targeted exclusively for our Play apps. That being said, it’s a reminder of why in general we should avoid bringing framework code into libraries.

sql2o’s speedy vindication

Yesterday I wrote about a problem I’d run into with sql2o’s getKey() method. The sql2o developer responded to me on twitter, and pointed out that since sql2o is just calling the JDBC PreparedStatement.getGeneratedKeys() method, this isn’t wrong with sql2o per se: it’s a problem with the underlying JDBC driver and ultimately with postgres itself. Even people using straight JDBC have to do workarounds, and many of those workarounds end up being slower (requiring multiple queries) than simply guaranteeing that the leftmost column contains the generated value we’re after.

Much thanks to sql2o for the speedy response!

sql2o’s getKey() and postgres

sql2o is not the cause of this issue. It’s a problem with postgres’s JDBC driver. I retract any expressed or implied criticism of the sql2o project represented by this post’s previous title or the paragraphs below.

I’m using sql2o for persistence on my current project, a microservice written in Spark. Sql2o is a good fit both because it’s fast and tiny and because it minimizes configuration. It’s great (and I’ll write about how to use it later), but it has at least one really frustrating caveat: the Connection.getKey() method.

getKey() is supposed to give us the generated primary key of a newly-inserted record. In ORMs like Hibernate, we don’t need to do that: the object’s field corresponding to the key gets populated when we persist it. But it’s not so bad:

And for several hours today, it worked wonderfully.

My issue happened when I realized that I’d set up my table’s ID column as an integer instead of a bigint. This might be one of the occasions where we’d blow past MAX_INT. So I dropped and re-added the column, as you do:

And when I made another request to my microservice, I got an exception:

That right there is pretty darn un-google-able. There’s a stackoverflow answer that’s specific to PostGIS, but nothing that had to do with the apparent discrepancy between a Java Long and what should have been Postgres’s direct equivalent.

Thinking I was very clever, I decided to hammer a very duct-tape converter in there:

Which fortunately came back with a much more explicit exception:

I thought at first that the giant JSON object was the entire record, serialized, and that somehow I’d lost track of what the key should be and postgres or sql2o or an intermediate gremlin was relying on some mishmash of the entire record as a composite key. I re-created the key as an integer, making sure to specify that yes it was the primary key and yes the generation strategy and so forth. That didn’t help.

Staring at the exception, I realized that the String we were failing to parse as a Long wasn’t the entire object: it was the json representation of one of the child objects I’m persisting for this model. In fact, it was the second field specified in the model, and the second column I’d specified in my original CREATE statement. This leaves one very promising conclusion: that the leftmost column is the “key,” at least for sql2o’s “getKey()” call. Dropping and re-creating the primary key column the way I did moved it all the way to the right, so it wasn’t being returned by getKey() any more.

Dropping the entire table and re-creating it re-ordered the columns appropriately, and since the leftmost column was now the primary key again, everything worked.

Touch Events: Doodling from Mobile Browsers

Mouse events are not exactly the same as touch events, although they’re similar. That meant that my websocket canvas drawing app only did half its job on mobile pbrowsers: you could see the lines drawn by people on desktop browsers, but you couldn’t draw anything back. Here’s how to hook up a very simple touch event handler. MDN has a more complete reference.

First, we need to hook up the event listeners:

Then we write the event handlers. Since we want touch events to do the same thing mouse events are already doing, I extracted the mouse event handlers’ method bodies, and had both the touch event and the mouse event call the same function:

 

Note that our handleTouchMove function refers to an array of touches, e.changedTouches, using only the 0th element. The changedTouches array supports multi-touch, which is incompatible with our single-pen doodling paradigm.

Deploying a Spark application built with SBT to Heroku

Heroku is a cloud application platform that takes care of many operational concerns – since I have to serve as my own devops for extracurricular projects, that’s pretty appealing. Spark has a tutorial for Heroku deployment, but Spark’s tutorials assume you’re using Maven, and I’m using SBT. Fortunately, Heroku provides an SBT plugin and a reference. Between the two of ’em, we can figure out what to do to deploy a Spark app (in this case, my websocket canvas doodler) to Heroku.

  1. Sign up for a Heroku account, and install the Heroku toolbelt.
  2. Set up your SBT and Spark app.
  3. Add the sbt-heroku and sbt-native-packager plugins to plugins.sbt. Note that the version of sbt-native-packager is different from that described in the Heroku reference:
  4. Add this method to your Spark app, and call port(getHerokuAssignedPort()); in your main() method to determine the port assigned by Heroku:
  5. Create your Heroku app, using the -n flag to avoid adding a git remote:
  6. Add enablePlugins(JavaAppPackaging) and herokuAppName to build.sbt, replacing “your-app-123” with the name Heroku assigned your app:
  7. Finally, deploy the app:

Having completed these steps, you can navigate to your app at http://your-app-123.herokuapp.com, replacing “your-app-123” with the name assigned in step 4.