Post Category: Miscellaneous

These are miscellaneous, possibly personal, topics that don’t fit into a specific category.

Summarizing "Humans Need Not Apply"

The ever-popular CGPGrey recently released a video on the potential future economic challenges of AI and automation, "Humans Need Not Apply". The longest video on his channel yet, it has attracted a good amount of attention in the first 24 hours, particularly on reddit, where long discussions broke out in a handful of popular sub-reddits, including /r/Futurology, /r/Economics, /r/videos, and /r/CGPGrey itself.

It's a departure from his typical style, which is usually something of a depth dive on a purely factual, but complex, topic. This time he focuses on the modern problem of how future expansion of AI and automation will affect the human job market. The video covers, at a high level, the current state of automation and how he strongly believes it will soon prove capable of taking over many jobs we typically think of as outside the realm of computer and machinery automation, leaving a lot of people "out of work through no fault of their own".

Having read a lot of replies to the video, I would like to offer my take on Grey's position in a way that will hopefully clarify some points and address some common counter-arguments. I think he made his point clearly, but it may help some to see things restated slightly differently. I will try my best to stick to what was put forth in the video and avoid my own thoughts. (Naturally, I will assume you watched the video.)

Grey argues that how automation is adopted in the future will be very different from how it was in the past. Historically, automation has benefited humans. When a job becomes more automated we obviously reap the benefit of not having to do it ourselves, reap the benefit of having a job performed better than we did it, and the job the machines took over gets replaced in some way. For the large part we still have enough jobs available, particularly for skilled workers. There is a prevalent attitude of thinking that future automation won't pose a significant threat to the job economy because "it's always worked out in the past". But Grey argues that the future of automation cannot be extrapolated from the past:

  • Automation will expand at a speed we haven't seen before. In the past, automation has tended to expand relatively slowly. Usually only a couple industries were revolutionized at a time and it would take many years to make the transition. New generations have time to train for different jobs, workers from one industry can shift to another industry, etc.

    But in the future, automation will invade many industries very quickly. We won't have the luxury of easing into a massively automated world. There are major business incentives to capitalize on automation, and the engineering effort is actually there to deliver. AI used to be a theoretical field of study, but now it's one of the most popular subjects of academic and self-motivated study in engineering and one of the most demanded fields of computer science employment. We're seeing practical growth in this area like we've never seen before.

  • More types of jobs will be automated than ever before. In the past, we've largely seen manual tasks automated. Machines were single-purpose and largely stupid at some level. Highly specialized skill sets, professional occupations, and the such, have typically been safe from automation. Not so anymore. High-paying professions dominated by highly trained, specialized humans will fall prey to automation. There won't be a safe-haven of jobs that we can turn to.

    These have always been our fall-back plan. We've usually been able to give less-desirable jobs to machines and move the workers to equivalent or nicer jobs. But what happens when the machines are doing those jobs too? So far, automation doesn't do the "smart" jobs, it does jobs that we don't want to do (like dig ditches) or that are too complex for us (like calculate an inverse square root millions of times a second), but they don't really do "intelligent" or "judgment" things. That's our domain. Except, Grey contends, it isn't. AI has started to automate things we consider "intelligent" and it's doing quite well. General-purpose computing and learning will allow AI to enter many new domains.

    The implication here is that historically we've seen individual jobs become automated. In the future, it may be entire professions.

  • Grey points out that the 32 most common professions in the United States are over 100 years old, meaning that we have not yet to deal with automation taking a huge chunk of our jobs. And many of those most common professions are solid candidates for the next generation of automation.

In short, we have many times more automation waiting for us in the near future than we've experienced in the past and a good portion of it's going to be for types of jobs we've never seen automated.

Of course, worries about jobs in a future of increased automation isn't new. People have always worried about machines taking their jobs. The novella Manna takes Grey's exact warnings about AI and explores them to the extreme; it was published 11 years ago. Books on the general end of capitalism significantly predate that. Why does Grey contend that this is the time to look for a falling sky?

Because those futuristic machines are already here. The video quickly mentions many jobs for which automations sounds like a futuristic dream but in reality already have existing, successful automation. They may not be mass-produced, mass-marketed, cheap enough for bulk purchase, or finely tuned enough to fully replace a human, but the near-human proof-of-concept has already been built and demonstrated successfully. We already have the blueprints to build them and we've done it, so the "hard" part is behind us, the rest is time and business.

So to fix the problem, what's his call to action? Actually, there's a notable lack thereof. Rather, my primary take-away was that we need to start thinking about these kinds of problems. When we have economic instability, automation taking more jobs than it is creating, and a rising gaps between the poor and middle class, it will be too late to sit down and refactor large portions of society and the economy from scratch. Rather, we need to be constantly aware of the impending problem so that when it starts to manifest itself we can quickly react to it. Being aware of the impending problem allows us to pre-think through the possible solutions and be prepared to adopt them when the time comes.

We will have problems like:

  • How do you treat multiple industries of people who were hard workers with skilled job sets that have been largely obsoleted?
  • How do you maintain standards in living in a country that doesn't need everyone to work?
  • How do you educate the next generation when most jobs are a stone's throw away from being automated?

And so forth. None of those questions are new to philosophers, but a lot of first world nations haven't seriously pondered them, let alone come to any decisions, let alone made any moves toward adapting.

People are resilient, and while it's true that societies can adapt to substantial change, they generally need the change to be gradual. Macroeconomic changes are not exactly agile. One of Grey's main points above is that the changes will probably happen quickly. If we're unlucky, entire industries could disappear from the human job market not in a couple decades, but a couple years. The necessary changes to accommodate it would be substantial.

Because the economic shift will be unprecedented and will possibly usher in completely new ideas about job, career, and education expectations and standards of living, we will need to re-think a lot of how society operates. If re-thinking large portions of society is the only long-term solution, we're going to wish that we'd spent the preceding years thinking about those problems and taking every preemptive step possible.

I like Grey's video (and I also enjoy his musings in general). But once again, here's a reminder that this is just an article summarizing my take on the video, it is not necessarily my personal thoughts on the matter.

A Hacker News Parody Thread

