Checking Python files with Vim

Vim is an ex­ce­llent edi­to­r, and mas­te­ring it lea­ds to mo­re pro­duc­ti­vi­ty. Even thou­gh is ve­r­y ex­ten­si­ble and allo­ws to be con­fi­gu­red by many plu­g-ins I ra­ther keep it as sim­ple as po­s­si­ble, ­tr­ying not to use many plu­g-ins (nei­ther pa­cka­gers like Vund­le, etc.).

Ho­we­ve­r, I do make use of an ex­ten­sion that che­cks Py­thon fi­les for error­s, PE­P8, a­mong other things: flake8. Be­cau­se I do not use plu­g-in pla­tfor­ms for Vi­m, I ins­ta­ll just this one ma­nua­ll­y, by making the co­m­mand flake8 avai­la­ble sys­te­m-wi­de [1].

Then the ins­ta­lla­tion is as sim­ple as do­wn­loading the pro­ject and co­ying the fi­les in­to the ~/.­­vi­­m/­­ftplu­­gi­n/­­p­­y­­thon di­rec­to­r­y. Make su­re you ha­ve the fo­llo­wing li­ne added on your ~/.­­vi­­mrc:

filetype plugin indent on

The fea­tu­res I use are main­ly the syn­tax and PE­­P-8 com­plian­ce che­cker­s. It can al­so warn you about unu­s­ed im­por­ts, and cy­clo­ma­tic com­ple­xi­ty.

It is use­ful be­cau­se things like PE­­P-8 com­plian­ce help to ha­ve a good co­de qua­li­ty, and the­re­fo­re a mo­re rea­da­ble and main­tai­na­ble co­de ba­se, spe­cia­lly on lar­ge pro­jec­ts wi­th lo­ts of fi­les and mo­du­le­s.

Tha­t’s all. For mo­re de­tails and other con­fi­gu­ra­tion tips che­ckout my Vim se­tup.

[1] Another option would be to install it on your virtual environment, but then you have to make sure to install it once per project. It is actually better, because you are not using the global system environment, but for packages like this, it should not be an issue, it’s your choice.

Alpine email client

Al­pi­ne is a so­ftwa­re I de­fi­ni­te­ly re­co­m­mend for tho­se who like mi­ni­ma­lis­tic appli­ca­tion­s ­that go strai­ght to the point in or­der to get the things do­ne. It’s an email clien­t, wi­th no GUI, whi­ch allo­ws me to read emails be­tter than by means of the web pa­ge [1] wi­thout any dis­trac­tion­s, fo­cu­sing on what is just im­por­tan­t. It is al­so great that sho­ws on­ly the text (the ­re­le­vant part of the emai­l) and it can fo­llow the li­nks by laun­ching the de­fault bro­w­se­r.

It is sim­ple, fast and per­fec­tly sui­ta­ble for che­cking my old in­box wi­th week­ly lis­ts up­da­tes. I­t’s inhe­rited from an old pro­jec­t, ca­lled pi­ne, and in Fe­do­ra it can be ins­ta­lled by:

sudo dnf install alpine

Then you just need to con­fi­gu­re the email ac­count se­ttings (o­ne last ti­me to vi­sit the pa­ge, ­but that would be the last :-) and you’­re read­y.

[1] Not for gmail but from another older account I have

Libvirt networking libraries

Fe­do­ra 21 wo­rks­ta­tion see­ms to co­me wi­th a lot of vir­tua­li­za­tion fea­tu­res and most of the lib­virt li­bra­ries ins­ta­lle­d. I on­ly had to add the KVM vi­r­­tua­­l-­­ma­­na­­ger whi­ch is ­the KVM appli­ca­tion I am mo­re fa­mi­liar wi­th. Ho­we­ve­r, the new ver­sion of the lib­vir­t* li­bra­rie­s ha­ve ne­two­rking fea­tu­res that are great for the da­ta cen­tre en­vi­ron­men­t, but ma­y­be not the best op­tio­n ­for a par­ti­cu­lar wo­rks­ta­tio­n, so I added the fo­llo­wing pa­cka­ges in or­der to set up an ea­sie­r ­ne­two­rk con­fi­gu­ra­tion for my lo­cal vir­tual ma­chi­nes.

