Forráskód Böngészése

Adding 5 chapters

Swaroop C H 12 éve
szülő
commit
fa4c556adf
6 módosított fájl, 1227 hozzáadás és 0 törlés
  1. 308 0
      12-problem-solving.pd
  2. 351 0
      13-oop.pd
  3. 159 0
      14-io.pd
  4. 204 0
      15-exceptions.pd
  5. 180 0
      16-standard-library.pd
  6. 25 0
      fabfile.py

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 308 - 0
12-problem-solving.pd


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 351 - 0
13-oop.pd


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 159 - 0
14-io.pd


+ 204 - 0
15-exceptions.pd

@@ -0,0 +1,204 @@
+# Exceptions
+
+Exceptions occur when certain *exceptional* situations occur in your program.  For example, what if you are going to read a file and the file does not exist? Or what if you accidentally deleted it when the program was running? Such situations are handled using **exceptions**.
+
+Similarly, what if your program had some invalid statements? This is handled by Python which **raises** its hands and tells you there is an **error**.
+
+## Errors 
+
+Consider a simple `print` function call. What if we misspelt `print` as `Print`? Note the capitalization. In this case, Python *raises* a syntax error.
+
+~~~
+>>> Print('Hello World')
+Traceback (most recent call last):
+  File "<pyshell#0>", line 1, in <module>
+    Print('Hello World')
+NameError: name 'Print' is not defined
+>>> print('Hello World')
+Hello World
+~~~
+
+Observe that a `NameError` is raised and also the location where the error was detected is printed. This is what an *error handler* for this error does.
+
+## Exceptions 
+
+We will **try** to read input from the user. Press `ctrl-d` and see what happens.
+
+~~~
+>>> s = input('Enter something --> ')
+Enter something --> 
+Traceback (most recent call last):
+  File "<pyshell#2>", line 1, in <module>
+    s = input('Enter something --> ')
+EOFError: EOF when reading a line
+~~~
+
+Python raises an error called `EOFError` which basically means it found an *end of file* symbol (which is represented by `ctrl-d`) when it did not expect to see it.
+
+## Handling Exceptions 
+
+We can handle exceptions using the `try..except` statement.  We basically put our usual statements within the try-block and put all our error handlers in the except-block.
+
+~~~python
+#!/usr/bin/python
+# Filename: try_except.py
+
+try:
+    text = input('Enter something --> ')
+except EOFError:
+    print('Why did you do an EOF on me?')
+except KeyboardInterrupt:
+    print('You cancelled the operation.')
+else:
+    print('You entered {0}'.format(text))
+~~~
+
+Output:
+
+~~~
+$ python try_except.py
+Enter something -->     # Press ctrl-d
+Why did you do an EOF on me?
+
+$ python try_except.py
+Enter something -->     # Press ctrl-c
+You cancelled the operation.
+
+$ python try_except.py
+Enter something --> no exceptions
+You entered no exceptions
+~~~
+
+How It Works:
+
+We put all the statements that might raise exceptions/errors inside the `try` block and then put handlers for the appropriate errors/exceptions in the `except` clause/block. The `except` clause can handle a single specified error or exception, or a parenthesized list of errors/exceptions. If no names of errors or exceptions are supplied, it will handle *all* errors and exceptions.
+
+Note that there has to be at least one `except` clause associated with every `try` clause. Otherwise, what's the point of having a try block?
+
+If any error or exception is not handled, then the default Python handler is called which just stops the execution of the program and prints an error message. We have already seen this in action above.
+
+You can also have an `else` clause associated with a `try..except` block. The `else` clause is executed if no exception occurs.
+
+In the next example, we will also see how to get the exception object so that we can retrieve additional information.
+
+## Raising Exceptions
+
+You can *raise* exceptions using the `raise` statement by providing the name of the error/exception and the exception object that is to be *thrown*.
+
+The error or exception that you can raise should be a class which directly or indirectly must be a derived class of the `Exception` class.
+
+~~~python
+#!/usr/bin/python
+# Filename: raising.py
+
+class ShortInputException(Exception):
+    '''A user-defined exception class.'''
+    def __init__(self, length, atleast):
+        Exception.__init__(self)
+        self.length = length
+        self.atleast = atleast
+
+try:
+    text = input('Enter something --> ')
+    if len(text) < 3:
+        raise ShortInputException(len(text), 3)
+    # Other work can continue as usual here
+except EOFError:
+    print('Why did you do an EOF on me?')
+except ShortInputException as ex:
+    print('ShortInputException: The input was {0} long, expected at least {1}'\
+          .format(ex.length, ex.atleast))
+else:
+    print('No exception was raised.')
+~~~
+
+Output:
+
+~~~
+$ python raising.py
+Enter something --> a
+ShortInputException: The input was 1 long, expected at least 3
+
+$ python raising.py
+Enter something --> abc
+No exception was raised.
+~~~
+
+How It Works:
+
+Here, we are creating our own exception type. This new exception type is called `ShortInputException`. It has two fields - `length` which is the length of the given input, and `atleast` which is the minimum length that the program was expecting.
+
+In the `except` clause, we mention the class of error which will be stored `as` the variable name to hold the corresponding error/exception object. This is analogous to parameters and arguments in a function call. Within this particular `except` clause, we use the`length` and `atleast` fields of the exception object to print an appropriate message to the user.
+
+## Try .. Finally 
+
+Suppose you are reading a file in your program. How do you ensure that the file object is closed properly whether or not an exception was raised? This can be done using the `finally` block. Note that you can use an `except` clause along with a `finally` block for the same corresponding `try` block. You will have to embed one within another if you want to use both.
+
+~~~python
+#!/usr/bin/python
+# Filename: finally.py
+
+import time
+
+try:
+    f = open('poem.txt')
+    while True: # our usual file-reading idiom
+        line = f.readline()
+        if len(line) == 0:
+            break
+        print(line, end='')
+        time.sleep(2) # To make sure it runs for a while
+except KeyboardInterrupt:
+    print('!! You cancelled the reading from the file.')
+finally:
+    f.close()
+    print('(Cleaning up: Closed the file)')
+~~~
+
+Output:
+
+~~~
+$ python finally.py
+Programming is fun
+When the work is done
+if you wanna make your work also fun:
+!! You cancelled the reading from the file.
+(Cleaning up: Closed the file)
+~~~
+
+How It Works:
+
+We do the usual file-reading stuff, but we have arbitrarily introduced sleeping for 2 seconds after printing each line using the `time.sleep` function so that the program runs slowly (Python is very fast by nature). When the program is still running, press `ctrl-c` to interrupt/cancel the program.
+
+Observe that the `KeyboardInterrupt` exception is thrown and the program quits. However, before the program exits, the finally clause is executed and the file object is always closed.
+
+## The with statement 
+
+Acquiring a resource in the `try` block and subsequently releasing the resource in the `finally` block is a common pattern. Hence, there is also a `with` statement that enables this to be done in a clean manner:
+
+~~~python
+#!/usr/bin/python
+# Filename: using_with.py
+
+with open("poem.txt") as f:
+    for line in f:
+        print(line, end='')
+~~~
+
+How It Works:
+
+The output should be same as the previous example. The difference here is that we are using the `open` function with the `with` statement - we leave the closing of the file to be done automatically by `with open`.
+
+What happens behind the scenes is that there is a protocol used by the `with` statement. It fetches the object returned by the `open` statement, let's call it "thefile" in this case.
+
+It *always* calls the `thefile.__enter__` function before starting the block of code under it and *always* calls `thefile.__exit__` after finishing the block of code.
+
+So the code that we would have written in a `finally` block should be taken care of automatically by the `__exit__`method. This is what helps us to avoid having to use explicit `try..finally` statements repeatedly.
+
+More discussion on this topic is beyond scope of this book, so please refer [PEP 343](http://www.python.org/dev/peps/pep-0343/) for a comprehensive explanation.
+
+## Summary 
+
+We have discussed the usage of the `try..except` and `try..finally` statements. We have seen how to create our own exception types and how to raise exceptions as well.
+
+Next, we will explore the Python Standard Library.

+ 180 - 0
16-standard-library.pd

@@ -0,0 +1,180 @@
+# Standard Library
+
+The Python Standard Library contains a huge number of useful modules and is part of every standard Python installation. It is important to become familiar with the Python Standard Library since many problems can be solved quickly if you are familiar with the range of things that these libraries can do.
+
+We will explore some of the commonly used modules in this library. You can find complete details for all of the modules in the Python Standard Library in the ['Library Reference' section](http://docs.python.org/3.0/library/) of the documentation that comes with your Python installation.
+
+Let us explore a few useful modules.
+
+Note
+
+:   If you find the topics in this chapter too advanced, you may skip this chapter. However, I highly recommend coming back to this chapter when you are more comfortable with programming using Python.
+
+## sys module 
+
+The `sys` module contains system-specific functionality. We have already seen that the `sys.argv` list contains the command-line arguments.
+
+Suppose we want to check the version of the Python command being used so that, say, we want to ensure that we are using at least version 3. The `sys` module gives us such functionality.
+
+~~~
+>>> import sys
+>>> sys.version_info
+(3, 0, 0, 'beta', 2)
+>>> sys.version_info[0] >= 3
+True
+~~~
+
+How It Works:
+
+The `sys` module has a `version_info` tuple that gives us the version information. The first entry is the major version. We can check this to, for example, ensure the program runs only under Python 3.0:
+
+~~~python
+#!/usr/bin/python
+# Filename: versioncheck.py
+import sys, warnings
+if sys.version_info[0] < 3:
+    warnings.warn("Need Python 3.0 for this program to run",
+        RuntimeWarning)
+else:
+    print('Proceed as normal')
+~~~
+
+Output:
+
+~~~
+$ python2.5 versioncheck.py
+versioncheck.py:6: RuntimeWarning: Need Python 3.0 for this program to run
+  RuntimeWarning)
+
+$ python3 versioncheck.py
+Proceed as normal
+~~~
+
+How It Works:
+
+We use another module from the standard library called `warnings` that is used to display warnings to the end-user. If the Python version number is not at least 3, we display a corresponding warning.
+
+## logging module 
+
+What if you wanted to have some debugging messages or important messages to be stored somewhere so that you can check whether your program has been running as you would expect it? How do you "store somewhere" these messages? This can be achieved using the `logging` module.
+
+~~~python
+#!/usr/bin/python
+# Filename: use_logging.py
+import os, platform, logging
+
+if platform.platform().startswith('Windows'):
+    logging_file = os.path.join(os.getenv('HOMEDRIVE'), os.getenv('HOMEPATH'), 'test.log')
+else:
+    logging_file = os.path.join(os.getenv('HOME'), 'test.log')
+
+print("Logging to", logging_file)
+
+logging.basicConfig(
+    level=logging.DEBUG,
+    format='%(asctime)s : %(levelname)s : %(message)s',
+    filename = logging_file,
+    filemode = 'w',
+)
+
+logging.debug("Start of the program")
+logging.info("Doing something")
+logging.warning("Dying now")
+~~~
+
+Output:
+
+~~~
+$python use_logging.py
+Logging to C:\Users\swaroop\test.log
+~~~
+
+If we check the contents of `test.log`, it will look something like this:
+
+~~~
+2008-09-03 13:18:16,233 : DEBUG : Start of the program
+2008-09-03 13:18:16,233 : INFO : Doing something
+2008-09-03 13:18:16,233 : WARNING : Dying now
+~~~
+
+How It Works:
+
+We use three modules from the standard library - the `os` module for interacting with the operating system, the `platform` module for information about the platform i.e. the operating system and the `logging` module to *log* information.
+
+First, we check which operating system we are using by checking the string returned by `platform.platform()` (for more information, see `import platform; help(platform)`). If it is Windows, we figure out the home drive, the home folder and the filename where we want to store the information. Putting these three parts together, we get the full location of the file. For other platforms, we need to know just the home folder of the user and we get the full location of the file.
+
+We use the `os.path.join()` function to put these three parts of the location together. The reason to use a special function rather than just adding the strings together is because this function will ensure the full location matches the format expected by the operating system.
+
+We configure the `logging` module to write all the messages in a particular format to the file we have specified.
+
+Finally, we can put messages that are either meant for debugging, information, warning or even critical messages. Once the program has run, we can check this file and we will know what happened in the program, even though no information was displayed to the user running the program.
+
+## urllib and json modules 
+
+How much fun would it be if we could write our own program that will get search results from the web? Let us explore that now.
+
+This can be achieved using a few modules. First is the `urllib` module that we can use to fetch any webpage from the internet. We will make use of Yahoo! Search to get the search results and luckily they can give us the results in a format called JSON which is easy for us to parse because of the built-in `json` module in the standard library.
+
+**TODO** Use some other example that doesn't use YUI API, maybe twitter firehose, etc.
+
+~~~python
+#!/usr/bin/python
+# Filename: yahoo_search.py
+
+import sys
+if sys.version_info[0] != 3:
+    sys.exit('This program needs Python 3.0')
+
+import json
+import urllib, urllib.parse, urllib.request, urllib.response
+
+# Get your own APP ID at http://developer.yahoo.com/wsregapp/
+YAHOO_APP_ID = 'jl22psvV34HELWhdfUJbfDQzlJ2B57KFS_qs4I8D0Wz5U5_yCI1Awv8.lBSfPhwr'
+SEARCH_BASE = 'http://search.yahooapis.com/WebSearchService/V1/webSearch'
+
+class YahooSearchError(Exception):
+    pass
+
+# Taken from http://developer.yahoo.com/python/python-json.html
+def search(query, results=20, start=1, **kwargs):
+    kwargs.update({
+        'appid': YAHOO_APP_ID,
+        'query': query,
+        'results': results,
+        'start': start,
+        'output': 'json'
+    })
+    url = SEARCH_BASE + '?' + urllib.parse.urlencode(kwargs)
+    result = json.load(urllib.request.urlopen(url))
+    if 'Error' in result:
+        raise YahooSearchError(result['Error'])
+    return result['ResultSet']
+
+query = input('What do you want to search for? ')
+for result in search(query)['Result']:
+    print("{0} : {1}".format(result['Title'], result['Url']))
+~~~
+
+Output:
+
+**TODO**
+
+How It Works:
+
+We can get the search results from a particular website by giving the text we are searching for in a particular format. We have to specify many options which we combine using `key1=value1&key2=value2` format which is handled by the `urllib.parse.urlencode()`> function.
+
+So for example, open [this link in your web browser](http://search.yahooapis.com/WebSearchService/V1/webSearch?query=byte+of+python&appid=jl22psvV34HELWhdfUJbfDQzlJ2B57KFS_qs4I8D0Wz5U5_yCI1Awv8.lBSfPhwr&results=20&start=1&output=json) and you will see 20 results, starting from the first result, for the words "byte of python", and we are asking for the output in JSON format.
+
+We make a connection to this URL using the `urllib.request.urlopen()` function and pass that file handle to `json.load()` which will read the content and simultaneously convert it to a Python object. We then loop through these results and display it to the end-user.
+
+## Module of the Week Series 
+
+There is much more to be explored in the standard library such as [debugging](http://docs.python.org/dev/library/pdb.html), [handling command line options](http://docs.python.org/3.0/library/getopt.html), [regular expressions](http://www.diveintopython.org/regular_expressions/index.html) and so on.
+
+The best way to further explore the standard library is to read Doug Hellmann's excellent [Python Module of the Week](http://www.doughellmann.com/projects/PyMOTW/) series or reading the [Python documentation](http://docs.python.org/py3k/).
+
+## Summary 
+
+We have explored some of the functionality of many modules in the Python Standard Library. It is highly recommended to browse through the [Python Standard Library documentation](http://docs.python.org/py3k/library/index.html) to get an idea of all the modules that are available.
+
+Next, we will cover various aspects of Python that will make our tour of Python more *complete*.

+ 25 - 0
fabfile.py

@@ -67,6 +67,31 @@ MARKDOWN_FILES = [
         'slug': "python_en-data_structures",
         'title': "Python : Data Structures",
     },
+    {
+        'file': '12-problem-solving.pd',
+        'slug': "python_en-problem_solving",
+        'title': "Python : Problem Solving",
+    },
+    {
+        'file': '13-oop.pd',
+        'slug': "python_en-object_oriented_programming",
+        'title': "Python : Object Oriented Programming",
+    },
+    {
+        'file': '14-io.pd',
+        'slug': "python_en-input_output",
+        'title': "Python : Input Output",
+    },
+    {
+        'file': '15-exceptions.pd',
+        'slug': "python_en-exceptions",
+        'title': "Python : Exceptions",
+    },
+    {
+        'file': '16-standard-library.pd',
+        'slug': "python_en-standard_library",
+        'title': "Python : Standard Library",
+    },
 ]