OmniAICreator/Qiita-1.07M huggingface dataset:
【Firebase / Flutter Web】firestoreEmulatorとローカル実行アプリを接続する。

環境：Mac Catalina 10.15.7
開発対象：Flutter Web
エディター:Visual Studio Code

main.dartで起動コマンドのオプションにより、分岐させる処理を追加する。

```dart
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:cloud_firestore/cloud_firestore.dart';


void main() async {

  const isEmulator = bool.fromEnvironment('IS_EMULATOR');//追記
  print('start(isEmulator: $isEmulator)');

  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();

//以下追記　↓  
  if (isEmulator) {
    /* 起動時にオプションをつけた場合→"--dart-define=IS_EMULATOR=true" */
    FirebaseFirestore.instance.settings = Settings(
      host: 'localhost:58080',//エミュレーターのローカルURL
      sslEnabled: false,
      persistenceEnabled: false,
    );
  }
//ここまで追記　↑ 

  runApp(MyAppHome());
}
```

launch.jsonにオプション付きで登録しておく

```launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "port1234",
            "request": "launch",
            "type": "dart",
            "a,rgs": ["-d", "chrome","--web-port", "1234"],
        },
     //以下追記
        {
            "name": "emu1234",
            "request": "launch",
            "type": "dart",
            "args": ["-d", "chrome","--web-port", "1234","--dart-define=IS_EMULATOR=true"],
        }
    ]
}
```
参考
https://qiita.com/someone7140/items/26fa2f5710b5b36e537f
https://medium.com/flutter-jp/firebase-emulator-938e9a0cdfad
https://www.filledstacks.com/post/how-to-setup-firebase-emulator-with-flutter/
iOSシミュレーターの位置情報を超簡単に更新できるset-simulator-locationでGPSデバッグを快適に

## iOSシミュレーターのGPS情報更新は緯度経度の入力が面倒

最近iOSアプリのGPSの機能をデバッグする機会があり、複数の異なるロケーションで表示をテストしたい場面がありました。
通常シミュレーターのGPS情報は、シミュレーターのナビゲーションメニューから `Features > Location > Custom Location` を選択し、緯度と経度を直接数値で入力する必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17214/2909e78d-1c57-687f-8f48-647e2109cca3.png)
この設定方法だと **いちいちメニューを開くのが面倒** ですし、何より **緯度経度をGoogle Mapsなどで調べ、カンマ区切りの情報を2つの数値に分割してコピペする** という煩雑な作業が発生します :cyclone: 
そのため、以前の私のように「極力位置情報の更新は行わない」という無駄(?)な努力をしている方もいるかもしれません。

## set-simulator-locationは地名で位置情報を検索し設定してくれる神ツール

この作業を楽にする方法がないか調べていたところ `set-simulator-location` というCLIツールを発見したのですが、これが神ツールでした :exclamation:

https://github.com/MobileNativeFoundation/set-simulator-location

インストールはhomebrewかmintに対応しています。

```sh
$ brew install lyft/formulae/set-simulator-location
$ mint install lyft/set-simulator-location
```

