Inject jQuery offline

I've been experimenting with a way to circumvent wifi network password screens, and found myself needing to inject jQuery into a page without having an Internet connection (see jquerify otherwise). Here's what I did in Chrome:

{

"name": "File holder", 

"version": "1.0"

}

 

  • Go to chrome://extensions/ in Chrome
  • Click "Load unpacked extension" and select your folder
  • Note the "ID" from your new extension. This is how you'll load files from it.
  • Add the following JavaScript to the developer console:

 

var element1 = document.createElement("script");

element1.src = "chrome-extension://aaaabbbbccccdddd/jquery.min.js"; // use your extension's ID

element1.type="text/javascript";

document.getElementsByTagName("head")[0].appendChild(element1);

 

That will allow you to use jQuery without having an internet connection.

This is how you actually teach people to program

This won't be a short post, but it'll give you a summary of close to a year's worth of trying to teach people how to program. We know what works and what doesn't, and so far there's a lot of stuff out there that just doesn't work, based on our own experience and what our paying customers are telling us (they're mostly people who tried and gave up on Codecademy, Codeschool, Udacity, and Coursera).

TLDR version:

  • Graduated from UIUC in May of 2011
  • Started OfficeHours.TV
  • Co-founded Niroka
  • Co-founded Dojo, which later became Bloc, which we announced on stage at LAUNCH
  • Raised some seed money, hired 2 friends from college
  • Started a class of 15 students, announced a class for 45 students--we've had 70 applications, turned down half, and accepted 20. Skip to the bottom about engagement if you want to understand how we're actually teaching people to learn to program.

I bought a one-way ticket to San Francisco right after graduating, which is where I planned to start a fashion startup without having met my co-founder (I realize how crazy this sounds). I had been talking to him on the phone, working with him for about 6 months, and we both were UIUC alumni.

As any broke college student, I didn't have the personal runway to work on the startup while my new cofounder was doing a wedding and honeymoon that lasted several months. I also wasn't passionate about fashion--I wear a Dropbox and Rap Genius shirt 6 days out of the week, and I've been known to go out to bars in basketball shorts and sandals.

Why was OfficeHours.TV my first project? It seemed like something people wanted, and it was a good extension to writing Startups Open Sourced.

OfficeHours.TV: get advice and feedback from entrepreneurs

The first thing I built was OfficeHours.TV. At its peak, someone bid $600 for 30 minutes of Brian Chesky's time. The problem is that model was not easily repeatable. It's difficult to find a lot of people who had Chesky's clout, and harder to get them to hold regular office hours as they were donating the money to charity. There was probably a total of $3,000 in transactions from this project.

I started looking at possible co-founders midway through. I knew @choxi from school, and I ended up working on the project with him remotely while he was at Groupon leading their social team. If you're looking at cofounders, this is a great way to do it. Add them as a GitHub collaborator and see what they do. @choxi was committing code that night, and before long he was committing more code than I was. I initially tried walking him through the code base on Skype and he was like "it's alright, I can read the code, you don't have to explain everything to me."

I eventually convinced @choxi to move here in October rather than January because we would do YC again (I'm an alum). I didn't realize that there was a conflict of interest policy for companies of the same stage--this varies depending on investors, and most investors will not invest in you if they've already invested in a competitor. That's all good and fine, but we had to turn to a different source of seed funding (more on that shortly). Basically, nothing went according to plan. That's no exaggeration.

Here's what the home page of OfficeHours.TV looks like:

Niroka: learn anything from anywhere

So OfficeHours.TV was losing steam after a month or so because we were running out of people to reach out to. It was around this time that @choxi and I started working on Niroka: Skillshare meets Udemy. We allowed people to teach classes both online and offline. We posted fliers all over campuses around San Francisco. At one point we were trespassing in an all-female residence, shamelessly posting fliers to let people know they could teach or become any musician from playing the guitar, piano, or being a DJ. If you're a college student in San Francisco or Berkeley and you used a public restroom in the fall of 2011, you probably heard about Niroka.

There were some logistical problems here: the people asking to become instructors did not want strangers in their homes using their equipment, nor did they want to carry the equipment to a location. We basically had to become a Zipcar for musical equipment. We were on the phone with42Floors--I was in the same YC class as Jason Freedman so I knew what he was up to before they announced--and they were telling us we'd need some retail space to do this. But investors pushed back on this idea and said it didn't scale. Here's what the site looked like at one point:

I have some personal gripes about investors. They feel too shortsighted, but I get how their funds work and why they need returns on a 5 or 10-year scale. The other one is that nearly every investor will tell you that "team matters the most," but that's merely convincing BS. At least it was convincing; it could have been unconvincing BS and that's not a whole lot better.

I only know of a few investors that actually stick to the "we care most in the team" mantra. In reality, traction is the single most important thing you need, followed by who else is in the syndicate, and then finally team gets a little bit of weight. The flaw in thinking here--and I think it's driven by being shortsighted--is that you can invest in a company with traction right now, but if that traction goes away, you'll be left with two guys and you are gambling on the hope that they're good enough to figure something else out. I'm not saying I want to spend 20 years building a company that doesn't go anywhere, but I think the order of the priorities is off. Team should always come first. People like YC get this: you can fund entrepreneurs and if they're good, they'll figure something out eventually. Hey, did you know you could even apply without an idea now?

Back to the drawing board: Dojo (Bloc) is born

At this point, with a whiteboard full of ideas to solve our own problems and most of them scratched out for various reasons, we were excited by Heroku's new Cedar Stack and the possibility of deploying apps on behalf of the user. What happens if you remove the local development and deployment hurdles to an aspiring programmer out there? Is it possible to learn faster? Do people stay motivated and engaged because of this? We tested this hypothesis. Dojo was born, and there was some excitement when we showed off our prototype. Nobody had done this, not evenCodecademy was experimenting with app deployments.

About 5,000 application deployments in, we decided to start hitting the streets for some seed investment. One of the first investor meetings we had with YC alumni Jude Gomila lead to a chain reaction of meetings that would follow. Jude liked us as a team, but he also really liked the idea. "This is fucking cool and I wish I had done this" is the phrase we remembered from walking out of that meeting of Heyzap's offices. A slew of introductions followed, in addition to criticism about how poor our pitch deck, executive summary, and investor pipeline spreadsheet were. I focused full-time on fundraising around this time.

Dojo was renamed to Bloc because we didn't want to get sued by a similarly-named company for trademark infringement. Trybloc.com went through two major iterations. The first version was essentially Ace editor and emscripten in the browser. It was a glorified TryRuby and looked like this:

The second version had a guide, editor, and tasks ('tasks' were unit tests that ran remotely on your code which was deployed to S3). It was built mostly around the announcement of the product at LAUNCH 2012. Watch me present on stage here. We hired the amazingly awesome Matthew Skiles to do the front end. It definitely looked and worked better than our previous version:

We even hand-crafted our beta invites as wooden blocks with invite codes on them:

The reason this model doesn't work can best be summarized this way: developers today use their own tools because it just works. You can't run and hide from a terminal. You need to embrace the terminal, and you need to embrace the editor because that's the best development experience that exists right now. The company that puts all of this in the cloud or the browser isn't coming any time soon. There are just some things that aren't going to work well in the browser, and programming is one of them.

There were a few other problems we noticed around this time.

User engagement: I suspect any company involved in teaching people how to program is having trouble with this. Basically, we saw a tradeoff when you are trying to capture a user who wants to learn how to program. You can gather up lots of them if you start with something trivial (see Codecademy's home page) but you end up with what we've heard others describe as tourists who were not committed. We made a conscious decision that we didn't want casual users. We wanted the type of person who has tried to learn how to program, got stuck, and gave up. This person knows something doesn't feel quite right when they try to learn how to program, they just feel anxiety and frustration. It's something hackers take for granted because we grew up with computers, Freenode, Stack Exchange, and our own nerdy friends, professors, and TAs who helped us when we got stuck.

Revenue: Our model was not working in a way that helped us. We had deployments, but none of our numbers were impressive enough for most investors. We didn't have the revenue, and we didn't have the staggering user growth (although we did get decent adoption with 40K apps deployed and over 5,000 users, it just wasn't good enough).

Technical challenges: When you make changes to an application, you want to see changes immediately. That's how developers work right now: they make a change, save a file, and hit refresh and see it in their browser instantly. It works really well that way because the feedback loop is tight. To "hack" this problem, we asked users to complete these tasks and then ran unit tests against users' code with the click of a button. This was nothing like the string matching and code injection we did in the first iteration of Bloc. These were actual unit tests being run against applications we were uploading to an S3 server on the fly. Ultimately, it just wasn't good enough. Deployment times through Heroku were 2 minutes, so we needed to find a way to speed that up to a few seconds, and we didn't have the runway to do it.

Value: At the end of the day, we may have been nerding out more than we were genuinely satisfying customers. Some people thought what we were doing was cool, but we knew deep down that we couldn't help people apply for an entry level developer job or build their own applications independently. It wasn't an immersive learning experience.

Fundraising process during Bloc

I remember walking away from the fundraising process worn out and broke. As Louis C.K. would say: I would have been so broke that if something was free, I couldn't even afford it. My credit card had been maxed out at $10k; I never went that far into debt before. Walking back from a McDonald's in the Mission District on a cold night in November, I asked Roshan if he could cover my rent in January because I would be out of money, and he thought he could. Turns out he was also out of money by January, and we had to ask our family to help us cover February's rent. Any hope your family had in your "entrepreneurial dreams and aspirations" is soon met with a little more skepticism when you're in debt and asking them to pay for your rent.

We hired two employees (friends we knew from college) before we even had the money to pay them. One of them quit their job, and the other turned down an offer to join us. I distinctly remember sitting down with them in February and telling them we may have to go get jobs. I could barely hold it together at the gym that night. As I was biking home, I broke down at a secluded street corner in Palo Alto and did that thing babies do when they need their diapers changed. I'm typically not emotional, but this was a low point for me. It was around this time I started scheduling interviews with tech companies.

At any lowest point in the game (and there were many), I would always tell myself and everyone else: "This is par for the course." If you can't handle being in debt, constant passes/rejections from investors you look up to and whose opinion you respect, you think your startup is without a doubt going to fail, and you have to tell your friends they have to get a job somewhere else and you can't pay them on time, you may not mentally be ready to handle the ups and downs of startup life. This is why naivety is so important for those who will do it anyway. They have no idea what they're about to get themselves into, and if they did, they might decide not to do it.

Solving the ever elusive engagement problem

Of all problems out there, engagement remains the biggest. We can get the users and the revenue. As of last week, people will pay us $3,000 for 8 weeks of mentorship to learn how to become web developers. We've had over 70 applications, we've accepted 20, and we've turned down about half of those.

We're actually in a really nice position because we get to pick who we want to work with. As long as you're driven, don't easily give up, are fully committed, and you're easy to talk to (read: not an asshole), you're in. I give the same advice to people who ask me to read their YC applications: don't give them a reason to reject you. That's a lot easier than it sounds; some people actually overthink the application and think every answer has to be pristine perfect. Just focus on not screwing it up. At YC's scale, it's probably far easier to find one good reason to reject you (eg an unjustified uneven equity split) than it is to get a bunch of green lights lined up. Disclaimer: this is my own opinion and observation.

Try putting yourself in our shoes. You want to teach people how to program, but everything you've tried stops working very quickly because the user walks away. How would you fix that problem right now? I'll tell you how we did it, but take a step back first.

Here's something we know for certain: people want to learn how to program, and it's still an unmet need. Try to answer this question: I want to learn how to program, so I'm going to ________________. Most people start out this way by getting a book, and then they get stuck somewhere. Most people don't know about Freenode and most people on Freenode aren't going to help beginners with their seemingly trivial problems.

When I trace my own experience, the learning pace accelerated drastically when I had someone sitting next to me to prevent the "getting stuck" phenomenon that often requires a rubber duck to power through. It was actually @siong1987 who helped me learn the fastest in the winter of 2008. It could have gone slower and more painfully, but we were both there writing code together. I picked it up very quickly because I didn't get stuck for very long on any single problem. I had an unfair advantage.

For beginners, too many problems exist to block the flow, and users get stuck in the anxiety fragment. Programs like Dev Bootcamp and Code Academy are nice, but they fill up quickly, require a full time commitment and cost more ($12k for DBC, $6k for CA, and $3k for us). If you live in San Francisco, you should do DBC. We're actually directly inspired by their model; Shereef Bishay--who I call the Egyptian Paul Graham--has been mentoring us and guiding us on how to go about building this.

When there's money and reputation on the line, people don't want to fail. These are two of the strongest motivators that exist. After nearly a year of iterating on educational startups, we think we've found the ideal combination to solve the engagement problem.

Commitment. A student pays $3,000 to take the class, and we've already found that this works as a great filter to find people who are already motivated and excited about learning to program. Having money on the line is a great motivator, just like having a gym membership.

Connections. The very first interaction (the interview) someone has with us is a face-to-face Skype call. The second interaction (the follow up) is also a Skype call. E-mails are too impersonal and make it easy to back out. Students build connections with other students in their cohort. It's the same reason choosing a friend as a cofounder is such a good idea: the potential disappointment in walking away is a strong deterrent to hold the company together. This makes it difficult to give up and motivates students to work harder; they don't want to let their peers down.

Interviews. By doing interviews, we understand what scheduling conflicts exist, what kind of goals someone has, and how much time they can commit to the program. We wouldn't accept someone if we didn't think they could complete the program--we rejected an applicant on the spot during an interview because they said they could not commit to the 3 hours per day. We at least know this was the wrong time for them to be doing this. We also are up front about our willingness to drop students because of their lack of commitment; we are estimating that 3 or 4 will be dropped from any given cohort.

Feedback loops. If we aren't doing a good job of teaching, we'll know very quickly because we have multiple interactions with every student each week. Likewise, we know if they're struggling. I personally will require my students to blog each week, I'll do retrospectives on Fridays, I'll do code reviews weekly, and I'll be doing several Skype calls each week with them.

There are questions about whether this model scales, but it can be applied to anything, even outside of programming. You don't need 4 years and piles of debt; you can learn faster when your mentors are good and you commit to immersing yourself. You could do this with UI design, animation, foreign languages, or anything really.

We're on track to generate $100,000 in revenue in the next 2 months. We're now opening it up to accept mentors here--have you ever wanted to get paid a $150k salary for a teaching fellowship?

If there's something you want to learn, tell me and we'll find the right mentor to teach it.

The predictable criticism of my latest VentureBeat post

I've heard a few people criticize my advice when I wrote "How To Land Meetings with Anyone", although the response has overwhelmingly been very positive. It's one of the most-liked stories (by Facebook likes) on VentureBeat.

There are two major criticisms that I'd like to respond to. I wanted to first point out that trolls appear to running rampant on the post; I've only recently understood how to spot them and when to not respond. I'm talking about comments like this:

This has to be one of the lamest things I have ever read on hacker news. Hacking the system? Its called persistence. Yes, sometimes it can work, other times it can get you shitlisted. Is this the kind of crap they teach Urbana-Champaign? No wonder I rarely hire a recent college graduate.

There's a few things here. First, the person thought the advice is horrible. I can understand that. They also claim I'm misusing the term "hack", which has happened in the past before, so maybe I should actually explain that part.

Complaint #1: This isn't "a hack." And you're being greedy (according to Joel Spolsky, who completely missed the entire point of my advice)

If you read a comment from Joel Spolsky, he claims that his blog is the reason that he's been able to get meetings with anyone he wants. That's great, but I've already recommended that people write blogs before. Nothing new there, and it's a bit off topic if we're actually looking at what the article is about. This article is not called "The long term solution to getting recognized and meeting people." The reason I called this "hacking the system" is because it's literally that: a hack. It just works; it's a short-term solution; it gets the job done. It might not work on everyone, but hey, so far it has landed me 3 meetings with people I shouldn't have been able to meet with, and it got Evan an investor and mentor. Zero complaints, 100% success rate. You can criticize the tactic all you want, but it works. If done correctly, there's no reason why it wouldn't work if someone else tried it.

There's actually a legitimate complaint about the uniqueness of this advice, which I'll address, but as for the rest of this person's comment: I've realized lately that I just need to be able to know when someone is trolling and not respond to them. I used to respond to every single comment someone would write, but now I know better. As an example: whether you hire a college graduate or not has no relevance to anything the post has said. If you're using me as a way to determine what all college graduates are like, n=1 is a horrible sample size. Perhaps all the other companies out there aggressively trying to recruit grads are also doing it wrong, maybe they need to be educated. To imply this is "coming from Urbana-Champaign" just shows complete ignorance on the user's part. This tactic wasn't mine, I explicitly said it came from a guy who has recently started a company and came from the Stanford Graduate School of Business.

I've predicted that there would be people who would write that the post was a bad idea. I even wrote that in the original post. But Joel Spolsky's comment borders on trolling. The first time I read the comment, I was under the impression that he tried all of the advice he listed out, and that led to him being successful. As it turns out, that was all just part of a rant where he quoted Dale Carnegie and made it seem as if what I was saying was some form of manipulation to get things from people. So you're saying that if you invest in my company, you don't get any benefit? I'm just sucking your time and energy from you like a leech? No, investments are mutually beneficial. I think investors need to at least have the decency to respond to the requests they get. I'm not saying you have to take every meeting. But give people a straight answer. This conversation about "how to get busy people's attention" wouldn't even be happening if they'd just give a straight answer in the first place. If you don't want to invest, say "Sorry, I'm not interested." If you want them to stop e-mailing, say "Sorry, this isn't a good fit right now. I'll contact you if that changes." It's kind of like when investors string entrepreneurs along saying "It sounds interesting, maybe we can chat in 2 weeks and see how things are going." YC gets thousands of applications twice a year, and they send every single team a response, whether they were accepted or not.

So what Joel is effectively saying is "if you want meetings with anyone, start blogging. Then you can meet with people in 2 years." That's really not what this article is about, although the irony is amusing. Going by Joel Spolsky's advice, I have tried to offer something for free to help other entrepreneurs out, and his response was "Ef you" along with a harsh criticism. You're just a hard man to please, Joelsky. You also broke rule #1 in Carnegie's book on How to Handle People: "Don't criticize, condemn, or complain."

Anyway, I could have easily written something like what was recommended about being charitable and offered the same Dale Carnegie advice, but there's already a book written on that--this is written for people who are being ignored, think there's a strong mutual fit, and need to give the busy person a nudge. Worse things could definitely happen. I had a friend who asked me if he should show up uninvited to YC interviews, and I told him that was a horrible idea. That's desperate, not persistent. Persistence in that case is applying during every batch, despite being rejected. I got rejected when I applied to a college, and I reapplied 3 times to one of the most competitive colleges in the university, and the highest-ranked college in the country. I didn't show up at the admissions office and say "You all made a mistake, I'm not leaving until you change your decision." Whether sending e-mails once a day is desperate is up for interpretation, but in my book it's fine as long as you've already been sending e-mails for a while and that isn't working. You obviously can't just start off by saying "I'm going to e-mail you every day for a month", I mentioned that in the original article.

So there are people who want to make this seem like a huge moral problem, when it's really not that at all. It's not about being greedy, it's about being persistent. In order for this to be greedy, I'd have to be screwing you over and benefiting at your expense. But that's clearly going against rule #3: have good reasons for meeting someone. You need to tell them why they'd benefit too. Conclusion: Spolsky trying to make this into an issue about greed is really off-topic and melodramatic at best.

The other criticism is definitely legitimate: (Complaint #2)

I'm sure that part of the success of this technique is that it's relatively unique.

That's true, and in that case it's time to adjust the strategy a bit. Just as web designers will take UI elements from Mac OS, retool and reuse them in web sites and applications, you should also tweak the general idea to fit your own purpose better. As a recreational interest, I read The Game by Neil Strauss, and that entire field of social dynamics comes with a huge disclaimer: you need to take the examples and adjust them. You can't repeat the same material used by other people because it doesn't work. Same thing going on here.

Right now, this tactic is probably only going to be used by a few people. Joel Spolsky makes it out as if everyone reading this advice will do it, but so far I've only heard from one person who has acted on it. And that's just how it goes with the stuff I write. It scares off most people and nobody really acts on it. But for the few who do, your chances of getting a meeting are pretty high. The one person who tried the tactic to land a meeting got an immediate e-mail and landed the meeting. So far, the success rate is still 100%.

But you should always be thinking about this and adjusting the execution slightly.

Finally, I thought this was brilliant:

Anyone else noticed lots of VC's and Angels tweet when they are flying somewhere? How about driving to the airport they are flying into and waiting for them to come through the arrivals gate holding a sign with their name on. A free ride to wherever they are going in return for hearing your pitch. Considered doing this, but my gut tells me this is just too stalker like to work. Think it would freak me out if someone did it to me.

Then someone chimed in with an awesome comment:

That is an awesome idea. As long as the person wasn't creepy and I didn't already have a ride, anybody trying to get my attention for a business proposition could get it this way. But I agree that it would be better if they emailed..."I see you're hitting LAX tomorrow. I know you've been busy. Can I give you a lift to wherever you're headed from the airport and get that 10 minutes I've been looking for?" Awesome.

This is just one awesome example. There are probably many tactics you could use to get a meeting, and this e-mail doesn't have to be "the one." The point of this article was to spark conversation around other methods. It's not evil, it's not greedy, it's just a method and the worst that happens is you'll get ignored. You may be labeled as annoying, but so far it hasn't happened--and that's the metric I use when I judge something. I want to know how it works in the real world, and so far, it has been flawless.

startups open sourced is out, go grab it! (and how to deal with traffic)

forgot i haven't written anything on my personal blog about the book i announced last week, and the follow up that i just wrote today.

this tweet summarizes how today has gone for me. what a ride. i learned a few things from all of this.

quick recap on what i did to deal with the traffic:

  1. first thing i foolishly tried to reboot the linode. all this does is delay the next reboot, i don't know why i did this. guess i was in panick mode.
  2. i decided to resize my linode box from 512MB to 4GB. except the first time i tried, i just assumed it worked, then i waited another 10 minutes while the server was still frozen. linode UI failed me, it said "shut off your machine first, THEN do the resize." so i shut it off, did the resize, and booted it back up.
  3. i waited, minutes went by and nothing. i got a blank page. what in the world is going on? i'm a top story on hacker news, and my site isn't even working after i resized it. i open up apache's config file, based on a tip in the comments from the follow up, and change 'Keep Alive' to OFF. i restarted the apache process.
  4. i did another reboot on linode. now it works.
  5. i try editing my post, except it just hangs when i hit 'update' from wordpress. what, i can't even edit my own post now? i look at apache logs, i try another reboot (people hate me at this point, only 50% have actually seen the page load by now). i see nothing but SIGTERM messages, okay that's normal i've shut this thing down about 5 times so far.
  6. i try to install w3 total cache so that the pages are static and served from memory. that's what was killing me in the first place. i get permission problems, even though i ran chmod 777 on wp-content and wp-content/uploads. i e-mailed someone for help, and they made some suggestions that i couldn't really make use of.
  7. out of pure curiosity, i go to login via phpmyadmin. i see a familiar error message: "session_write_close() write failed: No space left on device (28)" okay, i've seen this before, this probably means mysql logs have eaten up all the space i've allocated to my disk image. this is easy to fix, just resize the disk image. i go into linode, do the resize. another UI fail: i miss that i need to shut down the box first, then resize the image, and then boot it again. okay, so the resize is done.
  8. voila. everything works perfectly. permission problems from w3 cache are gone, i can finally update my own post, the server is blazing fast serving up pages in mere milliseconds. i got billed $150 for the resize, but i was reassured from a hacker news reader that this gets pro-rated by linode.

life is good when stuff just works.

scrape wikipedia

built a quick recursive wikipedia scraper with depth limit in ruby because wget was an epic fail. uses nokogiri, which is excellent for using CSS selectors.

this script will recursively get all categories based on a single category, so as an example i started off here: http://en.wikipedia.org/wiki/Category:Algorithms and then a text file is created which creates a full list of categories and subcategories. i set the initial depth limit to 3, otherwise it goes really deep and starts getting things that are no longer relevant to the original category.

i'll add more code later to scrape the pages of all the categories.

edit: the code was updated, you should uncomment the lines at the bottom to make this work.

edit: need to scrape stackoverflow? very simple scraper here with delay timer -- i got blocked from stackoverflow the first time i tried this.

scrape hn

working on a search engine and i am using hacker news as a test forum.  if anyone needs to do something similar, feel free to use my simple scraper:

grab top stories from hacker news

grab all comments for each story

it's pretty crappy code but wget would not suffice. uses nokogiri which works pretty nicely.

edit: sad face =[ hn only lets you go 1104 stories deep

edit 2: pg says comment count is omitted sometimes to optimize for speed; removed that metric

edit 3: i used lemur to do the actual work of searching and indexing. i added the Okapi BM25 ranking function to computeWeight() in DBInterface.cpp. this is one of the key ranking functions google uses.

hacking your apartment's electronic entry system

i was talking to a founder of a startup since i'm publishing a book in april (shameless plug: it's about how many of today's startups came to be and the founders' stories). i ask every founder to answer the same question that shows up on the YC application: talk about the time you most successfully hacked some (non-computer) system to your advantage.

of the 30 interviews i've done so far, i've seen lots of creative answers.  one of the answers reminded me that our apartment uses RFID to get into the building from the outside.  the doors to get into my apartment lock automatically at night, so you need the RFID card to get in.  there's also keypad that allows you to enter in a room number.  so if i typed in my room number, the apartment calls my cell phone and i can talk to the person outside via a speaker near the keypad.

edit: shortly after this went up, i realized who inspired this hack. it was dan gross and robby walker (the guys who started greplin.com). special thanks to them, and some of the hacks they use at greplin.com are genius. the book will go into detail.

so i realized after pushing all the buttons on my cell phone that "9" unlocks the door.  in effect, if you get locked out because you had to throw the garbage out at 2am, you must have either your cell phone or RFID card. if you're missing those, you're locked out for good.

i thought it'd be cool to try and hack this, so here's what i did:

  1. i signed up for a twilio account.  this is free and they actually give you $30 of credit when you join.  they'll give you a free sandbox number, which you can use to test your scripts.
  2. in order to imitate the "9" being pressed which unlocks the door, i tried to find somewhere in twilio's API that supported single-digit dialing but they didn't offer it.  if i tried to call a single-digit number, it just threw an error and said "invalid number" on the call logs.  twilio however does support playback of mp3, so i did a search for the list of DTMF tones and found them here in mp3 format.
  3. i wrote the very simple script (here's a link to the sample twilio script) which upon receiving a call, plays back the dial tone "9." i uploaded this to my linode box along with the mp3 file and asked my apartment to update my cell number after switching my twilio account over from the sandbox number to a real number.
  4. i got a notice that the number was updated, and i started letting myself in without keys.

i realized that this would be an easy hack to do in other places where keyless entry systems worked the same way.  an e-mail could be sent to the apartment manager to the effect of "i've updated my cell phone number, i wanted to let you know. can you please update it for me? -resident name" and since most apartment managers probably don't verify the e-mail address, you could probably just find the resident names on a directory outside where the mailboxes are at. probably not too useful since that's just one layer of security though.

here's a video of the hack in action:

math behind dope wars drug trading for profit

disclaimer: this is not a complex analysis on the statistics of trading and risk in a game like dope wars.  it's mostly an uncovering of how simple the trading actually is, and is my attempt to offer some suggestions on how to make it a little more challenging to generate profit quickly in a game like this.

after looking at the python source code for dope wars, i realized there are no complex algorithms for trading drugs.  but as i'm building drug wars, i'm looking for a way to limit the profit potential to a new player to keep it interesting (too much profit makes a game too easy to win).

it turns out that's easy to do even using simple math.  an actual example using the drugs from that version of dope wars:

table of drugs + price range (minimum..maximum)

Acid    1000..4400
Cocaine    15000..29000
Hashish    480..1280
Heroin    5500..13000
Ludes    11..60
MDA    1500..4400
Opium    540..1250
PCP    1000..2500
Peyote    220..700
Shrooms    630..1300
Speed    90..250
Weed    315..890

from each of these drugs, we can see the minimum and maximum amount each will sell for.  as an example, on a very good day i can buy lots of cocaine for $15,000, then i can turn around and sell it on another very good day for $29,000.  that's a profit of $14,000 per unit of drug sold.  nice!

we can calculate the differences between the max and minimum drug price:

Acid    3400
Cocaine    14000
Hashish    800
Heroin    7500
Ludes    49
MDA    2900
Opium    710
PCP    1500
Peyote    480
Shrooms    670
Speed    160
Weed    575

i think there are a few ways of looking at the profit margins.  under a single trade it might be ((max-min)/(highest_max_of_all_drugs))*100.  in dope wars, it's sometimes possible to assume you can purchase the max of any drug--so would you always want to purchase cocaine?  the amount of return by the following (assuming no limit to buying a given drug):

((total money / min price) * max price) / total_money

to give a simple example, if you have $10,000 and you buy ludes, you can generate 5.4x return under the best scenario.  this allows you to generate (max-min) a number of (total_money/min) times.

Acid    4.4x
Cocaine    1.9x
Hashish    2.5x
Heroin    2.3x
Ludes    5.4x <- the cheapest drug, also the most profitable
MDA    2.9x
Opium    2.3x
PCP    2.5x
Peyote    3.1x
Shrooms    2.0x
Speed    2.8x
Weed    2.8x

if you want to make a game like this difficult to beat, i think you'll want to:

  1. keep the difference between the max and min price low.  this reduces the chance that a drug can be bought really low and sold really high.
  2. keep the minimum buying price high.  this reduces the number of times the things from #1 can happen.

my instinct was that cocaine would be the best drug to purchase since it had the largest difference (one trade would at best earn you $14,000).  but if there aren't any limits, you'd be better off doing a lot of smaller trades of ludes.

i haven't accounted for what you do in various situations when you have a limit on the drugs sold.  this is in many versions of the game, so i'd need to understand the likelihood of how many drugs are available in an area first.  i might write another post on that shortly, since that is really what we'd want to understand.  you'd also want to consider how much money you have at any given time.

i think a strong algorithm would do a few things:

  1. cause all locations to have an initially low demand
  2. associate an addiction multiplier to each drug, so as the drug is purchased, the demand increases and so does the price
  3. increase the presence of a police force as a drug with a high addiction multiplier increases in a location, making the risk higher to trade
  4. create a cap on how many drugs can be traded in a location (e.g. sold between players or limited by the system)

navigator.geolocation working only sometimes or not working at all

really annoying if you've ever worked with navigator.geolocation, you'll realize that sometimes it just doesn't work at all.  i thought there was some type of rate limiting where you can only make a request x times per hour.  as it turns out, there are error callbacks and by default navigator.geolocation has an infinite timeout.  to make matters worse, navigator.geolocation sometimes just doesn't work at all making it very unreliable.

as an example: this function will wait up to 15 seconds and then call the error callback if it cannot find the location:

direct geocoding places: turn a place name into latitude longitude values

i recently found the need to grab the latitude,longitude values for some unique place names.  i didn't find anything from the major services:

  • google places is closed right now, so have to join a waiting list
  • foursquare api, google maps api, and simplegeo api all require a starting latitude and longitude

the easy hack to the starting point is to choose an arbitrary starting point and set a large radius.  the problem is that all of the services i tried have an implicit restriction on how high you can set the radius.  none of them will let you run a search for "stanford university" starting in kansas and looking at a 1,500 mile radius (1,500 is slightly over half the total diameter of the united states, starting from the "geographical center of the united states" which is in lebanon, kansas).

so i ended up finding a solution with geokit, which was my last guess because it hasn't seen an update in over a year from its github repo.

installing:

usage:

of course, if you are using this in a large script and need to check whether it worked or not:

note: if you're hosting your rails app on heroku, your lat, long columns must be type decimal.  mysql will allow lat,long colums as strings, postresql requires a decimal.  mysql is also not case-sensitive on record searches, while postgresql is.  these were kind of annoying when testing in production.