Реализуйте список

Мне нужно реализовать список для мобильного телефона. Единственные соответствующие элементы управления - это клавиши со стрелками вверх и вниз. В списке должно отображаться столько строк элементов из списка, сколько поместится на экране (screen_rows), одна строка должна быть выделена (sel_row), и отображение должно завершаться, если пользователь нажимает стрелку вверх при выделении первого элемента или стрелку вниз если выделен последний элемент (то есть, последний элемент должен отображаться и выделяться, если пользователь нажимает кнопку, когда выделен первый элемент). Стрелка вверх выделяет предыдущий элемент, а стрелка вниз - следующий.

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

def up_key(self):
    if self.sel_row > 0:
       self.sel_row -= 1

    elif self.top_item > 0:  # top_item is the index of the first list item 
        self.top_item -= 1

    elif self.top_item == 0:
        if self.n_lines >= self.screen_rows: # n_lines is the number of items in the list
            self.top_item = self.n_lines - self.screen_rows
            self.sel_row = min(self.screen_rows-1, self.n_lines-1)
        else:
            self.top_item = 0
            self.sel_row = self.n_lines-1


def down_key(self):
    if self.sel_row < self.screen_rows-1 and self.sel_row < self.n_lines-1:
        self.sel_row += 1

    elif self.sel_row == self.screen_rows-1:
        bottom_item = self.top_item + self.screen_rows
        if bottom_item == self.n_lines:
            self.top_item = 0
            self.sel_row = 0
        if bottom_item < self.n_lines:
            self.top_item += 1

    elif self.sel_row == self.n_lines-1:
        self.top_item = 0
        self.sel_row = 0

def set_pos(self, pos):  # display item with index pos
    if pos < 0:
        pos = 0
    elif pos >= self.n_lines:
        pos = self.n_lines - 1

    if pos < self.screen_rows:
        self.top_item = 0
        self.sel_row = pos
    else:
        self.sel_row = min(self.screen_rows, self.n_lines)//2 - 1
        self.top_item = pos - self.sel_row
        if self.top_item >= self.n_lines - self.screen_rows:
            self.top_item = self.n_lines - self.screen_rows - 1
            self.sel_row = pos - self.top_item - 1

РЕДАКТИРОВАТЬ: после каждой функции я вызываю функцию перерисовки экрана, которая перерисовывает экран с top_item вверху и выделенной строкой sel.

Я добавил тег псевдокода на случай, если у кого-то есть версия для чего-то, кроме Python.


person foosion    schedule 20.10.2009    source источник


Ответы (1)


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

Переходя к вашему коду, я полагаю, что set_pos должен вызываться сразу после того, как up_key или down_key будут завершены (вы не разъясняете это полностью).

Меня больше всего беспокоит повторяемость и асимметрия между вашими двумя _key процедурами. Конечно, учитывая, что ваши спецификации настолько похожи для клавиш вверх и вниз, вы хотите делегировать одну функцию, которая принимает аргумент «приращение», либо +1, либо -1. Эта общая функция может сначала выполнить self.sel_row += increment, а затем немедленно вернуться в обычном случае, когда sel_row все еще в порядке, т.е. if self.top_item <= self.sel_row < self.top_item + self.screen_rows; в противном случае обработайте случаи, когда sel_row покинул текущую отображаемую область, настроив self.top_item, завершив работу, если это не вызывает необходимости зацикливания, или, наконец, обработайте случаи зацикливания.

Я бы очень хотел применить «плоский лучше, чем вложенный», многократно используя конструкции вида «сделать некоторый требуемый шанс состояния; если сейчас все в порядке, вернуть», а не логически более сложный », если простое выполнение будет в порядке , затем сделайте простое; иначе, если нужно что-то посложнее, но не ужасное, тогда сделайте что-нибудь сложное; иначе, если мы находимся в действительно сложном случае, займитесь действительно сложной проблемой "- последнее далеко более подвержен ошибкам и в любом случае труднее следовать.

person Alex Martelli    schedule 20.10.2009
comment
Раньше я видел списки, реализованные на c или c ++, в первые годы программирования с графическим интерфейсом, но я не мог найти никаких примеров. В любом случае, я посмотрю, упростит ли это изменение, как вы предлагаете, и вернусь, если потребуется. - person foosion; 20.10.2009
comment
@foosion, да, до появления GUI-фреймворков и виджетов с разумной функциональностью, когда кто-то программировал до голого xlib или тому подобного, он писал свои собственные виджеты - был там, сделал это, но LONG < / i> время назад! -) - person Alex Martelli; 21.10.2009
comment
@Alex, прошло всего около 20 лет :-) - person foosion; 21.10.2009