インストールしたら、コマンドラインでおもむろに `set-simulator-location -q 地点名` のように打つだけで、なんと **マップで指定位置を検索し、座標を起動中のシミュレーターのロケーションにセットしてくれるのです :laughing:**
検索の機能性がMapアプリと同じなので、日本語などの多言語検索にも対応しているのが嬉しいですね :flag_jp: 
ちなみに裏では[MapKit APIを叩いている](https://github.com/MobileNativeFoundation/set-simulator-location/blob/daee5387946f72346a2f6d7511b0d217e381412a/sources/query.swift#L5)みたいです。

## DEMO `set-simulator-location` を使って位置情報を更新する様子

とりあえず動作の様子を先にみてほしいので動画を貼ります :exclamation: 
![result.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17214/51382015-c442-6799-49e4-c033940e3880.gif)
これなら位置情報の更新がすごく楽になりますね :thumbsup: 

## 使い方

`-q` オプションの引数に地名を与えると、検索と位置情報の設定が可能です。

```sh
$ set-simulator-location -q 東京駅 # 駅名
> Setting location to 35.6810419 139.7672144

$ set-simulator-location -q 富士山頂 # ランドマーク
> Setting location to 35.35975 138.73118

$ set-simulator-location -q Retty Inc # 会社名
> Setting location to 35.65394870599763 139.74173247814178

$ set-simulator-location -q 명동 #　ハングルなどMapKitが対応している入力言語なら何でもOK
> Setting location to 37.5626802 126.9847376
```

なお検索の基準点が日本だと皇居付近で固定されているようで、複数ヒットする可能性があるようなクエリを使うとそこから一番近い場所に飛ぶようになっていました。
ただ詳細な挙動は不明なので、指定コンビニなどをクエリにする場合は店名まで指定する必要がありそう。

```sh
$ set-simulator-location -q コンビニ # 市ヶ谷付近のコンビニがヒットする
> Setting location to 35.691158245798476 139.74538564682007

$ set-simulator-location -q ローソン三田一丁目店
> Setting location to 35.6546947 139.74188

$ set-simulator-location -q ラーメン二郎 # 神田二郎がヒット
> Setting location to 35.6886097 139.7712955
```

もちろん緯度経度を指定することも可能で、その場合は `set-simulator-location -c [緯度] [経度]` で指定します。

```sh
$ set-simulator-location -q 35.6810419 139.7672144
> Setting location to 35.6810419 139.7672144
```

GPS機能のデバッグが捗ること間違いないので、iOSでGPS機能を使って開発する方はインストール必須のツールだと思います :exclamation:
パッケージマネージャ「yarn」を使用してshellを実行する

yarnは起動するスクリプトを制御する事にも使用できます。

#■インストール

```bash
npm install -D npm-run-all
```

#■使用方法

**<font color=blue>npm-run-all</font>**をインストールするとpackage.jsonに記載のスクリプトを「シーケンシャル実行」と「パラレル実行」の指定が可能になります。

```bash
# シーケンシャル
# package.json の dev:test1 を実行してから dev:test2 を実行
run-s dev:test1 dev:test2

#パラレル実行
# package.json の dev を並列に実行
run-p dev:*
```

#■実行サンプル

```package.json
{
  "name": "xxx",
  "scripts": {
    "dev": "run-p dev:*",
    "dev:test1": "echo 1",
    "dev:test2": "echo 2",
    "dev:test3": "echo 3"
  },
  "devDependencies": {
    "npm-run-all": "^x.x.x"
  }
}
```

```bash
# 実行方法
yarn dev
# dev:test1、dev:test2、dev:test3 が全て実行されます
```

#■実行サンプル2（実行したshellから呼び出す）

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

# いろいろ処理を行う

run-p dev:*
```

```package.json
{
  "name": "xxx",
  "scripts": {
    "dev": "/bin/bash startup.sh",
    "dev:test1": "echo 1",
    "dev:test2": "echo 2",
    "dev:test3": "echo 3"
  },
  "devDependencies": {
    "npm-run-all": "^x.x.x"
  }
}
```

```bash
# 実行方法
yarn dev
# startup.shが実行され、dev:test1、dev:test2、dev:test3 が全て実行されます
```

#■関連
https://qiita.com/error484/items/5cf981f40edce6f58b91
[python] dashで「Address already in use」エラーが出たときの解決策かもしれない

困ってる人以外が見ても意味わからんと思いますが、困ってる人には役立つかもしれません。
日本語でググってもすぐに出てこなかったのでメモ。

```
OSError: [Errno 48] Address already in use
```
こんなエラーが出た場合の話。

自分の場合は、下記のようにポートをデフォルトから変えてやることで直りました。

```python
if __name__=='__main__':
    app.run_server(debug=True, port=8051)
```
この後 http://127.0.0.1:8051/ にアクセスすると動いてました

昔Flask使ってた時のものと競合してたのかなぁ？
理由はよくわからんが動けばok。おわり
Raspberry Pi で mosquitto 2.0 を使う

次のページを参考にしました。
[Install mosquitto on Raspberry Pi](https://snapcraft.io/install/mosquitto/raspbian)
[Using the snap package](https://mosquitto.org/documentation/using-the-snap/)

Snap を使ってのインストールになります。

snapd のインストール

```bash
sudo apt update
sudo apt install snapd
```

再起動

```bash
sudo reboot
```

core のインストール

```bash
sudo snap install core
```

mosquitto のインストール

```bash
sudo snap install mosquitto
```

インストールが完了すると、mosquitto は走っています。

```text
$ ps ax | grep mosquitto
 2316 ?        Ss     0:00 /bin/sh /snap/mosquitto/665/launcher.sh
 2339 ?        S      0:00 /snap/mosquitto/665/usr/sbin/mosquitto -c /var/snap/mosquitto/common/mosquitto.conf
 2374 pts/0    S+     0:00 grep --color=auto mosquitto
```

バージョンの確認

```text
$ /snap/mosquitto/665/usr/sbin/mosquitto -h
mosquitto version 2.0.12

mosquitto is an MQTT v5.0/v3.1.1/v3.1 broker.
```

ローカルで pub/sub の確認

```bash:go_sub_mqtt.sh
BROKER="localhost"
#
TOPIC="sample/imageTopic"
#
echo $BROKER
mosquitto_sub -d -t orz -h $BROKER --topic $TOPIC
```

```bash:go_pub_mqtt.sh
BROKER="localhost"
#
TOPIC="sample/imageTopic"
#
echo $BROKER
message='{"name": "sensor3", "temp": 25.5}'
echo ${message}
mosquitto_pub -d -t orz -m "${message}" \
    -h  $BROKER --topic $TOPIC
```

このままでは、外部からはアクセスが出来ないので、設定の変更。
次のファイルを作成します。

```text:/var/snap/mosquitto/common/mosquitto.conf
persistence false
user root
listener 1883
allow_anonymous true
```

mosquitto の再起動

```bash
sudo snap restart mosquitto
```

ログを見るには

```bash
sudo snap logs mosquitto
```

次のバージョンで確認しました。

```text
$ uname -a
Linux violet 5.10.60-v7l+ #1449 SMP Wed Aug 25 15:00:44 BST 2021 armv7l GNU/Linux
```

mosquitto 1.5.7 のインストール方法はこちらです。
[Raspberry Pi で mosquitto を使う](https://qiita.com/ekzemplaro/items/ab90dd630c3ad8e819ab)
通信処理をRxで拡張して怠惰にプログレス表示

# よくあるパターンの通信関連のUI実装は楽をしたい
- 通信中はプログレスを出します。終わったら消します。
- 通信エラーの時は、エラー表示をします。

本当によく実装する内容なので、便利なものを作って、何も考えずに楽に実装して、細かいUI実装に専念していきたいです。
そのほうがみんな嬉しい。

# こんな感じでできると嬉しい。

通信処理を行う実装イメージ

```.swift

let progressTracker: PublishRelay<Bool> = .init()

// UIではこれをsubscribeする
let progress: Signal<Bool> 

someEvent
  .flatMap {
    // 通信処理
  }
  .trackProgress(progressTracker) // progressの表示/非表示
　　　　.trackError(errorTracker) // エラーも似たように
  .toDoSomeOperator
...
```


UI実装箇所のイメージ

```.swift
viewModel.progress
　　.emit(to: SVProgressHUD.rx.isVisible)
 .dispose(by: disposeBag)

```

# 作ってみた
ちょっとgistを使ってみたかったのでgistに書いてみました。
https://gist.github.com/y-hakutaku/0424241d0863893a90f4ce9542a9f3b2
Nelua導入 & チュートリアル

# Neluaとは
公式HP : [Nelua Programming Language](https://nelua.io/)

## 特徴
公式サイトから翻訳して軽くまとめてあります
自分で翻訳するのが面倒な方向けの記事になります．

+ 静的型付け
    + コンパイル時に型チェックが行われ，効率的なバイナリが生成されます．また，コンパイラは型を推論することができます．
+ メモリ効率
    + 手動でメモリ管理を行うことができ，オプションのガベージコレクタはLuaよりも効率的です．
+ Luaフレーバー
    + Luaを知っているならNeluaも書くことができる．同じ構文，セマンティクス，機能，APIを持っています．
+ 安全性
    + 未定義の動作を最小限に抑え，コンパイル時のチェックと実行時のチェックを行うことで，安全な言語を目指しています．
+ C言語にコンパイルされる
    + Neluaのコンパイラは最初にC言語を生成し，それをネイティブコードにコンパイルします．
+ どこでも使える
    + 最小限の依存関係しかないので，ウェブを含め，C言語が利用できるあらゆる環境で使用できます．
+ 自己完結型
    + Neluaは外部ライブラリを使用せず，Cコンパイラがあれば利用できます．

この記事で説明できなさそうな特徴に関しては省略させてもらいました．他にも，メタプログラミングが可能であったり，コンパイラがLuaで書かれているために変更可能である，などの特徴があります．

ロードマップを確認したところ，完全にLuaの機能をNeluaで再現できているわけではなく，これから実装を進めていくつもりのようです．

## Install
公式HPより
筆者の環境はWSL2 Ubuntuです

```
git clone https://github.com/edubart/nelua-lang.git
cd nelua-lang
make install
nelua examples/helloworld.nelua
```

おなじみの hello worldと出ます．

## Tutorial
今度は `--verbose`オプションを付けて実行します．

```
nelua --verbose examples/helloworld.nelua
```

コンパイラによりhelloworld.cというファイルが生成され，そのファイルがgccによりコンパイルされる過程が表示されているはずです．
gcc以外のコンパイラを用いたい場合は， `--cc` オプションを使い，Clangなどのコンパイラを使うことが可能です．

## シンタックスハイライト
現時点では Sublime Text向けに[nelua-sublime](https://github.com/edubart/nelua-sublime) のみが存在しています．他のエディタでは不完全ではありますが，Lua向けのシンタックスハイライトで代用することが可能です．

チュートリアルは以上で完了です．開発途中なのでこれだけしか用意されていないようですが，examplesやtestsが参考になるかと思います．
副業メンバーばっかりの組織でTODOタスクの進捗状況を可視化してみた

## はじめに
この記事では、メンバーの大半が副業かつリモートワークのRimo合同会社にてプロダクトマネージャーをしている @miya1to9 が副業メンバのタスク進捗状況をgithubで可視化している方法について共有します

## 背景
副業メンバーは稼働時間や稼働量が人によって、また時期によってバラバラです
例) 

* Aさんは平日週3で稼働している一方で、Bさんは土日いずれかのみ稼働
* Aさんは今週は本業が忙しいので平日稼働不可


そのため、タイミングによってはプロジェクトの進みが芳しくないことがあります

## 取り組み：TODOタスクの進捗可視化

### 課題

稼働時間も稼働量もバラバラでリモートワークが中心の副業メンバが合計で40人以上もいると、進捗管理が難しく「あれ？Aさんにはいま何のタスクお願いしてるっけ？」「Bさんにお願いしたタスクっていまどうなっているのかな...」となりがちでした。

ただ副業組織では、通常の組織と比べてメンバー各々のTODO管理が特に大事だと思っています。

というのも、副業メンバーは当然ながら本業がメインのため、必ずしもRimo合同会社のビジョンやミッションを深く理解してくれているとは限りません。
そのため、例えタスクが振られていなくても会社のビジョンやミッションに合わせて自らタスクを見つけて自走する、といった、いわゆる一般的な企業で求められている行動が構造上起こりにくいです。

### 解決策
そこで、副業メンバ各々のTODOタスクの進捗を可視化した上で

* あるメンバにアサインしたタスクが完了していて指示待ち状態であれば追加のタスクをお願い
* タスクをアサインしたものの進捗連絡や進め方の相談がないまま長時間(目安：１-2週間)経過してしまっているようであればnudgeする(つっつく)

していくことがプロジェクトを前に進めていく上で重要となります。
結論として、Rimo合同会社ではgithubのdiscussionとprojectを活用しています。


### タスク自体 => Issue

* タスク自体はIssueで管理
* 何故やりたいかと何をやるべきかが書かれている

![2021_09_04_19_17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1949528/a3c799f4-9ba6-cd10-334c-47085f01eba3.png)

### メンバーごとのタスク管理 => Discussion


* 各メンバは自身がやることにしたタスクをコメントにて列挙
* 各コメントへのリプライで必要に応じて進捗ヒアリング

![スクリーンショット_2021-09-04_18_55_50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1949528/ea1dedb7-3e2e-0005-d0a6-82435173967e.png)

Issueと違い各コメントに対してコメントを書けるので、タスクごとの進捗を管理できるためDiscussionを利用しています。

### 全体の把握 => Project

* Discussionの各メンバのコメントを参照しカンバン形式で各メンバのタスクを列挙
* 終わったタスクはアーカイブに移す

![スクリーンショット 2021-08-29 17.06.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1949528/80285f7f-232d-ecfa-dd11-3235c3a20382.png)

「XXのリリース」のようなものももちろんプロジェクトで管理していますが、人ごとの進捗もプロジェクトで可視化することで誰かが止まっちゃっているとか、誰かが空いているということがわかりやすくなります。
複数のObservableStateMachineTriggerの順番を知りたい時の小技

#動機
UniRXのObservableStateMachineTriggerが便利だったので何個も使っていたのですが、困ったことがありました。
以下のようなAnimatorからGetBehavioursした時に、どれがどのStateのものか分からなくなってしまったのです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1947827/eaa755be-eae3-f398-66d6-532cf6a2e338.png)

具体的には

```cs
ObservableStateMachineTrigger[] triggers;
animator = GetComponent<Animator>();
triggers = animator.GetBehaviours<ObservableStateMachineTrigger>();

//State1
triggers[0].OnStateEnterAsObservable()
            .Subscribe(_ =>
            {
                //State1の処理
            })
            .AddTo(this);

//State2
triggers[1].OnStateEnterAsObservable()
            .Subscribe(_ =>
            {
                //State2の処理
            })
            .AddTo(this);
```
こんなコードがあったとして、State1がtriggers[0]とtriggers[1]のどっちに対応するのかわからないという状況です。
2個くらいなら間違っても入れ替えれば済むのですが、数が増えると大変ですね...

#力技で解決
多分正しいやり方ではないのですが、とりあえずなんとかなる方法を見つけました。

```cs
AnimatorController animatorController;
ChildAnimatorState[] states;
        
        states = animatorController.layers[0].stateMachine.states;
        for (int i = 0; i < states.Length; i++)
        {
            Debug.Log(states[i].state.name);
        }
```        
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1947827/e0fb3b3b-8662-134a-fda0-0aaf665d4a3d.png)

こんなコードを実行するとDebug.LogにStateの名前が全部出てきます。
この中でObservableStateMachineTriggerがついている物を数えて行けばどのStateがtriggerいくつなのか分かります。

おそらくもっといい方法があると思いますが、とりあえずこれでなんとかなったので書いておきます。
.bash_profile を変更して source コマンドも実行したのに変更が反映されない

# はじめに
**Flutter** の環境構築中にパスを通す場面があり、`.bash_profile`にパスを追記した。
保存して`source`コマンドで変更を反映したけれど上手くいかず、ターミナルの再起動も試したけど上手くいかず。

原因と解決方法を忘れないためにメモ。

# やったこと
### .bash_profile にパスを追加

```bash:.bash_profile
export PATH="$PATH:/Users/ユーザ名/Developer/flutter/bin"
```

### `source`コマンドで変更を反映

```console
source ~/.bash_profile
```

### 変更の反映を確認

```
which flutter
>> flutter not found
```

パスが通っていない。
`source`コマンドで即座に変更が反映されているはずだけれど、とりあえずターミナルを再起動することにした。

再度確認。

```
which flutter
>> flutter not found
```

結果は変わらず。

`.bash_profile`の中身を見てみる。

```
cat ~/.bash_profile
>> export PATH="$PATH:/Users/ユーザ名/Developer/flutter/bin"
```

書いた内容は保存されていた。
でも反映されていない、、、

### シェルの確認
ここで、もしかして自分の使っているシェルって **bash** じゃなくて **zsh** では？と思い、コマンドで確認。

```
echo $SHELL
>> /bin/zsh
```

使っているのが **zsh** なので、いくら **bash** に変更を加えても反映されるはずがなかった。

### `.zshrc`を作成・編集
もともと`.zshrc`ファイルが無かったので、新しく作成した。

```
touch .zshrc
```

**vim** で作ったファイルを編集、パスを追記。

```zsh:.zshrc
export PATH="$PATH:/Users/ユーザ名/Developer/flutter/bin"
```

### 変更を反映

```console
source ~/.zshrc
```

### パスが通っているか確認

```
which flutter
>> /Users/ユーザ名/Developer/flutter/bin/flutter
```

これで無事、パスが通った。

### 終わりに
よく見たら、ターミナルの一番上に普通に **zsh** と書いてあった。
環境設定とかMacのこととか、本当に知識不足なのを改めて反省。
VisualStudioで、同一のソリューション内でプロジェクトをコピーする方法

Visual Studio 2019で、同一ソリューションにあるプロジェクトをコピーする方法。

ソリューションSol1にプロジェクトProj1が存在したとします。
Sol1──Proj1
このProj1からProj2をコピーすることを考えます。
Sol1┬─Proj1
　　└─Proj2
そのままコピーしようとすると、手動でのファイルが多いのでおすすめしません。
一旦、別のソリューションSol2へコピーしプロジェクト名をProj1を追加します。
Sol2──Proj1
その後Proj1をProj2に変更します
Sol2──Proj2
元のソリューショへ追加するという点がポイントです。
Sol1┬─Proj1
　　└─Proj2
めんどうな感じがしますが、手動でのファイル修正を大幅に削減できるのでおすすめです。

## 手順

1.最初の状態。Sol1にProj1が存在している

Sol1──Proj1

2.Sol2を作成し、Proj2フォルダを作成する。Proj1の内容をコピーする

Sol2──Proj1

3.Sol2を開き、ソリューションで、追加＞既存のプロジェクト＞Proj1を選択して追加します。次に、Proj1を名前を付けて保存でProj2とする

Sol2──Proj2

4.Proj2の修正を行う

* ソリューションではなく、Proj2プロジェクトを右クリック＞プロパティ＞アプリケーションの「アセンブリ名」と「既存の名前空間」を変更する。
* 修正したファイルをすべて保存する。必ず、ファイル＞すべて保存　を実施する。

5.Sol2のProj2を削除する。

Sol2──

6.エクスプローラーで、Sol1の下にProj2をコピーします。

7.Sol1を開いてソリューションで、追加＞既存のプロジェクト＞Proj2を選択して追加します。

Sol1┬─Proj1
　　└─Proj2





参照：

[Visual Studio 2019でプロジェクトを複製して別名をつける方法](https://ai-gaminglife.hatenablog.com/entry/2020/05/02/152208)

[Visual Studioのプロジェクトフォルダをコピーして、別名のプロジェクトを作成する。](https://my-web-note.com/vs-project-folder-copy-rename/)
[rails]routes.rbとは？

##初めに

####なぜこの記事を書きたかったのか
・自分の知識を言語化させ記憶に定着させたいから。
・アプリ制作をするのにroutes,controller,model,database,viewをより意識するため。

####環境
・Macbook Air (Retina, 13-inch,2019)
・プロセッサ 1.6GHz デュアルコアIntel Core i5
・メモリ　8GB 2133 Mhz LPDDR3
・MacOS Big Sur　バージョン 11.5.2

####記事の目次
1)what is routes?
2）routesでなにができる？

##what is routes?
プラウザから受け取ったリクエストをチェックしてコントローラへ渡す仕事をしてくれる。
この一文だけだとわからないので、細分化させて考えてみる.

```
（ブラウザからコントローラまでの動き）
１）ブラウザがアクションが生成される（アクション＝oooコントローラのoooアクションが生成）
２）生成されたアクションをroutesへ渡す。
３）事前にroutes内に登録したアクションを探す。
４）ある場合は指定されたcontrollerへ渡す。ない場合はエラーと通告。
５）渡されたらリクエストされたアクションを実行する　。

(イメージ)
１）アクションの地図を生成するスイッチを押す。
２）routesさんへ地図を渡し、場所がわかれば案内してくれて、わからなければそんな場所はないよと怒る。
３）controllerさんの元へ案内したあと、地図に書かれたアクションを実行する。
```
##routesで他に何ができる?
####root to：とroot_pathで遷移先を指定できる(https://qiita.com/janani/items/947b3655de4809f53cad)
####resources、アクションについて(https://qiita.com/janani/items/fb8d3f35ddf06a320c3f)
####ネストについて( https://qiita.com/janani/items/b8aa93c9e7e5e52bf07e )

##最後に
#####routesを使って意識せずとも何がどう動くかはわかっているけど、実際文字として表すと難しい。。。って思いました。ここまで、読んでくださってありがとうございます！
【備忘録】DockerfileでCOPYするときの書き方

DockerfileのCOPY時のディレクトリ指定をどのように書けば良いかわからなかったので、実験してみた。

# ローカルのディレクトリ構成
```bash
$ tree
.
├── Dockerfile
├── dir1
│   ├── sample1.txt
│   └── sample2.txt
└── dir2
    └── sample3.txt
```

# パターンA
```Dockerfile:Dockerfile
FROM node:14.17.6

WORKDIR /app

RUN apt update && apt install tree

COPY . .
```

結果は以下の通り↓

```sh
# tree -A
.
├── Dockerfile
├── dir1
│   ├── sample1.txt
│   └── sample2.txt
└── dir2
    └── sample3.txt
```

# パターンB
```Dockerfile:Dockerfile
FROM node:14.17.6

WORKDIR /app

RUN apt update && apt install tree

COPY ./ .
```

結果は以下の通り↓

```sh
# tree -A
.
├── Dockerfile
├── dir1
│   ├── sample1.txt
│   └── sample2.txt
└── dir2
    └── sample3.txt
```

パターンAと同じになった

# パターンC
```Dockerfile:Dockerfile
FROM node:14.17.6

WORKDIR /app

RUN apt update && apt install tree

COPY ./* .
```

結果は以下の通り↓

```sh
# tree -A
.
├── Dockerfile
├── sample1.txt
├── sample2.txt
└── sample3.txt
```

ローカルのディレクトリ構成を無視して、全てのファイルが同じ階層にコピーされた
Hantek 6022BEのwindows10にインストール

#Hantek 6022BE
6022BEは、帯域幅20MHz、2チャンネル、サンプルレート48MS / sおよび二つプローブを備えた、デジタルストレージオシロスコープです。

![IMG_4783.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675881/ff32006b-155d-74f3-50f2-48f05643c2ea.jpeg)


#インストール方法

#ダウンロード
[Hantekホームページ](http://www.hantek.com/)から6022BEに必要な「<font color="red">Application software</font>」と「<font color="red">Driver</font>」

http://www.hantek.com/


#ドライバーの準備
・デバイスマネージャーを開きます。
・PCに__*Hantek 6022BE*__を接続します。
・ほかのデバイスから「<font color="red">不明なデバイス</font>」を更新を選択します。
・「<font color="red">コンピュータを参照してドライバーを検索</font>」。
・先ほどダウンロードした「<font color="red">Driver</font>」を選択して、インストールします。
・ドライバーが正常に更新されましたドライバーの準備は完了です。


#アプリケーションをインストール手順
先ほどダウンロードしました、softwareファイルから__Setup.exe__をダブルクリックして設定していきます。

デスクトップに
![スクリーンショット 2021-09-04 151438.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675881/b0e3e166-be9e-bc20-6ceb-958ca898fcb7.jpeg)
追加されました。



アプリ画面になります。
![スクリーンショット 2021-09-04 150946.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675881/acb93532-4d90-7fb4-be6b-3487b3d832b3.jpeg)
準備が完了しました。



#インストール手順動画
下の画像を選択すると動画が再生されます。
YouTubeに飛びます。
https://youtu.be/zn1D2km_tFw

[![IMAGE ALT TEXT HERE](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675881/070f874c-0031-2ad5-2b7a-abe9b036a5e0.jpeg)
](https://youtu.be/zn1D2km_tFw)

### 参考
* [Hantekホームページ](http://www.hantek.com/)
[Rails]root to:を使ってroot_pathアクションで遷移先を指定できる

##初めに

####なぜこの記事を書きたかったのか
・自分の知識を言語化させ記憶に定着させたいから。

####環境
・Macbook Air (Retina, 13-inch,2019)
・プロセッサ 1.6GHz デュアルコアIntel Core i5
・メモリ　8GB 2133 Mhz LPDDR3
・MacOS Big Sur　バージョン 11.5.2

##root to:を使ってroot_pathアクションで遷移先を指定できる
####1)viewでroutes.rbに信号を送るボタンを作る

```rb
<%= link_to "ボタンの名前”, root_path>
```
![rootpath sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102030/5803beef-03bf-4302-16c4-8f19a4c2ac7a.png)

####2)routes.rbにその信号のアクションを設定する

```rb
root to: 'コントローラ名#アクション'
```

![root to sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102030/08fea719-db5e-1ad6-6441-54385aead419.png)

####３）oooo.controller.rbに指定したアクションの命令式を設定
＊下記の場合、命令式は未記入だがindexへ遷移してくださいとなる。

```rb
def index
（命令式）
end
```
![rootpath action sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102030/4032929d-7dad-e1c3-9cdb-00baae4a07be.png)

##最後に
・基礎中の基礎だけどこれでページ遷移したいときは、だいたいこの流れなので大事だと思う！
・読んでくれてありがとう！
Coprime 2 [AtCoder Beginner Contest 215 D]　が解けなかった

#概要
タイトルに書いてある通り。なんとかかんとか解いてみたが計算時間の関係でうまくいかなかった
やり方としては
Aiの最大の素数を羅列する
→それらをAiの全数の素因数かどうか判定する
→素因数のものの定数倍のものを与えられたKから除く

だいたいTEになったり間違っていたりした。あきらめて解説のものをコーティングしなおす

#コード
```rust:main.rs
use std::time::{Duration, Instant};


fn era(m:i32) -> Vec<i32>{
 let n =m as usize;
  let mut count :i32 =0;
  let mut torf = vec![1; n];

    for j in 1..( (n+1)){
     if torf[j] == 1{ 
      for i in 2..(n/2){
          if (j+1)*i <= n {
          torf[((j+1)*i -1) as usize] =0;
          }else{break}
        }
      }
      count+=1;
      if count *count> n as i32{

        break}
    }

    torf
}


fn mat (v: Vec<i32>  ) -> Vec<i32> {//k mean vector.len()

  let maxn = v.iter().max().unwrap();
  let mut temp:Vec<i32> = Vec::new();
  let mut p_num :i32;

  for (i,j) in (era(*maxn)).into_iter().enumerate(){
    p_num =i as i32;
        if j == 1{
          for k in &v{
            if k < &((&p_num +1)){
            continue
            }
            if k % (p_num +1)  ==0{
            temp.push(p_num +1 );
            break
            }
        }
      
    }

  }

  temp
}

fn main() {
  /*
  input! {

    n:usize,
    m:i32,
    v: [i32; n]
  }
  for i in 0..10{
  v.push(i*(i+1));
}
*/
let mut v:Vec<i32> = Vec::new();
for i in 0..500{
  v.push(i*(i+1));
}

let mut v= vec![6,1,5];
let n = v.len() as usize;
let m =  12 as i32;

  let mut ans:Vec<i32> = Vec::new();
  let mut torf = vec![1; m as usize];


let mut p = mat(v);




  if p.len() !=1{
    p.remove(0);
    }

  for i in &p{
    for j in 1..(m/2) {
      if j*i <= m {
      torf[(j*i -1) as usize] =0;
      }else{break}

    }
  }

 for k in 0..(m) as usize{
   if torf[k] == 1{
     ans.push( (k+1) as i32);
   }
 }

 println!(" {}",ans.len());
 for x in ans{
 println!(" {}",x);
 }

}

