Archive for the 'Blogging Theory' Category

Using Baidu

July 16, 2008

As the leading Chinese search engine, Baidu, is used by over 5 million people and has over 57 services but with limited English content or support it is literally a world apart. The main page with its sparse minimalism is familiar enough, as is the single text field for a query. But overlaying a translation differences start to come out.

First up there is some English there on the main page, as a top level search choice no less. Specifically there is a tab for ‘MP3’. Which probably is less English than a technical shorthand for an audio encoding scheme. But it would be kind of funny if 20 years later long after the MP3 format is long forgotten if ‘MP3’ became a loan word for free digital music.

But it is weird. Consider if Google or Yahoo had a top level search tab for 搜索风云榜 right between news and shopping.

So fortunately if your Chinese is not very good you can of course make use of Google’s translation tools. Which is handy. So starting with news you can just click right here to see the current results for the news page on Baidu.

The results are the mostly familiar China news, international, financial, sports entertainment and such. But there is also a page for the Olympics (which could be handy) and the international news page has a military section. Whoa. There’s an addition to add to the Google News >World page. But then again why not.

The final tip is from the main page shown above is the 搜索风云榜 or ‘fengyun bang’ or baidu trends page. Top searches, top ten lists and yes a scrolling window of garbled stuff, like a query for ‘rogue eunuchs’. Whoa again. I think this posts is done.

How to comment in BOLD

June 26, 2008

It’s pretty nifty how the default WordPress admin settings allow you to see the top incoming search terms. The top bold lentil terms are currently:  

banana sushi, homemade bottle opener, mccain stencil, holes, personalized styrofoam cups, use of parenthesis, oboe, numonic definition, frogs, john mccain stencil, self.response.out.write, gustave doré, chuck close, unlucky numbers, and so on.

Which is like whoa. How about that banana sushi post. But then further down the list I see lots of queries for “how to write bold comments” and “how to comment in bold letters” and such and because the blog is titled ‘bold lentil’ people click here.

Fine.

Let’s do something useful this time. Assuming the comment window you are typing into supports HTML then to comment in bold you will need to do the following:

1. start your comment, when you get the word you want in bold stop

2. type the begin bold tag: <b>

3. then type your words

4. the type the end bold tag: </b>

5. finish your comment.

So for example if you wanted to comment on this post: “Wow this is such a useful post.” and say you wanted to emphasize the word useful with some bold then you would type: “Wow this is such a <b>useful</b> post.” Which should look like this after it’s posted: “Wow this is such a useful post.” If doesn’t you can always move on to ranting about the sub-par blogging software.

Google App Engine: Adding JavaScript and Images

May 15, 2008

Bold lentil now has a dynamic graphical jump page.

It’s here.

Yes it’s hosted on app engine and yes it uses JavaScript. I was at a talk the other day by Dick Wall and there was speculation about what language might be supported after python. I think the question is what languages will be supported after python and JavaScript.

