Abdullah Diab’s Blog

I’m Learning Python part 8

I’m Learning Python part 8

<p>
  <img title="Python" src="//www.python.org/images/python-logo.gif" alt="Python" /></div> 
  
  <h1 style="font-family:Georgia;">
    Python 3.0
  </h1>
  
  <p>
    Since the last time I wrote an article Python many changes happened in my life, one of them is the release of Python 3.0 (Which is known also as Python3K and Python3000).
  </p>
  
  <p>
    Python 3.0 is the first intentionally backwards incompatible Python release, which means that there are some changes you must notice before start coding in Python 3.0.
  </p>
  
  <p>
    Don&#8217;t worry that much, the language has become more useful, and also there is <a href="//docs.python.org/library/2to3.html">2to3 source-to-source conversion tool</a> which converts your Python 2.x code to meet the requirements of Python 3.0 🙂
  </p>
  
  <p>
    To find more about change in Python please refer to <a title="What's" href="//docs.python.org/3.0/whatsnew/3.0.html">Python website</a>.
  </p>
  
  <p>


P.S.

  <p>
    From now on all the code will be written in Python 3.0.
  </p>
  
  <h1 style="font-family:Georgia;">
    Decimal vs. float
  </h1>
  
  <p>
    Please try the following code in your python console:
  </p>
  
  <pre class="lang:python decode:1">

d = 0.1 print(d) print(str(d))

  <p>
    You&#8217;d get this output:
  </p>
  
  <div>
    <strong><span style="color:#666666;font-family:verdana;">0.10000000000000001</span></strong>
  </div>
  
  <p>
    <strong><span style="color:#666666;font-family:verdana;">0.1<br /> </span></strong>Strange ain&#8217;t it?<br /> The second value is the one you put in the variable.<br /> The first one is the real value represented in memory. This is not Python&#8217;s fault, this happens because of the way computer store float values in memory as 0&#8217;s and 1&#8217;s, computers use floating point IEEE-745 representation.
  </p>
  
  <p>
    Using this representation unfortunately we can&#8217;t represent any float value using 0&#8217;s and 1&#8217;s, and 0.1 is one of those poor values (The reason is that it can&#8217;t be represented in sum of powers of 0.5).
  </p>
  
  <p>
    So what all programming languages do is that they ignore the small fraction so it would be 0.1 instead of 0.10000000000000001, but Python doesn&#8217;t.
  </p>
  
  <p>
    Try this code in Java if you have:
  </p>
  
  <pre class="lang:python decode:1">

public class NoDifference{   public static void main(String[] args){     double a = 0.1;     System.out.println(a);     a = 0.10000000000000001;     System.out.println(a);   } }

  <p>
    You&#8217;d get this output:
  </p>
  
  <div>
    <strong><span style="color:#666666;font-family:verdana;">0.1</span></strong>
  </div>
  
  <p>
    <strong><span style="color:#666666;font-family:verdana;">0.1</span></strong>
  </p>
  
  <p>
    <strong></strong>So Java doesn&#8217;t differ those two values while they&#8217;re different. (Such a difference could make a disaster in a nuclear reactor :twisted:)<br /> If you want to go with the flow and ignore this difference in your calculations you&#8217;d have to use another data type than float, you&#8217;ll have to use Decimal.
  </p>
  
  <pre class="lang:python decode:1">

from decimal import Decimal d = Decimal(“0.1”) print(d)

  <p>
    <strong><span style="color:#666666;font-family:verdana;">0.1</span></strong>
  </p>
  
  <p>
    <strong></strong>Decimal data type allows you to represent any decimal value you want 🙂
  </p>
  
  <p>
    It also supports addition, subtraction, multiplication, division and modulo, but the two sides must be Decimals.
  </p>
  
  <h1 style="font-family:Georgia;">
    Functions
  </h1>
  
  <p>
    Let&#8217;s write a function that prints Fibonacci series to a given boundary:
  </p>
  
  <pre class="lang:python decode:1">