```

これのソースをまんまrustに移植した
https://kanpurin.hatenablog.com/entry/2021/08/21/232035

```
use std::time::{Duration, Instant};

fn main() {
  /*
  input! {

    n:usize,
    m:usize,
    v: [usize; n]
  }

*/
let mut v:Vec<usize> = Vec::new();
for i in 0..5000{
  v.push(i*(i+1));
}

//let mut v : Vec<usize>= vec![6,1,5];
let n = v.len() as usize;
let m =  1200 as usize;

  let mut ans:Vec<usize> = Vec::new();
  let mut maxn = *v.iter().max().unwrap() as usize;
  if m > maxn{
    maxn = m;
  }
let mut KK = vec![1; maxn+1 as usize];
let mut isprime = vec![1; maxn+1 as usize]  ; 
let mut prime:Vec<usize> = Vec::new();


for a in v{
  KK[a] = 0;
}
//era
for i in 2..(maxn+1){
  if isprime[i] == 0{
    continue
  }
  //
  for j in 2..(m){
    let p_j = j*i;
    if p_j <= (maxn) {
      isprime[p_j] = 0;
      //
      KK[i] = KK[i]*KK[p_j];
    }else{break}

  }
  if KK[i] == 0{
    prime.push(i);
  }
}


for p in prime{
  for j in 2..(m){
    let p_num = p*j;

    if p*j <= (m){
      KK[p_num] = KK[p] * KK[p_num];
    }else{break}
  }
}

ans.push(1);
for i in 2..(m+1){
  if KK[i] ==1{
    ans.push(i);
  }
}



 println!(" {}",ans.len());
 for x in ans{
 println!(" {}",x);
 }

}
```
無事クリア。
二分探索法について　値の探索(paiza)

# はじめに
paiza問題集　二分探索　値の検索（PHP編）を解いたので二部探索について自分用にまとめる。

[二分探索 値の検索](https://paiza.jp/works/mondai/binary_search/binary_search__basic_step0)


# 二分探索法とは？
探索の代表的なアルゴリズムの一つ。
探索対象のデータ群が***「昇順」***または***「降順」***に並んでいる場合に使用できる。
二分探索法は、データ群をざっくりと二つに分けながら対象を絞り込んでいく探索法。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381376/ef2cafbb-62b4-527b-7c92-f2ba73c0d477.png)

上記画像の例で説明すると
まず、配列の真ん中の値である「7」と今回検索したい「9」を大小比較する。
9のほうが大きいため、探索範囲を右半分に絞る。
次の探索範囲の真ん中の値である「11」と検索したい「9」を大小比較する。
9のほうが小さいため、探索範囲を左半分に絞る。

このように繰返し真ん中の値と比較して範囲を狭めていき対象を絞り込む。
そのため、昇順あるいは降順であらかじめソートされていないとこの探索法は使えない。

***参考***
・キタミ式イラストIT塾 基本情報技術者 平成31/01年　
(Capter16-8 データを探索するアルゴリズム)

# 実際の問題

> 〇問題文
ソートされた数列 A = (A_1, A_2, ..., A_n) と、q 個の整数 k_1, k_2, ..., k_q が与えられます。各 k_i について、数列 A に含まれているなら Yes と、含まれていないなら No と出力してください。
なお、n, q の最大値はいずれも 200,000 です。


> 〇条件
・ 入力はすべて整数
・ 1 ≦ n ≦ 200,000
・ -10^9 ≦ A_i ≦ 10^9 (1 ≦ i ≦ n)
・ A_1 ≦ A_2 ≦ ... ≦ A_n
・ 1 ≦ q ≦ 200,000
・ -10^9 ≦ k_i ≦ 10^9 (1 ≦ i ≦ q)


今回、nとqは最大200000個まで存在するということなので、もし線形探索法で行うと計算量がO(n)であるため、最大200000 × 200000 回処理をする必要がある。
→そこで二部探索法を使用する。

***〇計算量***
線形探索法　O(n)
二分探索法　O(logn)



# 実装

```php
//入力値の取得
$n = trim(fgets(STDIN));
$array = explode(' ', trim(fgets(STDIN)));
$q = trim(fgets(STDIN));

