Search Results: "ag"

16 July 2011

Steve Kemp: There is a reason why I test sites

Recently I was at a pub and there was an advert for pub tokens displayed on the window. Seemed like a cute idea: Perfect for friends, family, remote hackers/developers & similar. When I got home I checked out their site. Seemed simple and nice enough, with good coverage (in terms of local drinking establishments that would accept their tokens). I decided to sign up, with the intention of gifting my sister with some delicious beer. Unfortunately that's where it all went wrong. I tend to act the same on all new sites. Partly to amuse myself, partly to get a feel for how safe/secure/good the site is, I'll try to login with a few different values. You know you're in trouble when you see responses like this:
SELECT * FROM cms_module_pubtokens_users where email = '"'' AND
   password =''"' LIMIT 1
Fatal error: Call to a member function FetchRow() on a non-object in
  /home/pubtokens/U79P18WQ/htdocs/includes/functions.php on line 291
Suffice it to say I sent them an email, then poked them on twitter, but to no avail. In conclusion they don't get my money, and I couldn't recommend them to anybody else at this point either. As I'm not a customer at least I can rest easy knowing my details haven't been compromised at any point over the past few months. ObQuote: "It can't rain all the time" - The Crow

Matthew Palmer: MySQL replication and crash recovery

The question was recently asked, How do I perform crash recovery on a MySQL master/slave database cluster? Because replication is async, a transaction that has been committed to the master may not be able to leave the master before the crash happens. The short answer is, you don t. Asynchronous replication, by it s very nature, is prone to these sorts of issues, and MySQL doesn t make life easier in general by using query replay. Some of the issues aren t massive: for instance, if a slave crashes, the master will keep replication logs for the slave until it comes back up (as long as the slave comes back before the master decides some of the replogs are too old and starts deleting them, of course), so as long as you can live without a master for a while, you can recover and continue along your merry way. Promoting a slave to be a master, on the other hand, is a situation frought with peril. Here, you ve just got to hope hope that your chosen slave is consistent with the master s state at death (because it s async, you have no guarantees about that), and that all the other slaves have the same ideas about what counts as the current state of the data. If your newly-promoted slave managed to apply an update that another slave didn t, that slave will be out of sync with reality (until such time as the now-dead master comes back and replays all those queries hahahaha). To even guarantee that any slaves have a consistent view of the data as compared to the new master, you ve got to rereplicate everything from the new master, because MySQL s where are you up to? counter is master-specific. I ve heard people who have to deal with this sort of thing these days say that the Maatkit tools are handy for dealing with various issues of this type (monitoring, repairing the database when it gets inconsistent). However, I prefer to keep right the hell away from MySQL replication altogether, after a year of having to gently coax an insane MySQL tree replication setup to do the right thing for any extended period, and watching a group of DBAs at Engine Yard go slowly insane. My preferred alternatives are: Never discount the value of the Jaws approach to scaling ( we re gonna need a bigger boat^Wmachine ) hardware is so ridiculously cheap, relative to the clueful sysadmin time needed to make (and keep) MySQL replication running, that you really need to be at the huge end of town (where other scaling issues are going to bite you in the arse first) before spending too much time on your database is worth the investment. Even then, you ll get more bang for your buck from: than you ever will from the constant, mind-numbing grind that is keeping MySQL replication going.
  1. The term comes from a time when a colleague near-screamed This slave cluster keeps fucking me! at a particularly intransigent set of MySQL slaves.

John Goerzen: Decreasing Time to Eternal September

For those of you that aren t familiar, please read about the Eternal September, which refers to the lasting damage to a community when vast numbers of newbies suddenly enter and dramatically harm the quality and usefulness if discussions.

15 July 2011

Alexander Reichle-Schmehl: About Debian, The Hurd and Linux or in short: Yes, we will still have a Linux kernel

A lot of online magazines are currently reporting about Debian, its port to the Hurd kernel and plans for the next release. However, there seem to be quite some misunderstandings. One online magazine took the cake by titling Debian 7.0 Wheezy: Erste Pl ne f r Hurd statt Linux-Kernel (rough translation: Debian 7.0 Wheezy: First plans for Hurd instead of Linux kernel), and a colleague already asked me, if we are really going to drop the Linux kernel. So let's clarify one thing: The Debian Project does not plan to drop its port to the Linux kernel (nor its two ports to the FreeBSD kernel for what it's worth). Apparently it all started with a short status report and if you read it, you'll just read that some people are trying and planing to get Debian 7 (aka wheezy) to be released with an additional port to the Hurd. It is not yet clear if they will achieve their goal, nor did anyone ever mention anything about replacing the Linux or the FreeBSD kernel. So, calm down, nothing changed, just someone talking about the possibility of adding yet another port to the next release. Please note the adding.

