[PYTHON] I searched for works that are highly evaluated by Naro

Completely for myself. First of all, I don't know the Markdown format, so I don't show it to people. If you want to know only the result, here

Overview

Isn't the ranking of Naruro works reliable? → I want to know interesting works! !! → Ranking from monthly ranking and quarterly ranking based on average evaluation score

→ Works with a rating of 500 or less may be biased (law of large numbers), so I excluded them though it is bad! Since the deviation value is also added to the evaluation points, the works that seem to be interesting are obvious! You did it!

Click here for the code! I wrote it all in pythonista on iphone! I'm a high school student and forgive me for dirty codes!

I made it messily with the momentum, so even if I make a mistake, it is not something that can be shown to people.


import requests,json,datetime,math
import console #Maybe the pythonista library?
from statistics import mean,stdev
#from time import sleep(For debugging)
#from pprint import pprint(For debugging)


today = datetime.date.today().strftime('%Y%m%d')

bg = {
	1: 'love',
	2: 'Fantasy',
	3: 'Literature',
	4: 'SF',
	99: 'Other',
	98: 'Non-genre'
	}
gg = {
	101: 'Another world [romance]',
	102: 'Real world [romance]',
	201: 'High fantasy [fantasy]',
	202: 'Low fantasy [fantasy]',
	301: 'Junbungaku [Literature]',
	302: 'Human drama [literary arts]',
	303: 'History [literary arts]',
	304: 'Detective story [literary arts]',
	305: 'Horror [literary arts]',
	306: 'Action [literary arts]',
	307: 'Comedy [literary arts]',
	401: 'VR game [SF]',
	402: 'Space [SF]',
	403: 'Science fiction [SF]',
	404: 'Panic [SF]',
	9901: 'Fairy tale [Other]',
	9902: 'Poetry [Other]',
	9903: 'Essay [Other]',
	9904: 'Replay [Other]',
	9999: 'Other [Other]',
	9801: 'Non-genre [non-genre]'
}


def uni(seq):
	seen = []
	return [x for x in seq if x not in seen and not seen.append(x)]


#Get monthly ranking information
def otherlist():
	u = 'https://api.syosetu.com/rank/rankget/?&out=json&rtype='+today[:6]+'01-m'
	al = requests.get(u)
	ali = json.loads(al.text)
	return ali


#narrow.Read the guy you added to txt
def get_add_data():
	with open('narrow.txt') as f:
		l_strip = [s.strip() for s in f.readlines()]
	return uni(list(filter(lambda a: a != '', l_strip)))#Avoid duplication with empty data and return
	


#Pass the ncode of your favorite novel and a file for additional data(narrow.txt)Write to
def add_data(ncode):
	with open('narrow.txt', mode='a') as f:
		f.write(ncode+'\n')
	print('success')
	
def getdata():
	c = 0
	#Analysis from quarterly ranking
	u1 = 'https://api.syosetu.com/rank/rankget/?&out=json&rtype='+today[:6]+'01-q'
	zen = requests.get(u1)
	zeli = json.loads(zen.text)
	#Get quarterly ranking novel information
	
	add_list = otherlist()
	#Monthly ranking data added
	for i in get_add_data():
		#Further narrow.Add ncode written in txt
		add_list = add_list +[dict(ncode=i)]
	for a in add_list:
		zeli.append(a)
		
	#At this point zeli has a quarter,Monthly ranking+narrow.Contains additional data for txt
	
	all_data = list()
	errors = list()
	l = len(zeli)
	for n in zeli:
		url='https://api.syosetu.com/novelapi/api/?out=json&of=t-w-r-a-ah-bg-g-ka&ncode='+n['ncode']
		#Get novel information from ncode
		
		detail = dict()
		
		res = requests.get(url)
		text = json.loads(res.text)
		
		i=zeli.index(n)
		
		#A nice loading bar found on the net
		bar_template = "\r[{0}] {1}/{2}   {3}"
		x = math.ceil(l/30)
		p = math.ceil(((l-i)/x))
		
		#Adjustment to prevent the bar from collapsing(Without this, every multiple of 10 will be jerky)
		if(p+i/x < 30):p = p + 1
		elif (p+i/x > 30):p = p - 1
		
		if(i!=l):com='Loading'
		else:com='Loading completed'
		bar = "#" * math.ceil(i/x) + " " * p
		print(bar_template.format(bar,i,l,com), end="")
		
	
		if(text[0]['allcount']==0):
			errors.append('Error:Ncode='+n['ncode'])
			
		else:
			text=text[1]
			detail['Number of people to evaluate']=text['all_hyoka_cnt']
			detail['Average rating']=math.ceil(text['all_point']*10000/text['all_hyoka_cnt'])/1000
			
			detail['Title of work']=text['title']
			detail['Number of reviews']=text['review_cnt']
			detail['Conversation rate']=text['kaiwaritu']
			detail['Large genre']=bg[text['biggenre']]
			detail['Small genre']=gg[text['genre']]
			all_data.append(detail)
			c = c + 1
			
			#if c == 10:
				#return all_data
			
	for error in errors:
		print('\n'+error)
	#It spits out ncode which was a read error because it was deleted
	
	return all_data
	