//二分探索
for ($i = 0; $i < $q; $i++) {
    $left = 0;
    $right = $n-1;
    $value = trim(fgets(STDIN)); //検索したい値
    $flag = false;
    
    while ($left <= $right) {
        $mid = floor(($left + $right) / 2);
        if ($array[$mid] == $value) {
            $flag = true;
            break;
        } elseif ($array[$mid] < $value) {
            //検索したい値が真ん中のデータより大きい場合、左端の範囲を更新する
            $left = $mid + 1;
        } else {
            //検索したい値が真ん中のデータより小さい場合、右端の範囲を更新する
            $right = $mid - 1;
        }
    }
    
    if ($flag) {
        echo "Yes";
    } else {
        echo "No";
    }
    echo "\n";
}
```

# まとめ
今回は二部探索法の問題を解いた。
基本情報で昔勉強したことを思い出した。実際にコードを書いてみるとより理解が深まって勉強になった。
Paizaの問題でレートが上がってくると、データ量が多くなってきて線形探索では規定時間内に処理が終わらないため、様々なアルゴリズムについて引き続き学習していきたい。
with_indexメソッドについて

皆様こんにちは、プレイライフの熊崎です！

本日２本目の記事はwith_indexメソッドについて書こうと思います。

## with_indexメソッドとは
> 生成時のパラメータに従って、要素にインデックスを添えて繰り返します。インデックスは offset から始まります。
ブロックを指定した場合の戻り値は生成時に指定したレシーバ自身です。
参考URL： https://docs.ruby-lang.org/ja/latest/method/Enumerator/i/with_index.html

## どのようなタイミングで使用するのか？
→ 繰り返し処理の最中に、index（添字）を使用したいとき

### 具体例
あるイベントの開催候補日の配列を、`第一希望： 2021年9月５日`のように、添字も含めた文字列を表示したいとき

```sample.rb
candidate_dates = ['2021年9月5日', '2021年9月6日', '2021年9月7日']
candidate_dates.each.with_index(1) do |date, index|
  p "第#{index}希望：#{date}"
