野球リーグスコア管理システムとキャップ野球情報局に関する進捗です。
旧システムについてはこちらの記事をご覧ください。
以前、こういう記事を書いたのですが、
設定を変えるたびにnpm installしないと反映されないのが不便だったのもあり、同じDB、同じアプリケーションサーバを使っているならば、即座に反映されるDBに保持するのがよいという考えに変わりました。
2つのアプリケーションで共通していてテキストファイルで保持していたデータは以下の2つです。
試合ごとのyoutube URLは自分でDB設計を変えたときに用意していたみたいですが、完全に存在を失念していました。
特段新しい技術の導入はしてないです。
以下のパッケージを使う。
- passport-twitter
- twitterログインを行うライブラリ
- express-session
- ログイン情報をセッション(メモリ)に格納するライブラリ。
- express-mysql-session
- 揮発するメモリのセッション情報をmysqlに格納するライブラリ。
reactJSからAPI(NodeJS/Express)へはcredentialsを要求するようにする。
ユーザが書き換えるテーブルに履歴テーブルを用意した。
これでこのプロジェクトの合計テーブル数は21となった。
これまで権限レベルが単一だったが、今回権限を制限したユーザを想定しているので権限周りの実装を行った。
スコア入力で大人数の中から選手を選ぶのに自動入力コンポーネントを使用している。
react-autocompleteはどうもモバイルフレンドリーではなかったようで、モバイルでサジェストが見えなくなってしまう欠点があったので使用するコンポーネントを移行した。
他プロジェクトではすでに導入しているSCSSをこのプロジェクトでも導入。最も古参プロジェクトだったのでCRA(react-scripts)のバージョンを上げるなど。
オートサジェスト修正した pic.twitter.com/ZMB7IBKccB
— ckoshien/みんなのSCORE ver4α (@ckoshien_tech) April 18, 2020
アカウントの申請をいただくと、「チーム管理者」として招待します。チーム管理者は・新規試合登録・自チーム試合結果編集・自チームメンバー登録ができます。 pic.twitter.com/3TCUtyyRCz
— ckoshien/みんなのSCORE ver4α (@ckoshien_tech) April 18, 2020
長らくボードを放置していましたが、
みんなのSCOREのversion4に向けて開発を開始しました。
の計算を三塁打を加味したものに修正。
メンテナンスの都合上、セイバーメトリクスの計算をSQLからTypescript側で行うように修正。
CASE
WHEN ((sum(hit)+sum(twobase)*1+sum(homerun)*2)/sum(at_bats)) is null THEN 0
WHEN ((sum(hit)+sum(twobase)*1+sum(homerun)*2)/sum(at_bats)) is not null THEN ((sum(hit)+sum(twobase)*1+sum(homerun)*2)/sum(at_bats))
END as slg,
CASE
WHEN ((sum(hit)+sum(four_ball))/sum(tpa))+((sum(hit)+sum(twobase)*1+sum(homerun)*2)/sum(at_bats)) is null THEN 0
WHEN ((sum(hit)+sum(four_ball))/sum(tpa))+((sum(hit)+sum(twobase)*1+sum(homerun)*2)/sum(at_bats)) is not null THEN ((sum(hit)+sum(four_ball))/sum(tpa))+((sum(hit)+sum(twobase)*1+sum(homerun)*2)/sum(at_bats))
END as ops,
(sum(hit)+sum(four_ball))/sum(tpa) as obp,
((((sum(hit)+sum(twobase)*1+sum(homerun)*2)+0.26*sum(four_ball)-0.03*sum(strike_out)+3*sum(tpa))*(sum(hit)+sum(four_ball)+2.4*sum(tpa)))/(9*sum(tpa))-0.9*sum(tpa))*27/(sum(at_bats)-sum(hit)) as RC27,
CASE
WHEN sum(at_bats)/sum(strike_out) is null THEN 0
WHEN sum(at_bats)/sum(strike_out) is not null THEN sum(at_bats)/sum(strike_out)
END as not_strike_out,
CASE
WHEN sum(at_bats)/sum(homerun) is null THEN 0
WHEN sum(at_bats)/sum(homerun) is not null THEN sum(at_bats)/sum(homerun)
END as avg_homerun,
CASE
WHEN sum(rbi)/sum(at_bats) is null THEN 0
WHEN sum(rbi)/sum(at_bats) is not null THEN sum(rbi)/sum(at_bats)
END as avgRbi,
public calcSABR = (players) => {
for(let i = 0; i < players.length; i++){
players[i].average = players[i].hit/players[i].at_bats;
players[i].slg = (players[i].hit + players[i].twobase*1 + players[i].three_base*2 + players[i].homerun*3 )/players[i].at_bats;
players[i].obp = (players[i].hit + players[i].four_ball)/players[i].tpa;
players[i].ops = players[i].slg + players[i].obp;
const rc27b = players[i].slg * players[i].at_bats + 0.26 * players[i].four_ball - 0.03 * players[i].strike_out;
const rc27a = players[i].slg * players[i].at_bats + players[i].four_ball;
const rc27c = players[i].at_bats + players[i].four_ball;
players[i].rc27 = ((rc27a + 2.4*rc27c)*(rc27b + 3*rc27c)/(9*rc27c))-(0.9 + rc27c);
players[i].not_strike_out = players[i].at_bats/players[i].strike_out;
players[i].avg_homerun = players[i].at_bats/players[i].homerun;
players[i].avgRbi = players[i].rbi/players[i].at_bats;
}
return players;
}
チーム管理者は
みんなのSCORE、キャップ野球情報局はユーザの皆さんのご意見を募集しています。