Register Guidelines E-Books Today's Posts Search

Go Back   MobileRead Forums > E-Book Software > Calibre > Plugins

Notices

Reply
 
Thread Tools Search this Thread
Old 02-19-2021, 03:33 AM   #331
capink
Wizard
capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.
 
Posts: 1,196
Karma: 1995558
Join Date: Aug 2015
Device: Kindle
Quote:
Originally Posted by ownedbycats View Post
Could it be used to, for instance, put the average rating of a category into a custom column for icon rules? (Not sure how it would handle multiple categories though.)
The formulas action already has a "mean" function that should be able to handle things like this. You can combine it with from_search() function to get the desired result. See the help on formulas action for more.
capink is offline   Reply With Quote
Old 02-19-2021, 04:26 AM   #332
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,447
Karma: 8012886
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Quote:
Originally Posted by ownedbycats View Post
Could it be used to, for instance, put the average rating of a category into a custom column for icon rules? (Not sure how it would handle multiple categories though.)
Probably, depending on the details. One would select the category, then iterate through the selection adding the ratings for books in the category. The last step would be a single-field-edit to put the average into a custom column. This process could do multiple categories at the same time by using a tags-like column and for each category putting "category:rating" into the column.

A custom icon rule would extract the category of interest, separate out the rating, then choose the appropriate icon.
chaley is offline   Reply With Quote
Advert
Old 02-19-2021, 04:32 AM   #333
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,447
Karma: 8012886
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Quote:
Originally Posted by capink View Post
The formulas action already has a "mean" function that should be able to handle things like this. You can combine it with from_search() function to get the desired result. See the help on formulas action for more.
That is a good solution. "from_search" and "for" work together well in this case. Get the list of categories of interest, loop through them searching for books, compute the mean, then construct the result.
chaley is offline   Reply With Quote
Old 02-19-2021, 06:18 AM   #334
capink
Wizard
capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.
 
Posts: 1,196
Karma: 1995558
Join Date: Aug 2015
Device: Kindle
@chaley: The chain variables action already has a column (the value column) that accepts templates as value. I am thinking about adding the new functionality to this action; by adding a third column with a checkbox. When checked, the template will iterate over all books. I will also make right clicking the value cell pop up the template dialog.

I think that way you can, if you choose, skip the set_globals part because the new value will be automatically re-assigned to the named variable (the name column). Any thoughts?

Edit: set_global would still be used if a user wants to set more than one variable, as in your previous example, but must be sure to choose a different identifier in the chains variable name column.

Last edited by capink; 02-19-2021 at 06:24 AM.
capink is offline   Reply With Quote
Old 02-19-2021, 07:06 AM   #335
capink
Wizard
capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.
 
Posts: 1,196
Karma: 1995558
Join Date: Aug 2015
Device: Kindle
Another thing, does it make sense to persist some variables beyond the lifetime of the current chain? Maybe with additional option, or a certain prefix!
capink is offline   Reply With Quote
Advert
Old 02-19-2021, 07:47 AM   #336
compurandom
Wizard
compurandom ought to be getting tired of karma fortunes by now.compurandom ought to be getting tired of karma fortunes by now.compurandom ought to be getting tired of karma fortunes by now.compurandom ought to be getting tired of karma fortunes by now.compurandom ought to be getting tired of karma fortunes by now.compurandom ought to be getting tired of karma fortunes by now.compurandom ought to be getting tired of karma fortunes by now.compurandom ought to be getting tired of karma fortunes by now.compurandom ought to be getting tired of karma fortunes by now.compurandom ought to be getting tired of karma fortunes by now.compurandom ought to be getting tired of karma fortunes by now.
 
Posts: 1,012
Karma: 500000
Join Date: Jun 2015
Device: Rocketbook, kobo aura h2o, kobo forma, kobo libra color
Is there a reason to clear all the variables every time? Why not just leave them there, and if a chain wants to zero out totals before starting, it should be able to set them all at the start of the chain.

Is that too messy?
compurandom is offline   Reply With Quote
Old 02-19-2021, 07:54 AM   #337
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,447
Karma: 8012886
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Quote:
Originally Posted by capink View Post
@chaley: The chain variables action already has a column (the value column) that accepts templates as value. I am thinking about adding the new functionality to this action; by adding a third column with a checkbox. When checked, the template will iterate over all books. I will also make right clicking the value cell pop up the template dialog.
This will work well. I have made an example average_rating action using this idea. And yes, opening the template editor is a fine idea.
Quote:
I think that way you can, if you choose, skip the set_globals part because the new value will be automatically re-assigned to the named variable (the name column). Any thoughts?
You are right. However, someone might want to use a Formula action to see the result before changing the library metadata.
Quote:
Edit: set_global would still be used if a user wants to set more than one variable, as in your previous example, but must be sure to choose a different identifier in the chains variable name column.
You are right, but I suspect this won't be common. We will see.
chaley is offline   Reply With Quote
Old 02-19-2021, 08:20 AM   #338
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,447
Karma: 8012886
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Average Rating example

