Subscribe: Sandro Tosi
Added By: Feedage Forager Feedage Grade B rated
Language: English
account  changeset  code  debian  files  gmail  google  list  lot  migrate  mysql  new  package  packages  python  services  time 
Rate this Feed
Rate this feedRate this feedRate this feedRate this feedRate this feed
Rate this feed 1 starRate this feed 2 starRate this feed 3 starRate this feed 4 starRate this feed 5 star

Comments (0)

Feed Details and Statistics Feed Statistics
Preview: Sandro Tosi

Sandro Tosi

A blog about things I do: Debian, Linux, Python, whatever

Updated: 2018-03-06T07:27:00.659+01:00


What's that code: Elementary S04E09


they hacked a car and around 7:27 in the episode they are analyzing the car's computer source code, that's some sweet compression they say, but it turns out it's Perl interpreter source code, with Perl replaced with Auto (after all it's the auto code right?) and following lines

another interesting code copy was in The Americans (cant remember season or episode), when they were trying to acquire the ECHO program source code, what's on the screen is actually MATLAB source code(image)

Debian source package name from the binary name


it looks like i forgot all the times how to do that, and apparently i'm not able to use google good enough to find it out quickly, let's write down one way to get the source package name from the binary package name:

dpkg-query -W -f='${source:package}\n'

(since it accepts a list of packages, you can xargs it).

there are probably another million ways to do that, so dont be shy and comment this post if you want to share your method(image)

How to change your Google services location


Several services in Google depends on your location, in particular on Google Play (things like apps, devices, contents can be restricted to some countries), but what to do if you relocate and want to update your information to access those exclusive services? Lots of stories out there to make a payment on the playstore with updated credit card info etc etc, it's actually a bit different, but not that much.

There are 3 places where you need to update your location information, all of them on Google Payments:

  1. in Payment Methods, change the billing address of all your payment methods;
  2. in Address Book, change the default shipping address;
  3. in Settings, change your home address.
Once that's done, wait some minutes, and you might also want to logout/login again in your Google account (even tho Google support will tell it's not necessary, it didnt work for me otherwise) and you should be ready to go.

DICOM viewer and converter in Debian


DICOM is a standard for your RX/CT/MRI scans and the format most of the times your result will be given to you, along with Win/MacOS viewers, but what about Debian? the best I could find is Ginkgo CADx (package ginkgocadx).

If  you want to convert those DICOM files into images you can use convert (I dont know why I was surprised to find out imagemagik can handle it).

PS: here a description of the format.(image)

CFEngine: upgrade Debian packages


say you use CFEngine to install Debian packages on your server, so it's likely you'll have a bundle looking like this:bundle agent agentname{    vars:        "packages" slist => {                             "pkg1",                             "pkg2",                             "pkg3"                            };    packages:        "$(packages)"            package_policy => "addupdate",            package_method => apt_get;}this works great to guarantee those packages are installed, but if a newer version is available in the repositories, that wont be installed. If you want CFEngine to do that too, then the web suggests this trick:    packages:        "$(packages)"            package_policy => "addupdate",            package_version => "999999999",            package_method => apt_get;which tweak the install system declaring that you want to install version 999999999 of each package, so if you have available a higher version than the one installed, CFEngine will happily upgrade it for you. It works great.. but sometimes it doesn't. why oh why?That's because Debian versions can have a epoch: every plain version (like 1.0-1) has an implicit epoch of 0, and same goes for the 999999999 above, that means if any of the installed packages has an epoch, that version will sort higher than 999999999 and the package wont be upgraded. If you want to be sure to upgrade every package, then the right solution is:    packages:        "$(packages)"            package_policy => "addupdate",            package_version => "9:999999999",            package_method => apt_get;[...]

Attending the Codecademy


You've probably already got it, I'm surveying several sites to improve programming skills. This episode is about Codecademy.

It's a very well done site, for people that want to learn a language. It has a Python track, along with several others: Ruby, JQuery, Javascript & so on.

You'll be required to actually write code and run it! yes, the code you write is then executed in a web "interpreter" (modified for educational purposes) and the output displayed on screen. In a section is also possible to write to files and have their contents shown on another tab.

I'd encourage you to start from it if you never saw Python and you're willing to learn if from the ground up.(image)

Spending a Sunday on


