Generating random strings in Erlang

November 7th, 2009

I could not find any decent examples from the web on how to generate a random string with a certain set of characters and length in Erlang. The basic idea for such a method is to take a string of allowed characters and loop N times where the N is the length of the resulting string. Then at each loop we take some random character from the string that contains the required set of characters. Sounds relatively simple, right? Next we have to write this in Erlang. This is what I came up with…

1
2
3
4
5
6
get_random_string(Length, AllowedChars) ->
    lists:foldl(fun(_, Acc) ->
                        [lists:nth(random:uniform(length(AllowedChars)),
                                   AllowedChars)]
                            ++ Acc
                end, [], lists:seq(1, Length)).

Ok, Erlang is not the most readable language in the world and a simple thing such as generating a random string can look pretty tedious. No worries. I’ll go through the method line by line.

I’m using the lists:foldl method here. What it does is that it goes through a list (from left to right) and calls a function that has as it’s parameter a value from that list and the result form the previous iteration. The result of the method is the result of the last call to the function. The list I give as a parameter to lists:foldl is a sequence of numbers from one to the length of the resulting random string. For that I use the lists:seq method. This is how we define how many times we loop.

I’ll explain the fun() that is the first parameter of lists:foldl. Here is what it looks like separate from the whole code.

fun(_, Acc) ->
     [lists:nth(random:uniform(length(AllowedChars)), AllowedChars)]
          ++ Acc
end

The first parameter of the function is the value from the given list ([1, 2, 3, 4,..., N]) and we don’t use it (hence the underscore). The second parameter Acc is called the accumulator that is the result from the previous iteration. To achieve our goal of producing random strings we use lists:nth and random:uniform method calls to pick a random character from the AllowedChars string. Note that the lists:nth returns the integer value of that character so that is why the method call is wrapped in square brackets making the result a string (in Erlang strings are lists of integers). What we do then is that we add the Acc (the result of the previous iteration) to the result and this way build our random string.

There is also a third parameter for the lists:foldl method that you probably have guessed already. Naturally, you also have to give the value of the accumulator for the first iteration, which in this case is empty list [] or empty string since strings in Erlang are actually lists.

Here is an example of the result that the method produces.

test:get_random_string(32, "qwertyQWERTY1234567890").     
"8qttW01wQET1qRTt1r4tr2T392QY94Re"

Automatic code reloading in Erlang

November 3rd, 2009

I’ve recently got back to coding Erlang and noticed a neat module that I didn’t know existed that is probably worth writing a blog entry about. I’ve started developing a PubSubHubbub hub in Erlang called Hubbabubba and I’m using the great Mochiweb HTTP library as the HTTP server implementation. I discovered the reloader.erl module that comes with Mochiweb. It automatically reloads the code when you have the application running and you modify the code (remember to compile as well). This is something that I’ve found very useful when developing with Django or AppEngine and I’m really satisfied that there is a similar solution for Erlang as well.

Using zc.buildout in a Twisted project

February 8th, 2009

I’ve been learning how to use zc.buildout in my Python projects. It seems to be used mostly by the Zope and the Plone communities, but I feel that it might be a useful tool to be used in any Python project. I do lots of work with Twisted and I wanted to try zc.buildout with a Twisted project. It wasn’t trivial and I wasn’t able to find any good examples, so I thought I might as well document my experiences here.

Let’s start this exercise by setting a new virtual Python environment using virtualenv. It gives you a nice constrained Python environment that does not mess up your system. Easiest way to get virtualenv on your system is by using setuptools. When you have setuptools installed you can get virtualenv by typing:

$ easy_install virtualenv

Now that you have virtualenv installed it’s time to create the virtual environment. In this example I will create the environment in a directory called twistedenv. You can place it anywhere you want in your system.

$ mkdir twistedenv
$ virtualenv --no-site-packages twistedenv/
New python executable in twistedenv/bin/python
Please make sure you remove any previous custom paths from your /Users/teemu/.pydistutils.cfg file.
Installing setuptools............done.

Now that the virtual environment is setup you can activate it by typing:

$ cd twistedenv
$ source bin/activate

This will activate the new Python interpreter that was installed in twistedenv/bin/python.

Ok, now we can get to the actual topic, that is how to use zc.buildout with a Twisted project. What you will need is a bootstrap script that will install zc.buildout inside your environment and a buildout configuration file. Let’s start with the configuration file, since we need that before running the bootstrap script. In zc.buildout the configuration file is called buildout.cfg. It will tell the buildout system, what packages are needed and setup your development system in a blink of an eye. I’ll start with an example that will install Twisted and some dependencies and a sample Twisted application that is under development. Here’s the buildout.cfg that will do this.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
[buildout]
parts =
    depends
    twisted
    twisteds