I spent some free time over the last few days putting together a parody comment thread for the news/link aggregator Hacker News (HN). (This parody isn't officially affiliated with Hacker News whatsoever.) As with any community, HN has its quirks and predictable comments. It has an interesting mix of young entrepreneurs, highly skilled senior engineers, web developers, managers, etc, which can make for an interesting mix of discussion.

For fun, I wrote a mock comment thread for a hypothetical link to a tech guru blog post. The parody comments attempt to humorously encapsulate the quirks that stand out to me when I read such a comment thread. Such quirks include things like differences in attention to detail, which posts garner the most replies, knowledge grand-standing, which comments end up at the bottom, and popular off-topic tangents. Some of it isn't unique to HN, but it was fun to include anyway.

Ignoring the rule of not explaining your jokes, here is some of the effort I put into the parody. (Don't read this before you read the actual page.)

  • Some of the comments are meant to be taken verbatim, others are just meta-commentary on their content. The two styles are interspersed without any markings to distinguish them. I was afraid that giving the two types different formatting would detract from the formatting parody so hopefully it will be obvious which way they should be taken.
  • All the URLs are mini-jokes. (The "reply" URLs are meta-jokes about potential replies that didn't work as well as actual comments, usually because they're the type of thought or comment that we I consider briefly before moving on. The links to HN resources are commentary about those resources.)
  • The timing of the posts isn't arbitrary, and some of the positions of comments with their time ordering are mini-jokes too.
  • Some of the usernames are commentary on the type of person who I think of when reading such a comment, some of them are just gibberish, and some are just juxtaposition jokes.
  • All of the numbers in the page source are mini-jokes themselves.
  • I kept the downvote arrows for those who crave, but have not earned, the ability to downvote comments. (Voting does nothing, obviously.)
  • I used the actual HN page markup, although I now hate myself for doing so.

I hope I covered my bases for parody work. I tweaked the main logo and site title, none of the page's resources are being pulled from the original website, and there's a big "parody" banner at the top.

It's worth noting this is not the first Hacker News parody: HN front page parody.

It was fun to make, and I hope HN readers enjoy it. Here's my account on HN and the parody's submission to HN.

[Edit, 1.5 hours later]: The response on HN was fantastic - thanks guys! The comment thread is at least as funny as the parody itself, one should definitely read it after reading the parody.

My First Float Tank Experience

I don't think that most people would consider lying in a dark, soundproof box for over an hour to be relaxing. But, I'm not most people.

I recently tried an isolation chamber, aka "float" tank, for the first time. A float tank allows the participant to come as close as possible to not experiencing any of their physical senses for a prolonged period of time (hence another name, "sensory deprivation chamber"). The the tank allows virtually no light or sound and has a shallow pool of highly dense salt water that keeps a human body afloat, permitting you to float while touching, seeing, or hearing anything. The goal is that, once inside for a while, you feel like you are disconnected from your senses while you float in nothing.

People have various motivations for using float tanks. Using them for just 40 minutes can alleviate stress, allow the body to heal injuries more efficiently, allow muscles to relax, and provide a other skin and edge case medical benefits. Some people, like me, just find the idea relaxing. Most people I talk to don't think they would enjoy the experience (and they're probably right), but I'm a very introverted person and I spend much more time inside my head than out of it. When I'm thinking I find external stimuli to be distracting, too much of it can be annoying or even tiring. I enjoy having quiet time with very little stimulation, and a float tank is the quietest session you can have. When I found commercial sensory deprivation chambers being marketed as flotation tanks I was instantly intrigued and bid my time until I had the chance to try one.

My Experience

I went to a local salon and spa, which offered a couple of float tanks among its services. Float tanks aren't too easy to find, but after some searching around it seems that most metropolises have at least one place that offers them. The float tank itself was essentially a large, covered bathtub in a small, dark room just a couple feet wider and longer than the tank itself. The procedure was to shower, enter the tank, close the hatch behind yourself, and an attendant would knock on the room's door once the time was up (taking further measures to wake you if necessary). I opted not not use background music (recommended) and to float in the nude (to avoid feeling any clothing, also recommended).

Closing the hatch behind me for the first time felt odd. I can't say I've ever stepped into a small box with no practically no light or sound. There was a sudden rush as I could almost feel the light and sound leaving my brain and I was suddenly very aware of how much of both I had been processing just before closing the hatch. The tank was virtually sound proof; I couldn't hear anything; no hallway chatter, no honking cars, no footsteps, nothing.

The Physical Aspect

The water was just one foot deep, but the extreme salt density made that plenty to keep me afloat. I extended my arms and legs to touch the sides of the tank and center myself, then pulled my limbs slowly off the side to let myself sit motionless in the middle. This was tricker than it may sound, since the slightest bit of momentum can cause drift and eventually touching the sides. I had to try a couple times to succeed.

At that point I experienced a very unique feeling. I saw nothing, heard nothing, and felt almost nothing. The water was body temperature and whenever I was motionless for an extended period of time the water feeling would subside to being minimally noticeable. But any movement or conscious thought about it would allow me to feel it. The feeling wasn't distracting by any means, but it was still a sensory connection to outside world.

One of the keys to floating is to relax as much as possible, both mentally and physically. Relaxing physically was actually a bit trickier than I had expected. I tend to be somewhat highly strung internally and I often tense muscles without realizing it. (I believe most people do this to some extent or another.) It took longer and more focus than I expected to relax all my muscles. After about 5 minutes I realized that I still had some of my facial muscles on the left side of my mouth tensed slightly, a little later I realized my right quadriceps were a little tensed, yet later I realized I had re-tensed my face, etc.

After about 20 to 30 minutes of being completely motionless it felt like my muscles were almost dead. While I knew I could move any muscle I wanted to, it felt like it would require tremendous effort to do so. At one point I twitched my foot, just for fun. It felt like there was a 10 pound force working against my foot as I twitched it. I think it may have produced some muscular benefits, since I felt several brief localized muscle spasms that were possibly tight muscles relaxing.

The sensation of lying in the tank was nothing like lying in bed. For one thing, my posture, suspended in the water on my back, let my head sit farther back than it would if I were lying on a normal hard surface. Initially it was a bizarre feeling, since it felt like my head was sitting too far back and of my control, but I got used to it. The rest of my body was held in a perfectly comfortable floating equilibrium. You can still feel a bed, the sheets feel soft, the mattress offers firm, albeit ignorable, resistance. The float tank offered no sensation or feeling. It wasn't snuggly, warm, or just kind of quiet. It felt like as close to nothing as possible. (Interestingly, tests have shown that replacing dense water with a bed does not provide the same benefits.)

The Mental Aspect

Once I was centered and relaxed I was very comfortable and felt completely alone with my thoughts. I let my mind wander for some of the time, and I let myself focus my thinking for other times. Aside from my own heartbeat, it kind of felt like time stopped.

My brain felt so unencumbered while thinking. It was like a CPU able to run a dedicated process without interruption from I/O and other processes seeking time-share. When they were focused, my thoughts were in one of those extremely laser-like grooves that come along only occasionally. I had compiled a general list of things to think about in the tank before hand, and without going into specifics they covered various ideas from my programming projects to philosophical quandaries. I was able to analyze and organize things very quickly, and had extra time to pursue other ideas that came up I felt no time pressure while thinking, I moved from step to step as I felt comfortable doing so.

My biggest motivations for using the float tank was relaxation along with my thoughts. I was not disappointed.

Other Things

Unfortunately, I did make a mistake. At some point early on I instinctively touched my face with my hand, probably to scratch an itch. At about the 15 minute mark I opened my eyes, just to see how much light there was in the tank now that my eyes were adjusted (answer: almost none, I could barely make out the walls 2 to 3 feet away). That allowed some very salty water to run into my eyes. I was doomed because I couldn't get it out of my eyes with my salt-water covered body. I tried ignoring it, but after my eyes burned for 20 seconds I gave in. I exited the tank, wiped my face off with a towel, got some water from the shower and cleaned my face and thoroughly flushed my eyes, and got back in. The problem took only a minute to fix, but it was still a disruption.

I ended up floating for a total of 1 hour 45 minutes. That's a long time to be without any physical stimulation, but I really enjoyed it. I came out of it very relaxed and feeling pretty good. I didn't even fall asleep once, although I had kind of expected to. I would do it again.

Advice to Potential Floaters

Based on my experience, here is what I would offer to anyone planning to try float session.

  • Spend a minute in the beginning getting yourself positioned. - You don't want to touch any of the sides of the float tank. Unfortunately, any bit of momentum causes you to drift, and if you start drifting you likely will probably bump into a side. Any time I made any noticeable movement I extended my arms and legs to the side until they touched the sides, used them to center myself, then slowly withdrew them.

  • Avoid getting salt water in your eyes. - This may seem extremely obvious, but it's worth emphasizing. Don't even get salt water on your face, and avoid opening your eyes regardless.

  • Spend some time focusing on relaxing your muscles. - I think that focusing on your body too much would defeat part of the purpose of floating, but it's worth spending some time up front intentionally relaxing all your muscles. It may not be as easy as lying down and telling yourself to relax. I'd recommend spending 5 or so minutes just focusing on relaxing every muscle from your face to your toes. It's very easy to tense them unintentionally.

How do you know if you would enjoy floating? It's probably impossible to know short of actually doing it, but here's a pseudo-test to screen out some who definitely would not like it: Take a pair of the best earmuffs or headphones you can find, put them on, and lie on a bed in a dark room without a pillow for five minutes. If you feel like ending before the time is up, you would probably not enjoy it. If you find it relaxing, floating may be enjoyable for you. (I enjoy doing that sort of thing, that's why I was fairly certain I would enjoy a float tank.)

My Sweatshirt

In just four days of wearing my new favorite sweatshirt on campus for the first time I got four separate complements on it. Three people asked me where they could buy it. Since then I've received dozens of compliments, mostly from strangers who, although they don't know me, know an elegant math expression when they see it.

Unfortunately, this sweatshirt is not explicitly for sale anywhere. I had it custom made because I couldn't find anything like it.

My Euler's Identity Sweatshirt


I love my sweatshirt, I'd sell it on a store like CafePress if I could find one that sells black sweatshirts. Since I can't, the next best thing is to provide the instructions to get one.

The image: You can get the image I used for the screen-printing here. However, the company I used for the screen-printing required you to upload an inverted version of the image (at least as of the last time I used their services), which you can download here. If one doesn't work try the other.

The company: The company I used to screen-print the image is Blue Cotton. I chose the Hanes Pullover sweatshirt (Printing -> Sweats -> Hooded Sweatshirt -> F170 Hanes Pullover Hood), but they do offer other sweatshirts. The Hanes sweatshirt has the advantage of having the lowest polyester content (90% cotton) of any of their sweatshirts, which is a good thing for a screen print and has the side benefit of being very comfortable.

The image sizing: For my sweatshirt, an extra-large, I chose to make the image 9.5 inches wide (be sure you lock the width/height ratio when scaling the image on the sweatshirt) and centered it 2 inches below the collar (you'll have to eyeball this measurement). It took a long time for me to decide on those dimensions, but I finally did and I think they're perfect, which is saying something. You might want to scale the width for sweatshirts of different sizes, my rough guess would be to subtract/add .75 to 1 inches per size smaller/larger.

So all you have to do is go to the website, select your sweatshirt, upload the image, set the width/placement, and order it.

Background for the sweatshirt

I'm a math major, and I like elegance. Euler's Identity is my favorite mathematical expression: it's a simple expression of universal truth via constants. It's fascinating how the five most fundamental constants of math are all uniteable in a single, simple expression.

In addition to math, I like t-shirts. I tend to treat t-shirts as billboards for things that I like -- you won't find a blank shirt in my drawer. As need had it, in winter of '07/'08 I found myself in need of a new sweatshirt. Like the rest of my upper-body apparel, I wanted it to say something interesting. I wanted the sweatshirt to be "nice-ish" so that I could wear it to "nice-ish" events, so I didn't want a busy/complicated design. it had to be simple, yet elegant. Settling on a simple expression of Euler's Identity was easy. My second stipulation was that the sweatshirt had to be black.

I started my search at the obvious place for a weird request like that: CafePress. I found a couple of sweatshirts with Euler's Identity, but a) They had obnoxious brand logos, and b) Cafepress doesn't sell black sweatshirts. After an extensive search of the Internet, it became obvious that no one offered anything like what I was looking for (shocking, considering the obvious demand). So I decided to have the shirt custom screen-printed.

The design of the sweatshirt

Thus I was faced with two tasks. The first task was creating the image I wanted to be screened onto the sweatshirt. The second task was finding someone to screen-print the image. Neither task turned out to be as simple as it might seem.

Creating the image was difficult because the only decoration for the black sweatshirt was going to be the bold, white text of Euler's Identity. Thus the styling of the text was very important. In order to truly do the equation justice, and make the sweatshirt look as simply elegant as possible, the font had to be perfect. Not fancy, but not boring. Just slightly elegant.

Getting the image screen-printed turned out to be difficult because there were two major conditions for the screen-printing: I had to be able to have a transparent background, and I was not going to order in bulk. Most custom screening companies violated the former of these two requirements, and the few that allowed background colors required bulk orders. In addition, some companies didn't offer sweatshirts in black.

The final solution

Finally, however, a solution was reached. I designed the image using the "i" and "pi" symbols generated by a Linux-based LaTeX front-end called eqe. I generated the rest of the equation using characters from the Tahoma font in the Linux-based image editor KolourPaint. I needed a very large size image to achieve a sufficient DPI, which was recommended to be at least 90. Both programs allowed me to create the images at a large size with excellent quality, but not a size quite large enough. So I used Gimp to expand the size and I used its anti-aliasing feature to keep the font's smooth despite being enlarged. The result is shown here. (This is a scaled-down version of the image, for bandwidth reasons. Click the image to download the full-size image, the one you would use for actual screen-printing.)

Euler's Identity

View the inverted version.

I also found a company, called Blue Cotton that allows one to screen-print an image, choose a color to make transparent, and doesn't require a bulk order. (Choose Printing -> Sweats -> Hooded Sweatshirt -> F170 Hanes Pullover Hood.) Thrilled to have a working image and a working company, all I had to do was manually place the image on the sweatshirt. I spent (no joke) probably 3 hours total moving the image around on the shirt, higher, lower, bigger, smaller, trying to get it just the right size and at just the right height. Finally I decided on a 9.5 inch width at 2 inches below the collar, which I am pleased to say is the perfect size/placement (for an XL).

Close-up picture of the screen-printed text on the sweatshirt.

Also, kudos go out to my girlfriend for her extreme patience with me. The sweatshirt was a Christmas present from her to me. Being a nit-picky perfectionist, it was decided that I had actually best do the bulk of the designing. I didn't even finish the design until the end of January. Giving it to me was an excellent idea, and it's one of my all-time favorite articles of clothing.

My Review of ABeka Acadamy

ABeka Academy is the child of the larger Pensacola Christian College that handles grade school and high school. The two academic institutions have the same philosophies, same teachings, same standards, and are, ultimately, run by the same people. ABeka is based out of Pensacola, Florida, and they offer a nation-wide home school charter program for home school families who want to give their kids an at home, Christian education. They offer their program for the entire K-12 grade spectrum.

At a glance ABeka may seem like the perfect answer to a lot of home schoolers' needs. They provide the books, materials, instruction, grades, and a diploma. All you have to do is send them a few thousand dollars per year and grade the student's quizzes with an answer key ABeka provides.

But for all ABeka does, there's a lot they don't do. I'm an ABeka high school student, and everything I say comes from three years of experience in ABeka's high school program, and I say that ABeka is not all they're made out to be. (Note that I only spent three years in ABeka -- I'll explain later.)

Like a lot of students, I joined the ABeka high school program my freshman year because I needed the instruction their DVD courses offer. My mom's teaching was adequate until then, but she had three younger kids to take care of and home school as well and the material I was covering in school was getting harder for her to explain. So when I started high school, we decided it would be easier for both of us if I did all my schooling via ABeka. We did the same research that basically all other prospective ABeka students have done, and they appeared to be a solution for our needs. As it turned out, we didn't know as much about them as perhaps we should have.

I took classes at a community college during high school. Not being the type of person who wanted to take two classes when one would suffice, I asked ABeka if they would give me credit for my college classes and count them towards my high school record. This seemed like a reasonable request, since every public and private school I know of does so, on the grounds that a college class should meet the standards for a high school class.

But no. My college classes may have been good enough for UC Davis and UC Berkeley (the two schools that accepted me when I transfered out of community college years later), but they were not good enough for ABeka. ABeka said that they would not give me credit for college classes, and, when pressed for the reason why, said that it was because they could not validate that the classes I took would satisfy their standards. That is, seriously, what we were told. My college classes weren't veritably good enough for their high school requirements.

Now, I could understand why ABeka might frown on an anthropology class, biology class, or any class in that general area because of the philosophical and (potentially) anti-Christian teachings commonly associated with such classes (ABeka is, after all, a Christian school) but I was asking ABeka to accept computer and math classes -- classes that carry no such philosophical baggage. In fact, they were classes that ABeka didn't even offer but that I would need for my college major later in life. (Ironically, ABeka is big on "preparing you for college", by the way.) It is standard procedure for kids in high school to take a community college class when their high school doesn't offer an equivalent class –- I've shared classes with a couple of them myself - but ABeka apparently doesn't see fit to accommodate anyone in this area, and their refusal to credit students for college classes boxes some students into a very tight corner, as I'll explain later.

Along the lines of ABeka's high standards, they're very anal about problem solving methods. I happen to be gifted in mathematics. Since an early age I've always excelled in math; I was actually factoring and solving elementary Algebra problems by age 8 when most kids are doing arithmetic. Math and logic come naturally to me and I usually solve problems quickly and with minimal work.

As it turns out, doing so is not a practice ABeka encourages. They wanted to see every little step and sub-step of my math work. I would sit down and breeze through a test with 98% accuracy, and lose 10% because I "didn't show enough work". I can understand that, as the graders, they need to see some work between my beginning and ending steps, so I would always show my work at important intervals. But I didn't show enough, even though anyone looking at what I did could tell what I was doing. I could combine three steps in my head and turn what they deemed an eight-step problem into a four or three step problem just by my normal way of solving problems. I wouldn't condense the steps too much, though, and would usually include a step or two more than I personally needed to just for good measure. But I would, consistently, get scrawled red-ink notes on my tests informing me that I wasn't showing enough work because doing work, showing the important steps of the solution, and getting the correct answer wasn't good enough. If I were shortening 10 step problems to four step problems I might see their point, but, like I said, I wasn't doing that. I can recall multiple instances where I actually lost points for shortening a four-step problem down to a two or three step problem.

Wanting to see the steps a student uses to solve a math problem is reasonable, but ABeka wasn't insisting I be reasonable. They were insisting I memorize and regurgitate their step-by-step solutions.

Throughout ABeka's math courses, I found myself painfully trying to find extra sub-steps to write down, so that I would actually get full credit for my work. There were many tests where I actually lost more points to not showing enough work than to making mathematical errors.

Unfortunately, this is very typical of ABeka. They don't encourage creativity and ingenuity; they encourage memorization and regurgitation. Understanding math isn't important, following steps 1, 2, and 3 is. That's a horrible way to teach math. At the end of such a class, a student will not have learned anything life-applicable, they will have learned how to memorize math steps. And, as a math major, I'm here to tell you that that flat out doesn't work. Ask any math student or math professor at any university and they'll tell you that that learning method isn't worth beans to students.

Another issue I have with their math department is that they only offer three real years of traditional, consecutive math study, their fourth year is devoted exclusively to consumer math –- if you opt to take math at all. That's fine, I have nothing against people taking consumer math, but not everyone benefits from it. No disrespect to anyone who has taken consumer math, but anyone who plans on majoring in something science, engineering, or math related does not want to waste an entire year on consumer math. It isn't going to help them in anything. If they're going to be an engineer, they obviously have the math skills necessary to understand consumer math as it comes in life. What they need for their careers is a strong understanding of trigonometry and calculus. They have so much math they'll need to study they can't afford to spend a year not progressing towards higher math.

But ABeka doesn't offer calculus. The highest level of math they offer is a hybrid trigonometry/advanced geometry/pre-calculus class. If you could just go down to the local community college and get your calculus class that way it wouldn't be so bad, but, as I discussed earlier, that isn't exactly an option. ABeka won't accept college classes, so you're stuck with what they offer unless you double up and do ABeka's full school load in addition to calculus at college. Possible, yes. Reasonable? Not really.

If you'd hoped, in lieu of getting any calculus, to get a good, solid trigonometry foundation (which, believe me, you future engineers and mathematicians will need), you're in for a disappointment. Their hybrid trigonometry/advanced geometry/pre-calculus class is, in my opinion, the worst math class they offer. They try to cram too much into one class, and the class as a whole is devoid of direction. You have a semester of trigonometry, then you have a semester of geometry, and at the end they announce that you're ready for calculus. I've taken college pre-calculus, and it's nothing like what their pre-calculus is. So for the record, you're not usually ready for calculus by the time you're done with that class. If you have the option of doing so without hurting your planning, take a real pre-calculus class at your community college your senior year of high school. It'll get you better prepared for actual calculus and it'll help keep your mind in shape during your year of vacation from math at ABeka.

Also, I'd go so far as to say that their hybrid trigonometry/advanced geometry/pre-calculus textbook(s) are the worst textbooks I have ever used. The books are confusing, very poorly organized, vaguely worded, and sometimes just ramble about nothing that make sense. A good math textbook will be something (if you go on in a field related to math) that you reference in later years when you have a question on that topic. I myself have referenced every math textbook I've used since Algebra II -- except their trigonometry/geometry one.

Along the lines of bad math classes, trigonometry/advanced geometry/pre-calculus isn't the only bad one, so are Algebra I and II. The Algebra series is almost the same subject both years, as best I could tell. Half of Algebra II is contained in Algebra I, just a little differently, which logically means that either their Algebra II moves back to overlap traditional Algebra I or their Algebra I moves ahead to overlap traditional Algebra II. Anyone familiar with ABeka definitely knows the answer to that. (For non-Abeka’ers, Algebra I moves ahead. ABeka never reaches backward for anything. When in doubt push too fast and slow down later. That is their motto.) Students don't get the opportunity to take math gradually and let it grow on them; they get it shoved into their face. There's a difference between memorizing math and understanding math. Students can memorize math in the same way they memorize poems, and then forget it a couple years (or weeks) later. Math, taught properly, shouldn't be like that. What good is it that way?

The algebra textbooks are nothing to brag about either. They're poorly organized and confusing. Woe to the student, or mother, who doesn't have the DVDs and opts to learn the material straight from the book. I taught myself exclusively almost all of the math I learned in school through their 8th grade math level, but, once I hit their Algebra I textbook, it all came to a shuttering halt. I couldn't teach myself the material any more, and that prompted us to to sign up for their video program. Their math textbooks are good and I would recommend them up to 8th grade. After that they're horrible and I would recommend you look elsewhere.

(I've heard many other people voice the exact same thing about ABeka's textbooks. In the beginning I wondered if it was just my mom and I who didn't like the difference between ABeka's lower grade math books and their high school text books, but I've met a lot of people who agree. I've even had people e-mail me, after reading what I say, who say the exact same thing, "ABeka was great, right up until high school.")

For those who don't know me, and for those who do know me, let me remind you, I'm a math major. Math is what I do, math is what I understand, and math is what I've studied. I would confidently say that I'm more than qualified to speak on their math program. And doing so, I grade it a C. Sure it could be worse, but that's almost a failing grade. (I guess it's better than it sounds. A C is, after all, by ABeka's standards, about, what, an 85%?*)

* This is meant to be funny. ABeka students won't find this funny, though, because this is too close to reality to be funny.

Now, leaving the realm of math and going to the complete opposite side of the spectrum...

Their English program is somewhat insane. Each year's English class is basically two classes rolled into one. It was like they couldn't decide whether to focus on grammar or literature, so they just decided to get the best of both worlds and decided to do both. Looking back, I think that English was by far their most intense subject. There was always grammar homework to do, literature to read and comprehend, and poems to memorize. Constantly, constantly, constantly. Write this, memorize that, etc. Due to the amount of material covered, English had about twice the number of quizzes of any other subject. There were actually quite a few classes composed of nothing but a pile of 15-minute quizzes.

I'm all for students having good grammar and being able to write well because it's a necessary life skill. I think less highly of literature, but it has its merits. But ABeka needs to decide what they want to do with their English program. Forcing students to concurrently deal with two nearly full time subjects is just stupid. I can't help but notice, at my college, that the English Writing and English Literature classes are in completely separate categories, and I don't think that's by chance. One class. One subject. It works best that way. Someone should point that out to ABeka.

I don't know why the four years of high school English aren't split into two years of each subject. The fact that they try to teach grammar in English for all four years of high school is just weird. I mean, you don't need four years of English grammar. Eventually you need to concentrate on just writing (enough with the sentence diagrams already). But no. They try to fit the exact same material into each English class for four years. I think they should just split their classes up into two years of writing and two years of literature (or some other ratio). The writing classes would consist of learning to write, and the literature classes would consist of learning to comprehend literature and poem memorization. Each class would be object-oriented, and just maybe you wouldn't find yourself diagramming sentences going into your senior year. I have never heard of anyone else having to do that.

Overall, their English program seems to be aimless. You do four years of it, and at the end you've spent countless hours writing the same essays multiple times, diagramming the same sentences over and over, and memorizing of poems that, honestly, you don't remember a tenth of by the end. For a private school with their reputation, it sure is easy to go through their program and not improve your writing abilities. It could be argued I'm proof of that.

This brings up yet another subject I want to point out. ABeka is known for being tough, which isn't bad. Tough isn't a bad thing, in and of itself, and I personally like tough. My problem with ABeka is how tough they are in combination with how inflexible their schedules are. They don't give students homework to complete by the end of the chapter, or by the end of the week, rather, by every class the last assignments are due and new assignments are issued. There's no buffer period for students to manage. If you do all the homework and assignments for each class, every day is an exact repetition of the last.

In college, and I have report that this is similar in public schools, my workloads rise and fall in each subject over each week. Each day has different priorities and different subjects that need to be studied. In ABeka, it's the same thing every day. Every day you have to do x, y, and z, and it has to be done today so that tomorrow you can do the new and improved X, Y, and Z. Not only does it not allow for personal interruptions in life it gets very old very fast. If you're not a good "just grinding away at it" person, you'll get bored of ABeka in about a month. It'll become a seemingly endless, boring chore.

Like I said at the beginning, I only did three years of ABeka's high school program. I left at the start of my senior year. But hopefully, by now, you understand why I left. I didn't leave because I was a failing, lazy student. I left because they couldn't meet my needs. I needed math and computer classes; they didn't provide them and wouldn't accept college alternatives. Their grading was obnoxious and discouraged creativity and originality. Their English workloads were irritatingly heavy with no sense of direction or real accomplishment and distracted me from beneficial activities. And in general, I grew to simply loathe their classes.

I left Abeka a straight A student after three fairly miserable years and joined the ACAEA in my senior year, graduated half way through the year, and promptly started college.

On that note, going from ABeka's high school program to college was a huge change. And I have to say, in all honesty, ABeka's scholastic training didn't help a bit. Their environment was completely different from college. Nothing ABeka teaches or encourages by way of study habits and scholastic conditioning will be useful in any normal college. And nothing they say you'll need in college you actually will need in college. The teachers in ABeka's video lectures make the occasional remark about how you're going to need skill X or knowledge Y to survive in college and/or the rest of life, and nine times out of ten it's completely bogus. The exception is their Bible classes. Those are by far the most practical and best classes they offer.

In college, they're interested in creativity and ingenuity. They're concerned that you get the right answer, rarely how you got there. Your homework, if you even have any that is obligatory to turn in, is collected sporadically in chunks, allowing you to pick it up and do it at your own pace whenever you need to. The focus is to gain understanding and brainpower, and they're usually pretty relaxed about it.

In summary, here are my complaints about ABeka Academy. I've talked a lot, but this list summarizes the main points that I've talked about:

  1. ABeka will not accept college classes.
    • They don't offer calculus.
    • Their trigonometry/advanced geometry/pre-calculus math class is bad, and doesn't prepare you for when you eventually do take calculus.
    • Their algebra series is too aggressive.
  2. Their English program is heavy, time consuming, and redundant.
  3. Their overall teaching style is too anal and procedure oriented.
  4. They don't prepare you for real life, despite the fact they incessantly insist that they do.

So... These are just my own thoughts about ABeka, and I know that there are those who would disagree with my opinions. Some people aren't like myself. Some people like the hard workloads and "just do it" mentality of ABeka. That's fine, but those people are the minority, most other people don't fit well with ABeka, and I'd like for those people to know what they're getting into before they find it out the hard way.

How do you know if you're right for ABeka? If you're a casual, independent, questioning person, ABeka probably won't be a good fit. Conversely, if you like memorizing 15 20-line poems a year, having your homework dictated to you day by day, and taking only three real years of math, you probably will fit with ABeka. And that's fine. I'm not saying ABeka is morally evil, I'm just saying that I personally don't like them. And I think that a lot of other people, judging from ABeka's turnover rate, don't like them either, but don't know enough when they begin to know that.

But, ultimately, it's all about education. Never forget the primary function of school. School is to teach you knowledge and, most importantly, expand your understanding. Pick what works with your personality and educational mindset the best.

Implementation of Blowfish in C

This algorithm implementation is a part of my cryptography implementations project. The full project, along with licensing information and more detail, is hosted on GitHub.


This is an implementation of the Blowfish block cipher.

There are two steps to the cipher. First, five sets of tables are initialized using the user's key and the blowfish encryption algorithm itself (making the algorithm recursive). Second, the data is encrypted using the permutated tables initialized previously.

Code Documentation

  • void key_schedule(uchar user_key[], BLOWFISH_KEY *keystruct, int len)
    This generates an encryption key from a user-supplied key.
    • uchar user_key[]
      This is the user-supplied key.
    • BLOWFISH_KEY *keystruct
      This is the key structure that will be used to encrypt data later in the encryption functions.
    • int len
      This is the length, in bytes, of the key in the first parameter. It may be any value up to 448.
  • blowfish_encrypt(uchar in[], uchar out[], BLOWFISH_KEY *keystruct)
    blowfish_decrypt(uchar in[], uchar out[], BLOWFISH_KEY *keystruct)
    These functions encrypt and decrypt data, accordingly, using a Blowfish key structure.
    • uchar in[]
      This is the data to be encrypted, for the blowfish_encrypt() function, and the data to be decrypted for the blowfish_decrypt() function.
    • uchar out[]
      This is where to store the output encrypted data, for the blowfish_encrypt() function, and the output decrypted data for the blowfish_decrypt() function.
    • BLOWFISH_KEY *keystruct
      This is the key structure that is generated by the key_schedule() function (above). It is the same for both encrypted and decryption.


  1. Create the arrays to hold both input and output data for the encryption and/or decryption functions and a BLOWFISH_KEY structure.
  2. Call the key_schedule() function with the key, the BLOWFISH_KEY structure, and the length of the key in bytes.
  3. To encrypt data, call the blowfish_encrypt() function passing the array with the plaintext, the array to hold the output ciphertext, and the key structure.
  4. Do decrypt data, call the blowfish_decrypt() function passing the array with the ciphertext, the array to hold the output plaintext, and the key structure.



In this implementation, all the initial P-Box and S-Box constants are stored in static memory location and copied to temporary memory locations for use in the key initialization step. This is because the S-Box and P-Box values will be altered during the key initialization for each key. If the implementor wishes to encrypt data using multiple keys in the same session, then the key initialization function must be called more than once, and each time it is called it must start with the same constant values.

Assuming the developer only needs to use one Blowfish key, this code could be slightly optimized to just use the one set of S/P-Boxes. These factors are only of practical concern for extremely computationally-weak machines (specialized hardware).

Cryptanalysis of the Blowfish algorithm itself to date has yielded but a few minor flaws, placing Blowfish as one of the best 64-bit block ciphers in existence. However, 64-bit block ciphers can leak information about the plaintext and should not be used if possible. So although no reasonable attacks exist against Blowfish itself, its 64-bit block size make it less than undesirable in the modern cryptographic world.

Implementation of Base 64 in C

While not a cryptographic algorithm, this implementation is a part of my cryptography implementations project because it's a handy encoding. The full project, along with licensing information and more detail, is hosted on GitHub.


This is an implementation of Base64 encoding.

Base64 is an encoding scheme that allows binary data to be represented as text. It accepts a bit string of any length, splits it up into chucks of 6 bits, and replaces each chunk with its corresponding value from the list of characters:
When the input is not an even multiple of 6 bits, the character '=' is appended to the output as padding as needed.

Since the input has 8 bits of significant data and the output has 6 significant bits of data (there are 26=64 characters in the array above), the input to output ratio is very close to 3:4.


  • void base64_encode(unsigned char in[], unsigned char out[], int len)
    This encodes raw data to Base64.

    • unsigned char in[]
      This contains the data to be encoded.
    • unsigned char out[]
      This will contains the output. The array should be larger than the input by a scale of 4:3, with a two character buffer.
    • int len
      This is the length, in bytes, of the input.
    • int newline_flag
      This is a flag, which can be set to true or false, to indicate whether or not the function should insert a newline in the base64 output every 76 characters. The technical specification for Base64 calls for this value, but this was based on technical standards/difficulties of the past and isn't always desirable. By setting it to a non-zero value, a newline character will be added every 76 output characters (to wrap it in a rough rectangle shape), if it is set to 0 then the output will be one long string.
  • base64_decode(unsigned char in[], unsigned char out[], int len)
    This function decodes Base64 code into its original form.

    • unsigned char in[]
      This contains the Base64 data to be decoded.
    • unsigned char out[]
      This is the output array, it should be at least 3/4 the length of the input data, with an extra character of buffer.
    • int len
      This is the length of the input Base64 data.
    • Note: There is no need to include a newline flag for the decoding function, as it automatically parses out newline characters.


  1. First create/allocate two arrays to contain your original and encoded data.
  2. Determine the length of the data you wish to encode. Pass the input data, the array to contain the output, and the length of the data as arguments to the base64_encode() function.
  3. When you wish to decode the data, use the base64_decode() function. It works the same way, except the data gets decoded.



This is the traditional base64 encoding scheme. The internet version of base64, in order to be URL friendly, replaces the last two characters of the substitution array, "+" and "/", with "*" and "-", respectively.

Update (7-26-06): Thanks to Christoph Otto for fixing a NULL termination bug.

Implementation of AES in C

This algorithm implementation is a part of my cryptography implementations project. The full project, along with licensing information and more detail, is hosted on GitHub.


This is an implementation of the AES block cipher in 128, 192, and 256 bit modes, where the bit size corresponds to the key length. The algorithm encrypts plaintext in block sizes of 128 bits.


  • KeySchedule(unsigned char key[], unsigned int w[])
    This function takes the generated key (128, 192, or 256 bits in length) and generates a key schedule to use in encryption.

    • unsigned char key[]
      Must contain 16, 24, or 32 bytes of data to be used as the key.
    • unsigned int w[]
      Must be 60 32-bit integers in size. This will be the outputted key schedule.
    • int keysize
      Must be the size of the key in bits, limited to the values 128, 192, or 256.
  • aes_encrypt(unsigned char in, unsigned char out, unsigned int key[], int keysize)
    aes_decrypt(unsigned char in, unsigned char out, unsigned int key[], int keysize)
    These functions encrypt and decrypt data, respectively.

    • unsigned char in[]
      The plaintext to be encrypted. The array must be 16 bytes in size.
    • unsigned char out[]
      The output ciphertext. The array must be 16 bytes in size.
    • unsigned int key[]
      The "w" array key schedule from the KeySchedule() function.
    • int keysize
      Ensure it's the same value as the "keysize" value in KeySchedule() function.

Code Usage

  1. Call the KeyExpantion() function with the encryption key you want to use, the key schedule array, and the number of bits in length of the key.
  2. To decrypt data, call the aes_encrypt() function with the input plaintext array, an array to hold the output ciphertext, and the size of the original key in bits (same as the value passed to the KeyExpantion() function).
  3. To decrypt data, call the aes_decrypt() function with the input ciphertext array, an array to hold the output plaintext, and the size of the original key in bits (same as the value passed to the KeyExpantion() function).



I've only taken basic steps towards optimizing this, so the implementation is fairly slow.

This implementation has not been designed to resist side-channel attacks.

There are a couple extra simple functions included in this code, printstate(), print_rnd_key(), and print_arry(), that are strictly debugging functions. These are not a part of the AES implementation and may be removed, they only exist to aid in debugging the code should someone try to alter the code. I used them excessively when originally writing this implementation.

Implementation of SHA-256 in C

This algorithm implementation is a part of my cryptography implementations project. The full project, along with licensing information and more detail, is hosted on GitHub.


This is an implementation of the SHA-256 hash algorithm.

Code Documentation

  • SHA256_CTX
    A MD5 structure that will hold all hash-related data and calculations as the hash is calculated.
  • SHA256_init(SHA256_CTX *ctx)
    Initializes the SHA256_CTX object.
  • SHA1_update(SHA256_CTX *ctx, unsigned char data[], int len)
    Once an object has been created and initialized, the data to be hashed must be added. Due to practical limitations, it may not be optimal (or possible) to add all the data to the SHA256 hash in one data chunk, so the function inputs, stores, and calculates data as it is received, allowing the data to be added in as many chunks as necessary.

    • unsigned char data[]
      This is the data to be added to the hash.
    • int len
      This is the length, in bytes, of the data in the "data" array.
  • SHA256_final(SHA256_CTX *ctx, unsigned char hash[])
    Finalize and output the hash.
    • unsigned char hash[]
      This is the array to store the output hash, which is 32 bytes long.

Code Usage

  1. Create an SHA256_CTX object.
  2. Initialize it with sha256_init().
  3. Read some/all of the data to hash into an array, calculate the size of the data, and add it to the hash with sha256_update().
  4. Repeat the previous step for all the data you want to hash.
  5. Finalize and output the hash with sha256_final().

Repeat steps (2) to (5) for as many hashes as you want to calculate.



The 32-bit words (aka, unsigned integers) used in the code assume little endian byte ordering. The SHA-256 specification uses the big endian byte order, so some byte-reversals are made when copying data into and out of integers in this code.

Note that this only provides the 256-bit variant of the SHA-2 specification.

This algorithm has only basic optimizations, and does not have very fast benchmarks. This algorithm has passed testing against numerous test vectors, including all official vectors.

Implementation of (Triple) DES in C

This algorithm implementation is a part of my cryptography implementations project. The full project, along with licensing information and more detail, is hosted on GitHub.


This is an implementation of the DES and 3 DES block ciphers. 3DES (is simply the DES algorithm iterated three times and sometimes referred to as Triple DES. This algorithm encrypts plaintext in block sizes of 8 bytes.

Code Documentation

For DES:

  • void key_schedule(unsigned char key[], unsigned char schedule[][6], unsigned int mode)
    This function generates a multi-dimensional key schedule from a user-supplied key, the key schedule will be used for encryption.

    • unsigned char key[]
      Must contain 8 bytes of data to be used as the key.
    • unsigned int schedule[][6]
      Must be 16 arrays of 6 bytes each. This will contain the final key output.
    • unsigned int mode
      This value should be set to appropriate the macro-defined ENCRYPT or DECRYPT value.
  • void des_crypt(unsigned char in[], unsigned char out[], unsigned char key[][6])
    This function both encrypts and decrypts text using the key schedule.

    • unsigned char in[]

      This contains the plaintext/ciphertext to be encrypted/decrypted. It must contain 8 bytes of data. Padding may be necessary if it is the last block of the plaintext.
    • unsigned char out[]
      This contains the encrypted/decrypted ciphertext/plaintext output. It must be 8 bytes in size.
    • unsigned int key[][6]
      The "schedule" array from the key_schedule() function.

For 3DES:

  • void three_des_key_schedule(unsigned char key[], unsigned char schedule[][16][6], unsigned int mode)
    • unsigned char key[]
      This array must contain 24 bytes of data to be used as the encryption key.
    • unsigned int schedule[][16][6]
      Must be 3 arrays each with 16 arrays of 6 bytes each.
    • unsigned int mode

      Set this equal to the macro-defined ENCRYPT or DECRYPT values.
  • three_des_crypt()
    function must be called, the same function both encrypts or decrypts the data.

    • unsigned char in[]
      Must contain 8 bytes of data to be encrypted/decrypted.
    • unsigned char out[]
      Must be 8 bytes in size to hold the encrypted/decrypted data.
    • unsigned int key[][16][6]

      The "schedule" array from three_key_schedule() function.

Code Usage

For DES:

  1. Generate an 8 byte key. Note that only the seven most significant bits of each byte will actually be used.
  2. Use the key_schedule() function to generate a key schedule from the eight byte key.
  3. Use the des_crypt() function to encrypt your plaintext in blocks of 8 bytes. (You will likely have to pad your last block of plaintext.) The output is the ciphertext.
  4. To decrypt the ciphertext, switch the "mode" argument for des_crypt() and pass said function the ciphertext as input.

For 3DES:

  1. Generate a 24 byte key. Note that only the seven most significant bits of each byte will actually be used.
  2. Use the three_des_key_schedule() function to expand the key into a key schedule.
  3. Use the three_des_crypt() function to encrypt your plaintext in blocks of 8 bytes. (You will likely have to pad your last block of plaintext.) The output is the ciphertext.
  4. To decrypt the ciphertext, switch the "mode" argument for three_des_crypt() and pass said function the ciphertext as input.



This implementation adheres fully to the official DES specification and includes the Initial Permutation and Inverse Initial Permutation steps that are often neglected for convenience due to their lack of cryptographic purpose.

This is an amateur implementation of DES. It has benchmarked to be fairly slow and has not been designed to be resistant to any sort of side-channel attacks.