This example action computes the average rating for 3 Genres and their children then stores those ratings in a tags-like custom column in the form 'genre name':average_rating.

Here is the complete chain:
Click image for larger version

Name:	Clipboard01.jpg
Views:	871
Size:	50.4 KB
ID:	185466

It starts by selecting all the books in the library:
Click image for larger version

Name:	Clipboard04.jpg
Views:	873
Size:	70.4 KB
ID:	185465

It then runs a template to compute the average ratings, saving that value in a chain variable (global):
Click image for larger version

Name:	Clipboard02.jpg
Views:	894
Size:	21.6 KB
ID:	185467

The template in the chain variables action is:
Code:
program:
	genres = 'Comics, Mysteries, Science Fiction';
	res = '';
	for g in genres:
		ratings = from_search('rating', strcat('#genre:"=.', g, '"'));
		total = 0;
		cnt = 0;
		for r in ratings:
			if r != "None" then
				total = add(total, r);
				cnt = add(cnt, 1)
			fi
		rof;
		if cnt ># 0 then
			avg = divide(divide(total, 2), cnt)
		else
			avg = 0
		fi;
		res = list_union(res, strcat(g, ':', avg), ',')
	rof;
	res
I chose to ignore unrated books. If no books are rated then the average is set to zero. One could just as easily put nothing into the result.

@capink:I couldn't get the mean() function to work. How do I convert the result of "from_search()" to an "iterable"?

Next it saves the computed value to a tags-like column:
Click image for larger version

Name:	Clipboard05.jpg
Views:	876
Size:	26.8 KB
ID:	185469

The template in the Single Field Edit is
Code:
program:
	globals(avg_ratings = '');
An example of the output is:
Code:
Comics:1.5, Mysteries:2.0, Science Fiction:3.0
Finally it clears the selection:
Click image for larger version

Name:	Clipboard03.jpg
Views:	898
Size:	71.0 KB
ID:	185468
chaley is offline   Reply With Quote
Old 02-19-2021, 08:24 AM   #339
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,447
Karma: 8012886
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
BTW: there is a bug in the "for" statement. It doesn't strip leading and trailing blanks from list items. The above template uses a fixed version. The bug can be worked around using re() to strip of leading and trailing blanks. Or
Code:
g = list_item(g, 0, ',').
chaley is offline   Reply With Quote
Old 02-19-2021, 08:35 AM   #340
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,447
Karma: 8012886
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Quote:
Originally Posted by capink View Post
Another thing, does it make sense to persist some variables beyond the lifetime of the current chain? Maybe with additional option, or a certain prefix!
My concern is "mysterious behavior" that depends on a sequence of choices. I am not convinced that action A should affect action B. If it does then there should be something that explicitly declares "action global" variables that persist. Or perhaps the notion of "super actions" that run named actions in a sequence using the same globals dict.

The next question is their lifetime. Do they live for the calibre invocation, while a library is open, while a VL is open, or something else?
chaley is offline   Reply With Quote
Old 02-19-2021, 10:13 AM   #341
capink
Wizard
capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.
 
Posts: 1,196
Karma: 1995558
Join Date: Aug 2015
Device: Kindle
Quote:
Originally Posted by chaley View Post
This example action computes the average rating for 3 Genres and their children then stores those ratings in a tags-like custom column in the form 'genre name':average_rating.
Nice work.

Quote:
Originally Posted by chaley View Post
@capink:I couldn't get the mean() function to work. How do I convert the result of "from_search()" to an "iterable"?
I don't know what exactly is happening. But removing the spaces in the genres like below, makes it work. Will investigate this later:

This is working for me:

Code:
program:
	genres = 'Comics,Mysteries,Science Fiction';
	res = '';
	for g in genres:
		ratings = from_search('rating', strcat('#genre:"=.', g, '"'));
		avg = mean(ratings);
		res = list_union(res, strcat(g, ':', avg), ',')
	rof;
	res
Notice that mean discards any non numerical value. If someone wants None values to weigh on the average, modify as follows:

Code:
program:
	genres = 'Comics,Mysteries,Science Fiction';
	res = '';
	for g in genres:
		ratings = from_search('rating', strcat('#genre:"=.', g, '"'));
		ratings = re_non_numerical(ratings, 0);
		avg = mean(ratings);
		res = list_union(res, strcat(g, ':', avg), ',')
	rof;
	res
Also there is a bug with the mean function when it is fed an empty list or a list that contains no numerical values. Will fix this in the next release.

