Я перевожу проект с Python на Node.js - до этого момента все шло хорошо. У меня есть функция, которая должна конвертировать количество опыта у кого-то в уровень. Я попытался переписать рабочую функцию из Python в Node.js, но функции возвращают совершенно разные ответы, и я не могу понять, почему.
Python :
def calculateLevel(exp):
if exp < 83: return 1
else:
calcExp = 0
for level in range(1, 1000):
diff = int(level + 300 * math.pow(2, float(level)/7))
calcExp += diff
if exp < calcExp//4:
break
return level
Node.js:
const _ = require("underscore");
// ...
function calculateLevel(exp) {
return new Promise((resolve, reject) => {
if (exp < 83) resolve(1);
else {
var calcExp = 0;
for (var i in _.range(1, 1000)) {
calcExp += parseInt(i + 300 * Math.pow(2, i/7));
if (exp < Math.floor(calcExp/4)) {
resolve(i);
break;
}
}
}
});
}
Например, calculateLevel(123456)
в Python возвращает 51
(правильный ответ), но await calculateLevel(123456);
в Node.js возвращает 15
(неправильный ответ).
Очевидно, что в версии Node.js что-то не так, но я не могу понять, что это такое.
Любая помощь приветствуется. Заранее спасибо.
4 ответа
В Python:
for i in range(1, 10)
print(i)
Создаст последовательность для 1 2 3 4 5 6 7 8 9
for...in
в JavaScript будет перебирать ключи, а не значения.
Так что for (var i in _.range(1, 1000)) {
всегда будет 0 ... 999
Измените его на for...of
function calculateLevel(exp) {
return new Promise((resolve, reject) => {
if (exp < 83) resolve(1);
else {
var calcExp = 0;
for (var i of _.range(1, 999)) {
calcExp += parseInt(i + 300 * Math.pow(2, i/7));
if (exp < Math.floor(calcExp/4)) {
resolve(i);
break;
}
}
}
});
}
Кроме того, неясно, почему вы используете Promise здесь, потому что у вас нет асинхронного кода здесь. Таким образом, вы можете полностью удалить Обещание здесь.
const _ = require("underscore");
// ...
function calculateLevel(exp) {
if (exp < 83) return 1;
else {
var calcExp = 0;
for (var i of _.range(1, 1000)) {
calcExp += parseInt(i + 300 * Math.pow(2, i/7));
if (exp < Math.floor(calcExp/4)) {
break;
}
}
return i;
}
}
console.log(calculateLevel(123456))
Просто добавлю свое мнение, так как у вас уже есть принятый ответ.
Хотя вы конвертируете блок кода Python в Javascript, я чувствую, что вам не обязательно использовать тот же синтаксис и имена методов.
Например, если мы возьмем следующий блок кода в Python и JS;
Python :
def calculateLevel(exp):
if exp < 83: return 1
else:
calcExp = 0
for level in range(1, 1000):
diff = int(level + 300 * math.pow(2, float(level)/7))
calcExp += diff
if exp < calcExp//4:
break
return level
Примечание: здесь используется for level in range(1, 1000):
.
То же самое можно сделать с помощью цикла while
. Так что это может выглядеть примерно так:
level = 0
while level <= 1000:
diff = int(level + 300 * math.pow(2, float(level)/7))
calcExp += diff
if exp < calcExp//4:
break
return level
Но зацикливание на for in range()
в Python более эффективно, чем использование while
. Если бы я запустил простой тест, я увидел бы следующие результаты.
for in range()
: 55 вызовов функций за 0,000 секунд
while
: 1650 вызовов функций за 0,001 секунды
Хотя в случае с Python это так, в Javascript все обстоит иначе (и в вашем подходе, где используется функция подчеркивания range()
). Хотя имена функций выглядят одинаково, это не означает, что они имеют такую же производительность, как в Python.
Фактически, цикл по _.range()
намного медленнее, чем цикл по while
. Если вы посмотрите на некоторые результаты тестов, вы увидите что-то вроде этого:
Using _.range(1, 1000)
: на 67,67% медленнее
https://jsbench.me/b2jl4vvgnw/1
Итак, со всем этим, я думаю, что лучше написать это, используя цикл while, и с небольшой модификацией я бы написал это так:
function calculateLevel(exp) {
var level = 1;
if (exp > 83){
var calcExp = 0;
while(level <= 1000){
calcExp += parseInt(level + 300 * Math.pow(2, level/7));
if (exp < Math.floor(calcExp/4))
break;
level++;
}
}
return level;
}
Надеюсь, это поможет!!
if (exp < Math.floor(calcExp/4)) {
resolve(i);
break;
}
Должно быть
if (exp < Math.floor(calcExp/4)) {
break;
}
resolve(i)
Я запустил этот код:
function calculateLevel(exp) {
return new Promise((resolve, reject) => {
if (exp < 83) resolve(1);
else {
var calcExp = 0;
for (var i=1; i<1000; i++) {
calcExp += parseInt(i + 300 * Math.pow(2, i/7));
if (exp < Math.floor(calcExp/4)) {
resolve(i);
break;
}
}
}
}); }
console.log(calculateLevel(123456));
И он вернулся 51.
Что-то еще, вероятно, вызывает проблему.
Похожие вопросы
Новые вопросы
javascript
Для вопросов, касающихся программирования в ECMAScript (JavaScript / JS) и его различных диалектах / реализациях (исключая ActionScript). Этот тег редко используется отдельно, но чаще всего ассоциируется с тегами [node.js], [jquery], [json] и [html].