So I have a node.js application that contains the getAccountInfoFromToken function below, and I want to test it with Mocha. This function has been gutted and the account details are embedded now instead of called in to make the example clearer.

Promise = require('bluebird'),
getAccountInfoFromToken: function(token) {
    return new Promise(function(resolve, reject){
        // Get Account details
        var sample_return = {
            "accounts": [
                {
                    "account_id": 1725389
                }
            ],
        };
        var accounts = sample_return["accounts"];
        if (accounts.length > 0) {
            resolve(accounts);
        } else {
            reject('No Accounts');
        }
    });
}

So initially I took a very naive approach to the test because I wasn’t clear on how javascript compared arrays. So I had the test you see below.

"use strict";

describe("token_vending_machine", function () {
    var tvm = require("../src/server"),
        sinon = require("sinon"),
        assert = require("assert"),
        expected_token_return = [
            {"account_id": 1725389}
        ];

    describe("#getAccountInfoFromToken()", function () {
        it("should return the right details when called with a token", function () {
            tvm.getAccountInfoFromToken("test").then(function (data) {
                assert.equal(data, expected_token_return);
            })
        });
    });
});

However Mocha would report that as a pass but then I got an error from Bluebird about a possibly unhandled AssertionError… like you see in the output below.

token_vending_machine
    #getAccountInfoFromToken()
    ✓ should return the right details when called with a token
Possibly unhandled AssertionError: [{"account_id":1725389}] == [{"account_id":1725389}]
    at /Users/jmyers/dev/token_vending_machine/test/tvm.js:40:24
    at tryCatch1 (/Users/jmyers/dev/token_vending_machine/node_modules/bluebird/js/main/util.js:43:21)
    at Promise$_callHandler [as _callHandler] (/Users/jmyers/dev/token_vending_machine/node_modules/bluebird/js/main/promise.js:627:13)
    at Promise$_settlePromiseFromHandler [as _settlePromiseFromHandler] (/Users/jmyers/dev/token_vending_machine/node_modules/bluebird/js/main/promise.js:641:18)
    at Promise$_settlePromiseAt [as _settlePromiseAt] (/Users/jmyers/dev/token_vending_machine/node_modules/bluebird/js/main/promise.js:804:14)
    at Promise$_settlePromises [as _settlePromises] (/Users/jmyers/dev/token_vending_machine/node_modules/bluebird/js/main/promise.js:938:14)
    at Async$_consumeFunctionBuffer [as _consumeFunctionBuffer] (/Users/jmyers/dev/token_vending_machine/node_modules/bluebird/js/main/async.js:75:12)
    at Async$consumeFunctionBuffer (/Users/jmyers/dev/token_vending_machine/node_modules/bluebird/js/main/async.js:38:14)
    at process._tickDomainCallback (node.js:463:13)


1 passing (8ms)

That possible assertion error is a real thing because I thought my test was passing when it wasn’t because Mocha wasn’t getting the information it needed. Next I tried to catch the error and throw it. So I edited the test like so…

    describe("#getAccountInfoFromToken()", function () {
        it("should return the right details when called with a token", function () {
            tvm.getAccountInfoFromToken("test").then(function (data) {
                assert.equal(data, expected_token_return);
            }).catch(function (err) {
                console.error(err);
            })
        });
    });

That lead to a timeout error, which actually made Mocha show the test as failing. It also logged what the actual error was. That output is below

token_vending_machine
    #getAccountInfoFromToken()
{ [AssertionError: [{"account_id":1725389}] == [{"account_id":1725389}]]
name: 'AssertionError',
actual: [ { account_id: 1725389 } ],
expected: [ { account_id: 1725389 } ],
operator: '==',
message: '[{"account_id":1725389}] == [{"account_id":1725389}]' }
    1) should return the right details when called with a token


0 passing (2s)
1 failing

1) token_vending_machine #getAccountInfoFromToken() should return the right details when called with a token:
    Error: timeout of 2000ms exceeded
    at null.<anonymous> (/Users/jmyers/dev/token_vending_machine/node_modules/mocha/lib/runnable.js:157:19)
    at Timer.listOnTimeout [as ontimeout] (timers.js:112:15)