end
#=> "第1希望：2021年9月5日"
#   "第2希望：2021年9月6日"
#   "第3希望：2021年9月7日"
```

## 特徴

- 開始番号を指定できるため、直感的にわかりやすいコードをかける。
- mapメソッドやselectメソッドなどにも使用できる。

### 開始番号を指定できるため、直感的にわかりやすいコードをかける。

```sample.rb
# each_with_indexを使用した書き方
fruits.each_with_index do |fruit, index|
  p "私が#{index + 1}番目に好きな果物は#{fruit}です。" # 開始番号を指定できないため、 index + 1と書く必要がある。
end
#=> "私が1番目に好きな果物はリンゴです。"
#   "私が2番目に好きな果物はオレンジです。"
#   "私が3番目に好きな果物はバナナです。"

# each.with_indexを使用した書き方
fruits.each.with_index(1) do |fruit, index| # 開始番号を指定できるので、こちらの方が直感的にわかりやすい
  p "私が#{index}番目に好きな果物は#{fruit}です。" 
end
#=> "私が1番目に好きな果物はリンゴです。"
#   "私が2番目に好きな果物はオレンジです。"
#   "私が3番目に好きな果物はバナナです。"

```

### mapメソッドやselectメソッドなどと組み合わせて使用できる。

with_indexメソッドはEnumeratorクラスのメソッドのため、Enumeratorオブジェクトを返すmapメソッドやselectメソッドなどと組み合わせて使用することができる。

```sample.rb
candidate_dates = ['2021年9月5日', '2021年9月6日', '2021年9月7日']
candidate_dates.map.with_index(1) do |date, index|
  "第#{index}希望：#{date}"
end
#=> ["第1希望：2021年9月5日", "第2希望：2021年9月6日", "第3希望：2021年9月7日"]
```

## まとめ

- mapメソッドやselectメソッドにもindexを振れる。
- each_with_indexと違って、開始番号を指定できる。
- 繰り返し処理の中で添字を使用したい場合に使われる。

## 参考資料

- https://docs.ruby-lang.org/ja/latest/class/Enumerator.html#I_WITH_INDEX
- https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/each_with_index.html
Windows11 + WSL2 + DockerDesktop+GPU(Nvidia)+Jupyterlabの環境構築方法

#はじめに

本記事は私がタイトル通りの環境を構築するために行ったことのまとめです。

※2021年9月4日現在の内容です。

#構成
OS:Windows 11 Homes Insider Preview 22449.1000
WSL2:ubuntu 20.04LTS
Docker:version 20.10.8

#手順
1.Windows10 Insider Preview Buildのインストール
2.WSL2のインストール
3.Docker Desktopのインストール
4.Nvidiaドライバをインストール
5.NGCコンテナイメージにいろいろとオプションを付けてコンテナを作る
#手順1~4
手順1~4に関して windows上のWSL2でCUDAを使用する環境構築の手順を説明してくれているこちらの記事や

https://qiita.com/ksasaki/items/ee864abd74f95fea1efa


Nvidiaさんが直々に説明してくれているこちらのサイト

https://docs.nvidia.com/cuda/wsl-user-guide/index.html#release-notes

を参考に構築してみて下さい。windows11で環境構築を行っても問題ありませんでした。

#手段5
ここからが本題。
windows+dockerでGPU対応のJupyter labを動かしたいが、以下の記事を参考に環境構築を行ってみたがどうにも上手くいかない。Dockerコンテナ内でJupyter Labは立ち上がるものの、Windows上のブラウザでJupyter Labを表示することができない。以下の記事の内容が決して悪いわけではなく、両記事の環境構築までの手順が多く、どこかで自分がミスってる可能性が高い。


https://qiita.com/gonzou122/items/7b5e74d7c4c5f3e969af

https://zenn.dev/mosamosa/articles/b187cb5380be87


<br>


「もっと簡単できないもんかな～」と考えるのが人間の性。他の記事を探していると、以下の記事(WSL2は関係なく、ただ単にDocker上でJupyter Labを起動してhttp://localhost:8888 でJupyter Labを利用するもの）を発見。

https://qiita.com/ao_log/items/5438f2aaf5c2b46d2ccb

ものは試しに、記事内で紹介されているdocker コマンドを

```php
docker run --rm --name jupyter -d -p 8888:8888 \
    -v `pwd`/workspace:/workspace -w /workspace \
    continuumio/anaconda3 \
    jupyter-lab --no-browser --port=8888 --ip=0.0.0.0 \
    --allow-root --NotebookApp.token=''
```
以下のように"--gpus all"の追加と、anacondaコンテナイメージではなく、NGCコンテナイメージに変更して起動した。

```php
 docker run --gpus all --rm --name jupyter -p 8888:8888\
     -v `pwd`/workspace:/workspace -w /workspace\
     nvcr.io/nvidia/pytorch:21.07-py3 \
     jupyter-lab --no-browser --port=8888 --ip=0.0.0.0  \
     --allow-root --NotebookApp.token=''
```

すると、windwos上のchromeブラウザで http://localhost:8888 にアクセスすると、Jupyter Labを利用できるではないか。しかも、torch.cuda.is_available()もTrueを示している。

「粉砕！玉砕！大喝采！」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324917/9b900c9e-c58f-24e2-228f-6e91200fdd27.png)

タイトル通りの環境を他の類似記事よりもだいぶ簡単に構築ができました。
メモ ... Node.js バージョン管理 (n, npm)


|本シリーズのトップページ|
|:--|
|https://qiita.com/robozushi10/items/1b499030d5462fe7e791|

# 概要

Node.js インストールまでの経路(手順).
なぜ、n と npm の 2つに分かれているのかは知らないが[^1]、遭遇した場合に備えておく.[^2]

## 図

| n 使用時 | nvm 使用時 | 
|:--|:--|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1246056/69e6270d-f875-db02-4fc7-f64dd4bbb0be.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1246056/1257b5e7-745e-3617-5297-c6c81cc78cbc.png)|

## 図の補足

### 上左図「n使用時」について

```bash
#! (1) まず Node.js と npm をインストールする
$ apt install nodejs npm

#! (2) n を使って Node.js をインストールする
$ n stable

#! (3) node -v でバージョンが表示されれば OK
$ node -v
v14.17.6

#! (4) ここで上記 (1) で導入済みの古い版の Node.js をアンインストールしても良い.
#! 恐らく (2) で Node.js をインストールしたタイミングで npm もインストールされているので、
#! 旧版である (1) の Node.js と npm を削除しても問題無い.
$ sudo apt purge -y nodejs npm

```

### 上右図「nvm使用時」について

```bash
#! (1) nvm をインストールする
$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash

