Scott Hanselman

Why isn't People-Centric UI Design taking off?

January 27, '14 Comments [86] Posted in Musings
Sponsored By

NOTE: This post is just speculation and brainstorming. I'm not a UX expert by any means, although I have worked in UI testing labs, run A/B tests, yada yada yada. I dabble. Also, I work for Microsoft, but on the Web and in Open Source. I use an iPhone. Those facts don't affect my ramblings here.

Screenshot from my Windows 3.1 Virtual MachineiPhone screenshot from Flickr User philozopher used under CC

I'm just a little disappointed that 30 years later (longer of course, if you consider Xerox Alto and before, but you get the idea) and we're still all looking at grids of icons. But not just icons, icons are great. It's that the icons still represent applications. Even on my iPhone or iPad I can't have an icon that represents a document. The closest I can get is to add a URL from Mobile Safari.

After Windows 3.1, Microsoft made a big deal about trying to say that Windows was a "document-centric operating system." OS/2 Warp did similarly, except object-centric, which was rather too meta for the average business user. Bear with me here, this is old news, but it was a big deal while we were living it. They kept pushing it up through Windows 98.

This document-centric approach is reflected in a number of Windows 98 features. For example, you can place new blank documents on the Desktop or in any folder window. You can access documents via the Documents menu on the Start menu. You can click a file icon and have its associated application open it, and you can define actions to be taken on a file and display those actions as options in the context menu

Today on the desktop we take all this for granted. Ubuntu, OS X, Windows all know (for the most part) how a document was created and let us open documents in associated programs. iOS is starting to get similar document-centric abilities, although it appears Open In is limited to 10 apps.

In Windows Phone and Windows 8+ I can pin People to the Start Screen. It's a killer feature that no one talks about. In fact, Nokia recently tweeted a screenshot of a 1080p Windows Phone (I've been testing the this last month myself) and I think they made a mistake here. Rather than pinning People, Faces, Groups, Friends, Family, Co-Workers, etc, they shrunk down a bunch of ordinarily good looking icons to their most unflattering to see how many they could fit on the screen.

(Plus they have 19 Updates pending, which I just find annoying.)

Here's mine next to theirs, just to contrast. Now, far be it from me to tell someone how to personalize their phone, I'm just trying to show that it doesn't have to be cartoonish.

What I'm really interested in is why do we, as humans, find App Centric interfaces more intuitive than People Centric ones?

Be5xQ4aCMAABrmy wp_ss_20140127_0006

The "story" around People Centric is that you don't think "go to twitter and tweet my friend" or "go to Skype and call my friend," instead you click a picture of your friend and then contact them in any possible way using any enlisted app from there.

For example, if I search my Windows machine for "Scott Guthrie" I get this (Scott is lousy about keeping his pictures up to date.)

image

You can see from here I can Email, Call, Facebook, Skype (if he had Skype), or get a map to his house. All his actual accounts, Twitter, Facebook, etc are linked into one Scott Guthrie Person.

Screenshot (56)

It works great on the phone, where I'm more likely to do more than just email. Note at the bottom there's a chain with a number showing that my wife has 6 accounts (Google, Hotmail, Facebook, Skype, etc) that are all linked into one Contact.

image

Folks that use Windows Phone mostly know about these features, and the hardcore users I know pin people to Start. On the desktop, though, I never see this. I wonder why. I am surprised that in a people focused world of social networks that elevating our friends, family and loved ones to be at least peers with notepad.exe would have happened by now.

What do you think, Dear Reader? Have you given this some thought in your interfaces?


Sponsor: Thanks to Red Gate for sponsoring Blog Feed this week! Want Easy release management? Deploy your SQL Server databases in a single, repeatable process with Red Gate's Deployment Manager. There's a free Starter edition, so get started now!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Introducing Windows Azure WebJobs

January 23, '14 Comments [42] Posted in Azure
Sponsored By

