Book Review: Programming Clojure
Posted: July 13, 2011 Filed under: Clojure | Tags: Clojure, functional programming, Stuart Halloway 2 CommentsIf I were to write my What I Did This Summer essay this Fall — it would be how I struggled to learn the Clojure language. Since May of this year, using book review recommendations, I’ve purchased Practical Clojure (Apress) and The Joy of Clojure (Manning).
In addition, Chas Emerick is writing Clojure Programming (O’Reilly) which, along with Clojure in Action, is about to be released in early Fall.
Stuart Halloway’s Programming Clojure (Manning) was reviewed as an excellent book, but one comment said it was older and only covered Clojure 1.0. Although I value the books I’ve purchased, unfortunately I fell for the comment that Programming Clojure was an older book. As a result I initially missed out on a very well written book that helps guide those of us who are new to functional programming (FP) into the Clojure language. In other words, this is a very good book for those of us not used to Lisp or functional programming.
As it is with many books, especially some of the advanced Python books I’ve purchased, I’ll come back to the other books I’ve purchased as references or to take advantage of another viewpoint, so I am not disappointed to have purchased them.
I’m on a mission to learn well, appreciate, and eventually use Clojure in our production environment. For me this is serious enough that I’ve enrolled in a to-be-announced, instructor-led Clojure course at http:/codelesson.com .
Having programmed in many different languages, I heartily recommend Programming Clojure as a good book overall and certainly a good first book for Clojure.
Enjoy!
Clojure: Storing Data for Later Use
Posted: July 1, 2011 Filed under: Clojure | Tags: Clojure, let, local variables, traversing sequences Leave a commentOne of the biggest hurdles I’ve encountered learning Clojure is when to traverse a sequence or merely to apply a function to it, like zipmap. The other hurdle is how to populate local variables properly in a let statement.
The program I am designing to learn Clojure reads a .csv file filled with water meter data. My goal is to extract a premise id and reading, and do something with that data. The premise id is in column 12, zero-indexed at all, and reading is at column 2, zero-indexed by 1.
zipmap takes the values derived from the two map statements, and creates a sequence of values, which is what I wanted. The read-map value can be passed on to other functions.
This solution came from clojure Google group. Enroute to this solution, I tried various ways to populate the map variable, and these did not work or generated a compile-time error. It would be good for someone to write a cookbook that discussed pulling data out of files and storing it in different ways in local variables.
(ns test-csv (:gen-class) (:use clojure.contrib.command-line) (:use clojure-csv.core)) (defn process-file "Process csv file and prints a column in every row" [file-name] (let [data (slurp file-name) rows (parse-csv data) read-map (zipmap (map #(nth % 11 nil) rows) (map #(nth % 1 nil) rows))] (println read-map))) (defn -main [& args] (with-command-line args "Get csv file name" [[file-name ".csv file name" "resultset.csv"]] [[file-name ".csv file name" 1]] (println "file-name:", file-name) (process-file file-name)))
Clojure: Command Line Processing
Posted: June 20, 2011 Filed under: Clojure | Tags: Clojure, command line arguments Leave a commentIf I have any complaints about Clojure documentation it’s lack of I/O basics in the core documentation, like reading and writing files. This is a small matter, though, because there are lots of folks out there talking about those issues, like http://tech.puredanger.com/2010/02/25/clojure-command-line-options/.
I’ve modified my own .csv reading application to take a file name from the command line:
(ns test-csv (:gen-class) (:use clojure.contrib.command-line) (:use clojure-csv.core))</code> (defn process-file "Process csv file and prints first item in every row" [file-name] (let [data (slurp file-name) rows (parse-csv data)] (dorun (map #(println (first %)) rows)))) (defn -main [&amp; args] (with-command-line args "Get csv file name" [[file-name ".csv file name" 1]] (println "file-name:", file-name) (if file-name (process-file "resultset.csv") (process-file file-name))))
As the Google Clojure Users Group pointed out, there is a better way to get the default file on the command line, in case none is specified:
(defn -main [& args] (with-command-line args "Get csv file name" [[file-name ".csv file name" "resultset.csv"]] (println "filename:" file-name) (process-file file-name)))
Tolerant Technical Communities
Posted: June 14, 2011 Filed under: Clojure, Python | Tags: Clojure, community, Python, resources Leave a commentI don’t know what it is about the Clojure community, but it is very accepting of beginners and questions that sometimes ask for feedback stating the obvious. I have been programming over thirty years and paid to do so for over twenty-five years. I have used a lot of languages, but Lisp syntax has always thrown me for a loop.
The Clojure users group on Google http://groups.google.com/group/clojure?hl=en, Getting Clojure http://www.gettingclojure.com/, and resources on this blog’s Clojure Resource Page https://drknucklehead.wordpress.com/clojure-resources/ are good places to ask questions and get help.
It would be unfair of me not to include the Python community in this tribute as well. The core Python community is always encouraging and willing to answer questions. They are also a great group of people.
Programming Languages Used and Using
Posted: June 11, 2011 Filed under: Programming, Python | Tags: Bliss, C, Informix 4GL, JavaScript, Perl, PL/I, Python, VB, VBScript Leave a commentThese are the computer programming languages I have used over the past few years.
1985 – 1987
PL/I Subset G
1987 – 1990
C, Bliss, Assember (DEC VAX)
1990 – 2000
C, C++
2000 – 2002
VBScript/VBA
2002-2003
Java, C, C++, Perl
2004 – current
Informix 4GL, C, VB, Perl, Python, JavaScript, Clojure
Book Review: Pro Python Marty Alchin
Posted: June 7, 2011 Filed under: Python | Tags: Python Leave a commentPro Python is one of those books whose detail and clear writing took some time to appreciate. I purchased it while still learning Python, and other than taking a cursor look at the chapters, I did not have time to read it. I purchased the book during the implementation of an Automated Meter Reading (AMR) application that handles meter configuration and reads.
Eventually, I had time to read the book in greater detail. First, it contains the first, full, good description of Python decorators I have ever read. I had searched the web pretty thoroughly for an explanation before finding in Pro Python. The book breaks down advanced topics into basics, functions, classes, meta programming, and includes distribution, not always covered by other texts.
This book does more to explain the Python mindset needed for clear, concise code, than some of the explanations I have read that seem to favor dictating a “Python Way” to the reader. Therefore, once you have learned Python basics, this book is a must for your library.
Bon Apetit!
Why Clojure?
Posted: June 7, 2011 Filed under: Clojure, Programming | Tags: Practical Clojure, The Joy of Clojure 3 CommentsThese days, I program in several environments using several well-known traditional languages. These are to maintain old Informix “forms” code written in Informix 4GL and a few specialized I/O routines written in C; web programming using Javascript, Perl, PHP, Django/Python, and Python server applications and applets.
While browsing SoftPro’s web site — my favorite on-line and walk-in book seller in Centennial, CO — http://softpro.com/ — I came across a book called The Joy of Clojure. I wondered what Clojure was and why it was created.
Then, I read a very good review on two Clojure books — http://programmingzen.com/2010/07/16/in-depth-book-review-practical-clojure/ — and wound up purchasing both books mentioned in the review, The Joy of Clojure and Practical Clojure. Each book targets something different, and appears to be very well written.
Given the wide-spread interest in Python and that web sites web sites are written using html, JavaScript, Perl, PHP or a framework like Rails or Django are mainstream, the likelihood our town will ever see Clojure production programs is unlikely.
I am instead learning Clojure, because it is unlike other languages I’ve used. However, given its relationship with Java, learning Clojure might not turn out to be a long shot, at least learning functional programming might turn out not to be a long shot.
mod_wsgi 64-bit
Posted: February 11, 2011 Filed under: Django | Tags: django, mod_wsgi, Python 2 CommentsWhen building mod_wsgi there are two things to remember if you are building on a 64-bit Linux system. My examples came from Red Hat Enterprise Linux 5 WS.
Here is the link to these and other problems:
http://code.google.com/p/modwsgi/wiki/InstallationIssues
First, When running configure make sure the –enable-shared switch is used. This will create a shared object library similar to this /usr/local/lib:
-r-xr-xr-x 1 root root 5624411 Feb 7 10:11 libpython2.6.so.1.0
You will need to add a link, so this library can be found by Apache or your web server:
lrwxrwxrwx 1 root root 19 Feb 7 10:11 libpython2.6.so -> libpython2.6.so .1.0
And finally, don’t forget to compile the library’s location into make (mod_wsgi’s build directory).
LD_RUN_PATH=/usr/local/lib make
before running make install.
Building the shared library information is important, so you do not get an error like this:
Syntax error lin line 200 of /etc/httpd/conf/httpd.con Cannot load /etc/httpd/modules/mod_wsgi.so into server: libpython2.6.so.1.0: cannot open shared object file: No such file or directory
I had mistakenly thought you Apache would use environment variables to locate the shared library.
Choosing Django: mod_wsgi Configuration
Posted: February 10, 2011 Filed under: Django | Tags: django, media, mod_python, mod_wsgi Leave a commentThe focus of using mod_python is to load and configure in Apache’s configuration file.
Here is a typical configuration extract for mod_python:
SetHandler python-program PythonHandler django.core.handlers.modpython SetEnv DJANGO_SETTINGS_MODULE settings SetEnv PYTHON_EGG_CACHE /tmp/.python_eggs PythonOption django.root /home/amr/django/amr PythonPath "['/home/amr/django/amr/bin', '/home/amr/django', '/home/amr/django/amr', '/home/amr/django/amr/media', '/home/amr/django/amr/media/admin'] + sys.path" PythonDebug On
On the other hand, mod_wsgi is mentioned in the Apache configuration, but a lot more of the configuration is contained within the mod_wsgi handler, which you write:
WSGIScriptAlias / /usr/local/www/wsgi-scripts/wsgi_handler.py <Directory /usr/local/www/wsgi-scripts> Order allow,deny Allow from all </Directory>
Here is a working mod_wsgi handler:
import os import sys PROJECT_ROOT = os.path.realpath(os.path.dirname(__file__)) sys.path.append(PROJECT_ROOT) sys.path.append(os.path.join('/home/amr/django')) sys.path.append(os.path.join('/home/amr/django/amr')) sys.path.append(os.path.join('/home/amr/bin')) sys.path.append(os.path.join('/usr/local/www/documents/media')) sys.path.append(os.path.join('/usr/local/www/documents/media/media')) os.environ['DJANGO_SETTINGS_MODULE'] = 'amr.settings' os.environ['PYTHON_EGG_CACHE'] = '/tmp/python_egg_cache' import django.core.handlers.wsgi application = django.core.handlers.wsgi.WSGIHandler()
And finally, here is the full Apache configuration, which will allow loading css and other static documents along with the Django admin site.
Listen 8002 <VirtualHost _default_:8002> AliasMatch ^/([^/]*\.css) /usr/local/www/documents/media/$1 Alias /media/ /usr/local/www/documents/media/media/ Alias /static/ /usr/local/www/documents/media/ <Directory /usr/local/www/documents/media/> Order deny,allow Allow from all </Directory> WSGIScriptAlias / /usr/local/www/wsgi-scripts/wsgi_handler.py <Directory /usr/local/www/wsgi-scripts> Order allow,deny Allow from all </Directory> ServerAdmin someone@someone.com </VirtualHost>
Finally, the pertinent environment variables from settings.py
# Main URL for the project BASE_URL = 'http://myserver:8002' # Absolute path to the directory that holds media MEDIA_ROOT = '/usr/local/www/documents/media/' # URL that handles the media served from MEDIA_ROOT MEDIA_URL = 'http://myserver:8002/' # URL prefix for admin media -- CSS, JavaScript and images. ADMIN_MEDIA_PREFIX = BASE_URL + '/media/'