View Single Post
Old 12-19-2023, 05:44 AM   #4
chaley
Grand Sorcerer
chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.
 
Posts: 12,476
Karma: 8025702
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
You can generate a list of books in a series (or any other column) with at least N books in the series with a template search. I felt like playing with it and here is a solution that works for me.

Steps:
  1. Create a stored template (Preferences / Template functions / Stored templates).
    • The template name is 'count_books_with_same_field_value'. It can actually be what you want, but it must be a valid name and you must use this name below.
    • The template is
      Code:
      python:
      def evaluate(book, context):
      	args = context.arguments
      	if args is None or len(args) != 2:
      		return 'Bad argument count. Must be 2 (column, count)'
      	
      	column = args[0]
      	min_count = int(args[1])
      
      	globals = context.globals
      	db = context.db.new_api
      
      	if globals is None or 'possibles' not in globals:
      		possibles = set()
      		id_count_map = db.get_usage_count_by_id(column)
      		for id,count in id_count_map.items():
      			if count >= min_count:
      				possibles.add(db.get_item_name(column, id))
      		globals['possibles'] = possibles
      
      	possibles = globals['possibles']
      	book_vals = db.field_for(column, book.id)
      
      	if not isinstance(book_vals, (tuple, list)):
      		book_vals = list((book_vals,))
      	for v in book_vals:
      		if v in possibles:
      			return '1'
      	return ''
    • Press the "Create" button to store the template.
    Here is a screen capture of the Stored template dialog.
    Click image for larger version

Name:	Clipboard01.jpg
Views:	517
Size:	162.1 KB
ID:	205326
  2. Create a template search
    • Click the "Advanced search" icon in the search bar (a gear).
    • Choose "Template search"
    • Set the "Template value" to "True"
    • Set the "Comparison type" to "Set/Not set"
    • Set the "Template" to
      Code:
      program: count_books_with_same_field_value('series', 4)
      where 'series' is the column lookup key you want to check, and '4' is the minimum count you want.
    • Here is a screen capture of the Template search dialog
      Click image for larger version

Name:	Clipboard02.jpg
Views:	476
Size:	71.5 KB
ID:	205327
  3. Save the new template search as a saved search if you wish

For example, this template search:
Code:
template:"""program: count_books_with_same_field_value('series', 4)#@#:b:True"""
will produce a list of books in any series with at least 4 books.

Comparison of approaches:
  • The techniques mentioned in the above posts do something similar, one item at a time. For example, sorting by count in the tag browser then clicking on a series with the count you wish will produce a list of books in that series.
  • The template search approach described here produces a list of books in all series with at least the count you wish.
I can't say which technique works better for you.
chaley is offline   Reply With Quote