sudo dnf install virt-install libvirt-daemon-config-network

In or­der to re­flect the chan­ges and start using the new fea­tu­res, we need to res­tart its ser­vi­ce:

systemctl restart libvirtd.service

After tha­t, when crea­ting a new vir­tual ma­chi­ne, the NAT op­tion is ena­ble­d, and the vir­tua­l ­ma­na­ger wi­th hand­le the NAT or bri­dging con­fi­gu­ra­tion au­to­ma­ti­ca­ll­y, whi­ch allo­ws me to de­ploy new ­ma­chi­nes fas­te­r.

Do not import *

It is we­ll-k­no­wn among Py­thon de­ve­lo­pers (or at leas­t, it should be­), that is a bad idea to im­port eve­r­y­thin­g ­from a mo­du­le, for exam­ple by doing from <mo­du­le> im­port *.

The idea on this pos­t, is to hi­gh­li­ght and ga­ther the rea­sons why this is a bad prac­ti­ce, in or­der to co­llec­ti­ve­l­y i­den­ti­fy many un­de­si­red effec­ts. Ho­we­ve­r, wi­thout lo­sing prag­ma­tis­m, in ca­se the­re are so­me odd rea­sons why this ­mi­ght be ac­cep­ta­ble, I wi­ll al­so men­tion the­m, if an­y. Le­t’s see whe­re we ge­t.

  1. You do not know what you get
    An ar­bi­tra­ry Py­thon script may con­tain any co­de, and most of it wi­ll be exe­cuted when ­per­for­ming the im­port * part (you can­not re­ly on how __­na­me__ is hand­le­d). ­The in­ter­fa­ce is to­ta­lly un­clea­r: you do not know what com­pu­ta­tions per­for­ms, what ob­jec­ts wi­ll im­por­t, etc. In ge­ne­ral is mo­re effi­cient to im­port as few de­fi­ni­tions as po­s­si­ble.
  2. Iden­ti­fiers appear ma­gi­ca­lly
    In any de­cen­tly rea­da­ble Py­thon scrip­t, the pro­gra­m­mer must be able to lo­ca­te eve­ry de­fi­ni­tio­n, whi­ch mean­s ­to iden­ti­fy whe­re does eve­ry iden­ti­fier co­me fro­m. For exam­ple, a va­ria­ble na­med x can ei­ther be a pa­ra­me­te­r of the func­tion in the cu­rrent sco­pe, a va­ria­ble al­ready de­fi­ned (a­s­sig­ne­d), or a na­me al­ready im­ported (from mod im­port x), etc. By per­for­ming the in­co­rrect im­por­t, this va­ria­ble mi­ght appear out of the blue, mea­ning that I wi­ll ha­ve an x tha­t wi­ll not be nei­ther a pa­ra­me­te­r, nor a de­fi­ni­tion nor a de­cla­red im­por­t. This mean­s, I can­no­t ­tra­ck the ori­gin or x. The si­tua­tion ge­ts wor­se if the­re are not one, but many im­port * sta­te­men­ts. ­De­bu­gging be­co­mes a ni­ght­ma­re.
  3. Na­mes­pa­ces are one ho­nking great idea — le­t’s do mo­re of tho­se!
    Strai­ght from the Py­thon zen [1]. By im­por­ting eve­r­y­thing from a mo­du­le, the be­ne­fi­ts of the na­mes­pa­ce­s a­re so­me­how los­t. Ins­tea­d, eve­r­y­thing (or a lot of things), mi­ght get to be ca­lled the sa­me, me­s­sin­g wi­th the cu­rrent sco­pe. Mo­reo­ve­r, new im­port de­fi­ni­tions mi­ght ove­rri­de pre­vious ones.
  4. Ex­pli­cit is be­tter than im­pli­cit
    Agai­n, eve­ry iden­ti­fier that we want im­ported should be do­ne ex­pli­ci­tly (the * is not ve­ry de­cla­ra­ti­ve).