I've played a bit with Project Euler but all of their problems are math-centric, which is nice but not exactly what I'm looking for: some real-world programming problems to get back into the coding field.

So asking my friend Google, I found CodingBat: it has a Python section with several tasks to complete. I must say they are some kinda trivial to solve, once you know some idiomatic Python code, but some are a bit more interesting. If you're a junior Python coder, or want to get a grip on the language, give it a look.

Oh, and if you know some website that would give me some real-world programming coding problems (something that would be useful on the job, not just coding for fun), I would love to hear you.(image)

Project Euler - Problem 6


Here's my solution to Project Euler problem 6:

# where the numbers list ends
n = 100

# handy function to square a number
pow2 = lambda x: pow(x, 2)

# first compute the sum of the squares
sumsq = sum(map(pow2, range(1, n+1)))
# then the square of the sum
sqsum = pow2(sum(range(1, n+1)))

print sqsum - sumsq

Project Euler - Problem 4


Here's my solution to Project Euler problem 4:

# handy function to check if a number is palindrome
def is_palindrome(i):
return str(i) == str(i)[::-1]

# what's the max?
max_p = 0

# multiply all numbers `i` between 100 and 998, with all between i+1 and 999
for i in xrange(100, 999):
for j in xrange(i+1, 1000):
p = i * j
if is_palindrome(p) and p > max_p:
max_p = p

print max_p

Comments are welcome.

Update: fixed as per Alex comment.(image)

Start a MySQL instance to run Debian package build-time tests


I'm the maintainer of MySQL Connector/Python Debian package, and it's shipped with several unittests, but they require a MySQL instance to be run against, so up to know I wasn't able to run them at build-time.

But I want to change that, so I wanted to find a way to spawn a MySQL instance just for testing purposes. I've searched a lot, and then found a package solving the same problem: php5.

The package has a script that takes care of starting/stopping the instances, and debian/rules file sets up instance parameters and then it starts the instance before the tests and then stops it after them.

It's a very interesting solution, so I thought of sharing + taking notes to self, just in case I need it in other situations.(image)

How to migrate your entire Google account to a new one


