OmniAICreator/Qiita-1.07M huggingface dataset:
Config ファイルを検索して、設定を書き換える

JMeter にコンフィグファイルがあり、これをプロビジョニング時に書き換える必要が発生した。以前Go言語でやったことはあるが、シェルスクリプトでは、やったことがないので、方法を調べてみる。

# 設定変更の方式

property ファイルはよく Java で使われるが、例えば GO 言語だと、読むライブラリはあっても書くほうはなかった。プロビジョニング時で固定の変更をしたい場合きっとシェルファイルの中で実施するのが楽だろう。

* [ファイルの中身の一部を置換して書き換える](https://qiita.com/shoma2da/items/dec1bae6b49780e399e3)

ブログがあったので、自分でサンプル書いて理解してみる。jmeter.property ファイルをとってきて書き換えてみる。自分が変えたい行は

```properties
# Set this if you don't want to use SSL for RMI
#server.rmi.ssl.disable=false
```

このオプションを有効化したい。ブログを見てコマンドを書く。`#`とかはなんかエスケープが必要かなと思いつつまずそのままやると、普通に動く。

```bash
$ sed -i -e "s/#server.rmi.ssl.disable=false/server.rmi.ssl.disable=false/" jmeter.properties
```

これで無事ファイルが変更されたので、今回の fix としてはこれでよいが、意味を使わずに知るのは気持ちわるので、もう少し調べてみる。

ここにいいブログがあった

* [sedでファイルを上書き保存](http://www.dab.hi-ho.ne.jp/sasa/biboroku/unix/sed-i.html)

# オリジナルの保存

`-i` は `--in-place` オプションでこのオプションによって、ファイルの特定の場所の上書き更新ができる。ちなみに、オリジナルのファイルを保存したい場合は、`-i` に対してsuffix を指定できる。

```bash
$ sed -i.bak -e "s/#server.rmi.ssl.disable=false/server.rmi.ssl.disable=false/" jmeter.properties
$ diff ./jmeter.properties ./jmeter.properties.bak 
334c334
< server.rmi.ssl.disable=false
---
> #server.rmi.ssl.disable=false
```

大変良い感じだ。では、`-e` は何だろう？これは、script だ。sed は、Manによると、ストリームエディタで、基本的なテキストのトランスフォーメーションをするとあります。

> -e script, --expression=script
>  add the script to the commands to be executed

スクリプトというとわかりずらいですが、このトランスフォーメーションをするスクリプトです。つまり、sedのコマンドになります。コマンドの詳細はここで見れます。

* [【 sed 】コマンド（基礎編その4）――文字列を置き換える／置換した行を出力する](https://www.atmarkit.co.jp/ait/articles/1610/17/news015.html)

今回は`s/before/after/`の置換コマンドです。ちなみに最後の`/`を忘れたらおこられました。

今回はこれでいけそうです。
個人開発するのって楽しいね。未経験からエンジニアになるまで、なってからを自作アプリと一緒に振り返る

タイトルは [人を描くのって楽しいね](http://www.asahi-net.or.jp/~zm5s-nkmr/index.html) から引用

既に色々な場所で「未経験からエンジニアになる方法」とか「未経験からエンジニアになってから学んだこと」記事があるのでそれに乗っかる形で大学卒業 ~ エンジニアとしてキャリアを積み始める ~ 現在まで何をしてきたかをざっくりと振り返ってみる。

# 先にまとめ

ポートフォリオは[こちら](https://shanttiy.netlify.com/)。 見てもらえるとありがたいです。

とにかくプライベートで自分の作りたいものを見つけて開発するといろんなメリットがあることがわかった。

- 新しい技術やツールをメインに学習できる
- 生活をハックして快適ライフを過ごせる
- ポートフォリオのネタにできるので、転職活動するときに有利になる(かも?)
- 収益化すれば当然お金が入ってくる(私はこの領域に達していないが...)
- なにより新しいアイデアを「モノ」にする事自体がプログラミング学習のモチベーションになっていた

# 黎明期(本当にやりたいことが大学卒業寸前にみつかる)

当時私は大学で機械系の専攻を受けていたが、大学卒業寸前に友人からプログラミングを勧められて学習を始めた。触れてみると結構面白かったのでとりあえず社会人になってからの新しい趣味に追加。

この時期は本当に何から手をつけていいかわからず、個人開発は特に行なっていない。ひたすら学習、学習、学習！

一番お世話になったのは[ドットインストール](https://dotinstall.com/)これのおかげで大学卒業時にはRuby on Railsで「Hello World!」までできるようになった。

# 成長期(プログラミングをしない会社に就職。理由は待遇がいいから)

大学卒業後はプログラミングとは無縁の機械部品メーカーに就職した。待遇も勤務形態も業界全体でみると恵まれている方だったが肝心の仕事内容が「自分にとって為になる」ものとは思えなかった。

当時プログラミングにハマっていた事が「今の仕事が自分に向いていない」という気持ちに拍車をかけていたのかもしれない。

そして、この時期から個人開発の沼にはまり込んで行くことになる。

## Active Reco Book

- [リポジトリ](https://github.com/Shantti-Y/active_reco_book)

新卒入社した会社で利用していた社員のメンタルを管理する為のサービスを模倣した作品。何のサービスかはここでは名指しはしないが、「この内容なら俺でも作れるのでは？」と思って作り始めた。

一時期Herokuを使ってサービスを公開していたが、今はクローズしてGithubに残骸だけが残っている状態...

### 得られた知識や技術

- HTML
- CSS
    - SCSS
- Ruby
    - Ruby on Rails
- JavaScript
    - jquery
- Windowsで仮想サーバを構築
- Heroku
- Git
    - GitHub

学んだことは、デプロイするところまで一人でやりきればサービス開発・運用に最低限必要な知識を得られる事。また思い返してみてもこれを作った経験が後に個人開発の楽しみを見出すきっかけになっているかもしれない。


# 転換期(私、駆け出しエンジニアになります)

入社して1年経ったころに本格的にプログラミングやりたいので転職活動を開始。でもこのままだと未経験から何もしていない状態なのでその前に作品を作りたいと考えていた。その時に参加していた勉強会の主催者から課題としてやってみないかと開発の話を持ちかけられた。その時作ったのがNohSightだ。

## NohSight

- [リポジトリ](https://github.com/Shantti-Y/Noh-app)

能楽関連のイベントを配信するサイト。こちらも一時期サービス公開していたが現在は停止中。

### 得られた知識や技術

- Ruby
    - Ruby on Rails
- JavaScript
    - Vue.js
- CI
    - Circle CI
- RDBMS
    - PostgreSQL
    - MySQL

ここからWebプログラミングのトレンドを追い始め、所謂今時のWeb技術というものに手を出し始める。この作品とポートフォリオを作成して転職活動に持ち込んだところ、受けたほとんどの企業からも好印象だったようで選考を受けた7社中4社から採用のお達しを得られた。

# 停滞期(といっていいのかな？)

転職活動を終え、Webエンジニアのキャリアがスタート。この時期はとにかく慣れない仕事を覚えるので精一杯で個人開発は行なっていない。ただ、仕事として開発をすることで個人ではできない・得られない技術や知見、経験を得ることができた。

### 得られた知識や技術

- Ruby
    - Ruby on Rails
- JavaScript
    - Vue.js
    - Nuxt.js
- チームで開発すること
    - デザイン -> エンジ開発 -> QA -> リリースまでのフローを踏む
    - サービスの運用やデータメンテナンス

# 現在(自分のキャリアに選択肢が見えてくる)

仕事の回し方・進め方のコツを掴み、ある程度余裕ができたので再び個人開発活動を開始。

## Setlify

- [リポジトリ](https://github.com/Shantti-Y/SetList)
- [サイト](https://setlify-236901.appspot.com/)

Spotifyのプレイリストを自動生成してくれるアプリ。

### 得られた知識や技術

- Spotify API
- JavaScript
    - Node.js
        - express
    - React
- GCP

ここからバックエンドが本格的にJSONだけを返すフロントエンドと分離したタイプのシステム設計にハマりだす。アプリ開発完全に理解した。

## Nikocale

- [リポジトリ](https://github.com/Shantti-Y/Chalendiary)
- [サイト](https://nikocale.com/)

その名の通りニコカレ。

### 得られた知識や技術

- Material UI
- Kotlin
    - Spring Boot
- Firebase
    - Authentication
- Websocket
- AWS
    - EC2

今まで業務に必要な知識の学習のために個人開発をしていたが、ここから現在まで業務と関係ない、でも仕事にも使えそうな技術を中心に選定してアプリを作るというスタンスに切り替えた。今後はTypeScriptにも手を出していく予定。

## 再まとめ

個人開発でやれることは学習、生活ハック、転職を有利にするなど色々なメリットがあるので

時間が空いていたらやろう、個人開発！
PowerAppsのFormで入力エリアが出力されなかったとき

# 概要
自分のメモみたいな記事です。
結構、察して読んでいただく事になります。

# PowerAppsでハマった経緯
Power appsからAzure Sql Databaseに接続して新規登録する画面を作ろうとしたら、
入力エリアが作成されなかった。

# 対処法
varcharだったカラムをnvarcharに型を変更したら、入力エリアも表示されるようになった。
対処はできたけど、原因は不明。

# まとめ
教えて詳しい人！
IchigoJamでタイピングソフト(その1)キーレイアウト表示


IchigoJamを子どもが使うとき、キーボードになれるためのプログラム。

配置を覚えつつ、遊べるようなアプリを作るためのその１。

■もくじ
キー配置表示(その１※このページ)
問題出題(その２)
正解判定＆次へorプログラム終了処理(その３)

■使う関数
STR関数、代入された文字列の指定した文字位置、文字数を返します
STR(変数名＋開始からずらす文字位置,出力文字数)　


■コード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71746/4f69ff98-6032-c5bd-9d6f-606beba7db5b.png)
5 CLS
10 A="QWERTYUIOPASDFGHJKLZXCVBNM
30 FOR I=0 TO 25
40 ?STR$(A+I,1);" ";
45 IF (I=9 OR I=18 OR I=25) THEN ?:? 
50 NEXT

■実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71746/17b8865a-8665-e546-6f19-e39632712e45.png)

■WEBで試したい方
下記アクセス後　RUN[エンター]　で実行されます
https://fukuno.jig.jp/app/IchigoJam/#5%20CLS%0A10%20A%3D%22QWERTYUIOPASDFGHJKLZXCVBNM%0A30%20FOR%20I%3D0%20TO%2025%0A40%20%3FSTR%24(A%2BI%2C1)%3B%22%20%22%3B%0A45%20IF%20(I%3D9%20OR%20I%3D18%20OR%20I%3D25)%20THEN%20%3F%3A%3F%20%0A50%20NEXT%0A

■参考ページ
文字列対応の IchigoJam ver 1.2β4 でジャンケンゲーム改良
https://fukuno.jig.jp/1266
人工知能を学習した備忘録

参加したネットでの人工知能学習の備忘録

１．データを読み込む
１）ライブラリのインポート
　　 numpy, pandas, matplotlib
２）データの読み込み
３）データの各カラムの確認
４）データフレームの先頭や末尾の確認
    DataFlame.head()
    DataFlame.tail()
５）データフレームの形の確認
    DataFlame.shape
６）データフレームの各カラムのデータの確認
    DataFlame.info()
　　このときに欠損値の存在確認ができる
７）カラムの形の変更
８）データの並び替え
　　DataFlame.sort_values(by="カラム", ascending=True(昇順) or False(降順) , inplace= True(更新する) or False(更新しない))
９）インデックスの付加・更新
　　DataFlame.set_index(keys="カラム", inplace=True(更新する) or False(更新しない)
１０）重複カラムの確認
１１）重複カラムの削除
　　　DataFlame.drop(Columns="カラム", inplace=True(更新する) or False(更新しない))
２．データの統計量
１）データの確認
　　DataFlame.describe()
画像が一覧表示できるlsコマンド lsix の紹介

##lsix について
画像付きでファイルを一覧表示出来るコマンドです。
こんな感じでターミナル上で `lisx` と打つと、ディレクトリにある画像ファイルを一覧表示してくれます。
![lsix.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13048/e50ae995-fee8-76ed-5a93-8bb01a095658.gif)

ローカルだけではなく、サーバ上にインストールしておけば ssh 越しに Webアプリケーションの image ディレクトリの画像をサクっと確認する様な用途にも使えて便利です。


##動作環境と必要なものについて
各OSで動作します。必要なのは

- SixelGraphics で画像表示が可能なターミナルエミュレータ
- ImageMagick


だけです。
ターミナルについては mlterm / Xterm /urxvt / iTerm2 等を使ってください。
Windows10 では WSL で wsltty を使うのが簡単です。[こちらの記事](https://qiita.com/rattcv/items/cecbd0d20d1882989fc0)を参考にして頂ければと思います。


今の ImageMagick は標準で sixel への変換処理が出来る様になっています。普通にOSのリポジトリからインストールしましょう。Ubuntu 等であれば、

```
~% sudo apt-get install imagemagick
```

でOKです。

##lsix のインストール
[こちら](https://github.com/hackerb9/lsix.git)のリポジトリから、`clone`するなり、zip をダウンロードするなりして展開します。
lsix の実体は Imagemagick の `convert`コマンドを使用したシェルスクリプトなので、展開したディレクトリ配下の`lsix`というファイルを、パスが通った場所にコピーするだけでインストール完了です。

##使い方

画像があるディレクトリ上で `lisx` と打つだけで、オプションはありません。
こんな gif アニメの場合は
![310776_245.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13048/baba9bfd-9a92-3684-0c04-b1bf10071ae1.gif)

展開して表示されます。
![pic2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13048/834c8e94-5ec5-901e-29e1-c8acb1cfe07d.png)

PDF も表示可能ですが、少し変換に時間がかかる為デフォルトではスルーされるので、 `lsix *pdf` 等と明示指定するとOKです。


以上、是非試してみてください！
Catalyst スイッチのIOSをアップグレードする方法

Catalyst スイッチのアップグレードを実施する機会があったので，備忘録として手順のメモをまとめました．

#前提条件
- Catalyst にIPアドレスが設定されており，IPを用いて通信できる
- 作業端末にTFTPサーバーが用意されている (私はSolarWinds を使用しました．Vector から無料でダウンロードできます)
- アップデート対象のIOS ファイルを入手している (Cisco のサイトからダウンロードしてください)

アップグレードの概要は下記の図のような形です．
Catalyst にSSH で接続できれば，コンソールケーブルは不要かもしれないけど...
![ios_upgrade.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438083/dc8f0916-271f-dcd5-e866-f0464050b77c.png)


#Step.1 不要なファイルを削除する
まず初めに，IOSのアップグレードに必要な容量を確保するため，不要なファイルを削除します．

```console:実行コマンド
> enable
# install remove inactive
```

その後，フラッシュメモリの容量が1 GB 以上の空きがあるかを確認します．

```console:実行コマンド
# show flash:
```

途中に"Do you want to remove the above files? [y/n]" と尋ねられたら，y を入力する．

XXXX bytesの部分で1 GB 以上空きがあれば，アップグレードに支障はありません．

```console:出力結果例
...(結果省略)
XXXX bytes avaliable (YYYY bytes used)
```

#Step.2 IOSをアップロードする
次に，アップグレードバージョンのIOS をCatalyst にアップロードします．
方法はいろいろありますが，今回は一般的なTFTP サーバーを用いた方法を実施します．

```console:実行コマンド
# copy tftp://192.168.0.1/【IOSファイル名】 flash:
```
今回はバージョン16.09.04 へのアップグレードだったので，IOSファイル名は"cat9k_lite_iosxe.16.09.04.SPA.bin" でした．

また，実行前に実施することとして，<b>TFTP サーバのルートディレクトリの設定</b>と<b>作業端末のファイアウォールの無効化の設定</b>が必要です．
今回はルートディレクトリは"C:/ciscoios"としてそのディレクトリにIOSファイルを配置，Windows FW はUDP通信に関して作業時は無効にしました．

情報がいろいろ表示されますが，基本すべてEnter で問題ありません．!が複数表示されていれば，ファイルは転送されて行っています．「OK」という文字が最後に表示されれば，無事にファイル転送は完了しているはずです．

以下のコマンドを実行して，転送したファイルが存在するか確認します．

```console:実行コマンド
# dir flash:*.bin
```

転送したファイルが表示されればOKです．（今回の場合，cat9k_lite_iosxe.16.09.04.SPA.bin が表示される）


#Step.3 IOSをアップグレードする
アップロードしたIOS ファイルをインストールします．

```console:実行コマンド
# install add file flash:cat9k_lite_iosxe.16.09.04.SPA.bin activate commit
```

途中で，"This operation requires a reload of the system. Do you want to proceed? [y/n]" と尋ねられたらyと入力する．システムのリロードが必要になるので，本番機で実施する場合などはSNMP の監視など気を付けること．

リロードが終了すると再度ログインから始まるので，enable モードに戻っておく．
リロードは10分くらい時間がかかった記憶がある．

#Step.4 バージョンを確認する

最後に，アップグレードされたかを確認する．

```console:実行コマンド
# show version
```

所望のバージョン番号 (今回の例では"<b>16.09.04</b>")が表示されれば，アップグレードは完了している（はず）！！
同じチームにいて最高に心強かったエンジニアの特徴をまとめてみた

これまで私はプロダクトマネジメントやデザインディレクションを行う立場として、BtoBにBtoC、iOSにAndroidにWebにWatchOSにIoT、ゼロイチにグロース。様々な分野、プラットフォーム、フェーズでサービスを開発する機会に恵まれてきました。

その中で一緒にチームを組んだフロントエンド、サーバーサイド、iOS、Android、インフラ、データ、様々なエンジニアの方を思い出しながら「ああ、心強いな」と感じた色々なタイプの特徴を、リスペクトの想いを持って、プロダクトマネージャーやデザイナーの視点でまとめてみました。

それではいってみましょう。

## 目的にフォーカスしている
要件をただ実装するのではなく、ビジネスの目的はなにか、ユーザーが真に求めているものはなにか、なにがサービスの生死を分けるのか、技術は目的を達成するための手段だと客観的に捉え、真の目的に対して解決策を提案し続けてくれるエンジニアがいると、マジで心強かったです。

## サービスのビジョンに共感している
組織やサービスのビジョンに共感してくれているとやっぱり嬉しい。自分の原体験と結びつけて「自分がこのサービスに取り組む意味」を考えている人に会うと感動します。この人となら熱くてクールなものを作れそうだとわくわくします。

## 企画段階からアイデアを出してくれる
企画段階から参加し、技術的観点から提案をしてくれるエンジニアの方がいると超心強い。できないと思ってたいことが実はできると知ることもあるし、できると思っていることがさらに良い方法で実現できるとわかる時もある。企画の可能性がグンと広がります。

## 事業領域の理解が深い
そのサービスの事業領域で何をおさえておくべきか、深く学んで理解している人のアウトプットはやはり質が高いものであることが多かったです。共通言語が増えるのでコミュニケーションも捗りました。

## リーダーシップがある
「いやいや、僕はリーダーやりませんよ」みたいなことを言いながら、なんだかんだでみんなを束ねて粘り強く問題を解決してチームをゴールに導いていく人。本当に心強いです。

## 問題解決できそうな人を連れてきちゃう
今いるメンバーだけで問題を解決することが難しくなった際に、解決できる人を社外からでも連れてきちゃう人。推進力がすごい。シンプルに超ありがたかったです。

## 継続学習する姿勢がハンパない
常に学び続け、歴史に詳しく、最新の技術にも明るい人。チームが車輪の再発明をしてしまいそうなシーンで、世にある技術を用いてクールにショートカットしちゃうエンジニアはかっこいい。

## 大工にもなれるし建築家にもなれる
プロトタイプを作るときは「さっ」と器用にこしらえらちゃう大工のように動き、本格的にサービス開発をする際は将来の拡張性を見据えてアーキテクチャを構築する建築家のようにもなれちゃうエンジニア。かっこ良かった。

## フロントエンドもバックエンドもできる
フルスタックなのが必ずしも良いことなのかは私にはわからないですが、少なくとも自分の注力スコープ以外の理解も深いとコミュニケーションも円滑になるので、チームに柔軟性が生まれるなと感じました。

## 全能感におぼれてない
私の知るすごいと感じるエンジニアほど、謙虚な方が多い印象があります。無知の知じゃないけど、謙虚でなければ学び続けられないのかもしれないですね。

## デザインに興味がある
前職が「デザインの力を証明する」ことに魂を注いでる会社だったので、ご多分にもれず私もデザインが大好きです。だから時にはデザイナー以上に美を、矜持を追求してくれるエンジニアと働けたときは本当に楽しかったです。そういうエンジニアはデザイナーの隣に座ろうとしてくれるんです。私はエンジニアとデザイナーが隣同士で楽しそうに話し合いながらガシガシ作って試しまくる姿が大好きです。

## こっそり実装しちゃう
知らぬ間にボタンにめっちゃ気持ち良いインタラクションを実装してたり、思わず愛しちゃいたくなるようなローディングを勝手に作っちゃったり、アプリのUIに心地よい音を仕込んでたり。少しでも良いプロダクトにできるかもしれない可能性をこっそり試し、イタズラな笑顔で披露してくれるエンジニアが大好きでした。

## ユーザーインタビューやユーザーテストに進んで参加してくれる
ユーザーがどんな痛みを抱えているのか、自分たちのサービスをどのように使ってくれているのか、それをリアルに感じ取れる場に興味を持って参加してくれるのは嬉しかった。やはりその場の空気を一緒に感じられると「良いものを作ろう」と一緒に熱くなり、チームでのアウトプットの質も大いに向上するなと感じます。

## ものづくりの場以外でもおもしろい
いま最も仲良くさせていただいているエンジニアである @hirokidaichi さんとは、会うたびにぶっとんだ話ばかりして笑い合ってます。すごいエンジニアの方とは、ものづくりの場以外で話していてもめちゃくちゃおもしろいです。

--

ダーッと挙げてみました。ここにまとめた特徴を、いくつかでも持っている人が同じチームにいると非常に心強いし、一緒にやってて楽しいなとあらためて思います。こうして見ると半分はスキルというよりマインドの話ですね。

私だけだと視点が偏ると思うので、みなさんが色々な立場や場面で「こんなエンジニアがいると心強いよね」と感じた人の特徴をぜひ聞かせてください。

私としては、このQiitaを書くにあたって頭に浮かんだエンジニアのような人たちが「めっちゃおもしろい！」と言いながらものづくりに取り組める現場を作り続けたいと、強く思っています。偉そうにまとめたからにはがんばらねば。

みなさんも出会う機会があれば、ぜひ一緒に最高の体験を作っていきましょう！

**追記：**

もし一緒にものづくりをしようぜと思ってくれるこころづよエンジニアの方がいましたら、ぜひTwitterやFacebookでDMをいただけると嬉しいです。
Scratchでプログラミングを好きになろう

この記事はScratch Advent Calendar 2019 12/22の記事です。

突然ですが、Scratchって、面白いですよね!!
親しみやすいUIでありながら、作品を作り込もうとしたらかなり凝った物が作れるため、プログラミング初学者にオススメしたいツールです。

Scratchを使って音楽を演奏する体験を通じて、学習者にどの様な力が身につくかを説明したいと思います。

# テーマ曲と事前準備

今回のテーマ曲はきよしこの夜と言う、言わずとしれた名曲です。
小さい頃にハンドベルなどで演奏した事があると言う方も多いのではないでしょうか？

楽譜もインターネットで確認出来るため、これを見ながらScratchで再現していきます。
https://ototama.com/music/folksong/score.php?id=231

事前準備は、Scratchの「音楽」を有効にするのみです。
以下画面キャプチャを参考に有効にしてください。

Scratchプロジェクトの画面左下にある、拡張機能を追加をクリックする。
![スクリーンショット 2019-12-19 15.01.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36448/375586a0-89e6-377c-dfcc-c817b8aafd21.png)

拡張機能一覧から「音楽」をクリックする。
![スクリーンショット 2019-12-19 15.01.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36448/cf4012b3-23a1-2488-98f0-32f3f82aac6c.png)

これで準備は完了です!!

# 楽譜を読みながらScratchで再現する。

冒頭の「きーよぉしー こぉーのよーるー」をScratchで演奏してみたいと思います。
ドレミで言うと、「そーらそーみー そーらそーみー」になります。
※拍が適当な所はご容赦いただけると幸いです。。。

<img width="263" alt="スクリーンショット 2019-12-16 12.50.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36448/285a2c46-c3e1-20a4-c364-7fdc1c3f909a.png">

どうでしょう？こうなったら良いのにな・こうした方が良いのではといった違和感を感じますでしょうか？
以下違和感を感じたら、大変センスがあります。

・「きーよぉーしー」と「こぉーのよーるー」が同じブロックを使うため、めんどくさい。
・「67の音符」と言われてもピンとこない。

上記違和感を解決した物がこちらになります。
![スクリーンショット 2019-12-19 14.45.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36448/da5a4acc-fdb6-252a-cdb9-19e25055ccbe.png)

Scratchは、同じ動きをする作品でも作り方にこだわる事で、以下の様な利点があります。
・変数の概念が身に付く
・繰り返しの概念が身に付く

# 輪唱にしてみる

カエルの歌で有名な、同じ旋律を一定の間隔でずらして歌う輪唱をScratchで再現してみます。
組み上げたブロックがこちら。
![スクリーンショット 2019-12-19 15.11.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36448/b2fc7b2f-a118-0964-eb69-ffa95739f15e.png)

上記ブロックには、以下の概念が盛り込まれています。
・関数の概念
・非同期プログラミングの概念

Scratchが上達していくと、一度に複数のスプライトに対してお願いをしたくなる事が良くあります。
「メッセージを送る」という直感的な文言で非同期プログラミングの感性が身につくのはとても素晴らしい事ではないでしょうか？

# まとめ

Scratchは遊びながらプログラミングの感覚を養うのに最適なツールです。
音楽意外にも流行りのAIやIoTの要素もいれる事が出来るので、ぜひ色々試して見てください!!
前の値と比較する

小ネタ

#はじめに
`timechart`で時系列の表を作って、３０分前の値と比較したいとかの場合とか、いろいろな場合での前の値との比較方法をいろいろと

```Splunk:SPL
| makeresults count=2 
| streamstats count 
| eval _time = if (count==2,relative_time(_time,"-1h@m"), relative_time(_time,"@m")) 
| makecontinuous span=1m _time 
| eval count=random() % 100
```
データはこちらを使用

#delta
[Delta@Splunk>docs](https://docs.splunk.com/Documentation/SplunkCloud/8.0.1/SearchReference/Delta)

```
| delta count as defference
```
| _time | count | defference |
|:--|--:|--:|
| 2019/12/22 08:24:00 | 1 |   |
| 2019/12/22 08:25:00 | 55 | 54 |
| 2019/12/22 08:26:00 | 75 | 20 |
| 2019/12/22 08:27:00 | 29 | -46 |

前の値との差分をだしてくれる。
_p=_ を指定することでどれだけ前の値と比較するか指定できる。

#autoregress
[autoregress@Splunk>docs](https://docs.splunk.com/Documentation/Splunk/8.0.1/SearchReference/Autoregress)

```
| autoregress count
| eval perc=round(count/(count+count_p1)*100)."%"
| eval perc=case(count = count_p1,"±", count > count_p1,"+",count < count_p1,"-").perc
```

| _time | count | count_p1 | perc |
|:--|--:|--:|:--|
| 2019/12/22 08:35:00 | 69 |   |   |
| 2019/12/22 08:36:00 | 32 | 69 | -32% |
| 2019/12/22 08:37:00 | 53 | 32 | +62% |
| 2019/12/22 08:38:00 | 35 | 53 | -40% |

`delta`と違い、前の値をそのまま出す`autoregress`
こんな感じで前の値との比較を少し凝った形にしたい時に使う。
こちらも　_p=_　が指定できる。

:sweat_smile: ダッシュボードSingle valueで表示したら、自動でやってくれてるね。これ
#streamstats
[streamstats@Splunk>docs](https://docs.splunk.com/Documentation/Splunk/8.0.1/SearchReference/streamstats)

```
| streamstats current=f last(count) as count_p1
```

| _time | count | count_p1 |
|:--|--:|--:|
| 2019/12/22 08:40:00 | 17 |   |
| 2019/12/22 08:41:00 | 88 | 17 |
| 2019/12/22 08:42:00 | 81 | 88 |
| 2019/12/22 08:43:00 | 89 | 81 |

`autoregress`の出力と同じにしてみた。
_current=f_がポイント。
`autoregress`との違いは、条件を`eval`にて指定できること。
あとは _window=_が指定できるので、いろいろ応用が効く。

```
| streamstats current=f last(eval(if(searchmatch("hoge"),count,NULL))) as count_p1
```
文字列_hoge_があるログの前の値とか指定できる。

#まとめ
表（じゃなくてもいい）の順番を`reverse`とか`sort 0 `で揃えて使うのが基本。
この３つのコマンドを使えば、前の値との比較は大丈夫　:sweat:　かな
ローカル環境にMAMPをインストールする


1. 以下のサイトから、MAMPをダウンロードする。

[MAMP](https://www.mamp.info/en/downloads/ "MAMP")

※デフォルトで、PRO版(試用期間あり)がインストールされます。

2. MAMPを起動すると、以下の画面になります。
![スクリーンショット 2019-12-22 9.18.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33953/c0d81aaa-db52-6ccc-05f8-8eda413209ae.png)

3. 設定画面でポート番号を変更できます。
![スクリーンショット 2019-12-22 9.20.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33953/344d00ff-01f0-f90f-a19a-860214d6fa48.png)

4. 設定画面でドキュメントルートを変更できます。（無料版は一つのみ）
![スクリーンショット 2019-12-22 9.21.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33953/b64dfefc-e2be-df5c-7036-af7912e5cbce.png)

5.PHP情報確認
[PHPINFO](http://localhost:8888/MAMP/index.php?language=English&page=phpinfo "PHPINFO")

また、php.iniは以下にあります。
![スクリーンショット 2019-12-22 9.27.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33953/8cf2395c-705d-6ad4-ced9-b0308a5da001.png)
]
Go の make の channel使ったときのデフォルト値

# 課題
make で channel を使ったときのデフォルト値が気になった。

```golang
quit := make(chan os.Signal)
```

普段はキャパシティとかが後につくけど、これはどういうことだろう？デフォルト値は？

# 定義

* [Making slices, maps and channels](https://golang.org/ref/spec#Making_slices_maps_and_channels)

こちらにこんな表があった。

```golang
Call             Type T     Result

make(T, n)       slice      slice of type T with length n and capacity n
make(T, n, m)    slice      slice of type T with length n and capacity m

make(T)          map        map of type T
make(T, n)       map        map of type T with initial space for approximately n elements

make(T)          channel    unbuffered channel of type T
make(T, n)       channel    buffered channel of type T, buffer size n
```

make は３つに大きくわかれているのですな。make(T) は、「バッファされない」がデフォルトのようです。
気になったのでソースコードを読んでいると、同じくコメントでありました。

> //	Channel: The channel's buffer is initialized with the specified
//	buffer capacity. If zero, or the size is omitted, the channel is
//	unbuffered.

すっきり。
[vscode Prettier - Code formatter]で prettier.openOutput 的なエラーが突然出た場合

# 右クリックで違うバージョンを入れる

![Screen Shot 2019-12-22 at 9.27.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16757/4164a61e-b6ed-4d4d-5f29-266870b43446.png)

たぶん問題はPrettier - Code formatterがバージョンアップして何らかの問題を抱えている。今までの動作が問題なければ最新ではない古いバージョンに入れ替えるとたぶん直る。
【Sinatra】Active Recordでつまずいた！～事象編

SinatraでActive Recordを使い、マイグレーションを実行しよとしたときにめちゃめちゃつまずいた話です。

解決編はこちらからどうぞ。
https://sunnydayservice.qrunch.io/entries/OtGeYUlG7WWdWgvA

```cannot load such file -- sinatra/activerecord```のエラーから始まり、しばらくどうしていいか分かりませんでした。

多大なる記事を参考にしましたが、参考にした記事を載せると、「この記事の通りにやっても出来ひんのかーい！」ってなるので、特に分かりやすいなと思った記事を参考に上げさせてもらいます。
記事通りに設定したのに、```rake```コマンドでマイグレーションできなかった方に向けた内容です。
*win10を使用しています。

※参考
https://railsgirls-bne.github.io/sinatra-app-guide
https://github.com/janko/sinatra-activerecord

参考にも載せた[こちら](https://railsgirls-bne.github.io/sinatra-app-guide)の記事が体系的にsinatraのアプリを組むのに、詳しく書かれてるかなと思うので、こちらの記事と見比べながら進めます。

# まず、何をしたか

sinatraでWebアプリを組む練習をしていました。

http://recipes.sinatrarb.com/p/databases/postgresql-activerecord?#article
こちらのsinatraのreadmeにも記載されていたり、他の記事にも記載されている通り、Gemファイルを作成し、```bundle install -(略)```でGemファイルを作ってDBの設定だ！ってところでRakeファイルを使い、マイグレーションだってところまで出来てました。

## 具体的に、何をしたか

１.Sinatraアプリのために、任意のフォルダを作ります。
２.Gemファイルを作成します。```bundle install```を流します。
３.その他のフォルダ、ファイルを作成します。
４.ymlファイルを作成します。
５.Rakeファイルを作成します。
６.```bundle exec rake～ ``` を流します。←ここで```cannot load such file -- sinatra/activerecord```のエラーが発生　


具体的なコードは、、、

アプリのディレクトリ配下で```bundle init```を実行し、Gemファイルを作成します。


```Gemfile
#Gemfile

source 'https://rubygems.org'

gem "sinatra"
gem "rake"
gem "sqlite3"
gem "activerecord"　#最近のアップデートでActive Record6がインストールされました。
gem "sinatra-activerecord"
```

これで```bundle install```すると、sqlite3、rakeコマンド、Active Recordをsinatraのアプリで使用することが出来ます。



アプリのディレクトリ配下で、```config```フォルダを作成します。
```config``` フォルダ配下に、```application.rb``` と、```database.yml``` を作成します。




```config/application.rb
# require gems and classes
require 'bundler'
Bundler.require
$: << File.expand_path('../', __FILE__)
Dir['./app/**/*.rb'].sort.each { |file| require file }

# configure sinatra
set :root, Dir['./app']
set :public_folder, Proc.new { File.join(root, 'assets') }
set :erb, :layout => :'layouts/application'
```




```config/database.yml
sqlite: &sqlite
  host: 127.0.0.1
  adapter: sqlite3

development:
  <<: *sqlite
  database: db/development.sqlite3

production:
  <<: *sqlite
  database: db/production.sqlite3

test:
  <<: *sqlite
  database: db/test.sqlite3
```

説明は割愛します。

## Rakeファイルの作成とRakeコマンド

そして、アプリのディレクトリ配下で、```Rakefile```を作成します。



```Rakefile
#Rakefile
require './config/application'
require 'sinatra/activerecord/rake'
```

この２行でいいみたいなんです！

記事によると、こういう記述の仕方もありました。

```Rakefile
#Rakefile
require 'sinatra/activerecord'
require 'sinatra/activerecord/rake'
```

この状態で、Rakeコマンドが使えるみたいです。
例えば、この状態で```bundle exec rake　-T ```コマンド(Rakeファイルのタスクの確認)を流すと、Rakeファイルに登録されたのタスクが一覧で出るみたいですが、私の場合、```cannot load such file -- sinatra/activerecord```のエラーが発生しました。

activerecordに```sinatra/activerecord```を呼び出す機能がついてるのか思いきや、そうでもないみたいでした。。。
ReadmeやGitHubで他のコードを見ても、これだけの記述のものが多かったので、自分の設定ミスなのかもしれませんが、動かないものは動かない。

もし、この方法だけで出来た方がいればコメントを頂きたいです。

## まとめ
次回は解決後のコードを載せます！
WSLディストリビューションの保管場所を変更する

# 事前準備
Windows Power Shellを管理者として実行し、WSLサービスの再起動をしておきます。
これを怠ると、ディストリビューションの移動に失敗することがあります。

```
PS C:\> net stop LxssManager
PS C:\> net start LxssManager
```

# 移動先フォルダの作成
今回は、Dドライブの`WSL`フォルダに移動することにしました。
フォルダを作成し、権限を付与します。

```
PS C:\> cd d:
PS D:\> mkdir WSL
PS D:\> icacls D:\WSL /grant $env:USERNAME":(OI)(CI)(F)"
```

# LxRunOfflineのダウンロード
[ここ](https://github.com/DDoSolitary/LxRunOffline/releases)からLxRunOffline.zipをダウンロード。
ここでは、`LxRunOffline-v3.4.0.zip`をダウンロードしました。
zipファイルを適当なフォルダに展開します。今回は`C:\LxRunOffline`フォルダに展開しました。

# WSL ディストリビューション名の取得
移動操作のために、ディストリビューション名を取得しておきます。

```
PS D:\> cd c:\LxRunOffline
PS C:\LxRunOffline> .\LxRunOffline.exe list
Ubuntu-18.04
```
`Ubuntu-18.04`がディストリビューション名です。

# ディストリビューションの移動
moveコマンドを使用し、WSLフォルダを移動します。
- `-n` ディストリビューション名
- `-d` ディストリビューションの移動先

```
PS C:/LxRunOffline> .\LxRunOffline.exe move -n Ubuntu-18.04 -d d:\wsl\Ubuntu-18.04
```

以下のコマンドで、移動先を確認できます。

```
PS C:\LxRunOffline> .\LxRunOffline.exe get-dir -n Ubuntu-18.04
d:\wsl\Ubuntu-18.04
```

# 注意事項
ディストリビューションの移動を行うと、ディストリビューションのアンインストールしても、移動先フォルダは残ったままになるようです。

以上。
【Sinatra】でActiveRecord

Avtive Recordが使用できるのはRailsだけだと思ってたのですが、Sinatraでも使用できるようです。
(他のフレームワークや言語でも使用可です)
Sinatraでは、Gemファイルに```gem 'activerecord'```を追加します。

[Active Record](https://railsguides.jp/active_record_basics.html)について
Railsの記事ですが、同じRubyを使用しているということもあり、当記事を中心にまとめていきます。

*参考
https://railsguides.jp/active_record_basics.html
https://qiita.com/tfrcm/items/80625a75959591c2b7cd#activerecord%E3%81%A8%E3%81%AF

# Acitve Recordの概要

Active Recordは、プログラムとデータベースのやり取りを簡単にしたものです。アクセスコードを書くだけでSQL文うぃ書かずに、データベースに接続することができます。その機能のことを、オブジェクト/リレーショナルマッピング(O/RマッピングやORMと略されることもあります)といいます。

## Active Recordの機能

・モデルおよびモデル内のデータを表現する
・モデル同士の関連付け(アソシエーション)を表現する
・関連付けられているモデル間の継承階層を表現する
・データをデータベースで永続化する前にバリデーション(検証)を行なう
・データベースをオブジェクト指向スタイルで操作する

改めて見るとめちゃくちゃ便利ですやん。

## 命名規則

ガチガチにあります。複数形/単数形の区別をする必要があります。(Active Recordの機能で複数形/単数形の分類はやってくれますが。)

>データベースのテーブル名を探すときに、モデルのクラス名を複数形にした形で探します。
bookというモデルクラスがある場合に、これに対応するデータベースのテーブルはbooksになります。

モデル名を単数形で指定してモデルを作成しても、DB上では複数形の名前となってテーブルが作成されるということです。





## スキーマのルール
スキーマとはデータベースの構造のことです。

Active Recordでは、テーブルで使用するカラム名にもルールがあります。

#### 外部キーと主キー

外部キーはActive Recordがモデル間の付けをするときに使用されます。
このカラムはテーブル名の単数形_id(book_id...)で使用します。

主キーはRailsではマイグレーションを実施したときに、idという名前で作成されます。


#### その他

>・created_at: レコード作成時に現在の日付時刻が自動的に設定されます
・updated_at: レコード更新時に現在の日付時刻が自動的に設定されます
・lock_version: モデルにoptimistic lockingを追加します
・type: モデルでSingle Table Inheritanceを使う場合に指定します
・関連付け名_type: ポリモーフィック関連付けの種類を保存します
・テーブル名_count: 関連付けにおいて、所属しているオブジェクトの数をキャッシュするのに使われます。たとえば、Articleクラスにcomments_countというカラムがあり、そこにCommentのインスタンスが多数あると、ポストごとのコメント数がここにキャッシュされます。

Active Recordが用意しているキーを認識していないといけませんね。
特に、外部キー、主キーの概念は押さえておいた方がいいでしょう。

## データの読み書き

Active Recordでは、CRUDの機能が自動的に実装されるので、テーブルに保存されているデータをアプリケーションで操作できます。

userモデルがある場合、
User.(アクション)で、データベースの操作を行うことが出来ます。

User.create
User.all
User.delete...

## バリテーション（検証）
Active Recordを使い、モデルがデータベースに書き込まれる前に、モデルの状態を検証(validation)することが出来ます。

データベースに変更を加えるので、バリテーションはとても作業です。
https://railsguides.jp/active_record_validations.html

save,updateメソッドは、バリテーションに失敗するとFalseを返し、データベースに変更を加えません。

また、より破壊的なsave!、update!メソッドは失敗すると、ActiveRecord::RecordInvalidを返します。

## コールバック

https://railsguides.jp/active_record_callbacks.html

特定のイベントが発生した場合に処理を呼び出すことが出来ます。詳しくは実装したことが無いので割愛させていただきますm(__)m

## まとめ
Active Recordすげー！
【Sinatra】Helperを追加

sinatraでHelperメソッドを呼び出し方を見ていきます！

*参考
http://sinatrarb.com/intro.html
https://hawksnowlog.blogspot.com/2017/10/sinatra-with-haml.html
https://codeday.me/jp/qa/20190301/335130.html



# Helperについて

処理を共通化し、コードを見やすくしたり、コードの記述量を減らしたい場合、処理内容を「呼び出し可能な位置」に置くことです。

http://sinatrarb.com/intro.html
こちらではヘルパーメソッドをアプリのファイルに直接記述してますが、自分はRailsから始めたので少し違和感があります。笑
なので、ヘルパー用に新しくファイルを作成し、ヘルパーメソッドを呼び出す方法も紹介します。

なお、今回呼び出したいヘルパーメソッドは、与えられた引数に「bb」を追加して返すという単純なものです。

# アプリファイルにヘルパーメソッドを埋め込む場合

こちらは単純です。



```myapp.rb
#中略

helpers do
    def  plusbb(a)
        return(a+"bb")
    end
end

get '/' do
  @code = "ブリ"
  @content = plusbb('aa')
  erb :index
end
```


view/index.erb
```
<div><%= @code %></div>
<div><%= @content %>:ヘルパー呼び出し</div>
```

ヘルパーメソッドを直接アプリのファイルに書き込むことで、indec.erbからヘルパーメソッドを呼び出すことができました。

# 別ファイルにヘルパーメソッドを記述へする場合

こちらは、別ファイルにモジュールを作成し、そのモジュールを呼び出します。

myapp.rbと同じディレクトリに「helpers/helpers.rb」のフォルダとファイルを作成します。



```helpers/helpers.rb
module Testhelper
    def  plusbb(a)
        return(a+"bb")
    end    
end
```

Testhelperというモジュールの中に、先ほどと同じplusbb(引数)のメソッドを定義しました。




```myapp.rb
中略
require './helpers/helpers.rb'

helpers Testhelper

get '/' do
  @code = "ブリ"
  @content = plusbb('aa')
  erb :index
end
```

こちらも追記するコードがあります。
```require './helpers/helpers.rb'```で、helpersフォルダ配下のhelpers.rbを呼び出します。
```helpers Testhelper```は、ヘルパーメソッドを呼び出しています。

view/index.erb
```
<div><%= @code %></div>
<div><%= @content %>:ヘルパー呼び出し</div>
```

でアプリファイル内でヘルパーメソッドを呼び出す場合と全く同じ結果になります。

# まとめ
ヘルパーメソッドはアプリファイル内に処理が速いのかなと思います。
でも、モジュール化し、処理を呼び出すことはアプリが大規模になるにつれ必要となってくるので、ヘルパーメソッドのみならず、他の場面でも参考にしていただけると幸いです。
【Sinatra】でレンダリング

SintraでHTMLファイルの呼び出しをしていきます！

*参考
https://qiita.com/kimioka0/items/751e460cbb59c70379c6#05-url%E3%81%8B%E3%82%89%E3%81%AE%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%82%92%E4%BD%BF%E3%81%8A%E3%81%86-2
http://sinatrarb.com/intro.html
https://qiita.com/itaya/items/f5b915e2b89457c6f514


# Railsとほぼ同じ

やり方はRailsとほぼ同じでした。

myapp.rb
``` myapp.rb
中略

get '/' do
  @code = "ブリ"
  erb :index
end
```

サーバ起動後、http://localhost:4567/
を探しに行きます。
```@code = "ブリ"```　で、@codeにHTMLファイルで使える変数を持たせることが出来ます。

```erb:index```　で、同ディレクトリ配下のview/index.erbファイルを探しに行きます。


ここはRailsと違うところですね。
Railsならindex.html.erbとなってますし、ファイル名も決まり切ってます。
自由に設計できるのも良いですね。

view/index.erb

```
<div><%= @code %>ってます</div>
```

てな感じでHTMLファイルを呼び出すことができます。


# erbの呼び出しファイルを並べてみる

myapp.rb
``` myapp.rb
中略

get '/' do
  @code = "ブリ"
  erb :index
end
```

で、erbファイルを複数呼び出すことはできないのかと思い、viewフォルダに適当なerbファイルを2つ追加することにします。

myapp.rb
```
get '/' do
  @code = "ブリ"
  erb :index
  erb :code
  erb :sub
end```

すると、erbで呼び出す一番下の「erb :sub」が呼び出されました。
「erb :~~」を存在しないファイルをの内容を指定するとエラーになったので、記述されているファイルは全部呼び出されて、最終的に表示されるのが一番下に記述されているファイルなんじゃないかなと思います。

「erb :~~」で呼び出すのは記述されているファイルの一番下のものになることが分かりました。

#共通レイアウトの設定

viewファイルの下に共通レイアウト用の```layout.erb```を作成します。

layout.erb
```
<head>
  <mata charset="utf-8">
  <title><%= @title %></title>
</head>
<body>
    <div>title</div>
    <%= yield %>
</body>
</html>
```

こちらもRailsと同じく```<%= yield %>```を使用することで、erbのファイルを呼び出すことが出来ます。
しかし、すべてのファイルに共通レイアウトが設定されてしまいます。

そこで、```myapp.rb```のerbファイル行に```, :layout => nil```を追加します。

myapp.rb

```
get '/' do
  @code = "ブリ"
  @title = "main"
  @content = "main contnt"
  erb :index
end

get '/sub' do
  @code = "タイ"
  erb :code, :layout => nil
end
```

http://localhost:4567/
では、共通レイアウトが適応され、titleという文字列が出現すると思います。

http://localhost:4567/sub
では共通レイアウトがnilなので、共通レイアウトが適応されません。
初心者によるプログラミング学習ログ 191日目

#100日チャレンジの191日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

191日目は

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>191日目<br><br>udemyでVue.js<br>vue.jsでカンタンなtodoリスト作成<a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a> <a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1208498972291022850?ref_src=twsrc%5Etfw">December 21, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Terraformerを利用してDatadog Dashboardをmodule化するのがすごい簡単だった話

# はじめに
これは[terraform Advent Calendar 2019](https://qiita.com/advent-calendar/2019/terraform)の22日目の記事です。
同日空いていたので、[この記事](https://qiita.com/eigo_s/items/3e59bd973041bc59337c)とクロスポストしようとしてしまったのですが、Qiita的にダメだったので、記事内で書いたダッシュボード用のTerraformリポジトリを作るにあたって初めて[Terraformer](https://github.com/GoogleCloudPlatform/terraformer)を利用してみたところ、ものすごい簡単にDatadogのDashboardがmodule化できた話を書きます。
※横着しようとしたのがダメでした。。。。。。。

# Terraformerとは？
AWS/GCP/Datadogなどの環境設定をTerraformのtfコード化してくれるすばらツールです。
自分は[こちら](https://qiita.com/donkomura/items/a69fc28109c2b59f3831)で初めて知り、使ってみたいなって思い続けて、Datadogのダッシュボードをコード化するにあたって利用しました。

# Datadog DashboardのTerraform module化 
流れとしてはものすごいシンプルです。

- 1. テンプレート化するための元となるダッシュボードをTerraformerでインポートする
- 2. インポートし作成されたtfコード内で、変数化すべきところを変数化し、module化する
- 3. それを各サービス用のディレクトリから呼び出して、ダッシュボードを作成する

1の部分は、terrafomerのサンプルのように
`./terraformer import datadog --resources= dashboard --filter=datadog_dashboard=[コード化したいダッシュボードのID] --api-key=[API key] --app-key[Applicationn key]`
とするだけでものすごい簡単でした。
メルペイさんの[こちらの記事](https://tech.mercari.com/entry/2019/12/09/122134)では、Dynamic Blockへの書き換えを行ったりしていたのですが、自分の場合はそのようなことはしていません。
理由としては下記の通りです。

- 提供するダッシュボードは、Datadog自体に慣れていないことも考えられる各サービス向けに提供するテンプレートであり、作成後の編集は各サービスにお任せしている
- 元々、Datadog Agent用に共通のタグ設計を行っており、変数化する項目がサービス識別向けのタグ、環境定義のタグの2種類程度だった

そのため、modules内もシンプルになりました。

```
modules/datadog_dashboard/
├── dashboard_list.tf             # ダッシュボードリストを定義するファイル
├── host_deep_dive_dashboard.tf   # 障害対応時など各ホストを深掘りしてメトリクスみるためのダッシュボード
├── output.tf                     # terraform apply後にダッシュボードやダッシュボードリストをアウトプットするためのファイル
├── service_dashboard.tf          # 各サービス向けのダッシュボードのテンプレート
└── variables.tf                  # 変数定義
```

output.tfですが、terraformはapplyするまで作成されるリソースのIDがわからないため、applyとあわせてURL確認できるようにこのようにしています。
中身もシンプルです。

```hcl
output "host_deep_dive_dashboard_id" {
  value = "${datadog_dashboard.host_deep_dive_dashboard.id}"
}

output "service_dashboard_id" {
  value = "${datadog_dashboard.service_dashboard.id}"
}

output "service_id_dash_list_id" {
  value = "${datadog_dashboard_list.service_id_dash_list.id}"
}
```

これをmodules呼び出し側でこのようにさらにoutputしつつ、URLを生成しています。

```hcl
output "host_deep_dive_dashboard_url" {
  value       = "https://${var.datadog_url}/dashboard/${module.datadog_dashboard.host_deep_dive_dashboard_id}"
  description = "host deep dive dashboardのURL"
}

output "service_dashboard_url" {
  value       = "https://${var.datadog_url}/dashboard/${module.datadog_dashboard.service_dashboard_id}"
  description = "service dashboardのURL"
}

output "service_dashboard_list_url" {
  value       = "https://${var.datadog_url}/dashboard/lists/manual/${module.datadog_dashboard.service_id_dash_list_id}"
  description = "dashboard listのURL"
}
```

# 終わりに
ダッシュボード用のterraformでoutput内容を加工し、URL生成を行う、みたいなことを初めて行ったのですが、他でも利用できそうなので、今後はもっとterraform outputも活用していきたいな、と思う所存でした。
BOM 付き UTF-8 csv ファイルのカラムを RSpec で検証する時は BOM を取り除く必要があった

## はじめに

BOM 付き UTF-8 の csv ファイルのカラム名を RSpec で検証しようと思ったときにハマったので、備忘録を残しておきます。

## tl;dr

BOM 付き UTF-8 の csv ファイルのカラム名を RSpec で検証するときは、`CSV.parse` するときにBOM を取り除く必要がありました。

```ruby
csv = CSV.parse(csv_content.sub(/^\xEF\xBB\xBF/, ''))
```


## 背景

RSpec でアプリ側で作成した csv ファイルが適切に出力されていたか確認するために、csv のカラム名を検証しようとしていました。

サンプルは以下のような形です。

```ruby
require 'rails_helper'

RSpec.describe Sample do
  describe '#method' do
    it 'checks if csv columns is valid' do
      # Sample.csv_content が csv ファイルを出力するメソッド
      csv_content = Sample.csv_content
      csv = CSV.parse(csv_content)
      expect(csv[0][0]).to eq '日付'
      expect(csv[0][1]).to eq '時刻'
    end 
  end
end
```


`Sample.csv_content` は以下のような形です。方法については以下を参考にしました。
（実際の処理は BOM 付き csv ファイルをそのままダウンロードして出力するような処理だったので、BOM を無理やりつけてはいません）

[BOM付きUTF-8のCSVを作成する（Excel文字化け対策） - Qiita](https://qiita.com/necojackarc/items/5e865a4aa039fdd3f2c0)


```ruby
class Sample
  def self.csv_content
    # bom = %w(EF BB BF).map { |e| e.hex.chr }.join
    # コメント踏まえ 2019/12/24 修正
    bom = "\uFEFF"
    content = CSV.generate do |csv|
      csv << ['日付', '時刻']
      csv << ['2019/12/22', '14:00']
    end 
    bom + content
  end 
end
```

出力する csv ファイルは以下の通りです。こちらが BOM つき UTF-8 のエンコーディングになっています。

```csv
日付,時刻
2019/12/22,14:00
```

## BOM 付きのままだと検証が失敗する

しかし実際に RSpec を実行しようとすると、`expect(csv[0][0]).to eq '日付'` の部分で検証チェックに失敗します。エラーは以下のような形です。

```
expect(csv[0][0]).to eq '日付' expected: "日付" got: "日付" (compared using ==)<
```

一見、expected と got が同じ値に見えるので、何が原因なのか最初はわかりづらいですね。。

RSpec 実行中にデバッガーで処理を止め、文字列エンコードを ascii-8bit にして確認すると、

```
expected: "\xE6\x97\xA5\xE4\xBB\x98"
got: "\xEF\xBB\xBF\xE6\x97\xA5\xE4\xBB\x98"
```

got のほうが `\xEF\xBB\xBF` 分だけ長いことがわかりました。これは BOM そのもので、`CSV.parse` しても、文字列先頭の BOM はそのままついてくるということでした。。

## 解決方法

`CSV.parse` する対象の csv 文字列から、BOM を取り除く処理を書きます。文字列の最初に表示される BOM のみ `sub` で空文字に置換するイメージです。

```
csv_content = Sample.csv_content
csv = CSV.parse(csv_content.sub(/^\xEF\xBB\xBF/, ''))
```

## そもそも BOM とは

Byte Order Mark の略です。[Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%90%E3%82%A4%E3%83%88%E3%82%AA%E3%83%BC%E3%83%80%E3%83%BC%E3%83%9E%E3%83%BC%E3%82%AF) から引用します。

> プログラムがテキストデータを読み込む時、その先頭の数バイトからそのデータがUnicodeで表現されていること、また符号化形式（エンコーディング）としてどれを使用しているかを判別できるようにしたものである。
> 
> UnicodeがはじまったころはアメリカではASCII、ヨーロッパなどではISO-8859、日本ではShift_JISやEUC-JPが主流であり、使用されている符号化方式がUnicodeであることを明確に区別する必要があった。その方法として、先頭のデータにテキスト以外のデータを入れることが発案された。

復数の国で異なるエンコーディングが使われていた中で、世界共通の文字コードとして扱われる Unicode との区別し、ファイルを開く際に Unicode のエンコーディングかどうかを判別できるようにしたのですね。

## 終わりに

なんとなく言葉だけ知っていた BOM について、この機会に改めて調べられてよかったです。

## 参考

* [ruby - Is there a way to remove the BOM from a UTF-8 encoded file?  - Stack Overflow](https://stackoverflow.com/questions/5011504/is-there-a-way-to-remove-the-bom-from-a-utf-8-encoded-file)
FirestoreのSubCollectionの簡単な使い方（最低限メモ）


記事化するようなことでもありませんが、ま、メモということで。
SubCollectionにするか、別に分けたコレクションを作るかはいつも悩みます。

下記で試していることは３つ。

* サブコレクションの作成（コレクションとサブコレクションを新規に同時で作るような状況）
* コレクション取得時にサブコレクションがどう見えるか（見えない確認）
* GroupCollectionを利用した検索


いろいろな書き方はあるかと思うが一旦下記のようにした。

>ECサイトとかで一人のユーザーが「一般ユーザー」、「ショップ運営者」、「管理者」とかの権限を持つような状況を想定（したが、あまりいいサンプルではない。別Collectionを用意したほうがいいかも）。


```js
const admin = require('firebase-admin');

admin.initializeApp({
    credential: admin.credential.cert('/path/to/key.json'),
    databaseURL: 'https://xxxxxxxxxx.firebase.com',
});

const db = admin.firestore();

(async () => {

    //サブコレクション作成
    const docId = db.collection("users").doc().id;
    await db.collection("users").doc(docId).set({ name: 'hoge' });
    await db.collection("users").doc(docId).collection("shopInfo").doc(docId).set({ level: 'user', id:docId });
    await db.collection("users").doc(docId).collection("adminInfo").doc(docId).set({ level: 'admin', id:docId });

    //サブコレクション参照
    const snapshots = await db.collection("users").doc(docId).collection("shopInfo").get();
    snapshots.docs.map(doc => {
        console.log(doc.data());
    })

    //CollectionGroup
    const groupSnapshots = await db.collectionGroup("shopInfo").where('level','==','user').get();
    groupSnapshots.docs.map(doc => {
        console.log(doc.data());
    })

})()

```
minimalでない式に命名することの難しさ

　　minimalな式: 種類@Sportが通時的にも共時的にも1である式

　例えば，templateMethod@TemplateMethodPatternに名付けることは，難しい．Verbは数字のようにBinary Operationをsupportしていない．
　結局，ForEx([fetchIt, constructIt])のようなDelegaterめいた名称に落ち着いてしまうのは，doItThenDoItExのような名称では冗長に堕すのを避けられないためだろう．並行した場合は，ForEx([doItAlongDoItExThendoItExAlongDoIt])．
　現時点で動詞として定義されている動詞群は人類が命名に成功した部分集合．
　How to do name themについては，今後，検討してゆく．
固定翼のミリョク


###自然災害の爪痕
房総豪雨からまだ数ヶ月。
千葉県内都市部ではかなりの部分が復旧した様に見える。
先日、果樹圃場の状況確認要請を受け房総半島の南端地域に出向いた。
報道でも話題になった地域である。
6ヶ所ほどの撮影を行ったのだが、未だ圃場までの農道が塞がれ、状態が確認できていない箇所が相当数あるのだ。確認できない以上、行政の補助事業への申請すらできない。
GPSの届かない谷間の傾斜地にある圃場にATTIモードで離陸、GPSを十分に捕まえられる高度になってからPモードに変更しマッピング撮影を行う。
と、あいにくGSProのサテライトマップが雲に隠れた地域で、事前にプランも立てられず、現地飛行でプランを立てようとも思ったが、トンビの襲来に自動飛行は危険なため、手動にてインターバル撮影を敢行。
HDMIモニター側で状況を確認していた園主さんのショックを装う言葉の数々が痛々しい。
2日間6ヶ所の圃場を撮影しオルソモザイク3dタイル化しOpenAerialMap経由での報告を済ました。
*静止画、では分かりにくい、潰れた小屋、倒れた果樹木が3dタイルで確認できます。
<img width="1024" alt="39E966D3-BF65-468A-AA64-2F1107A7A467.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539556/d1b26b73-1f98-b01e-3266-68ce36ef251d.jpeg">

####被災地撮影に思うこと
今回は依頼のあった圃場を個別に撮影したわけだが、わずか6ヶ所、飛行時間、距離の小さい回転翼のため、ほとんどの時間は離発着場所までの移動に割くしかなかった。山あいの飛行の為、周囲の樹木トンビに怯え、早く下ろしたい衝動の中での撮影であった。
房総豪雨の直後にDRONEBIRDとして行った、君津市での撮影を思い起こし、2日あれば、この地域全体を一気に撮影し、オルソ画像から判定して問題箇所を詳細撮影出来ればより効果の高い情報が得られるのに、と感じた。
####固定翼の効果と弱点
固定翼は回転翼に比べ、長距離、広範囲の移動が可能である。したがって、カメラの性能次第で高高度から広範囲を撮影することができる。
また万が一、墜落した際にも真っ逆さまに墜落する可能性の高い回転翼に比べ、滑空し軟着陸することで落下場所での対人対物の被害が少なくて済む。
しかし風の影響を受けやすく、離発着は風向きに合ったそこそこの距離が必要になる。また、ホバリングは出来ないし、もちろん後退も出来ない。翼をもった形状は獲物もしくは縄張りを荒らす敵に見え、アタックを受ける可能性が高かったり、前述の前方にしか進めない移動性能から逃げる方向が限られる。
デメリットだらけに見える固定翼機だが最初に述べた距離と範囲の魅力は絶大なものだ。
たまに前後すらわからなくなる回転翼に比べ、悠々とバンクさせながらきれいな弧を描いた旋回は「操縦している感」満点で気持ちの良いものだ。(今回の用途には関係ないが（笑）)
####ParrotDISCOという機体
数年前にParrot社からリリースされたDISCOという機体。それまでほぼ、自作か産業用の高価な機体しかなかった自動飛行可能な小型デルタ翼機が当時のドローン系アーリーアダプターの心に刺さった。
ラジコン飛行機からシフトしてきたオヤジフライヤー、ちょっと目新しくWaypoint飛行が出来る、比較的低価格な機体(20万くらいだったかな)。
リリース当時、迷いに迷いつつ、離発着場所が制限され、飛ばしてもあっという間に目視外になるウチの敷地では、メイデンフライトでフライアウェイとなるのが目に見えていたので諦めていた。そして2年ほど前、コストコで6万ほどで投げ売りがなされているというFacebook上の声で反射的に入手してしまう。それからつい先日までほんの数度しか飛ばさず、DRONEBIRDの定期訓練に投入。ファームアップと周囲のアドバイスをもとになんとかFreeFlight(DISCO用waypoint飛行アプリ)にて飛行経験を積む。
マッピングには直下方向の写真が望ましいため、GoproHERO7の搭載を目論む。数々の同志の応援(ケシカケ？w)にて、いよいよ回復手術へ
続く(とおもう)
![IMG_2547.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539556/c6611a70-1544-e9e8-b8fd-63269473b867.jpeg)
禍つヴァールハイトで実装された雪シェーダーを紹介します

この記事は [KLab Advent Calendar 2019](https://qiita.com/advent-calendar/2019/klab) 22日目の記事です。

# はじめに
こんにちは、クライアントエンジニアのnorm81です。

[禍つヴァールハイト](https://www.magatsu-wahrheit.com/)ではクリスマスイベントが絶賛開催中です。
今回はクリスマスイベントで実装された雪シェーダーを紹介します。
紹介する動作確認済み環境は Unity 2017.4.29f1 になります。

# 実装されたシェーダー
・地面に雪が積もるシェーダー
・天井に雪が積もるシェーダー
・スクリーンベースの雪が降るシェーダー

norm81が主に担当したのは地面に雪が積もるシェーダーですが
それ以外も各項で紹介します。


# 地面に雪が積もるシェーダー
![snow1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100161/8896a510-1cf6-0fa4-c897-fef1cad8f10d.gif)
専用のマスクテスクチャを使ってマスクの白い部分から、
マテリアルに設定されたレンジ値を基に、順々に表示されています。
頂点ごとに接線と角度計算して屋根にも使っています。

マスクテクスチャ
<img width="256" alt="マスクテクスチャ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100161/ed3605f4-8265-7637-2971-9335812fcee6.png">


プロパティ
<img width="441" alt="snow1_prop.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100161/94e0d8e5-d3ac-0d0d-15d4-198c078f15ab.gif">

関連箇所を抜き取ったシェーダー

```snow1.shader
sampler2D _HeightmapTex; // マスクテクスチャ
half _Snow; // Snow Level: レンジ域
half _SnowOffset; // Snow Offset: レンジ基準値オフセット
half _SnowSmooth; // Snow Smooth: 境界値付近のアルファ値
half4 _SnowColor; // Snow Color: 対象を上書きする色
half4 _SnowDirection; // Snow Ditection: 角度差の基準とする法線

v2f vert(appdata_t v)
{
    v2f f;

    // 省略
    float3 worldSpaceNormal = mul(unity_ObjectToWorld, v.normal).xyz;
    worldSpaceNormal = normalize(worldSpaceNormal);

    // NOTE: fragで計算した方がレンジの反映精度が高いが、計算回数の省略目的とstep境界値付近のぼかしにv2fの補間を使っている。
    float theta = dot(worldSpaceNormal, _SnowDirection.xyz);
    float threshold = (0.5 - _Snow) * 2.0;
    f.snowalpha = _SnowColor.a * (1 - step(theta, threshold));
    // 省略
    return f;
}

half4 frag(v2f f) : COLOR
{
    half3 color = tex2D(_MainTex, f.uv);

    // 省略
    half3 Heightmap = tex2D(_HeightmapTex, f.uv.xy);
    float snowHeight = (1.0 - Heightmap.r) + _Snow + _SnowOffset;
    float snowAlpha = f.snowalpha * saturate((snowHeight - 1.0 + 0.0001) / (_SnowSmooth + 0.0001)); // 0.0001: Check division by zero.
    color = lerp(color, _SnowColor.rgb, snowAlpha * step(1.0, snowHeight));
    // 省略
    return half4(color, 1.0);
}
```

# 天井に雪が積もるシェーダー
![snow2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100161/e24a9425-cb7b-fe8f-01f7-e9c95bd96c13.gif)
天井と記載しているのは、上面図のマスクテクスチャを使っているためです。
メリットとして可視範囲を上手くフォローできればテクスチャ最小1枚ですむので
メモリが節約できます。

マスクテクスチャ
<img width="256" alt="マスクテクスチャ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100161/901784b5-ca6c-75cc-89ec-9661a28d1a87.png">


# スクリーンベースの雪が降るシェーダー
![snow3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100161/5294fd8a-b2ad-d2ce-4f79-d08e63865936.gif)
下位互換のため、GPU インスタンシングではなく
必要なパーティクル数に分割した格子メッシュを用意します。

用意したメッシュの頂点入力について下記セマンテイクスを流用する形でベイクします。
・法線：座標変換前の基点座標
・カラー：アニメーション座標

<img width="400" alt="マスクテクスチャ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100161/afa0bb09-962b-cd97-74ad-ddf695ac57f3.jpeg">


あとは、自前シェーダーでパーティクル要件として座標変換・描画以外に
ビルボード処理などを行なっています。


# おわりに
雪の足跡を作るとか、キャラクター形状に雪が積もるとか
某ステルスアクションゲームのような実装みたいなことをやってみたいです。
「できるPowerBI」を読んで

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/402d4b41-1364-64c5-53bf-552ea686a85c.jpeg">
　[「できる Power BI データ集計・分析・可視化ノウハウが身に付く本」](https://www.amazon.co.jp/dp/B082VP5V5Y/ref=cm_sw_r_tw_dp_U_x_mdMaEbDAW39)が、2019/12/20にKindle版、12/23に紙版がでました。Power BIに関することを軸とし、Kindle、紙のみとして日本語の本として出版された最初の本です。一読した時に紙面ででてきたリンク、気になったところ、関連リンク、(個人的に勝手ながら)関連事項かなと思うことなどなど、以下に記しします。

## 基本事項メモ

**単行本（ソフトカバー）:** 328ページ
**出版社:** インプレス
**ISBN-10:** 4295008036
**ISBN-13:** 978-4295008033
### 章立て

準備編
　第1章 Power BI の概要を知ろう
　第2章 利用する環境をセットアップしよう
　第3章 基本を理解しよう
実践編
　第4章 データを取得して編集しよう
　第5章 ビジュアルを利用してデータを可視化しよう
　第6章 レポートを Power BI サービスに発行しよう
応用編
　第7章 さまざまなデータの取得と更新方法を知ろう
　第8章 レポートを仕上げるテクニックを知ろう
共有編
　第9章 組織内で活用しよう

## 本誌に関するメモ
         
#### (P12)練習用ファイルのダウンロード先等関連URL

 親切なことに本文で説明されるサンプルのダウンロードができます。12/22時点でダウンロードページが一時リンク切れでエラーになっていました（今は修正されています）。
 
  - [サンプルファイルのダウンロードURL](https://book.impress.co.jp/support/aftercare/download/500803.zip)
  - [サポートサイト](https://book.impress.co.jp/books/1119101121)
  - [イルミネート・ジャパンさんのブログ](https://www.illuminate-j.jp/blog/pbi-book?fbclid=IwAR1-ttEnn2ZiKgwwV1X7smyQ37FYW_hj1cckBeAMaPuOHokvtPY3stOlVRE)

#### (P19 レッスン2）公式ページの最新情報のリンク

日本語に加えて、英語のリンクは以下です。URL内のja-jpかen-usかの違い。当然英語が更新が早い。

| タイトル     |  
|:-----------------|
|[Power BI Desktop の最新の更新プログラムの新機能（日）](https://docs.microsoft.com/ja-jp/power-bi/desktop-latest-update) | 
|[What's new in the latest Power BI Desktop update（英）](https://docs.microsoft.com/en-us/power-bi/desktop-latest-update) | 
|[Power BI サービスの新機能（日）](https://docs.microsoft.com/ja-jp/power-bi/service-whats-new) | 
|[What's new in the Power BI service（英）](https://docs.microsoft.com/en-us/power-bi/service-whats-new) |

#### (P27 レッスン5）Power BIサービスのサインアップのメールアドレス
　他のレッスンでもOffice365との関連の補足がありますが「利用可」となっているメールアドレスは、Office365で使うアドレスがあるならば、そのアドレスを使う、が利便性が高いです。
ワークスペースなどO365グループと関係するものがPower BIサービス上でも扱えます。

なお、個々の会社等組織で利用等が許されている/云々は個々の事項なので、利用者の方々のそれぞれ適合する形で...ということになるかと。

### (P192 レッスン45/P292 レッスン60) 自動で1時間に1回 OneDrive上のExcelを更新する場合
　Excelに接続する場合、OneDriveからの接続だと実質5分に1回更新されます。実際の画面の選択の方法等はYugoさんのSlideshare [Teams の”チーム”と Office 365 グループを理解して Power Platform を活用せよ](https://www.slideshare.net/yugoes1021/teams-office-365-power-platform)の図解がわかりやすいです。

### (P198 レッスン46) データベースに関する接続方法

 3種類の接続方法に関して、[MSさんの関連ブログ](https://blogs.msdn.microsoft.com/dataplatjp/2017/04/05/power-bi-data-access/)にも説明上ブログ記事の対象外と書いてありますが、[ストリーミングデータセット](https://docs.microsoft.com/ja-jp/power-bi/service-real-time-streaming)や[REST API](https://docs.microsoft.com/ja-jp/rest/api/power-bi/?redirectedfrom=MSDN)によるプッシュ型のデータセットがあります。YugoさんのSlideshare[開発者におくる Power BI を使う時に考えるべきアーキテクチャ ～ データを溜めるのは誰だ？ ～](https://www.slideshare.net/yugoes1021/power-bi-98674803)がわかりやすいです。


## おわりに

　私も最初は理解がなかなかできなかった、Power BI Desktop（無料 or Pro）とPower BI Serviceとの違いや基本的な概念、用語など非常に丁寧に説明されており、さらにできるシリーズならではの図解がてんこもりにあるので、初心者が基礎を学ぶ第一歩を踏むのに非常時に有用と感じました。
Unityでゲームつくりてえ

備忘録です。



## 自分の記事
Dpad（十字キー）
https://qiita.com/togetetu/items/a62402648fb52ae6f7b1

マウス関連
https://qiita.com/togetetu/items/07560181fecfce33a6f0

自機狙い
https://qiita.com/togetetu/items/e09466f50bc62cd7cbe0


## 参考にさせていただいた記事
衝突判定
https://qiita.com/moscoara_nico/items/8eee1de552601a8a8f1f
GithubActionsでプライベートリポジトリをsubmoduleとして取り込む

GithubActionsでプライベートリポジトリをsubmoduleとして取り込む方法は**submodule add**コマンドで**https**方式で追加したか**ssh**方式で追加したかによって変わります。それぞれのメリットデメリットを説明しつつ、実現方法を記しておきます。

```
https方式
git submodule add https://github.com/u-nation/GITHUB_REPOSITORY.git
ssh方式
git submodule add git@github.com:u-nation/GITHUB_REPOSITORY.git
```

## https方式
手軽なのは**https**方式です。
以下の権限を持つパーソナルアクセストークンを作成し、**secrets**に登録してワークフロー内でwithオプションに渡してあげるだけで済みます。
※パーソナルアクセストークンは[**https**方式しか使えません](https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line#using-a-token-on-the-command-line)。[^1]
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58939/a0aac8b5-5a54-9d95-c43d-22d072064bc5.png"width=600px>

```yaml:.github/workflows/sample.yml
      - name: submodule
        uses: actions/checkout@v1
        with:
          submodules: true
          token: ${{ secrets.PERSONAL_TOKEN }}
```

- メリット 手軽さ
- デメリット パーソナルアクセストークンは発行したアカウントがアクセスできるリポジトリ全てに権限が及ぶのでトークンが漏れた場合のセキリュティリスクが大きい。Bot用のアカウントを作成やトークン作成の依頼・共有など運用がしんどい。

## ssh方式
1. ssh-keygenコマンドで秘密鍵公開鍵を作成
2. submodule先のリポジトリのDeploy Keysに公開鍵を登録(必要に応じてwrite権限を付与)
3. 取り込む方のリポジトリのsecretsに秘密鍵を登録
4. ワークフローでsshの設定とsubmodule update --initをする

```yaml:.github/workflows/sample.yml
      - uses: actions/checkout@v2
      - name: SSH Setting
        env:
          TOKEN: ${{ secrets.TOKEN }}
        run: |
          mkdir -p /home/runner/.ssh/
          echo -e "$TOKEN" > /home/runner/.ssh/id_rsa
          chmod 600 /home/runner/.ssh/id_rsa
      # https://github.com/actions/checkout#checkout-submodules
      - name: Checkout submodules
        shell: bash
        run: |
          git submodule sync --recursive
          git submodule update --init --force --recursive
```

- メリット 鍵の権限はそのリポジトリに限定されるので漏れた時のセキュリティリスクが軽減される。必要に応じて各々が鍵の設定を追加できるので運用が楽。
- デメリット 鍵作ったり設定するのがちょっとだけめんどい。

## 所感
企業でGithubを使う場合は大抵プライベートなリポジトリだと思うので、誰かのお役に立てると嬉しいです。

ssh方式を実現するのに6時間位ハマって辛かったですが、運用が楽になるのでssh方式がオススメです。

### 注釈
#### 注釈

[^1]: GithubActionsに移行する前は、AWSのCodeBuildを使用していました(GithubAcitonsの方がめちゃくちゃ早いです)。その時は秘密鍵をSystem Managerで用意してssh方式をしていましたが、途中で[https方式のsubmoduleオプションが登場しました。](https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/create-project.html#cli-sources-gitsubmodulesconfig)
データ分析案件のPMに読んでほしい

#パネルディスカッションで出た悩み
先日、データサイエンティストとしてパネルディスカッションにパネラーとして参加しました。
その時受けた相談の一つが、「データ分析案件のPMをやっているが、案件マネジメントに困っている」というお話でした。
そこで、そんな人たち向けに案件マネジメントの仕方の助言となるようなスライドを作ってみました。


https://docs.google.com/presentation/d/e/2PACX-1vSf6s5-gi-wk0QFE6r1eNIhv0BKKztWHbirkQfflQLn890ttaR0cS6KXuyeq2X7g3Y8szX2Wstw681O/pub?start=false&loop=false&delayms=3000



困っている原因はいくつかあり、これはその一例向けでしかないのですがお役に立つと幸いです。
今後も不定期にデータ分析PM初心者向けのスライドを作っていこうと思います。
上記のパネルディスカッションでも出たのは「精度が～」と言われ終わり時がわからないパターンなので、次はそういう状況で困っているPM向けのスライドを作る予定です。

#はてなブログも書いています
良ければこちらも見ていただけると喜びます。
ゆくゆくはコード以外の雑多なことははてなブログに記載しようかな思ってます。
https://data-analy.hatenablog.com/