04/24(月) 2017
はやりもの観察
https://instances.mastodon.xyz/list
jpぽいものの比率をなまあたかかく観察。
使う場合は、上のをユーザー数で並べ替えてからコピーしてファイルに保存しましょう。
#!/usr/bin/ruby # -*- coding: utf-8 -*- require 'optparse' selector='mstdn\.jp|pawoo|\.jp|\.nico|\.tokyo|\.nagoya|yokohama|\.osaka|japan|okinawa|ryukyu' barsize=100 file=false max=false limit=false raw=false upto=70 jp=false opt = OptionParser.new opt.on('-s size',"bar size") {|v| barsize=v.to_i } opt.on('-f d',"file name") {|v| file=v } opt.on('-m d',"max") {|v| max=v.to_i } opt.on('-l d',"limit") {|v| limit=v.to_i } opt.on('-u d',"limit sumPercent") {|v| upto=v.to_i } opt.parse!(ARGV) def mshow mark,num,max max=max.to_i half=max/2 mid1=max/4 mid2=max/4*3 st=max/8.0 blnk=" " max.times{|i| #break if i>num case i when half print"/" when max-1 print"|" when mid1,mid2 print":" when (st*5).to_i,(st*6).to_i,(st*7).to_i print"." when num..max print blnk else print mark end } per=format"%.1f",num*100/max per="" if mark=="-" puts " #{per}" end class Array def rejtop dust="Statuses.*Connections.*Registrations.*Uptime" if self.select{|i|i=~/^###|#{dust}/}.size>0 st=false tmp=[] self.each{|i| if st tmp<<i elsif i=~/^###|#{dust}/ st=true end } tmp else self end end end def ver li v=1 k=li.select{|i|i=~/Score.*Instance.*Version/}.size p k v=2 if k>0 v end class String def field split(/\t/) end end def usersField f ver=ver(File.readlines(f)) n=case ver when 1 [2,3] when 2 [2,4] else [2,3] end p [:v,ver] n end def calc f,k,fnum p k liAll=File.readlines(f) li0=liAll.rejtop li=li0.map{|d|d.field[fnum].to_i}-[0] jpRaw=li0.select{|i|i=~/#{k}/} jp=jpRaw.map{|d|d.field[fnum].to_i} sum=li.inject(0){|i,s|s+i} sumj=jp.inject(0){|i,s|s+i} med=li[li.size/2] li2=li-[1] med2=li2[li2.size/2] li3=li-[1,2] med3=li3[li3.size/2] under=Proc.new{|n,l| total=l.size [:"u#{n}", s=l.select{|i|i<n}.size,(format"%.1f%",s*100.0/total)] } small=[] small<<under.call(10,li) small<<under.call(100,li) small<<under.call(1000,li) wall=[] rate=0.84 li.each_cons(2){|i,j| r=format"%.2f",i.to_f/j wall<<[j,r] if i*rate>j && i-j>5 } [wall,med,med2,med3,small,sum,sumj,li,jpRaw,li0] end li=ARGV.map{|i|i.to_i} max=li.shift if ! max nf=2 uf=3 medium=0 medium2=0 medium3=0 small=0 wall=[] if file nf,uf=usersField(file) wall,medium,medium2,medium3,small,max,sumj,li,jp,raw=calc(file,selector,uf) end size=limit||li.size p [:user,max,:jp,sumj,format("%.2f%",sumj.to_f*100/max),:foreign,max-sumj,:medium,medium,:dropSmall,medium2,medium3,:instance,li.size,:jp,jp.size,format("%.2f%",jp.size.to_f*100/li.size),:iSmall,small] p [:cliff,wall] if $DEBUG p li p jp.map{|i|tmp=i.field;[tmp[nf],tmp[uf]]} p jp.size end ex=raw.map{|i|i.field[nf]=~/(\.[^\. ]*) *$/;$1} hs=Hash.new(0) ex.each{|k|hs[k]+=1} elimit=50 elimit=-1 if $DEBUG sep=" " puts "[rank order]",hs.keys.sort_by{|k|-hs[k]}.map{|k|"#{hs[k]}#{k}"}[0..elimit]*sep if $DEBUG puts "[name order]",hs.keys.sort.map{|k|"#{hs[k]}#{k}"}[0..elimit]*sep end puts raw[0,10].map{|i| d=i.field d=format"%-5s %7s %-26s %10s %15s",*d[0,5] if d.size>5 d } if upto n=0 tmp=0 pto=upto.to_f/100 li.each{|i| tmp+=i n+=1 break if tmp>pto*max } size=n end rate=barsize*1.0 size.times{|i| n=li[i]*rate/max mshow "*",n,rate } mshow "-",rate,rate def v list,key,num=3 (list.select{|i|i=~/#{key}/}[0]||"").field[num].to_i end def top3 list,key,nf=2,num=3 limit=3 ns0=list.select{|i|i=~/#{key}/}.map{|i|[i.field[nf],(i.field[num]||"").to_i]}.sort_by{|n,v|-v} ns=ns0[0,limit] cnum=5 p [:top,*ns0[0,cnum]] sum=ns.inject(0){|s,i|s+i[1]} end m,p,n=v(raw,"mstdn.jp",uf),v(raw,"pawoo",uf),v(raw,".nico",uf) t=top3(jp,"",nf,uf) puts "mstdn.jp #{m} pawoo #{p} :diff #{m-p}(#{format "%.2f",(m-p).to_f/m*100}%) jptop3:#{format"%.2f",t*100.0/max}%"
(動かないままだと何なので更新するが、それ以上の意味はないので、何かの参考にはしないように。手元で動くと面白いでしょうっていう程度の趣旨。jsonがあるようなのでそれを使った方がよい 2017-05-02)
むにゃむにゃ追っていたら
なんだかpawooのusersが一度1000くらい減った、id消せないということらしいのに、なにがあったのだろうか。調べないけど
コメント
トラックバック - http://rubyist.g.hatena.ne.jp/hatecha/20170424