I've been using a Google account since years, but having a "more serious" one along. The time has come to make the switch and elect the other as main one.Google has a lot of services, and I'm using several of them, so changing the main account requires to migrate data of those services to the new account, given it's not possible to merge two accounts. To know the full list of services your account is signed in, go to your Account Product page. Some migrations are easy, others hell no: so I'm writing this post to keep track of the migration as it's going on.First of all, there's a really good post about this migration at LifeHacker: it contains a lot of info I'm using here, but not all the services I need. Additionally, Google has a list of services and methods to migrate from one account to another.Just to be generic, I'll call AccountSRC the original account and AccountDST the one I want to migrate to.Migrate GMailGMail is probably the most important service I have, and also the most difficult one to migrate. I have a lot of filters, so the first step is to migrate them:Login into GMail for AccountSRCGear icon > Settings > LabsEnable the "Filter import/export" pluginReload GMail to enable the plugin (if not done automatically)Gear icon > Settings > FiltersAt the bottom of the page, Select allExport: this will download an XML file with the filters in itLogin into GMail for AccountDSTEnable "Filter import/export" pluginLoad the file containing the saved filtersImport all (or select which one) filters; this will also create automatically the labels defined in the filters.I currently have a forward rule from AccountDST to AccountSRC: so let's revert the forward direction: from AccountSRC to AccountDST. This will allow the new account to receive the mails sent to the old one.Login into GMail for AccountDSTGear icon > Forwarding and POP/IMAP > Disable forwarding: this will stop redirecting mails from AccountDST to AccountSRCLogin into GMail for AccountSRCGear icon > Forwarding and POP/IMAP > add a forwarding addressEnter AccountDST as the address to forward mails toA verification code is sent to AccountDST and you'll need to enter that code in AccountSRC to verify you have access to both mailboxesOnce verified, select "Forward a copy of incoming mail to" to AccountDST and to delete the GMail copy on AccountSRCThere's no automatic way to migrate all your settings from the old GMail account to the new one, so you'll have to comparing settings pages to set what you had before to AccountDST. I suggest to first enable the labs you have on AccountSRC, and then go thru every page and report the configurations.Did I forget something? yes, the hardest part: migrate mails! There are a lot of guides about migrating mails, the way I prefer is thru IMAP and Thunderbird (as described here): you'll move IMAP folders, and since they are equivalent to GMail labels, you'll automatically get your email with the correct labels (yes, the same mail appears in several folders, one for each label, and moving an email from one folder will not remove it from all the others).Enable IMAP access on both AccountSRC and AccountDSTOpen Thunderbird (or Icedove if you're on Debian like me) and register both accountsYou can now start moving folders/emails from AccountSRC to AccountDSTCopying a (missing) folder, will automatically create a label with the same nameMoving a mail from the same folders on the two accounts will add the label called with the name of the folder to that emailBe ready, it's a LOOOOONG process, but it's safe and it guarantees a perfect resultWith the method above you have all the labels y[...]

Mercurial: what's the tag containing this changeset?


In software development, you often need to know: when was this feature released? in which releases was this changeset included?

Typical example is: you're debugging a problem, you find out what's the changeset introducing it, now you want to know when that changeset was firstly released (i.e. included in a tag) - how to do that?

hg log -r "cset:: and tag()"

where cset is the changeset you're looking for.

So know I know that Sphinx new way to load searchindex was introduced in the this changeset, and released for the first time in 1.0b2:

$ hg log -r "423faa03c908:: and tag()"
changeset:   2261:b494009dccf1
tag:         1.0b2
user:        Georg Brandl
date:        Sun May 30 19:52:08 2010 +0200
summary:     Release preparation for 1.0b2.


PS: why did I need to know that? because Matplotlib is still using the old way, but Debian needs the new one.(image)

Get the lines unique on the first field(s)


uniq is a great tool, since it returns the unique (adjacent) lines of the given input. But it has a limitation: it can't check for uniqueness only the first N fields (while it allows to ignore them, weird).

So, what to do if you have a long file, and lines with several fields, but you're only interested in getting the line with the different first 2 field (but all the rest of the line content? awk to the rescue!

$ awk '!x[$1]++' file

will print the (complete) lines of file that has the first field unique. You can set $1$2 to have lines unique on the first 2 fields, and so on. Thanks to this forum post, but there's some other interesting articles.(image)

Trick of today: find -daystart


What to get the files older than today? Run

    find /path/ -type f -daystart -mtime +0

it will return only the files older than today, no matter the time the command is executed (by default, -mtime counts multiples of 24 hours from now). Kinda nice when you want to archive yesterday log files.(image)

Print a NUL-terminated string with awk


I thought it would have been easier to print a NUL-terminated string in awk (mawk as it's the default in Debian), but after some trial-and-fail I was able to come up with this kinda ugly solution:

$ echo -e "123\n456" | awk 'BEGIN { ORS="" } { print $0 ; printf("%c", "") }'  | xargs -n1 -0 echo 


  • set the Output Records Separator (ORS) to the empty string (default is the \n, new line)
  • print the input line (do your elaboration there, if you need)
  • print the null character, as explained in the mawk manpage: "mawk cannot handle ascii NUL \0 in the source or data files.  You can output NUL using printf with %c, and any other 8 bit character is acceptable input."
  • show that it's actually emitting NUL-terminated strings
There's really no better way to do that?

Mercurial: how to completely remove a named branch


I like so much the git feature branch workflow, that in the early days of development on Python with Mercurial I created some named branches; well, that is something you should not do.

In Mercurial, the changeset contains the branch name, so you cannot develop on a separated (named) branch and then merge on default and hope that branch goes away, because it will stay.

What do I do now? Python Mercurial repository is quite big (around 200Megs) so I wanted to avoid to re-check it out. Thanks to the help of the folks on #mercurial (on freenode IRC network) I found my solution: strip the branch!

Please note that strip is dangerous. Use it only as last resort, and mind you can lose data with it. That said, it's a very powerful tool :) My main aim was to remove completely those named branches, leave no traces, and lose the changes I made on them. Another important aspect is that I didn't merged those branches on default.

So, how to get rid of a named branch:

$ hg strip "branch(${BRANCHNAME})"

and re-iterate for all the branches you have, that's it. Now, to be completely sure they were removed and no spurious changes are in the repository, you can:

$ hg pull -u
$ hg outgoing

and if it says "no changes found" you're sure that those branches are really gone.(image)

And what am I now? A Python Core Developer!


Yeah, since a couple of hours I'm officially a Python Core Developer (and this confirms it, so I'm not dreaming!)

I'm now in that mixed state in between the happiness and the fear I'll do stupid mistakes and I'll be ashamed of myself. But hey, it's only those who do nothing that make no mistakes.

Interesting days ahead, a lot of procedures to learn and get used to, hopefully also a lot of bugs fixed :) That's for sure, I'll go step by step, following the better be safe than sorry rule.