No­w, so far the­se mi­ght be so­me of the main rea­sons about why im­por­ting eve­r­y­thing from a Py­thon mo­du­le is usua­lly not a good idea. Ho­we­ve­r, in ca­se the co­de at stake is just a sim­ple tes­ting scrip­t, or an in-­li­ne sen­ten­ce on ip­y­tho­n, the­re could be no­thing wrong about it.

In addi­tio­n, al­thou­gh I am not a big fan of im­port sta­te­men­ts in­si­de func­tions (so­me­ti­mes they are ne­ce­ssar­y, thou­gh), im­por­ting eve­r­y­thing from a pa­cka­ge wi­thin a func­tion is not a big pro­ble­m, be­cau­se the sco­pe is al­ready na­rro­we­d.

Just to be clea­r, this is by no means an ab­so­lu­te sta­te­men­t, but an idea pre­sen­ted in or­der to wri­te be­tter co­de. O­ne of the things I like the most about Py­thon is that en­cou­ra­ges good prac­ti­ce­s. The­re­fo­re, if I rea­d an im­port sta­te­ment like this, un­le­ss the­re are so­me ve­ry good rea­sons to do so, I wi­ll thi­nk that li­ne as a co­de-s­me­ll [2].

[1] import this
[2] https://c2.com/cgi/wiki?CodeSmell

Writing forward-compatible software in Python

Py­thon 3 is the fu­tu­re of Py­tho­n. Ho­we­ver the­re mi­ght be a pro­blem in the ­co­m­mu­ni­ty if bo­th Py­thon 3 and 2 co­exis­t. The for­mer one was great an­d ­bri­llian­t, but it is ti­me to start wri­ting so­ftwa­re in the new ver­sion in or­de­r ­to mo­ve to­war­ds new fea­tu­res and im­pro­ve­men­ts.

Le­t’s start by the be­gin­nin­g. One of the rea­sons I alwa­ys pre­fe­rred Py­thon ove­r ­the rest of the pro­gra­m­ming lan­gua­ges is be­cau­se it is mo­re ad­van­ce­d, mea­nin­g ­that in­clu­ded many con­cep­ts that other lan­gua­ges did no­t. For exam­ple, thi­nk of how ear­ly Py­thon adop­ted ideas like lamb­da func­tion­s, dy­na­mic ty­pin­g, ­du­ck ty­pin­g, con­text ma­na­ger­s, me­ta­cla­s­ses and so on, whi­le other te­ch­no­lo­gie­s (­na­me­ly Ja­va, C++ for exam­ple [1]) we­re sti­ll using da­ta struc­tu­res and ca­llin­g ­them “ob­jec­ts”. Py­thon has alwa­ys been many steps ahea­d.

Great news are that this is no ove­r: Py­thon is sti­ll im­pro­ving at a fast pa­ce. And that is pre­ci­se­ly the is­sue wi­th Py­thon 3. As a re­sult of tha­t e­vo­lu­tio­n, the new ver­sion of Py­thon must chan­ge so­me of its in­ter­nals in or­de­r ­to pro­per­ly im­ple­ment new fea­tu­res, and this is what lead it to be in­com­pa­ti­ble wi­th ear­lier ver­sion­s, whi­ch should not be a pro­ble­m. But it see­ms it is.

So­me de­ve­lo­pers do not like the new re­lea­se, and they are not keen on mi­gra­tin­g ­the co­de ba­se. They ar­gue that Py­thon 3 “is wron­g” be­cau­se it is not ba­ckwar­ds com­pa­ti­ble, but my ques­tion he­re is why are we thi­nking ba­ckwar­ds ins­tead of fo­rwar­ds. A pro­gra­m­ming lan­gua­ge as a mo­del or con­cep­t, must evol­ve, im­pro­ve, so we s­hould be thi­nking on the fu­tu­re of the lan­gua­ge ra­ther that on its ­pas­t. I thi­nk they are mis­sing the new idea­s, the way Py­thon is chan­ging in or­der to in­cor­po­ra­te mo­re effi­cient me­cha­nis­ms. Perhaps this ti­me, the leap wa­s ­too bi­g.

I thi­nk the best for the lan­gua­ge is to adopt its new ver­sio­n, and do not thi­nk of it as a di­ffe­rent one. The­re­fo­re, when we say “P­y­tho­n”, it should be­ un­ders­tood that we are ta­lking about just one sin­gle ver­sio­n.