Now I knew I needed to use a deepEqual to get the test to pass; however, I still didn’t wanna have to wait 2 seconds per test for my test to get marked as a failure. Enter Mocha’s done function which tells Mocha that the test is complete. It needs to be called after the assertion, and in the error handler in order to work properly. Here is the updated test.

describe("#getAccountInfoFromToken()", function () {
    it("should return the right details when called with a token", function (done) {
        tvm.getAccountInfoFromToken("test").then(function (data) {
            assert.equal(data, expected_token_return);
            done();
        }).catch(function (err) {
            done(err);
        });
    });
});

the clearer Mocha output:

token_vending_machine
    #getAccountInfoFromToken()
    1) should return the right details when called with a token


0 passing (6ms)
1 failing

1) token_vending_machine #getAccountInfoFromToken() should return the right details when called with a token:
    AssertionError: [{"account_id":1725389}] == [{"account_id":1725389}]
    at /Users/jmyers/dev/token_vending_machine/test/tvm.js:35:24
    at tryCatch1 (/Users/jmyers/dev/token_vending_machine/node_modules/bluebird/js/main/util.js:43:21)
    at Promise$_callHandler [as _callHandler] (/Users/jmyers/dev/token_vending_machine/node_modules/bluebird/js/main/promise.js:627:13)
    at Promise$_settlePromiseFromHandler [as _settlePromiseFromHandler] (/Users/jmyers/dev/token_vending_machine/node_modules/bluebird/js/main/promise.js:641:18)
    at Promise$_settlePromiseAt [as _settlePromiseAt] (/Users/jmyers/dev/token_vending_machine/node_modules/bluebird/js/main/promise.js:804:14)
    at Async$_consumeFunctionBuffer [as _consumeFunctionBuffer] (/Users/jmyers/dev/token_vending_machine/node_modules/bluebird/js/main/async.js:75:12)
    at Async$consumeFunctionBuffer (/Users/jmyers/dev/token_vending_machine/node_modules/bluebird/js/main/async.js:38:14)
    at process._tickDomainCallback (node.js:463:13)

Now to actually make the two arrays compare properly and getting a passing test. All that we need to do is to do a deepEqual instead of an equal.

describe("#getAccountInfoFromToken()", function () {
    it("should return the right details when called with a token", function (done) {
        tvm.getAccountInfoFromToken("test").then(function (data) {
            assert.deepEqual(data, expected_token_return);
            done();
        }).catch(function (err) {
            done(err);
        });
    });
});

And our happy Mocha output:

token_vending_machine
  #getAccountInfoFromToken()
    ✓ should return the right details when called with a token


1 passing (6ms)

The Importance of Early (Organizers)

One of the most important time periods for a conference is the early bird periods. So you know you want to have an event, and the CFP is taking off. But, how on earth do you make it reality. This is where early birds and launch sponsors are a HUGE help. One of the most expensive parts of a conference is that up front section where you are need to secure vendors and make deposits. You’re not sure how big of a success your conference is going to be and you’re nervous about being on the hook for all these expenses.

Reaching out and engaging your potential attendees early is critical. It builds excitement for the event not on in them, but also in you. It’s this early excitement that you need to secure the initial funds required for a great event. In the early bird periods, you’d like to get roughly 40% of your tickets sold. The fervor will increase as the event gets closer, but deposits are a very, very real thing that is due up front. Consider offering hugely discounted tickets or other perks such as unique swag or recognition for your early bird and launch sponsors.

Don’t get discouraged, it’s a war and it will take time. You won’t sell out of tickets before the scheduled is even announced. So don’t fret it if you make your deposits, but don’t see every ticket. Keep contacting and reaching out to people.

The Importance of Early (Attendees)

If you are interested in an event, not only can being an early bird often save you money, but it ensures the viability of the event. It also keeps the organizers from going insane. It’s a HUGE undertaking to run an event, and the high they get with each ticket sale will propel the organizers to do even more than they often envisioned. Plus in community conferences, it’s people who have a shared interested in the same thing you do, and want to make a better community. This is a super simple way to push that forward.

The Importance of Early (Sponsors)