Jon Dowland: puppet revisited

In an earlier post, I asked a number of questions, most of which are now answered. Here's a recap: I wrote
I stumbled across some CF Engine-style definitions for puppet in a Debian Administration article (taken originally from puppet's own wiki, which have since been moved/deleted)
Perhaps it was removed with good reason This is a fairly horrid solution to the problem. Phil was the first to suggest investigating Augeas, a neat tool that abstracts away the nasty specifics of parsing the myriad configuration file formats and provides a unified, tree-like interface for adjusting configurations. The interface reminds me of manipulating XML via the DOM. More on Augeas in a later blog post I also wrote
package [foo,bar]: syntax worked fine, but is a little verbose and the package list is awkward to maintain buried inside the puppet syntax. I spent some time trying to see whether I could populate a puppet list based on the contents of a file: then I could list the packages one-per-line in a separate file. I haven't found a way of doing that yet.
I haven't found a more concise way of solving this problem, but as I have grown more familiar with puppet's syntax I have become less bothered by it. I igo suggested pre-processing the puppet configuration, but I'd rather not complicate my provisioning approach (VCS hooks) by attempting that. Finally I wrote
Using my laptop as a second node also exposed some interesting puppet client behaviour. Once I went off-site, the laptop tried to look up puppet on foreign networks (such as my home network). I would have assumed that, once the strong SSL association had been made, the client would try to connect to the FQDN of the server. This probably isn't a serious problem in practice, as we probably won't need to rely on nodes off-site talking to the configuration server, but I hope that the client doesn't trust any host that happens to answer to puppet...
I'm pleased to report that the client is at least this clever: it refused to talk to a local puppetmaster that I setup at home.

Jon Dowland: puppet packages

Puppet lets you install packages on your system, like this:
package   'foo': ensure => installed  
You can also ask it to make sure that the package is kept up-to-date:
package   'foo': ensure => latest  
What does "latest" mean? How does this interact with a mixed repository sources.list on Debian? It turns out that both ensure => installed and ensure => latest honour pinning. For example: if you have a stable system; sid in your sources.list and pinning set up; either of the above will install stable's version of foo. I think ensure => latest is less useful than it might initially appear. If you install a package foo and use ensure => latest, but foo depends on packages bar and baz, it will only ensure that foo is up-to-date, not bar or baz. Similarly any other packages that you have not installed with puppet will not be kept up-to-date unless you name them explicitly. If you want to automatically take all updates from your distributor, you need to use another mechanism to do so.

Dirk Eddelbuettel: MCMC and faster Gibbs Sampling using Rcpp

Sanjog Misra, who uses Rcpp for Monte Carlo Markov Chain (MCMC) analyses in quantitative marketing, kindly set me a short example of Rcpp use. The example is based on a blog post by Darren Wilkinson which itself discusses and compares the suitability of R, Python, Java or C for MCMC analysis, using the Gibbs sampler as a concrete example. Darren's post is worth checking out: he stresses the rather pragmatic aspects of how fast and/or easy it is to write the code, rather than just the mere runtime. As such, he is not too concerned with a speed advantage of Python over R which he sees at a factor of around 2.4, leaving him to continue to prototype in R. Similarly, with C 'only' being faster than Java by a factor of two, he prefers Java for the numerically more demanding parts. We do of course advocate the use of Rcpp to combine the best aspects of R and C++, respectively. This Gibbs sampler example provides a nice backdrop. So working with Darren's example, consider the same Gibbs sampler for a bivariate distribution (and apologies for the lack of latex typesetting on my blog)
f(x,y) = k x^2 exp( -x y^2 - y^2 + 2y - 4x)
where the conditional distributions are
f(x y) = (x^2)*exp(-x*(4+y*y))               ## a Gamma density kernel
f(y x) = exp(-0.5*2*(x+1)*(y^2 - 2*y/(x+1))  ## a Gaussian kernel
Sanjog then spotted and corrected a small error in the variance expression in Darren's derivation; this is now acknowledged on Darren's website. Full details are in the R script now committed in SVN. The R code for the Gibbs sample can therefore be written as follows below. Note that this uses thinning to minimize serial correlation in the conditional densities--which renders the computation more demanding as 'N times thin' draws have to be generated:
## Here is the actual Gibbs Sampler
## This is Darren Wilkinsons R code (with the corrected variance)
## But we are returning only his columns 2 and 3 as the 1:N sequence
## is never used below
Rgibbs <- function(N,thin)  
    mat <- matrix(0,ncol=2,nrow=N)
    x <- 0
    y <- 0
    for (i in 1:N)  
        for (j in 1:thin)  
            x <- rgamma(1,3,y*y+4)
            y <- rnorm(1,1/(x+1),1/sqrt(2*(x+1)))
         
        mat[i,] <- c(x,y)
     
    mat
 
A second variant can be computed using the R bytecode compiler which appeared with the recent release of R 2.13.0 (and which we analysed in this blog post from April). This is as easy as
## We can also try the R compiler on this R function
RCgibbs <- cmpfun(Rgibbs)
Thanks to Rcpp and the inline package, we can also write a C++ variant that can be built and launched from R with ease. The C++ code is assigned to an R text variable gibbscode. (And we used to typeset such code on the blog as a character string, ie in a faint red color---but have now switched to highlight it as if it were freestanding C++ code. It really is passed as a single string to R which then uses the cxxfunction() to compile, link and load a C++ function built around the code. See previous posts on the inline package for more.)
## Now for the Rcpp version -- Notice how easy it is to code up!
gibbscode <- '

  using namespace Rcpp;   // inline does that for us already
  // n and thin are SEXPs which the Rcpp::as function maps to C++ vars
  int N   = as<int>(n);
  int thn = as<int>(thin);
  int i,j;
  NumericMatrix mat(N, 2);
  RNGScope scope;         // Initialize Random number generator
  // The rest of the code follows the R version
  double x=0, y=0;
  for (i=0; i<N; i++)  
    for (j=0; j<thn; j++)  
      x = ::Rf_rgamma(3.0,1.0/(y*y+4));
      y = ::Rf_rnorm(1.0/(x+1),1.0/sqrt(2*x+2));
     
    mat(i,0) = x;
    mat(i,1) = y;
   
  return mat;             // Return to R
'
# Compile and Load
RcppGibbs <- cxxfunction(signature(n="int", thin = "int"),
                         gibbscode, plugin="Rcpp")
It is noteworthy how the code logic is essentially identical between the basic R version, and the C++ version. Two nested loops control draws of x from a Gamma distribution, conditional on y, as well as draws of y from a Normal, conditional on x. Add a small amount of parameter passing to obtain the parameters N and thin, allocation of a results matrix and setup of the random number generator state to remain consistent with R, as well as a return of the matrix---and that is all. As Darren's code uses the GNU GSL in its C variant, I also became interested in seeing how a C/C++ hybrid variant using our RcppGSL package would fare. The code is below.
gslgibbsincl <- '
  #include <gsl/gsl_rng.h>
  #include <gsl/gsl_randist.h>
  using namespace Rcpp;  // just to be explicit
'
gslgibbscode <- '
  int N = as<int>(ns);
  int thin = as<int>(thns);
  int i, j;
  gsl_rng *r = gsl_rng_alloc(gsl_rng_mt19937);
  double x=0, y=0;
  NumericMatrix mat(N, 2);
  for (i=0; i<N; i++)  
    for (j=0; j<thin; j++)  
      x = gsl_ran_gamma(r,3.0,1.0/(y*y+4));
      y = 1.0/(x+1)+gsl_ran_gaussian(r,1.0/sqrt(2*x+2));
     
    mat(i,0) = x;
    mat(i,1) = y;
   
  gsl_rng_free(r);
  return mat;           // Return to R
'
## Compile and Load
GSLGibbs <- cxxfunction(signature(ns="int", thns = "int"),
                        body=gslgibbscode, includes=gslgibbsincl,
                        plugin="RcppGSL")
This code is similar to the version using just Rcpp, but we need to allocate space for the GSL random generator object (and later release that memory allocation), and we do of course call the GSL functions. This also necessitates declaring the function using the two header files listed as arguments for the include argument of cxxfunction(). So how is the performance? The script (now committed in Rcpp's SVN repo as examples/RcppGibbs/RcppGibbs.R, and also part of the next release) creates the output below when running in non-interactive mode (whereas interactive mode creates a few charts too):
edd@max:~/svn/rcpp/pkg/Rcpp/inst/examples/RcppGibbs$ r RcppGibbs.R
Replication # 1 complete 
Replication # 2 complete 
Replication # 3 complete 
Replication # 4 complete 
                    N=1000 N=5000 N=10000 N=20000
Elasped Time (R)     0.124  2.650  10.511  41.773
Elasped Time (RC)    0.081  1.916   7.594  30.280
Elapsed Time (Rcpp)  0.003  0.076   0.306   1.221
Elapsed Time (Rgsl)  0.002  0.049   0.196   0.784
SpeedUp Rcomp.       1.530  1.380   1.380   1.380
SpeedUp Rcpp        41.330 34.870  34.350  34.210
SpeedUp GSL         62.000 54.080  53.630  53.280
               test replications elapsed  relative user.self sys.self
4  GSLGibbs(N, thn)           10   7.845  1.000000      7.84        0
3 RcppGibbs(N, thn)           10  12.218  1.557425     12.22        0
2   RCgibbs(N, thn)           10 312.296 39.808286    311.98        0
1    Rgibbs(N, thn)           10 420.953 53.658764    420.59        0
The first block is a hand-computed comparison using four sets of parameters; the second block uses the excellent rbenchmark package to compare ten runs at twenty-thousand draws. We see a nominal increase in performance due to the bytecode compiler, saving roughly 38 percent which seems appropriate given that the R code mostly controls the loops; actual work in undertaken in the already compiled RNG functions. The Rcpp variant is about 34 times faster than the pure R code. Sanjog reported higher increases on his OS X machines (and Darren's post echos a similar order of magnitude). However, on my i7 running Linux I always obtained an improvement in the mid- to high thirties. That is certainly already a rather pleasant result. What surprised and stunned me at first was that the GSL solution scores an improvement of around 53 times (close to the factor of 60 reported by Darren). A closer look at the code (shown above) makes it clear that there are very few compute-intensive operations outside of the RNG draws. I validated this further with a second study timing just one million draws each from a Gaussian and Gamma using R via Rcpp, and using the GSL. It turns out that the R code is about 2.5 times slower for random draws from the Gamma distribution than the GSL. Inspection of the source code---in files src/nmath/rgamma.c for R and randist/gamma.c for the GSL shows why. R uses a much more complex (and presumably more precise) algorithm. I may follow up with Martin Maechler to see if we can illustrative the numerical benefits of this more expensive approach---this blog entry is getting long enough already. So to sum up: Gibbs sampling is a somewhat resource-heavy Monte Carlo Markov Chain method for investigating multivariate distributions. R excels at quick and simple explorations, albeit at somewhat slower execution speed. The Rcpp package can help by providing easy means to accelerate simulations by a significant factor. The example discussed here is now in SVN repository for Rcpp and will be part of the next release.

Updated 2011-07-16: Darren has just updated his comparison; fixed two typos here too.

14 July 2011

Kai Wasserb ch: Vim: automatically delete whitespaces and CRs

Yesterday's blog entry garnered a lot of attention and some responses (in the form of e-mails, which is totally fine). Two of them deserve, as far as I'm concerend, their own little entry in the mini-series I kicked off. So, here we go: First up was reader Sylvain "ythier" Hitier, who suggested adding
set list lcs=eol: ,tab: -,trail: 
to your .vimrc and making use of the :list option. The above line will highlight tabulators, trailing whitespaces and the end of a line. And it'll allow you to differentiate the three.
A warning though: you would want to deactivate this, in case you want to do copy and pasting with your mouse. [UPDATE] Sylvain just sent me a little key binding for C&P he's using to toggle the highlighting:
function CutPaste()
  setlocal paste! nu! list!
endfunction
map <F10> :call CutPaste()
[/UPDATE] The second really nice idea came by courtesy of Thilo Six to my attention:
" automatically delete trailing whitespace & Dos-returns     2
fun! <SID>MyDeleteTrailingWhitespace()
  if ! &bin
    let l:l = line(".")
    let l:c = col(".")
    silent! :%s/[\r \t]\+$//
    call histdel("search", -1)
    call cursor(l:l, l:c)
  endif
endfun
autocmd BufWritePre,FileWritePre * call <SID>MyDeleteTrailingWhitespace()
The above snippet will automatically delete trailing whitespace and carriage returns as added by a lot of Windows programs.
Again a little warning: the function is executed automatically, so be sure you have only replacements included in the regular expression you really want to get deleted! Thanks a lot for all the input I've received!

Dominique Dumont: I m a Debian Developer now :-)

He he , after6 months of hard labor (just kidding, it wasn t difficult) I m now a brand new Debian Developer. I plan to continue the work I did before, mainly Perl module packaging, helping getting a recent rakudo in Debian, and improving configuration tools (as upstream author). I wish to thanks heartfully all the people that helped me before and during the new maintainer process:
gregoa, xoswald and the whole pkg-perl team. Too bad I can t go to Banja-Luka. All the best

Jamie McClelland: GnuCash with python bindings

Hats off to the GnuCash developers and the Parit Worker Collective for the python bindings to GnuCash. If there is any doubt that free software makes life easier it's being able to write your own accounting import scripts while reading the original source code. I had to re-compile Debian's version of GnuCash because it doesn't have the python bindings enabled by default. As root:
apt-get build-dep gnucash
apt-get install python-dev
As a non privileged user:
apt-get source gnucash
cd gnucash-N.N.N # varies depending on your version)
Then, edit debian/rules and add --enable-python-bindings to the dhautoconfigure command. I replaced the line:
--enable-locale-specific-tax
With the lines:
--enable-locale-specific-tax \
--enable-python-bindings
Then, update the change log with:
dch
Built the new package:
dpkg-buildpackage -rfakeroot -uc -b
I then wrote a python module. It logs into the server running our members database, runs a script to export tab delimited lists, and then imports them into our gnucash xml file. It's far from perfect (I'm fairly new to python). Also - I have sheepishly inserted code that searches for certain values by accessing the gnucash file directly (via python's xml handling modules). I couldn't figure out how to do the search I needed with they available python methods, although it may very well be there and I just couldn't figure it out. If anyone is interested in using it for a template:
#!/usr/bin/python
import sys 
import os
import time
import csv
import warnings
from xml.dom.minidom import parse
from gnucash import Session,  GncNumeric
from gnucash.gnucash_business import Customer, Invoice, Entry, BillTerm
from decimal import Decimal
import datetime
import tempfile
import subprocess
def main(argv = None):
  if argv is None:
    argv = sys.argv
  path = os.environ['MFPL_GNUCASH_PATH']
  if not os.path.exists(path):
    print """Path (%s) does not exist. Please set 
    MFPL_GNUCASH_PATH environment variable\n""" % path
    return 1 
  if os.path.exists(path + '.LCK'):
    print """Lock file exists. Is GNUCash running?\n"""
    return 1 
  command = argv[1]
  import_file = None
  if 2 in argv:
    if argv[2] == '--from-file':
      if argv[3]:
        if os.path.exists(argv[3]):
          file_path = argv[3]
          import_file = open(file_path,'r')
        else:
          print "Can't find file to import: %s" % argv[3]
          return 1
      else:
        print "Please pass path to file if using --from-file"
        return 1
    else:
      print "I didn't understand the argument: %s" %s
  # download import file if not provided
  if import_file == None:
    import_file = get_data(command)
  # The file might be gzipped, so
  # open and save it 
  s = get_gnucash_session(path) 
  s.save()
  s.end()
  # Wait a second, so we can create a backup
  # without a name collision
  time.sleep(1)
  # Open for real now...
  s = get_gnucash_session(path) 
  xml_dom = parse(path) 
  if command == "members":
    ret = import_members_from_file(s, xml_dom, import_file)
  if command == "invoices":
    ret = import_invoices_from_file(s, xml_dom, import_file)
  s.save()
  s.end()
  return ret
def get_data(command):
  import_file = tempfile.NamedTemporaryFile()   
  if command == 'members':
    remote_cmd = 'acc-member-list'
  else:
    remote_cmd = 'acc-invoice-list'
  args = [ '/usr/bin/ssh', 'mayfirst@hay.mayfirst.org', '/home/mayfirst/bin/' + remote_cmd ]
  subprocess.call(args,stdout = import_file)
  return import_file
def import_invoices_from_file(s, xml_dom, csvfile):
  dialect = 'excel-tab'
  csvfile.seek(0)
  reader = csv.reader(csvfile, dialect)
  nodes = xml_dom.getElementsByTagName('gnc:GncCustomer')
  already_entered = 0
  entered = 0
  for row in reader:
    member_id = row[0]
    invoice_id = row[1]
    invoice_date = row[2]
    invoice_amount = row[3]
    invoice_desc = row[4]
    if not member_id.isdigit():
      # header line or not coded to a member?
      continue
    member_id = int(member_id)
    invoice_id = int(invoice_id)
    if invoice_exists(xml_dom, invoice_id):
      # print "Already entered %s (%s)" % (invoice_date,invoice_id)
      already_entered += 1
    else:
      if not member_exists(xml_dom, "No Name McGoo - fix me" , member_id):
        print "Skipping member id %s, invoice id %s - member doesn't exist" % (member_id, invoice_id)
      else:
        invoice_enter(s, member_id, invoice_id, invoice_date, invoice_amount, invoice_desc )
        entered += 1
  print "Invoices entered from last two months: %s (%s already existed)" % (entered, already_entered)
  return True
def get_guid_from_member_id(nodes,member_id):
  member_id = pad_number(member_id)
  for node in nodes:
    for child in node.childNodes:
      if child.nodeName == 'cust:guid':
        guid = child.childNodes[0].data
      if child.nodeName == 'cust:id':
        if member_id == child.childNodes[0].data:
          return guid   
def import_members_from_file(s, dom, csvfile):
  dialect = 'excel-tab'
  csvfile.seek(0)
  reader = csv.reader(csvfile, dialect)
  already_entered = 0
  entered = 0
  for row in reader:
    member = row[0]
    member_id = row[1]
    if not member_id.isdigit():
      # header line?
      continue
    member_id = int(member_id)
    if member_exists(dom, member, member_id):
      #print "Already entered %s (%s)" % (member, member_id)
      already_entered += 1
    else:
      member_enter(s, member, member_id )
      entered += 1
  print "Members entered from last two months: %s (%s already existed)" % (entered, already_entered)
  return True
def get_gnucash_session(path):
  with warnings.catch_warnings():
    warnings.simplefilter("ignore")
    return Session(path, is_new = False)
def member_enter(s, member, member_id):
  print "Entering %s with id %s" % (member, member_id)
  book = s.book
  root = book.get_root_account()
  commod_table = book.get_table()
  USD = commod_table.lookup('CURRENCY', 'USD')
  member_id = pad_number(member_id)
  new_customer = Customer(book, member_id, USD, member)
def invoice_enter(s, member_id, invoice_id, invoice_date, invoice_amount, invoice_desc):
  book = s.book
  root = book.get_root_account()
  commod_table = book.get_table()
  USD = commod_table.lookup('CURRENCY', 'USD')
  invoice_id = pad_number(invoice_id)
  member_id = pad_number(member_id)
  invoice_date_object = datetime.datetime.strptime(invoice_date, "%Y-%m-%d %H:%M:%S") 
  member = book.CustomerLookupByID(member_id)
  assert( member != None )
  assert( isinstance(member, Customer) )
  assets = root.lookup_by_name("Assets")
  recievables = assets.lookup_by_name("Recievables")
  income = root.lookup_by_name("Membership Dues")
  invoice = Invoice(book, invoice_id, USD, member, invoice_date_object )
  invoice_value = gnc_numeric_from_decimal(Decimal(invoice_amount))
  invoice_entry = Entry(book, invoice)
  invoice_entry.SetDescription(invoice_desc)
  invoice_entry.SetQuantity( GncNumeric(1) )
  invoice_entry.SetInvAccount(income)
  invoice_entry.SetInvPrice(invoice_value)
  invoice_entry.SetDate(invoice_date_object)
  invoice_entry.SetDateEntered(invoice_date_object)
  print "Entering invoice %s %s %s" % (invoice_id, invoice_date, invoice_amount)
  invoice.PostToAccount(recievables, invoice_date_object, invoice_date_object, "", True)
def pad_number(num):
  return "%(number)06d" %   'number': num  
def member_exists(dom, member, member_id):
  member_id = pad_number(member_id)
  for node in dom.getElementsByTagName('gnc:GncCustomer'):
    for child in node.childNodes:
      if child.nodeName == 'cust:name':
        for grandchild in child.childNodes:
          if member == grandchild.data:
            return True
      if child.nodeName == 'cust:id':
        for grandchild in child.childNodes:
          if member_id == grandchild.data:
            return True
  return False
def invoice_exists(dom, invoice_id):
  invoice_id = pad_number(invoice_id)
  for node in dom.getElementsByTagName('gnc:GncInvoice'):
    for child in node.childNodes:
      if child.nodeName == 'invoice:id':
        for grandchild in child.childNodes:
          if invoice_id == grandchild.data:
            return True
  return False
def gnc_numeric_from_decimal(decimal_value):
    sign, digits, exponent = decimal_value.as_tuple()
    # convert decimal digits to a fractional numerator
    # equivlent to
    # numerator = int(''.join(digits))
    # but without the wated conversion to string and back,
    # this is probably the same algorithm int() uses
    numerator = 0
    TEN = int(Decimal(0).radix()) # this is always 10
    numerator_place_value = 1
    # add each digit to the final value multiplied by the place value
    # from least significant to most sigificant
    for i in xrange(len(digits)-1,-1,-1):
        numerator += digits[i] * numerator_place_value
        numerator_place_value *= TEN
    if decimal_value.is_signed():
        numerator = -numerator
    # if the exponent is negative, we use it to set the denominator
    if exponent < 0 :
        denominator = TEN ** (-exponent)
    # if the exponent isn't negative, we bump up the numerator
    # and set the denominator to 1
    else:
        numerator *= TEN ** exponent
        denominator = 1
    return GncNumeric(numerator, denominator)
if __name__ == "__main__":
  sys.exit(main())

David Welton: The Long Tail of the Clued In

Nearly three years ago, I wrote an article comparing Linode and Slicehost having been first a Slicehost customer and then switched to Linode. I would have been happy to stay with Slicehost, because they seemed like good people, but the 64bit vs 32bit issue, especially, tilted things very far in Linode's favor. I thought the results were damning, and many people agreed with me, judging by the number of people clicking through the affiliate link I added later. Based on some comments I read from this guy, who did a similar comparison, at http://journal.uggedal.com/vps-performance-comparison/ I think that between the two of us we drove a lot of customers towards Linode.
Those articles have been out there for years, and are very easy to find with Google. Curious to monitor the situation, a while ago, I set up a Twitter search feed for "Slicehost vs Linode" to see if people were talking about my article, and what other people were suggesting. Overwhelmingly, those suggestions have been for Linode too. Recently, Rackspace, who acquired Slicehost several years ago, announced they would be shutting down Slicehost and transitioning their customers to Rackspace: http://www.readwriteweb.com/cloud/2011/05/rackspace-shutting-down-sliceh.php And yet - people are still asking about Slicehost vs Linode on Twitter! This is a useful reminder to me of how much, in our profession (and likely others, but I'm going with what I know) there is a core of the very clued in, who follow all the latest trends (and, negatively, fads too, at times), and are highly informed about everything that's going on. Outside that, though, there is a pretty long tail of people who are much less informed. That's not a criticism of those people, either; perhaps they follow the latest developments in gold mining technology or something else that's much more relevant to their lives than "computer stuff". It's something to keep in mind when marketing things - you think that everyone must have got the message, that no one could possibly not know what's going on, but it's actually quite difficult to really, reliably communicate something to a broad range of people.

Rapha&#235;l Hertzog: How to squash Debian release critical bugs

Squashing release critical (RC) bugs is one of the most helpful way to contribute to Debian. Because those are the bugs that we need to get rid of in order to release the next stable version. Let s see how you can help. The process is really simple:
  1. Find a RC bug that you can fix
  2. Prepare a fixed package
  3. Send the patch to the BTS
  4. Get your fixed package uploaded
I have already covered points 2 and 3 in a former article: How to prepare patches for Debian packages. So I m not going to repeat myself in this article, instead I ll cover how to find a release critical bug to fix and how to get your package uploaded. Find a RC bug with UDD The Ultimate Debian Database (UDD) provides a neat interface to query the bug tracking system: http://udd.debian.org/bugs.cgi. The form contains many options to customize the query, we ll try explain some. First, at the top, you can decide to list bugs based on whether or not they affect testing/stable/unstable. Indeed, thanks to version tracking the BTS knows if a bug applies to the version of the package present in a given distribution. I suggest you pick a choice that includes sid because that s where you re going to push your fixed package. If sid is not affected by the bug, you can t do much about it (except if you want to join the release team and help ensure updates are flowing from unstable to testing). I usually go for wheezy and sid because that filters out packages which are not in testing (and are thus not blocking the next release). Then you have lots of filters to further reduce the list of bugs. It s important to reduce the noise as you typically have several hundreds of RC bugs at a given time. I suggest you the following settings for a start, but you re free to try other combinations depending on what you want to achieve (I ll give some examples later): I usually sort the results by source package so that I immediately see if several RC bugs are affecting the source package. And I might add popularity contest information to get a feel of whether the package is widely used or not. You can see the results of the suggested query here. Other interesting queries: Find a RC bug with rc-alert The downside of the above method is that you get bugs on packages that you don t know at all and that you might not care about. Some of them might even be better removed instead of fixed. With the rc-alert command (provided by the devscripts package), you will get a list of RC bugs
on packages that are installed on your computer. It should be much more restrictive. And you have command line options to further filter the list just like with the UDD form. Bonus feature: you can also filter by debtags allowing you to restrict the bugs to packages which are implemented in programming languages that you know.
$ rc-alert --include-dists TU --exclude-tags P+ --debtags implemented-in::perl,implemented-in::python
Package: gwibber
Bug:     608724
Title:   gwibber bypasses certificate checking when providing the login/password for OAuth
Flags:   [     S  ] (security)
Dists:   [STU] (stable, testing, unstable)
Debtags: implemented-in::python, interface::x11, role::program, uitoolkit::gtk, works-with::im, x11::application
[...]
Get your fixed package uploaded Usually sending the patch to the BTS is more than enough. The maintainer or another Debian developer will pick it up at some point. But if you re interested in becoming a Debian maintainer/developer, it might be worth to push your changes more quickly and get credited by a proper upload with your name. Instead of just preparing a patch, you should also prepare a fixed package following the rules of a Non-Maintainer Upload. Put this package somewhere online (for example on mentors.debian.net). When you send your patch to the BTS, include the link to the updated package and express your wish to get this update sponsored. If you haven t heard anything from the maintainer after 2-3 days, try to find a sponsor on debian-mentors@lists.debian.org. NMUs are easier to review than completely new packages and many Debian developers like to kill RC bugs, so there s a good chance that you ll find someone. Now happy RC bug-squashing! And if you really enjoy it, you can subscribe to debian-bugs-rc (~3000 mails per month) :-)
If you want to read more articles like this one, click here to subscribe to my free newsletter. You can also follow me on Identi.ca, Twitter and Facebook.

No comment Liked this article? Click here. My blog is Flattr-enabled.

Asheesh Laroia: Open Source Bridge 2011: they love me (and gave me a scarf)!

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.

13 July 2011

Junichi Uekawa: Tried running qemu-user-static.

Tried running qemu-user-static. It seems to work at least for armel, apart from some weird cdebootstrap brokenness on stable. It's much easier to control than a QEMU system image and having to maintain a linux kernel. I saw a bunch of qemu: Unsupported syscall: 341 (arm_sync_file_range?) and Unsupported ioctl: cmd=0xc020660b but that didn't seem to affect a lot. I see a somewhat outdated page in Debian Wiki about this set up. I think most problems have been solved and things are much simpler now with current Debian stable.

Lior Kaplan: An RTL issue in Ubuntu s installation

Earlier this week I saw a request for help from the Israeli community to fix an RTL issue in the Ubuntu installation. Although the request is in Hebrew, the screenshots speak for themselves and show the cropped text on the right side of the screen. There s a combination of a few problems:
  1. Some of the text has LTR directionality, probably due to sentences beginning with an English word. This could be worked around by some translation changes or forcing directionality with RLM characters.
  2. The text is aligned to the left. This might be due to the sames reasons above. Maybe it s also possible to override the alignment of RTL languages regardless of the directionality.
  3. The text is cropped on the left side. Seems that just mirroring the English positions isn t enough to get good results. (I didn t check the code to see if that s actually what is done, but that s one of the common ways I saw to handle support for RTL programs).
LP bug #798768 was reported a month ago, but it seems to repeat LP bug #560114 reported in April 2010. Any help with these issues will be more than welcome. Of course, I ll be glad to help in any possible way (sorry, I don t write code) and I m sure this also applies to the members of the local community.
Filed under: Ubuntu

Torsten Werner: Certified Scrum Master

I ve passed the CSM exam of the Scrum Alliance today after having a 2 day training last week! That means that I am really agile now. :) The training was really good.

Steve McIntyre: Project Harmony?

So, the "Harmony Project" launched their set of contributor agreements and tools last week. Colour me unimpressed... There's a claim on their website that they are a "community-centered group", but I don't see any list of people and organisations who contributed to this work. That bothers me. Regarding their aim to "assist organisations which use contribution agreements", I don't think that there is anything of value here for the Free Software community at all. Free Software developers don't need contribution agreements, and in my opinion encouraging their use like this is only going to cause further splintering of the community. We've managed for a very long time without them, why start now? As a developer, I personally don't believe in contribution agreements at all. If I contribute code to a project, it will be under the terms of a good Free Software license or not at all. That's all that's needed. There's a fair body of opinion out there on this - see pieces from Bradley Kuhn, Richard Fontana and Dave Neary for more discussion. What do you think?

Clint Adams: Savannah Doldrums

About a month ago, I submitted a project request to Savannah. It made sense at the time to host it there for a variety of reasons, but now I am still waiting for project approval. I am told that the reason my very exciting project is sitting there collecting moss is that there is a lack of reviewers. So if you want to help Savannah out, you should write to savannah-hackers-public@gnu.org.

Daniel Baumann: Debian Live 6.0.2 Images

Two days before the 6.0.2 squeeze point release a user reported that usb-hdd images are not bootable for him. We could not reproduce that for several days but thanks to David Endler, we found out a few days ago that the reason for this is the following commit: Setting partition flags after creating the filesystem, workaround for bug in parted where we result in having the partition type set to linux otherways. The original problem was that in some situation the code resulted in having a wrong partition type and that can let to confusion for some bioses. For other reasons, the applied workaround has the side effect to cause parted to not set the bootable flat at all anymore and by that creating an even bigger problem - most crappy bioses these days require the bootable flag to be set and refuse to boot from a device otherwise (Missing Operating System). Or in other words, the fix solved the original problem but created another one that is affecting much more bioses. Rather than doing a hasty and suboptimal build of 6.0.2 with the commit reverted (and wasting resources for a 6.0.2a build some time later), we have looked into fixing the original problem properly without causing side effects. Images for the 6.0.2 squeeze point release will therefore be published in the next couple of days.

Jordi Mallach: Not going to DebConf 11

3 months ago, I was positive I would be attending DebConf 11 in Banja Luka, but as the time to buy tickets and plan the trip came closer, I began to realise I don't have lots and lots of vacation, and I probably prefer spending them doing something that absolutely rocks my world. I've always enjoyed the Debian conferences when I've been lucky to be there, but last year's experience in the Pyrenees was nothing a DebConf can compare to, and I've decided to spend time seeking similar experiences this summer. With much regret, because I love meeting the wonderful people that make up Debian and DebConfs, I have to say that after all and once again, I won't make it.

Next.

Previous.