develop = ./src
 
[versions]
Twisted = 8.2.0
pyOpenSSL = 0.8
pyserial = 2.4
pycrypto = 2.0.1
 
[depends]
recipe = minitage.recipe:egg
eggs =
    pyOpenSSL
    pyserial
    pycrypto
 
[twisted]
recipe = minitage.recipe:egg
eggs = Twisted
 
[twisteds]
recipe = minitage.recipe:scripts
interpreter = twistedpy
extra-paths = ${buildout:directory}/src
eggs =
  ${twisted:eggs}
  ${depends:eggs}

I’ll briefly explain what it does. Section buildout is the first thing to put in the config file. It lists what parts of the configuration file are used and the location of the code that is being developed. The section called depends installs the dependencies for Twisted using recipe minitage.recipe. Section twisted naturally installs Twisted, but it does not install the scripts that are installed to the bin directory. That is what the section twisteds is for. By the way, you are free to choose the names of the sections or parts except for the buildout section. In the twisteds section we also define the variable interpreter to create us a new Python interpreter that will be used when running these scripts. For this interpreter we define which eggs are included in the interpreter path and using extra-paths variable we can include our development code there also. It is useful that we can keep our own code separate from 3rd party code while developing it. Section versions can be used to specify which versions of 3rd party libraries we want to use. If you don’t specify a version, a newest version available is used.

Now that we have the buildout.cfg file ready, we can bootsrap the buildout. Download the bootstrap script from this URL and put it in the twistedenv directory. Before running the bootstrap script you can make sure that you are using the Python interpreter from the virtual environment to run it instead of the syste Python. Do that by typing:

$ which python
/Users/teemu/Programming/twistedenv/bin/python

As you can see, for me it shows that I’m using the Python interpreter from inside the twistedenv where we created the virtual environment. That is good. Naturally, for you the complete path is something else. Then we can run the bootstrap script by typing:

$ python bootstrap.py
Creating directory '/Users/teemu/Programming/twistedenv/parts'.
Creating directory '/Users/teemu/Programming/twistedenv/eggs'.
Creating directory '/Users/teemu/Programming/twistedenv/develop-eggs'.
Generated script '/Users/teemu/Programming/twistedenv/bin/buildout'.

As you can see from the output the script created couple of directories and generated a script called buildout to the bin directory. Now our buildout environment is almost ready. The only thing is missing is that our ./src directory does not contain any code. You will see an error if you now try to run bin/buildout.

Let’s create a quick sample Twisted application to demonstrate a more complete buildout environment. This is what we need. Create the required directories for our code:

mkdir -p src/sample
mkdir -p src/twisted/plugins
touch src/sample/__init__.py

Then we need the following files:

src/sample/tap.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from twisted.application import internet
from twisted.web import server
from twisted.web.resource import Resource
from twisted.python import usage
 
class SimpleResource(Resource):
    isLeaf = True
    def render_GET(self, request):
        return "<h1>It Works!</h1>"
 
 
class Options(usage.Options):
    pass
 
 
def makeService(config):
    site = server.Site(SimpleResource())
    return internet.TCPServer(8080, site)

src/twisted/plugins/sample.py:

1
2
3
4
5
6
7
8
from twisted.application.service import ServiceMaker
 
Sample = ServiceMaker(
    "Sample",
    "sample.tap",
    "Twisted sample application",
    "sample"
)

And last, but not least, src/setup.py:

1
2
3
4
5
6
7
8
9
10
11
12
from setuptools import setup
 
setup(name='sample',
      version='0.0.1',
      description='Sample Twisted application',
      author='Teemu Harju',
      author_email='teemu.harju@gmail.com',
      url='http://blog.teemu.im',
      packages=['sample'],
      package_data={'twisted.plugins': ['twisted/plugins/sample.py']},
      zip_safe=False
)

These files will create a Twisted application called sample that runs a webserver on port 8080 that responds “It works!” when the root URL is accessed.

Now, run:

$ bin/buildout
...

I’ve not put the output to the example since there is so much of it. But after the buildout is ready and if everything worked fine you can test that your environment is ready by running the bin/twistd script like this:

$ bin/twistd --help

The output should contain our sample application and you can run it by typing:

$ bin/twistd -n sample

