Ответы пользователя по тегу Python
  • Почему input(int()) автоматически выставляет 0?

    Kademn
    @Kademn
    Злой
    input всегда возвращает строку. Параметр, который принимает input, это то, что будет напечатано для пользователя, как приглашение к вводу, после которого он сможет вводить данные. Вы передаёте туда int(), который возвращает 0, именно это и печатает input, как приглашение к вводу данных.
    Вместо того, чтобы печатать фразу "Сколько школьников?" print('Сколько школьников?') лучше передать эту фразу в input, чтобы он напечатал её, как приглашение к вводу:

    s = input('Сколько школьников? ')

    В s будет строка, теперь чтобы преобразовать это в число и совершать математические операции, необходимо преобразовать s в integer:
    s = input('Сколько школьников? ')
    s = int(s)


    Или можно записать это одной строкой, вложив одну функцию в другую:
    s = int(input('Сколько школьников? '))
    Ответ написан
    Комментировать
  • Как в Python 3 работает функция int()?

    Kademn
    @Kademn
    Злой
    Как в Python 3 работает функция int()?

    В первую очередь необходимо отметить, что int это встроенный класс, а не функция. Да, фактически его используют как функцию, и даже в документации его можно найти в разделе built-in funcitons, но технически это класс.

    print(a) возвращает None

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

    Так как правильно?

    a = 12
    a = int(12)
    a = int.__new__(int, 12)


    В каждом из этих трех случаев будут работать методы __new__ и __init__. Python так устроен, что у всех объектов есть эти методы, они вызываются самим интерпретатором и вам не нужно делать это самостоятельно.
    Сначала вызывается метод __new__, этот метод возвращает объект (только что созданный инстанс), и у этого объекта вызывается метод __init__.
    Ответ написан
    Комментировать
  • Как раздуплить Source-Query на Python 3+?

    Kademn
    @Kademn
    Злой
    Ваш код рабочий, если не считать последней строчки, где вы к строке плюсуете байты. Ответ вы не получаете потому, что запрос составлен неправильно, но это уже вопрос не языка программирования или сокетов, а формата запросов и ответов. Запрос должен начинаться с четырёх 'FF' байт.
    import socket
     
    IP = '195.62.53.149'
    PORT = 27015
     
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.connect((IP, PORT))
    sock.send(b'\xff\xff\xff\xffTSource Engine Query')
    sock.settimeout(120)
    text = sock.recv(1024)
    print(b'res ->' + text)


    > python cs_udp.py 
    b'recv -> \xff\xff\xff\xffI0Euro-Cs.Ru | Public | 1000FPS\x00de_dust2_2x2\x00cstrike\x00Counter-Strike\x00\n\x00\x03\x14\x00dl\x00\x011.1.2.7/Stdio\x00\x80\x87i'


    UPD:
    Я никогда не работал с этим форматом. Есть библиотека pytho-valve. Первый же пример из её документации отлично отрабатывает с твоим сервером без лишних телодвижений.
    import valve.source.a2s
    
    SERVER_ADDRESS = ('195.62.53.149', 27015)
    
    with valve.source.a2s.ServerQuerier(SERVER_ADDRESS) as server:
        info = server.info()
        players = server.players()
    
    print("{player_count}/{max_players} {server_name}".format(**info))
    for player in sorted(players["players"],
                         key=lambda p: p["score"], reverse=True):
        print("{score} {name}".format(**player))


    > python udp_client.py 
    4/20 Euro-Cs.Ru | Public | 1000FPS
    39 1UP|mam?a
    31 zakeman4
    16 Cosmodesant
    0 (А.У.Е.ШПАНА) хуй


    Ссылка на документацию
    Ответ написан
    3 комментария
  • Вывести время в секундах python3?

    Kademn
    @Kademn
    Злой
    Ответ написан
    Комментировать
  • Как работать с crontab на Mac?

    Kademn
    @Kademn
    Злой
    Ну как же так?
    Ведь, даже если вы англицкого изречения не понимаете и `man crontab` прочитать не в силах, то неужели и во всех поисковиках вас забанили?
    Вот, к примеру, поисковик 10 в степени 100, первой ссылкой по запросу `man crontab` выдает вот это
    Если уж использовать нечто более "руководственное", наподобие `crontab мануал`, в любой из поисковых машин, то какой-нибудь мануал вам непременно обеспечен.
    Чудеса, да и только, не правда ли?
    Ответ написан
  • Правильное отображение прогрессбара на Python - что не так?

    Kademn
    @Kademn
    Злой
    Давайте по-порядку.
    Вот участок кода, отвечающий за прогресс-бар:
    for i in range(lenLi):
        sys.stdout.write('\r')
        sys.stdout.write("[%-30s] %d%%" % ('='*i, i))
        sys.stdout.flush()

    Во-первых вывод в консоль у вас неправильный. Длина вашего прогресс-бара 30 символов. Значит при каждой итерации нужно выводить количество символов, соответствующее итерации, не забывая, что нельзя выводить дробное количество символов. К примеру, если длина списка у вас 5, значит 30/5=6 символов добавляет каждая итерация цикла. Но вы переписываете весь прогресс-бар, поэтому можно посчитать "часть" от всей длины (30 символов) для этого шага. Например для длины 5, шаг 1 - это 1/5 длины, шаг 2 это 2/5 длины и т.д. Тогда количество символов это количество символов для "полной" длины умножить на полученную часть.
    part = float(i)/(lenLi-1)
    symbols_num = int(30 * part)

    lenLi -1, так как выше вы увеличивали длину на единицу (видимо для range), то тогда range стоило бы начинать с 1, а не с нуля. А проценты легко получить умножив part на 100, не забыв сменить форматирование вывода с '%s%%' на, скажем, '%3.2f%%', так как в выводе дробное число и оно очень плохо смотрится, если %s.
    Теперь прогресс-бар будет выводиться правильно:
    for i in range(1, lenLi):
        sys.stdout.write('\r')
        part = float(i)/(lenLi-1)
        symbols_num = int(30 * part)
        sys.stdout.write("[%-30s] %3.2f%%" % ('='*symbols_num, part*100))
        sys.stdout.flush()

    Правда, чтобы успеть увидеть изменения, добавьте в цикл wait(), иначе все 100% заполнятся за доли секунды.
    UPD
    Да, вы для каждой ссылки заполняете прогресс-бар от нуля до 100 процентов. Цикл внутри цикла не нужен. Прогресс-бар должен быть частью for x in li:. Но, для правильного отображения прогресс-бара, вам необходимо считать номер шага. Для это можно либо завести переменную, которая будет считать шаги, либо использовать функцию enumerate:
    for step_number, x in enumerate(li):
    Учитывая, что вам удобнее нумеровать шаги с единицы, правильнее было бы использовать
    for step_number, x in enumerate(li, 1):
    А вообще, если вы хотите использовать прогресс-бар и в других местах кода, то стоило бы завести отдельную функцию для печати прогресса, которая принимает дробное число от 0 до 1 или процент в качестве аргумента и выводит в консоль соответствующий прогресс-бар, возвращая каретку в начало строки.
    Полагаю, что этих подсказок более, чем достаточно. Дальше попробуйте сами.
    Ответ написан
    3 комментария
  • Каким образом у разных объектов оказывается общим один параметр?

    Kademn
    @Kademn
    Злой
    Дело в том, что переменная `calls` объявлена в классе и ее наследуют все экземляры этого класса. И у них у всех, при создании, self.calls указывает на одно и тоже место в памяти, на оду и ту же переменную. Так как переменная в памяти это изменяемый объект, изменяя его в любом из экземпляров, вы видите измененный объект в любых других экземплярах, да и в самом классе тоже.
    Если хотите, чтобы при создании экземпляра создавался новый объект в памяти, а не наследовался указатель, используйте __init__, который вызывается при создании экземпляра.
    class SubClass(object):
        def __init__(self):
            self.calls = set()


    Кстати сказать, что с классом SomeClass у вас абсолютно таже история. Изменяемый объект (словарь param), указатель на который наследуют все экземпляры.
    Ответ написан
    3 комментария
  • Интересует соотношение задач программы к её объёму. Возможно как-то оптимизировать код?

    Kademn
    @Kademn
    Злой
    А что по-вашему оптимизация, позвольте осведомиться? Это не однозначный вопрос. Вы спрашиваете про код?
    Да, это рабочий код, но он выглядит плохо. Нет, простите, он выглядит ужасно. Самое первое что необходимо уяснить - никогда ничего не писать (если вы точно не понимаете зачем) в основной области файла. Все должно быть разбито на функции. Этих немыслимых уезжающих вправо try - except - else - if, вложенных друг в друга через if'ы while True циклов и прочей, извините, лапши не случилось, если бы вы использовали функции для повторяющихся участков кода и вызывали бы их.
    Вот пример без нагромождения if'ов. Он не идеален, в первую очередь потому что он может быть сложен для прочтения, но он таков для большей компактности и потому, что в нем использованы некоторые "альтернативные" методы, которые могли бы использовать вы и о которых вы вопрошали:
    # coding: utf-8
    
    import random
    
    
    def ask(message, known_answers=['нет', 'да'], yes_no=True):
        answer = '\n'
        while answer not in known_answers: 
            answer = input(message)
            if answer not in known_answers:
                print('Возможные варианты: ', ' '.join(known_answers))
        return known_answers.index(answer) if yes_no else answer
    
    def game():
        # supporting function
        def _input_x():
            x = None
            while x is None:
                try:
                    x = int(input('Введите x: '))
                except ValueError:
                    print('Введите целое число')
            return x
        # messages
        answers = ['Ответ неверный', 'Верно']
        is_winner = ['К сожалению, вы проиграли', 'Вы - победитель']
        # actions
        actions = {'+': lambda x, i: x+i,
                   '-': lambda x, i: x-i,
                   '*': lambda x, i: x*i,
                   '/': lambda x, i: x/i
                  } 
        # initial values
        life = 4
        count = 10
        
        # main loop
        while life and count:
            # condition
            x = _input_x()
            i = random.randint(1, 5)
            print('Случайная величина = ', i)
            random_action = random.choice(list(actions.keys()))
            y = actions[random_action](x, i)
            print('Результат действия = ', y)
            
            # answer
            answer = ask('Что это было за действие?: ',
                         known_answers=list(actions.keys()), yes_no=False)
            # result
            result = actions[answer](x, i) == y
            print(answers[result])
            if result:
                count -= result
            else:
                life -= not result
                print('Прав на ошибку - ', life)
        
        # game result    
        print(is_winner[bool(life)])
    
    def run():
        print('Суть этой игры такова: вы указываете любое целое число x, программа выбирает случайную'
          ' величину и выводит на экран результат одно из четырёх действий. Ваша задача - указать'
          ' арифметический знак действия (сложение (+), вычитание (-), умножение (*), деление (/)),'
          ' полагаясь на результат. 10 Правильных ответов приведут вас к победе.')
        while ask('Играем? да/нет: '):
            game()
        print('Всего хорошего')
    
    
    if __name__ == '__main__':
        run()


    Если разберетесь как он работает, вы научитесь новому.
    Если я показался грубым или заносчивым - извините.
    Если будут вопросы - пишите, постараюсь ответить.
    Если..
    Ответ написан
  • Сколько памяти займет скрипт на питоне?

    Kademn
    @Kademn
    Злой
    Список хранит ссылки на переменные в памяти, а значит список длиной N в 32-х битных системах будет иметь размер (2*2)*N, а в 64-х битных (4*2)*N
    >>> from sys import getsizeof
    
    >>> l = list()
    >>> print getsizeof(l)
    32 (в 32 битной системе)
    64 (в 64 битной системе)

    Значит искомая величина 32 + (2*2)*N (в 32 битной системе), 64 + (4*2)*N (в 64 битной системе), где N - длина списка.
    Но список хранит указатели, а значит место займут еще и сами данные. В вашем случае данные имеют тип integer
    >>> from sys import getsizeof as gs
    >>> a = int()
    >>> print gs(a)
    12 (в 32 битной системе)
    24 (в 64 битной системе)

    Значит памяти всего израсходуется
    32 + (2*2)*N + N*12 (в 32 битной системе)
    64 + (4*2)*N + N*24 (в 64 битной системе)

    Для списка из 7млн чисел имеем:
    32 + (2*2)*7000000 + 7000000*12 = 112000032 байт = 109375 Кбайт = 106.8 Мбайт
    64 + (4*2)*7000000 + 7000000*24 = 224000064 байт = 218750 Кбайт = 213.6 Мбайт
    Ответ написан
    Комментировать
  • Зачем в python range() если есть xrange()?

    Kademn
    @Kademn
    Злой
    Сначала было слово и слово было Python... бла бла бла....
    А потом добавили range, который создавал всю последовательность натуральных чисел в памяти и это было хорошо, так как можно было их итерировать.
    А потом добавили xrange, который не добавлял весь набор в памяти, а вычислял следующий элемент, ничего не зная про остальные (предыдущие и последующие элементы), почти ничего не занимая в памяти. Так появились генераторы. И поняли, что генераторы это хорошо, отделили генераторы от итераторов и стало так.
    А потом Девид Бизли на Пайконе 2008, высеченными на камне презентациями... ой я увлекся.
    Ответ написан
    Комментировать
  • Для обучения python есть ли подходящие репозитории на github?

    Kademn
    @Kademn
    Злой
    Дополняя ответ bobrovskyserg
    https://github.com/aliev/runestone - подходящий репозиторий на гитхаб
    aliev.me/runestone/index.html - сам перевод online.
    Ответ написан
    Комментировать
  • Как вывести график функции и множество точек?

    Kademn
    @Kademn
    Злой
    не использовать внешних библиотек вроде Matplotlib

    А какие можно?

    Для самостоятельной работы с изображениями можете взять Pillow например. Там же и нарисуете.

    Если вообще ничего нельзя, то тогда можно взять спецификацию какого-нибудь графического формата файлов и написать свою собственную реализацию на Python. Там останется немного до собственной библиотеки умеющей строить графики функций c блекджеком с сжатием без потерь и прозрачными пикселями.. ну вы понимаете..
    Вот, например, Запись png-изображения на чистом python, за работоспособность этого кода не могу ручаться. Но, возможно, вы ищете что-то подобное.
    Ответ написан
    Комментировать
  • Как авторизоваться на сайте с помощью python?

    Kademn
    @Kademn
    Злой
    Подозреваю, что вам необходимо использовать requests.Session()
    url = 'https://...'
    login = 'login'
    password = 'password'
    s = requests.Session()
    r = s.get(url, auth=(login, password))


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

    Еще, зачастую, чтение чужого кода помогает понять как правильно (или неочень) пользоваться тем или иным инструментом. Скрипт авторизующийся в вконтакте и качающий музыку пишет, пожалуй, каждый начинающий питонщик. Найти несложно.
    Немало также статей по парсингу сайтов с помощью python. В них непременно будет urllib или requests. Например тут.
    Вообщем, ищите и обрящете =)
    Вот и в результате послал в гугл, мда. =)

    upd. Раз вы самообучаетесь для себя, попробуйте порешать задачи тут: checkio.org. Полезнее всего будет не просто решать задачи, а смотреть как ту же задачу решили другие, много нового для себя откроете и цели в виде решения очередной задачи всегда будут иметься (ачивки, если вы искушенный задрот, тоже самоцель). В примерах оставленными другими есть как хорошо документированные, так и безумные решения завернутые в одну строку.
    Ответ написан
    3 комментария
  • Как можно сделать таймер?

    Kademn
    @Kademn
    Злой
    import time
    
    
    class Stopwatch:
        """ Counts passed seconds """
        def __init__(self):
            self.init_time = time.time()
            self.seconds = 0
            self.last_check = self.init_time
    
        def checkseconds(self):
            now = time.time()
            count = int(now - self.last_check)
            mod = now - self.last_check - count
            self.seconds += count
            self.last_check = now - mod


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

    Тоже самое, с помощью генераторов:
    import time
    
    def stopwatch():
        """ Coroutine that returns number of seconds
            passed after initialization
        """
        # Initialization
        init_time = time.time()
        seconds = 0
        last_check = init_time
        
        # Main loop
        while True:
            now = yield seconds
            count = int(now - last_check)
            mod = now - last_check - count
            seconds += count
            last_check = now - mod


    Теперь создаем генератор и, также почаще, посылаем ему настоящее время:
    # Создаем сопрограмму
    my_watcher = stopwatch()
    
    # Не забываем про инициализацию (первый yield)
    my_watcher.send(None)
    
    # Остальные send будут возвращать количество пройденных
    # после инициализации секунд
    passed_seconds = my_watcher.send(time.time())
    <...>
    passed_seconds = my_watcher.send(time.time())
    Ответ написан
    Комментировать