OmniAICreator/Qiita-1.07M huggingface dataset:
特定のOutlookメール情報をGoogleスプレッドシートへ記録するボット

Outlookメールから、特定の宛先・件名のメールを受信したら、Googleスプレッドシートに記録するボットを作りました。

**【メール】**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/725039/c52d9179-79c8-e337-61e8-3a3c3acad4e1.png" width=400>
**【スプレッドシート】**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/725039/1668c9f5-94af-eb12-d4b2-719d3f17e2f0.png">

#作成経緯
勤め先の会社で運用しているシステムで何かしらエラーが発生した際にメールと電話連絡が来て対応してます。
都度、対応（解決）しますが、四半期ごとにユーザーへエラー発生件数や原因、対応などの報告が必要になるので、せめて発生日とエラー内容を纏めておきたかったので、内容を記録出来るようにしてみました。

#構成
**[Integromat](https://www.integromat.com/)**
・「Microsoft 365 Email -Watch messages」でOutlook連携し、条件に合致するメールを検索。
・「HTTP -Make a request」でGoogle Apps Script の Webhook へPOSTリクエスト。
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/725039/15b7adea-08e7-31f1-e024-2cf152febde3.png)

**Google Apps Script（GAS）**
・スクリプトのWebhookを有効にして、「doPost」でパラメータ受け取り。
・受け取ったパラメータをスプレッドシートに書き込み。

#実装
####Integromat
●Microsoft 365 Email - Watch messagesを追加
・Connection：自身のメールアドレス　※ログインしてIntegromatを有効化
・Folder：受信トレイ（検索先）
・Watch：Only unread（未読のみ）
・Search：From:[メールアドレス] Subject:Critical Subject:Warning
　（特定のアドレスから かつ 件名にCriticalかWarningを含む）

●HTTP - Watch messages
・URL：[GASのWebhook URL]?subject={{4.subject}}&dates={{4.createdDateTime}}
・Method：POST
※subjectに件名、datesに受信日を渡してPOSTして、GAS側でこのパラメータをシートに記録します。
　<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/725039/5b199d6c-9cbb-4ec7-4906-4c52075ea57e.png" width=400>

####Google Apps Script スクリプト
●新規でスプレッドシートを作成し、「ツール」から「スクリプトエディタ」を起動。

```javascript:.gs
// POSTリクエスト
function doPost(e) {
  // body部のJSONを受け取り　※上手く取れないから止めた。
  // var params = JSON.parse(e.postData.getDataAsString());
  // var subject = params.subject;
  
  // 受け取ったキーをスプレッドシートに書き込み（URLパラメータ）
  writeLogToSheet(e.parameter.subject, e.parameter.dates);
  // データ内容を返します
  const data = { text: `POSTリクエスト` };
  return ContentService.createTextOutput(JSON.stringify(data));
}

// シートにログを書き込む
function writeLogToSheet(subject = 'x', dates = 'y') {
  // シート取得
  const sheet = SpreadsheetApp.getActiveSheet();
  // ループを回して1行ずつすでに記録されていないか確認していく
  let currentRow = 1;
  while (true) {
    // 記録されていない行が見つかったとき：
    if (!sheet.getRange(currentRow, 1).getValue()) {
      
      // 1列目にdatesを記録（受信日）
      sheet.getRange(currentRow, 1).setValue( Utilities.formatDate(new Date(dates), "JST", "yyyy/MM/dd (E) HH:mm:ss") );
      // 2列目にSubjectを記録（件名）
      sheet.getRange(currentRow, 2).setValue( subject );
      // ループ中断
      break;
    }
    currentRow++;  // 次の行へ
  }
}
```
●スクリプトエディタで「公開」タブの「ウェブアプリケーションとして導入」を選択。
・Project version：New
・Execute the app as：自身のGoogleアカウント
・Who has access to the app：Anyone,even anonymous
●WebhookのURLをコピーして、Integromatの「HTTP - Watch messages」のURLに張り付け。

#今後の展開
メールの内容も渡そうと思ったが、上手く取れなかった。html形式で取れるようだが、parameterでは取れない。BodyにJSON形式で渡してみようとしたが、これも上手く取得できず。（コメント化した部分）

わざわざWebhookでやる必要もない気もします。IntegromatでGoogleスプレッドシートの追記とかも出来そうなので。（試してないですが。）また、MS系なら、Power Automateのほうが楽かも。（これも試してない。）

Microsoft 365 と連携しようと思えばできるのは新たな発見。（セキュリティ上会社でNGかも。。）メールの内容から必要な文字列だけ抜き出して記録出来るとなお良しかな、、（今後に期待。）
GASで公開してからコードを変更しても反映されない（メモ）

e.parameter.[Key] で初めはパラメータキーとして[text]という値を受け取っていたが、これを[body]に変えて、再度WebhookのURLを叩いても値を受け取れなかった。
>WebhookURL
 https\://script.google.com/macros/～?text=hello! 　→textを取得できる
 https\://script.google.com/macros/～?body=hello! 　→bodyを取得できない

#元のコード

```javascript:.gs
// GETリクエスト
function doGet(e) {
  // textというキーに値があればそれをスプレッドシートに書き込みます（URLパラメータ）
  // データ内容を返します
  const data = { text: `GET ` + e.parameter.text };
  return ContentService.createTextOutput(JSON.stringify(data));
}
```

#変更後のコード
```javascript:.gs
// GETリクエスト
function doGet(e) {
  // bodyというキーに値があればそれをスプレッドシートに書き込みます（URLパラメータ）
  // データ内容を返します
  const data = { text: `GET ` + e.parameter.body};
  return ContentService.createTextOutput(JSON.stringify(data));
}
```

#結論（解決）
保存して、**再度WebhookのURLを取得しなおせば**上手くいった。
恐らく、アプリとして公開した時点で保存？されるのだろうと思う。
**公開してからコードを書き換える場合は、要注意としてメモ。**
Azure Synapse Analytics の SQL Serverless (SQL on-demand) で 日本語が文字化けした時の対応例

# 背景

Synapse では、リンク設定されている Azure Storage や Cosmos DB の内容などを、右クリックから SQL文を直ぐに作成してくれる機能があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/788214b8-280b-4f47-02ef-7824fb99a51a.png)


Microsoft が用意してくれているサンプルデータは英語のものが多いため、日本語のデータでクエリ実行すると文字化けする事が多くあります。

SQL Serverless は、データを個別に持ちません。Azure Data Lake Storage Gen2 上にファイルとして見える状態にしています。ですので、ファイルを確認すると日本語で表示できるのに、Azure Synapse Studio で表示させようとすると、文字化けする事になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/67adc8e5-a512-a459-a004-eb7f78f00de7.png)

これは、扱っている SQL Serverless (on-demand) の文字列の**照合順序**の設定に起因しているみたいです。
照合順序は、Server - Database - Table - Column の単位で柔軟に設定ができます。が、Synapse Studio の利便性を考えると、Table 以下では面倒です。Serverの設定は出来ないですので (恐らく)、現実的な **Database レベル**での設定を行います。

データベースの照合順序の設定または変更:

https://docs.microsoft.com/ja-jp/sql/relational-databases/collations/set-or-change-the-database-collation?view=sql-server-ver15


画面の右上を見ると [master] Database に接続をしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/110aac88-291b-a6ba-08ce-71f89426499b.png)


以下のT-SQLクエリで設定されている照合順序を確認します。

```sql
SELECT CONVERT (varchar(256), SERVERPROPERTY('collation'));
```

結果

```shell
SQL_Latin1_General_CP1_CI_AS
```



要は西洋圏の文字列です。
**UNICODE**の照合順序を設定します。

照合順序情報の表示
https://docs.microsoft.com/ja-jp/sql/relational-databases/collations/view-collation-information?view=sql-server-ver15


# 手順

## 1. SQL Database に新規 Database を作成し、その際に照合順序を設定

`opendata`の部分は、お好きな名前に変更ください😊

```sql
CREATE DATABASE opendata COLLATE Latin1_General_100_BIN2_UTF8
```

終了です😊

## 2. 確認

SQL Serverless で、T-SQL 実行時に、Database を切り替えてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/18a5bc96-4377-1802-56ab-853a8605b992.png)


master:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/87798081-e58e-930d-2130-4935b10c1cb1.png)

照合順序を設定した database:

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/3254f1a0-e964-6108-8224-01af36bef6d4.png)

# まとめ

Synapase の SQL Serverless は、SQL Engine で作られている事に立ち返る事が重要です。そして、文字化けについての対応は、ストレージへの格納方法、抽出するプロトコルの設定、アプリケーションの表示など多岐の場面で行われています。UNICODEの恩恵を私たちは知らないうちに受けているんだなーと改めて確認できました。

Spark で問題が起こったら、どうしたらいいのかも、対応しやすいと思います😎

2020/11/17 追記:
Always use UTF-8 collations to read UTF-8 text in serverless SQL pool:
https://techcommunity.microsoft.com/t5/azure-synapse-analytics/always-use-utf-8-collations-to-read-utf-8-text-in-serverless-sql/ba-p/1883633

2021/1/25 追記:
照合順序を、上記 Blob にあった `Latin1_General_100_BIN2_UTF8` に変更。
Power BIからAzure Databricksに接続した際のクラスター起動検証


