Windows 8 to 8.1 App Considerations: Screen Size

One of the most frequent questions/concerns I’m seeing in community is:  what application changes do I need to consider for Windows 8.1 development?   Is there anything I should be doing today in my Win8 apps to make it easy to move to 8.1 in the future? There’s a ton of great info that came out of the recent //build conference.  In my opinion, the main design consideration to take into account with applications in Win8.1 is to handle multiple screen sizes and states effectively.  Conceptually, this is nothing new:  when developing web applications or desktop apps, you have to assume the application will be viewed on a variety of form factors and handle the layout effectively. When Windows 8 first shipped, apps would run either full screen or in snapped view.  Further, the minimum resolution requirement were 1366x768, and snapped applications have a width of 320px and full height.  This simplified the design slightly, and as a result, many samples had code like the following (C#): private void Current_SizeChanged(object sender, Windows.UI.Core.WindowSizeChangedEventArgs e) { if (Windows.UI.ViewManagement.ApplicationView.Value == Windows.UI.ViewManagement.ApplicationViewState.Snapped) { //handle snapped view -- hide stuff, etc. } } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Here, we’re handling the screen size changed event and if the view is snapped, rearranging/hiding elements as necessary, or if it’s not snapped, doing something equally appropriate.  A far better approach, though, is to not worry about snapped view specifically, and simply return to the tried and true method of examining the current app dimensions and scaling appropriately.  In JavaScript, we can do something like: window.addEventListener("resize", handleResize); function handleResize(eventArgs) { var screenWidth = window.outerWidth; var screenHeight = window.outerHeight; if (screenWidth <= 320) { //should be snapped } //handle other combinations } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }   This is a far more flexible approach, and because Windows 8.1 will support a wider array of screen dimensions and snapped combinations, it’s just best to consider how your app will work at any given resolution.  Particularly for HTML/JS apps, it’s just smarter, too, as we don’t have to have any Win8 specific code and instead can leverage the same logic regardless of platform. To test your apps, I enjoy using ModernMix from Stardock.  ModernMix is a tool that allows you to run Windows 8 modern/store apps in a window on the desktop.   While you can also use the Windows Simulator to simulate different resolutions, ModernMix is lightweight and also allows you to instantly resize your apps, making it easier to test/debug screen and layout issues.  I like using it to debug non-screen issues, also, as it minimizes the flipping back/forth from desktop to full screen modern apps on a single monitor.  The simulator is still very useful for a variety of other scenarios, like screen rotation.  Disclosure: I paid for my own copy of ModernMix, and this is solely my opinion on its use as a tool for helping to build applications.  Use at your own risk. Effectively handling virtually any screen size is the best way to future proof an app.  You don’t necessarily have to handle every conceivable screen resolution – put the plumbing in place now to make it easier as the platform evolves.  You’ll be glad you did.

Compressing as Individual Files in Folder

Let’s see how long it takes Jim Christopher to jump in with a better PowerShell solution.  :) I had a directory full of .avi files that contains RAW, uncompressed data at 60fps from a camera (for astroimaging).   Even capturing just a few minutes of data amasses  over 10GB of data: No wonder my drive filled up so quickly.  For archiving the data, I wanted to zip each file into its own file, not into a folder.  Because I had about 50GB of videos to do, I wanted a simple cmd to do it for each folder.  This is pretty easy to do with 7-Zip.  Bring up a command prompt in the folder you’d want each file to be individually zipped:     Assuming you have 7-Zip installed in its default location, use a command like: for %I in ("*.avi") do "c:\Program Files\7-Zip\7z.exe" a "%I.zip" "%I" -mx=5 -mmt=4 –tzip   You’ll see the progress in the command prompt: You can, of course, tweak that as necessary.   This compresses each file nicely, now consuming about 1.6GB.    This is a handy way to zip up large number of files into individual archives!

Windows 8 Pop Up (and Under), Setting up Family PC Settings

