OmniAICreator/Qiita-1.07M huggingface dataset:
WebApiGoodpartsを読んでる


# 不要なエンベロープ
APIのレスポンスデータとして、こんなレスポンスがよくある

```json
{
    header {
        status:1,
        errCode:0
    },
    body {
        ...実際のデータ...
    }
}
```
ここで記載している「header」や「body」というのをエンベロープと呼ぶ。
エンベロープは日本語では「封筒」と呼ぶみたい。
同じデータ構造を返すために実際のデータをくるむことを目的としたデータ構造を指す。
で、このエンベロープは不要とのこと。

APIのレスポンスは利用者側からは仕様として既知であり、その情報がheaderにあろうがbodyにあろうが使用したいパラメータはわかるので、余計な構造が1枚挟まれているだけの状態になっているからだと。

こういった形で実装しそうだったから気をつけよっと。

# APIで返す日付
## フォーマット
APIで返す日付のフォーマットはRFC3339が良いとのこと。
こんなフォーマット。
20018-11-13T12:23:30+09:00
RFC3339はインターネット上で用いる標準形式でもあるとのこと。

自身が作るAPIが何に使われるかによって決めるのがベストかな。

プログラム内で時間操作感はどうなんだろ。
変換のライブラリが用意されてればいいんだけどさくっと検索じゃ見つからなかった。

## タイムゾーン
日本向けに公開するなら、"+09:00"つけてもいいけど、インターネットは全世界とつながってるのでUTC標準時の方が良い。
これも対象とするプロダクトによって判断するか。


# エラーの表現
## ステータスコードで表現
エラーの表現はまずステータスコードで表現すること。
200:成功
300:リダイレクト
400:クライアントサイドに起因するエラー
500:サーバーサイドに起因するエラー
状況に合わせてこれらのステータスコードを使い分ける。
書くステータスコードにも細かく番号が分かれているので、それを使い分ける。
どこにも当てはまらなければ、400や500などざっくりした表現を使うのは有り。

ダメな例として、200でレスポンスしているにも関わらず、レスポンスデータは内部の判定ロジックでパラメータエラーを判定しその内容を返しているみたいな状態はNG。

http://www5.plala.or.jp/vaio0630/mail/st_code.htm

こういうのも眺めておきたい。

# HTTPの仕様を理解しておく
## 通信料の節約
キャッシュを利用する。
キャッシュは期限切れモデルと検証モデルの2パタンでサーバーから最新データを取得するかを判断する仕組みが存在する。

### 期限切れモデル
有効期限や現在日時からの経過時間を設定し、その時間間隔を判定して最新情報を取得する場合に使用する。

### 検証モデル
サーバーの情報が変更されたかを判定して最新情報を取得する場合に使用する。
現在に日時やコンテンツ量から生成したハッシュ値を用いることが多い。

どちらを使うかは実装次第。
天気予報とか、ある程度の時間軸ないで変化しないものは期限切れモデルがよさそう。
検証モデルはコンテンツの変更が頻繁に行われるものがいいかな。
最新情報のニュースを配信するサイトとか、不定期に更新される系かな。

もちろん明示的にキャッシュさせたくない場合にも、制御の仕組みは要されている。

# API内での別ドメイへのリクエスト
特定のwebページ内から、別ドメインへのリクエストは仕様上許可されていない。
この許可されてない状況に条件付きで許可できる仕組みがCORS(Cross Origin Resource Sharing)

