Designed to be used in the field, the program allows individuals to quickly describe their concerns about a friend or family member. Using an algorithm based on a meta analysis of existing literature of behavioral indicators of PTSD, the program returns an assessment summary suggesting actions steps to the user.
As the software development subcontractors for the project, our task was to develop an easy-to-use interface and workflow, then implement the expert system strategies necessary to provide accurate recommendations.
The project required us to build a desktop application that might also need to be used on the web, so we developed our tool in Adobe Air. After a few different iterations and focus group testing, we settled on a simple linear navigation structure – the right arrow moves you forward and the left arrow moves back.
It’s amazing how the best ideas usually turn out to be so simple.

Before getting to any specific questions, users are able to type their concerns into a text box (if they’re connected to the internet). This allows the user to express themselves right from the start, getting to the most important issues immediately.
It’s kind of like your doctor asking, “So, how are you feeling today?”.

Based on an extensive knowledgebase grounded in the literature, the unstructured text submitted by the user is analyzed for relevant content. Then, the program automatically answers any applicable multiple choice questions.
Of course, we show the user what questions were answered by their free-text entry and give them the opportunity to change their response.

Users continue through 4 sets of simple yes/no questions, things like: “Does your friend or relative seem to be distant or removed from others?” If they answer Yes, they must indicate the severity on a scale of 1 to 5. Users can answer as many or as few questions as they want.

Only 17 questions later (the entire process typically takes under 5 minutes), PAS provides a recommendation and explains which factors contributed to the assessment. While the feedback is not an official diagnosis, it give military personnel practical advice about how to respond, or what actions are appropriate.
Users can email the report to their supervisor, or save it to their computer for future reference. To ensure privacy issues don’t prevent someone from using the tool, none of the answers are stored.