The worst best part about being the Microsoft guru when a new OS ships is configuring PCs for family members.   In Windows 8, it’s a big relief that the new start screen makes things inherently more secure and less worrisome, but in desktop mode and since I have family members who haven’t upgraded yet, I get asked about pop ups and pop “under” windows all the time, and configuring family safety settings.  The challenge is striking a balance between stopping annoying popups while allowing desirable popups to be allowed through.  It’s a little bit like a smoke detector in a house: you want to work when there’s a fire, but not go off every time you snuff out a candle or burn the toast.  The first thing I do when setting up a new PC is that I configure all popups to open in a new tab.  This makes it easy to manage where a popup came from to keep things grouped, but also prevents popups from constantly getting above/under your space.   To do this, open the settings in IE: And on the Internet Options page, click Tabs: On the Tabs window, be sure to select “Always open pop-ups in new tab”: This way, even if you disable all pop up behavior, it’s still manageable.   For power users, the pop up settings page allows quite a bit of configuration: The default setting is medium, which works well in most situations however a few pop ups are occasionally possible – in particular, when the user clicks a link, and this is how many pop up/under windows are opened.    This setting allows pop up windows from sites in the trusted sites or local intranet zone. The high setting disables all pop ups, but can be overridden by holding CTRL+ALT when clicking a link.  This is great for power users, but too prohibitive for most casual users. The low setting is similar to the medium setting, except it allows all pop ups from secure SSL (https://) sites without requiring an explicit entry in the allowed sites section.  An entry into the allowed sites allows pop ups from those sites, regardless of the blocking level. Although I haven’t seen a document specific to Windows 8, for the true geek, there’s some good info on this MSDN page on the security zone templates. Family Safety The next most important thing, particularly for kids, is to configure family safety settings.  Seriously.  Don’t do this later, do it right now.  This can be done on earlier versions of Windows, but I’ll focus on Windows 8 here.   From either the control panel, search for family safety: Or, just start typing family safety on the start screen and select ‘settings’ on the search results: When configuring family safety, there are a ton of great options to balance exactly what the child is allowed to do: Most of these are pretty self explanatory, but the web filtering is likely most important: Out of the box, this is a great first step to making sure the content they see is not inappropriate.  When my daughter logs in and opens a web browser, she’ll see: Now, if I try to go to my blog, the content by default is blocked: If it’s a local account only, the parent must be present at the PC to give permission to view a site.  Otherwise, all of the accounts and permissions can be handled online – this is great for situations where I might not be around and can approve requests remotely. The other great part about this is the reporting and time limit features.   My daughter is fairly possessive of her PC, but I can monitor everything remotely without being too invasive, and set a curfew or other time limits.  So, there you have it.  Lots of configurability, but the most important aspect is allowing her to own her own PC without me worrying about inappropriate content.  It does take a small amount of setup, but it’s worth it.

Coding for Kids #3. Bugs!

In the first post, we introduced the problem.  We’re writing a program that solves the problem of finding 100 point words, where each letter in the word corresponds to its position in the alphabet (A=1, B=2, Z=26).  In the second post, we coded the basic solution that allows the user to enter a word, and we calculate the result. We have a bug, though, because we made the assumption that the letters passed in are lower case.  The word “automated” is a 100 point word, but “Automated” is displaying only 99 points, because the first “A” in the word isn’t getting recognized correctly.  Remember, in computer programming, we need to be precise. There are a couple of ways to solve this.  The first way will be to simply tack on extra if statements to deal with capital letters, like so: if (c == 'a') return 1; if (c == 'A') return 1; .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }But, we already decided this function isn’t all that efficient, and this doubles the number of if statements.  Fortunately, C#, and more specifically, the .NET Runtime that hosts the application, has a rich set of functionality in the base class libraries (that is, what’s “in the box”) that can do some typical work for us.   In this case, the string object contains a number of useful methods to convert the entire string to either upper or lower case characters. For example, we can modify the getWordValue function to something like this: 1: private int getWordValue(string theWord) 2: { 3: int wordValue = 0; 4:   5: foreach (char c in theWord.ToLower()) 6: { 7: wordValue += getCharacterValue(c); 8: } 9:   10: return wordValue; 11: } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Notice on line 5, we’re calling ToLower() on theWord, which converts the entire word to lower case characters.  If we rerun the application (F5) and try the word “automated” with a mix of characters, we’ll see we get the correct value: Even though we fixed the bug, our code is fragile.  What that means is that there are assumptions about the code that, if not corrected, will cause errors or unexpected behavior down the road.  For example, the getCharacterValue function still assumes the character is lower case, even though getWordValue anticipates that.  Sometimes, and especially in small projects, you just accept that the code is not ideal and move on.  Before we move on to reading files and finding 100 point words, let’s solve a couple of problems here in the code.   The first thing to understand is that computers store all data as 0’s and 1’s … called binary.  Each binary digit is called a bit, and 8 of those are called a byte.  The way computers translate those zeros and ones into a letter and words is through encoding.   Encoding is a standardized way to convert a binary number into a character.   Going through the ins and outs of encoding is worthy of a number of blog posts, but think of it like a map.  The computer sees a binary number like 01100001 – which happens to equal 97 decimal.   The computer has a character map that says the number 97 is equal to the letter ‘a’ (specifically the lower case ‘a’).   Without a character map, the computer has no way of knowing this is supposed to be an ‘a’.   As you might guess, the character map says the number 98 is equal to ‘b’, and so on, where ‘z’ is 122.   And while we’re at it, that character map also says ‘A’ (upper case) is 65, and ‘Z’ is 90.   These numbers have roots in a character encoding set known as ASCII, and it was convenient because all western characters could be represented in a single byte (more specifically, it could really be done with only 7 bits).  Today, it’s common for applications, and our runtime, to use Unicode – a more modern way to map the binary data to characters using extensible code points.  By extensible, it’s possible for Unicode to have code points that encompass virtually any number of languages. The point of the above, though, is that for English use, Unicode maintains compatibility with ASCII.  So, we can rely on those character numbers (65-90 for upper, and 97-122 for lower case) to tell us if we have an upper or lower case number.   Computers can process numbers _real_ fast, so instead of doing an evaluation of the character as we have been, let’s evaluate the number instead: 1: /// <summary> 2: /// Returns the value of a given character, where the 3: /// value is determined by its location in the alphabet. 4: /// (A or a = 1, B or b = 2, etc.). Case insensitive. 5: /// </summary> 6: /// <param name="c">The character to be evaluated.</param> 7: /// <returns>The numerical value of the character, 1-26.</returns> 8: private int getCharacterValue(char c) 9: { 10: //get the numerical/ASCII value of the letter 11: int charValue = (int)c; 12:   13: //if the character is an lower case letter a-z 14: if (charValue >= 97 && charValue <= 122) 15: { 16: return charValue - 96; 17: } 18:   19: //if the character is an UPPER case letter A-Z 20: if (charValue >= 65 && charValue <= 90) 21: { 22: return charValue - 64; 23: } 24:   25: //not an A-Z or a-z character, return 0 26: return 0; 27: } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } The first thing we’re doing on line 10 is creating a local variable, charValue, to hold the numerical value of the character, c, passed in.  (int)c is called a cast.   We know we have a character, but we want it represented as a number.  The cast allows us to do that.   We cast it to a variable (charValue) because it reads clearer and is more efficient than casting a char potentially many times over.  A word of warning:  you need to know what you’re doing when you cast.   It’s safe to cast a character as an int to get the numerical value, but when getting into more complicated scenarios, failed casts raise an exception which need to be handled (and exception handling outside the scope of this series).   In general, I wouldn’t recommend working with character values directly unless you really were sure of what is going on encoding-wise.  This is a good example of it being okay, because we have very specific rules and expectations, and the app is overall quite simple. Our if statements on line 14 and 20 look to see if the character’s numerical value falls in the given range.  The double ampersand (&&) is a logical AND operation so both conditions must be true for the if to evaluate to true.   If it’s a lower case letter, we simply return that value minus 96, which will give us a number of 1 to 26.   Same for the upper case, although we subtract 64 to get its value.  The code above is more concise, runs FAR faster (though, is _still_ not the best if can be), but it’s not quite as readable or obvious as to what it’s doing.  That’s where effective commenting comes in.  Notice, too, we solved the upper/lower case issue in a far better way – it’s not as fragile.   We do lose some flexibility, however – if the “game” changes and makes vowels worth double, for example, we’d have to go back to something else.  Also, notice we check for lower case characters first.  This is deliberate:  while it will handle either lower or upper case, if the characters passed in are more often than not lower case, we return the value and it’s one less if block that gets evaluated.   For the purposes of our program, it’s not significant except as an academic exercise in code optimization.  For now, we’ll call this “good enough” and move on to the next challenge:  finding words!

