I’m trying to convert a Javascript function to Python. Most of it was no problem but there’s one statement I’m not sure how to convert:
color = +("0x" + color.slice(1).replace(color.length < 5 && /./g, '$&$&'))
The Python so far is:
color = +("0x" + color[:1].replace( len(color) < 5 and /./g, '$&$&') )
idk what +()
or /./g
are for. The complete JS function is:
function lightOrDark(color) { // Variables for red, green, blue values var r, g, b, hsp; var threshold = 127.5 // Check the format of the color, HEX or RGB? if (color.match(/^rgb/)) { // If RGB --> store the red, green, blue values in separate variables color = color.match(/^rgba?((d+),s*(d+),s*(d+)(?:,s*(d+(?:.d+)?))?)$/); r = color[1]; g = color[2]; b = color[3]; } else { // If hex --> Convert it to RGB: http://gist.github.com/983661 color = +("0x" + color.slice(1).replace(color.length < 5 && /./g, '$&$&')) console.log(color) r = color >> 16; g = color >> 8 & 255; b = color & 255; } // HSP (Highly Sensitive Poo) equation from http://alienryderflex.com/hsp.html hsp = Math.sqrt( 0.299 * (r * r) + 0.587 * (g * g) + 0.114 * (b * b) ) // Using the HSP value, determine whether the color is light or dark return hsp > threshold; }
Advertisement
Answer
The /./g
is a regular expression and the +()
coerces a string into a number (and the 0x
makes it hexadecimal). In Python you’d use the re
module and the int()
builtin for that.
The replace
duplicates the characters if the color is written in its short form. The Python equivalent is a re.sub()
. You use a backslash instead of a dollar for back-references in Python’s regex dialect. So 1
refers to the first matching group.
>>> import re >>> color = "#123456" >>> re.sub("(.)", r"11" if len(color)<5 else r"1", color[1:]) '123456' >>> color = "#abc" >>> re.sub("(.)", r"11" if len(color)<5 else r"1", color[1:]) 'aabbcc'
So for a short string, this replaces each character with itself twice, but for a long string this replaces each character with itself once (no change).
Then you use a base of 16 to convert a hexadecimal string to an int:
>>> int('aabbcc', 16) 11189196
All together:
int(re.sub("(.)", r"11" if len(color)<5 else r"1", color[1:]), 16)