def main():
	sources = getdata()
	l = len(sources)
	sources = uni(sources)
	
	ex = 0
	lr = []
	l0 = []
	l1 = []	#Evaluation number of 1000 or more
	l2 = []
	l3 = []
	l4 = []
	l5 = []
	
	console.clear()
	#pythonista3 console clear
	
	for data in sources:
		if(data['Number of people to evaluate'] < 500):
			#Excludes less than 500 evaluations(To prevent bias such as 10 points by one evaluation)
			ex = ex + 1
			#Exclusion number measurement
		else:
			lr.append(data['Title of work'])		#Title of workリスト
			l0.append([data['Title of work'], data['Average rating']])	#Title of workとAverage ratingの関係
			l1.append(data['Average rating'])	#Evaluation point list
			l3.append([data['Title of work'], data['Small genre']])	#Title of workとSmall genreの対応
			l4.append([data['Title of work'], data['Conversation rate']])	#Title of workとConversation rateの対応
			l5.append([data['Title of work'], data['Number of reviews']])	#Title of workとNumber of reviewsの対応
	
	mn = mean(l1)	#Average evaluation points of all analyzed works
	sd = stdev(l1)	#Evaluation point standard deviation
	k = 0
	
	for x in l1:	#Find the deviation value h
		h = ((x-mn)*10/sd)+50
		l2.append([lr[k],math.ceil(h*100)/100])
		k=k+1

	d1 = dict(l0)	#Work name and evaluation points
	d2 = dict(l2)	#Work name and deviation value
	
	d3 = dict(l3)	#Work name and small genre
	d4 = dict(l4)	#Title of work and conversation rate
	d5 = dict(l5)	#Title of work and number of reviews
	
	d1_sorted = sorted(d1.items(), key=lambda x:x[1], reverse=True)	#Sort the evaluation points in order of rank
	d2_sorted = sorted(d2.items(), key=lambda x:x[1], reverse=True)	#Sort deviation values
	
	w = 0
	print('Total number of data:'+str(l))
	print('Number of cases not evaluated(Evaluation number less than 500):'+str(ex))
	print('Number of net data without duplication:{}'.format(len(sources)))
	print('Average rating:'+str(math.ceil(mn*10000)/10000))
	for y in d1_sorted:
		print('##'+str(w+1)+'Rank\n###『'+y[0]+'』\n genre:'+d3[y[0]]+'\n Evaluation points:'+str(y[1])+'\n Evaluation deviation value:'+str(d2_sorted[w][1])+'\n Sentence conversation rate:'+str(d4[y[0]])+'%\n Number of reviews:'+str(d5[y[0]]))
		#The average evaluation score is 100 points.
		w = w + 1	#Find out what value
		
if __name__ == '__main__':
	main()
	#If you want to search for a novel, please search with another editor

And the result

The top 10 works that seemed interesting (high average rating) were:

By the way, my favorite is Rebuild World.

There were some works I didn't know at all, so I'll read them.

1st place "Book lover Shimojo-I can't choose the means to become a librarian-"

2nd place "Matter that was made a useless human by the angel next door"

3rd place "Shangri-La Frontier-Kusoge Hunter, Challenge God Game-"

4th place "Holy Cup of Ellis"

5th place "Rebuild World"

6th place "Ghost of mourning wants to retire-The weakest hunter dreams of a hero- [Web version]"

7th place "As a result of a fake marriage with an otaku colleague, every day is a lot of fun! 』\

8th place "Rosa, the nobleman wants to watch over love from the shadows"

9th place "King of the Dead in the Palace of the Dead [Web version]"

10th place "Deacon of the villain daughter-She I raised is very cute- (serialized version)"

Detailed results are here

Recommended Posts

I searched for works that are highly evaluated by Naro
I searched for CD commands.
I searched for prime numbers in python
[Python] I searched for various types! (Typing)
I tried installing a driver for a NIC that is not recognized by Linux