Coding for Kids #2. Code!

In my last post, I introduced the problem we’re trying to solve via an introductory computer program:  finding 100 point words where each letter of the alphabet corresponds to its place in the alphabet (A=1, B=2 … Z=26).  At this point, we’ve built the basic template for the app, but haven’t yet written any code.   It’s time to write some basic functions (or methods) that help solve this.  For coding veterans, remember – this initially is about solving the problem as a beginner and optimizing later.   When programming, it’s often easiest to work backwards – that is, the program flow is getting the user input, parsing it, then determining the value.   To write code to do this, it’s easiest to determine the value of a character first, working backwards.   So, let’s write a simple method that does this.   We’ll want a method that accepts a character, and returns an integer.  Within the code template established in the first post, add a method like this under the button click event handler: 1: private void btnCalculate_Click(object sender, EventArgs e) 2: { 3: 4: } 5:   6: /// <summary> 7: /// Returns the value of a given character, where the 8: /// value is determined by its location in the alphabet. 9: /// </summary> 10: /// <param name="c">The character to be evaluated.</param> 11: /// <returns>The numerical value of the character.</returns> 12: private int getCharacterValue(char c) 13: { 14: if (c == 'a') return 1; 15: if (c == 'b') return 2; 16: if (c == 'c') return 3; 17: // ... 18: if (c == 'z') return 26; 19:   20: return 0; 21: } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } The green text are comments.  Like the button method above it (that doesn’t do anything), our method is private (means it can only be used in this class), returns an integer (int), is called getCharacterValue, and accepts a character (char) we’ll just call c.  Normally, you’d want your variables, like c, to be clear names … such as firstName or dateOfBirth.  But for a simple character, it’s common to just use a single letter like this.  Remember, c is not “C” as in the letter of the alphabet – c is a variable that represents any possibly character.   All the code within the method must be encapsulated with curly braces { }.   Notice that we have a bunch of if statements.  An if statement evaluates a condition in parentheses.  If the condition is true, it executes the code that follows.    We could optionally execute multiple lines of code by putting it in curly braces, or include an else section.   The return command stops executing code, and returns the value if the function is true.  So, suppose that we do something like: int charValue = getCharacterValue('b'); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } The runtime (that is, what is executing our code) calls our getCharacterValue function passing in ‘b’.  We’re assigning the result of that call to an integer called charValue.   Logically, you know the result should be 2, and therefore, charValue should be 2.  If you were to follow the function as it executes, it would hit line 14 and see if the character is an ‘a’ … it’s not, so it keeps going.  It is a ‘b’, so it immediately stops executing and returns 2.   If the character passed in is ‘z’, you can see that it’s relatively inefficient.  We’re evaluating 26 if statements.   We’ll address that another time, but for now, it’ll do.   If it gets all the way to the end, we’ll return 0. My daughter asked me why we use 2 equal signs when comparing … such as c == ‘a’ … the short version is that one equal sign is assignment, whereas two is an evaluation.   Notice that in my one line sample code, we’re assigning charValue with a single equal sign.  That means we’re assigning the value of that function to our variable charValue.   Remember that computers need precise instructions, and so, in the if statements, we’re asking the runtime if these two things are the same – we’re asking it to evaluate.  We now have a method that determines the value of a single character … but what about an entire word?  Multiple characters in a computer program are called a string.   What we need to do is write another function that accepts a string, parses it for each character in the string, adding up the value of each character along the way.   To solve this, we need a variable to keep track of each character’s value.   We also need a way to look at each character in a string.  Fortunately, there’s an easy way to do that. 1: private int getWordValue(string theWord) 2: { 3: int wordValue = 0; 4:   5: foreach (char c in theWord) 6: { 7: wordValue += getCharacterValue(c); 8: } 9:   10: return wordValue; 11: } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } When our function is called, we’ll use a temporary variable called wordValue that we initially assign to zero.  Next we have a foreach statement.  A foreach is a fancy kind of loop.   There are different kinds of loops, with subtle advantages and disadvantages.  A foreach makes it easy to iterate over objects in a collection – in this case, characters in a string. What the foreach is saying is that for every character (called c) in theWord, execute the code in curly braces.  In that code block, we assign wordValue to itself plus the value of getCharacterValue of the current character in theWord.  (The += means ‘itself plus…’.)   If the word is “test”, the foreach code block is executed 4 times, the first time c is ‘t’, then ‘e’, then ‘s’, then ‘t’.  When that is done, wordValue should be the sum of each character’s value, so we’ll just return that. Now all we need to do is make it so when the button is clicked, we grab the value of the YourWord textbox, and display it in the WordValue textbox.  private void btnCalculate_Click(object sender, EventArgs e) { txtWordValue.Text = getWordValue(txtYourWord.Text).ToString(); } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } We can do this in one line of code in our button event handler.  First, one thing to know is that classes encapsulate functionality.  A TextBox is a class, as is our button.  We don’t have to worry about the inner workings of the textbox – such as how to draw the box, handle user input, etc.   The textbox contains a number of properties that can be accessed that make it easy for us to get or set the value of something within the class.  In the case of the textbox, it has a Text property that lets us get or set the value of the text in the textbox.  Properties are accessed by using a “.” – so, in the line above, we’re assigning the value of the Text property in the txtWordValue, and also reading the value of the Text property in the txtYourWord textbox. We call getWordValue, passing in the txtYourWord.Text value, which would be whatever the user types in the box.  Now, what’s that ToString()?   You’ll see ToString() a lot in C#.  Remember, with C# and many languages, you need to be very precise.  When getWordValue returns, what is it?  It’s an integer.  A whole number.  Computers deal with numbers differently and more simply than they do strings.   The Text property of the textbox gives you a string, and also expects a string if being assigned to.  We have a number.  So, in essence, calling ToString() turns, for example, the number 42 into the string “42”.  Let’s hit F5 and run the program.  Using the word “test”, we’ll see the following.  We’ll also try “automated” – an apropos 100 point word! Let’s not get too excited.  Let’s try it again, this time using the word “Automated” (notice the capital “A”): Our first bug.  We’ve barely written code and it’s already inefficient, buggy, etc.  The problem is that “A” is not the same as “a” … there are a number of ways to solve this, but we’ll look at those in part 3.    In the meantime, here’s the code for this version: Download VS12 Project

