Skip to content

Commit

Permalink
More internal updates
Browse files Browse the repository at this point in the history
  • Loading branch information
kushaldas committed Aug 28, 2012
1 parent 2a6505c commit 97c16b6
Show file tree
Hide file tree
Showing 11 changed files with 576 additions and 196 deletions.
3 changes: 2 additions & 1 deletion en-US/Python_for_you_and_me.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
<xi:include href="file.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="classes.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="modules.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="collections.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="virtualenv.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="acknowledgment.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="Appendix.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<index/>
</book>

15 changes: 8 additions & 7 deletions en-US/acknowledgment.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@
</para>
<para>
<itemizedlist>
<listitem><para>Jared Smith</para></listitem>
<listitem><para>Marco Mornati</para></listitem>
<listitem><para>Nicu Buculei</para></listitem>
<listitem><para>Paul W. Frields</para></listitem>
<listitem><para>Pradeepto K Bhattacharya</para></listitem>
<listitem><para>Sankarshan Mukhopadhyay</para></listitem>
<listitem><para>Jared Smith</para></listitem>
<listitem><para>Marco Mornati</para></listitem>
<listitem><para>Nicu Buculei</para></listitem>
<listitem><para>Paul W. Frields</para></listitem>
<listitem><para>Pradeepto K Bhattacharya</para></listitem>
<listitem><para>Prashad J. Pandit</para></listitem>
<listitem><para>Sankarshan Mukhopadhyay</para></listitem>
<listitem><para>Sayamindu Dasgupta</para></listitem>
<listitem><para>Stephanie Whiting</para></listitem>
<listitem><para>Prashad J. Pandit</para></listitem>