Now you can start developing your Twisted application and test it in your safe and restricted environment using virtualenv and buildout. By the way, if you want to get out of your virtual Python environment you can do that simply by typing:

$ deactivate

It would be probably good to include some kind of a test runner in the buildout script to make sure that your buildout is not broken. How that can be done is probably a blog post topic of it’s own. That’s all for now. Have fun with buildout and Twisted. Feel free to ask in the comments if this didn’t work for you for some reason.

Python For Series 60 v.1.9 Released For Testing

December 28th, 2008

Python for Nokia’s Series 60 platform has been around for four years now and to be honest, not much has happened on that front during the past year. However, suddenly on 24th of December Nokia releases a version 1.9.0 of the Python for Series 60 that is a major rewrite of the whole thing and comes now with Python 2.5 version of the core language. As usual, the odd-number version branch means that the release is for testing purposes only and the even-numbered 2.0 version branch should be released once it becomes more stable. Blog at Croozeus.com has done pretty nice wrap up of the new release and here are my thoughts.

First of all I should mention that as I write this blog entry I’ve not yet had time to test the new Python for Series 60 release. So I apologize beforehand for all false comments I’m about to make.

It seems that they are giving a lot more focus on the ease of development in this new release. Which is a really good thing I must say. What pleases me the most is that they are planning on improving the Python runtime deployment so that the end-user or the guy that is installing Python applications should not have to worry too much about having or not having the Python runtime installed on his phone. Definitely a good thing. The new release includes a packaging tool that is not part of the S60 SDK and is basically ensymble with added GUI. Ensymble is an excellent tool and it is very nice to see it included in the official PyS60 release.

Like mentioned already, the new release includes the version 2.5 of the Python interpreter and most of it’s standard libraries. Ok, the word “most” does not sound good here. I’ll focus first on the good things. First, the new release has Expat XML parser in it. Definitely a good thing since XML is something that pretty much every application out there uses and so far people have had to make ugly regexp XML parsers or use 3rd party package of expat to be able to parse XML in their PyS60 applications. However, I would say that including JSON parser as the official Python 2.6 release did lately, would probably be a good idea too.

Also, inclusion of asyncore and more compliant socket module sounds nice. I can’t wait to try Twisted on PyS60 and see how it works. One could do some crazy things with that on a mobile phone.

Then to the things that are not included from the standard Python 2.5 libraries. Now, I don’t have too much information on this since, like said before, I haven’t tried the new release yet. However, to my disappointment I noticed that sqlite3 is not included. SQLite should probably be a platform component in S60 because it is kind of becoming a de facto standard in mobile platforms since both iPhone and Android platforms use it. I don’t know what is the equivalent in S60 or does such exist but having some kind of storage other than just plain text file for PyS60 applications would be extremely nice thing to have.

Ok, I have to try out the new PyS60 release soon. I’m hoping that I will be pleasantly surprised. I’ll definitely write more about it later.

Setting your SRV records straight for XMPP

December 14th, 2008

I’ve noticed that DSN SRV records are something that are not very common knowledge among even some of the really techy people. Well, the reason is probably that most people never need to know what they actually are. I’m gonna explain them here briefly and show how I set the DNS SRV records for my XMPP server hosted at Slicehost.com.

Ok, so what these DNS SRV records are. If you’re familiar with the DNS MX record you know that it is used to indicate where is the email server that is hosting a certain domain. For example, I have domain service.com and I’m running my webserver at www.service.com and my email server is at smtp.service.com. Naturally, I would want my users to have email addresses like user@service.com. Here I would set the DNS MX record to point to smtp.service.com so when email servers communicate with each other they can ask from DNS server that “where is the email server for domain service.com?”.

DNS SRV records were specified for a bit more general purpose than MX records that can be used with email only. You might have XMPP server at xmpp.service.com and would like your users have also XMPP address of the format user@service.com. This is how the SRV records for the XMPP look like. This is an example of SRV records I’ve set for my XMPP server at teemu.im.


_xmpp-client._tcp.teemu.im. 82698 IN SRV 10 0 5222 teemu.im.
_xmpp-server._tcp.teemu.im. 86400 IN SRV 10 0 5269 teemu.im.

What there actually mean? Well, the _xmpp-client._tcp.teemu.im. line is the line that XMPP clients use to ask from DNS that “where I can find the XMPP server for domain teemu.im?”. The DNS server responds that “the XMPP server can be found from host teemu.im port 5222″. The other line that has _xmpp-server._tcp.teemu.im. is used by the XMPP servers when they talk to each other using the XMPP server-to-server protocol, similarly as the email servers use the MX records to find out information about each other.

