How to get current working directory in Python
import os os.getcwd() 'C:\\Python25'
import os os.getcwd() 'C:\\Python25'
sofeng@tortoise:~$ sudo apt-get install flashplugin-nonfree Reading package lists... Done Building dependency tree Reading state information... Done Package flashplugin-nonfree is not available, but is referred to by another package. This may mean that the package is missing, has been obsoleted, or is only available from another source E: Package flashplugin-nonfree has no installation candidateIt appears as if I didn't add the multiverse repository. But I did. It turns out I didn't press the "Reload" button after adding the new repositories. hmmph. went back and did that and everything worked good.

If you have more than one window in your emacs session, it's nice to make the active window stand out by changing the color of the mode line. In my standard Windows emacs installation, the active window's mode line is gray and the inactive window's is light grey. This makes it difficult to distinguish which window is active. By adding the following line to your .emacs file, you can make the active window's mode line blue instead of gray.
(set-face-background 'modeline "#4477aa")
It'd be nice if I could make a thin blue border surrounding the window like in Eclipse, but I couldn't figure out how to do that. The commented-out lines in the screenshot didn't do the trick.
I am trying to search through various text and highlight certain search terms within that text using HTML markup. As an example, if I take a paragraph of text from Paul Prescod's essay, I would like to highlight the search terms "lisp", "python", "perl", "java", and "C" each in different colors. My first attempt at this problem looked somthing like:
for sentence in re.split(r"[?.]\s+", text):
match = re.search(r"\blisp\b", sentence, re.I)
if match:
color = 'red'
else:
match = re.search(r"\bpython\b", sentence, re.I)
if match:
color = 'blue'
else:
match = re.search(r"\bperl\b", sentence, re.I)
if match:
color = 'orange'
I didn't finish it because, not only is it ugly and verbose, it doesn't do what I want. Instead of matching all the search terms, it only matches the first one in each sentence. Fortunately, I took some time to rethink the problem (i.e. search the internet (this thread on the Python mailing list was helpful (I guess my Perl background is still showing) as was this article which I previously referenced. (hmmm, this is starting to look like Lisp.))) and made a prettier (and correct) version using my new favorite regular expression method, finditer, and the MatchObject's lastindex attribute. Here is the working example:
import re
COLOR = ['red', 'blue', 'orange', 'violet', 'green']
text = """Graham says that Perl is cooler than Java and Python than Perl. In some circles, maybe. Graham uses the example of Slashdot, written in Perl. But what about Advogato, written in C? What about all of the cool P2P stuff being written in all three of the languages? Considering that Perl is older than Java, and was at one time the Next Big Language, I think you would have a hard time getting statistical evidence that programmers consider Perl "cooler" than Java, except perhaps by virtue of the fact that Java has spent a few years as the "industry standard" (and is thus uncool for the same reason that the Spice Girls are uncool) and Perl is still "underground" (and thus cool, for the same reason that ambient is cool). Python is even more "underground" than Perl (and thus cooler?). Maybe all Graham has demonstrated is that proximity to Lisp drives a language underground. Except that he's got the proximity to Lisp argument backwards too."""
regex = re.compile(r"(\blisp\b)|(\bpython\b)|(\bperl\b)|(\bjava\b)|(\bc\b)", re.I)
i = 0; output = "<html>"
for m in regex.finditer(text):
output += "".join([text[i:m.start()],
"<strong><span style='color:%s'>" % COLOR[m.lastindex-1],
text[m.start():m.end()],
"</span></strong>"])
i = m.end()
print "".join([output, text[m.end():], "</html>"])
finditer. For each match, non-matching text and matching text surrounded with the HTML <span> tag are appended to the output string. start() and end() return the indices to the start and end positions of the matching text. The color of the text is determined by using lastindex to index into a list of colors. lastindex is the index of the group of the last match. So, it is "1" if "lisp" is matched, "2" if "python" is matched, "3" if "perl" is matched, and so on. I need to subtract 1 because the list indexing starts at 0. The last line adds on the rest of the non-matching text, and prints it. When viewed in a browser, it looks something like this:Graham says that Perl is cooler than Java and Python than Perl. In some circles, maybe. Graham uses the example of Slashdot, written in Perl. But what about Advogato, written in C? What about all of the cool P2P stuff being written in all three of the languages? Considering that Perl is older than Java, and was at one time the Next Big Language, I think you would have a hard time getting statistical evidence that programmers consider Perl "cooler" than Java, except perhaps by virtue of the fact that Java has spent a few years as the "industry standard" (and is thus uncool for the same reason that the Spice Girls are uncool) and Perl is still "underground" (and thus cool, for the same reason that ambient is cool). Python is even more "underground" than Perl (and thus cooler?). Maybe all Graham has demonstrated is that proximity to Lisp drives a language underground. Except that he's got the proximity to Lisp argument backwards too.
Fredrik Lundh wrote a good article called Using Regular Expressions for Lexical Analysis which explains how to use Python regular expressions to read an input string and group characters into lexical units, or tokens. The author's first group of examples read in a simple expression, "b = 2 + a*10", and output strings classified as one of three token types: symbols (e.g. a and b), integer literals (e.g. 2 and 10), and operators (e.g. =, +, and *). His first three examples use the findall method and his fourth example uses the undocumented scanner method from the re module. Here is the example code from the fourth example. Note that the "1" in the first column of the results corresponds to the integer literals token group, "2" corresponds to the symbols group, and "3" to the operators group.
import re
expr = "b = 2 + a*10"
pos = 0
pattern = re.compile("\s*(?:(\d+)|(\w+)|(.))")
scan = pattern.scanner(expr)
while 1:
m = scan.match()
if not m:
break
print m.lastindex, repr(m.group(m.lastindex))
2 'b' 3 '=' 1 '2' 3 '+' 2 'a' 3 '*' 1 '10'
Since this article was dated 2002, and the author was using Python 2.0, I wondered if this was the most current approach. The author notes that recent versions (i.e. version 2.2 or later) of Python allow you to use the finditer method which uses an internal scanner object. Using finditer makes the example code much simpler. Here is Fredrik's example using finditer:
import re
expr = "b = 2 + a*10"
regex = re.compile("\s*(?:(\d+)|(\w+)|(.))")
for m in regex.finditer(expr):
print m.lastindex, repr(m.group(m.lastindex))
Running it produces the same results as the original.
timing module he used for performance profiling is no longer included in Python 2.5. So I went to the Python documentation and found that there are 3 profilers currently included with Python 2.5: profile, cProfile, and hotshot. (See 25. The Python Profilers in the Library Reference for more info.) I made a quick choice to use cProfile and tried out the fastest and slowest of the 6 methods. Below is the code and the results. It turns out, for me, the second method is not as significantly different as the original test. (Maybe because this was improved between Python 2.2 and 2.5? I'm guessing.) However, it is much more concise, and appears to be the more elegant, declarative approach that I have founnd myself reading about recently.import cProfile
BIG_NUMBER = 1000000
def method1():
mystring = ''
for i in xrange(BIG_NUMBER):
mystring += `i`
return mystring
def method2():
return ''.join([`i` for i in xrange(BIG_NUMBER)])
cProfile.run('method1()')
cProfile.run('method2()')
$ python test.py
3 function calls in 2.515 CPU seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 2.515 2.515 <string>:1(<module>)
1 2.515 2.515 2.515 2.515 test.py:5(method1)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
4 function calls in 1.734 CPU seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 1.734 1.734 <string>:1(<module>)
1 1.609 1.609 1.734 1.734 test.py:11(method2)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.125 0.125 0.125 0.125 {method 'join' of 'str' objects}I often process text line by line using the splitlines() method with a for loop. This works great most of the time, however, sometimes, the text is not neatly divisible into lines, or, I need to match multiple items per line. This is where the re module's finditer function can help. finditer returns an iterator over all non-overlapping matches for the regular expression pattern in the string. (See docs.) It is a powerful tool for text processing and one that I don't use often enough.
Here is a simple example which demonstrates the use of finditer. It reads in a page of html text, finds all the occurrences of the word "the" and prints "the" and the following word. It also prints the character position of each match using the MatchObject's start() method. (See docs.) Note that, for simplicity, I didn't mess with the HTML tags at all. I just pretended it was plain text. Oh, and the example text is taken from Steve Yegge's article: How To Make a Funny Talk Title Without Using The Word "Weasel"
Python code:
import re
import urllib2
html = urllib2.urlopen('http://steve-yegge.blogspot.com/2007/08/how-to-make-funny-talk-title-without.html').read()
pattern = r'\b(the\s+\w+)\s+'
regex = re.compile(pattern, re.IGNORECASE)
for match in regex.finditer(html):
print "%s: %s" % (match.start(), match.group(1))
Results:
1301: The Word 12291: The Word 13367: the cut 14025: the car 15050: the free 15513: the third 15558: the sessions 15617: the ONLY 15684: the ground 15911: the OSI 15933: The Attack 16051: The gist 16115: the term 16178: the creator 16741: the thing 16850: the same 16877: the thing 16942: the next 17131: the talk 17374: the room 17727: the hell 17782: the term 17830: the 1980s 18083: the whole 18158: the same 18230: the mountain 18305: the seat 18537: The pro 18718: the banner 18928: the poor 19006: the midst 19223: the buzzwagon 19326: the source 19437: the OSI 19855: the OSI 19927: the other 20055: the Ten 20404: The 22 20517: the OSI 20616: the book 21098: the collective 21553: the proposed 21681: the Five 21932: the nearest 22690: The rest 22858: the entertaining 23255: the crap 23561: the next 23661: the registration 23963: the registration 24114: the restaurant 24289: the people 24456: the second 24597: the current 24871: The Style 24929: the front 25047: the curtain 25132: the movie 25159: The hospital 25249: the night 25881: the way 25892: the rear 25927: the crowd 26194: the podium 26262: the front 26521: the door 26593: the front 26622: The economist 27128: the thing 27228: The next 27290: the Pirate 27409: the material 27461: the crowd 27621: the next 27916: The technician 28084: the way 28487: the technician 28735: the exciting 35709: The Next 36587: The Pinocchio 45436: the Kingdom 45679: The Truth 51623: the same 52526: The Word
$ fc-listURxvt*font: xft:Bitstream Vera Sans Mono:size=12 Urxvt*boldFont: xft:Bitstream Vera Sans Mono:size=12:style=Bold
$ urxvtBitstream Charter:style=Bold Bitstream Charter:style=Bold Italic Bitstream Charter:style=Italic Bitstream Charter:style=Regular Bitstream Vera Sans Mono:style=Bold Bitstream Vera Sans Mono:style=Bold Oblique Bitstream Vera Sans Mono:style=Oblique Bitstream Vera Sans Mono:style=Roman Bitstream Vera Sans:style=Bold Bitstream Vera Sans:style=Bold Oblique Bitstream Vera Sans:style=Oblique Bitstream Vera Sans:style=Roman Bitstream Vera Serif:style=Bold Bitstream Vera Serif:style=Roman Charter:style=Bold Charter:style=Bold Italic Charter:style=Italic Charter:style=Regular Clean:style=Regular ClearlyU Alternate Glyphs:style=Regular ClearlyU PUA:style=Regular ClearlyU:style=Regular Courier 10 Pitch:style=Bold Courier 10 Pitch:style=Bold Italic Courier 10 Pitch:style=Italic Courier 10 Pitch:style=Regular Courier:style=Bold Courier:style=Bold Italic Courier:style=Bold Oblique Courier:style=Italic Courier:style=Oblique Courier:style=Regular Cursor:style=Regular Fixed:style=Bold Fixed:style=Bold SemiCondensed Fixed:style=ja Fixed:style=ko Fixed:style=Oblique Fixed:style=Oblique SemiCondensed Fixed:style=Regular Fixed:style=SemiCondensed Helvetica:style=Bold Helvetica:style=Bold Oblique Helvetica:style=Oblique Helvetica:style=Regular Lucida:style=Sans Lucida:style=Sans Bold Lucida:style=Sans Bold Italic Lucida:style=Sans Italic LucidaBright:style=Italic LucidaBright:style=Regular LucidaTypewriter:style=Sans LucidaTypewriter:style=Sans Bold Luxi Mono:style=Bold Luxi Mono:style=Bold Oblique Luxi Mono:style=Oblique Luxi Mono:style=Regular Luxi Sans:style=Bold Luxi Sans:style=Bold Oblique Luxi Sans:style=Oblique Luxi Sans:style=Regular Luxi Serif:style=Bold Luxi Serif:style=Bold Oblique Luxi Serif:style=Oblique Luxi Serif:style=Regular New Century Schoolbook:style=Bold New Century Schoolbook:style=Bold Italic New Century Schoolbook:style=Italic New Century Schoolbook:style=Regular Newspaper:style=Regular Terminal:style=Bold Terminal:style=Regular Times:style=Bold Times:style=Bold Italic Times:style=Italic Times:style=Regular Utopia:style=Bold Utopia:style=Bold Italic Utopia:style=Italic Utopia:style=Regular