fREWdiculous!
16 Apr
The end! Ok not quite. So this was the last day of the conference. It was shorter than the other days and most of us had to checkout anyway. Still exciting!
First off we got an awesome demo of the Designer. It looks like it will be extremely useful for exploring the framework and playing with layouts. You can edit multiple components at once, as if it were an IDE. You can even load data into grids on the designer. The bad news is that it looks like the Designer will be a service or an Air app that you buy. I understand the motivation behind that, but it’s still frustrating.
The next talk I went to was the Application Deployment talk. Very good information, but little of it was new to me. First off, Yahoo has written a lot of best practices for website performance. Take a look at those. YSlow is based on those and can tell you if you are following some of those best practices. YSlow 2.0 is in development and will be made of unicorn’s and rainbows. Typically you should skip your overall score and just look at the specific items. Gzip is good to use. Putting versions on your filenames can really help with performance (more on this later.) CSS should be in the header and as much JS as possible should be in the body. This will allow you to load basic JS and render the page before all of the JS is loaded. Minify your JS. ETags probably won’t actually help you unless you are huge.
Firebug network monitor is your friend. Fiddler (.NET app) can help for some esoteric things like file uploads or flash interaction that won’t show up in firebug. JSLint is an amazing tool that can help you write better code. Some of the people there wrote a Yahoo Widget that will automatically run JSLint on any files that have been changed. Very cool!
You should use parseInt(foo, 10) instead of just parseInt(foo). Why? Because parseInt defaults to octal.
JS Builder is a .NET app written by the ext people that will compress your javascript
files nicely. It can also be run from the CLI for batch usage.
CSS Sprite generation can significantly reduce your server pings. Also it can reduce images a lot due to boilerplate png stuff in icons (30%!) Use this to automate the process.
You need a favicon because browsers will always check for it. Be careful about giving it a big expire time because you cannot always just rename it as older browsers only check for favicon.ico.
And that was basically it! I didn’t go to the next session because we were way over time and I had to check out. In general I really enjoyed the conference and think I learned a lot from it. The only major problem I had was the Ritz stuff I mentioned before. Other things they did were really cool. For example: to ask questions in the panel you posted them online and you could vote them up and then they would answer the ones with the highest votes. This was good because people who talk really slow had less of a chance to slow us down etc. I think they should have given the field a max length, as too many words are just confusing anyway.
I give the conference 4.5/5 stars. Great in almost every way
16 Apr
Ok, the next session I went to on Day 2 was the session on Refactoring. Refactoring is one of the few high quality buzzwords that I hear regularly, so I was excited to hear what the talk would go over. It was very much Ext specific, but the final changes to the component that we “Extified” were amazing.
First off, what does it mean to Extify a component? The comp needs to fit into the Component Model, which is mostly a lifecycle issue. Typically this will be extending an existing component or creating a new one by inheriting from Component. Refactoring also involves clean code, consistent code, and hardest of all, documented code. And part of that which is fairly Ext specific is that the configuration should be elegant; or the config needs to be predictable and not have too many options.
Unfortunately this session was like drinking from a firehose, so I couldn’t take notes more than that. For the most part though it involved simple changes like moving view changes out of the component entirely and into CSS. Documentation should be done with ext-doc, which I look forward to setting up at work. Config option names need to be thought through carefully so that they match well with the rest of the framework. Other nice things that were done is to allow a store to be defined as a store, a store config, an array, or a store id. Keep your eyes peeled for the notes from this presentation. Should be excellent.
The next session I went to was another usability session. I am of the opinion that it’s hard to have too many of these. This session was a lot more hands-on, specific ideas than the other session.
His first recommendation was to show that background events are occurring. First go look at Forever21. Make your browser window 1024×768. Go to a product and add it to your cart. The part of the page that shows that the item has been added to the cart is not where you clicked, and probably isn’t even in view. Did anything happen? Is the page just going slow? Nope. You added it every time you clicked.
Now, on the other hand, check out this Ext sample. Note how when you use the menus messages pop up fairly unobtrusively. Also note that the time the messages are displayed can be increased and they can be set up to go away when the user clicks them. Much nicer!
In that same vein, try to avoid modal browser feedback as it freezes not just your whole app, but often the whole browser. Also avoid feedback about trivial events that the user does not care about. If at all possible, make actions easy to undo. For the actions that cannot be undone, warn your user.
Speed matters for all applications. There are some easy ways to make ext applications very snappy. Use xtypes possible as they allow for lazy instantiation on rendering. When waiting for the server, a basic load mask should be used for .5s or more. If it takes 5s or more, use a spinner or some other kind of progress indicator. If it takes more than 10s a real progress bar should be used. Note that real progress bars can still be faked by precalculating how long certain sets of data take.
The help tool for the title of a panel can be used for easy context sensitive help. In general the user shouldn’t need help, but it doesn’t hurt to make it available.
Also, your app should stay out of the user’s way. UI inconsistencies can confuse the user and slow them down. Try your best to be consistent across your application. I chimed in here to mention that we actually put UI standards in code by making classes to inherit from. That way you actually have to do more work to make a part of the application look different.
Labels and messages need to be well thought out. Don’t ever let a user see lorem ipsum or even just poorly worded text. Don’t be vague in your text (“invalid input” etc.) Maintain your tone (informal vs. formal style.)
Be careful about button placement. Ok/Cancel should always be in the same order. Ok should actually normally be a verb, like “Create” or “Destroy.” Also the cancel action should be demarcated somehow. A red icon works, or some people even go so far as to make the positive action a button and the negative action a link.
As you grow your application beware of making too much clutter. The example given in the talk was Google vs. iGoogle. Switching between the two is easy and you aren’t forced to use iGoogle at all.
You should favor clarity and predictability over cleverness and coolness. For example, the speaker mentioned making a wizard where a regular form made more sense. The form is easier for the user and less work to implement.
In general layouts should flow left-to-right, top-to-bottom. So more general things should come first in that ordering. And furthermore try not to make user interfaces extremely busy. A 40% data density is optimum. Again, try to keep your UI balanced.
The use of ellipsis (…) in menus to point out which commands bring up new dialogs is a good convention. Shortcut keys for menu commands should be underlined, and the shortcuts should be mentioned in tooltips as well. 10 or more items in a menu are too many. Use submenus etc. Often used items should be closer to the top of the menu. Often used commands should have icons, but too many icons can look cluttered.
Use grouping in grids to reduce clutter. Use cell renderers to highlight important information. In editable grids, make it clear which fields are not editable. As we all know, too many rows and columns is bad, even though every user everywhere wants it.
In forms you shouldn’t use check boxes for radio buttons and vice versa just because you prefer the appearance. That is very confusing for users.
Also with treepanels it’s a good idea to preserve tree state to save the users from having to open the sub trees all the time.
Next up was “Ask the Ext Team.” I learned a lot from this panel. First off, creating manager classes to decouple classes can help with complex interaction. Or you could use the new Ext 3 bubbling feature. Another really cool idea they mentioned was making your top level ns inherit Observable and make it a singleton, and then allow things to communicate through that. I *love* that idea.
LongPollingProvider can allow for Comet (faked push.)
Ext is corporately located in Tampa, but there are devs in DC, Australia, and other places.
Good places to learn about Ext are the wiki and the forums.
The Ext team recommends extending classes only when you are actually making your own functionality as opposed to just configuring a class. (I humbly disagree
) You do need to buy a new license to use Ext 3.
Component.mon is a replacement for on that does some memory management for you. The listeners config doesn’t use it, but it doesn’t have to.
Also interesting to note: the presenters actually used Ext for the slides. It was very cool and made very good sense for their use case.
HBox and VBox are really cool and will help with layouts immensely.
After that we all went out in the courtyard to talk. It was a lot fun to talk to some of the other devs. I even met a few that I ended up riding to the airport and eating with the next day
And that’s it for Day 2. Stay tuned for the exciting conclusion: Day 3!
15 Apr
Enjoy day 2:
First off was the Ext 3 Release. They gave some interesting history (Ext 1.0 was released exactly 2 years ago today!) And then mentioned a few features of Ext 3. Mainly it was about Ext.Direct and how it is a solution for communication to/from the server that is apparently a need in the community. I hope to use it myself; but we’ll have to see based on the spec. More on that later. As for the designer the plan is not only to make it visual but also reusable, which is pretty exciting for me.
Honestly I was a little disappointed with the release. A lot of time was spent on GWT, which is kinda cool, but only half of the people there could use it, and even less do. I was hoping for a Chuck style release with a button and hype. Oh well
The next thing that I went to was Dissecting Ext’s Signature Sample. The app was very cool. I really liked learning about the implementation details. Often I have found the quality of the examples lacking (see here, in particular this horrendous line: [var firstGridDropTargetEl = firstGrid.getView().el.dom.childNodes[0].childNodes[1];
]), and therefore not good enough to model an application after. Well, this example app was just rife with great examples of how to do things.
First off, the spoke about namespaces. That was pretty much the same as what we already all know.
Second, how about implementing your App object as a singleton? A good idea and makes perfect sense if I’d ever thought of it myself. I also happened to find out about the itemId/getComponent stuff here. Apparently it was around in Ext 2.2, but it wasn’t documented. The idea is that you can set an itemId property on an item, and then on the container you can call getComponent(‘itemId’) to find that item. It’s kinda like non-global ids. Too bad it was never documented… Now that we have Ext 3.0 there is an even better way though!
Before you had to do this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | Ext.ux.Foo = Ext.extend(Ext.Foo, { initComponent: function() { var this.foo = new Blah({...}); var config = { ... items: this.foo }; Ext.apply(this, Ext.apply(this.initialConfig, config)); Ext.ux.Foo.superclass.initComponent.apply(this,arguments); }, someFn: function() { this.foo.bar } }); |
Now you can do this:
1 2 3 4 5 6 7 8 9 10 11 12 13 | Ext.ux.Foo = Ext.extend(Ext.Foo, { initComponent: function() { var config = { ... items: {xtype: 'blah', ref: 'foo'} }; Ext.apply(this, Ext.apply(this.initialConfig, config)); Ext.ux.Foo.superclass.initComponent.apply(this,arguments); }, someFn: function() { this.foo.bar } }); |
That is pretty excellent right there!
They also mentioned some Ext style stuff. This should be done when you make your own classes. First you list your properties, then overridden methods, and then you end with new methods that are specific to the class. They also mentioned that all strings used in the class should be properties to allow for simple i18n. Nice to know. We also had some good talks about regular old (aka bizarre) javascript OO. Any complex variables defined in the properties (classes, maybe arrays too) are basically class variables. So they only get instantiated on load time and they are shared (for better or worse) by all objects of that type. This has caused issues for me in the past, but I can see where it would be good for performance reasons.
The Ext.DataView class could be excellent for the TemplatePanel that I have created. I have to look into it some more, but something to look at nonetheless.
Plugins basically are a method for doing Mixins with javascript. I won’t go into why mixins are a good thing. Just look it up. One way or another, this will really help make our classes of higher quality. As for ext 3, we can now use ptype (like xtype) for plugins, and Ext.preg (like Ext.reg) for registering plugins. Excellent!
Ext.Direct sounds like it could clear up a lot of our boilerplate code on the server side….maybe. Basically what it would do is expose choice methods from our model classes. So instead of making four line actions that find a specific model and return the json version of the model, it happens automatically with some configuration. Beside that stuff it also automatically batches queries. So if you load two stores on one page they should automatically be batches into one request and one response. Depending on how hard it ends up being on the server side it could be totally awesome.
Next we had another QA panel. I learned that Ext tends to be getting a foothold anywhere that it is used. Static ids are a bad idea (not news.) Use xtypes for lazy instantiation when you can. Creating usable components is a good idea. HTML is bad; use JSON and Templates instead. Singletons are good. To be an Ext superstar spend 4+ hours per day on the forums. All the Ext superstars are stoked about Ext.Direct. As established too many times already, people don’t test with Ext UI stuff. And lastly, most Ext apps are not public facing.
Next was User Experience Design with Ext JS. This talk was a big deal. There were tons of people there and it was a very solid presentation. I couldn’t take perfect notes because the slideshow and what the presenter said didn’t match up for the first few slides. I’ll just document what I understood.
First off, user experience is based on psychology; what your users expect etc.
Design is based on decisions and constraints. One perfect example was that in the hotel one of the presentation rooms was way too wide, so most people couldn’t see the screen. That was a decision, whether a conscious one or not. Constraints are based on technology, costs, etc.
Design is not art. Or in other words, there is a science to it. That doesn’t mean it’s not creative. Part of his point here was that design is not graphic design. In fact, he said that you could basically ditch graphic design and still have good applications if you still paid attention to User Experience design.
One tip he gave for User Experience Design was that you shouldn’t pretend to be your user, because you just can’t. Instead, pretend to be your app and ask yourself how you should interpret what the user is doing. Furthermore, you can’t really learn from users without actually watching them. This isn’t news to me, but it’s still great advice. We use GoToMeeting for this.
Another point was that it’s good to think of the user experience with the “Halloween Principle.” That is, imagine your user is a mother of three on Halloween. They are in the middle of something fairly complex and then trick or treaters ring the bell. The user gives them candy, goes back to the app, and has no idea what she was doing. Can she remember where she was based on the visual clues in your app?
Another interesting insight that the presenter gave is that if your app has no bugs and the user uses it, they will be happy (and probably rate your app 7/10.) If a user finds a bug and you don’t fix it, they will be upset, but probably blame themselves (3/10.) But the important thing is that if there is a bug, and you fix it immediately and give them very personal service, they will be extremely satisfied and even go out of their way to advocate you. I can give you an example of this. Last week I ran into a few bugs with Ext 3.0. I posted about them on the forums and two were fixed in 5 minutes and one was fixed in less than a day. I am extremely happy about that service and I really will tell people about that.
(This is going to be a long post…)
Next up is the idea of flow. Basically a user will be most effective when the difficulty of the things they are trying to do match up with their skill level. So if they are extremely skilled and doing very simple things, they will get bored and be unproductive. On the other hand it’s fairly obvious that if you have a very inexperienced user they won’t be able to do extremely complex tasks.
Also interesting: a lot of small features matter much more to users than one huge one. This one isn’t that hard to understand. Just think about small things in software you use that drives you crazy. And how often do you use that one amazing feature that they added?
WTFs per minute are a good metric for user interfaces.
Don’t fall in love with your work because you need to be willing to throw it away.
Don’t “bend” (aka train) your users. Change the software so that it is more flexible. Part of that is that basically you need to be able to get to different parts of you software from numerous different angles. Think hotkeys, menubars, right click menus, etc.
Balance items on the screen so everything isn’t just on one side or the other.
Match your colors (use kuler for example.)
Align things. This will help your users when they look at different parts of your app.
Make things look 3-D. Your app should look like the user can touch it and the focused things are in the front and non focused are in the back, etc. See here for demos of the app the presenter made. Note: that is all ExtJS.
Ok, I have lots more to post, but it’s midnight and I have a conference to be at at 8:30 tomorrow. I’ll post the rest of my notes tomorrow. The sessions tomorrow end much sooner, so it shouldn’t be to much.
14 Apr
For the benefit of my memory, my coworkers, and the rest of the intarwub, I am posting my expanded notes on the Ext Conference 2009. They are supposed to put up slides and video, so hopefully blog posts won’t be a major resource, but we’ll see.
I must give my impressions of things only barely related to the conference before I get into real content though. We are at the Ritz-Carlton, which is nice. But it’s expensive and the amenities are not worth the price. First off, the wifi isn’t free. Oh wait, the wifi in your room actually is non existent. So you pay 10$ for 24 hours of tethered connection. The wifi in the conference is free, but guess what, no power plugs aside from the few ones near the wall! My boss said I could get the wifi and expense it, but it’s still really slow. Streaming music just doesn’t work. I am streaming music fine over my G1 instead and that’s fine. Wait, maybe I could listen to the music on the cable TV! Oh wait… that costs too.
On another note, the conference is attended by an extremely diverse crowd. I think it would be safe to say that half of the crowd is not native to the US. There are something like 4 or 5 women though, so not entirely heterogeneous.
So with that aside, real content:
First off Douglas Crockford (you know, the guy who invented JSON?) did a very generic presentation on the future of Javascript. It was fun and encouraging, but won’t really help us for a long time. Numerous times throughout the conference it has been mentioned that IE6 is still very much dominant. I am very happy that most of our customers can be convinced to use at least IE7. There was a lot of fun history in Crockford’s talk, but I’ll leave that out for brevity’s sake. The next version of JavaScript (ECMAScript 5) is supposed to improve on a lot of the features of JS.
Browser interoperability is supposed to get a lot better because the implementations (browsers) will not be making as many decisions. Many common practices will be codified as parts of the standard.
Security is supposed to be improved upon significantly. The use strict mode (see next section) will help with that. Also objects can be “hardened” where they cannot be changed after creation. Same with properties on objects. But the global (window) still exists.
The strict mode is going to be optional. You shouldn’t use it in cargo culted code as it will probably break your code. It removes a bunch of “bad” features and could theoretically give better performance.
Some syntax has been relaxed. For example, if you do this in IE it will break: { class: ‘foo’ }. That is part of the spec and it is no longer an issue. Better yet, trailing commas are to be allowed!
All kinds of functions are added to arrays, objects, and functions to make them easier to work with. My favorite of course is a built in map
Regexps are better, JSON parsing is built into the browser.
But of course, IE6, 7, and 8 will be around for a long time before we can use this stuff, so don’t get excited. Just look forward to the future.
After that happens security needs to be looked into significantly. The current model is insecure if you ever include things like ads from external sites. It seems that a lot of that can be taken care of with Caja though. Interesting!
The next session was What’s New in Ext 3. As we all already know there is the lightweight core. It’s like JQuery or Prototype in that it’s a toolkit for websites as opposed to applications. It’s a subset of Ext so you will be able to use it with existing knowledge. It is Open Source (kinda, MIT.) It is unobtrusive and small. It has a great API and an excellent manual.
We have the new ListView, which is like a grid, but way simpler, so much more performant. Instead of a monster like Grid which can do everything, you just add plugins to allow it to do more. This is not supposed to supplant Grid.
Charting is very cool and surprisingly easy. Interesting things about it is that if you have say, a grid that shares a store with a chart, editing a value in the grid and saving it to the store will automatically change it on the chart. Very exciting stuff. Based on YUI charts.
Group tabs are kinda cool, but I doubt we will be using them any time soon. You’ll have to look at examples to see what they are.
The row editor for grids looks very cool. I can see using that, but again, you’ll need to look at it to see what it is.
Buttons are way better than before. They are sizable, stylable, and most importantly, you can place them anywhere as they can participate in layout.
Toolbars are now real containers, so you can put more stuff in there. Awesome. This allows things like ribbons etc.
BufferedGridView is a way to get better performance out of a grid. It only renders the rows that are visible, so it can make showing large datasets much faster. The only drawback is that the rows must have a static height.
The Debug Console is basically a way to have firebug in IE. Very cool!
HBox and VBox will be replacing Column and Row Layouts respectively. They are very flexible.
Ext ARIA is a way to get accessibility in your ext apps. It is currently not complete. The way you use it is by adding another js file to your include list and it will override a bunch of ext things.
resetBodyCss is a cool way to get your vanilla CSS back when you want it. So all of Exts CSS resets go away when you use this on a given panel.
I also went to the Ext.Data session, but I didn’t take very good notes because I already knew most of it from Ext 2. The few things that I learned were that Field classes represent the specific parts of a Record. I hope to override the date field so that it defaults to our date format. There is also a convert function that can be specified in a field on a record. Imagine a renderer, but much more basic. I also learned that mapping allows for mapping to actual objects and not just records. For example, if a record looks like this: {name: ‘frew schmidt’, currentLocation: { x: 10.23343, y: 4.32325 }}, I could define a field like this: {name: ‘yLocation’, mapping: ‘currentLocation.y’}. I could see using that in the future.
I also went to the Back to the Basics session. Again, I only wrote down things I didn’t already know. So semicolons are optional in JS. Did you know that can cause bugs? Example:
1 2 3 | return { foo: 'bar' }; |
1 2 3 4 | return { foo: 'bar' }; |
The second fails because javascript assumes you forgot a semicolon and puts it there for you.
And: how to make a singleton in JS:
1 2 3 4 5 6 7 8 | var Foo = function() { var privateGlobalFoo = ...; return { getFoo: function() { return privateGlobalFoo } } }();// <-- note the parens. |
Basically the parens run the function and return the value into Foo. If you try to call Foo as a function it will fail. Neat!
And lastly, I went to Ext.util. This session was very packed with info, so I ended up just writing down classes that I didn’t already know about to look up later
My list was: Ext.KeyMap, Ext.KeyNav, Ext.Editor, and String.format.
Other things I took away from throughout the day: testing is just not done in ext for the most part. A lot of people want it, but it’s just not going to happen. Dynamically configured grids are not that unusual. Extremely large datasets are not that unusual. There are lots of .NET and Java users, a few PHP users, and very few perl users. Almost everyone uses JSON and almost no one uses XML. The whole Ext team uses Aptana and maybe one other editor. Ext Designer should come for 3.1. An Ext Marketplace for extensions is planned. Theming Ext 3 will be extremely easy compared to Ext 2. Dynamic loading should be much easier in the future, though probably not core.
I’ll post again tomorrow. Hope you enjoyed it!
4 Apr
We all know programmers who, when they need to copy/paste more than one thing, just use a temporary window to keep track of the copied data. Well vim has that feature solved.
First off, we have multiple copy/paste buffers, known as registers. So I can copy and paste three different things into three different registers. To copy a line to register a, use “ayy. Then to paste that line you would use “ap. So we have plenty of registers. It gets better! What if you want to copy a bunch of stuff into one register? Well, first I would clear it with :let @a = ”, but that’s not required. Anyway, you can add to a register by using “Ayy. This will copy the current line onto “a. So you can do this over and over to add to the “a register!
But that requires too much work. Yesterday I wanted to add all lines with the word “name” into “a. Here is how I can do that with one line: :g/name/y A.
Awesome!
1 Apr
So in the project we are doing at work right now the customer has a fairly old dataset. Old enough that it originally was impossible to properly capitalize all of your words. I do a search and get a list of customers:
1 2 3 4 5 | AMERICAN AIRLINES SOUTHWEST AIRLINES A.O.G. L3 COMMUNICATIONS ... |
Why are you yelling at me?! I want to say.
Yesterday I had 30 minutes left in the day and I figured that I might as well do something that would make me feel good. I decided to make a DBIC inflator that would fix this issue. The idea is that in your DBIC setup you don’t just have Core, but also +ACD::SillyString and then when you configure your columns this takes care of recapitalizing things. You just add silly_string => ‘title_case’ to your column definition and it will DWIM. Maybe eventually I’ll add support for sentences. Also after I clean it up I’d like to put it on CPAN. We’ll see!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | package ACD::SillyString; use strict; use warnings; use base qw/DBIx::Class/; __PACKAGE__->load_components(qw/InflateColumn/); sub register_column { my ($self, $column, $info, @rest) = @_; $self->next::method($column, $info, @rest); return unless defined($info->{silly_string}); my $type = lc $info->{silly_string}; if ($type eq 'title_case') { $self->inflate_column($column => { inflate => sub { my ($value, $obj) = @_; if ($value eq uc $value or $value eq lc $value) { $value =~ s/(\w)(\w+ ?)/\U$1\L$2/g; } return $value; } }); } } |
On thing that I really like about this code is that it only applies to strings which are all uppercase or all lowercase. That way if the customer does correctly capitalize things, or wants to change the way that the code is capitalized by the model, they can. It really makes everything look a lot more professional.
31 Mar
Until recently most of the work I have done with DBIC has been very basic. I made a lot of simple classes, done some basic searches, paginated, and that was more or less it. The only thing in there that is really a major change from vanilla DBI was the pagination. Oh the glory of automatic pagination!
Well, recently I have been doing more complex things, and let me tell you, it has been a joy!
First off, Wes told me about the idea of a TO_JSON method. What I had been doing previously was in the controller I would list the columns I wanted from a class when I turned it into JSON. This is fine for the simple case, when all you want is simple data; but what if you want the data from a related table? Not so great. So I decided to set up TO_JSON methods for all of the classes. Now we just use whatever that provides in the controller. Sometimes we return more data than we would have otherwise, but since we paginate to 25 records by default that hasn’t become a problem. That cut the controller code down by maybe 25%. That’s significant in my book!
And then there are complex searches. Here is a scenario I had yesterday: the customer wanted to search in table X, which is related to table Y, based on some criteria for Y. In DBI I would have had to define a join blah blah blah. Because I predefined the relationship from X to Y in the model class, this was my search:
1 2 3 4 5 |
That’s it for now, but I am sure this story is not over…
28 Mar
I’m sorry that I’ve neglected this blog so much the past couple of weeks. I will give excuses promptly, and then I will immediately follow that with another post that you will hopefully find of value
So I was fairly sick this week and that really killed my output. It’s hard to pursue what you love when you don’t even feel alive. Turns out a lot of my friends got sick around the same time, so I image that something is going around. The irony (tragic, according to Meriam-Webster) was that last week was also when we had decided to demo our customer’s product.
And that is a great segue into what this post is about: how we do demos for our customers.
We do a loose form of agile development at my company, mostly due to the lack of much organization or planning as a whole. In general I think this is a good thing. On the project I am working on we are trying to do something closer to SCRUM. We haven’t quite mastered it yet, but we are doing iterations and demos for our customers and Neil and I meet every day to talk about progress. I am not quite organized enough at this point to keep up with a burndown chart and I keep forgetting to even do anything with the bug tracker. We are getting there nonetheless.
The point of my digression there is that we do these demos for the customers, but instead of just showing them all of our features we try to take it a step further. Features are great, but if the program is hard to use it doesn’t matter.
So what we do is set up a GoToMeeting session, I explain how we are in the project timeline to make the guys with the money happy, and then we give control to whoever will be using the feature we have completed. We give them a few directives but no directions, or at least as few as possible.
Usually they figure stuff out, but it is interesting to see what they try, and that gives us a good idea of how they think. For example, yesterday we were demoing a user system with groups. The way you would add/remove groups from a user was to drag the groups from/to a couple of grids. Seems simple enough. But the user tried to drag available groups onto the user data instead of into the user’s groups.
So when I get the chance I will make it so that that works too. The other interesting thing is the following conventional wisdom: users don’t read directions. I know that’s true, but every now and then you think, “hey, this is something that’s not perfectly obvious, so let’s put a but of text in there to make it clear.” We put something like six words in this panel, and they were at 25pt font. Guess what? Even though they were on the panel that they explained, the user didn’t read them. I may or may not leave the words there, with the knowledge that they currently just clutter up the page.
There are numerous reasons to do demos this way. They give the customers a sound mind that everything isn’t just faked. We can see what we are doing wrong from a design perspective. The customer can raise objections about possible misunderstandings we may have had. And with a user base as small as we have, we are also training them in the new application piecemeal.
And it looks like I may have to put off that other post as I have a hot date now
Have a great weekend, and stick to your requirements!
21 Mar
Furr by Blitzen Trapper
is the Album of the Week. This post (as well as 2-3 others) should have been done earlier in the week, but I was a little swamped. Sorry if you were on the edge of your seat
So Furr has definitely been my favorite album this week. I can tell because Last.fm tells me I have listened to it ELEVEN TIMES in the past 7 days. I would describe the style as somewhere between Neko Case (indie country) and Bob Dylan. I have also seen the band compared to Neil Young as well.
Their style is also slightly erratic, with songs like Fire & Fast Bullets, which brings OK Go to mind, and then Gold For Bread which is more like older rock, but with weird noises in the song at some parts. Very intriguing music.
Factoid: both Furr and God & Suicide have been on the NBC show Chuck. You may not like that show, but it definitely has lots of indie music (whatever that means.)
I dig the lyrics. The first song that caught my ear, Furr, is about the transformation from man to wolf to man. And then we have Black River Killer:
Then I went to the river for to take a swim
You know that black river water is as black as sin
And I washed myself clean as a newborn babe
And then I picked up a rock for to sharpen my blade
Favorite songs: Furr, God & Suicide, Black River Killer, Fire & Fast Bullets, Saturday Nite, Gold For Bread.
Colors: Tan and Brown.
15 Mar
Hopefully everyone reading this blog knows the function map. Map maps one array onto another with a simple function. For example, if I had a list of names at my old school and I wanted a list of emails I could do something like this:
1 2 | my @names = ('frew schmidt', 'bob barr', ); # etc... my @emails = map { s/\s+//; "$_\@letu.edu" } @names; |
I think that’s pretty great. I thought it would be cool to reinvent the wheel and implement map in Perl 6. One of them will be implemented the typical way and the other will be the Perl 6 (as far as I can tell) way.
Here’s the obvious way:
1 2 3 4 5 6 7 8 9 10 | sub map1(Code $fn, @list) { my @new_list; for @list { @new_list.push($fn($_)); } return @new_list; } map1({ $_ * 2 },[ 1,2,3,4,5 ]).perl.say; map1(sub ($f) { $f + 2 },[ 1,2,3,4,5 ]).perl.say; |
Pretty simple. We make a new list; iterate over the original list and push the value returned from the code onto the new list. But look at how much we have to think about the new list! The important part is the operation, not the list, or at least that’s what I think.
With that in mind, map round 2:
1 2 3 4 5 6 7 8 9 10 | sub map2(Code $fn, @list) { gather { for @list { take $fn($_); } } } map2({ $_ ** 2 },[ 1,2,3,4,5 ]).perl.say; map2(sub ($f) { $f ** 2 },[ 1,2,3,4,5 ]).perl.say; |
Gather/take, as mentioned previously, abstracts the idea of creating a new list.
And as for a question that Sol mentioned previously about gather and take:
… is gather / take just syntactic sugar, or is it implementing lazy evaluation, or is it even opening up the possibility of threading?
I think that gather/take is really just a pretty syntax. I think that it depends on what is inside of your gather for what is possible. You could even iterate over the contents of a file inside of a gather, in which case I am sure you couldn’t do threads. I guess lazy evaluation is theoretically possible though… But that would depend both on what is inside of the gather and what uses it.