Wednesday, May 18, 2011

Blogger is BACK

Yay! My Page entitled "web2py Cheat Sheet" was back in my drafts just now. Big thanks, Blogger Folks. Love and peace, Joe

Saturday, May 14, 2011

NOT TRUE YET - Blogger Buzz: Blogger is back

The Blogger Folks say: Blogger Buzz: Blogger is back My new Page [NOT a Post but a Page] entitled something like "web2py Cheatsheet" is still missing. As far as I am concerned "Blogger is [not yet] back". I sure hope you Blogger Folks restore it. Thanks for the help in advance. Joe

Tuesday, May 3, 2011

Make the Eclipse JUnit Test Suite wizard work for JUnit-4

Background.
I recently got back into Java being inspired by the growth of the Android platform and Java's close link to it. I needed a refresher tutorial on Java and Eclipse and found "Eclipse and Java for Total Beginners" which after getting over my pride and reviewing the first couple of lessons is just what I needed. This very well thought out and produced tutorial also gives an excellent introduction to "Test Driven Development". Another benefit.

The Problem.
The tutorial is based based on JUnit-3. I installed the more up-to-date JUnit-4 and the Eclipse "JUnit Test Suite" wizard BLEW UP! :..)... I googled "eclipse JUnit 4 Test Suite wizard problem" and concluded that it seems to be well known, so I thought I'd publish my work-around here.

The Work-Around. 
The specific variable names in the work-around are based on the tutorial code. You can see what the tutorial recommended by going to Lesson- 8 at about 10min:50sec. Here is the work-around:

-in Package Explorer View TotalBeginner/test rclick org.totalbeginner.tutorial
    new.other.Java.JUnit.JUnitTestSuite
        wizard dialog comes up
            -next, press Finish to select default of (BookTest, PersonTest)
                creates a new class AllTests
-*** wizard will say ***:  
    Warning: No test classes selected
    *** because i use JUnit-4 Wizard needs JUnit-3 ***
    -click Finish anyway
-Fix wizard generated code
    1. delete everything from the wizard code 
        EXCEPT the package definition in this case:
            package org.totalbeginner.tutorial;
    2. put in something like the following code 
        2.1 here's the code:
            @RunWith(Suite.class)
            @Suite.SuiteClasses(value={BookTest.class, PersonTest.class})
            public class AllTests {}
        2.2 Change/Add to the example "BookTest.class" & "PersonTest.class" items,
            appropriate items for your situation. 
        2.3 use eclipse quickfix to create appropriate import statements
            -click in error code marked with red squiggly underline
            -ctl-1 for quick fix
            -select suggestion that generates the appropriate import
            -continue until no more errors 
            -for this example 2 imports were generated:
                import org.junit.runner.RunWith;
                import org.junit.runners.Suite;

Saturday, April 9, 2011

Real World Tkinter GUI

Here is a real world Tkinter GUI that I made for a command line application that translates between MIDI files and Text files. The code follows the screen shot.



# -*- coding: ISO-8859-1 -*-
import sys

if not('.' in sys.path): sys.path.append('.')
import midi24txt 

from Tkinter import *
from tkFileDialog import *

# thinking in tkinter http://www.ferg.org/thinking_in_tkinter/all_programs.html

class TheGui:
    def __init__(self, parent):
        #------- frmSetup ----------#
        self.frmSetup = Frame(parent, bd=5)
        self.frmSetup.pack()
        
        self.inChoices = ('Text', 'Midi')
        self.varRadio = IntVar()
        
        self.r1 = Radiobutton(self.frmSetup, text="Convert Text INPUT into Midi OUTPUT",
            variable=self.varRadio, value=0, command=self.selRadio)
        self.r1.pack(anchor=W)

        self.r2 = Radiobutton(self.frmSetup, text="Convert Midi INPUT into Text OUTPUT", 
            variable=self.varRadio, value=1, command=self.selRadio)
        self.r2.pack(anchor=W)
        #------- frmSetup ----------#

        sep = Frame(parent, width=1, bd=5, bg='black')
        sep.pack(fill=X, expand=1)
         
        #------- frmIn ----------#
        # http://effbot.org/tkinterbook/tkinter-widget-styling.htm
        self.frmIn = Frame(parent, bd=5)         
        self.frmIn.pack()

        self.lblIn = Label(self.frmIn, text='Text Input File Path', width=20)
        self.lblIn.pack(side=LEFT) 

        self.inFilePath = StringVar() # http://effbot.org/tkinterbook/entry.htm
        self.entIn = Entry(self.frmIn, width=20, textvariable=self.inFilePath)
        self.entIn.pack(side=LEFT)
        

        self.btnIn = Button(self.frmIn, text='Browse', command=self.btnInBrowseClick)
        self.btnIn.pack(side=LEFT) 
        #------- frmIn ----------#
        
        
        #------- frmOut ----------#
        self.frmOut = Frame(parent, bd=5)
        self.frmOut.pack()

        self.lblOut = Label(self.frmOut, text='Midi Output File Path', width=20)
        self.lblOut.pack(side=LEFT) 

        self.outFilePath = StringVar()
        self.entOut = Entry(self.frmOut, width=20, textvariable=self.outFilePath)
        self.entOut.pack(side=LEFT) 

        self.btnOut = Button(self.frmOut, text='Browse', command=self.btnOutBrowseClick)
        self.btnOut.pack(side=LEFT) 
        #------- frmOut ----------#
        
        sep = Frame(parent, width=1, bd=5, bg='black')
        sep.pack(fill=X, expand=1)
        
        #------- frmButtons ----------#
        self.frmOut = Frame(parent, bd=5)
        self.frmOut.pack()
        
        self.btnConvert = Button(self.frmOut, 
            text='Convert', command=self.btnConvertClick)
        self.btnConvert.pack() 
  
    #------- handle commands ----------#
    def selRadio(self):
        self.lblIn.config(text = self.inChoices[self.varRadio.get()] 
            + ' Input File Path')
        self.lblOut.config(text = self.inChoices[(self.varRadio.get()+1)%2] 
            + ' Output File Path')
        print str(self.varRadio.get())
   
    def btnInBrowseClick(self):             
        rFilepath = askopenfilename(defaultextension='*', 
            initialdir='.', initialfile='', parent=self.frmIn, title='select a file') 
        self.inFilePath.set(rFilepath)
        print self.entIn.get()
    
    def btnOutBrowseClick(self):  
        rFilepath = asksaveasfilename(defaultextension='*', 
            initialdir='.', initialfile='', parent=self.frmIn, title='select a file') 
        self.outFilePath.set(rFilepath)
        print self.entOut.get()
    
    def btnConvertClick(self):  
        if self.varRadio.get() == 0:
            inputTextFilePath = str(self.inFilePath.get())
            outputMidiFilePath = str(self.outFilePath.get())
            print 'midi 4 txt', inputTextFilePath, outputMidiFilePath
            midi24txt.mid4txt(inputTextFilePath, outputMidiFilePath)
        else:      
            inputMidiFilePath = str(self.inFilePath.get())
            outputTextFilePath = str(self.outFilePath.get())            
            print 'midi 2 txt', inputMidiFilePath, outputTextFilePath
            midi24txt.mid2txt(inputMidiFilePath, outputTextFilePath)
 
  
