0

I am reading a javascript source and I need to convert it to Python.

Here is the code, since I am just a beginner, I dont get .reduce() function at all

function bin2dec(num){
    return num.split('').reverse().reduce(function(x, y, i){
        return (y === '1') ? x + Math.pow(2, i) : x;
    }, 0);
}

Here is what I have tried so far

def bin2dec(num):
    listNum = list(num)
    listNum = map(int, listNum)
    x = listNum[-1]
    listNum.reverse()
    for i in range (len(listNum)):
        if listNum[i] == 1:
            x = x + 2**listNum[i]
        else:
            x = x
    return x

But it is not correct.

1
  • 1
    It’s silly in JavaScript too, because there’s let bin2dec = num => parseInt(num, 2);. Commented Jul 16, 2022 at 4:58

2 Answers 2

3

Normal Equivalence

  • Javascript parseInt(x, 2)
  • Python int(x, 2)

Using Same Method as Posted Code

from functools import reduce
import math

def bin2dec(s):
    return reduce(lambda x, y_i: x + int(math.pow(2, y_i[0])) if y_i[1] == '1' else x, 
                  enumerate(reversed(s)), 
                  0)

Test

print(bin2dec('110'))  # outut: 6

Explanation

  • reversed(s) to replace Javascript num.split('').reverse()
  • Python's reduce function from functools has signature reduce(function, iterable[, initializer])
    • Use Python lambda function in place of Javascript's function(x, y, i){... (1st argument)
    • Javascript reduce provide current value and current index y, i
    • Python only provides current value, so we use enumerate(..) on values array to convert to current index, current value pairs (2nd argument)
    • y_i are value tuples, with y_i[0] = index and y_i[1] the value
    • use 0 as initializer (last argument in reduce)
  • int to convert the value of math.pow from float to integer
  • Python if else expression in place of Javascript's ? ternary operator

Simpler Python Code than Using Reduce

def bin2dec(s):
    return sum((0, 2**i)[y == '1'] for i, y in enumerate(s[::-1]))
Sign up to request clarification or add additional context in comments.

Comments

1

You can just use the built-in int function:

int("010010", 2)

>>> 18

That said I found a pretty interesting alternative approach using js2py. You can feed it the whole js function as a string, allowing you to effectively use js inside python:

import js2py

bin2dec = js2py.eval_js("""
function bin2dec(num){
    return num.split('').reverse().reduce(function(x, y, i){
        return (y === '1') ? x + Math.pow(2, i) : x;
    }, 0);
}
""")

bin2dec("010010")

>>> 18

Install with pip install js2py


You made a lot of mistakes with your attempt, the map function returns an iterator, not a list. Generally, just avoid map and filter and just use a list comprehension instead.

You also raised 2 to the power of the value (1 or 0) when it should have been the index.

Here's a working version of your example:

def bin2dec(num):
    listNum = [int(n) for n in num]
    total = 0
    listNum.reverse()
    for i, n in enumerate(listNum):
        if n == 1:
            total += 2 ** i
    return total

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.