At the end, I'd like to thank all the people at Python that made this possible, they are quite a number, so if I'd named them, I surely forgot someone, and it would be unfair! So well, you know who you are, and this big THANK YOU is yours :)(image)

Read multiple variables from stdin in a bash script


I procrastinated to look up this for such a long time.. today was enough. What I want to achieve is reading a line from stdin and split it among several variables, naively I'd do:

$ echo "A BB CCC" | read a b c
$ echo $a $b $c

(no output.) As well explained here the above code doesn't work, but this one does:

$ read a b c < <(echo "A BB CCC")
$ echo $a $b $c

as a hint, <(cmds) is called process substitution.(image)

I'm going to EuroPython 2011


I just got confirmation my company will sponsor me for EuroPython 2011 (thanks, so I'll be able to attend the whole week; a lot of amazing talks and the code sprints in the weekend: this is going to be a great time!

Are you coming?(image)

Python: group a list in sub-lists of n items


A long list, and you want to process its items n at a time; easy, but how to split that list in sublists of n elements (except the last one, of course)?

I looked a bit into the stdlib but it doesn't seem to exist anything I could use (oh, did I say I'm still on 2.4?) so I directed my research to Google, and found a nice recipe at ActiveState, but it has the problem it discards the last list, if it has less than n items.

Searching again, I got more lucky with this article: it's a generator of tuples from a list, splitting every n elements and optionally return the last semi-full tuple. I slightly modified it to obtain:

def group_iter(iterator, n=2):
""" Given an iterator, it returns sub-lists made of n items
(except the last that can have len < n)
inspired by"""
accumulator = []
for item in iterator:
if len(accumulator) == n: # tested as fast as separate counter
yield accumulator
accumulator = [] # tested faster than accumulator[:] = []
# and tested as fast as re-using one list object
if len(accumulator) != 0:
yield accumulator

How would you have done it?(image)

MySQL master/slave chain


Have you ever needed to create a MySQL databases replication chain like A->B->C where B is slave of A and master of C? Me neither, until yesterday.

Since it took us about an afternoon to make it works (along with our DBAs, so we're not alone ;)) let's share some knowledge.

A very brief recap of how MySQL replication works:

  1. slave I/O thread connects to the master, gets the new information from the binlog files and stores them in the relay log;
  2. slave SQL thread reads the relay log and applies the changes to the slave database, without changing the slave binlog files.
That said, B replicates correctly from A, but C is unable to replicate from B because B doesn't change its binlog files with updates coming from A, because there's no changes done directly on B.

In order to make the chain works, you need to add the parameter log-slave-updates on B configuration: that will reply the changes from relay log to binlog, and so C will see the changes it needs to correctly replicate.

PS: mysqldump --master-data (executed on the slave server against the master) would help you set up the correct information for replication.



As you probably know, Shani is our pet hedgehog. We finally managed to setup a blog just for her (sorry, it's in italian only), and also we uploaded tons of her photos.

You don't remember her? Here's a cute reminder:


EuroPython 2011 @ Florence, IT - it's coming!


Just when I was looking for a contact email to ask news about EuroPython 2011 dates... I noticed they are already there!! June 19 to 26 !

Book your flights, reserve your vacations, hope to see you all there!

PS: this year, PyCon Italia joins EuroPython in a single conference - the bigger the funnier

Re: Converting date to epoch


Alexander,did you even consider that I might need to convert a date to epoch in a python script? :)(image)

Convert a date to epoch


it seems like an easy quest, ain't it? well, it took me far too long to get it done, so let just write it down, so that maybe I won't forget in 2 seconds:
>>> import time
>>> str = '2009-03-04'
>>> format = '%Y-%m-%d'
>>> time.mktime(time.strptime(str, format))
>>> int(_)
and here you have your epoch (if you just need seconds, use int()).