## 概要
Power BI から、Databricksにクエリを発行した際に、Databricksのクラスターが自動で起動するかの検証を実施しました。

ドキュメントにて下記のような記載があり、Power BIからDatabricksに接続した際にはODBC経由になるため、Databricksのクラスターが自動で起動するようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/126aff8f-24f2-1018-65eb-1a3c65ea6aaf.png)
引用元：[クラスターの管理](https://docs.microsoft.com/ja-jp/azure/databricks/clusters/clusters-manage#start-a-cluster)

## 確認結果
### 1.下記のテーブルを用意
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/023e8668-4523-ff6d-a20e-49434142f904.png)

### 2.Power BI Desktopにて上記データを用いたレポートを作成して、Power BI Services上に配置。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/0d15c910-44d3-9476-a670-818d274704cc.png)

接続情報については、下記のような認証の設定を事前に実施する必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/ccefdbcb-2f00-f7e6-3835-f0398d3010f1.png)

### 3.Databricksのクラスターを停止
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/7e9f265c-f466-d0cf-023a-99107c395f6d.png)

### 4.Power BI Services上のレポートを表示後、ビジュアルの一部を変更する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/5e933845-1e33-5794-979f-a478de757534.png)

### 5.Databricksのクラスターが起動後、クエリが実行されたことを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/3f3d5085-6c35-74eb-e5bf-5f729555ddac.png)

## 補足

タイムアウト値の設定によっては、クラスターが起動する前にタイムアウトエラーとなる場合があるようです。

参考：
https://qiita.com/ryoma-nagata/items/c690cdb410b344c490ab
herokuにデプロイすると 『We're sorry, but something went wrong.If you are the application owner check the logs for more information.』が立ちはだかった。


プログラミング初学者です。
認識の誤り、そもそも間違ってるで？というところはご教授いただけると嬉しいです。

``・エラー発生の要因
・要因発見までの方法
・なぜその要因がエラーになるのか``

について記述しています。

#herokuデプロイ後に特定ページで『We're sorry, but something went wrong.If you are the application owner check the logs for more informatio』が立ちはだかった件
ユーザー登録後に遷移するページでエラーがでました。
![デプロイエラー.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764924/7b621319-735b-9cea-0173-c1208ecf12bb.png)

ローカル開発環境（cloud9）では問題なく表示できていたのですが・・
エラー発生以降、ググって試して、ググって試してを繰り返し、1日半かけて無事解決。

__さて、何が原因だったのか__


##結論


該当コントローラーのアクションの記述が間違っていました。

```Ruby
@user = User.find_by(params[:id])
#間違い

@user = User.find(params[:id])
#こっちが正しい
```


##学び

この問題の重要なところは、__メソッドが違っていたという答えではなく、エラーを解決するまでの方法です。__


釣った魚より、釣る方法のほうが再現性は高い。
独学でプログラミング学習を始めて、1日以上悩んだのは今回が初めて。
エラーへの向き合い方をいい加減、考えないといけません。

**今回のエラーから、herokuエラーが発生した時の対応方法をまとめておきます。**



##We're sorry, but something went wrong

![デプロイエラー.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764924/7b621319-735b-9cea-0173-c1208ecf12bb.png)



このエラーは今回のようにメソッドミス、syntax_error、migrationファイルの反映がされていないなど色んな原因で発生するようです。

私もそうでしたが、ほとんどが
__①DBの問題
②コードの問題__
で解決しているパターンが多いようです。

①に関してはURLのid番号が登録のたびに増えているため、登録はできていそう
②なら多数あるディレクトリからエラーを見つけないといけません。

心が折れました。
どこに原因があるのかわからん。


herokuエラー　原因の調べ方
===

方法は色々ありますが、

```
ターミナルで

heroku logs -tail 
(heroku logs -t　でも可)
```

これでエラーの詳細を確認しました。

ただ、どこにエラーが書いているのか初学者には分からない。

そのためはじめはさらっと流し見してました。

今回これだけ時間がかかったのは__このログとちゃんと向き合わなかった事。__

Qiita、teratail、ブログをみても「ログで確認する」って書いてあるのにね。

大事な事なのでもう一度言う！！

__エラーメッセージ、ログとちゃんと向き合う！！__


じっくり落ち着いて見てみると

```terminal
Completed 500 Internal Server Error in 6ms (ActiveRecord: 1.9ms | Allocations: 568)
```

以外にも、もう一つエラーがあった。

```
ActiveRecord::StatementInvalid (PG::DatatypeMismatch: ERROR:  argument of WHERE must be type boolean, not type integer)
```

めちゃくちゃActiveRecordでエラーって書いてますね。

エラーの内容は
__「whereの引数は整数じゃなくて、真偽値じゃないとだめだよ」__
とのこと

データベースからの検索でミスがあるのか？と調べ、冒頭のコードミス発見に至る。


#「find」「find_by」の違い


参考
Railsチュートリアル
https://qiita.com/nakayuu07/items/3d5e2f8784b6f18186f2
https://qiita.com/tsuchinoko_run/items/f3926caaec461cfa1ca3


__findメソッド__

まずfindは主キー（railsでは自動的にid）で検索できる。
params[:id]では文字列としての数字（例：'1'）が返ってきますが、findメソッドが自動的に整数に変換してくれます。

そのため

```Ruby
User.find(params[:id])

#と

User.find(整数)

```
等価です。


__では次にfind_byは？__
主キー以外でも検索できるメソッド
構文としては

```Ruby
User.find_by(id: 1)
User.find_by(name: "em")
```


つまりエラー発生時のコードではどの属性を検索しているかわからなかった。


```Ruby
User.find_by(1)
```
になっていたわけで、当然エラーになる。



#未解決：User.find_by(1)がなぜローカル開発環境で動作していたか

統合テストで該当ページへのルーティング、アクション、html.erbの表示が正しく動作しているかをチェックするようにしていて、findでもfind_byでもGreenで返ってくる。

今のところ理由は分からない。
分かったら追記します。



#学びまとめ
・エラーメッセージ、ログとしっかり向き合う
・herokuでのエラーは``heroku logs --t``で見れる
・「find」、「find_by」の違い
PhpStormでのLaravelプロジェクトのコード補助

# 概要
最近、デプロイ時にcomposerが2にバージョンアップされた状態で実行されてしまいpsr-4のエラーが出てしまい、今まで出ていた警告等を含めて対応することになりました。でも、何故か昔はLaravelのModelのwhereの様なメソッドが認識出来てたの認識（あまり気にしてなかったので勘違いの可能性も）でしたが参照が出来なく、phpstormのコード補助機能が使えないことにイライラして来ました。

参考：https://medium.com/legacybeta/using-composer-2-0-with-psr4-388b78b98aaa

# composer.jsonを指定
composer.jsonで指定しているpsr-4について連携する目的で設定しますが、それ以外の利点もあるかと思います。

参考：https://pleiades.io/help/phpstorm/using-the-composer-dependency-manager.html#appoint-a-default-composer-json

「Preference」 > 「Languages & Frameworks」 > 「PHP」 > 「Composer」の順で入ります。
![スクリーンショット 2020-10-30 12.52.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489182/13819b84-d37e-a73e-74c9-88afd2140a34.png)

こちらの画面です。プロジェクトのcomposer.jsonを設定したらOKです。自分の場合はpackageの更新をチェックする必要がないと思いましたので、「Check for available package updates」のチェックを外しました。それで「install」や「show log」も正常に動きます。

この設定でpsr-4の警告がずらっと出ると思いますので、対応は必須（composer2で問題が発生すると）だと思います。

# LaravelのModelのコード補助
目的にModelのメソードのコード補助ですが、fluentクラスの補完も出来るようです。

参考１：https://www.sd-milieu.net/posts/laravel-completion/
参考２：https://github.com/barryvdh/laravel-ide-helper

## 開発モジュールのインストール

```
# composer require --dev barryvdh/laravel-ide-helper
```
参考した記事では「doctrine/dbal」も設置しますが、「barryvdh/laravel-ide-helper」をインストールすると一緒にインストールされます。

## ide-helperの作成

```
# php artisan ide-helper:generate
```
## Modelのコード補助を作成

```
# php artisan ide-helper:models --dir="app/Models"
Do you want to overwrite the existing model files? Choose no to write to _ide_helper_models.php instead (yes/no) [no]:
 > 
```
ここで英語質問が。。。一瞬固まりましたが、簡単に説明すると対応方法がPHPDocの記入で対応することで既にある全Modelクラスに直接書きます？それとも「_ide_helper_models.php」ファイルに書きますか？のことです。

「yes」を選択するのをオススメしますが、何かの理由で「no」を選択しないと行けない場合はPhpStormで以下の警告の対応をしないと行けないです。

```
multiple definitions exist for class
```
作成された「_ide_helper_models.php」を見ると分かると思いますが、同じクラス名が作られてそこにPHPDocが定義されていますので、PhpStorm的に同じクラスが複数あるからどちらなの？って感じです。これは対応方法は警告を表示しない方法しかないようです。

参考：https://stackoverflow.com/a/23079082

