OmniAICreator/Qiita-1.07M huggingface dataset:
m5stackでストップウォッチを作る

#タイマ割込み使ってストップウォッチを作ってみよう
m5stackを使ってストップウォッチを作ってみました。

- `Button A`でSTART/STOP
- `Button B`でSTOP状態の時だけRESET
- `Button C`は機能無し

m5stackについて調べた自分の記事のテスト編になります。
>m5stackで遊ぼう
https://qiita.com/zasshyu6/items/35a1048a9781bdcfebb7

##開発環境
- windows 10 Home 64bit 
- Visual Studio Code 1.36.1
- PlatformIO
    - 使用言語はarduino

##m5stackのタイマ割込について
以下の説明を参考にしました

>ESP32 Arduino: Timer interrupts
https://techtutorialsx.com/2017/10/07/esp32-arduino-timer-interrupts/

英語なので読むのしんどい・・・グーグル翻訳が大活躍です
しかし、読んではみたものマクロが何をやっているかわからない・・・
`portENTER_CRITICAL` `portEXIT_CRITICAL` `portENTER_CRITICAL_ISR` `portEXIT_CRITICAL_ISR`
以上のマクロを調べてみたら以下の記事が見つかった
>ESP32でマルチタスクを行う為の、とりあえずここまで判った事 by freeRTOS ２０タスク目　[ESP32]
https://hamayan.blog.so-net.ne.jp/2018-03-06

なんと！RTOSのAPIじゃないか!!!
そしてクリティカルセクションってなんだ!って調べたら以下の記事に乗っていました
>マイコン徹底入門:RTOS編:フリーのリアルタイムOS活用法: 6. クリティカルセクション
http://miqn.net/rtos/54.html

なんでRTOSのAPI？
そもそもarduinoってRTOSじゃないよね？
気になったので調べてみたら以下の記事にだいぶ詳しく載っていました

>Arduino – ESP32 のマルチタスク ( Dual Core ) を試す
https://www.mgo-tec.com/blog-entry-arduino-esp32-multi-task-dual-core-01.html

 - `aruduino core for the esp32`で`FreeRTOS API`をたたくことでマルチコア対応ができる

gpio関連は`arduino API`、割り込みとかマルチスレッドとか周期実行は`FreeRTOS API`
というと、結構ガチな周期制御できるのでは・・・奥が深すぎる・・・

#ストップウォッチを作ってみた

上記を踏まえ、ストップウォッチということで以下の2パターンで作ってみてどう変わるかを試します

1. `loop()`関数の中だけでLCD表示を行う。
2. マルチスレッドで処理を行う。

 - 組みながら調べてみたこと
    - `portMUX`は同期をとるためって書かれてましたが、ミューテックスの機能かな・・・
    - `IRAM_ATTR`はArm-coreのセクション直叩きしてるみたいな感じ

##1. `loop()`関数の中だけでLCD表示を行う。

ソースはgithubに上げました。
https://github.com/zasshyu66/m5stack_Study/tree/master/StopWatch1

中身は以下の様になってます。

 - `loop()`内の処理
    - LCD表示
    - 表示用数値の演算
    - Start/Stop/Resetの処理(主にチャタリング防止)


 - タイマ割込は`5usec`ごとにカウンタをカウント
    - `1usec`周期の割込でカウントしようとしたが`loop()`関数の監視に引っかかってリセットがかかる模様

`portENTER_CRITICAL` `portEXIT_CRITICAL`を使ってLCD表示の時に割り込み禁止をかけてみると`msec`周期のカウントになってしまったので使う必要がないと判断しました。
やっぱりLCDの処理は時間がかかりますね。

##2. マルチスレッドで処理を行う。

ソースはgithubに上げました。
https://github.com/zasshyu66/m5stack_Study/tree/master/StopWatch2

 - `loop()`内の処理
    - 無し

 - `thread1()`内の処理
    - Start/Stop/Resetの処理(主にチャタリング防止)

 - `thread2()`内の処理
    - LCD表示
    - 表示用数値の演算

threadでの監視周期をもたせない場合は4秒くらいでリセットがかかってしまう
`vTaskDelay()`を持たせるとリセットがかからずに動いてくれる
`vTaskDelay()`はどうやら`usec`周期で動いている様子
なので、結局`1usec`周期の動作を行うことは無理そうです
残念

また、マルチスレッドにしたことでボタン動作が不安定になってしまった。
この辺もいろいろいじらないといけなさそう・・・難しい・・・

##次にやること
次にパルスカウンターを作ろうと思ったが、タイマ割込やマルチスレッドの動作のやり方など勉強することが色々あるのでどうしようか迷い中です。
タイマ割込を調べましたがESP32の奥の深さにはまってしまいました。

(2019/08/19更新)
ストップウォッチを使って気になったところを調べて直しました。
>続・m5stackでストップウォッチを作る
https://qiita.com/zasshyu6/items/a68d98edb08ef5439434
m5stackでUART Loop Backをしてみる

#teratermでループバックテスト
m5stackを使ってUARTテストをします。
`m5stack - USB - PC(teraterm)`とつないでやり取りしてみました。

m5stackについて調べた自分の記事のテスト編になります。
>m5stackで遊ぼう
https://qiita.com/zasshyu6/items/35a1048a9781bdcfebb7

##開発環境
- windows 10 Home 64bit 
- Visual Studio Code 1.36.1
- PlatformIO
    - 使用言語はarduino

##m5stackのUARTについて
ESP32のDatasheetとm5stackの回路図とにらめっこしながら調べてみたら以下のことが分かった。

- ESP32には`UART0,1,2`と3チャンネル用意されている。
    - `UART0`は`GPIO1,3`
        - `CP2104`をつかってUSB-UART変換をしている。
        - m5-Busで外部にも出ているが、USBだけで使うのが無難かな。
    - `UART1`は`GPIO9,10`
        - このPINは`GD25Q32C`っていうシリアルフラッシュにつながっていてm5-Busに出ていないので使用不可。
    - `UART2`は`GPIO16,17`
        - m5-Busに出てるピンで唯一何もつながっていないチャンネル。

PlatformIOでは`UART0,1,2`はそれぞれ`serial`,`serial1`,`serial2`と設定されている。
`serial`は`HardwareSerial.cpp`でそれぞれ定義されていたが、`serial1`は接続pinの関係上使えない様子です。
以下の記事も参考にさせていただきました。ありがとうございます。
>m5stackのserial1は無い
https://boiledorange73.hatenablog.com/entry/2018/11/08/181752

#m5stackにUSBをつないで通信してみよう

以上を調べたので実際にくんでみました。
main.cppだけgit hubに上げました。
https://github.com/zasshyu66/m5stack_Study/tree/master/USBserialloopbacktest

シリアルの設定は以下。(速度以外デフォルト)

 - `serial(UART0)`
 - `Data bit :8 bit`
 - `No Parity`
 - `1 stop bit`

テストはteratermでPCとUARTやり取りをしました。
動作は、PCで入力された文字をLCDに表示とPCにそのまま返しています。
`ButtonA,B,C`はそれぞれが押されたらPC側へボタンが押されたという表示をする。
ボタンのほうはチャタリングとか押しっぱなし判定は入れてないので押してる間はPCに表示を送り続けます。

本当は動画とか入れればいいんだろうけど、動画取るのめんどくさかったのでまたの機会に・・・

##次にしてみること
これにてPCとのやり取りはできたので次の実験へ移ります。
>タイマ割込み使ってストップウォッチを作ってみよう
https://qiita.com/zasshyu6/items/c0bd9bb592192b3c80e7
ユーザー目線で、テレワークとVDI

昨日・一昨日と勉強会に参加させてもらったのですが、そんな勉強会の最中に社内システムのトラブルに巻き込まれました。私物PCから使えるVDI環境があるのでそれでつないで、トラブルシュートして、事なきを得ました。

