Проблема с преобразованием исходного кода Javascript в Python

#javascript #python #python-3.x

#javascript #python #python-3.x

Вопрос:

Я пытаюсь преобразовать функцию Javascript в Python. По большей части это не было проблемой, но есть одно утверждение, которое я не уверен, как преобразовать:

 color =  ("0x"   color.slice(1).replace(color.length < 5 amp;amp; /./g, '$amp;$amp;'))
 

Python до сих пор:

 color =  ("0x"   color[:1].replace(
            len(color) < 5 and /./g, '$amp;$amp;')
        )
 

idk для чего () или /./g для чего. Полная функция JS:

 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 amp;amp; /./g, '$amp;$amp;'))
        console.log(color)
        r = color >> 16;
        g = color >> 8 amp; 255;
        b = color amp; 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;
}
 

Комментарии:

1. Первый вопрос, который нужно задать, «что он делает», потому что вы могли бы перенести точный код, но бесконечно лучше писать код на pythonic, который выполняет то же самое, что и обязательно довольно разный код JS из-за различий между стандартными библиотеками двух языков. Игнорируйте код Python сейчас: объясните, что делает JS, глядя исключительно на JS. Каково ожидаемое содержимое color ? Учитывая это, что делает код?

2. @Mike’Pomax’Camermans конечно, если вас не смущает синтаксис. Я никогда раньше не видел такого принуждения к типу. Это необычно и на мгновение напомнило мне о лямбда-исчислении. Я также забыл, что существуют объекты регулярных выражений.

Ответ №1:

Это /./g регулярное выражение () , которое преобразует строку в число (и 0x делает его шестнадцатеричным). В Python вы бы использовали re модуль и int() встроенный для этого.

replace Дублирует символы, если цвет записан в краткой форме. Эквивалентом Python является re.sub() . Вы используете обратную косую черту вместо доллара для обратных ссылок на диалекте регулярных выражений Python. So 1 относится к первой соответствующей группе.

 >>> 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'
 

Итак, для короткой строки это заменяет каждый символ самим собой дважды, но для длинной строки это заменяет каждый символ самим собой один раз (без изменений).

Затем вы используете основание 16 для преобразования шестнадцатеричной строки в int:

 >>> int('aabbcc', 16)
11189196
 

Все вместе:

 int(re.sub("(.)", r"11" if len(color)<5 else r"1", color[1:]), 16)
 

Ответ №2:

Это довольно компактная строка кода. Давайте разберем это.

Во-первых, () это то же Number() самое, что и в этом случае, оно также может быть альтернативно реализовано с использованием parseInt() .

Далее /./g просто регулярное выражение. Сам по себе он ничего не делает. Это просто значение типа "hello" или 3 . Это первый аргумент для replace() .

Таким образом, строка может быть переписана как:

 let temp1 = color.slice(1); // In this case can also be rewritten as color.substr(1)
                            // It basically removes the first character

if (color.length < 5) {
    temp1 = temp1.replace(/./g, '$amp;$amp;'); // This replaces each character with itself twice.
                                         // For example "123" is replaced with "112233"
}

let temp2 = "0x"   temp1. // This adds "0x" to the previous string so that
                          // it will look like a hexadecimal number.

color = parseInt(temp2); // Convert string of hexadecimal number to a number.
 

Я лично не знаю Python, но приведенное выше должно быть легко переписано на любом языке.

Если вам не нравятся регулярные выражения, вы можете переписать код удвоения числа с помощью цикла. Ниже приведена альтернативная реализация, которая вообще не использует никаких причудливых функций / методов:

 // Remove first character (color.slice(1))
let temp1 = "";
for (let i=1; i<color.length; i  ) { // copy every character except color[0]
    temp1 = temp1   color[i];
}

// Convert 3-letter color to 6-letter color, eg #69a to #6699aa
if (color.length < 5) {
    let temp2 = "";
    for (let i=0; i<3; i  ) {
        temp2 = temp2   temp1[i]   temp1[i];
    }

    temp1 = temp2;
}

let temp3 = "0x"   temp1. // This adds "0x" to the previous string so that
                          // it will look like a hexadecimal number.

color = parseInt(temp3); // Convert string of hexadecimal number to a number.
 

Обратите внимание, что обе версии приведенного выше кода выполняют точно то же самое, что и строка:

 color =  ("0x"   color.slice(1).replace(color.length < 5 amp;amp; /./g, '$amp;$amp;'))