The SRV records can also be used to do “poor mans load balancing” by using the priority and weight attributes, but I won’t go in to that now. Instead, I’ll show you how you can configure DSN SRV records on Slicehost.com server. This is because I use Slicehost, but the same principles apply for other hosting providers as well.

First, go to your SliceManager and login. There choose the “DNS” tab and you should see something like this:

Slicehost's SliceManager DNS Zones Tab

Slicehost's SliceManager DNS Zones Tab

Now click “Records” and then “new record”. Fill the form as shown below:

Slicehost SliceManager new DNS SRV record for XMPP clients

Slicehost SliceManager new DNS SRV record for XMPP clients

Note that the value in “Name” field starts with underscore although it is not visible in the screenshot.

Do the same for the server-to-server protocol, except for the name set _xmpp-server._tcp.domain.com. and for the data use 0 5269 domain.com..

You can use tool called dig for testing your configuration. Type the following line to see if your configuration is correct:

dig @ns1.slicehost.net SRV _xmpp-client._tcp.domain.com

The result should be:


;; ANSWER SECTION:
_xmpp-client._tcp.domain.com. 86400 IN SRV 10 0 5222 domain.com.

By the way… when configuring DNS it is good to set the time-to-live value to something relatively small. In case you make mistakes, you don’t need to wait until the DNS record will be updated. Other good practice is to use the @nameserver.domain.com parameter for dig command so that the entry does not propagate to other DNS servers and you can change it pretty much when ever you want.

Google Calendar on Nokia 770 HOWTO

August 6th, 2007

Dan Tye posted a comment on my blog describing how it is possible to make your Google Calendar viewable from your Nokia 770 or from Nokia N800 using the good old Opera browser. It seemed really useful so I decided to post it here so more people will be able to find it.

Anyone who has editing control of their own web site can see their Google calendar on the Nokia 770. here is HOW:

1. On your PC, Click the down arrow next to your calendar listing on the left side of your google calendar page and choose CALENDAR SETTINGS from the drop-down.
2. Under “Private Address” in this page, choose the HTML icon.
3. A POP-UP will appear. Click the link to “Configuration Tool”
4. This page will format HTML you can paste into a private address web page you create to display your Google calendar. (choose option 2 under CONTROLS so the Google Icon will not take the top 1/3 of the page.
5. After copying the resulting code to a file or clipboard, simply create your own calendar page on your own web site. Paste the html into the body of the code view of your web page and publish/save it. You may want to set your web site robots.txt file to ignore this calendar page, thus keeping it a bit more private (KGP, not PGP!)

Shortcomings – yes, but better than no access to your Google Calendar!

DMT

Python for Series 60 Goes Final

July 10th, 2007

Finally it happened. It was announced today in the Forum Nokia Python section that a 1.4.0 final version of Python for Series 60 has been released. This is something that I’ve been waiting this for a long time since I’ve been kind of pissed of with the Symbian signing policy. And guess what… this final version of PyS60 has been officially signed by Nokia with all developer certificate capabilities so no more signing is required for Python application in order to access e.g., the GSM location or GPS APIs. How cool is this? Finally, it is humanly possible to develop applications for S60 mobiles. You can expect to see more PyS60 related stuff in this blog once the summer holidays are over. Until then, have a good summer…. I know I will. :D

Yet another style update

July 10th, 2007

I did yet another style update for the site. After a while, the last theme I used started to feel a bit too much eye-candy and it didn’t work very well on the Internet Explorer so I decided to make my own theme. This one is based on a CSS template made by Andreas Viklund. I’m still not totally satisfied with it and it still does not work correctly on Internet Exporer, but I’m working on it.

Blog style update

July 7th, 2007

To celebrate the summer I thought I should update the blog layout a little. It was sort of outdated already. This is what I came up with. It is still “under construction”, but I try to fix it little by little and probably by the end of the summer it will be final.

Pownce

July 7th, 2007

I just got invited to Pownce. Thanks to salvatore for that. It’s like Twitter but way better. It allows users to do micro-blogging, and share links and files between each other. You can follow my public profile here. I just wish I could use Pownce also from my Nokia N800 or from my mobile phone. It would be more real-time that way since I’m carrying those with me pretty much all the time. Well, maybe they’ll open an API soon so I could write some client for that purpose then. Btw, I’ve got couple of invites left to share if someone is interested.

Pownce