OmniAICreator/Qiita-1.07M huggingface dataset:
[Mac]VagrantにCentOS6.10環境構築

環境構築の手順をよく忘れてしまうのでメモ。

# boxの追加

```
$ vagrant box add banto/centos-6.10
```
virtualboxを使っているため2を選択

```
1) parallels
2) virtualbox
3) vmware_desktop

Enter your choice: 2
```
boxが追加されたか確認

```
$ vagrant box list
bento/centos-6.10 (virtualbox, 202103.18.0)
```

# 環境構築

環境構築用のディレクトリを作成

```
$ mkdir centos6.10
$ cd centos6.10
```
初期化 (Vagrantfile作成)

```
$ vagrant init bento/centos-6.10
$ ls
Vagrantfile
```
Vagrantfileに設定を追加してIPアドレスを割り当て 

```
config.vm.network "private_network", ip: "192.168.33.10"
```
仮想マシンを起動

```
$ vagrant up
```
起動できたか確認

```
$ vagrant status
default                   running (virtualbox)
```
sshで接続 (パスワードはvagrant)

```
$ ssh vagrant@192.168.33.10
[vagrant@localhost ~]$ 
```
仮想マシンを終了

```
$ vagrant halt
```
ifって大事


Chat_appというアプリのテキストにて

```rb:app/controllers/rooms_controller.rb
  def destroy
    room = Room.find(params[:id])
    room.destroy
    redirect_to root_path
  end
```
###削除に失敗してもルートパスに飛ばされる


furimaというアプリテキストにて

```rb:app/controllers/items_controller.rb
  def destroy
    if @item.destroy
      redirect_to root_path
    end
  end
```

削除に成功すればルートパスに飛ばされる。
削除に失敗したときは同じ画面のまま
Firebase CloudFunctions バージョンアップ後のエラー対応

## CloudFunctions がサポートするnode.jsのバージョンが変わったことで、バージョン対応時にエラーが出ることがあります。

エラーの例
 
```
Error: process.env.GCLOUD_PROJECT is not set.
```

```
at /workspace/node_modules/firebase-functions/lib/providers/firestore.js:99:23 
at cloudFunctionNewSignature (/workspace/node_modules/firebase-functions/lib/cloud-functions.js:102:13) 
at cloudFunction (/workspace/node_modules/firebase-functions/lib/cloud-functions.js:151:20) 
at /layers/google.nodejs.functions-framework/functions-framework/node_modules/@google-cloud/functions-framework/build/src/invoker.js:199:28 
at processTicksAndRejections (internal/process/task_queues.js:93:5) 
Function execution took 203 ms, finished with status: 'error' 
```

```
TypeError: Cannot read property 'name' of undefined
    at snapshotConstructor (/workspace/node_modules/firebase-functions/lib/providers/firestore.js:125:72)
    at cloudFunctionNewSignature (/workspace/node_modules/firebase-functions/lib/cloud-functions.js:119:34)
    at cloudFunction (/workspace/node_modules/firebase-functions/lib/cloud-functions.js:151:20) 
```

process.env.GCLOUD_PROJECTは廃止されたはずですが、なぜかエラーになります。

## 対応
ローカルのnode.jsのバージョンをv15以上にあげます。
その後で、npmとfirebase関連のモジュールのアップデートを行います。

```
npm update -g npm
npm install firebase-functions@latest -g
npm install firebase-admin@latest -g
```

## デプロイ
package.json内にnodeのバージョンを記載

```package.json
  "engines": {
    "node": "14"
  },
```

index.tx内にプロジェクトIDを記載

```index.ts
import * as functions from 'firebase-functions'
import * as admin from 'firebase-admin'
import * as stream from 'stream'

admin.initializeApp()
process.env.GCLOUD_PROJECT = "your project id"
```

なくてもいいかもしれないが、同じエラーが出ると面倒なので書いておきます。

デプロイして確認

```
firebase deploy --only functions
```

### 関連リンク
- https://www.javaer101.com/ja/article/48243723.html
- https://www.gitmemory.com/issue/firebase/firebase-functions/563/667137133
- https://stackoverflow.com/questions/65536660/how-to-set-firebase-config-and-gcloud-project-in-firebase-project
- https://github.com/firebase/firebase-functions/issues/437
- https://www.javaer101.com/ja/article/23112673.html


