В данной статье мы затронем основы Python. Мы все ближе и ближе к цели, в общем, скоро приступим к работе с основными библиотеками для Data Science и будем использовать TensorFlow (для написания и развертывания нейросетей, тобишь Deep Learning).

Установка


Python можно скачать с python.org. Однако если он еще не установлен, то вместо
него рекомендую дистрибутивный пакет Anaconda, который уже включает в себя большинство библиотек, необходимых для работы в области науки о данных.

Если вы не используете дистрибутив Anaconda, то не забудьте установить менеджер пакетов pip, позволяющий легко устанавливать сторонние пакеты, поскольку некоторые из них нам понадобятся. Стоит также установить намного более удобную для работы интерактивную оболочку IPython. Следует учитывать, что дистрибутив Anaconda идет вместе с pip и IPython.

Пробельные символы


Во многих языках программирования для разграничения блоков кода используются
фигурные скобки. В Python используются отступы:

# пример отступов во вложенных циклах for
for i in [ 1, 2, 3, 4, 5] :
print (i) # первая строка в блоке for i
for j in (1, 2, З, 4, 5 ] :
print ( j ) # первая строка в блоке for j
print (i + j) # последняя строка в блоке for j
print (i) # последняя строка в блоке for i
print ( "циклы закончились ")

Это делает код легко читаемым, но в то же время заставляет следить за форматированием. Пробел внутри круглых и квадратных скобок игнорируется, что облегчает написание многословных выражений:

# пример многословного выражения
long_winded_computation = (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 +
11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20) 

и легко читаемого кода:
# список списков
list_of_lists = [ [ 1 , 2, 3 ) , [4, 5, 6 ] , [ 7 , 8, 9 ] ]
# такой список списков легче читается
easy_to_read_list_of_lists = [1, 2, 3 ) ,
                             [4, 5, 6 ) ,
                             [7, 8, 9 ) ] 

Для продолжения оператора на следующей строке используется обратная косая черта, впрочем, такая запись будет применяться редко:

two_plus_three = 2 + 3

В следствие форматирования кода пробельными символами возникают трудности при копировании и вставке кода в оболочку Python. Например, попытка скопировать следующий код:

for i in [ 1, 2, 3, 4, 5] :
# обратите внимание на пустую строку
print (1)

в стандартную оболочку Python вызовет ошибку:

# Ошибка нарушения отступа : ожидается блок с отступом
IndentationError : expected an indented blосk

потому что для интерпретатора пустая строка свидетельствует об окончании блока кода с циклом for.

Оболочка IPython располагает «волшебной» функцией %paste, которая правильно вставляет все то, что находится в буфере обмена, включая пробельные символы.

Модули (Импортирование библиотек)


Некоторые библиотеки среды программирования на основе Python не загружаются по умолчанию. Для того чтобы эти инструменты можно было использовать, необходимо импортировать модули, которые их содержат.

Один из подходов заключается в том, чтобы просто импортировать сам модуль:

import re
my_regex = re.compile ("[0-9]+",re.I)

Здесь re — это название модуля, содержащего функции и константы для' работы с регулярными выражениями. Импортировав таким способом весь модуль, можно обращаться к функциям, предваряя их префиксом re.

Если в коде переменная с именем re уже есть, то можно воспользоваться псевдонимом модуля:

import re as regex
my_regex = regex.compile("[0-9)+",regex.I)

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

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

import matplotlib.pyplot as plt

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

from collections import defaultdict , Counter
lookup = defaultdict(int)
my_counter = Counter() 

Функции


Функция — это правило, принимающее ноль или несколько входящих аргументов и возвращающее соответствующий результат. В Python функции обычно определяются при помощи оператора def:

def double(х) :
"""здесь, когда нужно, размещают
многострочный документирующий комментарий docstring,
который поясняет, что именно функция вычисляет.
Например, данная функция умножает входящее значение на 2"""
return х * 2

Функции в Python рассматриваются как объекты первого класса. Это означает, что их можно присваивать переменным и передавать в другие функции так же, как любые другие аргументы:

