[TypeScript] node.jsで開発する

$ npm init -y
$ npm install typescript @types/node –save-dev
$ tsc –init
L tsconfig.jsonはtypescriptに関する設定情報ファイル

– webpack設定ファイルの作成
$ npm install webpack ts-loader @webpack-cli/generators
$ npx webpack-cli init
Typescript, Y, Y, Y, none, Y, npm, Y, Y, Y, Y

package.config.json

host: "192.168.34.10",

index.htmlとindex.tsを書き換える
$ npm run build
L distフォルダが作成される
$ npm run serve

なるほど、なかなかやりおる

[TypeScript]はじめの一歩

$ npm install typescript
$ tsc –V
Version 4.4.3

sample.ts

console.log("Welcome to TypeScript!")

$ tsc sample.ts

console.log("Welcome to TypeScript!");

webでtsを使用する

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
	<script src="sample.js"></script>
</head>
<body>
	<h1 class="bg-primary text-white p-2">Sample page</h1>
	<div class="container py-2">
		<p class="h5" id="target">wait...</p>
	</div>	
</body>
</html>

sample.ts

window.addEventListener('load', (event) => {
	let p = document.querySelector('#target')
	p.textContent = "This is message by typescript."
})

なるほど

[TypeScript] 基礎

型指定

var onigiri: string = 'onigiri',
	calories: number = 200;

function todaysMeal(food: string, energy: number): string {
	return `my ${food} has ${energy} calories`
}

todaysMeal(onigiri, calories)

インターフェイス
L オブジェクトがある構造に合っているかの型チェックに使用

interface Person {
	name: string;
	age: number;
}

function intro(person:Person): string {
	return `My name is ${person.name}. I am ${person.age}`
}

var ken = {
	name: 'Ken',
	age: 20
}

intro(ken)

クラス

class Menu {
	items: Array<string>;
	pages: number

	constructor(item_list: Array<string>, total_pages: number){
		this.items = item_list;
		this.pages = total_pages;
	}

	list(): void {
		console.log("out menu for today:");
		for (var i=0; i<this.items.length; i++){
		console.log(this.items[i]);
		}
	}
}

var sundayMenu = new Menu(["pancakes","waffles","orange juice"], 1);

sundayMenu.list();

$ node hello.js
out menu for today:
pancakes
waffles
orange juice

なるほど、型付言語だとGoと近いな

[javascript] ページ離脱時にポップアップ表示

ページ離脱時にポップアップ表示
formのsubmitの際はポップアップ非表示

<h1>商品ページ</h1>
	<form action="/" method="get" id="form" class="form-example">
	  <div class="form-example">
	    <label for="name">商品名: </label>
	    <input type="text" name="name" id="name" value="チョコレート">
	  </div>
	  <div class="form-example">
	    <label for="name">購入者名: </label>
	    <input type="text" name="name" id="name">
	  </div>
	  <div class="form-example">
	    <label for="email">個数: </label>
	    <input type="number" name="number" value="1">
	  </div>
	  <div class="form-example">
	    <input type="submit" value="今すぐ購入">
	  </div>
	</form>
	<br><br>
	<a href="/">リンク</a>
	<script>

		var onBeforeunloadHandler = function(e) {
    		e.returnValue = 'ページから離れます。よろしいでしょうか?';
		};
		window.addEventListener('beforeunload', onBeforeunloadHandler, false);

		const path = location.pathname;

		var cookies = document.cookie; 
		var cookiesArray = cookies.split(';'); 

		for(var c of cookiesArray){ 
		    var cArray = c.split('='); 
		    if( cArray[0] == 'page' && cArray[1] == path){ 
		        window.removeEventListener('beforeunload', onBeforeunloadHandler, false);
		    }
		}		

		const form = document.getElementById('form');
		form.addEventListener('submit', function(e) {
		    window.removeEventListener('beforeunload', onBeforeunloadHandler, false);
		}, false);

		var date1,date2;
		var kigen = 1;
		date1 = new Date();
		date1.setTime(date1.getTime() + kigen*24*60*60*1000);
		date2 = date1.toGMTString();

		document.cookie = "page=" + path+";expires=" + date2;
	</script>