Coding for Kids #1. The Beginning.

My daughter, a 5th grader, has shown an occasional interest in programming but having so many frameworks and platforms available today is both a blessing and a curse.  I began to learn programming by hacking Maxit, Hunt the Wumpus, Adventure, and others.   There were no graphics, no internet, no multiplayer. I saw her doing working on something when it occurred to me this would be a fun afternoon project to solve via code.  She was looking for “dollar words” – words that added up to 100 points (or cents, I suppose) where each letter is worth their index in the alphabet (A=1, B=2, etc.). I really liked this problem because it’s something that can be solved iteratively, and bits can be optimized later for further instruction.  If you’re like me, you immediately start trying to figure out the most efficient way to map a given letter to a point value … simple if/then?  Regex?  Character code map?   Lots of options!  Immediately, in this type of routine, you can see the tradeoffs between simplicity, reuse, and speed. I decided to write this series to be approachable by non-programmers and newcomers, because it can be a lot of fun to solve with your kids!   If you’re already a programmer, some of this may seem rather basic, but then, so is the problem(s) we are solving and it’s a great way to get started. Step 1.  Assuming you have never coded before, you need to download a code editor.   These are typically called IDEs for Integrated Development Environment because it can do much more than just be a text editor.   While we could technically write code in notepad, an IDE is often preferred because it can help you be more productive by compiling code, allowing you to debug, catching errors, and can autocomplete items.  Visual Studio is a fantastic IDE, and there are a number of free versions for problems just like this called Visual Studio Express.    If you don’t have it, download it now.  For this project, we’ll create a simple desktop application, so you’ll need the VS2012 Express Desktop version. Step 2.  Before we even start coding, it’s helpful to be clear on the problem.   We want a program that gives us 100 point words based on the scoring method mentioned above.  Ideally, it would be great if it could give us ALL 100 point words in the English language.  With a computer, we need to be explicit, so we’d want them sorted alphabetically.   While we’re at it, wouldn’t it be nice to let the user tell the program to find words of a certain value?  Why not 200 point words? These are great ideas for future versions, but let’s start simple.  The user types in a word, and the program displays the value of that word. Step 3. Launch Visual Studio.  If it’s the first time you’re launch it, you’ll need to select a profile, such as “C# Development Settings.”  We’ll use C# to solve this problem.  C# is a programming language.   A fun exercise in the future would be to convert this to another language – it’s a good way to learn a new programming language. Once loaded, select File > New Project.  On the New Project window, you’ll see templates which act as starting points for many different kind of applications.  Your screen may look different from mine, but essentially, you’ll want to select, under the Visual C# tree, the Windows > Windows Forms Application template.   Give it any name you’d like – in this case, I chose 100PointWords (though, you’ll see later why this name is limiting): Let’s familiarize ourselves with the environment.  Click the picture below for a larger version: This is the IDE.  On the left side of the screen is the Toolbox.  If you don’t see the Toolbox, you can click the View menu and select Toolbox from the drop down.    The Form1 we see is the design surface.   The design surface allows us to drag and drop, resize, and otherwise visually manipulate our application.   On the right side of the screen is the Solution Explorer window.  Our solution can contain any number of individual projects – in this case, we have only one, our 100PointWords application.   Form1 is currently loaded. If you double click on the Form1 design surface, you’ll go from design view into code view.   This will open the Form1.cs file and display the code associated with our application: 1: namespace _100PointWords 2: { 3: public partial class Form1 : Form 4: { 5: public Form1() 6: { 7: InitializeComponent(); 8: } 9:   10: private void Form1_Load(object sender, EventArgs e) 11: { 12:   13: } 14: } 15: } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Not a whole lot of code yet.  A namespace is a container that encapsulates any number of classes typically at the project level.   A class is used as a container for a given object, like a form (in this case).   This is partial class.  Without getting into too many details, what this means is that the designer file and the code file will get combined at compile time into a single class.  This makes it easier for us to work on code here, and keep the design separate where we can drag and drop items visually. Step 4.  Now, let’s start dragging some controls from the toolbox onto our form.  Switch back to the design surface tab.   Take a look at the screenshot below: Now just drag and drop some labels, textboxes, and a button from the toolbox onto the design surface (just drag and drop!).   They can be moved with the mouse, or fine tuned with the arrow keys.  A label is just that – some text.  We’ll have one label say “Your Word:” and the other label say, “Word Value:”.   We’ll have two textboxes – the top one is where the user enters a word, and the bottom is where we’ll display the word value. On the lower right side of the screen, you’ll notice we have the properties window for the current textbox, called “txtYourWord” … if you don’t see the properties window, right click the top textbox and select Properties, as shown in the screenshot above. By default, the textbox will have a name like “textbox1” and the button will be “button1” … it’s helpful to change these to reflect their purpose, so in the properties window, change the top textbox to “txtYourWord” and the bottom to “txtWordValue”, and the button to “btnCalculate”.  For the button, you’ll change two values in the properties window:  the text, which should say, “Calculate!”, and the name, which is “btnCalculate.”  There are a LOT of properties in that properties window – don’t let it confuse you.  We can ignore everything except the name and text values.  While you’re there, update the labels to something like the screenshot above (“Your Word” and “Your Value”). For controls like textboxes, buttons, etc., it’s common to use an identifier like “txt” or “btn” in the name so that, in code, it’s easier to recognize we’re dealing with a textbox and a button.  (This is known as Hungarian notation in computer programming speak.) With the mouse over the button, double click the calculate button: And you should see, in the code file: What we’ve just done is wire up an event handler.    This is a fancy way of saying, “When the user clicks the Technorati Tags: beginner,code,c#,development button, run this piece of code.”  Which, as of right now, does nothing.   An event handler simply responds to some type of event – like a button click.  Events are happening all the time – when a key is pressed, the mouse is moved, etc.    Notice that this function, btnCalculate_Click, has a few declarations.  The first is that it’s private.  That means this function (or method) can only be called from within this class.  Void is the return value – in this case, we’re not returning anything, so the return type is void.   The items in parentheses are items passed into the method.  For our purposes, we can ignore these for now. Now, if you’re really curious, you can open up the designer code file (Form1.Designer.cs) and see that all double clicking the button did was add this line of code for you: this.btnCalculate.Click += new System.EventHandler(this.btnCalculate_Click); We won’t go any further into event handling here, but event handling is key to modern app development. Congratulations!  We have the program laid out and ready for code.   We’ve leveraged the design surface to build the look of our application, and now what we need to do is dive into some code to make it all happen.   Stay tuned for part 2!