### 対応したCloudFunctionsを利用しているアプリ
- [P-Chat !](https://apps.apple.com/jp/app/p-chat-%E3%82%86%E3%82%8B%E5%8F%8Bsns%E3%82%A2%E3%83%97%E3%83%AA/id1447657356)
MVの『超』「超」基本

閃いたのはここ！

フリマアプリのdestroyアクションを作っていました。

```rb:app/controller/itemscontroller.rb
  def destroy
    @item.destroy
  end
```

しっかりとかけていると思ったのですが、

![20210423-010445.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/f57174e0-7e8e-87ca-3b28-074bdd73c82f.png)

こんなエラーがでます。

###idナンバー２１をもったデータが見当たりません。ここなんです。
###[Cとは]
###コントローラークラスにはアクションのためのメソッドがいてあります。
###アクションでは表示画面を作らないといけません。コントローラーアクション
###と同じ名前のcreateならcreate.html.erb、indexならindex.html.erb
###があれば自動的に読み込まれます。そういう仕様です。
###No.21番のid番号をもつ表示画面localhost３０００/items/21を
###自動的に読み込もうとしてエラーが起こるんです。
###でも、これこそがMVC超基本。VCなんです。
###またviewに引き渡すハッシュデータはコントローラー側で
###＠のついたインスタンス変数を用意します。これはスコープ（変数の届く範囲）
###のためそうなっています。


いくつか調べ回って最後に原理原則にぶち当たりました。
覚えて調べてしても抜け漏れっていっぱいあります。
日々精進。日々鍛錬。
【初心者向け】Pythonコードの読み方

##はじめに
※ポエムです。悪しからず。

よくこれからプログラミングをやろうとしている方から**「どういう言語が習得しやすいでしょうか？」**という質問を受けます。

それに対して意見を言うと...
**「エラーが出た時に、一つずつ原因を探って潰すための思考法が身についているかどうか？」**が重要だと思い始めました。

要はコードとエラー文を読み飛ばさずに読めるか？

この観点が重要そうです。

読める状態とはどういう状態なのかを考えてみたいと思います。

##読める状態とは、イメージ同定と具体例同定できる状態
読める状態とは、イメージ同定と具体例同定、ができる状態だと考えます。
この２つの単語は、国立情報学研究所が考案したリーディングスキルテストで導入されている概念です。


具体的な定義をみていきましょう。

- 具体例同定【辞書、理数】(INST)
 - 文章と図形やグラフを比べて内容が一致するかどうかを認識 する力を問う。

- イメージ同定(REP)
 - 文章で書かれた定義を読んで、それと合致する具体例を認識 する能力を問う。
 

[リーディングスキルテスト](https://www.city.toda.saitama.jp/uploaded/life/63777_117049_misc.pdf)についてはこちらをご覧ください。(戸田市の事例が有名です)

要は文章から図形や具体例を認識できるか？が問われています。

##例文

これをプログラムに置き換えてみましょう。

```Python:変数への代入
str = abc
int = 123
```

「変数と代入」では数字や文字から変数に向かって矢印を引いている図形をイメージできると読めている状態と言えるのではないでしょうか。
![スクリーンショット 2021-04-23 1.09.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271238/223003b6-2dda-e839-29cc-4b50097f466f.png)


### イメージ同定(文章から図形への変換)

```Python:関数の設定
def addition(x, y):#関数の定義
    print(x + y)#関数で行う処理
```

### 具体例同定(具体的な数字を入れて考える)

aとbの2つの数字を受け取れる箱(関数)を定義して
受けとった場合にa+bの結果を出力する。

具体的に10と20を入れてみる。

すると10+20で30と出力される。
![スクリーンショット 2021-04-23 1.17.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271238/f16e7967-1c4c-d392-4eec-452ff8f5a897.png)

こういう図形と具体例の認識が、素早く複雑にできるようになるのがプログラミングの上達なんではないかなと思います。

##まとめ
日々エンジニアとして業務していると、大量のリファレンスを読むことになるため、**ついつい読み飛ばしをしてしまいがち**ですが、**文章から連想される図形と具体例を常に確認しながら読んでいきたい**と、改めて思いました。
アドミニストレーター認定試験に向けた学習 ⇒ アドミニストレーター認定の準備: レポートと自動化 ⇒ ワークフローと自動化の学習

１．「ワークフローと自動化」セクションは、アドミニストレーター認定試験の何 % を占めていますか?
２．アドミニストレーター認定試験の「ワークフローと自動化」セクションの主なトピックはどれですか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/05c059de-e9d6-943b-95e7-b6734c057791.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/5330a8ee-dac5-4d01-5c97-ea25128dacb4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/849f5879-412d-8860-874b-c586b3d4b101.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/175363c0-2942-3ce5-35f4-e9e74bbb8411.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/8e7f892a-0f01-146f-11b6-aecd0d40f10e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/1a898b5c-ec27-9bac-5620-0736dfb1e914.png)
Ubuntu18.04LST セットアップ備忘録

## セットアップ
- ipアドレスをGUIで固定しておく<br>
- PPTP接続の場合、DNSにPPPoEも指定する。

```
sudo apt update && sudo apt upgrade
sudo apt install openssh-server
```

## Nvidia Driver & CUDA & CuDNN
- セキュアブートをOther OSへ変更、セキュリティキーを削除しておく
- [公式HP](https://www.nvidia.co.jp/Download/index.aspx?lang=jp)から、NVIDIAドライバをダウンロードしておく。<br>
- [公式HP](https://developer.nvidia.com/cudnn)から、インストールするCUDAバージョンにあったcuDNNをダウンロードしておく

```
# NVIDIA Driver ver.460.73.01
sudo apt install gcc make
sudo bash NVIDIA-Linux-x86_64-460.73.01.run

# CUDA ver.11.2.1
wget https://developer.download.nvidia.com/compute/cuda/11.2.1/local_installers/cuda_11.2.1_460.32.03_linux.run
sudo sh cuda_11.2.1_460.32.03_linux.run
echo '### CUDA Path ###' >> ~/.bashrc
echo 'export PATH="/usr/local/cuda/bin:$PATH"' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH="/usr/local/cuda/lib64:$LD_LIBRARY_PATH"' >> ~/.bashrc
source ~/.bashrc

# cuDNN ver.8.1.1.33-1
sudo dpkg -i libcudnn8_8.1.1.33-1+cuda11.2_amd64.deb
sudo dpkg -i libcudnn8-dev_8.1.1.33-1+cuda11.2_amd64.deb
sudo dpkg -i libcudnn8-samples_8.1.1.33-1+cuda11.2_amd64.deb
```

## パッケージ
```
# 各種パッケージのインストール
sudo apt install -y curl git vim swig \
    build-essential libssl-dev libffi-dev pkg-config ccache ecm mesa-utils \
    python3.7 python3.7-dev python3.7-tk python3.7-distutils \
    libopencv-dev libgl1-mesa-dev

# CMake
wget https://github.com/Kitware/CMake/releases/download/v3.20.1/cmake-3.20.1.tar.gz
tar zxvf cmake-3.20.1.tar.gz
sudo mv ~/cmake-3.20.1 /opt/
cd /opt/cmake-3.20.1/
sudo ./bootstrap
sudo make && sudo make install

# PATHの追加
echo '### CMake ###' >> ~/.bashrc
echo 'export PATH=/opt/cmake-3.20.1/bin/:$PATH' >> ~/.bashrc
source ~/.bashrc
```
## Python3.7
```
curl -kL https://bootstrap.pypa.io/get-pip.py | sudo python3.7
```
## Docker & Docker Compose
[別記事](https://qiita.com/rewolfiluac/items/a950605125683a69d4bd)

## SSHの公開鍵認証
- id_rsa.pubをホームへコピー

```
# 鍵生成
ssh-keygen -t rsa

# 鍵の登録
cat id_rsa.pub >> ~/.ssh/authorized_keys

# 権限変更
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

# 設定の変更
sudo vi /etc/ssh/sshd_config

# 設定内容
ChallengeResponseAuthentication no
PasswordAuthentication no

# デーモンの再起動
sudo /etc/init.d/ssh restart
```

## RDP
```
sudo apt install xserver-xorg-core xorgxrdp xrdp
sudo vi /etc/polkit-1/localauthority/50-local.d/45-allow-colord.pkla

# 設定内容
[Allow Colord all Users]
Identity=unix-user:*
Action=org.freedesktop.color-manager.create-device;org.freedesktop.color-manager.create-profile;org.freedesktop.color-manager.delete-device;org.freedesktop.color-manager.delete-profile;org.freedesktop.color-manager.modify-device;org.freedesktop.color-manager.modify-profile
ResultAny=no
ResultInactive=no
ResultActive=yes

# サービスの再起動
systemctl restart polkit.service
```

## Git
```
git config --global user.name "ユーザー名"
git config --global user.email メールアドレス
```
C言語ポインタを理解するための簡単な例〜誰でもわかるポインタのメリット〜

## ポインタを理解するためのステップ

- 値と参照について
- 関数の引数について
- インスタンスについて
- ポインタがない場合とある場合のサンプルコード
- まとめ

## 値と参照について

メモリ上のデータは

- アドレス -> 1000 ~ 1003
- 値 -> メモリの中身

この2つで構成されているイメージです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123610/e08c93dc-a8e6-e250-cbd6-698c376bbd72.png)
[【C言語】ポインタ](https://yttm-work.jp/lang/c/c_0012.html)


アドレスのことを参照
値のことを値
と呼ぶのが一般的です。

## 関数の引数について
C 言語では、関数の引数に *値* しか渡すことができません。
なので、関数の引数にインスタンスを渡し、そのインスタンスに関数内で変更を加えるためには **ポインタというアドレスを値として扱う変数** が必要になります！！！（ここ重要）

## ポインタがない場合とある場合のサンプルコード

```Main.c
#include <stdio.h>
typedef struct list {
    int first;
    int second;
    int sum;
    int sub;
} list;

// ポインタなしの関数
void sum_and_sub(list list) {
    printf("list address in sum(): %d\n", &list);
    list.sum = list.first + list.second;
    printf("sum in sum(): %d\n", list.sum);
    list.sub = list.first - list.second;
    printf("sub in sum(): %d\n", list.sub);
}

// ポインタありの関数
void sum_and_sub_pointer(list *list) {
    printf("list address in sum_pointer(): %d\n", list);
    list->sum = list->first + list->second;
    printf("sum in sum_pointer(): %d\n", list->sum);
    list->sub = list->first - list->second;
    printf("sub in sum_pointer(): %d\n", list->sub);
}

int main(void) {
    struct list list1;
    list1.first = 1;
    list1.second = 5;
    list1.sum = 0;
    list1.sub = 0;
    printf("list1 address in main(): %d\n", &list1);
    sum_and_sub(list1);
    printf("sum by sum(): %d\n", list1.sum);
    printf("sub by sum(): %d\n", list1.sub);
    sum_and_sub_pointer(&list1);
    printf("sum by sum_pointer: %d\n", list1.sum);
    printf("sub by sum_pointer: %d\n", list1.sub);
}
```

```実行結果
list1 address in main(): -1886710432
list address in sum(): -1886710416
sum in sum(): 6
sub in sum(): -4
sum by sum(): 0
sub by sum(): 0
list address in sum_pointer(): -1886710432
sum in sum_pointer(): 6
sub in sum_pointer(): -4
sum by sum_pointer: 6
sub by sum_pointer: -4
```

sum 関数では、呼び元で定義している `.first`, `.second` を受け取ることはできています。
が、 sum 関数内で `.total` に代入した値を呼び元の main 関数で参照することはできませんでした。

sum_pointer 関数では、 sum_pointer 関数内で `.total` に代入した値を呼び元の main 関数で参照することはできました〜〜

アドレスが、適切に渡されていることもわかると思います。

## まとめ
インスタンスの中身を更新したけりゃポインタを使え

## 補足
非常に非常に簡単にポインタのメリット、概念を説明するための記事です。他にもいっぱいメリットはあります。
- 戻り値が一つだが、複数の値をインスタンス内に保持し、予呼び元に返却することができる
- メモリの節約になる

などなど
詳細は他の記事を見てくれよな！
文字列への変数展開（書式指定文字列）

```py
print('My name is {} {}.'.format('Taro', 'Tanaka'))

print('My name is {0} {1}.'
      'Watashi ha {1} {0}'.format('Taro', 'Tanaka'))

print('My name is {name} {family}.'
      'Watashi ha {family} {name}'.format(name='Taro', family='Tanaka'))
```
実行結果：

```txt
My name is Taro Tanaka.
My name is Taro Tanaka.Watashi ha Tanaka Taro
My name is Taro Tanaka.Watashi ha Tanaka Taro
```
fstring

```py
a = 'a'
print(f'a is {a}')

x, y, z = 1, 2, 3
print(f'a is {x}, {y}, {z}')
print(f'a is {z}, {y}, {x}')

name = 'Taro'
family = 'Tanak'
print(f'My name is {name} {family}. Watashi ha {family} {name}')
```
実行結果：

```txt
a is a
a is 1, 2, 3
a is 3, 2, 1
My name is Taro Tanak. Watashi ha Tanak Taro
```
【初学者による】Dockerってなんやねん

GoogleにDockerってなんやねんと聞いても小難しい説明しか出てこなかったため、
初学者の目線で説明します。

#Dockerとは？
コンテナ型の仮想化プラットフォームである！

ふーん。なんやよう分からんが、要は

#####仮想環境を構築し動かす仕組み 　　ってことね
Dockerを使えばアプリを簡単に開発・デプロイできるぞ！！すごい！！
___
#####仮想環境ってなんぞ？
君が使ってるPC(Mac bookとか)の上でWindowsとかLinuxOSとか別のOSを動かせる仕組み！

君が使っているPC(のOS)＝ホストOS
ホストOS上で動く別のOS＝ゲストOS
と呼ばれてるぞ
___

#Dockerのメリット
いっぱいあるけど、最大のメリットは、
####みんなが同じ環境で開発できること！

みんながみんな同じPCを使ってるわけじゃないから、開発しにくいわ...
という状況でも、Dockerがあればみんなが同じ環境(仮想環境)で開発ができるぞ！
チーム環境超捗るわ！


####その他のメリットたち
* 開発環境・テスト環境・本番環境全部使えるで
* 少ないコマンドで仮想環境を構築出来るよ 
* コードで管理できるから、他の人の環境を手に入れたり、配布することができるぞ
* Dockerの環境ごとデプロイできるぞ

___
なるほどねこの世の全てが分かったわ
　
別の記事で導入方法を書きます
ビデオ会議アプリ「Jitsi Meeet」をdockerで構築する

# はじめに
- 先日、本屋で立ち読みした時に、[Jitsi Meet](https://jitsi.org/jitsi-meet/) というOSSのソフトウェアがあるということを知り    
興味があったので、勉強がてらdockerで構築してみることにした。

---

# 環境
- MacBook Pro(Retina, Mid 2012)
- macOS Catalina
- Docker version 20.10.5, build 55c4c88

---

# 前準備
## Docker Desktopのインストール
- ググってください。

## ドメイン取得
- 使用するドメインは[ddo.jp](https://ddo.jp/)で取得

---

# Jitsi設定手順

## GitHubリポジトリのclone

```zsh:リポジトリのclone
nekonisi@nekonisi-mbp workspace % git clone https://github.com/jitsi/docker-jitsi-meet
Cloning into 'docker-jitsi-meet'...
remote: Enumerating objects: 2834, done.
remote: Counting objects: 100% (178/178), done.
remote: Compressing objects: 100% (139/139), done.
remote: Total 2834 (delta 61), reused 117 (delta 30), pack-reused 2656
Receiving objects: 100% (2834/2834), 976.38 KiB | 1.62 MiB/s, done.
Resolving deltas: 100% (1361/1361), done.
```

## .envファイルの設定
### .envファイル作成
```zsh:.envファイルの作成
nekonisi@nekonisi-mbp workspace % cd docker-jitsi-meet 
nekonisi@nekonisi-mbp docker-jitsi-meet % cp env.example .env
```

### .envを編集
```.env:.env
 32 # Directory where all configuration will be stored
 33 CONFIG=~/.jitsi-meet-cfg
 34 
 35 # Exposed HTTP port
 36 #HTTP_PORT=8000
 37 HTTP_PORT=80
 38 
 39 # Exposed HTTPS port
 40 #HTTPS_PORT=8443
 41 HTTPS_PORT=443
 42 
 43 # System time zone
 44 #TZ=UTC
 45 TZ=Asia/Tokyo
 46 
 47 # Public URL for the web service (required)
 48 #PUBLIC_URL=https://meet.example.com:8443
 49 PUBLIC_URL=https://your.domaininfo <-ここは各自の設定に書き換え
(省略)
 74 #
 75 # Let's Encrypt configuration
 76 #
 77 
 78 # Enable Let's Encrypt certificate generation
 79 #ENABLE_LETSENCRYPT=1
 80 ENABLE_LETSENCRYPT=1
 81 
 82 # Domain for which to generate the certificate
 83 #LETSENCRYPT_DOMAIN=meet.example.com
 84 LETSENCRYPT_DOMAIN=your.domaininfo <-ここは各自の設定に書き換え
 85 
 86 # E-Mail for receiving important account notifications (mandatory)
 87 #LETSENCRYPT_EMAIL=alice@atlanta.net
 88 LETSENCRYPT_EMAIL=your@mail <-ここは各自の設定に書き換え
```

### .envを暗号化

```zsh
nekonisi@nekonisi-mbp docker-jitsi-meet % ./gen-passwords.sh 
```

### 設定ファイル等の保存ディレクトリ作成
```zsh
mkdir -p ~/.jitsi-meet-cfg/{web/letsencrypt,transcripts,prosody,jicofo,jvb}
```

---

# dockerの起動
```zsh
docker-compose pull
```

```zsh
docker-compose up -d
```

---

# 動作確認
https://取得したドメインで、画面が表示されたら終了です。
「https://取得したドメイン/ルーム名」で誰でもアクセスできます。
![スクリーンショット 2021-04-22 23.49.50 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1124047/3c29b913-4a58-c6e8-5cca-a34c1bdd6def.png)

![スクリーンショット 2021-04-23 0.15.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1124047/5fa0cb8c-5e5f-06f1-c55c-2830265c86cb.png)
↑画像は携帯とPCで通話したときのスクショです。

---

# むすび
- ビデオ会議アプリが想像の100倍簡単に実現できた。
- コロナがまた盛り上がってきたので、ビデオ会議ツールの需要も増えるとも思う。  
営業の人は提案の一つとして知っておくといいかも（Apache License 2.0なので商用利用は可能です）
- GW中に同郷の友達とオンライン飲み会を予定しているので、その時に使えたらいいな。

# 参考記事
https://qiita.com/zembutsu/items/efb1713337d89f9a1bf0
【Unable to boot device because it cannot be located on disk.】分かり易く画像で解決！

>`作業環境`
BigSur 11.2.3 / macbook_Air M1 / Xcode_version 12.4


- [x] simulatorが起動しない,,
- [x] 再インストールもだめ,,
- [x] 調べてもあまり出てこない,,

同じように私も苦労しましたが、結論「再起動」で解決しました。
忘備録として、試した事を記録しています。

<br>
<details>
<summary><strong>〜目次〜</strong></summary>
 [1. 削除](#1-削除)
　 [1-1. ファイルの削除](#1-1-ファイルの削除)
　 [1-2. 完全削除](#1-2-完全削除)
[2. 再インストール](#2-再インストール)
　 [2-1. 最新バージョンのインストール](#2-1-最新バージョンのインストール)
[3. 再起動](#3-再起動)
</details>

#1. 削除
####1-1. ファイルの削除
```
/Applications/Xcode.app
/Library/Preferences/com.apple.dt.Xcode.plist
~/Library/Preferences/com.apple.dt.Xcode.plist
~/Library/Caches/com.apple.dt.Xcode
~/Library/Application Support/Xcode
```
〜(チルダ)の位置には、xcodeファイルのあるフォルダを記入。
よくわ分からないという方は、Chromeの検索欄にコピペして確認して下さい。
自動で検出されます。

|![スクリーンショット_2021-04-21_18_56_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/912206/e74de6ba-e27c-c726-69e3-b06ea81e5198.png)|
|:-:|

下画像にあるパスをターミナルにコピペして実行しましたが、エラーは解決されず、、

|![スクリーンショット_2021-04-21_18_52_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/912206/b9da39c9-f1a6-7462-0565-fe8c7196294e.png)|
|:-:|

<br>
####1-2. 完全削除
```
Xcodeのビルド中間生成ファイルを全て削除する
~/Library/Developer/Xcode
~/Library/Developer/CoreSimulator
```
これも同じように実行しましたが、まだエラーが出ます。

<br>
#2. 再インストール
####2-1. 最新バージョンのインストール
[Developerページ](https://developer.apple.com/downloads/index.action?name=Xcode)で、AppleIDを入力

|![スクリーンショット 2021-04-22 7.11.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/912206/e0779e67-111d-5ae9-ac41-c72b479aa15a.png)|
|:-:|
サインインしたら、バージョンを選択してインストール

|![スクリーンショット_2021-04-22_7_21_35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/912206/63d66deb-6a16-a02d-575e-e5253c30953f.png)|
|:-:|

>`beta版`
ベータ版ソフトウェア（プレビュー版／シード版）とは、まだ公開されておらず開発中のプレリリースバージョンのソフトウェアです。デベロッパとして、ベータ版ソフトウェアを使用してAppleの最新技術を開発中のAppにあらかじめ組み込むことで、ソフトウェアが公開される際に最新のAppを提供できます。
引用元:[AppleDeveloperサポート](https://developer.apple.com/jp/support/beta-software/)

<br>
#3. 再起動
アプリの再起動ではなく、本体電源の再起動でsumilatorは起動しました。

最後まで読んで頂きありがとうございました。
まだまだ初学者ですので、もっと良い記述の方法があればご指摘お願い致します！
超初心者がAWSについて勉強してみた①～VPC編～

##概要
アラフォーのAWS初心者が学んだことをつらつら書いていきます。

##今回の目標
VPCを作成する。


##教材
[AWS CloudTech](https://aws-cloud-tech.com/)で学びはじめました。
AWSを学びたい人は心者でも丁寧にまた安価(参考書1冊分+コーヒー2缶)で学べるのでお勧めです。

##前提条件
AWSにIAMユーザとしてサインイン出来ることとします。不明な場合は、AWS公式ハンズオンの[ここ](https://pages.awscloud.com/event_JAPAN_Ondemand_Hands-on-for-Beginners-1st-Step_LP.html?trk=aws_blog)を参照していただくかググっていただければ、情報はたくさん落ちています。
(公式ハンズオンの場合は、申し込みフォームより登録が必要です。)

##用語集
構築するのに最低限必要な用語を書きます。
★region
データセンターが集まった各地域の事。北アメリカやヨーロッパ、アジアの様々な地域に存在しており、地域ごとに利用料金は異なる。基本遠いほど通信に時間がかかる。

★VPC(Virtual Private Cloud)
AWSアカウントに紐づいた専用の仮想ネットワーク環境。リージョンに作成される。

##構成図
今回構成する構成図はこちら
超単純です。

![VPC構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1213609/15517fc6-ac37-8293-1ab6-ac58ee8e0f2c.png)

では具体的な手順に入っていきます。

##リージョン選択
AWSマネージメントコンソールにあるリージョン情報を東京にします。恐らく初回ですと、
バージニア北部とかになっているかと思います。
要はVPCを作成するリージョンを選択するということです。
※リージョンの選択によって、通信速度,料金,サービスが違ってくるようですが、通信速度を考えて近いリージョンであること、学習用であることを考えて東京を選択します。
![リージョン選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1213609/0a5f35d0-bb30-d51e-2624-ac9b2985afa7.png)

##VPC検索
AWSマネージメントコンソールでVPCを検索して、VPCのダッシュボードを開きます。
![VPC検索.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1213609/c49b2809-a7ff-7cab-c45b-89a5788e604e.png)

##VPC作成
VPCのダッシュボードでVPCを選択します。
![VPC選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1213609/9432bc8c-9b1d-1a85-ca9a-aeba9f69ee92.png)

最初に1行あるのは、デフォルトVPCです。今回新たにtest-vpcというVPCを作成してきます。
VPC作成を押してください。

![VPC作成1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1213609/e2fa051a-7f08-a23b-768d-2382059d6087.png)

名前タグ・・・test-vpc
IPv4 CIDR ブロック・・・10.0.0.0/21
を入力します。
その他はデフォルトで良いです。
入力したらVPCを作成を押します。
【補足】
IPV6 CIDR ブロック・・・VPCをIPv6で使用する場合、選択するようです。私は使用したことありません。今回は使用する予定がないので、ブロックなしのままで良いです。

テナンシー・・・ハードウェアを物理的に占有する時に選択します。通常は共有ホストですが、ホストを占有して、セキュリティ面等を考慮する時に選択するようです。割高です。
今回は、学習用のため、デフォルトで構いません。
![VPC作成2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1213609/5e615166-dde3-2e90-065e-7d7f82449008.png)

作成されましたので、×を押して、VPCを押します。
![VPC作成3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1213609/fd5f0ff8-e058-1b54-48a1-255964b72efd.png)

VPCが正しく作成されてことを確認します。
![VPC作成4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1213609/c9240db7-8edf-7c50-fb94-f78fe02cb905.png)

はい。作成されましたね。今回はここまでです。
次回はサブネットを作成してきます。
サブネット編は[こちら](https://qiita.com/konaga99/items/4530c4432f6963759e8b)
以上
109シネマズの予約情報をGoogleカレンダーに登録

# はじめに

この投稿は[TOHOシネマズの予約情報をGoogleカレンダーに登録](https://qiita.com/hiro_nishi/items/c6d08ede03484e06bf57)の109シネマズ版です。
設定方法などはTOHOシネマズ版と同じなので上の記事を参考にしていただき、
この記事ではソースコードだけ公開します。

# ソースコード

```javascript
function create109EventFromGmail(){
  var calendar = CalendarApp.getDefaultCalendar();
  var start = 0;
  var max = 1;
  var event_length = 120; // 終了時間はわからないので120分で固定
  // タイトル名を検索
  var threads = GmailApp.search('１０９シネマズ　チケットご購入完了のお知らせ',start,max);
  
  for(var i in threads){
    var thread = threads[i];
    var msgs = thread.getMessages();
    
    for(var j in msgs){
      var msg = msgs[j];
      var body = msg.getPlainBody();
      if (body == "") continue;
      
      // 情報を取得
      var id = body.match(/購入番号：(\d+)/)[1];
      var date = body.match(/上映日　：(\d+\/\d+\/\d+)/)[1];
      var time_from = body.match(/上映時間：(\d+:\d+)/)[1];
      var cinema = body.match(/劇場名　：(.*)/)[1];
      var theater = body.match(/上映劇場：(.*)/)[1];
      var name = body.match(/上映作品：(.*)/)[1];
      var seat = body.match(/座席　　：(.*)/)[1];
      
      theater = cinema + " " + theater

      var start_date_time = new Date(date+" "+time_from+":00");
      var end_date_time = new Date(date+" "+time_from+":00");
      end_date_time.setMinutes(start_date_time.getMinutes() + event_length);

      Logger.log("ID: " + id);
      Logger.log("Date: " + date);
      Logger.log("Time: " + time_from + "～");
      Logger.log("Theater: " + theater);
      Logger.log("Name: " + name);
      Logger.log("Seat: " + seat);

      // 既存予定有無確認
      var registed_events = calendar.getEvents(start_date_time, end_date_time, {search: "["+id+"]"+name});
      if(registed_events.length == 0) {
        // Googleカレンダーへの投稿
        var options = {
          description: body,
          location: theater
        };
        
        var event = calendar.createEvent("["+id+"]"+name,
                                            start_date_time,
                                            end_date_time,
                                            options);
        Logger.log("Calendar Registered: " + event.getId());
      } else {
        Logger.log("Already registered. (count:"+registed_events.length+") ("+registed_events[0].getTitle()+")");
      }
      Logger.log("----------------------------------");
    }
  }
}
```

109シネマズは会員になると、エグゼクティブシートに無料でアップグレードできるのが良いですね！
【RSpec】"let"と"let!"とbeforeの違いと実行順序

### はじめに
rspecのテストコードを書くために"let"と"let!"の違いを調べていたところ、今度は"let!"と"before"の違いや実行順序に関して気になったのでまとめてみました。
### "let"とは
rspecには"let"というメソッドがあります。
これは呼び出された時にはじめてデータを読み込む「遅延読み込み」を行う機能です。

```rb:
  describe 'let'do
    let(:user) { build(:user) }

    it 'userインスタンスが有効であること' do
      expect(user).to be_valid 
             ※↑ここではじめて読み込まれる
    end
  end
```

上記のように呼び出された時にはじめてデータを読み込むので、無駄にデータベースに問い合わせてしまってテストが遅くなるといったことを予防してくれます。

ちなみに上記のテストはパスします。

逆に下記のテストは通りません。

```rb:
  describe 'let'do
    let(:user) { create(:user) }
    let(:user_task) { create(:task, user_id: user.id, title: 'test_title') } 

    it 'userがtaskを持っていること' do
      expect(user.tasks.first.title).to eq 'test_title' 
    end
  end
```
このテストでは、「user」は呼び出されているのでテストデータが読み込まれますが、
「user_task」は呼び出されていないので、このままでは「let(:user_task)　・・・・」の部分は、ただの無駄な記述になってしまいます。

### "let!"とは
先程のテストをパスさせるために使うのが、「let!」メソッドです。
こちらは"let"と違い、テストが実行される前に自動的にテストデータが読み込まれます。

なので、先程の「let(:user_task)」の部分を「let!」にします。

```rb:
  describe 'let'do
    let(:user) { create(:user) }
    let!(:user_task) { create(:task, user_id: user.id, title: 'test_title') } 

    it 'userがtaskを持っていること' do
      expect(user.tasks.first.title).to eq 'test_title' 
    end
  end
```

上記のテストではまず、taskインスタンスの入った変数「user_task」が作成されます。

続いて、expect内のテストが実行されるので、今回はテストがパスします。


### beforeとは
beforeは、「let!」とほぼ同じと思っていただいて問題ありません。、、、、多分。

主な違う点は、インスタンス変数の定義以外にも使用できることです。

例えば、ログイン後の動作をテストしたい場合、

```rb:
  describe 'after login' do
    let(:user) { create(:user) }
    before { login(user) } #loginメソッドを定義している前提
    
    it 'is success to edit user' do
      visit edit_user_path(user)
      fill_in "Email", with: "edit_user@example.com"
      click_button "Update"
      expect(page).to have_content 'User was successfully updated.'
      expect(current_path).to eq user_path(user)
    end
  end
```
この長さのテストコードではあまり意味がありませんが、通常はログイン後に確認したい挙動はたくさんあるはずなので、
このようにbeforeで定義することで、コードのリファクタリングにもなります。

### "let!"と"before"の実行順序
先程の説明で「let!」と「before」はほぼ同じと言いましたが、実行順序はどうなるのでしょうか？

結論から言うと、定義した順番で実行されます。

例えば以下のような場合、

```rb:
let!(:user_1) { create(:user) }
before { user_2 = create(:user) }
let!(:user_3) { create(:user) }
```
上から順にuserインスタンスが作成されていきます。

### 結局どれ使えばいいの？
これに関しては状況次第です笑

簡単にまとめると、

・"let"　←　テストで何回か使うインスタンス変数がある時
・"let!"　←　テストのブロック内で毎回使うインスタンス変数がある時
・"before"　←　テストのブロック内で毎回適用させたいメソッドなど（インスタンス変数以外）がある時

あくまで参考程度ですがこんな感じの基準でいいと思います笑

間違いなどあればコメントください！


### 参考
[「let・let!・before」の違いと実行順序（RSpec） - ryotaku's Tech Blog](https://www.ryotaku.com/entry/2019/09/10/000000)
[rspec 「let」と「let!」の違い](https://qiita.com/clbcl226/items/3db2189f75747b4af2d3)
文字列のメソッド

```py
s = 'my name is Mike.hi Mike.'
is_true = s.startswith('my name')
print(is_true) #True

print(s.find('Mike')) #11　前から検索
print(s.rfind('Mike')) #19 後ろから検索
print(s.title()) #My Name Is Mike.Hi Mike.
print(s.capitalize()) #My name is mike.hi mike.
print(s.upper()) #MY NAME IS MIKE.HI MIKE.
print(s.lower()) #my name is mike.hi mike.
print(s.count('m')) #2
print(s.replace('Mike', 'Nancy')) #my name is Nancy.hi Nancy.
```
【AWS】IAMロールについて

#プログラミング勉強日記
2021年4月22日

#IAMロールとは
　AWSのサービスなどのリソースに対してAWSの捜査権限を付与する仕組み。AWSリソースは、グループやユーザではなく、ほかのアカウントやEC2といったサービスなど。基本的には、AWSのサービス間のアクセスの許可・拒否といったAWSのサービスに対して設定する。

#IAMロールへのポリシー適用
　システム設計からAWSサービス間の連携有無を抽出する。まず、システム設計ではAWSサービス間の連携箇所を特定する。次に、必要な権限設定の設定を行う。リソースに対して必要な権限設定の割り出しを行う。
　例) EC2インスタンスがバッチ処理でS3にデータを保存し、EC2インスタンスにS3へのアクセス権限を設定する。
　別のAWSアカウントやウェブIDなどの別アカウントに対して<b>一時的なアクセス権限を付与する</b>ことも、IAMロールの役割。なので、IAMロールはAWSサービスのリソースに対して権限を設定するだけのものではない！
　→一時的にユーザに権限を与える・アクティブディレクトリなどと統合認証をする。(IAMロールはエンティティに権限を付与できる)
htmlの書き換え

# html（）
- 任意のHTML要素を取得したり意図的に要素を追加・書き換えをすることができる
- 取得されるHTMLは要素内の全ての子孫要素までが対象

#htmlの取得
```php
  <body>
    <h1>jquery</h1>
    <ul>
      <li>リスト１</li>
      <li>リスト２</li>
      <li>リスト３</li>
      <li>リスト４</li>
    </ul>
    <script>   
      console.log($('li:eq(2)').html()); //リスト３
    </script>
  <body>
```
#htmlの書き換え
```php
  <body>
    <h1>jquery</h1>
    <ul>
      <li>リスト１</li> //<li><a href="http://google.com">google</a></li>
      <li>リスト２</li>
      <li>リスト３</li>
      <li>リスト４</li>
    </ul>
    <script>   
      $(function() {
          $('li:eq(0)').html('<a href="http://google.com">google</a>');
      }) 
    </script>
  </body>
```
Raspberry Pi 4B にWindows10ARMを入れて SSDからブート その後３

ラズパイに M.2 PCIe NVMe対応SSD Logitec LMD-SMB256UCを接続し
Windows10 ARM64を起動できるか試してみました

NVMeのSSDを持っていなかったので外付けキットを買いました
それと電源供給用のUSBHUBはELECOMのU3HC-A424P10BKも買いました
ACアダプターがなかったのでスマホ用予備バッテリーを接続しています

前回使ったFeature update to Windows 10, version 21H1 (19043.906) arm64 の
ISOファイルをWoRでSSD書き込みました

起動手順は前回と同様です

設定後Windowsが起動してインストールは成功したのですが、費用がかかったけど
速度的には変化なし、USBケーブルが増えて見た目はきたなくなるしNVMe SSDの発熱が大きいです

ということで、今回は良いとこなしです

この続きは　https://qiita.com/jibri/items/70446750c68b86871a6c
サブスク作った話

[json to csv](https://jsontocsvconv.com)というJSONをCSVに変換するサブスクのサービスを作ったのでそのポエムを書かせてください。

## はじめに

多くのビジネス書に、何もしないでお金が入ってくるものが資産、何もしないでお金が出ていくものが負債、と書かれてあるのを目にするので、負債になるサブスクは極力使いたくないし、多くの人に負債を負わせるサブスクを作るのもどうなんだろう、と思っていた矢先、なんとなく[サブスクリプション――「顧客の成功」が収益を生む新時代のビジネスモデル](https://www.amazon.co.jp/dp/B07HY1TND9/ref=cm_sw_em_r_mt_dp_CWMP7X9WAQKD23TV9GFM)という本を読んでみたのですが、今多くの企業はみんなサブスクを始めている！AmazonもAdobeもAppleもそうだ！みたいに書かれていて、まぁ確かに日本のWeb系の会社とかもほとんどサブスクだし、むしろエンジニアでいることと、サブスクを提供することは切っても切り離せないんじゃないのか、と思い、エンジニアの自分を否定したくないという気持ちから、むしろサブスクは、持ち家に対する賃貸みたいなもので、柔軟にサービスを止めたり変更したりすることができる分、顧客にとってはそっちの方が良いはず。その上で大きな会社がサブスクをやっている、いや、サブスクをやっているから大きな会社になっているとしたら、個人開発でもサブスクのアプリを積極的に作成することで、人を雇う余裕や、他のサービスを作成する余裕ができ、その結果自分だけでなく、自分の周りや顧客、ひいては世界中の人々を幸せにすることができるのではないか。サブスクは悪じゃない。正義だ！と、自分を洗脳することにしました。そうすると、だんだんサブスクが作りたくなってきて、私はエンジニアだ。普段からあんなに勉強してるじゃないか。頑張ったら作れると思う。よし作ろう。と言うことで、趣味でサブスクの開発を始めました。

## アイデア出し

でじゃあ何を作ろうと考えた時に、以前[ＯＲＩＧＩＮＡＬＳ　誰もが「人と違うこと」ができる時代](https://www.amazon.co.jp/dp/B01GPGQPBA/ref=cm_sw_r_tw_dp_HB4DFS8NYR3DGT68TVNM)という本を読んだ時に、後発の企業より先発の企業の方がだいたい６倍失敗している、という内容があったので、完全に新しいものを一か八かで作るのではなくて、既存のサービスの改良版にしようと思いました。その上で、自分が実際にお金を払ったことのあるサービスが良いなぁと思ったので、何かないかと考えたところ、大学院生の時にJSONをCSVに変換する海外のサブスクのサービスに１ヶ月だけ課金していたことを思い出し、そのデザインがあまり良くなかったことと、ちょっと使いにくかったこともあり、それの改良版を作ることにしました。

## どう作ったか

最近サブスクで加入中のAmazon Prime Videoにある東京男子図鑑というドラマを見ていたのですが、その中で主人公がスタートアップ企業に入社するというシーンになり、それを見ていたら、今回作るアプリもせっかくやるんだから、スタートアップっぽく、誰かと一緒に作りたい、でもお金で揉めたくない、という思いになり、その話を友達([@kangaeru0123](https://twitter.com/kangaeru0123))のデザイナーにしたところ、お金無しでやるで、と言われたので、その友人と一緒にdiscordを繋げたりしながら開発を始めました。私がジョブズで、彼がウォズニアックです。
その上で、友人がFigmaやらTailwind CSSやらVue.jsでUIを実装してくれている間に、私はJSONをCSVにコンバートするための処理やログイン、決済の処理、友達が作ったUIのscriptの処理などをTypeScriptで書いていきました。2週間ほどで完成しました。
肝心のサブスクの決済の処理についてですが、今回サブスクアプリを初めて作るので、決済の実装が大変そうだなぁと思いながら、おそるおそる「firebase stripe subscription」と、なんとなく聞いたことのあるサービス名を入れて検索してみると、[Firebase Extensions | Run Subscription Payments with Stripe](https://firebase.google.com/products/extensions/firestore-stripe-subscriptions)というサイトが１番上に出てきたのですが、どうやらFirebaseにはExtension(拡張機能)というものがあるそうで、この拡張機能はStripeが公式で用意しているものなのですが、もうStripeとかCloud Functionsとか全然気にしなくて大丈夫、とりあえず手順通りにこの拡張機能を使ってくれたら、全部セットアップするから、というものでして、これじゃん、と思い早速使ってみました。こういう系って結局どこかでバグがでて１から自分で作った方が早かった、ということが多い印象なのですが、なんと、めちゃくちゃわかりやすい説明文で、ほとんどつまづくことなく、ものすごいスピードでサブスクの機能が完成してしまいました。この拡張機能、2020年の夏頃に出たらしいのですが、本当に誰でも簡単にサブスクが作れてしまいます。もはや鬼に金棒改め、エンジニアにこの拡張機能です。これさえあれば、いつでも面白いアイデアを思いついたらサブスクを作って、安定した収入を確保できてしまいます(まぁアイデア次第ですが)。全エンジニアが使えるようになっておくべき技術の１つとも言っても過言では無い気がします。

## おわりに

ちまたではエンジニアは稼げる！と言われたり、言われなかったりしますが、それはこういうお金を稼ぐ仕組みを作れるからなのかもしれません。ちなみにサブスクじゃなくて広告で稼ぐのはどうなのか、という話ですが、サブスクリプションの本いわく、YoutubeとFacebookがほとんどの広告市場を独占していて、その他大勢の会社で残りの椅子を取り合うゲームはやめておいた方が良い、となっていましたし、実際広告で稼いでいる個人開発者をほとんど見たことがないので、あんまり広告はよくない気がします。ただ買い切りのサービスは割と良いよと、サブスクリプションの本の中で書いていた気もします。まぁまだ1/4くらいしか読んでいませんが。とりあえず技術力がある方は、ぜひサブスクを作る、という選択肢も考えてみてください。あとJSONをCSVに変換したい場合、ぜひ[json to csv](https://jsontocsvconv.com)使ってみてください！
【Swift学習初日の方へ】 意識しておくと理解度UP! Swiftの特徴4選

#はじめに
数週間前よりSwift学習を始めた初心者から初心者へ送るアドバイスです！
Rubyを学習してきた身としては、初めはSwift...???って感じでした。
しかし、言語の違いや特徴を知ってから理解が早くなった！...気がするので、短いですが基本的な4つの特徴を共有します。

##①静的型付き言語 (Swift, Java, C#,Go,Scala)
Swiftは静的型付き言語に分類される言語です。

簡単に言うと、コンパイル時など実行前に変数や定数の型の情報を決定する言語のことです。
(*コンパイル・・・人間が書いたコードをコンピュータ用に変換すること　翻訳！)

↓イメージ
![スクリーンショット 2021-04-22 19.39.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1008995/da361759-22ca-bbce-81b5-eedafdac7bdc.png)

hogeに数列を代入しようとすると、赤マーカーでCannot assign value...とエラー文が表示されます。
例えばRubyでは実行してからエラーがわかりますよね。
Swift含め静的型付き言語は、このように事前にエラーが判明するんです！　イイね！！

まとめると・・・
誤った型の値が代入されるとコンパイルエラーになり、プログラムが実行されない。
つまり、実行前にエラーが判明し、安全性が高い。大規模プログラムに向いている。

コードを書くと、よくこのエラーに遭遇すると思います！

<details><summary>動的型付き言語(Ruby,Python,JavaScript,PHP)</summary>
静的型付き言語とは逆に、変数や定数のデータ型の宣言をしない言語です。
メリット：記述が少ない、簡単
デメリット：エラーが実行時にしかわからない　強制終了する</details>

##②nilの許容をコントロールできる

Swiftは基本的に変数、定数にnilを許容しません。
(*nil・・・値が存在しないこと)
メリットは、初期化されていない値や参照先が存在しない値の実行時エラーを防止し、より安全性を強化することができます。

一方で、nilを許容したい時もありますよね。(プロフ登録で写真は登録してもしなくても良いとか？)
そう言う時は**Optinal(オプショナル型)**を使うことでnilを許容します。

```
let a: Int? //aはOptional<Int>型 =>nilを許容
let b: Optional<Int> //bもOptional<Int>型 =>nilを許容
let c: Int // nilを許容しない
let d: Int! //暗黙的アンラップInt型 =>nilを許容

a = nil // エラーなし
b = nil // エラーなし
c = nil // コンパイルエラー
d = nil // エラーなし
```
!と?の違いは長くなりそうなので今回は割愛します。
↓この方の記事がとても丁寧で分かりやすかったです！
https://qiita.com/maiki055/items/b24378a3707bd35a31a8#optional-chaining


##③型推論

シンプルですが、代入する値で型を推測できる場合は、型の宣言が不要という仕組みです。
型の宣言を沢山しなくてすみますね！Swift優しい！

```
let a = 123 // aはInt型だな！
let b = "piyo" // bはString型だな！
```

##④ジェネリクス

特定の型に縛られず、汎用的なプログラムが書ける便利機能です。
例えば、同じ関数を整数型にも文字列型にも使いたいときを想像してみましょう。

```
func hoge(_ a:Int,_ b:Int)->Int{ //_(アンダースコア)は外部引数無し
    return(a,b)
}
//↑の表記　関数を名前で呼ぶ場合は、関数名(外部引数名 内部引数名: データ型)->戻り値と記述する。
(*外部引数は関数の外部で呼び出し時に、内部引数は関数内で使用されます。呼び名ですね！)

let hogehoge = hoge(10,50) // => (10,50)

func hoge(_ a:String,_ b:String)->String{ 
    return(a,b)
}

let hogepiyo = hoge("明日も","頑張ろう！") // => ("明日も","頑張ろう!")
```
型ごとに同じ記述はしんどいですよね。。。
=>**ジェネリクス関数**の出番！！

``` 
func hoge<T>(_ a:T,_ b:T)->(T,T){ //型指定なし Tは型引数と呼ばれます。
    return(a,b)
}

let hogehoge = hoge(10,50) //=> (10,50) 整数型になっている！
let hogepiyo = hoge("明日も","頑張ろう!") //=> ("明日も","頑張ろう!") 文字列型になっている！
```

型引数Tが引数に応じて置き換えられているんですね〜。
汎用的に関数を使用できるので、型ごとに関数を作らなくて済むので楽チンですね！

また、上の例で外部引数が出てますが外部引数があると、コードを書くときに外部引数を打つと予測変換で出てくるので便利です！

#さいごに
簡単ですが、特徴なんとなく分かりましたでしょうか。
Swiftって、人に優しい言語なんだなあと個人的に思いました！
私自身も勉強仕立てなので、誤っている箇所があればご指摘いただきたいです。(勉強になりますので！)

なんかこんな感じの見たなと、ぼやっと思い出せるだけでも理解度が異なると思います！

引き続き、頑張りましょう！
【Python】仮想環境でpip installしたのにグローバルにインストールされてしまう【Tips】

## 困ったこと
タイトルの通りですが、仮想環境で`pip install`したのにグローバルにインストールされてしまう事象が起きました。

## 環境
Python 3.8.2

## 結論
初期化したら直った。
`deactivate`で仮想環境を抜けてから実行しましょう。
インストール済みのモジュールも消えてしまうので注意しましょう。

```terminal
# .venv は各自の仮想環境名で実行してください
$ python -m venv --clear .venv
```

## 確認したこと
`activate`した状態で対話型シェルを起動し、prefixを確認してみたら、仮想環境のパスになってませんでした。
[参照:システムパラメータと関数](https://docs.python.org/ja/3/library/sys.html#sys.base_prefix)

```terminal
$ activate
(.venv):python
>>> import sys
>>> help(sys)
...
# DATA: のあたりに記載されているパスが仮想環境のパスになってない
exec_prefix = こことか
executable = こことか
prefix= こことか
```

## おわりに
なんで起きたのか気になって眠れない。（そうでもないか）
`python -m venv --clear`が実際何してるのか後で見ておこう。
文字列のインデックスとスライス

```py
word = 'python'
print(word[0]) #p
print(word[1]) #y
print(word[0:2]) #py
print(word[2:5]) #tho
print(word[2:]) #thon
print(word[:2]) #py
print(word[-1]) #n
print(word[:]) #python
#word[0] = 'j' エラー出る
print(word[:]) #python
print(len(word)) #6
```
PHPでAPI作成

# はじめに
今回この記事を書こうと思ったのは普段はSwiftの勉強を主にしているのですがそれだけでは就職活動がうまく行かないなと感じ、PHPの勉強を始めたのがきっかけとなります。
PHPの勉強を始めた時はPHPでWebアプリを作れればいいなと言うぐらいの気持ちだったのですが作ったアプリをスマホアプリとしても使えたら面白いなと思ったためAPIの作成の仕方まで調べたので備忘録として、また自分のようにAPI作りたいと思った人のために役にたてばいいなと思います。

# 簡単なAPIの作成
では、早速簡単なAPIの作成をしましょう。
このコードはこちらのnoteの記事を丸パクリしています。
[PHPで簡単なWebAPIを実装してみる【初心者向け】](https://note.com/kazztech/n/ndb3a5468f299)

```php
<?php
    // 文字コード設定
    header('Content-Type: application/json; charset=UTF-8');
    
    // numが存在するかつnumが数字のみで構成されているか
    if(isset($_GET["num"]) && !preg_match('/[^0-9]/', $_GET["num"])) {
        // numをエスケープ(xss対策)
        $param = htmlspecialchars($_GET["num"]);
        // メイン処理
        $arr["status"] = "yes";
        $arr["x114"] = (string)((int)$param * 114); // 114倍
        $arr["x514"] = (string)((int)$param * 514); // 514倍
    } else {
        // paramの値が不適ならstatusをnoにしてプログラム終了
        $arr["status"] = "no";
    }
    
    // 配列をjson形式にデコードして出力, 第二引数は、整形するためのオプション
    print json_encode($arr, JSON_PRETTY_PRINT);
?>
```

コードがかけたら
`XAMPP -> Service -> Apacheを選択 -> start`
`XAMPP -> Network -> localhost:8080 -> enable`
でサーバーを立ち上げましょう。

```
http://localhost:8080/アプリ名/ファイル名.php?num=114
```

を開きましょう。

json形式で多分教示されていると思います。

これでめっちゃ簡単なAPIは作成できました。
ですが、実際はデータベースが絡んでくるのでデータベースからデータを取得しましょう。


# databaseからデータを取得するAPI

```php
<?php
    header('Content-Type: application/json; charset=UTF-8');

    $dsn = "mysql:host=localhost;dbname=データベース名;charset=utf8";
    $user = 'root';
    $password = '';

    $dbh = new PDO($dsn, $user, $password);
    $dbh -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $sql = 'select * from テーブル名 where 1';

    $stmt = $dbh -> prepare($sql);
    $stmt -> execute();

    while(true) {
        $rec = $stmt -> fetch(PDO::FETCH_ASSOC);

        if ($rec === false) {
            break;
        }
        $arr[] = $rec;
    }

    print json_encode($arr, JSON_PRETTY_PRINT);

?>
```

```
http://localhost:8080/アプリ名/ファイル名.php
```

に接続してみましょう。
データがあれば表示されると思います。
今回はデータベースから全件取得なのでパラメータなしでSQL文も短いです。
もし取得したい条件があるならパラメータを渡してあげましょう。

以下サンプルです。

```php
//Twitterのような投稿アプリで特定の文字列を含む内容の投稿を取得したい時
$content_query = $_GET["content_query"];
$sql = 'select * from post where content like "%'.$content_query.'%"';
```

```
http://localhost:8080/アプリ名/ファイル名.php?content_query="検索したい文字列"
```
これで欲しいデータが取得できます。

もし、エラーが出た場合は以下の項目を確認してください。
・データベースがあるか、間違っていないか
・テーブルがあるか、まちがっていないか
・mysqlのサーバーを立ち上げているか
これらがちゃんとできているのにエラーが出る時はググってください。

また、本番で使うには例外処理が必要になるので調べてください。

# 最後に
PHPの勉強をしている期間Swiftの勉強していなかったのでSwiftの能力は上がってないですがこうやってAPIを作ってSwiftでも使えるようにするのはかなり楽しかったですし、エンジニア（笑）としての能力は少し上がったかなと感じました。
さらに久しぶりに触るSwiftは新鮮に感じることができました。
今回はGETのみの記事ですがPOSTも難しくないので調べてコードを書いてみて欲しいです。
【Rails】Ｗin環境でRailsをインストールしようとして、While executing gem...(OptionParser::MissingArgument)missing argumentと言われたときの対処法【Windows】

<h2>症状</h2>
Windows環境にRailsの環境設定をしようとしたときに、Railsをインストールしようとしたとき、下記のエラーが表示されてしまいました。(Windows 10 Pro 64 ビット)

```terminal:ターミナル
gem install rails -v
ERROR:  While executing gem ... (OptionParser::MissingArgument)
    missing argument: -v
```

翻訳すると、「gemの実行中...（OptionParser :: MissingArgument）引数がありません」でした。


<h2>解決方法</h2>
きちんと、バージョンを指定したら、インストールできました。

```terminal:ターミナル
gem install rails -v "6.0.3"
```
FizzBuzz問題

非常に有名なプログラミングの問題とのことなので
備忘録として残しておく

1〜100までの数字をターミナルに出力。ただし、「3の倍数」のときは数字の代わりに文字列でFizz、「5の倍数」のときはBuzz、3と5の倍数である「15の倍数」のときはFizzBuzzと出力するという問題。

問題文からの仕様を整理すると

- 数字の1~100を出力する
- 値が3の倍数のときだけ、"Fizz"という出力に置き換える
- 値が5の倍数のときだけ、"Buzz"という出力に置き換える
- 値が3と5の倍数のときだけ、"FizzBuzz"という出力に置き換える

そしてこの問題は条件分岐と条件の組み合わせを利用するのが鍵とのことだ

```ruby
def fizz_buzz
  num = 1
  while num <= 100 do
    puts num

    num = num + 1
  end
end

fizz_buzz
```

まずは１〜１００までの数字を出力するコードを記述
条件を指定して繰り返し処理をする場合は、whileメソッドを使用

```ruby
def fizz_buzz
  num = 1
  while num <= 100 do
    if num % 3 == 0    # 3の倍数のとき
      puts "Fizz"
    elsif num % 5 == 0    # 5の倍数のとき
      puts "Buzz"
    else    # それ以外のとき
      puts num
    end

    num = num + 1
  end
end

fizz_buzz
```
続いて、「3の倍数」のときは数字の代わりに文字列でFizzと、「5の倍数」のときはBuzzと出力

```ruby
def fizz_buzz
  num = 1
  while (num <= 100) do
    if num % 15 == 0    # 15の倍数のとき
      puts "FizzBuzz"
    elsif (num % 3) == 0    # 3の倍数のとき
      puts "Fizz"
    elsif (num % 5) == 0    # 5の倍数のとき
      puts "Buzz"
    else    # それ以外のとき
      puts num
    end

    num = num + 1
  end
end

fizz_buzz
```
そしてここに「15の倍数（3と5の倍数）」の時についての条件式を追加。しかし、このまま下に追加してしまうと上記4行目の「3の倍数であるか」または6行目の「5の倍数であるか」という条件式が真になり、FizzまたはBuzzと表示されてしまう。

したがって、if文の最初に「15の倍数」のときはFizzBuzzと出力する条件を追加する。
コマンド実行中だけSSHポートフォワーディングを有効化する

# SSHポートフォワーディング
便利ですね。普通はこんな具合に`ssh`コマンドを立ち上げっぱなしにすると思います。

```
$ ssh www.example.com -fNL 8000:localhost:8000  # -Lでポート指定、-fNでバックグラウンド待機
$ mycommand foo bar  # ポートフォワーディングが必要なコマンドを実行する
mycommandの出力：fooをbarするにゃん
$ mycommand hoge fuga  # SSH起動中はポートフォワーディングが持続する
mycommandの出力：hogeをfugaするにゃん
...
```

さて、特定のコマンドを実行する間だけポートフォワーディングしたいとします。ナイーブにやるならこうなりますね。

```
$ ssh www.example.com -NL 8000:localhost:8000 &
[1] 4273
$ mycommand foo bar
mycommandの出力：fooをbarするにゃん
$ kill 4273
[1]+ Done        ssh www.example.com -NL 8000:localhost:8000 &
```
これではタイプしている間に宇宙が熱的死を迎えてしまいます。

# まずは関数化
とりあえず面倒な部分を設定ファイルにまとめます。

```ssh:~/.ssh/config
Host myhost
HostName www.example.com
LocalForward 8000 localhost:8000
```

```bash:~/.bash_profile
function spf() {
  ssh $1 -N &  # $1はサーバ名
  local pid=$!  # SSHのプロセスIDを保存する
  shift  # $2以降はコマンドとその引数
  $@  # コマンドを呼び出す
  kill $pid  # SSHポートフォワーディングを止める
}
```
これで`ssh`でリモートのコマンドを実行するようなノリで使えるようになりました。

```
$ spf myhost mycommand foo bar
[1] 42365
mycommandの出力：fooをbarするにゃん
[1]+ Done        ssh myhost -N &
```
コマンドの出力の前後に余計なメッセージが出ちゃいますねえ。ぐんにょり。

# 余計なメッセージを消す
コマンドの前後のメッセージは、バックグラウンドジョブの起動と終了のメッセージです。これらを非表示にする処理を追加すれば…

```bash:~/.bash_profile
function spf() {
  set +m  # バックグラウンドジョブの終了メッセージを非表示にする
  { ssh $1 -N & } 2> /dev/null  # バックグラウンドジョブの起動メッセージを消す
  local pid=$!  # SSHのプロセスIDを保存する
  shift  # $2以降はコマンドとその引数
  $@  # コマンドを呼び出す
  kill $pid  # SSHポートフォワーディングを止める
  sleep 0.01  # ジョブ終了メッセージが出ないように少し待ってから
  set -m  # 終了メッセージの表示設定をもとに戻す
}
```
🏆🏆🏆　優　勝　🏆🏆🏆

```
$ spf myhost mycommand foo bar
mycommandの出力：fooをbarするにゃん
```

# ポートフォワーディングを意識せず使う
もしSSH接続先が1つに決まっているならば、エイリアスを設定すると…

```bash:~/.bash_profile
alias mycommand='spf myhost mycommand'
```
🏰🏰🏰　殿　堂　入　り　🏰🏰🏰

```
$ mycommand foo bar
mycommandの出力：fooをbarするにゃん
```
ポートフォワーディングを意識する必要もなくなりましたとさ。

# 謝辞
バックグラウンドジョブの起動メッセージを消す方法は、ひよどりBasistさんに教えていただきました。ありがとうございます。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">{ sleep 100 &amp; } 2&gt; /dev/null<br>ちょっと違うかも</p>&mdash; ひよどりBasist (@VisualBasist) <a href="https://twitter.com/VisualBasist/status/1385192302033858564?ref_src=twsrc%5Etfw">April 22, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
FlutterWebでローカル環境実行時のポート番号を指定する

## 概要
Flutter2.0が最近出たので、久々にローカルで動かしてみました。Flutter2.0ではWebへの正式対応するということで、ローカル環境で実行する場合はサーバのプロセスを立てる形になります。ここで何も設定しないとサーバプロセスのポート番号が自動で割り当てられるのですが、これを指定して実行する方法を紹介します。

## 方法
・実行時の引数に`--web-port 5555`のような感じで、実行時に指定したいポート番号を設定します。
・VSCodeで起動している場合は`launch.json`で、`"args": ["--web-port", "5555"]`のように設定を追加します。
・なお、上記の方法はバージョン2.0で動作確認しています。


## 参考
[How to specify a port number while running flutter web](https://stackoverflow.com/questions/58248277/how-to-specify-a-port-number-while-running-flutter-web)
MySQLの使い方（メモ）

#最初に
僕がMySQLを勉強していくうえで重要そうなものを初心者視点でまとめてみたものです。
間違いがあるかもしれないです...（間違えないように気を付けます）

###MySQLの起動
```
net start mysql57
```
※mysql57の部分は各自変える
###MySQLの停止
```
net stop mysql57
```
###MySQLへの接続/ログイン
```SQL
mysql --user=root --password
```
rootユーザーとしてログイン
###MySQLからログアウト
```SQL
exit;
```
###データベース一覧を見る
```SQL
SHOW databases;
```
###データベース作成
```SQL
CREATE DATABASE study CHARACTER SET utf8;
```
※studyは作るデータベースの名前
###データベースの選択
```SQL
USE study;
```
###テーブル一覧を見る
```SQL
SHOW tables;
```
###テーブル構造の表示
```SQL
DESCRIBE users;
```
※usersはテーブルの名前
###テーブル作成
```SQL
CREATE TABLE users
(
  id serial primary key,
  name VARCHAR(40) not null
);
```
##INSERT（データの挿入）
```SQL
INSERT INTO users(name)
VALUES ('username1');
```
##SELECT
###全件全列参照
```SQL
SELECT * FROM users;
```
###全件、指定した列だけ参照
```SQL
SELECT name FROM users;
```
※この場合、nameという列を全件参照
###条件指定
```SQL
SELECT * FROM users
WHERE name="username1";
```
###条件指定（AND/OR）
```SQL
SELECT * FROM users
WHERE name="username1"
AND name="username2";
```
```SQL
省略
OR name="username2";
```
###LIKE演算子
```SQL
SELECT * FROM users
WHERE name LIKE "%user%";
```
※前後に%を付ける。片方だけ付けると前方一致や後方一致になる。
###
```SQL

```
React×Firebase(create-react-app)連携時の注意事項

# 本ページの趣旨
FireBaseに記載されているドキュメントを流し読みすると、つまづきやすいポイントを記載する。

## Node.jsのバージョン
最新版は対応していない、必ずFareBaseのドキュメントを確認すること。

## farebase init 時の注意事項
基本はコマンドラインに書いている通りに進めてOKだが、注意が必要な個所がある。
**そもそも英語をまじめに読めば回避できる。**

### indexの上書き

```
File public/index.html already exists. Overwrite? (y/N)
```
**y**を選択するとindex.htmlが上書きされて消える。

### 本番環境のディレクトリ
```
What do you want to use as your public directory?
```
ReactはBuildフォルダに本番環境が入るので、下記を入力すること。

```
build
```

## ロケーション
**asia-northeast1 （東京）**を選択する。
間違えるとプロジェクトの作成からやり直しする必要がある。

## Functionsの使用
**無料プランでは使用できない**ため、従量課金制プランに変更する必要がある。
複数のcsvを1つのブックの各シートにコピーしてみた

#1. 背景
過去に投稿した記事で複数のCSVファイルを1つのブックの各シートにまとめたいとの質問があった為作成しました。
#2. ソースコード
取り敢えず、下記のコードをコピペすれば動作するはずです。素人のコードですので、読みづらい点はご容赦ください。

```vb
Option Explicit

Sub Main()
    Dim SelectedFiles As Variant '入力ファイル名の一覧
    Dim inputfile As String '入力ファイル名
    Dim OutputWB As Workbook '結合データ記入用ワークブック

    Set OutputWB = Workbooks.Add
    OutputWB.Worksheets(1).Name = "入力ファイル一覧"

    'エクスプローラーを起動し、ファイルを選択
    SelectedFiles = Application.GetOpenFilename("CSVファイル(*.csv),*.csv", MultiSelect:=True)

    'CSVを読み込む
    Call ReadCSV(SelectedFiles, OutputWB)
End Sub

Private Sub ReadCSV(ByRef datafiles As Variant, ByVal wb As Workbook)
    Dim filecounter As Integer, arraycounter As Integer, rowcounter As Integer
    Dim buf As String
    Dim tmp As Variant, inputfile As Variant
    Dim pos As Integer
    
    filecounter = 1
    For Each inputfile In datafiles
        wb.Worksheets(1).Cells(filecounter, 1).Value = inputfile
        'データコピー先となるシートを追加
        wb.Worksheets.Add After:=wb.Worksheets(wb.Worksheets.Count)
        'シート名をcsvのファイル名に変更
        pos = InStrRev(inputfile, "\")
        wb.Worksheets(wb.Worksheets.Count).Name = Mid(inputfile, pos + 1)
        'コピー先の行数を初期化
        rowcounter = 1
        Open inputfile For Input As #1
        Do Until EOF(1)
            '一行分を読み込む
            Line Input #1, buf
            '区切り文字で分割する
            tmp = Split(buf, ",")
            For arraycounter = 0 To UBound(tmp)
                wb.Worksheets(1 + filecounter).Cells(rowcounter, arraycounter + 1).Value = tmp(arraycounter)
            Next
            rowcounter = rowcounter + 1
        Loop
        Close #1
        filecounter = filecounter + 1
    Next inputfile
End Sub
```
#2-1. 変更点
今回のプログラムは[過去に投稿した記事](https://qiita.com/Naruhidon/items/9245bdf7f51d7e1e6c17)のプログラムを9割流用していますので、プログラムの流れはそちらをご確認ください。今回変更した点は、csvの値を記入する前に、新規にシート追加し、記入先を追加したシートにした点です。

```vb
Private Sub ReadCSV(ByRef datafiles As Variant, ByVal wb As Workbook)
    Dim filecounter As Integer, arraycounter As Integer, rowcounter As Integer
    Dim buf As String
    Dim tmp As Variant, inputfile As Variant
    Dim pos As Integer
    
    filecounter = 1
    For Each inputfile In datafiles
        wb.Worksheets(1).Cells(filecounter, 1).Value = inputfile
        'データコピー先となるシートを追加
        wb.Worksheets.Add After:=wb.Worksheets(wb.Worksheets.Count)
        'シート名をcsvのファイル名に変更
        pos = InStrRev(inputfile, "\")
        wb.Worksheets(wb.Worksheets.Count).Name = Mid(inputfile, pos + 1)
        'コピー先の行数を初期化
        rowcounter = 1
        Open inputfile For Input As #1
        Do Until EOF(1)
            '一行分を読み込む
            Line Input #1, buf
            '区切り文字で分割する
            tmp = Split(buf, ",")
            For arraycounter = 0 To UBound(tmp)
                wb.Worksheets(1 + filecounter).Cells(rowcounter, arraycounter + 1).Value = tmp(arraycounter)
            Next
            rowcounter = rowcounter + 1
        Loop
        Close #1
        filecounter = filecounter + 1
    Next inputfile
End Sub
```