I'm currently running 16 web sites on Windows Azure. I have a few Virtual Machines, but I prefer to run things using "platform as a service" where I don't have to sweat the underlying Virtual Machine. That means, while I know I can run a Virtual Machine and put "cron" jobs on it, I'm less likely to because I don't want to mess with VMs or Worker Roles.

There are a few ways to run stuff on Azure, first, there's IAAS (Infrastructure as a Service) which is VMs. Then there's Cloud Applications (Cloud Services) where you can run anything in an Azure-managed VM. It's still a VM, but you have a lot of choice and can run Worker Roles and background stuff. However, there's a lot of ceremony if you just want to run your small "job" either on a regular basis or via a trigger.

Azure Explained in one Image

Looking at this differently, platform as a service is like having your hotel room fixed up daily, while VMs is more like managing a house yourself.

Azure Explained in one Image

 

As someone who likes to torch a hotel room as much as the next person, this is why I like Azure Web Sites (PAAS). You just deploy, and it's done. The VM is invisible and the site is always up.

However, there's not yet been a good solution under web sites for doing regular jobs and batch work in the background. Now Azure Web Sites support a thing  called "Azure WebJobs" to solve this problem simply.

Scaling a Command Line application with Azure WebJobs

When I want to do something simple - like resize some images - I'll either write a script or a small .NET application. Things do get complex though when you want to take something simple and do it n times. Scaling a command line app to the cloud often involves a lot of yak shaving.

Let's say I want to take this function that works fine at the command line and run it in the cloud at scale.

public static void SquishNewlyUploadedPNGs(Stream input, Stream output)
{
var quantizer = new WuQuantizer();
using (var bitmap = new Bitmap(input))
{
using (var quantized = quantizer.QuantizeImage(bitmap))
{
quantized.Save(output, ImageFormat.Png);
}
}
}

WebJobs aims to make developing, running, and scaling this easier. They are built into Azure Websites and run in the same VM as your Web Sites.

Here's some typical scenarios that would be great for the Windows Azure WebJobs SDK:

  • Image processing or other CPU-intensive work.
  • Queue processing.
  • RSS aggregation.
  • File maintenance, such as aggregating or cleaning up log files. 
  • Other long-running tasks that you want to run in a background thread, such as sending emails.

WebJobs are invoked in two different ways, either they are triggered or they are continuously running. Triggered jobs happen on a schedule or when some event happens and Continuous jobs basically run a while loop.

WebJobs are deployed by copying them to the right place in the file-system (or using a designated API which will do the same). The following file types are accepted as runnable scripts that can be used as a job:

  • .exe - .NET assemblies compiled with the WebJobs SDK
  • .cmd, .bat, .exe (using windows cmd)
  • .sh (using bash)
  • .php (using php)
  • .py (using python)
  • .js (using node)

After you deploy your WebJobs from the portal, you can start and stop jobs, delete them, upload jobs as ZIP files, etc. You've got full control.

A good thing to point out, though, is that Azure WebJobs are more than just scheduled scripts, you can also create WebJobs as .NET projects written in C# or whatever.

Making a WebJob out of a command line app with the Windows Azure WebJobs SDK

WebJobs can effectively take some command line C# application with a function and turn it into a scalable WebJob. I spoke about this over the last few years in presentations when it was codenamed "SimpleBatch." This lets you write a simple console app to, say, resize an image, then move it up to the cloud and resize millions. Jobs can be triggered by the appearance of new items on an Azure Queue, or by new binary Blobs showing up in Azure Storage.

NOTE: You don't have to use the WebJobs SDK with the WebJobs feature of Windows Azure Web Sites. As noted earlier, the WebJobs feature enables you to upload and run any executable or script, whether or not it uses the WebJobs SDK framework.

I wanted to make a Web Job that would losslessly squish PNGs as I upload them to Azure storage. When new PNGs show up, the job should automatically run on these new PNGs. This is easy as a Command Line app using the nQuant open source library as in the code above.

Now I'll add the WebJobs SDK NuGet package (it's prerelease) and Microsoft.WindowsAzure.Jobs namespace, then add [BlobInput] and [BlobOutput] attributes, then start the JobHost() from Main. That's it.

