Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/app/static/doc/myosa/ch008_a-standalone-python-program-for-reading-etexts.xhtml
diff options
context:
space:
mode:
Diffstat (limited to 'app/static/doc/myosa/ch008_a-standalone-python-program-for-reading-etexts.xhtml')
-rw-r--r--app/static/doc/myosa/ch008_a-standalone-python-program-for-reading-etexts.xhtml244
1 files changed, 0 insertions, 244 deletions
diff --git a/app/static/doc/myosa/ch008_a-standalone-python-program-for-reading-etexts.xhtml b/app/static/doc/myosa/ch008_a-standalone-python-program-for-reading-etexts.xhtml
deleted file mode 100644
index 4afdb21..0000000
--- a/app/static/doc/myosa/ch008_a-standalone-python-program-for-reading-etexts.xhtml
+++ /dev/null
@@ -1,244 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
- "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml"><body><h1> A Standalone Python Program For Reading Etexts
-</h1>
-<h2>The Program
- <br/></h2>
-<p>Our example program is based on the first Activity I wrote, <strong>Read Etexts</strong>.&#160; This is a program for reading free e-books.
- <br/></p>
-<p>The oldest and best source of free e-books is a website called <em>Project Gutenberg</em> <a href="http://www.gutenberg.org/wiki/Main_Page).">(</a><a href="http://www.gutenberg.org/wiki/Main_Page" target="_top">http://www.gutenberg.org/wiki/Main_Page</a>).&#160; They create books in plain text format, in other words the kind of file you could make if you typed a book into Notepad and hit the Enter key at the end of each line.&#160; They have thousands of books that are out of copyright, including some of the best ever written.&#160; Before you read further go to that website and pick out a book that interests you.&#160; Check out the "Top 100" list to see the most popular books and authors.
-</p>
-<p>The program we're going to create will read books in plain text format only.
-</p>
-<p>There is a Git repository containing all the code examples in this book.&#160; Once you have Git installed you can copy the repository to your computer with this command:
-</p>
-<pre>git clone git://git.sugarlabs.org/\
-myo-sugar-activities-examples/mainline.git</pre>
-<p>The code for our standalone Python program will be found in the directory <strong>Make_Standalone_Python</strong> in a file named <strong>ReadEtexts.py</strong>.&#160; It looks like this:
- <br/></p>
-<pre>#! /usr/bin/env python
-import sys
-import os
-import zipfile
-import pygtk
-import gtk
-import getopt
-import pango
-
-page=0
-PAGE_SIZE = 45
-
-class ReadEtexts():
-
- def keypress_cb(self, widget, event):
- "Respond when the user presses one of the arrow keys"
- keyname = gtk.gdk.keyval_name(event.keyval)
- if keyname == 'plus':
- self.font_increase()
- return True
- if keyname == 'minus':
- self.font_decrease()
- return True
- if keyname == 'Page_Up' :
- self.page_previous()
- return True
- if keyname == 'Page_Down':
- self.page_next()
- return True
- if keyname == 'Up' or keyname == 'KP_Up' \
- or keyname == 'KP_Left':
- self.scroll_up()
- return True
- if keyname == 'Down' or keyname == 'KP_Down' \
- or keyname == 'KP_Right':
- self.scroll_down()
- return True
- return False
-
- def page_previous(self):
- global page
- page=page-1
- if page &lt; 0: page=0
- self.show_page(page)
- v_adjustment = \
- self.scrolled_window.get_vadjustment()
- v_adjustment.value = v_adjustment.upper - \
- v_adjustment.page_size
-
- def page_next(self):
- global page
- page=page+1
- if page &gt;&#8286;= len(self.page_index): page=0
- self.show_page(page)
- v_adjustment = \
- self.scrolled_window.get_vadjustment()
- v_adjustment.value = v_adjustment.lower
-
- def font_decrease(self):
- font_size = self.font_desc.get_size() / 1024
- font_size = font_size - 1
- if font_size &lt; 1:
- font_size = 1
- self.font_desc.set_size(font_size * 1024)
- self.textview.modify_font(self.font_desc)
-
- def font_increase(self):
- font_size = self.font_desc.get_size() / 1024
- font_size = font_size + 1
- self.font_desc.set_size(font_size * 1024)
- self.textview.modify_font(self.font_desc)
-
- def scroll_down(self):
- v_adjustment = \
- self.scrolled_window.get_vadjustment()
- if v_adjustment.value == v_adjustment.upper - \
- v_adjustment.page_size:
- self.page_next()
- return
- if v_adjustment.value &lt; v_adjustment.upper -\
- v_adjustment.page_size:
- new_value = v_adjustment.value + \
- v_adjustment.step_increment
- if new_value &gt; v_adjustment.upper -\
- v_adjustment.page_size:
- new_value = v_adjustment.upper -\
- v_adjustment.page_size
- v_adjustment.value = new_value
-
- def scroll_up(self):
- v_adjustment = \
- self.scrolled_window.get_vadjustment()
- if v_adjustment.value == v_adjustment.lower:
- self.page_previous()
- return
- if v_adjustment.value &gt; v_adjustment.lower:
- new_value = v_adjustment.value - \
- v_adjustment.step_increment
- if new_value &lt; v_adjustment.lower:
- new_value = v_adjustment.lower
- v_adjustment.value = new_value
-
- def show_page(self, page_number):
- global PAGE_SIZE, current_word
- position = self.page_index[page_number]
- self.etext_file.seek(position)
- linecount = 0
- label_text = '\n\n\n'
- textbuffer = self.textview.get_buffer()
- while linecount &lt; PAGE_SIZE:
- line = self.etext_file.readline()
- label_text = label_text + unicode(line,
- 'iso-8859-1')
- linecount = linecount + 1
- label_text = label_text + '\n\n\n'
- textbuffer.set_text(label_text)
- self.textview.set_buffer(textbuffer)
-
- def save_extracted_file(self, zipfile, filename):
- "Extract the file to a temp directory for viewing"
- filebytes = zipfile.read(filename)
- f = open("/tmp/" + filename, 'w')
- try:
- f.write(filebytes)
- finally:
- f.close
-
- def read_file(self, filename):
- "Read the Etext file"
- global PAGE_SIZE
-
- if zipfile.is_zipfile(filename):
- self.zf = zipfile.ZipFile(filename, 'r')
- self.book_files = self.zf.namelist()
- self.save_extracted_file(self.zf,
- self.book_files[0])
- currentFileName = "/tmp/" + self.book_files[0]
- else:
- currentFileName = filename
-
- self.etext_file = open(currentFileName,"r")
- self.page_index = [ 0 ]
- linecount = 0
- while self.etext_file:
- line = self.etext_file.readline()
- if not line:
- break
- linecount = linecount + 1
- if linecount &gt;= PAGE_SIZE:
- position = self.etext_file.tell()
- self.page_index.append(position)
- linecount = 0
- if filename.endswith(".zip"):
- os.remove(currentFileName)
-
- def destroy_cb(self, widget, data=None):
- gtk.main_quit()
-
- def main(self, file_path):
- self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
- self.window.connect("destroy", self.destroy_cb)
- self.window.set_title("Read Etexts")
- self.window.set_size_request(640, 480)
- self.window.set_border_width(0)
- self.read_file(file_path)
- self.scrolled_window = gtk.ScrolledWindow(
- hadjustment=None, vadjustment=None)
- self.textview = gtk.TextView()
- self.textview.set_editable(False)
- self.textview.set_left_margin(50)
- self.textview.set_cursor_visible(False)
- self.textview.connect("key_press_event",
- self.keypress_cb)
- buffer = self.textview.get_buffer()
- self.font_desc = pango.FontDescription("sans 12")
- font_size = self.font_desc.get_size()
- self.textview.modify_font(self.font_desc)
- self.show_page(0)
- self.scrolled_window.add(self.textview)
- self.window.add(self.scrolled_window)
- self.textview.show()
- self.scrolled_window.show()
- v_adjustment = \
- self.scrolled_window.get_vadjustment()
- self.window.show()
- gtk.main()
-
-if __name__ == "__main__":
- try:
- opts, args = getopt.getopt(sys.argv[1:], "")
- ReadEtexts().main(args[0])
- except getopt.error, msg:
- print msg
- print "This program has no options"
- sys.exit(2)
-</pre>
-<h2> Running The Program
-</h2>
-<p>To run the program you should first make it executable.&#160; You only need to do this once:
-</p>
-<pre>chmod 755 ReadEtexts.py</pre>
-<p>For this example I downloaded the file for <em>Pride and Prejudice</em>.&#160; The program will work with either of the Plain text formats, which are either uncompressed text or a Zip file.&#160; The zip file is named <strong>1342.zip</strong>, and we can read the book by running this from a terminal:
-</p>
-<pre>./ReadEtexts.py 1342.zip</pre>
-<p>This is what the program looks like in action:
-</p>
-<p><img alt="The standalone Read Etexts program in action." src="static/ActivitiesGuideSugar-ReadEtexts_01_1-en.jpg" width="646" height="503"/></p>
-<p>You can use the <em>Page Up, Page Down, Up, Down, Left</em>, and <em>Right</em> keys to navigate through the book and the '+' and '-' keys to adjust the font size.
-</p>
-<div class="objavi-forcebreak">
-</div>
-<h2>How The Program Works
-</h2>
-<p>This program reads through the text file containing the book and divides it into pages of 45 lines each.&#160; We need to do this because the <strong>gtk.TextView</strong> component we use for viewing the text would need a lot of memory to scroll through the whole book and that would hurt performance.&#160; A second reason is that we want to make reading the e-book as much as possible like reading a regular book, and regular books have pages.&#160; If a teacher assigns reading from a book she might say "read pages 35-50 for tommorow".&#160; Finally, we want this program to remember what page you stopped reading on and bring you back to that page again when you read the book next time.&#160; (The program we have so far doesn't do that yet).
-</p>
-<p>To page through the book we use <strong>random access</strong> to read the file.&#160; To understand what random access means to a file, consider a VHS tape and a DVD.&#160; To get to a certain scene in a VHS tape you need to go through all the scenes that came before it, in order.&#160; Even though you do it at high speed you still have to look at all of them to find the place you want to start watching.&#160; This is <strong>sequential access</strong>.&#160; On the other hand a DVD has chapter stops and possibly a chapter menu.&#160; Using a chapter menu you can look at any scene in the movie right away, and you can skip around as you like.&#160; This is random access, and the chapter menu is like an <strong>index</strong>.&#160; Of course you can access the material in a DVD sequentially too.
-</p>
-<p>We need random access to skip to whatever page we like, and we need an index so that we know where each page begins.&#160; We make the index by reading the entire file one line at a time.&#160; Every 45 lines we make a note of how many characters into the file we've gotten and store this information in a Python list.&#160; Then we go back to the beginning of the file and display the first page.&#160; When the program user goes to the next or previous page we figure out what the new page number will be and look in the list entry for that page.&#160; This tells us that page starts 4,200 characters into the file.&#160; We use seek() on the file to go to that character and then we read 45 lines starting at that point and load them into the TextView.
-</p>
-<p>When you run this program notice how fast it is.&#160; Python programs take longer to run a line of code than a compiled language would, but in this program it doesn't matter because the heavy lifting in the program is done by the TextView, which was created in a compiled language.&#160; The Python parts don't do that much so the program doesn't spend much time running them.
-</p>
-<p>Sugar uses Python a lot, not just for Activities but for the Sugar environment itself.&#160; You may read somewhere that using so much Python is "a disaster" for performance.&#160; Don't believe it.
-</p>
-<p>There are no slow programming languages, only slow programmers.
- <br/></p></body></html> \ No newline at end of file