So assuming you have a useful JavaScript function in a thumbs.js file and it starts with an array of urls:

  function stepThumbnails(theSign) {
    var theURLs = new Array();
    theURLs[0] = "";
    theURLs[1] = "https://boldlentil.wordpress.com/2007/05/05/hello-world/";
    theURLs[2] = "https://boldlentil.wordpress.com/2007/05/05/cetacean-mutation/";
    theURLs[3] = "https://boldlentil.wordpress.com/2007/05/06/four-things-about-the-new-r2d2-mailboxes/";
    theURLs[4] = "https://boldlentil.wordpress.com/2007/05/09/domestic-politics/";
    theURLs[5] = "https://boldlentil.wordpress.com/2007/05/10/two-hundred-and-thirty-one-things-i-learned-using-the-internets/";
    theURLs[6] = "https://boldlentil.wordpress.com/2007/05/10/still-havent-finished-my-post-on-prcrastination/";
...
    theURLs[92] = "https://boldlentil.wordpress.com/2008/04/21/karl-attacks/";
    theURLs[93] = "https://boldlentil.wordpress.com/2008/04/23/toxoplasmosis-choose-your-own-post-ending/";
    theURLs[94] = "https://boldlentil.wordpress.com/2008/04/24/lenigme-by-gustave-dore/";
    theURLs[95] = "https://boldlentil.wordpress.com/2008/05/01/gm-to-cut-1000s-announces-failed-business-plan/";
    theURLs[96] = "https://boldlentil.wordpress.com/2008/05/01/dont-something-the-elephant-seals/";

Then add some code to define the width, height and size of the jump pages (in terms of number of thumbnail images). And then add some calculations for a starting and ending value for the specific array of thumbnails.

    var max = 96;
    var wide = 4;
    var high = 4;
    var theStep = (wide * high);
    var myStep = (theStep * theSign);
    if (theSign == 0) {
      var one = 1;
      var two = 1;
      var tre = theStep;
    }
    else {
      var one = parseInt(document.f1.theStartValue.value);
      var two = one + myStep;
      if (two < 1) two = 1;
      if (two > max) {
        two = one;
      }
      document.f1.theStartValue.value = two;
      var tre = two + myStep - 1;
      if (myStep < 0) tre = two - myStep - 1;
    }

Finally some more JavaScript to loop over the range to create a table of image thumbnails. Nothing fancy here.

    theText = '<p>';
    var theTable = '<table>';
    var twoPlus = two;
    for (i = 0; i < high; i++) {
      theTable += '<tr>';
      for (j = 0; j < wide; j++) {
        twoPlus = two + (i * wide) + j;
        if (twoPlus <= max) {
          theTable += '<td><a href=';
          theTable += theURLs[twoPlus];
          theTable += '><img src="/images/thumbnails/thumbnail-'+twoPlus+'.gif" border=0></a></td>\n';
        }
        else {
          thetable += '<td></td>\n';
        }
      }
      theTable += '</tr>';
    }
    theTable += '</table>';
    document.getElementById('theCurrentThumbnails').innerHTML = theText + theTable;
    document.f1.theStartValue.value = two;

Then save this file in a directory /static/js in the same directory as the root python code. Now I’m sure all this can be done more succinctly in python but if you already have some JavaScript handy why not use it?

The next step is to set up the images file. In this case I used /static/images/thumbnails. The thumbnails were created using a script file to be square and 128 by 128. Some experimentation seemed to lead me to believe that the /static for both the js and images was required. Anyways with the JavaScript code above in the /static/js directory and the GIF thumbnails in the /static/images/thumbnails directory it’s time to edit the app.yaml file to look something like:

application: 1boldlentil
version: 6
runtime: python
api_version: 1

handlers:
- url: /
  script: boldlentil.py

- url: /js
  static_dir: static/js

- url: /images/thumbnails
  static_dir: static/images/thumbnails

- url: /.*
  script: boldlentil.py

The two new handlers are for the JavaScript and for the images. Pretty easy once you know to add both of these to a /static directory and also know not to reference this /static in the code. Finally, the boldlentil.py file has to be edited to add a /jump page. This is pretty straightforward:

class jumpPage(webapp.RequestHandler):
  def get(self):
    self.response.headers['Content-Type'] = 'text/html'
    self.response.out.write('')
    self.response.out.write('')
    self.response.out.write('<head>');
    self.response.out.write('<script language="JavaScript" src="/js/thumbs.js">');
    self.response.out.write('</script>');
    self.response.out.write('</head>');
    self.response.out.write('<body onLoad="stepThumbnails(0)">');
    self.response.out.write('<form name="f1">');
    self.response.out.write('  <input type="hidden" name="theStartValue" value="1"><p>');
    self.response.out.write('  <input type="button" value="-15" onClick="stepThumbnails(-1)">');
    self.response.out.write('  <input type="button" value="+15" onClick="stepThumbnails(1)" ><p>');
    self.response.out.write('</form>');
    self.response.out.write('</body>');
    self.response.out.write('<div id="theCurrentThumbnails">');
    self.response.out.write('</div>');
    self.response.out.write('<a href=https://boldlentil.wordpress.com/><b>Bold Lentil</b> <a><p>');
    self.response.out.write('');
    self.response.out.write('</html>');

The final result is simple and appealing in a minimalist, wisenheimer way. And unlike computing randomish numbers the jump page even registers on the dashboard.

Google App Engine: Fun with the Datastore

May 12, 2008

The Datastore is the App Engine online database for use by your online application. So not only does Google host your python code but as you accumulate application data and format it as a database they will also manage that data. The last post had adding a form to collect user seed values for the online randomish number generator. Now it’s time to store those seed values in the 1boldlentil application Datastore. Start with adding this line to import the app engine database functionality:

from google.appengine.ext import db

After this a database of seed values should be declared before the main page. This database is pretty simple and at this point consists of the seed value as an integer and the date for that entry. Google has their worked example in their documentation but you have to dig to get a list of types and properties which is here.

class SeedValues(db.Model):
  theSeed = db.IntegerProperty()
  date = db.DateTimeProperty(auto_now_add=True)

Finally we’ll use the two page structure of a simple form to collect a seed value followed by a page to print the values generated with that seed value. So for version five of the application we’ll have a /5s to hold the form and /5 to show the results. The /5s is identical to the /4s from the previous post so it won’t be shown here. The results created with /5 are different though. The top part of this class declaration has theSeed declared and assigns it to the seed value from the form. This value is then put into the database with thisSeed.put().

class version5Page(webapp.RequestHandler):
  def post(self):
    userSeed = int(cgi.escape(self.request.get('theSeed')))
    thisSeed = SeedValues()
    thisSeed.theSeed = userSeed
    thisSeed.put()
    self.response.headers['Content-Type'] = 'text/html'
    self.response.out.write('')
    self.response.out.write('')
    self.response.out.write('theSeed=');
    self.response.out.write(userSeed)
    self.response.out.write('<p>');
    self.response.out.write('<a href=https://boldlentil.wordpress.com ')
    self.response.out.write('target="_blank">')
    self.response.out.write('<b>Randomish Numbers</b></a><p>')
    random.seed(userSeed)
    stop = 25
    i = 1
    while i <= stop:
      self.response.out.write(random.random())
      self.response.out.write('<br>')
      i = i + 1
    self.response.out.write('<p><b>Last 10 seed values:</b> ')
    LastTenSeeds = db.GqlQuery("SELECT * FROM SeedValues ORDER BY date DESC LIMIT 10")
    for aSeed in LastTenSeeds:
      self.response.out.write(cgi.escape(str(aSeed.theSeed)))
      self.response.out.write(' ')

After the now too familiar for loop to print out the resulting randomish numbers is a Google Query Language or GQL query for the last ten seed values which are then printed to the screen. Once again pretty simple. Define the specific database class to be used by the application, create an instance and fill it and then access with queries.

The result is: here.

Note that the types and properties also has built in support for GPS coordinates, IM and ratings. No the next post will not be about letting you readers rate each other randomish number generator seed values. But it’s tempting.

Google App Engine: Basic Form Handling

May 9, 2008

Behind every good psuedo-random generator there is a good seed value for that psuedo-random generator.

The previous three versions of the online randomish generator simply used pythons default seed of the system time. This would be a good place to add a simple HTML form to allow users to enter their own seed value. First off you’ll need to remember to:

import cgi

Then define a class for the seed form input page. Note the standard workhorse HTML form in the code. The action is set equal to “/4” and the method is a post. This class is defined in webapp.WSGIApplication as (‘/4s’, version4Seed) and is the url linked to from the / or entry url for 1boldlentil.

class version4Seed(webapp.RequestHandler):
  def get(self):
    self.response.headers['Content-Type'] = 'text/html'
    self.response.out.write('')
    self.response.out.write('')
    self.response.out.write('<html><body>');
    self.response.out.write('<form action="/4" method="post">')
    self.response.out.write('<div>Seed value:')
    self.response.out.write('<input type="text" name="theSeed" size="11"></div>')
    self.response.out.write('<div><input type="submit"')
    self.response.out.write('value="Compute Randomish Numbers"></div>')
    self.response.out.write('</form></body></html>')

Then define the page that takes this form post and generates the corresponding random numbers using the seed values. The user seed is passed to the page using cgi.escape(self.request.get(‘theSeed’)) and this value is used to seed the random number generator. Now every time you use the page with the same random number generator the program will return the same 25 numbers.

class version4Page(webapp.RequestHandler):
  def post(self):
    userSeed = int(cgi.escape(self.request.get('theSeed')))
    self.response.headers['Content-Type'] = 'text/html'
    self.response.out.write('')
    self.response.out.write('')
    self.response.out.write('theSeed=');
    self.response.out.write(userSeed)
    self.response.out.write('<p>');
    self.response.out.write('<a href=https://boldlentil.wordpress.com ')
    self.response.out.write('target="_blank">')
    self.response.out.write('<b>Randomish Numbers</b></a><p>')
    random.seed(userSeed)
    stop = 25
    i = 1
    while i <= stop:
      self.response.out.write(random.random())
      self.response.out.write('<br>')
      i = i + 1

In the main() the webapp.WSGIApplication declares that (‘/4’, version4Page).

Which is pretty easy. Import cgi, define class/url tuple for the form and another class/url tuple to handle the data. Pretty straightforward. And testing on the local machine calling the url /4 directly without filling out the form just returns a blank page. Once its uploaded to appspot though it will give a 405 to try to access the page/url directly without filing in the form.

Version 4 of randomish numbers is here.

Google App Engine: the Users API

May 8, 2008

The previous versions of the online randomish numbers generator have been open to the entire web. The App Engine users API can be used to require a user login with a Google user account. Once again start by importing the corresponding code:

from google.appengine.api import users

In this case the password protected version of the online randomish number generator will be added to version 3 of the app. This app will be located at /3 and will call version3Page and starts by setting the value of user to the current user using the third line below.

class version3Page(webapp.RequestHandler):
  def get(self):
    user = users.get_current_user()
    if user:
      self.response.headers['Content-Type'] = 'text/html'
      self.response.out.write('')
      self.response.out.write('')
      self.response.out.write('<a href=https://boldlentil.wordpress.com target="_blank">')
      self.response.out.write('<b>Randomish Numbers</b></a> for ')
      self.response.out.write(user.nickname() + '.<p>')
      stop = 25
      i = 1
      while i <= stop:
        self.response.out.write(random.random())
        self.response.out.write('<br>')
        i = i + 1
      self.response.out.write('<a href=' + users.create_logout_url("/") +'>sign out</a><p>');
    else:
      self.redirect(users.create_login_url(self.request.uri))

If the user is logged in then the randomish numbers are generated. The user is greeted by writing the value of user.nickname() to the page. Finally a link is added at the bottom so that the user can log out. This log out link is created with users.create_logout_url( “/” ) and the “/” will return the user to the top of the boldlentil app. If the user is not logged in then self.redirect(users.create_login_url(self.request.uri)) sends the user to a login screen to log in. Pretty straight forward.

The result is here.

The users API also has separate functions handle admin login so that, for example, certain pages can be accessed only by admins. The User Objects page notes that “at this time, the users API does not provide permanent unique identifiers for Google Accounts.” Although the same page also says that “unique user IDs and email address change propagation may be implemented in a future release.”

Google App Engine: Twice as Many Randomish Numbers with webapp Framework

May 8, 2008

Previous app engine fun resulted in a simple online randomish number generator. This is all well and good but this example didn’t make any use of the webapp framework and, really, don’t the users really deserve twice as many random numbers?

So starting with the previous python to generate random numbers the first step is to import the corresponding code:

import wsgiref.handlers
from google.appengine.ext import webapp

Next define a class for the main page. This is / or entry web page for the application. In this case it’s simply some URLs that point to versions one and two of the randomish number generators. This is called with a request handler. Note that the two versions are linked to a specific URLs, in this case /1 and /2.

class MainPage(webapp.RequestHandler):
  def get(self):
    self.response.headers['Content-Type'] = 'text/html'
    self.response.out.write('')
    self.response.out.write('')
    self.response.out.write('Randomish Numbers: ')
    self.response.out.write('<a href=/1 target="_blank">')
    self.response.out.write('<b>version 1</b></a>, ')
    self.response.out.write('<a href=/2 target="_blank">')
    self.response.out.write('<b>version 2</b></a><p>')
    self.response.out.write('<a href=https://boldlentil.wordpress.com target="_blank">')
    self.response.out.write('<b>Bold Lentil</b></a><p>')

Once the MainPage is defined the next class to define is the version 1 page. This page generates 25 randomish numbers. w00t!

 class version1Page(webapp.RequestHandler):
  def get(self):
    self.response.headers['Content-Type'] = 'text/html'
    self.response.out.write('')
    self.response.out.write('')
    self.response.out.write('<a href=https://boldlentil.wordpress.com target="_blank">')
    self.response.out.write('<b>Randomish Numbers</b></a><p>')
    stop = 25
    i = 1
    while i <= stop:
      self.response.out.write(random.random())
      self.response.out.write('<br>')
      i = i + 1

After the version 1 page, the next step is to the version 2 page. This page generates 50 randomish numbers. Woot! Woot!

class version2Page(webapp.RequestHandler):
  def get(self):
    self.response.headers['Content-Type'] = 'text/html'
    self.response.out.write('')
    self.response.out.write('')
    self.response.out.write('<a href=https://boldlentil.wordpress.com target="_blank">')
    self.response.out.write('<b>Randomish Numbers</b></a><p>')
    stop = 50
    i = 1
    while i <= stop:
      self.response.out.write(random.random())
      self.response.out.write('<br>')
      i = i + 1

Finally what event loop would be complete without a main()? Note the tuples inside of WSGIApplication that link /1 and /2 to version1Page and version2Page respectively.

def main():
  application = webapp.WSGIApplication(
                                       [('/', MainPage),
                                        ('/1', version1Page),
                                        ('/2', version2Page)],
                                       debug=True)
  wsgiref.handlers.CGIHandler().run(application)

if __name__ == "__main__":
  main()

Revise the app.yaml with the new version number and then upload. Note that after uploading the code it will be necessary to use the versions menu item to switch the default to the new version.

The final result is here.

Google App Engine: Randomish Numbers Generator

May 6, 2008

Got my invite to try out Google App Engine.

Logged in and downloaded version 1.0.1.

But then noted I also had to update python. Downloaded and installed 2.5.2.

Then installed the App Engine.

Read through the helloworld example and noted the page about GQL or Google’s “SQL-like language for retrieving data entities from the App Engine scalable datastore” (but without the joins)

Elsewhere there is the App Engine blog, a comparison to EC2 and a port of the engine to EC2.

Now to do some quick coding, an online randomish numbers generator.

import random
print 'Content-Type: text/html'
print ''
print ''
print '<a href=https://boldlentil.wordpress.com target="_blank">'
print '<b>Randomish Numbers</b>'
print '</a><p>'
stop = 25
i = 1
while i <= stop:
  print random.random()
  print '<br>'
  i = i + 1

Wrote this to tools/app-engine/boldlentil/1/boldlentil.py. Also wrote a simple app.yaml using the helloworld example. From /usr/local/google_appengine can then run this simple test app using:

./dev_appserver.py /Users/boldlentil/tools/app-engine/boldlentil/1

Checking http://localhost:8080/ the app returns a screen of randomish numbers. So far so good. The simple user guide goes on to describe the web application framework but I can’t wait, let’s see if I can get this uploaded as is. Jump to http://appengine.google.com/ and now it’s time to select an Application Identifier and an Application Title. But it’s probably a good time to read the Google App Engine Terms of Use. Can’t be under 13 years old. OK. Also “the Service is provided to you without charge for up to 500MB of disk storage, 10GB incoming bandwidth per day, 10GB outgoing bandwidth per day, 200 million megacycles of CPU per day and 2,000 emails per day.” Sounds good. Finally, “by submitting, posting or displaying the Content on or through the Service you give Google a worldwide, royalty-free, and non-exclusive license to reproduce, adapt, modify, translate, publish, publicly perform, publicly display and distribute such Content for the sole purpose of enabling Google to provide you with the Service in accordance with its privacy policy.” Sounds good.

You upload python and they get Content. I guess randomish numbers are content.

So next up creating an application Bold Lentil and using appcfg.py to upload the application.

./appcfg.py update /Users/boldlentil/tools/app-engine/boldlentil/1

Finally use gmail email and login to complete the upload.

Now to test it here.

It worked – and testing it only used 14.95 of my 199608.00 Gigacycles. Slick!

Toxoplasmosis: Choose Your Own Post Ending

April 23, 2008

What sort of parasite gives a rat a suicidal attraction to cats?

A nasty one.

Toxoplasma gondii.

Passed from cat gut to rat brain and back again this parasite would seem to leave the host cats unaffected while giving the host rat brain damage. Connecting the cats and rats is feces. The toxoplasma passes out of cats and into rats. The rats then get slower and less afraid of cats and easier to be eaten by the cats. Which is not to say that the rats are fearless. They still have what seems to be a typical level of rat anxiety. But unlike uninfected rats, they appear to be fearless of rat urine.

Selective impairment of smell due to a parasite.

Altered perception and nihilistic behaviors, infected predators and reckless rodents. Fascinating but what’s the point you are asking yourself? You choose:

If you think the glass is half full click here,

If you think the glass is half empty click here,

If you think the glass is mostly empty space click here.

The Post that got me Kicked Off Google

April 20, 2008

This was originally going to be a blog post titled “You know you’re an alphabetical list-maker when…” but part of the way through researching the post (6 letters from the end to be exact) I got a 403 from Google. Ah well you get the idea. If anyone can find links for K, V, W, X, Y and Z add them to the comments. Be careful with those alphabetical list making blog posts… don’t be alphabetical.

You know you’re in Alabama when,

You know you were born in the 80’s when,

You know you’re in Cambodia when,

You know you’re a digital photographer when,

You know you’re an Episcopalian if,

You know you’re from Flint when,

You know you’re a grammar geek when,

You know you’re Hungarian if,

You know you’re from Idaho if,

You know you’re from Jersey when,

You know you’re living in 2008 if,

You know you’re in Macau when,

You know you’re a New Yorker when

You know you’re at an Osvaldo Golijov opera when,

You know you’re a political staffer when,

You know you’re a runner when,

You know you’re a Sox fan when,

You know you’re in Tennessee when,

You know you’re at university when,