[1] At the time of this writing just the latest version of Java incorporated lambda expressions, which have been available in Python for many years.

Presentations with reveal.js

Ol­d-­fas­hio­ned PP­T’s pre­sen­ta­tions are from the 90’s, and le­t’s fa­ce it, we are in the a­ge of the web bro­w­se­r. So, the last ti­me I had to ga­ve a ta­lk, I de­ci­ded to use a be­tter te­ch­ni­cal su­ppor­t.

After a qui­ck sear­ch for al­ter­na­ti­ve­s, I found many op­tion­s, in­clu­din­g we­ll-k­no­wn li­bra­rie­s, un­til I fi­na­lly de­ci­ded for re­vea­l.­js.

It is wri­tten in Ja­vaS­cript wi­th good CSS the­me­s, and it does not re­qui­re ex­pert kno­w­le­dge on tho­se te­ch­no­lo­gie­s. In or­der to play the pre­sen­ta­tio­n, you laun­ch an HT­ML fi­le from a web bro­w­ser or ­you can al­so run it wi­th a sta­tic ser­ve­r.

Ad­van­ta­ges:

  • Ver­sion con­tro­l: Gi­ven the fact that your pre­sen­ta­tion is ma­de from sour­ce co­de, it is po­s­si­ble ­to tra­ck chan­ges by using gi­t.
  • A be­tter cro­ss-­pla­tform su­ppor­t: it does not re­ly on a par­ti­cu­lar so­ftwa­re in a par­ti­cu­lar ver­sion to be pre­sent (web bro­w­sers are ubi­qui­tous no­wa­da­ys).
  • Com­pa­ti­bi­li­ty: WY­SIW­YG.
  • Able to host your pre­sen­ta­tion in the cloud and ac­ce­ss it from an­ywhe­re.

Rea­sons to use it / ni­ce things about it:

  • We are in 2014
  • Su­ppor­ts Ma­rk­do­wn lan­gua­ge

To be clea­r: I am not sa­ying that this is a be­tter al­ter­na­ti­ve be­cau­se is newer of mo­der­n, ­but be­cau­se of the ad­van­ta­ges lis­te­d. In other wor­d­s, if we count wi­th de­ve­lo­ped tool­s at our dis­po­sal, it would be a good idea to use the­m.

He­re are so­me sim­ple and ba­sic exam­ples of pre­sen­ta­tions I am wo­rking on. (­DIS­CLAI­ME­R: they mi­ght be in di­ffe­rent lan­gua­ges, and the pa­ge is in pro­gress).

Vim commands for improved productivity

Introduction

I would like to des­cri­be my fa­vou­ri­te Vim co­m­man­ds that I use on a dai­ly ba­sis, in or­der to sha­re so­me tips that could help you if you are new in this edi­to­r, or ­to im­pro­ve your ex­pe­rien­ce even if you use it.

  • J : Use­ful when or­ga­ni­zing co­de, this wi­ll join the li­ne be­low to the cu­rrent one.
  • ci) (“­chan­ge in­si­de ‘)’): Ac­tua­ll­y, the clo­sing bra­cket could be chan­ged by any other thin­g (­like ‘]’, ‘}’, etc.). This wi­ll era­se eve­r­y­thing wi­thin the bra­cke­ts and set you in in­sert mo­de (­the c could al­so be chan­ged for d for exam­ple if you just want to de­le­te). Agai­n, this is ­ve­ry use­ful when re­fac­to­ring co­de, if you want to chan­ge the pa­ra­me­ters of a func­tion de­fi­ni­tio­n, or whate­ver is in a blo­ck, etc.
  • (s­elect so­me co­de wi­th vi­sual mo­de and then) zf : wi­ll fold the se­lec­ted co­de. zd for un­fol­din­g.
  • % : alo­ne or along wi­th so­me other ope­ra­to­r, is use­ful for ope­ra­ting wi­th ma­tchin­g ­bra­cke­ts in the co­de. It wi­ll ma­tch the clo­sing bra­cket of the one you ha­ve the cur­sor in.
  • C or D : if you want to chan­ge or de­le­te from the cu­rrent po­si­tio­n up to the end of the li­ne, res­pec­ti­ve­l­y.
  • t, (or any other cha­rac­ter ins­tead of co­m­ma) wi­ll point you until that cha­rac­te­r. ­The good about this, is that is po­s­si­ble to chain it wi­th other co­m­man­d­s, for exam­ple: “ct,” wi­ll chan­ge all the con­tent un­til the next co­m­ma.
  • < or > wi­ll in­dent the co­de fo­llo­wing the “a­rro­w” di­rec­tio­n (ac­cor­ding to what is set in shi­ftwi­dth).
  • = Au­to­ma­ti­ca­lly in­den­ts co­de (u­se­ful when hi­gh­li­gh­ting co­de in vi­sual mo­de).
  • w, e or b wi­ll point you to the next wor­d, to the end of the wor­d, or back to the pre­vious wor­d, res­pec­ti­ve­l­y. The ni­ce thing about the­se ope­ra­tors is when they wo­rk ­com­bi­ned wi­th other­s, for exam­ple:
    • cw wi­­ll chan­­ge the next word.
    • db wi­­ll de­­le­­te the pre­­vious wo­r­­d.
  • { or } for mo­ving up or do­wn th­rou­gh pa­ra­gra­phs, res­pec­ti­ve­l­y.