using Microsoft.WindowsAzure.Jobs;
using nQuant;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
JobHost host = new JobHost();
host.RunAndBlock();
}

public static void SquishNewlyUploadedPNGs(
[BlobInput("input/{name}")] Stream input,
[BlobOutput("output/{name}")] Stream output)
{
var quantizer = new WuQuantizer();
using (var bitmap = new Bitmap(input))
{
using (var quantized = quantizer.QuantizeImage(bitmap))
{
quantized.Save(output, ImageFormat.Png);
}
}

}
}
}

CONTEXT: Let's just step back and process this for a second. All I had to do was spin up the JobHost and set up a few attributes. Minimal ceremony for maximum results. My console app is now processing information from Azure blob storage without ever referencing the Azure Blob Storage API!

The function is automatically called when a new blob (in my case, a new PNG) shows up in the input container in storage and the Stream parameters are automatically
"bound" (like Model Binding) for me by the WebJobs SDK.

To deploy, I zip up my app and upload it from the WebJobs section of my existing Azure Website in the Portal.

image

Here it is in the Portal.

image

I'm setting mine to continuous, but it can also run on a detailed schedule:

12schdmonthsonpartweekdaysoccurences

I need my WebJob to be told about what Azure Storage account it's going to use, so from my Azure Web Site under the Connection Strings section I set up two strings, one for the AzureJobsRuntime (for logging) and one for AzureJobsData (what I'm accessing). 

image

For what I'm doing they are the same. The connection strings look like this:

DefaultEndpointsProtocol=https;AccountName=hanselstorage;AccountKey=3exLzmagickey

The key here came from Manage Access Keys in my storage account, here:

image

In my "Hanselstorage" Storage Container I made two areas, input and output. You can name yours whatever. You can also process from Queues, etc.

image

Now, going back to the code, look at the parameters to the Attributes I'm using:

public static void SquishNewlyUploadedPNGs(           
[BlobInput("input/{name}")] Stream input,
[BlobOutput("output/{name}")] Stream output)

There's the strings "input" and "output" pointing to specific containers in my Storage account. Again, the actual storage account (Hanselstorage) is part of the connection string. That lets you reuse WebJobs in multiple sites, just by changing the connection strings.

There is a link to get to the Azure Web Jobs Dashboard to the right of your job, but the format for the URL to access is this: https://YOURSITE.scm.azurewebsites.net/azurejobs. You'll need to enter your same credentials you've used for Azure deployment.

Once you've uploaded your job, you'll see the registered function(s) here:

image

I've installed the Azure SDK and can access my storage live within Visual Studio. You can also try 3rd party apps like Cloudberry Explorer. Here I've uploaded a file called scottha.png into the input container.

image

After a few minutes the SDK will process the new blob (Queues are faster, but blobs are checked every 10 minutes), the job will run and either succeed or fail. If your app throws an exception you'll actually see it in the Invocation Details part of the site.

image

Here's a successful one. You can see it worked (it squished) because of the number of input bytes and the number of output bytes.

image

You can see the full output of what happens in a WebJob within this Dashboard, or check the log files directly via FTP. For me, I can explore my output container in Azure Storage and download or use the now-squished images. Again, this can be used for any large job whether it be processing images, OCR, log file analysis, SQL server cleanup, whatever you can think of.

Azure WebJobs is in preview, so there will be bugs, changing documentation and updates to the SDK but the general idea is there and it's solid. I think you'll dig it.

Related Links


Sponsor: Big thanks to combit for sponsoring the blog feed this week! Enjoy feature-rich report designing: Discover the reporting tool of choice for thousands of developers. List & Label is an award-winning component with a royalty-free report designer. Free trial!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Yak Shaving Defined - I'll get that done, as soon as I shave this yak.

January 23, '14 Comments [23] Posted in Musings
Sponsored By

Un Yak - by Ludovic Hirlimann, used under Creative Commons http://flic.kr/p/ab5d1NI've used the term Yak Shaving for years. You're probably shaving yaks at work all the time and don't realize it.