[GCP] PythonでBigQueryからグローバルウェイTMCNの価格を取得してmatplotlibで2軸で表示

まず、GCPにBigQueryにTMCNの価格を入れます。

1. nomics.comというサイトからFree CSVをdownload
https://nomics.com/assets/tmcn-timecoin-protocol

直近100日分のデータを取得できる。timestamp, open, hight, low, close, volumeなど、一般的なデータ形式。

2. GCPのBigQueryにDownloadしたtmcnのデータをimport

3. PythonでGCP BigQueryからデータを取得して、matplotlibで2軸の折れ線グラフを作る

from google.cloud import bigquery
import matplotlib.pyplot as plt

client = bigquery.Client.from_service_account_json('./client_credentials.json')

QUERY = (
    'SELECT * FROM `gce-test-331622.test.tmcn` ORDER BY timestamp ASC LIMIT 100')
query_job = client.query(QUERY)  
rows = query_job.result()

x = []
y1 = []
y2 = []
for row in rows:
    print(str(row.timestamp)[0:10] + " close:" + str(row.close) + " volume:" + str(row.volume))
    date = str(row.timestamp)[0:10]
    x.append(date)
    y1.append(row.close)
    y2.append(row.volume)

plt.figure(figsize=(10,8))
fig, ax1 = plt.subplots()
ax2 = ax1.twinx()

plt.title("tmcn 2021/08/13-2021/11/21")

ax1.plot(x, y1, marker=".", color = "magenta", linestyle = "--")
ax1.set_ylabel('$close-price(pink)$')
ax2.plot(x, y2, marker="o", color = "cyan", linestyle = ":")
ax2.set_ylabel('$trade-volume(blue)$')

plt.savefig('img/tmcn.jpg',dpi=100)

4. 作成した画像をHTMLで表示

	<h1>timcoin protocol</h1>
	<a href="https://github.com/TimeCoinProtocol/timecoin">TimeCoinProtocol / timecoin</a><br>
	<img src="img/tmcn.jpg" width="400" height="300">
// 省略

5. Githubにpushして、Google Cloud DeployでGCEにデプロイする

steps:
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
  entrypoint: gcloud
  args: ['compute', 'scp', '--recurse', 'img', 'instance-1:/var/www/html/img' , '--zone','asia-northeast1-a']
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
  entrypoint: gcloud
  args: ['compute', 'scp', '--recurse', 'index.html', 'instance-1:/var/www/html/index.html' , '--zone','asia-northeast1-a']

cloudbuild.yamlで以下のように書くと、argsは下のargsしか実行されないので、2回書かなければならないので注意が必要

