OmniAICreator/Qiita-1.07M huggingface dataset:
既存のスクリーンショットよりイイ~WinShot~

#WinShotとは
　WindowsOS向けで、現場でよく使われている**「画面キャプチャソフト」**です。
　すでに搭載されてあるスクリーンショット(winボタン+PrintScreen)より
　**細かい設定ができて、作業エビデンスを撮る**のに役立ちます。
　BMP/JPEG形式の**画像ファイルを編集/保存**ができて**サイズがスリム**です。
##どこで知った
　そもそもインフラエンジニアは、どんな仕事をしているのかを
　**YouTube動画**で探していたら、この方の作業現場で使われるツール紹介で知りました。
　　　　　　　　　　[>>駆け出しインフラエンジニアが仕事で気をつけることは何なのか？？](https://www.youtube.com/watch?v=fwrwwlGjrgE&list=PLcuk2r7VR-0TDf0mDLYsM634C3z2ZQPSi&index=9&t=448s)
###作業環境
　 Windows 10 Home 
　 WinShot 1.53a
##ソフトをインストールする
　こちらから[>>WinShotダウンロード]
(https://forest.watch.impress.co.jp/library/software/winshot/)
　![スクリーンショット 2021-03-15 125808.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1203650/e31ce278-a292-68cb-bcb3-ac0dfece41ac.png)
　ダウンロードされたら**「圧縮フォルダ(zip)」**なのですべて展開します。
　フォルダの中にある**「WinShot.exe」**をダブルクリックしてインストールを進めて下さい。
##保存せずに使ってみる...と思ったら
今から指定範囲をきめて**キャプチャー画像を表示**させてみます。

　1.　デスクトップ上の**exeファイル**をダブルクリックで起動
　2.　右下にあるインジケータを表示して**WinShotアイコン**を右クリック
　3.　プレビュー表示から**矩形範囲選択**をクリック...ん？
![スクリーンショット (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1203650/6d447d0c-291a-3f94-6174-5ce8248e3974.png)
　**Windows10**の方でお気づきになったと思いますが、**画面ズレ**ます。
　**対処方法**は、こちらにある**記事を参考**にしてLGTM評価してあげて下さい。
　　　　　[>>Windows10でWinshotを使用するとキャプチャーがずれる場合の対処法](https://qiita.com/yasushi-jp/items/bf4868876eb6f9534291)
![スクリーンショット (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1203650/e2644b90-73f1-2b48-5041-1f074b88d774.png)
　カーソル部が十字マークになって、さらに拡大ウィンドウが出てくる。
　**左クリックで視点が固定**されて、そこから自由に**画面サイズをプレビュー**できます。
　ちなみに、**右クリック**で上記の**指定選択を解除**します。
##環境設定
 　ここも同じように**WinShotアイコンに右クリック**して**環境設定**を選択します。
![スクリーンショット (10).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1203650/d2f843b9-0a18-bb5a-bda4-318ca8e4fd56.png)
　**「基本設定」**では、ピクチャの中に**WinShotフォルダー作成して保存先**にしました。
　次に**「ホット・キー」**をクリックします。
![スクリーンショット (11).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1203650/35b531db-979b-d063-eeff-99cebf5b5f0d.png)
　ホット・キーでは、**ショートカットキー**を設定していきます。
　**保存せずに使ってみる...と思ったら**で行ったのが**「プレビュー表示(矩形範囲指定)」**です。
　こちらを選択して**ユーザ設定**を**Ctrl+Shift+Z**にしました。
　理由は、**小指＝**Ctrl / **薬指＝**Shift / **中指＝**Z　と、**手のかたちを変えずにそのまま**
保っていられるからです。
　　　　　　　　　　　　　　**注意：Ctrl+Shift**を同時押してから**Zキー**を押すのがコツ。

![スクリーンショット (15).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1203650/7ea68709-652e-bd65-492a-f8b250c0ecf6.png)

　上の画面のように指定した範囲を**「プレビュー」**してくれます。ただ、保存時にファイル名を記入する手間があります。もし**「先にスクリーンショットを数枚撮ってから編集/加工」**する場合は以下の設定を行います。

![スクリーンショット (16).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1203650/509cf575-dd5d-8434-ec70-fd290d436de0.png)

　「環境設定」→「ホットキー」→**「JPEGで保存」**を選択してお好みのユーザ設定を決めてOK.
　これで自動的にファイルに保存されて、しかもファイル名が番号付けられます。

![WS000001.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1203650/9e5bd7d8-ccf3-1744-d594-452d6cda9744.jpeg)

　設定環境を完了すると上のアイコンがデスクトップに出てきます。削除すると、設定が初期化されます。
IllegalArgumentException 発生: Value 'C:Program Files (x86)Javajre1.8.0_251bin' given for org.gradle.java.home Gradle property is invalid (Java home supplied is invalid) java.lang.reflect.InvocationTargetException


> わかりやすそう＆今の業務に役立つであろう動画を見つけたので
Springスターター・プロジェクトを作成して作ってみようと思ったら
いきなり出鼻をくじかれたので解決方法について記録

# エラーの内容
```
IllegalArgumentException 発生: Value 'C:Program Files (x86)Javajre1.8.0_251bin' given for org.gradle.java.home Gradle property is invalid (Java home supplied is invalid)
java.lang.reflect.InvocationTargetException
```

# 解決方法
ユーザー配下に作られるgradle.propertiesの
以下の部分を削除することで
エラーが出なくなってBUILDが成功した

.gradleフォルダ
　┗gradle.properties

```gradle.properties
org.gradle.java.home=C:\Program Files (x86)\Java\jre1.8.0_251\bin
```

# コンソール（BUILD SUCCESSFUL）　

```
> Task :nothing UP-TO-DATE

BUILD SUCCESSFUL in 2m 43s
作業ディレクトリー: C:\workspace_Servlet\techShare_20210324
Gradle ユーザー・ホーム: C:\Users\（ユーザー名）\.gradle
Gradle ディストリビューション: ターゲット・ビルドからの Gradle ラッパー
Gradle バージョン: 6.8.3
Java ホーム: C:\Eclipse2020\pleiades\eclipse\jre
JVM 引数: なし
プログラムの引数: なし
Build Scans Enabled: false
Offline Mode Enabled: false
> Task :cleanEclipseWtpComponent UP-TO-DATE
> Task :cleanEclipseWtpFacet UP-TO-DATE
> Task :cleanEclipseWtp UP-TO-DATE
> Task :eclipseWtpComponent
> Task :eclipseWtpFacet
> Task :eclipseWtp

BUILD SUCCESSFUL in 5s
5 actionable tasks: 2 executed, 3 up-to-date
```
# 参考記事と学習動画
https://stackoverflow.com/questions/39010338/java-home-supplied-via-org-gradle-java-home-is-invalid-invalid-directory-us

https://www.youtube.com/watch?v=IWH_EZwQhSY

# 感想
やる気になって始めてもすぐエラーで止まってしまう
（むしろスタートさえ出来てない。。:innocent:
display: flex; アウトプット

display: flex;は、親要素に記述し、
子要素のclassセレクタ内に横並びにする内容を記述します。

```css
.card__wrapper {
  display: flex; 　/*親要素に記述*/
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
}

.card { /*子要素*/
  width: calc((100% - 50px) / 3);
  margin-bottom: 40px;
}
```
↓each文の外に親要素のclassセレクタを記述します。

```ruby

  <div class="card__wrapper">　#親要素
    <% @tweets.each do |tweet| %>
          <%= render partial: "tweets/tweet", locals: { tweet: tweet } %>
    <% end %>
  </div>
```
↓render先のファイルです。
　子要素でまとめることで、子要素ごとにeach文で繰り返しされます。

```ruby
<div class="card">　#子要素
  <%= link_to '詳細', tweet_path(tweet.id), class: :card__btn, method: :get %>
  <%= link_to '編集', edit_tweet_path(tweet.id), class: :card__btn, method: :get %>
  <%= link_to '削除', tweet_path(tweet.id), class: :card__btn, method: :delete %>
  <%= link_to "投稿者: #{tweet.user.nickname}", user_path(tweet.user.id), class: :card__user, method: :get %>    
  <%= "タイトル: #{tweet.title}" %>  
  <%= "内容: #{tweet.text}" %><br>
</div>
```
rails g scaffold で楽々下準備

安易はcrud処理も自動で作ってくれる優れもの^^
だと思っております　笑

## scaffoldとは
他の`rails g`コマンドは不要で、
Webアプリケーションに必要な`crud処理`も一度に自動で組み立ててくれるのがscaffold。

# scaffoldの使い方

`$ rails g scaffold hoge title:string content:text`
このコマンドだけでhogesコントローラーやhogeモデルができる。
$ rake db:create
$ rake db:migrate
$ rails s

以上で
`index show new edit create update destroy`
７つのアクションの準備ができます。
Defoldの画面構成を教えたい！

# はじめに
[前回](https://qiita.com/nonzu/items/eae176d34a6766d7c75b)インストールしたDefoldの画面がこうなってます。
![画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620977/244ce00a-b1de-b604-6b9d-fbf596921009.png)
# 本題
この記事では、この画面をこのように8つに分割して1つ1つ説明しようとおもいます。
![分割.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620977/8e17344d-fd08-c452-15a5-b836886c77c2.png)
### ① Menu
これは普通のソフトにもよくあるメニューです。メニューで色々できますが、必要なときに必要なものだけ説明しようと思います。
### ② Assets
Assetsはフォルダを示しています。ゲームに使う画像ファイルやプログラムのファイルを全部ココで管理します。
### ③ Changed Files
ここは初心者さんは使わないです。Gitを使う人はコレを使います。
Gitを使っている人は変更点をこんな感じに表示させることができます。
![changed_files.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620977/1600571c-3bbb-507d-dbd8-c99f0589ae85.png)
　**＋**　が追加されたファイル、　**ー**　が削除されたファイル、　__*__　が変更されたファイルです。
ファイルを選択して、**"Revert"**ボタンを押すと、選択したファイルを変更前の状態に戻すことができます。
また、変更されたファイルを選択し、 **"Diff"**ボタンを押すと、変更前と変更後の比較をすることができます。
![Diff.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620977/538d0bfb-a726-69bb-0101-4816e800544a.png)
長々と説明しましたが、とりあえずGitを使う人にはちょっと便利で、使わない人にはなくてもOKな機能です。
### ④ メインの画面
Assetsからファイルをダブルクリックで開くとここに表示されます。実際に作業するスペースはココです。
### ⑤ 色々
**Console**と**Curve Editor**と**Build Errors**と**Search Results**があります。
正直良くわかりません。実行結果などが **Console**に出てきてくれるくらいで、それ以外は全然使った事がありません。
### ⑥ Outlines
ここは④で開いている**ファイルの構造**(この表現が正しいかわからないけど) が表示されます。
Outlinesもよく使います。多分使ってたら何なのかよく分かると思います。
### ⑦ Properties
⑥の中にある要素を選択すると、その要素のプロパティを設定できます。色とか大きさとかですね。
これも結構使います。
### ⑧ Footer
アプデの有無や、アップデートの状況、バンドルの状況が表示されます。あんまり気にしなくても困りません。
アプデに関しては次回の記事で説明しようかなと思います。
(バンドルはゲームを実行ファイル(.exe)として出力することを指します。ゲームを配布したりするのに必要な作業です。)

# さいごに
なんか、記事が短くて物足りない感もありますが、本題が終わったのでこれくらいにしようと思います。
次回が気になる人は[目次](https://qiita.com/nonzu/items/73a39368855f3e1e0f28)をチェックすると更新されているかもしれません。
GO言語を使って自分のPCでWEBサーバー構築

モジュールについて学習している中、ここに来てプログラミング入門者である私に初めての課題が課せられました。自分のパソコンを使いWEBサーバーを立ててみて下さいというものでした。今まで動画や参考書に頼りっぱなしで、自分の力でなんとかするとなると、まず何からしていいのかさっぱりでした。まず、自分のパソコンをサーバーにするで検索をかけましたが知見が足りなすぎて、いろんなところを行ったり来たり。ヒントを頂き、Qiitaでなんとかそれらしき記事を発見！　早速作業にとりかかりました。GOには標準でHTTPパッケージが用意されているようで、自分のIPアドレスを使用し、ローカル環境で静的コンテンツを作ることができます。

```
mkdir HELLO
cd HELLO
```
では、ディレクトリ(コンピュータのファイルシステムにおいて、ファイルをグループ化するための特殊なファイルで、整理・管理する場所)をターミナル画面で作成していきます。

```
touch main.go
mkdir -p start/stylesheets
touch start/index.html start/stylesheets/style.css
```
エクスプローラー(ホームディレクトリ)に「HELLO」ディレクトリ(フォルダ)を作成し、その中にメインコードになる「main.go」とコンテンツ(結びつく内容)に当たる「start」ディレクトリ、その中には基本レイアウトである`HTML`「index.html」と装飾である`CSS`「stylesheets」ディレクトリ内の「style.css」をそれぞれ作成します。
###では、main.goから順にコーディングして行きましょう
![hellom.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/25357819-c904-1e46-ba9b-48294544a33a.png)

```main.go
package main

import (
	"log"
	"net/http"
)

func main() {
	fs := http.FileServer(http.Dir("start"))
	http.Handle("/", fs)
	log.Println("Listening...")
	http.ListenAndServe(":3030", nil)
}
```
変数fsにディレクトリを指定し、IPアドレスを利用するルーティング設定をする（"/"というアクセスがきたら「start」ディレクトリのコンテンツを表示）http.Handle は表示する「URL」と「URL」に対応する http.Handler を DefaultServeMux に登録する関数になります。Liten関数を使い３０３０通信用ポートを確保し、サーバーを立ち上げさせます。「start」ディレクトリは以下内容です。
![helloi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/423e189e-76ea-1e92-0e86-f1caec063d86.png)

```index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="/stylesheets/style.css">
  </head>
  <body>
    <h1>はじめまして!!!!!!</h1>
  </body>
</html>
```
外部リソースを指定する際に使用する「link」でモジュール(ここで言うと、main.go,index.html,style.css)の結びつけます。
![hellos.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/af6a69f8-1bca-7c11-c64c-c589adc03c82.png)

```style.css
body {color: #5f2bc0}
```
#main.goを動かしてサーバーを立ち上げてみましょう！

```
go run main.go
```
ターミナルでrunコマンドを叩き、enterキーで実行してみると。ブラウザ上で`http://192.xxx.xxx.xx(IPアドレスなど、ローカルホスト):3030/`にアクセスすると↓
![はじめまして.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/dee2a945-855c-869b-7b0f-03600181d95b.png)
「はじめまして!!!!!!」と表示されました。サーバー上では常に動き続けているので、消したい場合はターミナル上で`go run`のコマンドをCtrl(コントロール)＋Cでinterrupt(中断)すれば、止まります。
Ransackで全角半角跨いだの検索を行う

*600 Contributions達成記念*

# TL;DR
入力されたキーワードを加え、全角、半角バージョンを追加して、`_any`をつけて検索します。

```rb
User.ransack({name_cont_any: ['テストﾃｽﾄ123abC', 'ﾃｽﾄﾃｽﾄ123abC', 'テストテスト１２３ａｂＣ']})
```

# 全角<=>半角変換
## 英数字
### 半=>全
```rb
"abc123".tr('0-9a-zA-Z', '０-９ａ-ｚＡ-Ｚ')
=> "ａｂｃ１２３"
```

### 全=>半
```rb
"１２３ａｂＣ".tr('０-９ａ-ｚＡ-Ｚ', '0-9a-zA-Z')
=> "123abC"
```

## カタカナ
### 全=>半
```rb
require 'nkf'

NKF.nkf('-w -x -Z4', 'イロハ')
=> "ｲﾛﾊ"
```

### 半=>全
```rb
NKF.nkf("-w -X", "ｲﾛﾊ")
=> "イロハ"
```

# `OR`検索
こんなレコードがあると仮定します

```js
#<User id: 1, family_name: "実験", first_name: "花子", family_name_kana: "ジッケン", first_name_kana: "ﾊﾅｺ">
```

名前の仮名が全角か半角かは決められない場合、全ての`ハナコ`さんを検索したい場合、検索キーワードを上記の手法で全角１セット、半角１セットを用意して、下記のRansack述語(Predicate)で検索できます

```rb
User.ransack({ family_name_kana_or_first_name_kana_cont_any: ['ハナコ', 'ﾊﾅｺ'] }).result
  User Load (1.0ms)  SELECT "users".* FROM "users" WHERE (("users"."family_name_kana" ILIKE '%ハナコ%' OR "users"."family_name_kana" ILIKE '%ﾊﾅｺ%') OR ("users"."first_name_kana" ILIKE '%ハナコ%' OR "users"."first_name_kana" ILIKE '%ﾊﾅｺ%'))
```

# 参考

- [全角⇔半角の変換を行う（英数字、カタカナ）](https://www.yoheim.net/blog.php?q=20191101)
- [Ransackで簡単に検索フォームを作る73のレシピ - any - ORで繋ぐ(値が複数)](http://nekorails.hatenablog.com/entry/2017/05/31/173925#023-any---OR%E3%81%A7%E7%B9%8B%E3%81%90%E5%80%A4%E3%81%8C%E8%A4%87%E6%95%B0)
- [RubyでIntegerと文字を相互変換する](https://qiita.com/chezou/items/947900faef4c1032ed94)

# おまけ
[全角⇔半角の変換を行う（英数字、カタカナ）](https://www.yoheim.net/blog.php?q=20191101)で紹介された英数字の全半角変換アルゴリズムをRubyでアレンジしました。

```rb
# 半角英数字 => 全角英数字
"abc123".gsub(/[a-zA-Z0-9]/){|c| (c.ord + 0xFEE0).chr }
=> "ａｂｃ１２３"

# 全角英数字 => 半角英数字
"１２３ａｂＣ".gsub(/[ａ-ｚＡ-Ｚ０-９]/){|c| (c.ord - 0xFEE0).chr }
=> "123abC"
```
OpsWorks と Elastic Beanstalk の違い

## 勉強前イメージ

ansibleみたいな構成管理ツールと
Elastic Beanstalkはなんだっけ？

## 調査

### OpsWorks とは

ChefやPuppet を使って運用を自動化する構成管理のサービスで
システムの構成などを一元的に設定することができます。

詳細は [こちら]() をご確認ください

### Elastic Beanstalk とは

アプリケーションデプロイの自動化サービスで
運用管理などをAWSに任せてアプリをデプロイするだけでアプリケーションを動かすことが出来ます。

詳細は [こちら](https://qiita.com/miyuki_samitani/items/07f794f0d4e3c72803c5) をご確認ください

### 違い

- OpsWorks は `サーバの構成` を管理・デプロイするサービス
- Elastic Beanstalk は `アプリ` を簡単にデプロイするサービス

## 勉強後イメージ

ちょっと調べればわかったんだけど、
そういう管理ツールとかいっぱいあってややこしくて書いた

## 参考

- [[レポート]AWS Elastic Beanstalk, AWS OpsWorks, AWS CodeDeploy, AWS CloudFormation を使った自動デプロイ #AWSSummit](https://dev.classmethod.jp/articles/awssummit-tokyo-2015-ta-05/)
Rails 長い文字列を省略する方法

文字数が多くなると
当然横に大きく膨れてきます。
そこで制御するメソッドを書き記しておきます。


## truncateとは
文字数を切り捨て表示する

##参考資料
https://railsdoc.com/page/truncate


```java:app/viwes/hoge/index.html.erb
<%= "1234567890".truncate(5) %>
表示
12345...
```

`truncate`を使用することで文字数が制御できます！
【AWS＆Firebase】SESとTrigger Emailを連携してみた

どうもアッキーです。

毎日記事を更新しており、ついに１００個近くまで迫ってまいりました。

やっぱりアウトプットはいいですね。

と言うことで今回は、AWSのSESとFirebaseのTrigger Emailを連携させてみたいと思います。

SESでの設定は割愛します。

もしまだSESでの設定を行っていない方は以下の記事をご覧ください。

・[【AWS】AWS初心者がRoute53＋SES＋S3＋Lambdaを使って、独自ドメインに送られてきたメールをGmailに転送してみた](https://qiita.com/akki-memo/items/71cab2a38a0c5a6d904f)
・[【AWS】AWS初心者がRoute53＋SESを使って、独自ドメインでGmailからメールを送信してみた
](https://qiita.com/akki-memo/items/616671ccb009a0202113)

SESの設定が済んでいる艇で話を進めていきますのでご了承ください。

それでは参りましょう！

#認証情報の作成#

恐らくSESで既に設定を終えている方は、１度SMTPの認証情報を作成していると思います。

その時に、ユーザーネームとパスワードが表示されたはず。

忘れてしまった方は、これを機にもう一度作成しましょう。

ここで、問題なのがパスワードに``/``が入っている場合、**必ず**もう一度作成してください。

なぜかは後で説明します。

もう一度言います。

パスワードに``/``が入っている場合、**必ず**もう一度作成してください！

AWSのSESの画面へ行きh左のメニュー欄から``SMTP Settings``を開き``Create My SMTP Credentials``からSMTP認証情報を作成して下さい。

作成出来たらユーザー名とパスワードが表示されます。

一応認証情報をダウンロードしておきましょう！

#Trigger Emailの設定#

次に、[こちら](https://firebase.google.com/products/extensions/firestore-send-email?hl=ja)からTrigger Emailをインストールしてください。

インストールし終えたら、認証情報などの登録画面に行くと思うので下記の表を参考に認証情報の入力を行ってください。

|||
|---|---|
|Cloud Functions location|Tokyo (asia-northeast-1)|
|SMTP connection URI|smtp://**ユーザー名**:**パスワード**@email-smtp.<**SESの登録を行ったリージョン** 例：ap-northeast-1>.amazonaws.com:587|
|Email documents collection|mail|
|Default FROM address|info@example.com（メール送信するアドレスを入力）|

SMTP connection URIが少し見づらいと思うので以下のようになればOKです！

``smtp://ABSHSISIIS:mcsihHISCHISCq3292u48hd@email-smtp.ap-northeast-1.amazonaws.com:587``

ここで、先ほど注意したパスワードに``/``が入っていると認証情報正しく判定してくれません。

今一度、パスワードに``/``が入っていないかご確認ください。

その他にも３つ設定があると思うのですが、ここは後からでも変えれるので何もしなくてOK！

これで、メールを送信する準備は整いました。

後はCluudFirestoreでコレクションを追加してあげれば、自動的にメールが送信されます。

以下に例を載せておきます。

```index.js
const functions = require('firebase-functions')
const admin = require('firebase-admin')

// 省略

const db = admin.firestore()

exports.sendContactMail = functions.region('asia-northeast1').https.onCall(async (data, context) => {
  return await db.collection('mail').add({
    to: data.to,
    message: {
      subject: 'テストメール',
      html: `
        <h1>テスト</h1>
      `
    }
  })
})
```

こんな感じでCloudFunctionsから追加してあげるとメールが送信されます。

Firebaseからのメール送信はほぼ１００％で届きます。

開発段階で失敗したところを見たことがありません。

日本特有のau、docomo、softbankなどのキャリアメールにもしっかりと届きます。

ここで、エラーが出ている方は恐らく設定段階の``SMTP connection URI``が間違えている可能性が十分に高いです。

パスワードに``/``が入っていないか、URIに間違いないかをもう一度確認してみてください。

以上、「【AWS＆Firebase】SESとTrigger Emailを連携してみた」でした！

また、何か間違っていることがあればご指摘頂けると幸いです。

他にも初心者さん向けに記事を投稿しているので、時間があれば他の記事も見て下さい！！

あと、最近「ココナラ」で環境構築のお手伝いをするサービスを始めました。

気になる方はぜひ一度ご相談ください！

Thank you for reading
駆け出しエンジニア用！結構業務で出てくる単語③

## 対象
- 駆け出しエンジニア
- エンジニアになりたい

## 概要
これは実務未経験からエンジニアに転職し、日々わからない単語が出てくるので、そのメモとアウトプットです！
エンジニアを目指している方などはこういった知識を身につけておくと転職した際に役立つかと思います！！！
今回はプログラミングにはあまり関係なく知見といった感じです。

## オーソリって
オーソリゼーションの略です。
最近は決済周りの要件をまとめることが多いので結構頻繁に出てくる単語です。

"許可"だったり "承認"といった意味を持ちます。
例えば店舗で1万円のある商品をカードで買いたい！！
となったとします。
しかし、店舗ではそのカードが不正に利用されていないか？しっかりと決済できるカードか？
といったことはわかりません。

そこで決済する際に決済会社にしっかり使えるカードが確認をとる必要があります。(カードおの上限は残っているかなど)

ここで決済会社はカード利用枠の1万円分を確保します。
するとカード利用枠は1万円分ヘリ、これで決済が成立するわけです。

実際はもっと複雑みたいですが、ざっと理解するとこんな感じみたいです。

オーソリは第三者の不正利用を防いだり、ご利用可能額を確認する作業として極めて重要な作業です。
逆に言うとオーソリゼーションが失敗するとカードが利用できません、、、
といったことになるのです。

## 洗い替え
カードが使えない原因として、カードの有効期限が切れてしまっている。
といったことが挙げられます。

洗い替えとは一度登録したクレジットカードを期限などが更新されたタイミングで更新してくれる仕組みです。
よくあるのがサブスクリプションサービスなどで継続的な決済が必要な場合など。

登録しているカードが更新などで変更された場合に、非常に手間になります。
そこを解消してくれると言うことです

お疲れさまでした！
Vue.jsのカスタムディレクティブを理解する

## 前提知識
Vue.jsの基本的な知識

## カスタムディレクティブとは？
まずディレクティブとはv-ifとかv-forとかvのついたVue.jsの特有の属性です。
これはVueで予め決まっている物があるのですが、こちらを自分でカスタマイズできると言うことです！！！



## 早速やってみる
今回はHome.vueのコンポーネントを作る想定で行なっていきます。
Vue　cliを使用しています。

```components/Home.vue
<template>
  <p v-color>Home</p>
</template>
```

こんな感じで今回はv-colorといったカスタムディレクティブを作成していきます。

```main.js
import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false
Vue.directive("color", function (el) {
  el.style.backgroundColor = "red"
});

new Vue({
  render: h => h(App),
}).$mount('#app')

```

説明するとまずはVue.directiveと言うものが使えます。
第一引数にディレクティブ名をつけます。
今回はv-colorなので"color"を名付けています。

第２引数には本来はオブジェクトをとることができます。

```main.js
Vue.directive("color", {
  bind() {
    // ディレクティブが初めて対象の要素にひも付いた時、最初のレンダリング
  },
  inserted() {
    //親Nodeに挿入された時componentで言うmounted
  },
  update() {
    // コンポーネントが更新されるタイミングで、子コンポーネントが更新される前
  },
  componentUpdated() { 
    // コンポーネントが更新されるタイミングで、子コンポーネントが更新された後
  },
  unbind() {
    // ディレクティブの要素が削除された時
  },
})
```

本来であればこんな感じです。
この中でもよく使うのはbindとupdateです。

なのでこの二つは省略記法があります。
それがfunction()です。
Vue.directiveはデフォルトで第二引数にfunctionの関数を設定することで、bindとupdateを同じ処理で実行することができます。

```main.js
Vue.directive("color", function (el) {
  el.style.backgroundColor = "red"
});
```
ここには様々な引数が取れますがまずはelですelementはカスタムディレクティブがつく対象の要素を表します。

つまり今回はp要素です。
つまりp要素のbindとupdate時に背景色を赤にする。といったディレクティブになります。

次にもう一つbindingといった引数をとることができます。
こちらはv-colorからデータを引き継ぐことができます。

```Home.vue
<template>
  <p v-color="'blue'">Home</p>
</template>
```
v-colorの値をblueで設定していきます。
カスタムディレクティブの中は基本的にjavascript式になっているので、こちらはしっかりと文字列に直してあげましょう！

```main.js
Vue.directive("color", function (el, binding) {
  el.style.color = "1px solid red"
  el.style.color = binding.value
});

```

functionはbindingといった引数をとることができbinding.valueで参照するカスタムディレクティブの値のデータを受け取ることができます！！！


### 複数の引数をとる場合

```Home.vue
<template>
  <p v-border="{color: 'red', width: '300px'}">Home</p>
</template>
```
値をオブジェクトでとります！

```main.js
Vue.directive("border", function (el, binding) {
  el.style.border = "1px solid red"
  el.style.color = binding.value.color
  el.style.width = binding.value.width
});
```

そうするとbinding.value.オブジェクトのキーでデータを受け取ることができます！

## 引数をとる場合
カスタムディレクティブは引数をとる場合はv-border:引数のような形で引数が取れます。

注意点としてカスタムディレクティブは引数を一つしかとることができません。

```Home.vue
<template>
  <p v-border:dotted="{color: 'red', width: '300px'}">Home</p>
</template>
```
今回はdottedの引数にしていきます。

```main.js
Vue.directive("border", function (el, binding) {
  el.style.color = binding.value.color
  el.style.width = binding.value.width
  el.style.borderStyle = binding.arg
});
```
引数を受け取る場合はbinding.argで受け取れます！！

## カスタムディレクティブをローカル登録する
今までやっていたのはグローバル登録で、グローバル上で使えるようになっていました。
実はこれローカル登録もできて、コンポーネント毎に設定することもできます！

```Home.vue
<template>
  <p v-border:dotted="{color: 'red', width: '300px'}">Home</p>
</template>

<script>
export default {
  directives: {
    border(el, binding) {
      el.style.color = binding.value.color
      el.style.width = binding.value.width
      el.style.borderStyle = binding.arg
    }
  }
}
</script>
```

これで先ほどの状態と全く同じ動きをします。
directivesを設定してあとはborderの関数で引数をとるだけですね！！

お疲れさまでした！
コラッツの問題

[Longest Collatz sequence](https://projecteuler.net/problem=14)を解いたので、忘備録


#pythonによる回数計算

```python:collatz.py
def collatz(n, c = 1):
    if n == 1 : 
        return c
    else:
        c += 1
        return collatz(n // 2, c) if n % 2 == 0 else collatz(3 * n + 1, c)
```
10からスタートすると
10　→　5　→　16　→　8　→　4　→　2　→　1
と変化して、１になるまでの回数を計算する関数_collaz_

`collatz(10)`の結果は、`7`となる。
再帰を使っている割には動きはよくて、あとで１００００００回くりかえしてもなんとか動いた。

#１０００００までのうち一番多い回数を調べる。

##単純にやってみる
```python:bruteforce.py
def collatz(n, c = 1):
    if n == 1 : 
        return c
    else:
        c += 1
        return collatz(n // 2, c) if n % 2 == 0 else collatz(3 * n + 1, c)


def longest_collatz(n):
    i = 1
    l = []
    while i <= n:
        l.append(collatz(i))
        i += 1
    return (max(l), l.index(max(l))+1)

print(longest_collats(1000000))
```
ボーとして待っていると、回答がタプルで返ってくる。
pythonってすごいな。

##工夫してみる。
```python:use_dict.py
def l_collatz(n):
    d = {}
    colz=lambda x: x // 2 if x % 2 == 0 else 3 * x +1
    d[1] = 1
    for i in range(1,n + 1):
        k = 0  # 回数を初期化
        c = i
        while c not in d:  #　すでに数字がでていない場合
            k += 1
            c = colz(c)
        d[i] = k + d[c]  # 以前出てきた数字がきた場合、回数を足して終了
    return sorted(d.items(), key=lambda x:x[1])[-1]
    #  値で降順ソートして一番最初を返してる
print(l_collatz(1000000))
```

`lambda`や辞書を使って、いったん出てきた数字を辞書に格納してスピードアップしたもの

結構見やすく書けた

##もっと工夫してみる

```python:use_dict_list.py

def ll_collatz(n):
    d = {1:1}
    for i in range(1, n + 1):
        k = 0
        c = i
        l = []
        while c not in d:
            l.append(c)
            k += 1
            c = c // 2 if c % 2 == 0 else 3 * c + 1
        for idx,v in enumerate(l):
            d[v] = k - idx + d[c]

    return max(d, key=d.get)

print(ll_collatz(10000000))
```

いったん出てきた数字はすべて辞書にしてみた
速度はあまり変わらなかった・・・・
奇数の時にできる数が多くて、効率が悪くなっているような気がする。

#まとめ

再帰とか、辞書をなんとか使えるようになってきたのがいい感じです。
TypeScriptでデザインパターン[4.FactoryMethod]

# はじめに
Typescriptでデザインパターンをやっていくシリーズ（にする予定です）

結城 浩さんの「Java言語で学ぶデザインパターン入門」をTSに置き換えてTS力をあげていこうという趣旨です。

https://www.amazon.co.jp/%E5%A2%97%E8%A3%9C%E6%94%B9%E8%A8%82%E7%89%88Java%E8%A8%80%E8%AA%9E%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E5%85%A5%E9%96%80-%E7%B5%90%E5%9F%8E-%E6%B5%A9/dp/4797327030

前回はこちら
- [TypeScriptでデザインパターン[1.Iterator]](https://qiita.com/zackey2/items/2fa106a8d68455b34c41)
- [TypeScriptでデザインパターン[2.Adapter]](https://qiita.com/zackey2/items/6c2292b88ff9f0cb2c91)
- [TypeScriptでデザインパターン[3.TemplateMethod]](https://qiita.com/zackey2/items/8c8cfdc1726f4b0c5c58)

# メモ
- TSにはfinalがない
    - 継承させないようにするにはどうしたらいいんだろう？(2度目）
- FactoryMethodパターンの使い所
    - 複雑なインスタンス生成処理をカプセル化
    - インスタンス化前後の処理を強制
    - インスタンスの生成は子に任せる（[Wikipediaの例](https://ja.wikipedia.org/wiki/Factory_Method_%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3)）
    - そんなところか？ 抽象度が高すぎていまいちわからない。


# Code

```ts
namespace FactoryMethod {
  abstract class Product {
    abstract use(): void;
  }

  abstract class Factory {
    create(owner: string): Product {
      const p = this.createProduct(owner);
      this.registerProduct(p);
      return p;
    }

    abstract createProduct(owner: string): Product;
    abstract registerProduct(product: Product): void;
  }

  class IDCard extends Product {
    private owner: string;
    constructor(owner: string) {
      super();
      console.log(owner + "のカードを作ります。");
      this.owner = owner;
    }
    use(): void {
      console.log(this.owner + "のカードを使います。");
    }
    getOwner(): string {
      return this.owner;
    }
  }

  class IDCardFactory extends Factory {
    private owners: string[] = [];

    createProduct(owner: string): Product {
      return new IDCard(owner);
    }
    registerProduct(product: Product): void {
      this.owners.push((product as IDCard).getOwner());
    }
    public getOwners(): string[] {
      return this.owners;
    }
  }

  class Main {
    main() {
      const factory = new IDCardFactory();
      const card1 = factory.create("つざき");
      const card2 = factory.create("ふじいかぜ");
      const card3 = factory.create("ほしのげん");
      card1.use();
      card2.use();
      card3.use();
    }
  }
  new Main().main();
}


```
H - 1-9 Grid, C - 高橋君の給料, G - Longest Path

##[H - 1-9 Grid](https://atcoder.jp/contests/past202004-open/tasks/past202004_h)

O(N^2*11)
漸化式は、

```
i,j 現在の座標
i2,j2 前の座標
cost[i][j] = min(cost[i][j], cost[i2][j2] + abs(i-i2) + abs(j-j2))
```

```python:python
import sys
import math
import heapq
import itertools
from collections import deque
from functools import reduce

# main
def main():
    N, M = list(map(int, input().split()))
    A = []

    for i in range(0, N):
        row = str(input())
        A.append(row)

    graph = []
    for i in range(0, 11):
        graph.append([])

    for i in range(0, N):
        for j in range(0, M):
            if A[i][j] == 'S':
                v = 0
            elif A[i][j] == 'G':
                v = 10
            else:
                v = int(A[i][j])
            graph[v].append([i,j])

    INF = 10**12
    cost = []
    for i in range(0, N):
        cost.append([INF] * M)

    si, sj = graph[0][0]
    cost[si][sj] = 0

    for n in range(1, 11):
        for i, j in graph[n]:
            for i2, j2 in graph[n-1]:
                cost[i][j] = min(cost[i][j], cost[i2][j2] + abs(i-i2) + abs(j-j2))

    gi, gj = graph[10][0]
    ans = cost[gi][gj]
    if ans==INF:
        ans = -1
    print(ans)

            
# エントリポイント
if __name__ == '__main__':
    main()
```

##[C - 高橋君の給料](https://atcoder.jp/contests/abc026/tasks/abc026_c)

漸化式は、

```
0 (N+1以上)
1 (部下が0人)

部下が存在する場合の給料
min_v = 10**10　
max_v = 0
v = f(i)
min_v = min(min_v, v)
max_v = max(max_v, v)
return max_v + min_v + 1
```

```python:python
import sys
import math
import heapq
import itertools
from collections import deque
from functools import reduce

N = 0
child = []

def dfs(n):
    if n == N+1:
        return 0
    if len(child[n]) == 0:
        return 1

    min_v = 10**10
    max_v = 0
    for i in child[n]:
        v = dfs(i)
        min_v = min(min_v, v)
        max_v = max(max_v, v)
    
    return min_v + max_v + 1

# main
def main():
    global N, child
    N = int(input())

    for i in range(0, N):
        child.append([])

    for i in range(0, N-1):
        p = int(input())
        child[p-1].append(i+1)

    ans = dfs(0)
    print(ans)

# エントリポイント
if __name__ == '__main__':
    main()
```

##[G - Longest Path](https://atcoder.jp/contests/dp/tasks/dp_g)

O(N+M)

```python:python
import sys
import math
import heapq
import itertools
from collections import deque
from functools import reduce

N = 0
graph = []
indeg = []
length = []
done = []

def dfs(n):
    global length, done
    if done[n]:
        return length[n]

    for i in graph[n]:
        length[n] = max(length[n], dfs(i) + 1)

    done[n] = True

    return length[n]

# main
def main():
    sys.setrecursionlimit(1000000)
    global N, graph, indeg, length, done
    N, M = list(map(int, input().split()))

    graph = []
    for i in range(0, N):
        graph.append([])
    indeg = [0] * N
    length = [0] * N
    done = [False] * N

    for i in range(0, M):
        x, y = list(map(int, input().split()))
        graph[x-1].append(y-1)
        indeg[y-1] += 1

    for i in range(0, N):
        dfs(i)

    print(max(length))

# エントリポイント
if __name__ == '__main__':
    main()
```
useEffectとは

#useEffectとは

外部(APIなど)との通信や、DOMの直接的な更新等、関数の外のスコープに影響を与えるような処理は、副作用と呼ばれる。
Reactコンポーネントにおいて副作用を扱わなければならない場合、useEffectを使用して記述することが推奨されている。

```javascript

useEffect(() => {
    firebase.auth().onAuthStateChanged(user => {
        setUser(user)
    })
}, [])
```

第一引数には、副作用として実行する関数を与える。
useEffectに指定することで、副作用は、コンポーネントの描写が終わった後に実行される。

また、第二引数には、副作用を実行する頻度を設定することができる。
第二引数を与えなかった場合、コンポーネントの描写後、毎回実行される。
第二引数に配列を与え、要素として変数を指定すると、指定した変数に変更があった場合のみ実行される。
今回のように空の配列を与えた場合には、初回描写時にのみ実行される。

今回は指定の頻度で十分だった。無駄な処理を避けることを心がける。


#MEMO
副作用を有する可能性のある命令型のコードを受け付けます。

useEffect に渡された関数はレンダーの結果が画面に反映された後に動作します。副作用とは React の純粋に関数的な世界から命令型の世界への避難ハッチであると考えてください。

デフォルトでは副作用関数はレンダーが終了した後に毎回動作しますが、特定の値が変化した時のみ動作させるようにすることもできます。
kintone上でWebSpeechAPIを利用して音声認識して文字起こしする【動作確認編】

### 本記事を読むにあたっての注意点
動作実行を確認できる段階でのコードになります。
文字通り動作確認だけしたい、出来る確信を得たいという方はこちらの記事で十分かと思います。

記法の不統一、コーディングの不備不足、機能の少なさなどがございます。
実装可能なクオリティに仕上げたものは [kintone上でWebSpeechAPIを利用して音声認識して文字起こしする【改良編】](https://qiita.com/jhon931/items/69290377d8b3fb929ed8)で追記しておりますので、ご興味がある方は通して読んでいただけたらと思います。
本記事を参考にしつつあなた自身のコーディングをしていただけたら幸いです。


### 前提知識
- kintone
- JavaScript (kintone JavaScrip API)
- HTML
- WebSpeechAPI

### 実装後イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1233009/d03aacb6-ead0-d3e4-375b-c0539f1c24a6.png)

### プロセス
1. 録音開始、終了ボタンを設置
1. 認識した音声を表示させる\<input\>を設置
1. WebSpeechAPIを設定しボタンを機能させる（録音開始、録音終了、同時に文字起こし）
1. kintone JavaScript APIで、レコード保存するとkintoneのフィールドに文字列が転記させる

***
### コード全体
```js:WebSpeechAPI_on_kintone.js
(function () {
    "use strict";
    kintone.events.on("app.record.edit.show", function (event) {

        // start,stop ボタン生成
        const startButton = document.createElement("button");
        startButton.innerText = "録音開始";
        startButton.id = "start-btn";
        startButton.className = "recognition-buttons";

        const stopButton = document.createElement("button");
        stopButton.innerText = "録音終了";
        stopButton.id = "start-btn";
        stopButton.className = "recognition-buttons";

        // 文字起こし用<input>作成
        const tempForm = document.createElement("input");
        tempForm.id = "temp_input";
        tempForm.type = "text";
        tempForm.maxlength = "300";
        tempForm.value = "";
        tempForm.size = 129;
        kintone.app.record.getSpaceElement('form_space').appendChild(tempForm);

        // Web Speech API の設定 (SpeechRecognitionクラス)
        const SpeechRecognition = webkitSpeechRecognition || SpeechRecognition;
        const recognition = new SpeechRecognition();
        recognition.lang = "ja-JP";
        recognition.interimResults = true;
        recognition.continuous = true;

        let resultString = "";
        recognition.onresult = (event) => {
            let intermString = "";
            for (let i = event.resultIndex; i < event.results.length; i++) {
                let transcript = event.results[i][0].transcript;
                if (event.results[i].isFinal) {
                    resultString += transcript + " ";
                } else {
                    intermString = transcript;
                }
            }
            document.getElementById("temp_input").value = resultString + "<" + intermString;
        };

        // 録音ボタンの処理、ボタンの設置
        startButton.onclick = () => {
            recognition.start();
        };
        stopButton.onclick = () => {
            recognition.stop();
        };
        kintone.app.record.getSpaceElement('buttonSpace').appendChild(startButton);
        kintone.app.record.getSpaceElement('buttonSpace').appendChild(stopButton);
        return event;
    });

    // 保存実行前に一時保存から取得してフィールドに移す
    kintone.events.on("app.record.edit.submit", function (event) {
        let str = document.getElementById("temp_input").value;
        event.record.aaa.value = str;
        return event;
    });
})();
CMake でビルドしたあとにカスタムコマンドを実行するメモ

## 背景

CMake でターゲット(e.g. .exe, .so)がビルドできたらカスタムコマンドを実行したい.
実行できるかの確認, 簡単なテスト, .so の依存関係チェックなど
(add_test として実行するには適さないような処理)

## 方法

https://stackoverflow.com/questions/44212101/cmake-how-to-have-add-custom-command-run-after-all-project-files-are-built

`add_custom_command` + `POST_BUILD` でいけました.
(`add_custom_target` **ではない**ので注意)

### 注意点

`add_custom_command` の TARGET はカレントの CMake で定義したものでないとダメとあります.

https://cmake.org/cmake/help/latest/command/add_custom_command.html#build-events

関数でターゲットを処理するようなもの, たとえば pybind11 でモジュール定義(`pybind11_add_module`) とは組み合わせることができました.

```cmake
pybind11_add_module(mytarget sources.cc)

# OK
add_custom_command(TARGET mytarget POST_BUILD COMMAND mycmd VERBATIM)
```

また, 一旦ターゲットがビルドできた場合(e.g. ソースコードに変更なくて .exe, .so にも変更無い場合)にはポストビルドは実行されません.

したがって .exe に変更は無いが設定ファイルを変えて `make` しなおしてポストビルドをトリガーするというのはできないです.

毎回トリガーしたい場合は, `ALL` ターゲットに追加するか, もしくは `add_custom_target(mytest ...)` で `make mytest` などとして明示的にコマンド呼び出しするしかなさそうです.

## おまけ

.so に依存したファイルを, dest 先のファイルが変更しているときだけコピーするみたいなのは `-E copy_if_different` と組み合わせて実現できます.

```cmake
    # Copy libc++.dll
    add_custom_command(TARGET mymod POST_BUILD        # Adds a post-build event to MyTest
        COMMAND ${CMAKE_COMMAND} -E copy_if_different  # which executes "cmake - E copy_if_different..."
            "${LLVM_MINGW_ROOT_ABSPATH}/x86_64-w64-mingw32/bin/libc++.dll"      # src
            $<TARGET_FILE_DIR:mymod>)           # dest
```
KotlinでFirestoreのTimestampをDate型に変換

Firestoreで取得したTimestampを、Kotlinで扱うためにDate型に変換します。
簡単です。

```Kotlin:MainActivity.kt
//FirestoreのドキュメントからTimestampデータを取り出す
val firebase_timestamp = document.data["timestamp"] as com.google.firebase.Timestamp
//Date型へ変換する
val date = firebase_timestamp.toDate()
[memo] QR コードで Wi-Fi のアクセスポイント設定するやつ

# QR コードで Wi-Fi のアクセスポイント設定するやつ

Wi-Fi の接続情報を QR コードで表すのには、いろいろな(独自)仕様があるみたいなので、メモ。

## ZXing の Wi-Fi 接続用 QR コード

```
WIFI:S:(SSID);T:(タイプ);P:(暗号キー);;
```

※コロンとセミコロンが混在しているので注意

タイプは以下のどれか。

* `WEP`
* `WPA`

最近は、いろいろなところで同じ形式が使われているみたい。
ZXing 独自形式が広まって使われているのだと思っていますが、もしかしたらどこかの共通的な形式なのかも。

* アプリ版（ライブラリ版）
  * https://github.com/zxing/zxing
  * アプリ版では、タイプに `WPA2` (たしか `WPA`と同じ意味)とか `WPA2_EAP` とか `nopass` (?) もあった気がする

* 作れるページ
  * https://zxing.appspot.com/generator
  * 上記ページでは Hidden? にチェックを入れると `H:true` というのが付くみたい。SSID ステルス対応なのかな？ `WIFI:S:(SSID);T:(タイプ);P:(暗号キー);H:true;;`
  * パスワード無しも作れる `WIFI:S:(SSID);;`
  * たまに SSID がダブルクォーテーションでくくられる。よくわからん。

* 同じ形式で使えるもの
  * Android の標準機能
  * iOS11以降の標準QRリーダー（標準カメラ）
  * ロボットのSota ? https://sota.vstone.co.jp/home/wi-fi_qrcode/
  * UQ WiMax2 のらくらくQR ?

## Buffalo の「セットアップカード」、QRSetup

```
S=(SSID)
KA=(暗号キー)
E=WPA2PSKAES
M=(MACアドレス/BSSID)
P=(プロダクト名)
```

多分、こんな感じ。

`E=` のところに、ほかのものがあるかどうか不明（上記は ZXing の `WPA` に当たるのだと思う）

* 作れるページはなさそう

## IOデータの「QRコネクト」

```
WI:
SS:(SSID)
EN:(タイプ)
PA:(暗号キー)
```

タイプは以下のどれか

* `WPA`
* `WEP`
* `NONE` - この場合には暗号キーは空を指定

* 作れるページ
  * https://wssl.iodata.jp/qr_code/index.html

## Aterm の「らくらくQRスタート」

暗号キーなどを暗号化してあるらしい

* 作れるページ
  * https://display.qr.aterm.jp/cgi-bin/qr_me_create.cgi
  * ただし、作れるのは初期値（工場出荷時の値）だけらしい

Aterm の機器が手元にないので、QR コードをつくれず詳細は不明

## アララ/デンソーの「QR WI-FI」

有効期間の設定や、アクセス解析も可能
専用アプリが必要らしい

* 作れるページ
  * https://m.qrqrq.com/
(Rails)画像投稿機能[refile refile-mini_magick]

#前提

- `ImageMagick`インストールしておいてください

```ruby:Gemfile
gem "refile", require: "refile/rails", github: 'manfe/refile'
gem "refile-mini_magick"
```
Gemfileに記述後
`$ bundle install`します。


```ruby:
<h1>画像投稿フォーム</h1>
<%= form_with model: @post, local:true do |f| %>
  <h4>画像</h4>
  <%= f.attachment_field :image %>
  <%= f.submit '投稿' %>
<% end %>
```
`f.attachment_field`使うことで投稿できるようになります。
#modelを追加
```ruby:post.rb
  attachment :image 
```
`_id`を抜いた部分を記述します。

#画像表示
```ruby:posts/show.html.erb
<%= attachment_image_tag @post, :image, format: 'jpeg', fallback: "no-image-icon.jpg", size: "120x120" %>
```
画像がなかったら`fallback: "no-image-icon.jpg"`を表示する。
`image`フォルダーに適当な画像を入れる。
FirebaseMessagingのトークンを取得する際のエラー解消方法

# エラー

Firebaseのチュートリアルを進めていると、クライアントアプリのインスタンスの登録トークンを取得するステップにあたります。

https://firebase.google.com/docs/cloud-messaging/android/client?hl=ja#retrieve-the-current-registration-token

チュートリアルでは以下の記載があります。
>現在のトークンを取得する必要がある場合は、FirebaseMessaging.getInstance().getToken() を呼び出します。

同じくチュートリアルでは、kotlinの場合のコード例が紹介されています。

```kotlin:
FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->
    if (!task.isSuccessful) {
        Log.w(TAG, "Fetching FCM registration token failed", task.exception)
        return@OnCompleteListener
    }

    // Get new FCM registration token
    val token = task.result

    // Log and toast
    val msg = getString(R.string.msg_token_fmt, token)
    Log.d(TAG, msg)
    Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
})
```

ただし、これをこのまま貼り付けると、`OnCompleteListener`が未定義だの`TAG`が未定義だの`msg_token_fmt`が未定義だの怒られてしまいます。

# 解決方法

これを解消するには、まず以下のようにいくつかimportします。

```kotlin:
import android.util.Log
import com.google.firebase.messaging.FirebaseMessaging
import com.google.android.gms.tasks.OnCompleteListener
```

次に、変数LOGを宣言します。

```kotlin:
var LOG = "MyLog"
```

ここまでをまとめると、例えば[AndroidDeveloperのチュートリアルアプリ](https://developer.android.com/training/basics/firstapp?hl=ja)を作っていた場合は、次のようになります（Toastは省略）。

```MainActivity.kt
package com.example.myfirstapp

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

//いろいろimport
import android.util.Log
import com.google.firebase.messaging.FirebaseMessaging
import com.google.android.gms.tasks.OnCompleteListener

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 変数
        var TAG = "MyLog"

        // トークン
        FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->
            if (!task.isSuccessful) {
                Log.w(TAG, "Fetching FCM registration token failed", task.exception)
                return@OnCompleteListener
            }

            // 新しい登録トークンを取得
            val token = task.result

            // ログに出力
            val msg = getString(R.string.msg_token_fmt, token)
            Log.d(TAG, msg)
        })
    }
}
```

また、`msg_token_fmt`のエラーについては、`res/values/strings.xml`を開き、以下のようにします。

```strings.xml
<resources>
    <string name="app_name">My First App</string>

    //これを追加
    <string name="msg_token_fmt" translatable="false">FCM registration token: %s</string>
</resources>
```

これで無事アプリが実行され、Logcatにトークンが出力されます。
【cloud9 特によく使うショートカットキー12選（mac）】

#はじめに#

ショートカットキーは非常に便利。
だけど、使うモノによってコマンドが異なる。

今までVScodeを使っていて、cloud9でも同じコマンドを打った時、
全然違うアクションが行われてしまうことがあったので、
今回はcloud9で個人的に特によく使うショートカットキーだけ並べる。

#cloud9　特によく使うショートカットキー12選#

| ショートカットキー | アクション |
|:-:|:-:|
| ⌘ + C |  コピー |
| ⌘ + X |  切り取り |
| ⌘ + V |  貼り付け |
| ⌘ + D |  横一行削除 |
| ⌘ + S |  上書き保存 |
| ⌘ + Z |  操作一つ戻す |
| ⌘ + Y |  操作一つ進む |
| ⌘ + F | 検索  |
| ⌘ + R |  リロード（主にプレビューページで使用） |
| ⌘ + alt + ↑↓  | 横一行を矢印方向にコピー  |
| tab | インデント字下げする  |
| ctl + @ | インデント字上げする  |
ArduinoIDEのシリアルプロッタの縦軸(y軸)を固定する

みんな大好きArduinoIDEのシリアルプロッタ．

取得してきたアナログ値をグラフで表示してくれる便利な機能なのですが，デフォルトでは取得値ごとに縦軸が自動で縮小拡大してしまいグラフの概観を知りたい時に不便だなと思い，どうにかして解決する方法を考えてみました．

結論から言うと，ゴリ押しプレイなので優しく見守っていただければ幸いです．
（強い人は自分で縦軸固定したグラフ書けるように組んじゃうのが良いかと思います）

#センサ値と定量値*2をカンマで区切る
センシングした値がぶれることによって縦軸が移動するのであれば，センシングした値とは異なる2つの定量値のデータを一緒に表示しちゃえばいいじゃない（上端と下端を固定しよう）というのが今回の解決策になります．もっとスマートな方法があると思うんですけど，とにかく今回は動けば良いということでこのような方法にしました．

```C++:SerialTest.ino
/*
20210324作成
とあるセンサのセンシングテスト
シリアル通信でアナログ値を取得してきてシリアルプロッタに表示する
*/

//取得してくるアナログ値
int value = 0;
//上端
int up = 800;
//下端
int down = 0;

void setup() 
{
  //AOをINPUTにする
  pinMode(A0,INPUT);
  //シリアル通信開始
  Serial.begin(9600);
}

void loop() 
{
  //アナログ値をセットする
  value = analogRead(A0);
  Serial.print(value);
  //カンマで区切る
  Serial.print(",");
  Serial.print(up);
  //カンマで区切る
  Serial.print(",");
  Serial.print(down);
  //改行
  Serial.println("");
  delay(50); 
}
```
カンマで区切ることによってIDEが異なるデータのグラフとして認識してくれるので，それを利用してずっと同じ値を表示し続けて上端と下端を固定しています．あとは自身が取得したいアナログ値によってupやdownなどの数値を変えていただければ．

#シリアルプロッタを起動してみる
上記のプログラムをお手持ちのマイコンに書き込んだ後，ツール>シリアルプロッタを起動すると上端がup下端がdownに固定されたグラフとセンシングしてきたアナログ値が表示されていると思います．
![スクリーンショット 2021-03-24 16.29.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540710/8b873abd-5270-adae-a8f1-8989e6dc5495.png)

以上になります．
大したことはしてないですが，ちょっとしたTipsとして活用してもらえたら嬉しいです．
何か質問などがあればTwitterのDMなどでご連絡いただければ幸いです．
stringやnumberがtruesyかfalsyかでbooleanを代入したい時

stringやらnumberやらがtruesyかfalsyかでbooleanを代入したい時があると思うが、
そういう時に

```typescript
if (str) {
  object.bool = true
} else {
  object.bool = false
}
```
とか

```typescript
object.bool = str ? true : false
```
と書くのがとても煩わしく感じた。

これは、実は

```typescript
object.bool = !!str
```
これで対応できる。

## しくみ
特別な構文を使っているとかそういうわけではない。

```typescript
!str 
```
こう書くと「””」ならtrue、「"hoge"」ならfalseになる。
それをさらに反転しているだけ。

```typescript
!!str 
```
「””」なら!true、つまりfalseが取れるというわけ
Laravel6 + Vue-CLI + Vue-Router 最短SPA構築

#はじめに
Laravel6とVue-CLIで手軽にSPAを開発したかった。
元のディレクトリ構成をいじらずに簡単に出来るようにしたかった。
Vue-Routerの初期設定ではURLに「/app」が付いてしまうので、これを排除したかった。
VuetifyがまだVue3に対応していないのでVue2にて作成。
自分用にやり方をまとめる。

#参考
https://qiita.com/bokuranokyo/items/1b14852c09395bf99941

https://tech.cydas.com/entry/vue-laravel-mspa1

#やり方
<h3>１．Laravel6のインストール</h3>
コマンドプロンプトにて

```
composer create-project laravel/laravel test "6.*"
```
<h3>２．Vue-CLIのインストール</h3>
Routerの選択を忘れずに。

```
cd test
npm install -g @vue/cli

vue create frontend

? Please pick a preset……
>Manually select features

? Check the features needed for your project……　
 (*) Choose Vue version
 (*) Babel
 ( ) TypeScript
 ( ) Progressive Web App (PWA) Support
>(*) Router   //Router選択
 ( ) Vuex
 ( ) CSS Pre-processors
 (*) Linter / Formatter
 ( ) Unit Testing
 ( ) E2E Testing
 
 Choose a version of Vue.js that you want ……　
> 2.x

以下すべてEnterキー。
```

<h3>３．vue.config.jsファイルの作成</h3>
test\frontendフォルダ内に、以下の内容のvue.config.jsを作る

```test\frontend\vue.config.js
module.exports = {
    outputDir: '../public/app',
    publicPath: '/app',
    pages: {
        index: {
            entry: 'src/main.js',
            template: 'public/index.html', 
            filename: '../../resources/views/index.blade.php',
        },
    },
};
```
<h3>４．Vue-RouterのベースURL設定</h3>

```test\frontend\src\router\index.js
const router = new VueRouter({
  mode: 'history',
  base: "/",  //書き換え
  routes
})
```

<h3>５．Laravelのルート設定</h3>
```test\routes\web.php
<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/{any?}', fn() => view('index'))->where('any', '.*');
```

<h3>６．ビルドで完成</h3>

コマンドプロンプトにて

```
cd frontend
npm run build 
```
完成です。

#まとめ
簡潔ですが、やり方をまとめました。
最後までご覧いただきありがとうございます。
[Rails]CSV生成処理をモデルで書いてるけどそれって正しいの？

# 概要

CSV生成処理をモデル側で書いてる案件をよく見ます。
※実際にはエスケープ処理なども必要ですが、今回は簡略化してます。

```ruby:app/models/user.rb
class User < ApplicationRecord
  def self.build_csv
    csv = ["氏名,ニックネーム,電話番号"]
    all.map do |user|
      row = "#{user.full_name},#{user.nickname},#{user.phone_number}"
      csv << row
    end

    csv.join('\n')
  end
end
```

今回は↑の設計に疑問を投げかける投稿です。

# これの何処が問題なの？

自分なりに、上記の様なCSV生成処理をモデル側で書く設計の違和感について解説していきます。

### MVC の観点から見た違和感

Rails は MVC モデルのフレームワークです。
MVC において、クライアントへの最終的な出力はViewの役割であり、今回のケースで言うと、CSVの中身がクライアントへの最終的な出力( == Viewの責務)であると考えられます。
このことから、MVC の観点から言うとCSV生成処理はView層でやるのが妥当ではないかと考えられます。


### この設計で実際のところどんな問題が起きるの？

設計の話はどうしても抽象的でイメージがしづらいので、「こういうときに困るだろうな」という例を上げてみます。

例えば、以下のような要望が来たとしましょう
・管理画面でユーザー一覧のCSVをダウンロードしたい
・出力内容は `氏名,ニックネーム,電話番号`

そして、モデル側にCSV生成処理を書きます。(記事最上部のコードと全く一緒です。)

```ruby:app/models/user.rb
class User < ApplicationRecord
  def self.build_csv
    csv = ["氏名,ニックネーム,電話番号"]
    all.map do |user|
      row = "#{user.full_name},#{user.nickname},#{user.phone_number}"
      csv << row
    end

    csv.join('\n')
  end
end
```

そして、後から以下のような要望が来たとします。
・一般ユーザーもユーザー一覧CSVをダウンロードできるようにしたい
・CSVダウンロードボタンは、一般ユーザー向けのユーザー一覧画面に設置したい
・個人情報は漏らしてはいけないので氏名は「○○」、電話番号は最初の2桁だけ表示してのりは伏せ字にしたい。
・ニックネームはそのまま表示したい

↑こういった要望が追加されると、修正方法としては
1. `self.build_csv` メソッドに `for_admin` の様なフラグ変数を引数として渡して `self.build_csv` メソッド内で分岐する
2. `self.build_csv_for_general` のようなメソッドを追加して、一般向けCSVの生成はこちらのメソッドに任せる

のどちらか2択になるかと思います。

1は、フラグ変数で表示を分岐してるので、内部の処理が複雑化したり、一般向けCSVに個人情報が漏れ出す不具合が起きそうで不安です。

また、2は User モデルのCSV種類が増えるたびにメソッドが増えていき、fat model になりそうです。

# モデルで書くのが良くないなら、何処で書けばよいの？

自分はCSV生成処理はView側で書くようにしてます。

~~勝手に~~ [こちらの記事](https://qiita.com/Syojsyo/items/ac9e58ac9d9ded2603d7) を参考にさせていただきました。ありがとうございます。

まずは、上記要望の管理者向け CSV を実装していきます。
コントローラ側では、CSV出力用のViewを呼び出して、 `send_data` でファイルを返す処理を書きます。

```ruby:app/controllers/admins/users_controller.rb
class Admins::UsersController < ApplicationController
  def download
    @users = User.all
    send_data render_to_string, filename: "users.csv", type: :csv
  end
end
```

そして、CSVの内容はView側で行います。

```ruby:app/views/admins/users/download.csv.ruby

csv = ["氏名,ニックネーム,電話番号"]
@users.map do |user|
  row = "#{user.full_name},#{user.nickname},#{user.phone_number}"
  csv << row
end

csv.join('\n')
```


次に、上記一般ユーザー向け CSV を実装していきます。

```ruby:app/controllers/users_controller.rb
class UsersController < ApplicationController
  def download
    @users = User.all
    send_data render_to_string, filename: "users.csv", type: :csv
  end
end
```

そして、CSVの内容はView側で行います。
一般向けなので本名、電話番号は伏せて出力します。

```ruby:app/views/users/download.csv.ruby

csv = ["氏名,ニックネーム,電話番号"]
@users.map do |user|
  row = "○○,#{user.nickname},#{user.phone_number[0..2]}X-XXX-XXXX"
  csv << row
end

csv.join('\n')
```

これで一般向け、管理者向けCSV生成処理をView側で実装できました。


# 最後に

今回は設計寄りの話をしました。
設計には正解がないので、自分の実装案が必ずしも正解とは限りませんし、案件によってはモデルに実装したほうが良いケースももしかしたらあるかもしれません。

大事なのは **一度立ち止まって「この処理はこの箇所で実装するべきか」をしっかり考えること** だと思います。
考えた上で「CSV生成処理をモデルで書こう」という結論が出たなら、それはそれで一つの回答ではないかと思います。
Dockerエラー：Syntax error - can't find = in "RUN" の解決策



Dockerビルド中に起きたエラーの解決策です。

#エラー内容
```
$ docker-compose build
failed to solve with frontend dockerfile.v0: failed to create LLB definition: Syntax error - can't find = in "RUN". Must be of the form: name=value
```
どうやら "RUN" で Syntax error が起きている様子。


#問題となったDockerfile

```
FROM node:12.5.0-alpine

WORKDIR /app

ENV LANG=C.UTF-8 \
    TZ=Asia/Tokyo

RUN apk update && \
    apk upgrade && \
    npm install -g n && \
    npm install -g create-nuxt-app && \
    yarn install &&\
    rm -rf /var/cache/apk/* \   ← 改行が入っている！

ADD . /app
~                   
```


#問題が解決されたDockerfile

```
FROM node:12.5.0-alpine

WORKDIR /app

ENV LANG=C.UTF-8 \
    TZ=Asia/Tokyo

RUN apk update && \
    apk upgrade && \
    npm install -g n && \
    npm install -g create-nuxt-app && \
    yarn install &&\
    rm -rf /var/cache/apk/*　　　 ← 改行を消しました！

ADD . /app    ​
```

```
$ docker-compose build
[+] Building 30.1s (10/10) FINISHED  
 => (中略)
Successfully built 999eaa37e4901ef302ab6634715b5a0bc0829b8c9eec7dbcb05a3f4d1ed84bff
```
無事に通った。基本的なことを大事にしていきたいです。
.envファイルをつくった時に気をつけたい事

apiを叩くときにapikeyを隠すために.envファイルを作成すると思います。
（gitで管理されないようにするため）

その際、一度再起動しないとエラーになります。
僕はそれでしばらく悩みました。。。（ググったら同じ悩みの人がいてすぐ解決案を知れました）
なので

.envファイルを作成→apikeyを設定→.gitignoreに.envを記述→「再起動」

この手順でやりましょう！

またNetlifyでデプロイする際も注意が必要です。
.gitignoreでgitから管理されてない状態のため、環境変数を設定しないといけないです。
またここでしばらく悩みました。。。

deploysetting→Build&dploy→Environment variables

ここでkeyとvalueを設定できます。するとデプロイできるかと思います


最後に

エラー発生した際はググることももちろん大切ですが、時間を掛けすぎるのもよくないかなと思います。
身近に質問できる環境を作ることをお勧めします！
【FileMaker】"URL から挿入"でエラーコード102が返る時に読んでね

お題のとおり、"[URL から挿入](https://help.claris.com/ja/pro-help/content/insert-from-url.html?Highlight=URL%20%E3%81%8B%E3%82%89%E6%8C%BF%E5%85%A5)"ステップでエラーコード102が返って、「なんのこっちゃ？」と思って検索した時に辿り着いたあなた、私も同じ思いをしました。

[エラーコード](https://help.claris.com/ja/pro-help/content/error-codes.html)：102は、「フィールドが見つかりません」です。

スクリプトで、こう、書いてませんか？
![スクリーンショット 2021-03-24 17.48.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/c39f79f8-5d2a-5674-93c7-62bceaf3d08c.png)
ターゲットにフィールドを設定しているパターンです。
これはこれで間違いではありません。
正しいのですが、ヘルプにもある通り、このターゲットフィールドは **実行している最中のレイアウト上に存在** する必要があります。
ヘルプから抜粋してみましょう。
![スクリーンショット 2021-03-24 17.50.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/32b28946-47cf-724e-913d-e90b5982467b.png)

ヘルプにさら〜っとしか書いていないので見落としがちですが、ここは要注意です。
変数であれば、宣言されていない場合でも自動で作成されて実行結果がセットされるので、以下の書き方はいかがでしょうか。
![スクリーンショット 2021-03-24 17.53.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/61ef5bcd-2279-aa40-c53a-4260b7d6a334.png)

もしくは、レイアウト外にターゲットフィールドを設置する、でもいいと思いますが、うっかり消されないように。。。
![スクリーンショット 2021-03-24 17.58.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/fb6f27af-3ea1-b420-dbdc-950b461d7dd6.png)

これで解決しましたか？
OpenCVのソースにMotion JPEGのストリーミングを利用する

##はじめに
庭に来る野鳥の監視カメラが作りたかったんですが、darknetで鳥検出を行う都合上、画像処理は屋内、カメラのみを屋外に置く必要がありました。
MJPEG-Streamerや、ESP32CAMなどを屋外に置き、屋内のPCでOpenCVなどを利用して画像処理を行う方法について記載しています。

##やったこと
具体的には屋内のJetson Xavier NXでdarknetを動かして鳥検出を行っています。
この画像ソースとしてGStreamerのsouphttpsinkを利用して外部のMotionJpegのストリーミングを利用しました。
分かれば単純なんですが、これを見つけるまでが大変だったので、備忘録として。

##GStreamer
[GStreamer](https://gstreamer.freedesktop.org/ "GStreamer")はオープンソースの画像処理のフレームワークです。

##OpenCV
OpenCVの画像入力には、通常は
cv2.VideoCapture( SRC )
を用いて処理する画像を1フレームずつ取得します。
Jetson上では、SRCに数字を入れると、カメラを番号で指定してフレームを取得できます。
FILEPATHを指定することで動画ファイルをソースとすることができます。
ここのGStreamerのパイプラインを指定する文字列を指定することで、GStreamerで処理後の画像をソースとすることができます。

##souphttpsrc
[souphttpsrc](https://gstreamer.freedesktop.org/documentation/soup/souphttpsrc.html?gi-language=c "souphttpsrc")はgstreamerのソースとしてHTTPサーバからストリーミングされたデータを利用します。

##成果物

```
ｃｖ2．VideoCapture( "souphttpsrc location=http://192.168.1.39:8081/stream ! image/jpeg,width=800,height=600,framerate=1/1 ! queue ! jpegdec ! videoconvert ! appsink" )
```
http://192.168.1.39:8081/stream
がストリーミングのURLとなりますのでここを環境に合わせて変更してください。
当然ながらユーザインターフェースなしの動画部分のURLである必要があります。