• Вопрос по словарям Python?

    @javedimka
    Хочу сока
    from collections import defaultdict
    
    
    s = {'Которая часто': 6, 'чулане хранится': 7, 'Который построил': 8, 'Который бранится': 2, 'хвоста Который': 4}
    
    def sum_update(d):
        updated = defaultdict(int)
        for k, v in d.items():
            updated[k.split()[0]] += v
        return dict(updated)
        
    
    sum_update(s)
    
    # {'Которая': 6, 'Который': 10, 'хвоста': 4, 'чулане': 7}


    Более логичный (значения словаря - счетчики = Counter) способ по наводке от longclaps:
    from collections import Counter
    
    
    def sum_update(d):
        updated = Counter()
        for k, v in d.items():
            updated[k.split()[0]] += v
        return dict(updated)
    Ответ написан
    3 комментария
  • Как получить определенное значение из словаря в шаблоне django?

    @javedimka
    Хочу сока
    Чтобы узнать как правильно вытащить значения, надо сначала узнать почему они вообще приходят в таком неудобном виде, а если возможности узнать и исправить нету - преобразовать в более удобный вид, например во вложенные списки:
    def table_view(request):
        data = {'2A':
                ['Name', 'State',
                 'Name2', 'State2',
                 'Name3', 'State3',
                 'Name4', 'State4',
                 'Name5', 'State5']
                }
        data['2A'] = [data['2A'][i:i+2] for i in range(0, len(data['2A']), 2)]
        return render(request, 'app/template.html', {'students_data': data})


    И тогда в шаблоне:
    {% for student in data %}
    <tr>
        <input type="hidden" name="stud" value="{{ student.0 }}" />
        <td>{{student.0 }}</td>
        <input type="hidden" name="state" value="" class="state"/>
        <td id="editable">{{ student.1 }}</td>
    </tr>
    {% endfor %}

    или как вариант - использовать namedtuple, но что там по скорости будет не знаю.
    Ответ написан
    7 комментариев
  • Кто-то использовал prefix_default_language=False для удаления префикса языка?

    @javedimka
    Хочу сока
    У Джанго есть багтрекер ->
    https://code.djangoproject.com
    В форму поиска, prefix_default_language ->
    https://code.djangoproject.com/search?q=prefix_def...
    Можно приступать к изучению возможных проблем.
    Ответ написан
    Комментировать
  • Проблемы в юнит тесте (Entry matching query does not exist)?

    @javedimka
    Хочу сока
    см. update
    Ошибка возникает при обработке сигнала pre_save. В тесте test_article_sorting() создается объект статьи, перед сохранением в бд посылается сигнал pre_save и выполняется функция delete_old_article_image, где в строчке
    article = Article.objects.get(pk=instance.pk)
    .get() метод пытается получить несуществующий объект статьи из бд и после этого рэйсит ошибку DoesNotExist
    Одно из нескольких возможных решений - обернуть в блок try/except:
    @receiver(pre_save, sender=Article)
    def delete_old_article_image(sender, instance, *args, **kwargs):
        if instance.pk:
            try:
                article = Article.objects.get(pk=instance.pk)
                if instance.image and article.image != instance.image:
                    slide.image.delete(False)
            except Article.DoesNotExist:
                pass

    Ну и естественно все это тоже надо покрыть тестами, тут их будет как минимум 3.

    UPDATE:

    Сегодня что-то вспомнил этот вопрос, еще раз открыл, понял почему на "продакшене" работало, а в тестах нет:
    Как я уже говорил, в тестах, ты создаешь объекты статьи с помощью шортката .create() который внутри себя создает объект obj с указанными тобою параметрами и вызывает save() для его сохранения в базу данных, отправляется сигнал pre_save, в хэндлер передается твой объект с имеющимся pk, выполняется твой код, условие if instance.pk срабатывает и начинается попытка получить несуществующий объект из базы, что оканчивается ошибкой.

    Почему работало на живом сайте? Вот почему:

    На "живом" сайте, когда ты создаешь новый объект, при его сохранении в хэндлер сигнала pre_save() передается instance с pk == None, так как primary key вешается самой базой данных после всех джанговских штучек, поэтому на этом этапе if instance.pk возвращало False и вложенный код не выполнялся.

    Когда же ты редактировал уже существующий объект при сохранении в хэндлер pre_save() передавался "уже имеющийся" в базе объект у которого есть pk и у которого, возможно, теперь слегка измененные данные (раз уж редактируем то что-то да меняем) что приводило к выполнению условия if instance.pk и выполнению вложенного кода который успешно получал уже существующий базе объект.

    Поэтому, решить проблему с тестами можно было просто убрав явное вешание pk из тестов, оставив эту работу бд:
    first_article = Article.objects.create(
        # pk=150,
        ...   
        )
    
    second_article = Article.objects.create(
        # pk=160,
        ...   
        )
    
    third_article = Article.objects.create(
       # pk=170,
       ...
       )
    
    data = {first_article.pk: 2, second_article.pk: 0, third_article.pk: 1}


    И instance.pk проверять следует так:
    @receiver(pre_save, sender=Article)
    def delete_old_article_image(sender, instance, *args, **kwargs):
        if instance.pk is not None:
                article = Article.objects.get(pk=instance.pk)
                if instance.image and article.image != instance.image:
                    slide.image.delete(False)
    Ответ написан
    Комментировать
  • Как красиво вывести квадратное уравнение в консоль?

    @javedimka
    Хочу сока
    Если хочется оставить принудительное форматирование во float, то можно сделать так:
    def quadratic_eq_formatter(nums):
        num_f = {1: '{:+.0f}', 0: '{:+.1f}'}
        eq = '{}x^2{}x{}=0'.format(*(num_f[x.is_integer()] for x in nums))
        return eq.format(*nums) if nums[0] < 0 else eq.format(*nums)[1:]
    
    nums = (a, b, c)
    print(quadratic_eq_formatter(nums))

    print(quadratic_eq_formatter([-3.0, -2.7, 7.0]))
    '-3x^2-2.7x+7=0'
    print(quadratic_eq_formatter([2.0, 5.0, -4.0]))
    '2x^2+5x-4=0'
    print(quadratic_eq_formatter([-2.1, -4.5, 8.3]))
    '-2.1x^2-4.5x+8.3=0'

    А чтобы уж вообще красиво было, то ^2 в
    eq = '{}x^2{}x{}=0'.format(*(num_f[x.is_integer()] for x in nums))

    можно поменять на
    eq = '{}x\u00B2{}x{}=0'.format(*(num_f[x.is_integer()] for x in nums))

    тогда получится что-то типо:
    print(quadratic_eq_formatter([-2.0, 5.0, 5.2]))
    -2x²+5x+5.2=0
    Ответ написан
    Комментировать
  • Возможно ли заставить Python искать метод в экземпляре?

    @javedimka
    Хочу сока
    Ну гуглится же: "python assign bound method to existing class"
    https://stackoverflow.com/questions/972/adding-a-m...
    Там же по ссылке есть второй способ.
    In [1]: class A:
       ...:     def sayHello(self):
       ...:         print('Hello!')
       ...:
    
    In [2]: def sayHello(self):
       ...:     print('Hey')
       ...:
    
    In [3]: a = A()
    
    In [4]: b = A()
    
    In [5]: a.sayHello()
    Hello!
    
    In [6]: a.sayHello = sayHello.__get__(a)
    
    In [7]: a.sayHello()
    Hey
    
    In [8]: b.sayHello()
    Hello!
    Ответ написан
    1 комментарий
  • Как задать название функции для register_next_step_handler?

    @javedimka
    Хочу сока
    Ничего не понял, но наверное как-то так
    >>> def heyfunc():
    ...     print('hey')
    ...     
    >>> def supfunc():
    ...     print('sup')
    ...     
    >>> funcdict = {'heyfunc': heyfunc, 'supfunc': supfunc}
    >>> f_name = input()
    hey
    >>> next_func = funcdict.get(f_name+'func')
    >>> next_func
    <..function heyfunc at 0x10926d268..>
    >>> next_func()
    hey

    Кстати, если хочется упороться, то можно сделать декоратор:
    card_funcs = {}
    
    def register_cf(card_func):
        '''register card function'''
        card_funcs[card_func.__name__] = card_func
        return card_func
    
    @register_cf
    def card_func1():
        print('Running card1')
    
    @register_cf
    def card_func2():
        print('Running card2')
    
    @register_cf
    def card_func3():
        print('Running card3')
        
    if __name__ == '__main__':
        print('running funcs from registry:')
        for fn, fobj in card_funcs.items():
            print(fn, '->', fobj)
            fobj()
    
    -----
    running funcs from registry:
    card_func3 -> <..function card_func3 at 0x1069ae9d8..>
    Running card3
    card_func2 -> <..function card_func2 at 0x1071ea9d8..>
    Running card2
    card_func1 -> <..function card_func1 at 0x10db190d0..>
    Running card1

    Не надо словарь хардкодить + удобно расширять
    Ответ написан
    1 комментарий
  • Как правильно Update выполнить в базе postgresql?

    @javedimka
    Хочу сока
    >>> import re
    >>> keywords = ['ИД безопасности:', 'Тип входа:', 'Дата:', 'Код события:']
    >>> pattern = re.compile(r'\s+\w+|'.join(keywords))
    >>> with open('log.txt', encoding='utf-8' ) as f:
    ...     for line in f:
    ...         if pattern.search(line):
    ...             print(line)
    ...
    Дата:          04.07.2017 13:04:31
    
    Код события:   4624
    
      ИД безопасности:		система
    
    Тип входа:			7
    
      ИД безопасности:		rootpc\root

    Ну и как видно не все они уникальны
    Ответ написан
    7 комментариев
  • Ошибка типов переменных в python?

    @javedimka
    Хочу сока
    c = ["You are", b ,"years old."] - здесь year, а не years

    c = ["You will be born in", b ," years."] - здесь убрать пробел внутри " years" (перед самим словом)
    Ответ написан
    Комментировать
  • Как обработать сигнал нажатия на кнопку QPushButton?

    @javedimka
    Хочу сока
    С отступами накосячил, у тебя методы в классе TeachingWindow определенны внутри метода __init__, а должны быть под ним
    Ответ написан
    Комментировать
  • Как поймать код выполнения команды, посланной в python-скрипте в sh через subprocess?

    @javedimka
    Хочу сока
    returncode = subprocess.run(['sh',  'команда, которую я выполняю'], stdout=subprocess.PIPE).returncode
    print(returncode)

    https://docs.python.org/3/library/subprocess.html
    class subprocess.CompletedProcess
    И, возможно, тебе стоит запускать subprocess.run() с аргументом shell=True
    Ответ написан
    Комментировать
  • Как вывести сгенерированные случайные числа в четыре колонки?

    @javedimka
    Хочу сока
    >>> ints = [random.randint(-10,10) for x in range(1,101)]
    >>> while ints:
    ...     print('{0:>5}{1:>5}{2:>5}{3:>5}'.format(*ints[:4]))
    ...     ints = ints[4:]
    ... 
        5    5    6   -2
       -4    6    0    4
        9   -7    6    5
       -1    0    2   10
        7   -8    8    1
        7    4   -7    6
       -5   -6   -3    9
        2   -4    2    2
       -1    9   -7   -2
        5   10    4   10
       -9    8    5    7
        7    9   -5   -7
        9   10   10    9
        0   -8   -4   -3
       -5    5    6  -10
        1   -6   -4   -9
       -2    5   -4    2
       10   10    9   -6
       -1   -3   -3   -1
        2    6   -5   -7
       -5    1    7   -3
        3    9   -8   -7
       10    5   -5    6
        2    9   -1   -4
       -1   -2   -9   -2
    Ответ написан
    4 комментария
  • Как реализовать поиск по полному имени, имея два раздельных поля в базе (first_name, last_name)?

    @javedimka
    Хочу сока
    from django.db.models import Q 
    
    def find_user_by_name(query_name):
       qs = User.objects.all()
       for term in query_name.split():
         qs = qs.filter( Q(first_name__icontains = term) | Q(last_name__icontains = term))
       return qs

    stackoverflow.com/questions/9009635/django-queryse...

    Q objects

    Но вообще, если еще не поздно, я бы сделал одно поле full_name, first_name и last_name получал бы через методы модели, а поиск через icontains и проблем бы не было.
    Ответ написан
    8 комментариев
  • Как ВЫВЕСТИ все строки из базы sqlite на python?

    @javedimka
    Хочу сока
    Очевидно, что использовать правильный метод - fetchall()
    https://habrahabr.ru/post/321510/
    Ответ написан
    Комментировать
  • Как форматировать список list?

    @javedimka
    Хочу сока
    with open("list.txt","w") as file:
        for seq in product(key[0], key[1], key[2], repeat=1):
            print(' '.join(seq), file=file)
    Ответ написан
  • Как переопределить стиль форм в джанго?

    @javedimka
    Хочу сока
    Чтобы изменить стандартный вид отрисовки формы на твой собственный, можно переопределить метод __str__() формы:
    def __str__(self):
        return self.as_div()


    Второй вопрос какой-то очень не очень.
    html_class_attr - это строка которая генерируется в методе _html_output() на основе каких-то данных, каких - не знаю, надо копать глубже в сорцы, такое в доках не пишут.
    Ответ написан
  • Как в Python сделать вывод таблицей?

    @javedimka
    Хочу сока
    Самый простой способ с помощью Python вывести таблицу с данными в терминале или cmd это установить какой-нибудь модуль для ascii таблиц, например: PrettyTable

    $ pip install PrettyTable

    Теперь в коде:

    from prettytable import PrettyTable  # Импортируем установленный модуль.
    
    # Определяем твою шапку и данные.
    th = [...]
    td = [...]
    
    columns = len(th)  # Подсчитаем кол-во столбцов на будущее.
    
    table = PrettyTable(th)  # Определяем таблицу.
    
    # Cкопируем список td, на случай если он будет использоваться в коде дальше.
    td_data = td[:]
    # Входим в цикл который заполняет нашу таблицу.
    # Цикл будет выполняться до тех пор пока у нас не кончатся данные
    # для заполнения строк таблицы (список td_data).
    while td_data:
        # Используя срез добавляем первые пять элементов в строку.
        # (columns = 5).
        table.add_row(td_data[:columns])
        # Используя срез переопределяем td_data так, чтобы он
        # больше не содержал первых 5 элементов.
        td_data = td_data[columns:]
    
    print(table)  # Печатаем таблицу


    Вывод:
    +-------------------+---------------+------+-------------+------------+
    |    MAC Address    |   IP Address  | Mode | Rate (Mbps) | Signal (%) |
    +-------------------+---------------+------+-------------+------------+
    | 11:11:11:11:11:11 | 192.168.0.103 | 11n  |      65     |    100     |
    | 11:11:11:11:11:11 | 192.168.0.103 | 11n  |      65     |    100     |
    | 11:11:11:11:11:11 | 192.168.0.103 | 11n  |      65     |    100     |
    | 11:11:11:11:11:11 | 192.168.0.103 | 11n  |      65     |    100     |
    | 11:11:11:11:11:11 | 192.168.0.103 | 11n  |      65     |    100     |
    +-------------------+---------------+------+-------------+------------+


    А теперь представь сколько бесполезных разговоров могло быть опущено и времени сэкономлено, если бы у тебя с первого раза получилось нормально вопрос сформулировать? Вот то-то и оно.
    Ответ написан
    2 комментария
  • Не могу доделать цикл, нужно чтоб переберало по 1 ссылке, затем сохранял, картинку с сайта с новым именем, цикл есть разные но робит, как быть?

    @javedimka
    Хочу сока
    import requests
    import bs4
    
    
    tut = []
    names = []
    
    r = requests.get('https://vk.com/uporols_you').text
    soup = bs4.BeautifulSoup(r, 'lxml')
    im = soup.find_all('img', class_='ph_img')
    
    for a in im:
        s = a.get('data-src_big').split('|')[0]
        tut.append(s)
    
    for num, link in enumerate(tut):
        p = requests.get(link)
        out = open("img%s.jpg" % (num), 'wb')
        out.write(p.content)
        out.close()


    Все 5 смешных картинок сохранились в папку с именами (img0.jpg, img1.jpg и т.д.)
    for num, link in enumerate(tut, start=1): - если надо чтобы начиналось с 1, а не с нуля.

    Почему у тебя не работало? Ну в первом случае потому что range(1,5) дает последовательность чисел от единицы до 5, не включая 5, т.е. 1, 2, 3, 4. Получается картинок у тебя 5, а имен 4. Потом в один прекрасный момент в твоем цикле:

    for t, a in tut, names:

    переменной t был присвоен линк, а переменной а имя присвоено не было, поэтому ты получил ошибку:

    ValueError: too many values to unpack (expected 2)

    Хардкодить такое вообще странно, можно(не нужно) использовать "in len(range(tut))", а потом когда подскажут про enumerate - использовать enumerate.

    Вот только в первый раз код немного другой у тебя был, с генератором прямо в цикле. Теперь понятно почему я посоветовал посмотреть в генератор?

    Почему у тебя второй вариант не работал? Ну потому что надо понимать как работают вложенные циклы for в питоне. Чтобы понять, можно запустить такой код в интерпретаторе или терминале
    for i in ('a', 'b', 'c', 'd'):
        for x in ('1', '2', '3', '4'):
            print(i + " => " + x)

    Ты просто на каждой итераций 4 раза сохранял одну картинку и присваивал ей разные имена, потом на следующем линке делал тоже самое перезаписывая те 4 сохраненные картинки, в итоге все последние 4 сохраненные картинки это одна и та же картинка с последнего линка.

    Удачи.
    Ответ написан
    4 комментария
  • Как на python3 сделать аналог cmd?

    @javedimka
    Хочу сока
    Используй словарь.
    На твоем же примере read 2017 admin
    Функции в примере просто будут выводить все переданные аргументы:
    def create(*args):
        print("'Create' Function with given args:")
        for arg in args:
            print('%8s' % (arg))
    
    
    def read(*args):
        print("'Read' Function with given args:")
        for arg in args:
            print('%8s' % (arg))
    
    
    def update(*args):
        print("'Update' Function with given args:")
        for arg in args:
            print('%8s' % (arg))
    
    
    def delete(*args):
        print("'Delete' Function with given args:")
        for arg in args:
            print('%8s' % (arg))
    
    # Словарь с функциями. Ключом является вводимая команда.
    options = {"create": create,  "read": read, "update": update, "delete": delete}
    
    # Входим в бесконечный цикл, программа не будет завершаться после выполнения
    # первой же введенной команды.
    while True:
        # Получаем строку от пользователя и разбиваем по пробелам в список.
        # Если user input = read 2017 admin, то получим ['read', '2017', 'admin'].
        command = input("command? ->").split()
        # Используем метод словаря .get() для получения функции
        # связанной с введенной командой, записываем ее в переменную option.
        option = options.get(command[0])  # command[0] - операция индексации списка.
        # Проверяем удалось ли получить функцию связанную с командой пользователя.
        if option:
            # Если удалось, то вызываем функцию с аргументами полученными с помощью
            # операции извлечения среза и распаковки списка в отдельные аргументы.
            option(*command[1:])


    Вывод :
    command? ->read 2017 admin
    'Read' Function with given args:
        2017
       admin
    command? ->


    Бонусом небольшое объяснение про звездочку.

    Инструкция * в зависимости от того где она находится делает разные вещи(помимо умножения):

    В строке с объявлением функции ( def create(*args): ) она позволяет "запаковать" все переданные функции аргументы в один кортеж args. То есть нет необходимости указывать какие именно позиционные аргументы ожидает получить функция, можно передать любое их количество (нуль и более).

    В строке с вызовом функции ( option(*command[1:]) ) она позволяет "распаковать" все элементы последовательности в отдельные позиционные аргументы. То есть все объекты в указанной последовательности command[1:] будут передаваться в функцию как отдельные позиционные аргументы.

    В примере сверху если предварительно не распаковать command[1:] в отдельные аргументы, звездочка запакует в кортеж args целый список, т.е. получим (['2017', 'admin']) - кортеж с одним объектом внутри, что сломает наши функции, придется дополнить цикл тремя лишними символами для их работоспособности (добавить индексацию кортежа: for arg in args[0]). Если же распаковать, то получим кортеж с двумя объектами внутри, что позволит напрямую пройтись в цикле по кортежу.

    Больше информации про распаковку аргументов, индексацию списка и извлечению срезов можно найти в гугле. ( Например про родственника звездочки * двойную звездочку ** которая помогает в работе с именованными аргументами)
    Ответ написан
    Комментировать