The term was coined by Carlin J. Vieri, a Ph.D. at MIT back in the 90s.

Yak shaving is what you are doing when you're doing some stupid, fiddly little task that bears no obvious relationship to what you're supposed to be working on, but yet a chain of twelve causal relations links what you're doing to the original meta-task.

Phrased differently, yak shaving is all that stuff that you need to do to solve some problem.

Here's a task. "Hey, Scott, can you deploy that web site?

Ok, do I have access? No, gotta get it. Passwords? Deployment technique? Web Farm? Scaling how? Web framework not configured? Oh, what about the connection string?

"Hey, Scott, is that site deployed yet?"

"No, I'm still shaving this yak."

Yak photo by Ludovic Hirlimann used under Creative Commons

Programming in a nutshell

* Ren and Stimpy of course, were first, but it was used at MIT in the context of irritating technology ceremony.


Sponsor: Big thanks to combit for sponsoring the blog feed this week! Enjoy feature-rich report designing: Discover the reporting tool of choice for thousands of developers. List & Label is an award-winning component with a royalty-free report designer. Free trial!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Hanselman's Newsletter of Wonderful Things: December 17th, 2013

January 22, '14 Comments [8] Posted in Newsletter
Sponsored By

I have a "whenever I get around to doing it" Newsletter of Wonderful Things. Why a newsletter? I dunno. It seems more personal somehow. Fight me.

You can view all the previous newsletters here. You can sign up here to the Newsletter of Wonderful Thingsor just wait and get them some weeks later on the blog, which hopefully you have subscribed to. If you're signed up via email, you'll get all the goodness FIRST. I also encourage you to subscribe to my blog. You can also have all my blog posts delivered via email if you like.

Here's the last Newsletter from December. Subscribers get the new one first. ;)


Hi Interfriends,

Thanks again for signing up for this experiment. Here's some interesting things I've come upon this week. If you forwarded this (or if it was forwarded to you) a reminder: You can sign up at http://hanselman.com/newsletter and the archive of all previous Newsletters is here.

Remember, you get the newsletter here first. This one will be posted to the blog as an archive in a few weeks.

Scott Hanselman