Windows 8: Cannot Connect to Printer

I have a Canon MP830 USB printer hooked up to my always on workstation at home, and this is shared so that anyone in the house can use it to print.   I haven’t had any issues until trying to add the printer in Windows 8.  When I tried to add the network printer: It looks like the printer is being added ok, but then I would be given the dreaded 0x00000002 error: This is a driver issue.  But what I couldn’t quite understand is why.  The drivers were all 64 bit, it’s USB … and I’ve added other printers (since I travel around) without problem.   The first thing I tried to do is see if I could get the printer to work locally.  I plugged the USB cable into the Windows 8 laptop, and it worked right away: So, the driver is working locally.  I tried again to add it as a network printer, thinking maybe it would use the correct driver or somehow missing the correct the driver to use, but it failed again. The way I solved this was like so … and note, if the printer still won’t work when connected locally, this method won’t help: Navigate to the Control Panel –> Hardware –> Devices and Printers, and select Add a Printer. On the dialog that appears, select “The printer that I want isn’t listed” option: And then “Add a local printer or network printer with manual settings” option: Add a new local port: And in the dialog that pops up, enter the network path to the printer (host name, plus the printer share name): Now you’ll get to specify the driver to use.  Windows has already installed driver because I tested the printer locally first, so I can select it right away.  Otherwise, you’ll need a driver disk or can attempt to have Windows Update find it for you: And boom, printer added: So, why is this problem happening?  I received the same error on two different machines.   Fortunately because this was easily solved, I didn’t spend much time diving in.  But if I had to guess, I suspect the Win8 machine asks the server for a compatible driver, and an error occurs trying to negotiate.   Using this method essentially allows us to manually select the driver.