ところで、「VDIで働き方改革！」とか、働き方改革というキーワードに関連して頻繁に出てきます。
厚労省の[働き方改革のいくつかの取り組み](https://www.mhlw.go.jp/stf/seisakunitsuite/bunya/0000148322.html)の１つに「柔軟な働き方がしやすい環境整備」があり、さらにその中の１つとして「テレワーク普及促進関連」の事業があります。

じゃ、そもそもVDIって？と調べてみてもシステム面から記事は多いけど、ユーザー目線でどうなのよ？というのはあんまり出てこないので、自分の考えを整理するためにザックリまとめてみました。



#テレワークって？

[時間や場所にとらわれない柔軟な働き方のこと(日本テレワーク協会）](https://japan-telework.or.jp/tw_about/)とある。通常の勤務先でないオフィス使うケースや、在宅勤務、などもその１つ。

オフィス以外の場所で、会社PCで業務をしようと思ったら「オフィスじゃないとそもそも社内システムにつなげられない」だとか「VPNで接続しないと社内システムにつなげられない」ケースもある。VPN接続すれば業務できます、ならテレワークできちゃうといえる。


「VDIでテレワーク！」なんて記事よく出てくるけど、上記の通りでテレワーク環境の整備にVDIじゃなくてもいい。でもVDIならできることもあったりする。



#VDIって？

遠くのPC環境を遠隔で操作して、画面だけ手元のPCに表示して使えるシステム。

たとえば、手元のPCではAという作業をしつつ、Bという作業を並行して行いたいとき、PCは2台必要になってしまうことも。2台並べてたら場所も食うし、2台使えないケースもある。
VDIも使えるなら、手元のPCではAという作業をしつつ、VDI上の別のPCでBという作業を並行して行える。1台分のスペースで十分。

遠くのPCと書いたけど、実際にはPCが物理的に1台1台並んでいるわけではなくて、会社が管理しているサーバーの中で複数のPCが動いていて、そのうちの1つを使うと思えばいい。



#会社のオフィス以外で使えるの？

ざっくり、社内からしか使えないVDIと、社外からでも使えるVDIにわけられる。
テレワークのためにVDIを選ぶなら、社外から使えないと意味がない。

セキュリティに~~やかましく言って邪魔ばっかりする情シスがいるような~~厳しい会社だと、社外からアクセスさせない、あるいはできないようなところもある。
また、昔からあるようなVDIだと、テレワーク以外を目的に導入してたりするので、その場合はやっぱり社外から使えない。

テレワークでVDIを使うなら、社外から使えるVDIが必須。ただ、社外から使えるとしても、ある程度のセキュリティは考えないといけない。アカウントとパスワードだけで使うのは不安。アカウントとパスワードと、「別の何か」で不正利用を防ぐ仕掛けが必要になってくる。


#私物からVDIって使えるの？

さっきの「別の何か」次第で、会社端末からしかアクセスできないVDIと、BYODからでもアクセスできるVDIにわけられる。

「会社貸与PCであること」で制限しているケースだと、私物でのテレワークは実現できない。
「VPNで接続していたらOK」なケースだと、VPNが会社端末だけに制限されてたら、やっぱり私物端末では使えない。

「認証アプリなどで本人確認できること」で制限しているケースだと、私物で使えるといえそう。
認証アプリスマートフォンに予めアプリをインストールしておいて、ログインするたびにアプリに通知が来て承諾したら使える（身に覚えがない通知がきたら不正ログインされている）とか、アプリにPINが表示されるのでそれをパスワードとは別に入力するとか、そういうやつ。面倒かもしれないけど、アカウントとパスワードだけでは安全でないことはだんだん当たり前になってきてるので、これぐらいはやってるほうがベター。


で、だいたいノートPCも軽くはないので、あまり持ち運びしたくない。「自宅にPCがあるのでそれで業務したいです」が実現できれば便利だし、もし災害などで出社できないようなケースでも業務継続できたりする。このあたりは、私物から使えるVDIのメリットの1つ。


#DaaSって？

VDIと同じようにDaaSって言葉も出てくる。超ざっくりだと、クラウド上に構築されてて（社内のサーバーとかじゃなく）、インターネット越しにアクセスできるVDIのこと。
私物からアクセス不可とか、社内からしかアクセスできないとかであって、この2つ満たしてたらDaaS。

使う側からすれば、社外から安全に便利につかえるなら、DaaSでも、DaaSでなくても構わない。管理者目線だとDaaSじゃないVDIは管理が大変だし、その上「社外から使えるよ！」とか「私物からアクセスできるよ！」を実現するのはかなり大変。DaaSのだったら管理する負荷は小さくなる。


#まとめ

普段使い慣れてるPCでテレワークできることを選ぶなら、VDIでなくてもいい。実際PCにファイル保存してたり、個別のアプリ使っているケースもあるし。

私物利用のテレワークを前提としたVDIには、PC持ち歩かなくてもいいメリットがある。


来年にはオリンピックもあるし、そうでなくても通勤ラッシュは大変。テレワークの選択肢の１つにVDIを入れてもいいと思う。
イベントオブジェクトfunction(e)のeとthisの違いについて　簡易メモ

#この記事について
jQueryの学習中に気になったことを調べ、解決したので
メモとして書いています。

###・違いについて調べた経緯
ブラウザが元々持っている処理をキャンセルするメソッド
preventDefault()についての学習で以下の
コードが書かれていた。

~~~javascript:script.js
$(function() {
  $('form').on('submit', function(e) {
    console.log('送信ボタンが押されました');
    e.preventDefault();
  });
});
~~~

このコードを見たときにeのイベントオブジェクトをfunctionの第一引数として持たせているが、thisでもいいのでは？
と思い,
イベントオブジェクトfunction(e)のeとthisの違いについて
調べました。


#eとthisの違いについて
###・this
関数の中に記述することでイベント発生元の要素を取得することができ、関数内で使用できる。上記のコードだと$('form')の要素。

~~~javascript:script.js
$(function() {
  $('form').on('submit', function() {
    this == $('form')//←イメージ
  });
});
~~~

###・イベントオブジェクトe
function(e)と記述することでイベント発生元の要素だけでなく押されたキーの情報なども取得できる。

~~~javascript:script.js
$(function() {
  $('form').on('submit', function(e) {
    e == $('form').on('submit',//←イメージ
  });
});
~~~
blazer で SQL の LIKE 句による部分一致検索で変数を使う

## はじめに

Rails アプリにおいて、直接 SQL を実行してレポートを作成するときに、[blazer](https://github.com/ankane/blazer) という gem を使っています。

こちらの gem で SQL の LIKE 句を使い、部分一致のキーワードで変数を使おうと思ったときに少しハマったので、調べたことをまとめます。

## 課題

以下のように、LIKE 句を使った部分一致で、`hoge` というキーワードが含まれている `name` を検索する SQL を書くとします。

```sql
SELECT
  name
FROM
  users
WHERE
  name LIKE '%hoge%'
```

この `hoge` の部分を変数にして、任意のキーワードで部分一致を使えるようにすると便利そうだと思ったので、`hoge` の部分を `{keyword}` と書き換えました。
※変数の使い方は [README](https://github.com/ankane/blazer#variables) 参照

```sql
SELECT
  name
FROM
  users
WHERE
  name LIKE '%{keyword}%'
```

しかし、こちらで例えば `fuga` というキーワードで SQL を実行しようとすると、`fuga` の両端がシングルコーテーションで囲まれてしまい、SQL 構文エラーになってしまいました。

```sql
SELECT
  name
FROM
  users
WHERE
  name LIKE '%'fuga'%'
```

ここからシングルコーテーションを外せないかなど色々試したのですがうまくいかず、ハマった状態が続きました。

## 解決策

あれこれ調べていたところ、以下の issue に解決策が記載されていました。
[Support for variables that are already inside quotes · Issue #179 · ankane/blazer · GitHub](https://github.com/ankane/blazer/issues/179)

変数の両端からシングルコーテーションを取り除くのではなく、それぞれを文字列として扱い、連結させれば OK とのことでした。

DB で PostgreSQL を使っている場合は、変数と`%` の間に `||` 演算子を入れます。

```sql
SELECT
  name
FROM
  users
WHERE
  name LIKE '%' || {keyword} || '%'
```

DB で MySQL を使っている場合は、`CONCAT`関数で連結させます。

```sql
SELECT
  name
FROM
  users
WHERE
  name LIKE CONCAT('%', {keyword}, '%')
```

## 終わりに

使っているライブラリで困ったときには、そのリポジトリの issue を追ってみるとヒントがあることが多いなと思いました。
issue ともっと親しくなっていきたいと思います。

## 参考

* [GitHub - ankane/blazer: Business intelligence made simple](https://github.com/ankane/blazer)
* [Support for variables that are already inside quotes · Issue #179 · ankane/blazer · GitHub](https://github.com/ankane/blazer/issues/179)
OpenCVでHSV色空間のHueを扱う時の注意点

OpenCVで物体識別を行う際に、OpenCVのHSV色空間、特にHueの扱いではまったので、まとめておく。

# まとめ
- Hueは0から179の範囲を取る。
- 他のアプリケーションではHueは0から360を取る場合もある。その場合は、OpenCVでデータを読み書きする時にHueを2倍するか1/2倍にする。
- 0から179の範囲外でも動くけど混乱の元なので、0から179のレンジに収める。

# OpenCVの仕様
https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/py_colorspaces/py_colorspaces.html?highlight=hsv
> For HSV, Hue range is [0,179], Saturation range is [0,255] and Value range is [0,255]. Different softwares use different scales. So if you are comparing OpenCV values with them, you need to normalize these ranges.

以下のように書いてある。
- OpencCVの場合、HSVではHueは0から179、Saturationは0から255、Valueは0から255の範囲だよ
- 他のアプリケーションと範囲違うかもよ
- 正規化（0から179の範囲に合わせてから）して使ってね

画像処理ソフトではHueは0から360を取るケースが多いようなので、OpenCV側で2倍するか1/2倍にする。

# RGB、CMYK、Hue(0-360)、Hue(Opencv)の早見表
HSVのS、Vの値を最大値とした場合の早見表（S=100 or 360、V=100 or 360で固定）

| RGB 16進数表記 | RGB(0-255) | CMY(0-100) | H(H=0-360) | Hue(OpenCV H=0-179)|
|:-:|:-:|:-:|:-:|:-:|
| `#ff0000` | (255,0,0) | (0,100,100) | 0 | 0 |
| `#ff7f00` | (255,128,0) | (0,50,100) | 30 | 15 |
| `#ffff00` | (255,255,0) | (0,0,100) | 60 | 30 |
| `#80ff00` | (128,255,0) | (50,0,100) | 90 | 45 |
| `#00ff00` | (0,255,0) | (100,0,100) | 120 | 60 |
| `#00ff80` | (0,255,128) | (100,0,50) | 150 | 75 |
| `#00ffff` | (0,255,255) | (100,0,0) | 180 | 90 |
| `#0080ff` | (0,128,255) | (100,50,0) | 210 | 105 |
| `#0000ff` | (0,0,255) | (100,100,0) | 240 | 120 |
| `#8000ff` | (128,0,255) | (50,100,0) | 270 | 135 |
| `#ff00ff` | (255,0,255) | (0,100,0) | 300 | 150 |
| `#ff0080` | (255,0,128) | (0,100,50) | 330 | 165 |
| `#ff0000` | (255,0,0) | (0,100,100) | 360 | n/a |


# Hueに範囲外の値を指定した場合
以下の図は、OpenCVでHueに0から700の値を指定した場合（横軸がHue）。
256、512のところで0（赤色）に戻っている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69163/df55cec5-48aa-53a7-a873-9b4790b1c5f5.png)

これから分かるようにHueが256以上になると0に戻る。
180から255までは見た目問題なく動作するけど、256以上は想定と違う動作になる。
混乱の元になるので、OpenCVではHueは0から179で使うこと。
GASでメールを送信するスクリプト


function sendMail(){
  var tgtSheet = SpreadsheetApp.getActiveSheet();
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var fileName = SpreadsheetApp.getActive().getName();
  var sheetName = SpreadsheetApp.getActiveSheet().getName();
  var pdf = ss.getAs('application/pdf');
  
  var dAddress = "***@***.**.**";
  var subject = fileName;
  var content = "各位\n\nお疲れ様です。\n";
  content += "" + fileName + "を作成いたしました。\n";
  content += "" + ss.getUrl() + "\n\n";
  content += "ご確認の程、よろしくお願いいたします。";
  
  if (confirm("送信後は変更禁止です。勤務表・交通費・業務移動費を提出しますか？")){
  MailApp.sendEmail(dAddress,subject,content,{attachments:pdf});
  }
}
function confirm(mes){
  var res = Browser.msgBox(mes, Browser.Buttons.OK_CANCEL);
  // it returns "ok" or "cancel"
  if (res === "ok") return true;
  else return false;
}
AWS認定ソリューションアーキテクト – アソシエイトを20時間で取得

# はじめに
普段は主にネットワーク技術支援やインフラ構築のプロジェクトに携わっており、2か月前までAWSの経験なし。最近自社のウェブサービスをAWS上に展開することとなり、何故かいきなり構成検討～設計を主幹で担当することになった。
そのついでにSAAを取得したので、本試験の感想と勉強方法を書いておく。

# 本試験の感想
受験日　：2019/8/3
受験費用：16,200円
受験時間：130分
問題数　：65問
スコア　：804/1000
結果　　：合格

40分程余らせて試験を終えた。文量は1問あたり平均2～3行。日本語への翻訳が微妙な問題もあったが、ちゃんと準備した上で試験に臨めば大体意味は分かる。
選択肢の中から最適な設計を選択させられる問題の割合が多かった。ベンダー試験でありがちな細かいパラメータ（例えばOSコマンドの引数とかオプションとか）を問われるような、いわば暗記勝負の問題が少ないという点は個人的に良かった。

# 勉強方法
めんどくさがりなのでオーバーワークしないことが最優先事項。とは言え今後も実務でAWSを使っていく手前、興味が湧くトピックは余計に調べたりもした。なお、タイトルにもある「20時間」というのは机上の勉強時間の合計時間。並行して実務で触っているので、そういう環境にいない方にとってこの時間は参考にならないかもしれない。
ざっくりした勉強の流れは以下の通り。

(1)[黒本](https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5-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-%E2%80%93-%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88%E6%95%99%E7%A7%91%E6%9B%B8/dp/4295005495)を読む（4時間）
 ⇒内容の70%を理解する、くらいの気持ちでとにかくさっさと読む。4時間くらいで1周した。「4時間で読むこと」よりも「70%理解すること」が大事。

(2)定番の[WEB問題集](https://aws.koiwaclub.com/exam/)を半周する（15時間）
⇒有料だがこのWEB問題集を解くのが最も効率的なアウトプット学習の方法だと思う。ただしこのWEB問題集はチート問題集ではないということを理解して活用すること。問題がそのまま本試験に出るとかはなく（類似問題はある）、あくまで効率的な学習を目的としている。問題を解きながら理解が浅いと感じたトピックについては[公式の資料と動画](https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-service-cut/)等で確認しながら進める。
ちなみに自分はWEB問題集を半周したくらいで「もういいかな」という感覚になったが、これは経験値によって変わるはずなので鵜呑みにしないこと。インフラ設計の経験や知識が少ない方ならば繰り返し問いたりして、本質的な理解を深める工夫が必要になると思う。

(3)公式模擬試験を受験（30分）
⇒とりあえず8割取れていたので勝手に安心して本試験の申込みをした。ただ多くの方が仰る通り、模擬試験は本試験に比べてかなり簡単なのでここでギリギリだった場合はもう少し勉強した方がいいかもしれない。


# 次の目標
せっかくなのでSAP取得。その前に秋の情報処理でネスペ。
初めてのQiita投稿

Qiitaに何かしら投稿しようと思って、書きました。
初めての記事はQiita記事の書き方です。

#目次
- 書こうと思った経緯
- 目次の書き方
- 見出しの書き方
- コードの表示
- 強調
- イタリック
- 灰色表示
- リンクの貼り方
- 最後に
- 参考資料

#書こうと思った経緯
自分は頭も悪く、できる人間でもなく、プログラミングも遅い。
その上、要領も悪く、論理思考力も不足し、発信力もない。
コミュニケーション力もなく、受動的。
このままではいけないと思いました。
せめて、発信力はつけたいと思い、今回投稿しました。

#目次の書き方
目次は下記のように書きます。

```
- 書こうと思った経緯
- 目次の書き方
- 見出しの書き方
- コードの表示
- 強調
- イタリック
- 灰色表示
- リンクの貼り方
- 最後に
```

#見出しの書き方
`#`を最初につけて、その後に見出しを書きます。

```
#見出し
```

#コードの表示
下記のように、コードの前後にバッククオート「\`」を3つ書きます。

> *```*
> System.out.println("Hello World");
> *```*

#強調
強調したい場合、下記のように`*`2個もしくは`_`2個で囲います。
> \*\*d\*\*
> \_\_d\_\_

そして、結果は以下のようになります。
**d**

#イタリック
イタリックで表示したい場合、下記のように`*`もしくは`_`で囲います。
> \*d\*
> \_d\_

そして、結果は以下のようになります。
*d*

#灰色表示
灰色表示したい場合、下記のようにバッククオート「\`」で囲います。
> \`d\`

そして、結果は以下のようになります。
`d`

#リンクの貼り方
リンクの貼り方は下記のように書きます。

```
[タイトル](URL)
```

#最後に
書いてる内容は、たいしたものではないですが、この記事を見てくれたなら幸いです。

#参考資料
[Qiita初心者の投稿方法備忘録](https://qiita.com/cloversoft/items/0f12f3a739312d35cb8f)
[Markdown記法 チートシート](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)
[Qiita記事の書き方〜基本の基本〜](https://qiita.com/48saaan/items/ec2e823e598b457d42eb)
Visual Studio CodeでC/C++プログラミング

VS CodeでC/C++プログラミング方法。Remote Development拡張機能を使って、Windows端末からLinux環境の開発をしているので、コンパイラー設定等はLinux環境の内容になっているが、別環境でもほぼ同じだと思う。Linux環境には、gccとgdbをインストールしておくこと。

# C/C++ extension for VS Codeのインストール
VS Codeの`Extension`画面で**C/C++**を検索し、C/C++拡張機能をインストール。

![VS_Code_C_Extension.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253975/8fbb5ada-5c36-97c9-b533-547c45624c95.png)

# 作業フォルダの作成
ソースコードを配置するフォルダを適当に作成する。作成したフォルダをVS Codeから`File -> Open Folder...`で開く。
以降の設定を終えると、このフォルダ内に.vscodeフォルダが作成され、下記の3個のファイルが作成される。

* c_cpp_properties.json (IntelliSense設定)
* tasks.json (Build設定)
* launch.json (Debugger設定)

# IntelliSense設定
1. コマンドパレット(`F1`)に**C/C++**と入力し、`C/C++: Edit Configurations (UI) `を実行
2. 開いた`C/C++ Configurations`タブの`Compiler path`にコンパイラのフルパス（Linuxの場合、**/usr/bin/gcc**等）を入力。
3. `Include path`にヘッダファイルのフルパス（Linuxの場合、**/usr/include/\*\***等）を入力。ディレクトリの最後に**を入力すると、配下のディレクトリを再帰的に検索する。
4. `C/C++ Configurations`タブを閉じる。

これにより、.vscodeディレクトリにc_cpp_properties.jsonが作成される。

# Build設定
1. `File -> New File`を選択し、新規ソースファイルを作成。
2. 適当にソースを記述。
3. `F1`を押して、`C/C++: Build and Debug Active File` -> `gcc build and debug active file`を実行してコンパイル。
4. VS Codeの画面下部にターミナルWindowが表示され、実行結果が表示される。

![VS_Code_C_Extension_Build.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253975/f4d30506-93e0-2548-a6e8-c8654922c9e8.png)

これにより、.vscodeディレクトリにtasks.jsonが作成される。

# Debugger設定
1. 上記のBuild後に、VS Codeの画面左に表示されているDebugウィンドウ上部の歯車アイコンをクリック。
2. `C++(GDB/LLDB)` -> `gcc build and debug active file`を選択。
3. `launch.json`が開く。`miDebuggerPath`にデバッガのフルパス（Linuxの場合、**/usr/bin/gdb**等を）を入力して、保存。

これにより、.vscodeディレクトリにlaunch.jsonが作成される。

# プログラムのビルド & デバッグ
設定が一通り終わり、ソースの記述が終わったら、コンパイルは`Shift + Ctrl + B` -> `C/C++: gcc build active file`で実行。
デバッグは`F5`で可能。

これで最低限のことはできる。

<!--
# ToDo
* 設定ファイル（tasks.json,launch.json）の書き方
* デバッグ方法
-->

# 参考リンク
[Get Started with C++ and Mingw-w64 in Visual Studio Code](https://code.visualstudio.com/docs/cpp/config-mingw)
バッチファイルでbasename

ファイルのフルパスを渡して、そのファイル名だけを取得するbasename処理をバッチファイルで作ってみます。

# ソース

```basename.bat
@echo off

call :basename C:\hoge\fuga.csv
echo basename1:%basename%

call :basename C:\hoge\fuga\piyo.csv
echo basename2:%basename%

exit /b

:basename

	setlocal
	endlocal & set basename=%~nx1

exit /b
```

# 実行結果

```
>basename.bat
basename1:fuga.csv
basename2:piyo.csv
```

# 解説

バッチパラメータの`%~nx1`を利用して渡されたパラメータからファイル名と拡張子だけを取り出すことで実現しています。

# 関連記事

[バッチファイルでdirname](https://qiita.com/danishi/items/44fe6c430e6d222bd137)
rails bootstrap Paginationの基本

### ■ 環境
+ windows 8.1
+ Rails 5.1.6
+ ruby 2.3.3p222 (2016-11-21 revision 56859) [i386-mingw32]
+ Bundler version 1.15.3

Gemfileに以下を追加

```:Gemfile
gem 'will_paginate',           '3.1.6'
gem 'bootstrap-will_paginate', '1.0.0'
```

```bash:
$ bundle update
$ bundle install
```

```ruby:app/controllers/Users_controller.rb
class UsersController < ApplicationController
  def index
    @users = User.paginate(page: params[:page], per_page: 5)
    #per_pageで1ページに表示可能な個数を指定できる
  end
end
```

```eruby:app/views/users/index.html.erb
<!-- 上で設定した@usersを使い表示させる -->

<% @users.each do |user| %>
  <p><%= link_to user.name, user %></p>
<% end %>
<%= will_paginate %>

<!-- ↓ will_paginateを少しいじる。詳しくは参照2に行くと良い-->
<% @users.each do |user| %>
  <p><%= link_to user.name, user %></p>
<% end %>
<%= will_paginate @users, previous_label: '&lt 前へ', next_label: '次へ &gt' %>

```

##参照
1. [ruby on rails tutorial](https://railstutorial.jp/chapters/updating_and_deleting_users?version=5.1#sec-pagination)
2. [https://qiita.com/Nukioman/items/5e35ded48dfcab389c75](https://qiita.com/Nukioman/items/5e35ded48dfcab389c75)
バッチファイルでdirname

ファイルのフルパスを渡して、その親パスを取得するdirname処理をバッチファイルで作ってみます。

# ソース

```dirname.bat
@echo off

call :dirname C:\hoge\fuga.csv
echo dirname1:%dirname%

call :dirname C:\hoge\fuga\piyo.csv
echo dirname2:%dirname%

exit /b

:dirname

	setlocal
	endlocal & set dirname=%~dp1

exit /b
```

# 実行結果

```
>dirname.bat
dirname1:C:\hoge\
dirname2:C:\hoge\fuga\
```

# 解説

バッチパラメータの`%~dp1`を利用して渡されたパラメータからドライブ文字とファイル名以外のパスだけを取り出すことで実現しています。

# 関連記事

[バッチファイルでbasename](https://qiita.com/danishi/items/e4cca1c80220607b0f0e)
GASでSlackボット作成

#Slack APIを使いこなす

[Documents](https://api.slack.com/#read_the_docs)

##postMessage
messageをSlackチャンネルにポストする関数

```js
var postMessage    = "https://slack.com/api/chat.postMessage";
var app_auth_token = "xoxb-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
var channel        = "#xxxxxxxx";
var message        = "It is sample message!!";

function postMessageToSlackChannel(app_auth_token, channel, message){
  
  const params = {
    "token" : app_auth_token,
    "channel" : channel,
    "text" : message
  };
  const payload = JSON.stringify(params);
  
  const options = {
    "method"      : "post",
    "contentType" : "application/json",
    "headers"     : {"Authorization" : "Bearer "+ app_auth_token},
    "payload"     : payload
  };
```

##files.upload
fileをSlackチャンネルにポストする関数
postMessageと違ってoptionsの指定channelが複数形になっていないと指定されたチャンネルにアップロードされなくてつまづいた。
仕様書はよく読みましょうということ。


※今回はSpreadSheet上のファイルをアップロードする。

```js
var postMessage    = "https://slack.com/api/files.upload";
var app_auth_token = "xoxb-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
var channel        = "#xxxxxxxx";
var wsName = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("シート名");
var charts = wsName.getCharts();
var filename = 'chart.png'
var file = charts[0].getBlob().getAs('image/png').setName(filename);

function uploadFileToSlackChannel(app_auth_token, channel, file){
  
  const payload = {
    "token"          : app_auth_token,
    "channels"       : channel,
    "file"           : file
  };
  
  const options = {
    "method"      : "post",
    "payload"     : payload
  };
  
  return UrlFetchApp.fetch(uploadFileUrl, options);
}
```
【Sinatra】サーバを再起動せずにコードの更新を行う

sinatraで、コードを変更した際にサーバを再起動しないとコードの変更が反映されません。面倒くさいさいですよね。

ということで、自動でコードの変更がが反映されるようにしましょう！

※参考
https://codingcast.techdrive.top/sinatra/bundler/
https://qiita.com/k-ta-yamada/items/9e35c5f8b31862267e01

*windows10環境を使用しています。

#Gemファイルの作成

アプリを作成しているディレクトリまで移動してください。
そこでGemファイルの作成を行います。

```
$ bundle init
```

でGemファイルが作成されます。

windows環境ではGemファイルは隠しファイルになってるので、隠しファイルの表示を行いましょう。
フォルダのエクスプローラの「表示」オプションから隠しフォルダの設定の変更を行うことが出来ます。

オプションを選択します
![スクリーンショット (53)_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203857/bf36d236-6a58-5a37-9039-3127ff85815e.jpeg)


表示オプションを選択後、「隠しファイル、隠しフォルダー、および隠しドライブを表示する」を選択後、OKを押します。
![スクリーンショット (54)_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203857/605aeb09-724c-2aed-d4dc-31f02fed541a.jpeg)


#Gemファイルの編集
次にGemファイルの編集を行います。

```Gemfile.
source 'http://rubygems.org'

gem 'sinatra'
gem 'sinatra-reloader'
```

sinatraとsinatraリローダーを表記しています。

#アプリのファイルの編集

```myapp.rb
require 'rubygems'
require 'bundler'

Bundler.require
```

こちらの表記をアプリに対して行います。

こう記述することによって、Gemファイルに記述されている内容を持ってくることができ、require~を書かなくて済むようになります。

もう一度```bundle install```を実施します。

これでコードの編集時にサーバを再起動しなくても、コードの変更が自動で反映されます。
Content-Typeを理解する


#Content-Typeとは？
*Content-Type*
メールやホームページのファイルにくっつけて送られる「このファイルは、こんな種類のファイルですよ」といった情報。またOptionalで文字エンコードの指定（Shift-JISとかUTF-8とか）も書いてある項目

*MIMEタイプ*
MIME(Multipurpose Internet Mail Extensions 通称：メディアタイプ)
メールやホームページのファイルにくっつけて送られる「このファイルは、こんな種類のファイルですよ」といった情報
[MIMEタイプとの違いを理解](https://wa3.i-3-i.info/diff324type.html)

#Content-Type種類
|Content-Type | Kind |
|:--|:--|
| text/plain | テキストファイル |
| text/html | htmlファイル |
| text/css | cssファイル |
| text/javascript | javascriptファイル |
| text/csv | CSVファイル |
| application/json  | JSONファイル  |
| application/pdf  | PDFファイル  |
| application/vnd.ms-excel  | EXCELファイル  |
| application/vnd.ms-powerpoint  | PowerPointファイル  |
| application/msword  | WORDファイル  |
| image/jpeg | JPEGファイル(.jpg, .jpeg)  |
| image/png  | PNGファイル  |
| image/gif  | GIFファイル  |
| image/bmp  | Bitmapファイル  |
| application/zip  | Zipファイル  |
| application/x-lzh  | LZHファイル  |
| application/x-tar  | tarファイル/tar&gzipファイル  |
| audio/mpeg  | MP3ファイル  |
| audio/mp4  | MP4ファイル  |
| video/mpeg  | MPEGファイル（動画）  |

#参考記事
https://www.yoheim.net/blog.php?q=20171201
Windowsライセンス認証結果をコマンドの標準出力から取得する方法

# 結論

cscriptにslmgrのパスを渡します。
状態確認だけであれば「/dli」オプション、もっと詳細な情報が知りたい場合は「/dlv」オプションを使用します。

```
C:\>cscript "C:\Windows\System32\slmgr.vbs" /dli

Microsoft (R) Windows Script Host Version 5.812
Copyright (C) Microsoft Corporation. All rights reserved.

名前: Windows(R), Core edition
説明: Windows(R) Operating System, RETAIL channel
プロダクト キーの一部: XXXXX
ライセンスの状態: ライセンスされています
```


# 経緯

### きっかけは検証の自動化

皆さん、**IaC（Infrastructure as Code）**やってますか？
昨今ではアプリケーションだけでなく、インフラ界隈でも構築・検証を自動化するために（簡単な）コードを書くことが求められております。

ただ時代の潮流に乗るわけではありませんが、構築したWindowsServerのOS設定値が正しく設定されているかを確認するために「コンピュータの管理」やら「コントロールパネル」やら「サーバの役割・機能」やらをGUIで徘徊して確認してキャプチャを取って…という行為を毎回するのはバカバカしいな、というのは以前から感じておりました。
なので、汎用的なOS設定値を取得するようなコードをコマンドベースで書いて結果を取得して検証を自動化していく、という流れには大賛成なわけですが、WindowsServerの設定値をコマンドで確認していくにあたって、厄介なのが**Windowsライセンス認証確認**です。


### slmgrはvbsである

Windowsライセンス認証をGUIで確認する場合、「システム」から確認するのが一般的かと思います。
<img width="393" alt="001.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97680/8dd38f3a-2c1c-80ba-3d9b-a164ff13f5fa.png">

この確認をCUIで行いたい場合に出てくるコマンドがslmgrですが…
slmgrによる確認結果は、メッセージボックスで表示されてしまいます。

```
C:\>slmgr /dli
```
<img width="223" alt="002.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97680/2b66ab48-81e8-8ad5-7658-47c8dc7490cc.png">

忌々しいですよね、これ。
なんでコマンドで入力してるのにメッセージボックスで返してくるんや…
まぁそれは、slmgrがvbsであることに起因しているものと思われます。

```
C:\>where slmgr
C:\Windows\System32\slmgr.vbs
```

slmgr.vbsの2770行目くらいに、こんな記述があります。

```slmgr.vbs
Private Sub LineFlush(str)
    WScript.Echo g_EchoString & str
    g_EchoString = ""
End Sub
```
`WScript.Echo`をvbs内に記述した場合、通常は対話向けであるWScriptにより処理されるため、メッセージボックスとして出力されているようです。

### vbsのメッセージボックスを標準出力させる

Wscriptにより処理されているvbsを明示的にCscriptで処理させるには、Cscriptの引数としてvbsを渡してやればよいです。

```
C:\>cscript "C:\Windows\System32\slmgr.vbs" /dli

Microsoft (R) Windows Script Host Version 5.812
Copyright (C) Microsoft Corporation. All rights reserved.

名前: Windows(R), Core edition
説明: Windows(R) Operating System, RETAIL channel
プロダクト キーの一部: XXXXX
ライセンスの状態: ライセンスされています
```

これで、無事にWindowsライセンス認証結果を標準出力で返してもらうことができました。

なお、補足しておくと、WscriptとCscriptはいずれもWSH(Windows Script Host)というWindowsスクリプト実行環境で稼働する実行エンジンです。WscriptはGUIでの対話向け、Cscriptはコンソール操作向けの利用が想定されている点で異なります。

|               |Wscript           |Cscript             |
|:-------------:|:----------------:|:------------------:|
| 本体のパス |"C:\Windows\System32\wscript.exe"|"C:\Windows\System32\cscript.exe"|
| 用途          | GUI(対話向け)     | CUI(コンソール操作) |
| WScript.Echo  | メッセージボックス | コンソール標準出力  |


# おわりに

ライセンス認証をコマンドベースで確認するのになんでこんな面倒なことをしなければいけないのかと思いますが、きっと今後はPowershellとかで簡単に認証結果を返してくるようになることでしょう。知らんけど。願望です。

記載の誤り等あればぜひご指摘をお願いします。

### 参考サイト
[WscriptとCscriptの違い－WSH@Workshop](http://wsh.style-mods.net/topic3.htm)
[cscript と wscript の違い | 文字の出力方式
](http://tooljp.com/windows/chigai/html/WSH/cscript-wscript-chigai.html)
Node.jsでコンソールの表示を上書きする

# ダメな方法

まずはダメな方法です。こういうスクリプトを実行すると、表示が追いつかずガタガタになります。

```javascript:test.js
const main = function (f) {
  f()
}

const printAbcde = function () {
  process.stdout.write("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n");
  process.stdout.write("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n");
  process.stdout.write("cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\n");
  process.stdout.write("dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\n");
  process.stdout.write("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\n");
}

const mainLoop = function () {
  for (;;) {
    console.clear();
    printAbcde();
  }
}

main(mainLoop);
```

毎回、console.clear関数で画面を上に流していることが原因です。

# 良い方法
console.clear関数を呼び出すのは最初の1回だけでいいです。あとは毎回、上書き前のタイミングでcursorTo関数を呼び出しカーソル位置を左上(x:0, y:0)へ戻します。

mainLoop関数を以下のように書き換えます。

```javascript:test.js
const mainLoop = function () {
  console.clear();
  for (;;) {
    require('readline').cursorTo(process.stdout, 0, 0);
    printAbcde();
  }
}
```

# 一部を上書きする

mainLoop関数を以下のように書き換えます。

```javascript:test.js
const mainLoop = function () {
  console.clear();

  printAbcde();
  printAbcde();
  printAbcde();

  require('readline').cursorTo(process.stdout, 10, 4);
  process.stdout.write(" !!!!! UPDATE TEXT !!!!! ");

  require('readline').cursorTo(process.stdout, 40, 11);
  process.stdout.write(" !!!!! UPDATE TEXT !!!!! ");

  for (;;);
}
```

4行10列と11行40列のテキストが上書きされます。


# 参考ページ
https://nodejs.org/api/readline.html#readline_readline_cursorto_stream_x_y_callback
Typescript(Javascript)でURLクエリパラメーターを更新する

# URLクエリパラメーターを更新するクラス
※ Typescriptで書いてます。Javascriptの場合は型指定あたりを削除すれば動くと思います。

```ts
class MySearchParams {
    static update(key: string, value: string): boolean {
        const params = MySearchParams.toObject();
        params[key] = value;
        const url = "?" + Object.keys(params).map(
            (key: string) => key + "=" + params[key]).join("&");
        history.replaceState('', '', url);
        history.pushState('', '', url);

        return true;
    }

    static get(key: string): string {
        const params: any = MySearchParams.toObject();
        return params[key];
    }

    static toObject(): Object {
        let vars = {}, max: number, hash: any, array: any = "";
        let url = window.location.search;

        if (url.length === 0) {
            return vars;
        }
        hash = url.slice(1).split('&');
        max = hash.length;
        for (let i = 0; i < max; i++) {
            array = hash[i].split('=');
            vars[array[0]] = array[1];
        }

        return vars;
    }
}
```


# 使い方は以下のとおり
## 指定パラメーターの更新
```ts
MySearchParams.update(key, value)
```
## 全てのパラメーターを連想配列で取得
```ts
MySearchParams.toObject()
```
## 指定パラメーターの取得
```ts
MySearchParams.get(key)
```

ブラウザのバージョンなどによっては、動作しないかもです。問題点などありましたら、コメントなどで指摘していただけると助かります\<m(_ _)m\>
Solitaire(1)



```C#:Solitaire
public static string[] suits = new string[] { "C", "D", "H", "S" };
    public static string[] values = new string[] { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};

    public List<string> deck;
```
まずマークと数字とデッキをstaticとListで設定します
staticはクラス名.変数名でどこからでもアクセスできる利点があり
Listはforeachなど列挙型として利点があります。

```C#:Solitaire
public static List<string> GenerateDeck()
    {

        List<string> newDeck = new List<string>();
        foreach (string s in suits)
        {
            foreach (string v in values)
            {
                newDeck.Add(s + v);
            }
        }

        return newDeck;
    }
```

```C#:Solitaire
public void PlayCards()
    {
        deck = GenerateDeck();
        //test the cards in the deck:
        foreach (string card in deck)
        {
            print(card);
        }

    }
```

```C#:Solitaire
PlayCards();
```

Consoleを確認するとすべてのカードが認識されているのが分かります

```C#:Solitaire
void Shuffle<T>(List<T> list)
    {
        System.Random random = new System.Random();
        int n = list.Count;
        while (n > 1)
        {
            int k = random.Next(n);
            n--;
            T temp = list[k];
            list[k] = list[n];
            list[n] = temp;
        }
    }
```

```C#
void Start()
    {
        PlayCards();
        Shuffle(deck);
    }
```

```C#:Solitaire
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Solitaire : MonoBehaviour
{

    public static string[] suits = new string[] { "C", "D", "H", "S" };
    public static string[] values = new string[] { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" };

    public List<string> deck;


    // Start is called before the first frame update
    void Start()
    {
        PlayCards();
    }

    // Update is called once per frame
    void Update()
    {
        

    }

    public void PlayCards()
    {
        deck = GenerateDeck();
        Shuffle(deck);

        //test the cards in the deck:
        foreach (string card in deck)
        {
            print(card);
        }

    }

    public static List<string> GenerateDeck()
    {

        List<string> newDeck = new List<string>();
        foreach (string s in suits)
        {
            foreach (string v in values)
            {
                newDeck.Add(s + v);
            }
        }

        return newDeck;
    }
    void Shuffle<T>(List<T> list)
    {
        System.Random random = new System.Random();
        int n = list.Count;
        while (n > 1)
        {
            int k = random.Next(n);
            n--;
            T temp = list[k];
            list[k] = list[n];
            list[n] = temp;
        }
    }
}
```
Swift4.2で文字読み上げ機能実装

#文字読み上げ機能概要
ボタンを押すと指定した文字を読み上げてくれるシンプルな機能。

version 
swift4.2

##参考動画
以下のYoutube動画を参考にしました。
https://www.youtube.com/watch?time_continue=1081&v=MO_09UCI5i0

##コード
SpeechService.swiftというファイルを用意して、このファイル内で読み上げ機能の設定をします。
languageの箇所を変更すると他の言語で読み上げてくれます。
使える言語はiPhoneにインストールされているもので、日本語、英語、中国語など様々です。

```swift:SpeechService.swift
import UIKit
import AVFoundation

class SpeechService {
    
    private let synthesizer = AVSpeechSynthesizer()
     // 再生速度を設定
    var rate: Float = AVSpeechUtteranceDefaultSpeechRate
    // 言語を英語に設定
    var voice = AVSpeechSynthesisVoice(language: "en-US")
    
    func say(_ phrase: String) {
        // 話す内容をセット
        let utterance = AVSpeechUtterance(string: phrase)
        utterance.rate = rate
        utterance.voice = voice
        
        synthesizer.speak(utterance)
    }
    
    func getVoices() {
        
        AVSpeechSynthesisVoice.speechVoices().forEach({ print($0.language) })
    }
}
```

ViewControllerでspeechServiceクラスのsay関数を呼び出す事で引数の文字列を読み上げてくれます。
speechService.say("hoge")とするとhogeと読み上げてくれます。

```swift:ViewController.swift
import UIKit
import AVFoundation

class ViewController: UIViewController{
    
    let speechService = SpeechService()
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
 
    @IBAction func touchedButton(_ sender: Any) {
        speechService.say("hoge")
    }
    
}
```
今回は、ViewControllerのtouchedButtonとストーリーボードが紐づいているので、ボタンを押す事で、文字が読み上げられます。

<img width="477" alt="スクリーンショット 2019-07-06 15.27.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243749/a7ccc4db-8b92-0311-a50e-a377ac3945d1.png">
IDLEとターミナルの違い

## これは何 ##

Pythonコーチとして書いているブログのQiita版です。

[Source: https://cyta.jp/python/b/91971](https://cyta.jp/python/b/91971)

## IDLEとは ##

Pythonの入門書などを見ますと、「まず実行環境としてIDLEを使います」という始まり方の本が(特にここ数年は)多いように感じます。


そもそもIDLEとは何かと言うと、<a href="https://docs.python.org/ja/3/library/idle.html" target="_blank">Pythonのドキュメント</a>によると
<blockquote>IDLE は Python の統合開発環境で、学習用環境です。</blockquote>
だそうです。<br /><br />


「だそうです」などど言う他人事のような語尾を見て「あれ? コーチのくせにIDLEも知らないの???」と思われた方もいらっしゃるかもしれません...。
ある意味ではその通りです。日常業務でも自身のPythonの学習でもIDLEを使ったことが全くと言っていいほどありません。

それはなぜか、なぜIDLEを使わなくてもPythonが実行できるのか、というのがこの投稿の肝の部分になります。


## IDLEとは(再び) ##

IDLEがすでにインストールされているとして、IDLEを立ち上げると、いきなりPythonのコードを入力できる状態になっていると思います。

「`>>>`」という記号が行頭に出てると思うんですね。

これを専門用語では「プロンプト」と言います。
「ここにPythonのコードを打ち込んでくださいね。待ってます。」という待受け状態を表現しているものです。

「`>>>`」に続けて<code>print("Hello, IDLE!")</code>と打ち込みEnterを押すと、ひとつ下の行に<code>Hello, IDLE!</code>と返ってくると思います。
入力後の全体の状態は下のようになると思います。

```python
>>> print("Hello, IDLE!")
Hello, IDLE!
>>>
```

2行目の<code>Hello, IDLE!</code>は1行目の<code>print("Hello, IDLE!")</code>にPythonが応じて返したものなので行頭にプロンプト(「`>>>`」)がありません。
3行目は次のPythonコードを待ってますよ、という意味で再びプロンプトが表示されています。

ちなみにこのコードの入力とそれに対する応答の繰り返しをREPL(Read, Eval, Print, Loopの略)と言います。
REPLの主語はコンピュータになります。人間の側ではないです。
コンピュータが、
1) コードを読んで(Read
2) その内容を評価して(Eval)
3) 評価した結果を表示し(Print)
4) 次のコードを待ち受ける状態(1)に戻る(Loop)
ということをするわけです。


## ターミナルでPythonを実行する ##

ターミナルでPythonを実行するのは拍子抜けするほど簡単です。
※ Windowsではいくつかの選択肢があるのでそれはまた別の機会に書きます。

まずはターミナルを立ち上げます。

ターミナルの場合は「`$`」や「`%`」がプロンプトになります。(特に何も手を加えてなければ「`$`」が表示されるかと思います。)

ここで注意なのが、ターミナルはPython専用ではないということです。
Python以外のたくさんのプログラミング言語やコマンドを実行できる「汎用REPL」と理解してください。

そのためここで一手間加えます。
ターミナル標準の「`$`」というプロンプトに続けて<code>python</code>と打ち込みEnterを押す。

これだけです!

すると「`$`」だったプロンプトがIDLEと同じ「`>>>`」に変化するはずです。

ここからは基本的にIDLEの使い方で説明した内容と同じになります。


※ ターミナル上でPythonプロンプトを終了するには `Ctrl+D`(Controlキーを押しながら「D」キー)を入力してください。


## IDLEはターミナルを優しくしたもの ##

つまりIDLEでできることはすべてターミナルを使っても実行可能です。

というか、ターミナルのほうが「親」のようなイメージですね。
ターミナルでできることの中から、Pythonに関係するところだけ切り取ってまとめたものがIDLEと思っていいでしょう。

「てことは、ターミナルがあれば、IDLEは別になくても良い???」

と思われた方もいらっしゃるのではないでしょうか。

コーチ個人の感覚ではそうなります。

ではIDLEにまったく存在意義がないかというとそれは違います。


ターミナルは汎用的でなんでもできるのですが、汎用的なために扱いが難しい面があります。
代表的なのは「すべてをコマンドで打ち込む必要がある」という点です。

初心者の身からすると「全部コマンドか...」と思うと結構げんなりするものです。

こういった「実際問題、ちょっと初心者には難しいなぁ」という操作を、IDLEでは他の普通のアプリ(エクセルとか)と同じ用にマウス操作可能にします。

つまり、<strong>IDLEは初心者がPythonを実行するハードルを下げるためにより優しいインターフェイスにしたもの</strong>、と捉えればよいと思います。



Python学習の参考になれば幸いです。
VirtualBox上のUbuntu 18.04の画面サイズを自動で切り替えられるようにする

# はじめに
「VirtualBox上のUbuntuの画面サイズを自動で切り替え」というのはVirtualBoxでUbuntu使う人にとってはまず最初にやることな気がしています。なので、検索すればいろいろやり方を解説している記事が出てくるのですが、どれも中途半端にしか手順が書かれておらず、半日ほど時間を無駄にしてしまいました。

このため、二度とこんなことにならないようにするべく、なるべく漏れなく、また注意点についても言及したメモを書きます。

# 環境
今回は以下の環境を使用

- Host OS: Windows 10
- VirtualBox: 6.0.10
- Guest OS: Ubuntu Desktop 18.04 LTS
    - 最小インストールを利用
    - OSをインストールした直後

# 「VirtualBox上のUbuntu 18.04の画面サイズを自動で切り替え」の手順

ざっくりとした流れは以下の通り。

1. Guest Additions のインストール
2. 画面サイズを自動で切り替えできるか確認

実はここまではどの解説記事でも書かれているが、１については「画面サイズ」「自動切り替え」などの単語で検索して出てくる記事には重要な手順が書いてない場合が多かったので、その部分について詳しく書きます。

## 1. Guest Additions のインストール
Guest Additions のインストールについて説明していきます。

### [重要] Guest Additionsのインストールの事前準備 
この部分がない記事が多かった印象なので注意してください。
Guest Additionsをインストールする前に、以下のものをインストールしておく必要があります。

1. カーネルのヘッダー
2. gcc
3. make
4. perl

右クリックをして「端末を開く」を選択してterminalを起動して、以下のようにインストールします。

```bash
$ sudo apt update
$ sudo apt install gcc make perl linux-headers-$(uname -r)
```

### Guest Additions インストール
次に、Guest Additionsをインストールします。
以下のように「デバイス」→「Guest Additions CD イメージの挿入」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21366/4f5a6148-d5b6-6c88-bbd5-0f30a9e0e7dc.png)

次にこのようなものが出てくるので「実行する」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21366/c0fa1392-7de5-1395-45f2-323c3d45db6e.png)

実行すると管理者の認証が必要なので、パスワードを入力。

成功するとこんなメッセージがでます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21366/7a6bb19f-6e57-3f2b-35ca-002c8086e092.png)

ちなみに、**必要なパッケージが入ってないとこんな感じで怒られるので、メッセージに従って必要なものをインストールしてください。（超重要）。**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21366/be1c6b14-3f46-5fdc-fdc7-bd22720e347a.png)
(メッセージのぱっと見はほとんど同じなので、インストールに失敗していると気が付かず、時間をつぶしました・・・。このときはgccとmake、perlが足りなかった模様)


最後にUbuntuを再起動します。
ちなみに、これでもうまくいかない場合は「Guest Additions インストール」などのキーワードで検索すると良いかと思います。

## 2. 画面サイズを自動で切り替えできるか確認
再起動後、うまく自動で切り替わるか確認します。

Windows側のウィンドウの最大化ボタンを押してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21366/7f0d5a7e-7dfa-7a59-22d0-21b53a25b7b1.png)

これで、Ubuntuの画面の周りに空白がなくウインドウの最大化ができれば成功です。
Jetson NanoをWindowsから接続してGUIで使おう！


##ローカルPC側での操作

SSHクライアントの、[MobaXterm](https://mobaxterm.mobatek.net/download-home-edition.html) をダウンロードしてインストールしましょう。(インストーラ有りのほうでいいと思います)

Sessionボタンをクリックして、SSHを選択し、以下の設定で接続します。(マシン名がjetbot, ユーザー名がjetbotの場合)　マシン名で接続できない場合は、IPアドレスで接続することもできます。

- RemoteHost: jetbot
- Specify username: jetbot

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331144/ca7dc694-3c45-7ede-a22b-a0e68c7a66aa.png)

左側のSFTPタブにエクスプローラー風のファイルツリーが表示されているので、ファイルをドラッグアンドドロップしてコピーしたり、ダブルクリックで編集することもできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331144/6db315da-5b47-1b80-e127-fcd87bf9b5cd.png)

以下のようなコマンドをterminalに入力することで、いろいろ操作することができます。X11サーバーも含まれているので、GUIのアプリケーションを起動することもできます。下の Follow terminal folderにチェックを入れることで、cdコマンドで移動したところに同期してくれます。

```bash
# ファイルブラウザ
nautilus

# 画像、テキストなどを開く
xdg-open <画像ファイル名>
xdg-open <テキストファイル名>
xdg-open <URL, directory, ...>

# システム設定
unity-control-center

# ネットワーク接続設定
sudo nm-connection-editor

# notebook
sudo apt install jupyter
jupyter notebook

# firefox
sudo apt install firefox
firefox

# 数独
gnome-sudoku

# bb (ascii-art Demo、サウンドはNG?)
sudo apt install bb
bb

```
bbは必見です(^^)！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331144/1287a23b-010f-c0a7-95f5-e9cf1eab3c07.png)

MobaXtermのMac版が無いのが残念です...
Rails ルーティングの基礎とRESTful

#はじめに
Railsのルーティングについて調べましたので、まとめようと思います。
Railsのルーティングについて一気にまとめてしまうと長くなってしまいますので、
今回は

* Railsのルーティングの基礎
* RESTful

に絞りました。
#ルーティングの基礎
##ルーティングとは
リクエストのURLに応じて、どの処理を実行するかを決定するしくみを指します。
Railsの場合、次の手順で実行するコントローラとアクションを決定します。

1. クライアントがリクエストを送る
1. パスを解析し、ルート定義を検索する
1. 検索されたルート定義に基づいて対応するコントローラ、アクションを呼び出す

##ルーティングの設定
ルーティングの設定は/config/routes.rbに定義します。

```ruby:routes.rb
Rails.application.routes.draw do
  get 'members' => 'members#index'
end
```
これは
**リクエストのURLの末尾がmembersだった場合 =>
membersコントローラのindexアクションを呼び出す**
と定義しています。
##ルーティングとコントローラの設定例
例えば、次のコントローラとアクションを定義して

```ruby:members_controller.rb
class MembersController < ApplicationController
  def index
  end
end
```
次のルーティングを定義して

```ruby:routes.rb
Rails.application.routes.draw do
  get 'members' => 'members#index'
end
```
次のリクエストを送信すると
※ http\://localhost:3000/の部分はホスト名で、Railsのデフォルトポートは3000です。

```
http://localhost:3000/members
```
Membersコントローラのindexアクションが呼ばれます。
#RESTful
##Railsのルート設計
RESTの性質を持つルート設計のことをRESTfulと言います。
Railsのルート設計はRESTfulです。
※ RESTfulでないルート設計も可能です。しかしRailsにはRESTfulなルート設計が前提の機能も存在するため、注意が必要です。
##RESTとは
以下の原則に沿った Webサービスの設計モデルを指します。

1. セッションなどの状態管理を行わない
1. 情報を操作する命令が体系化されて定義・共有される
1. 情報に対して汎用的な構文で一意に識別される
1. 情報に、別の情報や別の状態へのリンクを含めることができる

一つ一つ具体的にまとめてみます。
###セッションなどの状態管理を行わない
クライアントの送信する情報には、全てのやりとりが含まれています。
サーバはクライアントの状態を保持しません。
このようなクライアントとサーバのやりとりはステートレスと言われます。
逆に状態を保持する場合はステートフルと言われます。

例としてECサイトで買い物する場合

**ステートフルの場合**
1. 商品Aをカートに入れる
2. 商品Bをカートに入れる
3. カート内の商品を購入

**ステートレスの場合**
1. 商品Aをカートに入れる
2. 商品Aと商品Bをカートに入れる
3. カート内の商品を購入

ステートフルの場合、サーバ側でカートに入れた商品の状態を保持しているため、クライアントは追加する商品の情報のみ送信します。
ステートレスの場合、サーバ側でカートの状態を保持していないため、クライアントは送信する情報にすべてのやりとりを含める必要があります。

###情報を操作する命令が体系化されて定義・共有される
***なに(リソース)に対してどうするか(HTTPメソッド)***でルート定義を設定すること
HTTPメソッドとはクライアントがサーバに対して出す依頼のことで、主に次のようなものがあります。

* GET:取得
* POST:作成
* PUT:更新
* PATCH:部分更新
* DELETE:削除

リソースとはユーザ情報や画像データなど、情報全般のことを指します。

例えば以下のルーティングの場合

```ruby:routes.rb
Rails.application.routes.draw do
  get 'members' => 'members#index'
end
```
Members(リソース)をGET(取得)するとルート設計しています。

###情報に対して汎用的な構文で一意に識別される
すべてのリソースはURIで識別されるということです。

###情報に、別の情報や別の状態へのリンクを含めることができる
ハイパーテキスト(他の文書への参照を埋め込める)を拡張したハイパーメディア(文字情報に加え、画像や音声などの情報を扱えるようにし、対応づけたもの)を使おうということです。
ハイパーメディアを用いることで、現在のアプリケーションの状態や、違う情報へのリンクなどを表現します。

## メリット
* ステートレスなため、サーバ側の負荷が少ない
* HTTP標準のメソッドを使用することで、一貫性のあるルートを設計できる
* URIに規則が生まれるため、アプリ開発者はリソースを管理しやすい

#おわりに
RailsのルーティングとRESTfulについてまとめました。
間違っているところなどがありましたら、教えていただけるとありがたいです。
Julia の速度

Juliaの実行速度がどのくらい速いのか、簡単なループで計測してみた。やっていることはランダムに作った倍精度浮動小数点数100万個を加算するだけだ。

## Juliaのコード
Juliaのコードはこんなかんじ。

```Julia
randoms = rand(1000000)

function mysum(v)
    sum = 0
    for i in v
        sum += i
    end    
end

using BenchmarkTools
mysum(randoms)
@benchmark mysum($randoms)
```
benchmarkを取る前に一度空振りしているのはJITコンパイルさせるため。

## Pythonのコード

Pythonのほうも一応速度を意識してインデックスで回してみた。イテレータでやるよりは速いはず。

```Python
import random
import time

SIZE = 1000000
randoms = [random.random() for _ in range(SIZE)]

def mysum(v):
    sum = 0.0
    for i in range(len(v)):
        sum += v[i]
    return sum

now = time.time()
mysum(randoms)
then = time.time()

print (then - now)
```

## Cのコード

Cはこんな感じ。Cで時間を測定する正しい方法がよくわからないけど、もう少しまともなライブラリはないのだろうか。2019年だぞ。

```
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>

#define VECSIZE 1000000
int main(){
    double randoms[VECSIZE];
    for (long i = 0; i < VECSIZE; i++)
        randoms[i] = (double)rand() / RAND_MAX;

    struct timespec now, then;
    clock_gettime(CLOCK_MONOTONIC, &now);

    double sum = 0.0;
    for (long i = 0; i < VECSIZE; i++)
        sum += randoms[i];

    clock_gettime(CLOCK_MONOTONIC, &then);
    
    double diff = (double)(then.tv_sec - now.tv_sec) +
                  (double)(then.tv_nsec - now.tv_nsec) * 0.000000001;

    printf("%lf: %lf sec.\n", sum, diff);
}
```

## 結果

JuliaはBenchmarkツールを使ってちゃんと計測しているが、PythonやCは一回だけなのでちょっと不公平だけど。実行は手元のMacbook Pro。

### Julia
```
julia> include("test.jl")
500387.1306197926
BenchmarkTools.Trial: 
  memory estimate:  0 bytes
  allocs estimate:  0
  --------------
  minimum time:     985.463 μs (0.00% GC)
  median time:      1.005 ms (0.00% GC)
  mean time:        1.024 ms (0.00% GC)
  maximum time:     1.728 ms (0.00% GC)
  --------------
  samples:          4873
  evals/sample:     1
```
まあ、だいたい1msだと言っていいだろう。

### Python
```
$ python test.py
0.0528540611267
```
だいたい50msぐらい。

### C
```
$ gcc -O3 test.c; ./a.out; ./a.out
500030.059810: 0.001236 sec.
500030.059810: 0.001252 sec.
```
1.2ms ぐらい。

## まとめ
なんと、この単純なループでは、
JuliaとCがほぼ同じ速度、Pythonは50倍遅いという結果になった。型情報も何もつけていないコードでこの速さというのはさすがにびっくり。予想外。ちなみに、いろいろ型情報をつけたコードで試してみたが、速度は変わらなかった。

Cのアセンブラコード出力を見てみるとループアンローリングもされたそこそこ最適化されたコードになっている。Juliaのコードを`@code_native`で見てみると、アンロールされていない比較的単純なコードになっている。この後ろにLLVMが来て、更に最適化されるのだろうか？

なお、おそろしいことに、Juliaの組み込み関数`sum`を使うとさらに3−4倍速い。

```
julia> @benchmark sum($randoms)
BenchmarkTools.Trial: 
  memory estimate:  0 bytes
  allocs estimate:  0
  --------------
  minimum time:     236.386 μs (0.00% GC)
  median time:      267.007 μs (0.00% GC)
  mean time:        272.185 μs (0.00% GC)
  maximum time:     916.661 μs (0.00% GC)
  --------------
  samples:          10000
  evals/sample:     1
```

こちらのコードを見るとSIMDを使って加算の順番を変えてやっているようだ。

また、組み込みの`reduce`を使ってもほとんど同じ性能が得られる。すごい。

```
julia> @benchmark reduce(+, randoms)
BenchmarkTools.Trial: 
  memory estimate:  16 bytes
  allocs estimate:  1
  --------------
  minimum time:     242.448 μs (0.00% GC)
  median time:      289.671 μs (0.00% GC)
  mean time:        300.357 μs (0.00% GC)
  maximum time:     799.867 μs (0.00% GC)
  --------------
  samples:          10000
  evals/sample:     1
```
Firebaseで初めてサンプルプロジェクトを動かそうとした時の認証エラー

GCPのFirebaseを初めて使いました。
アプリケーションを構築しようとした時にハマったので、メモを共有しようと思います。

結論から申し上げますと、技術的な話しはなくて割と理不尽な結果でした。。。
# 現象
サンプルプロジェクトをデプロイ後、初めて「Friendly Chat」にアクセスした時です。
画面右上のログインボタンを押して、認証をしようとしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223257/2ffdffed-d1c9-2a8d-4785-d2b85920750b.png)

すると下記のようなエラーが表示されました。
このエラーの解決方法がなかなか見つからず、悩みました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223257/28e2ad3a-91f5-80f9-f8b6-5db1a73aab9d.png)

#解決策
エラーメッセージの「Learm more」からリンク先に進み、認証情報の更新を行いました。
アプリケーション名を「Friendly Chat」から「Friendly Chat2」に変更しました。
##変更前
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223257/4b11fe27-27ab-06b8-0845-516162d424b3.png)
##変更後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223257/c6e12091-c9aa-ae98-665e-762425565608.png)

その後おさまりが悪いと思ったのでアプリケーション名を「Friendly Chat」に戻しています。その後も正常に稼働しました。

以上。
なんやねん。。。
csvへの書き出し

# 環境
OS: Windows7 
Metatorader: XMtrading MT5 5.00 build 2085
MetaEditor:5.00 build 2085

# 文言定義
MT : MetaToraderの略称

# 概要
指標カレンダー情報を定期的にmariaDBへ格納する為、
一時的にcsvファイルとして格納したい。

# はまった所
・ファイルの出力先が固定されている。
　　MTではセキュリティの観点から操作出来るフォルダが決まっている。
　　操作可能なフォルダは下記の2種類となる。
　　　・端末データを格納するフォルダ
　　　　　TerminalInfoString(TERMINAL_DATA_PATH)
　　　　　で確認出来る。
　　　・クライアント共通のフォルダ
　　　　　TerminalInfoString(TERMINAL_COMMONDATA_PATH)
　　　　　で確認出来る。

　　上記フォルダへシンボリックリンクで別のドライブのフォルダを指定しても、権限を同じにしてもフォルダの参照は出来なかった。
　　今回は指定フォルダへの書き出しへの優先度は低い為検証はしないが、今後**指定フォルダへの書き込みが必要な場合はMT自体の設定を変更する方法**なり考えないといけない。　　


・書き出したファイルがバイナリだった。
　　指標カレンダーは専用の構造体を用いて値が格納されている為、
　　普通にファイルへの書き出しではバイナリで書きだされる。
　　（やったこと①）
　　指標カレンダーは専用の構造体に値を格納している訳で当たり前だったのですが、構造体の中身を展開し書き出す方法が解んなかったのでとりあえずループで構造体の中身をそれぞれ指定して書き出す様にしました。
　今回のスクリプトでは連続でやったり短期で何度も呼びだす事は無いのでそれでいいかなと、、、(やったこと②)

# やったこと/結果(OK or NG)

### 共通　指標カレンダー情報の取得

```
   MqlCalendarValue values[]; ①値格納用変数の定義
   datetime date_from=D'01.01.2000';　②取得開始日時の指定
   datetime date_to=D'01.01.2009';　　③取得完了日時の指定
   CalendarValueHistory(values,date_from,date_to)　④valuesへカレンダー情報の格納
```

### ①単純にファイルに書き出し/NG
　なんかバイナリとして出力されているみたいで、普通に見れない。

```
   FileSave("test.csv",values,FILE_COMMON);
```

### ②繰り返しでファイルに出力/OK
 そもそも今回取得したデータは構造体となっている為　構造体の中身を展開しないといけなかったぽい。
　なので第一配列を一行づつ取得して、構造体の中の変数を取得し、それをcsv形式の文字列へ変換
　最後に文字列をファイルに書き出す処理へ変更した。

```
  if(CalendarValueHistory(values,date_from,date_to)){ ①指標カレンダー情報が取得出来ているか確認。取得出来ていたら下記を実行
      int file_handle=FileOpen("event.csv",FILE_READ|FILE_WRITE|FILE_CSV|FILE_COMMON);　②「event.csv」ってcsvファイルをCSV形式で読み込み・書き込み権限有りでクライアント共通のフォルダから開く(無ければ新規作成)
      if(file_handle!=INVALID_HANDLE) ③ファイルが開けたか確認
      {
     for(int i=0;i<ArraySize(values); i++){　④第一次配列の個数まで繰り返し処理を実行
// 変数への格納
      string recodes = values[i].id +"," + values[i].event_id + ",";　⑤構造体の変数を指定し値をカンマ区切りで格納
      if(values[i].actual_value == -9223372036854775808)　⑥MQL5の仕様により、欠落した値はINT64_MIN(-9223372036854775808)になっている為、NULL文字へ変換する必要が有り判定処理を実施。
         recodes = recodes +"\\N,";⑦NULLの場合MariaDBのNULL文字として[\N]を入力
      FileWrite(file_handle,recodes); ⑧ファイルへ文字列を書き込む
     }⑨ループ終了
     FileClose(file_handle);　⑨ファイルを閉じる。
     }
```