All posts by Tom H

AWD Using Device Detection

Searching for ‘Adaptive Web Design’ (AWD) on google.com yields a variety of results, not all of which imply the use of device detection. At the time of this writing, wikipedia’s page on the topic is a mere stub.

AWD Without Device Detection

In his book Adaptive Web Design, Aaron Gustafson discusses general principles of web design, but does not mention device detection — at least not in the first edition. (I have not yet read the second edition.)

Articles describing the difference between AWD and Responsive Web Design (RWD) at techrepublic.com and css-tricks.com assert that the difference relies on breakpoints, stating that AWD uses them but RWD does not. However the responsive themes I have seen rely on breakpoints in media queries to determine which CSS rules to use to layout the markup served to the browser.

These articles all imply that all web servers deliver the same content to all browsers, regardless of the device type.

AWD With Device Detection

My understanding and use of the term coincides with this sitepoint.com article, which answers the question, “What is Adaptive Web Design.” Their answer maintains that it involves serving content selectively, depending on the device.

In my mind, with AWD it is the server rather than the browser that adapts to the device.

This technique implies some sort of device detection. Software does this by processing the
user agent
(UA) string that your browser sends to the server in the request.

Your User Agent String

You can see the UA string that your browser sends to servers at useragentstring.com. The page includes a table that breaks it down and describes the information it contains.

Chrome.Com has a page written for developers describing the UA strings it sends to servers, based on the device being used (Android or Apple).

Note that the server has access to this information even when you are in a private or incognito window.

RESS and “Dynamic Serving”

Another term for this sort of technique is REsponsive Web Design with Server Side Components (RESS). (I am sorry, but this acronym does not appeal to me, for a number of reasons, so I prefer not to use it.)

Given the name, this of course implies some sort of responsive design. My three sites fall into this category, but my online interactive resume, which uses device detection but no media queries, does not.

Google calls this technique “Dynamic Serving,” and offers a page offering tips for doing it properly.

Media Queries

Interestingly, it is possible to use media queries to serve different css files to devices, based on their characteristics, for example, the screen width. I for one would prefer (but have not used) this technique to responsive techniques that send the same content to all devices and rely on the browser to decide how present this content.

Mobile users may be surprised to learn that sites using RWD actually send content, then use media queries to hide it.

Saving Bandwidth

For me, the bottom line is we should not be sending content to someone — especially if they are on a mobile device — only to hide it. If your phone has a tight data plan, or you live in an area where that sort of thing is expensive, then I am sure you will agree that doing so is downright irresponsible.

But based on the apparent popularity of RWD techniques, apparently that’s just me.

The Conscientious Programmer

Because of previous experiences, I always take great care to try to write clean code that is easy to maintain.

These efforts have paid off! I have always received positive feedback — and at worst (best?) a helpful pointer — from colleagues who have reviewed my code.

As this short essay and this page on Stack Overflow demonstrate, there are plenty who agree with me in this respect.

Is Conscientiousness Obsolete?

As things change more and more quickly, some people might assert that being careful is no longer important, because today’s technology will soon be obsolete. More and more we see this, as technical debt increases to the point where legacy systems require total replacement.

This is certainly a valid point, and we need to be mindful about how much time we spend chasing an idea down a rabbit hole and trying to make things just exactly perfect.

Not So Fast!

Another side to this idea is that, because things change more quickly, it is our professional responsibility to help others embrace this change by writing more maintainable code.

As the trend away from full-time employment towards temporary gigs continues, it becomes more important for the next person — whose experience may be vastly different from our own — to be able to quickly understand how the current system works, so they can quickly make the desired changes.

My Personal Preference

Obviously, I can see merit in both sides of the debate.

But to be perfectly honest, I prefer to be conscientious, perhaps because it’s in my nature (I grew up with a lot of guilt).

When done with a project, I like to feel good about what I’ve done. I like to be confident I’ve done a good job and didn’t just “hack something up” to meet a deadline — not that there’s anything wrong with that — provided it’s what the customer wants.

Preventing Misunderstandings

Here are some techniques that can help alleviate possible misunderstandings when it comes to quality:

  • If you are planning to replace a system and just need a very few minor but important changes made, be sure to state this up front, so that we know that in this instance quality is unimportant.
  • Setting a fee for the finished product, based on its value to the customer, is preferable to paying for work by the hour. The set fee scheme alleviates the risk of unwillingly paying more for “high quality,” which can be difficult to define and in some cases even be totally undesired.
  • Stating up front that your company is on a strict budget and at this time cannot afford any extra expense for “high quality.” If you are interested in improving things once the company’s finances stabilize, this is good to know, because we can leave “TODOs” in the code to help the next person.
  • Building a “quick and dirty” prototype. A true prototype should be built with the intent of discarding it and starting over from scratch, if and when it proves the viability of your ideas. If you think the prototype might go into production at some future date, be sure to mention this up front.