</itemizedlist>
I am missing some names in the above list, will add them soon
</para>
Expand Down
121 changes: 76 additions & 45 deletions en-US/classes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,70 +24,87 @@
<para>
in the statements you can write any python statement, you can define functions (which we call methods of a class).
</para>
<screen><![CDATA[>>> class MyClass:
<programlisting language="Python"><![CDATA[>>> class MyClass:
... a = 90
... b = 88
...
>>> p = MyClass()
>>> p
<__main__.MyClass instance at 0xb7c8aa6c>
]]>
</screen>
</programlisting>
<para>
In the above example you can see first we are declaring a class called MyClass, writing some random statements inside that class. After the class definition, we are creating an <emphasis>object</emphasis> p of the <emphasis>class</emphasis> MyClass.If you do a dir on that...
</para>
<screen><![CDATA[>>> dir(p)
<programlisting language="Python"><![CDATA[>>> dir(p)
['__doc__', '__module__', 'a', 'b']
]]>
</screen>
</programlisting>
<para>
You can see the variables <emphasis>a</emphasis> and <emphasis>b</emphasis> inside it.
</para>
</section>
<section id="pythonforyouandme-Classes-initmethod">
<title>__init__ method</title>
<para>__init__ is a special method in python classes, it is the constructor method for a class. In the following example you can see how to use it</para>
<screen><![CDATA[>>> class Student:
... def __init__(self, name, branch, year):
... self.name = name
... self.branch = branch
... self.year = year
... print "A student object is created"
... def getName(self):
... return self.name
... def setName(self, name):
... self.name = name
...
<programlisting language="Python"><![CDATA[class Student(object):
"""
Returns a ```Student``` object with the given name, branch and year.
"""
def __init__(self, name, branch, year):
self.name = name
self.branch = branch
self.year = year
print "A student object is created"
def set_name(self, name):
"""
Sets the name of the student.
:arg name: new name ofthe student.
"""
self.name = name
def get_name(self):
"""
Returns the name of the student.
:return: a string contain the student's name
"""
return self.name
]]>
</screen>
</programlisting>
<para>
__init__ is called when ever an object of the class is constructed.That means when ever we will create a student object we will see the message "Creating a new student" in the prompt. You can see the first argument to the method is <emphasis>self</emphasis>. It is a special variable which points to the current object (like `this` in C++). The object is passed implicitly to every method available in it , but we have to get it explicitly in every method while writing the methods. Example shown below.
</para>
<screen><![CDATA[>>> std1 = Student()
<programlisting language="Python"><![CDATA[>>> std1 = Student()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __init__() takes exactly 4 arguments (1 given)
>>> std1 = Student('Kushal','CSE','2005')
A student object is created
]]>
</screen>
</programlisting>
<para>
In this example at first we tried to create a Student object with passing any argument and python interpreter complained that it takes exactly 4 arguments but received only one (self). Then we created an object with proper argument values and from the message printed, one can easily understand that <emphasis>__init__ </emphasis> method was called as the constructor method.
</para>
<para>
Now we are going to call <emphasis>getName()</emphasis> and <emphasis>setName()</emphasis> methods.
</para>
<screen><![CDATA[>>> std1.getName()
<programlisting language="Python"><![CDATA[>>> std1.get_name()
'Kushal'
>>> std1.setName()
>>> std1.set_name()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: setName() takes exactly 2 arguments (1 given)
>>> std1.setName('Shreyank Gupta')
>>> std1.getName()
TypeError: set_name() takes exactly 2 arguments (1 given)
>>> std1.set_name('Shreyank Gupta')
>>> std1.get_name()
'Shreyank Gupta'
]]>
</screen>
</programlisting>
<para>
First we called getName on the object we created, then tried to call setName without any arguments and we got an error. Next we again called setName with argument 'Shreyank Gupta'. Now calling getName gives 'Shreyank Gupta' as the output.
</para>
Expand All @@ -106,56 +123,70 @@ TypeError: setName() takes exactly 2 arguments (1 given)
<title>student_teacher.py</title>
<programlisting language="Python"><![CDATA[#!/usr/bin/env python
class Person:
class Person(object):
"""
Returns a ```Person``` object with given name.
"""
def __init__(self,name):
self.name = name
def getDetails(self):
def get_details(self):
"Returns a string containing name of the person"
return self.name
class Student(Person):
"""
Returns a ```Student``` object, takes 3 arguments, name, branch, year.
"""
def __init__(self,name,branch,year):
Person.__init__(self,name)
self.branch = branch
self.year = year
def getDetails(self):
return (self.name, self.branch, self.year)
def get_details(self):
"Returns a string containing student's details."
return "%s studies %s and is in %s year." % (self.name, self.branch, self.year)
class Teacher(Person):
def __init__(self,name,papers):
Person.__init__(self,name)
"""
Returns a ```Teacher``` object, takes a list of strings (list of papers) as
argument.
"""
def __init__(self, name, papers):
Person.__init__(self, name)
self.papers = papers
def getDetails(self):
return (self.name, self.papers)
def get_details(self):
return "%s teaches %s" % (self.name, ','.join(self.papers))
person1 = Person('Rahul')
student1 = Student('Kushal','CSE',2005)
teacher1 = Teacher('Prashad',['C','C++'])
person1 = Person('Sachin')
student1 = Student('Kushal', 'CSE', 2005)
teacher1 = Teacher('Prashad', ['C', 'C++'])
print person1.getDetails()
print student1.getDetails()
print teacher1.getDetails()
print person1.get_details()
print student1.get_details()
print teacher1.get_details()
]]>
</programlisting>
<para>
The output:
</para>

<screen><![CDATA[[kdas@kdas code]$ ./student_teacher.py
Rahul
('Kushal', 'CSE', 2005)
('Prashad', ['C', 'C++'])
<screen><![CDATA[$ ./student_teacher.py
Sachin
Kushal studies CSE and is in 2005 year.
Prashad teaches C,C++
]]>
</screen>
<para>
In this example you can see how we called the __init__ method of the class Person in both Studentা and Teacher classes' __init__ method. We also reimplemented <emphasis>getDetails()</emphasis> method of Person class in both Student and Teacher class. So, when we are calling <emphasis>getDetails()</emphasis> method on the teacher1 object it returns based on the object itself (which is of teacher class) and when we call <emphasis>getDetails()</emphasis> on the student1 or person1 object it returns based on <emphasis>getDetails()</emphasis> method implemented in it's own class.
In this example you can see how we called the __init__ method of the class Person in both Student and Teacher classes' __init__ method. We also reimplemented <emphasis>get_details()</emphasis> method of Person class in both Student and Teacher class. So, when we are calling <emphasis>get_details()</emphasis> method on the teacher1 object it returns based on the object itself (which is of teacher class) and when we call <emphasis>get_details()</emphasis> on the student1 or person1 object it returns based on <emphasis>get_details()</emphasis> method implemented in it's own class.
</para>
</section>
<section id="pythonforyouandme-Classes-multiple-inheritance">
Expand All @@ -177,14 +208,14 @@ Rahul
<para>
As we already know how to create an object , now we are going to see how to delete an python object. We use <emphasis>del</emphasis> for this.
</para>
<screen><![CDATA[>>> s = "I love you"
<programlisting language="Python"><![CDATA[>>> s = "I love you"
>>> del s
>>> s
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 's' is not defined
]]>
</screen>
</programlisting>
<para>
<emphasis>del</emphasis> actually decreases reference count by one. When the reference count of an object becomes zero the garbage collector will delete that object.
</para>
Expand Down
98 changes: 98 additions & 0 deletions en-US/collections.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?xml version='1.0'?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
]>

<chapter id="pythonforyouandme-Collections">
<title>Collections module</title>
<para>
In this chapter we will learn about a module called <emphasis>Collections</emphasis>. In this module we some nice data structures which will help you to solve various real life problems.
</para>
<programlisting language="Python">
<![CDATA[>>> import collections]]>
</programlisting>
<para>
This is how you can import the module, now we will see the available classes which you can use.
</para>
<section id="pythonforyouandme-Collections-Counter">
<title>Counter</title>
<para>
<emphasis>Counter</emphasis> is a <emphasis>dict</emphasis> subclass which helps to count hashable objects. Inside it elements are stored as dictionary keys and counts are stored as values which can be zero or negative.
</para>
<para>
Below we will see one example where we will find occurrences of words in the Python LICENSE file.
</para>
<example>
<title>Counter example</title>
<programlisting language="Python"><![CDATA[>>> from collections import Counter
>>> import re
>>> path = '/usr/share/doc/python-2.7.3/LICENSE'
>>> words = re.findall('\w+', open(path).read().lower())
>>> Counter(words).most_common(10)
[('2', 97), ('the', 80), ('or', 78), ('1', 76), ('of', 61), ('to', 50), ('and', 47), ('python', 46), ('psf', 44), ('in', 38)]]]>
</programlisting>
</example>
<para>
Counter objects has an method called <emphasis>elements</emphasis> which returns an iterator over elements repeating each as many times as its count. Elements are returned in arbitrary order.
</para>
<programlisting language="Python">
<![CDATA[>>> c = Counter(a=4, b=2, c=0, d=-2)
>>> list(c.elements())
['a', 'a', 'a', 'a', 'b', 'b']]]>
</programlisting>

<para>
<emphasis>most_common</emphasis> is a method which returns most common elements abd their counts from the most common to the least.
</para>
<programlisting language="Python">
<![CDATA[>>> Counter('abracadabra').most_common(3)
[('a', 5), ('r', 2), ('b', 2)]]]>
</programlisting>
</section>
<section id="pythonforyouandme-Collections-defaultdict">
<title>defaultdict</title>
<para>
<emphasis>defaultdict</emphasis> is a dictionary like object which provides all methods provided by dictionary but takes first argument (default_factory) as default data type for the dictionary. Using defaultdict is faster than doing the same using <emphasis>dict.set_default</emphasis> method.
</para>
<example>
<title>defaultdict example</title>
<programlisting language="Python">
<![CDATA[>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
>>> d = defaultdict(list)
>>> for k, v in s:
... d[k].append(v)
...
>>> d.items()
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]]]>
</programlisting>
</example>
<para>
In the example you can see even if the key is not there in the defaultdict object, it automatically creates an empty list. <emphasis>list.append</emphasis> then helps to append the value to the list.
</para>
</section>
<section id="pythonforyouandme-Collections-namedtuple">
<title>namedtuple</title>
<para>
Named tuples helps to have meaning of each position in a tuple and allow us to code with better readability and self-documenting code. You can use them in any place where you are using <emphasis>tuples</emphasis>. In the example we will create a namedtuple to show hold information for points.
</para>
<example>
<title>Named tuple</title>
<programlisting language="Python">
<![CDATA[>>> from collections import namedtuple
>>> Point = namedtuple('Point', ['x', 'y']) #Defining the namedtuple
>>> p = Point(10, y=20) #Creating an object
>>> p
Point(x=10, y=20)
>>> p.x + p.y
30
>>> p[0] + p[1] #Accessing the values in normal way
30
>>> x, y = p #Unpacking the tuple
>>> x
10
>>> y
20]]>
</programlisting>
</example>
</section>

</chapter>
8 changes: 5 additions & 3 deletions en-US/datastructure.xml
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ parthan uses Ubuntu
<para>
Many times it happens that we want to add more data to a value in a dictionary and if the key does not exists then we add some default value. You can do this efficiently using <emphasis>dict.setdefault(key, default)</emphasis>.
<programlisting language="Python">
>>> data = {}
<![CDATA[>>> data = {}
>>> data.setdefault('names', []).append('Ruby')
>>> data
{'names': ['Ruby']}
Expand All @@ -328,18 +328,20 @@ parthan uses Ubuntu
>>> data.setdefault('names', []).append('C')
>>> data
{'names': ['Ruby', 'Python', 'C']}
]]>
</programlisting>
</para>
<para>
When we try to get value for a key which does not exists we get <emphasis>KeyError</emphasis>. We can use <emphasis>dict.get(key, default)</emphasis> to get a default value when they key does not exists before.
</para>
<programlisting language="Python" role="PYTHON">
>>> data['foo']
<programlisting language="Python">
<![CDATA[>>> data['foo']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'foo'
>>> data.get('foo', 0)
0
]]>
</programlisting>
<para>
If you want to loop through a list (or any sequence) and get iteration number at the same time you have to use <emphasis>enumerate()</emphasis>.
Expand Down
Loading

0 comments on commit 97c16b6

Please sign in to comment.