Biella Coleman: How to secure revolution in Silicon Valley
[m] maybe we ll have some more fiber optic cable cuts in silicon valley and then the revolution will happen
Even though Enrico is not smiling on this picture, he s one of the friendliest Debian person that I know. I always enjoy his presentations because he can t refrain from inserting jokes or other funny tricks. Subscribe to my newsletter to get my monthly summary of the Debian/Ubuntu news and to not miss further interviews. You can also follow along on Identi.ca, Twitter and Facebook.
5 comments Liked this article? Click here. My blog is Flattr-enabled.
There was another question recently on StackOverflow that I had meant to
discuss in a follow-up post here. User deltanovember asked
about slow recursive functions
and used the very classic
Fibonacci number
as an example. To recap, Fibonacci number are defined with two initial
values F(0) = 0 and F(1) = 1; thereafter the Fibonacci number F(n) is defined
as the sum of the two preceding numbers: F(n) = F(n-2) + F(n-1).
This leads to very straightforward implementations using recursion:
Unfortunately, this elegant implementation which remain close to the abtract formulation of the recurrence algorithm performs very poorly in R as there is noticeable overhead in function calls which becomes dominant in a recursion. This lead to the original question on StackOverflow, and the accepted answer uses a trick presented by Pat Burns in his lovely R Inferno: rewrite the solution using a computer science trick called memoization:## R implementation of recursive Fibonacci sequence fibR <- function(n) if (n == 0) return(0) if (n == 1) return(1) return (fibR(n - 1) + fibR(n - 2))
That is a fair answer, and even more was suggested with a link to a terrific analysis calling the Fibonacci recurrence the worst algorithm in the world. That is also fair, but all the basic research into better algorithms exploiting some structure of the problem to advance performance (and of course understanding) is overlooking one crucial part: algorithm analysis is essentially independent of the language. So whatever improvements we obtain by thinking really hard about a problem are then available for other implementations too. So with a tip of the hat to the old Larry Wall quote about Lazyness, Impatience and Hubris, I would like to suggest what I consider a much simpler route to much better performance: recode it in C++ using both Rcpp (for the R/C++ integration) and inline for the on-the-fly compilation, linking and loading of C++ code into R.fibonacci <- local( memo <- c(1, 1, rep(NA, 100)) f <- function(x) if(x == 0) return(0) if(x < 0) return(NA) if(x > length(memo)) stop("'x' too big for implementation") if(!is.na(memo[x])) return(memo[x]) ans <- f(x-2) + f(x-1) memo[x] <<- ans ans )
This single R function call## inline to compile, load and link the C++ code require(inline) ## we need a pure C/C++ function as the generated function ## will have a random identifier at the C++ level preventing ## us from direct recursive calls incltxt <- ' int fibonacci(const int x) if (x == 0) return(0); if (x == 1) return(1); return (fibonacci(x - 1)) + fibonacci(x - 2); ' ## now use the snippet above as well as one argument conversion ## in as well as out to provide Fibonacci numbers via C++ fibRcpp <- cxxfunction(signature(xs="int"), plugin="Rcpp", incl=incltxt, body =' int x = Rcpp::as<int>(xs); return Rcpp::wrap( fibonacci(x) ); ')
cxxfunction() takes the code
embedded in the arguments to the body variable (for the core
function) and the incltxt variable for the helper function we
need to call. This helper function is needed for the recursion as
cxxfunction() will use an randomized internal identifier for the
function called from R preventing us from calling this (unknown) indentifier.
But the rest of the algorithm is simple, and as beautiful as the initial
recurrence. Three lines, three statements, and three cases for F(0), F(1) and
the general case F(n) solved by recursive calls. This also illustrates how
easy it is to get an integer from R to C++ and back: the
as and wrap simply do the right thing
converting to and from the SEXP types used internally by the C
API of R.
A performance comparison of the basic R version fibR, its
byte-compiled variant fibRC and
and the C++ version fibRcpp shown above is very compelling.
We have added a file fibonacci.r to the large and still growing
set of examples included with Rcpp, and we can just
execute that script with Rscript or (as here) r
from the littler package:
So the recursion for the original argument of N=35 takes just over a minute at about 61.5 and 61.9 seconds, respectively, for the R version and its byte-compiled variant (as per the column titled elapsed). So byte-compilation essentially offers no help for the bottleneck of slow function calls. The C++ versions relying on Rcpp which created in a few lines of code and a single call toedd@max:~/svn/rcpp/pkg/Rcpp/inst/examples/Misc$ r fibonacci.r Loading required package: inline Loading required package: methods Loading required package: compiler test replications elapsed relative user.self sys.self 3 fibRcpp(N) 1 0.092 1.0000 0.09 0.00 2 fibRC(N) 1 61.480 668.2609 61.47 0.00 1 fibR(N) 1 61.877 672.5761 61.83 0.02 edd@max:~/svn/rcpp/pkg/Rcpp/inst/examples/Misc$
cxxfunction however takes just 92
milliseconds---or a relative gain of well over six-hundred times.
That provides another nice demonstration of what Rcpp can do. Improved
algorithms for well-understood problems are surely one way to accelerate solutions.
But there are (many ?) times when we do not have the luxury of being able to
think through to a new and improved approach. Or worse, such an approach may
even introduce new errors or inaccurracies if we get it wrong on a first try.
With Rcpp, we are able to the express the problem as written in its original statement: a simple
recursion. The gain relative to a slow R implementation is noteworthy---and
could of course be improved further if we really needed to by relying on
better algorithms like memoization. But for day to day tasks, I gladly take
speedups of (up to) a few hundred times thanks to
Rcpp without having to do hard
algorithmic work.
Before closing, a quick reminder that I will be giving two classes on
Rcpp in a few weeks. These will be in New York on September 24, and San Franciso on October 8, see
this blog post as well as
this page at Revolution Analytics (who are a
co-organiser of the classes) for details and registration information.
After many years of successfully dodging doing any serious programming in PHP, I had to get my feet wet with PHP for my RL job: I was requested to develop a simple but non-trivial module for our Institute's Drupal-based webpage.
It basically meant two and a half weeks devoted to head-scratching: I had read the very good John van Dyk's Pro Drupal Development book, and knew it would be an important resource were I to face writing a module or work on a theme beyond the most basic stuff So I checked it out of the library, and started basically writing something similar to my good and trusty Perl code. After all, PHP seems quite similar to Perl, although forcing you to write more for no gain (i.e. requiring an array() declaration whenever you want to store more than one value together) or lacking important and useful constructs (not having a sane way to prepare a SQL statement for multiple executions with different parameters Yes, there are DB access methods that do provide it, but Drupal 6 does not use them).
Anyway, book in hand, I started understanding while implementing (which is way different than just reading the book, right?) Drupal's notions. I cannot say I like them, but it's ahem doable.
Now, I hit a problem twice. I chose to ignore it the first time, as it was a corner case I'd look into later on, but had to devote for hours of my attention later on. When designing the menu (which for Drupal means not only the facility which prepares/displays links to the bits of functionality, but also the access control layer and the action dispatcher a huge yay! for responsability separation!), I had only two access levels: Public and administrator. So, this seemed like a good fit:
'third/action', 'something/else'); $items[$item]['access callback'] = TRUE else
$public refused to be publicly visible.
It was not until after a severe amount of head-scratching I came across this jewel in the PHP online manual:
Warning This function may return Boolean FALSE, but may also return a non-Boolean value which evaluates to FALSE, such as 0 or "". Please read the section on Booleans for more information. Use the === operator for testing the return value of this function.GRAH. Using a sane language for some time had made me forget about the problems of true/false sharing space with other meaningful values. So, yes, checking for inclusion of a value in an array in PHP this way should be compared with class-bound identity (that's what
=== means) to FALSE, or better yet, using a function that exclusively returns a boolean (as in_array()).
Anyway While arrays (which in PHP are any kind of list, be it keyed as a hash or consecutive as a traditional array) are such an usual construct in any language, please do take a look at PHP's array-handling API. Too long. Too complex. Too many corner cases.
I cannot but wonder what keeps PHP as a popular language. It hurts.
Brent S. Elmer reported the Debian bug
#640000 on Thursday September 1st, against evolution.
Bug #630000 was reported as of June 10th. This time, it took a little
bit more than 2.5 months for 10,000 bugs.
This #640000 bug was indeed "fixed" very quickly as it turns out it
was not a bug..:-).. Congratulations to Corsac for fixing it..:-)
about:tabs url to see the damage on your session. Please note that the number of groups is currently wrong until you open the tab grouping interface.
This is what the extension has to say about my session 2 days ago, right after a startup:
http://buildd.debian.org/iceweasel. It gives me the build status of the latest iceweasel package I uploaded to Debian unstable. That url is particularly known in my browsing history, and is the first hit when I type buildd in the urlbar (actually, even typing b brings it first). Unfortunately, that url redirects to https://buildd.debian.org/status/package.php?p=iceweasel through an HTTP redirection. I say unfortunately because when I type buildd in the urlbar, I get 6 suggestions for urls in the form http://buildd.debian.org/package (I also watch other packages build status), and the suggestion to switch to the existing tab for what the first hit would get me to is 7th. Guess what? The suggestion list only shows 6 items ; you have to scroll to see the 7th.
The result is that I effectively have fifteen tabs open on that url.
I also keep a lot of bugzilla.mozilla.org bugs open in different tabs. The extension tells me there are 255 of them for 166 unique bugs. Largely, the duplicate bug tabs are due to having these bugs open in some tab, but accessing the same bugs from somewhere else, usually a dependent bug or TBPL. I also have 5 tabs opened on my request queue. I usually get there by going to the bugzilla home page and clicking on the My Requests link. And I have several tabs opened on the same bug lists. For the same reason.
When I started using tab groups, I splitted in very distinct groups. Basically, one for Mozilla, one for Debian, one for stuff I want to follow (usually blog posts I want to follow comments from), and one for the rest. While I was keeping up with grouping at the beginning, I don t anymore, and the result is that each group is now a real mess.
Firefox has hundreds of millions users. It s impossible to create a user experience that works for everyone. One thing is sure, it doesn t work for me. My usage is probably very wrong at different levels, but I don t feel my browser is encouraging me to use it better, except by making my number of opened tabs explode to an unmanageable level (I already have 30 tabs more than when I started writing this post 2 days ago).
There are a few other things I would like to know about my usage that my extension hasn t told me yet, either because it doesn t tell, or because I haven t looked:
I stopped my story in early 1994, after my Big Switch to the
mysterious and new world of Linux.
My home server, kheops, is now running Debian and is fed with news and
mail by FrMug, formerly French Minix Users Group and now run by AFAU,
the "Association Fran aise des Amateurs de Usenet".
As I'm still console-challenged, I'm reading mail and news on another
machine I have at home, named "khephren", which is running an, ahem,
beta copy of Microsoft Windows 95. Yeah, I know...:-)
These 1994-1999 years were mostly the Usenet years, for me. I
gradually became more and more involved in several fr.* newsgroups,
either related to the Linux world...or to the Windows world. The
latter was professionnally a bonus for me as 1994 is also the year
where I switched from the Material Science department at Onera to the
Network and Computing Department. My mission there was to accompany
the increasing prevalence of personal desktop workstations in the
daily life of what was formerly the Big Castle of Computing at Onera,
hosting various generations of Cray computers, most of which being in
the Top500 world supercomputers (we even had one in the Top10, very
briefly, at somepoint).
So, I was "the PC and Windows guy" in this world of supercomputing,
Unix and network wizards. But my hobby at home helped me keeping and
growing skills in both "worlds" which, over the years, has proven to
be a not so common profile..:-)
Meanwhile, at home, I was spending hours and nights reading those
newsgroups...or getting involved in fr.* hierarchy management..or
expanding my friends network to many people in the news, Linux, BSD
worlds.
That lasted for about 3 years with ups and downs (with three young
kids at home, you end up having slightly less time...). I was
gradually improving my home server use, adding more functionalities to
it, for instance setting it up as a file and print server with Samba
1.9.something (this will be the beginning of a long story with
samba!).
Unfortunately, my dear Ren had
passed in the meantime. Ren did so
much for Linux in France that he'll be the only link I give in
this article. If you happen to go through P re Lachaise cemetery in
Paris, go to its Memory garden instead of visiting Jim Morrison's
grave and drink a whisky bottle in memory of Ren .
Or just install one of the most funnily named Debian packages: le-dico-de-rene-cougnenc
and, again, drink something to his memory (whisky is highly preferred).
We then reached 1997 and a specific event: my father (who was very
sick for years) passed during summer, some time after my grand-father
passed too. As it apparently happens for
many people, it triggerred me into the interest for family
history. After all, those people who are going away are family
memories. And, in some way, I wanted to keep track of this memory.
As a consequence, I started collecting family memories, interviewing
my close relatives (the oldest ones) and ending, of course, in
tracking all this with my computers. That was the start of a long
genealogy research that sent me on the track of the Perrier family (of
course), but also all other branches, on my mother and father side, as
well as reconstructing the tree of cousins we have, etc, etc.
As anybody who did that knows, this is quite an endless task but I
went very committed to it. I quickly ended up in joining research
groups that were using the recent growth of personal access to
Internet communication. Those groups were, in these 90's, building
elaborated systems where people can help together in their research
instead of having to travel to places where archives are stored. I
participated to many such groups and even ended up animating one who
was doing research in archives of the "Yvelines" "d partement", my
place of living (even though I have no family branch there). At the
same time, other groups were sending me research results for my own
family in the French region where my roots are.
Collective effort, help others for free, you can recognize things that
are a constant all over these years, indeed.
It actually helped me in tracking my Perrier ancestors up to about
1680, with 11 generations of men holding that name (from
Jean-Baptiste, my son, up to tienne Perrier, who is born about
1640-1650, in the small village named Briant in Sa ne et Loire, in
France). Or even climbing up to Laurent Polette, born circa 1510,
mentioned in a document date February 1562. He his my oldest known ancestor.Those folks being 15 generations
before me. My oldest ancestor is born under Fran ois the First, King
of France, protector of Leonardo Da Vinci, at the time La Joconde was
painted or the Chambord castle was built. Doh.
Unfortunately, genealogy software, at that time, was quite poor for
Unix systems. Lifelines was a quite strong development but wasn't that
user-friendly and I ended up using a Windows-based "shareware"
software written by an individual. Still, my Linux machine was used
quite intensively: databases were stored there, and saved there, all
important informations were there, my mail was received there, along
with dozens of mailing lists I was reading. I even hosted a few
mailing lists on my home server.
Still, in the meantime also, again in 1997, in October, another event
happened. We had a pollution peak in Paris area and October 1st was
the first (and as of now the only ever) day where driving restrictions were applied.
Up to that moment, I was driving to/from work (30 kilometers one way).
I decided to use this opportunity to really test public transport, for
one full month. As
I knew it would take me much more time than driving, I tried to
imagine a way to use that time.
How about reading mail and news on a laptop instead of only at home?
Done... In a few days, I found a used Compaq Aero laptop (486 16MHz),
I installed Debian "bo" on it, switched my mail and news workflow to
console programs (mutt and slrn) and here we go!
So, finally, in October 1997, I was using Linux nearly all time long,
the only exception being genealogy data handling.
That laptop was named "mykerinos" (the small pyramid) and....my laptop
is still named mykerinos, though it's now the 5th mykerinos I have..:-)
Ah, and since then, I nearly always use public transport to go to/from
work. Debian addiction is good for the planet!
At some point (I don't remember exactly when...about 1999, I think), DSL connections
appeared and one of the first DSL FAI emerged on France: Free. I was already
using their services for dialup access, but DSL was then a revolution:
persistent connection! And nearly immediately, static IP!
I became one of their first DSL customers (and I'm still
one). Moreover, I had then friends working there...and they had many
Debian machines to host their services.
So, with the help of my Freenix friends, some DNS hosting on their
machines and the still tireless eu.org entirely free domain, perrier.eu.org was born.
Immediately, this gave me opportunities for doing many interesting
things with my home server: setting up www.perrier.eu.org and use
it....for learning web things and sharing genealogical data. For
instance, I ended up hosting some data sent by other genealogists such
as digital copies of archives for some French regions, all served
through my 512/128kbps DSL line (quickly upgraded to 2Mb, IIRC).
And, very quickly, I felt the need to share my family tree, of course!
And here comes Geneweb.
Written (in Ocaml) by Daniel de Rauglaudre, Geneweb was (and still is)
by far one of the best tools to share genealogy data over the Net. So,
I ended up installing it on my home machine. Guess how I did that?
"apt-get install geneweb", of course. Yes, it was packaged. Indeed by
Brent Fulgham who did the initial release on July 22nd 2000.
Here, my memory is a little bit vague. I think I actually packaged
Geneweb for my own use and sharing it on upstream FTP site, forking Brent's package as a start, but updating
to latest upstream release. Then I quickly ended up having discussions
with Brent about this new upstream release, and that lead to:
geneweb (3.10-3) unstable; urgency=low
* Merging with unofficial package from Geneweb ftp site
(in preparation of new maintainer [Christian Perrier] takeing
over responsibility). Note that all of this work is from
Christian.
* Default database dir is now writable by members of geneweb group
* New geneweb group added at installation
* Package tries to properly handle former installations of the
unofficial Geneweb package available on Geneweb ftp site
* Debconf dialogs translated in french
* More languages available
* Creation of /var/geneweb/etc, /var/geneweb/cnt, /var/geneweb/images
with proper permission so that authorised users may use these also
* When de-installed, all databases are exported with gwu (should allow
smooth upgrades when the databse format changes)
-- Brent A. Fulgham <bfulgham> Mon, 22 Jan 2001 19:30:47 -0800
See? Already "debconf translation to French"! "More languages
available". Here we are.
As discussed with Brent, he propsoed me to take the package over. So,
on January 11th 2001, I had applied in the New Maintainer Process.
I'm amazed how quickly it went indeed: there was a tool I needed, it
needed to be packaged, I could handle the packaging...and then I
decided to be involved.
Here we are: bubulle is on his way to become one of those magicians
who are building the best universal operating system. Yes, me, the
clueless material scientist..:-)
How did it go? You'll know this in next episode, of course...
For a (german) talk I ll be giving soon I was interested in a list of open source projects which use Jenkins. Jenkins is a great open source continuous integration server. I was wondering whether such a list exists but since it doesn t exist yet I created my own and Kohsuke Kawaguchi (creator of Hudson/Jenkins) suggested to blog about it. There we go.
So, we stopped our very boring story around 1992. Let's summarize
where I was at that moment:
User BobH asked
on StackOverflow about accelerating path-dependent loops. He provided a simple example in which a vector gets filled conditional on the value of
the preceding element. Simple to code, but hard to vectorise.
By the time I saw that question yesterday evening, Josh Ulrich had already posted a nice answer suggesting
to switch from ifelse to if to escape the overhead of a vectorised expression on simple scalars. I meekly added a comment
suggesting that Rcpp would likely do well on this and that someone should volunteer
such an answer. Well, it is still August and Mr. Someone is on holiday, so this morning I followed up with such an answer. And as it turns out to
work quite well indeed, we will repost it here.
Let's start with the general setup, and the two functions supplied by Josh. We also byte-compile these using the compiler package which
is the culmination of several years of work by R core member Luke Tierney. This package was added to R
during the last major release, and we assessed it
in this earlier blog post as well as several Rcpp-related
follow-ups. We also load the packages for on-the-fly 'inline' compilation and easy benchmarking:
We see that basic worker just assign to the i-th element based on the preceding element. Function two uses the aforementionedlibrary(inline) library(rbenchmark) library(compiler) fun1 <- function(z) for(i in 2:NROW(z)) z[i] <- ifelse(z[i-1]==1, 1, 0) z fun1c <- cmpfun(fun1) fun2 <- function(z) for(i in 2:NROW(z)) z[i] <- if(z[i-1]==1) 1 else 0 z fun2c <- cmpfun(fun2)
if statement, and both are also byte-compiled.
Writing the same code in C++ using both Rcpp (for the R/C++ integration) and
inline for the on-the-fly compilation, linking and loading of C++ code into R is pretty
straightforward too:
This single R function call takes the code embedded in the argument to thefunRcpp <- cxxfunction(signature(zs="numeric"), plugin="Rcpp", body=" Rcpp::NumericVector z = Rcpp::NumericVector(zs); int n = z.size(); for (int i=1; i<n; i++) z[i] = (z[i-1]==1.0 ? 1.0 : 0.0); return(z); ")
body variable, builds a complete function in temporary file,
and then compiles, links and loads it. We can now call funRcpp() just like the other four functions and do so via the
benchmark() function of the rbenchmark package.
We can focus on the columns labelled elapsed and relative. The C++ version is faster by a factor of almost one-hundred compared to the byte-compiled version of funtion2, and almost four-hundred times faster than the plain-R variant of function2. And function1 is even worse, coming at well over twenty-two-hundred times the run-time of the C++ version. Byte-compilation also helps little here. For comparison, we also ran the original example of a very short vector, called more frequently:R> z <- rep(c(1,1,0,0,0,0), 100) R> identical(fun1(z),fun2(z),fun1c(z),fun2c(z),funRcpp(z)) [1] TRUE R> R> res <- benchmark(fun1(z), fun2(z), + fun1c(z), fun2c(z), + funRcpp(z), + columns=c("test", "replications", "elapsed", "relative", "user.self", "sys.self"), + order="relative", + replications=1000) R> print(res) test replications elapsed relative user.self sys.self 5 funRcpp(z) 1000 0.005 1.0 0.01 0 4 fun2c(z) 1000 0.482 96.4 0.48 0 2 fun2(z) 1000 1.989 397.8 1.98 0 3 fun1c(z) 1000 11.365 2273.0 11.37 0 1 fun1(z) 1000 13.210 2642.0 13.21 0
The qualitative ranking is unchanged: the Rcpp version dominates. Function2 usingR> z <- c(1,1,0,0,0,0) R> res2 <- benchmark(fun1(z), fun2(z), + fun1c(z), fun2c(z), + funRcpp(z), + columns=c("test", "replications", "elapsed", "relative", "user.self", "sys.self"), + order="relative", + replications=10000) R> print(res2) test replications elapsed relative user.self sys.self 5 funRcpp(z) 10000 0.047 1.00000 0.04 0 4 fun2c(z) 10000 0.134 2.85106 0.13 0 2 fun2(z) 10000 0.328 6.97872 0.32 0 3 fun1c(z) 10000 1.080 22.97872 1.08 0 1 fun1(z) 10000 1.243 26.44681 1.24 0
if instead of the vectorised ifelse is second-best with the byte-compiled version being about twice as fast that the plain R
variant, but still almost three times slower than the C++ version. And the relative differences are less pronounced: relatively speaking, the
function call overhead matters less here and the actual looping matters more: C++ gets a bigger advantage on the actual loop operations in the longer
vectors. That it is an important result as it suggests that on more real-life sized data, the compiled version may reap a larger benefit.
All in all a nice demonstration of Rcpp, and a gain of almost one-hundred to the best
byte-compiled version is nothing to sneeze at---especially when it is so easy to write and load a five-line C++ function thanks to
Rcpp.
Before closing, a quick reminder that I will giving two classes on
Rcpp in a few weeks. These will be in New York on September 24, and San Franciso on October 8, see
this blog post as well as
this page at Revolution Analytics (who are a
co-organiser of the classes) for details and registration information.
This year without our friends from Grml, but The MirOS Project
(all two active developers and our Booth Babe gecko2@) will of
course attend FrOSCon, nicknamed
Froschkon, again.
We ll have a pre-event meal time at my favourite Jugoslawian
Restaurant on Friday (20:00 CEST) contact me privately for the
co rdinates if interested. On Saturday and Sunday we ll staff a
booth and answer questions about the many projects we have (more
or less) running, including but not limited to paxmirabilis (aka
MirCPIO), The MirBSD Korn Shell
aka mksh(1), jupp the editor,
and developers private projects such as slowly undermining Debian
or Google-Go. While slow we are still working on World Domination.
And teaching
people good shell programming by example code.
We might even bring CDs, but I m still working on the ISO last
night s build aborted because the OS grew a bit making the floppy
image not fit any more. (Solution, drop ping(8) and rtsol(8), but
re-add sf(4) and bce(4) now that they fit again.)
The first day of the Desktop Summit was yesterday, Saturday, August 6. I loved it and gave a presentation. There are two very different stories I can tell on the topic of gender equality in
free software. I'll start with the bad.
Together with Revolution Analytics, I will be offering two more
one-day classes on the Rcpp package for seamless integration of
R and C++.
The format will follow the workshop Romain and I gave
during the tutorial day preceding this year's R/Finance conference. The style will once again be
hands-on, with copious concrete examples and solid coverage of most aspects of Rcpp
and related packages such as RInside,
RcppArmadillo and others. The eight-hour schedule contains about six hours
of instruction, split into four sessions of around ninety minutes. This leaves ample time for both lunch and coffee breaks, and for informal
discussions and Q+A.
Two one-day classes will be offered: The first in
New York on Saturday, September 28, 2011 and the second one two weeks later in
San Franciso on Saturday, October 8, 2011.
Please see the official course page for
more details, concrete location info and maps as well as registration details.
Feel free to contact me at the usual email address with questions.