In my experience, few clients will say they do not care about high quality, but their preference makes itself apparent in other ways, which can be unfortunate.

Direct communication is always preferable to nuance — which is easily lost when working remotely.

Over-Thinking or Due Diligence?

I like to take my time when solving a problem. More than once I’ve coded up a complicated solution, only to take a look at it and figure out a much simpler way to do the same thing.

To some, this is over-thinking. To me, it’s due diligence.

I like to come up with multiple solutions and pick the best one, rather than rush to implement the first idea, even though the initial solution might be sub-optimal.

Communication is Key

Moreover, if I am working for you on an hourly basis and you prefer I deliver an end result that might be something less than “just exactly perfect,” please state this up front.

Properly communicating your preferences allows me to keep an eye on the finished product and deliver an optimal result, regardless of whether we agree on what exactly constitutes “high quality.”

Run These Sites From My Home

One of my favorite sites is BuiltWith.Com. It will tell you plenty about this site, but one thing it doesn’t know is that I run it, and several others, from my home.

Geek Pride and Land Lines

I am very proud of the fact that I have a static IP address and run these sites out of my home. My internet provider is Forethought.Net, and the ability to host sites is included with my internet connection and land line.

Land lines may be old-fashioned, but this is the sort of offer I cannot refuse.

Well-Rounded Cheapskate

I assure you that in running these sites I do everything that needs to be done. This is partly because I like to be well-rounded, but mostly because I am a cheapskate.

I also assure you that I do not consider myself an expert in any of these tasks. For one thing, I dislike the term “expert” in any context, and for another, I am always open to ways to improve on my processes. One reason I dislike the term is because an “expert” would never question their own abilities….

If you’re interested, some of my more important processes and tools are available in my jmws_accoutrements repository on github.

“Everything” Means Everything

In case you do not run any websites out of your home, here is a list of what I mean by “everything:”

  • obtain static ip
  • conceive the types of sites I want to host
  • purchase domain names
  • buy the requisite hardware
  • configure the home network
  • install requisite operating systems and software and keep it up to date
  • learn the technologies needed to create these sites
  • actually do the work of creating these sites
  • create databases and site users with sufficiently secure credentials
  • imagine, organize, write, format, and post content
  • keep up-to-date backups of code and content
  • configure the server, ensuring it is secure
  • deploy sites to server, along with updates as they become available
  • design, write, test, and maintain programs to add any functionality that is missing out of the box
  • keep up-to-date with industry trends
  • document programs written
  • document deployment and other important processes
  • register the sites with google
  • comply with any requests google makes concerning security and searchability

If this looks like a lot of work, I can assure you that it is.

Favorite Practices

In addition to saving me money, a big advantage to doing things this way his lets me find out first hand what type of work I like best.

I like the programming best, and the writing and design tasks are close behind that. Testing and deploying are not quite as fun, but I don’t have to do them much, and I am too much of a cheapskate to be willing to pay someone else to do it, so we do what we have to do.