steps:
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
  entrypoint: gcloud
  args: ['compute', 'scp', '--recurse', 'img', 'instance-1:/var/www/html/img' , '--
  args: ['compute', 'scp', '--recurse', 'index.html', 'instance-1:/var/www/html/index.html' , '--zone','asia-northeast1-a']

うーむ、データ量が多い時などはBigQueryは使えそうだにゃーーーーーーーー

[GCP] ローカルのPythonでBigQueryの値を取得したい

### 1.google-cloud-bigqueryをinstall
公式のドキュメントに沿って進めます
https://googleapis.dev/python/bigquery/latest/index.html

$ pip3 install google-cloud-bigquery

### 2. credential情報の取得
– GCP IAMのサービスアカウント「*-compute@developer.gserviceaccount.com」のKeysからADD Keyでjsonタイプのcrudential情報を取得
– client_credentials.jsonに名前を変更してpythonを実行するフォルダに保存

### 3. Pythonを実行
BigQueryでテーブルを作成した日本アマチュアゴルフランキングのデータを操作します。

from google.cloud import bigquery

client = bigquery.Client.from_service_account_json('./client_credentials.json')

QUERY = (
    'SELECT * FROM `gce-test-331622.test.ranking` ORDER BY rank ASC LIMIT 10')
query_job = client.query(QUERY)  
rows = query_job.result()

for row in rows:
    print("ランク:" + str(row.rank) + " 名前:" + row.name + " 年齢:" + str(row.age))

$ python3 main.py
ランク:1 名前:中島 啓太 年齢:21
ランク:2 名前:蝉川 泰果 年齢:20
ランク:3 名前:米澤 蓮 年齢:22
ランク:4 名前:鈴木 晃祐 年齢:21
ランク:5 名前:杉浦 悠太 年齢:20
ランク:6 名前:河本 力 年齢:21
ランク:7 名前:平田 憲聖 年齢:20
ランク:8 名前:大嶋 港 年齢:16
ランク:9 名前:松井 琳空海 年齢:14
ランク:10 名前:岡田 晃平 年齢:19

ぎょええええええええええええええええええええええ

for row in rows:
    print("ランク:" + str(row.rank) + " 名前:" + row.name + " 年齢:" + str(row.age))
    f = open(today +'.txt', 'a')
    f.write("ランク:" + str(row.rank) + " " + row.name + " 年齢:" + str(row.age))
    f.write("\n")
    f.close()

テキストに書き込んで、PHPで読み込むこともできる
うおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおお
感動した🍣

[GCP] BigQueryで日本アマチュアゴルフランキングのデータを操作

BigQueryで、publicデータではなく、独自のデータの操作方法について学びます。
日本アマチュアゴルフランキングのサイトから、Excelデータをダウンロードします。
http://www.jga.or.jp/jga/html/jagr/male/ranking/ranking_1.html

1.1行目のカラムは残して、CSVで保存

2.BigQueryのAdd Data
3.Create tableでテーブル作成
L 保存したCSVを読み込む

 L スキーマを設定していく。ストロークPT、プレイスPTはfloatにする

4. Advanced optionsでheader rows to skipを1に設定する
5. Create tableでテーブルが作成される

6. Queryで実行する

SELECT * FROM `gce-test-331622.test.ranking` LIMIT 1000

ぎゃああああああああああああああああああああああああ
助けてええええええええええええええええええ

[GCP] BigQueryを使いたい

BigQueryとは
L サーバレスなデータウェアハウス
  L 自動スケーリングにより大規模なデータセットから高速に分析結果を得ることができる
  L 1ヶ月10GBまでストレージ無料枠
  L ウェブUI, bqコマンド、BigQuery REST APIからクエリ実行

まずBigQueryのページを開きます

public datasetでBitcoin Cash Cryptocurrencyを選択

queryの実行

SELECT FROM `bigquery-public-data.crypto_bitcoin.transactions-2021-10-28T23_18_45` WHERE block_timestamp_month = "2021-11-21" LIMIT 10

Syntax error: SELECT list must not be empty at [1:8]

あれ?

SELECT * FROM `bigquery-public-data.crypto_bitcoin.transactions-2021-10-28T23_18_45` WHERE block_timestamp_month = "2021-10-28" LIMIT 10

This query will process 564.8 MiB when run
-> no result

あれええええええええ

samplesのshakespeareを使います。

SELECT * FROM `bigquery-public-data.samples.shakespeare` LIMIT 10

基本はselect文で抽出するのね。
うーん、データが大きすぎるとテストするのも躊躇しますね。

[bxslider]パワーポイントの資料をHTMLでスライドショーで表示

パワポの資料をHTML上でスライダーで表示したい。
jQueryの”bxslider”を使う。bxsliderはcdnで使います^^

### 前準備
パワポの各スライドをスクリーンショットでpng画像にします。

### html
slider.html
L パワポの縦横比は16:9なので、width740, height:520でOKです。

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<script
  src="https://code.jquery.com/jquery-3.6.0.min.js"
  integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
  crossorigin="anonymous"></script>
	<link rel="stylesheet" href="https://cdn.jsdelivr.net/bxslider/4.2.12/jquery.bxslider.css">
	<script src="https://cdn.jsdelivr.net/bxslider/4.2.12/jquery.bxslider.min.js"></script>
	<script>
		$(document).ready(function(){
			$('.bxslider').bxSlider({
				mode:'fade',
			});
		});
	</script>
</head>
<body>
	<ul class="bxslider">
		<li><img src="img/slide1.png" width="720px" height="540" style="margin:auto; left:0; right: 0;"></li>
		<li><img src="img/slide2.png" width="720px" height="540" style="margin:auto; left:0; right: 0;"></li>
		<li><img src="img/slide3.png" width="720px" height="540" style="margin:auto; left:0; right: 0;"></li>
		<li><img src="img/slide4.png" width="720px" height="540" style="margin:auto; left:0; right: 0;"></li>
		<li><img src="img/slide5.png" width="720px" height="540" style="margin:auto; left:0; right: 0;"></li>
	</ul>
</body>
</html>

### 表示する側(html)
iframeで表示します。

<body>
	<h1>資料</h1>
	<iframe src="slider.html" seamless width="720px" height="610px"></iframe>
</body>

よっしゃあああああああああああああああ

[GCP] GCEにGo Revelの環境を構築してデプロイ

### 環境構築
1.ローカルにGCloudをインストール
$ curl -O https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-363.0.0-linux-x86_64.tar.gz
$ tar -zxvf google-cloud-sdk-363.0.0-linux-x86_64.tar.gz
$ ./google-cloud-sdk/install.sh
$ ./google-cloud-sdk/bin/gcloud init
Your Google Cloud SDK is configured and ready to use!
$ pwd
/home/vagrant/gcp/

$ cd ~
$ sudo vi .bash_profile

source /home/vagrant/gcp/gcpgoogle-cloud-sdk/completion.bash.inc
source /home/vagrant/gcp/gcpgoogle-cloud-sdk/path.bash.inc
$ source ~/.bashrc

2.GCPでGCEの作成
Region: asia-northeast1(Tokyo)
Zone: asia-northeast1-a
Machine Series: E2
Machine Type: e2-micro(2 vCPU, 1GB memory)
Boot disk: Ubuntu20.04LTS ※defaultだとDebianになっているので、 ubuntuに変更する
Access Scope: Allow default access
Firewall: Allow HTTP traffic
-> create
-> 設定した内容で作られているかinstancesのviewで確認できる

gcloudによる接続確認
$ gcloud compute ssh instance-3

3.GCE(ubuntu20.04)にGoのインストール
$ sudo apt install golang-go
$ sudo apt-get install –reinstall ca-certificates
$ git config –global http.sslverify false
$ go get github.com/revel/revel
$ go get github.com/revel/cmd/revel
$ go get github.com/cbonello/revel-csrf
$ go get github.com/vansante/go-ffprobe
$ go get github.com/aws/aws-sdk-go
$ go get github.com/go-sql-driver/mysql

$ cd go/src/github.com
$ mkdir me

4.GCEにデプロイ
$ gcloud compute scp –recurse go/src/github.com/me/prd instance-3:/home/vagrant/go/src/github.com/me –zone asia-northeast1-a

5.GCEにmysqlインストール
$ sudo apt update
$ sudo apt install mysql-server
$ sudo mysql –defaults-file=/etc/mysql/debian.cnf
mysql> ALTER USER ‘root’@’localhost’ IDENTIFIED WITH mysql_native_password BY ‘${new password}’;
$ mysql -u root -p
mysql> create database test;
mysql> use test;

create table users(
id int primary key auto_increment,
name varchar(255) unique,
email varchar(255),
password varchar(255),
filepath varchar(255),
message text
);
insert user
mysql> insert into users(name, password) values (‘user1’, ‘5f4dcc3b5aa765d61d8327deb882cf99’);

sudo vi /home/vagrant/go/src/github.com/me/prd/conf/app.conf
http.port = 80

firewall設定
GCPホーム > ネットワーキング > VPCネットワーク > ファイアウォールルール

項目 入力例
名前 default-allow-9000
説明 Allow 9000 from anywhere
ログ オフ
ネットワーク default
優先度 1000
送信 / 受信 上り
一致したときのアクション 許可
ターゲット タグ use-9000
IP 範囲 0.0.0.0/0
プロトコルとポート tcp:9000

GCE
GCPホーム > コンピューティング > Compute Engine > VMインスタンス
ファイアウォール ネットワークタグ に先ほどのターゲットタグである「use-9000」追記

/home/vagrant/go/bin/revel run -a prd
${externalIP}:9000 で動作確認

ぎゃああああああああああああああああああああああああああああ