Being an early sponsor is great for your company. It makes sure you are the first name people see when they hit the website, and often those websites are hit most during the call for proposals, ticket sales launch, and the month leading up to the event. If you get in early, you’ll be there for all three of those time periods. Often times you can negotiate reduced rates or additional perks like special shout outs and mentions above your sponsored level. You also demonstrate to everyone visiting that page, that you care about the community in which they work. They will remember that the next time they need a service or are looking for a new job. Community focused customers and employees will push you to new heights. Also, many times you are a member of that same community and will want your own employees to attend. Your early sponsorship helps ensure the success of the conference.

This post is part of a series:

Proposals

Selecting proposals from the CFP process is very difficult, and you need a very diverse group of talk selection committee members. It is also one of the first parts where PR can get out of hand and negativity brews around the event. We received over 100 proposals, and we had a total of 36 slots… UGH.

PyCon has a great selection process in my opinion. It shifts through HUNDERDS of talks. You can see the details here. We adapted that slightly to fit the smaller scale of PyTennessee.

Overview

  • By Nov 3rd: Initial review took place on the website. The committee reviewed each proposal, left feedback for the author, and voted on the proposal using an “identify the champion” system. We also meet occasionally on IRC to discuss talks and coordinate feedback to presenters.
  • Nov 3rd: IRC review begins. The first round, nicknamed “kittendome”, reviewed each talk in isolation, determining if the proposal would be a “good talk” for PyTN. Some talks were rejected at this point; the rest will passed on to…
  • Nov 3rd: The second round, nicknamed “Thunderdome”. The remaining talks (typically about half of the proposals) were grouped by topic into groups of 3-5. During Thunderdome, we’ll discussed one group at a time, and select the best talk(s) from each group.
  • Nov 4th: Notify Speakers
  • Nov 15th: Publish Talk listing

Initial Review

The committee had two goals here: * Give feedback to authors and help them improve their proposals (authors could edit proposals up until the CfP closes). * Get an initial set of votes from as many committee members as possible. This will inform the later meetings.

We made sure that each talk got reviewed by at least 3 committee members (and ideally more).

Voting

The process we used to assess proposals was based on the Identify the Champion process. The idea is to to assess each talk and identify “champions” and/or “anti-champions” – people who will argue strongly for or strongly against a talk in initial review.

The document linked above uses an “A/B/C/D” scale for reviewing; we use the same idea, but use “+1/+0/-0/-1” labels (after the Apache voting system). These votes mean:

+1 – I will champion the talk at the program committee meeting. The topic sounds good and the proposal is solid. This vote means you’re willing to put your reputation on the line in favor of the proposal and its author, and that you believe PyTN would be worse off for not having the talk.

+0 – This topic is good and the proposal is solid. The speaker is capable of correcting any deficiencies, and I think a significant number of PyTN attendees would want it available. I don’t feel strongly enough about it to serve as its champion at the program committee meeting.

-0 – I am not in favor of this talk as proposed. The talk, the topic, or the proposal has problems that concern me. I’d rather see it not accepted.

-1 – This talk or its proposal has significant problems. I believe that PyTN would be worse off for having it, so I will argue strongly to reject this talk.

If you don’t know enough about a topic to judge a proposal’s coverage of it, or it’s a topic you tend to actively avoid, you should not recuse yourself from voting on that basis alone. You can still judge the structure of the proposal, the likelihood that the speaker can cover the material proposed in the time allotted, whether the topic is likely to appeal to others, etc.

“Obvious” accepted/rejected talks

After the initial review, there will be a small set of talks that are “obviously good” or “obviously bad”. We’ll set a threshold, by committee consensus, for talks that are automatically rejected or get to automatically skip ahead to Thunderdome. This is usually something like “reject all talks with 3 or more -1s and no +0s or better” or “accept all talks with at least 4 +1s and no -1s”. Let me know your thoughts

These accepted talks aren’t a free pass to PyTN - it just means that the talk goes directly to Thunderdome. A reject is final, however; it weeds out the few obviously bad proposals that nobody on the PC wants to support. After the initial review we had nine 45 minute talks, and six 30 minute talks that all had roughly equal ratings, or a program committee member who really wanted to raise a talk up the rankings.

IRC Meetings

