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’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’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’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’s fault, this happens because of the way computer store float values in memory as 0’s and 1’s, computers use floating point IEEE-745 representation.
</p>
<p>
Using this representation unfortunately we can’t represent any float value using 0’s and 1’s, and 0.1 is one of those poor values (The reason is that it can’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’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’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’t differ those two values while they’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’d have to use another data type than float, you’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’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’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’s name, method’s name must meet the same requirements for variable’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>
“””Prints …””” 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’t return a value, let’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’t when called.<br /> You can set arguments values when calling by writing Name = Value.<br /> Default parameters can’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’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’s explain what I meant by saying “are evaluated only once”:<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’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’m sorry, I’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>