On Price Fixing and eBooks

Can someone please explain to me why Amazon is catching heat from publishers for their eBook pricing?

It seems to me that, since the marginal cost of each additional eBook sold is $0, and since Amazon is selling eBooks so as to make the maximum profit possible, that should also make the book publishers the maximum amount of profit possible.

Why is this a bad thing?

Give A Little (HackNY 2012s)

Hey guys! I’ve been pretty heads down with Grassroutes and schoolwork lately, but I took a few days “off” to go to Philly to ride the MongoDB bus to HackNY in New York City (and then fly back to Pittsburgh). I worked with Tess Rinearson, Nick Meyer, Alice Lee, and Willy [last name not given on the internet], and we built a webapp called Give A Little.

The basic premise is that often you hear people say something like “for the price of that latte for a week, you could feed a small village in Africa!” We wanted to make it easy for people to have their latte and feel like they’re saving the world too. When you sign up to Give A Little, you’re prompted to pick a Foursquare venue category, an amount, and a charity. Then, whenever you check in, we’ll add the dollar amount you specified to your tab, and we’ll bill you at the end of the month and donate the money to the charity you picked. You can add as many rules as you want, each with different categories, amounts, and charities.

Unfortunately, I borked something in between when we “finished” and when we demo’d, so we had an awkward moment during the demo when the checkin wasn’t recorded by our app. A lesson for ye: if you make a change, no matter how trivial, test it! (I’ve been spending a lot of the past few weeks in the Grassroutes codebase cleaning up the code and writing tests. Not my favorite thing.) Luckily, my teammates weren’t particularly wrathful.

We also weren’t able to get the credit card processing going, which was actually somewhat of a relief for me, because handling people’s money makes me nervous. >.>

In the end, we got an honorary mention from the HackNY judges for “Hacking For Good”! I’m really happy with how things turned out, and super proud of my teammates. Great work guys!

 

Bonus amusing anecdote for reading this far: being the person on my team most knowledgeable about Rails, I decided to hold “Rails Office Hours” (relatively) early on Saturday night while Alice was still working on the design. Amusingly for me, a few other people (like Jim Grandpre, of Coursekit fame, and Yahel Carmon, who I’d only interacted with over Twitter previously) started listening in, and we had a cool discussion about the Rails stack and other technologies. I think (hope?) that everybody learned something, so maybe this is something I will start doing at other hackathons? Who knows!

And to Chris Wiggins, if you’re reading this: thanks for coming over and introducing yourself! I wish you and all of your fellows this summer the best of luck, and I will certainly be back for HackNY in the fall. =)

A Simple Test

Wow. I’m really shocked by the number of people saying “it’s just a joke!” after the Sqoot hackathon invitation listed “Women to serve you drinks” as a “perk” of their hackathon. Since apparently many people are confused as to what constitutes sexism, I’ve created a simple test:

Would it be incredibly _____ist if you used another minority group? If yes, then it’s sexist.

There are few black people in tech, so let’s see how that invitation would look:

 

Come to our hackathon!

Perks!
Blacks: we have a ton of attractive black people ready to serve you drinks! Our PM is a real slavedriver.

 

Yup, that’s incredibly offensive. How can you argue that it’s different for women? It’s not ok to joke about this.

(Especially  if you want to do things like keep your sponsors. But that shouldn’t be your motivation. Kudos to Cloudmine, Heroku, and Apigee.)

 

Hosting a static website from S3

I’m trying to move my web hosting off of DreamHost, because they’ve had some problems recently. I decided that since most of my content is static, I would try to host my sites from S3. Yesterday, I did a trial run with a website of mine that doesn’t actually get any traffic. Here’s an overview of what you need to do to set up your own static site:

1. Create an account on AWS, and then create a bucket for your website on the AWS Management Console. (Other blogs suggest that if your website is www.example.com, your bucket needs to be named www.example.com, but I suspect that isn’t actually the case.)

2. Upload your website’s files to your bucket.

3. Create a bucket policy that lets everything be viewable. To do this, select your bucket, then click “Properties” (in the upper right) and then click on the “Permissions” tab (if that isn’t selected). Click “Edit Bucket Policy”, and then click on the “AWS Policy Generator”. This should open a new tab.