「Preferences」 > 「Editor」 > 「Inspections」 > 「PHP」 > 「Undefined」 > 「Undefined class」で「Don't report multiple class declaration potential problems」にチェックを入れます。
![スクリーンショット 2020-10-30 13.20.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489182/ae334de6-d1ee-7bd9-4ddb-75517414958c.png)

# 最後に
上記の内容はphpの正しいコーディングをする為の補助機能を活性するものです、その警告をどのくらい直すかどうかは本人の責任です。この習慣を付ければいつの間に良いソースが出来るかと思います。
トップへ戻るボタンの使い方

#scrollTop

```html
<div id="js-page-top"><a href="#">TOP</a></div>
```

```js
$(function(){
  //ページトップ
  $("#js-page-top").on("click", function () {
    $("body,html").animate(
      {
        scrollTop: 0,
      },
      300
    );
    return false;
  });
});
```

![スクリーンショット 2020-11-02 8.52.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633943/da80c3f9-f163-1db6-affd-32ce83c3bd95.png)
Raspberry Pi「cannot currently show the dekstop」

# 事象

Raspberry Piを職場に設置して暫く経ったある日、VNC接続できなくなってた！
`cannot currently show the dekstop` というエラーが出る。
`raspi-config`からVNCをEnableにしても改善せず。
`Desktop Autologin Desktop GUI, automatically logged in as 'pi' user`を設定しても改善しない！

# 解決

`raspi-config > 7 Advanced Options > A5 Resolution` で解像度の設定をする

# 参考（というよりほぼそのまま引用:pray:）

https://blog.goo.ne.jp/jde_aki/e/ec8b3bcfe66286a2eb3ab24196259884

# あとがき

ググりワードがよくなかったのか、なかなか解決方法がHITしませんでした。
備忘録も兼ねてPOST。

もう少しで初期化してしまうところでした。
C言語(コンパイル、構造体)

##はじめに
-C言語の用語をまとめる
-大学で教わった範囲の知識です

#####1
**コンパイル**とは、ソースコードから実行可能ファイルを生成すること
example.cからa.exeやa.outなどを生成

**プリプロセッサ指令**とは、コンパイルする前にソースコードに変更を加えること
ソースコードの先頭`#include`や`#define`など
ディレクティブとも呼ばれる

**プリプロセッサ**とは、プリプロセッサ指令を担当する機能のこと
(gcc環境の場合`gcc -E example.c`で確認できる)

**オブジェクトファイル**とは、コンパイルして吐き出された生のファイルexample.o

**リンク**とは、最終的な実行可能ファイルを生成する手続き
（a.exeやa.outにexample.oをリンク）

#####2 構造体
**構造体**とは、いくつかの変数や定数をまとめて作られるデータ型のこと

**メンバ**とは構造体変数が持つ、変数のこと

**ドット演算子**とは構造体変数の実体そのものにアクセスするためのもの

**アロー演算子**とは構造体変数のアドレスを指定するもの

**メンバアクセス演算子**とはドット演算子とアロー演算子のまとめた呼び名




#####3 構造体のサンプルコード
プログラム例(サラスの公式を使った3次行列式の計算)

```c

#include <stdio.h>
int main(void){

    struct matrix
        {
            double a11,a12,a13,a21,a22,a23,a31,a32,a33;
        };

    struct matrix X={1,0,0,0,1,0,0,0,1};
//構造体変数 X を定義、個々の値｛～｝を代入

    double d1,d2,d;
    //3×3サラス前半
    d1=(X.a11)*(X.a22)*(X.a33) + (X.a12)*(X.a23)*(X.a31) + (X.a13)*(X.a21)*(X.a31);
    //3×3サラス後半
    d2=(X.a13)*(X.a22)*(X.a31) + (X.a12)*(X.a21)*(X.a33) + (X.a11)*(X.a23)*(X.a32);
    //3×3サラスの公式
    d=d1 - d2;

    printf("det(X)= %f",d);
    return 0;
}
```
UbuntuにAnacondaで構築するTensorFlow-GPU環境【０】

# ゴール
Ubuntu Desktop/Serverをインストールした所から、TensorFlowによるGPU計算ができる環境をAnacondaで構築する。

# 対象者
Linuxに不慣れでAnaconda等の仮想環境もよくわからないという深層学習エンジニア

# 機材
OS: Ubuntu 18.04LTS Desktop/Server

# この記事のモチベーション
　私自身、Ubuntu Serverにおいて深層学習(Deep Learning)を行いたく、TensorFlowのGPU版を動かすための環境構築を行いましたが、情報を集めることや注意するポイントの多さに圧倒されました。したがって自身の備忘録のため、また、同じ志を持つ人たちに向けてまとまった情報を提供することで、様々なページの往復や順番の違いなどで知識をつなぎ合わせる苦しみを減らせればと考えたため、知識や反省点を環境構築の過程の中で説明したドキュメントを作成しました。

# ドキュメントの構成
環境構築を4つの条件に分けました。
煩雑にならないように一つの条件に対して一つの記事で説明します。
この章を含めてドキュメントは全5部構成です（Jupyter Notebookについても続編で書くかもしれません）。

環境構築のための**4つの条件**について説明します。TensorFlowのGPU版（TensorFlow-GPU）を動かすために上から順にクリアしていきます。
1. Deep Learningを行う計算力（compute capability）のある比較的新しいGPU（nVidia社製）を搭載していること
2. GPUの適切なドライバーが入っていて、使用可能な状態になっていること
3. tensorflow-gpuやGPUのドライバ（CUDA）、ディープラーニング用のライブラリ（cuDNN）を入れる環境が作られていること
4. Pythonや条件2の一つ一つがバージョンの互換性を持っていること

一個一個の条件に対応して目次を立てています。上から順に取り組んでいくことで条件をクリアしていけるようになっています。

#### [UbuntuにAnacondaで構築するTensorFlow-GPU環境【１】〜GPUスペック確認編〜](https://qiita.com/captain-sadami/items/a0e1fee2e20ba371a8bc)
TensorFlowはGPUに一定の計算力を求めます。まず、その条件を満たしているかを一つ目の記事で確認していきます。

#### [UbuntuにAnacondaで構築するTensorFlow-GPU環境【２】〜nVidiaドライバーインストール編〜](https://qiita.com/captain-sadami/items/0df5a14f4a42a74dc748)
サーバーのGPUを計算に用いるためには専用のドライバーをOSにインストールする必要があります。関門ですので二つ目の記事で細かく説明していきます。

#### [UbuntuにAnacondaで構築するTensorFlow-GPU環境構築【３】〜Anaconda仮想環境作成編〜](https://qiita.com/captain-sadami/items/a026130c2fbb3513b6e2)
さらにGPUをディープラーニングに用いるためにも必要なライブラリが存在します。それらを受け入れる土台の環境を作るため、三つ目の記事ではAnacondaで仮想環境（記事の中で述べます）を構築していきます。

#### [UbuntuにAnacondaで構築するTensorFlow-GPU環境構築【４】〜CUDA、cuDNNインストール編〜](https://qiita.com/captain-sadami/items/c9be816856c57ef0ae52)
最後に四つ目の記事ではライブラリを仮想環境上にインストールしていきます。この際バージョンの互換性がないと正常に動かないため、一記事を割いて解説していきます。