In addi­tio­n, no­te that you do not need to know all po­s­si­ble co­m­man­d­s, jus­t ­tho­se that wi­ll help you wi­th your nor­mal ac­ti­vi­tie­s. This means that is could be enou­gh wi­th a sma­ll ­sub­set of all the fea­tu­res (the list I wro­te is ve­ry short in­dee­d). And this is pre­ci­se­ly the idea be­hind this pos­t: to show ho­w ­so­me few co­m­man­ds applied in the ri­ght con­tex­t, mi­ght make you edit fas­te­r.

All in all, Vim is a great edi­to­r, fu­ll of ama­zing fea­tu­res. Lear­ning it is ac­tua­lly wor­th it, in the sen­se that you wi­ll get an ama­zing pro­duc­ti­vi­ty in re­turn (you’­ll ty­pe and edi­t ­co­de fas­te­r).

Default arguments in Python functions

This post is ba­sed on a gist I wro­te a whi­le ago, about why is ­not a good idea to pa­ss de­fault mu­ta­ble ob­jec­ts as pa­ra­me­ter­s in py­thon func­tion de­fi­ni­tion­s.

Whi­le the gist is ex­plai­ned th­rou­gh an exam­ple that uses lis­ts, the ­prin­ci­ple is appli­ca­ble to all sor­ts of ob­jec­ts (dic­tio­na­rie­s, se­ts, etc.).

If you are an ex­pe­rien­ced py­thon de­ve­lo­pe­r, you pro­ba­bly knew this ca­vea­t, ­ne­ver­the­le­ss is so­me­thing in­te­res­ting to show to new py­thon de­ve­lo­per­s, an­d ­to re­mem­ber even if you ha­ve been wri­ting co­de in Py­thon for year­s.

Starting a gnome-shell extension

Sin­ce I mo­ved from Ubun­tu to Fe­do­ra ear­ly this yea­r, I chan­ged my desk­to­p en­vi­ron­ment from uni­ty to Gno­me She­ll.

I must say it is a great ex­pe­rien­ce. At the be­gin­ning I was thi­nking on what was be­tter com­pa­red to uni­ty (be­cau­se I did not like Uni­ty). Re­gar­ding this ­com­pa­ri­son I found a mo­re sta­ble and usa­ble win­dow ma­na­ge­r. I sti­ll pre­fer so­me­thin­g ­sim­pler perhap­s, but it wo­rks good and it is ni­ce.

Just out of cu­rio­si­ty, one day I started ma­na­ging so­me ex­ten­sion­s. Oh, by the wa­y, ­you wi­ll pro­ba­bly be ins­ta­lling so­me ex­ten­sions for Gno­me she­ll, so­me of them are u­se­ful and so­me others make it mo­re usa­ble. That dro­ve me to the ex­ten­sions de­ve­lo­per API, whi­ch tur­ned out to be qui­te sim­ple and in­te­res­tin­g.

