CSVからデータを取り出して合計ポイントの計算まで完了しました。今回はそれをソートしてポイントラインキングっぽくしてきます。
HSPのソート命令を確認
文字列でのソートと数値でのソートがありますが、今回はポイントランキングなので当然「数値」のソートを利用します。
配列変数を数値でソート
sortval p1,p2
p1 : 数値型の配列変数名
p2 : 並び順 (0=小さい順/1=大きい順)
そう難しくはなさそうですね。ただ、数字を並び替えるなら、対応するドライバー名も並び替えないと意味がありません。そのための命令を探すと
ソート元のインデックスを取得
sortget p1,p2
p1 : 結果が代入される変数名
p2 : インデックスNo.
ソートした際にその元のインデックスが取得できるので、これを使うと良さそうですね。
ソートしてみよう
では、実際にプログラムを書いてみます。ポイントをソートするので
sortval driver_point, 1
ソートしたものを順番に調べて、元インデックスを取得。そこから対応するドライバー名を探し出す。ということで
repeat (ドライバー数) sortget num, cnt sort_driver(cnt) = driver_name(num) loop
上で使用するsort_driverを用意しておきましょう。
sdim sort_driver 40, 40
さらに用心して
ドライバー名が空だったりする場合がありそうなので、その部分を回避するように処理しておきましょう。
if driver_name(num) = "" : continue
さらに、ここでは簡易出力の予定なのでトップテンまでにしておけば、ドライバー名が空になることはほぼ無いと思われます(現在のルールでは10位までポイントが付与されるので)。ということでrepeatの回数はドライバー数から「10」に変更します。
repeat 10 sortget num, cnt if driver_name(num) = "" : continue sort_driver(cnt) = driver_name(num) loop
ここまでをチェックしてみると
ちゃんとトップテンがソートで表示されてますね!
htmlで簡易出力してみる
簡易的にhtml出力する形ですが、それならランキングを出力するプログラムの方が詳細が分かるのでこの部分で出力する意味があまりない状態になってしまいます。なので少し改良したいと思います。
- どのグランプリが終了した段階のものかを表示させる
- 各グランプリへのリンクを張る
といったことに挑戦してみたいと思います。
最新グランプリ名を取得
csvからグランプリ名を取得します。現時点で終わっているグランプリの中で一番新しいのは項目の部分、後ろから3つ目に格納されている文字を使うと良さそうです。
考え方としては以下の感じでしょうか。
- 項目部分をsplitで分割して、statに収まった分割した数から3を引けば該当する部分の文字列が取得できる
コードにしてみると
noteget text_line, 0 split text_line , ",", buf lastracename = buf(stat - 3)
さらに、「 result:pos」といういらない文字を消去しておきたいので
strrep lastracename, " result:pos", ""
を追加します。これで最新のグランプリ名が取得できました。
リンク処理用のデータ取得
次にリンク処理用のデータですがファイル名をレース順に取得していきたところ。そういえばCSVを出力する際に使用したのが「GP名+ result:pos」だったのは、先ほどの最新グランプリ名の取得で利用したので覚えているかと思います。で、ファイル名の法則はというと
GP名+ result.html
だったりします。つまり、「 result:pos」を「 result.html」にすることでファイル名の取得もできそうですね。
また、レース名が入っている場所は
- レース名:(3 × n + 1)番目 n=0、1、2、3…
となるので、発想を逆転してみると(おぉ、逆転裁判w)
- レース名:nを3で割った時に余りが1の場所 n=0、1、2、3…
となります。これをふまえてhtmlのタグを作ってしまいましょう。
a_tag = "" repeat race_cnt if (cnt\3 != 1) : continue a_text = filename(cnt) : strrep a_text, ":pos", "" a_link = filename(cnt) : strrep a_link, ":pos", ".html" a_tag += "<a href='html/" + a_link + "'>" + a_text + "</a> " loop
今回のポイントランキング簡易htmlはhtmlフォルダに入れない予定なので、aタグ部分に「html/」を付与してます。
htmlを作成する
さて、タグ部分もできたので、本体になるhtml部分を作成していきましょう。タイトルは「2017 ポイントランキングtop10」にします。そして、1~10位の順番でドライバー名とポイントを並べて、その下にレースの詳細へのリンクを用意。さらに、終了GP名を記載。これをhtmlで書くと
<h1>2017 ポイントランキングtop10</h1> <ul><li> <div class="drivername">Nico Rosberg</div> <div class="point">385</div> </li> (中略) </ul> <p>※ABU DHABI GP 終了時点のランキング</p> (aタグ)
という感じにします。これをコードにおこすと
html_text = (htmlの定型部分+簡単なcss+タイトルなど) repeat 10 html_text += "<li>\n<div class=\"drivername\">" + sort_driver(cnt) + "</div>\n<div class=\"point\">" + driver_point(cnt) + "</div>\n</li>\n" loop html_text += "</ul>\n<p>※ " + lastracename + " 終了時点</p>\n" + a_tag + "</body>\n</html>\n"
そして、最後に保存部分を記述します。
nkfcnv html_text,html_text,"Sw" //HTML出力 chdir home_pos notesel html_text notesave "pointranking.html" noteunsel
これで完成! 実行してみると
htmlを開いてみると
Japan GP result をクリックすると
それっぽく出力できたんじゃないでしょうか?
まとめ
今回は全戦CSVからドライバーランキングtop10と各レース結果のリンク付きのhtml出力を作成しました。それっぽい仕上がりになったんじゃないでしょうか? 途中にあるコードだけでは分かりにくい部分もあると思うので、この下にある全コードと比較しつつ見ていただけると幸いです。いよいよF1開幕まであと少し。今年はどんな展開が繰り広げられるんでしょうか? 楽しみです。
#include "hspinet.as" // into_pos home_pos = dir_cur html_pos = dir_cur + "\\html" csv_pos = dir_cur + "\\csv" // folder_check dirlist chk, "*.*", 5 if instr(chk, 0, "html") = -1 : mkdir "html" if instr(chk, 0, "csv") = -1 : mkdir "csv" // csv_check chdir home_pos dirlist chk, "Raceresulturl.csv" await 1 if (stat = 0) { csv_text = "GP Name,URL\n" } else { notesel csv_text noteload "Raceresulturl.csv" noteunsel } chdir csv_pos dirlist chk, "allresult.csv" await 1 if (stat = 0) { allresult_csv = "driver Name" } else { notesel allresult_csv noteload "allresult.csv" noteunsel } // 初期設定 chdir home_pos sdim driver_name, 40, 40 dim driver_point, 40, 40 sdim sort_driver, 40, 40 //main notesel allresult_csv // lastracename & filename a tag noteget text_line, 0 split text_line , ",", filename race_cnt = stat lastracename = filename(stat - 3) strrep lastracename, " result:pos", "" a_tag = "" repeat race_cnt if (cnt\3 != 1) : continue a_text = filename(cnt) : strrep a_text, ":pos", "" a_link = filename(cnt) : strrep a_link, ":pos", ".html" a_tag += "<a href='html/" + a_link + "'>" + a_text + "</a> " loop //dialog a_tag repeat notemax, 1 noteget text_line, cnt split text_line, ",", csv_data if csv_data(0) = "" : break driver_name(cnt) = csv_data(0) race_cnt = (stat - 1) / 3 sum_point = 0 repeat race_cnt sum_point += int(csv_data(3*cnt+2)) loop driver_point(cnt) = sum_point loop sortval driver_point, 1 repeat 10 sortget num, cnt if driver_name(num) = "" : continue sort_driver(cnt) = driver_name(num) //mes sort_driver(cnt) + "\t:" + driver_point(cnt) loop noteunsel // makehtml html_text = "<!DOCTYPE html>\n<html>\n<head>\n<meta charset=\"utf-8\">\n<meta http-equiv=\"content-language\" content=\"ja\">\n<title>2017 ポイントランキングtop10</title>\n<style>\nbody {\ncounter-reset: drivername;\n}\nli {\ndisplay: flex;\n}\ndiv {\nmargin-right: 1rem;\n}\n.drivername, .team {\nwidth: 12rem;\n}\n.country {\nwidth: 6rem;\n}\n.drivername:before {\ncounter-increment:drivername;\ncontent:counter(drivername) \"位 \";\ndisplay: inline-flex;\nwidth: 3rem;\n}\n</style>\n</head>\n<body>\n<h1>2017 ポイントランキングtop10</h1>\n<ul>" repeat 10 html_text += "<li>\n<div class=\"drivername\">" + sort_driver(cnt) + "</div>\n<div class=\"point\">" + driver_point(cnt) + "</div>\n</li>\n" loop html_text += "</ul>\n<p>※ " + lastracename + " 終了時点</p>\n" + a_tag + "</body>\n</html>\n" //dialog html_text nkfcnv html_text,html_text,"Sw" //HTML出力 chdir home_pos notesel html_text notesave "pointrankingtop10.html" noteunsel end stop