Site Sponsors:
Paginated item-picker for console listings in Python 3 
Adding to the critical mass of things that many want to do - yet cannot find a nice example on how to do - submitted for your approval please find a little class I chose to call PrintPickerList:

"""
Opportunity to support the pagination of a list so
as to allow a console user to select an item therefrom.
"""


class PrintPickerList:

def __init__(self, array=[]):
"""
Initilize the class for assignment

:return: An item with an empty list
"""
self.last_selection = -1
self.pages = array
self.page_size = 20
self.use_list(array)

def use_list(self, zlist, szpage=20):
"""
:param zlist: a list() full of string items to choose from
:param szpage: The size of the page to scroll around.
:return: True if all was well
"""
if type(zlist) is not type(self.pages):
return False
self.last_selection = -1
self.pages = zlist
self.page_size = szpage
return True

def print_header(self):
"""
An opportunity to print a column header - called once per page view
:return: Nothing
"""
pass

def print_item(self, zbss):
"""
The default row-printing logic. Feel free to use inheritance to replace
and / or otherwise update this vector as you require / desire

:param zbss: The zero-based subscript of the item to print.
:return: Nothing
"""
print("{0:02d}:\t[{1:^50}]".format(zbss+1, self.pages[zbss]))

def pick_item(self):
"""
Allow the console user to page up and down thru list,
looking for an item to select. Once selected, the
array-adjusted element number will be returned.

:return: Array-subscript selected. -1 if no item was selected.
"""
page = 0
max = len(self.pages)
if max == 0:
return -1

while True:
self.print_header()
for item in range(page, max):
nzi = item + 1
self.print_item(item)
if nzi % self.page_size == 0:
break
try:
print("p = prev, n = next, q = quit, `n` = choice")
sel = input("Enter selection: ").strip()
if sel.isnumeric():
self.last_selection = -1 # jic
sel = int(sel)

self.last_selection = sel
self.last_selection -= 1 # array is n-1
break
else:
if sel == 'p':
page -= self.page_size
if sel == 'n':
page += self.page_size
if sel == 'q':
self.last_selection = -1 # Done - no selection
break

except Exception as ex:
print(ex)

finally:
while page >= max:
page -= self.page_size
if page < 0:
page = 0

# Clean-up the results:
if self.last_selection >= max:
self.last_selection = max - 1
if self.last_selection is not -1 and self.last_selection < 0:
self.last_selection = 0
return self.last_selection


if __name__ == '__main__':
doc = list()
for ref in range(100):
doc.append("Selection number" + str(ref))
pager = PrintPickerList()
if pager.use_list(doc) is False:
print("Big problem")
exit(-1)
sel = pager.pick_item()
selected = "No item selected."
if sel is not -1:
selected = doc[sel]
print("You selected '" + selected + "'")

The 'docstrings pretty much say it all. Yet allow us to note that we can paginate many other types - as well print column headers - by either updating, and / or inheriting + overriding:

    def print_header(self):
pass

def print_item(self, zbss):
print("{0:02d}:\t[{1:^50}]".format(zbss+1, self.pages[zbss]))

So if you have ever wanted to allow a user to scroll thru a large list of items - certainly if that list is far too large to readily fit on the screen - then you might enjoy putting PrintPickerList to work in your own Pythonic masterpieces. --It's 'kinda like having a more++ for use from within the Python console 'ui.


Enjoy the journey,

-Rn




BlogBlock[Python-Advanced-Classes]

Comments

Add Comment
Comments are not available for this entry.