Next, we held meetings in IRC to discuss the talks. We allowed a champion to speak for the talk being discussed, and allowed the rest of the program committee to respond. We then took another vote. This process continued until all of those talks were refined down to the list you see on the schedule, and a set of backup talks.
There we three attempts to add a 5th track to the conference to accommodate more of the talks. We wanted to accept many more talks than we did; however, we have a big enough event on our hands now for a first one. Then we wrapped up with a vote on the conference as a whole. The question was, “Did anyone feel that any one talk would detract from PyTennessee being a great conference?” After that passed, we have the list you see today

Kittendome

In the first round of meetings, we went through each proposal individually. The goal here was simple to determine if a given talk – reviewed in isolation – is potentially good enough for PyTN. That is, in the first round we reviewed talks strictly on their merits and avoid holding them up against similar talks (we do that next, in Thunderdome).

We reviewed talks, one at a time. We gave a couple minutes for the champions (identified by the website votes) to make an argument for the talk. Then, a few minutes of general debate. Finally, we voted yay/nay on each talk. Majority rules - a majority of “yay” votes will indicated that the talk was accepted – it moves onto Thunderdome. A majority of “nay” votes indicated that the talk was rejected – it’s out. The chair will break ties.

Thunderdome

After round one has ended, we’re left with a set of talks that are all “good enough” for PyTN, and so we pit similar talks head-to-head and try to select the best.

In each “round” of Thunderdome we reviewed 3-5 talks, roughly grouped by theme/content/topic/etc. Out of each group we’ll got one or more winners, possibly some damaged talks, and some talks that are out. We did this by discussing, and then the committee voted for the talks they liked. Members voted for any number of talks (including none or all of them).

The winners were the talks from the group that absolutely should be at PyTN. It advanced and was safe from future cuts. It’s on the program! The winners were talks that had a 75% supermajority.

Damaged talks were ones that had been voted down by Thunderdome but aren’t quite out of the running yet. There may not be any damaged talks in a given group, or all talks may end up damaged. Damaged talks are any talks that didn’t win, but did receive votes from at least 50% of the committee. Talks that were selected by fewer than 50% of the committee in attendance are out – they will not appear at PyTN.

We then allowed a champion to speak for each damaged talk, and allowed the rest of the program committee to respond. We then took another vote. This process continued until all of those talks were refined down to the list you see on the schedule, and a set of backup talks.

There we three attempts to add a 5th track to the conference to accommodate more of the talks. We wanted to accept many more talks than we did; however, we have a big enough event on our hands now for a first one.

Then we wrapped up with a vote on the conference as a whole. The question was, “Did anyone feel that any one talk would detract from PyTennessee being a great conference?” After that passed, we had the list that appeared at the conference.

UGH… DRAMAS

