OmniAICreator/Qiita-1.07M huggingface dataset:
プログラミング超絶初心者の学習履歴

#はじめに
僕は自動車のハードウェア設計が専門で、プログラミングらしいものはエクセルの関数や簡単なマクロを使う程度（web上に公開されているものを少しだけ加工して使うレベル）で、苦手意識も強く避けて来たというのが正直なところでした。
しかしここ何年かはデータ収集・処理・分析が主業務となり、

**<font color = "red">「あぁプログラミングができれば・・・」</font>**

と思うことが多くなったため、
重い腰を上げて、2020年の春からボチボチと勉強を始めています。
僕の場合は**<font color = "blue">"データ”**に関する自動化や高度化を行いたかっため、
Pythonを軸としてプログラミングの世界に飛び込むことにしました。

以下、自分の記録　兼　もしかし僕のような　”非IT畑の方”　の参考になるかも
ということでボチボチ学習歴を記載していこうと思います。

ちなみに、”どういう順序で学ぶべきか？”ということは全く考えず、
興味の赴くままに、行き当たりばったり学んでいるので、参考にはならない可能性が高いですがご容赦ください笑


#Python学習記録

| 時期 | 内容 | 詳細 |
| :---: | :---: | :---: |
| 2020年3月頃 |意を決してTechgym（プログラミング教室）へ | とにかく自己コントロールができないので、無理矢理勉強せざるを得ない状況を作ろうと、2時間ほどの無料講習会に参加。Techgymの特徴は文法などは基本的に教えず、いきなり課題を与えられる点。最低限のヒントが提示され、それを参考にどうコードを書くべきか自分で考える→書く→また考える→どうしてもわからなければ回答を見る、のくり返しで学習していく。やりたいコト、作りたいモノをまず定め、それに必要な知識を優先的に付けるスタイルで、とにかく実践力重視。個人的には、 いきなり”Pyhtonとは？”的な講義ではなく、**<font color = "red">簡単でもコードを書いて実行→目的を達成ということを体験できて、とてもいいスタートになったと思います**。教室に通うことも考えましたがコロナにより断念。|
| 2020年3月頃 | Udemyで動画を爆買い | 本を読みながら勉強というのが大の苦手で、動画での勉強を選択。"Python" "初級" "入門"などのキーワードで評価が高く面白そうなものを5本ほど購入。定価だと5万円分くらいでしょうが、常にセール価格の気がするので実際は1万円ほどで購入できたと思います。|
|2020年4月頃 |Udemyで学習を開始|あるあるですが、動画を購入した時点がかなり満足してしまい、2週間ほど放置。これじゃいかんと奮い立って一番面白そうだと思った【ゼロから始めるデータ分析】というコースを視聴。”ゼロから”の名に相応しく、Anacondaの導入から説明が入るので、超絶初心者の自分にぴったりでした。こちらのコースはTechgymと近いスタイルで、文法などの説明はあまりなく、**”この時はこういうコードを書きました。ではこうしたい時はどうしたらいいでしょう？考えてみてください”**というスタイルで、個人的には楽しく学習を続けられました。動画そのものは8時間くらいだったと思いますが、自分で考えたり写経したりする時間があるので実際には倍の16時間程かけて学習を終えたと思います。|
|2020年4月頃|Udemyで学習を開始　その2|一つ目のコースを終えたことで「なんかできるかも」と謎の自信が湧いてしまい、次は飛び級気味に【人工知能・機械学習】のコースの視聴を開始。前半はよかったのですが、後半に入るとひたすら写経が続く感じで、**<font color = "red">”なぜこう書くんだろう？　今どういう処理をしているんだろう？”**とブラックボックス度合いが高くなり、学習意欲が低下してきました。14時間の動画を8時間程見たところで、”あーちょっと疲れた”となり、Udemyをそっ閉じしました。|
|2020年5月頃|さくらインターネットの無料プログラミング教材で勉強スタート|Udemyの経験から**<font color = "red">”さすがに少しは基本的な記述方法や構文は理解しとかないときついな”**と思っていたら、さくらインターネットさんが丁度教科書的なドキュメントを無料公開してくれていて、それを完全に写経しながら理解していくという形で、基礎中の基礎を学んでいきました。これによって<font color = "blue">超絶初心者から超初心者にアップグレード</font>されたような気がします。|
typescriptで使用できるORMライブラリ

## そもそもORMとは
ORM（Object-Relational Mapping）は、オブジェクト指向パラダイムを使用してデータベースからデータを照会および操作するのに役立つ手法です。

#### 利点
- データモデルを1か所に記述することになるため、コードの更新、保守、再利用が簡単になります。
- MVCコードの記述を強制するので、コードがよりクリーンになります。
- SQLクエリを作成する必要はありません。
- データベースレベルの変更を頻繁に行う必要はありません。
- ほとんどの作業は自動化されています。

#### 欠点
- 複雑なクエリでのパフォーマンスの問題。
- 慣れるまでは学習コストがかかります。

## typescriptで使用できるORMライブラリ

#### 1. Sequelize

- よく知られているPromiseベース（promiseをサポートしてる）のNode.js ORM
- MySQL、MariaDB、SQLite、Microsoft SQLServer、Postgresで使用できます。
- Sequelizeは機能が多く人気があります。
- [他のORMに比べてドキュメントも豊富](https://sequelize.org/v5/index.html)
- https://github.com/sequelize/sequelize

```typescript:example
const { Sequelize, Model, DataTypes } = require('sequelize');
const sequelize = new Sequelize('sqlite::memory:');

class User extends Model {}
User.init({
  username: DataTypes.STRING,
  birthday: DataTypes.DATE
}, { sequelize, modelName: 'user' });

(async () => {
  await sequelize.sync();
  const jane = await User.create({
    username: 'janedoe',
    birthday: new Date(1980, 6, 20)
  });
  console.log(jane.toJSON());
})();
```

#### 2. TypeORM

- 2016年頃に導入され、その人気は過去2、3年で急速に高まっています。
- この人気の背後にある主な理由は、TypeORMがTypeScriptとJavaScript（ES5、ES6、ES7、ES8）を非常にサポートしていることです。
- TypeORMは、最新のJavaScript機能を引き続きサポートし、開発者があらゆる種類のテクノロジーを使用できるようにするための新機能を提供することが目標であると述べています。
- MySQL、MariaDB、Postgres、CockroachDB、SQLite、Microsoft SQL Server、Oracle、SAP Hana、sql.js、MongoDBなどの幅広いデータベース管理システムもサポートしています。
- 他のJavaScriptORMと比較したTypeORMのもう1つの特徴は、アクティブレコードパターンとデータマッパーパターンの両方をサポートすることです。これにより、開発者は高品質で疎結合のスケーラブルなアプリケーションでコードを記述できます。
- 実装していてまだまだ情報量が少ないのがネックだと感じますが、直感的で書きやすいです。
- テーブル単位でコメントがつけられないのが地味に気になる。

```typescript:example
import {Entity, PrimaryGeneratedColumn, Column, BaseEntity} from "typeorm";

@Entity()
export class User extends BaseEntity {

    @PrimaryGeneratedColumn()
    id: number;

    @Column()
    firstName: string;

    @Column()
    lastName: string;

    @Column()
    age: number;

}
```


#### 3. Mongoose

- MongoDB用に特別に設計されたオブジェクトモデリングツール（MongoDB：ドキュメントベースのNoSQLデータベースシステム）
- https://mongoosejs.com/docs/documents.html


#### 4. Bookshelf

- Knex SQLクエリビルダと、それは、PostgreSQL、MySQLの、とSQLite3のデータベース管理システムをサポートしています。
- JavaScriptでデータベースにクエリを実行し、これらのオブジェクト間の関係を形成する際の一般的なタスク用の単純なライブラリを提供することです。
- https://bookshelfjs.org/


#### 5. Objection.js

- PostgreSQL、MySQL、およびSQLite3データベース管理システムをサポートしています。
- 公式のtypescriptサポート。
- オプションのJSONスキーマ検証。
- [SQLの機能の見やすさ](https://vincit.github.io/objection.js/guide/query-examples.html#find-queries)。
- [トランザクションの使いやすさ](https://vincit.github.io/objection.js/guide/transactions.html)。
- データベーススキーマの自動作成とモデル定義からの移行。・・・エトセトラエトセトラ・・・
- https://github.com/Vincit/objection.js/


引き続き追記していきます！
参考
https://docs.google.com/spreadsheets/d/1mJ3uffp9TqrCvxHbnaEs_q8D5CorNx6R_DXq9cI8rU4/edit#gid=691713550
【Java】Javaの3つの特徴

#Javaの特徴
* **オブジェクト指向**
* **Java仮想マシン**
* **ガベージコレクション**

##オブジェクト指向はデータを中心に考える
* そもそも本質はデータをどう加工するか、何をしたいのかはデータが中心に考える
* オブジェクト指向ではプログラムの中で扱う対象をモノ(オブジェクト)で表現
* アプリを構成するものは全てオブジェクトによって表現され、その組み合わせによってアプリを構成する
* **データとその操作をカプセル/一体化してコードをかく**
* よくやりがちな失敗は他のオブジェクトのデータを参照するメソッドを書き、他のオブジェクトのメソッドが別のオブジェクトのデータを参照してしまう
* オブジェクト1のメソッドが意味がなくなる→データオブジェクトという(凝集性が悪い)
* **オブジェクト1のデータを参照するのはオブジェクト1のメソッドでないといけない**
* 基本的にはデータとメソッドは一体化しよう！

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282755/fb3dd252-c3d3-7081-539f-f9cd1e128775.png)


##Java仮想マシンはバイナリコード
* JavaはJava仮想マシンの上で動作
* JavaはC++ の改良版である（とも言える）が実行するときは全く違う構成になっている
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282755/e742f4cc-87cc-118f-c6a0-d11c53603257.png)

###C++
* PCに電気が入りCPUが動く
* CPUはマシン語で動いてる
* アセンブラ記述(C/C++)→コンパイル→マシン語(バイナリコード)
* アセンブラでかくとダイレクトにマシン語になる
* バイナリコードのみがCPUを直接動かすことができる

###Java
* Java仮想マシンの上で動作
* CPUの上にJava仮想マシンを作る
* Java仮想マシンがCPUを直接動かせるバイナリコードである
    * JDK、JREをインストールしないとJava仮想マシンが動かない
* Javaをコンパイルすると中間コードを吐き出す
    * 中間コードはバイナリコードの上で動かす必要
* 中間コードを介するので直接CPUを動かすC++より遅い(と言われた)
* Javaなので遅いのではない

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282755/37c56c13-e7e4-8c6e-b061-34169cf223d0.png)

