Я — JavaScript-разработчик. Код пишу в основном на React (иногда на Vue), немного на TypeScript, немного на Node, немного знаю SQL, но...
Короче говоря, сложно было не заинтересоваться Python.
Как известно, лучший способ научиться "кодить" — это писать код.
Предлагаю вашему вниманию 50 популярных в сфере программирования задач, решенных с помощью Python и JavaScript.
Цель — сравнить языки на предмет предоставляемых ими возможностей.
Задачки не очень сложные, хотя имеется парочка из категории продвинутых.
Предполагается, что вы владеете хотя бы одним из названных языков на среднем уровне.
Я старался комментировать ключевые моменты. Однако, это не гайд по JavaScript или Python, поэтому за подробностями работы той или иной функции или метода вам придется обращаться к другим источникам (в конце концов, что это за разработчик, который не умеет гуглить).
Если вы найдете более оптимальное или эффективное с точки зрения производительности решение, поделитесь им в комментариях или пришлите мне в личку, я обязательно добавлю его в список. Единственное условие — решение должно быть не просто другим, а лучшим по объективным причинам.
Я старался выбирать задачи, которые, во-первых, можно без особого труда (т.е. без "плясок с бубном") решить на обоих языках, во-вторых, можно решить аналогичным или хотя бы похожим образом. Отчасти поэтому некоторые решения могут выглядеть нетипичными для того или иного языка. Это опять же обусловлено сравнением между функционалом и конструкциями JavaScript и Python.
Python
print('Hello world!')
JavaScript
console.log('Hello world!')
// или
alert('Hello world!')
Фраза "Hello world" переводится не как "Привет, мир", а как "Привет всем" или, если быть более аутентичным, "Привет, народ". Вы знали об этом?
Python
# переменные для чисел
num1 = 2
num2 = 4
# num1, num2 = 2, 4 - так делать можно, но не рекомендуется
# переменная для суммы
sum = num1 + num2
# f-строки позволяют интерполировать переменные
print(f'{num1} + {num2} = {sum}') # 2 + 4 = 6
JavaScript
const num1 = 4
const num2 = 2
// const num1 = 4, num2 = 2 - так делать можно, но не рекомендуется
const sum = num1 + num2
// для интерполяции переменных в `JS` используются шаблонные или строковые литералы
console.log(`${num1} + ${num2} = ${sum}`) // 2 + 4 = 6
Python
num = 4
# получаем 2.0
sqrt = num ** 0.5
# встроенная функция `int()` преобразует число в целое
print(f'Квадратным корнем {num} является {int(sqrt)}')
# Квадратным корнем 4 являет
# для выполнения математических операций в `Python`
# имеется специальный модуль
from math import sqrt
print(sqrt(4)) # 2.0
JavaScript
const num = 4
// получаем 2, поэтому необходимость в округлении числа до целого отсутствует
const sqrt = num ** 0.5
console.log(`Квадратным корнем ${num} является ${sqrt}`)
// для выполнения математических операций в `JS`
// имеется глобальный объект
console.log(Math.sqrt(4)) // 2
Здесь можно почитать про различные способы вычисления площади треугольника.
Если a, b и c — три стороны треугольника, то согласно формуле Герона для того, чтобы вычислить площадь треугольника,
p = (a + b + c) / 2
s = √(p * (p - a) * (p - b) * (p - c))
p — это полупериметр, а s — площадь.
Python
a = 5
b = 6
c = 7
# вычисляем полупериметр
p = (a + b + c) / 2
# вычисляем площадь
s = (p * (p - a) * (p - b) * (p - c)) ** 0.5
# `round(num, count)` используется для округления числа в ближайшую сторону
# `count` - количество цифр после запятой
print(f'Площадь треугольника со сторонами {a}, {b} и {c} равняется {round(s, 2)}')
JavaScript
const a = 5
const b = 6
const c = 7
const p = (a + b + c) / 2
const s = (p * (p - a) * (p - b) * (p - c)) ** 0.5
// в `JS` метод `Math.round()` округляет число до целого в ближайшуй сторону,
// поэтому мы используем метод `toFixed(count)`
console.log(`Площадь треугольника со сторонами ${a}, ${b} и ${c} равняется ${s.toFixed(2)}`)
Python
x = 5
y = 10
# с помощью дополнительной (временной) переменной
t = x
x = y
y = t
# такой трюк в `JS` провернуть нельзя,
# но там есть другой
x, y = y, x
# с помощью сложения и вычитания
x = x + y
y = x - y
x = x - y
# c помощью умножения и деления
x = x * y
y = x / y
x = x / y
# с помощью исключающего ИЛИ (XOR)
x = x ^ y
y = x ^ y
x = x ^ y
JavaScript
// в целом, все то же самое, за исключением следующего:
// переменные должны объявляться с помощью ключевого слова `let`,
// чтобы они были мутабельными (изменяемыми)
// в `Python` по умолчанию все переменные являются мутабельными
let x = 5
let y = 10
let t = x
x = y
y = t
// трюк на `JS`
// обратите внимание на ; перед [
;[x, y] = [y, x]
// с помощью сложения и вычитания
// c помощью умножения и деления
// с помощью исключающего ИЛИ (XOR)
Python
В Python для этого существует специальный модуль:
# импортируем метод из модуля
from random import randint
# такая функция называется лямбдой
get_random_int = lambda min, max: randint(min, max)
print(f'Случайное целое число в диапазоне от 0 до 100: {get_random_int(0, 100)}')
JavaScript
В JS готовой функции для этого нет, поэтому придется реализовать ее самостоятельно:
// такая функция называется стрелочной
// ~~ - это сокращение для `Math.floor()` - округление числа до целого в меньшую сторону
// `Math.random()` возвращает случайное число от 0 до 1
const getRandomInt = (min, max) => ~~(min + Math.random() * (max - min + 1))
console.log(`Случайное целое число в диапазоне от 0 до 100: ${getRandomInt(0, 100)}`)
Python
# запрашиваем км у "юзера" с помощью `input()`
# `float()` преобразует строку в число с запятой
km = float(input('Введите значение в км: '))
# фактор преобразования
f = 0.621371
# вычисляем мили
m = km * f
# km = m / f
print(f'{km} километров - это {round(m, 2)} миль')
JavaScript
// запрашиваем км у юзера с помощью `prompt()`
// `Number()` преобразует строку в число
const km = Number(prompt('Введите значение в км: '))
const f = 0.621371
const m = km * f
alert(`${km} километров - это ${m.toFixed(2)} миль`)
Python
# запрашиваем градусы Цельсия у юзера
c = float(input('Введите значение в градусах Цельсия: '))
# преобразуем Цельсий в Фаренгейт
f = (c * 1.8) + 32
# c = (f - 32) / 1.8
print(f'{c} градусов Цельсия - это {round(f, 2)} градусов Фаренгейта')
JavaScript
// запрашиваем градусы Цельсия у юзера
const c = Number(prompt('Введите значение в градусах Цельсия: '))
const f = c * 1.8 + 32
alert(`${c} градусов Цельсия - это ${f.toFixed(2)} градусов Фаренгейта`)
Python
# сигнатура обычной функции
# отступы имеют принципиальное значение,
# обозначая блоки кода
def is_pos_neg:
# если
if n > 0:
return 'Positive'
# иначе если
elif n == 0:
return 'Null'
# иначе
else:
return 'Negative'
print(
is_pos_neg(
# преобразуем строку в число c запятой
float(
input('Number: ')
)
)
)
JavaScript
// сигнатура обычной функции
// фигурные скобки имеют принципиальное значение,
// обозначая блоки кода
function isPosNeg {
// если
if (n > 0) {
return 'Positive'
// иначе если
} else if (n === 0) {
return 'Null'
// иначе
} else {
return 'Negative'
}
}
alert(
isPosNeg(
// `+` (унарный префиксный плюс) - это сокращение для `Number()`
+prompt('Number: ')
)
)
Python
# это называется коротким вычислением
# истина if условие else ложь
is_odd_even = lambda n: 'Even' if n % 2 == 0 else 'Odd'
print(
is_odd_even(
float(
input('Number: ')
)
)
)
JavaScript
// тернарный оператор
// условие ? истина : ложь
// обратите внимание, что в `JS` имеется 2 оператора равенства
// старайтесь всегда использовать `===`
const isOddEven = => (n % 2 === 0 ? 'Even' : 'Odd')
alert(
isOddEven(
prompt('Number: ')
)
)
Раз уж мы заговорили про наличие 2 операторов равенства в JS, здесь же обращу ваше внимание на следующее:
Високосным является год, который делится на 4 без остатка, за исключением столетий (оканчивающихся на 00). В последнем случае год будет високосным, если делится без остатка на 400.
Python
def is_leap_year(year):
if (year % 4) == 0:
if (year % 100) == 0:
if (year % 400) == 0:
return 'Leap'
else:
return 'Not leap'
else:
return 'Leap'
else:
return 'Not leap'
# функцию можно переписать с помощью логических операторов `and` (И), `or` (ИЛИ) и `not` (НЕ)
def is_leap_year(year):
# `\` используется для объединения нескольких строк кода
# в один блок
if (year % 4) == 0 and (year % 100) == 0 and (year % 400) == 0 \
or (year % 4) == 0 and not (year % 100) == 0:
return 'Leap'
else:
return 'Not leap'
print(
is_leap_year(
int(
input('Year: ')
)
)
)
JavaScript
function isLeapYear(year) {
if (year % 4 === 0) {
if (year % 100 === 0) {
if (year % 400 === 0) {
return 'Leap'
} else {
return 'Not leap'
}
} else {
return 'Leap'
}
} else {
return 'Not leap'
}
}
// функцию можно переписать с помощью логических операторов `&&` (И), `||` (ИЛИ) и `!` (НЕ)
// объединение нескольких строк кода в один блок
// происходит автоматически
function isLeapYear(year) {
if (
(year % 4 === 0 && year % 100 === 0 && year % 400 === 0) ||
(year % 4 === 0 && !(year % 100 === 0))
) {
return 'Leap'
} else {
return 'Not leap'
}
}
alert(
isLeapYear(
// еще одна функция для преобразования значения в целое число
// второй аргумент - система счисления (в данном случае десятичная)
parseInt(
prompt('Year: '),
10
)
)
)
Python
def get_largest_num(n1, n2, n3):
if (n1 >= n2) and (n1 >= n2):
return n1
elif (n2 >= n1) and (n2 >= n3):
return n2
else:
return n3
print(get_largest_num(1, 3, 2)) # 3
# существует встроенная функция
print(max(3, 1, 2))
JavaScript
function getLargestNum(n1, n2, n3) {
if (n1 >= n2 && n1 >= n3) {
return n1
} else if (n2 >= n1 && n2 >= n3) {
return n2
} else {
return n3
}
}
console.log(getLargestNum(1, 3, 2)) // 3
// существует встроенная функция
console.log(Math.max(3, 1, 2))
Простым является число, которое больше 1 и делится только на себя и 1. Простыми являются числа 2, 3, 5, 7 и т.д. А число 6, например, таковым не является, поскольку является составным: 2 * 3 = 6.
Python
def is_prime:
if n > 1:
# `range()` осуществляет перебор (итерацию) в указанном количестве
# возможные сигнатуры:
# `range(end)`
# `range(start, end)`
# `range(start, end, step)`
for i in range(2, n):
# если имеется число, на которое `n` делится без остатка
if (n % i) == 0:
return 'Not prime'
# если такого числа нет
return 'Prime'
# если число < 1
return 'Invalid'
print(
is_prime(
int(
input('Number: ')
)
)
)
JavaScript
// в `JS` не существует аналога `range()`,
// поэтому функцию придется реализовать по-другому
function isPrime {
if (n > 1) {
let i = 2
// выполнять блок кода до тех пор, пока...
while (i < n) {
if (n % i === 0) {
return 'Not prime'
}
i++
}
return 'Prime'
}
return 'Invalid'
}
alert(
isPrime(
parseInt(
prompt('Number: '),
10
)
)
)
Python
def get_primes(min, max):
primes = []
for n in range(min, max + 1):
if n > 1:
for i in range(2, n):
if (n % i) == 0:
# оператор `break` используется для выхода из цикла
break
else:
# `append()` помещает элемент в конец списка
primes.append
return primes
print(get_primes(1, 100))
JavaScript
function getPrimes(min, max) {
const primes = []
for (let i = min; i <= max; i++) {
if (i > 1) {
// индикатор того, что число является простым
let isPrime = true
for (let j = 2; j < i; j++) {
if (i % j === 0) {
isPrime = false
break
}
}
if (isPrime) {
// `push()` помещает элемент в конец массива
primes.push(i)
}
}
}
return primes
}
console.log(getPrimes(1, 100))
Факториал — это произведение всех целых чисел от 1 до указанного. Например, факториалом числа 6 является 1 * 2 * 3 * 4 * 5 * 6 = 720. "Указанное число" должно быть положительным. В качестве небольшой оптимизации следует принять во внимание, что факториалом чисел 1 и 2 являются, соответственно, 1 и 2.
Python
def get_factorial:
if n < 0: return 'Invalid'
if n < 2: return n
# это называется рекурсией
# чтобы понять рекурсию, необходимо сначала понять рекурсию
return n * get_factorial(n - 1)
print(get_factorial(6)) # 720
JavaScript
function getFactorial {
if (n < 0) return 'Invalid'
if (n < 2) return n
return n * getFactorial(n - 1)
}
console.log(getFactorial(6)) // 720
Python
def get_mult_table:
for i in range(1, 11):
print(f'{n} * {i} = {n * i}')
get_mult_table(9)
JavaScript
function getMultTable {
for (let i = 1; i < 11; i++) {
console.log(`${n} * ${i} = ${n * i}`)
}
}
getMultTable(9)
Последовательность Фибоначчи — это последовательность целых чисел 0, 1, 1, 2, 3, 5, 8 и т.д. Два первых числа — это 0 и 1. Последующие числа — это результат сложения двух предыдущих.
Python
# рекурсивная реализация будет гораздо менее производительной
def get_fibonacci_sum:
if n < 0: return 'Invalid'
if n <= 1: return n
a = 1
b = 1
for i in range(3, n + 1):
c = a + b
a = b
b = c
return b
print(get_fibonacci_sum(10)) # 55
JavaScript
function getFibonacciSum {
if (n < 0) return 'Invalid'
if (n <= 1) return n
let a = 1
let b = 1
for (let i = 3; i <= n; i++) {
let c = a + b
a = b
b = c
}
return b
}
console.log(getFibonacciSum(10)) // 55
Натуральные числа — числа, возникающие естественным образом при счете (1, 2, 3, 4, 5, 6, 7 и т.д.).
Python
def get_natural_sum:
if n < 0: return 'Invalid'
s = 0
while n > 0:
s += n
n -= 1
return s
print(
get_natural_sum(10)
)
# с помощью лямбда-функции
get_nat_sum = lambda n: 'Invalid' if n < 0 else int(n * (n + 1) / 2)
print(
get_nat_sum(10)
)
JavaScript
function getNaturalSum {
if (n < 0) return 'Invalid'
let s = 0
while (n > 0) {
s += n
n -= 1
}
return s
}
console.log(
getNaturalSum(10)
)
// с помощью стрелочной функции
const getNatSum = => n < 0 ? 'Invalid' : n * (n + 1) / 2
console.log(
getNatSum(10)
)
Python
def get_power_of_2:
# `r` - список с результатами
# `list(iterable)` создает список
# `iterable` - итерируемая или перебираемая сущность
# `map(function, iterable)` - вызывает `function` для каждого элемента в `iterable
r = list(map(lambda x: 2 ** x, range(1, n + 1)))
for i in range:
# `r` извлекает элемент с указанным индексом
print(f'2 ** {i + 1} = {r}')
get_power_of_2(10)
JavaScript
function getPowerOf2 {
// `Array.from(iterable, function)` - создает массив, в том числе с помощью функции,
// вызываемой для каждого элемента массива
// `length` - длина создаваемого массива
// `function` принимает элемент и его индекс
const r = Array.from({ length: n }, (_, i) => 2 ** (i + 1))
for (const i in r) {
// `r` извлекает элемент с указанным индексом
console.log(`2 ** ${+i + 1} = ${r}`)
}
}
getPowerOf2(10)
Python
# создаем список, первым элементом которого является `10`, с шагом `10`, до `210`
nums = list(map(lambda x: x, range(10, 210, 10)))
# `filter(function, iterable)` выполняет фильтрацию списка
# `function` возвращает логическое значение - критерий фильтрации
div_nums = lambda n: list(filter(lambda x: (x % n) == 0, nums))
print(div_nums(6))
JavaScript
const nums = Array.from({ length: 10 }, (_, i) => i > 0 ? (i + 1) * 10 : 10)
// `filter(function)` возвращает отфильтрованный массив
const div_nums = => nums.filter(_n => _n % n === 0)
console.log(div_nums(6))
Наибольший общий делитель (он же наивысший общий фактор) — это положительное целое число, на которое без остатка делятся 2 (и более) других числа. Например, число 12 является НОД чисел 36 и 48.
Python
def get_gcd(x, y):
# переменная для меньшего числа
s = x
if x > y: s = y
for i in range(1, s + 1):
if ((x % i == 0) and (y % i == 0)):
# в данном случае мы можем "переиспользовать" переменную `s`
s = i
return s
print(get_gcd(48, 36)) # 12
JavaScript
function getGcd(x, y) {
let s = x
if (x > y) s = y
// мы не можем переопределять переменную `s`,
// потому что используем ее в цикле
let r = 1
for (let i = 1; i <= s; i++) {
if (x % i === 0 && y % i === 0) {
r = i
}
}
return r
}
console.log(getGcd(24, 54)) // 6
Наименьшее общее кратное — это положительное целое число, которое делится без остатка на два (и более) других числа. Например, число 84 является НОК чисел 12 и 14.
Python
def get_lcm(x, y):
# переменная для большего числа
g = x
if x < y: g = y
# осторожно: потенциально бесконечный цикл
while True:
if (g % x == 0) and (g % y == 0):
break
g += 1
return g
print(get_lcm(12, 14)) # 84
JavaScript
function getLCM(x, y) {
let g = x
if (x < y) g = y
// осторожно: потенциально бесконечный цикл
// в данном случае мы можем переиспользовать переменную `g`
while (true) {
if (g % x === 0 && g % y === 0) {
break
}
g += 1
}
return g
}
console.log(getLCM(24, 54)) // 216
Python
def get_factors:
f = []
for i in range(1, n + 1):
if n % i == 0:
f.append(i)
return f
print(get_factors(123)) # [1, 3, 41, 123]
JavaScript
function getFactors {
const f = []
for (let i = 1; i <= n; i++) {
if (n % i === 0) {
f.push(i)
}
}
return f
}
console.log(getFactors(321)) // [1, 3, 107, 321]
Почему бы не реализовать его на классах?
Python
class Calc:
# инициализация класса
def __init__(self):
# результат
self.result = 0
# метод для добавления числа
def add(self, n):
self.result += n
# возвращаем экземпляр, чтобы иметь возможность выполнять операции в цепочке
return self
# для вычитания
def sub(self, n):
self.result -= n
return self
# для умножения
def mult(self, n):
self.result *= n
return self
# для деления
def div(self, n):
self.result /= n
return self
# создаем экземпляр
calc = Calc()
# выполняем операции
calc.add(5).sub(3).mult(4).div(2)
# выводим результат
print(int(calc.result)) # 4
JavaScript
class Calc {
// инициализация класса
constructor() {
this.result = 0
}
// в `JS` `this` (`self`) явно передавать не требуется
add {
this.result += n
// возвращаем экземпляр, чтобы иметь возможность выполнять операции в цепочке
return this
}
sub {
this.result -= n
return this
}
mult {
this.result *= n
return this
}
div {
this.result /= n
return this
}
}
// создаем экземпляр
const calc = new Calc()
// выполняем операции
calc.add(5).sub(3).mult(4).div(2)
// выводим результат
console.log(calc.result) // 4
Лично я предпочитаю функциональный стиль программирования, поэтому классов в примерах больше не будет.
Такое преобразование выполняется посредством деления числа на 2 с выводом остатка в обратном порядке. Проще показать:
Python
def convert_to_binary:
if n < 0: return 'Invalid'
if n > 1:
# `//` - оператор деления с округлением в меньшую сторону
# рекурсия
convert_to_binary(n // 2)
# конкатенация вывода
# в `JS` такой "фичи" нет
print(n % 2, end = '')
convert_to_binary(34)
# вывод результата
print() # 100010
JavaScript
function convertToBinary {
if (n < 0) return 'Invalid'
// переменная для двоичного представления
const binary = []
while (n >= 1) {
// метод `unshift()` помещает элемент в начало массива
binary.unshift(n % 2)
n = ~~(n / 2)
}
// объединяем элементы массива в строку
return binary.join('')
}
console.log(convertToBinary(34)) // 100010
// в `JS` есть встроенная функция `toString(radix)`,
// где `radix` - это система счисления
console.log((34).toString(2)) // 100010
Матрица может быть представлена в виде вложенного списка (массива), где каждый элемент — это строка матрицы. Пример матрицы 3x2, где 3 — это количество строк, а 2 — количество столбцов:
[
[2, 4],
[6, 8],
[1, 3]
]
Доступ к первой строке матрицы x можно получить через x[0], а доступ к первому элементу первой строки — через x[0][0].
Обратите внимание: эта задача относится к категории продвинутых. Можете пропустить ее, если читаете статью в первый раз.
Python
def add_matrices(x, y):
# результирующая матрица
result = [
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
]
# `len()` возвращает длину списка
# выполняем итерацию по количеству строк
for i in range(len(x)):
# выполняем итерацию по количеству столбцов
for j in range(len(x[0])):
result[j] = x[j] + y[j]
return result
# матрица раз
x = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
# матрица два
y = [
[9, 8, 7],
[3, 2, 1],
[6, 5, 4]
]
print(add_matrices(x, y))
'''
[
[10, 10, 10],
[7, 7, 7],
[13, 13, 13]
]
'''
# данная техника называется представлением списков (list comprehension)
add_matrices_advanced = lambda x, y: [[x[j] + y[j] for j in range(len(x[0]))] for i in range(len(x))]
print(add_matrices_advanced(x, y))
JavaScript
function addMatrices(x, y) {
const result = [
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
]
// выполняем итерацию по количеству строк
for (const i in x) {
// выполняем итерацию по количеству столбцов
for (const j in x[0]) {
result[j] = x[j] + y[j]
}
}
return result
}
const x = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
const y = [
[9, 8, 7],
[3, 2, 1],
[6, 5, 4]
]
console.log(addMatrices(x, y))
/*
[
[10, 10, 10],
[7, 7, 7],
[13, 13, 13]
]
*/
// стрелочная функция
// `map(function)` вызывает `function` для каждого элемента массива
// она принимает 2 параметра: элемент и его индекс
// и возвращает новый массив
const addMatricesAdvanced = (x, y) =>
x.map((_, i) => x.map((_, j) => x[j] + y[j]))
console.log(addMatricesAdvanced(x, y))
Транспонированная матрица — это матрица, полученная из исходной посредством замены строк на столбцы.
Обратите внимание: эта задача относится к категории продвинутых.
Python
def transpose_matrix(x):
# мы хотим преобразовать матрицу 3x2 в матрицу 2x3
# количество строк `x` количество столбцов
result = [
[0, 0, 0],
[0, 0, 0]
]
for i in range(len(x)):
for j in range(len(x[0])):
result[j] = x[j]
return result
x = [
[1, 2],
[4, 5],
[7, 8]
]
print(transpose_matrix(x))
'''
[
[1, 4, 7],
[2, 5, 8]
]
'''
# представление списков
transpose_matrix_advanced = lambda x: [[x[j] for j in range(len(x))] for i in range(len(x[0]))]
print(transpose_matrix_advanced(x))
JavaScript
function transposeMatrix(x) {
const result = [
[0, 0, 0],
[0, 0, 0]
]
for (const i in x) {
for (const j in x[0]) {
result[j] = x[j]
}
}
return result
}
const x = [
[1, 2],
[4, 5],
[7, 8]
]
console.log(transposeMatrix(x))
/*
[
[1, 4, 7],
[2, 5, 8]
]
*/
// стрелочная функция
const transposeMatrixAdvanced = (x) =>
x[0].map((_, i) => x.map((_, j) => x[j]))
console.log(transposeMatrixAdvanced(x))
Палиндром — это строка (слово, число и т.д.), которая читается одинаково в обоих направлениях. Примеры: "borrow or rob", "а роза упала на лапу Азора".
Python
def is_palindrome(str):
# ''.join() - объединение в строку
# str.split(' ') - преобразование строки в массив по разделителю (в данном случае - пробелу)
# ''.join(str.split(' ')) - удаление пробелов из строки
# casefold() - нечувствительность к регистру, приведение к нижнему регистру
str = ''.join(str.split(' ')).casefold()
# инверсия строки - изменение порядка следования букв на противоположный
rev = reversed(str)
# сравнение списков
return list(str) == list(rev)
print(is_palindrome('Borrow or rob')) # True
JavaScript
function isPalindrome(str) {
// `replace()` - удаление пробелов с помощью регулярного выражения
// `toLowerCase()` - приведение к нижнему регистру
str = str.replace(/\s/g, '').toLowerCase()
// `split()` - преобразование строки в массив
// `reverse()` - инверсия
// `join()` - объединение в строку
const rev = str.split('').reverse().join('')
return str === rev
}
console.log(isPalindrome('А роза упала на лапу Азора')) // true
Python
# лишние символы
symbols = '''!()-[]{};:'"\,<>./?@#$%^&*_~'''
def clear(str):
# переменная для строки, очищенной от лишних символов
cleared = ''
# перебираем строку по буквам
for char in str:
# если буква не является одним из лишних символов
if char not in symbols:
# добавляем ее к очищенной строке
cleared += char
return cleared
print(
clear('Привет!! - сказал он --- и вошел')
) # Привет сказал он и вошел
JavaScript
const symbols = `!()-[]{};:'"\,<>./?@#$%^&*_~`
function clear(str) {
let cleared = ''
for (const char of str) {
if (!symbols.includes(char)) cleared += char
}
return cleared
}
console.log(
clear('Привет!! - сказал он --- и вошел')
) // Привет сказал он и вошел
Python
def sort_words(str):
# разбиваем строку на массив слов и
# приводим каждое слово к нижнему регистру
words = [word.lower() for word in str.split()]
# сортируем слова
words.sort()
return words
print(sort_words('Остро нуждающаяся в сортировке строка'))
'''
[
'в',
'нуждающаяся',
'остро',
'сортировке',
'строка'
]
'''
JavaScript
function sortWords(str) {
// разбиваем строку на массив слов по пробелу и
// приводим каждое слово к нижнему регистру
const words = str.split(' ').map((word) => word.toLowerCase())
words.sort()
return words
}
console.log(sortWords('Остро нуждающаяся в сортировке строк'))
/*
[
'в',
'нуждающаяся',
'остро',
'сортировке',
'строка'
]
*/
Python
# все гласные латиницы
vowels = 'aeiou'
def get_vowels_count(str):
str = str.casefold()
# `fromkeys(iterable, initialValue)`
count = {}.fromkeys(vowels, 0)
for char in str:
# если буква гласная
if char in count:
# увеличиваем значение соответствующего ключа словаря на 1
count[char] += 1
return count
str = 'Hello! How are you today?'
print(
get_vowels_count(str)
) # { 'a': 2, 'e': 2, 'i': 0, 'o': 4, 'u': 1 }
JavaScript
const vowels = 'aeiou'
function getVowelsCount(str) {
str = str.toLowerCase()
// `[...vowels]` - преобразуем строку в массив с помощью spread-оператора
// `reduce(function, initialValue)` - аккумулирует результат на основе значений массива
const count = [...vowels].reduce((a, c) => {
a[c] = 0
return a
}, {})
for (const char of str) {
if (vowels.includes(char)) {
count[char] += 1
}
}
return count
}
const str = 'Hello! How are you today?'
console.log(
getVowelsCount(str)
) // { 'a': 2, 'e': 2, 'i': 0, 'o': 4, 'u': 1 }
Обратите внимание: эта задача (точнее, 3 задачи) относятся к категории продвинутых. Это последняя относительно сложная задача, дальше будет намного проще.
Половина пирамиды
Python
def draw_half_pyramid(rows):
# для каждой строки
for i in range(rows):
# рисуем `*` в количестве,
# соответствующем порядковому номеру строки
for j in range(i + 1):
# `stdout` остается открытым
print('* ', end = '')
# переход на новую строку
if (i + 1) < rows: print('\n')
draw_half_pyramid(5)
'''
*
* *
* * *
* * * *
* * * * *
'''
JavaScript
function drawHalfPyramid(rows) {
// строка со звездочками
let pyramid = ''
// для каждой строки
for (let i = 1; i <= rows; i++) {
// рисуем `*` в количестве...
for (let j = 0; j < i; j++) {
pyramid += '* '
}
// переход на новую строку
pyramid += '\n'
}
return pyramid
}
console.log(drawHalfPyramid(5))
/*
*
* *
* * *
* * * *
* * * * *
*/
Перевернутая половина пирамиды
Python
def draw_inverted_half_pyramid(rows):
# движемся в обратную сторону
for i in range(rows, 0, -1):
for j in range(0, i):
print('* ', end = '')
if i > 1: print('\n')
draw_inverted_half_pyramid(5)
'''
* * * * *
* * * *
* * *
* *
*
'''
JavaScript
function drawInvertedHalfPyramid(rows) {
let pyramid = ''
for (let i = rows; i > 0; i--) {
for (let j = 0; j < i; j++) {
pyramid += '* '
}
pyramid += '\n'
}
return pyramid
}
console.log(drawInvertedHalfPyramid(5))
/*
* * * * *
* * * *
* * *
* *
*
*/
Полная пирамида
Python
def draw_full_pyramid(rows):
k = 0
p = ''
for i in range(1, rows + 1):
for j in range(1, (rows - i) + 1):
p += ' '
while k != (2 * i - 1):
p += '# '
k += 1
if i < rows: p += '\n'
k = 0
return p
print(draw_full_pyramid(5))
'''
#
# # #
# # # # #
# # # # # # #
# # # # # # # # #
'''
JavaScript
На JS я решу эту задачу не таким лаконичным, но более понятным способом:
function drawFullPyramid(rows) {
let levels = ''
const mid = ~~((2 * rows - 1) / 2)
for (let row = 0; row < rows; row++) {
let level = ''
for (let col = 0; col < 2 * rows - 1; col++) {
// в данном случае мы сразу формируем тот или иной уровень
// в зависимости от положения колонки -
// до или после середины
level += mid - row <= col && col <= mid + row ? '#' : ' '
}
levels += level + '\n'
}
return levels
}
console.log(drawFullPyramid(5))
/*
#
# # #
# # # # #
# # # # # # #
# # # # # # # # #
*/
Python
dict_1 = { 'a': 1, 'b': 2 }
dict_2 = { 'b': 3, 'c': 4 }
# совпадающие ключи перезаписываются
print(dict_1 | dict_2) # { 'a': 1, 'b': 3, 'c': 4 }
# `**` - распаковка словарей
print({ **dict_1, **dict_2 })
JavaScript
const obj1 = { a: 1, b: 2 }
const obj2 = { b: 3, c: 4 }
// совпадающие ключи перезаписываются
console.log(
Object.assign(obj1, obj2)
) // { a: 1, b: 3, c: 4 }
// `...` - распаковка объектов
console.log({ ...obj1, ...obj2 })
Python
my_list = [[1], [2, 3], [4, 5, 6]]
# представление списков
flat_list_1 = [n for sub in my_list for n in sub]
print(flat_list_1) # [1, 2, 3, 4, 5, 6]
# встроенная функция `sum()`
flat_list_3 = sum(my_list, [])
print(flat_list_3)
# модуль `itertools`
import itertools
flat_list_2 = list(itertools.chain(*my_list))
print(flat_list_2)
JavaScript
const myList = [[1], [2, 3], [4, 5, 6]]
// встроенный метод `flat()`
const flatList1 = myList.flat()
console.log(flatList1) // [1, 2, 3, 4, 5, 6]
// встроенный метод `reduce()`
const flatList2 = myList.reduce((a, c) => {
c.forEach((i) => a.push(i))
return a
}, [])
console.log(flatList2)
// двойная итерация
// ключевое слово `const` делает иммутабельным
// значение самой переменной, а не массива
const flatList3 = []
for (const i of myList) {
for (const j of i) {
flatList3.push(j)
}
}
console.log(flatList3)
Python
# список (list)
my_list = [1, 2, 3, 4, 5]
# сигнатура
# `[start:end:step]`
# полная копия
print(my_list[:]) # [1, 2, 3, 4, 5]
# от второго до пятого элемента
print(my_list[1:5]) # [2, 3, 4]
# через 1 элемент, начиная с первого
print(my_list[::2]) # [1, 3, 5]
# извлекаем последний элемент
# это не относится к копированию
print(my_list[-1]) # 5
JavaScript
// массив (array)
const myList = [1, 2, 3, 4, 5]
// сигнатура
// `slice(start, end)`
// данный метод не такой мощный как питоновский аналог
// полная копия
console.log(myList.slice()) // [1, 2, 3, 4, 5]
// от второго до пятого
console.log(myList.slice(1, 5)) // [2, 3, 4]
// последний элемент - хак
console.log(...myList.slice(-1)) // 5
// последний элемент - не хак
console.log(myList[myList.length - 1])
// последний элемент - скоро, в `Chrome` уже работает
console.log(myList.at(-1)) // 5
Python
# словарь (dictionary)
dict = { 1: 'a', 2: 'b', 3: 'c' }
# ключи и значения
for key in dict:
print(key, dict[key])
'''
1 a
2 b
3 c
'''
# еще ключи и значения
for key, val in dict.items():
print(key, val)
# или
for key, val in dict.iteritems():
print(key, val)
# ключи
for key in dict.keys():
print(key)
# значения
for val in dict.values():
print(val)
JavaScript
// объект (object)
const obj = { 1: 'a', 2: 'b', 3: 'c' }
// ключи и значения
for (const key in obj) {
console.log(key, obj[key])
}
/*
1 a
2 b
3 c
*/
// еще ключи и значение
Object.entries(obj).forEach(([key, val]) => {
console.log(key, val)
})
// или
for (const [key, val] of Object.entries(obj)) {
console.log(key, val)
}
// ключи
Object.keys(obj).forEach((key) => {
console.log(key)
})
// значения
for (const val of Object.values(obj)) {
console.log(val)
}
Python
dict = { 1: 'b', 3: 'c', 2: 'a'}
# сортировка по значениям
sorted_dict_1 = {
key: val \
for key, val \
# key - критерий сортировки (в данном случае - значение)
in sorted(dict.items(), key = lambda i: i[1])
}
print(sorted_dict_1) # { 2: 'a', 1: 'b', 3: 'c' }
# сортировка по ключам
sorted_dict_2 = { key: val for key, val in sorted(dict.items(), key = lambda i: i[0]) }
print(sorted_dict_2) # { 1: 'b', 2: 'a', 3: 'c' }
JavaScript
// объект для примера пришлось изменить
// поскольку встроенный метод `Object.fromEntries()`
// выполняет автоматическую сортировку по ключам
// при создании объекта из вложенного массива
const obj = { a: '2', c: '1', b: '3' }
// логику сортировки лучше вынести в отдельную функцию
// по умолчанию функция выполняет сортировку по ключам
// благодаря параметру `i` со значением `1` по умолчанию
const sortObj = (obj, i = 0) =>
Object.fromEntries(
// `sort()` принимает функцию для сортировки
// `localeCompare()` сравнивает строки с учетом локали
Object.entries(obj).sort((a, b) => a.localeCompare(b))
)
// по ключам
const sortedObj1 = sortObj(obj)
console.log(sortedObj1) // { a: '2', b: '3', c: '1' }
// по значениям
const sortedObj2 = sortObj(obj, 1)
console.log(sortedObj2) // { c: '1', a: '2', b: '3' }
Python
my_list = []
# `not`
if not my_list:
print('Empty')
# + `len()`
if not len(my_list):
print('Empty')
# в `JS` так не получится
if my_list == []:
print('Empty')
JavaScript
const myList = []
// ! - [] -> 0 -> false + ! - false -> true
if (!!myList) {
console.log('Empty')
}
// ! - 0 -> false -> true
if (!myList.length) {
console.log('Empty')
}
// самый очевидный и надежный способ
// или `myList.length === 0`
if (myList.length < 1) {
console.log('Empty')
}
Python
list_1 = ['a', 'b']
list_2 = list(range(3, 5))
list_2.append('a')
# в `Python` списки можно конкатенировать путем сложения
joined_1 = list_1 + list_2
print(joined_1) # ['a', 'b', 3, 4, 'a']
# распаковка
joined_2 = [*list_1, *list_2]
print(joined_2)
# исключение дубликатов
joined_uniq = list(set(joined_1))
print(joined_uniq) # [3, 'b', 'a', 4]
# модификация списка посредством его расширения
list_2.extend(list_1)
print(list_2) # [3, 4, 'a', 'a', 'b']
JavaScript
const list1 = ['a', 'b']
// еще один встроенный метод для создания массивов
const list2 = Array.of(3, 4)
list2.push('a')
// распаковка
const joined1 = [...list1, ...list2]
console.log(joined1) // ['a', 'b', 3, 4, 'a']
// объединение
const joined2 = list2.concat(list1)
console.log(joined2) // [3, 4, 'a', 'a', 'b']
// исключение дубликатов
// набор (set) сразу преобразуется в обычный массив
const joinedUniq = [...new Set(joined1)]
console.log(joinedUniq) // ['a', 'b', 3, 4]
// модификация массива путем его расширения
list2.splice(-1, 0, ...list1)
console.log(list2) // [3, 4, 'a', 'b', 'a']
Python
my_str = 'I like Python'
# по аналогии со списком
substr = my_str[2:6]
print(substr) # like
JavaScript
const myStr = 'I like JavaScript'
// по аналогии с массивом
const subStr1 = myStr.slice(2, 6)
console.log(subStr1) // like
// специальные встроенные методы
// deprecated
const subStr2 = myStr.substr(2, 5)
console.log(subStr2) // like
const subStr3 = myStr.substring(2, 6)
console.log(subStr3) // like
// разница между методами `substr()` и `substring()`
// состоит в том, включается ли последний элемент в подстроку
Python
import random
# import secrets
def get_random_item(list):
if not list:
return 'Empty'
else:
return random.choice(list) # secrets.choice(list)
print(get_random_item(['a', 3, 'c', 1, 'b'])) # 3
JavaScript
// функция для получения случайного целого числа
const getRandomInt = (min, max) => ~~(min + Math.random() * (max - min + 1))
// функция для получения случайного элемента
const getRandomItem = (arr) => arr[getRandomInt(0, arr.length - 1)]
console.log(getRandomItem(['a', 3, 'c', 1, 'b'])) // 'b'
Python
my_list = ['a', 1, 1, 'a', 2, 'b', 'a']
# `count()`
a_count = my_list.count('a')
print(a_count) # 3
# это также работает для строк
my_str = 'Hello world'
l_count = my_str.count('l')
print(l_count) # 3
JavaScript
const myList = ['a', 1, 1, 'a', 2, 'b', 'a']
const myStr = 'Hello world'
// фильтрация и длина массива
const a_count = myList.filter((i) => i === 'a').length
console.log(a_count) // 3
// преобразуем строку в массив
const l_count = [...myStr].filter((i) => i === 'l').length
console.log(l_count) // 3
Python
indexes = [0, 1, 2]
languages = ['JavaScript', 'Python', 'PHP']
# `zip()` & `dict()`
my_dict_1 = dict(zip(indexes, languages))
print(my_dict_1) # { 0: 'JavaScript', 1: 'Python', 2: 'PHP' }
# `zip()` и представление списков
my_dict_2 = { k: v for k, v in zip(indexes, languages) }
print(my_dict_2)
JavaScript
const indexes = [0, 1, 2]
const languages = ['JavaScript', 'Python', 'PHP']
// цикл
const obj1 = {}
// нам нужен не только элемент, но и его индекс
// потому что элементы первого массива не всегда будут совпадать с индексами
for (const i in indexes) {
obj1[indexes] = languages
}
console.log(obj1) // { 0: 'JavaScript', 1: 'Python', 2: 'PHP' }
// `reduce()`
const obj2 = indexes.reduce((a, c, i) => {
// `c` - текущий элемент
// `i` - его индекс
a[c] = languages
return a
}, {})
console.log(obj2)
Python
import re
str_with_spaces = 'some string with many spaces '
# заменяем 2 и более пробела на один
# `sub(regexp, replacement, string)`
str_without_spaces = re.sub(r'\s\s+', ' ', str_with_spaces)
print(str_without_spaces) # some string with many spaces
JavaScript
const strWithSpaces = 'some string with many spaces '
// заменяем 2 и более пробела на один
// `replace(substring | regexp, replacement)`
const strWithoutSpaces = strWithSpaces.replace(/\s\s+/g, ' ')
console.log(strWithoutSpaces) // some string with many spaces
Python
from enum import Enum
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 1
print(Color.RED) # Color.RED
print(Color.GREEN.name) # GREEN
print(Color.BLUE.value) # 3
В JS не существует такого типа данных, как перечисление, но его можно сымитировать, "заморозив" объект:
JavaScript
const Color = Object.freeze({
RED: 1,
GREEN: 2,
BLUE: 3
})
// value
console.log(Color.RED) // 1
Два слова являются анаграммами, если состоят из одинаковых букв. Например, анаграммами являются слова "binary" и "brainy", или "раздвоение" и "дозревание".
Python
def is_anagrams(x, y):
# приводим слова к нижнему регистру
x = x.lower()
y = y.lower()
if (len(x) == len):
# и сортируем их
sorted_1 = sorted(x)
sorted_2 = sorted
if (sorted_1 == sorted_2):
return True
else:
return False
else:
return False
word_1 = 'Binary'
word_2 = 'brainy'
print(is_anagrams(word_1, word_2)) # True
JavaScript
function isAnagrams(x, y) {
x = x.toLowerCase()
y = y.toLowerCase()
if (x.length === y.length) {
sorted_x = x.split('').sort().join('')
sorted_y = y.split('').sort().join('')
if (sorted_x === sorted_y) {
return true
}
return false
}
return false
}
const word1 = 'Раздвоение'
const word2 = 'дозревание'
console.log(isAnagrams(word1, word2)) // true
Обратите внимание: при сравнении строк, состоящих из нескольких слов, необходимо также удалять из них все пробелы.
Классика.
Python
my_str = 'hello'
# `upper()` + slice
cap_str_1 = my_str[0].upper() + my_str[1:]
print(cap_str_1) # Hello
# `capitilize()`
cap_str_2 = my_str.capitalize()
В JS отсутствует встроенный метод для капитализации строки.
JavaScript
const str = 'hello'
const capStr1 = str[0].toUpperCase() + str.slice(1)
console.log(capStr1) // Hello
// показать всем, что ты крут
// деструктуризация и шаблонные литералы
const capitilize = ([first, ...rest]) =>
`${first.toUpperCase()}${rest.join('')}`
const capStr2 = capitilize(str)
console.log(capStr2)
Python
# рекурсивно
def get_permutations(s, p = [], i = 0):
if i == len(s):
p.append(''.join(s))
for j in range(i, len(s)):
words = [c for c in s]
words, words[j] = words[j], words
get_permutations(words, p, i + 1)
return p
print(get_permutations('qux'))
# ['qux', 'qxu', 'uqx', 'uxq', 'xuq', 'xqu']
# `itertools`
from itertools import permutations
per = [''.join(p) for p in permutations('baz')]
print(per) # ['baz', 'bza', 'abz', 'azb', 'zba', 'zab']
JavaScript
function getPermutations(str) {
if (str.length < 2) {
return str.length === 2 ? [str, str[1] + str[0]] : [str]
}
return str
.split('')
.reduce(
(a, c, i) =>
a.concat(
getPermutations(str.slice(0, i) + str.slice(i + 1)).map((v) => c + v)
),
[]
)
}
console.log(getPermutations('qux'))
// ['qux', 'qxu', 'uqx', 'uxq', 'xqu', 'xuq']
Python
import time
def timer(time_in_sec):
while time_in_sec:
m, s = divmod(time_in_sec, 60)
formated = f'{m:02d}:{s:02d}'
print(formated, end = '\r')
time.sleep(1)
time_in_sec -= 1
timer(5)
JavaScript
function timer(timeInSec) {
const timerId = setInterval(() => {
let m = ~~(timeInSec / 60)
let s = timeInSec - m * 60
if (m < 10) m = '0' + m
if (s < 10) s = '0' + s
console.log(`${m}:${s}`)
timeInSec -= 1
if (timeInSec < 0) {
clearInterval(timerId)
}
}, 1000)
}
timer(5)
Пусть 2 последних задачки будут посвящены бэку.
Python
import os
# абсолютный путь к текущей директории
__dirname__ = os.path.abspath(os.getcwd())
# небезопасно: при наличии создаваемой директории будет выброшено исключение
try:
os.makedirs(f'{__dirname__}/parent/child/nested')
except FileExistsError:
print('Exists')
import distutils.dir_util
# безопасно
distutils.dir_util.mkpath(f'{__dirname__}/some/dir')
JavaScript
import { dirname } from 'path'
import { fileURLToPath } from 'url'
import { promises as fs } from 'fs'
// абсолютный путь к текущей директории
const __dirname = dirname(fileURLToPath(import.meta.url))
// безопасно
// для сравнения обработки исключений
try {
await fs.mkdir(`${__dirname}/parent/child/nested`, { recursive: true })
} catch (e) {
console.error(e.message || e)
}
Обратите внимание: приведенный код должен запускаться с помощью команды node filename. При этом файл должен быть модулем, т.е. иметь расширение .mjs или же в ближайшем package.json должно содержаться поле type со значением module.
Предположим, что у нас имеется директория files с тремя файлами в формате TXT. Как нам получить названия этих файлов?
Python
import glob, os
__dirname__ = os.path.abspath(os.getcwd()) + '/files'
def get_filenames(ext):
filenames = []
# читаем содержимое директории `files`
os.chdir(__dirname__)
# если файл имеет указанное расширение
for filename in glob.glob(f'*.{ext}'):
# добавляем его в список
filenames.append(filename)
# возвращаем список
return filenames
print(get_filenames('txt'))
# ['baz.txt', 'foo.txt', 'bar.txt']
JavaScript
import { dirname } from 'path'
import { fileURLToPath } from 'url'
import { promises as fs } from 'fs'
const __dirname = dirname(fileURLToPath(import.meta.url))
async function getFilenames(ext) {
const result = []
// читаем содержимое директории `files`
const filenames = await fs.readdir(`${__dirname}/files`)
for (const filename of filenames) {
// если файл имеет указанное расширение
if (filename.includes(`.${ext}`)) {
// добавляем его в массив
result.push(filename)
}
}
return result
}
// функция возвращает промис
getFilenames('txt').then(console.log)
// [ 'bar.txt', 'baz.txt', 'foo.txt' ]
Фух… это было утомительно, но, вместе с тем, невероятно увлекательно, не правда ли?
Как видите, синтаксические конструкции и основной функционал JavaScript и Python являются очень похожими, а во многом даже идентичными (без учета некоторых незначительных отличий), что при необходимости позволяет с относительной легкостью перейти с одного языка на другой.
Вопрос в том, имеется ли необходимость в такой "миграции"?
Обратите внимание: дальше я выскажу собственное мнение с позиции веб-разработчика.
Существенное преимущество JavaScript заключается в том, что он не нуждается в интерпретаторе, т.е. код на JS выполняется браузером напрямую. Это очень сильно облегчает разработку веб-приложений.
Если мы говорим о REST API, то реализовать его на Express, например, намного проще, чем на Django или FastAPI, хотя последний синтаксически схож с сочетанием Express и TypeORM или Prisma (во многом благодаря широкому использованию декораторов).
С другой стороны, если мы говорим о реализации, скажем так, продвинутого сервера, то благодаря огромному количеству, в том числе, встроенных модулей, Python имеет некоторые преимущества перед Node.js.
Есть мнение, что у Python имеются некоторые проблемы с асинхронностью — у меня не было возможности в этом убедиться.
В свою очередь, в Node.js в последнее время царит некоторая неразбериха за счет одновременного существования двух разных подходов к разработке: одного, основанного на колбеках, который считается устаревшим, и другого, основанного на промисах и async/await, который требует дополнительных усилий по настройке окружения и не в полной мере заменяет первый подход.
Благодарю за внимание и хорошего дня!
- со мной работает много людей, которые пишут код на Python
- вокруг много разговоров про Python
- повсюду преподают Python
- Яндекс любит Python (раньше Гугл тоже его любил, но теперь у него есть Go)
Короче говоря, сложно было не заинтересоваться Python.
Как известно, лучший способ научиться "кодить" — это писать код.
Предлагаю вашему вниманию 50 популярных в сфере программирования задач, решенных с помощью Python и JavaScript.
Цель — сравнить языки на предмет предоставляемых ими возможностей.
Задачки не очень сложные, хотя имеется парочка из категории продвинутых.
Предполагается, что вы владеете хотя бы одним из названных языков на среднем уровне.
Я старался комментировать ключевые моменты. Однако, это не гайд по JavaScript или Python, поэтому за подробностями работы той или иной функции или метода вам придется обращаться к другим источникам (в конце концов, что это за разработчик, который не умеет гуглить).
Если вы найдете более оптимальное или эффективное с точки зрения производительности решение, поделитесь им в комментариях или пришлите мне в личку, я обязательно добавлю его в список. Единственное условие — решение должно быть не просто другим, а лучшим по объективным причинам.
Я старался выбирать задачи, которые, во-первых, можно без особого труда (т.е. без "плясок с бубном") решить на обоих языках, во-вторых, можно решить аналогичным или хотя бы похожим образом. Отчасти поэтому некоторые решения могут выглядеть нетипичными для того или иного языка. Это опять же обусловлено сравнением между функционалом и конструкциями JavaScript и Python.
1. Вывести сообщение "Hello world!"
Python
print('Hello world!')
JavaScript
console.log('Hello world!')
// или
alert('Hello world!')
Фраза "Hello world" переводится не как "Привет, мир", а как "Привет всем" или, если быть более аутентичным, "Привет, народ". Вы знали об этом?
2. Сложить два числа
Python
# переменные для чисел
num1 = 2
num2 = 4
# num1, num2 = 2, 4 - так делать можно, но не рекомендуется
# переменная для суммы
sum = num1 + num2
# f-строки позволяют интерполировать переменные
print(f'{num1} + {num2} = {sum}') # 2 + 4 = 6
JavaScript
const num1 = 4
const num2 = 2
// const num1 = 4, num2 = 2 - так делать можно, но не рекомендуется
const sum = num1 + num2
// для интерполяции переменных в `JS` используются шаблонные или строковые литералы
console.log(`${num1} + ${num2} = ${sum}`) // 2 + 4 = 6
3. Извлечь квадратный корень из числа
Python
num = 4
# получаем 2.0
sqrt = num ** 0.5
# встроенная функция `int()` преобразует число в целое
print(f'Квадратным корнем {num} является {int(sqrt)}')
# Квадратным корнем 4 являет
# для выполнения математических операций в `Python`
# имеется специальный модуль
from math import sqrt
print(sqrt(4)) # 2.0
JavaScript
const num = 4
// получаем 2, поэтому необходимость в округлении числа до целого отсутствует
const sqrt = num ** 0.5
console.log(`Квадратным корнем ${num} является ${sqrt}`)
// для выполнения математических операций в `JS`
// имеется глобальный объект
console.log(Math.sqrt(4)) // 2
4. Вычислить площадь треугольника
Здесь можно почитать про различные способы вычисления площади треугольника.
Если a, b и c — три стороны треугольника, то согласно формуле Герона для того, чтобы вычислить площадь треугольника,
- сначала необходимо вычислить разность полупериметра и каждой его стороны
- затем найти произведение полученных чисел, умножить результат на полупериметр и найти корень из полученного числа
p = (a + b + c) / 2
s = √(p * (p - a) * (p - b) * (p - c))
p — это полупериметр, а s — площадь.
Python
a = 5
b = 6
c = 7
# вычисляем полупериметр
p = (a + b + c) / 2
# вычисляем площадь
s = (p * (p - a) * (p - b) * (p - c)) ** 0.5
# `round(num, count)` используется для округления числа в ближайшую сторону
# `count` - количество цифр после запятой
print(f'Площадь треугольника со сторонами {a}, {b} и {c} равняется {round(s, 2)}')
JavaScript
const a = 5
const b = 6
const c = 7
const p = (a + b + c) / 2
const s = (p * (p - a) * (p - b) * (p - c)) ** 0.5
// в `JS` метод `Math.round()` округляет число до целого в ближайшуй сторону,
// поэтому мы используем метод `toFixed(count)`
console.log(`Площадь треугольника со сторонами ${a}, ${b} и ${c} равняется ${s.toFixed(2)}`)
5. Произвести обмен значениями между переменными
Python
x = 5
y = 10
# с помощью дополнительной (временной) переменной
t = x
x = y
y = t
# такой трюк в `JS` провернуть нельзя,
# но там есть другой
x, y = y, x
# с помощью сложения и вычитания
x = x + y
y = x - y
x = x - y
# c помощью умножения и деления
x = x * y
y = x / y
x = x / y
# с помощью исключающего ИЛИ (XOR)
x = x ^ y
y = x ^ y
x = x ^ y
JavaScript
// в целом, все то же самое, за исключением следующего:
// переменные должны объявляться с помощью ключевого слова `let`,
// чтобы они были мутабельными (изменяемыми)
// в `Python` по умолчанию все переменные являются мутабельными
let x = 5
let y = 10
let t = x
x = y
y = t
// трюк на `JS`
// обратите внимание на ; перед [
;[x, y] = [y, x]
// с помощью сложения и вычитания
// c помощью умножения и деления
// с помощью исключающего ИЛИ (XOR)
6. Функция для получения случайного целого числа в заданном диапазоне
Python
В Python для этого существует специальный модуль:
# импортируем метод из модуля
from random import randint
# такая функция называется лямбдой
get_random_int = lambda min, max: randint(min, max)
print(f'Случайное целое число в диапазоне от 0 до 100: {get_random_int(0, 100)}')
JavaScript
В JS готовой функции для этого нет, поэтому придется реализовать ее самостоятельно:
// такая функция называется стрелочной
// ~~ - это сокращение для `Math.floor()` - округление числа до целого в меньшую сторону
// `Math.random()` возвращает случайное число от 0 до 1
const getRandomInt = (min, max) => ~~(min + Math.random() * (max - min + 1))
console.log(`Случайное целое число в диапазоне от 0 до 100: ${getRandomInt(0, 100)}`)
7. Функция для преобразования километров в мили
Python
# запрашиваем км у "юзера" с помощью `input()`
# `float()` преобразует строку в число с запятой
km = float(input('Введите значение в км: '))
# фактор преобразования
f = 0.621371
# вычисляем мили
m = km * f
# km = m / f
print(f'{km} километров - это {round(m, 2)} миль')
JavaScript
// запрашиваем км у юзера с помощью `prompt()`
// `Number()` преобразует строку в число
const km = Number(prompt('Введите значение в км: '))
const f = 0.621371
const m = km * f
alert(`${km} километров - это ${m.toFixed(2)} миль`)
8. Функция для преобразования градусов Цельсия в градусы Фаренгейта
Python
# запрашиваем градусы Цельсия у юзера
c = float(input('Введите значение в градусах Цельсия: '))
# преобразуем Цельсий в Фаренгейт
f = (c * 1.8) + 32
# c = (f - 32) / 1.8
print(f'{c} градусов Цельсия - это {round(f, 2)} градусов Фаренгейта')
JavaScript
// запрашиваем градусы Цельсия у юзера
const c = Number(prompt('Введите значение в градусах Цельсия: '))
const f = c * 1.8 + 32
alert(`${c} градусов Цельсия - это ${f.toFixed(2)} градусов Фаренгейта`)
9. Функция для определения того, каким является число: положительным, отрицательным или нулем
Python
# сигнатура обычной функции
# отступы имеют принципиальное значение,
# обозначая блоки кода
def is_pos_neg:
# если
if n > 0:
return 'Positive'
# иначе если
elif n == 0:
return 'Null'
# иначе
else:
return 'Negative'
print(
is_pos_neg(
# преобразуем строку в число c запятой
float(
input('Number: ')
)
)
)
JavaScript
// сигнатура обычной функции
// фигурные скобки имеют принципиальное значение,
// обозначая блоки кода
function isPosNeg {
// если
if (n > 0) {
return 'Positive'
// иначе если
} else if (n === 0) {
return 'Null'
// иначе
} else {
return 'Negative'
}
}
alert(
isPosNeg(
// `+` (унарный префиксный плюс) - это сокращение для `Number()`
+prompt('Number: ')
)
)
10. Функция для определения того, каким является число, четным или нечетным
Python
# это называется коротким вычислением
# истина if условие else ложь
is_odd_even = lambda n: 'Even' if n % 2 == 0 else 'Odd'
print(
is_odd_even(
float(
input('Number: ')
)
)
)
JavaScript
// тернарный оператор
// условие ? истина : ложь
// обратите внимание, что в `JS` имеется 2 оператора равенства
// старайтесь всегда использовать `===`
const isOddEven = => (n % 2 === 0 ? 'Even' : 'Odd')
alert(
isOddEven(
prompt('Number: ')
)
)
Раз уж мы заговорили про наличие 2 операторов равенства в JS, здесь же обращу ваше внимание на следующее:
- логическими значениями в Python являются True и False (с большой буквы), а в JS — true и false
- индикатором отсутствия значения в Python является None, а в JS у нас целых 3 таких индикатора — undefined, null и NaN
11. Функция для определения того, является ли год високосным
Високосным является год, который делится на 4 без остатка, за исключением столетий (оканчивающихся на 00). В последнем случае год будет високосным, если делится без остатка на 400.
Python
def is_leap_year(year):
if (year % 4) == 0:
if (year % 100) == 0:
if (year % 400) == 0:
return 'Leap'
else:
return 'Not leap'
else:
return 'Leap'
else:
return 'Not leap'
# функцию можно переписать с помощью логических операторов `and` (И), `or` (ИЛИ) и `not` (НЕ)
def is_leap_year(year):
# `\` используется для объединения нескольких строк кода
# в один блок
if (year % 4) == 0 and (year % 100) == 0 and (year % 400) == 0 \
or (year % 4) == 0 and not (year % 100) == 0:
return 'Leap'
else:
return 'Not leap'
print(
is_leap_year(
int(
input('Year: ')
)
)
)
JavaScript
function isLeapYear(year) {
if (year % 4 === 0) {
if (year % 100 === 0) {
if (year % 400 === 0) {
return 'Leap'
} else {
return 'Not leap'
}
} else {
return 'Leap'
}
} else {
return 'Not leap'
}
}
// функцию можно переписать с помощью логических операторов `&&` (И), `||` (ИЛИ) и `!` (НЕ)
// объединение нескольких строк кода в один блок
// происходит автоматически
function isLeapYear(year) {
if (
(year % 4 === 0 && year % 100 === 0 && year % 400 === 0) ||
(year % 4 === 0 && !(year % 100 === 0))
) {
return 'Leap'
} else {
return 'Not leap'
}
}
alert(
isLeapYear(
// еще одна функция для преобразования значения в целое число
// второй аргумент - система счисления (в данном случае десятичная)
parseInt(
prompt('Year: '),
10
)
)
)
12. Функция для определения наибольшего числа
Python
def get_largest_num(n1, n2, n3):
if (n1 >= n2) and (n1 >= n2):
return n1
elif (n2 >= n1) and (n2 >= n3):
return n2
else:
return n3
print(get_largest_num(1, 3, 2)) # 3
# существует встроенная функция
print(max(3, 1, 2))
JavaScript
function getLargestNum(n1, n2, n3) {
if (n1 >= n2 && n1 >= n3) {
return n1
} else if (n2 >= n1 && n2 >= n3) {
return n2
} else {
return n3
}
}
console.log(getLargestNum(1, 3, 2)) // 3
// существует встроенная функция
console.log(Math.max(3, 1, 2))
13. Функция для определения того, является ли число простым
Простым является число, которое больше 1 и делится только на себя и 1. Простыми являются числа 2, 3, 5, 7 и т.д. А число 6, например, таковым не является, поскольку является составным: 2 * 3 = 6.
Python
def is_prime:
if n > 1:
# `range()` осуществляет перебор (итерацию) в указанном количестве
# возможные сигнатуры:
# `range(end)`
# `range(start, end)`
# `range(start, end, step)`
for i in range(2, n):
# если имеется число, на которое `n` делится без остатка
if (n % i) == 0:
return 'Not prime'
# если такого числа нет
return 'Prime'
# если число < 1
return 'Invalid'
print(
is_prime(
int(
input('Number: ')
)
)
)
JavaScript
// в `JS` не существует аналога `range()`,
// поэтому функцию придется реализовать по-другому
function isPrime {
if (n > 1) {
let i = 2
// выполнять блок кода до тех пор, пока...
while (i < n) {
if (n % i === 0) {
return 'Not prime'
}
i++
}
return 'Prime'
}
return 'Invalid'
}
alert(
isPrime(
parseInt(
prompt('Number: '),
10
)
)
)
14. Функция для вывода всех простых чисел в заданном диапазоне
Python
def get_primes(min, max):
primes = []
for n in range(min, max + 1):
if n > 1:
for i in range(2, n):
if (n % i) == 0:
# оператор `break` используется для выхода из цикла
break
else:
# `append()` помещает элемент в конец списка
primes.append
return primes
print(get_primes(1, 100))
JavaScript
function getPrimes(min, max) {
const primes = []
for (let i = min; i <= max; i++) {
if (i > 1) {
// индикатор того, что число является простым
let isPrime = true
for (let j = 2; j < i; j++) {
if (i % j === 0) {
isPrime = false
break
}
}
if (isPrime) {
// `push()` помещает элемент в конец массива
primes.push(i)
}
}
}
return primes
}
console.log(getPrimes(1, 100))
15. Функция для вычисления факториала числа
Факториал — это произведение всех целых чисел от 1 до указанного. Например, факториалом числа 6 является 1 * 2 * 3 * 4 * 5 * 6 = 720. "Указанное число" должно быть положительным. В качестве небольшой оптимизации следует принять во внимание, что факториалом чисел 1 и 2 являются, соответственно, 1 и 2.
Python
def get_factorial:
if n < 0: return 'Invalid'
if n < 2: return n
# это называется рекурсией
# чтобы понять рекурсию, необходимо сначала понять рекурсию
return n * get_factorial(n - 1)
print(get_factorial(6)) # 720
JavaScript
function getFactorial {
if (n < 0) return 'Invalid'
if (n < 2) return n
return n * getFactorial(n - 1)
}
console.log(getFactorial(6)) // 720
16. Функция для вывода таблицы умножения для указанного числа
Python
def get_mult_table:
for i in range(1, 11):
print(f'{n} * {i} = {n * i}')
get_mult_table(9)
JavaScript
function getMultTable {
for (let i = 1; i < 11; i++) {
console.log(`${n} * ${i} = ${n * i}`)
}
}
getMultTable(9)
17. Функция для вычисления суммы чисел из последовательности Фибоначчи до указанного
Последовательность Фибоначчи — это последовательность целых чисел 0, 1, 1, 2, 3, 5, 8 и т.д. Два первых числа — это 0 и 1. Последующие числа — это результат сложения двух предыдущих.
Python
# рекурсивная реализация будет гораздо менее производительной
def get_fibonacci_sum:
if n < 0: return 'Invalid'
if n <= 1: return n
a = 1
b = 1
for i in range(3, n + 1):
c = a + b
a = b
b = c
return b
print(get_fibonacci_sum(10)) # 55
JavaScript
function getFibonacciSum {
if (n < 0) return 'Invalid'
if (n <= 1) return n
let a = 1
let b = 1
for (let i = 3; i <= n; i++) {
let c = a + b
a = b
b = c
}
return b
}
console.log(getFibonacciSum(10)) // 55
18. Функция для вычисления суммы натуральных чисел от 1 до указанного
Натуральные числа — числа, возникающие естественным образом при счете (1, 2, 3, 4, 5, 6, 7 и т.д.).
Python
def get_natural_sum:
if n < 0: return 'Invalid'
s = 0
while n > 0:
s += n
n -= 1
return s
print(
get_natural_sum(10)
)
# с помощью лямбда-функции
get_nat_sum = lambda n: 'Invalid' if n < 0 else int(n * (n + 1) / 2)
print(
get_nat_sum(10)
)
JavaScript
function getNaturalSum {
if (n < 0) return 'Invalid'
let s = 0
while (n > 0) {
s += n
n -= 1
}
return s
}
console.log(
getNaturalSum(10)
)
// с помощью стрелочной функции
const getNatSum = => n < 0 ? 'Invalid' : n * (n + 1) / 2
console.log(
getNatSum(10)
)
19. Функция для вывода чисел в степени 2 от 1 до указанного
Python
def get_power_of_2:
# `r` - список с результатами
# `list(iterable)` создает список
# `iterable` - итерируемая или перебираемая сущность
# `map(function, iterable)` - вызывает `function` для каждого элемента в `iterable
r = list(map(lambda x: 2 ** x, range(1, n + 1)))
for i in range:
# `r` извлекает элемент с указанным индексом
print(f'2 ** {i + 1} = {r}')
get_power_of_2(10)
JavaScript
function getPowerOf2 {
// `Array.from(iterable, function)` - создает массив, в том числе с помощью функции,
// вызываемой для каждого элемента массива
// `length` - длина создаваемого массива
// `function` принимает элемент и его индекс
const r = Array.from({ length: n }, (_, i) => 2 ** (i + 1))
for (const i in r) {
// `r` извлекает элемент с указанным индексом
console.log(`2 ** ${+i + 1} = ${r}`)
}
}
getPowerOf2(10)
20. Функция для определения всех чисел, которые делятся на другое число без остатка
Python
# создаем список, первым элементом которого является `10`, с шагом `10`, до `210`
nums = list(map(lambda x: x, range(10, 210, 10)))
# `filter(function, iterable)` выполняет фильтрацию списка
# `function` возвращает логическое значение - критерий фильтрации
div_nums = lambda n: list(filter(lambda x: (x % n) == 0, nums))
print(div_nums(6))
JavaScript
const nums = Array.from({ length: 10 }, (_, i) => i > 0 ? (i + 1) * 10 : 10)
// `filter(function)` возвращает отфильтрованный массив
const div_nums = => nums.filter(_n => _n % n === 0)
console.log(div_nums(6))
21. Функция для вычисления наибольшего общего делителя
Наибольший общий делитель (он же наивысший общий фактор) — это положительное целое число, на которое без остатка делятся 2 (и более) других числа. Например, число 12 является НОД чисел 36 и 48.
Python
def get_gcd(x, y):
# переменная для меньшего числа
s = x
if x > y: s = y
for i in range(1, s + 1):
if ((x % i == 0) and (y % i == 0)):
# в данном случае мы можем "переиспользовать" переменную `s`
s = i
return s
print(get_gcd(48, 36)) # 12
JavaScript
function getGcd(x, y) {
let s = x
if (x > y) s = y
// мы не можем переопределять переменную `s`,
// потому что используем ее в цикле
let r = 1
for (let i = 1; i <= s; i++) {
if (x % i === 0 && y % i === 0) {
r = i
}
}
return r
}
console.log(getGcd(24, 54)) // 6
22. Функция для вычисления наименьшего общего кратного
Наименьшее общее кратное — это положительное целое число, которое делится без остатка на два (и более) других числа. Например, число 84 является НОК чисел 12 и 14.
Python
def get_lcm(x, y):
# переменная для большего числа
g = x
if x < y: g = y
# осторожно: потенциально бесконечный цикл
while True:
if (g % x == 0) and (g % y == 0):
break
g += 1
return g
print(get_lcm(12, 14)) # 84
JavaScript
function getLCM(x, y) {
let g = x
if (x < y) g = y
// осторожно: потенциально бесконечный цикл
// в данном случае мы можем переиспользовать переменную `g`
while (true) {
if (g % x === 0 && g % y === 0) {
break
}
g += 1
}
return g
}
console.log(getLCM(24, 54)) // 216
23. Функция для определения всех чисел, на которые без остатка делится указанное
Python
def get_factors:
f = []
for i in range(1, n + 1):
if n % i == 0:
f.append(i)
return f
print(get_factors(123)) # [1, 3, 41, 123]
JavaScript
function getFactors {
const f = []
for (let i = 1; i <= n; i++) {
if (n % i === 0) {
f.push(i)
}
}
return f
}
console.log(getFactors(321)) // [1, 3, 107, 321]
24. Простой калькулятор
Почему бы не реализовать его на классах?
Python
class Calc:
# инициализация класса
def __init__(self):
# результат
self.result = 0
# метод для добавления числа
def add(self, n):
self.result += n
# возвращаем экземпляр, чтобы иметь возможность выполнять операции в цепочке
return self
# для вычитания
def sub(self, n):
self.result -= n
return self
# для умножения
def mult(self, n):
self.result *= n
return self
# для деления
def div(self, n):
self.result /= n
return self
# создаем экземпляр
calc = Calc()
# выполняем операции
calc.add(5).sub(3).mult(4).div(2)
# выводим результат
print(int(calc.result)) # 4
JavaScript
class Calc {
// инициализация класса
constructor() {
this.result = 0
}
// в `JS` `this` (`self`) явно передавать не требуется
add {
this.result += n
// возвращаем экземпляр, чтобы иметь возможность выполнять операции в цепочке
return this
}
sub {
this.result -= n
return this
}
mult {
this.result *= n
return this
}
div {
this.result /= n
return this
}
}
// создаем экземпляр
const calc = new Calc()
// выполняем операции
calc.add(5).sub(3).mult(4).div(2)
// выводим результат
console.log(calc.result) // 4
Лично я предпочитаю функциональный стиль программирования, поэтому классов в примерах больше не будет.
25. Функция для преобразования числа в двоичное представление
Такое преобразование выполняется посредством деления числа на 2 с выводом остатка в обратном порядке. Проще показать:
Python
def convert_to_binary:
if n < 0: return 'Invalid'
if n > 1:
# `//` - оператор деления с округлением в меньшую сторону
# рекурсия
convert_to_binary(n // 2)
# конкатенация вывода
# в `JS` такой "фичи" нет
print(n % 2, end = '')
convert_to_binary(34)
# вывод результата
print() # 100010
JavaScript
function convertToBinary {
if (n < 0) return 'Invalid'
// переменная для двоичного представления
const binary = []
while (n >= 1) {
// метод `unshift()` помещает элемент в начало массива
binary.unshift(n % 2)
n = ~~(n / 2)
}
// объединяем элементы массива в строку
return binary.join('')
}
console.log(convertToBinary(34)) // 100010
// в `JS` есть встроенная функция `toString(radix)`,
// где `radix` - это система счисления
console.log((34).toString(2)) // 100010
26. Функция для сложения матриц
Матрица может быть представлена в виде вложенного списка (массива), где каждый элемент — это строка матрицы. Пример матрицы 3x2, где 3 — это количество строк, а 2 — количество столбцов:
[
[2, 4],
[6, 8],
[1, 3]
]
Доступ к первой строке матрицы x можно получить через x[0], а доступ к первому элементу первой строки — через x[0][0].
Обратите внимание: эта задача относится к категории продвинутых. Можете пропустить ее, если читаете статью в первый раз.
Python
def add_matrices(x, y):
# результирующая матрица
result = [
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
]
# `len()` возвращает длину списка
# выполняем итерацию по количеству строк
for i in range(len(x)):
# выполняем итерацию по количеству столбцов
for j in range(len(x[0])):
result[j] = x[j] + y[j]
return result
# матрица раз
x = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
# матрица два
y = [
[9, 8, 7],
[3, 2, 1],
[6, 5, 4]
]
print(add_matrices(x, y))
'''
[
[10, 10, 10],
[7, 7, 7],
[13, 13, 13]
]
'''
# данная техника называется представлением списков (list comprehension)
add_matrices_advanced = lambda x, y: [[x[j] + y[j] for j in range(len(x[0]))] for i in range(len(x))]
print(add_matrices_advanced(x, y))
JavaScript
function addMatrices(x, y) {
const result = [
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
]
// выполняем итерацию по количеству строк
for (const i in x) {
// выполняем итерацию по количеству столбцов
for (const j in x[0]) {
result[j] = x[j] + y[j]
}
}
return result
}
const x = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
const y = [
[9, 8, 7],
[3, 2, 1],
[6, 5, 4]
]
console.log(addMatrices(x, y))
/*
[
[10, 10, 10],
[7, 7, 7],
[13, 13, 13]
]
*/
// стрелочная функция
// `map(function)` вызывает `function` для каждого элемента массива
// она принимает 2 параметра: элемент и его индекс
// и возвращает новый массив
const addMatricesAdvanced = (x, y) =>
x.map((_, i) => x.map((_, j) => x[j] + y[j]))
console.log(addMatricesAdvanced(x, y))
27. Функция для транспонирования матрицы
Транспонированная матрица — это матрица, полученная из исходной посредством замены строк на столбцы.
Обратите внимание: эта задача относится к категории продвинутых.
Python
def transpose_matrix(x):
# мы хотим преобразовать матрицу 3x2 в матрицу 2x3
# количество строк `x` количество столбцов
result = [
[0, 0, 0],
[0, 0, 0]
]
for i in range(len(x)):
for j in range(len(x[0])):
result[j] = x[j]
return result
x = [
[1, 2],
[4, 5],
[7, 8]
]
print(transpose_matrix(x))
'''
[
[1, 4, 7],
[2, 5, 8]
]
'''
# представление списков
transpose_matrix_advanced = lambda x: [[x[j] for j in range(len(x))] for i in range(len(x[0]))]
print(transpose_matrix_advanced(x))
JavaScript
function transposeMatrix(x) {
const result = [
[0, 0, 0],
[0, 0, 0]
]
for (const i in x) {
for (const j in x[0]) {
result[j] = x[j]
}
}
return result
}
const x = [
[1, 2],
[4, 5],
[7, 8]
]
console.log(transposeMatrix(x))
/*
[
[1, 4, 7],
[2, 5, 8]
]
*/
// стрелочная функция
const transposeMatrixAdvanced = (x) =>
x[0].map((_, i) => x.map((_, j) => x[j]))
console.log(transposeMatrixAdvanced(x))
28. Функция для определения того, является ли строка палиндромом
Палиндром — это строка (слово, число и т.д.), которая читается одинаково в обоих направлениях. Примеры: "borrow or rob", "а роза упала на лапу Азора".
Python
def is_palindrome(str):
# ''.join() - объединение в строку
# str.split(' ') - преобразование строки в массив по разделителю (в данном случае - пробелу)
# ''.join(str.split(' ')) - удаление пробелов из строки
# casefold() - нечувствительность к регистру, приведение к нижнему регистру
str = ''.join(str.split(' ')).casefold()
# инверсия строки - изменение порядка следования букв на противоположный
rev = reversed(str)
# сравнение списков
return list(str) == list(rev)
print(is_palindrome('Borrow or rob')) # True
JavaScript
function isPalindrome(str) {
// `replace()` - удаление пробелов с помощью регулярного выражения
// `toLowerCase()` - приведение к нижнему регистру
str = str.replace(/\s/g, '').toLowerCase()
// `split()` - преобразование строки в массив
// `reverse()` - инверсия
// `join()` - объединение в строку
const rev = str.split('').reverse().join('')
return str === rev
}
console.log(isPalindrome('А роза упала на лапу Азора')) // true
29. Функция для удаления лишних символов из строки
Python
# лишние символы
symbols = '''!()-[]{};:'"\,<>./?@#$%^&*_~'''
def clear(str):
# переменная для строки, очищенной от лишних символов
cleared = ''
# перебираем строку по буквам
for char in str:
# если буква не является одним из лишних символов
if char not in symbols:
# добавляем ее к очищенной строке
cleared += char
return cleared
print(
clear('Привет!! - сказал он --- и вошел')
) # Привет сказал он и вошел
JavaScript
const symbols = `!()-[]{};:'"\,<>./?@#$%^&*_~`
function clear(str) {
let cleared = ''
for (const char of str) {
if (!symbols.includes(char)) cleared += char
}
return cleared
}
console.log(
clear('Привет!! - сказал он --- и вошел')
) // Привет сказал он и вошел
30. Функция для сортировки слов в алфавитном порядке
Python
def sort_words(str):
# разбиваем строку на массив слов и
# приводим каждое слово к нижнему регистру
words = [word.lower() for word in str.split()]
# сортируем слова
words.sort()
return words
print(sort_words('Остро нуждающаяся в сортировке строка'))
'''
[
'в',
'нуждающаяся',
'остро',
'сортировке',
'строка'
]
'''
JavaScript
function sortWords(str) {
// разбиваем строку на массив слов по пробелу и
// приводим каждое слово к нижнему регистру
const words = str.split(' ').map((word) => word.toLowerCase())
words.sort()
return words
}
console.log(sortWords('Остро нуждающаяся в сортировке строк'))
/*
[
'в',
'нуждающаяся',
'остро',
'сортировке',
'строка'
]
*/
30. Функция для определения количества гласных в строке
Python
# все гласные латиницы
vowels = 'aeiou'
def get_vowels_count(str):
str = str.casefold()
# `fromkeys(iterable, initialValue)`
count = {}.fromkeys(vowels, 0)
for char in str:
# если буква гласная
if char in count:
# увеличиваем значение соответствующего ключа словаря на 1
count[char] += 1
return count
str = 'Hello! How are you today?'
print(
get_vowels_count(str)
) # { 'a': 2, 'e': 2, 'i': 0, 'o': 4, 'u': 1 }
JavaScript
const vowels = 'aeiou'
function getVowelsCount(str) {
str = str.toLowerCase()
// `[...vowels]` - преобразуем строку в массив с помощью spread-оператора
// `reduce(function, initialValue)` - аккумулирует результат на основе значений массива
const count = [...vowels].reduce((a, c) => {
a[c] = 0
return a
}, {})
for (const char of str) {
if (vowels.includes(char)) {
count[char] += 1
}
}
return count
}
const str = 'Hello! How are you today?'
console.log(
getVowelsCount(str)
) // { 'a': 2, 'e': 2, 'i': 0, 'o': 4, 'u': 1 }
31. Функция для рисования пирамиды
Обратите внимание: эта задача (точнее, 3 задачи) относятся к категории продвинутых. Это последняя относительно сложная задача, дальше будет намного проще.
Половина пирамиды
Python
def draw_half_pyramid(rows):
# для каждой строки
for i in range(rows):
# рисуем `*` в количестве,
# соответствующем порядковому номеру строки
for j in range(i + 1):
# `stdout` остается открытым
print('* ', end = '')
# переход на новую строку
if (i + 1) < rows: print('\n')
draw_half_pyramid(5)
'''
*
* *
* * *
* * * *
* * * * *
'''
JavaScript
function drawHalfPyramid(rows) {
// строка со звездочками
let pyramid = ''
// для каждой строки
for (let i = 1; i <= rows; i++) {
// рисуем `*` в количестве...
for (let j = 0; j < i; j++) {
pyramid += '* '
}
// переход на новую строку
pyramid += '\n'
}
return pyramid
}
console.log(drawHalfPyramid(5))
/*
*
* *
* * *
* * * *
* * * * *
*/
Перевернутая половина пирамиды
Python
def draw_inverted_half_pyramid(rows):
# движемся в обратную сторону
for i in range(rows, 0, -1):
for j in range(0, i):
print('* ', end = '')
if i > 1: print('\n')
draw_inverted_half_pyramid(5)
'''
* * * * *
* * * *
* * *
* *
*
'''
JavaScript
function drawInvertedHalfPyramid(rows) {
let pyramid = ''
for (let i = rows; i > 0; i--) {
for (let j = 0; j < i; j++) {
pyramid += '* '
}
pyramid += '\n'
}
return pyramid
}
console.log(drawInvertedHalfPyramid(5))
/*
* * * * *
* * * *
* * *
* *
*
*/
Полная пирамида
Python
def draw_full_pyramid(rows):
k = 0
p = ''
for i in range(1, rows + 1):
for j in range(1, (rows - i) + 1):
p += ' '
while k != (2 * i - 1):
p += '# '
k += 1
if i < rows: p += '\n'
k = 0
return p
print(draw_full_pyramid(5))
'''
#
# # #
# # # # #
# # # # # # #
# # # # # # # # #
'''
JavaScript
На JS я решу эту задачу не таким лаконичным, но более понятным способом:
function drawFullPyramid(rows) {
let levels = ''
const mid = ~~((2 * rows - 1) / 2)
for (let row = 0; row < rows; row++) {
let level = ''
for (let col = 0; col < 2 * rows - 1; col++) {
// в данном случае мы сразу формируем тот или иной уровень
// в зависимости от положения колонки -
// до или после середины
level += mid - row <= col && col <= mid + row ? '#' : ' '
}
levels += level + '\n'
}
return levels
}
console.log(drawFullPyramid(5))
/*
#
# # #
# # # # #
# # # # # # #
# # # # # # # # #
*/
32. Объединить два словаря (объекта) в один
Python
dict_1 = { 'a': 1, 'b': 2 }
dict_2 = { 'b': 3, 'c': 4 }
# совпадающие ключи перезаписываются
print(dict_1 | dict_2) # { 'a': 1, 'b': 3, 'c': 4 }
# `**` - распаковка словарей
print({ **dict_1, **dict_2 })
JavaScript
const obj1 = { a: 1, b: 2 }
const obj2 = { b: 3, c: 4 }
// совпадающие ключи перезаписываются
console.log(
Object.assign(obj1, obj2)
) // { a: 1, b: 3, c: 4 }
// `...` - распаковка объектов
console.log({ ...obj1, ...obj2 })
33. Преобразовать вложенный список (массив) в одноуровневый (плоский)
Python
my_list = [[1], [2, 3], [4, 5, 6]]
# представление списков
flat_list_1 = [n for sub in my_list for n in sub]
print(flat_list_1) # [1, 2, 3, 4, 5, 6]
# встроенная функция `sum()`
flat_list_3 = sum(my_list, [])
print(flat_list_3)
# модуль `itertools`
import itertools
flat_list_2 = list(itertools.chain(*my_list))
print(flat_list_2)
JavaScript
const myList = [[1], [2, 3], [4, 5, 6]]
// встроенный метод `flat()`
const flatList1 = myList.flat()
console.log(flatList1) // [1, 2, 3, 4, 5, 6]
// встроенный метод `reduce()`
const flatList2 = myList.reduce((a, c) => {
c.forEach((i) => a.push(i))
return a
}, [])
console.log(flatList2)
// двойная итерация
// ключевое слово `const` делает иммутабельным
// значение самой переменной, а не массива
const flatList3 = []
for (const i of myList) {
for (const j of i) {
flatList3.push(j)
}
}
console.log(flatList3)
34. Копировать список (массив) (сделать его срез)
Python
# список (list)
my_list = [1, 2, 3, 4, 5]
# сигнатура
# `[start:end:step]`
# полная копия
print(my_list[:]) # [1, 2, 3, 4, 5]
# от второго до пятого элемента
print(my_list[1:5]) # [2, 3, 4]
# через 1 элемент, начиная с первого
print(my_list[::2]) # [1, 3, 5]
# извлекаем последний элемент
# это не относится к копированию
print(my_list[-1]) # 5
JavaScript
// массив (array)
const myList = [1, 2, 3, 4, 5]
// сигнатура
// `slice(start, end)`
// данный метод не такой мощный как питоновский аналог
// полная копия
console.log(myList.slice()) // [1, 2, 3, 4, 5]
// от второго до пятого
console.log(myList.slice(1, 5)) // [2, 3, 4]
// последний элемент - хак
console.log(...myList.slice(-1)) // 5
// последний элемент - не хак
console.log(myList[myList.length - 1])
// последний элемент - скоро, в `Chrome` уже работает
console.log(myList.at(-1)) // 5
35. Перебрать ключи и значения словаря (объекта)
Python
# словарь (dictionary)
dict = { 1: 'a', 2: 'b', 3: 'c' }
# ключи и значения
for key in dict:
print(key, dict[key])
'''
1 a
2 b
3 c
'''
# еще ключи и значения
for key, val in dict.items():
print(key, val)
# или
for key, val in dict.iteritems():
print(key, val)
# ключи
for key in dict.keys():
print(key)
# значения
for val in dict.values():
print(val)
JavaScript
// объект (object)
const obj = { 1: 'a', 2: 'b', 3: 'c' }
// ключи и значения
for (const key in obj) {
console.log(key, obj[key])
}
/*
1 a
2 b
3 c
*/
// еще ключи и значение
Object.entries(obj).forEach(([key, val]) => {
console.log(key, val)
})
// или
for (const [key, val] of Object.entries(obj)) {
console.log(key, val)
}
// ключи
Object.keys(obj).forEach((key) => {
console.log(key)
})
// значения
for (const val of Object.values(obj)) {
console.log(val)
}
36. Отсортировать словарь (объект) по ключам и значениям
Python
dict = { 1: 'b', 3: 'c', 2: 'a'}
# сортировка по значениям
sorted_dict_1 = {
key: val \
for key, val \
# key - критерий сортировки (в данном случае - значение)
in sorted(dict.items(), key = lambda i: i[1])
}
print(sorted_dict_1) # { 2: 'a', 1: 'b', 3: 'c' }
# сортировка по ключам
sorted_dict_2 = { key: val for key, val in sorted(dict.items(), key = lambda i: i[0]) }
print(sorted_dict_2) # { 1: 'b', 2: 'a', 3: 'c' }
JavaScript
// объект для примера пришлось изменить
// поскольку встроенный метод `Object.fromEntries()`
// выполняет автоматическую сортировку по ключам
// при создании объекта из вложенного массива
const obj = { a: '2', c: '1', b: '3' }
// логику сортировки лучше вынести в отдельную функцию
// по умолчанию функция выполняет сортировку по ключам
// благодаря параметру `i` со значением `1` по умолчанию
const sortObj = (obj, i = 0) =>
Object.fromEntries(
// `sort()` принимает функцию для сортировки
// `localeCompare()` сравнивает строки с учетом локали
Object.entries(obj).sort((a, b) => a.localeCompare(b))
)
// по ключам
const sortedObj1 = sortObj(obj)
console.log(sortedObj1) // { a: '2', b: '3', c: '1' }
// по значениям
const sortedObj2 = sortObj(obj, 1)
console.log(sortedObj2) // { c: '1', a: '2', b: '3' }
37. Определить, является ли список (массив) пустым
Python
my_list = []
# `not`
if not my_list:
print('Empty')
# + `len()`
if not len(my_list):
print('Empty')
# в `JS` так не получится
if my_list == []:
print('Empty')
JavaScript
const myList = []
// ! - [] -> 0 -> false + ! - false -> true
if (!!myList) {
console.log('Empty')
}
// ! - 0 -> false -> true
if (!myList.length) {
console.log('Empty')
}
// самый очевидный и надежный способ
// или `myList.length === 0`
if (myList.length < 1) {
console.log('Empty')
}
38. Объединить два списка (массива) в один
Python
list_1 = ['a', 'b']
list_2 = list(range(3, 5))
list_2.append('a')
# в `Python` списки можно конкатенировать путем сложения
joined_1 = list_1 + list_2
print(joined_1) # ['a', 'b', 3, 4, 'a']
# распаковка
joined_2 = [*list_1, *list_2]
print(joined_2)
# исключение дубликатов
joined_uniq = list(set(joined_1))
print(joined_uniq) # [3, 'b', 'a', 4]
# модификация списка посредством его расширения
list_2.extend(list_1)
print(list_2) # [3, 4, 'a', 'a', 'b']
JavaScript
const list1 = ['a', 'b']
// еще один встроенный метод для создания массивов
const list2 = Array.of(3, 4)
list2.push('a')
// распаковка
const joined1 = [...list1, ...list2]
console.log(joined1) // ['a', 'b', 3, 4, 'a']
// объединение
const joined2 = list2.concat(list1)
console.log(joined2) // [3, 4, 'a', 'a', 'b']
// исключение дубликатов
// набор (set) сразу преобразуется в обычный массив
const joinedUniq = [...new Set(joined1)]
console.log(joinedUniq) // ['a', 'b', 3, 4]
// модификация массива путем его расширения
list2.splice(-1, 0, ...list1)
console.log(list2) // [3, 4, 'a', 'b', 'a']
39. Извлечь подстроку из строки
Python
my_str = 'I like Python'
# по аналогии со списком
substr = my_str[2:6]
print(substr) # like
JavaScript
const myStr = 'I like JavaScript'
// по аналогии с массивом
const subStr1 = myStr.slice(2, 6)
console.log(subStr1) // like
// специальные встроенные методы
// deprecated
const subStr2 = myStr.substr(2, 5)
console.log(subStr2) // like
const subStr3 = myStr.substring(2, 6)
console.log(subStr3) // like
// разница между методами `substr()` и `substring()`
// состоит в том, включается ли последний элемент в подстроку
40. Функция для получения случайного элемента массива
Python
import random
# import secrets
def get_random_item(list):
if not list:
return 'Empty'
else:
return random.choice(list) # secrets.choice(list)
print(get_random_item(['a', 3, 'c', 1, 'b'])) # 3
JavaScript
// функция для получения случайного целого числа
const getRandomInt = (min, max) => ~~(min + Math.random() * (max - min + 1))
// функция для получения случайного элемента
const getRandomItem = (arr) => arr[getRandomInt(0, arr.length - 1)]
console.log(getRandomItem(['a', 3, 'c', 1, 'b'])) // 'b'
41. Определить количество вхождений элемента в массиве
Python
my_list = ['a', 1, 1, 'a', 2, 'b', 'a']
# `count()`
a_count = my_list.count('a')
print(a_count) # 3
# это также работает для строк
my_str = 'Hello world'
l_count = my_str.count('l')
print(l_count) # 3
JavaScript
const myList = ['a', 1, 1, 'a', 2, 'b', 'a']
const myStr = 'Hello world'
// фильтрация и длина массива
const a_count = myList.filter((i) => i === 'a').length
console.log(a_count) // 3
// преобразуем строку в массив
const l_count = [...myStr].filter((i) => i === 'l').length
console.log(l_count) // 3
42. Объединить два списка (массива) в словарь (объект)
Python
indexes = [0, 1, 2]
languages = ['JavaScript', 'Python', 'PHP']
# `zip()` & `dict()`
my_dict_1 = dict(zip(indexes, languages))
print(my_dict_1) # { 0: 'JavaScript', 1: 'Python', 2: 'PHP' }
# `zip()` и представление списков
my_dict_2 = { k: v for k, v in zip(indexes, languages) }
print(my_dict_2)
JavaScript
const indexes = [0, 1, 2]
const languages = ['JavaScript', 'Python', 'PHP']
// цикл
const obj1 = {}
// нам нужен не только элемент, но и его индекс
// потому что элементы первого массива не всегда будут совпадать с индексами
for (const i in indexes) {
obj1[indexes] = languages
}
console.log(obj1) // { 0: 'JavaScript', 1: 'Python', 2: 'PHP' }
// `reduce()`
const obj2 = indexes.reduce((a, c, i) => {
// `c` - текущий элемент
// `i` - его индекс
a[c] = languages
return a
}, {})
console.log(obj2)
43. Удалить лишние пробелы из строки с помощью регулярного выражения
Python
import re
str_with_spaces = 'some string with many spaces '
# заменяем 2 и более пробела на один
# `sub(regexp, replacement, string)`
str_without_spaces = re.sub(r'\s\s+', ' ', str_with_spaces)
print(str_without_spaces) # some string with many spaces
JavaScript
const strWithSpaces = 'some string with many spaces '
// заменяем 2 и более пробела на один
// `replace(substring | regexp, replacement)`
const strWithoutSpaces = strWithSpaces.replace(/\s\s+/g, ' ')
console.log(strWithoutSpaces) // some string with many spaces
44. Создать перечисления (enum)
Python
from enum import Enum
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 1
print(Color.RED) # Color.RED
print(Color.GREEN.name) # GREEN
print(Color.BLUE.value) # 3
В JS не существует такого типа данных, как перечисление, но его можно сымитировать, "заморозив" объект:
JavaScript
const Color = Object.freeze({
RED: 1,
GREEN: 2,
BLUE: 3
})
// value
console.log(Color.RED) // 1
45. Функция для определения анаграмм
Два слова являются анаграммами, если состоят из одинаковых букв. Например, анаграммами являются слова "binary" и "brainy", или "раздвоение" и "дозревание".
Python
def is_anagrams(x, y):
# приводим слова к нижнему регистру
x = x.lower()
y = y.lower()
if (len(x) == len):
# и сортируем их
sorted_1 = sorted(x)
sorted_2 = sorted
if (sorted_1 == sorted_2):
return True
else:
return False
else:
return False
word_1 = 'Binary'
word_2 = 'brainy'
print(is_anagrams(word_1, word_2)) # True
JavaScript
function isAnagrams(x, y) {
x = x.toLowerCase()
y = y.toLowerCase()
if (x.length === y.length) {
sorted_x = x.split('').sort().join('')
sorted_y = y.split('').sort().join('')
if (sorted_x === sorted_y) {
return true
}
return false
}
return false
}
const word1 = 'Раздвоение'
const word2 = 'дозревание'
console.log(isAnagrams(word1, word2)) // true
Обратите внимание: при сравнении строк, состоящих из нескольких слов, необходимо также удалять из них все пробелы.
46. "Капитализировать" строку
Классика.
Python
my_str = 'hello'
# `upper()` + slice
cap_str_1 = my_str[0].upper() + my_str[1:]
print(cap_str_1) # Hello
# `capitilize()`
cap_str_2 = my_str.capitalize()
В JS отсутствует встроенный метод для капитализации строки.
JavaScript
const str = 'hello'
const capStr1 = str[0].toUpperCase() + str.slice(1)
console.log(capStr1) // Hello
// показать всем, что ты крут
// деструктуризация и шаблонные литералы
const capitilize = ([first, ...rest]) =>
`${first.toUpperCase()}${rest.join('')}`
const capStr2 = capitilize(str)
console.log(capStr2)
47. Функция для определения всех вариантов строки
Python
# рекурсивно
def get_permutations(s, p = [], i = 0):
if i == len(s):
p.append(''.join(s))
for j in range(i, len(s)):
words = [c for c in s]
words, words[j] = words[j], words
get_permutations(words, p, i + 1)
return p
print(get_permutations('qux'))
# ['qux', 'qxu', 'uqx', 'uxq', 'xuq', 'xqu']
# `itertools`
from itertools import permutations
per = [''.join(p) for p in permutations('baz')]
print(per) # ['baz', 'bza', 'abz', 'azb', 'zba', 'zab']
JavaScript
function getPermutations(str) {
if (str.length < 2) {
return str.length === 2 ? [str, str[1] + str[0]] : [str]
}
return str
.split('')
.reduce(
(a, c, i) =>
a.concat(
getPermutations(str.slice(0, i) + str.slice(i + 1)).map((v) => c + v)
),
[]
)
}
console.log(getPermutations('qux'))
// ['qux', 'qxu', 'uqx', 'uxq', 'xqu', 'xuq']
48. Создание счетчика (таймера)
Python
import time
def timer(time_in_sec):
while time_in_sec:
m, s = divmod(time_in_sec, 60)
formated = f'{m:02d}:{s:02d}'
print(formated, end = '\r')
time.sleep(1)
time_in_sec -= 1
timer(5)
JavaScript
function timer(timeInSec) {
const timerId = setInterval(() => {
let m = ~~(timeInSec / 60)
let s = timeInSec - m * 60
if (m < 10) m = '0' + m
if (s < 10) s = '0' + s
console.log(`${m}:${s}`)
timeInSec -= 1
if (timeInSec < 0) {
clearInterval(timerId)
}
}, 1000)
}
timer(5)
49. Создание вложенной директории
Пусть 2 последних задачки будут посвящены бэку.
Python
import os
# абсолютный путь к текущей директории
__dirname__ = os.path.abspath(os.getcwd())
# небезопасно: при наличии создаваемой директории будет выброшено исключение
try:
os.makedirs(f'{__dirname__}/parent/child/nested')
except FileExistsError:
print('Exists')
import distutils.dir_util
# безопасно
distutils.dir_util.mkpath(f'{__dirname__}/some/dir')
JavaScript
import { dirname } from 'path'
import { fileURLToPath } from 'url'
import { promises as fs } from 'fs'
// абсолютный путь к текущей директории
const __dirname = dirname(fileURLToPath(import.meta.url))
// безопасно
// для сравнения обработки исключений
try {
await fs.mkdir(`${__dirname}/parent/child/nested`, { recursive: true })
} catch (e) {
console.error(e.message || e)
}
Обратите внимание: приведенный код должен запускаться с помощью команды node filename. При этом файл должен быть модулем, т.е. иметь расширение .mjs или же в ближайшем package.json должно содержаться поле type со значением module.
50. Получение названий файлов с расширением ".txt"
Предположим, что у нас имеется директория files с тремя файлами в формате TXT. Как нам получить названия этих файлов?
Python
import glob, os
__dirname__ = os.path.abspath(os.getcwd()) + '/files'
def get_filenames(ext):
filenames = []
# читаем содержимое директории `files`
os.chdir(__dirname__)
# если файл имеет указанное расширение
for filename in glob.glob(f'*.{ext}'):
# добавляем его в список
filenames.append(filename)
# возвращаем список
return filenames
print(get_filenames('txt'))
# ['baz.txt', 'foo.txt', 'bar.txt']
JavaScript
import { dirname } from 'path'
import { fileURLToPath } from 'url'
import { promises as fs } from 'fs'
const __dirname = dirname(fileURLToPath(import.meta.url))
async function getFilenames(ext) {
const result = []
// читаем содержимое директории `files`
const filenames = await fs.readdir(`${__dirname}/files`)
for (const filename of filenames) {
// если файл имеет указанное расширение
if (filename.includes(`.${ext}`)) {
// добавляем его в массив
result.push(filename)
}
}
return result
}
// функция возвращает промис
getFilenames('txt').then(console.log)
// [ 'bar.txt', 'baz.txt', 'foo.txt' ]
Фух… это было утомительно, но, вместе с тем, невероятно увлекательно, не правда ли?
Как видите, синтаксические конструкции и основной функционал JavaScript и Python являются очень похожими, а во многом даже идентичными (без учета некоторых незначительных отличий), что при необходимости позволяет с относительной легкостью перейти с одного языка на другой.
Вопрос в том, имеется ли необходимость в такой "миграции"?
Обратите внимание: дальше я выскажу собственное мнение с позиции веб-разработчика.
Существенное преимущество JavaScript заключается в том, что он не нуждается в интерпретаторе, т.е. код на JS выполняется браузером напрямую. Это очень сильно облегчает разработку веб-приложений.
Если мы говорим о REST API, то реализовать его на Express, например, намного проще, чем на Django или FastAPI, хотя последний синтаксически схож с сочетанием Express и TypeORM или Prisma (во многом благодаря широкому использованию декораторов).
С другой стороны, если мы говорим о реализации, скажем так, продвинутого сервера, то благодаря огромному количеству, в том числе, встроенных модулей, Python имеет некоторые преимущества перед Node.js.
Есть мнение, что у Python имеются некоторые проблемы с асинхронностью — у меня не было возможности в этом убедиться.
В свою очередь, в Node.js в последнее время царит некоторая неразбериха за счет одновременного существования двух разных подходов к разработке: одного, основанного на колбеках, который считается устаревшим, и другого, основанного на промисах и async/await, который требует дополнительных усилий по настройке окружения и не в полной мере заменяет первый подход.
Благодарю за внимание и хорошего дня!
Решил 50 задач и ответил на вопрос — Python или JavaScript?
Привет, друзья! Я — JavaScript-разработчик. Код пишу в основном на React (иногда на Vue), немного на TypeScript, немного на Node, немного знаю SQL, но... со мной работает много людей, которые...
habr.com