This site is not of my creation but it is the type of website I’ve wished for for quite a while and have considered creating more than once. Project Euler hosts a series of math / computer programming problems that let a coder test his or her skills. As of 4/16/07, I’ve completed the first 14 problems.
If you are a UNIX/Linux user of any kind, I highly recommend reading Eric S. Raymond’s The Art of UNIX Programming. While I was expecting his book to be fairly one-sided about the virtues of UNIX and the shortcomings of everything else, I found the entire book to be well-balanced, informative, and very readable. TAUP could easily be used as a text for a programming class, but it’s really more of a “philosophy of programming” book. This book is filled with tons of quotable material, so I will resist the urge to make a quote-fest of this book review…
Raymond begins with a solid chapter on the Philosophy behind UNIX. He provides a number of great guiding principles for developing smart, streamlined applications. Where he could be abstract and vague, he provides concrete, usable advice. One of the great things about the book is his ample use of quotations from other UNIX gurus. From Doug McIlroy‘s A Quarter Century of Unix:
This is the Unix philosophy: Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface.
He also quotes Rob Pike on his 6 rules of C programming. I found the last two to be especially poignant:
Rule 5. Data dominates. If you’ve chosen the right data structures and organized things well, the algorithms will almost always be self-evident. Data structures, not algorithms, are central to programming.
Rule 6. There is no Rule 6.
Raymond goes on to compare and contrast the major operating systems of the past 20 years, including VMS, MacOS, OS/2, Windows, BeOS, MVS, VM/CMS, and Linux. He provides a framework and vocabulary for discussing OSes. Concepts like multitasking, process-spawning, file formats (e.g. textual vs. binary), and internal system boundaries differ greatly from OS to OS and have profound effects on the end user experience. Again, Raymond covers fairly academic material, making rigorous arguments using carefully defined terms. But he presents the material in a very novel and personal way, making the book feel less like a textbook and more like a pleasure read.
Once we understand the type of development environments various OSes can offer us, Raymond begins to describe criteria which we can use to set quality software apart from average software, like compactness and orthogonality. Compact software has the property that it can fit conceptually inside a human’s head. Orthogonal software has the property that operations are atomic and have no unexpected side effects; they change one thing without affecting others. Often, the concepts for good software design are best-illustrated by example, and Raymond provides many such examples to drive each point home. One of my favorite things about this material is that it has changed my thinking about design/architectural elements in my own programs.
Again, I’ll avoid the urge to summarize every chapter, as much as I’d like to. There is something to be said for letting the next reader get as much out of the book as I did. There are, however, a couple other sections of the book that I felt were compelling and deserve discussion.
One of the more enjoyable sections of the book for me was that on Unix Interface Design Patterns. Those of us who have taken a software engineering class may already have been exposed to some of the popular design patterns, so most of the vocabulary is familiar. Raymond describes patterns like The Filter Pattern, of which grep is a good example. Among other patterns, he also describes The Cantrip Pattern, The Sink Pattern, and The Compiler Pattern. The Cantrip Pattern is the simplest Unix design pattern as it has no inputs or outputs; its behavior is only affected by startup conditions. Classic examples of the Cantrip Pattern include rm and touch. Raymond reminds us to resist the temptation to write more interactive programs when a Cantrip will suffice because the program will lose scriptability.
In a further discussion of the software complexity idea, Raymond uses his “Tale of Five Editors” to explore the trade-offs between interface and implementation complexity. The five editors he compares and contrasts are: ed, vi, Sam, Emacs (my personal preference), and Wily, an editor I had neither used nor heard of. Raymond gives accurate, matter-of-fact descriptions of each of the editors and shows how . When ultimately arriving at the question of the Right Size for Software, Raymond leaves us with the Rule of Parsimony: “Write a big program only when it is clear by demonstration that nothing else will do.”
For every interesting part of the book that I mentioned in this review, there are 5 or 6 that are equally thought-provoking and affirming to those of us that embrace the *nix culture. I can’t recommend this book any stronger to any hacker or fan of Unix.
First Things First
8 Reasons to Use Python
- Lists, Tuples, and Dictionaries
- Intuitive Looping Techniques
- Text Processing and String Operations
- Exception Handling
- Tons of Standard Libraries
- Working with Files
- Simple HTTP/Web Services
1. Lists, Tuples, Dictionaries
- Lists – basically arrays (actually linked lists), can contain multiple data types, accessible by index, can be used as a stack or queue, can be sliced/concatenated
- append, insert, remove, pop, count, sort, reverse
- Tuple – statically defined, can be accessed by index but cannot be modified after instantiation, can be used as dictionary keys
- Dictionary – accessed by key, value pairs, constant lookup time, unordered in memory
- keys, items, del
2. Intuitive Looping Techniques
- for i in range(10):
- for name in [‘karl’, ‘lenny’, ‘barney’, ‘moe’]:
- for i, j in enumerate(myList):
print i, j
- for k, v in myDictionary.iteritems():
print k + “‘s value is”, v
- questions = [‘who’, ‘what’, ‘when’, ‘where’]
answers = [‘Mr. Green’, ‘revolver’, ’11:00′, ‘Lounge’]
for q, a in zip(questions, answers):
print q + “:”, a
3. Text Processing and String Operations
- Strings can be indexed like C, but substrings can also be specified with slice notation
- s, s[:2], s[4:], s[-3:],…
- Standard string library provides dozens of useful functions
- split, join, lower, upper, replace, title, isalnum, isdigit,
whitespace, punctuation, printable, etc., etc.
- Very easy to implement “filter-type” programs like grep
- input = sys.stdin.readlines()
- makes parsing formatted text files trivial, e.g. Apache log parsing
4. Exception Handling
Very easy to catch exceptions and run separate code for error handling routines
something = that_could + produce_an_exception
this_code = gets_run( only_if_exception_thrown )
5. Simple Sockets
6. Tons of Standard Libraries
- Python ships with over 300 standard libraries for programmers to use:
- >>> help()
- Just to name a few:
- calendar, Cookie, cookielib, datetime, distutils, htmllib,
HTMLParser, httplib, math, md5, optparse, os, random, re,
smtplib, socket, string, struct, sys, time, urllib, urlparse,
7. Working with Files
- Reading and writing files is very simple in Python
- open(), read(), write(), close()
- os library provides many useful function calls for filesystem access
- chdir, chmod, execv, getcwd, listdir, mkdir, remove, rmdir,
8. Simple HTTP / Web Services
- Almost everything provided to the programmer by httplib and other HTTP/URL libraries
Putting it all Together
I am definitely open to discussion on this topic as it’s one that’s close to my heart. If you’re a Perl advocate or would otherwise like to make a case against the use of Python, I strongly encourage you to send me an email. I am more than happy to try to defend it 🙂
Result: Q high
Hands required: 1
I’ve added code that logs each alert to a local database so that 1) duplicate alerts aren’t sent, even if the the stories are posted days or weeks apart, and 2) you can easily check which alerts have been sent historically.
Additionally I added a debug mode such that if you run
> ./feedMonitor.py --console
the script prints to the console only and doesn’t send the email or log to the DB, so that you can see what types of alerts might be sent with the present script options.
I recently wrote a Python script which monitors RSS feeds for user-specified keywords. The need for this script arose from the large number of security websites and mailing lists I monitor for work-related posts. And you know how big a fan of automation I am…
All you need to run this script is Python and a SMTP server to send messages. If you know of an open SMTP relay feel free to use that, but you may find it easier to simply install Sendmail locally. The script is configured by default to send messages to
localhost, so if you’re going to go the open relay route, you’ll need to configure the script accordingly.
For now, it is probably best to set the script up to run as a cron job and have the script run automatically every 10-30 minutes or so, depending on how urgently you need the alerts to come. Eventually, I will add to the script the ability to log which alerts were mailed in a SQL database so that 1) you don’t receive duplicate alerts, and 2) you can have a record of which alerts have been mailed historically.
Stay tuned for updates to the script, and feel free to contact me if you have any questions.
East Bay Psychotherapist
Licensed Clinical Social Worker provides psychotherapy and counseling services for couples and individuals in the East Bay Area.