root = Tk()
root.title("Convert between Midi and Text Files")
#http://infohost.nmt.edu/tcc/help/pubs/tkinter/std-attrs.html#geometry
#http://infohost.nmt.edu/tcc/help/pubs/tkinter/toplevel.html
root.geometry("350x200+10+10")
gui = TheGui(root)
root.mainloop()

Thursday, February 24, 2011

Making my web2py site use a default_application other than welcome on WebFaction.

Here are the steps on webfaction.
  1. $ cd ~/your_path_to_web2py/web2py
  2. $ cp routes.example.py routes.py #there is no routes.py at first
  3. [edit routes.py as follows
        line was: default_application = 'init'    # ordinarily set in base routes.py
        line now: default_application = 'other'   # ordinarily set in base routes.py
  4. $ cd ../apache2/bin
  5. $ ./restart

Wednesday, February 23, 2011

Fixing my "my web2py is unable to create a new application on WebFaction" problem.

Please go here to read a full discussion of the problem. Here is a summary of the steps i took to fix this problem.


  1. Made sure that memory capacity is not a problem.
    1. SSHed into my WebFaction account.
    2. $ ps -u user -o pid,rss,command
      output is: PID, Total memory in bytes, full path of process.
    3. I saw that i was over my memory limit.
    4. Upgraded to get more memory.
    5. Tested to see if that worked. IT DID NOT.
  2. I read this thread.
    1. Made sure that the web2py directory contained a directory named "deposit".
    2. It did.
    3. Re-tested - NO GOOD.
  3. Opened a WebFaction Ticket.
    1. WebFaction Support suggested that I "...try running the web2py daemon script manually ("python2.5 web2py[.py]") to initialize those systems".
    2. Decided i would do that.
  4. Ran web2py from the SSH command line to initialize it.
    1. $ cd ~/path_to_troubled_web2py_instance/web2py/
    2. $ python2.5 web2py.py
      Up came web2py saying:
      ****************
      web2py Enterprise Web Framework
      Created by Massimo Di Pierro, Copyright 2007-2011
      Version 1.92.1 (2011-02-16 15:04:40)
      Database drivers available: SQLite3, pymysql, PostgreSQL
      Starting hardcron...
      choose a password:
      please visit:
       
      http://127.0.0.1:8000/
      use "kill -SIGTERM 6744" to shutdown the web2py server
      ****************
    3. I let it run for a couple of minutes to initialize.
    4. $ kill -SIGTERM 6744  # The number 6744 varies. Use the number mentioned by web2py.
    5. Re-tested by by using IE8 to https login to the associated web2py admin from my windows XP desktop. SUCCESS. I was able to create the "home" app.  




Tuesday, February 22, 2011

Concatenating web2py HTML Helpers

Say you want to produce something like this list of links dynamically, into an HTML page, from a web2py controller:

mobyJoe.me

 
Here is what you would put into your controller to concatenate (append) HTML Helpers:
def index():
    page_info = DIV(
                A('NOAA Weather', _href='http://mobile.weather.gov/'), BR(),
                A('Google Mobile', _href='http://m.google.com/'), BR(),
                A('Twitter Mobile', _href='http://mobile.twitter.com/')
                )
    return dict(page_info=page_info)
 
Here is what would go into your associated view:
{{extend 'layout.html'}}
{{=page_info}}
 
Here's the reason. Lot's of HTML helpers are derived from the DIV helper. According to the web2py epydocs at line 523, DIV
"Behaves like a dictionary regarding updating of attributes. 
Behaves like a list regarding inserting/appending components."