Ha­ving pla­yed a li­ttle bi­t, I de­ci­ded to co­de a (ve­r­y) sim­ple ex­ten­sion that does just one ­sin­gle thin­g. I ca­lled it “sim­ple-­na­me” and it is avai­la­ble at: Sim­ple-­Na­me-Ex­ten­sion

It re­mem­bers so­me li­ttle de­tail I was mis­sing from so­me pre­vious win­dow ma­na­gers that I ha­ve u­s­ed along the year­s, whi­ch is to dis­play the user­na­me of the cu­rren­tly lo­gge­d-in use­r.

I must say tha­t, I co­de it just for the sake of lear­ning and ex­pe­ri­men­ting wi­th and API and a bit of Ja­vaS­crip­t. In addi­tion I found ve­ry in­te­res­ting to see fron­t-end re­lated te­ch­no­lo­gies like Ja­vaS­cript or CSS u­s­ed in the desk­top en­vi­ron­ment (not that is so­me­thing new, but sti­ll funn­y).

To sum up, I wanted to hi­gh­li­ght that is in­te­res­ting to learn new te­ch­no­lo­gie­s, even wi­th li­ttle an­d ­sim­ple steps like a new API, li­bra­r­y, etc. It is not for the te­ch­no­lo­gy itsel­f, but for the sake of ­lear­ning :)

On returning consistent data types

This post is ins­pi­red on an is­sue I on­ce foun­d, whi­le I was using a we­ll-k­no­wn li­bra­ry in Py­thon fo­r ­par­sing YA­ML fi­le­s. The pro­blem was that when it was loading the con­tent of the fi­le, the re­sult wa­s ­not co­he­ren­t, be­cau­se so­me­ti­mes it re­tur­ned the con­tent as a py­thon dict, but if the fi­le was emp­ty, the ­re­turn va­lue was No­ne.

Do you no­ti­ce so­me­thing odd he­re?

What if I want to use the re­sul­t? I can­not do it safe­l­y, for exam­ple:

1
2
3
content = yaml.load(...)  # with the correct parameters and file name
for tag, values in content.items():
    pass  # process as required...

If con­tent is No­ne, it wi­ll rai­se an Attri­bu­teE­rror sa­ying that No­ne has no­ a­ttri­bu­te ca­lled “i­te­ms” (whi­ch is true).

The­re­fo­re, the de­ve­lo­per should ca­tch the ex­cep­tion or avoid the cor­ner ca­se, by doing so­me­thing like the fo­llo­win­g:

content = yaml.load() or {}

That could be a ca­se of “co­ding de­fen­si­ve­l­y”, making su­re that the pro­gram wi­ll not fail un­de­r ­most con­di­tions (it would al­so re­qui­re to add an as­sert or to rai­se an ex­cep­tio­n ­perhap­s, but that is a di­ffe­rent to­pi­c). I ac­tua­lly agree wi­th de­fen­si­ve pro­gra­m­min­g, ­but I thi­nk it is be­tter if the li­bra­ry itself has a mo­re co­rrect be­ha­viou­r, res­pec­tin­g ­the in­ter­fa­ce (that is: if you are going to re­turn a dic­tio­na­r­y, and the­re is not con­ten­t, ­then the lo­gi­cal as­sump­tion is to ex­pect an emp­ty dic­tio­na­r­y). ­This must be the de­fault be­ha­viou­r, not so­me­thing to be set by pa­ra­me­ter­s.

This could be thou­ght as an ins­tan­ce of a mo­re ge­ne­ral pro­blem that oc­curs when so­me func­tio­n is in­ten­ded to re­turn “X or Y”. In my opi­nio­n, if X and Y do not sha­re the sa­me in­ter­fa­ce, ­the­re is a po­ten­tial bug (in the Ob­jec­t-O­rien­ted pa­ra­digm we would say that the­re is no po­l­y­mor­phis­m, or ma­y­be that the “con­trac­t” is not being res­pec­te­d).

This is an exam­ple that I wanted to hi­gh­li­gh­t, be­cau­se it mi­ght help you to wri­te clea­ner co­de.