Added a CLI-Interface and 'analyze' command

This commit is contained in:
Dominik Moritz Roth 2021-06-16 15:12:26 +02:00
parent 051a22b124
commit 00c72df281

155
main.py
View File

@ -306,7 +306,7 @@ def scoreUnread(G, globMu, globStd, errorFac=0.6):
node['score'] = None node['score'] = None
def printBestList(G, num=25): def printBestList(G, num=-1):
bestlist = [] bestlist = []
for n in list(G.nodes): for n in list(G.nodes):
node = G.nodes[n] node = G.nodes[n]
@ -317,7 +317,7 @@ def printBestList(G, num=25):
for i, book in enumerate(bestlist): for i, book in enumerate(bestlist):
print("["+str(i+1).zfill(int(math.log10(num)+1))+"] "+book['title'] + print("["+str(i+1).zfill(int(math.log10(num)+1))+"] "+book['title'] +
" ("+" & ".join(book['authors'])+"): {:.5f}".format(book['score'])) " ("+" & ".join(book['authors'])+"): {:.5f}".format(book['score']))
if i == num-1: if num!=-1 and i == num-1:
break break
@ -475,12 +475,8 @@ def genScores(G, books):
return globMu, globStd return globMu, globStd
def recommendNBooks(n): def recommendNBooks(G, mu, std, n):
G, books = buildFullGraph()
mu, std = genScores(G, books)
removeRestOfSeries(G) removeRestOfSeries(G)
removePriv(G)
removeBad(G, mu-std-1.5) removeBad(G, mu-std-1.5)
removeKeepBest(G, int(n*2) + 5, maxDistForRead=1.5) removeKeepBest(G, int(n*2) + 5, maxDistForRead=1.5)
removeEdge(G) removeEdge(G)
@ -501,15 +497,7 @@ def recommendNBooks(n):
scaleOpinionsByRating(G) scaleOpinionsByRating(G)
addScoreToLabels(G) addScoreToLabels(G)
printBestList(G, num=n) def fullGraph(G):
genAndShowHTML(G, True)
def fullGraph():
G, books = buildFullGraph()
mu, std = genScores(G, books)
removePriv(G)
removeEdge(G) removeEdge(G)
removeHighSpanTags(G, 7) removeHighSpanTags(G, 7)
removeDangling(G, alsoBooks=False) removeDangling(G, alsoBooks=False)
@ -521,19 +509,14 @@ def fullGraph():
scaleOpinionsByRating(G) scaleOpinionsByRating(G)
addScoreToLabels(G) addScoreToLabels(G)
printBestList(G, num=100)
genAndShowHTML(G)
def readBooksAnalysis(G, minRating=0, showAllTags=True, removeUnconnected=False):
def readBooksAnalysis():
G, books = buildFullGraph()
mu, std = genScores(G, books)
removePriv(G)
removeUnread(G) removeUnread(G)
removeBad(G, minRating)
if not showAllTags:
removeEdge(G) removeEdge(G)
removeHighSpanTags(G, 15) removeHighSpanTags(G, 15)
removeDangling(G, alsoBooks=False) removeDangling(G, alsoBooks=removeUnconnected)
removeTopLists(G) removeTopLists(G)
pruneTags(G, 8) pruneTags(G, 8)
@ -541,9 +524,125 @@ def readBooksAnalysis():
scaleOpinionsByRating(G) scaleOpinionsByRating(G)
addScoreToLabels(G) addScoreToLabels(G)
printBestList(G, num=100)
def analyze(G, type_name, name, dist=2.7):
from fuzzywuzzy import fuzz
type_ident = type_name[0]
full_name = type_ident + "/" + name
bestRatio, match, n = 0, None, 0
for ni in list(G.nodes):
node = G.nodes[ni]
if node['t'] == type_name or type_name=="any":
if name==node['label'] or full_name==node['label']:
match, n = node, ni
break
ratio = fuzz.ratio(node['label'], name)
if ratio > bestRatio:
bestRatio, match, n = ratio, node, ni
menge = set()
pruneDist(G, match, n, dist, menge)
for n in list(G.nodes):
if n not in menge:
G.remove_node(n)
removeHighSpanTags(G, 12)
if dist > 1:
removeDangling(G, True)
scaleBooksByRating(G)
scaleOpinionsByRating(G)
match['value'] += 100
addScoreToLabels(G)
def pruneDist(G, node, n, dist, menge, firstEdge=False):
if dist <= 0:
return
dist -= 1
if menge==set():
firstEdge=True
menge.add(n)
if node['t'] in ['tag']:
if firstEdge:
dist-=0.1
else:
return
bestlist = []
keeplist = []
for m in list(G.adj[n]):
book = G.nodes[m]
if book['t'] not in ['topList']:
if 'score' in book and book['score'] != None:
bestlist.append(book)
elif 'rating' in book and book['rating'] != None:
keeplist.append(book)
else:
book['score'] = 0
bestlist.append(book)
bestlist.sort(key=lambda node: node['score'], reverse=True)
toKeep = min(int(dist*10), math.ceil(len(bestlist) * dist - len(keeplist)*0.5))
if toKeep <= 0:
keeplist.sort(key=lambda node: node['rating'], reverse=True)
keeplist = keeplist[:min(int(dist*10), int(len(keeplist) * dist))]
bestlist = []
else:
bestlist = bestlist[:toKeep]
for m in list(G.adj[n]):
node = G.nodes[m]
if node in bestlist or node in keeplist:
pruneDist(G, node, m, dist, menge, firstEdge=firstEdge)
def cliInterface():
import argparse
parser = argparse.ArgumentParser(description='TODO: Write Description.')
parser.add_argument('--keep-priv', action="store_true")
parser.add_argument('--remove-read', action="store_true")
parser.add_argument('--remove-unread', action="store_true")
parser.add_argument('--no-web', action="store_true")
parser.add_argument('--no-list', action="store_true")
cmds = parser.add_subparsers(required=True, dest='cmd')
p_rec = cmds.add_parser('recommend', description="TODO", aliases=['rec'])
p_rec.add_argument('-n', type=int, default=25, help='number of books to recommend')
p_read = cmds.add_parser('read', description="TODO", aliases=[])
p_read.add_argument('--min-rating', type=int, default=0)
p_read.add_argument('--all-tags', action="store_true")
p_read.add_argument('--only-connected', action="store_true")
p_show = cmds.add_parser('analyze', description="TODO", aliases=[])
p_show.add_argument('type', choices=['any', 'book', 'recommender', 'author', 'series'])
p_show.add_argument('name', type=str)
p_show.add_argument('-d', type=float, default=2.7, help='depth of expansion')
p_full = cmds.add_parser('full', description="TODO", aliases=[])
args = parser.parse_args()
G, books = buildFullGraph()
mu, std = genScores(G, books)
if not args.keep_priv:
removePriv(G)
if args.remove_read:
removeRead(G)
elif args.remove_unread:
removeUnread(G)
if args.cmd=="recommend":
recommendNBooks(G, mu, std, args.n)
elif args.cmd=="read":
readBooksAnalysis(G, args.min_rating, args.all_tags, args.only_connected)
elif args.cmd=="analyze":
analyze(G, args.type, args.name, args.d)
elif args.cmd=="full":
fullGraph(G)
else:
raise Exception("Bad")
if not args.no_list:
printBestList(G)
if not args.no_web:
genAndShowHTML(G) genAndShowHTML(G)
if __name__ == "__main__": if __name__ == "__main__":
recommendNBooks(45) cliInterface()