<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>ToddHa's WebLog : Python</title><link>http://blogs.msdn.com/toddha/archive/tags/Python/default.aspx</link><description>Tags: Python</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Subtle mistakes are often the worst</title><link>http://blogs.msdn.com/toddha/archive/2008/04/16/subtle-mistakes-are-often-the-worst.aspx</link><pubDate>Wed, 16 Apr 2008 11:08:32 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8398771</guid><dc:creator>toddha</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/toddha/comments/8398771.aspx</comments><wfw:commentRss>http://blogs.msdn.com/toddha/commentrss.aspx?PostID=8398771</wfw:commentRss><description>&lt;p align="center"&gt;&lt;a href="http://blogs.msdn.com/blogfiles/toddha/WindowsLiveWriter/SubtleMistakesareoftentheworst_DF7/EnvironmentVariables_2.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="355" alt="EnvironmentVariables" src="http://blogs.msdn.com/blogfiles/toddha/WindowsLiveWriter/SubtleMistakesareoftentheworst_DF7/EnvironmentVariables_thumb.png" width="323" align="right" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="left"&gt;A few weeks ago, I noticed that some of my installs on my laptop started failing. I thought it was odd, but most of the things I install are pre-beta, so I figured that they hadn't yet started to support Windows Server 2008. Some things, out of beta, like Windows Live Writer, don't support 2k8 at all, so my laptop is set up to dual boot between 2k8 and Vista. Strangely enough, the installs were often failing during the very beginning of the setup process. One such install that failed was the Silverlight 2 Beta 1 SDK. &lt;/p&gt;  &lt;p align="left"&gt;&lt;em&gt;[Un?]&lt;/em&gt;Fortunately, it was the first of many installers to actually give me good information and tell me that it couldn't write the installation log to the temp directory. I had plenty of hard drive space, so I took a look at what my environment variables were for TEMP and TMP so I could look at the permissions of that folder.&lt;/p&gt;  &lt;p align="left"&gt;What I saw (and isn't pictured), is that my user variables were set to:&lt;/p&gt;  &lt;p align="left"&gt;TEMP=%USERPROFILE%\AppData\Local\Temp;C:\Progra~1\Python25   &lt;br /&gt;TMP=%USERPROFILE%\AppData\Local\Temp&lt;/p&gt;  &lt;p align="left"&gt;Aha! The problem is so obvious now. A few weeks ago I installed Python. Python doesn't add itself to your path, so if you want to have access to it from anywhere, you need to add the Python install directory to your PATH variable. Apparently, I had tried doing this.&lt;/p&gt;  &lt;p align="left"&gt;Unfortunately, the UI you are presented with could use some ... tweaking. Notice that there are two sets of New, Edit, and Delete buttons, all with different hot keys. If you expect Alt+E to be Edit, you're correct. However, you're incorrect if you think it will edit the item that is selected and focused. When I hit Alt+E, it always edits the selected User variable, regardless of what is focused.&lt;/p&gt;  &lt;p align="left"&gt;It's a pretty poor UI, but fortunately it's one that most mainstream users won't need to see very often, if ever. And all others (like me) should take more time in editing their environment variables to make sure they are correct!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8398771" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/toddha/archive/tags/Python/default.aspx">Python</category><category domain="http://blogs.msdn.com/toddha/archive/tags/Programming/default.aspx">Programming</category><category domain="http://blogs.msdn.com/toddha/archive/tags/Windows/default.aspx">Windows</category></item><item><title>Assumptions are the mother of all (part 2).</title><link>http://blogs.msdn.com/toddha/archive/2007/04/26/assumptions-are-the-mother-of-all-part-2.aspx</link><pubDate>Thu, 26 Apr 2007 04:33:31 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2278032</guid><dc:creator>toddha</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/toddha/comments/2278032.aspx</comments><wfw:commentRss>http://blogs.msdn.com/toddha/commentrss.aspx?PostID=2278032</wfw:commentRss><description>&lt;p&gt;In my own time, I've been learning Objective-C for fun. I'm not sure why, perhaps I didn't feel I spent &lt;strong&gt;enough&lt;/strong&gt; time in front of a computer. But I digress.&lt;/p&gt; &lt;p&gt;One of the interesting things I've learned is that the following code works.&lt;/p&gt; &lt;p&gt;Note that I assume we have a class named &lt;em&gt;ArbitraryObject&lt;/em&gt;, and that it has a method that takes no parameters entitled &lt;em&gt;foo&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Objective-C&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;ArbitraryObject * obj;&lt;br&gt;obj = nil;&lt;br&gt;[obj foo];&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Interesting, this code doesn't crash. In comparison, the following languages all crash when you try to do the equivalent.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;ArbitraryObject obj = null;&lt;br&gt;obj.foo();&lt;/code&gt;&lt;/p&gt; &lt;p&gt;This is the easy one. We get a &lt;em&gt;NullReferenceException&lt;/em&gt; thrown.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Java&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;ArbitraryObject obj = null;&lt;br&gt;obj.foo();&lt;/code&gt;&lt;/p&gt; &lt;p&gt;This is another easy one. We get a &lt;em&gt;NullPointerException&lt;/em&gt; thrown.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Python&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;obj = None&lt;br&gt;obj.foo()&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Since we don't have to type what &lt;em&gt;obj&lt;/em&gt; is, we get an &lt;em&gt;AttributeError&lt;/em&gt; talking about how the &lt;em&gt;NoneType&lt;/em&gt; object doesn't have an attribute of &lt;em&gt;foo&lt;/em&gt;. Not exactly the same as before, but close enough.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;C++&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;ArbitraryObject * obj = 0;&lt;br&gt;obj-&amp;gt;foo();&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Note that this isn't the entire code required to get the program to crash (and I'm not sure what spurred me to prove to myself that it wouldn't work). The MS VC++ compiler was optimizing my defects away in different ways. I had to add an instance variable to the ArbitraryObject class, assign it in the constructor, and have foo return the variable. Then in the calling code I printf'd it. But I'm ignoring this for simplicity.&lt;/p&gt; &lt;p&gt;But regardless, it's an access violation error.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;What we've proved is that Objective-C works very differently from how other programming languages work. There are some pros and cons of this, depending on your perspective. It's just important to know how things work.&lt;/p&gt; &lt;p&gt;A couple notes : &lt;/p&gt; &lt;ol&gt; &lt;li&gt;I use&amp;nbsp;&lt;em&gt;nil&lt;/em&gt;, &lt;em&gt;null&lt;/em&gt;, &lt;em&gt;0&lt;/em&gt;, and &lt;em&gt;None&lt;/em&gt; interchangeably.&amp;nbsp;  &lt;li&gt;I'm assuming the compiler hasn't optimized your (possibly intentional) errors away.  &lt;li&gt;I really have nothing against any programming language or technology, so please don't assume that I'm some [arbitrary technology/programming langauge] basher or fanboy (even though Objective-C is primarily an Apple&amp;nbsp;language, and Apple is a competitor to Microsoft).&amp;nbsp;This is just another example of where you might think things work one way, and work a different way completely. &lt;li&gt;I find this particular example fascinating.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;&lt;strong&gt;Performance&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Comparing Objective-C performance to C#, Java, and Python isn't really fair as they all have to be translated into machine language at runtime.&lt;/p&gt; &lt;p&gt;However the C++ comparison&amp;nbsp;is fair. What I'm assuming is happening in Objective-C (without diving into&amp;nbsp;PPC assembly) is that there's a check before each function call that says, "Hey, if this address is nil then jump over this block of code that sets up for and executes the&amp;nbsp;function call." So assumedly you have a some extra instructions every time you make a function call. Not a big deal, especially these days where we have a bazillion clock cycles per second, but definitely something that you need to think about if you're trying to squeeze every cycle out of the processor.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Program Flow&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;This is the main root problems I would assume. I'm going to use C# to flesh out the code, but you can easily translate it to Objective-C. More on this after the code.&lt;/p&gt; &lt;p&gt;Let's go back to our example code and flesh it out a bit in order to prove a point.&lt;/p&gt; &lt;p&gt;&lt;code&gt;public class ArrayWrapper&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&amp;nbsp;static int [] array = new int[] { 1, 2, 3, 4 };&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private static int index = 10;&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static SetIndex(int index)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ArrayWrapper.index = index;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public int GetIndexedValue()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // note that this crashes&amp;nbsp;if index is the default value&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return ArrayWrapper.array[ArrayWrapper.index];&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;}&lt;br&gt;&lt;br&gt;public class ArbitraryObject&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;we don't have to define an empty constructor, but will anyways!&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public ArbitraryObject() { }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void foo()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ArrayWrapper.SetIndex(2);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/code&gt;&lt;code&gt;&lt;br&gt;}&lt;/code&gt;&lt;/p&gt; &lt;p&gt;And now for the driver code function.&lt;/p&gt; &lt;p&gt;&lt;code&gt;public void DriverFunction(ArbitraryObject obj)&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; obj.foo();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // here we have assumed that obj.foo() did it's job and set the&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// index of the ArrayWrapper to a valid value&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(ArrayWrapper.GetIndexedValue().ToString());&lt;br&gt;}&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Ok, so this seems like a really stupid example, but it's point is to show that you're assuming that the ArbitraryObject class worked in order for the rest of the function to work.&lt;/p&gt; &lt;p&gt;Let's run some tests. These are based on whether or not obj.foo( ) worked. I'm not going to translate this to Objective-C, but you can easily see what happens.&lt;/p&gt; &lt;p&gt;C# Tests&lt;br&gt;Valid instance of Arbitrary Object : Wrote out "3" to the console.&lt;br&gt;Null reference : NullReference exception at line &lt;em&gt;xxxx&lt;/em&gt;.&lt;br&gt;&lt;br&gt;Objective-C Tests&lt;br&gt;Valid instance of Arbitrary Object : Wrote out "3" to the console.&lt;br&gt;Null reference : Out of bounds error.&lt;/p&gt; &lt;p&gt;Ok, so we still get an error in Objective-C. And it's relatively easy to debug what's happening. But if the user gets this, the app will have crashed. And they'll get upset. Arguably, they'd get upset in C# too.&lt;/p&gt; &lt;p&gt;But what if the default index was valid? Like 0? We wouldn't crash, but we'd get incorrect results. Which is a LOT harder to debug. But doesn't crash for the user. Maybe it affects the final results that they're looking it for. Maybe it doesn't.&lt;/p&gt; &lt;p&gt;My point to all this is that this introduces a lot of subtleties to debugging something that you have to think about when writing or debugging the code. I'm not saying that it's bad at all. Sometimes you don't care about if the line fails or not -- and you don't have to write a bunch of function calls prefixed with&amp;nbsp;&lt;em&gt;if (reference != null)&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;Another reason to not make assumptions about the way things work (especially in new programming languages). :)&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2278032" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/toddha/archive/tags/Python/default.aspx">Python</category><category domain="http://blogs.msdn.com/toddha/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/toddha/archive/tags/Objective-C/default.aspx">Objective-C</category><category domain="http://blogs.msdn.com/toddha/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://blogs.msdn.com/toddha/archive/tags/Programming/default.aspx">Programming</category></item><item><title>Assumptions are the mother of all.</title><link>http://blogs.msdn.com/toddha/archive/2007/02/07/assumptions-are-the-mother-of-all.aspx</link><pubDate>Wed, 07 Feb 2007 23:44:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1621572</guid><dc:creator>toddha</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/toddha/comments/1621572.aspx</comments><wfw:commentRss>http://blogs.msdn.com/toddha/commentrss.aspx?PostID=1621572</wfw:commentRss><description>&lt;P&gt;While working on one of&amp;nbsp;my side projects at work,&amp;nbsp;I encounted something interesting with the % sign. The code that I'm going to talk about has nothing to do with any upcoming products -- it's simply a side project I'm working on in my free time that uses WCF and WPF (which are 2 major features of the .NET Framework 3.0). That being said, I've (hopefully) abstracted away everything project specific.&lt;/P&gt;
&lt;P&gt;The problem I encountered came from doing some basic math in C# code. Simply, I construct an equation and evaluate what the answer should be by going from left to right (ignoring operator precedence). So when I came up with some final result, I wanted to&amp;nbsp;double check that I was correct.&amp;nbsp;But since I don't keep track of every equation or answer, I had to write a quick tool to trace through it. I'm a big fan of Python for prototyping&amp;nbsp;because I've spent a lot of time in it and understand it well. So I copied over my C# code, made some slight modifications to save the intermediate data&amp;nbsp;and then parse and print the data at the end, and ran it. 
&lt;P&gt;My final answer in Python didn't match that from the one calculated in C# (note that C++ returns the same as C#). The algorithm looked correct, but the final results didn't match. 
&lt;P&gt;Eventually, I&amp;nbsp;found my problem. Take the following simple equation as an example: 
&lt;P&gt;&lt;EM&gt;-13&amp;nbsp;% 6 = ?&lt;/EM&gt; 
&lt;P&gt;C# evaluates this to -1. Python, on the other hand, evaluates to 5. &lt;EM&gt;Um...what?&lt;/EM&gt; Which one is correct? 
&lt;P&gt;Well, it depends on your point of view. Technically they're both correct.&amp;nbsp; Just one method takes it&amp;nbsp;one step further than the other. 
&lt;P&gt;&lt;EM&gt;-13 + 6 = -7&lt;/EM&gt; 
&lt;P&gt;&lt;EM&gt;-7 + 6 = -1&lt;/EM&gt; (C# answer) 
&lt;P&gt;&lt;EM&gt;-1 + 6 = 5&lt;/EM&gt; (Python answer) 
&lt;P&gt;Hm. At first I thought that the in Python the answer will always be in the set &lt;EM&gt;{0, 1, 2, .... n-1 }&lt;/EM&gt;, and the C# answer will always be in the set &lt;EM&gt;{0, ±1, ±2, .... ±(n-1) }&lt;/EM&gt;. To check this, I ran another simple equation through Python and C#. 
&lt;P&gt;&lt;EM&gt;8 % -3 = ?&lt;/EM&gt; 
&lt;P&gt;&lt;EM&gt;8&amp;nbsp;+ -3 = 5&lt;/EM&gt; 
&lt;P&gt;&lt;EM&gt;5&amp;nbsp;+ -3 = 2 &lt;/EM&gt;(C# answer)&amp;nbsp; 
&lt;P&gt;&lt;EM&gt;2 + -3 = -1&lt;/EM&gt; (Python answer) 
&lt;P&gt;Theory crushed. Python and C# follow the same basic principle rule of all the answer being in the set &lt;EM&gt;{0, ±1, ±2, ... ±(n-1) }&lt;/EM&gt;. But why does Python always take it further than the C# ? 
&lt;P&gt;So I looked up the community &lt;A title="defition of modulo" href="http://en.wikipedia.org/wiki/Modulo_operation" mce_href="http://en.wikipedia.org/wiki/Modulo_operation"&gt;definition of modulo&lt;/A&gt;. 
&lt;P&gt;It turns out that the % sign has no strict definition. Python keeps the same sign as the divisor. C# keeps the same sign as the dividend. 
&lt;P&gt;What you should take away : don't always assume that operators will work the same in different languages. 
&lt;P&gt;Extra credit : 
&lt;P&gt;Windows Live Search and Google both provide basic calculator functions in their search. For example, searching for the term "2 + 2" in WLS and Google both give 4. But what about "-13 % 6"?&amp;nbsp;Why&amp;nbsp;do / don't they give the same answer?&amp;nbsp; 
&lt;P&gt;&lt;A title="(Hint : look at who uses Python)" href="http://en.wikipedia.org/wiki/Python_software" mce_href="http://en.wikipedia.org/wiki/Python_software"&gt;Answer&lt;/A&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1621572" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/toddha/archive/tags/Math/default.aspx">Math</category><category domain="http://blogs.msdn.com/toddha/archive/tags/Python/default.aspx">Python</category><category domain="http://blogs.msdn.com/toddha/archive/tags/C_2300_/default.aspx">C#</category></item></channel></rss>