- ①web画面(https://a.com)
- ②別ドメイン(https://b.com)  
  
①のページ内で②は呼び出せない。これが前述した仕様上の制限。
これを回避するために、①のレスポンスヘッダーでアクセス許可するURIを定義しておけば、②のAPIも実行できるという形になる。

web画面側を実装する際に必要な知識になるかな
利用シーンは多そう。

# 学びから実装での考慮すること
- 不要なネスト(エンベロープ)は実装しないようにしよう
- 通信料を考慮し、少ない情報で的確な情報を返せるようにしよう
- HTTPのレスポンスコードを適切に使って、「一般的に」使われることを考慮した設計とし、だれが利用しても想定が付くような状態のリクエスト,レスポンスを設計しよう
【Cassandra】ディストリビューション (随時更新)

# Cassandraについて
(もともとは) FacebookのAvinash LakshmanとPrashant Malikが開発した分散データベースで、2008年にOSSとして公開されたもの

ディストリビューションやバージョンごとの差異が大きいので、既存ドキュメントやコンテンツ情報を活用する場合はかなり気をつけないといけない。

# ディストリビューション

### Apache Cassandra
- コミュニティ版のCassandra ( http://cassandra.apache.org/ )
- 最新バージョンは4.0.0 ( 2021/07/26 )
- 最新の安定バージョンは3.11.10 ( 2021/02/01 )
- 3.0 ( 旧バージョン ) の最新は 3.0.24 ( 2021/02/01 )
- 2.2 ( 旧バージョン ) の最新は 2.2.19 ( 2020/11/04 )
- 2.1 ( 旧バージョン ) の最新は 2.1.22 ( 2020/8/31 )

### DSE ( DataStax Enterprise )
- Datastax社が提供、サポート
- 2021/07/27時点の最新バージョンは6.8.14 
- リリースノート 
( https://docs.datastax.com/en/dse/6.8/dse-admin/datastax_enterprise/releaseNotes/RNdse.html )
- DDACとの差異については[DATASTAX社の説明ページ](https://www.datastax.com/products/offerings)の下の方の表を参照
GitHubユーザーなら60秒で作成できるプレゼン資料


PowerPointを使わずにスライドを作成したいと思ったことはないでしょうか？[GitPitch](https://gitpitch.com/)というサービスを使うと、GitHub上で、MarkDown形式で記述するだけで、PowerPointのようなプレゼン資料(スライド)を簡単に作成し、公開することができます。

## 最も簡単なプレゼンの作成手順

1. (前準備)GitHubのアカウントがない場合は作成しておきます。

2. [GitPitch In-60-Seconds for GitHub Users](https://github.com/gitpitch/in-60-seconds)にアクセスし、[Fork]ボタンをクリックして、フォーク(自分のリポジトリ内に複製)します。　
<img width="775" alt="Untitled.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331144/c58c6d8e-3c66-bbb6-ce77-29d5ede88352.png">

3. フォークしたリポジトリ内の、README.mdの右側、鉛筆アイコンをクリックして、編集モードにします。 
 <img width="406" alt="Untitled.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331144/ce345e6f-8654-4093-cac7-6720989ec759.png">

4. 一番上の```https://gitpitch.com/gitpitch/in-60-seconds```となっている箇所を```https://gitpitch.com/(あなたのGitHubユーザー名)/in-60-seconds```に修正し[Commit changes]ボタンをクリックして保存します。 
<img width="666" alt="Untitled.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331144/9590dc3e-2bce-7e97-6f58-5b3244185f3d.png">

5.[gitpitch|slideshow]ボタンをクリックすると、スライドショーが表示されます。　
<img width="384" alt="Untitled.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331144/7289e93f-511b-21cd-f328-3ae3e2cabecb.png">

プレゼン資料はPITCHME.mdというファイル名(固定です)で作成されており、
```https://gitpitch.com/(GitHubのユーザー名)/(PITCHME.mdの存在するGitHubのリポジトリ名)```
でアクセスできるようになります。　
<img width="561" alt="Untitled.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331144/8ee35e29-95c6-7a77-6a23-e56f7f7cf199.png">


## GitPitchのMarkDown記述方法
プレゼン資料は、PITCHME.mdファイルを編集して作成します。通常のMarkDown記法に加え、いくつか独自の記法が利用できます。

```MD:PITCHME.mdの例
PITCHME.mdの記述方法
---
「---」は、スライドのページ区切りです
---
「```![](画像へのパス)```」で画像を貼れます。
---
![](presentation.png)
---
詳しくはこちら↓
[Click here to jump straight into the interactive feature guides in the GitPitch Docs @fa[external-link]](https://gitpitch.com/docs/getting-started/tutorial/)
---
最後のスライド
```
上記の表示例
[![GitPitch](https://gitpitch.com/assets/badge.svg)](https://gitpitch.com/TaroNakasendo/GitPitchSample)
【FileMaker】計算式をゼロや空白で除算するとどんなエラーが返ってくるの？

FileMakerと関係ありませんが、我が家は割とデータベースの話に花が咲きます。
まったりとした休日のある日、話の流れは忘れましたがゼロディバイドの話が出、「そういえばFileMakerでゼロとか空白で除算するとエラーって何返ってくるんだっけ？」となり、記事にまとめました。

構文エラーになることはなるよね。
（きっとFileMaker技術者認定の方やFBAの方々には当然の話なんでしょうけど。。。）

# ランタイムエラーと構文エラー
初歩的なところで、前提としてまとめておきます。

|エラー|大体の説明|
|:-----------------|:-----------------|
| ランタイムエラー |式自体は合っているけれど、実際の計算をした時にレコードがなかったりで正常に処理が遂行できない時のエラー |
|構文エラー|そもそも計算できないでしょ？というようなエラー。例えば、カッコがないとか、今回のようなゼロや空白で除算など。|

カッコがない時、そもそもスクリプトを書いているときにエラーになるでしょ？というケースもありますが、変数に計算式としてカッコを書いていて、実は閉じカッコが足りなかった、という時に、実行している時に構文エラーが返ります。
[この辺](https://fmhelp.filemaker.com/help/18/fmp/ja/index.html#page/FMP_Help/evaluationerror.html)のFileMakerガイドを参考にしてください。

# ゼロ除算
まずは、ゼロで除算です。
<img width="850" alt="zero divide script" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/647171e4-0459-0b84-f20a-603af71af42d.png">

2行目では、いつも通りに計算をし、結果をrec変数に保存します。
3行目で、その時のエラーコードを取得します。
構文エラーを取得するには、[EvaluationError](https://fmhelp.filemaker.com/help/18/fmp/ja/index.html#page/FMP_Help/evaluationerror.html)という論理関数を使用すると取得できるので、4行目で構文エラーを取得します。

結果です。
<img width="441" alt="zero divide dialog" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/216ab412-1b59-a671-1db0-5ef9efa8f445.png">
構文エラーが返ってきました。
エラーコード15は、「0 で割ることができません」という内容です。

参照：[FileMakerエラーコード (ver.18)](https://fmhelp.filemaker.com/help/18/fmp/ja/index.html#page/FMP_Help%2Ferror-codes.html%23ww1030072)

全くもって納得できるエラーコードです。

# 空白除算
他の言語でいうところの、Null扱いに近いでしょうか？
多言語でも、Nullで除算はエラーが返ってきますので、大体想像はつきます。
<img width="798" alt="スクリーンショット 2019-10-22 16.54.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/6557733f-816a-b489-b2ae-8b37a6745580.png">

結果です。
<img width="442" alt="スクリーンショット 2019-10-22 16.54.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/15467051-a2fd-862c-bb69-a8fbfbd0f5d9.png">
同じく、構文エラー15が返ってきました。
エラーメッセージ自体は「0で、、、」ですが、要は除算できないというメッセージです。
カスタマイズしたエラーメッセージを出す場合は、「ゼロもしくは値が設定されていない状態で除算が行われました」という柔らかいメッセージの方が良さそうですよね。

#変数にして除算するとどうなる？
上記までは、単純に固定値を指定して除算しましたが、変数に割る値を代入して実行すると、同じ結果が返ってくるのでしょうか？
<img width="853" alt="variable divide" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/3c8ace09-b9c1-1af1-18b8-a92f69ea2b97.png">

結果は、同じでした。
<img width="444" alt="スクリーンショット 2019-10-22 17.01.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/9c76b602-350a-c93e-d30d-760f353d426b.png">
<img width="443" alt="スクリーンショット 2019-10-22 17.01.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/4758271a-76ff-62ff-4a94-819a6f21611b.png">

#計算する時どこまで実装するか
全ての計算式に構文エラーを確認していてはコードが煩雑になり可読性も悪くなりそうです。
除算に限らず、計算式がテキストであるとかゼロが含まれている計算になったらまずい（大抵まずいですが）場合、EvaluateErrorを実装する、という程度でしょうか。
今回は変数で対応しましたが、フィールドのデータで計算式を組み立てる時に、元々の入力制限として下限値を設定しておく、などの対策をしてEvaluateErrorが発生しない（しにくい）構造にするのも手かと思います。
正規表現とは　概要と使用方法

正規表現(Regular expression)について学習したので、備忘録も兼ねてまとめます。
記載に誤りなどございましたら、ご指摘いただけますと幸いです。
＊新たに学習したことなどあり次第、更新いたします。

#正規表現とは
文字列に特定の文字が含まれているかの確認や特定の文字を取り除くなどの操作を行うための技術。
主に下記のケースで使用される。

-文字列における一部分の置換
-文字列が制約を満たしているか確認
-文字列における一部分を抽出
*正規表現は様々な言語で同じようなコードで表すことができるように設計されているため、ほとんどの記述をRubyやJavaScriptなどの別言語間でも共有することができます。

#正規表現で使用するメソッド
1.subメソッド
2.matchメソッド
3.splitメソッド
以下で、詳細・使用方法を説明していきます。

##1.subメソッド
使用目的：文字列における一部分の置換
*第一引数に置き換えたい文字列を指定（/で囲む）し、第二引数に変換後の文字列を指定。
*第二引数を空欄にすれば、第一引数の部分が削除されます。
(スペースを削除する場合は(' ',' ')という記述となり、/は不要となります。
*.upcase /.downcaseを使用することで、大文字小文字の変更も可能です。

*グローバルマッチ 'g'
文字列内で指定した文字が複数含まれている場合、その全てを置換するという意味になります。
gsubではなくsubを使用した場合、初めの１つだけ置換されます。

```
tel = '000-1234-5678' =>出力：'000-1234-5678'
tel.sub(/-/,'')　=> 出力：'0001234-5678' 最初のハイフンしか置換（削除）されない。
tel.gsub(/-/,'') =>出力:'00012345678' 全てのハイフンが置き換え（削除）される。
```

##2.matchメソッド
使用目的：文字列が制約を満たしているか確認/文字列における一部分を抽出
*指定した文字列が含まれている場合は、MatchDataオブジェクトの返り値で得られます。
含まれていない場合は、返り値としてnilが得られます。
*MatchDataオブジェクト:
正規表現のマッチに関する情報を扱うためのオブジェクト。
マッチした文字列等をMatchDataオブジェクトで返します。
MatchDataオブジェクトから文字列等を取り出す際は、以下の様に配列からデータを取り出す時と同様の形で取り出すことができます。
md=[数字]で取り出せます。(-1と入力した場合は、最後にマッチしたものが出力されます。)

記載方法

```
if "Do you like cats?".match(/like/)
  puts "Match found!"
end
```

|文字列|意味|
|:--:|:--:|:--:|
|[a-z] |括弧で囲まれた文字のいずれか１個|
|\d|数字|
|{n,m} |直前の文字が最低n回、最大m回出現するもの|
|.|どの１文字でも|
|+|直前の文字の1回以上の繰り返し|
|i|大文字・小文字を区別しない検索*最後につけます。|
*他にも色々とありますが、割愛させていただきます。

##3.splitメソッド
使用目的：対象とする文字列区切り文字ごとに分割して出力。

```
sample = "AAA,BBB,CCC" =>出力："AAA,BBB,CCC"
sample.split(/,/)[2] =>出力:"CCC"
```

###その他
Javascriptにおけるバックスラッシュ'\'について
まず、Javascriptにおける正規表現オブジェクトの生成方法について。
生成方法は以下のようになってます。
1.コンストラクタ関数 RegExp()を用いる
2.「/（スラッシュ）」を使って正規表現を囲む「リテラル表現」を用いる

```js:使用例
１）コンストラクタ関数 RegExp()を利用
let url = new RegExp('https?://example\.com');

２）リテラル表現を利用
let url = /https?:\/\/example\.com/;
```
２のリテラル表現では、「/」以外はデリミタとして認められません。
上記のように正規表現ではスラッシュをエスケープする必要が生じます。
ここでバックスラッシュを活用します。
正規表現では、まず特殊文字が正規表現として評価されます、ドットの場合、任意の 1 文字に一致すると解釈されます。

```:例
正規表現　1. = 11 = 1A
正規表現　1.1 = 111 = 1A1
```

ここで、正規表現で「0.0.0.0」を抽出したい場合に、今まで同様に記載すると以下のようになってしまいます。

```:例
正規表現　0.0.0.0 = 0102030 = 0a0b0c0
```

ドット'.'を任意の文字と一致させるのに使用する特殊文字ではなく、そもそもの区切り記号として認識させるには、
バックスラッシュ（\）を使用することで解決できます。

0.0.0.0 に一致する正規表現は次のようになります。

```:例
正規表現　0\.0\.0\.0　= 0.0.0.0
```
*デリミタ:複数要素を列挙する際に、要素の区切りとなる記号や特殊文字（の並び）のこと。

以上となります。最後までご覧いただき、ありがとうございました！
今後も学習した事項に関してQiitaに投稿していきますので、よろしくお願いします！
記述に何か誤りなどございましたら、お手数ですが、ご連絡いただけますと幸いです。

#参考
https://www.rubyguides.com/2015/06/ruby-regex/

Javascript での正規表現の記述方法
http://www-creators.com/archives/4488

ドット（.）とバックスラッシュ（\）
https://support.google.com/analytics/answer/1034332?hl=ja
Rustを触ってみている感想

## はじめに
ご無沙汰しております、raqwelです。
最近Rustを勉強してみようかと思い立ってチュートリアルをポチポチやっています。
https://doc.rust-jp.rs/book/second-edition/foreword.html

そこで勉強したことを備忘録代わりにメモっていこうかと思います。

### Rustの特徴
・変数宣言したら基本イミュータブル
・**所有権**という概念。
　　GC（ガーベッジコレクション）なしでメモリの操作を安全に行うための考え方。Rustにおいて最も大事な概念。
　　ルールとしては以下の３つ
　　・Rustの各値は、所有者と呼ばれる変数と対応している。
　　・いかなる時も所有者は一つである。
　　・所有者がスコープから外れたら、値は破棄される。

その変数がスコープから外れたら値は破棄され、メモリが返還されるように自動でなっている。

```rust:example.rs
{
    let s = String::from("hello"); // sはここから有効になる

    // sで作業をする
}                                  // このスコープはここでおしまい。sは
                                   // もう有効ではなくなり、自動でメモリ返還される。
```

### 関数と所有権
値を関数に渡すことで、その値の所有権を動かす（ムーブ）ことになる。
ムーブしたものは、基本その関数の仮引数に所有権が譲られたままとなる。
（全部が全部ムーブされるわけではない。スタック領域に入るものはコレに該当しない）

```rust:example2.rs
fn main() {
    let s = String::from("hello");  // sがスコープに入る

    takes_ownership(s);             // sの値が関数にムーブされ...
                                    // ... ここではもう有効ではない

    let x = 5;                      // xがスコープに入る

    makes_copy(x);                  // xも関数にムーブされるが、
                                    // i32はCopyなので、この後にxを使っても
                                    // 大丈夫

} // ここでxがスコープを抜け、sも。だけど、sの値はムーブされてるので、何も特別なことはない。
  //

fn takes_ownership(some_string: String) { // some_stringがスコープに入る。
    println!("{}", some_string);
} // ここでsome_stringがスコープを抜け、`drop`が呼ばれる。後ろ盾してたメモリが解放される。
  // 

fn makes_copy(some_integer: i32) { // some_integerがスコープに入る
    println!("{}", some_integer);
} // ここでsome_integerがスコープを抜ける。何も特別なことはない。
```

・所有権を戻す方法もある。値を返してあげれば良い。
takes_ownership関数を以下のように変更すれば、呼び出し者と関数に所有権が戻る。

```rust:takes_ownership
fn takes_ownership(some_string: String) -> String {             // takes_ownershipは、戻り値を呼び出した関数にムーブする

    hoge_string = ..... // some_stringでなにか処理する

    hoge_string                              // hoge_stringが返され、呼び出し元関数に所有権がムーブされる
}
```

・所有権を渡さずとも**所有権を貸してあげれば**いちいち権利を全部譲渡したり返すとかを考えなくても済む。
渡す値と関数の引数に&をつけて参照するように設定すれば良い。その時も値は基本的にイミュータブルなので変更するときは`let mut hoge`みたいな感じで`mut`を付与して上げる必要がある。

もし、所有権がなかったりスコープを超えたアクセスをしようとするとコンパイル時にエラーを吐く。
そのため、複雑なメモリ参照による見つけにくいバグ（複数箇所から１つのメモリにある値を変更したり参照したりするようなもの）だったりメモリのリークだったりも所有権という考え方で防いでいる。

とりあえずこれで終わり。
続きはまた勉強したら随時追加していきます。
jsで文字列に変数埋め込みをする場合、mysqlライブラリのquery()を用いた際の注意

##環境
nodeJS

## プログラム
他の処理で得られた値を使ってsql作成する場合に以下のようなプログラムを作っていた

```javascript:server.js
connection.query(`select ${column_name} from ${table_name} where ${column_name}みたいな`, function (err, rows, fields) {
  if (err) { console.log('err: ' + err); } 
});
```

しかし、上記の場合エラーとなる。
バッククォートを用いた文字列を直接第一引数に入れてしまうのが問題。

以下のように、いったん変数に入れたら改善された

```javascript:server.js
let sql = `select ${column_name} from ${table_name} where ${column_name}みたいな`

connection.query(sql, function (err, rows, fields) {
  if (err) { console.log('err: ' + err); } 
});
```
## 結果
ふぅ〜！呼び出せた！
iOSのおしゃれな文字入力ライブラリつくってみた(swift)

#はじめに
今まで[いろいろ](#つくったのまとめ)iOSライブラリを作りましたが、中々使い道のないものばかりでした。

今回はいろんなアプリで使えるものということを主眼に置いて作成しました！！

[カラーピッカー](https://qiita.com/am10/items/82a4adb2267979841c9e)とかアプリ内で色を選択する機会はそうありません。しかし、大抵のアプリで行うことがあります。そう、文字入力です！！

文字入力といえば...ウィジャ盤！！！（ウィジャボード、いわゆるこっくりさん的なやつ）

#GitHub

つくったものはここ　[AMOuijaBoard](https://github.com/adventam10/AMOuijaBoard)

Cocoapods,Carthage,SwiftPMに対応してます。

#見た目
![board](https://user-images.githubusercontent.com/34936885/67257594-babb0a00-f4c7-11e9-98ba-32f18c7b2d9c.gif)

#機能
* タップで文字を選択できる(大文字アルファベットと数字のみ)
* GoodByeのタップを検知（Enter的な役割）
* フォントや色を設定できる

#使い方
1. AMOuijaBoardViewを設定する
	
	```swift
	// viewDidloadで初期化
	let boardView = AMOuijaBoardView(frame: view.bounds)

	// ここでフォントや色を指定

	boardView.delegate = self
	view.addSubview(boardView)
	```

2. デリゲートを設定する(2019/10/26修正)

	```swift
	func ouijaBoardView(_ ouijaBoardView: AMOuijaBoardView, didSelectKey key: AMOuijaBoardView.Key) {
	  switch key {
	  case .goodbye:
	    // GOOD BYEタップ時に呼ばれる
	    break
	  case .no:
	    // NOタップ時に呼ばれる
	    break  
	  case .yes:
	    // YESタップ時に呼ばれる
	    break
	  case .alphabet(let text):
	    // アルファベットタップ時に呼ばれる
	    // textはタップしたアルファベット（A~Z）
	    break
	  case .number(let text):
	    // 数字タップ時に呼ばれる
	    // textはタップした数字（0~9）
	    break
	  } 
	}
	```
	
描画の関係で幅は300~600で縦横の比は1:1.414です。この範囲外だとわりとレイアウトが崩れます...

小文字で受けたい場合は `text.lowercased()` で小文字にしてもらえれば小文字を取得できます。

日本語にしたい場合は `applyingTransform(_:reverse:)` でローマ字変換すればできなくもない気がします。

以前作った[UIViewを燃やすライブラリ](https://qiita.com/am10/items/f7b32ea5725feeb1469f)と組み合わせるとこんな感じです。

![burn](https://user-images.githubusercontent.com/34936885/67269119-0a61fb80-f4f1-11e9-890b-f26469e8573a.gif)

#さいごに
~~作ってから思いましたが入力ミスした場合の取消し処理がありません。~~

~~NOをタップでとか思いましたがそれだとYESの場合どうするか...~~
delegateを修正してYES/NOタップも受けれるようにしました。(2019/10/26修正)
NOタップのところで下記のような処理をすれば一文字削除ができます。（それでもやっぱりYESタップ時の処理が悩むところ...）

```swift
// inputTextが入力文字列
if !inputText.isEmpty {
  inputText.prefix(inputText.count - 1).map { String($0) }.joined()
}
```

計算処理やカーソル描画の妥協、タップするには間隔が狭すぎるなど改善点はいろいろあります:eyes::eyes::eyes:

#つくったのまとめ
* [アナログ時計を描画してみた（swift）](https://qiita.com/am10/items/0222e6966d58062d2eca)
* [スピードメーターをつくってみた（swift）](https://qiita.com/am10/items/0fe8cffac7dd7659eb2a)
* [めくるカレンダーをつくってみた(swift)](https://qiita.com/am10/items/2a929ca8196f33cb1d4a)
* [グラフを描画してみた(swift)](https://qiita.com/am10/items/aee964a8a7a9712d66f8#_reference-ca2e5485de5acf8eca97)
* [ちからわざで日本地図を描いてみた(swift)](https://qiita.com/am10/items/26de3242ee33b4bd4aae)
* [カラーピッカーをつくってみた(swift)](https://qiita.com/am10/items/82a4adb2267979841c9e)
* [面積比がそれっぽいベン図を描いてみた(swift)](https://qiita.com/am10/items/858041f70be4d8de5090)
* [UIViewを燃やしてみた（swift）](https://qiita.com/am10/items/f7b32ea5725feeb1469f)

##動作確認用にまとめたプロジェクト
* [Carthageで入れたやつ](https://github.com/adventam10/TestCarthage)
* [CocoaPodsで入れたやつ](https://github.com/adventam10/TestCocoaPods)
* [SwiftPMで入れたやつ](https://github.com/adventam10/TestSwiftPM)
git push 時 にエラーが出た話

# 目的

- git push実行時に起きたエラーについてまとめて今後同じことが起きても焦らないようにする。

# 経緯

1. githubにpushした。
1. 草が生えていないことを確認した。
1. ローカルリポジトリのgit configにメールアドレスが設定されていないことを確認した。(githubは設定されたメールアドレス情報でpushしないと草が生えない)
1. git configでメールアドレスを設定した。
1. pushした環境でコマンド`$ git commit --amend`を実行してしまった。
1. push時に下記のエラーが発生した。

  ```
  git push
  To github.com:miriwo0104/Qiita.git
  ! [rejected]        master -> master (non-fast-forward)
  error: failed to push some refs to 'git@github.com:miriwo0104/Qiita.git'
  hint: Updates were rejected because the tip of your current branch is behind
  hint: its remote counterpart. Integrate the remote changes (e.g.
  hint: 'git pull ...') before pushing again.
  hint: See the 'Note about fast-forwards' in 'git push --help' for details.
  ``` 

# エラーを解決するには？

1. コミットをする前にリモートの内容pullする。
1. マージコミットとしてローカルからリモートにpushする。

# 原因

一度リモートにpushした環境で`$ git commit --anemnd`を実行してしまった。  
1. 簡単に言うと、すでにpushしているコミットが見ている親コミットをamendしたコミットが見てしまってる。
1. コミットの歴史がローカルとリモートで異なるためにエラーが発生した。

# どうすべきだったのか？

1. リモートにpushした内容はamendしない。
1. pushしたコミットを一度revertしてコミットをやりなおすべきだった。
Google Mapのレストラン口コミ評価が良いエリアを可視化する

# 概要
Google Mapのレビュー点数が高いレストランが集まるエリアってどこなんだろ？と疑問に思い、ヒートマップにしてみました

# レビューのレーティングを取ってくる
[Place Search API](https://developers.google.com/places/web-service/search)を使います。[このWrapper](https://github.com/qpowell/google_places)を使わせて頂きました

* 単純にレストランの位置×レビューをプロットするとレストランが多い地域が赤いヒートマップになるだけなので、エリアをグリッド状に分割して、各グリッド内のレストランの平均レーティングで重み付けする想定で行きます
* 今回グリッドは約500m刻みになるよう設定したので、 `radius` を500とします
* 結果は最大20件までなのでレストラン密集地域ではAPIお任せのランダムな20件の平均となります

``` fetch_rating.rb
@client = GooglePlaces::Client.new(API_KEY)
col_num.times do |c|
  row_num.times do |r|
    lng = south_west[:lng] + c * diff
    lat = south_west[:lat] + r * diff
    result = @client.spots(lat, lng, language: :ja, types: :restaurant, radius: 500)

    # 平均出したりする処理...
  end
end
```
### 料金について
* 東京都だけに絞っても、網羅的にやろうとすると2188km²/0.25km²=約8700requestが必要
* 料金は[$13/1000req](https://cloud.google.com/maps-platform/pricing/sheet/?hl=ja)ぐらいになりそうなのでご利用は計画的に(今回取った範囲は無料クレジット内に収まりました)

# ヒートマップを描画する
* KibanaやTableauをこの為に用意するのは面倒
* Google Data Studioなら無料かつ手軽にヒートマップ化できるが、ズームレベルが「国」までしか選べない（USなら州までいける）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17941/264fda80-32e4-3081-9fa3-7387fe3afd18.png)
* という事でMaps JavaScript APIのHeatmapLayerを使います

# HeatmapLayer
* HeatmapLayerに渡すデータに `weight` を含ませると重み付けができる（weight: 3なら内部的に3つの点がプロットされる扱いとなる）
* しかし線形に反映されるだけだとこんな感じにメリハリの無いヒートマップになってしまう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17941/7d5b8448-4ce5-6c2c-43a6-65fea36897da.png)
* なので適当に `weight = Math.pow(weight, 3)` とかして非線形にします

結果はこんな感じです。
西麻布、目黒近辺、あとなんか西の方が強いですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17941/b45bdd73-d700-cf73-65e9-62cfd9f321c4.png)

``` heatmap.js
  fetch('summary.json')
    .then(response => response.json())
    .then(json => {
      const heatmapData = json.map(d => {
        const location = new google.maps.LatLng(d['location']['lat'], d['location']['lng'])
        const weight = Math.max(0, Math.pow(d['avg'] - 3, 3))
        return {location, weight}
      })
      const map = new google.maps.Map(document.getElementById('map'), {
        center: new google.maps.LatLng(35.672196, 139.729521),
        zoom: 12.3,
        maxZoom: 12.6,
        minZoom: 12,
        disableDefaultUI: true
      })
      const heatmap = new google.maps.visualization.HeatmapLayer({
        data: heatmapData,
        radius: 40,
        opacity: 0.5,
        gradient: ['white', '#ffff99', '#fff000', '#ff0000'],
      })
      heatmap.setMap(map)
    })
```

[こちら](https://jp.inamori.work/rating_heatmap)で動くものが見られます。
内緒だけど、[こちら](https://jp.inamori.work/rating_heatmap?low_rating=1)でレビューが低い地域が赤くなるバージョンも見られます。
homebrewでminikubeをインストール

homebrewを使ってminikubeをインストールする手順

## インストール手順
- brew caskのインストール 
`$ brew install cask`

- hyperkitのインストール
`brew install hyperkit`

- hyperkit driverのインストール
`brew install docker-machine-driver-hyperkit`

- 実行権限の付与
`chmod u+s /usr/local/opt/docker-machine-driver-hyperkit/bin/docker-machine-driver-hyperkit`

- minikubeのインストール
`brew cask install minikube`

- minikubeの起動
`minikube start --vm-driver=hyperkit`

- 起動状態の確認
`kubectl get node`

## 起動できない場合

「“minikube-darwin-amd64”は、開発元を検証できないため開けません。」と言われて起動できない場合、やむを得ないので一時的にダウンロードしたアプリケーションの実行を許可するため以下の様にする

```
$ sudo spctl --master-disable
$ minikube start --vm-driver=hyperkit
$ sudo spctl --master-enaable
```
PostgreSQL の認証を LDAP で行う

# 初めに
### 2019-10-03にPostgreSQL12 がリリースされました
https://www.postgresql.org/about/news/1976/
https://www.postgresql.org/about/press/presskit12/ja/#original_release

PostgreSQLにはLDAPでユーザー認証を行う機能があるようですが、あまり情報がないようでしたので、簡単に纏めました。
https://www.postgresql.jp/document/11/html/auth-ldap.html

LDAPはユーザの名前とパスワードの組み合わせの検証のみに使用されます。 そのため、LDAPを使用して認証を行うようにする前に、ユーザはデータベースに存在しなければなりません。

# 環境
- Ubuntu 18.04 LTS
- PostgreSQL 12 (--with-ldapでビルドしたもの)
- OpenLDAP 2.4.x

# PostgreSQL 12の構築と設定


## 必要なパッケージの導入

```bash
sudo apt update

sudo apt install gcc
sudo apt install make

sudo apt install libreadline-dev
sudo apt-get install zlib1g-dev

sudo apt install ldap-utils
sudo apt install slapd
sudo apt install libldap-dev
```


## PostgreSQL 12をビルド

```bash
tar xvf ./postgresql-12.0.tar.gz
cd ./postgresql-12.0
./configure --with-ldap
make
sudo make install
```
## OSユーザー(postgres)の作成

```bash
sudo adduser postgres
```

## PostgreSQLのデータディレクトリの作成
```bash
sudo mkdir /usr/local/pgsql/data
sudo chown postgres:postgres /usr/local/pgsql/data
sudo chmod 700 /usr/local/pgsql/data
```

## データーディレクトリの初期化

```
su - postgres
/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data 
```

## PostgreSQLを起動し接続

```
su - postgres
/usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data start  
/usr/local/pgsql/bin/psql  
```

## DBのユーザー(dbadmin)を作成

```
postgres=# CREATE ROLE dbadmin WITH SUPERUSER LOGIN;

postgres=# \du
Role name |                         Attributes                         | Member of
-----------+------------------------------------------------------------+-----------
dbadmin   | Superuser                                                  | {}
postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}

postgres=# \q
```

## DBの認証方法の設定

```bash
:/usr/local/pgsql/data/pg_hba.conf
:
#local   all             all                                    trust
local   all             all                                     ldap ldapserver=localhot ldapprefix="cn=" ldapsuffix="dc=example,dc=com" 
# IPv4 local connections:
host    all             all             127.0.0.1/32            ldap ldapserver=localhot ldapprefix="cn=" ldapsuffix="dc=example,dc=com" 
:
```
設定が済んだらPostgreSQLを再起動

# OpenLDAPの設定
## LDAPのユーザーエントリー(dbadmin)

OpenLDAPに以下のエントリーを追加、データベースに追加したユーザー名(dbadmin)と同じ名前のユーザーを作成する。

```:dbadmin.ldif
objectclass: top
objectclass: person
objectclass: organizationalperson
objectclass: inetorgperson
dn: cn=dbadmin,dc=example,dc=com
cn: dbadmin
sn: PostgresDB管理者
mail: dbadmin@example.com
userPassword: secret123     (ここはslappasswdコマンドを使ってハッシュ化すること)
```

# 認証

```
/usr/local/pgsql/bin/psql -U dbadmin -d <データーベース名>
Password for user admin: 
```

# 最後に

いろいろ試しているのですが、うまく行ったり行かなかったりで、なかなかの曲者です。
Dockerコンテナにポートを追加する


### 概要
Dockerを使っているとポートが足りなくなることがありますが、一度作ってしまったコンテナにポートを追加することはできません。
ではどうすればいいか。。そんな時はコンテナをイメージ化ｰ>ポートを付け加えてコンテナを再作成するのがオススメです。
### 参考にしたサイト
- 公式リファレンス
  - http://docs.docker.jp/engine/reference/commandline/run.html 
- ブログ記事　 
  - https://mahimahironron.hateblo.jp/entry/2019/10/18/Doceker%E3%81%AE%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%81%AB%E3%83%9D%E3%83%BC%E3%83%88%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%97%E3%82%88%E3%81%86

### コンテナをイメージ化する方法

- まず使用しているコンテナをストップします。

```
# docker stop <コンテナ名>
```

- コンテナからイメージを作成するにはdocker commitを使用します

```
# docker commit <コンテナ名> <イメージ名>
```

### イメージからコンテナを作成する方法

- 以下のコマンド実行することでイメージから新たにコンテナを作成することができます。

```
docker run --privileged -it -p <ホスト側のポート>:<docker環境のポート> -d --name <コンテナ名> -v <ホスト環境のディレクトリ>:<docker環境でのディレクトリ>  <イメージ>:<タグ> /sbin/init
```

- /sbin/init はコンテナ内での実行コマンドです。
一般的には/bin/bashが採用されます。
Pythonの並列処理でプロセスごとにMySQLに接続する方法

# 背景
Pythonで並列処理が簡単に実現できるのはわかったものの、プロセスごとにデータベースに接続する方法がわからず、調べてたどり着けたので、共有します。

# データベース接続なしの単純な並列処理の例
リストの値を渡して表示する、という単純な並列処理は、下記のコードで実現できます。

```python:multisample.py

from multiprocessing import Pool

def doSomething(x):
    print(str(x[0])

if __name__ == '__main__':

    idAry = [0, 1, 2, 3, 4]

    p = Pool(processes=プロセッサ数)
    p.map(doSomething,idAry)
    p.close()
    p.join()

```

このとき、呼び出す関数doSomethingのなかで、データベース接続して処理をしたい場合に今回ご紹介する方法が役立ちます。
毎回doSomethingのなかでデータベース接続するということでも実現できます。
だけど接続に時間がかかったり、接続上限数に達する可能性もあるので、おすすめできません。

# 並列処理でMySQLに接続する方法

たとえば会員マスタから会員IDを抽出し、会員ごとの購入回数を集計して表示するというプログラムを書くとします。
(SQLでGROUP BYでできるのは重々承知ですが^^;)

```python:sample.python

from multiprocessing import Pool
import mysql.connector

def init():
    global cnx #接続オブジェクトをグローバル変数で定義する。
    cnx = mysql.connector.connect(host="ホスト名", port="ポート番号", user="ユーザ名", password="パスワード",  database="データベース名")

def doSomething(x):
    curChild = cnx.cursor(buffered=True) #初期処理で作ったグローバル変数のDB接続オブジェクトからカーソルを作る

    sel_sql = "SELECT COUNT(*) FROM 購買データのテーブル WHERE 会員ID = '"  + str(x[0]) + "'"
    curChild.execute(sel_sql)
    res = curChild.fetchone()
    print(str(x[0]) + " " + str(res[0]))
    curChild.close()

if __name__ == '__main__':
    db = mysql.connector.connect(host="ホスト名", port="ポート番号", user="ユーザ名", password="パスワード",  database="データベース名")
    cur = db.cursor(buffered=True)

    sel_sql = "SELECT 会員ID FROM 会員マスタ"

    cur.execute(sel_sql)

    idAry = cur.fetchall()

    p = Pool(processes=プロセッサ数, initializer=init)　#initializerオプションで、初期処理関数を定義する。
    p.map(doSomething, idAry)
    p.close()
    p.join()
```

```initializer``` で各プロセスからMySQLへの接続を呼び出す　```init``` の定義が重要なポイントです。

ここで各プロセスの初期処理でデータベースへの接続を確立します。
その後、各プロセスの ```doSomething``` 実行では各プロセス用のデータベース接続からカーソルを作ってSQLを実行します。

接続回数は並列処理のプロセッサ数となるため、いちいち接続することもなくなり、実行速度がより高速になります。
Remote Configのデフォルト値を追加し忘れる問題

テストで解決。

```kotlin
import android.content.Context
import android.content.res.XmlResourceParser
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.xmlpull.v1.XmlPullParser

@RunWith(AndroidJUnit4::class)
class RemoteConfigTest {
    private lateinit var defaultXmlParser: XmlResourceParser

    @Before
    fun setUp() {
        val context: Context = InstrumentationRegistry.getInstrumentation().targetContext
        defaultXmlParser = context.resources.getXml(R.xml.remote_config_defaults)
    }

    @Test
    fun assertAllKeysHaveDefaultValues() {
        // デフォルト値が定義されているkeyを取り出す
        val keysWithDefaults: MutableSet<String> = mutableSetOf()
        while (defaultXmlParser.eventType != XmlPullParser.END_DOCUMENT) {
            if (defaultXmlParser.eventType == XmlPullParser.START_TAG && defaultXmlParser.name == "key") {
                defaultXmlParser.next()

                keysWithDefaults.add(defaultXmlParser.text)
            }

            defaultXmlParser.next()
        }

        // デフォルト値が定義されていないkeyを取り出す
        val keysWithoutDefaults: Set<String> = RemoteConfigManager.keys() - keysWithDefaults

        // デフォルト値が定義されていないkeyがなければ終了
        if (keysWithoutDefaults.isEmpty()) return

        throw IllegalStateException(
            """keyに対応するデフォルト値が存在しない:${keysWithoutDefaults.joinToString(separator = ", ")}"""
        )
    }
}
```

`XmlPullParser`の代わりに`XPath`を使うともっとすっきり書けるかもしれない。。
【Python】初学者が学習の為にトランプゲームを作成する(第1回)

※この記事は初学者である筆者の備忘録的扱いになります。

#はじめに
私は実務でPythonを使うことになり、勉強をしています。
トランプゲームを作成することによって、配列、関数、制御文等を学ぶことが出来ると考え、
作成を始めました。

#内容
作成を行うにあたって、ゲーム内容を考える前にトランプゲームのほとんどに共通する

**「デッキからカードを配る」**

というところから作っていこうと考えました。

実際に今回作成した**「デッキからカードを配る」**です。
↓↓↓↓↓↓↓↓↓↓

```
import random

mark = ["♤ ", "♧ ", "♡ ", "♢ "]
number = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
card_deck = []
player_card = []
cpu_card = []

def card_master():
    for mark_idx in range(4):
        for number_idx in range(13):
            card_deck.append(mark[mark_idx] + str(number[number_idx]))

def player(maisu):
    player_card.extend(random.sample(card_deck, maisu))
    for idx in range(maisu):
        card_deck.remove(player_card[idx])

def cpu(maisu):
    cpu_card.extend(random.sample(card_deck, maisu))
    for idx in range(maisu):
        card_deck.remove(cpu_card[idx])

card_master()
player(5)
cpu(5)
print(player_card)
print(cpu_card)
print(card_deck)
```

#解説
###・デッキを作る
まず、カードを作っていきます。
いろいろ考えましたが、一番シンプルなやり方です。

```
mark = ["♤ ", "♧ ", "♡ ", "♢ "]
number = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
```

リストに**マーク**と**数字**を格納します。

```
def card_master():
    for mark_idx in range(4):
        for number_idx in range(13):
            card_deck.append(mark[mark_idx] + str(number[number_idx]))
```

それぞれのマークに1~13の数字を結合し、それをデッキに格納していきます。
上記のこの部分

```
card_deck.append(mark[mark_idx] + str(number[number_idx]))
#リスト.append(<追加したい要素>)
```

.appendはリストに要素を追加(リストの一番後ろ)します。

デッキの中身はこのようになっています。
↓↓↓↓↓↓↓↓↓↓

```
['♤ 1', '♤ 2', '♤ 3', '♤ 4', '♤ 5', '♤ 6', '♤ 7', '♤ 8', '♤ 9', '♤ 10', '♤ 11', '♤ 12', '♤ 13', '♧ 1', '♧ 2', '♧ 3', '♧ 4', '♧ 5', '♧ 6', '♧ 7', '♧ 8', '♧ 9', '♧ 10', '♧ 11', '♧ 12', '♧ 13', '♡ 1', '♡ 
2', '♡ 3', '♡ 4', '♡ 5', '♡ 6', '♡ 7', '♡ 8', '♡ 9', '♡ 10', '♡ 11', '♡ 12', '♡ 13', '♢ 1', '♢ 2', '♢ 3', '♢ 4', '♢ 5', '♢ 6', '♢ 7', '♢ 8', '♢ 9', '♢ 10', '♢ 11', '♢ 12', '♢ 13']
```

###・カードを配る
次にプレイヤーにカードを配ります。

```
def player(maisu):
    player_card.extend(random.sample(card_deck, maisu))
    for idx in range(maisu):
        card_deck.remove(player_card[idx])
```

上記のこの部分

```
player_card.extend(random.sample(card_deck, maisu))
#リスト.extend(<追加したいリスト>)
#random.sample(<リスト>, <取得数>)
```

先程、リストに要素を追加する際は.appendを使いましたが、
今回は**リストにリストを追加する**ため.extendを使いました。
また、デッキからランダムなカードを取得するために、
random.sampleを使いました。

その後、デッキから取得されたカードをデッキから取り除きます。

```
card_deck.remove(player_card[idx])
#リスト.remove(<削除する要素>)
```

これでプレイヤー側は完成です。
これと同様にCPU側も作成しました。

###・結果
デッキからプレイヤーとCPUに5枚ずつカードを配り、配ったカードはデッキから削除
という動作を確認します。

```
['♡ 6', '♤ 13', '♧ 10', '♤ 12', '♤ 8']
['♧ 5', '♡ 1', '♢ 8', '♢ 9', '♢ 1']
['♤ 1', '♤ 2', '♤ 3', '♤ 4', '♤ 5', '♤ 6', '♤ 7', '♤ 9', '♤ 10', '♤ 11', '♧ 1', '♧ 2', '♧ 3', '♧ 4', '♧ 6', '♧ 7', '♧ 8', '♧ 9', '♧ 11', '♧ 12', '♧ 13', '♡ 2', '♡ 3', '♡ 4', '♡ 5', '♡ 7', '♡ 8', '♡ 9', '♡ 10', '♡ 11', '♡ 12', '♡ 13', '♢ 2', '♢ 3', '♢ 4', '♢ 5', '♢ 6', '♢ 7', '♢ 10', '♢ 11', '♢ 12', '♢ 13']
```

見づらいですが、1番目のリストはプレイヤー、2番目はCPU、3番目はデッキ。
配られたカードがデッキにない事を確認できました。

#最後に
ここまで作るのに4時間くらいかかっちゃいました。

作成するゲームはポーカーかブラックジャックかなーと思っています。
次回はゲームの内容を作成していきます。
Rails上におけるテストで、「1つのHTML要素に対し、複数のクラスが定義されていること」をテストする正しい書き方

「`alert`と`alert-danger`両方のクラスが定義されている`div`要素が存在すること」をテストしようとして、以下のようなテストを書いてもうまくいきません。

```ruby:
test "invalid signup information" do
  assert_select 'div.alert'
  assert_select 'div.alert-danger'
end
```

上述のテストだと、「`alert`というクラスが定義されている`div`要素と、`alert-danger`というクラスが定義されている`div`要素が別々に存在すること」のテストになってしまうためです。

「`alert`と`alert-danger`両方のクラスが定義されている`div`要素が存在することをテストする」ためには、ブロックを使って、以下のように記述する必要があります。

```ruby:
test "invalid signup information" do
  assert_select 'div.alert' do
    assert_select 'div.alert-danger'
  end
end
```
javascript基礎構文（document.getElementByIdとdocument.getElementsByClassName）


##趣旨
javascript基礎構文をまとめます。
今回はdocument.write（）とdocument.getElementById()とdocument.getElementsByClassName()です。


###document.write（引数）
引数に指定した文字列を書き出すことができる

```javascript:javascript
document.write("hello")
```

helloが表示される

```html:表示
hello
```

###document.getElementById()

document.getElementById()でIDを指定し、innerHTMLでIDを指定した要素の内容を変更する

```html:javascript
<div id ="get">messageBefore</div>

<script>
var def = document.getElementById("get");
def.innerHTML = "messageChanged";
</script>
```


innerHTMLで変更したmessageChangedが表示される

```html:表示
messageChanged
```

###document.getElementsByClassName()

document.getElementsByClassName()でclassを指定すると配列のようなオブジェクトを返す。
for文は（初期化値; 条件式; 増加分）{命令文}で繰り返し処理が走るので、for文で配列の中身を取り出すことができる。
.lengthで配列の長さをカウントしその長さの分だけ繰り返す。
今回はinnerHTMLで配列の番号を指定し、その要素の内容を変更する。

```html:javascript
<div class ="get">messageBefore</div>

<script>
var def = document.getElementsByClassName("get");
for (var i = 0; i < def.length; i++) {
  def[i].innerHTML = "messageChanged"
}
</script>
```

```html:表示
messageChanged
```
ロジック・シュミレーション徒然メモ

ロジック（論理）・シュミレーションの関するメモです。

## 'X' 伝搬問題

シュミレーションを流していると、信号に 'X'  が増えてゆく事がある。波形を見ると真っ赤になっているので心臓に良くない。どこかで発生した 'X'（アンノーン、不定値） が時間とともに回路のなかで伝搬、爆発してシュミレーションが失敗する。RTLのシュミレーションで問題なかったテストベンチがネットリストだと失敗するケースはこの症状の場合が多いかもしれない。さて、どうして'X'が発生するのか？

- 入力ポートがちゃんとつながってない
    - 対策： オープンなポートを見つけて、つなげる（もしくは、０，１で固定）
- ラッチがきちんとリセットできていない
    - 対策：X状態のラッチセルの特定、そのセルのリセット方法の確認
- 初期化が必要なクロックゲートセル
    - 対策：X状態のクロックゲートセルの特定、そのセルのリセット方法の確認
- ループで'X'から抜け出せない
    - 対策： 一時的に値を強制的にセットして（Force,Release文）、Xのループを断ち切る
- TristateのIO信号（inout ポート）、Z状態のバス信号が入力側でXに
    - 対策： 一時的に値を強制的にセット（Force,Release文）や入力信号をゲートできるようにしておく  
- タイミングエラー（遅延シュミレーション）
    - 対策： 論理合成のタイミング制約の見直し

などがある。基本的な作業は、「地道に発生源をつきとめて対策を施してゆく」 しかない。大雑把な流れは

1. 動作を波形で見てみる
2. 最初に（もしくは最初から）'X'になってる信号を洗い出す
3. 回路(HDL)を確認して、Testbenchの実装やライブラリの修正等で調整する
    - ポートならテストベンチを修正、入力信号を与える。
        - 場合によってはForce文で値を（一時的に）固定する
    - ラッチの場合、動作によってはうまく初期化出来ないことがある（非同期リセットなど、もしくはリセットが無い回路）。この場合、Force文で入力をよしなに操作したり、ラッチのモデルを修正したりする
    - タイミングエラーの場合は、警告が出るので発生源の特定は容易だが、修正はタイミング制約や回路の見直しとなる。
        - 時間がないとき、Holdの場合は、こっそり遅延を挿入して様子を見る


で、波形のダンプが曲者である。何も考えていないと、超巨大なVCDファイルが生成されてファイルシステムが一杯になる。そのため

- VCDでダンプする場合
    - 最初は、トップか上位の階層だけダンプして、問題のありそうな時間を特定する
        - VCDのダンプ時間と、階層をよしなに調整して、問題の信号やインスタンスを特定する。 例えば、
            - あるモジュールの内部信号を一旦全部表示してみて、X以外の信号をバッサリ削除する（初期にXになる信号だけ残す）
            - つぎに、最初に（最初から）Xになる信号とそのインスタンスを特定
            - インスタンスのコードを確認
- 論理シュミレーターのGUI上で波形を選びながら実行する
- 各社の解析ツールを使ってみる


余談、RISC-VのRocketCoreの内部レジスタの多くはリセットされない（初期値に依存しない）。RTLのシュミレーションでは乱数値がセットされる。しかしながら、これがネットリストのシュミレーションになると曲者で、標準のラッチは初期値が 'X' なので、そのまま動かすと内部信号が真っ赤になる。とっても困る。

参考

- 解説記事
    - https://www.techdesignforums.com/practice/technique/catch-x-propagation-issues-rtl/
    - https://www.techdesignforums.com/practice/guides/x-propagation/
    - https://www.cqpub.co.jp/dwm/contents/0012/dwm001201250.pdf
- 解析アプリ
    - Cadence Xcelium Simulator’s X-prop Technology
    - Cadence JasperGold® X-Propagation Verification App
    - Synopsys Xprop
    - Mentor Questa X-Check
BitriseのWorkflowを超簡単に取得する方法

## やりたいこと
BitriseのWorkflowをバックアップを兼ねてGitHubで管理したい！
Workflowはymlで記載されていて、GUIから取得することができるが、プロジェクトが大量にあると１つずつとるのがめんどい。
Bitrise APIで簡単に解決してみよう！

## Bitrise API
使い方は前に書いた記事を見てください！
https://qiita.com/satoshi-baba-0823/items/abf238b7950655f86c09

`/apps:GET`と`/apps/{app-slug}/bitrise.yml:GET`が使えそう！

## やり方
流れとしてはこんな感じで超簡単！
1. アプリの一覧を取得(`/apps:GET`)
2. アプリごとのbitrise.ymlを取得(`/apps/{app-slug}/bitrise.yml:GET`)

できたのがこれ！

``` sample.sh
#!/bin/bash
ACCESS_TOKEN={アクセストークン}

JSON_RESPONSE=$(curl -X GET "https://api.bitrise.io/v0.1/apps?sort_by=created_at" -H "accept: application/json" -H "Authorization: $ACCESS_TOKEN")
APPS=$(echo $JSON_RESPONSE | jq ".data")

JSON_LENGTH=`echo $APPS | jq length`

for APP_INDEX in `seq 0 $(expr $JSON_LENGTH - 1)`
do
    APP=$(echo $APPS | jq .[$APP_INDEX])
    APP_SLUG=$(echo $APP | jq -r .slug)
    APP_TITLE=$(echo $APP | jq -r .title | sed -e "s/\//_/g")
    curl -X GET "https://api.bitrise.io/v0.1/apps/$APP_SLUG/bitrise.yml" -H "accept: text/plain" -H "Authorization: $ACCESS_TOKEN" > ./yml/$APP_TITLE.yml
done
```

これでWorkflowを取得することができる！
Workflow書き換えまくってぶっ壊しても安心だね！
【Ruby on Rails/PostgreSQL】"PG::Error: ERROR:  duplicate key value violates unique constraint"と出てレコード作成できない時の対処法

## 今回の問題
- Rails/Active Recordで新しいレコードを作成しようとすると、エラーが出てしまう

```shell
PG::Error: ERROR:  duplicate key value violates unique constraint "addresses_pkey"
DETAIL:  Key (id)=(2) already exists.
```

## 原因
ActiveRecordでレコードを作成するとき、primary_keyが``id``になっている時は``Address.create(name: "toyota")``とidを指定せずに作成しても自動でidを付与してくれる。シーケンスも自動インクリメントしてくれる。

ただし、idの順序がすでに指定されてある場合などに``Address.create(id: 12, name: "suzuki")``とidを指定しレコード作成した場合、次のレコード作成時にシーケンスが自動インクリメントされない。そのため、``DETAIL:  Key (id)=(2) already exists.``というエラーが出てしまう。

## 解決方法

SQLを発行して、シーケンスを訂正する。下記のSQLを実行すると、テーブル内のレコードから``idの最大値＋１``した値をシーケンスとして保存してくれる。

```shell
# Addressテーブルのidのシーケンスを直す場合の例
SELECT setval('addresses_id_seq', coalesce((SELECT MAX(id)+1 FROM addresses), 1), false)
```

Railsアプリ内上記SQLを実行する場合は下記のように書く

```ruby
ActiveRecord::Base.connection.execute("SELECT setval('addresses_id_seq', coalesce((SELECT MAX(id)+1 FROM addresses), 1), false)")
```

## 参考サイト
- [PostgreSQLとRailsでシーケンスを手動で上げる](http://eienshinjin.hatenablog.com/entry/2014/11/05/105608)
[Unity]Update関数内で最初の一回だけ実行する

UnityのAwake()やStart()では書けず、Update関数内でシーンがロードされた後一回だけ実行する方法です。

```C#
bool isOnce = true;
void Update(){
    if(isOnce){
       //処理内容
       isOnce = false;
    }
}
```

bool型ではなく、int型を用いれば最初の3回だけ実行するといったことも可能です。

```C#
int Three = 0;
void Update(){
    if(Three < 3){
       //処理内容
       Three++;
    }
}
```
SikuliXでソーシャルゲームを自動化する

#「プリンセスコネクト！Re:Dive」をSikuliXで自動化する

![mypageclick_640x320_fps10.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265588/c50fc1d6-ad89-baa6-776b-7b492683ef88.gif)


##実行結果
https://youtu.be/4sBkp6W3O_Q

##SikuliXのコード
「マナを獲得する」手順は、15行で済む
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265588/2178dd44-e7fe-6ee2-2878-754cd1696834.png)
Salesforceって何？ Salesforceと他のカスタム開発って何が違うの？要件定義に大切なことって？

Salesforceって何？
Salesforceと他のカスタム開発って何が違うの？
っていう質問をよく受けるのですが、メモ程度に情報をまとめたので共有します。

####＜Salesforceって何？＞
Salesforceは顧客情報や商談情報などを管理するためのパッケージ製品です。（もちろん、他にも色々な機能あり。）
パッケージ製品なので、すでに一定の機能（顧客管理や商談管理、分析機能）が作りこまれた状態で売られています。
なので、まっさらな状態からの開発とは異なり、すでに提供されている機能を活用することで、検討や開発スケジュールの短縮、および初期コストの低減を目指すことができます。
（例えば、ユーザ要件（自分のToDoを表示したい）と、Salesforceの提供するToDo機能がうまくマッチしたら、ToDo表示機能の一切作りこみは不要で、ToDoを表示したい画面にドラッグアンドドロップで機能を配置して開発完了となります。
以下は一切作りこみをしていないSalesforceの「今日のToDo表示」機能です。
通常の開発だと、ラベルの位置は？とか色々決めて作りこむ必要があると思うのですが、そういう検討や設計は不要です）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450298/9979667d-04b7-1a28-b9d0-1ebc91de160c.png)


また、Salesforceはクラウド（＝ネット経由でシステムを提供）なので、ネット上で開発したり、アクセスしたりすることができ、お客様のセキュリティ問題がなければ、社内での持ち帰りや在宅での開発も可能となります。

特記事項としては、年に3回のバージョンアップで、強制的に機能追加されます。
（過去の例だと、突然ボタンや検索窓が増えたり、レイアウトの項目幅を広くするのか狭くするのかユーザ自身で設定できるようになったりします。
　余談ですが、Salesforceが提供する機能はネット上に仕様が掲載されているので、なるべく設計書をかかないようにすることがおすすめです。
　じゃないとバージョンアップで仕様が変わった時にメンテナンスが大変だし、反映が漏れてしまうリスクもあります。）


####＜Salesforceと他のカスタム開発って何が違うの？＞
前述の通り、Salesforceはパッケージシステムなので、まっさらな状態からの開発とは異なり、すでに提供されている機能を活用しながら開発を進めます。
開発というか、以下のように、パラメータを手動で設定するイメージになります。
逆に言うと、これ以外何もできないので、例えばボタン変えたいとか、リンク左に寄せたいなどの要望を言われたらクライアントと調整/検討が必要になります。
（ボタンの色を変えるために全部カスタマイズするとXXX万かかるんですけれど、作りこみますか？
それをやって業務にどれだけプラスになりますか？とか。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450298/cdbbd3d4-e6dc-63e4-3b6f-75f036e62046.png)


なので、クライアント要件が、Salesforceの提供している機能とマッチしない場合、カスタム開発と同様に作りこみが必要となるため、あまりパッケージを使うメリットがなくなります。
よって、要件定義前のフェーズなどでFit&Gapをし、本当にSalesforceを使うべきか診断することは非常に大事です。
（Salesforceの仕様に詳しいメンバーをアサインすることや、クライアントに制約を理解してもらうことが本当に大切です。）

※作りこみ＝以下のようにソースコードをがりがり書きます。（詳しくは書きませんが、作りこみするとなってもそれはそれで色々制約あります。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450298/456fd450-2adc-21cf-e024-e267402b4680.png)

また仮に、以下のようにクライアント要望とSalesforce機能が理論上マッチしても、
Salesforceには多くの制約があるため、クライアントにSalesforceを理解してもらった上で要件定義に入らないと、かなり苦しい要件定義になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450298/60077b36-1661-102a-9eab-a0178ad79c72.png)

例えば、Salesforceの入力画面、参照画面は以下のようなUIになります。
項目を5列表示するとか、ボタンの色を変えるとか、左上にボタンを置くとか、できません。
（Salesfroceは顧客管理ができるが、実際に提供できる画面イメージを見せたところ、ボタンの位置や項目配置列が最大2行などの制約から縦長の画面になってしまうなど諸々の理由により、「これじゃあ業務がまわらないから作りこむしかない」などの結論に達することもあり。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450298/4375111f-a8c6-d693-52a8-739e88d57721.png)




なので、長くなってしまいましたが、
Salesforce開発とカスタム開発の違いは、（細かいことを抜きにすると、）
すでに提供されている機能を活用しながら開発を進める点で異なります。

また、
　・Salesforceの仕様を知っていること
　・案件を始める前にFit&Gapをして本当にSalesforceを入れるか見定めること
　・クライアントへSalesforce（の主に制約）を理解してもらうことが大事、
となります。
Macでスクリーンショットの保存先を変更する

## 何ですかこれは
macOSのスクリーンショットはデフォルトでデスクトップ(`~/Desktop/`)に保存されますが、以前変更した設定を再変更したので、その手順をメモとして残しておきます。

## 実行時の環境
* macOS Mojave Version 10.14.5
* MacBook Pro (Retina, 13-inch, Early 2015)

## 手順
ターミナルで下記のコマンドを実行する

```sh
defaults write com.apple.screencapture location 任意のディレクトリ(フォルダ) # 保存先を変更する
killall SystemUIServer  # プロセスをkillして設定を読み込ませる
```

筆者の場合は`~/Documents/screenshots/`に保存したかったため

```sh
defaults write com.apple.screencapture location ~/Documents/screenshots/
killall SystemUIServer
```

を実行しました。

## デフォルトに戻したいとき
元の`~/Desktop/`に戻したい時は下記コマンドを実行します

```sh
defaults delete com.apple.screencapture location
killall SystemUIServer
```

## まとめのようなもの
筆者のような片付け下手くそ芸人は、デスクトップを魔境にする前に早いところ保存先を専用フォルダに設定すると良いかと思われます。
nvidia-smiでGPUのメモリ使用量を継続的に監視する

# nvidia-smiでGPUのメモリ使用量を継続的に監視する

データセット訓練中に、CUDAのメモリが足りずにエラー
一体どこでそんなにGPUのメモリを食っているんだ！
nvidia-smiを連打する？

いいや、もっといい方法があるぞ

```bash
#0.5秒毎にnvidia-smiの情報を更新して表示する
watch -n 0.5 nvidia-smi

#上記＋変更点をハイライト
watch -d -n 0.5 nvidia-smi
```
##実行結果

![Screenshot from 2019-10-22 15-46-59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/388647/1d0dc318-e43a-3a51-6df4-35d5dda883f0.png)

では〜
webpackで作成したファイルで__dirnameを使うと'/'が返ってくる問題

タイトルにある問題にけっこうハマってしまいました。
検索でなかなかヒットしなかったため、 簡単ですがメモとして残しておきます。

##__dirnameで'/'が返ってくる
node.jsでパスを取得するやり方はいくつかあります。
\_\_dirnameが実行しているファイルのパス、 process.cwd()は現在のディレクトリのパス、 後はよくpathモジュールを読み込んで使う感じですね。

今回はnpmモジュールを作成しており、 \_\_dirnameの値が欲しかったのですが、 常に'/'が返ってくる状態でした。__filenameは'./index.js'になっていました。

##解決策
process.cwd()などで頑張っても良いですが、 \_\_dirnameが使えないとつらい場合もあります。

おそらくwebpackを使用している方に起きていると思います。

```webpack.config.js
module.exports = {
  target: "node"
  node: {
    __dirname: false,
    __filename: false
  }
}
```
を追加することで正しい__dirnameのパスが取得できるようになります。



参考: [https://github.com/webpack/webpack/issues/1599](https://github.com/webpack/webpack/issues/1599)
【GitHub Pages】404 Not Foundになってしまう場合

<h1> エラー内容はよく読もう </h1>

<h2> エラー内容 </h2>

GitHub Pagesを使ってWebページを作ってみるものの、404 File not Found、、、
![gh-page_Not_Found.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517043/91444950-6bf8-c38f-4e94-0c876385999f.png)

なんでや。
<h2> 原因はファイル名 </h2>
よく見ると次のような記述が。

![gh-エラー内容.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517043/9670bdac-8254-f4e8-9736-314ccac122e8.png)

なるほど、作成したHTMLファイル名をindex.htmlにしていなかったことが原因か。

修正するとすぐに反映され、表示できるようになりました。



<h2> 参考 </h2>
<h3> GitHub PagesでWebページを作るための参考URL</h3>
[GitHub Pages を使った静的サイトの公開方法が、とても簡単になっていた(2016/10/21の記事)](https://www.tam-tam.co.jp/tipsnote/html_css/post11245.html)

こちらの記事でもファイル名はindex.htmlにせよと書いてくれています。
[GitHubでWebページを公開する方法(2014/07/21の記事)](https://qiita.com/Yuki_Yamashina/items/5d8208c450195b65344c)

過去の記事では、SettingsからGitHub PagesのSourceをmaster branchに変更してから保存ボタンを押すと書かれている場合もありますが、保存ボタンはなくなったみたいですね。


<h3> GitHub Pagesで404 File not Foundが表示される場合の参考URL </h3>
ファイル名がindex.htmlでも404 File not Foundが表示される場合もあるみたいです。

再コミットで解消されるケースがあるっぽい。
[GitHub Pagesの作り方（404が出てしまい挫折した人向け）(2019/06/12の記事)](https://qiita.com/KOJI-YAMAMOTO/items/38578a3f4c822a15ef49)


リポジトリを作り直すことも解決策の一つのようです。
[GitHub Pagesが404エラーのまま表示されない場合の対処法(2019/06/11の記事)](https://aoma23.hatenablog.jp/entry/github_pages_404)
自分用メモ(scope,データの読み出し,SQL関連)




scopeは、特定のクエリ使用を効率化するものである。
(何度も同じクエリ記載をしなくて良くなる)(メソッド化する)


RailsではSQLを書かなくて良いが、SQLについて大まかな理解をしていないと、後々しんどそう

##データ検索の基本
データを検索したり、更新するときは「行」と「列」を指定して、データが存在するフィールドを特定する。
##クエリとは
データベースに送る命令のこと

##SQLについて
クエリを書くための言語
リレーショナルデータベースに蓄積したデータを操作したり、定義したりするためのプログラム言語
国際標準化されているので、どのDBでも使える

ここでやる(20日の22時から)
https://www.atmarkit.co.jp/ait/articles/1112/20/news130.html

・できること
大量のデータを効率的に取得・更新・削除・追加できる

##SQLは二つに分類できる(データを操作-DML)(データを定義-DDL)

DML
データ操作に分類する文法をDMLという(SELECT,UPDATE,DELETE,INSERTなどが基本)
→今回はこっちを深掘りする

DDL
データベースのテーブルの作成や、定義する文法のことを特にDDLと呼ぶ

##SQLでのデータベース操作

##SELECT
(FROMで取得したテーブルの)**カラムを選択して、カラムのデータに処理をする感じ**

FROMでテーブル指定
SELECTの後に取得するカラムを書く(コンマを挟んで複数指定可)(*で全選択)
(SELECT:DISTINCTでデータの重複を除去する)
WHEREで条件指定(レコードの内容で絞り込む)(いろんな条件式使える=とか>とか)
データ抽出時の並び替えも可(ORDER BY)
(末尾)表示する検索結果データをLIMITで絞る

順序
どのテーブルのデータ？(FROMで指定)
テーブルのどのカラムのデータ？(動詞で指定)(SELECTなど)

```
SELECT [表示する要素名(複数指可 A,Bという記載)] FROM [テーブル名];
```
###DISTINCT(重複除去)
SELECT DISTINCT(カラム名)で取得されるカラムの重複をなくすことも可能

###四則演算
SELECT　カラム名*(+=/)数値
複数取得も可　name, price, price*1.1, price*2みたいな感じも可

##テーブル指定のFROMについて
FROMを使って、どのテーブルのカラムかを指定する

##条件指定のWHEREについて
WHEREは条件完全一致しか取得できない、なので部分一致は取得できない
なのでLIKEを使う
WHERE food(カラム名)　LIKE "%プリン(検索単語)%"(%：どんな文字列にも一致することを示す記号)
→foodというカラムで、プリンという文字を持っているデータを全て取得する(焼きプリン・プリン大福・焼きプリン大福も取得)


条件不一致を検出する際はNOTを使う
WHERE NOT　・・・

###NULLの取得
NULL(空のフィールド)を取得したい場合、=ではなく　IS NULLを使う(以外の取得はIS NOT NULL)

###複数の条件を検索したい場合
ANDやORの使用
WHERE　〜　AND　〜;　

###データの並び替え　ORDER BY
ORDER BY 並び替えたいカラム名　並べ方;
ASC(昇順)(小さい数→大きい数)
DESC(降順)(大きい数→小さい数)　

###LIMIT
末尾に記載する
データの検索結果の上から個数を絞る


###DISTINCTで重複を除く

https://guides.rubyonrails.org/active_record_querying.html#scopes
パイプ処理の終了ステータスの取得方法

# パイプ処理の終了ステータスの取得

パイプ処理を行った場合、特殊変数 $? に設定される値は
**一番最後に実行された**コマンドの終了ステータスとなる。

例）

```sample.sh
#!/bin/bash

$ exit 0 | exit 1 | exit 2
$ echo $?
2
```

### パイプ処理の途中のコマンドの終了ステータスの取得方法

パイプ処理の最後のコマンドの終了ステータスではなく、
パイプ処理の途中で実行しているコマンドの終了ステータスを取得したい場合の方法

特殊変数 $PIPESTATUS (配列)を使用することで、
パイプ処理で実行された各コマンドの終了ステータスを取得することができる (※bash 限定で ksh は不可)

```sample.sh
#!/bin/bash

$ exit 0 | exit 1 | exit 2
$ echo ${PIPESTATUS[@]}
0 1 2

# $PIPESTATUS [@]で配列の全要素を出力している
# @を数字に変えれば指定した位置のコマンドの終了ステータスを取得可能
```

### コマンドの実行結果と各コマンドの終了ステータスの両方取得したい

コマンドを実行した後にパイプ処理でPIPESTATUSをexitで終了ステータスを指定する

```sample.sh
#!/bin/bash

result=`exit 1 | echo "test"`
echo $?
echo $result

result=`exit 1 | echo "test2" ; exit ${PIPESTATUS[0]}`
echo $?
echo $result

#出力結果
0
test
1
test2
````




※備忘録のためわかりにくい部分ありましたらコメントください
コマンドプロンプトだけでBase64エンコードをする

# WindowsでBase64エンコードしたい

文字列をBase64でエンコードしたい時がたまにあります。

Windowsの場合、 `certutil` コマンドを利用すれば、新たなソフトをインストールせずにコマンドプロンプトだけでエンコードすることができます。

`certutil` に関する情報は多く見つかるのですが、意外とコマンドのみで完結する手順が記載されている記事が見当たらなかったため、忘れな内に書いてみます。



# 一行にまとめたコマンド

例えば、 `hoge` という文字列をBase64でエンコードしたい場合、以下のコマンドを実行すればよいです。

```bash
echo hoge | more > %temp%\src.txt && certutil -f -encode %temp%\src.txt %temp%\dest.txt && type %temp%\dest.txt
```

これで、以下のような文字列が出力されます。

```
-----BEGIN CERTIFICATE-----
aG9nZSANCg0K
-----END CERTIFICATE-----
```

`aG9nZSANCg0K` の部分が、Base64でエンコードされた文字列です。

引き続き、コマンドを解説していきます。



# コマンド解説

上記のコマンドは一行にまとまっていて便利ですが、少し読みづらいので、順番に説明します。


## `hoge` を `src.txt` に出力する

最初の処理はこちらです。

```bash
echo hoge | more > %temp%\src.txt
```

`hoge` という文字列を `src.txt` というファイルに書き込んでいます。

`%temp%` は一時ディレクトリです。Windows 10 の場合、 `C:\Users\ユーザー名\AppData\Local\Temp` になります。
今回の `src.txt` のように、使い捨てのファイルを書き出したりするときに、よく使います。



## `src.txt` をエンコードして `dest.txt` を生成する

次に、 `src.txt` をBase64でエンコードして `dest.txt` を生成します。

```bash
certutil -f -encode %temp%\src.txt %temp%\dest.txt
```

`certutil` はテキストファイルをBase64でエンコードするコマンドです。

以下のサイトを参考にしました。
[WindowsでBase64エンコード/デコードする方法](https://qiita.com/halpas/items/2296cf611a6370f640a3)

この段階で `dest.txt` には以下の文字列が書き込まれています。

```
-----BEGIN CERTIFICATE-----
aG9nZSANCg0K
-----END CERTIFICATE-----
```



## `dest.txt` の内容を表示する

最後に、 `dest.txt` の内容を標準出力します。

```bash
type %temp%\dest.txt
```

これでコマンドプロンプトの画面に、エンコードした文字列が表示されます！



# さいごに
以下のページを参考にさせていただきました。ありがとうございました。

- [WindowsでBase64エンコード/デコードする方法](https://qiita.com/halpas/items/2296cf611a6370f640a3)
- [対象ファイルをBase64でエンコード（デコード）するWindowsバッチ](https://qiita.com/yossiMan/items/c586e31d7c8eaf0f0068)