We attempted to do a fair and honest review of the talks, did we do a perfect job… No. Program Committee members were not allowed to submit talks, share talk reviews, or beseech outside opinions. During Kittendome and Thunderdome people abstained from voting for coworkers, bosses, close friends, etc. In my case, that meant I cast less than 5 votes the entire dome process for individual talks. :( I’m certain people could find flaws in our process, or point out some sort of bias.

I can be bought with Cookies, and that’s really no secret.

So what kind of drama did we have?

Well first, we were clear from the onset that we wanted to be a different conference. We picked a diverse group of talks, and didn’t limit ourselves to just python or even code. In fact, two of the highest vote getting talks were on Systematic Bias and Mental Health. Those were contentious in the organizers group, but the amount of “not python” was a shock to people. I got emails calling me stupid, saying I destroy the conference, and that I was doing Python a disservice.

Secondly, we choose to allow presenters to have multiple talks. During the domes, we didn’t pay attention to how many times a speaker names appeared in our selected talks other than to decide if we could vote or not due to some potential bias. After the committee members were done selecting talks, they noticed that a few speakers had multiple talks chosen. A discussion then occurred, and the decision was made to say these were the talks chosen, they are the talks that should be presented. Unfortunately, many of these people were friends or close to a few of the organizers. This also caused several emails accusing us of playing favorite or placating big name presenters, etc.

Finally, A few people we turned down sent nasty emails about how well known they were, or how great a presenter they are and how stupid I was for turning them down. In a few cases the submitted proposal was one line about the content and several lines about past presentations. As you can imagine the committee voted that talk down over one with a nice full proposal. I still got told I had no business running a conference, I obviously knew nothing about development, and that “my talk would have been selected at” conference X.

These three days lead to a massive cry!!! Thanks to strong support from the committee and a few members of our local community I made it through. I knew we had a great set of talks selected, and I knew that it was done as fair as possible. And a week later the drama had died down and people began to get excited about the talk selection and were tweeting about it.

And now looking back after the conference. It was totally worth all the drama. We had an overwhelmingly positive response at the event. I and the rest of the committee were ecstatic with the results.

This post is part of a series:

Venue(s)

Selecting a venue can be a long and frustrating process; however, it sets the stage for most every other aspect of the conference. It will be the stage for your speakers, dictate your food options, network choices, tracks, and schedule. During the venue selection process of PyTennessee we looked into about 10 different venues, and ultimately bumped up our selection a few times as our number of attendees increased. We initially expected 100 to 150 people, and it ended up a 281 registered and 247 attending.

Venue selection is a battle of compromises, so start by making a list of what you need from an event center. Our criteria for the venue were (in order): space for our conference tracks and young coders, security, price, A/V, WiFi, food availability, and hotel availability.

Space

When thinking about space for your conference, keep in mind how many tracks your gonna have, what kind of room layout you need, and how you will distribute any food or snacks. Also keep in mind how long you have access to the event space both for the conference days and setup/teardown. At PyTN, we only had access to the event space from 7AM-6PM Saturday and Sunday, and one classroom from 3PM-6PM Friday for setup time. This meant that we had only 3 hours to prepare for young coders, and our sponsors had to setup their tables Saturday morning. It also meant that we had to have any events after 6PM at another facility. Thank goodness Emma stepped up to help. This meant attendees had to find their own transportation from NSL to Emma to attend our party and sprints.

Our venue didn’t have a great way to setup for food. (it takes people way longer than you think to get food.) If you have more than 150 people, try to find a way to setup two lines. We had a good setup for many things, but I completely screwed up the food distribution process. We also had an issue with food for sprints the first night, as a vendor cancelled our order, another refused to help us, and we finally found a place but it caused our sprinters to get their food late. :(

Security

Wait, why is security so high on your list? Everyone has differing opinions about how to ensure the safety of their attendees. Some people like to use on campus/hotel security or use the local police force to handle any incidents. At PyTN, creating a safe place was a major part of our goals, and we wanted a visible security presence at all official events. Security is rarely included in the venue, but often they have pre-established relationships with security providers and occasionally pre-negotiated rates. For example, we used on campus security at the Nashville School of Law, and used Emma’s preferred security vendor for the events held there. We gave them simple instructions to mostly stay out of the way, but to make sure they made rounds and were noticed. Speaking of security, we treated them and all our vendors like they were our guests as well. We made sure to offer them food, shirts, stickers, bags, snacks, water, and anything else we thought they might want.

Pricing

The price for space is all over the place, and often the prices include bundled things or put restrictions on the vendors and services you can use. Often hotels and convention centers require you to use their kitchens, their A/V system or vendor, etc. This can make the overall cost of the conference more than you expect. So make a total cost sheet for every venue you look at so you can compare them accurately. You can see our cost of the venue and security during the day in the Space Rental fee, and Emma donated the use of their amazing space for sprints and the after party, but you can see our security costs for their space in the security line of our money post listed above.

A/V

A/V is the number one headache for speakers once they arrive at your site, and can affect video if you elect to do it at your conference. Make sure you have plenty of different input support, adapters, and patience. You will have speakers with every combination of OS, Window Manager, and output you can imagine. Don’t be afraid to ask the audience, often other people have a similar setup to the presenter, and will have the cable or adapter you need.

WiFi

Whatever you get it’s never enough… At the conference strive to have 1 ap/20 attendees (consumer access point) or 1 ap/60 attendees (commerical access point). Also, try to have at least 25Mbps download / 150 attendees. No that’s not a ton of bandwidth, but it will enable email, irc, etc. At sprints make sure to have 25Mbps / 30 attendees. These are my thoughts on the idea. Our wifi wasn’t perfect, but it was good enough for the event, and I heard zero complaints about it at sprints.

Food

Food is the greatest variable in a conference. It can cost next to nothing, or it can be your largest expense. Try to determine your source of food up front for both the conference days, and the other events such as sprints. This doesn’t mean you have to provide food, but it means you need to know how everyone is going to eat! It has to fit into your schedule as well. If people have to go out at lunch, you’ll need a longer break to accommodate that. Plan on providing snacks and drinks even if people are going to be going out for lunch. If your venue requires you to purchase food from them, be aware of the minimums and the cost per person. Food is also a chance for you to share a bit of the flair of your city. If your city is known for a type of food or a special restaurant try to serve or point people to that.

At PyTN, we had to supply food because the food options close to the venue weren’t very close or good. We attempted to have food for many of the different diets people follow. This is very difficult, and isn’t fully achievable. We did a decent job of having vegetarian options, but we failed to provide enough gluten-free options. To show off our city a bit, we served food from Edleys, Five Points Pizza, and Hattie B’s. The lack of acceptable food close by, and our food choices set our ticket prices for us. Food and space are the number one reasons PyTN wasn’t a free conference.

Hotels

Try to find hotels near your conference venue to reduce your attendees transportation requirements; however, attendee safety and comfort tops all! Nashville is a driving city, and we offered hotels that were 10 minutes away from our event venue to ensure they were in safe parts of town, and had quick access to food and grocery.

This post is part of a series and the first one is available here So if you read that and your still interested in running a conference let’s talk about the next scary topic before we move on into the good stuff.

There is simply a never ending list of things that require money when putting on a conference. This is a look at how we raised it, and the decisions we made with and about it.

Step 2: Money

So a conference has a ton of things that have to have deposits put down and ultimately paid in full. I’m gonna cover those in detail in the expense section below with the numbers from PyTennessee. Next I’m going to cover how we settled on the decision to charge for the conference and our ticket price. Finally I’m gonna wrap up with a section on handling sponsorships. None of these are 100% perfect, but it’s how we did it. NOTE: This is not our actually ledger, I rounded things off and I’m not disclosing direct amounts to or from individuals.

Before we go there, let’s talk about a very important part of the finances of a conference. If you don’t have an LLC, S-Corp, 501(c)3 etc, you will be personally liable for any issues at your event! Reread that sentence again. Gonna put in it forth in a different context. If you fail to have the money you need, you’re the one people will come to for the funds or refunds if the event isn’t satisfactory. Also, if you have a company behind the event, make sure to have an official rep sign any and all binding paper work to protect individuals for any extra risk. Get Insurance, and if you feel uncomfortable with anything just don’t do it.

Expenses

So let’s start with expenses. First and foremost, we had to have space to hold the event. When we started PyTN, we thought we would have roughly 100 people and maybe 150 at most. In fact our early sponsorship pitches talked about 75 to 100 attendees. We ended up with 281 tickets sold and 247 actually show up at the event. The venue we chose worked okay for the event, we could have used a better setup for lunch. Of course there is never enough wifi, but much of that just isn’t fixable in an event our size. The space rental was our 3rd highest expense. So these prices are rounded amounts for our event with 281 attendees. NOTE: We still had to pay this amount even though only 247 attended.

Nashville is a spread out city, and there weren’t a ton of close by food options so we had to provide food for our attendees as well. We also feed any speaker that wanted it food for every meal starting Friday at Lunch until Sunday at dinner. We also wanted to make sure attendees has plenty of snacks and drinks available at all times. This was our largest expense!

Our second largest expense was our young coders class, the costs for this included the RaspberryPis, books, and rooms. It also equipment rental to have all the needed monitors, keyboard, and mice required to hold the class.

Expense Amount
Food $7,600
Young Coders $4,500
Space Rental $3,600
Financial Aid $2,750
Bags $2,000
T-shirts $1,800
Printing $1,500
TEDxNashville $1,400
Paypal Fees $1,200
Prizes $1,000
Stickers $900
Badges $850
PyNash $600
Insurance $550
Security $500
Chair Expenses $400
EventBrite Fees $400
PyLadies $250

Total: $31,800

So the TEDx, PyNash, and Chair Expenses I feel need a bit of talking about. So TEDxNashville was the 501(c)3 we used to back PyTennessee. This greatly reduced the accounting and risk of putting on the event. The money we paid to them was used to help support their costs and expenses for servicing our event. This would have been WAY more expensive to attempt to manage and control on our own. We also gave in meetup, food and giveaways to PyNash to support the launch of a local Python user group. The last one was the cost for me to be able to spend the whole weekend in Nashville, I live roughly an hour away and it would have not been reasonable for me to drive home and back every day.

Optional Expenses

Another thing we looked into was having video done of the entire event. To me partial video wasn’t really an option. I didn’t want to pick who we did and didn’t record. Every presenter deserved video! I got compliments and comments on twitter about every single session. Video was priced to us starting at $7,000 and topping out at $9,000. This was over 25% of the conference budget! In the end we choose to grow the young coders class, and provide a better experience to the attendees that were onsite. Was this the right decision? It was to me. YMMV!

Ticket Price

So the first good conference organizer cry came over ticket prices. We knew that we couldn’t follow the awesome example of PyOhio, PyArkansas etc of having a totally free conference. Good food that could handle 281 people simply was not accessible nearby enough to have everyone leave and come back. We tried to figure up food costs and attempted to base ticket prices on that. Then we tried to work up a distribution so that the average ticket price would cover our food expenses. We collected roughly $10,000 in ticket sales prior to Eventbrite and PayPal fees. This made the average ticket price $35.60. Some had to pay more or less, but we felt this was a fair price. Then we began aggressively working to make sure we gave every single attendee that money back in other ways. Working out sponsorships that gave every attendee something. In our case that was a sling bag, shirt, O’Reilly ebook, Gondor credits, Emporium Discounts etc. I felt in the end that everyone got their money’s worth. Again this is my point of view, and 97% of the attendees who answered the survey said the cost was worth it.

Sponsorships

Someone who knows how to do sponsorship right should right a book. I got priceless guidance from Jesse Noller, PyOhio and PyCon Canada organizers. First is we always tried to find an individual in the company to talk too. Secondly, we always made sure to go to them with three options we thought their company would fit as a sponsor. We also worked with companies to make a special package just for them. Maybe they didn’t need tickets or didn’t want an ad. Maybe they wanted to spend just slightly less. Whatever it was we did everything we could to accommodate them. We also just straight up didn’t take money from some sponsors, we traded them out for services or assistance in other ways. We also didn’t charge anything if we couldn’t guarantee they would have a successful event with us. This flexibility worked great for us, and several times a company that we worked with came back and upped their sponsorship level. In general it seemed to me that if you focus on getting the sponsors you want involved and don’t get hung up on the money then it was more of a partnership than just a handout. It’s hard for me to say if the sponsors felt they got their money’s worth out of our event. I know a few of them thanked me personally and said they did. I hope they all felt that it was worth it.

In the end, we raised $23,000 in sponsorship money, and turned down quite a decent amount more that frankly we didn’t need or was for our failed video efforts.

Do you feel you wasted any money?

I’m been pondering this since the event, and I’m satisfied that we spent all the money in good faith and in a good manner. I wished I could have done more for the speakers. I think some people could nitpick the final budget and find money they would have not spent or repurposed for another area. As a whole I happy with how we spent them money, and I feel nothing was out of line. My one worry was the amount of food we had to give away and in some really sad cases throw away. We were expecting the 281 paid attendees to come and while we encouraged the 247 to eat as much as they wanted, there was simply too much food. We were able to give much of it away to a local church and senior center; however, we still ended up throwing away food each day that they didn’t need or wouldn’t accept.

What do you wished you could have done differently?

I really wished I could have done more for speakers, keynoters, and volunteers. While I was able to offer them a few niceties, they took time out of their own schedules, money from their own pockets and handled a lot of stress to make this event worth coming too. Honestly, our event was popular and great because of the amazing speaker and keynote line up. I also was initially really sad that we couldn’t do video this year. Looking back spending that money on young coders, and financial aid was a far better use of the funds for our first year. I wasn’t in a position to have to organize and handle one more task during the event.

I would have also not jumped ahead of the money we had in the bank at each step of the vendor selection process. Many times I was personally committing to a vendor prior to PyTN having the funds to cover that cost. This is a huge risk, and one I can’t even remotely suggest anyone else take on. It lead to a ton of sleepless nights and agonizing days. Conferences are a drag on the organizers expenses as well. Many deposits have to be made before money is available, and many meetings require buying lunch etc prior to there being funds.

In reflection, we couldn’t have done it differently this year, but we can make some changes for next year to close what I saw as short comings.