I greatly enjoy writing little scripts to help with deployment-related tasks, and am currently porting my bash scripts to python. (You can see these scripts in the bin directory of my jmws_accoutrements repo.

Because I am the only one using these experimental extensions, at this time it’s not really worth it to me to automate testing for this work. Kudos go to Drupal though for integrating automated testing out of the box.

Flow Is the Best

Ultimately, as I have learned in some of the online classes I’ve taken MOOCs, I love any type of work that involves flow. The linked-to article at PsychologyToday.com defines flow as being in a “state of effortless concentration and enjoyment.”

As you might imagine, working on my own for free can lead to occasional procrastination. That’s actually fine, because I always find that once I get going and into the flow of things, it can difficult to stop.

Moreover, “it’s all good,” and I greatly prefer any of this sort of work to at least 99% of the other occupations out there!

Leaders of Learning Class

I love learning, and it can be even more enlightening to learn about learning.

An excellent example of learning about learning is the HarvardX class Leaders of Learning, offered through edX.org. Although it quickly became apparent that the class was intended for educators, I decided to complete it anyway.

My final grade was 99% and I earned an Honor Code Certificate (pdf) for successfully passing it.

Modes of Learning

The class closely examined four modes of learning, based on the various combinations of these two independent qualities:

Collective or Individual
We can learn either in a group or alone
Hierarchical or Distributed
We can learn in either a formal environment, where the reward is a grade, perhaps leading to a degree of some sort, or in an informal environment, where the only reward is the additional knowledge

There are certainly other ways to look at learning, and at first these terms can seem a bit foreign. But this is how we analyzed the act of learning, and how education is changing, in this class.

Analyzing Four Ways to Learn

Because these qualities are independent, we can view the various combinations of them as quadrants in a table:

Collective Individual
Hierarchical Hierarchical-Collective learning often takes place in a classroom in a public school or at an accredited college or university Hierarchical-Individual learning takes place when a more knowledgeable person teaches a student one-on-one, for example, when tutoring
Distributed Distributed-Collective learning is the learning children might experience in a playground, when learning a sport, or what adults experience at meetups and conferences Distributed-Individual learning takes place when we read a book, on our own, to gain the knowledge therein and nothing more

The class began with a self-assessment. On the initial assessment, I scored much higher in the Distributed-Individual quadrant (73%) than I did in the others (20-30%).

The assessment was accurate because, since graduating from college, I have been mostly keeping up-to-date with technical advancements on my own, specifically by reading O’Reilly books.

Venturing into Other Quadrants

The class encouraged self-awareness and flexibility in crossing into other quadrants.

The class was intended for educators, and stressed that these four quadrants represent the playing field. With the internet changing everything, it’s important to know what your strengths and options are.

As a life-long learner, it’s also easy to see that flexibility on my part can lead to new and improved learning opportunities and experiences. In fact, this class was one of the things that encouraged me to start going to meetups and taking more MOOCs.

My First MOOC

The first Massively Open Online Class(MOOC) I took was The Science of Everyday Thinking, offered by The University of Queensland, Austrialia through edX.org.

I completed the class with a score of 84%, earning an Honor Code Certificate (pdf).

Constant Negativity

I grew up with a lot of negativity, and the echoes of those words continue to haunt me. I know that I am not alone in my struggle with these recurring thoughts, and work every day to fight them off, yet they persist.

This, my constant curiosity, and an enduring interest in psychology, led to my interest in this class. The time I spent in it was well rewarded.

Thinking and Our Biases

The class presented a wealth of information from a variety of people, but repeatedly referenced the book Thinking Fast and Slow by Daniel Kahneman. The result of decades of work, his book earned several awards, and the instructors referred to “System 1” (fast, subconscious) and “System 2” (slow, calculating) thinking throughout the class.

The class also discussed some of the unconscious many cognitive biases that affect our decisions, if we are not careful and take the time to think slowly. A complete list of these can be a bit overwhelming; it would be a mistake to let this fact deter you from learning about them, and how they can limit us from fulfilling our potential.

A Great Start!

The class was a great start to taking more, both at edX and at Coursera. As I later learned in the Leaders of Learning class I took at HarvardX, the internet is changing how we learn, opening up grand opportunities for all of us!

A Passion for Maintainable Code

Thanks to a book, named Code Simplicity, I finally realized one of the main things I love about programming so much.

Finally, after many years, I have discovered my passion! And that is: writing code that is easy to understand and maintain, and this boils down to keeping code as simple as possible.

The book analyzes the value of software, the effort needed to maintain it, and the desirability of the changes, even though we cannot be sure what the nature of these changes might be.  And it comes to the conclusion that all code needs to change eventually, and the future cost of making these changes is more significant than the initial cost of development.

The book made me realize that the real cost in software is not in the development of it, but in the maintenance.  By taking a little extra time and ensuring that code is maintainable, in the long run we save money.

And that is what I really enjoy about writing software.  Once I get a program to work once, I don’t like to stop there, the way some people do.  Instead, I like to take the time to look at what I’ve written and ask:

  • Does it make sense?
  • Could what it does be done any more simply?
  • Is there any cruft, any dead, unused code?
  • Will a new person understand it, quickly and easily?
  • Will a new person fix or enhance it, quickly and easily?
  • Will I understand it, quickly and easily, if I need to change it, in the middle of the night, a few years from now, or both?

To tell the truth, I actually have at times felt guilty about taking this extra step.  After all, the program works, why spend more time on it?  And of course there are times when I haven’t been able to take this extra step, and have regretted delivering something that I am not very proud of, something I know could be better, if only there was a bit more time.

This blog contains stories about the benefits of well-designed, easy to maintain code, and the hazards of poorly-designed, difficult to maintain code.

But I still encourage you to buy the book.

Why I Loved Going to College!

Rather than rely on my parents to pay for it, I worked my way through school, and did it my way.

After finishing my Bachelor’s of Science in Mathematics degree at Virginia Commonwealth University in 1986, I decided to get a Master’s degree.  Back then, Artificial Intelligence was a very hot topic.  The books and articles I read about it kept saying it was a very Interdisciplinary field.

Also, at the time, I was growing tired of playing music (I played bass in a bluegrass band) and took a class in Photography.  This led to a History of American Photography class, which led to other Art History classes.  Who would’ve guessed that I would love Art History?  In later years this would lead to interests in Dance and Film Noir, but I digress….

So I talked to Nicholas Sharp, who was in charge of Interdisciplinary Studies there at VCU, and to several other faculty members in both the School of the Arts and the College of Humanities and Sciences.  And I took some more undergraduate Art classes, including a Graphic Design class using those old Apple ][ E‘s.  Then I signed up for and got accepted to a graduate program in Math, and after a few semesters switched over to the School of Interdisciplinary Studies.

As an Interdisciplinary student, I took enough Computer Science classes to earn a Masters of Science in Math, and in addition took some Graduate-Level Independent Study Art classes.  These are the classes in which I wrote the first version of the Graphical Representations of Jungian Archetypes or GROJA program, using LISP on an old 8086 PC.

The Groja program uses the results of the MBTI personality test to draw an image of an individual’s personality.  Since the original version I have put three versions online, the latest of which is at SeeOurMinds.com .  But I digress yet again….

So, that’s why I loved going to college: I was able to pick the classes I wanted to take, and do them my way!

The GROJA Program

I wrote the GROJA program in Graduate School. GROJA stands for Graphical Representations of Jungian Archetypes.

Given the results of a questionnaire, the program draws an image of a person’s personality. The resulting image represents a person’s preferences, based on the four pairs of opposites that Carl Jung describes in his Description of the Types.

I wrote the first version in LISP and it ran natively on a PC. Since then I have used PHP to write three online versions. For details see the About page at Groja.com.

Due to security concerns, this program is no longer online. But I am able to run the most recent version locally. You can find a gallery of images in the Gallery at SeeOurMinds.Com.

When Coworkers Complain

My first programming job was writing code in an Assembly language for NCR Century minicomputers, called NEAT 3, for a trucking company.  For the record, the first day of my career was the Ides of March in America’s Bicentennial year: March 15, 1976.

We wrote the code on paper forms using pencils, used a key punch machine to punch cards, which were then read into one of the computers when the computer operator was able to get around to it.  We had two computers, and each had only two partitions, and only one of the partitions was capable of “cowpiling” programs.  (Our operator, Al, had a rather cynical sense of humor!)

Along with some enhancement and bug fix tasks, for example, changing the number of digits needed to represent a terminal – the equivalent of a primary record key in today’s terminology – from two digits to three, I remember working on a system to process claims for items damaged during transit.

And along with some other people, I worked with a woman whom I will call Carol, who was constantly complaining about how hard it was to understand the programs she had to make changes to.

This made a huge impression on me!  The last thing I would ever want to be is the type of person my coworkers complain about!

Specifically I remember her complaining about how the original author managed tables.  NEAT 3 provided a mechanism for iterating through tables, but the original author of the programs Carol was working on was too smart by half to use it.  Instead he  chose to “bump registers,” which means he would:

  1. store the address of the current row in the table in a register
  2. process the current row, saving the new values if required
  3. add a literal offset, such as 123, to the register, to access the next row in the table

So when Carol wanted to add or remove a field to or from the table, or change the size of an existing field, she had to find all occurrences of the current offset (123 in the example above) and change it to the new size.

That means that Carol had to find every piece of code in the entire system that iterated through these values, and update that offset, every time the length of the table changed.  In all of today’s modern programming languages, all a programmer should (!!!) have to do is change the contents of the table – which we hope should be defined only once – and they should be good to go.

This might not be so bad, if we had an Integrated Development Environment (IDE) or even a fancy text editor like vi (aka. “six“) but we were using punch cards.  Yeah.

The lesson I learned from that experience is that writing programs with an eye towards maintainability can not only help keep future programmers from being aggravated and hating you, but also save your employer a lot of money down the road!

As this recent post on slashdot, and even more so the responses to it show, Carol’s situation was hardly unique, or by any means antiquated.

When coworkers complain, valuable lessons can be learned!