tips

Cython: Tips and tricks

if you have more tricks comment below …

The last couple of days I started learning Cython …

What is Cython ?

Cython is compiled language that seamlesly integrates C with Python, plus more …

C, Cython, Python

The nice thing about is that the learning curve is very gradual. You can start w/o even changing your Python code.
Simply compiling it may speed up your script.

The next step is to start using Cython-the-language constructs.
Those include :

  • Declaring the type of the variables
  • Specifying who and how to call Functions/methods
  • Extension types : Classes which are implemented using Struct, instead of Dict allowing the dispatch resolution to happen at compile time, rather than runtime.

And finally you have the syntax to integrate directly C/C++ libraries and code.

Now on the

tips and tricks …

Creaing an array

Use 1D array instead of lists or numpy array whenever you can.
Red somewhere it is twice as fast than numpy.
In addition you can dynamically .resize() it in-place.

Here is the fastest way to create empty/zeroth array. First you need to have array templates prepared :

from cpython cimport array

cdef iARY = array.array('i') #integer
cdef IARY = array.array('I') #unsigned integer
cdef fARY = array.array('f') #float
cdef dARY = array.array('d') #double

then :

cdef ary = array.clone(fARY, size, 1)

Other options are :

cdef ary = array.array('f')
array.resize(ary, size)
array.zero(ary)

slower variant, but works on other types too :

cdef ary = array.array('f')
array.resize(ary, size)
ary[:] = 0

more on this here : Fast zero’ing

Accessing array elements

Here are several ways to access elements of array … from slower to faster.

ary[i] = value
ary._f[i] = value
#fastest, cause access the union struct directly
ary.data.as_floats[i] = value

the last one sped some portions of my code by ~30 times.

There are variations of the example above depending on the type :

  • _f, _i, _u …..
  • as_floats, as_ints, as_uints …..

A different len()

from cpython.object cimport Py_SIZE
#does not work on range()
cdef inline unsigned int clen(obj): return Py_SIZE(obj)

generates cleaner code, it should be faster. cpdef’d version is slower, which is expected.

type vs isinstance

if you have to do type checks use “type is …” instead of isinstance(), especially if you do several of them.

: x=type(5) 

: %timeit x is int
27.2 ns ± 4.12 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

: %timeit x is float
26.4 ns ± 0.731 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

: %timeit isinstance(5,int) 
52.6 ns ± 0.237 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

: %timeit isinstance(5,float) 
74.2 ns ± 1.28 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

: %timeit isinstance(x,int)                                                                                                                                           
71.5 ns ± 0.357 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

: %timeit isinstance(x,float)                                                                                                                                         
81 ns ± 1.32 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

---

: %timeit type(5) is int                                                                                                                                              
55 ns ± 0.487 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

: %timeit type(5) == int                                                                                                                                              
57.6 ns ± 1.59 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

: %timeit type(5) is float                                                                                                                                            
58 ns ± 1.26 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

Managing CSS colors with JavaScript

When you work with colors with JavaScript you have to use the rgb-format. But when you extract colors you get back the color as a string.

So I wrote several utility Functions to manage rgb colors.

function getbg(id) {// get background color
  let el = document.getElementById(id)
  let rgb = window.getComputedStyle(el).backgroundColor
  return rgb
}

function setbg(id,rgb) {// set background color
  let el = document.getElementById(id)
  el.style.backgroundColor = rgb
}

function rgb2ary(rgb_str) {
  return rgb_str.substring(4,rgb_str.length - 1).split(/,\s*/).map(a => Number(a))
}

function ary2rgb(ary){ return 'rgb(' + ary.join(',') + ')' }

function rand3() {
  return Array.from({length:3}, (_,x) => Math.floor(Math.random() * 255))
}

function rand_rgb() {return ary2rgb(rand3())}

here are some examples of how to use them :

> rand3()
[251, 1, 161]

> rand_rgb()
'rgb(25,120,161)'

> rgb2ary(rand_rgb())
[240, 137, 194]

> ary2rgb(rgb2ary(rand_rgb()))
'rgb(66,165,150)'

> setbg('abc',rand_rgb())

> getbg('abc')
'rgb(78, 43, 152)'

CSS: Fix WordPress theme

The other day I started using TAB’s from Ultimate Addons for Gutenberg (UAG) but there was a conflict with my THEME.

Because the tabs are implemented using <li><a>TAB</a></li> they had annoying mini squares from the <li> tag and underline from <a> tag … so I had to figure out the responsible CSS classes.

Once I found them using the browser Inspect tool (right click) :

.entry ul li, .entry ol ul li {
    list-style: square;
}
.entry a {
    color: #1b2b47;
    box-shadow: 0 1px 0 #aeb3c7;
}

I had to just exclude those rules for the UAG tab elements using not as seen below.

.entry ul li:not(.uagb-tab), .entry ol ul li {
    list-style: square;
}
.entry a:not(.uagb-tabs-list) {
    color: #1b2b47;
    box-shadow: 0 1px 0 #aeb3c7;
}

I still left the 1px underline for the hover effect.

Better than a Permalink

Do not do any changes to your site until you read the full Post !

Everyone is aware of the permalinks capability of WordPress, but for sites with fully or partially hierarchical structure there is an additional feature which can make your site easier to navigate and understand.

The idea is for the hierarchical part of your site to use this hierarchy in building your permalink. For example the following page “Learn Java” based on the structure of this site the permalink can be :

  • learn-java
  • learn/java
  • learn-programming/java
  • learn/programming/java

It is clear that the last one is the superior link if you know that every word in this link represents a page.

  • learn
  • learn/programming/
  • learn/programming/java

Again I’m emphasizing that you do that only for the parts of the site that exhibit hierarchy.

So if all what I said apply to your case, how do you do it ?

There is an option in the side panel in the Block editor where you specify Parent page, but if are like me and learned about this after the fact then you would use the Quick edit in the Dashboard > Pages > All Pages list (like shown below) to do the modifications.

Set all the pages in the hierarchy in the following manner :

  • learn => no parent
  • learn/programming/ => learn
  • learn/programming/java => learn/programming/

Why do you see the yellow highlights ? Because there are several things to account for that you have to take into consideration.

First you want your Title to stay descriptive, so you may keep it as it is.

Second your slug should be shorter because it is now part of the hierarchy. You don’t want to put there learn-java, because your permalink will become learn/programming/learn-java. We don’t want that.

The third thing is that if this page is a part of a menu you may have a different text there because of a space constraint.

In this site I have even deeper hierarchy : /understand/programming/languages/java/
But as you see I have many sub-hierarchies, instead of ONE, because otherwise the URL will get too long.

So you like the idea and want to jump in … A, a, a … not so fast. Changing the structure of your site means broken links. So before you start find yourself a plugin to mop up after you break some eggs.

I used “Broken Link Checker“.

Now you are good to go ….

Get a list of your plugins

I was looking to get a list of my Plugins, but I’m too lazy to copy and paste twenty times. So I did this :

  • Went to the plugin page
  • Right-mouse click
  • selected Inspect from the menu
  • went to Console tab
  • Pasted the code below and hit Enter
  • … and got my Plugin list
$x('//td[contains(@class,"plugin-title")]/strong').map(a => a.innerText).toString()

'Advanced Editor Tools (previously TinyMCE Advanced),Akismet Anti-Spam,All-in-One WP Migration,.....'

BTW in the browser console yo u can use $x(…) to find elements by using XPath.

enjoy …