##ガベージコレクションはメモリを自動で解放してくれる

###CPU/メモリ(DRAM)/ストレージ(HDD/SSD)の構成
* CPU/DRAMは基盤上で足がくっついている
    * データバス、アドレスバスでつながっている
        * DRAMが保存できる容量は8byteとする
        * **アドレスバス**は0-7までのどのアドレスにアクセスしたいか信号を出す　
        * **データバス**はその中身を出力
        * **CPU/メモリは1つの基盤**の上に乗っている
* これとは別に直でつながってる
* アドレスバスに**I/Oポート**というIO空間を指定するポートがついてる
    * **I/OポートにHDD/SSDがつながっている**
* CPUと直接つながってないのがストレージ(HDD/SSD)、直接つながっているのがDRAM 
* CPUが持っているメモリは電源がついてないと消える、HDDは磁性体に書き込むので電気を切っても残る
* メモリチップの種類
    * **DRAM**：DDR4規格など（CPUアクセスやレイテンシを決める規格）
    * **SRAM**：高速（今はあまり使わない）
    * **フラッシュメモリ**：外部メモリとして使う（SSDなど）
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282755/ded90595-fd75-0822-2ad8-490b19f4a324.png)


###メモリの仕組み
* 例えばZ80の場合、<br>
データバス8本+アドレスバス16本 (=CPUがアクセスしたい番地を示す)
    * 0000 0000 0000 0000 ~ 1111 1111 1111 1111 までアクセスできる
    * 8bitCPUのZ80の場合、**0~65535番地まである**
* **Java仮想マシンはOSにメモリを使う使わないを要求する**
* **OSはメモリをブロックで管理する機能がある**
    * Java仮想マシンはOSに100byteのメモリを要求
    * OSが管理している使ってない番地を仮想マシンに返す
    * Javaはそのメモリを使うことができる
* **メモリリーク**： あるApplicationで仮想マシンが使うと指定して終わりを伝えず死ぬと100byte使ったままになってしまい、他の領域に使えない
    * C/C++ではポインタを使いメモリアロケーターを使って割当、解放命令で解放してあげる
* Javaでは、提供するメモリはJDKのJavaマシン管理下
* `hoge = null;` と書くかJava仮想マシン終了で**自動でガベージコレクションがメモリを解放**してくれる

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282755/0f61fc10-84a7-e05d-7039-4209ba49d777.png)
【Chrome】z-indexを考慮した立体的なページレイヤーをChromeの開発者ツールで確認する。

メモとして残します。

先日z-indexが原因でボタンが押下できる判定が小さくなったという、事象を解決するのに時間がかかったため、こんなことにならないようにz-indexを考慮したページ全体を立体的に確認することができるプラグインないかなーと思ったら、chromeの標準機能でありました。


#やり方
F12でchromeの開発者ツール出して
Ctrl＋Shift＋Pでlayerメニュー出して、
「show layer」を選択すると立体的にz-indexを考慮したページレイヤーが見れます。
![chorome-dev-zindex-menu.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213462/1061a3bb-4755-fba1-5d2b-d66ac298167c.gif)



###グラブルwebバージョンで確認してみるとこんな感じ
![chorome-dev-zindex-g.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213462/5cae2d34-d0b3-738c-bdb9-cc9f3bb7f1d7.gif)


グラブルはレイヤー綺麗ですね。。。


以上。
[android]リアルタイムデベロッパー通知を使用した定期購入でのAccount Holdテストフローとnotification_typeメモ

##はじめに
既存アプリの定期購読でaccount holdとrestoreの対応をする際に
リアルタイムデベロッパー通知でサーバー側の処理を行うように変更した。
通知が13種類あり、実機テストで送られてくる番号を確認した際に若干こちらの想定と違う番号が送られてきたりしたため、テストフローに沿って通知をメモしておく。

