1.はじめに
今までjava,pythonでロト6(ロト7)について投稿してきた。
そして、ここにきても高額当選の波は来ていない。
「ロト6、ロト7の当選データを、他の言語の勉強に役立てなさい。」
というメッセージが天から降ってきているのだろう。
以下のようなものを満たすプログラムを作ろうと考えた。
(1)loto6かloto7かを、入力しないで選択したい。
(2)過去の当選実績のファイルを選択できるようにしたい。
(3)特定開催間における、前回の番号と次回の番号の出現回数、出現率の集計データをダウンロードできるようにしたい。
(4)出力したいタイプと選択されたファイルのフォーマットが違う場合は、メッセージを出して開始回などを入力できないようにする。
昔に、他部署に依頼されてツール作成のために勉強した事があったが、再勉強のために前回の内容のJavaScript版として記事を書くことにした。
2.入門メモ(フォーム部品関連)
今回使うフォーム。
(ファイル選択ボタン、ラジオボタン、テキストボックス、ボタン等を配置)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<script src="encoding.js"></script>
<title>Lotoデータcsv出力</title>
</head>
<body>
<h1>Lotoデータcsv出力</h1>
<form name="test">
<label><input type="radio" name="loto_r" value="6" checked>Loto6</label>
<label><input type="radio" name="loto_r" value="7">Loto7</label><br>
<input type="file" id="selfile"><br>
<input type="button" id="csvbtn" value="csv読み込み" onclick="OnCSVReadBtnClick();"/ disabled>
<div id="lotodiv"></div><br>
開始回:<input type="text" id="st" disabled><br>
終了回:<input type="text" id="ed" disabled><br>
<input type="button" id="csvoutbtn" value="csv出力" onclick="OnCSVOutBtnClick();"/ disabled>
<div id="csvmsgdiv"></div><br>
</form>
動作環境:Windows10
ブラウザ:chrome
2-1.ラジオボタンのi番目の要素の選択状態
document.getElementsByName("ラジオボタンのname").item(i).checked
trueなら選択状態、falseなら未選択状態
<label><input type="radio" name="loto_r" value="6" checked>Loto6</label>
<label><input type="radio" name="loto_r" value="7">Loto7</label><br>
例)上記Loto6の選択状態を取得するときは
document.getElementsByName("loto_r").item(0).checked
2-2.ラジオボタンの選択項目取得
i番目の項目が設定されている場合、
document.getElementsByName("ラジオボタンのname").item(i-1).value
で選択項目のvalue項目が取得できる。
2-3.テキストボックスの値取得
開始回:<input type="text" id="st" disabled><br>
document.getElementsById("テキストボックスのid").value
でテキストボックスのvalue項目が取得できる。
2-4.ボタン等の活性化/非活性化
オブジェクト(ボタン、テキストボックス等).disabled
で設定し、活性(false),非活性(true)
2-5.divタグの要素の設定
document.getElementById("divタグのID名").innderHTML=設定したい内容
設定例:
var csvmsg_div = document.getElementById("csvmsgdiv");
csvmsg_div.innerHTML="";
2-6 encoding.js
文字コード変換が必要な時使うプログラム。
今回はプログラムと同じフォルダに格納している。
3.流れ
3.1 ファイル選択
ロト6かロト7の分析データかを選んでから、ファイルを選択する。
(デフォルトはロト6)
ロト6のファイルの構成項目は
[開催回、日付、第1数字、第2数字、第3数字、第4数字、第5数字、第6数字]
ロト7のファイルの構成項目は
[開催回、日付、第1数字、第2数字、第3数字、第4数字、第5数字、第6数字、第7数字]
csv読み込みボタンを押すと、ファイルの列数、データ総数をチェックする。
3.2 集計開始回と集計終了回の入力
ファイルの形式のチェックが終わると、データ総数を表示する。
開始回と終了回を入力できるようになる。
3.3 csvファイル出力
開始回と終了回を入力し、csv出力ボタンを押下。
1<=開始回<終了回<=総開催数 の関係を満たす場合、csvファイルの
ダウンロードが始まる。
4.ソース
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<script src="encoding.js"></script>
<title>Lotoデータcsv出力</title>
</head>
<body>
<h1>Lotoデータcsv出力</h1>
<form name="test">
<label><input type="radio" name="loto_r" value="6" checked>Loto6</label>
<label><input type="radio" name="loto_r" value="7">Loto7</label><br>
<input type="file" id="selfile"><br>
<input type="button" id="csvbtn" value="csv読み込み" onclick="OnCSVReadBtnClick();"/ disabled>
<div id="lotodiv"></div><br>
開始回:<input type="text" id="st" disabled><br>
終了回:<input type="text" id="ed" disabled><br>
<input type="button" id="csvoutbtn" value="csv出力" onclick="OnCSVOutBtnClick();"/ disabled>
<div id="csvmsgdiv"></div><br>
</form>
<script>
var obj1 = document.getElementById("selfile");
var btn_csv = document.getElementById("csvbtn");
var btn_csvout = document.getElementById("csvoutbtn");
var loto_div = document.getElementById("lotodiv");
var csvmsg_div = document.getElementById("csvmsgdiv");
var text_st=document.getElementById("st");
var text_ed=document.getElementById("ed");
var radio_loto=document.getElementsByName("loto_r");
var filetext1="";
var loto_type="";
var last_cnt=0;
var splitstr=[];
var arr_status=[btn_csv,text_st,text_ed,btn_csvout];
//ダイアログでファイルが選択された時
obj1.addEventListener("change",function(evt){
text_st.value="";
text_ed.value="";
csvmsg_div.innerHTML="";
var file = evt.target.files;
//FileReaderの作成
var reader = new FileReader();
//テキスト形式で文字コードsjisで読み込む
reader.readAsText(file[0],"sjis");
//読込終了後の処理
reader.onload = function(ev){
//読み込んだテキストの内容をfiletext1に代入
filetext1=reader.result;
confirm("読み込み完了");
loto_div.innerHTML="";
csvmsg_div.innerHTML="";
}
set_objstatus(arr_status,1);
},false);
function OnCSVReadBtnClick(){
var flg0=0;
textdata=filetext1;
delimit0="\r\n";
delimit1=",";
text_st.value="";
text_ed.value="";
csvmsg_div.innerHTML="";
//csvを読み込んでデータ総数を見る
splitstr=textdata.split(delimit0);
for(i=0;i<splitstr.length;i++){
arrtmp=splitstr[i].split(delimit1);
if(splitstr[i].indexOf(delimit1)== -1){
confirm(i-1+"個のデータを表示");
last_cnt=i-1;
break;
}
}
arrtmp=splitstr[0].split(delimit1);
for(i=0;i<2;i++){
if(radio_loto.item(i).checked){
//選択されているvalueの値を取得
loto_type=radio_loto.item(i).value
}
}
if(radio_loto.item(0).checked && arrtmp.length !== 8){
confirm("列数が違います");
flg0=1;
}
if(radio_loto.item(1).checked && arrtmp.length !== 9){
confirm("列数が違います");
flg0=1;
}
if(flg0==0){
loto_div.innerHTML=last_cnt;
set_objstatus(arr_status,4);
}else{
set_objstatus(arr_status,1);
loto_div.innerHTML="";
}
}
function OnCSVOutBtnClick(){
st=text_st.value;
ed=text_ed.value;
var flg0=0;
if(isNaN(st)==false && isNaN(ed)==false){
if(Number(st)< 1 || Number(ed) < 1){
confirm("開始回、終了回は1以上を指定してください");
flg0=1;
}else if(Number(st)>=Number(ed)){
confirm("開始回は終了解より小さい値を指定してください");
flg0=1;
}else if(Number(st)>=last_cnt+1 || Number(ed)>=last_cnt+1){
confirm("データがありません");
flg0=1;
}else{
csvmsg_div.innerHTML="csv作成中";
}
}else{
confirm("数字を入力してください");
flg0=1;
}
if(flg0==1){
csvmsg_div.innerHTML="";
}else{
dict1=disp_lotopare(loto_type,st,ed);
dict2=count_lotonum(loto_type,st,ed);
var str1="前回数字,今回数字,カウント,出現率\r\n";
for (var key1 in dict1) {
val1=Number(dict1[key1]);
keys2=String(key1).split(",");
val2=Math.floor(val1*100/Number(dict2[keys2[0]]));
str1=str1+String(key1)+","+String(val1)+","+String(val2)+"\r\n";
}
//ファイル名の指定
var file_name = "Loto"+loto_type+"_"+st+"_"+ed+".csv";
//CSVのバイナリデータを作る
var toEnc = 'sjis';
var codes = str_to_unicode_array(str1);
var shiftJisCodeList = Encoding.convert(codes, toEnc, 'Unicode');
var uInt8List = new Uint8Array(shiftJisCodeList);
var blob = new Blob([uInt8List], {type: 'text/plain'});
var uri = URL.createObjectURL(blob);
//リンクタグを作る
var link = document.createElement("a");
link.download = file_name;
link.href = uri;
//作ったリンクタグをクリックさせる
document.body.appendChild(link);
link.click();
//クリックしたら即リンクタグを消す
document.body.removeChild(link);
delete link;
}
}
// 文字列から,Unicodeコードポイントの配列を作る
function str_to_unicode_array(str){
var arr = [];
for(var i = 0; i<str.length; i++){
arr.push(str.charCodeAt(i));
}
return arr;
}
//活性・非活性の設定
function set_objstatus(arr1,n1){
for(i=0;i<4;i++){
arr1[i].disabled=true;
}
for(i=0;i<n1;i++){
arr1[i].disabled=false;
}
}
//前回出力番号と今回出力番号の組み合わせ数
function disp_lotopare(loto_type0,st0,ed0){
st1=Number(st0);
ed1=Number(ed0);
//連想配列初期化
dict_loto={};
loto_type1=Number(loto_type0);
for(cnt=st1;cnt<ed1;cnt++){
arrtmp=splitstr[cnt].split(",");
arrtmp2=splitstr[cnt+1].split(",");
for(i=2;i<loto_type1+2;i++){
for(j=2;j<loto_type1+2;j++){
key1=String(arrtmp[i])+","+String(arrtmp2[j]);
if(key1 in dict_loto){
dict_loto[key1]=Number(dict_loto[key1])+1;
}else{
dict_loto[key1]=1;
}
}
}
}
return dict_loto;
}
//各回毎の番号の出力数の合計
function count_lotonum(loto_type0,st0,ed0){
st1=Number(st0);
ed1=Number(ed0);
//連想配列初期化
dict_loto={};
loto_type1=Number(loto_type0);
for(cnt=st1;cnt<ed1;cnt++){
arrtmp=splitstr[cnt].split(",");
for(i=1;i<loto_type1+2;i++){
key1=String(arrtmp[i]);
if(key1 in dict_loto){
dict_loto[key1]=Number(dict_loto[key1])+1;
}else{
dict_loto[key1]=1;
}
}
}
return dict_loto;
}
</script>
</body>
</html>
5.さいごに
JavaScriptで、当選データファイルを読み込んで、前回の数字と
次回にでやすくなる数字の傾向を出力することができた。
普段使い慣れていないこともあり、フォーム部品の制御は
なかなか苦戦した。
6.参考URL
1.KYO's LOTO
当選番号データのcsvファイルだけではなく、各数字の出現回数など様々なデータを収集されています。
2.モバイル通信とIT技術をコツコツ勉強するブログ
sjis変換をしてから、csvダウンロードの部分が参考になります。