$ apt-get install usb-modeswitch wvdialRecent versions of usb_modeswitch (and matching udev entries) already support the Huawei E1750 out of the box, a few seconds after attaching the device it's automatically switched into modem mode. After this has been done you should have three new serial devices, usually /dev/ttyUSB0, /dev/ttyUSB1, and /dev/ttyUSB2. You'll need /dev/ttyUSB0 for talking to the device using AT commands. The lsusb output should look like this (see here for full lsusb -vvv):
$ lsusb Bus 001 Device 045: ID 12d1:1436 Huawei Technologies Co., Ltd.(before usb_modeswitch was run, the USB IDs were 12d1:1446)
The required settings for connecting are documented at fonic.de, specifically the APN (pinternet.interkom.de). A username and/or password is not required. You need to provide your FONIC PIN though. Dialing is done using the *99# number and using the ATDT command.
I'm using the following wvdial config file:
$ cat /etc/wvdial.conf [Dialer Defaults] Modem = /dev/ttyUSB0 Baud = 460800 [Dialer pin] Init1 = AT+CPIN=1234 [Dialer fonic] Phone = *99# Username = foo Password = foo Stupid Mode = 1 Dial Command = ATDT Init2 = ATZ Init3 = AT+CGDCONT=1,"IP","pinternet.interkom.de"
For mobile Internet access you would do the following:
$ wvdial pin --> WvDial: Internet dialer version 1.61 --> Initializing modem. --> Sending: AT+CPIN=1234 AT+CPIN=1234 OK --> Modem initialized. --> Configuration does not specify a valid phone number. --> Configuration does not specify a valid login name. --> Configuration does not specify a valid password.
$ wvdial fonic --> WvDial: Internet dialer version 1.61 --> Initializing modem. --> Sending: ATZ ATZ OK --> Sending: ATZ ATZ OK --> Sending: AT+CGDCONT=1,"IP","pinternet.interkom.de" AT+CGDCONT=1,"IP","pinternet.interkom.de" OK --> Modem initialized. --> Sending: ATDT*99# --> Waiting for carrier. ATDT*99# CONNECT --> Carrier detected. Starting PPP immediately. --> Starting pppd at Mon Aug 1 xx:xx:xx 2011 --> Pid of pppd: 18672 --> Using interface ppp0 --> local IP address xxx.xxx.xxx.xxx --> remote IP address yyy.yyy.yyy.yyy --> primary DNS address 193.189.244.225 --> secondary DNS address 193.189.244.206
One of the first things that I worked on here at DebConf11 is supporting the HTML target in gnome-terminal. This means that if you copy a part of the screen and paste it into some application that handles HTML (such as evolution or my blog s edit field), attributes such as color and boldness are preserved. Here are some examples:
A man page
MAN(1) Manual pager utils MAN(1)
NAME
man - an interface to the on-line reference manuals
SYNOPSIS
man [-C file] [-d] [-D] [--warnings[=warnings]] [-R encoding] [-L locale] [-m
system[,...]] [-M path] [-S list] [-e extension] [-i -I] [--regex --wildcard]
[--names-only] [-a] [-u] [--no-subpages] [-P pager] [-r prompt] [-7] [-E
encoding] [--no-hyphenation] [--no-justification] [-p string] [-t]
[-T[device]] [-H[browser]] [-X[dpi]] [-Z] [[section] page ...] ...
man -k [apropos options] regexp ...
man -K [-w -W] [-S list] [-i -I] [--regex] [section] term ...
man -f [whatis options] page ...
man -l [-C file] [-d] [-D] [--warnings[=warnings]] [-R encoding] [-L locale]
[-P pager] [-r prompt] [-7] [-E encoding] [-p string] [-t] [-T[device]]
[-H[browser]] [-X[dpi]] [-Z] file ...
man -w -W [-C file] [-d] [-D] page ...
man -c [-C file] [-d] [-D] page ...
man [-hV]
DESCRIPTION
man is the system's manual pager. Each page argument given to man is normally
the name of a program, utility or function. The manual page associated with
each of these arguments is then found and displayed. A section, if provided,
Manual page man(1) line 1 (press h for help or q to quit)
A coloured diff from git
commit 55c514ae6a714abcfa818c33f00a2c051412c3d9
Author: Joachim Breitner <mail@joachim-breitner.de>
Date: Thu Jul 21 12:08:56 2011 +0200
Refactor vte_terminal_determine_colors_internal
to work on VteCellAttr instead of VteCell, and use it in
vte_terminal_cellattr_to_html.
diff --git a/src/vte.c b/src/vte.c
index 8bcc95d..7d4a6f1 100644
--- a/src/vte.c
+++ b/src/vte.c
@@ -6532,19 +6532,18 @@ swap (guint *a, guint *b)
static void
vte_terminal_determine_colors_internal(VteTerminal *terminal,
- const VteCell *cell,
+ const VteCellAttr *attr,
gboolean selected,
gboolean cursor,
guint *pfore, guint *pback)
guint fore, back;
Midnight commander
Links Datei Befehl Optionen Rechts < ~/build/gnome-terminal/vte .[^]> < ~/build/gnome-terminal/vte .[^]> 'n Name Gr e Modifikations 'n Name Gr e Modifikations /.. BERVZ. 20. Jul 18:23 /.. BERVZ. 20. Jul 18:23 /.git 4096 22. Jul 12:42 /.git 4096 22. Jul 12:42 /autom4te.cache 4096 22. Jul 11:20 /autom4te.cache 4096 22. Jul 11:20 /doc 4096 22. Jul 11:20 /doc 4096 22. Jul 11:20 /glade 4096 22. Jul 11:20 /glade 4096 22. Jul 11:20 /gnome-pty-helper 4096 22. Jul 09:47 /gnome-pty-helper 4096 22. Jul 09:47 /perf 4096 22. Jul 11:20 /perf 4096 22. Jul 11:20 /po 4096 22. Jul 11:20 /po 4096 22. Jul 11:20 /src 12288 22. Jul 12:41 /src 12288 22. Jul 12:41 /termcaps 4096 22. Jul 11:20 /termcaps 4096 22. Jul 11:20 .gitignore 935 22. Jul 11:20 .gitignore 935 22. Jul 11:20 AUTHORS 41 20. Jul 18:25 AUTHORS 41 20. Jul 18:25 COPYING 35068 22. Jul 11:11 COPYING 35068 22. Jul 11:11 ChangeLog.pre-git 433051 20. Jul 18:25 ChangeLog.pre-git 433051 20. Jul 18:25 HACKING 905 20. Jul 18:25 HACKING 905 20. Jul 18:25 MAINTAINERS 118 20. Jul 18:25 MAINTAINERS 118 20. Jul 18:25 Makefile 30512 22. Jul 11:20 Makefile 30512 22. Jul 11:20 Makefile.am 1247 22. Jul 11:11 Makefile.am 1247 22. Jul 11:11 Makefile.in 28812 22. Jul 11:20 Makefile.in 28812 22. Jul 11:20 NEWS 43910 20. Jul 18:25 NEWS 43910 20. Jul 18:25 README 496 20. Jul 18:25 README 496 20. Jul 18:25 aclocal.m4 377874 22. Jul 11:20 aclocal.m4 377874 22. Jul 11:20 *autogen.sh 610 20. Jul 18:25 *autogen.sh 610 20. Jul 18:25 BERVZ. BERVZ. 10G/104G (9%) 10G/104G (9%) Hint: To look at the output of a command in the viewer, use M-! ~/build/gnome-terminal/vte $ 1Hilfe 2Men 3Ansicht 4Bear~ten 5Kopieren 6Ver~ben 7Mkdir 8L schen 9Men s 10BeendenThese changes are discussed in GNOME Bugzilla bug #365121 and can be downloaded in my git repository. Unfortunately, I later found out that I was not basing my work on the current development version, which has changed considerably, so we will see how and when my changes will actually make it into GNOME. Also note that my blog s HTML editor actually modifies the HTML code, so looking at the source of this page does not give you the code that I generate. Update: I ported my changes onto the vte-next branch, so they could be merged now. Please follow the bug report if you want to know more.
See previous post for the rationale.
I ve then started migrating my mail using evolution.
First I ve installed dovecot and set it up so as to store my mail inside my $HOME/Maildir/ dir. Evolution will run dovecot on demand through a pipe, instead of through network access like with regular remote IMAP servers. So dovecot won t be started as a daemon. I ve been inspired by Roland s setup for this (even though I not using offlineimap).
Inside Evolution, I ve configured a second mail profile, for this local IMAP server, using the custom command to connect to server :"MAIL=maildir:$HOME/Maildir /usr/lib/dovecot/imap"
I ve migrated my existing mail folders using copy to function on all top-level mail folders from the local evolution storage, to copy them to the IMAP folders. Note that some folders that include a dot ( . ) need to be renamed, as the dot is a path separator for IMAP.
I ve adapted Evolution s vfolders definitions so as to take into account the active remote folders instead of the local ones, and that s it, the mail is migrated.
I m using fetchmail + procmail to fetch mail from remote servers and to deliver it to the Maildirs, using dovecot s deliver program, with something like :
DELIVER="/usr/lib/dovecot/deliver"
:0: w
$DELIVER
I ve migrated the filters of evolution to server-side Sieve rules so that dovecot s deliver sorts incoming mail in the right Maildirs. The dovecot config needs to be adapted to activate the sieve plugin (dovecot-sieve Debian package), in /etc/dovecot/conf.d/15-lda.conf :
protocol lda
# Space separated list of plugins to load (default is global mail_plugins).
mail_plugins = $mail_plugins sieve
log_path = /tmp/dovecot-deliver-errors.log
info_log_path = /tmp/dovecot-deliver.log
The original Evolution filters rules were stored in $HOME/.config/evolution/mail/filters.xml, so I wrote a quick python DOM parsing tool to extract the (long) list of definitions and generate Sieve rules for the $HOME/.dovecot.sieve config file (in which folder hierarchy uses a . path separator instead of a / ).
The sieve-test program can be used to check is sieve rules function as you want.
Now this is all setup, I only need to configure notmuch to index all the Maildirs. But this is left to another post.
I ve been fed up with Evolution being so buggy and slow, which was making managing my mail ever more painful as time passes. Still, one of the advantages of Evolution over other MUAs is the vfolders feature, which I ve been using intensively for years. Would there be some alternate way of managing my mail ?
I ve been reading about notmuch s progress in becoming a very powerful mail management / retrieval tool (it could very well replace the vfolder feature of Evolution), but unfortunately, it is not (yet) integrated with Evolution.
Others have documented their mail setup, and it seems that I could achieve a middle ground solution by migrating all my mail folders, currently stored inside Evolution s local storage, into Maildir folders managed by a local dovecot IMAP server. Evolution would still be my MUA, but it would store my mail inside Maildirs through dovecot. I ve been told that Evolution may be less buggy with IMAP than with local folders, which could solve my main annoyances. Also, it would make it possible to index mail with notmuch, as it supports the Maildir storage format.
I ve then decided to take the opportunity of a holiday period to start the migration attempt.
I ll document it in another post.
mksh R40b (nowadays with filled
in user s caveats (for R40, too!)
and packager s upgrade hints) has
just been released. This is a should-have upgrade, fixing a number of
admittedly some obscure bugs, changing things begun in R40, improving
upon others. Thanks to the PLD Linux guys for spotting all these errors;
thanks to them and phpnet.org both for adopting mksh so well.
I have also fixed a bug in nroff(1) which will lead to an even
nicer looking HTML manpage mksh(1) (after the next rebuild and upload of
a MirBSD snapshot scheduled RSN).
jupp 3.1.16 took on the task
of merging Debian joe changes (aiming at an upload). I also split the
jupprc file into three versions (2.8 generic/DOS, 3.1+jupp and 3.7/Unix)
because of the differences in the baseline executables making rc files
partially mutually incompatible (think Insert key), annoyingly warning
(think syntax, hmsg), or less usable (joe s new menu system).
jupp 2.8.2 is a companion to
jupp 3.1.16 mostly because of the new help window character map
Binaries for jupp should be updated RSN too.
Considering Banja Luka is arriving quickly, the r in RSN should be
taken with a few grains of salt. I ve also scheduled working on the pcc
Debian package for the next future; updating lynx and maybe others like
OpenSSH in MirBSD is also due; cvs(1) will receive more of my time, but
before the next Upload I d like to fix LP#12230 once verified.
Builds for Debian/m68k are also still running. I note I did in fact
not manage to make a new base image, yet (but 2.6.39 kernels
miss a patch, anyway, so waiting for 3.0 is ok). It s still using gcc-4.4
because nobody tests gcc-4.6 and gcj-4.6 FTBFS due to SIGSEGV, but that s
ok in my books. rsyslog is broken but sysklogd works.
The #ksh Freenode page finally
got a well-deserved link to Planet Commandline. Throw more my way!
Acronyms and translations,
too. (Got Norwegian and Rumanian covered in the meantime. No idea whether any
RTL languages will work in that beast. But I m young and need the money)
Since I m writing a wlog entry anyway let me thank Gunnar for a nice
summary on the current Free Culture discussion; my comments on Nina s site
seem to be eaten, but let me support it fully, although, of course, I normally
use a copycenter style licence, which
is specifically written for general works of authorship under copyright law,
not limited to software. I did in fact have that in mind. Maybe some people
will like it (it s less than one Kibibyte long) either generally or just for
their everyday random musings (they can then keep CC-BY-SA for the big works
if they so desire).
Wouter, grass background makes green headlines illegible. I ve never liked,
and never installed manually, cups either. (Benny tells me that Apple s new
version refuses to talk with a non-Apple cups, kinda defeating the whole idea
I think.) Port 9100 is JetDirect (probably with an HP in front and some subset
of trailing) and just nice. (Being able to talk ESC/P with your printer
like print '\033K\x07\0\x3E\x81\x99\xA5\xA5\x81\x3E' >/dev/lpa too
rocks though, IMHO. Yes, mine can, and I still can. /dev/lpa is BSD.)
Kai, thanks for your vimrc lines:
:highlight TrailWhitespace ctermbg=red guibg=red :match TrailWhitespace /\s\+$\ \+\ze\t/
Automatic removal is harmful, though I just fell into the trap since jupprc contains needed whitespace at EOL but manual removal (bound to ^K] in jupp) rocks. And I like that your solution uses such strong a colour vim users are the single most represented offender group for actually leaving the redundant whitespace at EOL there, and it should hurt their eyes. (Sadly there is some vehement disagreement preventing them from inclusion in grml-etc-core but that s why I re-post them here.) Ah, and jupp can of course display whitespace visibly (although it uses / , replacing the arrow with if no UTF-8, not ), accessible with ^Ov. Steve, want to put up a checklist for sites? We can crowdsource the testing to maybe get some interesting results Some other people would get more comments if they were idling in IRC (Freenode) or allow comments on their blog, specifically without too high an entrance barrier OpenID is ok, but many other things, and ECMAscript, are not; but I can t really say that loud because our wlog is static HTML compiled from a flat plaintext data source so it doesn t allow such either. I often forget what I wanted to add if I can t get it out quickly enough (especially at work). Sowwy Me like the cat picture postings (Amayita, Tiago, Gracias!).
Well, actually, just one, and it s not even mine.
Matt Stancliff benchmarked a few different
methods of SSL termination and found that nginx sucked
rocks relative to the other options. However, it
turns out the comparison wasn t as balanced as he originally thought, and
discovered that the SSL ciphers you use are quite
important.
As an aside, I like Matt s benchmark everything philosophy.
On Friday, June 24, the last day of Open Source Bridge, I won a scarf! It says, "Open Source Citizen."
I wasn't the only one. The attendees nominated people who "made an extra effort to help others and share their knowledge," and the conference committee chose the three people they felt exemplified this. The winners were Sumana Harihareswara, Igal Koshevoy, and me.
In case you don't know Sumana, she's the new Wikimedia Volunteer Development Coordinator, a friend, and a commenter here at Asheeshworld. In the photo of her and her new scarf, you can also see Ward Cunningham. I suggest reading her wrap-up about the conference, and checking out the notes from her talk.
I haven't met Igal, but I've learned he's a fixture of the Portland tech scene. He's user number one on opensourcebridge.org and one of the original contributors to calagator, the most important event calendar in the Portland tech world. That's just a brief summary; follow him on Twitter to keep in touch.
I started the conference a little shy, not wanting to introduce myself to people, so I hung out with Sumana. She talked to everyone she could find, and there I was standing next to her. On the first day, it was only because of Sumana's outgoingness that people knew who I was. On the second and third days, I was involved in two sessions: a panel on open source communities and a talk about the OpenHatch training missions.
I was extremely honored to be chosen. There were so many other spectacular people I met for the first time, like Valerie Aurora,
Jacinta Richardson, Brian Aker, and Alex Linsker. These are all people with three crucial traits: they're extremely knowledgeable, friendly, and opinionated. I'm glad I had a chance to attend and meet them!
Photo credits: Thanks to Noah Swartz for the photo of me. Sumana's photo comes from her post to wikitech-l. Igal's comes from his Open Source Bridge user profile.
Next.