# まずは
[UbuntuにAnacondaで構築するTensorFlow-GPU環境【１】〜GPUスペック確認編〜](https://qiita.com/captain-sadami/items/a0e1fee2e20ba371a8bc)
からスタートです。
bash for Windows で say したい

WSH（Windows Script Host）を利用する。

## 手順

1. WSH で読み上げプログラムを作成する
2. 読み上げプログラムにエイリアスを設定する
3. エイリアスを使って実行する

## 1. WSH で読み上げプログラムを作成する

巷でよく見かけるやつです。

```js:/c/bin/say.js
var args = [];
for(var i = 0; i < WScript.Arguments.length; i++) args.push(WScript.Arguments.Item(i));

var sapi = new ActiveXObject('SAPI.SpVoice');
sapi.Speak(args.join(' '));
```

## 2. 読み上げプログラムにエイリアスを設定する

`wscript`コマンドを利用すれば、bash から WSH が起動できます。

```sh:~/.bashrc
alias say="wscript /C/bin/say.js"
```

## 3. エイリアスを使って実行する

あとは通常のコマンドのように呼び出します。

```sh
say イエス
```

あくまで簡易的なものですが、Windows でも say コマンドが使えるようになりますね！
MyBatis で 自動採番されたキーを取得する際にハマった話

MySQLのAUTO_INCREMENTで自動裁判されたID（主キー）をオブジェクトにセットしようとしたら、１がセットされてしまった。


ドメインクラス

```java:Hoge.java

@Data 
@NoArgsConstructor
public class Hoge{
    private Integer id;
    private String message;
}
```

サービスクラス

```java:HogeService.java
public class HogeService{

    @Autowired
    private HogeMapper hogeMapper;    

    public addHoge(){
        
        Hoge hoge = new Hoge();
        hoge.setMessage("Hello");

        hoge.setId(hogeMapper.insert());

        System.out.println(hoge.getId());//1
        //IDが１になってしまう。
    }
} 
```

マッパー

```java:HogeMapper.java

@Mapper
public interface HogeMapper{
    Integer insert(Hoge hoge);
}
```

```xml:HogeMapper.xml
    <insert id="insert">
        INSERT INTO hoge(id, message)
        VALUES (#{id}, #{message})
        <selectKey resultType="Integer" keyProperty="id" order="AFTER">
            select @@IDENTITY
        </selectKey>
    </insert>
```

上記の方法だと、hogeに１のみセットされてしまう。

MyBatisの selectKey はオブジェクトに直接代入されるため、下記コードにすればIDが取得できる。

```java:HogeService.java
public class HogeService{

    @Autowired
    private HogeMapper hogeMapper;    

    public addHoge(){
        
        Hoge hoge = new Hoge();
        hoge.setMessage("Hello");

        hogeMapper.insert();

        System.out.println(hoge.getId());
        //自動採番されたIDが出力される！！
    }
} 
```

##まとめ

MybatisのSELECT KEYはオブジェクトに直接代入される。
MathMLの数式の要素内にハイパーリンクを入れる方法

#背景

現在HTML5になって、HTMLとMathMLが混在できるようになっていますが、
Microsoft EdgeやGoogle ChromeではMathMLの中にHTMLのaタグを入れるとエラーになるため、
MathMLの数式にリンクを入れる方法を探しました。

#実装方法

MathML2→3の変更点　https://www.w3.org/TR/MathML3/appendixf.html
日本語訳　http://washitake.com/MathML/ver3/appendixf.html

MathMLの仕様によると、MathML3になってからMathMLのタグすべてにhref属性が追加されたので、__MathMLの個々のタグのhref属性にリンクを入れる__ことでハイパーリンクを実装することができます。MathJaxのCDNを付ければ、MathJaxでも動作します。

```HTML:MathMLの要素リンク
<math>
	<mfrac>
		<mi href="http://washitake.com/MathML/ver3/appendixf.html">y</mi>
		<mi>x</mi>
	</mfrac>
</math>
```

MDN web docsのブラウザー互換性の項目によると、MathMLの全てのタグにhref属性を実装しきれていないブラウザーがある（例：[miタグ](https://developer.mozilla.org/ja/docs/Web/MathML/Element/mi#ブラウザー互換性)）とされていますが、実際に対応していないとされるiPhoneのSafariで試してみると動作しました。徐々に対応しているのかもしれません。

##互換性対策

ただもし実装状況が気になるのであれば、[mrowタグのhref属性](https://developer.mozilla.org/ja/docs/Web/MathML/Element/mrow#Browser_compatibility)に関してはほぼすべてのMathML対応ブラウザー(FirefoxとSafariのみ)が対応しているようですので、__リンクを付けたいMathMLタグの外側にhref属性付きmrowタグで囲む__方法で対応すれば無難です。MathJaxのCDNを付ければ、MathJaxでも動作します。

```HTML:MathML(mrowで囲む)
<math>
	<mfrac>
		<mrow href="http://washitake.com/MathML/ver3/appendixf.html">
			<mi>y</mi>
		</mrow>
		<mi>x</mi>
	</mfrac>
</math>
```

ただ本来はMathMLの全てのタグにhref属性があることが仕様なので、仕様通りに実装されることが望ましいので、互換性対策だけのためにmrowで囲むことは必要なくなってくると考えられますが、元々mrowタグは複数タグを一つのグループにまとめるための要素なので、その用途上MathMLのタグの中では比較的使用頻度が高いタグです。

特に分数や上付き下付き文字にはほぼ不可欠と言っても過言ではないタグですので、互換性用途以外でhref属性付きmrowタグで囲む場面は出てくると考えられます。

#複数要素に対するハイパーリンク

```HTML:MathML(複数要素を対象にしたハイパーリンク)
<math>
	<mfrac>
		<mrow href="http://washitake.com/MathML/ver3/appendixf.html">
			<mo>d</mo>
			<msup>
				<mi>e</mi>
				<mrow><mi>-i</mi><mo>&x2062;</mo><mi>x</mi></mrow>
			</msup>
		</mrow>
		<mrow><mo>d</mo><mi>x</mi></mrow>
	</mfrac>
</math>
```

__href属性付きmrowタグで囲めば動作します。__MathJaxのCDNを付ければ、MathJaxでも動作します。
Hello Programing

# Hello Programing(仮称)

コンセプトは初心者プログラマが簡単に扱える、総合プログラミングエディタを作ること
インターネットクラウドと連携すること
根本的なエンジニア学習教材とすること
低水準レベルも学ぶ要素とする

# 背景

プログラム作成の手順が分からない
たまたまPHPを学ぼうとして、読んだ本が分かりやすかった　https://www.amazon.co.jp/PHP-MySQL%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%96%E3%83%83%E3%82%AF-%E6%B0%B8%E7%94%B0-%E9%A0%86%E4%BC%B8/dp/4839947597
p172～p173の内容

# アイデア

まずＯＯＰのシナリオをつくるところから始まる。
できれば、ＣＬＩベースにしたい

# イメージ

以下の順に開発コンセプトを、人工無能で作成する　→　ときどきAI先生が入る場合がある

１．シナリオ分析
２．操作の書き出し
３．必要な情報の洗い出し
４．必要な処理の洗い出し
５．シナリオ分析でクラス生成
６．処理を追加
７．全言語でソースコードのひな型が完成する
８．具現化したいことをTODOで書き込む
９．GOOGLE翻訳されたコードが完成する
１０．GIT-HUBのリポジトリとして公開される
１１．全世界のエンジニアが参画して、知らない間にアプリが完成する

# 検討項目

レトロコンピュータで開発すること（PC8001、MSX，APPLEなど、ここは幅広く）
開発環境自体が一番簡単であることが望ましい
（但しＧＵＩとインターネットは、ハンディキャップなのでアセンブラで開発する）
・WEB-SERVER
・X-WINDOWS

# 最終的に

全人類がハッピーにコンピューターを使える世界にする
（ＡＩが人類の知能を超えてしまう前に・・・）

# 終わりに
　レトロｐｃ＋クラウド使えば、無限の可能性を感じる。。。
seabornとmatplotlibのfigureとaxesを使って複数のグラフを描く

# 概要
matplotlibをドキュメントを読まずに場当たり的に使っていると、
イマイチよく分からないままになるfigureとaxesをさらっと分かった気になる記事
(分かるわけではない)

# どうしてこれを書いたか

ちょっとドキュメントを読んだら分かった気になったので、
他の人にも分かった気になって欲しかったから。

# ちゃんと理解するには

- [公式](https://matplotlib.org/) を読む
- [matplotlibのめっちゃまとめ](https://qiita.com/nkay/items/d1eb91e33b9d6469ef51)
- [matplotlibの階層構造を知ると幸せになれる(かもしれない)](https://qiita.com/ceptree/items/5fb5e9e6f29d214153c9)

# 内容

## 前提

以下は省略して書きます。

```python
import numpy as np
import seaborn as sns
from matplotlib import pyplot as plt
```

## まずはじめに

figureとaxesはこんな関係。
figureが描画領域全体で、axesがグラフの描画領域

- グラフの描画領域が1つの場合
![pic1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86853/8fa9db5c-37f0-023b-846f-08ee1ff3c39d.png)


- グラフの描画領域が2つ(1行2列)の場合
![pic2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86853/09fa6dac-0333-5596-7b5a-6ade8502f753.png)


## からっぽのグラフの描画領域を1行2列の配置で2つ作ってみる

```python
# サイズが8,4の描画領域と1行2列のグラフの描画領域を作る
fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(8,4))

# figureのタイトルを設定する
fig.suptitle("figure_title")

# 1番目の描画領域にタイトルを設定する
ax[0].set_title("axes0_title")

# 2番目の描画領域にタイトルを設定する
ax[1].set_title("axes1_title")
```

実行結果
![スクリーンショット 2020-11-01 21.15.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86853/65baa66c-f8d4-77b6-9bb6-43c5b81952c0.png)

## グラフを描画してみる

```python
# 10000個の数字を作る
norm_arr = np.random.randn(10000)

# サイズが6,3の描画領域と1行2列のグラフの描画領域を作る
fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(6,3))

# figureのタイトルを設定する
fig.suptitle("figure_title")

# 1番目のaxesにタイトルを設定する
ax[0].set_title("axes0")

# 1番めのaxesにグラフを書く
ax[0].hist(norm_arr)

# 2番目のaxesにタイトルを設定する
ax[1].set_title("axes1")

# 2番目のaxesにseabornでグラフを書く
sns.histplot(norm_arr, ax=ax[1])
```

実行結果
![スクリーンショット 2020-11-01 21.21.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86853/27ca3b1f-e901-4098-0198-ab503d03b41a.png)

## 重ねて描画してみる

```python
# 前項のコードの末尾に以下のコードを追加する
x_scat = np.random.randn(100)
y_scat = np.random.randint(low=100, high=500, size=(1,100))
ax[1].scatter(x_scat, y_scat) #1番目のaxesに散布図を書く
```
実行結果
実行結果2番目のaxesに重ねて描画されているのが分かる。
![スクリーンショット 2020-11-01 21.59.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86853/aed45f13-e154-3136-2728-7618fa321f70.png)

おわり
Xcode を開く方法を考える会 (xed の存在を教える記事)


別に時間かけて考える必要はなく、好きに開きゃいいです。

- README に書く導入コマンドのあとに、Xcode を開くコマンドをキレイにかけたらいいなとか。
- いろんなプロジェクトを CLI から開く時、かんたんなコマンドで開けたら良いなとか。

そういうモチベの記事です！
基本どんなプロジェクトでもすぐ対応できるよう、独自の shellscript を書くとかは無しで。

# 1. xed コマンド

この記事を書こうと思ったメインの内容です。

```shell
xed .
```

プロジェクトを開くときの一番の問題は、**CocoaPods のせいで .xcworkspace があるプロジェクトと無いプロジェクトがあること**です。
このコマンドでは、 **.xcworkspace を優先して開き、なければ .xcodeproj を開いてくれます**。
また、プロジェクト名は気にしなくて問題ありません。

開く際に優先される順位は下記です。

1. Package (Xcode 11+)<br>Server-Side Swift などプロジェクトルートに Package.swift があるもの
1. xcworkspace
1. xcodeproj
1. playground

引用: https://stackoverflow.com/a/52739630


# 2. open コマンド

`xed` を知るまでは通常の `open` コマンドを利用していました。

```shell
# 1. 通常利用 (xcworkspace がある場合は xcodeproj と共に 2 つ開いてしまう)
open *.xc*

# 2. xcworkspace があってもなくてもいい感じに開く
open *.xcw* || open *.xc*

# 3. Xcode beta や別バージョン共存時に正しく開く
open -a Xcode-beta *.xc*
```

こちらで唯一 `xed` に勝る点は 3 です。
Xcode のバージョン移行時期は、 beta 版や過去バージョンなどと共存することがほとんだと思います。複数プロジェクトに関わってると、プロジェクトごとに移行の進捗も変わるため、適切な Xcode を開ける必要があります。


# 後記

最近は `Carthage` の Xcode 12 対応が遅れたりで、
`Swift Package Manager` への移行が加速してる感じがします。
この流れで `CocoaPods` も淘汰されたら .xcworkspace 無くなるので幸せですね。

他に良い方法があれば教えて下さい。
gasエラーtips

##本記事の目的
gasで自分が詰まったところ、エラーが発生したところを共有して皆さんの役に立てていただきたい

###エラー1:gasのwebアプリがgsuite配下では開けない問題
gsuiteで作成したwebアプリは公開してもgsuite内の人しか見ることができない。
例をあげるとgasでhtmlをgsuiteのアカウントで作成した場合、他のブラウザでログインしていない状態で見ようとするとドライブのエラーと表記が出る。
なのであまりないとは思うのですがgasでhtmlや、webアプリを作成されたときはgsuiteではなくフリー版の@gmail.comでないと公開できないです。
こちらのエラーに関しては詳しく下記の記事に書きました!是非ご覧ください。
https://qiita.com/taigasenren/items/821e541998283ac0eb3c


###エラー2
シートから時間の値を取得した場合の処理について



##最後に
随時追記していきます。最終更新(11/2)

現在私は個人事業主として下記のサイトの事業を取り進めております。(サイトはまだ作成して間もないのでまだガタガタです、、)
ホテルの自動チェックインのラインでの実装や、rpaの制作をメインに進めています。
作業の自動化等にご興味があれば是非ご連絡ください。何卒よろしくお願いいたします。
https://senren.work/
aws-cdkでエラー Argument of type ‘this’ is not assignable to parameter of type ‘Construct’

aws-cdkでコードを書いていたところ、以下の`this`の部分でエラーが起きました。

```
const table = new DynamoDb.Table(this, “hoge”, {
...
}
```

```
Argument of type ‘this’ is not assignable to parameter of type ‘Construct’
```

原因は、CDKのバージョンが合っていないときに起きるようです。
https://github.com/aws/aws-cdk/issues/542

例えば、CDKを導入後に新しくDynamoDBを使うことになったら、@aws-cdk/aws-dynamodbをインストールしますよね。この@aws-cdk/aws-dynamodbのバージョンと、以前にインストールした@aws-cdk/coreなどのバージョンは合わせておく必要があります。
【CSS】Footer（フッター）の固定方法

CSSで要素を編集する度に、上へ行ったり下に行ったり、あちこち移動するフッター…。
あんたはじっとしてなさい！ということでCSSでフッターを固定する方法を紹介します。

フッターを固定するコードは以下のようになります。

```css
footer{  
  position: fixed;
  left: 0;
  bottom: 0;
  width: 100%;
}
```

一行ずつ何をしているのか説明しますね。
<br>

:sparkles:一行目

```css
 position: fixed;
```
これは、要素を画面の決まった位置に固定したい時に使用します。
この画面では、LGTMやストックボタン、SNSのシェアボタンが画面をスクロールしても、いつでもスクリーンの同じ位置に表示されていますよね。
フッターの場合は、いつでも画面の一番下に表示されていて欲しいので、fixedを使用し「この要素（フッター）は、画面のある位置に固定したいです」と宣言します。
<br>

:sparkles:二行目と三行目（同じ仕組みなのでまとめて説明します）

先ほどは、「フッターを固定したい！」と宣言したので、次にどの位置に固定したいのかを書いていきます。

```css
 left: 0;
 bottom: 0;
```
これは、フッターを左また下からどのくらい離れた所に配置したいかを指定しています。
フッターは一番下にピローンと横たわっていて欲しいので、以下の図のように、左からゼロ距離かつ下からゼロ距離に配置します。
![Screenshot 2020-11-02 at 02.20.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/841745/6c137d44-a800-a9b3-6842-88aa05d54001.png)

:sparkles:四行目

```css
 width: 100%;
```
これは、フッターの幅を表してします。
フッターには画面に左端から右端までみょーんと伸びていて欲しいので、100%にします。
「100%」と画面に対する比率で設定することで、スクリーンの大きさやブラウザの幅に左右されず、どの大きさの画面でも、一番下の端から端まで表示されます。

ご参考まで。


参考元
[How TO - Fixed Footer](https://www.w3schools.com/howto/howto_css_fixed_footer.asp)
[CSSのpositionを総まとめ！absoluteやfixedの使い方は？](https://saruwakakun.com/html-css/basic/relative-absolute-fixed#section6)
Teradataの調査方法一覧

#状態の確認

###システム

| No. | 確認内容 | 説明 |
|:-:|:-:|:-:|
| 1 | [プロセスの状態](https://qiita.com/bickel/items/e5b0a6bb90960db463fa) |   |
| 2 | [接続しているセッション](https://qiita.com/bickel/items/b0ae42d837a87dfb6919)  |   |
| 3 | [HUTロックの取得状態](https://qiita.com/bickel/items/a8a28bb0f257e3a3c824)  |   |
| 4 | [リソース使用状況](https://qiita.com/bickel/items/f7a02501fd832585d807)  |   |
| 5  | [ログ](https://qiita.com/bickel/items/df9fdea836a965af5237)  |   |

#SQL
| No. | 確認内容 | 説明 |
|:-:|:-:|:-:|
| 1 | [統計情報](https://qiita.com/bickel/items/27bea1edd379abc52b87) |   |
| 2 | [実行されたSQL](https://qiita.com/bickel/items/06c6a52d2f21db2cfc9f)  | DBQL  |
| 3 | [実行計画](https://qiita.com/bickel/items/7291abffe4a8cc6b3d18)  |   |
|   |   |   |

#オブジェクト
| No. | 確認内容 | 説明 |
|:-:|:-:|:-:|
| 1 | [定義](https://qiita.com/bickel/items/390cc755143234fd72fe) |   |
ログ（messages）の確認方法

#目的
ログを確認する。（oracleのアラートログ）

#コマンド
| 内容 | コマンド | 実行例 |
|:-:|:-:|:-:|
| ログを確認  | gedit /var/log/messages 
| ログを確認(PDEツール)  | logview

#実行例
```
TDExpress1620_Sles11:/var/log # gedit /var/log/messages 
```

#参考
[]()
[]()
[]()
【TextAliveAppAPI】Segments（サビ・繰り返し区間）の概念

# 初めに
皆さんTextAliveAppAPI楽しんでますか？　生まれたばかりで文献が少ないですが、PVとかみてるといろいろ夢が広がりんぐで楽しいですよね。
しかしまぁほんとに文献がないので軽率に書き散らして行こうと思います。
言い換えると軽率に書き散らしているので薄い理解で書いてる可能性があるのであまり信じないでください。また、執筆時正しくても、バージョンアップで†破壊的変更†が行われて動かなくなる可能性もありますので、そこらへんよろしくおねがいします。
今回のテーマは「今いる区間の特徴を得る」です。

# Segmentとは
Segment、つまり区間という情報があります。しかしこの説明がサビ区間だとか繰り返し区間だとか書いてあってイマイチピンときません。
`Segments`にはサビかどうかの条件がありますが、これが`Segment`になると失われてしまいます。
思うよにこの情報を取り出せないので、やや複雑な記述をしなければならなそうです。

# Songleを知っていますか？
そもそも、サビだ何だの情報をどこから受け取っているのかと言えば、能動的音楽鑑賞サービス[Songle（ソングル）](https://songle.jp/)です。
ざっくりいうと、YouTubeとかニコニコ動画とかピアプロとかに点在する楽曲を解析してサビ情報とかコード情報とか音階を取得・表示するサービスです。
自動解析に加え人間による手直しもできるっぽいです。

で、これには下みたいな感じで、楽曲全体について楽曲構造を区間表示しています。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/220092/4d4f2ada-8715-afe8-f308-dbbe3ca6eb38.png)

>上部には、楽曲の全体構造として、**サビ区間がオレンジ・その他の繰り返し区間がブルー**で表示されています。クリックするだけでその区間の先頭にジャンプできるので、興味のある区間の頭出しをしたり、複数の区間を素早く聴き比べることができます。([使い方 - Songle](https://docs.songle.jp/help/))

これの位置情報が、各段として`player.data.songMap.segments`に`array`で保存されているのです。
この各段はそれぞれが類似していることを示しているらしいです。
なんか[この辺](http://winnie.kuis.kyoto-u.ac.jp/~yoshii/papers/ipsj-2013-goto.pdf)にそんな感じのことが書いてあった。
サビ以外の各段の順番に意味は無く、自動生成の結果からどの段がサビか(サビ同士は類似しているだろうだから、サビがあるならこれらの段のいずれかを選ぶことになる)を判定しそれを0番にコピーし、`chorus:true`をつけているようです。
（サビが二種類あるタイプの楽曲（どの曲がそれに該当するのかは知らない）とかあったらどういう扱いになっているのかは気になるところがありますね）

**追記**
どうやら上の話は自動生成の結果の場合みたいで、その後に手動で操作すればサビと別の段が一致しないような状態も作れるようです。イントロでしんみりverが流れる場合など、異なるという状況はありえます。
ちなみに、songleでは各段におけるsegmentsの長さが同一であるようになっていたのでテンポまで違うと思うようにはいきませんが……

指定された位置がサビのときだけサビの区間情報を返す`player.findChorus(time)`はありますが、これでは類似区間というデータを活かしきれなさそうです。
この辺をいい感じに使って、何段目かを取得するコードを書いておきます。

```sample.js
function getSegNumber(time){
  const ans=[];
  for(let i=0; i<segments.length; i++){
    Array.from(segments[i].segments, (z)=>{
      if(z.contains(time)) ans.push(i);
    });
  }
  return ans;
}
```
`segments`は`onVideoReady`あたりでの`player.data.songMap.segments`です。
楽曲によっては、複数の段にSegmentがあることがあるので配列で返しました。
chorus(サビ)の段は元の段がコピーされるようで、常に複数帰ってきます。
区間の合計数は20かそこらだろうからそんなに重い処理ではないし、各段それぞれにおいてSegment同士のかぶりは無いはずなので、実装はこんな感じで大丈夫だと思います。多分。


これで値を得ておけば、`ans[0]===0`でサビ判定もできます。（サビは常に0行目なので、一番最初にpushされます）


# 終わりに
こんな感じのやつがAPIにあっても良いと思うなぁ。（そんな実装手間じゃないから別に無いと困るほどじゃないけど）
**追記**
songleの編集操作をやっておくと理解がはかどります。
WordPressの残念なプラグインと強制アップデート

# 概要
WordPressの[Loginizer](https://ja.wordpress.org/plugins/loginizer/)というセキュリティプラグインに、致命的な脆弱性が見つかったことと、当該プラグインの強制アップデートが行われた話。


# Logininzerの脆弱性
Logininzerにはログイン試行を失敗したユーザ名やIPアドレスを記録する機能があるが、[DBに保存する際にSQLインジェクションの脆弱性があった](https://wpscan.com/vulnerability/10441)という不具合。セキュリティ強化プラグインを名乗っているのに、[「サニタイジングを試みて失敗した」ですらない](https://plugins.trac.wordpress.org/browser/loginizer/tags/1.6.3/init.php#L755)残念な脆弱性かつ、[2年前にもSQLインジェクションの脆弱性を指摘され修正していた](https://qiita.com/prograti/items/951949e407fe8a40043b)という本当に残念なプラグイン。

この脆弱性はログイン画面での入力を攻撃に使うため、未認証で利用できるSQLインジェクションということで、致命的な脆弱性と言える。

# WordPressでのプラグインの強制アップデート
恐らく、攻撃に特別な条件が不要なこと、攻撃が簡単なこと、プラグインのインストール数が多いことなどの理由を理由として、[WordPressの強制アップデート機能を利用しての当該プラグインのアップデートが行われた](https://www.tripwire.com/state-of-security/featured/loginizer-wordpress-plugin-forced-update/)。これは自動アップデートを無効にしていたとしても、依然有効な自動アップデート機能だった。

どのような機構で強制アップデートを行うことができたのか、今後調べてみる。
index.htmlだけでCSVを検索するシステムをつくる

# 概要
`index.html`だけでCSVを検索するシステムをつくりました。
以下の方法でCSVファイルを読み込み表示します。

- 予めアップロードしたCSVを読み込む
- `<input type="file">`でダイアログからCSVファイルを選択する

# 使用したフレームワーク

- JavaScript：Vue.js
- CSV変換：PapaParse
- CSS：bulma

# 使用したオープンデータ(CSVファイル)

以下のオープンデータを使用しました。

- https://www.itdashboard.go.jp/DataFeeds/csv#300
- https://www.e-stat.go.jp/stat-search/files?page=1&layout=datalist&toukei=00200521&tstat=000001011777&cycle=0&tclass1=000001094741

# 公開先

- コード
  - https://gitlab.com/tamoco-mocomoco/csv-search
  - コードは`index.html`だけをご確認ください【[こちら](https://gitlab.com/tamoco-mocomoco/csv-search/-/blob/master/public/index.html)】

- ウェブページ
  - https://tamoco-mocomoco.gitlab.io/csv-search

# できること

## 列を指定して検索できる

指定した列のデータに文字が含まれているモノだけを絞り込みます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412322/a08b3482-549c-34d6-78a9-0ae06b030944.png)


## 数値データなら比較できる

数値の場合なら以上や以下などで絞り込むことができます。
ただし、上手く比較できないデータもあったので要調査。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412322/eaaaefb3-0bf4-d06e-3f08-42e317ea1e00.png)

## 予め準備しておいたCSVを読み込むことができる

以下のフォルダ構成で予めCSVをアップロードしておいて読み込むこともできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412322/c780b979-0c27-d62c-f914-7b2b3eb1a597.png)

コード側は以下の`csvPathList`に設定します。

```
            el: '#app',
            data: {
                isMenuOpen: false,
                isHttpReq: false,
                csvTitle: null,
                csvCols: [],
                csvData: [],
                allCsvData: [],
                selectedCol: null,
                searchKeyword: null,
                numSearchMode: false,
                numSearchCondition: 'eq',
                numSearchParams: ['eq', 'gt', 'le'],
                searchNumMode: false,
                csvPathList: [
                    { btnName: 'data1', csvPath: 'csv/男女別人口全国都道府県（大正９年～平成27年）.csv' },
                    { btnName: 'data2', csvPath: 'csv/年齢（５歳階級）男女別人口－全国（大正９年～平成27年）.csv' },
                    { btnName: 'data3', csvPath: 'csv/年齢（５歳階級）男女別人口－都道府県（大正９年～平成27年）.csv' },
                    { btnName: 'data4', csvPath: 'csv/IT投資計画_InvestmentPlan_20201031015945.csv' }
                ]
            },
```

## CSVファイルを選択して読み込むことができる

メニューの「Import」をクリックすることで、ファイルダイアログからCSVファイルを選択できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412322/6712841f-d9e6-41d4-53ea-bee2ceda1ac8.png)

# ふりかえり
`index.html`だけでCSVを検索する仕組みをつくれました。
意外にお手軽に取り掛かることができ２～３時間くらいで作成できました。
環境などの準備が必要ないので初心者の方でも気軽にチャレンジしていただければ幸いです。

- ハマったポイント
  - `Papaparse`でCSVを読み込むことができます
  - `Papaparse`でも予めアップロードしたモノをダウンロードして読み込むこともできます
  - ただし`Shift-Jis`形式のCSVが上手く読み込めず文字化けしてしまいました
  - そのため敢えて`XMLHttpRequest`で読み込むようにしています
【Google日本語入力】数字キーを使うことなく「- 、1. 、#、~~」を打ち出す。

簡単な内容なので、サクッとスッキリ書きます。

# １．目的

キーボードの数字の列まで指を動かすことなく、Markdownでよく使う文字列を打ち出せるようにする。

# ２．手順

## 概要
ローマ字入力の割り当てに新規登録します。

## 手順
1. タスクバーに表示されている「あ」もしくは「A」を右クリック
2. 「プロパティ」を選択
3. ～設定画面が表示される～
4. 「一般」タブを選択。
5. 「キー設定＞ローマ字テーブル」の「編集」を選択。
6. 目的の内容を「ローマ字」として登録する。

## 設定例
- ```mn``` → ```- ``` 箇条書き用。「minus」のつもり。半角スペースあり。 
- ```sj``` → ```1. ``` 箇条書き用。「数字」のつもり。半角スペースあり。
- ```tk``` → ```#``` 見出し用。「tag keyword」のつもり。
- ```dl``` → ```~~``` 取り消し線用。「delete」のつもり。
- ```la```たちと重複する```xa```たちの登録は削除。「x」に機能を割り当てる。

## 注意点
- 既にあるローマ字入力と被らないようにする。

## 設定画面
![2020-11-02 ローマ字入力.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665190/b17df789-6f4a-2196-790d-38a7ebec8589.png)

## 設定サンプル
設定をエクスポートして追加分だけ取り出しました。

```
mn	- 
tk	#
sg	1. 
dl	~~
```


# ３．参考ページ
- https://technote.flyingjunk.net/955/

# ４．雑感
Google日本語入力を使っています。「きょう」が「2020-11-02」に変換されたりと結構重宝していますが、基本機能の「変換」については「変換候補の並び順」についてはMS-IMEに劣ると感じています。

まあ、地道に学習してもらうしかないと思って諦めていたのですが、「何かあるはず」と思って調べたら「抑制単語」や「zk」で「↑」と変換されることなどを知りました。VIM操作チックでちょっと喜んでいます。

危うくここで満足しかけるところだったのですが、一歩発想を推し進めて「カスタマイズできないか？」と思って調べました。で、今に至る。

# 以上
この素晴らしい TensorFlow Serving に祝福を! - docker-compose で簡単デプロイ

# はじめに

TensorFlow 2.0 から TensorFlow Serving が実装され，Flask で推論サーバを構築しなくても Docker を使い簡単にエンドポイントを作成できるようになりました．

今回は TensorFlow 2.0 と Docker と docker-compose を使い，簡単にエンドポイントを立てる方法を備忘録としてまとめました．

# 学習
今回は `fashion_mnist` を使い簡単にモデルを作成しました．

``` python
import json

import tensorflow as tf
from tensorflow import keras

fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
train_images = train_images / 255.0

d = {'signature_name': 'serving_default',
     'inputs': [test_images[0].tolist()]}

with open('./test_data.json', mode='w') as f:
    f.write(json.dumps(d))
    
model = keras.Sequential([
    keras.layers.Flatten(input_shape=(28, 28), name='inputs'),
    keras.layers.Dense(128, activation=tf.nn.relu),
    keras.layers.Dense(10, activation=tf.nn.softmax)
    ])

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(train_images, train_labels, epochs=5)

tf.saved_model.save(model, './models/fashion_model/1')
```

# エンドポイントを立てる

上記で保存したモデルを使いエンドポイントを立てます．

イメージは公式が公開している `tensorflow/serving` を使用します．
https://hub.docker.com/r/tensorflow/serving

```yaml
version: '3'
services:
  app:
    image: tensorflow/serving 
    container_name: fashon_endpoint_test
    ports:
      - 8501:8501
    volumes:
      - ./models:/models/fashion_model
    environment:
      - MODEL_NAME=fashion_model
      - MODEL_BASE_PATH=/models/fashion_model
```

### 簡単デプロイ！

```shell
$ docker-compose up
```

# テスト
```shell
$ curl -X POST -H "Content-Type: application/json" http://localhost:8501/v1/models/fashion_model:predict -d @test_data.json
```

楽勝

# おわりに

昨今では PyTorch がディープラーニングフレームワークのデファクトスタンダードになりつつあり，kaggle や 学術分野などでも多くのコードが PyTorch で書かれています．

PyTorch にはこのような機能がなく(少なくとも自分が調べた範囲では…もしあったら…ごめん)，モデルデプロイに関しては TensorFlow に軍配が上がった感覚を覚えました．

今回は触れませんでしたが，signature やメタデータの利用により，より可用性のあるモデル管理ができるらしいのですが，今回はデプロイから推論のお手軽さのみの紹介にとどめます．

# コード
https://github.com/TsuchiyaYutaro/tensorflow2_serving_test

# 参考
https://blog.ornew.io/posts/building-tensorflow-v2-serving-in-1-minute/
ActiveStorage vs CarrierWave

ActiveStorageが公表されてから1年以上経ちますが、いまだに伝統的手法(?)であるCarrierWaveに置き換わることはなく、どちらを使うか論争が続いているようです。（私は何となくActiveStorageを使っていました。）

基本的にバリデーションやクラウドストレージとの連携においては、手順の違いこそあれどちらもできますし、設定手順やコードの記述量もそれほど変わらないので、使用可否を判断する決定的な基準にはならなさそうです。

ですが、今回アプリ開発においてCarrieWaveを使おうと決めましたので、その理由をメモしておきます。

# 結論

- **viewsをvue.jsで書く場合は、Carrier Waveを使う**

## 理由1 erbを書かない場合はactive storageの強みを活かせない

- erbを使うか否かの違いは、HTML内に<%=  %>を使えるかどうかです。
Active Storageは前提として、<%=  %>でform_withで入力したりや@imageとかで画像表示をする時に、この中に画像の処理を記述することで、controllerのコード記述を少なく書けるのが特徴です。
- 言い換えれば、<%=  %>を使わずに画像を処理・保存するとなると、どこで画像処理などのプログラムを記述すれば良いかわかりにくいです。（できなくはないですが、わざわざしんどい思いをしてactive storageを使うメリットがありません）
- その点、CarrierWaveを使う方法では、CarrierWave::Uploaderというクラスが生成され、ここに画像の処理するコードを記載すれば良いんだなとわかりやすいです。（正確には画像加工はMiniMagickの仕事ですが、まあ良しなに解釈してください）

## 理由2 active storageはデータ構造がわかりにくい

- active storageを導入すると、BlobとAttachment の2つのモデルが自動的に生成されて、画像データはBlobに保管してAttachmentで紐づけることになります。
- これが直感的に分かり易ければ良いのですが、画像を呼び出したり編集したりする時に、どうやって画像データを指定すれば良いのか非常にわかりにくいです。（vueから画像を呼び出すような使い方をしていればなおさら。）
- 一方でCarrierWaveを使うと、URL生成やファイル取得はCarrierwaveのUploaderで記述できますし、画像はAWS S3に直接アップして、モデルはURLだけ保持するような書き方が直感的にできます。

# ActiveStorage vs CarrierWave論争

- 画像管理をActiveStorageからCarrierWaveへ乗り換えた話

> [https://tech.dely.jp/entry/2019/12/22/145733](https://tech.dely.jp/entry/2019/12/22/145733)

- [Rails6] CarrierWaveでActive Record(Active Storage)を使用せずにGCSに画像をアップする方法

> [https://nobunobu1717.site/?p=1393](https://nobunobu1717.site/?p=1393)

- Rails5.2から入る新機能ActiveStorageを使うべきか?

> [https://qiita.com/yatmsu/items/08b95e837ac7f24fb443](https://qiita.com/yatmsu/items/08b95e837ac7f24fb443)

公平な目で調べましたが、active storage反対派が多いですね・・・

私はアプリ開発はherokuの無料枠内で開発していますので、データの書き換えを頻繁にされると困ります。

# Active Storageでできること

Active Storageは使わないことにしましたが、Acive Storageを使えばスピード実装できるので便利な部分もあります。

- Active Adminで画像を保存できるようにする（ckeditorを使う）
**開発時にはすごく使える技です。**

> [https://qiita.com/uruzo/items/2fc37ec09a5e0aec6ace](https://qiita.com/uruzo/items/2fc37ec09a5e0aec6ace)

- 画像の保存は生の状態で行い、表示の時にサイズを整える。（variantで指定）

> [https://qiita.com/kazuomatz/items/3cdbd2c40576c2e9d89b](https://qiita.com/kazuomatz/items/3cdbd2c40576c2e9d89b)

# 私の設計

- 私はviewの中身をerbで書かずにvue.jsで書いています。その理由は、個人的なこだわりとして、viewsはテキストや画像の表示に特化するべきであると考えているため、RailsのviewsのようにHTML内にプログラムを書くやり方は好きではないからです。
- 言うまでもなくvueを使う場合は、HTML内に<%=  form_with %>などは使えず、フロント側とバック側はaxiosを使ったAPIでやりとりをしています。
- 画像の保存はBase64でエンコードして保存、画像の表示は画像リンクを指定して表示させます。（このやり方は別記事で書きます）
【JavaScript】axios(ajax)でエラー時のレスポンスbodyが取得できない

## はじめに

盲点だったのでメモ。
フロントからRailsのAPIへpostしてエラーになった際、詳細なメッセージをresponseボディに入れて返したかった。

##Ruby on Rails

```ruby
if user.save
  render json: { status: 200, data: user }
else
  render  status: :unprocessable_entity, json:{ messages: user.errors.full_messages }
end
```

## JavaScript

```javascript
axios
  .post(process.env.API_URL + '/api/v1/users/signup')
  .then((res) => {
    console.log(res)
   })
  .catch((e) => {
    console.log(e)
   })
```

## 結果

```shell
Error: Request failed with status code 422
    at createError (createError.js?2d83:16)
    at settle (settle.js?467f:17)
    at XMLHttpRequest.handleLoad (xhr.js?b50d:69)
```

<br>

### エラーのレスポンスbodyが取れない、、、
<br>

## 対処法

railsのエラーの返し方がいけないのかと思って詰まっていたが、問題はフロントだった。
エラーのresponseには以下のようにアクセスできる

```javascript
  .catch((e) => {
    console.log(e.response.data.messages)
   })
```

200の時はObjectを返してくれるのに、、、

``` shell
{data: {…}, status: 200, statusText: "OK", headers: {…}, config: {…}, …}
```

## まとめ
不得意だからと矛先をバックエンドに向けてしまっていたが、フロントの実力もまだまだだった。。。
壁に当たった時は、一旦決めつけを捨てて、原因を一つ一つ丁寧に探っていくべきだと改めて感じました。
JavaScriptで図形の左寄せの直角三角形を作る【自分用】

 初めての投稿です。
プログラミング初心者なので間違いはあると思いますが、あらかじめご了承ください。

今回は題名の通りJavaScriptで左寄せの直角三角形を作る方法です。
課題をやっていて躓いたため、誰かのためになればと思い、ここに覚書きとして残しておきます。

yahoo!知恵袋にはString.repeatメソッドを使うやり方が多くあり、たぶんそちらの方が主流（というか簡潔）なのではないかと思いますが
for文の2重ループにて処理する方法は以下の通りです。

```js
for(var i=0; i<5;i++){
  for(var a=0;a<i+1;a++){
  document.write("■");
}
document.write("<br>");
}
/*
■
■■
■■■
■■■■
■■■■■
*/
```
### ポイント
2行目のfor文の条件式a<i+1です。
iが０の時、a<0+1でaは1度のみ処理されます。
iが０の時はa<1+1（２になる）ので2回処理され・・・

というのを5回繰り返すコードになっています。

ご参考になれば・・・
PhpStorm＋Docker＋PHPUnitでテストをする

PhpStormの上の方に、RUNボタンがありますよね。
ここでいろいろなCofigurationを作ることで、Scriptを実行したり、
UnitTestを走らせることが出来ます。

今回は表題のとおり、Docker環境上でPhpStormからテストを走らせたい場合の
設定をしましたので共有します。


# Interpreterの設定
まず、PHPのInterpreterから設定が必要です。
今回の場合ははDockerコンテナ内のInterpreterを指定します。
```⌘,```で設定画面を開き、phpと検索するとLaguage$Frameworksというのが見えると思いますのでクリックしてください。

CLI Interpreterを設定します。
![Screen Shot 2020-11-01 at 22.06.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429030/117d985f-e96c-25b9-704b-6d969b17401d.png)

...を押すと下記のような画面になりInterpreterを追加できます。
左上の＋を押してください。
![Screen Shot 2020-11-01 at 22.07.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429030/cdde64ad-2bb5-9588-a04c-1cfb75fd4d9a.png)

From Docker...を押します。
![Screen Shot 2020-11-01 at 22.07.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429030/1c08d8ca-ff17-a1df-fb15-8b7e124ce495.png)

Docker Composeにチェックを入れ、ConfigurationFileにdocker-compose.ymlのPathを入力。
すると、コンテナ一覧がService:のところに現れると思うので、PHPがインストールされているコンテナを選んでください。
![Screen Shot 2020-11-01 at 22.08.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429030/fd2453be-526f-31e9-625d-ab6fd482a24b.png)

これで設定されました！
![Screen Shot 2020-11-01 at 22.08.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429030/7fbc54be-a202-ae88-f445-338ced8afebe.png)

# テスト側の設定
Test Frameworksを選択し、左上＋からPHPUnit by Remote Interpreterを追加します。
![Screen Shot 2020-11-01 at 22.25.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429030/5709786b-ab87-d267-9d35-9414dfd454a2.png)
先程設定したものを選択。
![Screen Shot 2020-11-01 at 22.26.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429030/dc2a40d3-34d0-35c0-2fd4-e734b5598fe8.png)
Path to Scriptに、Dockerコンテナ上にある```autoload.php```を選択します。
Default configuration fileにも```phpuni.xml```へのPathを書きます。
![Screen Shot 2020-11-01 at 22.28.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429030/f8e8fef5-9feb-01d1-5239-41d8df3784c1.png)

# 最後に実行ファイル設定
エディター右上のRUNボタン隣にEdit Configurationがあるのでクリック。
![Screen Shot 2020-11-01 at 22.54.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429030/84600e9d-f06f-1b9c-3e7a-e8af2f0e16ac.png)

左の＋ボタンからPHPUnit用設定を追加し、名前は任意のものをつけます。
Defined in the Configuration fileにチェックを付けてOKボタンを押したら完了
🎉
![Screen Shot 2020-11-01 at 22.30.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429030/c0773a5c-c373-fe42-dab0-6e287bd90016.png)
クラウドファンディングのメモ

#クラウドファンディングとは
アイデアにいいねと思ってくれる人を見つけるツール
・共犯者を作る手段
・資金調達
・顧客を知る
・PRにつながる

クラウドファンディングの種類
購入型：支援に対してモノ・コトでリターン
寄付型：リターンがない代わりに、考動で示す
金融型：支援に対して利子や配当でリターンする

#クラウドファンディングで成功するには

・初速をつける
必ず中盤は停滞する。初速に勢いをつけられれば成功しやすい。

・最初から大きいものを狙わない

・投稿する際に、作るのは最低限
　→可能性を検証できるレベル
　→イメージを説明できるレベル

・ストーリーが大事

#プロジェクトを眺めて思ったこと
・ただの通販になってるプロジェクトもある
・成功していないプロジェクトは、読んでもなにがしたいのか分からないものが多い
IFTTTの使い方。TwitterでいいねしたツイートをEvernoteのノートに自動保存する。

#IFTTTとは
色々なサービスを連携させることができます。

連携例はこちら。
[【超便利】IFTTTのアプレット・レシピおすすめ21選]
(https://www.webhack.jp/gadgets/21-recommended-applet-recipes-for-ifttt/)

#手順
下の画像の通りにやればできます。
<img width="500" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737363/b46b6ad5-431e-dffb-db43-339e230d6f41.png">

<img width="500" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737363/a31f58c0-e4af-f4c9-ed01-1406b1467865.png">

<img width="500" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737363/1940fc1b-9205-4f43-f06c-3098b8cc5c8f.png">

<img width="500" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737363/fb665472-bfd9-63e1-5b0d-3fe102972b30.png">

<img width="500" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737363/60eda8b1-5d78-dcba-dde0-95b8fd8fe4b7.png">

<img width="500" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737363/7e426d0f-403f-9ca9-32a9-513c1a73e9ab.png">

<img width="500" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737363/812a574b-ff64-5061-c646-f7e4a5941ad3.png">

↓Evenoteで作成するノートのタイトル、本文、どのノートブックに保存するか選べます。
「Add ingredient」を押すと、ツイートのどの情報を使うか選択可能です。
<img width="500" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737363/48d18186-0714-d5f0-732f-af4f350fae5c.png">

<img width="500" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737363/bb7b7ec8-8441-6d47-f2b6-87e18900587f.png">

<img width="500" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737363/6e3d967e-ea81-1571-e10d-b2f32db3df5e.png">

<img width="500" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737363/c71fe9a2-1d32-892f-e9bc-ef72b6cb1ab0.png">


#完成品
<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737363/57d156d9-a36e-a1dc-3d19-bf5b7f681ab1.png">

<img width="500" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737363/43c19b18-a6fa-8007-10e7-619e0d36d113.png">
VirtualBoxからvmWare Fusionに乗り換える方法

#はじめに
macOSのゲストOSとしてWindowsを使っている人はそれなりにいると思われます。
有償ではParallelsやvmWare、無償ではVirtualBoxやBootCampといった棲み分けでした。

先日、vmWare FusionがmacOSで(略）無償化されました。
VirtualBoxよりもvmWareの方が動作が軽い、ということは知っていましたので乗り換えました。
で、VirtualBoxからvmWare Fusionに乗り換えようとした際に、環境の移行でドタバタした記録です。

#1.VBoxで仮想環境をエクスポート
VirtualBoxAdd-inは削除しておきます。
仮想環境を停止させ、**ファイル→仮想アプライアンスのエクスポート**を実行
![スクリーンショット 2020-11-02 0.06.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844197/075a0d5e-1a08-583e-4b5c-8baa570fbaa1.png)
.ovaファイルが出力されます。

#2.vmWare Fusionで仮想環境をインポート
ｖｍWareFusionを起動して、仮想環境をインポート
![スクリーンショット 2020-11-02 0.07.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844197/b5b23b0c-4bc9-fa82-2f75-73b2fe4f899c.png)
![スクリーンショット 2020-11-02 0.08.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844197/6594cd59-1138-23ed-8b88-dcf3f3c9d3cf.png)
問題なければ数時間で移行できるはずです。

#問題が起きたのでディスクイメージを直接変換する
仮想環境の起動途中で止まります。
中間ファイルの解釈でずっこけているのではないか？と仮定。
直接、vdiファイルをVMDKファイルに変換します。GUIからでは出来ませんが、CUIではできるみたいです。

```
$VBoxManage clonehd --format VMDK /Users/hoge/hoge/Windows10.vdi /Users/hoge/hoge/win10.vmdk
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Clone medium created in format 'VMDK'. UUID: ########-####-####-####-############
```
これだけ。
これですんなり起動してしまいました。

以上。