# применить функцию f к единице
def apply_to_one(f):
'""'вызывает функцию f с единицей в качестве аргумента """
return f(1)
my _ double = double # ссылка на ранее определенную функцию
х = apply_to_one(my_double) # = 2

Кроме того, можно легко создавать короткие анонимные функции или лямбда выражения:

у = apply_to_one(lambda х: х + 4) # = 5

Лямбда-выражения можно присваивать переменным. Однако рекомендуют пользоваться оператором def:

another double = lаmbdа х: 2 * х # так не делать
def another_double (x) : return 2 * х # лучше так

Параметрам функции, помимо этого, можно передавать аргументы по умолчанию, которые следует указывать только тогда, когда ожидается значение, отличающееся от значения по умолчанию:

def my_print (message="мoe сообщение по умолчанию" ):
print (message )
my_print ( "пpивeт") # напечатает 'привет'
my_print () # напечатает 'мое сообщение по умолчанию'

Иногда целесообразно указывать аргументы по имени:

# функция вычитания
def subtract ( a=0, Ь=0 ) :
return а - b
subtract (10, 5)# возвращает 5
subtract (0, 5)# возвращает -5
subtract (b=5 )# то же, что и в предыдущем примере

В дальнейшем функции будут использоваться очень часто.

Строки


Символьные строки (или последовательности символов) с обеих сторон ограничиваются одинарными или двойными кавычками (они должны совпадать):

single_quoted_string = ' наука о данных ' # одинарные
double_quoted_string = "наука о данных" # двойные

Обратная косая черта используется для кодирования специальных символов. Например:

tab_string = "\t" # обозначает символ табуляции
len (tab_string)# = 1

Если требуется непосредственно сама обратная косая черта, которая встречается
в именах каталогов в операционной системе Windows, то при помощи r '"' можно создать неформатированную строку:

not_tab_string = r"\t" # обозначает символы ' \ ' и ' t '
len (not_tab_string) # = 2

Многострочные блоки текста создаются при помощи тройных одинарных (или
двойных) кавычек:

multi_line_string = """Это первая строка .
это вторая строка
а это третья строка """

Исключения


Когда что-то идет не так, Python вызывает исключение. Необработанные исключения приводят к непредвиденной остановке программы. Исключения обрабатываются при помощи операторов try и except:

try:
print (0 / 0)
except ZeroDivisionError :
рrint ( "нельзя делить на ноль ")

Хотя во многих языках программирования использование исключений считается плохим стилем программирования, в Python нет ничего страшного, если он используется с целью сделать код чище, и мы будем иногда поступать именно так.

Списки


Наверное, наиважнейшей структурой данных в Python является список. Это просто упорядоченная совокупность (или коллекция), похожая на массив в других языках программирования, но с дополнительными функциональными возможностями.

integer_list = [1, 2, З] # список целых чисел
heterogeneous_list = ["строка", 0.1 , True] # разнородный список
list_of_lists = [integer_list, heterogeneous_list, [] ] # список списков

list_length = len(integer_list) #длина списка = 3
list_sum = sum(integer_list)#сумма значений в списке = 6

Устанавливать значение и получать доступ к n-му элементу списка можно при помощи квадратных скобок:

х = list(range (10)) # задает список {0, 1 , . . . , 9]
zero = х [0] # = 0 , списки нуль-индексные, т. е . индекс 1-го элемента = 0
one = x [1] # = 1
nine = х [-1] # = 9, по-питоновски взять последний элемент
eight = х [-2] # = 8, по-питоновски взять предпоследний элемент
х [0] = -1 # теперь х = { - 1 , 1 , 2, 3, . . . , 9]

Помимо этого, квадратные скобки применяются для «нарезки» списков:

first_three = х[:З] # первые три = [-1 , 1, 2] 
three_to_end = х[3:] #с третьего до конца = {3, 4, ... , 9] 
one_to_four = х[1:5] # с первого по четвертый = {1 , 2, 3, 4] 
last_three = х[-3:] # последние три = { 7, 8, 9] 
without_first_and_last = x[1:-1] # без первого и последнего = {1 , 2, ... , 8] 
сору_ of _х = х[:] # копия списка х= [ -1, 1, 2, ... , 91

В Python имеется оператор ln, который проверяет принадлежность элемента списку:

1 ln [1, 2, 3] #True
0 ln [1, 2, 3] #False

Проверка заключается в поочередном просмотре всех элементов, поэтому пользоваться им стоит только тогда, когда точно известно, что список небольшой или неважно, сколько времени уйдет на проверку.

Списки легко сцеплять друг с другом:

х = [1, 2, 3]
х. extend ( [ 4, 5, 6] ) # теперь х = {1, 2, 3, 4, 5, 6}

Если нужно оставить список х без изменений, то можно воспользоваться сложением списков:

х = [1, 2, 3]
у = х + [4, 5, 6] #у= (1, 2, 3, 4, 5, 6] ; х не изменился

Обычно к спискам добавляют по одному элементу за одну операцию:

х = [1, 2, 3]
x.append (0)# теперь х = [1,2,3,0]
у= х [-1] # = 0
z = len (x)# = 4

Нередко бывает удобно распаковать список, если известно, сколько элементов в нем содержится:

х, у = [1, 2] # теперь х = 1, у = 2

Если с обеих сторон выражения число элементов не одинаково, то будет выдано сообщение об ошибке ValueError.

Для отбрасываемого значения обычно используется символ подчеркивания:

_, у = [1, 2] # теперь у == 2, первый элемент не нужен 

Кортежи


Кортежи — это неизменяемые (или иммутабельные) двоюродные братья списков.

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

my_list = [1, 2] # задать список
my_tuple = (1, 2) # задать кортеж
other_tuple = 3, 4 # еще один кортеж
my_list [1] = 3 # теперь my_list = [1 , 3]

try:
my_tuple [1] = 3
except ТypeError :
print ( "кортеж изменять нель зя" )

Кортежи обеспечивают удобный способ для возвращения из функций нескольких значений:

# функция возвращает сумму и произведение двух параметров
def sum_and_product (x, у ) :
return (х + у) , (х * у)
sp = sum_and_product (2, 3) # = (5, 6)
s, р = sum_and_product (S, 10) # s = 15, р = 50 

Кортежи (и списки) также используются во множественном присваивании:

х, у = 1, 2 # теперь х = 1, у = 2
х, у = у, х # обмен переменными по-питоновски; теперь х = 2, у = 1 

Словари


Словарь или ассоциативный список — это еще одна основная структура данных.

В нем значения связаны с ключами, что позволяет быстро извлекать значение, соответствующее конкретному ключу:

empty_dict = {} # задать словарь по-питоновски
empty_dict2 = dict () # не совсем по-питоновски
grades = { "Grigoriy" : 80, "Tim" : 95 } # литерал словаря (оценки за экзамены)

Доступ к значению по ключу можно получить при помощи квадратных скобок:

rigory_aleksee =  grades[ "Grigoriy"] # = 80

При попытке запросить значение, которое в словаре отсутствует, будет выдано сообщение об ошибке KeyError:

try:
kates_grade = grades [ "Kate "]
except КeyError:
рrint ( "оценки для Кэйт отсутствуют ! " )

Проверить наличие ключа можно при помощи оператора in:

grigoriy_has_grade = "Grigoriy" in grades #true
kate_has_grade = "Kate" in grades #false

Словари имеют метод get(), который при поиске отсутствующего ключа вместо вызова исключения возвращает значение по умолчанию:

grigoriy_grade = grades. get ( "Grigoriy ", 0)  # =80
kates_grade = grades.get ("Kate" , 0) # = 0 
no_ones_grade = grades.get ( "No One" ) # значение по умолчанию = None

Присваивание значения по ключу выполняется при помощи тех же квадратных скобок:

grades [ "Tim" ] = 99 # заменяет старое значение
grades [ "Kate"] = 100 # добавляет третью запись
num_students = len(grades) # = 3

Словари часто используются в качестве простого способа представить структурные
данные:

tweet = {
"user" : " grinaleks",
"text" : "Наука о данных - потрясающая тема",
" retweet_count" : 100,
"hashtags " : [ "# data", " #science", " #datascience " , " #awesome", "#yolo" ] }

Помимо поиска отдельных ключей можно обратиться ко всем сразу:

tweet_keys = tweet.keys() # список ключей
tweet_values = tweet.values() # список значений
tweet_items = tweet.items() # список кортежей (ключ, значение)

"user" in tweet_keys # True, но использует медленное in списка
"user" in tweet # по-питоновски, использует быстрое in словаря
"grinaleks" in tweet_values # True

Ключи должны быть неизменяемыми; в частности, в качестве ключей нельзя использовать списки. Если нужен составной ключ, то лучше воспользоваться кортежем или же найти способ, как преобразовать ключ в строку.

Словарь defaultdict


Пусть в документе необходимо подсчитать слова. Очевидным решением задачи является создание словаря, в котором ключи — это слова, а значения — частотности слов (или количества вхождений слов в текст). Во время проверки слов в случае, если текущее слово уже есть в словаре, то его частотность увеличивается, а если отсутствует, то оно добавляется в словарь:

# частотности слов
word_ counts = { }
document = { } # некий документ; здесь он пустой
for word in document :
if word in word counts:
word_counts [word] += 1
else :
word_counts [word] = 1

Кроме этого, можно воспользоваться nриемом под названием «лучше просить прощения, чем разрешения» и перехватывать ошибку при попытке обратиться к отсутствующему ключу:

word_ counts = { }
for word in document :
try:
word_counts [word] += 1
except КeyError :
word_counts [word] = 1

Третий прием — использовать метод get(), который изящно выходит из ситуации с отсутствующими ключами:

word_counts = { }
for word in document :
previous_count = word_counts.get (word, 0)
word_counts [word] = previous_count + 1

Все перечисленные приемы немного громоздкие, и по этой причине целесообразно использовать словарь defaultdict (который еще называют словарем со: значением по умолчанию). Он похож на обычный словарь за исключением одной особенности — при попытке обратиться к ключу, которого в нем нет, он сперва добавляет для него значение, используя функцию без аргументов, которая предоставляется при его создании. Чтобы воспользоваться словарями defaultdict, их необходимо импортировать из модуля collections:

from collections import defaultdict

word_counts = defaultdict(int) # int () возвращает 0
for word in document :
word_counts[word] += 1

Кроме того, использование словарей defaultdict имеет практическую пользу во время работы со списками, словарями и даже с пользовательскими функциями:

dd_list = defaultdict (list)# list () возвращает пустой список
dd_list [2].append (l) # теперь dd_list содержит (2: {1] }
dd_dict = defaultdict (dict ) # dict () возвращает пустой словарь dict
dd_dict ["Grigoriy"] [ "City" ] = "Seattle" # { "Grigoriy" : { "City" : Seattle"}
dd_pair = defaultdict (lambda: [0,0] )
dd_pair [2][1] = 1 # теперь dd_pair содержит (2 : {0,1] }

Эти возможности понадобятся, когда словари будут использоваться для «сбора»
результатов по некоторому ключу и когда необходимо избежать повторяющихся
проверок на присутствие ключа в словаре.

Словарь Counter


Подкласс словарей counter трансформирует последовательность значений в похожий на словарь defaultdict(int) объект, где ключам поставлены в соответствие частотности или, выражаясь более точно, ключи отображаются (map) в частотности.

Он в основном будет применяться при создании гистограмм:

from collections import Counter
с = Counter([0,1,2,0]) # в результате с = { 0 : 2, 1 : 1, 2 : 1 }

Его функционал позволяет достаточно легко решить задачу подсчета частотностей слов:

# лучший вариант подсчета частотностей слов
word_counts = Counter (document)

Словарь counter располагает методом most_common( ), который нередко бывает полезен:

# напечатать 10 наиболее встречаемых слов и их частотность (встречаемость)
for word, count in word_counts.most_common(10) :
print (word, count ) 

Множества


Структура данных set или множество представляет собой совокупность неупорядоченных элементов без повторов:

s = set ()# задать пустое множество
s.add (1) # теперь s = { 1 }
s.add (2) # теперь s = { 1, 2 }
s.add (2) # s как и прежде = { 1, 2 }
х = len (s) # = 2
у = 2 in s # = True
z = 3 in s # = False

Множества будут использоваться по двум причинам. Во-первых, операция in на множествах очень быстрая. Если необходимо проверить большую совокупность элементов на принадлежность некоторой последовательности, то структура данных set подходит для этого лучше, чем список:

# список стоп-слов
stopwords_list = [ "a", "an" , "at "] + hundreds_of_other_words + [ "yet ", " you"]
" zip" in stopwords_list # False, но проверяется каждый элемент
# множество стоп-слов
stopwords_set = set(stopwords_list)
" zip" in stopwords_set # очень быстрая проверка

Вторая причина — получение уникальных элементов в наборе данных:

item_list = [1, 2, 3, 1, 2, 3] # список
num_items = len( item_list) # количество = 6
item_set = set(item_list) # вернет множество (1, 2, 3}
num_distinct_items = len(item_set) # число недублирующихся = 3
distinct_item_list = list(item_set) # назад в список = [1,2,3]

Множества будут применяться намного реже словарей и списков.

Управляющие конструкции


Как и в большинстве других языков программирования, действия можно выполнять по условию, применяя оператор if:

if 1 > 2:
message "если 1 была бы больше 2 . . . "
elif 1 > 3:
message "elif означает 'else if '"
else:
message = " когда все предыдущие условия не выполняются, используется else "

Кроме того, можно воспользоваться однострочным трехместным оператором if-then-else, который будет иногда использоваться в дальнейшем:

parity = "четное" if х % 2 === О else "нечетное "

В Python имеется цикл whlle:

х = 0
while х < 10:
print (x, "меньше 10")
х += 1

Однако чаще будет использоваться цикл for совместно с оператором in:

for х in range (lO) :
print (x, "меньше 10" )
51

Если требуется более сложная логика управления циклом, то можно воспользоваться операторами

continue и break:
for х 1n range (10) :
1f х == 3:
continue # перейти сразу к следующей итерации
if х == 5:
break
print (x)
# выйти из цикла

В результате будет напечатано 0, 1, 2 и 4.

Истинность


Булевы переменные в Python работают так же, как и в большинстве других языков программирования лишь с одним исключением — они пишутся с заглавной буквы:

one_is_less_than_two = 1 < 2 #True
true_equals_false = True == False #False

Для обозначения несуществующего значения применяется специальный объект None, который соответствует значению null в других языках:

х = None
print (x == None )# напечатает True, но это не по-питоновски
print ( х is None ) # напечатает True по-питоновски 

В Python может использоваться любое значение там, где ожидается логический тип Boolean. Все следующие элементы имеют логическое значение False:

  • False; .
  • None;
  • set() (множество):
  • [] (пустой список);
  • {} (пустой словарь);

Практически все остальное рассматривается как True. Это позволяет легко применять операторы if для проверок на наличие пустых списков. пустых строк, пустых словарей и т. д. Иногда, правда, это приводит к труднораспознаваемым ошибкам, если не учитывать следующее:

s = some_function_that_returns_a_string () # возвращает строковое значение
if s:
first_char = s [0] # первый символ в строке
else:
first char = ""

Вот более простой способ сделать то же самое:

first_char = s and s [0] 
поскольку логический оператор and возвращает второе значение, в случае если первое истинное, и первое значение, в случае если оно ложное. Аналогичным образом, если х в следующем ниже выражении является либо числом, либо, возможно, None, то результат так или иначе будет числом:

safe х = х or 0 # безопасный способ

Встроенная функция all языка Python берет список и возвращает True только тогда, когда каждый элемент списка истинен, а встроенная функция any возвращает тrue, когда истинен хотя бы один элемент:

all ( [True, 1, { 3 }]) # True
all ( [True, 1, {}] ) # False, {} = ложное
any ( [ True, 1, {}]) # True, True = истинное
all ( [] ) # True, ложные элементы в списке отсутствуют
any ( [ ] ) # False, истинные элементы в списке отсутствуют 

Комментарии (96)


  1. andreymal
    04.05.2019 02:47
    +18

    Читать PEP-8, быстро!


    А отстутствие отступов в примерах сразу после заявлений о важности отступов — это пять. Пост хоть кто-нибудь вычитывал перед публикацией?


    1. Ktulhy
      04.05.2019 06:00
      +7

      Просьба на будущее всем "вводящим" в питон: пожалуйста, дорастите хотя бы до сеньора, а после этого начинайте учить других людей, тем более на такой большой площадке. От такого "обучения" людям только хуже, спасибо.


  1. Daddy_Cool
    04.05.2019 03:43
    -10

    Можно странный вопрос? Я знаю, что Питон популярный ЯП, но… зачем он нужен если есть Си/С++ на котором можно написать всё?
    Это некая концептуальная проблема для меня, я ставил Питон, поигрался и бросил не найдя применения.
    Можете привести примеры того, что легко-быстро-удобно делается на Питоне и тяжело и громоздко на Си?


    1. andreymal
      04.05.2019 03:58
      -6

      легко-быстро-удобно делается на Питоне

      Абсолютно всё.


      тяжело и громоздко на Си

      Абсолютно всё.


      Ручное управление памятью, постоянные выходы за пределы массива и соответствующие сегфолты, утечки памяти, наоборот double free, возня с указателями, забываемые проверки на null, #define true false — вы серьёзно считаете это всё удобным?


      1. Tanner
        04.05.2019 04:14
        +4

        Зато те задачи, где необходимо ручное управление памятью, очень удобно программировать на Си.


        1. andreymal
          04.05.2019 04:17
          -10

          Для «низкоуровневых» задач с недавних пор есть Rust, так что C/C++ теперь не подходят вообще ни для чего, кроме поддержки старого кода.)


          1. Tanner
            04.05.2019 04:20
            +1

            Ну, это уже отдельный вопрос. Хотя тоже имеет место быть.

            Можно странный вопрос? Я знаю, что Раст популярный ЯП, но… зачем он нужен если есть Си/С++ на котором можно написать всё?
            Это некая концептуальная проблема для меня, я ставил Раст, поигрался и бросил не найдя применения.
            Можете привести примеры того, что легко-быстро-удобно делается на Расте и тяжело и громоздко на Си?

            Ответите?


            1. andreymal
              04.05.2019 04:29
              -6

              Так то же самое:

              >Ручное управление памятью, постоянные выходы за пределы массива и соответствующие сегфолты, утечки памяти, наоборот double free, возня с указателями, забываемые проверки на null, #define true false — вы серьёзно считаете это всё удобным?

              И даже что-то из указанного вами ниже списка есть, но как непрофессионал от точного перечисления воздержусь. (Если спецы по Rust мимо пробегать будут, это пусть они расскажут)

              А вообще пост не про Си и не про Rust так-то, а мы тут оффтопим.)


          1. AlePil
            04.05.2019 09:10

            Вы с С/С++ перешли на Rust? И как вам после перехода?


            1. andreymal
              04.05.2019 12:41

              Лучше вы расскажите, как вам Heartbleed и ошибки в SMB?


              1. AlePil
                04.05.2019 13:13
                +2

                Вот тут я не понял при чем тут старая проблема связаная с отсутствием необходимой проверки границ в процедуре расширения RFC6520 для TLS/DTLS и тем более ошибки в SMB, написанном в т.ч. и на Python? Вы реально считаете, что ошибки имеются из-за C/C++ и только? На RAST пишется все без ошибок и работает безукоризненно? Мой вопрос был связан с Вашим высказыванием, что Rast уже заменил C/C++ и их можно забыть и, раз уж так категорично, я просто хотел узнать Ваше мнение о использовании этого языка, которое должно бы происходить от опыта работы с ним в реальных проектах.


                1. andreymal
                  04.05.2019 13:30

                  Вот тут я не понял при чем тут старая проблема связаная с отсутствием необходимой проверки границ

                  При том, что такие ошибки в C/C++ — обычное дело (блог PVS-Studio читаете?), и известная ошибка в SMB, найденная в 2017-м, была вовсе не в Python-коде.


                  На RAST пишется все без ошибок и работает безукоризненно?

                  Да. Если точнее, то в unsafe-коде накосячить таки можно, но его очень-очень мало, unsafe-код достаточно один раз тщательно проверить и вычитать, а весь остальной код будет автоматически безопасным. Многие программы можно написать вообще без unsafe-кода. В то время как в C/C++ весь код автоматически unsafe, и даже дисциплина не всегда помогает, и от подобных ошибок спасёт разве что PVS-Studio за много тысяч денег.


                  Rast уже заменил C/C++

                  Я такого не говорил. Rust в ближайшие десятки лет точно не заменит C/C++, потому что есть куча проектов, которые уже написаны на C/C++ и которые никто в здравом уме не будет переписывать на Rust. И да, в этих проектах постоянно находят ошибки, которые на Rust невозможны — список CVE в ядре Linux, думаю, сами нагуглите.


                  1. AlePil
                    04.05.2019 13:57

                    Как не говорили? А как трактовать фразу что для низкоуровневых задач есть Rust и C/C++ уже ни для чего не проходят?
                    Вообще, вы мне нравитесь. Мне вообще нравятся «фанаты» новых языков, которые сами на этих языках не пишут, и такие же фанаты всяких технологий, не понимающие как те технологии использовать и что у них под «капотом».
                    Идеальных. языков нет, и в ближайшее время не будет (даже естественных, кстати) и Rust тоже не идеален (вот например www.cvedetails.com/vulnerability-list/vendor_id-19029/product_id-48677/Rust-lang-Rust.html) и тоже вряд ли им будет. Если его не самовыпилят его создатели, раньше чем он вырастет из мвоих коротких штанишек, то он, конечно, займет свою нишу, может даже потеснит какой-то другой язык, но сегодня топить бездумно за Rust, указывая на ошибки кода, написанного на том же C++, это глупо. Обрастет Rust библиотеками и кодом, вот тогда и поговорим. Точнее поговорит уже новое поколение программистов, я уж точно буду на пенсии, в лучшем случае.


                    1. andreymal
                      04.05.2019 14:10

                      А как трактовать фразу что для низкоуровневых задач есть Rust и C/C++ уже ни для чего не проходят?

                      Если для вас это то же самое, что «уже заменил», то мне остаётся только посочувствовать вашей логике. То, что для низкоуровневых задач есть Rust, никак не отменяет того, что в том же линуксе бежать срочно заменять Си на Rust никто в здравом уме не будет.


                      вот например

                      Уязвимости в ядре и стандартной библиотеке возможны у любого языка программирования, так как где-то там внизу неизбежно есть unsafe-слой, без которого сделать что-либо просто невозможно. Тем не менее, баги и уязвимости в стандартной библиотеке выловят и исправят один раз, и всё на их базе будет безопасным, а в этих ваших C/C++ каждый проект нужно проверять индивидуально (сколько раз мне ещё про блог PVS-Studio нужно напомнить?). Так что это ваше «вот например» неуместно.


                      топить бездумно за Rust, указывая на ошибки кода, написанного на том же C++, это глупо.

                      Ошибки в коде почти каждого C++ проекта — вот что на самом деле глупо. Ошибки в стандартной библиотеке Rust найдут и исправят, а PVS-Studio на каждый существующий C++ проект никто накатывать не будет.


                      Точнее поговорит уже новое поколение программистов

                      Это новое поколение должно откуда-то взяться, поэтому говорить про Rust нужно уже сейчас. Чем я и занимаюсь. Мой опыт не имеет значения: есть много куда более опытных C++ программистов, переходящих на Rust и вполне довольных; думаю, без проблем нагуглите их блоги, если захотите. (Неосиляторы, которым не понравился спасающий от ошибок borrow checker, к сожалению, тоже есть и тоже гуглятся.)


                      1. AlePil
                        04.05.2019 15:23
                        +1

                        Так как Вы мне нравитесь все больше, таки отвечу.
                        Изучая естественные языки действительно очен важно на этих языках говорить и писать. Изучая ЯП, важно читать (код) и писать (код). Говоря о каком-то языке, особенно так, как делаете Вы, нужно не просто говорить опроблемах других языков, о которых вы знаете, судя по всему, из блога PVS-Studio и больше никак, а писать код. Да, писать чертов код, потому как просто вопеть о том, что все вокруг навоз, а вот это фича спасет мир, это непродуктивно. Хотите топить за Rust, так нет проблем, берете проблемный код на плюсах и показываете как круто переписать его на Rust. Или вообще небольшой проект. Только так, а не тыкая блогом PSV, в каждом абзаце, вы можете быть Евангелистом_Rast_По_Доброте_Душевной.
                        И потом, ошибки в коде каждого плюсового проекта, это так же нормально, как ошибки в коде каждого пайтон проекта или котлин проекта, так же как и джава проекта. Редко получается проект без ошибок. Очень хорошо то, что большинство ошибок сегодня кдается отловить раньше чем проект уйдет продакшен, но отловить их все — это утопия. Чем больше пишется на каком-то языке, чем больше проектов, тем больше ошибок находится. Это, опять же, нормально, потому как код пишут, пока по крайней мере, люди, а не роботы или ИИ.
                        Раз уж Ваш опыт, как Вы сами сказали, не имеет значения, то мой опыт, по крайней мере для меня, значение имеет. Когда я пишу код, то пишу на C/C++ и Python. Делаю это этак уже больше 20 лет. Около полугода назад я решил серьезно взглянуть на Rust. С первого взгляда язык мне понравился, хоть очень серьезно познакомиться с ним все еще не выходит по причине занятости. Что мне НЕ нравится, так это нездоровый хайп вокруг языка, начинающий иногда напоминать прошлогодний хайп по биткоину. Уже невозможно открыть материал по плюсам, что бы не увидеть толп хайперов-растоманов. Это говорит о незрелости сообщества и его юношеском максимализме. Но и это пройдет.


                        1. andreymal
                          04.05.2019 15:34
                          -1

                          проблемах других языков, о которых вы знаете, судя по всему, из блога PVS-Studio и больше никак

                          Этого более чем достаточно, чтобы всячески избегать C/C++. Я, по-вашему, должен закрывать глаза на лёгкую возможность допустить уязвимость по невнимательности? И вы, видимо, закрываете? Или вы надеетесь, что, имея 20 лет опыта, никогда не допустите мелкую опечатку по невнимательности, которая однажды случайно приведёт к CVE? Так тот же блог PVS-Studio наглядно демонстрирует, что это так не работает.


                          Хотите топить за Rust, так нет проблем, берете проблемный код на плюсах и показываете как круто переписать его на Rust.

                          На Хабре есть целый хаб про Rust — в том числе с переводами постов от Mozilla, которые переписывают Firefox на Rust и радуются, как всё прекрасно. Вперёд. Всё уже написано до меня. Я лишь напоминаю о существовании языка.


                          Редко получается проект без ошибок.

                          И на Rust логические ошибки или ошибки в unsafe-коде никто не отменял, да. Но вероятность допустить ошибку на Rust намного меньше, чем в том же C/C++. Раз вы уже взглянули на Rust, думаю, у меня нет необходимости читать лекции о том, как Rust защищает от ошибок. Опять же, есть хаб на Хабре, где всё уже рассказано до меня.


          1. Chuvi
            04.05.2019 13:30
            +2

            Мир, к сожалению, не ограничивается компьютерами с традиционными x86/AMD64 процессорами. Попробуйте что-то написать на расте, например, для процессора 1892вм7я, и сделать так, чтобы ваше творение заработало.


            1. andreymal
              04.05.2019 13:39

              К сожалению, вы правы. Уверен, со временем Rust повзрослеет и будет без проблем работать на любой микроволновке. Тем не менее, на тех же x86, arm и mips Rust работает уже сейчас.


              1. Chuvi
                04.05.2019 21:44

                Отлично. Завтра же скажу на работе, что нам нужно срочно переписывать все проекты на какой — то там раст. Думаю, руководство порадуется связанными с этим простоями.


                1. andreymal
                  04.05.2019 22:03
                  -1

                  Вы не в здравом уме и доводите всё до абсурда. С таким отношением проекты обречены независимо от языка программирования. Ни в одном своём комментарии я не предлагал бросать все дела и срочно переписывать всё на Rust.


      1. saipr
        04.05.2019 10:42
        -1

        Используйте tcl и все будет легко и удобно.


      1. MamontsevDS
        06.05.2019 16:04

        И сразу видно, ни у вас ни у комментатора выше программирование не является ни профессиональной деятельностью, ни хобби. И знакомы в с ним очень поверхностно.


        1. andreymal
          06.05.2019 16:13

          И сразу видно, что в гадание по аватарке комментариям вы не очень умеете. Я программирую на питоне десять лет, из них четыре зарабатываю, и даже на гитхабе у меня немного репозиториев валяется (в том числе на Rust и, внезапно, C++).


          Зато по вам сразу видно, что у вас программирование уж точно не является ни профессиональной деятельностью, ни хобби, иначе бы вы, имея хотя бы поверхностное представление об основах C++ и Python (ну и Rust заодно), понимали бы, что в моих комментариях всё написано абсолютно правильно и правдиво.


    1. Tanner
      04.05.2019 04:08
      +1

      Уорд Каннингем написал такое эссе: Key Language Feature. Оно даёт ответы на вопросы, подобные вашему.

      Кратко пробежимся по списку: higher order functions, lambda expressions, exception handling, resumable exceptions, closures, first-class types, causally reflective environment, introspection and reflection, modules, automatic type inference ? это всё есть в Python искаропки, но в C и C++ нужно писать много кода, чтобы реализовать все эти фичи.

      Мета-вопрос: почему вы этого не понимаете? Тоже есть ответ: Пол Грэм, Blub Paradox (по-русски).


      1. Daddy_Cool
        04.05.2019 12:33
        +1

        Да, там как раз очень понятно разложено ))). Спасибо!
        «когда он смотрит… вверх, он не осознает, что смотрит вверх. То, что он видит, — это просто „странные“ языки. Возможно, он считает их одинаковыми с Блабом по мощности, но со всяческими сложными штучками. Блаба для нашего программиста вполне достаточно, так как он думает на Блабе.»
        Я думаю на Си. )
        Кстати помнится вполне освоил Билдер ради создания интерфейсов, но в научной среде GUI редко нужны — отсюда и такое программирование.


        1. Tanner
          04.05.2019 13:00

          Рад был помочь.


      1. 0xd34df00d
        04.05.2019 15:43

        и C++

        Ага, и лямбд нет там, и исключений, и всего прочего.


        type inference

        Чтобы был type inference, нужно, чтобы были типы, а их в питоне нет («динамическая типизация» — оксюморон).


        Спасибо, но я лучше на плюсах без рефлекшона, чем на питоне без типов.


        1. roryorangepants
          04.05.2019 16:53

          а их в питоне нет

          Они есть и так, просто неявно. А с static type checking, который активно пропагандируется в последних версиях питона типы есть и явно.
          Плюс, если говорить об инфраструктуре numpy/pandas, например, то там ещё начинают играть роль сишные типы из numpy.


          1. 0xd34df00d
            04.05.2019 18:20

            Что значит «неявно»? Типы — это статически известные метки для тайпчекера. Их в классическом питоне нет.

            Если я правильно понимаю, то всякие там mypy больше похожи на подсказки для IDE/линтеров и этакие рантайм-проверки, что код соответствует типам. Да и с библиотеками и имеющимся кодом вопросы есть.


            1. roryorangepants
              04.05.2019 21:56

              Их в классическом питоне нет.

              Они есть. Без использования static type checking они есть у объектов, но не у переменных, а с использованием — они есть и у переменных тоже.


              1. 0xd34df00d
                04.05.2019 22:16

                Окей. Что вы называете типами?


            1. bano-notit
              04.05.2019 22:03

              > Типы — это статически известные метки для тайпчекера.

              В расте вообще можно написать только дефиницию функции и все типы внутри раст сам додумает. При этом у раста одна из самых сильных систем типов.

              Вы можете точно говорить, что вам не нравится в системе типов питона? (я, человек работавший с питоном и с его типами, по дефалту принимаю фразу «типов в питоне нет» за опечатку)


              1. 0xd34df00d
                04.05.2019 22:15

                В расте вообще можно написать только дефиницию функции и все типы внутри раст сам додумает. При этом у раста одна из самых сильных систем типов.

                Какое отношение явная/неявная типизация и глобальный вывод типов имеет к обсуждаемому разговору?


                У действительно сильных систем типов вывод типов, кстати, неразрешим (увы), так что додумывать тайпчекер будет долго. Но это такое.


                1. bano-notit
                  05.05.2019 11:45
                  +1

                  А можете привести пример такой сильной системы типов, в которой вывод неразрешим именно потому, что это математически не возможно, а не потому, что там просто не сделали такого?


                  Какое отношение явная/неявная типизация и глобальный вывод типов имеет к обсуждаемому разговору?

                  Типы — это статически известные метки для тайпчекера.

                  Статически известные это


                  String str = String.new()

                  ?


                  1. 0xd34df00d
                    05.05.2019 15:29

                    А можете привести пример такой сильной системы типов, в которой вывод неразрешим именно потому, что это математически не возможно, а не потому, что там просто не сделали такого?

                    System F как простейший практически полезный пример.


                    Статически известные это

                    Например.


                    Или если я в своем хаскеле напишу терм 1, то его тип будет Num a => a. Тоже статически известный тип.


                    Если вы упирали на необходимость явно писать String слева, то это совсем не обязательно.


        1. Tanner
          04.05.2019 21:51

          С каких это пор динамическая типизация ? это «нет типов»? Нет типов в ассемблерах, в BCPL. Почитайте хотя бы вики для приличия: “Python uses duck typing and has typed objects but untyped variable names… Despite being dynamically typed, Python is strongly typed…”.


          1. 0xd34df00d
            04.05.2019 22:14

            Давайте в разговоре о типизации ссылаться не на статью про питон в вики, а, например, на Types and Programming Languages.


            Тип — это именно статическая метка для статического тайпчекера, который статически (спасибо Тьюрингу) убеждается, что программа имеет смысл для некоторого определения смысла. И статический тайпчекер заведомо консервативен — для любого тайпчекера всегда будет существовать программа, которая имеет смысл, если стереть типы, но которая нетипизируема (снова спасибо Тьюрингу и проблеме останова). Последнее имеет интересные последствия по части наворачивания статических типизаций на изначально нетипизированные языки, но это другой разговор.


            Если у вас вместо этого в рантайме есть какой-то там код, который что-то проверяет, делает динамический диспатчинг на базе этого, скажем, и тому подобное, то это совсем другое.


            Иными словами, из питоновских «типов» типизация как из контрактов C++20 зависимые типы.


            1. Tanner
              04.05.2019 22:33
              +1

              Ну давайте, давайте ссылаться на эту книгу. Я её раньше не читал, но теперь вот с удовольствием открыл. Но что-то не могу я в ней найти такого утверждения, что именно статический тайпчекер делает язык типизированным. Наоборот, типизированный язык определяется как

              some attempt is made, either at compile time or at run-time, to check shape-consistency

              У Python с этим всё в порядке:

              >>> 1 + "a"
              Traceback (most recent call last):
              File "<stdin>", line 1, in <module>
              TypeError: unsupported operand type(s) for +: 'int' and 'str'

              Как вообще это получается, по-вашему: ошибка типа есть, а типов нет? Где тут логика?


              1. 0xd34df00d
                04.05.2019 22:40

                Так это именно проверки (и Пирс пишет это где-то, ЕМНИП, на второй странице первой главы, во введении, и там же и про статику), а не типы.


                Если я в коде С начну везде рядом с объектом (в смысле сишного стандарта) класть несколько байт с его идентификатором, и во всех операциях этот идентификатор проверять, то будет ли это динамической типизацией?


                PS Открыл сейчас книжку, и что-то не смог найти процитированный вами кусок. У меня читалка, правда, не умеет искать с разрывами строк, так что я мог тупо пропустить его. Где примерно ваша цитата?


                1. Tanner
                  04.05.2019 23:09

                  Вот более полная цитата:

                  1.1 What is a type system
                  A useful—though rough—distinction divides the world of programming languages into two parts:
                  • Untyped — programs simply execute flat out; there is no attempt to check “consistency of shapes”
                  • Typed — some attempt is made, either at compile time or at run-time, to check shape-consistency

                  Но это, в общем-то, частности. Я не понимаю вашей логики в целом. Если в Python нет типов, то как CPython отличает строку от числа? Что делает встроенная функция type?

                  Если в Python нет типов, значит, и классов там нет? Классы ? это ведь частный случай типизации. Или если класс сконструирован в рантайме, то он не считается классом?


                  1. 0xd34df00d
                    05.05.2019 04:46

                    Вот более полная цитата:

                    Хм, у меня, похоже, другой TAPL.


                    Загуглил полный текст в кавычках — да, другой. Если вам вдруг интересен не черновик, а полная книга, стукнитесь мне в личку.


                    Я не понимаю вашей логики в целом. Если в Python нет типов, то как CPython отличает строку от числа?

                    Рантайм-теги.


                    Что делает встроенная функция type?

                    Возвращает рантайм-тег.


                    Классы ? это ведь частный случай типизации.

                    Совсем необязательно. Можно взять словарь и назвать его классом, в конце концов. Некоторые языки так делают.


                    А логика у меня простая. Типы — это что-то, что позволяет дать какие-то гарантии корректности программы, не запуская её (какие именно — зависит от силы типизации). Если нужно запускать, то это ассерты, рантайм-проверки, ещё что-то, возможно, вставляемое компилятором (а почему нет?) или интерпретатором, но не более. Называть это типами — очень сильно размазывать смысл этого понятия.


    1. HerrDirektor
      04.05.2019 04:16
      +1

      Лет 20 назад я так же реагировал на взрывную популярность Delphi. Мол, зачем оно в принципе нужно, если есть C/C++?
      Однако через какое-то время пришлось признать, что очень многое в Delphi реализовано не в пример удобней (не обязательно лучше, именно удобней).
      Правда, Delphi сейчас где-то на задворках, а С++ по прежнему где-то в топе, но это к теме удобства не особо относится.
      Возможно, Питон постигнет та же участь, хех.
      Ну а пока имеем то, что имеем — многие вещи на Питоне пишутся сильно проще (быстрее, удобнее, итд...).


      1. alexs0ff
        04.05.2019 08:34

        del


    1. ittakir
      04.05.2019 08:50
      -5

      Python можно запустить хоть на чем, Windows, Linux, Raspberry Pi, роутер. Причем, все работает без переписывания, без возни с настройками. Просто ставишь сам Питон и запускаешь свою программу.
      А чтобы на всем этом собрать и запустить C++ программу, нужно обрести много гемороя с компиляторами, библиотеками.
      У Python есть Django/Flask для web-приложений. И запустить его опять же можно хоть где.
      Есть такие штуки как Amazon Lambda. Python там поддерживается, С++ нет.


      1. Kitsok
        04.05.2019 09:29

        Python можно запустить хоть на чем, Windows, Linux, Raspberry Pi, роутер.


        1. Kitsok
          04.05.2019 09:30
          +3

          Прошу прощения, рука дрогнула.
          После установки Питона на роутер, весьма вероятно, он перестанет маршрутизировать и начнет заниматься только выполнением вашей программы на Питоне.


          1. Dreyk
            04.05.2019 09:40
            -2

            если это нормальный роутер с хардверным управлением пакетами, то все будет нормально :)


            1. Kitsok
              04.05.2019 10:02

              Тогда надо начинать с "предположим, у нас есть бесконечное количество памяти, дискового пространства и вычислительных ядер".
              Реальность, увы, гораздо менее щедра.


          1. ittakir
            04.05.2019 10:36
            -1

            Допустим, такая была реальная задача: подключиться раз в 10 минут к сайту, сделать GET запрос, найти с помощью RegExp определенное число в коде страницы, сохранить это число в файл.
            Не думаю, что это хоть как-то затормозит роутер.
            Понятно, что ставить боевой web-сервер на тысячи пользователей на роутер не стоит даже и пытаться.


            1. Kitsok
              04.05.2019 10:50
              +2

              И ради этой задачи надо на роутер поставить Питон? Не статически скомпилированный бинарник из 100-строчной программы на С? Не luajit с необходимым количеством библиотек? В конце концов, не shell-скрипт, для которого на роутере уже все есть?


              1. ittakir
                04.05.2019 10:58
                -2

                А почему нет? Есть задача, есть платформа, работающая 24/7.


                1. Kitsok
                  04.05.2019 11:43
                  +1

                  А что туда qemu не поставить, и поверх нее Ubuntu с иксами?
                  Мне кажется, что единственным аргументом за установку Питона на роутер для решения этой конкретной задачи является умение решать эту задачу Питоном. В милом моему сердцу мире разработки для низкопроизводительных устройств с ограниченными ресурсами, принято подбирать решение, наиболее подходящее железу, и под эту задачу подбирать разработчика, а не наоборот. В мире больших серверов и ПО для массового обслуживания все наоборот, доля стоимости железа стремится к нулю, поэтому Питон с его порогом вхождения более чем востребован.


                  1. ittakir
                    04.05.2019 12:02
                    -1

                    Как я уже сказал, один и тот же код на Python будет работать одинаково, без переписывания и на роутере, и на VPSке, и под Windows в вашей любимой IDE.


                    1. Kitsok
                      04.05.2019 12:13
                      +1

                      Ну это во-первых не так, это приложение явно отъест существенно большую часть наличных ресурсов роутера, чем VPS, а во-вторых, как кроссплатформенностью копеечной задачи, решаемой, повторюсь, вовсе без установки дополнительного ПО на роутер, можно аргументировать установку Питона со всеми его модулями на роутер?
                      Это оставляя в стороне вопрос, что все эти модули придется скомпилировать с учётом имеющихся на роутере библиотек.


                  1. remzalp
                    05.05.2019 19:00

                    Микротик так умеет :)).
                    Позволяет в виртуальной машине запустить виртуальный роутер, который будет получать доступ к реальным портам.
                    Можно запихнуть OpenWRT + ТОР + гейши, настроить и радоваться :)


                    1. Kitsok
                      05.05.2019 19:12

                      Это мне напоминает сказку про скорняка и жадного богача. Запихнуть можно, работать будет соответственно имеющимся ресурсам.


      1. Tanner
        04.05.2019 10:38
        -1

        Windows лучше исключите из списка, не работает там Python по-нормальному. На этой платформе нет стандартного компилятора C, собрать сишный пакет для официального дистрибутива Python ? то ещё приключение, поэтому чаще приходится подставлять костылики: либо «зверь-сиди» с своими суррогатами вместо нормальных PyPI и Virtualenv (Anaconda, ActivePython), либо оверхед в виде MinGW.

        Конечно, Wheel-пакеты в своё время немного снизили накал страстей. Но, поскольку Microsoft ради Python за всю историю ни разу не пошевелил и пальцем (“Developers! Developers! Developers!”), для питонистов будет безопасней игнорировать эту платформу.


        1. remzalp
          05.05.2019 19:01

          Из 2019 года: благодаря wheel уже не так плохо.


      1. bano-notit
        04.05.2019 22:06
        +1

        Python можно запустить хоть на чем, Windows, Linux, Raspberry Pi, роутер. Причем, все работает без переписывания, без возни с настройками

        Ошибка. Обычный код аля "1+1" может работать везде, а вот код с библиотеками… Тут сначала нужно решить проблему с pip, который не всегда хорошо ставится. Потом решить проблему с либами, которые не всегда компилятся под винду. Ну и потом уже можно выдохнуть и вспомнить про версии самого питона...


    1. kaleman
      04.05.2019 11:12
      -3

      Он нужен тем, кто не может освоить С++
      В общем совершенно бесполезный язык.


    1. farcaller
      04.05.2019 11:21
      +3

      Для разнообразия отвечу серьезно.


      Питон идеален для быстрой аналитической работы. Скрутить rpc-клиент из генератора, выдернуть данные, разобрать в pandas, отрендерить график в mathplotlib, это все. Это классно. Это удобно (jupyter это вообще мечта). Далеко не факт что вы сможете сходу написать аналогичный по эффективности C/C++ код (numpy вылизан до безобразия по эффективности). Вам не надо искать как собрать какой-то пакет — вы берете и работаете.


      Да, по факту многие прототипы на python я потом переписываю на чем-то еще. На Go, на rust. Но питон позволяет поиграться с идеей уже сейчас и убедиться что она имеет право на жизнь.


      1. Daddy_Cool
        04.05.2019 13:26

        Спасибо! Надо предпринять вторую итерацию.


      1. 0xd34df00d
        04.05.2019 15:45

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


        1. roryorangepants
          04.05.2019 16:55
          +2

          Разве что человеку, который уже является Haskell-девелопером.
          И математикам из академии, переезжающим с Matlab, и разработчикам, влезающим в анализ данных из каких-то прикладных языков, Python тут будет удобнее.


          1. 0xd34df00d
            04.05.2019 18:21
            +1

            Эффективность от этого не зависит. Не так давно коллеге (который в питоне шарит) что-то там надо было распарсить и обработать — за пару часов результатов работы своего скрипта он не дождался. Моё поделие на х-ле отработало за время порядка нескольких минут.

            Ну и ругань на отсутствие явных типов и вопросы к тому, что где в какой переменной лежит, я слышу регулярно. Но нет, типы не нужны.


            1. roryorangepants
              04.05.2019 18:38
              +1

              Не так давно коллеге (который в питоне шарит) что-то там надо было распарсить и обработать — за пару часов результатов работы своего скрипта он не дождался. Моё поделие на х-ле отработало за время порядка нескольких минут.

              Дерзко предположу, что ваш коллега плохо шарит в питоне. numpy-стек очень хорошо оптимизирован, и правильно написанный код (где всё по максимуму считается через всяческие броадкастинги) должен быть крайне быстрым, сопоставимым по скорости с хорошим кодом на плюсах (ведь там под капотом и MKL, и всяческий SIMD). Поэтому хороший код на питоне и хороший код на хаскелле в сфере обработки данных должны быть примерно одинаковыми по скорости.


        1. farcaller
          04.05.2019 18:18

          А расскажите что там с хаскеллем, кстати. В контексте комментария я все же сравнивал с С/С++, так то R Studio есть отличный.


          С питоном я в последнее время постоянно использую colab.


          1. 0xd34df00d
            04.05.2019 18:23

            Использую Chart для графиков или diagrams для хардкора. statistics/hmatrix/etc для какого-то анализа. Мои задачи покрывает с лихвой.


      1. akhalat
        04.05.2019 16:42

        jupyter это вообще мечта


        А по мне, так это весьма ограниченный и урезанный клон Wolfram Mathematica Notebook.
        По крайней мере, после математики, при попытке работы с юпитером всё время чувствуешь себя не в той тарелке из-за кучи ограничений и урезанного функционала.

        Собственно, все те задачи быстрого прототипирования и «поиграться с идеей» более комфортно решаются в вольфраме.

        Хотя, для дата-сайенса, разумеется, питон будет лучше, но только из-за наличия большого числа готовых специализованных пакетов.


        1. farcaller
          04.05.2019 18:20

          А по мне, так это весьма ограниченный и урезанный клон Wolfram Mathematica Notebook

          В общем случае, справедливо. В данном сравнении могу сказать что питон просто проще интегрируется с прототипированием кода — веб-апи на математике не пишут все же, а тут можно написать веб-клиент и быстро его же и потестить. Питон, кмк, более универсален в этом вопросе.


          Математика офигенная потому что там датасеты из коробки.


    1. bano-notit
      04.05.2019 21:58
      +2

      В принципе есть мастера, которые топором выделывают просто офигительные произведения искусства из дерева. Есть виртуозы, умеющие с асфальта поднять монетку ковшом экскаватора.

      С помощью всего можно сделать всё. Просто монетку всё же легче поднимать магнитом, а фигурки делать ну хотя бы долотом.

      Мастера отличает не только владение определённым инструментом, но и умение выбрать кисть, которой он будет реализовывать конкретную мысль.

      Так же и в программировании, есть скрипты для скорости разработки, есть асм для максимальной эффективности. Между ними ещё целая гора инструментов под разные нужды, просто нужно знать какой и когда эффективнее применять.


      1. Daddy_Cool
        05.05.2019 01:19

        Ох… как прям поэтично.

        " нужно знать какой и когда эффективнее применять."

        Вот собственно об этом и был вопрос.
        Философские обобщения здесь очевидны и посему банальны.


        1. bano-notit
          05.05.2019 12:22
          +1

          Хорошо, хотите простейший пример, где питон выигрывает?


          Вот вам школьные задачки


          Py:
          def f(x,y,w,z):
              return int((x and not y) or (y==z) or not w)
          
          print('x y w z')
          for n in range(0b1, 0b10000):
              x = n>>3
              y = (n >> 2) & 1
              w = (n >> 1) & 1
              z = n & 1
          
              r = f(x, y, w, z)
              if not r:
                  print("{} {} {} {} = {}".format(x, y, w, z, r))

          C
          #include<stdio.h>
          
          int F(int x, int y, int w, int z){
              return (x & !y) || (y==z) || !w;
          }
          
          int main() {
          
              printf("x y w z\n");
          
              for (int i = 0b1; i < 0b10000; i++){
                  int x = i >> 3;
                  int y = (i >> 2) & 1;
                  int w = (i >> 1) & 1;
                  int z = i & 1;
          
                  int r = F(x,y,w,z);
                  if (!r)
                      printf("%i %i %i %i = %i\n", x, y, w, z, r);
              }
          
          }

          Разница даже не в количестве строк, а количестве мыслей, которые нужно применить. Сначала типы, потом библиотека, потом компиляция...


          Если хотите более сложные и приближенные к жизни примеры, то держите:


          1. Была задача сделать сервак для игрушки небольшой браузерной. Пусть будут карты. За 3 дня накатан макет на питоне, который прекрасно работал. Выдали деньги на разработку и клиент уже даже первый пакет правок подготовил по макету, а не по готовой кодовой базе. Лишние 10 часов не выброшено в мусорку.
          2. Личная задачка: на компе есть бд с треками (название, исполнитель, жанр ...) и плейлистами. Нужно при подключении телефона на его карточку копировать файлы из конкретного плейлиста. Сначала был сделан прототип на питоне, оттестирован, выявлен основной функционал. Потом была сделана программка на ржаве. Сейчас прекраснейшим образом работает.

          Таких примеров куча. Если свести их к одному тезису, то


          Питон — скриптовый язык без узкой специализации, который можно применить где угодно и быстро.


          1. tuxi
            05.05.2019 15:03

            Так никто особо и не спорит с тем фактом, что прототипирование на Питоне удобно и быстро. Просто для «неокрепших умов» такая легкость входа приводит к тому, что его начинают использовать везде и всегда. И как только на проект вместо 1 RPS, прилетает 10+ или 100+ RPS уже «поздно пить боржоми» и начинаются сначала танцы с бубнами, а потом переписывание.
            С моей точки зрения, питонист, который пришел в питон после C++ или чего то подобного, как правило принимает более грамотные и взвешенные решения по части использовать питон или нет на проде, нежели чем тот, который как сел на старте на питон, так и использует его везде и всегда, по делу и без дела.


            1. bano-notit
              05.05.2019 18:27

              С моей точки зрения...

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


              Возможно я просто ещё не настолько стар, чтобы понимать вымывающуюся гибкость сознания. Просто я пока вижу только то, что многие (я и сам иногда грешу) мыслят терминами. Вот в расто сообществе есть такой прекрасный термин, выражающий как раз негибкость и трафаретированность сознания — "ооп головного мозга".


          1. 0xd34df00d
            05.05.2019 15:35
            +1

            Сначала типы, потом библиотека, потом компиляция...

            А мне нравится проектировать сначала в типах. А менять потом код вообще одно удовольствие.


          1. Daddy_Cool
            05.05.2019 19:54

            О! Спасибо. Это дельно. В общем, чувствую — надо осваивать. )))


  1. sbnur
    04.05.2019 11:19
    +2

    Странно, конечно, знакомить программистское сообщество с языком, имеющим где-то 20-летнюю историю.
    Видно Хабр превращается в ленту типа — недавно я прочитал и расскажу, что понял


    1. GRaAL
      04.05.2019 11:56

      Есть люди, которые еще не знакомы с питоном. Некоторые из них недавно пришли на хабр. Почему нет?
      Я неоднократно начинал знакомство с какой-то технологии именно благодаря еще одной вводной статье. Видел её в ленте и вспоминал «точно, хотел же вот попробовать».


      1. bano-notit
        04.05.2019 22:11

        Как мне, так лучше почитать специализированный сайтик, который находится в первой строке поиска по питону, чем вот эту вот "статейку", которая мало того что просто ничему не учит, мало того что элементарный отступный синтаксис не учитывает, так 3 строка первого примера (for i in ( ... ]:) меня просто убивает своей безграмотностью.


  1. BasicWolf
    04.05.2019 11:23
    +2

    Ну вот опять… После такого «введения», желание познакомится с питоном пропадёт на веки вечные. Автор, вам самому бы не мешалось пройтись по официальному туториалу, перед тем как какие-либо руководства писать.


  1. tymanst
    04.05.2019 11:41
    +2

    А что за оператор ln в python?
    in знаю, а вот ln впервые вижу…


  1. mkvmaks
    04.05.2019 13:21

    Сам начал изучать Python — для чего? Не знаю, все про него говорят, все на нем делают… вот решил попробовать. Первые сложности — это банально синтаксис, а именно эти отступы и оформление кода. Далее, читая книгу все больше понимаю, что с данным языком программирования, кроме как выше писали для аналитических вещей и простых игр не уедешь ((( Для основной работы использую Lazarus, VBA, немного JS и на этих языка больше всего сделал для работы, чем на Python'е. ))) Прошло еще немного времени и интерес к данному языку еще больше угас (


  1. rudinandrey
    04.05.2019 13:50
    +2

    я тут мемчик один видел, всегда все интересно в ВК сохраняю, а тут видимо посмеялся и дальше прошел, так вот, там значит лестница, на первой ступени Hello, World потом структуры данных, алгоритмы, и на 4 или пятой ступеньке Data Science, и типа современный студент там с первой лестницы перешагивает 2,3 ступеньки и сразу на Data Science )) вот у меня от заголовка и тизера сразу же вспомнил эту картинку, т.е. Python для начинающих и сразу TensorFlow :-)))


    1. ZZahar
      04.05.2019 16:08

      Картинка


    1. tuxi
      04.05.2019 16:30
      +4

      1. na9ort
        04.05.2019 17:24

        Пиздец Это конечно жесть!


  1. iroln
    04.05.2019 16:07
    +3

    Автор, зачем ты это пишешь, если даже не можешь прочитать своё творчество и исправить некорректный код. Посмотри ещё раз на свой текст, где у тебя отступы в коде, что вообще со скобками творится (]?! Для кого, для чего писать такие статьи?


  1. ZaEzzz
    04.05.2019 16:12

    Гм… Может для начала стоит почитать теорию по машинному обучению?


    1. BasicWolf
      04.05.2019 17:01
      +2

      Чёрт, после вашего комментария до меня дошло: это не автор писал! Это результат «машинного обучения» по написанию статей о Питоне :D


      1. Jourloy
        04.05.2019 22:42

        Вы открыли мне глаза, спасибо большое :)


      1. saluev
        05.05.2019 10:35

        Судя по

        def subtract ( a=0, Ь=0 ) :

        (мягкий знак, Карл!) так оно и есть. Только где-то ещё имело место text recognition.


        1. roryorangepants
          05.05.2019 10:42

          Действительно. Автор воришка и накопировал куски текста и примеров из этой книги.


        1. Morgan_iv
          05.05.2019 11:54

          Благодаря хабровской подсветке синтаксиса в глаза сильно бросается буква З вместо цифры 3 в этом куске кода:

          for j in (1, 2, З, 4, 5 ] :
          Так что да, тут однозначно автоматическое распознавание текста + (возможно) автоматический перевод. Чем-то напоминает ситуацию в относительно недавней статье про автоматическую генерацию и публикацию в Google Play однотипных слот-машин


      1. technic93
        05.05.2019 19:19
        +3

        Мы присутсвуем при историческом событии. Это первый шаг: "ИИ прочитал статью по питону и написал об этом на хабр". Потом ещё пару книг прочтет и начнет писать код. Следите за новостями.


  1. spballiance
    05.05.2019 00:30

    на самом деле пробелы в большинстве не наказуемы. А вот отступы надо выучить, но я не вижу разницу между отступом и {} в количестве нажатий, а иногда даже отступ удобнее, чем поиск незакрытых скобок. Тот же пишарм половину этих действий автоматически делает