{"id":2709,"date":"2009-01-05T23:30:34","date_gmt":"2009-01-06T04:30:34","guid":{"rendered":"http:\/\/brucegarrett.com\/brucelog\/?p=2709"},"modified":"2009-01-06T09:34:01","modified_gmt":"2009-01-06T14:34:01","slug":"a-little-of-what-i-do-for-a-living","status":"publish","type":"post","link":"https:\/\/brucegarrett.com\/brucelog\/2709","title":{"rendered":"A Little Of What I Do For A Living"},"content":{"rendered":"<p><em>[Major Geek Alert&#8230;]<\/em>\n<\/p>\n<p>Some of you may have read the news items about Microsoft&#8217;s Zune player freezing up on its users last December 31st. The problem it turned out, was in a bit of software that calculates how many days since January 1st the current date is.&nbsp; I&#8217;ve no idea why the Zune&#8217;s software needed to do that, but it isn&#8217;t important to what I&#8217;m about to show you.&nbsp; I have fun doing the work I do, in a techno geeky kinda way, and I want to share a bit of that fun with you.\n<\/p>\n<p>The code that caused that particular bug was leaked out into the wild.&nbsp; Here&#8217;s the relevant fragment:<\/p>\n<blockquote><p>&nbsp; while (days &gt; 365)<br \/>\n&nbsp; {<br \/>\n&nbsp; &nbsp; &nbsp; if (IsLeapYear(year))<br \/>\n&nbsp; &nbsp; &nbsp; {<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (days &gt; 366)<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; days -= 366;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; year += 1;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br \/>\n&nbsp; &nbsp; &nbsp; }<br \/>\n&nbsp; &nbsp; &nbsp; else<br \/>\n&nbsp; &nbsp; &nbsp; {<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; days -= 365;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; year += 1;<br \/>\n&nbsp; &nbsp; &nbsp; }<br \/>\n&nbsp; }<\/p>\n<\/blockquote>\n<p>Don&#8217;t panic&#8230;it&#8217;s just code.&nbsp; Code is to a computer program what a chart is to music.&nbsp; It&#8217;s not so much the program, as instructions for how to create the program.&nbsp; It&#8217;s more human readable then the machine language code microprocessors digest, although that might seem a tad hard to believe if you&#8217;re seeing code here for the first time.&nbsp; It&#8217;s a kind of highly structured syntax that is precise enough to describe, step-by-step, a series of actions the computer needs to perform.&nbsp; That series of actions is called an &#8216;algorithm&#8217;.<\/p>\n<p>An algorithm is a series of steps needed to perform a specific task in a specific time.&nbsp; So for example, consider the steps necessary to bake a single cake.&nbsp; Those steps constitute an algorithm because they perform a specific task in a specific time.&nbsp; The task is baking a cake.&nbsp; When the cake is baked you are done.&nbsp; Note that a specific time isn&#8217;t necessarily a specific amount of time.&nbsp; The important thing is there is an end to it somewhere. The steps needed for a cake factory to make &#8216;cakes&#8217; is not an algorithm because there is no defined end to the task of baking cakes.&nbsp; It could be one cake or many.&nbsp; But you can repeat the algorithm for baking a single cake as many times as you like, once you have it defined.<\/p>\n<p>Writing computer programs is essentially the art of creating well defined, simple, straightforward algorithms.&nbsp; If you&#8217;ve got a head for that, the rest is a matter of mastering a particular programming language or more.&nbsp; The code fragment above is in a language called C++.&nbsp; Never mind why it&#8217;s called that and not something more warm and friendly like Fred or Ethel.&nbsp; Computer geeks are weird like that.<\/p>\n<p>This code fragment is from a larger bit of code that tries to determine the number of years the current year is from the year 1980, and the number of days since January 1st.&nbsp; Never mind for now <em>Why<\/em>.&nbsp; Just focus on the task: to get the number of years since 1980 and the number of days since January 1st.&nbsp;<\/p>\n<p>The function this code fragment lives in receives the current date in the form of the number of days since January 1, 1980.&nbsp; This seems odd, but it is how computers tell time.&nbsp; At the most basic level, they are merely counting fractions of seconds from a given starting point.&nbsp; Consider that a mechanical wrist watch (like the one I wear) tells the time only by counting ticks.&nbsp; If you know how many ticks there are in a second, then you can compute the second, the minute, and the hour by counting the number of ticks and that is just what a mechanical wrist watch does&#8230;mechanically.&nbsp; Computers do pretty much the same thing electronically, but their ticks are much smaller, and far more precise.\n<\/p>\n<p>We know there are 365 days in a normal year.&nbsp; So if we get a number that&#8217;s, let&#8217;s say 10220, we might just divide that by 365 to get the number of years that have passed.&nbsp; But the added factor of having leap years makes it less simple then that.&nbsp;<\/p>\n<p>Now let me try to make some sense of that C++ code for you.&nbsp; As I said, it&#8217;s a highly structured syntax that precisely describes the steps a computer program must perform.&nbsp; Just ignore the brackets&#8230;they&#8217;re just there to mark off specific sections of the code.&nbsp; Don&#8217;t worry about them.<\/p>\n<p>At the beginning of the code you see the word &quot;while&quot;.&nbsp; This is a <em>Keyword<\/em> in the C and C++ languages and it denotes the start of a program <em>Loop<\/em>.&nbsp; A loop is a series of steps that are repeated.&nbsp; They are very useful for repeating a series of steps over and over as just a few lines of code instead of one or more lines repeated exactly for every time the steps need to be executed. If, say, you had to do something a hundred times you would write the code to loop through the same steps a hundred times, rather then writing the same steps a hundred times in the code.&nbsp; If the steps change, then that&#8217;s a hundred changes you need to make.&nbsp; If you&#8217;ve written it as a loop you only need to change it once.&nbsp;<\/p>\n<p>Loops are also helpful if you don&#8217;t know ahead of time how many times you might have to repeat a particular set of steps.&nbsp; In the cake baking example for instance, you might have to stir some ingredients until they are mixed properly.&nbsp; If you were coding that, you&#8217;d write it as a loop where you stir the mix, and then test to see if it&#8217;s mixed well enough to stop.&nbsp; If not, stir once more.&nbsp; Test&#8230;stir&#8230;test&#8230;stir&#8230;&nbsp; And so on until the the test says you can stop stirring now.\n<\/p>\n<p>That test is important.&nbsp; It tells you when you can stop stirring.&nbsp; For now just hold this thought: <em>it is important to have a way out of a loop.<\/em><\/p>\n<p>The keyword &quot;while&quot; has a test enclosed in the parenthesis next to it: (days &gt; 365).&nbsp; This test compares the variable &quot;days&quot; against a literal value of 366.&nbsp; Think of a variable as a post office box with a name on it, and something inside.&nbsp; In this case, the variable is named &quot;days&quot; and it holds a number that represents a given number of days.&nbsp; This variable is set elsewhere in the code and we don&#8217;t need to know why or how at the moment.&nbsp; We&#8217;re just looking at what this one bit of code does.&nbsp;\n<\/p>\n<p>The &quot;&gt;&quot; symbol is an <em>Operator<\/em> in the C and C++ languages, which means &quot;greater then&quot;&nbsp; If &quot;days&quot; is &quot;greater then&quot; 365 then the next lines of code are executed.&nbsp; This test is at the beginning of the loop, which means the condition is tested first before any of the code in the loop is executed.&nbsp; If the test is true, the loop is entered.&nbsp; If not, the loop is never entered.&nbsp; So the loop takes a value for a number of days at its very beginning.&nbsp; If that value is greater then 365, the rest of the loop executes.&nbsp; If it isn&#8217;t, the loop is skipped over.&nbsp; Think of it as saying &quot;while the value stored in &quot;days&quot; is greater then 365, do the following&#8230;&quot;\n<\/p>\n<p>So we enter the body of the loop.&nbsp; The next line is &quot;if (IsLeapYear(year))&quot;&nbsp; Let me unpack that.&nbsp; The word &quot;if&quot; is another keyword, and it denotes a logical test.&nbsp; You are testing if something is, or is not true.&nbsp; The part in the parenthesis is the thing you are testing.&nbsp; IsLeapYear(year) is a function call with its own set of parenthesis.&nbsp; Functions are bits of code that return a value.&nbsp; This particular function returns a value of either true or false.&nbsp; We don&#8217;t need to see how this particular works for this example&#8230;just that it will return either &quot;true&quot; or &quot;false&quot; back to our &quot;if&quot; test.&nbsp; The word &quot;year&quot; in its parenthesis is another variable and it holds a number that represents the number of years since 1980.&nbsp;<\/p>\n<p>So we are passing in to the function IsLeapYear a number, and it returns either true or false depending on whether or not the number we give it, translates into a leap year.&nbsp; Remember, we&#8217;re counting the number of years since 1980.&nbsp; Lets say we make &quot;year&quot; equal to 3.&nbsp; We could as easily write the call as &quot;IsLeapYear(3)&quot;, and it would return false, since 1980 plus three years is 1983 which was not a leap year.\n<\/p>\n<p>Okay&#8230;still with me?<\/p>\n<p>An &quot;if&quot; test tests a condition, and the lines of code following the test are either executed or not depending on whether or not the test passed or failed.&nbsp; If IsLeapYear(year) returns true, then the next line is executed.\n<\/p>\n<p>The next line is another &quot;if&quot; test.&nbsp; if (days &gt; 366).&nbsp; This test compares the variable &quot;days&quot; against a literal value of 366.&nbsp; It is like the test at the beginning of the loop.&nbsp; If &quot;days&quot; is &quot;greater then&quot; 366 then the next lines of code are executed.&nbsp;<\/p>\n<p>These next lines actually do something.&nbsp; the line &quot;days -= 366&quot; means &quot;take the value that&#8217;s stored in the variable named &quot;days&quot;, subtract 366 from it and store the result back in that variable.&nbsp; The line &quot;year += 1&quot; means &quot;add one to the value stored in the variable named year and put the result back in that variable&quot;.&nbsp;<\/p>\n<p>A couple brackets on down (I told you to just ignore them) there is the word &quot;else&quot;&nbsp; It is another keyword that works with the keyword &quot;if&quot; to denote lines of code to be executed if the if test above fails.&nbsp; So in other words, if IsLeapYear(year) returns false, then the steps following the word &quot;else&quot; are performed.&nbsp; Think of the whole thing as &quot;if it&#8217;s a leap year do this&#8230;if it isn&#8217;t (else) do that&#8230;&quot;&nbsp; In this case, that is &quot;subtract 365 from the value of the variable named days&quot;, and &quot;add one to the value of the variable named year&quot;.<\/p>\n<p>So&#8230;still with me?&nbsp; This is what the code is doing.&nbsp; The algorithm it embodies is this:<\/p>\n<p>1) Repeat the following for as long as the value of &quot;days&quot; is greater then 365:<br \/>\n2) Check to see if &quot;year&quot; is a leap year.<br \/>\n3) If it is a leap year, check to see if the value of &quot;days&quot; is greater then 366.<br \/>\n4) If it is, then subtract 366 from &quot;days&quot; and add 1 to the value of &quot;year&quot;<br \/>\n5) If &quot;year&quot; isn&#8217;t a leap year, then subtract 365 from &quot;days&quot; and add 1 to the value of &quot;year&quot;<\/p>\n<p>There is our loop.&nbsp; Basically, it is taking a number that is the number of days since 1980, and subtracting 365 days for every normal year, 366 for every leap year, and when it finishes you should have a count of the number of years since 1980, and what&#8217;s left over is the number of days since January 1st.&nbsp; Simple&#8230;no?\n<\/p>\n<p>The bug in it is subtle.&nbsp; Let&#8217;s run through it for December 31, 2007.&nbsp; Lets say we have run this loop for a while and now we have a value of 26 in &quot;year&quot;.&nbsp; The value of &quot;days&quot; is 730.&nbsp;\n<\/p>\n<p>1) The value of &quot;days&quot; is greater then 365&#8230;so we do the loop again.<br \/>\n2) Check to see if &quot;year&quot; is a leap year.&nbsp; 26 years since 1980 is 2006.&nbsp; 2006 isn&#8217;t a leap year.&nbsp; So the code following the &quot;else&quot; keyword is executed.<br \/>\n3) We subtract 365 from &quot;days&quot; and add 1 to the value of &quot;year&quot;<br \/>\n4) We&#8217;re at the beginning of our loop again.&nbsp; The value of &quot;days&quot; is 365.&nbsp; 365 is not greater then 365.&nbsp; So the condition for continuing the loop is now false.&nbsp; So now we can exit the loop.<br \/>\n5) The end values are, year = 27, days = 365.<\/p>\n<p>Okay.&nbsp; That works.&nbsp; But now let&#8217;s try it for December 31, 2008.&nbsp; Lets say we have run this loop for a while and now we have a value of 27 in &quot;year&quot;.&nbsp; The value of &quot;days&quot; is 731.<\/p>\n<p>1) The value of &quot;days&quot; is greater then 365&#8230;so we do the loop again.<br \/>\n2) Check to see if &quot;year&quot; is a leap year.&nbsp; 27 years since 1980 is 2007.&nbsp; 2007 isn&#8217;t a leap year.&nbsp; So the code following the &quot;else&quot; keyword is executed.<br \/>\n3) We subtract 365 from &quot;days&quot; and add 1 to the value of &quot;year&quot;<br \/>\n4) We&#8217;re at the beginning of our loop again.&nbsp; The value of &quot;days&quot; is 366.&nbsp; 366 is greater then 365.&nbsp; So the condition for continuing the loop is still true.<br \/>\n5) Check to see if &quot;year&quot; is a leap year.&nbsp; 2008 is a leap year.&nbsp; So the code following the &quot;if&quot; keyword is executed.<br \/>\n6) Check to see if the value of &quot;days&quot; is greater then 366.&nbsp; 366 isn&#8217;t greater then 366, it&#8217;s equal to 366&#8230;so the code following the &quot;if&quot; keyword is not executed.<br \/>\n7) We&#8217;re at the beginning of our loop again.&nbsp; The value of &quot;days&quot; is still 366 and the value of year is still 28.&nbsp; 366 is greater then 365.&nbsp; So the condition for continuing the loop is still true.<br \/>\n10) Check to see if &quot;year&quot; is a leap year.&nbsp; The value of year wasn&#8217;t changed by the last run through the loop.&nbsp; It is still 2008 and 2008 isn&#8217;t a leap year.&nbsp; So the code following the &quot;if&quot; keyword is executed.\n<\/p>\n<p>(can you see this thing starting to run away now&#8230;?)<\/p>\n<p>11)&nbsp; Check to see if the value of &quot;days&quot; is greater then 366.&nbsp; 366 isn&#8217;t greater then 366, it&#8217;s equal to 366&#8230;so the code following the &quot;if&quot; keyword is not executed.<br \/>\n12) We&#8217;re at the beginning of the loop again&#8230;<\/p>\n<p>And that&#8217;s where we will keep on ending up until the heat death of the universe, or the Zune&#8217;s battery dies, whichever comes first.&nbsp; This is why the Zunes all locked up on December 31st, 2008.&nbsp; The code works fine during a normal year, and on every day but the last day of a leap year.&nbsp; But on the last day of a leap year that loop will run indefinitely, because there is no way out of it on that one day.<\/p>\n<p>Since this code was leaked out into the wild, everybody who does this for a living has an opinion on how to write that algorithm better.&nbsp; There is a kind of fine art and a pure pleasure to some of us in crafting tight, simple, elegant algorithms and some folks have their own deeply held religious beliefs on how to do it best.&nbsp; I haven&#8217;t had time to really wrap my head around what this algorithm is doing, but for kicks and grins I might try to write a better version of it myself later.&nbsp; It&#8217;s kinda fun to take something like this and try to craft something simple and clean and so logically pure it&#8217;s beautiful just to look at.&nbsp; But I&#8217;m in a testing and deployment phase of the project I&#8217;m one at work now though, and what went through my head when I saw this was they obviously didn&#8217;t test how it behaved during a leap year.\n<\/p>\n<p>This is the world I live and work in.&nbsp; This is what programming is and what programmer&#8217;s do.&nbsp; We build these tight little algorithms and embody them in computer code that hopefully allows you to get things done.&nbsp; Except when they don&#8217;t.<\/p>\n<p><em>[Edited a tad to explain the test at the start of the loop, and make some of the rest of it clearer&#8230;]<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>[Major Geek Alert&#8230;] Some of you may have read the news items about Microsoft&#8217;s Zune player freezing up on its users last December 31st. The problem it turned out, was in a bit of software that calculates how many days since January 1st the current date is.&nbsp; I&#8217;ve no idea why the Zune&#8217;s software needed [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[36,86],"class_list":["post-2709","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-computer-geeking","tag-the-redmond-follies"],"_links":{"self":[{"href":"https:\/\/brucegarrett.com\/brucelog\/wp-json\/wp\/v2\/posts\/2709","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/brucegarrett.com\/brucelog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/brucegarrett.com\/brucelog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/brucegarrett.com\/brucelog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/brucegarrett.com\/brucelog\/wp-json\/wp\/v2\/comments?post=2709"}],"version-history":[{"count":0,"href":"https:\/\/brucegarrett.com\/brucelog\/wp-json\/wp\/v2\/posts\/2709\/revisions"}],"wp:attachment":[{"href":"https:\/\/brucegarrett.com\/brucelog\/wp-json\/wp\/v2\/media?parent=2709"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/brucegarrett.com\/brucelog\/wp-json\/wp\/v2\/categories?post=2709"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/brucegarrett.com\/brucelog\/wp-json\/wp\/v2\/tags?post=2709"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}