#! (2) nvm を使って、Node.js をインストールする (npm も同時にインストールされる)
$ nvm install --lts
```
　

以上.


[^1]: 言語は異なるが、Python で pyenv, venv, pipenv, anaconda, conda, docker に遭遇してきたので、善し悪しの話よりも使える状態に持っていくことが優先である

[^2]: 実際、2021/09 時点では稀 (年間にして 1week ほど) にしか JavaScript や Node.js を使わないため、これらを使用するときには毎回 n、npm のメモを毎回読み返している.
UMTP-L1試験合格

UMTP-L1の試験に合格しましたので、共有致します。
今後受ける方の参考になれば幸いです。

#動機
- UML図を理解することで、作業効率UPを図るため
- 徐々に設計のタスクが任されるようになったこともあり、正しい表記法を理解しておきたいから

#前提知識
- シーケンス図を少し見たことある程度
- Java言語を学んだことがあるので、オブジェクト指向の知識はある

#勉強期間と方法
３週間程度

参考書：[[改訂版] UMLモデリング技能認定試験<入門レベル(L1)>問題集 -UML2.0対応](https://www.amazon.co.jp/%E6%94%B9%E8%A8%82%E7%89%88-UML%E3%83%A2%E3%83%87%E3%83%AA%E3%83%B3%E3%82%B0%E6%8A%80%E8%83%BD%E8%AA%8D%E5%AE%9A%E8%A9%A6%E9%A8%93-%E5%85%A5%E9%96%80%E3%83%AC%E3%83%99%E3%83%AB-%E5%95%8F%E9%A1%8C%E9%9B%86-UML2-0%E5%AF%BE%E5%BF%9C/dp/4774132454/ref=pd_sbs_14_img_0/355-5751850-0748217?_encoding=UTF8&pd_rd_i=4774132454&pd_rd_r=8b15cb9a-cb0d-40cb-ba2a-e80ddd8dc137&pd_rd_w=Bu6WE&pd_rd_wg=VILBK&pf_rd_p=ca22fd73-0f1e-4b39-9917-c84a20b3f3a8&pf_rd_r=FFK7RN7ZK0CFQA31YYGG&psc=1&refRID=FFK7RN7ZK0CFQA31YYGG)

- ↑を３週くらい
- L1-T2のみが本試験の対象になるが、前提知識がなかったので、T1も学習。
- １週目は、概要を掴むために、教科書部分のみをざっと見る。２週目から、問題も解く。
  - 暗記ではなく、なぜこのような書き方になるのか、解説を読んで理解する。
- その日に学習する章を決めることで、集中できる。

動画：[L1セミナーの動画視聴](https://umtp-japan.org/)（１回視聴のみ）

#結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1390683/79e6fe22-6f2d-72db-f2f9-692b3e055042.png)


#まとめ
暗記の試験ではないので、教科書部分や問題の解説を読み、よく理解してから受けることをオススメします。試験を受けてみて、「構造モデリング」と「振る舞いモデリング」は特に理解しておいた方が良いのかなと思いました。

また、時期を見つけて、UMTP-L2の試験を受けようと思います。
取り敢えず受かって良かった〜

最後まで読んで頂きありがとうございました。
go で構造体を比較したい時に、気軽に== を使って比較する前に、ポインタ型か、そうでないかをちゃんと確認しようね。

# golang における 「==」 の特性
golang における「==」 は、基本的には対象の同一性をみてtrue/false の判断をする。

ただ、比較する対象がポインタ型でない場合は同値性で判断してくれることもある

例えば
https://play.golang.org/p/E1Fty3pkKYI

```go
package main

import (
	"fmt"
)

func main() {
	nameA := FullName{"ヤマダ", "太郎"}
	nameB := FullName{"ヤマダ", "太郎"}
	nameC := FullName{"吉田", "太郎"}

	fmt.Println(nameA == nameB)　 // true
	fmt.Println(nameA == nameC) // false
}

type FullName struct {
	FirstName string
	LastName  string
}

```

このように、nameA, B, C にはFullName 型が入っており、その中に入れられたfirstName, LastName を比較してtrue/false をみてくれる

## ポインタ型の比較
一方で、ポインタ型を使った時の比較はどうか？

https://play.golang.org/p/8GDYk0ToXq-

```go
package main

import (
	"fmt"
)

func main() {
	nameA := NewFullName("ヤマダ", "太郎")
	nameB := NewFullName("ヤマダ", "太郎")
	fmt.Println(nameA == nameB) //false
}

type FullName struct {
	FirstName string
	LastName  string
}

func NewFullName(FirstName, LastName string) *FullName {
	return &FullName{
		FirstName,
		LastName,
	}
}
```

FullName型 のポインタ型を返却するNewFullName を使用して作成した値を比較すると比較対象の同一性を確認するようになる。
もちろん格納されているアドレスが異なるため、false になる
だが、NewFullName という関数からはポインタ型を返却することが読み取れないため、"ヤマダ", "太郎" という値が一致していることを期待して比較を行うと、意図せずfalse を返却する処理になってしまう。

# 結論
golang の比較は基本的には同一性の比較になっていることを忘れないように。
もしどうしても同値性で比較を行いたいのであれば、`reflect.DeepEqual` を使用すること。
WSLにgenieを導入しているとIntelliJ IDEAのターミナルがプロジェクトディレクトリで開かない問題

# はじめに
WSLにgenieを入れている方、そこそこいるのではないかと思います。 
genieとはWSLで`systemd`を`pid1`で実行させるためのツールで、`systemctl`を使うために導入します。
genieについては以下のページが詳しいです。

https://qiita.com/matarillo/items/f036a9561a4839275e5f

# 問題点
genieを使う際は基本的に`genie -s`を実行してシェルに入ります。
通常の使い方ではprofileファイル等にコマンドを書いておいて、自動的に`genie`の環境に入るようにすると思います。
しかし、**`genie -s`は必ずホームディレクトリでシェルを実行され、環境変数を引き継ぎません**。
これにより、IntelliJ IDEAのターミナルにWSLを指定していた場合に、
プロジェクトディレクトリではなくホームディレクトリが開かれてしまい、少々不便です。

# 解決
`genie -s`ではなく`genie -c`を使うことで解決できます。
以下の通り、`-s`はシェルを実行しますが、`-c`はコマンドを実行します。
そして、`-s`と違って`-c`はカレントディレクトリや環境変数を保持します。

```sh
Commands:
  -s, --shell                Initialize the bottle (if necessary), and run a shell in it.
  -c, --command <COMMAND>    Initialize the bottle (if necessary), and run the specified command in it.
```
※ `-c`と`-s`以外は省略しています。

ということで、実際に設定するコマンドは以下のようになります。

```powershell
wsl.exe genie -c "bash"
```

これをIntelliJ IDEAのターミナル設定の`Shell path:`部分に入力しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283028/5da9164b-3d9c-327b-84c9-0c918b00358e.png)

以上でターミナルがプロジェクトディレクトリで開くようになります。

# おわりに
IntelliJ IDEAがWSLに対応する前からgenieを入れていたため、
これに気づくまではずっとIntelliJ IDEAのバグなんだと思っていました😅
PCが変わり、WSL環境を新たに構築する際にやっと`genie`が原因だと気づきました。
安易にツールのバグだと思い込むのは良くないですね🥺

# 参考
arkane-systems/genie
https://github.com/arkane-systems/genie

"Open a linux shell" and genie
https://github.com/arkane-systems/genie/wiki/%22Open-a-linux-shell%22-and-genie
11 Steps：SourseTreeとGithubのSSH接続方法（For Mac）

初心者向け、ターミナルやGithub使えない人も操作できるように編集しました。
いくつか他の方の記事を参考にして設定をしましたが、途中でどこかが違うってなったので、自分のパソコンでうまくいった手順をまとめました。参考した記事は一番下に掲載してます。

（準備：SourseTreeとGithubダウンロードしログインしてください）

$はターミナルでの入力

1️⃣
Macのターミナルを開いてください。

<code>$ ssh-keygen -t rsa -C </code>
と入力してください。

まずはSSH認証の公開鍵と秘密鍵の作成です。

2️⃣

<code>Enter file in which to save the key (/Users/name/.ssh/id_rsa):</code>
と表示が出てきます。

Enterを押してください。（保存場所の確認）

3️⃣

<code>Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/name/.ssh/id_rsa.</code>

Enterを2回押してください。（パスワード設定、空でもいいのでEnter）

4️⃣

<code>$ cd ~/.ssh
$ ls
id_rsa      id_rsa.pub</code>

鍵の場所へ移動します。

（id_rsa: 秘密鍵、id_rsa.pub: 公開鍵）

5️⃣

<code>＄chmod 600 id_rsa</code>

秘密鍵の権限設定をします。

6️⃣

<code>$ open ~/.ssh/config</code>

configファィルの設定（中身を下のように編集してください）

Host    github.com
HostName github.com
User git
PreferredAuthentications publickey
IdentityFile  ~/.ssh/id_rsa
UseKeychain yes
AddKeysToAgent yes

7️⃣

<code>$ pbcopy < ~/.ssh/id_rsa.pub</code>

これで公開鍵をコピしました

8️⃣

Githubへ移動します。

「Github」→「Seetings」→「SSH and GPG Keys」

先ほどコピーしたKeyーを貼り付ける

![スクリーンショット 2021-09-03 19.16.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1977044/f5d7e1d7-15c9-e721-a623-cd27f19ee85f.png)

9️⃣

<code>＄ssh git@github.com </code>

githubへ接続する

1️⃣0️⃣

クローンしたいファィルのSSHをコピーする
![スクリーンショット 2021-09-03 19.21.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1977044/eeaf609c-304d-c531-61b3-58a3278811c9.png)



1️⃣1️⃣

コピーしたURLをsoucetreeにペースト

「新規」→「URLからクローン」→「ソースURL」


![スクリーンショット 2021-09-03 19.26.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1977044/77a13d82-1936-55cd-384a-269d893dfdc4.png)


これで完了です、おめでとう🎉


参考記事：
https://kumaskun.hatenablog.com/entry/2019/10/20/225335
https://qiita.com/evitch/items/5d87b8aab5cd72695d2b
https://note.com/nviveto/n/n66546cbb6334
ありがとうございました！
GitとGitHubを基本からまとめてみた【6】【React 最初からデプロイまで / GitHub Pages】

## デプロイとは
インターネット上に公開するということ。

## GitHub Pagesとは
『GitHub Pages』とは、GitHub のリポジトリから HTML、CSS、および JavaScript ファイル を直接取得し、任意でビルドプロセスを通じてファイルを実行し、ウェブサイトを公開できる静的なサイトホスティングサービスのこと。

## reactのプロジェクトを作成する

```
terminal
$ create-react-app <プロジェクト名> 
```

## GitHubPagesを使用してデプロイをする
(1) Githubでリポジトリを新規作成する。

(2) GitHubにログインし、Repositoriesタブを選択。『New』をクリックする。

(3)『Repository name』を記入し、『Create repository』をクリックする。

(4)terminalで『git init』を行う

```
$ git init
```
(5)terminalで『git remote add origin』を行う

```
$ git remote add origin『HTTPS』or『SSH』
```
(6)terminalで コードをaddする。

```
$ git add .
```
(7)terminalで コミットする。

```
$ git commit -m "コミットメッセージ"
```
(8)　master(もしくはmain)ブランチにプッシュする。
　（githubの仕様に変更があり、デフォルトで作成されるブランチの名前が「master」から「main」に
　　変更。githubのデフォルトで作成されているブランチ名を確認すること。）

```
// masterブランチにpushする場合
$ git push origin master