##テストシナリオ
テストのフローは公式に記載されている内容を参照。
 [更新頻度のテストシナリオ](https://developer.android.com/google/play/billing/billing_testing?hl=ja#renewal-rate-testing-scenarios)

####月次定期購入（新規定期購入→更新のテスト）
| 時刻 | ユーザーの操作 | システム イベント | 送られてくるnotificationType |
|:-:|:-:|:-:|:-:|
| 午後 12:00 | ライセンス テスト アカウントと「テスト支払い方法 - 常に承認」を使用して、アプリ内定期購入に登録します。 | 定期購入が開始します。 | （4）SUBSCRIPTION_PURCHASED  |
| 12:05 |   | 定期購入が更新されます | （2）SUBSCRIPTION_RENEWED |
| 12:10 |   | 定期購入が更新されます | （2）SUBSCRIPTION_RENEWED |
| 12:15 |   | 定期購入が更新されます | （2）SUBSCRIPTION_RENEWED |
| 12:20 |   | 定期購入が更新されます | （2）SUBSCRIPTION_RENEWED |
| 12:25 |   | 定期購入が更新されます | （2）SUBSCRIPTION_RENEWED |
| 12:30 |   | 定期購入が更新されます | （2）SUBSCRIPTION_RENEWED |
| 12:35 |   | 定期購入が終了します（6 回の更新後） | （3）SUBSCRIPTION_CANCELED （13）SUBSCRIPTION_EXPIRED  |
６回目の更新の時に通常だったらユーザーが定期購入を解約した時に送られる(3)が通知されてその後に有効期限切れの（１３）が送られてきます。


####猶予期間なしの月間定期購入（アカウントの一時停止を含む）、ユーザーが再開した場合（新規定期購入→Account Hold→再開のテスト）
今回の実装では猶予期間は設定せずaccount hold（一時停止）のみ対応したので一時停止、再開のテスト。

| 時刻 | ユーザーの操作 | システム イベント | 送られてくるnotificationType |
|:-:|:-:|:-:|:-:|
| 午後 12:00 | ライセンス テスト アカウントと「テスト支払い方法 - 常に承認」を使用して、アプリ内定期購入に登録します。 | 定期購入が開始します。 | （4）SUBSCRIPTION_PURCHASED  |
| 12:01 | Google Play アプリの [アカウント] > [定期購入] に移動して、テスト用定期購入をクリックし、支払い方法を「テスト支払い方法 - 常に不承認」に変更します。 |  |  |
| 12:05 |   | お支払いが不承認となり、アカウントの一時停止が開始されます | （5）SUBSCRIPTION_ON_HOLD  |
| 12:15 | Google Play アプリの [アカウント] > [定期購入] に移動して、テスト用定期購入をクリックし、支払い方法を「テスト支払い方法 - 常に承認」に変更します。 | 定期購入が再開され、更新されて、アカウントの一時停止が終了します。 | （1）SUBSCRIPTION_RECOVERED |
| 12:20 |   | 定期購入が更新されます | （2）SUBSCRIPTION_RENEWED |
| 12:25 |   | 定期購入が更新されます | （2）SUBSCRIPTION_RENEWED |
| 12:30 |   | 定期購入が更新されます | （2）SUBSCRIPTION_RENEWED |
| 12:35 |   | 定期購入が更新されます | （2）SUBSCRIPTION_RENEWED |
| 12:40 |   | 定期購入が更新されます | （2）SUBSCRIPTION_RENEWED |
| 12:45 |   | 定期購入が終了します（6 回の更新後） | （3）SUBSCRIPTION_CANCELED （13）SUBSCRIPTION_EXPIRED |
カード不承認状態を更新した場合はすぐに一時停止状態から定期購読状態に戻るのでGoogle Playの操作で通知が来た。

####猶予期間なしの月間定期購入（アカウントの一時停止を含む）、ユーザーによる非自発的チャーンの場合（新規定期購入→Account Hold→期限切れのテスト）
account hold状態から更新をしなかった場合に期限切れになるテスト

| 時刻 | ユーザーの操作 | システム イベント | 送られてくるnotificationType |
|:-:|:-:|:-:|:-:|
| 午後 12:00 | ライセンス テスト アカウントと「テスト支払い方法 - 常に承認」を使用して、アプリ内定期購入に登録します。 | 定期購入が開始します。 | （4）SUBSCRIPTION_PURCHASED  |
| 12:01 | Google Play アプリの [アカウント] > [定期購入] に移動して、テスト用定期購入をクリックし、支払い方法を「テスト支払い方法 - 常に不承認」に変更します。 |  |  |
| 12:05 |   | お支払いが不承認となり、アカウントの一時停止が開始されます | （5）SUBSCRIPTION_ON_HOLD  |
| 12:15 |  | 非自発的チャーンにより定期購入が解約されます | （3）SUBSCRIPTION_CANCELED （13）SUBSCRIPTION_EXPIRED |
アカウントの一時停止から解約までの時間は前後する模様。

##テストの注意点

+ 定期購入を開始した直後に以前の定期購入の期限切れの通知（13）SUBSCRIPTION_EXPIREDが送られてくる。(既に有効期限切れの定期購入に再度期限切れの通知(13)が来ることがある点に注意)
+ 定期購入が終了する時に(13)SUBSCRIPTION_EXPIREDが来てから（3）SUBSCRIPTION_CANCELEDが来ることがある（（3）SUBSCRIPTION_CANCELEDで何かしらの処理がある場合は注意）

##おわりに
実機でのテストは時間がかかるから結構大変。でもGooglePlayの動きは実機で確認しないと想定外の事が起きそうなのでちゃんとやらないとね。
猶予期間(Grace Period)を導入するとさらにテストが大変そうなのでやった時に追記するかもしれない。
「rm -rf」でrm -iのように確認する方法。

# rm -rfでやらかした！
先日**rm -rf ~/**を誤って実行してしまいました。
バックアップは取っていたので大事には至らなかったのですが、復旧が面倒だったので失敗から学ぶ方法を考えることにしました。

私の案としては、**rm -i**のように実行する前に今から消すディレクトリに確認を取るように設定することを本記事で提案します。

```bash
# こういう確認メッセージが欲しい。
$ alias rm='rm -i'
$ touch hoge
$ rm hoge
remove hoge? 
```

## 動作確認済み環境
Ubuntu 20.04 (bash)
MacOS Catalina (zsh)

## 作成したもの
まず、単純にシェルスクリプトを書いて、それにエイリアスを通そうと考えました。

```bash
# ダメな例
alias 'rm -rf'='hoge.bash'
# 定義できるけどなんかダサい
alias rm-rf ='hoge.bash' #rm とオプションの間のスペースがない。
```
どうやら**aliasにスペースを含んだものを定義できない**ようです。
そこでbashrcに**直接rm関数を定義**してオプションに**r,f**が含まれている場合のみ確認を表示するようにしました。

bashrcに以下の関数をコピペするだけで使用できます。

```bash

function rm(){
        DIR=`eval echo '$'$#`
        OPTION=${@%*$DIR} #パターンマッチングで引数全体からディレクトリ名を除いたオプション部分
    if [[ $OPTION =~ r && $OPTION =~ f ]]; then #オプションにr,fが含まれているか正規表現によるマッチング
        echo "rm -rf: remove directory $DIR? [y,n]"
        read yesnojudge
        case "$yesnojudge" in
            "y")
                command rm $@ #元のrmコマンドを実行
                ;;
            "n")
                :
                ;;
            ?)
                echo INVAILED OPTION
                ;;
        esac
    else
        command rm $@
    fi
}

```

## 実行イメージ

```bash
$ rm -rf hoge
remove directory hoge? [y,n]
```
確認メッセージが表示されyを打つとrm -rfが実行されます。

## 最後に
何かいい案が他にありましたらコメント欄で教えていただけると幸いです。
AZ-900を自宅受験で無料取得したお話(2020/10)



# はじめに
タイトルの通りですが、AZ-900を自宅受験で無料取得しました(2020/10/26合格)

# 無料取得方法
[MS Azureのイベント](https://azure.microsoft.com/ja-jp/community/events/?query=Fundamentals)にて2日間(午前中のみ)のオンライントレーニングを受けることで無料バウチャーが貰える(登録メールに来る)ので、[AZ-900予約ページ](https://docs.microsoft.com/ja-jp/learn/certifications/exams/az-900)から`Peason VUE でスケジュール`ボタンを押し、画面に従って予約して合格しましょう。
※2020/10/27現在は月3回程度開催しているようです。

# 試験申込時のスペック
- Azureに関してはアカウントを持っていないレベル(一度も触れたことが無い)
- AWSに関しては日常的に業務で使用しており「CLF, SAA, SAP, SysOps, SCS」の資格を保有

# 勉強方法
[Azure の基礎ラーニングパス](https://docs.microsoft.com/ja-jp/learn/paths/azure-fundamentals/)を一通り読みました。
上記以外の勉強はしていないです。
他のクラウドサービスを日常的に利用している方でしたら、上記をさらっと読むだけで受かると思います。
日常的にクラウドサービスを利用していない方だと10～30時間程度勉強すれば受かるかな～という感じです(個人の感想です)

# システムテスト
[システムテスト](https://docs.microsoft.com/ja-jp/learn/certifications/online-exams)は**必ず**行いましょう。
当日バタバタすると試験結果に影響しかねないので。。

# 自宅受験
お昼の12:00から試験だったので、11:45くらいから[MS ダッシュボード](https://www.microsoft.com/en-us/learning/dashboard.aspx)の `AZ-900`を選択して試験準備を行いました。
(MacBookPro2019 Midで受験しました。私は問題ありませんでしたが、PeasonのAppの影響で熱暴走してPC落ちる場合があるらしいです。。)

### 受験の流れ
1. [MS ダッシュボード](https://www.microsoft.com/en-us/learning/dashboard.aspx)から試験を選択し、受験ページで専用アプリを起動
2. スマホにSMSで事前準備用URLを送付(URL直打ちも可)
3. 顔写真撮影
4. 本人確認書類撮影
5. 部屋撮影(正面・後方・右方・左方)
6. 上記撮影が終わるとPC上で注意事項が表示
7. 試験監督より、カメラorノートPCを動かして部屋の中を見せられるように指示(私の場合全てチャットでした)
8. 指摘事項が有れば改善を求められる(私が言われたことは後ほど書きます)
9. 試験開始

### 私が言われた指摘事項
- 段ボールの上にPCを置いていたら、文字の書いてあるものは部屋の中に置いていけないと言われた
- 部屋の仕切りの摺りガラスに人影が映ったら試験中止と言われた(1人暮らしだったのでそのまま続行)。なお、布などで隠しても良いと言われました。

# 結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299739/cbdd9518-c3f6-480d-caee-080aabbd27db.png)

試験自体は10分程度で終わりました(準備含めると20分程度)
日常的にクラウドを利用している方なら、Azureのサービスについては勉強方法に記載したものをやれば十分受かります。
それ以外の方については[AZ-900 試験ページ](https://docs.microsoft.com/ja-jp/learn/certifications/exams/az-900)の↓にあるラーニングパスをやりこめば受かると思います。
[トレーニング](https://azure.microsoft.com/ja-jp/community/events/?query=Fundamentals)を受けることで試験自体は無料になるため、仕事上の都合などでどうしても一発で取得しないといけない場合以外はとりあえず受験してみて試験の感触を掴むのもありだと思います。

# おわりに
今後Azureを触る機会も増えてくると思うので、実際にAzureを触って更に理解を深めたいと思います。
この記事が皆様にとって有益な物となれば幸いです。
macでpython実行時に方向キーを押すと"^[[A^[[B^[[C^[[D"となってしまう対処法

*環境*
-
macOS:Catalina 10.15.7
python:3.8.5
VScode:1.50.1

*問題点*
-
VScodeのterminalにてpython実行時に、方向キーを押すと、"^[[A^[[B^[[C^[[D"と入力されてしまい、過去に一度入力した値でももう一度入力しなければいけなかった。

```python:
^[[A^[[B^[[C^[[D
```
*解決策*
-
今回は、「rlwrap」を導入することによってこの問題を回避します。
導入にあたって、「homebrew」を使用しますが、今回はこの「Homebrew」のインストールは割愛させていただきます。（Homebrewのインストールに関しての記事は既にたくさんあるため。）

*手順*
-
まず、「command+space」で「Terminal」と検索し、Terminal を起動。
そこで以下のように入力します。

```python:
brew install rlwrap
```
特に問題なければ、「rlwrap」がインストールされているはずなので、正常にインストールされたかを確認します。

```python:
$ rlwrap -v
rlwrap 0.43
```

こんな感じでバージョンが表示されれば大丈夫です。

あとは、pythonを実行する時に

```python:
$ rlwrap python a.py
```

と前に付け加えるだけです！
(python以外の言語では試していないのでわかりません！
ごめんなさい！)

おまけ
-
VScodeを使用している人だけにはなりますが、便利な設定がありますので紹介させていただきます。

まず、拡張機能の「Code Runner」をインストールします。
この拡張機能は対応している言語の実行を、再生ボタンを押すか、ショートカットキーでできるようになるため、非常に楽になる機能です。
![スクリーンショット 2020-10-27 11.26.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/827475/44194ce7-7755-637b-422f-b811c49ac5fd.png)

インストールができたら、歯車のマークをクリックし、一番下の「Extention Settings」を選択します。
次に、「User」と「Workspace」とあると思いますが、
「User」の中の「Run in Terminal」にチェックを付けます。
![スクリーンショット 2020-10-27 12.52.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/827475/b063668e-4d41-4f2d-6d8e-03767f5bae44.png)

次に、「Workspace」の方を選択します。
そして「Code-runner:Executor Map」という欄の中の「Edit in settings.json」をクリックします。
![スクリーンショット 2020-10-27 11.29.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/827475/9fec8816-028d-c711-58fd-85de5b90354d.png)

開いたsettings.json の中を探すと以下のようなコードがありますので、、

```python:settings.json
"python": "python -u",
```

これを次のように書き換えて保存します。

```python:settings.json
"python": "rlwrap　python -u",
```
こうすることで、「Code Runner」でpythonを実行した際にも自動で「rlwrap」がつくので、毎回入力せずに済みます。
Chromium版Edgeなら拡張機能なしでAPI叩けるみたい（試験的機能）

# はじめに
ブラウザからAPI叩きたいと思いまして、
拡張機能入れるほどでもないし、標準搭載されていないかなと、
最近メインで使用しているChromium版Edgeの設定を探してみました。
開発者ツールに、「**ネットワークコンソール**」という機能が用意されていました。

# ネットワークコンソール
![スクリーンショット 2020-10-27 114735.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283028/6e61be7e-95c8-627c-1140-18c55f684b3c.png)
使い方はシンプルで、タブ内左側に送りたい情報を入力し、「**Send**」ボタンを押すと、右側に結果が表示されるようになっています。

# 有効化

開発者ツール(F12)の設定の中に、「試験的機能」という項目があります。
ここの一番下に「Enable Network Console」という設定がありました。
![スクリーンショット 2020-10-27 114207.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283028/c87ee1c4-78d3-8f12-efce-7ad8858ecb60.png)
チェックを入れた後、Edgeを再起動します。
この時点ではまだタブは表示されておらず、「その他のツール」から選択すると使用できます。
![スクリーンショット 2020-10-27 120839.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283028/db64b5ee-b475-eac9-5057-34ddee30e832.png)

# おわりに
軽い気持ちでAPI叩きたいだけだったので、拡張機能入れなくてよかったのはありがたいです。

ちなみにこの機能はGitHubで管理されているようです。
https://github.com/microsoft/edge-devtools-network-console
ServiceNow - テーブルの検索

概要
ServiceNowでテーブルを検索する場合は.addQuery()と.addEncodedQuery()がある。
それらで検索する場合は対象にするフィールド名を指定する。
しかし、ServiceNowには全文検索機能もある。

|検索キー|説明|
|---|---|
|IR_AND_QUERY|すべての単語と一致|
|IR_OR_QUERY|どれかの単語と一致|
|IR_AND_OR_QUERY|どれかの単語と一致。全部と一致した結果を上に表示|

実行例：
ノレッジを検索する

```
var gr = new GlideRecord('kb_knowledge');
gr.addQuery('IR_AND_OR_QUERY', 'Creating a new user in Mac OS X');
gr.query();

while (gr.next()) {
  gs.print(gr.number+ ': ' + gr.ir_query_score);
}
```

実行結果：

```
*** Script: KB0000015: 39
*** Script: KB0000008: 7
*** Script: KB0000033: 5
```

利用したノレッジ記事
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/87f900a7-c522-2629-56bb-9e0cc1694067.png)
volatilityの作法 その23

#概要

volatilityの作法、調べてみた。
vistaでも、yarascanがやりたい。
「青い空を見上げればいつもそこに白い猫」やってみた。

#写真

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/e0fd9e0f-2ff3-c004-6945-69885d62c20d.jpeg)


#yara-rules


```
rule eicar_substring : eicar
{
    strings:
        $eicar_substring = "$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!"
    condition:
        all of them
}


```

以上。
Laravelコレクションのselect()とpluck()の違い

備忘録。

タイトル通り、Laravelコレクションのselect()とpluck()の違い。

両者をdd()してみてのあくまでもイメージ。細かくは理解していないけど。

### select('カラム名')
ddすると、目的のカラムの項目までは何階層かある。

### pluck('カラム名')
ddしてみると、目的のカラムの項目まですぐ直下。

あくまでも、イメージ。
SQLite3　テーブルにカラム（縦列）を追加する方法

#はじめに
この記事は数弱体質の体育大学生である私が、知りたかったことや躓いたところを書き留めておく備忘録です:santa_tone5:
間違いがあれば訂正をよろしくお願いします。

環境とか：windows10 VScode python

#データベースに接続する
まず初めに、SQLite3をダウンロードする。
その後、sqlite3.exeを保存したディレクトリ（保存先）に移動するためにコマンドライン（黒い画面）にcd 'path'と入力して移動する。pathが分からないときはsqlite3.exeを右クリックしてプロパティを確認すると（場所：）に書かれている。
（例）
```cd C:\Users\111\Downloads\sqlite3> 
```

次に、データベースに接続する。
コマンドラインに下記のコードを打ち込む。
下記の db にはデータベースの名前を入力。
入力した名前のデータベースが存在しないときは、入力した名前のデータベースが新しく作成される。
```./sqlite3 db.sqlite3
```

#テーブルにカラムを追加する
〇〇〇にはカラムを追加したいテーブルの名前を入れる。

△△△には追加したいカラムの名前を入れる。

☆☆☆にはデータ型を入力。
種類
・INTEGER
・REAL
・TEXT
・BLOB
・NUMERIC
```alter table 〇〇〇 add column △△△　☆☆☆;
```

#追加されたかどうか確認する

〇〇〇は確認するテーブルの名前を入れる。
```.schema 〇〇〇
```

#備考
不足している情報は私の学習進度に応じて追加していきます。:hotdog:
【Rails】SameSiteとSecure属性の付与〜Railsのセキュリティ対策〜

##はじめに
**社内でcookieのセキュリティに関する勉強会があったので、学んだことをまとめておきます〜〜**:writing_hand::writing_hand:
**Railsは優秀なフレームワークなので、そこそこのセキュリティ対策が標準装備されているんですよねえ。**
セキュリティについてはあまり考えなくても、実装できてしまうんですよねえ。
良いことでもあり、悪いことでもありますね:runner::runner:

## GoogleChrome80のリリース
2020年2月4日（現地時間）にGoogleChrome80が正式にリリースされました。
https://developers-jp.googleblog.com/2019/11/cookie-samesitenone-secure.html
今回のバージョンアップで**デフォルトのCookieのSameSite属性がNone⇒Lax**に変更されました。
また**SameSite属性をNoneにする場合、Secure属性を付与しなければならない**仕様になりました。

？？？
なにそれ？？

私もピンと来ませんでしたし、よくわからない方もいるかも知れないので、ざっくり解説します。

### SameSite属性
**SameSite属性とは、CSRF（クロスサイトリクエストフォージェリ）というサイバー攻撃からユーザーを守るために、Cookieに付与される属性のこと**です。
安全のためのCookieのオプション設定みたいに考えておいてください。

GoogleChrome80からこれのデフォルト値がNone⇒Laxに変更になったのです。
簡単に言うと**セキュリティが強化されました**ということです。
最近、Googleはセキュリティ対策に厳しいですからね〜

**SameSite属性は三段階にわかれています。**

| 属性 | 内容 |
|:-----------|:------------|
| None      | ドメインをまたいでCookieの受け渡しが可能        |
| Lax      | （GETでのリクエストのみ）ドメインをまたいでCookieの受け渡しが可能        |
| Strict      | ドメインをまたいでCookieの受け渡しが不可        |

セキュリティのレベル的には
**None < Lax < Strict**ですね。

つまり、ドメインをまたいでCookieの受け渡しができるか？できないのか？という違いを設定する設定のことですね！

### secure属性

Secure属性は**HTTPS化していないCookieの動作を制御する属性のこと**です。
**Secure属性が付与されているCookieはHTTPS通信の場合のみ送信できます。**
要はCookieが盗まれにくくなります。

**GoogleChrome80からはSameSiteがNoneのときはSecure属性を付与しなければならない仕様に変更になりました。**

つまり「SameSiteがNoneなんだろ？セキュリティー不安だからせめてSecure属性くらいつけておけよ〜」というGoogle様からのお達しということですね。

## Railsでの設定

ではGoogleChrome80の仕様もSameSite属性・secure属性も理解したところで、Railsで設定をしてみましょう！

```ruby:Gemfile
gem 'rails_same_site_cookie'
```
```ruby:ターミナル
bundle install
```

**はい。これだけです。**

特に設定等もいりません。gem「rails_same_site_cookie」をインストールするだけです。
めちゃめちゃ簡単ですね。
自動的に全cookieにSameSite=None; Secure属性が追加してくれます。

## 確認方法
確認方法も簡単です。
chromeの検証からApplicationをクリックして、使用中のCookieの中身を見ます。
**secure属性にチェックが入っていて、SameSite属性がNone**になっていたらOKです。

![スクリーンショット 2020-10-23 18.31.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501638/5f52daaa-883c-86ff-1846-46f7ba8842bf.png)

※ローカル環境では確認できないことがあるので注意してくださいね〜

## おわりに
勉強会でとんでもないハッカーに出会ってしまったので、毎日震えながら開発しています:baby::baby:
Simulatorが動かない：Unable to boot device because it cannot be located on disk.

Simulatorとの戦いが続く

Simulatorのいろいろなバージョンをインストールしているから、
結構ストレージを占めて、ストレージ不足。古いバージョンをを削除しようと、
この記事を参照して削除した。
https://shinespark.hatenablog.com/entry/2018/03/10/090000

'''
/Library/Developer/CoreSimulator/Profiles/Runtimes から、不要なシミュレータのバージョンのディレクトリを削除する。 rmtrash を使っている人はrmをシングルクォートで括って実行しよう。

~/Library/Developer/Xcode/iOS DeviceSupport にもバージョンごとにディレクトリが作成されているので、ここも削除する。
'''

そして使いたいバージョンを新しくインストールした。

私がどこかで変に操作したせいで、このエラーが続いて、Simulatorが出てこない。
Unable to boot device because it cannot be located on disk.

今度はこの記事を参照：
https://blog.ukoasis.me/2019/01/21/unable-to-boot-device/

xcrun simctl erase allを実行してSimultorのログファイル？を削除して
再度ビルドしたら、Simulatorが動いた。
BigQuery BI Engine

# BigQuery BI Engineについて
## BI Engineとは
BigQueryで利用できるインメモリ分析サービスです。インメモリなので通常のクエリにカラべて素早く結果をえることができます。また、メモリ内でキャッシングが働くので同時実効性もよくなります。

名前の通り、BIワークロードに向いています。BIでは、レポートやダッシュボードを通じて多くの人が同じようなデータアクセスをBigQueryなどのDWHに対して要求するのが一般的です。

## 何が嬉しいのか
[公式サイト](https://cloud.google.com/bi-engine/docs/overview?hl=ja#advantages_of)では次のようにメリットが謳われています。

- 高速: インサイトの成果をビジネスのスピードに合わせる
- 簡素化されたアーキテクチャ: 複雑なデータ パイプラインやサーバーを管理せずにすぐに開始
- スマートな調整: ごくわずかな構成

これらに関連した個人的な感覚での課題って以下のような感じだと思います。

- 一般的には、BIツールで作られたダッシュボードを開いた際に表示が遅いと、忙しいかつ裏の技術など知ったこっちゃないユーザは使わなくなっていきます。あるいは、どうしても使う必要があるときは不満を持って使いますが、それ以上その仕組みに期待はしなくなります。
- また、表示にストレスがなくビジネス上有用なダッシュボードは多くの人に使われます。するとDWHへの負荷が高くなり表示が遅くなったりエラーがでたりして、また愛想を尽かされます
- 最近、データをリアルタイムに分析するニーズが高まっており、今まさに自社のサービスで何が起きているかを分析するためには、データを素早くBIツールなどで見る必要がありますが、実はデータを集めてからまともに見れるようにするためには多くの処理が必要で、その構築と運用には専門性が要求されます。
- メモリ、ディスク、それらを活用したキャッシュなど、複数の処理方法でユーザに結果を返す場合、どういうクエリはどこで処理させるかを考慮する必要がある場合があります。また、場合によってはそのためにデータの置き場所を分けて管理したりする必要があって非常に運用が大変です。

## BI Engineの制約事項
速く結果が返ってきて同時実効性もいいなら全部これでいいじゃんと思いますが、もちろん機能上の制約とコストを考慮する必要があります。

BI Engineの一番大きな制約事項としては、今はBIツールとして[データポータル](https://marketingplatform.google.com/intl/ja/about/data-studio/)しか使えないと言うことです。

ただし、2020年の8月に行われたGoogle Cloudのオンラインイベント Google Cloud Next '20 OnAir のセッション[Always fast and fresh dashboards: Inside BigQuery BI Engine](https://youtu.be/kifUXfwqzVo)にて、LookerやTableauなどでもBI Engineが使えるAPIの提供を予定していることがアナウンスされました。 これは期待大です。

その他の制約事項として、以下のようなものがあります。これも詳しくは[公式サイト](https://cloud.google.com/bi-engine/docs/overview?hl=ja#limitations)を確認してください。

- ビューに対する一部のクエリ
- ターブルのパーティション数の最大値
- UDFや外部テーブルや分析関数などを利用したクエリ

## BI Engineの料金
実際の単価は変わる可能性があるので、[こちら](https://cloud.google.com/bi-engine/pricing?hl=ja)のリンクで確認しましょう。ここでは、料金システムを書きます。

BI Engineの基本的な料金の考え方は、メモリの容量を購入しその量に対して課金されるものになります。

ただ、BigQueryをオンデマンドではなく定額料金で使っている場合は、その契約スロット数に応じてBI Engineのメモリ容量がおまけのような形でついてきます。もちろんそのおまけに追加して必要な分追加で購入することもできます。
ServiceNow - Scripted REST APIの例

#概要
標準のScripted REST APIとresponse.setBody()を利用したScripted REST APIの例です。

###標準
配列に戻すデータを設定してreturnするだけです。

```
(function process( /*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {

    var incidentDetails = [];
    var number = request.queryParams.number.toString();
    if (!number) {
        incidentDetails.push('no incident number present');
    } else {
        try {
            var grIncident = new GlideRecord('incident');
            if (grIncident.get('number', number)) {
                incidentDetails.push(grIncident.number.toString());
            }
        } catch (e) {
            gs.error("ERROR=", e);
        }
    }
    return incidentDetails;
})(request, response);
```

###setBody()の例
ヘッダ情報、ステータスを設定して戻す内容を辞書にします。

```
(function process( /*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {

    var number = request.queryParams.number.toString();
    var hdrs = {};
    if (!number) {
        hdrs['Content-Type'] = 'application/json';
        response.setStatus(406);
        response.setHeaders(hdrs);
        response.setBody({'error':'no incident number present'});
    } else {
        try {
            hdrs['Content-Type'] = 'application/json';
            response.setStatus(200);
            response.setHeaders(hdrs);
            var grIncident = new GlideRecord('incident');
            if (grIncident.get('number', number)) {
                var result = grIncident.number.toString();
                response.setBody({'incident': result});
            }
        } catch (e) {
            gs.error("ERROR=", e);
        }
    }
})(request, response);
```
[Payjp] Payjp::InvalidRequestError No such tokenの解決法

## 概要
Payjpでcustomerを作成しようとした際、No such tokenというエラーを解決するのに時間を要したため、解決した流れを記載しておきます。


## エラーの内容
[![Image from Gyazo](https://i.gyazo.com/55bd0f1cff6750eb1dc948287405494b.png)](https://gyazo.com/55bd0f1cff6750eb1dc948287405494b)

上記のように、そのようなトークンはありませんと言われてしまいました。

- トークンはJs→Rails側に送信できている
- Completed 500 Internal Server Error

となっているため、サーバーサイド側のエラーだと思い、秘密鍵が合っているか等、色々試してみましたが解決できませんでした。

## card.jsの記述
サーバーサイド側のエラーだと踏んでいたのですが、jsの記述も確認してみました。

```javascript:card.js
const pay = () => {
  Payjp.setPublicKey(process.env.PAYJP_PUBLIC_KEY);
  const form = document.getElementById("charge-form");
  form.addEventListener("submit", (e) => {
    e.preventDefault();
    const formResult = document.getElementById("charge-form");
    const formData = new FormData(formResult);

    const card = {
      number: formData.get("number"),
      cvc: formData.get("cvc"), 
      exp_month: formData.get("exp_month"),
      exp_year: `20${formData.get("exp_year")}`
    };
    Payjp.createToken(card, (status, response) => {
      if (status === 200) {
        const token = response.id;
        const renderDom = document.getElementById("charge-form");
        const tokenObj = `<input value=${token}, type="hidden", name="card_token">`;
        renderDom.insertAdjacentHTML("beforeend", tokenObj);
       }
        document.getElementById("card-number").removeAttribute("name");
        document.getElementById("card-exp-month").removeAttribute("name");
        document.getElementById("card-exp-year").removeAttribute("name");
        document.getElementById("card-cvc").removeAttribute("name");

        document.getElementById("charge-form").submit();
        document.getElementById("charge-form").reset();
    });
  });
};
window.addEventListener("load", pay);
```

特におかしなところは無いように思えます・・・。

## ある違和感
同じような記述で、jsを使って商品の合計金額(total_price)をサーバーサイドに送信するコードも書いていました。

```javascript:sendTotalPrice.js
function sendTotalPrice() {
  const totalPriceDom = document.getElementById("cart-total-price")
  const totalPrice = parseInt(totalPriceDom.innerHTML);

  const renderDom = document.getElementById("charge-form");
  const totalPriceObj = `<input value=${totalPrice}, type="hidden", name="total_price">`;
  renderDom.insertAdjacentHTML("beforeend", totalPriceObj);
};
window.addEventListener('load', sendTotalPrice);
```
ここでおかしいと感じたことがあります。
[![Image from Gyazo](https://i.gyazo.com/c506d59ac8996094e6999d3d0a301c0d.png)](https://gyazo.com/c506d59ac8996094e6999d3d0a301c0d)
送信されたparamsのtotal_priceの中に
[![Image from Gyazo](https://i.gyazo.com/abfbb3d2102de7f13680e8a0208432c5.png)](https://gyazo.com/abfbb3d2102de7f13680e8a0208432c5)
不要な " , " が入ってしまっています。


## 原因はjs内の記述だった
トークンの値をフォームに含めるための記載に間違いがありました。

```js:間違い
 const tokenObj = `<input value=${token}, type="hidden", name="card_token">`;
```

```js:正しい
 const tokenObj = `<input value=${token} type="hidden" name="card_token">`;
```
value=${token}のあとのカンマ "," は不要でした！

## 勉強になったこと

Rails等のform_withなどでは属性を区切るためにカンマが必要ですが、HTML要素では属性を区切るカンマは不要ですね・・・。
<br>
同じような内容で悩まれている方がもしいらっしゃったら、参考になれば幸いです。
docker-compose upでpostgresが起動しなかったのでエラーを解決するに至った話

#laravelをインストールする前段階docker-compose upでコンテナを起動させたかったが出来なかった

ある学習教材をベースにlaravelの学習を進めていて、PostgreSQLを使ってコンテナを起動させる内容だったのですが、上手く起動しなかったのでエラー解決に至るまでの備忘録です。


##実際に行ったコマンド

```:ターミナル
 docker-compose up -d workspace php-fpm nginx postgres
```
up以降はオプションになってますが、最後についているpostgresが今回の話になります

無事にコンテナが起動されれば、

```:ターミナル
Creating laravel-sns_docker-in-docker_1 ... done
Creating laravel-sns_workspace_1        ... done
Creating laravel-sns_php-fpm_1          ... done
Creating laravel-sns_nginx_1            ... done
Creating laravel-sns_porstgres_1        ... done
```

この様に出るはずなのですが、私の場合は


```:ターミナル
Recreating laravel-sns_postgres_1 ... error
Creating laravel-sns_docker-in-docker_1 ... done
Creating laravel-sns_workspace_1        ... done
Creating laravel-sns_php-fpm_1          ... done
Creating laravel-sns_nginx_1            ... done

ERROR: for laravel-sns_postgres_1  Cannot start service postgres: Ports are not available: listen tcp 0.0.0.0:5432: bind: address already in use
```

こんな感じになってしまいました。

##原因

数ヶ月前に、今よりもっと何も解っていない時期にインストールしていたpostgresだと言う事がわかりました。

当時、MySQL以外のDBを使いたいと言う気持ちから特に何も考えずにインストールしていたpostgresの存在を思い出し、pgadminから接続状態を見たら、今回のエラー内容に出ているポート番号5432が接続状態になっていました。
※エラー解決する前に画面を残すのを忘れてしまってました。

##解決に向けた道筋を考える

今回はとある教材の学習中で起きたエラーでしたので、講師の方に相談した所、
・Ports are not available
・address already in use
辺りをキーワードに検索をしてみれば？と言うアドバイスを頂いたので、

Ports are not available→ポートが利用できない
address already in use→アドレスは既に使われている
と、ほぼ直訳の解釈を元に、検索をかけてこれかと思えるヒントを見付けました。

参考にさせてもらった記事
https://mebee.info/2020/04/20/post-7968/

これを元にポート番号5432を使用しているプロセスをkillすればいけるのかな？と思い早速実行

```:ターミナル
sudo lsof -i -P | grep ５４３２

pgAdmin4   2471 ---------   21u  IPv6 ---------      0t0  TCP localhost:64447->localhost:5432 (CLOSE_WAIT)
※アカウント名やトークンはーーで伏せさせてもらってます。
```
これでプロセス番号が2471だった事が解ったので、

```:ターミナル
kill 2471
```
でkillコマンドを実行

再度コンテナを起動

```:ターミナル
 docker-compose up -d workspace php-fpm nginx postgres

起動済みのコンテナは省略
 Starting 8d38216de390_laravel-sns_postgres_1 ... done
```

無事にpostgresも起動できました。

思えば当時インストールだけして、全く使っていなかったpostgresがずっとサーバーと接続済みだったんだな〜と言う事を思い知らされました。

無知の状態であれこれインストールする恐ろしさを知った反面、当時はkillコマンドとかも全く解っていなかったので、時間が立つ事で解決できる事もあるんだなと言う学びにもなりました。

めっちゃしょーもない内容ですが、もし1人でも同じ境遇の方がいて、何かのお役に立つかも知れません。
ヘッドレス Chrome で HTML を PDF に変換することができなかった (過去形)

# ヘッドレス Chrome で HTML を PDF に変換することができなかった (過去形)

ヘッドレス Chrome で HTML を PDF に変換できなくなっていて、調査していたらいつの間にかできるようになった. どうも 86.0.4240.75 の regression で 86.0.4240.111 で修正されたようだ.

参考: [ヘッドレス Chrome で HTML を PDF に変換する](https://qiita.com/c-yan/items/919868fde03190f37b43)
【AtCoder】エイシング　C - XYZ Triplets

エイシング プログラミング コンテスト 2020のC問題です。
苦戦したので、失敗したコードと共に振り返ってみました。


##失敗１(TLE)

```
n=int(input())
def f_count(j):
   count=0
   for x in range(1,j):
       for y in range(1,j):
           for z in range(1,j):
               if x**2+y**2+z**2+x*y+y*z+z*x==j:
                   count+=1
   return count
   
for i in range(1,n+1):
   print(f_count(i))
```


f(n)を求める関数f_count(j)を定義して、jに1～nまで代入して、出力する方法です。

時間超過になったので、zを消したりしてみましたが、それでも時間超過になりました。



**＜ポイント１＞**

解答を見てみると、nの最大値は10**4。x,y,zは二乗しているから、x,y,zの最大値は100より小さい。



**＜ポイント２＞**

f(1)の時、x,y,zを1～100まで全探索する → f(2)の時、x,y,zを1～100まで全探索する…としていては、時間がかかる。



##失敗２
```
N=int(input())
#f(N)を入れるリスト
ans_list=[0]*N
for x in range(1,100):
   for y in range(1,100):
       for z in range(1,100):
           s=x**2+y**2+z**2+x*y+y*z+z*x
           if s<=N:
               ans_list[s]+=1
           
  
for i in range(1,N+1):
  print(ans_list[i])
```

＜結果＞IndexError: list index out of range

x, y, zに1～100まで代入して、x**2+y**2+z**2+x*y+y*z+z*xの値を計算し、結果をリストans_listに入れていきました。

しかし、範囲を間違えました。ans_list[0]=[], ans_list[1]=f(1), ans_list[N-1]=f(N-1)としてしまったため、f(N)がリストに入らなくなってしまいました。



##正解１

```
N=int(input())
max_x=int(N**0.5)
ans_list=[0]*N

for x in range(1,max_x):
   for y in range(1,max_x):
       for z in range(1,max_x):
           s=x**2+y**2+z**2+x*y+y*z+z*x
           if s<=N:
               ans_list[s-1]+=1
               
for i in range(N):
   print(ans_list[i])
```
ans_list[s-1]+=1にしました。​

##正解２
```
n=int(input())

keys=[i for i in range(1,n+1)]
values=[0 for i in range(1,n+1)]
dic=dict(zip(keys,values))

for x in range(1,100):
    for y in range(1,100):
        for z in range(1,100):
            num=x**2+y**2+z**2+x*y+y*z+z*x
            if 1<=num<=n:
                dic[num]+=1


for key in dic:
    value=dic[key]
    print(value)
```
正解１は、リストのインデックスとf(n)のnがズレるのがすっきりしなかったので、辞書にしてみました。
Revitで読めるST-Bridgeファイル

# はじめに
ST-Bridge形式のファイルが[Revitのアドイン](https://apps.autodesk.com/RVT/ja/Detail/Index?id=7394150801622386883&appLang=ja&os=Win64, "ST-Bridge Link 2019")で読めるというので[構造設計小委員会](https://www.building-smart.or.jp/meeting/buildall/structural-design/, "構造設計小委員会")で公開されている「ST-Bridge_XML仕様説明書（ver.2.0.1）」を見ながら定義して書いていったつもりなのになぜかエラーが沢山出て読めませんでした。
読めるように色々比較したり試したりして理由が分かったので、後で忘れないよう仕様書と違った（主観）ところのメモを残します。
Revitは「Autodesk Revit 2019.2」を使用しています。

# ST-Bridge
## ST-Bridgeファイルとは
上記リンクの構造設計小委員会の説明によると
＞日本国内の建築構造分野での情報交換のための標準フォーマット
であり、BIM活用のために作られたもののようです。拡張子は.stb。
中身はXMLのため頑張ればスクリプト使って手作りができます。

## Revitアドインで読む際に気を付ける点
- 「StbSecSteelFigure\****」系不要<br>
そもそも仕様書19ページの図に「If necessary」とあるので必須ではなかったのですが、これがあると読み込んでくれませんでした。
- 「StbSecColumn_\*」系に「floor」が要る<br>
仕様書では「必須」に〇が付いていませんでしたが、部材（StbColumn等）の属性「name」を「1C1」のようにするなら必須でした。<br>
StbSecColumn_\* のfloor+name = StbColumnのname<br>
とできるようにしないといけなかったようです。floorなし、name=C1ですべての階の部材「\*C1」に対応してくれる、ということではありませんでした。

# Revitアドインでの読み方
1. [アドイン](https://apps.autodesk.com/RVT/ja/Detail/Index?id=7394150801622386883&appLang=ja&os=Win64, "ST-Bridge Link 2019")をインストール
2. C:\ProgramData\Autodesk\ApplicationPlugins\ST-Bridge Link 2019.bundle\Contents\SampleDataフォルダ内の 「Structure-Template2019.rte」をRevitで開く
3. 「REXJ」タブから「ST-Bridge Link」を開き、表示したいSTBファイルを選択
4. すべて「OK」
5. 数分待つ（この時あらかじめ3Dビューを開いておくとじわじわ作成されていくのが見えて面白い）
6. 変換ログに問題なければ成功

# 最後に
分かってから落ち着いて振り返ってみるとアドインの紹介ページや仕様書に書いてある通りといえばそうなのですが、やってる間はマジで分らなくて困りました。本当は先達にいてほしかったです。
OmniSciをCentOS 7 + GeForce RTX 2080 Tiで試してみた。

GPUを使ったSQLデータベースの先駆けでもあるOmniSci (旧MapD)をCentOS 7上で試してみました。
使ったのはサンプルのデータベースで、flights_2008_7Mというのです。GPUはPNYのRTX 2080Ti 11GBです。

ベースのコンピュータはCore i5 第七世代、16GB DDR 4 RAM、2TBのcrucial社製SATA SSDを使っています。

OmniSciのインストールの仕方は：
https://docs.omnisci.com/v4.4.1/4_centos7-yum-gpu-ce-recipe.html
にあります。

色々なフライトのデータが700万件入っている物です。
SQL文で機種がボーイング777または737の場合を抽出しています。

使ったコード(Python 3)は：

```python3:omnisci-test.py
from pymapd import connect
import pandas as pd
import time

start = time.time()
con = connect(user="admin", password="PasswordHere", host="localhost", dbname="omnisci")
df = pd.read_sql("SELECT plane_model, uniquecarrier, deptime, arrtime from flights_2008_7M where plane_model like '777%' or plane_model like '737%' limit 1000", con)

print(df.to_string())

path = './omnisci-data.txt'

with open(path, 'w') as f:
        print(df.to_string(), file=f)
end = time.time()
print("Time elapsed: " + str(end - start))
```
二つの前方一致LIKE検索をorした実行時間を測っていますが、SSDにも書き込んでいるので0.324秒でした。
SSDに書かない所までを測ってみると0.2803秒でした。

```bash:実行結果：
...
985     737-7H4            WN     1029     1126
986     737-7H4            WN     1720     1817
987     737-5H4            WN      754     1154
988     737-3H4            WN     1408     1511
989     737-7H4            WN     2039     2141
990     737-76Q            WN      622      813
991     737-5H4            WN     2125     2226
992     737-7H4            WN     2040     2156
993     737-3H4            WN      757      945
994     737-7H4            WN      641      739
995     737-3Q8            WN     1617     1903
996     737-3A4            WN     1304     1455
997     737-7H4            WN      737      843
998     737-7H4            WN     1952       42
999     737-5H4            WN     1729     1925
Time elapsed: 0.3249530792236328
```

試しにLIKE検索を一つにして見ました。（ボーイング
777のみ)

```python3:dfの部分
df = pd.read_sql("SELECT plane_model, uniquecarrier, deptime, arrtime from flights_2008_7M where plane_model like '777%' limit 1000", con)
```

こちらの結果は0.2931640148162842秒でした。(SSDに書き込みの前まで)

SSDに書き込みありは0.29114460945129395秒でした。
LIKEを二つにした程度ではあまり実行速度が変わらない事が分かります。


加藤 翼
株式会社インスパイアサーチ CEO
【Ruby on Rails】確認ページ作成

# 目標
![画面収録 2020-10-25 18.11.03.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700999/1d4c786f-e4cd-4b68-3fcb-939b4520b46c.gif)

# 開発環境
ruby 2.5.7
Rails 5.2.4.3
OS: macOS Catalina


# 準備
今回はscaffoldを使用し、投稿の確認画面を作成します。

```:ターミナル
$ rails g scaffold post body:string
$ rails db:migrate
```


# controllerの編集
下記を追加。

```rb:app/controllers/posts_controller.rb
def confirm
  @post = Post.new(post_params)
end
```

# routeの編集
下記を追加

```rb:config/routes.rb
  resources :posts
  post 'posts/confirm', to: 'posts#confirm', as: 'confirm'
```

# viewの編集
このままの状態であれば、new画面で投稿するとcreateアクションが実行され、保存されてしまいます。
したがって、new画面からはconfirmにparamsを飛ばすよう記述します。
```<%= render 'form', post: @post %>```を削除し、下記のように記述します。

```erb:app/viwes/posts/new.html.erb
<h1>New Post</h1>

<%= form_with(model: @post, local: true, url: confirm_path) do |form| %>
  <% if @post.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(post.errors.count, "error") %> prohibited this post from being saved:</h2>

      <ul>
      <% @post.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= form.label :body %>
    <%= form.text_field :body %>
  </div>

  <div class="actions">
    <%= form.submit %>
  </div>
<% end %>


<%= link_to 'Back', posts_path %>

```

app/viwes/posts配下にconfirm.html.erbを作成します。
```<%= @post.body %>```で投稿内容を表示し、
```<%= form.hidden_field :body %>```でcreateアクションにparamsを渡しています。

```erb:app/viwes/posts/confirm.html.erb
<div>投稿内容確認<br><br>
  <%= @post.body %><br><br>
</div>
<%= form_with(model: @post, local: true) do |form| %>
  <div class="actions">
    <%= form.hidden_field :body %>
    <%= form.submit %>
  </div>
<% end %>
```

# まとめ
投稿画面での確認画面はあまりないとは思いますが、
新規登録画面ではよく見る表示だと思いますので、
会員登録等の機能を実装するなら必須の機能です。

またtwitterではQiitaにはアップしていない技術や考え方もアップしていますので、
よければフォローして頂けると嬉しいです。
詳しくはこちら　https://twitter.com/japwork
3分アジャイル ふりかえり

![Screen Shot 2020-10-27 at 9.47.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/063b5b11-f079-9efb-e230-b933fb324211.png)[^1]


[^1]: ＪｏｎａｔｈａｎＲａｓｍｕｓｓｏｎ,西村直人,角谷信太郎. アジャイルサムライ達人開発者への道 (Japanese Edition) (Kindle Location 3634). Kindle Edition. 


---

## ふりかえりの方法

1. KPT（Keep, Problem, Try: ケプト）
2. KPT派生（KPTA、KWT、YWT、....たくさん）
3. タイムライン

その他たくさん

---

## KPT

Keep: 続けていきたいこと
Problem: 問題となっていること
Try: 挑戦すること

---

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/02447934-6121-df1f-b452-ecc7ef45738f.png)

---

# どの方法が良いか明日、意見をもらいたいです

---


## デイリー

1. 昨日やったこと
2. 今日やること
3. 自分が、チームが困っていること
【Android Studio4.1】ベクターアセットが表示されない問題

# [2020/11/18 追記] 解消されました。
Android Studio 4.1.1にアップデートしたら、
ベクターアセットが表示されない問題が解消されていました。
https://androidstudio.googleblog.com/2020/11/android-studio-411-available.html

# Android Studio4.1.0に更新したら…
ベクターアセットのマテリアルアイコンが表示されなくなりました。
![android_studio.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/827233/58bc84fc-284f-431f-a7e3-1412c1eb55dc.png)

# 解決方法
```
C:\Users\ユーザー名\AppData\Local\Android\Sdk\icons\material\materialicons
```
↑ここにマテリアルアイコンがすべて保存されているので、
使いたいアイコンのxmlを、プロジェクトのdrawableフォルダへ手動でコピーすることで解決しました。

## スタックオーバーフローでも…
スタックオーバーフローでも同じことが起きて困っている人がいた。
https://stackoverflow.com/questions/64382564/how-i-fix-nothing-to-show-in-my-vector-asset-in-android-studio

アイコンが保存されている場所までのURLにスペースが入っているとダメかも、とのこと。

同じ現象で困っている人の助けになればと思います。
ハッカソンのときの課題と解決のメモ（Node.jsとobniz）

#やろうとしていること
距離・照度・距離のセンサーを用いて、obniz経由でLINEにメッセージを出す。
（カラオケのときにコロナに気を配りつつ、2人の距離を詰めるには？）



#メモ
__■アカウント設定周り__
まずはLINEで送るときの「__Credential__」と送信先の「__userid__」を設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737206/aa3bca4f-7113-9ed6-3269-86715a976f9c.png)


何かのエラーが出た。
　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737206/4592a054-8a00-4188-180c-76460f2dc231.png)
⇒どうやら、送信先のユーザIDの文言の中に「node」という謎の文言を入れていたからでした


__■センサーの設定__
　超音波センサー(HC-SR04)
　　サービスの中身を変えねば。
　　距離が遠い≠人との距離が遠い
　　どうやって、物体なのか人なのかを判別するか。
　　仕組みなのか、座る位置なのか。
　　⇒判別させるというより、__座る位置を工夫する__ことで確実に人との距離を測れるようにする。

　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737206/cb3bd54f-f3e2-4f23-0301-1d2a02125676.png)

　照度センサー(CdS)
　　閾値の調整
　　部屋の明るさだと、明るすぎて大体メッセージ発行されてしまう。
　　明るさのステータス（閾値を超えた）が変わったときに１度メッセージを送る。
またステータスが変わればメッセージをまた送る。
　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737206/45587043-3068-d95f-f363-ee1d7af23b75.png)

　　データ取得頻度の調整
　　1秒に何十回と計測するのでメッセージ発行が多い
　　5秒に1回に変更。
　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737206/99e02fbe-d78d-fa38-bef3-8c7dd4e98160.png)



__■LINEへの送信__
　1人に対しては、問題なくいけた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737206/4517487c-e13f-be46-d759-2611644a15b8.png)

　lineを複数人に送れなかった問題。
　試しに自分が作っているBotに記載のある自分のIDをチームメンバーに渡して送ってもらった。
　⇒送られない。なぜか？
　⇒lineのIDはbotの中でユニーク。
　　つまり、自分Aさんが管理コンソールで見ているIDと、
　　Bot側で見えてみるAさんのIDは違う。
　　複数人に送るときはBotから見えるIDを使う。
SD法にかわる，印象評価軸をきめる評価グリッド法について

心理実験の印象を評価するときのおはなしです．
私は今は機械学習系のことをやっていますが，以前は心理実験で音楽を主観的に評価してもらいあれこれする系のことをしていて，たまにこういう話が恋しくなってしまうのです．

## 心理実験で人の印象を探る
さて．
心理実験とは人の知覚をアンケート調査を行なってデータを集め，それを分析するというものです．
私の研究室だと，音楽を聴いてそのキャッチーさはどれくらいか，何らかの加工をした音としていない音で印象がどのように変わるかを実験参加者の質問紙への回答によってデータを集めます．
心理実験を行う研究の代表例として，**何か対象に対して，人が抱く感性的な印象**を調べたい場合があります．例えば人は声をどのような観点で印象を持つかとか，味に対して抱く印象はどんなものがあるか等．
そのような実験では，

1. 質問紙の回答項目にいくつか評価項目を定め，尺度を作る 
2. 回答してもらう
3. 主成分分析や因子分析で大まかな評価観点を探る（因子分析だと因子の抽出）
4. 3. で得た評価観点から各データを評価して考察（因子分析だとデータの因子得点を求めるフェーズ）

というのが分析の流れです．
ここで問題となるのが1. で，どのような項目で回答してもらうかという問題があります．

よくあるのが**SD法 (Semantic Differential)**と呼ばれる方法です．
SD法は，対になる形容詞を評価基準として回答項目にする調査方法です．
リカート尺度を用いて，印象の構造を探るヒントとする方法です．

例としてはこのような感じです．
評価得点　	1　　2　　3　　4
項目1:	嫌い　|－－＋－－＋－－|	好き
項目2:	悲しい	|－－＋－－＋－－|	陽気な
項目3:	冷たい   |－－＋－－＋－－|	あたたかい
項目4:	かたい   |－－＋－－＋－－| やわらかい
項目5:	単純な	|－－＋－－＋－－|	複雑な

これらの項目をたくさん用意し，直接探ることのできない人の印象構造を捉える手立てとします．

## SD法の問題点
ここで問題となるのが，SD法で使われる形容詞は本当に妥当なのか？というところです．
SD法に使われている形容詞は一般的なものばかりです．これは対象・領域問わず多くの領域で幅広く応用が効く一方，対象特有の印象構造を捉えるのなら**もっと対象に特化した評価軸を定めてもよいのではないか**ということです．
> こぼれ話として，SD法を利用した実験は時に20以上の形容詞について回答する場合もあります．参加者の負荷が大きく，回答がぶれやすいです．．．また対象によってはほとんど不必要な形容詞も出てくるでしょう．環境音が可愛らしい-にくらしい？わからんわ！という感じ．

ここで役立つのが，**評価グリッド法**という方法です．

## 評価グリッド法とは
評価グリッド法は簡単に言うと**「人々が何を感じているかがわからなければ、直接聞いてしまえば良い」**
という考えのもと，**評価軸をインタビューに基づいて決める方法**です．

方法の概要としては，
1. 具体的な対象をいくつか用意（なるべくプロトタイプがバラバラになるとよい）
2. その対象についてそれぞれの差を考え，言語化する
3. 2. について，具体・抽象を行き来するように考え，構造化する
4. 3. を通して見つかった評価軸を質問項目に追加する
という流れです．

たとえば，**炭酸飲料に対して抱く印象**を探りたいとします．
1. コーラ，サイダー，ラムネ，レモン，炭酸水を対象とします．
2. 例えば，コーラとラムネはどっちが好きか考えて，コーラのほうが好きと考えました．理由はラムネは甘ったるいし，後味がなんか嫌ということだとします．
3. ではまず，**抽象化**としてなぜ甘いのがだめなのかを考えます．ベタベタするからとか，くどいからとか，たくさん理由を考えるといいでしょう．次に**具体化**として，いい後味って例えば何？ということを考えます．そうするとスッキリしているとか，口に残らないとか，色々出てくるでしょう．
4. ここで**「ベタベタする」，「くどい」，「スッキリした」，「口に残る」**という**対象特有の評価語を得ることができました．**

これをそれぞれのペアで繰り返すと，この対象における印象を得ることができます．

## 音の評価で実際に用いられた評価グリッド法について
音の評価で用いられた方法について紹介します．
日本音響学会の招待講演で発表された方法だそうです．

評価グリッド法を音の印象を探る心理実験に対して適用する時，難しくなるのが差異の言語化です．
その代わり，**プロトタイプどうしに共通要素を見つけ，どんどん階層的にグルーピングしていく**という方法をとります．
図で示すとわかりやすかったので，参考資料の図をお借りします．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/493056/be462420-5a03-5077-b574-5a23eead3fe2.png)
（参照: 川井 被験者自身の言葉を評価語とした音事象の評価構造の抽出,日本音響学会研究発表会講演論文集,pp.1047-1050,2020. より）

このように動物の声や水の音としてグルーピングし，そのグループはどんな特徴があるかを言語化して評価語を得ます．またそれをさらにグルーピングして自然音としてまとめて，その特徴を言語化して評価語を得て．．．を繰り返していきます．
（ただ無理にグルーピングしようとせず単独要素が残ってもいい，と本文中にありました．）

このようにして，言語化が難しい対象においても評価語を得る方法が存在しているようです．


## 評価グリッド法の欠点
常に評価グリッドが良いかと言われるとそうでもありません．
欠点としては

- 構造化を行う人が対象を熟知した人でないと，重要な評価語を取りこぼす可能性がある
- 恣意的になりがち


というような欠点が挙げられています．
これらが致命的となる場合であれば，SD法を使うほうがかえっていいのかもしれません．


## むずびに
対象に特化した印象評価語を探る評価グリッド法を紹介しました．SD法の評価で「これで本当に印象探れるのかよ・・・」と思った方にはぜひ試してみてほしい方法です．
よい心理実験ライフを．

## 参考文献
+ 川井 被験者自身の言葉を評価語とした音事象の評価構造の抽出,日本音響学会研究発表会講演論文集,pp.1047-1050, 2020.
+ 讃井 評価グリッド法の理論と実際,日本音響学会研究発表会講演論文集,pp.1043-1046, 2020.
Excelの関数は文字列を計算対象としない

- 環境
    - Microsoft Excel for Microsoft 365 MSO 32bit
    - Windows10 Pro 64bit バージョン1909

こんなExcelがある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159761/4147995b-40e0-0c50-9c9f-3fa60ea0107a.png)

# 書式設定で見た目は同じように見える
時間が入力されたセルの書式設定は`[h]:mm;@`となっているので[シリアル値][文字列]の行は見た目が同じである。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159761/810d90ea-18af-dcc7-6886-8680ac7d635d.png)

# 見た目が同じでも数値と文字列は違う
実際に入力されている値はこんな感じ

||時間1|時間2|時間3|説明|
|:-:|:-:|:-:|:-:|:-:|
|シリアル値|1900/1/5 12:25:00|15:45:00|1900/2/25 14:54:00|時間のみの入力なので<br/>1900-01-01からの経過時間ととらえられる|
|文字列|'132:25|'15:45|'1358:54|`'`があることで文字列ととらえられる<br/>プログラムなどで値を入れた場合に`'`がなくても文字列になることがある|

# SUM()関数は文字列を計算対象としない
文字列の行のSUM関数のセル(E4)は`0:00`となってしまう。

# 文字列を計算する方法
## 方法1. セルを編集して数値にする
![a.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159761/f9a45e15-cde5-fa53-0469-39e20c303da9.gif)

## 方法2. 関数ではなく算術演算子を使う
方法1.の場合は、文字列のセルが大量にあるととてつもなく面倒くさい。
なので関数ではなく算術演算子を使う。
それがF列である、単純に`+`でつないで`=B3+C3+D3`としている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159761/ad1a66c1-0f44-0504-566a-1ecd59b25bfa.png)
[初級]touchdesignerで植物をつくる！最強のL-system　葉編

#前回の続き
前回の[[初級]touchdesignerで植物をつくる！最強のL-system　枝編](https://qiita.com/miwa_maroon/items/c15f5512bfdc3f3ca4d1)では、
<b>L-systemSOP</b>を使ってこんなものを作りました。
![TouchDesigner 2020.22080_ C__Users_22034_Desktop_touchdesigner_project_tdsw_L-system_qiita用_qiita.2.toe_ 2020_10_26 15_33_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704869/d3b55f42-d32e-effc-974c-d2d40fd9ad50.png)

もし見てない方は、まずそちらへ！
https://qiita.com/miwa_maroon/items/c15f5512bfdc3f3ca4d1


#葉っぱをつけていく
実は今回はめっちゃ<b>簡単</b>！

それでは前回の続きから行きます。
まず、<b>Circle SOP</b>を追加し、Radiusの値を0.5に調整します。
そして、オペレーター右のoutputの穴から、L-systemSOPの<b>一番上</b>のinputの穴にノードをつなぎます。
![TouchDesigner 2020.22080_ C__Users_22034_Desktop_touchdesigner_project_tdsw_L-system_qiita用_qiita.2.toe_ 2020_10_26 15_33_50_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704869/a460ae77-33af-fec6-6618-bacbbfb977f1.jpeg)


そして、前回のコードに新たに
<b>J</b>
という文字を追記します

```:lsystem1_rules
context_ignore:F+-
premise:FFFA

A="F[-A]///F[-A]///F[^(10)A]J
```

コードの最後についた<b>J</b>は、<b>外部の葉っぱ</b>をつけることができます。
touchdesignerでは、一番上のinputをJとするほか、
<b>二番目をK、三番目をM</b>として最大3種類の葉っぱをつけることが可能です。
使い方も、Jとまったく同じです!
![TouchDesigner 2020.22080_ C__Users_22034_Desktop_touchdesigner_project_tdsw_L-system_qiita用_qiita.2.toe_ 2020_10_26 15_33_50 (2)_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704869/8d56b5c5-54ba-5113-d1ae-ab4dc38a5f54.jpeg)


今回の葉っぱはCircleでしたが、オリジナルの葉っぱを作れば、よりリアル感が増します。

#完成形
最終的にこんなものができたと思います。
![TouchDesigner 2020.22080_ C__Users_22034_Desktop_touchdesigner_project_tdsw_L-system_qiita用_qiita.2.toe_ 2020_10_26 15_46_45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704869/b8b632a2-f8de-ac61-d7b0-736b39c87ffb.png)

もしうまくいかないとか、葉っぱがつかない！など不具合があれば、こちらの動画でも実際に同じことをしてますので、ご参考にしてください。
##解説動画
clickでyoutubeに飛べます！
[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/5ghm-v1diaY/0.jpg)](http://www.youtube.com/watch?v=5ghm-v1diaY)

その他質問等あれば、なんでもご連絡ください。

#発展させれば
これを書いてる人が作ったやつですが

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">在宅ワークのみなさん<br><br>最高空間の家で、<br>盆栽、はじめませんか？<a href="https://twitter.com/hashtag/touchdesigner?src=hash&amp;ref_src=twsrc%5Etfw">#touchdesigner</a> <a href="https://twitter.com/hashtag/lsystem?src=hash&amp;ref_src=twsrc%5Etfw">#lsystem</a> <a href="https://twitter.com/hashtag/%E7%9B%86%E6%A0%BD?src=hash&amp;ref_src=twsrc%5Etfw">#盆栽</a> <a href="https://t.co/9UxIdq4VK6">pic.twitter.com/9UxIdq4VK6</a></p>&mdash; 三和田智也 (@miwata34) <a href="https://twitter.com/miwata34/status/1319195050283134976?ref_src=twsrc%5Etfw">October 22, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

これが<b>エモい!</b>と思った方は、[instagram](https://www.instagram.com/miwa_maroon/?fbclid=IwAR1pPo8JuqcurfWSRxI7RK8rdXykT9oChZnRLcOFhRFCmOAaFl9lr8mm-JM)のアカウントに他の作品も載ってますので、フォローお願いします!!

そのうち中級編もやろうかなー、、、

それでは！！