The tool is simple to use and gives military personnel a quick, anonymous method of expressing their concerns and receiving advice.
Idea Works developers, Matt and Kara, did a fantastic job building a solid, user-friendly program and our friends at Lincoln are currently shopping it around to different groups. We hope to see widespread adoption soon.
For information about using the Peer Advising System, please contact the Center for Suicide Prevention Research and Studies at 573.681.5225 or CSPRS{at}lincoln{dot}edu.
]]>Canonical, the company behind the Linux distribution Ubuntu, has coined the term “paper cut” for these issues and is starting a new initiative called “One Hundred Paper Cuts.” The idea is that they want to find 100 small bugs or issues that users have to deal with, and fix them. And they mean really small. For example, a bug that fits the qualifications for the initiative would be a button in the user interface that might be just a little too small. You may not notice that you have trouble clicking on those buttons, but it’s going to subtly impact your experience with the software. Imagine hundreds of these tiny issues scattered throughout the system. Now, the software feels broken.
It’s hard to justify fixing the smaller bugs, they take time and don’t seem to be valuable. Nobody seems to want to fix them because they don’t really affect getting new customers. But, they will affect keeping them around.
Keep in mind that one paper cut may be annoying, but one hundred is fatal.
]]>Most people who work with or around websites or web applications are aware of the mantra “Tables shouldn’t be used in design,” but I don’t think all of them understand why. To explain, I’d point you to a practical example: http://www.csszengarden.com/
The css Zen Garden is a great way to look at the power of separating content from design. Every page in the collection uses the same simple HTML page but achieves very different organization and style using simple CSS.
This wouldn’t be possible if you didn’t separate your design from your content. Using tables for layout exactly breaks this rule. A giant table that wraps your content to achieve three columns commits your page to a life of three columns with no hope of changing. (It should go without saying that tables have their place and their use…for building tables.)
Definitions: Markup, Style and Layout
It’s important to have clear definitions about the three components of web design. Some others may vary slightly, but I like to think of them this way.
Markup groups and annotates your content. For example, if a phrase is a heading, it gets marked appropriately. If two or three paragraphs are all related, they get grouped. If you have notes sprinkled throughout, each of the notes gets annotated in a similar way.
Style breaths life into your content by adding color, typography, background gradients, etc.
Layout is what defines the organization of your page. For example, three columns or two? Where should the header go in relation to the content? What about the footer?
In Practice: HTML, CSS and …
For markup, HTML is your tool at hand. If you use markup wisely, your HTML can read really well (i.e. make sense to a human) and offer insight into what content is important or related.
CSS is the style tool. If you want your headings to be big, read, and bold, then this is where you do it.
Layout is where things get cloudy. We don’t have a layout language that is standard. This is where and why people disagree with the table mantra described earlier. Without a real layout language, designers are left to hack together their own solution with a combination of HTML and CSS.
The Answer: Layout
Some designers choose to go with tables for layout, but as pointed out earlier, this is a bad idea because it makes your page very inflexible. I prefer to go with floating DIVs, although I’ll gladly admit that side effects of this method include headaches, shortness of breath and nausea.
One solution that designers are turning to is CSS frameworks, which typically take the form of CSS grids. A few of the more popular ones are the 960 Grid System, Blueprint and the YUI Grids.
These grid systems aren’t the final answer, they’re really just clever designers doing the best they can with the tools they have available. (For example, to make design changes you still need to go searching through your markup to change classes.) But they do make layout easier in the absence of a real layout language.
]]>Dojo.data is a fantastic abstraction layer for data stores such as JSON and XML. Dojo.data provides a fetch method which works like a SQL select statement except that it’s asynchronous. Fetch is used by providing your query, a success callback, and a error callback. Once the query is completed the proper callback is called with the returned items. This asynchronous system works great in web applications, allowing the query to be run over the network in the background while not disrupting the user’s experience. This behavior is consistent with the fundamental principles of AJAX.
We, however, are not currently working on a web application. One of our projects has a desktop app component and we’re using Adobe Air and dojo to fulfill this requirement. An asynchronous fetch just doesn’t make sense while we’re doing our data processing. The first thing we tried was a Google search for “dojo.data fetch synchronous”. None of the results gave us information on how to make fetch synchronous, but the third link on that page does give some good information. In that post Nathan Toone explains why fetch is asynchronous and has this to say:
One of the more common questions that I’ve seen is “How can I make this call synchronous?” If you find yourself asking that, you should reexamine what you are trying to accomplish, and change your approach to be more asynchronous. You’ll gain a lot of performance benefits in the long run. Remember, dojo is an Ajax library – not an Sjax library.
But, as the Dalai Lama said, “Learn the rules so you know how to break them properly.” See how to make fetch synchronous after the jump.
How to make fetch synchronous
Fetch is synchronous because of a call to dojo.xhrGet in the method _fetchItems in dojo.data.ItemFileReadStore. As of dojo release 1.2.2 the call was at line 311.
Here is the code in question:
var getArgs = { url: self._jsonFileUrl, handleAs: "json-comment-optional", preventCache: this.urlPreventCache }; var getHandler = dojo.xhrGet(getArgs);
Dojo.xhrGet by default is asynchronous and returns a dojo.Deferred object. This dojo.Deferred object is the same object that is returned from the original call to fetch. Dojo.xhrGet has a synchronous mode, which is turned on simply be adding “sync: true” to the parameters as follows:
var getArgs = { url: self._jsonFileUrl, handleAs: "json-comment-optional", preventCache: this.urlPreventCache, sync: true }; var getHandler = dojo.xhrGet(getArgs);
Fetch will now be synchronous. It would be possible to make this an option to fetch, but we didn’t need this for our application so we didn’t bother.
The take away point is that if you know JavaScript and are familiar with dojo you shouldn’t be afraid of hacking on the dojo source. If you come up with something good you should consider submitting a patch to dojo and they might even include it in the next release.
]]>
Web application and desktop application development varies in a few ways. One of these ways is product release cycles. Adobe Photoshop, which has been around since 1988, has shipped only 14 times in the last 20 years. In contrast we’ve “shipped” or pushed code onto the web 15 times in the last 20 weeks.
This is due partly to the fact that we are a much smaller company and are much more agile in our development. But, this is also due to the fact that traditional development cycles emphasize phases. First there is design, then development, then bug fixes and finally the product is prepared for release, printed on discs, and shipped out to retailers. This last step is not a trivial one, once a product is shipped to retailers it isn’t feasible to add a new feature or bug fix and give it to all customers without shipping again.
With a web application it is possible to develop continuously. The traditional development cycles still exist, but on a per feature basis instead of per product. We don’t have to worry about shipping our product to retailers, we can give it directly to the customer through the web, and we can constantly update it.
There is one major drawback to continuous development however, the lack of parties, specifically release parties. I imagine it is not difficult to drum up excitement for a release when the last year of your life was dedicated to it. But how do you get people excited for version 3.0 when you just pushed version 2.99?
Answer: You have cake. And so, as we internally wrap up version 3.0 of SAGrader we celebrate with cake.
]]>Step 1. Determining Inheritance – Typically you’re going to be subclassing an existing widget, so naturally you’ll need to inherit from that widget. But there are several other widgets you may chose to inherit from.
Step 2. Writing the Code – Each widget has some pretty basic methods you’ll want to override or add to, check out the widget life cycle to learn about all of them.
Code examples are after the jump.
Basic skeleton of the js:
// The widget you are providing
dojo.provide("sagrader.widget.Awesome");
// anything you inherit from or use
dojo.require("dijit._Templated");
// needed for contained
dojo.require("dijit._Container");
// params: "name of widget", widgets inherited from, your code
dojo.declare( "sagrader.widget.Awesome", [ dijit._Contained, dijit._Templated ], {
// Your template, can also use templateString and just put it inline.
// If you are inheriting from a widget using templateString you'll
// need to set "templateString: null" in your widget
templatePath: dojo.moduleUrl("sagrader.widget", "templates/Awesome.html"),
// Your widget's attributes, correspond to attributes you set in the HTML
some_attribute: '',
heres_one_that_has_a_default: true,
myButtonWidget: null,
// called after the widget is created, typically used as an init function
postCreate: function(args, frag){
// You call a superclass method this way, "arguments" is important
this.inherited("postCreate", arguments);
console.info("I'm called as soon as I'm loaded!");
// myButton is in the template as a dojoAttachPoint
this.myButtonWidget = new dijit.form.Button( {value: "Click Me!"}, this.myButton);
// Connect the onClick from the button to a function called "buttonClick"
dojo.connect(this.myButtonWidget, "onClick", "buttonClick");
},
buttonClick: function() {
console.info("Click!");
}
});
Basic template
<div class="outer_div">
<style type="text/css">
// whatever css you want needs to be in this file
.outer_div {
color: green;
}
</style>
<div dojoAttachPoint="myButton"></div>
<span>${some_attribute}</span>
</div>
You have access to any dojoAttachPoint nodes in the js.
What you’ll put in your main HTML file
<script type="text/javascript">
dojo.require("sagrader.widget.Awesome");
</script>
<div dojoType="sagrader.widget.Awesome" some_attribute="Some Text">
</div>
“Some Text” will appear in the widget template as well as be accessible in the Javascript.
Hopefully that helps get you started, hit up the comments if you have any questions.
]]>Start with The Big Picture. You should begin training by giving an overview of the company and its projects and later climb down to specifics. Even though your employee will not vividly recall all the general information you give them about the vast array of tools and procedures you use, it’s still important to expose them early on. It is the foundation of their learning, and you can revisit The Big Picture before going into each new tool or area of information to be learned. It takes a lot of sleep to assimilate vast amounts of information to the point where it can be usefully applied.
You’re a team. If you are pointing out a mistake your trainee made, it is often better to say something like “It looks like we forgot to…” or “We accidentally put this in wrong…” This lowers both stress and anxiety and lets you share responsibility for their learning. Share credit for tasks completed with your trainee, even if you did most of the work. They are doing a lot of work by learning. Using these methods, confrontations are minimized, more issues are openly resolved, and enthusiasm and morale are maintained.
It’s OK to make plenty of mistakes. You’re going to mess up, type in the wrong thing, be lost for an example, or explain things in such a way to incite laughter from your coworkers. Don’t worry about it. They would be doing the same thing. It’s more important to admit that you are wrong as soon as you realize it, and work towards finding the correct solution. That’s the essence of your work–problem solving. You’re an expert at making mistakes and finding solutions, not perfectly reciting facts and procedures you already know. Plus, making mistakes in front of new employees will create an atmosphere for them where it’s okay to make mistakes as a part of creative problem solving.
Explain the same things over again and again. You should expect to do this and not get frustrated too easily. Be very patient. Make sure your employee knows it is OK to ask for an explanation of anything you are doing, even twice, thrice, or the umpteenth time. Having them take notes is good, but you can’t expect every piece of information to make it into the notebook, or be easily found and applied to the current situation.
Take a break. Have someone else take over training for a day or two so you can catch up on other pressing issues and recuperate. In part II of this article, we’ll explore some topics to help you along after those first few critical days of training. You will learn about increasing efficiency, preventing burnout, and transitioning your trainee into being a productive employee.
]]>But, in our experience it’s always better to hire someone smart, not simply someone who is familiar or skilled with the tools used. Programming languages and environments are just syntax. Understanding computer science concepts is the hard part.
You can teach almost anything to someone who’s willing to learn, and companies should be wary of requiring candidates to know specific language sets or tools. If you hire the right people they’ll learn, and you’ll be better off in the end.
We practice what we preach: We’ve recently hired two interns for this summer. One has beginner Perl experience and the other has none. But, we have confidence that they’ll learn, and that they’ll learn fast enough that we won’t be impacted negatively.
]]>