Quote:
Originally Posted by chaley View Post
My concern is "mysterious behavior" that depends on a sequence of choices. I am not convinced that action A should affect action B. If it does then there should be something that explicitly declares "action global" variables that persist. Or perhaps the notion of "super actions" that run named actions in a sequence using the same globals dict.

The next question is their lifetime. Do they live for the calibre invocation, while a library is open, while a VL is open, or something else?
That makes sense. Will leave it as it is for now. Maybe in the future will add a template function to let the user persist whatever he wants.

Edit1: No need to create a template function for that. If a user wants to persist data, he can create an empty book record and use the single field edit to persist data to it.

Edit2: from_search() and from_selection() always return an iterable (comma separated values).

Last edited by capink; 02-19-2021 at 10:31 AM.
capink is offline   Reply With Quote
Old 02-19-2021, 11:14 AM   #342
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,447
Karma: 8012886
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Quote:
Originally Posted by capink View Post
This is working for me:

[...]
Note that in both cases you must divide the result of mean() by 2, either at the call or later in the list_union. For historical reasons calibre keeps ratings as numbers between 0 and 10. One star == 2, two stars == 4, etc.

The following template does that divide. I also changed the search to include only rated books so that the template can avoid writing xxx:0 if no books with that category are rated.
Code:
program:
	genres = 'Comics, Mysteries, Science Fiction';
	res = '';
	for g in genres:
		ratings = from_search('rating', strcat('rating:true and #genre:"=.', g, '"'));
		if ratings then
			avg = divide(mean(ratings), 2);
			res = list_union(res, strcat(g, ':', avg), ',')
		fi
	rof;
	res
Quote:
Also there is a bug with the mean function when it is fed an empty list or a list that contains no numerical values. Will fix this in the next release.
This is what confused me. I was debugging both the consequences of the extra space in the for loop variable and mean() not working. The extra space meant that the search was empty, triggering the mean() problem you found.

BTW: this is fun, all of figuring out the details of how action chains works, the "logic problem" of how to chain the steps, and constructing templates that compute what is needed. I also am finding some template functions that I might add. One is[list_]count_matching(l, sep, pattern) that returns how many items in l match the pattern.
chaley is offline   Reply With Quote
Old 02-19-2021, 11:17 AM   #343
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,447
Karma: 8012886
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
The fix to the for statement is now in master source.
chaley is offline   Reply With Quote
Old 02-19-2021, 12:17 PM   #344
capink
Wizard
capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.
 
Posts: 1,196
Karma: 1995558
Join Date: Aug 2015
Device: Kindle
Quote:
Originally Posted by compurandom View Post
Is there a reason to clear all the variables every time? Why not just leave them there, and if a chain wants to zero out totals before starting, it should be able to set them all at the start of the chain.

Is that too messy?
The variables are not cleared. Every chain runs in a loop of its own, that is garbage collected as soon as the chain ends.

I think as chaley pointed out, it is better not to persist variables because you are going to run into scope problems.

However, the user has the option to persist some variables before exiting the chain. This can be done by creating and empty book and calling it something like 'persistent storage'. You can persist whatever data you want into this book, by using the selection modifier to select it, then the single field edit template option to persist.
capink is offline   Reply With Quote
Old 02-19-2021, 12:19 PM   #345
capink
Wizard
capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.
 
Posts: 1,196
Karma: 1995558
Join Date: Aug 2015
Device: Kindle
Quote:
Originally Posted by chaley View Post
Note that in both cases you must divide the result of mean() by 2, either at the call or later in the list_union. For historical reasons calibre keeps ratings as numbers between 0 and 10. One star == 2, two stars == 4, etc.
I forgot about that.


Quote:
Originally Posted by chaley View Post
I also changed the search to include only rated books so that the template can avoid writing xxx:0 if no books with that category are rated.
Excluding by search is definitely more elegant.


Quote:
Originally Posted by chaley View Post
BTW: this is fun, all of figuring out the details of how action chains works, the "logic problem" of how to chain the steps, and constructing templates that compute what is needed. I also am finding some template functions that I might add. One is[list_]count_matching(l, sep, pattern) that returns how many items in l match the pattern.
It is. Hopefully the pattern in the function you are proposing is going to be regex.

Quote:
Originally Posted by chaley View Post
The fix to the for statement is now in master source.
Good. I will wait a couple of days and go ahead with the changes.
capink is offline   Reply With Quote
Reply


Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
[Editor Plugin] Editor Chains capink Plugins 106 06-17-2025 05:36 PM
Action Chains Resources capink Plugins 77 06-16-2025 12:45 PM
[GUI Plugin] Noosfere_util, a companion plugin to noosfere DB lrpirlet Plugins 2 08-18-2022 03:15 PM
[GUI Plugin] Save Virtual Libraries To Column (GUI) chaley Plugins 14 04-04-2021 05:25 AM


All times are GMT -4. The time now is 05:58 AM.


MobileRead.com is a privately owned, operated and funded community.