def fib(n):   “““Prints Fibonacci series up to n”””   a, b = 0, 1   while b < n:     print(b, end = " “)     a, b = b, a + b #Now we can call the function by its name fib(2000)

  <p>
    <strong><span style="color:#666666;font-family:verdana;">1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597</span></strong>
  </p>
  
  <p>
    Now let&#8217;s describe what we have done:
  </p>
  
  <ol>
    <li>
      def is a keyword in Python, def defines 🙂 it defines methods and classes.
    </li>
    <li>
      fib is the method&#8217;s name, method&#8217;s name must meet the same requirements for variable&#8217;s name. (first character a-z, A-Z or _, other characters a-z, A-Z, 0-9, _)
    </li>
    <li>
      (n) is the list of parameters, notice that no type names in this list. parameters are comma separated.
    </li>
    <li>
      : defines the scope of the method. All statements under this scope must be tab-aligned.
    </li>
    <li>
      &#8220;&#8221;&#8221;Prints &#8230;&#8221;&#8221;&#8221; is an optional string literal that describes what this method does, it will help you and other developers understand the purpose of the method, and it will also help you auto-generate documentation for your code.
    </li>
    <li>
      a, b = 0, 1. define two variables and give them two values. a handy way 🙂
    </li>
    <li>
      a, b = b, a + b. also assign two values to two variables.
    </li>
  </ol>
  
  <p>
    The previous code defines a procedure (not a function) because it doesn&#8217;t return a value, let&#8217;s modify the code so it builds an array of Fibonacci values instead of printing them:
  </p>
  
  <pre class="lang:python decode:1">

def fib(n):   “““Prints Fibonacci series up to n”””   a, b = 0, 1   result = []   while b < n:     result.append(b)     a, b = b, a + b   return result f = fib(100) print(f)

  <p>
    <strong><span style="color:#666666;font-family:verdana;">[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]</span></strong>
  </p>
  
  <p>
    What we have added is the return statement only, which returns a value to the caller.
  </p>
  
  <p>
    One more thing to be told is default arguments:
  </p>
  
  <pre class="lang:python decode:1">

def askYesNoQuestion(question, retries = 4, complaint = “Please write Yes or No only!"):   while retries > 0:     answer = raw_input(question)     if answer in [‘y’, ‘ye’, ‘yes’, ‘yep’]: return True     if answer in [‘n’, ‘no’, ‘nop’]: return False     retries -= 1     print(complaint)   raise IOError, “stupid user” #Now we can call it askYesNoQuestion(“Are you sure?”, 1, “What?!") askYesNoQuestion(“Overwrite?”, 1) #Same as askYesNoQuestion(“Overwrite?”, 1, “Please write Yes or No only!") askYesNoQuestion(“Do you know me?") #Same as askYesNoQuestion(“Do you know me?”, 4, “Please write Yes or No only!") askYesNoQuestion(“Do you have a pen?”, complaint = “You can say no if you want!") #Same as askYesNoQuestion(“Do you have a pen?”, 4, “You can say no if you want!")

  <p>
    Default arguments are assigned a default value if they aren&#8217;t when called.<br /> You can set arguments values when calling by writing Name = Value.<br /> Default parameters can&#8217;t be followed by non-default arguments.<br /> <strong>Important note</strong>:<br /> Default arguments are evaluated only once, so the following code will accumulate the values:
  </p>
  
  <pre class="lang:python decode:1">

def f(a, L = []):   L.append(a)   return L f(1) print(f)

  <p>
    <strong><span style="color:#666666;font-family:verdana;">[1]</span></strong>
  </p>
  
  <pre class="lang:python decode:1">

f(2) print(f)

  <p>
    <strong><span style="color:#666666;font-family:verdana;">[1, 2]</span></strong>
  </p>
  
  <pre class="lang:python decode:1">

f(3) print(f)

  <p>
    <strong><span style="color:#666666;font-family:verdana;">[1, 2, 3]</span></strong><br /> If you don&#8217;t want the function to behave like this you can write:
  </p>
  
  <pre class="lang:python decode:1">

def f(a, L = None):   if L is None:     L = []   L.append(a)   return L

  <p>
    Let&#8217;s explain what I meant by saying &#8220;are evaluated only once&#8221;:<br /> When the Python interpreter reaches the line that defines the method, it allocates a list in the memory and assigns its address to L the reference.<br /> Next time you call the function L will reference the same list it referenced the time it was created in memory, so it will always reference the same object.<br /> The second code actually referenced to None, so every time you call the function it will assign None to L.<br /> By understanding what I meant you can consider the following example:
  </p>
  
  <pre class="lang:python decode:1">

i = 10 def f(a, b = i):   return a + b i = 11 print(f(2)) # Will it print 12 or 13?

  <p>
    <strong><span style="color:#666666;font-family:verdana;">12</span></strong><br /> That&#8217;s because b was given the value of i before the interpreter reached the line in which i was give the value of 11.
  </p>
  
  <h1 style="font-family:Georgia;">
    Bottom Line
  </h1>
  
  <p>
    Not that much I presented in this part, but you should consider upgrading your Python knowledge to Python 3.0 for the next time.<br /> And by the way, I&#8217;m sorry, I&#8217;ve betrayed you and learned a lot during the last month, I have also started creating GUI Applications using Python and Qt, so please forgive me 🙂<br /> Cheers.
  </p></div>