4. Fill out the form with the following values (but without the quotes): Policy type => “S3 Bucket Policy”, Effect => “Allow”, Principle => “*”, Action => “GetObject”, ARN => “arn:aws:s3:::yourbucketname/*” (but replace yourbucketname with the name of your bucket, probably something like “www.example.com”). Click “Add Statement”, and then scroll down and click “Generate Policy”.

5. Copy the JSON from the popup, and then paste it in to the textarea on the “Edit Bucket Policy” tab in the AWS Management Console. Click save.

6. Now, we need to configure S3 to serve items as a website. In the AWS Management Console, click “Website” on the menu next to “Permissions”.

7. Click “Enable”, fill in the names of the files you want to be served by default (probably “index.html”) and on an error (perhaps “error.html”?).

8. Now, we need to configure your domain name to point to your S3 bucket. Probably in a new tab (since you’ll need to copy and paste your “endpoint” from this page later), go to your domain name registrar, and set up your @ and www records to be CNAMEs that point to your endpoint, but with the “http://” removed from the front, and the trailing slash replaced with a period. It should look like this: “www.example.com.s3-website-us-east-1.amazonaws.com.”

8a. Wait for DNS to propagate…

9. You’re done! Wasn’t that easy?

Resume Cracker (our TartanHacks project)

Last weekend, I went to TartanHacks, a hackathon at CMU that hopefully will become an annual or semiannual. I worked with Tess and her friend Geoff, both from Penn. (TartanHacks was CMU-only, except for the Penn students who were invited because several people at Penn were very helpful to the organizers.)

Our project ended up being coded in 6-8 hours, because Tess and I wanted to sleep (we were recovering from various illnesses), and Tess and Geoff didn’t get in until almost midnight. We also decided that we wanted to learn node.js, so we didn’t expect to be quite as successful as we were at PennApps with Grassroutes.

We ended up creating a very simple app that was all client side that gives you a markup language to create technical resumes that are formatted similarly to how Gayle McDowell recommends on her site. (We aren’t endorsed by her at all, and we since we can’t help you with content, you may wish to go here for that.)

You can find our app here: Resume Cracker. (Warning: copy your text before you go to “Printer Friendly” view. We still have work to do.)

As always, tweet me with questions/comments/concerns.

HTML/CSS: horizontal section dividers with ::after

This morning, I was working on my resume (which I keep in HTML), and I was hoping to have some horizontal dividers between sections like this:

Section

And I had forgotten that <hr> existed. What I ended up doing was using the ::after psudo-element, which I think is a much cooler solution anyway. ;)

Unfortunately, I don’t have a good solution for making the bar exactly fill up the width between the end of the text and the end of the page. What I ended up doing was this:

<style>
h2.work { display:block; white-space:nowrap; overflow:hidden; }
h2.work::after { content:""; width:1000px; border-bottom:1px solid black; margin:5px 10px; display:inline-block; }
</style>
<h2 class="work">Section</h2>

But maybe someone else can come up with a better solution than using white-space:nowrap; and overflow:hidden;? If you do, tweet me and I’ll put your solution up here.

Also, note that you may need to adjust the margin so that the border looks nice with your text. margin:5px 10px; just happened to look good for me. (Also also, ::after has display:inline; by default, so you at least need to make it display:inline-block; or it won’t let you set a width.)

PennApps and Grassroutes

I’m sorry if this isn’t super coherent. I just got back from participating in the semiannual PennApps hackathon at the University of Pennsylvania this weekend. (I didn’t get very much sleep.) I worked with Tess Rinearson and Nick Meyer to create Grassroutes, and we ended up winning second place. You can watch demos here; we start at about 29:05, and Tess did a great job with it.

Grassroutes was born out of an observation that we had made about SOPA: everywhere you go on the internet, there is a call to action to call/email/Facebook/Twitter/snail mail your people in Congress to make them see how evil SOPA is. However, this is because many of the people who don’t like SOPA are programmers, so they have no problem rolling their own widget to put on their site to exhort you to go do their bidding. Grassroutes makes it easy to create an embedable widget that you can place on your site that will tell your visitors to contact their Congresspeople to support your cause, so that anyone can do it. (You just need to know enough to copy and paste HTML.)

We use the Twilio API for in-browser calling, we use the Maxmind ruby gem to go from IP->zip code, and the SunLight Labs Congress dataset to go from zip code->elected officials. (Every widget is personalized for the viewer with their elected officials based on where they’re from.)

Check it out at grassroutes.us.

Three ways to improve your InterviewStreet CodeSprint solution

I’ve quite enjoyed the two CodeSprints that I’ve done so far. The questions have been challenging, but interesting and fun. During the first CodeSprint, I had a lot of trouble with my answers being algorithmically correct, but too slow to complete in the allotted time. Here are three things I’ve learned that have helped me reduce timeouts this time around:

1. Eliminate unnecessary looping or recursion. You almost always can’t brute force the solution (if that’s not what the problem calls for), or you will time out. This is by far the biggest thing. If you can’t figure out how to get rid of looping, take a step back, maybe go work on another problem, and see if you can think of a different algorithm to solve it. This is the most transferrable to the real world of my three things. You really can’t afford those extra CPU cycles.

2. Print your answer once. IO is slow. If you’re calling a print function several thousand times (or more), that can really take its toll over the course of the program. Instead, store your answers and just print them out at the end. This lesson is also transferrable to the real world, especially if you’re doing web development; DOM manipulation is slow, so you should try to make big changes all at once rather than making a bunch of small changes.

3. Cache recursive computations. Some of the problems are just begging to be solved by recursion over a small data set (at least compared to the memory they allow you to use). That said, if you try to just have your program execute the computation each time, it will not be fast enough. For CodeSprint, it is almost always worth it to make the memory/cpu time tradeoff, and cache the computations you’ve already done. In the real world, where there may not be as much repetition among the computations, or if memory is at more of a premium, it may not be as efficient to cache things.

I hope these help! Good luck with your last ~13.5 hours!

(A note on languages: I have noticed that for some slow algorithms, implementing it in a different language (say, going from Ruby to C) did allow more test cases to pass. However, I am very confident that InterviewStreet picked the language-specific timeouts so that all the problems can be solved in any language, if you have the fastest algorithm.)