// mainブランチにpushする場合
$ git push origin main
```
(9) Github『Setting』を選択し、GitHub Pagesの『Check it out here!』を押す。

(10)SourceをBranch masterを選択し、『Save』を押すとマスターアドレスを表示される。

(11)terminalで、yarn add gh pagesをインストールする。

```
$ yarn add gh-pages
```
(12) インストールが終わったら、package.jsonに"gh-pages":があるか確認し、編集する。

```package.json
//...
"homepage": "http://username.github.io/react-github-pages"
※ "dependencies": {　}の中には記載しない事!!

"scripts": {
  //...
  "predeploy": "npm run build",
  "deploy": "gh-pages -d build"
}
```
(13)デプロイする

```
$ npm run deploy
```

## 参考サイト
[React 最初からデプロイまで① GitHub Pages編]
(https://www.youtube.com/watch?v=Zb-JaSyVnyk&t=600s)
[GitHub PagesにReactアプリをデプロイする方法]
(https://qiita.com/yuitnnn/items/11375ea29ec023d19fdf)
【Android】Google Play Consoleで広告表示設定の変更をする

左メニューの「ポリシー」→「アプリのコンテンツ」
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694762/048c3f2a-3d0b-6238-df48-2afbb4274627.png" width="30%">

「広告」から現在の広告表示情報を変更
![スクリーンショット 2021-09-04 15.51.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694762/f50ba1c7-dbb3-b65f-3a4a-d4e5180af289.png)
[備忘録]@pageはscopedが効かない


nuxt.jsで作成しているWebアプリにて、あるページの印刷プレビューで横向きにしたかったので以下のように`@page`で向きを指定していました。

```css
<style lang="scss" scoped>
@page {
  size: landscape;
}
</style>
```

ただ、このページを表示した後に別のページで印刷プレビューを開くと横向きになってしまってました。
調べてみたところ、`@page`を指定した場合はグローバルなstyleタブで定義されており、scopedが効いていないことが分かりました。


# 対策

javascriptで対象ページのライフサイクルメソッドで動的にスタイルを付与／削除します


```typescript
  created() {
    const style = document.createElement('style');
    style.id = 'print-rotated-page';
    style.innerHTML = '@page { size: landscape }';
    document.head.appendChild(style);
  }

  destroyed() {
    const styles = document.head.getElementsByTagName('style');
    for (let i = 0; i < styles.length; i++) {
      if (styles[i].id === 'print-rotated-page') {
        document.head.removeChild(styles[i]);
      }
    }
  }
```
SEO対策のまとめ

こんにちは。

SEOって最近よく耳にする言葉ではないでしょうか？

SEOっておそらく検索順位に関することだとわかっている人は多いと思いますが、
詳しい内容を理解している方は限られてくると思います。

今回はそんなSEOの初心者でも分かる記事を下記のサイトで公開しておりますので
もし宜しければご覧ください。

<a href="https://portal-th.com/archives/97">SEOの基本やトレンドをわかりやすく解説！</a>


<h3>SEOの基本やトレンドをわかりやすく解説！</h3>
<ul>
<li>SEOとは？</li>
<li>検索エンジンにきちんとWebサイトの内容を理解させること</li>
<li>SEOのメリット</li>
<li>SEOのデメリット</li>
<li>SEOの施策の種類</li>
<li>v2020年のSEO対策の最新トレンドを紹介</li>
<li>vE-A-T</li>
<li>SERPs</li>
<li>利用をおすすめ！Googleが提供する解析ツールを2つ紹介</li>
<li>Google Search Console</li>
<li>Google Analytics</li>
<li>vSEOの外部対策（被リンク対策）をすることとは</li>
<li>質の高い被リンクを集めるための施策</li>
<li>SEOの基本やトレンドのまとめ</li>
</ul>

最新のSEO情報も盛り込んでいるので宜しければご覧下さい。

<a href="https://portal-th.com/archives/97">SEOの基本やトレンドをわかりやすく解説！</a>
【デザインパターン】JavaScriptで学ぶCommand

#はじめに
現在デザインパターンについて勉強中です。
今回はCommandついてまとめました。

https://qiita.com/suzuki0430/items/d44a83c500993a763c1d

https://qiita.com/suzuki0430/items/abbb433fd49e356e8643

#Command
Commandはリクエストに必要な処理をオブジェクトとしてカプセル化し、必要に応じて実行するための、振る舞いに関するデザインパターンの一つです。
リクエストの処理と実行を分離することで、命令のキューイング、ロギング、アンドゥなどが可能になります。

例えば、プログラム内の全てのユーザの操作がCommandオブジェクトとして実装されれば、プログラムは最近実行されたコマンドのスタックを保持することができるようになります。
ユーザがコマンドをアンドゥする際、プログラムは最後に実行されたCommandオブジェクトを取得(pop)し、そのオブジェクトの`undo()`メソッドを実行します。

#実装例
`Command`パターンで銀行でのお金の預貯金機能を実装します。
リクエストの処理(`deposit`, `withdraw`)を`BankAccount`クラス、実行(`call`, `undo`)を`BankAccountCommand`クラスに実装します。

`BankAccountCommand`で`call()`メソッドを実行する際に、コマンドが成功したかどうかを`succeed`で管理します。
こうすることで、`succeed`がtrueの場合のみ、`undo()`メソッドを実行されるようにできます。

```js
class BankAccount
{
  constructor(balance=0)
  {
    this.balance = balance;
  }

  deposit(amount)
  {
    this.balance += amount;
    console.log(
      `Deposited ${amount}, balance is now ${this.balance}`
    );
  }

  withdraw(amount)
  {
    if (this.balance - amount >= BankAccount.overdraftLimit)
    {
      this.balance -= amount;
      console.log(
        `Withdrew ${amount}, balance is now ${this.balance}`
      );
      return true;
    }
    return false;
  }

  toString()
  {
    return `Balance: ${this.balance}`;
  }
}
BankAccount.overdraftLimit = -500;

let Action = Object.freeze({
  'deposit': 1,
  'withdraw': 2
});

class BankAccountCommand
{
  constructor(account, action, amount)
  {
    this.account = account;
    this.action = action;
    this.amount = amount;
    this.succeeded = false;
  }

  call()
  {
    switch (this.action)
    {
      case Action.deposit:
        this.account.deposit(this.amount);
        this.succeeded = true;
        break;
      case Action.withdraw:
        this.succeeded = this.account.withdraw(this.amount);
        break;
    }
  }

  undo()
  {
    if (!this.succeeded) return;
    switch (this.action)
    {
      case Action.deposit:
        this.account.withdraw(this.amount);
        break;
      case Action.withdraw:
        this.account.deposit(this.amount);
        break;
    }
  }
}
```
以下のように、インスタンスを作って`call()`と`undo()`を実行します。

```js
let ba = new BankAccount(100);

let cmd = new BankAccountCommand(ba, Action.deposit, 50);
cmd.call();
console.log(ba.toString());

console.log('Performing undo:');
cmd.undo();
console.log(ba.toString());
```
すると、`deposit`した分の残高`balance`がアンドゥされたことを確認することができます。

```
Deposited 50, balance is now 150
Balance: 150
Performing undo:
Withdrew 50, balance is now 100
Balance: 100
```

#参考資料

https://www.udemy.com/share/101Bpe3@Wapeed1JE99zGyDGeFWUwPUAL8i7H6iKQ0y-TtL-LINIEnzqVstotj7Ap-XFh22W/
pandas dataframe で ValueError: Timezones don't match.

## Abstract

dataframe の timezone を Asia/Tokyo に設定しているカラムに datetime.timezone で timezone を設定した datetime instance を代入しようとしたら怒られたときのメモ。

```python
# コード詳細は後述
df.at[idx, 'last_modified_at'] = now

(ommit)

/opt/anaconda3/lib/python3.8/site-packages/pandas/core/arrays/datetimes.py in _check_compatible_with(self, other, setitem)
    477             # Stricter check for setitem vs comparison methods
    478             if not timezones.tz_compare(self.tz, other.tz):
--> 479                 raise ValueError(f"Timezones don't match. '{self.tz}' != '{other.tz}'")
    480 
    481     # -----------------------------------------------------------------

ValueError: Timezones don't match. 'Asia/Tokyo' != 'JST'
```

## まずは解決方法から

timezone の設定は datetime.timezone ではなく pytz を使う。

```python
import pytz
JST = pytz.timezone('Asia/Tokyo')
```

## 以下詳細


エラーメッセージを見ての通りだが、両辺の timezone を比較しており、違うと怒られる。

以下、関連する部分のコード抜粋


```python
# read_sql でロードした dataframe のカラムに timezone を設定している
df['created_at'] = df['created_at'].dt.tz_localize(None).dt.tz_localize('Asia/Tokyo')
df['last_modified_at'] = df['last_modified_at'].dt.tz_localize(None).dt.tz_localize('Asia/Tokyo')