(BTW, since you *love* email you can subscribe to my blog via email here: http://feeds.hanselman.com/ScottHanselman DO IT!)

P.P.S. You know you can forward this to your friends, right?


Sponsor: Big thanks to combit for sponsoring the blog feed this week! Enjoy feature-rich report designing: Discover the reporting tool of choice for thousands of developers. List & Label is an award-winning component with a royalty-free report designer. Free trial!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

How to display a QR code in ASP.NET and WPF

January 19, '14 Comments [26] Posted in ASP.NET | NuGetPOW | WPF
Sponsored By

qrcode.19303638I've half-jokingly said that there's never a good reason to use a QR Code. However, I'm working on an MVP (minimally viable product) for a small startup with Greg Shackles and we actually have a good reason to use one. We have a mobile device, a Web Site, and a Windows Application, and a QR Code is a pretty quick way to move data between the mobile device and the other applications without the mess of Bluetooth pairing.

As I mentioned, we display the QR code on an ASP.NET website, as well as within a Windows app that happens to be written in WPF. The iPhone app uses C# and Xamarin.

There's a great QR Code library called "ZXing" (Zebra Crossing) with ports in Java and also in C#. The C#/.NET one, ZXing.NET is a really fantastically well put together project with assemblies available for everything from .NET 2 to 4.5, Windows RT, Unity3D, Portable libraries and more. The site is filled with demo clients as well, although we didn't find one for ASP.NET or WPF. No matter, it's all just generating and showing PNGs.

I pulled in ZXing.NET from the NuGet package here, just install-package ZXing.Net.

How to display a QR code in ASP.NET

If you're generating a QR code with ASP.NET MVC, you'll have the page that the code lives on, but then you'll need to decide if you want to make an HTTP Handler that generates the graphic, like:

<img src="/path/to/httphandlerthatmakesQRcodepng">

or, you could take a different approach like we did, and embed the code in the HTML page itself.

Greg used an HTML Helper to output the entire image tag, including the inlined image, as in:

<img src="data:image/gif;base64,iVBORw0KG..." />            

Images in HTML directly as Data URIs are super fun and I think, often forgotten. If you show one to the average web dev they'll say "oh, ya...I knew about those, but never really used it." In fact, Data URIs have been around for a LONG time. Learn more about them at DataUrl.net.

Here's generating a QR Code within ASP.NET MVC from an HTML Helper:

public static class HtmlHelperExtensions
{
public static IHtmlString GenerateRelayQrCode(this HtmlHelper html, string groupName, int height = 250, int width = 250, int margin = 0)
{
var qrValue = "whatever data you want to put in here";
var barcodeWriter = new BarcodeWriter
{
Format = BarcodeFormat.QR_CODE,
Options = new EncodingOptions
{
Height = height,
Width = width,
Margin = margin
}
};

using (var bitmap = barcodeWriter.Write(qrValue))
using (var stream = new MemoryStream())
{
bitmap.Save(stream, ImageFormat.Gif);

var img = new TagBuilder("img");
img.MergeAttribute("alt", "your alt tag");
img.Attributes.Add("src", String.Format("data:image/gif;base64,{0}",
Convert.ToBase64String(stream.ToArray())));

return MvcHtmlString.Create(img.ToString(TagRenderMode.SelfClosing));
}
}
}

Nice and simple. The BarcodeWriter class within ZXing.NET does the hard work. We don't need to save our QR Code to disk, and because we're doing it inline from our HTML page via this helper, there's no need for a separate call to get the image. Also, the caching policy that we decide to use for the page applies to the image within, simplifying things vs. two calls.

How to display a QR code in WPF

Note: This code here may be wrong. I'm happy to hear your suggestion, Dear Reader, because I'm either missing something completely or there is no clear and clean way to get from a System.Drawing.Bitmap to a System.Windows.Media.imaging.BitmapImage. The little dance here with the saving to a MemoryStream, then moving into a BitmapImage (with the unintuitive but totally required setting of CacheOption as well) just sets off my Spideysense. It can't be right, although it works.

I'll update the post when/if a cleaner way is found.

See below for update!

First, the exact same BarcodeWriter usage from the ZXing.NET library.

var qrcode = new QRCodeWriter();
var qrValue = "your magic here";

var barcodeWriter = new BarcodeWriter
{
Format = BarcodeFormat.QR_CODE,
Options = new EncodingOptions
{
Height = 300,
Width = 300,
Margin = 1
}
};

using (var bitmap = barcodeWriter.Write(qrValue))
using (var stream = new MemoryStream())
{
bitmap.Save(stream, ImageFormat.Png);

BitmapImage bi = new BitmapImage();
bi.BeginInit();
stream.Seek(0, SeekOrigin.Begin);
bi.StreamSource = stream;
bi.CacheOption = BitmapCacheOption.OnLoad;
bi.EndInit();
QRCode.Source = bi; //A WPF Image control
}

Later, writing the Bitmap to a MemoryStream for manipulation, except in this case, we're putting the QR Code into the Source property of a WPF Image Control.

UPDATE: Thomas Levesque in the comments below suggests an extension within System.Windows.Interop (which explains me not finding it) called CreateBitmapSourceFromHBitmap. This still feels gross as it appears to requires a call to the native DeleteObject, but regardless, that's the price you pay I guess. It looks like this:

using (var bitmap = barcodeWriter.Write(qrValue))
{
var hbmp = bitmap.GetHbitmap();
try
{
var source = Imaging.CreateBitmapSourceFromHBitmap(hbmp, IntPtr.Zero, Int32Rect.Empty, System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
QRCode.Source = source;
}
finally
{
DeleteObject(hbmp);
}
}

It works well!


Sponsor: Big thanks to combit for sponsoring the blog feed this week! Enjoy feature-rich report designing: Discover the reporting tool of choice for thousands of developers. List & Label is an award-winning component with a royalty-free report designer. Free trial!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.