An Atlantic article, The Year 'the Stream' Crested, wonders if people are getting burnt out the endless wall style of running into information, and will withdraw from the sense of being "permanently unfinished". (The subheadline of the piece asks "The Stream is fun and fast, but don't you miss the sense of an ending?", and is therefore subject to Betteridge's Law of Headlines)
The Internet of the mid-90s had a much different vibe than the place today. Authors could make books, physical dead-tree books, full of interesting links on the "information superhighway". Yahoo made its mark by providing a searchable set of links that were submitted and vetted by humans-- nowadays, we'd call that "curated"-- and then Google came along and made a new, searchable world where the reputation of a site mattered more than its ability to stuff the keyword you were searching for 100,000 time in its hidden content. This is when the Web really came into its own, because Google made the interconnectedness really matter.
The early-2000s were an interesting time. People were empowered to carve out their own niche on the web and the era was marked by the Rise of the Blogs. Word-of-mouth and Google would let these sites gain regular audiences. Some of the more popular blogs, like BoingBoing or to a lesser extent Slashdot, had multiple editors to select the content, and a link from a popular site could send hitcounts skyrocketing.
And then came Facebook. Its News Feed was a powerful idea: by showing what people were posting on their Walls, you had a single age that was an aggregation of content by somewhat-like minded people. This was more egalitarian than the old blog model. (Those democratic notions were pushed even further on sites like Reddit, allowing popular links to be voted into attention in more global ways, not just among overlapping groups of Friends) They weren't the first to offer this "one stop shopping" view (I think of LiveJournal's Friends page (among other examples)) and they certainly aren't the only: Tumbler and especially Twitter are centered on that very concept. However, Facebook combined this type of Stream with the ability to connect with people you know in the real world, and started doing so at a time when most other sites were still letting people pick their own identities, ala AOL back in the day.
I think Facebook really changed the nature of the Web. For many years my personal website was the center of the online world for me and several friends, and had a vibrant comments section (as crappy and homebrew and prone to occasional spammer attacks as it was) -- in the late part of the last decade, that went away. Similarly my romance poetry site Love Blender went from having 400 submissions of poems a month in 2004 to 20 or so now. Now, this might just mean I'm a bad web marketer, and that's true, but I've heard of other similar experience people have had, and I really think Facebook is the harbinger of that change. It's simply more compelling to have a bunch of your friends finding interesting stuff than one friend, or a group of strangers.
So what now? This Wired article from earlier this year sees the future as all-stream, all-the-time. An article on medium.com (I find its reticence to label itself with a date irksome) rejects this and sees the traditional web of information at fixed retrievable locations reigning supreme. The answer, as always, is somewhere in between. The Stream taps into the deep "fear of missing out", as well as promising all-too-easy distractions from the workaday world. But the fixing of these infonuggets at reliable locations in cyberspace (man, remember that word?) is critical as well, both for sharing and for the benefit of our future selves, making sure that retrieval tomorrow is possible.
Friday, December 13, 2013
Wednesday, December 4, 2013
upon the nature of Java Swing vs HTML5
Taking over some Java Swing UI code... compared to HTML5/js, it feels SO WEIRD to try and build your nouns via a series of verbs...
Talking about this idea with a coworker, he pointed out I might be feeling the lack of "MVC"-- in a way HTML has the page as the view and the javascript as the controller, and I miss that when I have to build everything via commands in Java Swing.
Talking about this idea with a coworker, he pointed out I might be feeling the lack of "MVC"-- in a way HTML has the page as the view and the javascript as the controller, and I miss that when I have to build everything via commands in Java Swing.
Tuesday, December 3, 2013
the power of cdns
One of the people behind 4chan (NSFW site, in general) writes about small advantages adding up in use of a CDN.
A CDN is a "content delivery network", often a place to put "write once, read many" static content. We had found similar advantages to switching to a CDN at Alleyoop-- the way the cookies don't get sent is very helpful in reducing bandwidth. (And converting the embedded image references in the html to the new location was an awesome Perl task for me...)
A CDN is a "content delivery network", often a place to put "write once, read many" static content. We had found similar advantages to switching to a CDN at Alleyoop-- the way the cookies don't get sent is very helpful in reducing bandwidth. (And converting the embedded image references in the html to the new location was an awesome Perl task for me...)
Thursday, November 28, 2013
happy thanksgivukkah!
So today is a relatively cool day, the last time the first day of Hanukkah and Thanksgiving will intersect for over 70,000 years. That amazes me, so I busted out some jQuery and made up a little chart showing the wandering of the two holidays against the fixed secular calendar... this image is the top of it, you can see the rest at http://kirk.is/2013/11/28/. I enjoyed how this brought out the patterns of the shifting.
Wednesday, November 27, 2013
jquery 1.9.1 minmap
My html5 w/ jQuery boilerplate code grabs jQuery from the CDN, but sometimes I pull it down for local development. (I still use jQuery 1.9.1 for older IE compatibility) When I use a local copy, the console can get polluted with "jquery.min.map" not found -- this is a file that lets you map the minified code to a more readable version. Anyway, if it's not clear, the minmap for http://code.jquery.com/jquery-1.9.1.min.js is at http://code.jquery.com/jquery-1.9.1.min.map.
old macdonald had a computer, IE, IE, Ohhhhh
Back to some "make this work with older IE" issues.
My company has a javascript library for communicating with our service, and then an optional "renderer" for displaying data from the service.
While I wouldn't bother making the "renderer" without jQuery, we thought having the core library being jQuery-independent was a good idea, since the only thing we were using jQuery for was ajax calls. I previously discussed what that looked like but there was an IE-7 (at least) gotcha; it doesn't have "JSON" as a built-in, so the code wasn't working. The quickest solution then was to grab Crockford's json2 which will make a JSON object only if it doesn't exist already.
The renderer pulls down dynamic display information from the server and builds some custom CSS. Previously it would inject that CSS (in the variable "buf") via jQuery with the following line:
$("<style>").prop("type", "text/css").html(buf).appendTo("head");
That broke on IE. phpied.com offered a solution and a crossbrowser, legacy-friendly equivalent code looks like this:
var ss1 = document.createElement('style');
ss1.setAttribute("type", "text/css");
var hh1 = document.getElementsByTagName('head')[0];
hh1.appendChild(ss1);
if (ss1.styleSheet) { // IE
ss1.styleSheet.cssText = buf;
} else { // the world
var tt1 = document.createTextNode(buf);
ss1.appendChild(tt1);
}
Ah well, I've seen worse.
My company has a javascript library for communicating with our service, and then an optional "renderer" for displaying data from the service.
While I wouldn't bother making the "renderer" without jQuery, we thought having the core library being jQuery-independent was a good idea, since the only thing we were using jQuery for was ajax calls. I previously discussed what that looked like but there was an IE-7 (at least) gotcha; it doesn't have "JSON" as a built-in, so the code wasn't working. The quickest solution then was to grab Crockford's json2 which will make a JSON object only if it doesn't exist already.
The renderer pulls down dynamic display information from the server and builds some custom CSS. Previously it would inject that CSS (in the variable "buf") via jQuery with the following line:
$("<style>").prop("type", "text/css").html(buf).appendTo("head");
That broke on IE. phpied.com offered a solution and a crossbrowser, legacy-friendly equivalent code looks like this:
var ss1 = document.createElement('style');
ss1.setAttribute("type", "text/css");
var hh1 = document.getElementsByTagName('head')[0];
hh1.appendChild(ss1);
if (ss1.styleSheet) { // IE
ss1.styleSheet.cssText = buf;
} else { // the world
var tt1 = document.createTextNode(buf);
ss1.appendChild(tt1);
}
Ah well, I've seen worse.
Monday, November 25, 2013
mysterio errors thanks to json
Grr, just spent like 30-45 minutes trying to figure out why the most basic of Ajax loading scripts wouldn't work, something like
$.ajax({
type: "GET",
url: "contexts.json",
dataType: "json",
contentType:"application/json;",
success: function(res){ alert(res);
} );
On the network tab of chrome I could see the request getting made, but nothing was coming up.
Long story shorter, the request was told to parse JSON, but my contexts.json file had map keys that weren't quoted strings. And the parse failure was happening in that weird asynchronous lala land. (Unquoted keys are more or less fine in javascript, because of the way it handles them as labels.)
One way I could have avoided this annoyance was to run all static JSON through my favorite parser at http://json.parser.online.fr/ - it would have told me straightaway that by unquoted keys would blow up.
$.ajax({
type: "GET",
url: "contexts.json",
dataType: "json",
contentType:"application/json;",
success: function(res){ alert(res);
} );
On the network tab of chrome I could see the request getting made, but nothing was coming up.
Long story shorter, the request was told to parse JSON, but my contexts.json file had map keys that weren't quoted strings. And the parse failure was happening in that weird asynchronous lala land. (Unquoted keys are more or less fine in javascript, because of the way it handles them as labels.)
One way I could have avoided this annoyance was to run all static JSON through my favorite parser at http://json.parser.online.fr/ - it would have told me straightaway that by unquoted keys would blow up.
the webserver built into osx
This link talks about the apache server that comes built into OSX these days -- specifically the document root tends to be /Library/WebServer/Documents/
(tl;dr -- you can run commands like
sudo apachectl start
(where start could also be stop and restart))
and then you can see things in that folder at http://localhost (aka http://localhost:80 )
(tl;dr -- you can run commands like
sudo apachectl start
(where start could also be stop and restart))
and then you can see things in that folder at http://localhost (aka http://localhost:80 )
Saturday, November 23, 2013
the 10,000-foot view from the trenches of software development
Recently, a mutual friend put me in contact with a woman who wanted to pick my brain about software development. Coming from a strong business background herself, and having gotten into SQL a bit since, she found the idea of becoming a fulltime software developer appealing (lord have mercy on her soul) and wanted some advice on the lay of the land.
Thinking of how to describe the tech industry to someone new is a bit daunting. There is a ton of stuff out there that I "just know", from the casual programming I did before college (10 PRINT "KIRK IS GREAT! "; 20 GOTO 10 ) to my formal computer science degree to what I've picked up by being in the industry 15 year since. It's difficult to guess what someone who is moderately tech savvy but not really a hobbyist knows or doesn't know.
That said, I thought I'd try to lay out my understanding of the field, what's hot, what's not, what technology is used where and how, etc. This is of course a highly subjective description, but I do welcome input from other veterans. (As I review what I've written, I realize this is pretty biased towards my own experience writing web-based software, vs stuff that runs on desktops or on mobile devices)
SOME BACKGROUND
Sometimes it's hard for Programmers to understand why every seems to think programming is so difficult. In general, it ain't rocket science; if someone can cook following a recipe, or maybe make their own recipe for someone else to follow, they should have enough facility to program.
TEMPERAMENTS
Back in college, I noticed a divide between Computer Scientists and Engineers (at my school this got so political that the subdomain for the department went from "cs.tufts.edu" to "eecs.tufts.edu" and back.) The former tend to be more interested in what can possibly be computed in a formal and abstract way, the latter more into what computers can be used for. Personally I'm definitely in the latter camp.
Front End (UI/UX) Frontend is the part of the computer the user interacts with directly... the stuff that lives in the browser, that they see on their mobile device screen, etc. (UI is the nitty gritty details. UX is the more generalized approach to making a system that's easy for a user to understand.) This might refer to the stuff that actually lives in the browser, say (javascript and jQuery are popular there) or it might be the stuff that makes the webpages on the server before pushing them down to the user's desktop. (PHP, Ruby, for example, or ASP.Net on the Windows side)
Backend / Serverside - The part of the system that runs on the company's centralized computers. (There's some overlap with the idea of "The Cloud") For a mobile app, there may or may not be a server side component. But here much of the "heavy lifting is done". Java is really big here, and C# on the Microsoft side.
Database - when you need to store information for the long term, in general you use a database. Oracle used to be the big money thing here, but cheaper alternatives like MySQL and PostgresSQL have probably started to eclipse it. (SQL Server on the Microsoft side) Most of this stuff is SQL based, though there's a growing interest in "noSQL" alternatives (like MongoDB) that tend to be more based on documents rather than rows and columns)
There used to be a term "Midtier" but now I'm not sure what that means... maybe it's just another term for the serverside stuff that's not all the way back to the database.
This is most of the style of programming I've done-- but there's also a whole world of Desktop Applications (things that run directly on your Windows PC, Mac, or Linux Box) and lately Mobile Development (iOS and Android, mostly) has gotten a lot of excitement. Some of these apps will also have a server component-- for example, Instagram runs its own servers that its mobile apps talk to, and then also serve up webpages.
Sometimes you hear talk of The Cloud, which is just a simplified way of saying "a bunch of servers on the Internet". Some companies have started using Cloud-based services, like Amazon Cloud Service, to run the actual physical hardware that the server side software runs on. It's a great way for companies to save the expense of knowing how to run the damn things themselves.
OTHER TERMS
A completely incomplete and idiosyncratic glossary:
IDE is an expression that comes up a lot. It stands for "Integrated Development Environment" and what that means is a text editor, geared up to know more about the language you're coding in, plus connections to compile and run your code, and probably step through it while you're debugging. "Xcode" is the IDE for all things Apple, "Visual Studio" is the thing for Microsoft, "Eclipse" is popular for people doing Java.
API I'm not even going to Google what the initials stand for - it's just one of terms you use. An API is a library and supporting software that will handle a certain task for your program as you write it. For example, a Graphics API will give you functions to call to draw circles and lines and squares on the screen, so you don't actually have to write the code to draw just the pixels that are inside the circle you want (that API may then call another, lower-level API responsible for actually coloring each pixel, so that the Graphics API doesn't have to worry about talking with the physical screen hardware)
Abstraction - the API discussion is a good segue to this... at the lowest level, a program is 1s and 0s representing physical electrical states in a transistor. But it's way too hard to write complex things in 1s and 0s, so people invented computer languages that group various operations for the 1s and 0s into more human-like commands. In other words, even though you're still pushing around 1s and 0s, a computer language lets you right at a "higher level of abstraction". The code of the art program showing a rough model of a picture of the atom is higher level of abstraction that than the code that draws the circle, is a higher level of abstraction than the code that tells each pixel to be plotted, is higher than the code that tells the screen to be a certain color at a certain point in a hardware refresh rate (or whatever the hell screens are doing these days)
Design Patterns - giving certain names to high level ways of doing things, so developers can better talk to each other about how they made their program do what it does. For instance, a "Factory Pattern" describes ways of creating program objects without knowing all the details of the object you want to make, just how you want to use it.
Asynchronous - Man, now we're getting fancy! "Asynchronous" means you've triggered something happening, but you're code is not waiting around for the result... it will get "called back" when the action finishes. If a program is Synchronous, sometimes everything in its little world freezes until the action is done... this can lead to poor UX (See above)
Scaling - writing software and setting up systems so they "scale" means making it so many users can use it at once. "Does it scale?" is an important question. Back in history, the site "Friendster" fell by the wayside in part because it couldn't handle all the people who wanted to use it at once, and more recently Healthcare.gov also had "scaling issues"
HOW TO LEARN THINGS
One question is about how to learn things, pick up technologies.
This can be a bit of a chicken-and-egg problem: often a company will hire for a knowledge of a specific technology, but often an environment like a job is the best place to learn by making something in the real world; so you need to know tech to get a job, and you need the job to teach you the tech. So in practice is you can get hired for other knowledge or general competency, and then pickup the technology there. Or, often a project will add a technology as it grows and discovers new problems with the tech stack emerge.
There are other methods as well. A popular suggestion is to start your own open-source project, put it on GitHub. Personally I think this is kind of big and intimidating, but then again it took me a long time to realize the open source software can as full as dodge-y code as the "professional" stuff.
Even though over the past 3 or 4 years I've moved into the front-end, in 2009 or so I was behind with the developments that were letting more and more exciting stuff happen in the browser itself. Something I found (though after I used the "get hired for basic competency, then push" trick) are the newsletters of Cooper Press, especially "Javascript Weekly". This comes to your email inbox and is a great way to keep your finger of the pulse of what's going on in the tech space.
As a side note, another development of the past half-decade is the emergence of "Stack Overflow" as the repository of answer to a million little tech questions. I mean, for over a decade, "I guess I'll Google the error message before beating my head against this" was a tremendous tool in every developer's arsenal, but more and more the most relevant results are at Stack Overflow. (But since you use Google to get there anyway, this is more an observation/prediction of what will happen to the new developer, rather than advice of where to go. Presumably said developer already knows about Google.)
There are also a lot of good tutorials out there, and courses by Stanford and other universities, and stuff like Code Academy. I don't have as much experience with these... I do know sometimes there's a large gap between that kind of simplified tutorial and "the real world", so I would say if one of these courses seems easy, it's probably not doing its job thoroughly enough.
LANGUAGES/ENVIRONMENTS
In general, there are 3 things that set languages apart from one another:
1. The syntax and basic rules of it. It's been demonstrated that any popular language is about as expressive and powerful as any other one, but there are enough small differences that lateral changes can be tough. (Also, a language switch ideally gives a new angle to your perspectives on coding in general.)
2. The libraries and frameworks that are popular for it. Now, every language ends up getting a TON of small frameworks-- often by aspiring coders trying the "start an open source project to learn and put on resume" trick. My advice is to avoid these, unless it's clear it REALL solves your problems... which leads me to a digression:
TEMPERAMENTS PART 2
Another divide is in techies who like to build things from scratch vs finding a pre-existing library and using it. Sometimes this decision is referred to as "Make vs Buy" -- even if the "Buying" is something free, you might still be paying in terms of how the time spend to learn how to use the library properly.
PROS FOR BUY
PROS FOR MAKE
BACK TO LANGUAGES
Disclaimer: these are just my rough opinions from a decade or two in the industry. I might be missing big things, either because of my own experience or just because I'm not good at sitting and thinking of comprehensive lists.
C/C++ - Popular with people do things on Linux, and low-level (close to the hardware) type stuff. My first university classes were in these, but the languages were so primitive at the time that my opinion is probably unfairly biased against them. But they were a good start for me, because C-like syntax (with curly braces used to set aside blocks, arguments to functions in parentheses, return statements from functions and semicolons to explicitly say where each line of command ends) has influenced many other languages, Java, Javascript, Objective-C, and many more.
Java - Probably the most Java opportunities are for writing serverside code for big companies that have relatively comfortable amounts of time to "do the engineering right" This is where I was for much of the first decade of the 2000s. I also use it for toys I write, using a specific IDE/toolkit called Processing (see http://processing.org/ that provides an IDE and an API for artists and students to make cool, interactive things.) Also, programming for Android devices (phones, tablets, etc) is mostly in Java.
Javascript - Javascript is kinda like Java just like Rootbeer is kinda like Beer. This language is often thought of in conjuction with HTML5, more on the below. For years, it was kind of looked down on as a toy language for doing little tricks in the web browser, but over time that became amazing stuff like Gmail and Google Maps - the browser does more of the work, and doesn't have to wait for the server to populate ever little bit of the page. These days, it often goes with jQuery, which is a powerful API for manipulating stuff in the webpage (sometimes called "The DOM", Document Object Model, meaning the objects that represent the webpage the person is looking at) and for sending messages back and forth to the server. (Sometimes that's called AJAX, an acronym involving the asynchronous (see above) nature of a browser not freezing up while waiting for the server, and the messages are in JSON, see below) Lately there's been a move towards also having Javascript be the language for the stuff on the server -- there the most popular toolkit seems to be node.js. (except for jQuery, all these cool javascript libraries call themselves something.js)
2016 Update: I've been showing this article to a few people trying to get into tech, and so I guess it behooves me to keep it a little up to date. So I'm saying, I'm stunned at how popular Angular.js has become- I've rambled about it at length, and I am still surprised people are willing to give up so much transparency and decoupling of view and model into what's going on for a bit of componentization and not having to read/write form data fields (I think Google's "endorsement" (not that they use it, but hey) gave it an edge even when more mature things like Ember and React came out while Angular was still struggling to reach 2.0 helped a lot)
2020 Update: "React" seems to have been winning a lot here, especially when paired with Redux. I'm happy, of the Ember/React/Angular set, React was my clear favorite.
TANGENT: XML vs JSON
When a browser talks to a server, or two computers talk to each other in general, they have to figure out how they're going to wrap up the data they want to send to each other. "XML" was popular in the early 2000s... it looks kind of like HTML (see below) and was very careful about labeling its fields so it was clear just what the data it carried meant. It was also generally a big pain in the ass. "JSON" is the new hotntess in a lot of ways... it's a very simple and easy to read way of including lists, and key-value-pairs, and lists of key-value-pairs etc, and is easy to work with. It also happens to be the way you'd setup any data in Javascript code.)
HTML5/CSS - this is a different thing than most of the "languages" in this list, because it's something you might write a webpage in, not a program. HTML has long been how you write webpages, it has all these <tags> that wrap around the text content of the page, and carry the references to other things like images that might be visible on the page. "HTML5" is a hip buzzword, and in part it means the HTML document should be JUST the content and a minimal amount of tags saying what it is, and most everything that makes it pretty and controls how it looks should be in separate CSS files... CSS is a set of commands for describing color, border, position, etc etc of things that are on the page... see CSS Zen Garden for a clear idea of how different you can make a page by keeping the HTML the same, but changing the CSS (and maybe more importantly the image files the CSS refers to)
Ruby on Rails/Python/node.js/PHP - I'm lumping these together, even though that reflects my own history of "things I think are cool but don't know much about". These languages (well, 2 of those are specific toolkit) are very cool and powerful ways of writing server code... very popular with those little San Francisco and Cambridge and New York startups. It used to be COBOL was the way old business language (that you could still make a living on, especially around Y2K) and Java was young and hot, but now these are to Java what Java was to COBOL.) PHP is a little older and clunkier than the others, but still gets some play.
Perl - just like the Javascript section was bigger than the "hip server language" section because that's where my heads at these days, Perl gets a mention more because of what it meant to me than the industry right now. (Though I've heard it's making a revival in Japan, of all places.) Perl is a weird language that borrowed a lot of syntax and style from various languages, all Unix-based. When I came to it from C, however, it was a revelation. It taught me (and I'm listing these as things a new programmer should know a bit about):
Objective C - the kind of unusual language Apple uses. Used almost only by people who write stuff that runs on a Mac or iOS device, but that last group has EXPLODED in numbers over the last half-decade. Generally with the XCode IDE.
.Net/C# - This is to Microsoft what Objective C is to Apple. There is a LOT of businesses out there that code with stuff, they have some excellent certification classes so if you have the time and money to go through with that, you can absolutely get a good foot up and start a career that way. (Again, I'm not writing more about it because I've had less experience here.)
SQL - a popular language for interacting with databases in, each platform (Oracle / Postgres / MySQL / Miscrosoft Sequel Server ) has its own flavor. You should also be aware that there's a NoSQL movement of ways of storing data permanently that follow different patterns than SQL's Relational Database model (all these multiple, excel-like tables connected to each other via keys)
2020 Update: I don't know where to put this in, but some other languages/systems that are popular include Hibernate, which is a way of putting data in databases, Kafka, which is passing messages around a bunch of servers, so that the whole system can handle much more load, and then containerization is a big thing... when you're doing stuff on the cloud, you're making these little virtual computers on the rented big server...
SO IN CONCLUSION
This might be a work-in-progress that I will come back to, and I welcome feedback from experienced coders and aspiring newbies alike. What do you wish someone told you when you were starting out? Let me know and I'll add it here.
Thinking of how to describe the tech industry to someone new is a bit daunting. There is a ton of stuff out there that I "just know", from the casual programming I did before college (10 PRINT "KIRK IS GREAT! "; 20 GOTO 10 ) to my formal computer science degree to what I've picked up by being in the industry 15 year since. It's difficult to guess what someone who is moderately tech savvy but not really a hobbyist knows or doesn't know.
That said, I thought I'd try to lay out my understanding of the field, what's hot, what's not, what technology is used where and how, etc. This is of course a highly subjective description, but I do welcome input from other veterans. (As I review what I've written, I realize this is pretty biased towards my own experience writing web-based software, vs stuff that runs on desktops or on mobile devices)
SOME BACKGROUND
Sometimes it's hard for Programmers to understand why every seems to think programming is so difficult. In general, it ain't rocket science; if someone can cook following a recipe, or maybe make their own recipe for someone else to follow, they should have enough facility to program.
Programming is A. getting the knack of breaking a complicated procedure down into tiny steps and B. getting better at imagining what can go wrong, what are the unusual cases or inputs or conditions when the program is running that might interfere with an otherwise straightforward bit of coding. And I guess C. learning what's out there, what wheels are available that you really shouldn't reinvent, and familiarity with the libraries and code bases you're working on. This blog entry is all about C, I guess.
TEMPERAMENTS
Back in college, I noticed a divide between Computer Scientists and Engineers (at my school this got so political that the subdomain for the department went from "cs.tufts.edu" to "eecs.tufts.edu" and back.) The former tend to be more interested in what can possibly be computed in a formal and abstract way, the latter more into what computers can be used for. Personally I'm definitely in the latter camp.
The divide lives on in the industry, but shifted. Here the term Engineer often refers to someone who takes a more formal approach to their code, they'll try to make sure it's reusable, well-tested, etc from the get go. This is in opposition to a Hacker mentality (an overloaded term, to be sure: it can also refer to people who like to break into systems, and to people who just like modifying technologies to work in ways other than it was first intended.) The Hacker feels that "premature generalization is the root of all evil" (i.e. you make a system too complicated by trying to create it in a reusable fashion while only being able to guess at what the future uses of it would be) and also that spending too much time and energy on tests is not a good investment, since you can only test for things that you think will go wrong anyway, and anyway there are formal studies that indicate and really good tester system will be as complicated as the system it was meant to test. (End self-defensive soapbox.)
TECH LANDSCAPES
In some ways, technology for web based stuff in the industry reflects (or is reflected by) peoples choice of desktop computers:
Windows - kind of old and boring but gets the job done. Microsoft made some really nice IDEs (see below) and some companies dig having such a big name behind the technology their techies are using. They tend to offer pretty powerful languages, but often don't make it easy to know what's going on "behind the scenes". (A lot of hackers don't like systems that are powerful but hard to understand, because they're tough to deal with when something breaks, or when you want to make them do something a tad beyond what they're first programmed to do.) Popular languages are ASP.Net and C# (pronounced C-sharp)... more on that stuff later.
Unix - Linux is the most popular flavor of straight "Unix" Unix is a very famous, clean, hacker- (and engineer-) friendly environment. (Tangent: Unix has a philosophy as "treat everything as a stream of text, and then do things by passing your stream of text through a series of little programs (via "pipes")) This is the native territory for Java, Python, and Perl.
Macs - Macs have always been a favorite for artsy and designer types. Technically (well, semi-technically) these days OSX is a flavor of Unix, so there's some real overlap with Unix. Still certain technologies are probably more popular here, like node.js and jQuery
Unix - Linux is the most popular flavor of straight "Unix" Unix is a very famous, clean, hacker- (and engineer-) friendly environment. (Tangent: Unix has a philosophy as "treat everything as a stream of text, and then do things by passing your stream of text through a series of little programs (via "pipes")) This is the native territory for Java, Python, and Perl.
Macs - Macs have always been a favorite for artsy and designer types. Technically (well, semi-technically) these days OSX is a flavor of Unix, so there's some real overlap with Unix. Still certain technologies are probably more popular here, like node.js and jQuery
TERMINOLOGY
Software tends to have different layers:Front End (UI/UX) Frontend is the part of the computer the user interacts with directly... the stuff that lives in the browser, that they see on their mobile device screen, etc. (UI is the nitty gritty details. UX is the more generalized approach to making a system that's easy for a user to understand.) This might refer to the stuff that actually lives in the browser, say (javascript and jQuery are popular there) or it might be the stuff that makes the webpages on the server before pushing them down to the user's desktop. (PHP, Ruby, for example, or ASP.Net on the Windows side)
Backend / Serverside - The part of the system that runs on the company's centralized computers. (There's some overlap with the idea of "The Cloud") For a mobile app, there may or may not be a server side component. But here much of the "heavy lifting is done". Java is really big here, and C# on the Microsoft side.
Database - when you need to store information for the long term, in general you use a database. Oracle used to be the big money thing here, but cheaper alternatives like MySQL and PostgresSQL have probably started to eclipse it. (SQL Server on the Microsoft side) Most of this stuff is SQL based, though there's a growing interest in "noSQL" alternatives (like MongoDB) that tend to be more based on documents rather than rows and columns)
There used to be a term "Midtier" but now I'm not sure what that means... maybe it's just another term for the serverside stuff that's not all the way back to the database.
This is most of the style of programming I've done-- but there's also a whole world of Desktop Applications (things that run directly on your Windows PC, Mac, or Linux Box) and lately Mobile Development (iOS and Android, mostly) has gotten a lot of excitement. Some of these apps will also have a server component-- for example, Instagram runs its own servers that its mobile apps talk to, and then also serve up webpages.
Sometimes you hear talk of The Cloud, which is just a simplified way of saying "a bunch of servers on the Internet". Some companies have started using Cloud-based services, like Amazon Cloud Service, to run the actual physical hardware that the server side software runs on. It's a great way for companies to save the expense of knowing how to run the damn things themselves.
OTHER TERMS
A completely incomplete and idiosyncratic glossary:
IDE is an expression that comes up a lot. It stands for "Integrated Development Environment" and what that means is a text editor, geared up to know more about the language you're coding in, plus connections to compile and run your code, and probably step through it while you're debugging. "Xcode" is the IDE for all things Apple, "Visual Studio" is the thing for Microsoft, "Eclipse" is popular for people doing Java.
API I'm not even going to Google what the initials stand for - it's just one of terms you use. An API is a library and supporting software that will handle a certain task for your program as you write it. For example, a Graphics API will give you functions to call to draw circles and lines and squares on the screen, so you don't actually have to write the code to draw just the pixels that are inside the circle you want (that API may then call another, lower-level API responsible for actually coloring each pixel, so that the Graphics API doesn't have to worry about talking with the physical screen hardware)
Abstraction - the API discussion is a good segue to this... at the lowest level, a program is 1s and 0s representing physical electrical states in a transistor. But it's way too hard to write complex things in 1s and 0s, so people invented computer languages that group various operations for the 1s and 0s into more human-like commands. In other words, even though you're still pushing around 1s and 0s, a computer language lets you right at a "higher level of abstraction". The code of the art program showing a rough model of a picture of the atom is higher level of abstraction that than the code that draws the circle, is a higher level of abstraction than the code that tells each pixel to be plotted, is higher than the code that tells the screen to be a certain color at a certain point in a hardware refresh rate (or whatever the hell screens are doing these days)
Design Patterns - giving certain names to high level ways of doing things, so developers can better talk to each other about how they made their program do what it does. For instance, a "Factory Pattern" describes ways of creating program objects without knowing all the details of the object you want to make, just how you want to use it.
Asynchronous - Man, now we're getting fancy! "Asynchronous" means you've triggered something happening, but you're code is not waiting around for the result... it will get "called back" when the action finishes. If a program is Synchronous, sometimes everything in its little world freezes until the action is done... this can lead to poor UX (See above)
Scaling - writing software and setting up systems so they "scale" means making it so many users can use it at once. "Does it scale?" is an important question. Back in history, the site "Friendster" fell by the wayside in part because it couldn't handle all the people who wanted to use it at once, and more recently Healthcare.gov also had "scaling issues"
HOW TO LEARN THINGS
One question is about how to learn things, pick up technologies.
This can be a bit of a chicken-and-egg problem: often a company will hire for a knowledge of a specific technology, but often an environment like a job is the best place to learn by making something in the real world; so you need to know tech to get a job, and you need the job to teach you the tech. So in practice is you can get hired for other knowledge or general competency, and then pickup the technology there. Or, often a project will add a technology as it grows and discovers new problems with the tech stack emerge.
There are other methods as well. A popular suggestion is to start your own open-source project, put it on GitHub. Personally I think this is kind of big and intimidating, but then again it took me a long time to realize the open source software can as full as dodge-y code as the "professional" stuff.
Even though over the past 3 or 4 years I've moved into the front-end, in 2009 or so I was behind with the developments that were letting more and more exciting stuff happen in the browser itself. Something I found (though after I used the "get hired for basic competency, then push" trick) are the newsletters of Cooper Press, especially "Javascript Weekly". This comes to your email inbox and is a great way to keep your finger of the pulse of what's going on in the tech space.
As a side note, another development of the past half-decade is the emergence of "Stack Overflow" as the repository of answer to a million little tech questions. I mean, for over a decade, "I guess I'll Google the error message before beating my head against this" was a tremendous tool in every developer's arsenal, but more and more the most relevant results are at Stack Overflow. (But since you use Google to get there anyway, this is more an observation/prediction of what will happen to the new developer, rather than advice of where to go. Presumably said developer already knows about Google.)
There are also a lot of good tutorials out there, and courses by Stanford and other universities, and stuff like Code Academy. I don't have as much experience with these... I do know sometimes there's a large gap between that kind of simplified tutorial and "the real world", so I would say if one of these courses seems easy, it's probably not doing its job thoroughly enough.
LANGUAGES/ENVIRONMENTS
In general, there are 3 things that set languages apart from one another:
1. The syntax and basic rules of it. It's been demonstrated that any popular language is about as expressive and powerful as any other one, but there are enough small differences that lateral changes can be tough. (Also, a language switch ideally gives a new angle to your perspectives on coding in general.)
2. The libraries and frameworks that are popular for it. Now, every language ends up getting a TON of small frameworks-- often by aspiring coders trying the "start an open source project to learn and put on resume" trick. My advice is to avoid these, unless it's clear it REALL solves your problems... which leads me to a digression:
Another divide is in techies who like to build things from scratch vs finding a pre-existing library and using it. Sometimes this decision is referred to as "Make vs Buy" -- even if the "Buying" is something free, you might still be paying in terms of how the time spend to learn how to use the library properly.
PROS FOR BUY
- code is already written, duh!
- ideally code is well-tested by someone else, so you don't have to take on that cost either
- the cost of code is not just in the writing, but in the maintaining, and passing on to more people
PROS FOR MAKE
- writing code is fun (I think this one shows up to much for me)
- a prebuilt library solves your problem, sure, but probably 9 other problems you don't have. Therefore this is added cost in learning how to configure it.
- And when you DO configure it poorly (because lets face it, if you weren't under time pressure you're probably not in business), often it's tricky to debug, because the mistake you made is HERE, in the configuration file, but the reporting of the error is WAY OVER HERE, in the stack trace, and it's even odds if the problem will make sense to you, because the whole point of the Buy was to not understand the problem as deeply!
So, my biases tend to towards Make, but again I know some of that is just because coding is fun. When I do use a library, I have a strong preference for things that follow the Unix-like philosophy of "do one thing, and do it well", industry-leading platforms (like jQuery in the browser space), and things that are isolated libraries my code calls while still running the main program flow, vs advanced toolkits that are configured to manage the flow of execution.
BACK TO LANGUAGES
Disclaimer: these are just my rough opinions from a decade or two in the industry. I might be missing big things, either because of my own experience or just because I'm not good at sitting and thinking of comprehensive lists.
C/C++ - Popular with people do things on Linux, and low-level (close to the hardware) type stuff. My first university classes were in these, but the languages were so primitive at the time that my opinion is probably unfairly biased against them. But they were a good start for me, because C-like syntax (with curly braces used to set aside blocks, arguments to functions in parentheses, return statements from functions and semicolons to explicitly say where each line of command ends) has influenced many other languages, Java, Javascript, Objective-C, and many more.
Java - Probably the most Java opportunities are for writing serverside code for big companies that have relatively comfortable amounts of time to "do the engineering right" This is where I was for much of the first decade of the 2000s. I also use it for toys I write, using a specific IDE/toolkit called Processing (see http://processing.org/ that provides an IDE and an API for artists and students to make cool, interactive things.) Also, programming for Android devices (phones, tablets, etc) is mostly in Java.
Javascript - Javascript is kinda like Java just like Rootbeer is kinda like Beer. This language is often thought of in conjuction with HTML5, more on the below. For years, it was kind of looked down on as a toy language for doing little tricks in the web browser, but over time that became amazing stuff like Gmail and Google Maps - the browser does more of the work, and doesn't have to wait for the server to populate ever little bit of the page. These days, it often goes with jQuery, which is a powerful API for manipulating stuff in the webpage (sometimes called "The DOM", Document Object Model, meaning the objects that represent the webpage the person is looking at) and for sending messages back and forth to the server. (Sometimes that's called AJAX, an acronym involving the asynchronous (see above) nature of a browser not freezing up while waiting for the server, and the messages are in JSON, see below) Lately there's been a move towards also having Javascript be the language for the stuff on the server -- there the most popular toolkit seems to be node.js. (except for jQuery, all these cool javascript libraries call themselves something.js)
2016 Update: I've been showing this article to a few people trying to get into tech, and so I guess it behooves me to keep it a little up to date. So I'm saying, I'm stunned at how popular Angular.js has become- I've rambled about it at length, and I am still surprised people are willing to give up so much transparency and decoupling of view and model into what's going on for a bit of componentization and not having to read/write form data fields (I think Google's "endorsement" (not that they use it, but hey) gave it an edge even when more mature things like Ember and React came out while Angular was still struggling to reach 2.0 helped a lot)
2020 Update: "React" seems to have been winning a lot here, especially when paired with Redux. I'm happy, of the Ember/React/Angular set, React was my clear favorite.
TANGENT: XML vs JSON
When a browser talks to a server, or two computers talk to each other in general, they have to figure out how they're going to wrap up the data they want to send to each other. "XML" was popular in the early 2000s... it looks kind of like HTML (see below) and was very careful about labeling its fields so it was clear just what the data it carried meant. It was also generally a big pain in the ass. "JSON" is the new hotntess in a lot of ways... it's a very simple and easy to read way of including lists, and key-value-pairs, and lists of key-value-pairs etc, and is easy to work with. It also happens to be the way you'd setup any data in Javascript code.)
HTML5/CSS - this is a different thing than most of the "languages" in this list, because it's something you might write a webpage in, not a program. HTML has long been how you write webpages, it has all these <tags> that wrap around the text content of the page, and carry the references to other things like images that might be visible on the page. "HTML5" is a hip buzzword, and in part it means the HTML document should be JUST the content and a minimal amount of tags saying what it is, and most everything that makes it pretty and controls how it looks should be in separate CSS files... CSS is a set of commands for describing color, border, position, etc etc of things that are on the page... see CSS Zen Garden for a clear idea of how different you can make a page by keeping the HTML the same, but changing the CSS (and maybe more importantly the image files the CSS refers to)
Ruby on Rails/Python/node.js/PHP - I'm lumping these together, even though that reflects my own history of "things I think are cool but don't know much about". These languages (well, 2 of those are specific toolkit) are very cool and powerful ways of writing server code... very popular with those little San Francisco and Cambridge and New York startups. It used to be COBOL was the way old business language (that you could still make a living on, especially around Y2K) and Java was young and hot, but now these are to Java what Java was to COBOL.) PHP is a little older and clunkier than the others, but still gets some play.
Perl - just like the Javascript section was bigger than the "hip server language" section because that's where my heads at these days, Perl gets a mention more because of what it meant to me than the industry right now. (Though I've heard it's making a revival in Japan, of all places.) Perl is a weird language that borrowed a lot of syntax and style from various languages, all Unix-based. When I came to it from C, however, it was a revelation. It taught me (and I'm listing these as things a new programmer should know a bit about):
- Maps - these are the key-value pairs I mentioned before, a way of linking data with what it means. You give me the key "first name" I give you the value "Kirk", you give me the key "city" i give you the value "Arlington". This is a simple but powerful idea that shows up again and again in computer land.
- Strings - the C I was learning didn't have these in as easy a way. A "String" is just any bunch of text.
- Regular Expressions - a fancy way of breaking up a string and analyzing it. For example you might have a regular expression for currency, that would say "yes" to "4.33" or "$8" or "$1,121,55" and "no" to "$SK.SA" or "121.86.32"
- Memory Management - this is less of an issue than it used to be, but in some languages if you start using a piece of memory, you also have to let go of it when you're done, or else the computer program holds onto it forever. (This is called a memory leak.) Many programs take care of this for you, and as you gain experience as a programmer you'll learn when you have to pay attention it or when you can ignore it.
Perl is supergood at handling giant hunks of text files efficiently, and some use for it has come up in every job I've had.
Objective C - the kind of unusual language Apple uses. Used almost only by people who write stuff that runs on a Mac or iOS device, but that last group has EXPLODED in numbers over the last half-decade. Generally with the XCode IDE.
.Net/C# - This is to Microsoft what Objective C is to Apple. There is a LOT of businesses out there that code with stuff, they have some excellent certification classes so if you have the time and money to go through with that, you can absolutely get a good foot up and start a career that way. (Again, I'm not writing more about it because I've had less experience here.)
SQL - a popular language for interacting with databases in, each platform (Oracle / Postgres / MySQL / Miscrosoft Sequel Server ) has its own flavor. You should also be aware that there's a NoSQL movement of ways of storing data permanently that follow different patterns than SQL's Relational Database model (all these multiple, excel-like tables connected to each other via keys)
2020 Update: I don't know where to put this in, but some other languages/systems that are popular include Hibernate, which is a way of putting data in databases, Kafka, which is passing messages around a bunch of servers, so that the whole system can handle much more load, and then containerization is a big thing... when you're doing stuff on the cloud, you're making these little virtual computers on the rented big server...
SO IN CONCLUSION
This might be a work-in-progress that I will come back to, and I welcome feedback from experienced coders and aspiring newbies alike. What do you wish someone told you when you were starting out? Let me know and I'll add it here.
chrome on osx: remove specific sites from autocomplete
No, not because I don't want people to see my love of "goatsdoingnaughtythings.com" when I start typing "google", but because now I was annoyed that "amazon.co.uk" kept showing up when I started typing "amazon" -- anyway, to remove an autosuggestion on OSX chrome, make sure it's highlighted in the list and hit fn-shift-delete.
Monday, November 4, 2013
ajax without jquery
If you just want to make Ajax calls, including jQuery can be a little heavy handed.
Here is some code I munged from this Stackoverflow question. I embedded it in the singleton we used in the global namespace (here represented by "Wrapper") and fiddled with the function signatures and location of the JSON parsing/stringify-ing 'til it matched my expectations.
Wrapper = {}; // this is just a stand in for our main singleton
Wrapper.ajax = {};
Wrapper.ajax.x = function() {
try {
return new ActiveXObject('Msxml2.XMLHTTP')
} catch (e1) {
try {
return new ActiveXObject('Microsoft.XMLHTTP')
} catch (e2) {
return new XMLHttpRequest()
}
}
};
Wrapper.ajax.send = function(url, method, data, callback, errcallback, sync) {
var x = Wrapper.ajax.x();
x.open(method, url, sync);
x.onreadystatechange = function() {
if (x.readyState == 4) {
if (x.status == 200) {
if(callback) callback(JSON.parse(x.responseText))
} else {
if(errcallback) errcallback(JSON.parse(x.responseText))
}
}
};
if (method == 'POST') {
x.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
}
if(data != undefined) data = JSON.stringify(data);
x.send(data)
};
Here is some code I munged from this Stackoverflow question. I embedded it in the singleton we used in the global namespace (here represented by "Wrapper") and fiddled with the function signatures and location of the JSON parsing/stringify-ing 'til it matched my expectations.
Wrapper = {}; // this is just a stand in for our main singleton
Wrapper.ajax = {};
Wrapper.ajax.x = function() {
try {
return new ActiveXObject('Msxml2.XMLHTTP')
} catch (e1) {
try {
return new ActiveXObject('Microsoft.XMLHTTP')
} catch (e2) {
return new XMLHttpRequest()
}
}
};
Wrapper.ajax.send = function(url, method, data, callback, errcallback, sync) {
var x = Wrapper.ajax.x();
x.open(method, url, sync);
x.onreadystatechange = function() {
if (x.readyState == 4) {
if (x.status == 200) {
if(callback) callback(JSON.parse(x.responseText))
} else {
if(errcallback) errcallback(JSON.parse(x.responseText))
}
}
};
if (method == 'POST') {
x.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
}
if(data != undefined) data = JSON.stringify(data);
x.send(data)
};
Friday, October 25, 2013
quick and dirty javascript sounds
I've written about HTML5 audio before, but the quickest/dirtiest way is:
var fx = document.createElement('audio');
fx.setAttribute('src', 'soundfile.mp3');
fx.setAttribute('loop', 'loop'); //optional
//...
fx.play();
var fx = document.createElement('audio');
fx.setAttribute('src', 'soundfile.mp3');
fx.setAttribute('loop', 'loop'); //optional
//...
fx.play();
//...
fx.pause();
non-looping and resetting variants are left as an exercise for the reader.
Thursday, October 10, 2013
the welcoming details of old macpaint
Making the rounds is CloudPaint, a fairly faithful reproduction of the old MacPaint that you can use in the browser!
MacPaint really set the model most paint programs would use, especially the toolboxes. "Zoom" was relegated to a "FatBits", an option under "Goodies", rather than the magnifying glass used today, and there is only a hand to move to different parts of the image rather than scrollbars, but overall everything is quite recognizable and usable.
Folklore.org has the history of Bill Atkinson's creation of the program, including the "marching ants" style of showing area selection. The Computer History Museum also has a page about its development including a shot of its predecessor (it was based on a Lisa program called LisaSketch or SketchPad) before the toolboxes were added.
One lovely detail of the program is starting off with the big wide paintbrush selected-- it is so much more engaging than skritching out individual pixels with the pencil tool. (It also probably influenced the choice to use "hello." written in cursive for early promotional shots.) That kind of consideration to first user experience goes along way (especially with something as innovative of the Macintosh, which for many people was the first time they would have tried a computer mouse.)
Another fun thing is Painting and Filling with patterns. Once color came on the scene, these patterns sort of fell by the wayside, but there is something satisfying about seeing the swatch of area filled with a pattern that is fixed independent of the line used to draw it, almost like one is brushing a path of snow from a windshield and then seeing what is underneath.
I still haven't found a modern-day paint program with powerful features and an easy interface for OSX... Paint.NET for Windows was excellent in this regard. "Pixelmator" comes close, though has several annoyances (some of which I just found out were configurable settings, but overall it aims too high, UI-wise, trying to be Photoshop-Lite rather than MacPaint-Pro)
Folklore.org has the history of Bill Atkinson's creation of the program, including the "marching ants" style of showing area selection. The Computer History Museum also has a page about its development including a shot of its predecessor (it was based on a Lisa program called LisaSketch or SketchPad) before the toolboxes were added.
One lovely detail of the program is starting off with the big wide paintbrush selected-- it is so much more engaging than skritching out individual pixels with the pencil tool. (It also probably influenced the choice to use "hello." written in cursive for early promotional shots.) That kind of consideration to first user experience goes along way (especially with something as innovative of the Macintosh, which for many people was the first time they would have tried a computer mouse.)
Another fun thing is Painting and Filling with patterns. Once color came on the scene, these patterns sort of fell by the wayside, but there is something satisfying about seeing the swatch of area filled with a pattern that is fixed independent of the line used to draw it, almost like one is brushing a path of snow from a windshield and then seeing what is underneath.
I still haven't found a modern-day paint program with powerful features and an easy interface for OSX... Paint.NET for Windows was excellent in this regard. "Pixelmator" comes close, though has several annoyances (some of which I just found out were configurable settings, but overall it aims too high, UI-wise, trying to be Photoshop-Lite rather than MacPaint-Pro)
Tuesday, October 1, 2013
calling Ajax-derived telephone numbers in iOS javascript
Previously I mentioned a little demo iOS app that just wrapped a web widget. Part of the demo was to pull down a phone # from the server via an Ajax call and let the user try to dial it. This seemed to run afoul of Apple's "user initiated action" type of rules... my code worked if I triggered it from a button directly, but if I tried to make the call as the result of an Ajax call, no dice.
Problem was I was using
window.open('tel:######');
-- turns out doing
window.location = 'tel:######';
face no such restriction.
Phew! I was worried I was going to have to build a button and have the user press that one, too.
Monday, September 30, 2013
quick hit: minimal war building with ant
Sometimes I want a .war file but just with a few static files. While I have been known to use the hack of "zip the folder, rename it .war", that really requires a few extra files be inserted by hand into the folder (like META-INF etc) to do properly. Since I have ant on my system, I should use that.
If I have a folder of files, I just add this build.xml, and then typing ant makes me my "mything" war...
<project name="mything" default="build">
<target name="build">
<delete file="mything.war"/>
<war destfile="mything.war" needxmlfile="false">
<fileset dir=".">
<exclude name="build.xml"/>
<exclude name="mything.war"/>
</fileset>
</war>
</target>
</project>
That's about as simple as it can get and still be doing the right thing, I think.
If I have a folder of files, I just add this build.xml, and then typing ant makes me my "mything" war...
<project name="mything" default="build">
<target name="build">
<delete file="mything.war"/>
<war destfile="mything.war" needxmlfile="false">
<fileset dir=".">
<exclude name="build.xml"/>
<exclude name="mything.war"/>
</fileset>
</war>
</target>
</project>
That's about as simple as it can get and still be doing the right thing, I think.
Thursday, September 26, 2013
seeker and you shall finder
Something I had to look up "how did I do that again?" in my little toy/gamemaking: have an object that will gradually turn to a target.
I made a really pretty version of this in an art game called aRTSeroids which I cribbed for this entry...
It's easy enough to get a seeker to snap instantly to its target, just do atan2(deltaY,deltaX); -- figuring out "which direction should I turn to get my angle closer to it" is a little tricker.
I made a really pretty version of this in an art game called aRTSeroids which I cribbed for this entry...
It's easy enough to get a seeker to snap instantly to its target, just do atan2(deltaY,deltaX); -- figuring out "which direction should I turn to get my angle closer to it" is a little tricker.
You can see the source here. The seeker object has an x and y propery for its position on the screen, and then an a property with its current angle. It also has a MAXTURN that sets how far it can turn per click...
void seek(float rtx, float rty) { float dx = (rtx - x); float dy = ( rty - y);
//this trick seems to work to deal with the overlap.. //they consider the shortest path even if other side of screen if (abs(dx) > width/2) { dx *= -1.0; } if (abs(dy) > height/2) { dy *= -1.0; } float wantangle = atan2(dy, dx); float anglediff = (a - wantangle);
anglediff /= PI; //I prefer thinking in multiples of PI...
//this next bit catches the "runaround" if (anglediff > 1) { anglediff -= 2; } if (anglediff < -1) { anglediff += 2; } if (abs(anglediff) > .1) { //arbitrary value to ignore if (anglediff > 0) { a -= smaller(abs(anglediff*PI),MAXTURN); } else { a += smaller(abs(anglediff*PI),MAXTURN);; } //could just be MAXTURN if you don't mind oversteer } } }
float smaller(float a, float b){ if(a < b) return a; return b; }
The first trick is the "deal with the overlap". This is optional, but nice for games that feature screen wraparound-- (i.e. fly left, show up right)-- if you want to have definitive borders you can leave those lines out.
The next bit is just the hack I got to normalize the difference in the angle... esentially we try to make sure the difference between the angle it "wants" and where it is now is normalized between PI and -PI.
Finally, that smaller() code says it will either go MAXTURN or the difference in the angle. If it just went MAXTURN, it sometimes will do a little vibrate pattern as it overshoots the angle. (Come to think of it, I think that vibration is why I did that "arbitrary value to ignore")
Anyway, the code is a little clunky and weird but it works well, and should be useful to me in future projects.
quick and dirty iOS-web demos
If you're more experienced with html5 than xcode, or if you have another project need that means a mobile app is going to be primarily driven by a web view, http://conecode.com/news/2011/05/ios-tutorial-creating-a-web-view-uiwebview/ is very good.
Also, on the actual webpage, I built assuming for a width of 320px and had the following meta tags:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name = "format-detection" content = "telephone=no"/>
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width" />
<meta name="apple-mobile-web-app-capable" content="yes" />
So that's limited because it only works in iPhone portrait mode, but still, for a quick and dirty demo, not bad.
(For a quicker and dirtier demo of the idea: just add the webpage to the homescreen. When they start it up it will be in fullscreen, no-safari-random-widgets, and to the unaided eye looks about the same, except the icon will be a screenshot rather than something you can set.)
UPDATE: My buddy Jonathan Zaleski says
Also, on the actual webpage, I built assuming for a width of 320px and had the following meta tags:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name = "format-detection" content = "telephone=no"/>
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width" />
<meta name="apple-mobile-web-app-capable" content="yes" />
So that's limited because it only works in iPhone portrait mode, but still, for a quick and dirty demo, not bad.
(For a quicker and dirtier demo of the idea: just add the webpage to the homescreen. When they start it up it will be in fullscreen, no-safari-random-widgets, and to the unaided eye looks about the same, except the icon will be a screenshot rather than something you can set.)
UPDATE: My buddy Jonathan Zaleski says
You can control the home-screen icon w/ the following:
<link href="favicon.ico" rel="apple-touch-icon">
Good to know!
Wednesday, September 25, 2013
color schemes!
If you design things, and don't know a ton about color theory, you should know this exists:
Color Scheme Designer.
For example, I was given a logo, and was able to mockup some more attractive webpages by grabbing the hexcode for its background color and using one of the schemes from it. There's a science towards knowing what colors have compatible "feels", and then an art to making it all work together.
Color Scheme Designer.
For example, I was given a logo, and was able to mockup some more attractive webpages by grabbing the hexcode for its background color and using one of the schemes from it. There's a science towards knowing what colors have compatible "feels", and then an art to making it all work together.
Monday, September 23, 2013
quick and dirty "what will it look like in an iphone" mockup
<div style="background-image:url(iphone.png); width:396px; height:745px; position:relative;">
<iframe style="width:320px; height:460px; position:absolute; left:38px;top:145px; border:none;" src="http://kirk.is/"></iframe>
</div>
<iframe style="width:320px; height:460px; position:absolute; left:38px;top:145px; border:none;" src="http://kirk.is/"></iframe>
</div>
with this image:
The one problem is scrollbars will be visible. I mess around with scrolling="no", but that eliminates keyboard and mousewheel scrolling. I tried some other tricks but nothing really jelled.
(See also: http://www.responsinator.com/ )
(See also: http://www.responsinator.com/ )
Tuesday, September 17, 2013
two men enter, one man leaves (blast from the past)
(Just found something I wrote in 2004...) You know, I just thought of one major lack of Java, and to be fair, most C-derived programming languages: a function can have many input parameters but only one return value. That's a really odd asymmetry to have to put up with.
Perl, for example, handles it much better...it's no problem to write something like
($foo, $bar, $baz) = somefunction($a,$b,$c);
In Java, though, you'd have two ugly workarounds: create a wrapper object that contains each thing you want to return, or if the objects are complex, sometimes you can have the calling program create an object, pass it in, and let the called function fill in the blanks. (Kind of like Oracle's "INOUT" parameters.)
(Followup: since I wrote this in 2004, JSON has gained in popularity and influenced other languages too, so that returning or passing around a Map of key/value pairs is probably more acceptable than it used to be.)
Personally, I think this lack is something that provokes over use of Exceptions, which really do horrendous things to understanding a programs flow of execution.
Seriously, would it be so hard to add a syntax so something like this would work?
int foo;
String bar;
(foo,bar,String baz) = somefunction();
public int,String,String somefunction(){
return (5,"hey","ho");
}
Does anyone know if any of the other C-derived languages handle this case better? C# or any of that? I know they're hyper-conservative about adding this kind of structure to Java, since it breaks old compilers and what not. But still, it seems like one of those things that actually is pretty stupid and only around for legacy reasons but that everyone just kind of accepts.
Perl, for example, handles it much better...it's no problem to write something like
($foo, $bar, $baz) = somefunction($a,$b,$c);
In Java, though, you'd have two ugly workarounds: create a wrapper object that contains each thing you want to return, or if the objects are complex, sometimes you can have the calling program create an object, pass it in, and let the called function fill in the blanks. (Kind of like Oracle's "INOUT" parameters.)
(Followup: since I wrote this in 2004, JSON has gained in popularity and influenced other languages too, so that returning or passing around a Map of key/value pairs is probably more acceptable than it used to be.)
Personally, I think this lack is something that provokes over use of Exceptions, which really do horrendous things to understanding a programs flow of execution.
Seriously, would it be so hard to add a syntax so something like this would work?
int foo;
String bar;
(foo,bar,String baz) = somefunction();
public int,String,String somefunction(){
return (5,"hey","ho");
}
Does anyone know if any of the other C-derived languages handle this case better? C# or any of that? I know they're hyper-conservative about adding this kind of structure to Java, since it breaks old compilers and what not. But still, it seems like one of those things that actually is pretty stupid and only around for legacy reasons but that everyone just kind of accepts.
Thursday, September 12, 2013
gowen's interesting tip calculations
A program to calculate tips is classic, boring stuff, but my friend gowen has an interesting take on it: he requested an app that could help figure out the tip values that would result in "interesting" totals, like "43.21" or "33.33" or what have you.
tl;dr: see the bookmarklet-able result here.
I decided that I'd write a bookmarklet in Javascript as a prototype... this would allow for easy modifications and tweakings while still loadable on a portable device without going through an app store or any other flimflam. (Plus I'm a little lazy.)
I knew one basic rule: DO NO TRY TO DEAL WITH MONEY VALUES IN A FLOAT. Rounding errors are very likely to bite.
I had to throw away my first attempts at juggling currency because they were too complicated. I tried to store "dollars" and "cents" as separate parts of the same object, and then do all the math based on that... but stuff like negatives were going to get funky, and it was a pain in the butt.
A much easier system is to just store everything as cents and then translate to and from traditional "DDD.CC" notation.
So, with basic money wrangling down, I built an "interestingness detector" that would return what way a number was "interesting", or undefined if not. Here's what I decided was "interesting":
My first pass started from a minimum tip percentage and worked its way a penny at a time to a maximum tip percentage, printing out each one that met the criteria for interestingness. This generated too many values. I tweaked my loop so that it would only show the "first" interesting result for each type (i.e. one "even amount" value, one "palindrome" value, etc) but this was biased towards low tip amounts. I then made a loop that started with a base tip value, and then tried one cent more AND one cent less, then two cents more and two cents less, etc, and printed the first value for each interestness-type going either way, which keeps things closer to the target tip percentage.
So, the result was like this
Pretty geeky, huh?
Once that was set I made a bookmarket. At it's heart it's just wrapping the code in this block:
tl;dr: see the bookmarklet-able result here.
I decided that I'd write a bookmarklet in Javascript as a prototype... this would allow for easy modifications and tweakings while still loadable on a portable device without going through an app store or any other flimflam. (Plus I'm a little lazy.)
I knew one basic rule: DO NO TRY TO DEAL WITH MONEY VALUES IN A FLOAT. Rounding errors are very likely to bite.
I had to throw away my first attempts at juggling currency because they were too complicated. I tried to store "dollars" and "cents" as separate parts of the same object, and then do all the math based on that... but stuff like negatives were going to get funky, and it was a pain in the butt.
A much easier system is to just store everything as cents and then translate to and from traditional "DDD.CC" notation.
So, with basic money wrangling down, I built an "interestingness detector" that would return what way a number was "interesting", or undefined if not. Here's what I decided was "interesting":
- multiple of ten e.g. 40.00
- digit repeating e.g. 44.44
- ascending e.g. 45.67
- descending e.g. 43.21
- palindrome e.g. 43.34
- even amount e.g. 41.00
- repeated halves e.g. 43.43
My first pass started from a minimum tip percentage and worked its way a penny at a time to a maximum tip percentage, printing out each one that met the criteria for interestingness. This generated too many values. I tweaked my loop so that it would only show the "first" interesting result for each type (i.e. one "even amount" value, one "palindrome" value, etc) but this was biased towards low tip amounts. I then made a loop that started with a base tip value, and then tried one cent more AND one cent less, then two cents more and two cents less, etc, and printed the first value for each interestness-type going either way, which keeps things closer to the target tip percentage.
So, the result was like this
Pretty geeky, huh?
Once that was set I made a bookmarket. At it's heart it's just wrapping the code in this block:
javascript:(function(){
//code goes here
})();
this creates a "self-executing block", and any variables I made are scoped inside of it, and so won't interfere with the current page when the bookmarklet is called. I had that whole block as a standalone js file and provided instructions to copy and paste that as the URL of a bookmark. I also embeded it in the href="" of a link for more immediate satisfaction.
There might be a less clunky way of letting people make a bookmarklet, and I can't see a way of putting a link directly to the iOS homepage, say, like you can with normal sites, but this should do until I decide to make a real app.
Again, you can see the end result at alienbill.com.
Now updated to recognize PI as an interesting value, as well as sorting the results by generosity, and putting the numeric values into something like columns for readability...
Friday, August 30, 2013
make war, not love (for static content)
Updates have been sparse this summer! I guess some of that reflects the work I've been doing, a little less glamorously front-endy and sometimes more proprietary.
One project is using JBoss, which by nature is a bit less free-and-easy than the "here's the exploded war, just go edit the content!" defaults of Tomcat/Apache. I had a front end to deploy on it that was strictly static content.
The easiest way to make a .war for static content seems to be to have your static html etc in a directory, include an empty "WEB-INF" directory in that, and then (assuming "webclient" is both the name for the output file .war and the folder itself) from the directory above do:
jar cvf webclient.war -C webclient/ .
Simple enough.
I guess there may well be ways of getting JBoss to let you edit static content in place, but I didn't research them yet.
One project is using JBoss, which by nature is a bit less free-and-easy than the "here's the exploded war, just go edit the content!" defaults of Tomcat/Apache. I had a front end to deploy on it that was strictly static content.
The easiest way to make a .war for static content seems to be to have your static html etc in a directory, include an empty "WEB-INF" directory in that, and then (assuming "webclient" is both the name for the output file .war and the folder itself) from the directory above do:
jar cvf webclient.war -C webclient/ .
Simple enough.
I guess there may well be ways of getting JBoss to let you edit static content in place, but I didn't research them yet.
Sunday, August 4, 2013
PoMan3D: a simple 3d line engine for processing.js
Processingjs is amazing, the voodoo it pulls to get Java code running as Javascript is a wonder. The support for Processing's (already limited) 3D is wonky across browsers, so just for kicks I decided to go to the old fashioned ways of making lines in a kind of fakey-3D space.
Here is the result:
(Here is the source code)
All my engine can do is make lines in 3D space, centered at around an origin at 0,0,0, and rotateable at that origin on the X and Y axis (unlike some folks who do this stuff more seriously, I keep thinking of X and Y as being on the screen, and Z into the screen). It is optimized for working in a cube from -100,-100,-100 to 100,100,100
In setup() the code is:
PoMan3D pm3d;
pm3d = new PoMan3D(500, 500); //constructor given the screen size
Then, for every call of draw() :
pm3d.setScale(1.0); //optional call, 1 is default
pm3d.startDraw();
pm3d.rotateToMouse(); //convenience function, or call setRotateX()/setRotateY()
//add lines here
pm3d.endDraw();
There are two ways of adding lines: you can start a single endpoint (with x,y,z and color), and then add in a series of (x,y,z) points to make line segments. You can also just add a line with a color and two x,y,z endpoints:
pm3d.startLinePath(-100,-100,-100,BLACK);
pm3d.addToLinePath(100,-100,-100);
pm3d.addToLinePath(100,-100,100);
or
pm3d.add3Dline(-100, 100, -100, -100, -100, -100, BLACK);
So that's it... pretty easy. Besides rotating and scaling, its painting the line in "painter's order", i.e. back to front. It's not perfect, because it's taking the depth of an average of the endpoint, but in practice it's not terrible. It shouldn't be hard to put in polygons, or make stroke weight a bit smarter...
Anyway, here's the class:
class PoMan3D {
private float screenCenterX, screenCenterY;
private float scaler = 1.0;
private float rotateX,rotateY;
private ArrayList<scaledLine> linesToDraw;// = new ArrayList<scaledLine>();
PoMan3D(int w, int h) {
screenCenterX = w / 2;
screenCenterY = h / 2;
}
void rotateToMouse(){
setRotateX(map(mouseY,screenCenterX,height,0,-2*PI));
setRotateX(map(mouseX,screenCenterY,width,0,-2*PI));
}
void setRotateX(float a){
rotateX = a;
}
void setRotateY(float a){
rotateY = a;
}
void setScale(float s){
scaler = s;
}
void startDraw() {
linesToDraw = new ArrayList<scaledLine>();
}
void addScaledLine(scaledLine s) {
for (int i = 0; i < linesToDraw.size(); i++) {
scaledLine c = linesToDraw.get(i);
if (s.scaleval < c.scaleval) {
linesToDraw.add(i, s);
return;
}
}
linesToDraw.add(s);
}
void endDraw() {
pushMatrix();
translate(screenCenterX, screenCenterY);
for (scaledLine s : linesToDraw) {
stroke(s.c);
line(s.s1x, s.s1y, s.s2x, s.s2y);
}
popMatrix();
}
private float lastX, lastY, lastZ;
private color lastC;
void startLinePath(float x, float y, float z, color c) {
lastX = x;
lastY = y;
lastZ = z;
lastC = c;
}
void addToLinePath(float x, float y, float z) {
pm3d.add3Dline(lastX, lastY, lastZ, x, y, z, lastC);
lastX = x;
lastY = y;
lastZ = z;
}
void add3Dline(float x1, float y1, float z1, float x2, float y2, float z2, color c) {
float f1x = x1, f2x = x2, f1y = y1, f2y = y2, f1z = z1, f2z = z2;
f1x = rotation1(x1, z1, rotateY);
f2x = rotation1(x2, z2, rotateY);
f1z = rotation2(z1, x1, rotateY);
f2z = rotation2(z2, x2, rotateY);
f1y = rotation1(y1, f1z, rotateX);
f2y = rotation1(y2, f2z, rotateX);
f1z = rotation2(f1z, y1, rotateX);
f2z = rotation2(f2z, y2, rotateX);
float scale1 = map(f1z, -100, 100, .8 * scaler, 1.2 * scaler);
float scale2 = map(f2z, -100, 100, .8 * scaler, 1.2 * scaler);
f1x *= scale1;
f1y *= scale1;
f2x *= scale2;
f2y *= scale2;
addScaledLine(new scaledLine(f1x, f1y, f2x, f2y, scale1+scale2, c));
}
private float rotation1(float a, float b, float ang) {
return a*cos(ang) - b * sin(ang);
}
private float rotation2(float a, float b, float ang) {
return a*cos(ang) + b * sin(ang);
}
private class scaledLine {
float s1x, s2x, s1y, s2y, scaleval;
color c;
scaledLine(float ps1x, float ps1y, float ps2x, float ps2y, float pscale, color pc) {
c = pc;
s1x = ps1x;
s1y = ps1y;
s2x = ps2x;
s2y = ps2y;
scaleval = pscale;
}
void draw() {
color(c);
line(s1x, s1y, s2x, s2y);
}
}
}
Here is the result:
(Here is the source code)
All my engine can do is make lines in 3D space, centered at around an origin at 0,0,0, and rotateable at that origin on the X and Y axis (unlike some folks who do this stuff more seriously, I keep thinking of X and Y as being on the screen, and Z into the screen). It is optimized for working in a cube from -100,-100,-100 to 100,100,100
In setup() the code is:
PoMan3D pm3d;
pm3d = new PoMan3D(500, 500); //constructor given the screen size
Then, for every call of draw() :
pm3d.setScale(1.0); //optional call, 1 is default
pm3d.startDraw();
pm3d.rotateToMouse(); //convenience function, or call setRotateX()/setRotateY()
//add lines here
pm3d.endDraw();
There are two ways of adding lines: you can start a single endpoint (with x,y,z and color), and then add in a series of (x,y,z) points to make line segments. You can also just add a line with a color and two x,y,z endpoints:
pm3d.startLinePath(-100,-100,-100,BLACK);
pm3d.addToLinePath(100,-100,-100);
pm3d.addToLinePath(100,-100,100);
or
pm3d.add3Dline(-100, 100, -100, -100, -100, -100, BLACK);
So that's it... pretty easy. Besides rotating and scaling, its painting the line in "painter's order", i.e. back to front. It's not perfect, because it's taking the depth of an average of the endpoint, but in practice it's not terrible. It shouldn't be hard to put in polygons, or make stroke weight a bit smarter...
Anyway, here's the class:
class PoMan3D {
private float screenCenterX, screenCenterY;
private float scaler = 1.0;
private float rotateX,rotateY;
private ArrayList<scaledLine> linesToDraw;// = new ArrayList<scaledLine>();
PoMan3D(int w, int h) {
screenCenterX = w / 2;
screenCenterY = h / 2;
}
void rotateToMouse(){
setRotateX(map(mouseY,screenCenterX,height,0,-2*PI));
setRotateX(map(mouseX,screenCenterY,width,0,-2*PI));
}
void setRotateX(float a){
rotateX = a;
}
void setRotateY(float a){
rotateY = a;
}
void setScale(float s){
scaler = s;
}
void startDraw() {
linesToDraw = new ArrayList<scaledLine>();
}
void addScaledLine(scaledLine s) {
for (int i = 0; i < linesToDraw.size(); i++) {
scaledLine c = linesToDraw.get(i);
if (s.scaleval < c.scaleval) {
linesToDraw.add(i, s);
return;
}
}
linesToDraw.add(s);
}
void endDraw() {
pushMatrix();
translate(screenCenterX, screenCenterY);
for (scaledLine s : linesToDraw) {
stroke(s.c);
line(s.s1x, s.s1y, s.s2x, s.s2y);
}
popMatrix();
}
private float lastX, lastY, lastZ;
private color lastC;
void startLinePath(float x, float y, float z, color c) {
lastX = x;
lastY = y;
lastZ = z;
lastC = c;
}
void addToLinePath(float x, float y, float z) {
pm3d.add3Dline(lastX, lastY, lastZ, x, y, z, lastC);
lastX = x;
lastY = y;
lastZ = z;
}
void add3Dline(float x1, float y1, float z1, float x2, float y2, float z2, color c) {
float f1x = x1, f2x = x2, f1y = y1, f2y = y2, f1z = z1, f2z = z2;
f1x = rotation1(x1, z1, rotateY);
f2x = rotation1(x2, z2, rotateY);
f1z = rotation2(z1, x1, rotateY);
f2z = rotation2(z2, x2, rotateY);
f1y = rotation1(y1, f1z, rotateX);
f2y = rotation1(y2, f2z, rotateX);
f1z = rotation2(f1z, y1, rotateX);
f2z = rotation2(f2z, y2, rotateX);
float scale1 = map(f1z, -100, 100, .8 * scaler, 1.2 * scaler);
float scale2 = map(f2z, -100, 100, .8 * scaler, 1.2 * scaler);
f1x *= scale1;
f1y *= scale1;
f2x *= scale2;
f2y *= scale2;
addScaledLine(new scaledLine(f1x, f1y, f2x, f2y, scale1+scale2, c));
}
private float rotation1(float a, float b, float ang) {
return a*cos(ang) - b * sin(ang);
}
private float rotation2(float a, float b, float ang) {
return a*cos(ang) + b * sin(ang);
}
private class scaledLine {
float s1x, s2x, s1y, s2y, scaleval;
color c;
scaledLine(float ps1x, float ps1y, float ps2x, float ps2y, float pscale, color pc) {
c = pc;
s1x = ps1x;
s1y = ps1y;
s2x = ps2x;
s2y = ps2y;
scaleval = pscale;
}
void draw() {
color(c);
line(s1x, s1y, s2x, s2y);
}
}
}
Thursday, July 25, 2013
apps, native vs web and desktop vs mobile
A while back, someone on my twitter feed wondered about why people are always clamoring for standalone native apps on mobile, but on their PCs (OSX or Windows) it's difficult to get them to download an application.
I've been having the thought roll around in my brain a bit, and I've come up with two ideas:
1. Mobile apps provide a safe, sandboxed environment, and pages of attractive icons on mobile still have a bit of a UX zing in a way a desktop or laptop doesn't. Plus, I think Windows gave the idea of downloading software a bad reputation; especially the bundling of additional promotional crapware.
2. Mobile devices are much more personal than PCs. People enjoy webapps because they get to them from home or work or at a friends computer etc, but a mobile device is on your person almost all of the time.
Ok, so that's not such rocket science, but still.
I've been having the thought roll around in my brain a bit, and I've come up with two ideas:
1. Mobile apps provide a safe, sandboxed environment, and pages of attractive icons on mobile still have a bit of a UX zing in a way a desktop or laptop doesn't. Plus, I think Windows gave the idea of downloading software a bad reputation; especially the bundling of additional promotional crapware.
2. Mobile devices are much more personal than PCs. People enjoy webapps because they get to them from home or work or at a friends computer etc, but a mobile device is on your person almost all of the time.
Ok, so that's not such rocket science, but still.
Friday, July 5, 2013
php 101 boilerplate
I grew up on Perl, especially for quick and dirty web things, and in general PHP didn't differentiate itself enough for me to switch. However, my team at work seems more comfortable with PHP, and actually PHP often has a lot of useful libraries baked-in that would me more of a pain to install on Perl.
But I always have to look up a ton of little things in PHP, so here is a trivial file editor in PHP that will show me some basic stuff like reading and writing a file, loading POST'd data, escaping HTML characters, catching errors, comparing strings, etc -- it even has a S00PER SEKRIT password function.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>admin</title>
</head>
<body>
<?php
$secretpassword = "test";
$pass = $_POST["pass"];
$contents = $_POST["contents"];
set_error_handler("customError");
if($pass != ""){
if($pass == $secretpassword){
if(file_put_contents("file.txt",$contents) !== FALSE){
echo "Wrote File";
}
} else {
echo "Incorrect Password";
}
}
$contents = htmlspecialchars(file_get_contents("file.txt"));
function customError($errno, $errstr) {
echo "<b>Error:</b> [$errno] $errstr";
}
?>
<form method="POST" action="admin.php">
<textarea ROWS="8" COLS="80" name="contents"><?php echo $contents ?></textarea>
<br/>
Password: <input type="password" name="pass"><br/>
<input type="submit" value="update file">
</body>
</html>
Ain't rocket science, but might save me a few minutes in the future.
Thursday, June 27, 2013
on human wrists and instagram
While TV and computer screens have moved from 4:3 to 16:9, the 1:1 square crop is going to be more important in amateur photography and video, in part because it's more natural and comfortable to hold a phone upright when taking photos and especially video, and because portrait-mode video looks a bit daft.
Wednesday, June 19, 2013
UI HALL OF SHAME: The Kindle App
Alright, this is less "hall of shame" and more "time for Kirk to gripe", but...
The Amazon Kindle application is pretty decent. One thing that bugs me though is it has no way of categorizing books... it just shows them as one big pile with few sort options. People have been asking for this feature for years, and it's present on the Desktop app and some of the physical devices, but for some reason Amazon doesn't think it's a worthy addition. (Personally, I don't want to obsessively sort stuff, just establish a "read this sometime" pile.)
Here's another thing: the app has a decent enough "progress bar" showing where you are in the book, but it's always the full, cover-to-cover content of the book. Some books have giant indexes or reference sections that no one is going to page through, but it still counts against the current progress. And the thing is, I know that the books have a concept of "beginning and end of the main content" because A. it annoyingly hops me to "page 1" when I open a new book, sometimes bypassing interesting covers and dedications and introductions and B. it also annoyingly pops up a "rate this book!" dialog when I finish the last page of the main content. (Again, I think the older devices handled this a little better, with little markers on the scrollbar showing where various chapters begin... better than the generic single-value scrollbar the apps use.)
As a developer, I try to have an understanding of the cost of features... nothing comes for free, sometimes there are hidden complications or competing factors, and everything takes development hours and QA, but still it's frustrating when the "bang for the buck" ratio seems pretty good and nothing is done.
The Amazon Kindle application is pretty decent. One thing that bugs me though is it has no way of categorizing books... it just shows them as one big pile with few sort options. People have been asking for this feature for years, and it's present on the Desktop app and some of the physical devices, but for some reason Amazon doesn't think it's a worthy addition. (Personally, I don't want to obsessively sort stuff, just establish a "read this sometime" pile.)
Here's another thing: the app has a decent enough "progress bar" showing where you are in the book, but it's always the full, cover-to-cover content of the book. Some books have giant indexes or reference sections that no one is going to page through, but it still counts against the current progress. And the thing is, I know that the books have a concept of "beginning and end of the main content" because A. it annoyingly hops me to "page 1" when I open a new book, sometimes bypassing interesting covers and dedications and introductions and B. it also annoyingly pops up a "rate this book!" dialog when I finish the last page of the main content. (Again, I think the older devices handled this a little better, with little markers on the scrollbar showing where various chapters begin... better than the generic single-value scrollbar the apps use.)
As a developer, I try to have an understanding of the cost of features... nothing comes for free, sometimes there are hidden complications or competing factors, and everything takes development hours and QA, but still it's frustrating when the "bang for the buck" ratio seems pretty good and nothing is done.
Tuesday, June 18, 2013
excellent high level analysis of what we are seeing in the iOS7 beta release
http://mattgemmell.com/2013/06/12/ios-7/ is a really excellent overview of what are the likely goals of the changes in iOS7
Sunday, June 16, 2013
online tool for IP fun: xip.io
I haven't quite figured out when it will be useful to me, but http://xip.io/ seems like a good idea... using DNS wildcarding, it lets a developer hit any IP as if it were a remote URL. I think this would be good for development where a script hitting "localhost" provokes different results than a remote server.
Thursday, June 13, 2013
quick thoughts on iOS7
FWIW, I rolled back to iOS6 after having the dev build of iOS7 on my iPhone for a day. It was nice having a peek into the future, and fun to see how the sausage is made at Apple, but not worth dealing with instability, at least not for my day-to-day phone. The two bugs that pushed me back were 1. The calendar view woud sometimes duplicate events to the next day. 2. I kinda rely on my smart, "recently added" playlist to be able to play in reverse chronological order, and for some reason iO7 would only do oldest first.
It was fun, though. One of my favorite features, relatively unheralded, was a written description of the upcoming day:
That really maps to how I think... written words can be skimmed and reviewed in a way that spoken words can't, and they are flexible and expressive in a way hieroglyphics and pictograms generally aren't.
On the other hand, on both the Calendar view there and in the new app, the day is written out in a very boring fashion. For people like me who have sparse calendars, like 1 or 2 hour-ed out events per day, it's foolish and annoying to have to scroll so much.
The old Palm Pre had a more clever idea:
What's happening there is long stretches of the day are visibly "accordioned" into a fix size. (Also on iOS7 the Calendar app didn't seem to have a "list view" that is conceptually kind of similar, though if hit the magnifying glass to do a search, before you entered terms you had something very much like the old list view.) Given some other Palm features iOS seems to be borrowing from (like the full screen thumbnails in the multitask view), it would be cool for them to grab this one as well.
One final nitpick, though this might just be a "growing pain" that will go away... here's the current iOS7 lock screen:
It says "slide to unlock" but... which way? The answer is "to the right". This feels absolutely backwards to me... often the first screen I see is the first page of the homescreen, and it has more screens to its right. Mentally, I would therefore place the lock screen "to the left" of the homescreens. With this arrangement, it seems like the second page of the homescreen and the lock screen occupy the "same space".
The reason why it's like that is explained by this iOS6 screen capture:
They've kept it the same, because either they don't share my mental modeling, they were lazy, or they thought people were so used to the old slider that they didn't need to tell people any more.
It was fun, though. One of my favorite features, relatively unheralded, was a written description of the upcoming day:
That really maps to how I think... written words can be skimmed and reviewed in a way that spoken words can't, and they are flexible and expressive in a way hieroglyphics and pictograms generally aren't.
On the other hand, on both the Calendar view there and in the new app, the day is written out in a very boring fashion. For people like me who have sparse calendars, like 1 or 2 hour-ed out events per day, it's foolish and annoying to have to scroll so much.
The old Palm Pre had a more clever idea:
What's happening there is long stretches of the day are visibly "accordioned" into a fix size. (Also on iOS7 the Calendar app didn't seem to have a "list view" that is conceptually kind of similar, though if hit the magnifying glass to do a search, before you entered terms you had something very much like the old list view.) Given some other Palm features iOS seems to be borrowing from (like the full screen thumbnails in the multitask view), it would be cool for them to grab this one as well.
One final nitpick, though this might just be a "growing pain" that will go away... here's the current iOS7 lock screen:
It says "slide to unlock" but... which way? The answer is "to the right". This feels absolutely backwards to me... often the first screen I see is the first page of the homescreen, and it has more screens to its right. Mentally, I would therefore place the lock screen "to the left" of the homescreens. With this arrangement, it seems like the second page of the homescreen and the lock screen occupy the "same space".
The reason why it's like that is explained by this iOS6 screen capture:
They've kept it the same, because either they don't share my mental modeling, they were lazy, or they thought people were so used to the old slider that they didn't need to tell people any more.
Subscribe to:
Posts (Atom)