from datetime import date, datetime, timedelta, timezone
JST = timezone(timedelta(hours=+9), 'JST')

now = datetime.now(JST)
idx = df[df['id'] == id].index[0]
# エラーになる部分
df.at[idx, 'last_modified_at'] = now
```

上記 JST を生成している部分を datetime ではなく pytz を使うようにしたら正常に代入できた。

```python
import pytz
JST = pytz.timezone('Asia/Tokyo')
```


ちなみに、datetime.timezone の第二引数に 'Asia/Tokyo' を指定してみてはどうかと思ってやってみたが、ダメだった。

単純に名前だけの問題ではないらしい。

比較に使われている timezones.tz_compare を調べればわかりそうだけど、pytz を使えばいいや。


```python
JST = timezone(timedelta(hours=+9), 'Asia/Tokyo')
df.at[idx, 'last_modified_at'] = now

ValueError: Timezones don't match. 'Asia/Tokyo' != 'Asia/Tokyo'
```

なお、tz_localize は 'JST' という指定はできない。


```python
df['created_at'] = df['created_at'].dt.tz_localize(None).dt.tz_localize('JST')
df['last_modified_at'] = df['last_modified_at'].dt.tz_localize(None).dt.tz_localize('JST')

UnknownTimeZoneError: 'JST'
```

なので右辺を合わせてあげよう。


以上
Git commit --amendの使い方と注意点

# 概要

Gitでコミットをした後に「あ、この変更をコミットし忘れた！」ってことあると思います。
そんなときに使える amendという機能について知ったのでまとめます。

# 使い方

1. コミットし忘れたものをインデックスに追加（git add）
2. amendを実行する `git commit --amend`
3. エディタでコミットログが開かれるので必要があれば編集
4. コミットログを閉じるとコミットが更新されている

コミットし忘れたものをインデックスに追加した状態でamendするだけ。
すると、以前のコミットログがGitで設定したエディタで開かれるので
必要があればそのコミットログを編集し閉じると以前のコミットに
コミットし忘れたものが追加された状態でコミットされている。

# 注意点

既にプッシュしてリモートにあげたブランチにamendすると、
皆さんも一度は見たことがあるであろう下記エラーが出ます。

>To GithubのURL
> ! [rejected]        ブランチ名 -> ブランチ名 (non-fast-forward)
>error: failed to push some refs to 'リポジトリ'
>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

プッシュしようとしてもrejectedではじかれてしまうあれです。
一度プッシュしたコミットをamendによって別のコミットにすることで
ローカルとリモートブランチとの間に履歴の乖離が起こることが原因のようです。

```
[amend前]
a-b-c-d <-- origin/branch
a-b-c-d <-- branch
↓
[amend後]
a-b-c-d 　　　　 <-- origin/branch
a-b-c-e(amend)   <-- branch

amendした箇所（HEAD）で乖離が起こっている
（最新のブランチをプルせずプッシュしたときと同じような状況が発生する）
```

# 対処方法
先ほど記載した通り、結局リモートとローカルの間に乖離が起こっていることが
プッシュできない原因なので、リモートの内容をローカルに取り込みコンフリクトを解消。

1. プッシュ先であるリモートの最新情報をフェッチで取得 `git fetch origin/XXX`
2. リモートブランチの内容をローカルにマージで取り込む `git merge origin/XXX`
3. コンフリクトを解消してコミット
4. 改めてプッシュ

# 参考

https://gotohayato.com/content/445/
SQL テーブルのバックアップ/テーブルの再作成

# はじめに
DBの対象テーブル内のデータが一つもない状態で、動作確認をしたいが既存のデータは残しておきたい。
そんな時は、バックアップ用のテーブルを作成することで解決した。
バックアップのテーブル作成が想像以上に簡単だったため、記録用に残す。


# テーブルのバックアップ（SELECT INTO）
テーブルのバックアップは以下の通りです。

```
SELECT * INTO バックアップ用テーブル FROM バックアップ対象テーブル
```

こんなに簡単にできるとは…

# テーブル内のデータを削除する
今回はデータが一つもない状態で動作確認をしたいため、データを削除する。
ここで使用したのが、***TRUNCATE構文***

### TRUNCATE構文とは？
TRUNCATE構文は、テーブルを削除して、再作成（空のテーブル）する。
DELETE分のようにWHERE句による条件指定ができないものの、処理速度が速いとのこと。

```
TRUNCATE TABLE テーブル名
```
group_byメソッドの使い所について

みなさまこんにちは、プレイライフの熊崎です！

先週の土曜日にコロナワクチンの２回目接種を行ったのですが、３日ほど寝込んでしまいました。
ファイザーでも38℃くらい熱が出たので、かなり辛かったです。ですので、まだ受けていない方は事前に解熱剤を買っておくと良いかもしれません。

といったお話は置いといて、今日もメソッドのアウトプットを行っていきます。

## group_byメソッドとは

> ブロックを評価した結果をキー、対応する要素の配列を値とするハッシュを返す。
参考URL：https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/group_by.html

以下のような挙動を示す。

```sample.rb
(1..6).group_by {|i| i%3}   #=> {0=>[3, 6], 1=>[1, 4], 2=>[2, 5]}
# 参考URL：https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/group_by.html
```

各要素を３で割った時の余りの数をキーにして、余りの数が同じもの同士をグルーピングしている。
またEnumerableモジュールのメソッドのため、EnumerableモジュールをincludeしているArray,Hash,Range,Enumeratorクラスで使用可能。

## どんな時に使うのか？
→ ブロックを評価した結果に応じて要素を振り分けたいとき

### 具体例:学校のテスト
田中君と佐藤君と鈴木君がいて、テストの合格点は60点。田中君は70点、鈴木君は80点なので、合格。佐藤君は50点なので不合格とする。合格者と不合格者を分けたい。

```sample.rb
students = [
          {name: "田中", score: 70},
          {name: "佐藤", score: 50},
          {name: "鈴木", score: 80},
        ]

students.group_by { |s| s[:score] >= 60 ? "合格者" : "不合格者" }
#=> {"合格者"=>[{:name=>"田中", :score=>70}, {:name=>"鈴木", :score=>80}], "不合格者"=>[{:name=>"佐藤", :score=>50}]}
```

## 参考文献
[https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/group_by.html](https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/group_by.html)
[Rails]アプリ制作前のGemの導入の仕方

##はじめに

####記事の対象者
・Railsでアプリ開発を初めた人
・Gemの使い方などを知りたい人

####環境
・Macbook Air (Retina, 13-inch,2019)
・プロセッサ 1.6GHz デュアルコアIntel Core i5
・メモリ　8GB 2133 Mhz LPDDR3
・MacOS Big Sur　バージョン 11.5.2
・テキストエディタ＝Visual Studio Code

####記事の流れ
1)What is Gem？
2)どうやってGemを使うの？
3)状況によって使うGem

##What is Gem？
＝簡単にいうと、命令式（ある条件下にいるとき、何が、どういうふうに動け）が入っている箱のようなもの
・「むむむ？」どういうこっちゃ？と思ってるヒト→難しく考えなくて大丈夫！

####日常に使っているもので考えてみよう！

```
（１）パソコンで例えると。。
命令式が入っている箱＝電源ボタン
命令式＝（充電がちゃんとある、パソコンが、起動せよ）

（２）水道で例えると。。
命令式が入っている箱＝蛇口
命令式＝（水道料金を払っている、水が、放水）
```

##どうやってGemをつかうの？
####Gemをさがす
ほとんどのGemは「RubyGems.org」（https://rubygems.org/）に登録されています。
実装したい機能と関連したgemを探すことができます。

####Gemをインストールする準備
＊目星のGemをインストールする前に、多数のGemを管理するためのGem[bundler]を先にインストールしよう！

```
（ターミナル）
gem install bundler --version='2.1.4'
```

####Gemのインストール方法
探したGemをテキストエディタにあるGemfile内に置き、ターミナルでbundle installをする。

```
(置き場所)
（１）開発環境＋テスト環境 （２）開発環境 （３）テスト環境 （４）追加Gem 

（置き方）
gem 'gem名'

(ターミナルでインストール)

% cd ~/projects/アプリケーション名   ＊制作しているアプリのファイルへ移動する
↓
% bundle install                ＊Gemfileに記入したgemを一括でインストール
```
![gemfile sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102030/c36058c3-ecf6-cd1c-db21-6f5f7261015b.png)

##最後に
・ここまで読んでくださってありがとう！
APIとは何か

# APIとは
application programming Interfaceのことです。
Interfaceとは接点や橋渡しという意味です。
ユーザーとサービス提供者がアプリケーションをプログラミングを通して
webサービスを使う時の両者をつなぐものです。

# APIを叩くとは？
APIを叩くとはapplicationの情報を呼ぶ、つまり
applicationの情報を取得するということです。

ex) Twitterのその人のアカウントの情報、インスタならその人の投稿の情報を
取得したりします。







⚫︎参考資料
https://www.sbbit.jp/article/cont1/62752
https://qiita.com/antk/items/d762fdb3695cb85712ad
https://shiki0331.hatenablog.com/entry/2019/03/18/235251