Pull to refresh

Python или не Python

Reading time 3 min
Views 4.5K
Я расскажу о проблемах с которыми столкнулся, выбрав Python3 первым языком.
Я не изучал программирование в университете.
Я не хочу начинать holywar.

В 2016 Google советовал учить Python3 если нужен:

1. Легкий для старта язык.
2. Язык для машинного обучения.
3. Язык для простых 2d игр.

1. Я посмотрел первую лекцию курса Harvard CS50 на сайте JavaRush и понял, что не хочу:

#include <stdio.h>
int main(int argc, const char *argv[]) {
    printf("Hello world\n");
    return 0;
}

Когда можно так:

print('Monty Python')

JavaScript испугал комбинацией из трех систем: JS/HTML/CSS.

2. Машинное обучение вдохновляло тем, что все статьи и примеры напоминали киберпанк и научную-фантастику.

3. Можно программировать игры? Супер!

Я сделал import this, оценил философию Python и начал читать книгу Майкла Доусона «Программируем на Python». Через три недели после «Hello World!» я написал клон игры Life с GUI интерфейсом. Я полюбил Python и когда начались сложности я думал, что недостаточно знаю и пишу плохие алгоритмы.

Скорость

Я использовал tkinter и рисовал прямоугольники для создания клеток.
Поле 800x640. Размер клетки 10x10.

class Square(object):
    def __init__(self, canvas, x, y, size, main):
        self.canvas = canvas
        self.cel = self.canvas.create_rectangle(x, y, x + size, y + size, fill='#EEEEEE')
        self.main = main
        self.color_change = True
        self.canvas.tag_bind(self.cel, '<ButtonPress-1>', self.paint)



Такое маленькое поле не успевало полностью заполниться. Около 600 клеток быстро обновлялись, но как только, я уменьшил размер клетки до 4 – упала скорость изменения состояний клеток и отклика интерфейса.

Я удалил класс Square и начал рисовать пиксели по изображению. Интерфейс заработал нормально, но после 200 клеток все обновлялось очень медленно. Я нашел проблему в алгоритме. Рисовать клетку из 4 пикселей медленнее, чем из 1 пикселя.

def fill_black(self, x, y, color):
        for i in range((-self.cell // 2) - 1, (self.cell // 2) - 1):
            for j in range((-self.cell // 2) - 1, (self.cell // 2) - 1):
                xx = (x + i) % self.can_width
                yy = (y + j) % self.can_height
                self.cell_matrix.put(color, (xx, yy))

После исправлений, я получил 600 клеток на нормальной скорости и очень мелкие фигуры на экране. Мне удалось довести скорость до 900 клеток, когда я перестал проверять изображение на «черный пиксель» и стал хранить состояние системы в матрице.

def fill_black(self, coords, color, virt_color):
    x, y = coords
    self.virt_mat[x][y] = virt_color
    self.cell_matrix.put(color, (x, y))

Я установил pygame, перенес алгоритм и получил 9000 клеток на 4 fps. Но ведь игры работают быстрее, а там не только точки на экране.
Я начал подозревать, что дело в языке.
Я попробовал Cython. Система из 30000 клеток заработала на 4 fps.



Я не хотел С, но получил С.

Как запаковать для переносимости на другой компьютер?

С этим я справился с помощью py2app, но так и не понял как это работает.

Стандартная библиотека и сторонние модули

У меня не получилось этого оценить. Я постоянно устанавливал что-то еще и, иногда, модули не хотели работать друг с другом. У меня было три venv для отдельной запаковки приложений с tkinter, tkinter + pillow и pygame. Я смотрел в папку site-packages и не знал, что от чего зависит и зачем оно там лежит. Я не писал свои модули. Я искал готовые.

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

Я выбрал Lua. Почему-то, я выбрал еще один язык с не совсем привычным синтаксисом :-)

Скорость

Я сделал Life на Lua + Love2d. Я просто использовал функции языка и движка.

function Life:draw()
    love.graphics.setCanvas(self.canvas)
    love.graphics.clear()
    for y=1,self.rows do
        for x=1,self.cols do
            if self.cells[y][x]==1 then
                love.graphics.setColor(self.color)
                love.graphics.points(x-1,y-1)
            end
        end
    end
    love.graphics.setCanvas()
    love.graphics.setColor(set.WHITE)
    love.graphics.draw(self.canvas,self.x,self.y)
end

При 111735 живых клетках система работает на 18 fps.



Как запаковать для переносимости на другой компьютер?

Я написал скрипты на Lua + Love2d для запаковки приложений для MacOS и Windows. Да, инструкция есть на сайте, но теперь для меня этот процесс не так «волшебен», как с py2app.

Маленькая стандартная библиотека

Мне не хватало привычных функций Python: map, filter, reduce, range и пришлось сделать функциональную библиотеку. В Lua нет классов, но я почитал как их добавить в язык и лучше понял как работают классы в Python. Только с Lua я полюбил замыкания и генераторы.

Когда я попробовал все функции стандартной библиотеки и треть функций из модулей для взаимодействия с языком С, то у меня сложилось общее представление о языке. Это очень приятное чувство. Lua как-будто, хорошо подходит для начала, но язык не популярен.

Если бы я мог заново выбрать первый язык, то я начинал бы с JavaScript.
Почему?

1. Язык запускается в браузерах.
2. Популярен.
3. Знакомство с web.
4. JavaScript + pixi.js и игра Life заработатает без проблем.

А Python я бы стал изучать вместе с алгоритмами машинного обучения.
Tags:
Hubs:
+2
Comments 14
Comments Comments 14

Articles