One Azure Web Role, Multiple Websites

Windows Azure has been capable of running multiple websites in a single web role for some time now, but I found myself recently in a situation with 2 separate Azure solutions and was looking to combine them to create a single deployment.   Just like in IIS, this is most often done via host headers, so requests coming in can be forwarded to the correct site. The Goal The fine folks at infragistics created a really cool Silverlight-based reporting dashboard for Worldmaps.  Until now, each was running as its own Azure hosted service: Options to consolidate included folding the code into the Worldmaps site, which would involve actual work, or converting the site to use IIS instead of the hostable web core (HWC), which was, originally, the only way to host Azure deployments prior to version 1.3 of the SDK.  Under IIS, host headers can be used to direct traffic to desired correct site. Preconsiderations Inside the ServiceDefinition file, the <sites> section is used to define the websites and virtual directories, like so: <Sites> <Site name="Web" physicalDirectory="..\WorldmapsSite"> <Bindings> <Binding name="HttpIn" endpointName="HttpIn" /> </Bindings> </Site> <Site name="Reporting" physicalDirectory="..\..\igWorldmaps\WorldmapsDemo.Web"> <Bindings> <Binding name="HttpIn" endpointName="HttpIn" hostHeader="reporting.myworldmaps.net" /> </Bindings> </Site></Sites> Nothing too crazy in there, but I’ll talk about the paths later. The first problem is that I was using webrole.cs file in the Worldmaps application, overriding the Run method to do some background work: public class WebRole : RoleEntryPoint{ public override void Run() { // I'm doing stuff! } } The Run method is called from a different thread, and it did a lot of background processing for the site (logging data, drawing maps, etc.).   This is a great technique, by the way, to add “workers” to your website.  This is, by itself, not a problem to do under IIS or HWC, except, under the HWC version, the thread runs in the same process.   I could write to an in-memory queue via the website, and process that queue in the webrole.cs without problem, provided the usual thread safety rules are obeyed.  Likewise, the worker could read/write to an in memory cache used by the website.  Under IIS, though, the site and role are in a separate process, so it wasn’t possible to do this without re-engineering things a bit.  You don’t need to worry about this if you aren’t doing anything “shared” in your webrole.cs file. Add the Project In my existing Worldmaps solution, I added the infragistics “WorldmapsRporting” project by adding the project to the solution (right click the solution, and choose Add Existing Project): Hook it Up The <sites> tag (seen above) is pretty self-explanatory as it defines each site in the deployment.  For the first and main site, I didn’t provide a host header because I want it respond to pretty much anything (www, etc.).  For the second site, I give it the reporting.myworldmaps.net host header.  Here’s the tricky part, which in retrospect seems so straightforward.  The physicalDirectory path is the path to the web project, relative to the Cloud project’s directory.   When I first created the Worldmaps solution (WorldmapsCloudApp4 is when I converted it .NET 4), I had the cloud project, the website itself, and a library project in the same directory, like so, with the cloud project highlighted: So, the path the WorldmapsSite is up one level.  To get to the infragistics website, it’s up to levels, the into the igWorldmaps folder and into the WorldmapsDemo.Web folder.  We can ignore the other folders.  DNS The project in Windows Azure is hosted at myworldmaps.cloudapp.net, as seen from the Azure dashboard: …but I own the myworldmaps.net domain.  In my DNS, I add the CNAMEs for both www and reporting, both pointing to the Azure myworldmaps.cloudapp.net URL (picture from my DNS dashboard, which will vary depending on who your DNS provider is): Testing Locally To test host headers on a local machine, you’d need to add the DNS names to your hosts file (C:\Windows\System32\drivers\etc\hosts) , like so: 127.0.0.1    myworldmaps.net 127.0.0.1    www.myworldmaps.net 127.0.0.1    reporting.myworldmaps.net Overall, a fairly straightforward and easy way to add existing websites to a single deployment.   It can save money and/or increase reliability by running multiple instances of the deployment. Links http://www.myworldmaps.net http://reporting.myworldmaps.net

Music Library Synchronization, Sonos Tips

I love Windows Home Server.   I’ve been using Windows Home Server for years, and just purchased a Windows Home Server 2011(WHS) box from Newegg (great deal on a HP Proliant micro server).  Many have asked me why I like WHS so much – it’s NAS, it’s a media server, it’s backup.   It’s a step up from a simple NAS device (although, admittedly, not as plug and play), offers more flexibility and is more cost effective than a Drobo.  A small backup agent can take snapshots of your PC, typically on a daily basis, so they can be restored to a given point in time.  I keep snapshots of my initial installation, for example.  Restoring to those backups is a simple process.  I’m also a big fan of Sonos, a whole-home music solution that works amazingly well.  What Sonos has done exceedingly well is blend quality hardware, quality software, and reasonable (but not cheap) price points.  I have an extensive music collection, and I point Sonos to a share on my WHS box to index and stream music.  However, I consider my laptop my “database of record” for my music.  It’s where I download stuff, and I take it with me because I’m often on the road.  The problem I run into is keeping my WHS library in sync with my laptop.   In my case, I want to mirror my library on the WHS exactly as it is on my local collection – and because I’m often reorganizing my collection, adding tags, etc., I need a simple way to do this.  Enter Robocopy.   Robocopy (Robust file copy) is now built into Windows, and it’s a simple command line tool with a number of options to make this a snap.   For example, if I want to mirror a folder on my laptop with my WHS, this command will do it: c:\>robocopy "D:\Music" "\\BEAST\Sonos\music" /mir /r:10 /MT:8 D:\Music is my local folder, my server is \\Beast.  The /mir command is for mirror – it’s the same as using /purge and /e:  /purge is to delete files at the target folder that no longer exist in the source, and /e is to copy all subdirectories, including empty ones.   The /r:10 will tell it to retry up to 10 times, in case of some network glitch, and the /MT:8 will have Robocopy use 8 threads to speed things along.   (If you’re familiar with Robocopy, I don’t recommend using /z (restartable) mode as it adds overhead, not needed given the size of files we’re dealing with.) Now, what if you don’t keep all your music local, and just want to copy it over?   You don’t want to use /mir since it will remove files you otherwise want to keep!   The rest of the command will work fine, but if you move/rename files locally that were previously copied, you’ll have to remember to do that manually on the server.  Once Robocopy does its thing, you’ll get a nice summary:             Total    Copied   Skipped  Mismatch    FAILED    Extras Dirs :      1384        29      1355          0         0         0 Files :     15078       381     14697         0         0         0 Bytes : 117.188 g   3.212 g 113.975 g         0         0         0 Times :   0:16:40   0:02:52                       0:00:00   0:00:48 Here, it copied about 30 new folders.  It took about 16 minutes to run, but that’s largely due to new content, having copied some 3.2gb of new files.   Assuming minor changes only, the process typically runs in about 30 seconds. If you want to get fancy, you could even have Robocopy monitor your folders for changes.  The next challenge is to have Sonos update its music index once new files are copied over.   Sonos can update its index on a daily basis (or manually via the control software), but I want it done automatically after new files are copied over.  This one is a bit trickier, but thanks to some gurus in the Sonos forums, it’s not impossible.   I’m including the .exe file here for you to use.  Obviously, trusting an exe from someone on the web is not something I’d do, but it’s a .NET assembly which means you can use a tool like JustDecompile to crack it open and look at the source yourself.   Having said that, I’m not responsible if this code causes your computer to blow up, your music collection to vanish, or kills any puppies. The source code looks like so, and it sends an SOAP packet to a specified Sonos unit to trigger an index rebuild: using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.IO;using System.Net;namespace SonosIndexUpdater{ class Program { static void Main(string[] args) { string ip; if (args != null && args.Length > 0) { ip = args[0].Trim(); } else { Console.WriteLine("Missing IP Address. Please add IP address for any Sonos unit."); return; } string header1 = @"SOAPACTION: ""urn:schemas-upnp-org:service :ContentDirectory:1#RefreshShareIndex"""; string postData = @"<s:Envelope xmlns:s=""http://schemas.xmlsoap.org/soap/envelope/"" s:encodingStyle=""http://schemas.xmlsoap.org/soap/encoding/""> <s:Body> <u:RefreshShareIndex xmlns:u=""urn:schemas-upnp-org:service:ContentDirectory:1""> <AlbumArtistDisplayOption></AlbumArtistDisplayOption></u:RefreshShareIndex> </s:Body> </s:Envelope>"; string url = string.Format("http://{0}:1400/MediaServer/ContentDirectory/Control", ip); byte[] byteArray = Encoding.UTF8.GetBytes(postData); try { System.Net.WebRequest req = System.Net.WebRequest.Create(url); req.Headers.Add(header1); req.ContentType = "text/xml"; req.Method = "POST"; req.ContentType = "application/x-www-form-urlencoded"; req.ContentLength = byteArray.Length; req.Timeout = 5000; Stream dataStream = req.GetRequestStream(); dataStream.Write(byteArray, 0, byteArray.Length); dataStream.Close(); using (WebResponse response = req.GetResponse()) { Console.WriteLine("Response from Sonos: {0}", ((HttpWebResponse)response).StatusDescription); using (dataStream = response.GetResponseStream()) { using (StreamReader reader = new StreamReader(dataStream)) { string responseFromServer = reader.ReadToEnd(); Console.WriteLine("Data: {0}", responseFromServer); } } } } catch (Exception ex) { Console.WriteLine("Exception occured: {0}", ex.Message); } } }}   To use it, you’d just pass in the IP address of any Sonos unit:   c:\>SonosIndexUpdater 192.168.1.100 If you stumbled on this and aren’t a developer but want to try it out, you can build this for free using Visual Studio Express.    Here are some files:   EXE file only: DownloadVS2010 Solution: Download

Use the Windows Azure CDN for Assets

The most common response to running stuff in the cloud (Azure, Amazon in particular) is the that it’s too expensive for the little guy.   And generally, hosting VMs when a small shared site of something similar will suffice is a tough argument. There are aspects to Azure, though, that are very cost effective as they do “micro-scale” very well.  A good example of this is the Azure CDN, or more simply, Azure Blob Storage.   It’s effective to exchange files, it’s effective at fast delivery, and even lightweight security using shared access signatures (links that essentially only work for a period of time).    It’s durable:  not just redundant internally, but externally as well, automatically creating a backup in another datacenter. For MSDN subscribers, you already have Azure benefits, but even going out of pocket on Blob storage isn’t likely to set you back much:  $0.15/GB of storage per month, $0.01/10,000 transactions, and $0.15/GB outbound bandwidth ($0.20 in Asia; all inbound free).  A transaction is essentially a “hit” on a resource, so each time someone downloads, say, an image file, it’s bandwidth + 1 transaction.  Because these are micro transactions, for small apps, personal use, etc., it’s quite economical … often adding up to pennies per month.   A few typical examples are using storage to host files for a website, serve content to mobile devices, and to simply offload resources (images/JS files) from website code. Depending on usage, the Azure Content Delivery Network (CDN) can be a great way to enhance the user experience.  It may not always be the case (and I’ll explain why) but essentially, the CDN has dozens of edge servers around the world.  While your storage account is served from a single datacenter, having the data on the edge servers greatly enhances speed.   Suppose an app on a phone is retrieving documents/text to a worldwide audience … enabling CDN puts the content much closer.  I created a test storage account in North Europe (one of the Azure datacenters) to test this, using a small graphic from RPA:  http://somedemoaccount.blob.core.windows.net/images/dicelogo.png Here’s the same element via the CDN (we could be using custom DNS names, but for demo purposes we’re not): http://az32338.vo.msecnd.net/images/dicelogo.png Here’s a trace to the storage account in the datacenter – from North Carolina, really not that bad all things considered: You can see we’re routed to NY, then on across the pond, and total latency of about 116ms.   And now the CDN: MUCH faster, chosen not only by physical distance but also network congestion.   Of course, I won’t see a 100ms difference between the two, but if you’re serving up large documents/images, multiple images, or streaming content, the difference will be noticeable.  If you’re new to Azure and have an account, creating a storage account from the dashboard is easy.   You’d just click on your storage accounts, and enter a name/location: You’d typically pick someplace close to you or where most of your users are.   To enable CDN, you’d just click the CDN link on the left nav, and enable it: Once complete, you’ll see if on the main account screen with the HTTP endpoint: So why wouldn’t you do this? Well, it’s all about cacheability.   If an asset is frequently changing or infrequently used, it’s not a good candidate for caching.   If there is a cache miss at a CDN endpoint, the CDN will retrieve the asset from the base storage account.  This will incur an additional transaction, but more importantly it’s slower than if the user just went straight to the storage account.  So depending on usage, it may or may not be beneficial. 

My Apps

Dark Skies Astrophotography Journal Vol 1 Explore The Moon
Mars Explorer Moons of Jupiter Messier Object Explorer
Brew Finder Earthquake Explorer Venus Explorer  

My Worldmap

Month List