OmniAICreator/Qiita-1.07M huggingface dataset:
【ReactNative】ReactNavigationの基本をまとめる

#はじめに
ReactNativeで画面を遷移させる際に使う `React Navigation` ですが、様々なpropsが用意されているので、簡単にまとめていきたいと思います。

#別の画面を指定して遷移させる
定義されたルートの宛先名を指定することで、任意の画面に遷移させることができます。

```sample.js
onPress={() =>
  navigate('定義されたルート名', { sampleParam: '任意の引数' })
}
```

#ひとつ前の画面に戻る
`goBack()` を用いることで、現在表示している画面のひとつ前に戻ることができます。

```sample.js
onPress={() => goBack()} // ひとつ前の画面に遷移
```

#複数個前の画面に戻る
`pop()` を用いることで、現在表示している画面の複数個前に戻ることができます。

```sample.js
onPress={() => navigation.pop(2)} // ふたつ前の画面に遷移
```

#ナビゲーション履歴を初期化して遷移する
`reset()` を使うことで、ナビゲーション履歴を初期化して遷移することができます。

```sample.js
onPress={() => navigation.reset({
  index: 0,
  routes: [{ name: 'Home' }],
})};
```
GCPセキュリティ変更に伴うAppEngineのIAM更新について

# 概要

* GCPから以下のようなメールが来ていた
* 要約すると「セキュリティの変更を行うけどIAMで権限を変更しないとデプロイできなくなるから2021年1月27日までに権限変更しておいてね」かと
* 参考までに実際対応した記録を以下に記載

<img width="80%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57350/598ec240-31d8-c87c-0b5a-9dd1fa6b32ee.png">


```
件名：ご対応のお願い - AppEngineのIAMの更新が必要です

Google App Engine をご利用のお客様

Google Cloud では、App Engine のセキュリティ体制の変更を行っております。
今後、App Engine アプリケーションをデプロイするデベロッパーは、
App Engine のデフォルトサービス アカウントに対する
 iam.serviceAccounts.actAs 権限が必要になります。
これらの変更は、2021 年 1 月 27 日から適用されます。
デベロッパーの皆様がAppEngineアプリケーションのデプロイを継続できるように、
適切なサービス アカウント権限を持っていることを確認していただく必要があります。
以下の手順に沿って、2021年1月27日より前にこの変更を有効にしていただくことも可能です。
```

# 詳細

* プロジェクトのロール一覧からサービスアカウントについてのロールを検索
* サービスアカウント管理者を選択

<img width="80%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57350/15a86c31-fa77-d583-caf8-1b7567662866.png">

* ”iam.serviceAccounts.actAs”権限が入っている事を確認

<img width="70%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57350/2ccfb58f-0d1c-3c15-900d-6ab14183c7d1.png">

* デプロイするユーザを選択
* 前述のロールを適用

<img width="70%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57350/31e983a0-8c11-2f1a-5162-8b70433e987f.png">

* 新しくロールが選択できたら保存を選択し完了

<img width="100%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57350/f4cce6b7-1b5a-3f87-e84c-840af7f13197.png">

* メンバー一覧にて、対象となるデプロイユーザに”サービスアカウントユーザー"があることを確認
* 多分これでいいはず

<img width="90%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57350/c5747ccc-3a01-a2b9-d7de-f2f4e9e79380.png">
Pythonで少しでも見やすく、短くコーディングするためのコツ

こんにちは、rickyです。
今回はpythonでコーディングするときに少しでもコードを少しでも見やすくする方法、短くする方法をご紹介します。
pythonの初心者さんがより良いコードを書けるようになれれば幸いです。

+ 数値

```python:num.py
# before
num = 10000000

# after
num = 10_00_000
```

+ スワップ

```python:swap.py
# before
a, b = 2, 3
tmp = b
b = a
a = tep

# after
a, b = 2, 3
a, b = b, a
```

## 以下は短くは書けるが、可読性を損なう書き方。
pythonは誰が書いてもわかりやすいコードが求められているため、基本的には書かないほうがいい書き方。
ただ、短くはできるため、行数が短いことが求められる状況では役に立つ。

+ 変数宣言

```python:variable.py
# before
a = 1
b = 2

# after
a, b = 1, 2

# supplement
# 別の型同士でも可能
a, b = 3, "b"

# 追記　コメントよりご指摘いただきました。
# afterの書き方は可読性を下げる恐れがあります。
# ベクトルのx, y座標のような関連性の高い変数に対して使うのがベター
```

+ if文

```python:if.py
a, b = 1, 2

# before
if a < b:
    print("A")
else:
    print("B")

# after
print("A") if a < b else print("B")

# 追記　コメントよりご指摘いただきました。
# printでまとめれる
print("A" if a < b else "B")

# and, orを使って条件式を前に出すことができる
print(a < b and "A" or "B")
```

まとめ
pythonでコーディングをしている際に後から自分のコードを見直したときに可読性が悪いと感じ今回の記事を書きました。
個人的にif文の書き方はかなり参考になりました。
この記事がみなさんの役に立てば幸いです。
【while、each】【超初心者向け】繰り返し処理を使って配列に押し込む方法

# はじめに

こんにちは！
最近はrubyの問題にハマっていて、気付いたら夜中、みたいない毎日です…。
そん中、意外と便利なのに、記事としてあまり見かけない方法で
while文なんかを使って一気に配列から配列に押し込む方法をご紹介いたします。


##each文の活用
````ruby
# こちらでは数字と文字列がごちゃごちゃになった配列を数字の配列（int）と文字の配列(str)に分けてます
x_arry = [1,"a",2,"b",3,"c"]

int = []
str = []
i = 0
x_arry.each do |n|
  i += 1
  if n.to_s =~ /^[0-9]+$/　　#こちらは正規表現で、数字のみを条件分岐してます。
    int << n
  else
    str << n
  end
end
print int
# => [1, 2, 3]
print str
# =>["a", "b", "c"]
````
※正規表現については詳しい記事が山ほどありますので、そちらをご参照くださいませm(_ _)m

参考記事①
https://programming-dojo.com/%E3%80%90ruby%E5%85%A5%E9%96%80%E3%80%91%E6%95%B0%E5%AD%97%E3%81%8B%E3%81%A9%E3%81%86%E3%81%8B%E3%82%92%E5%88%A4%E5%AE%9A%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/
参考記事②
https://qiita.com/pecooh/items/ee392125727f04bafaed


次はwhile文みてみましょう。

## while文の活用
````ruby

# 配列にそれぞれaの配列とbの配列にある数字を足し算して配列に打ち込んでます。

a = [43,56,77,22,45,66,78,99,53,44]
b = [1,2,3,4,5,6,7,8,9,10]

answer_arry = []

i = 0
while i < a.length do
  ans = a[i] + b[i]
  answer_arry << ans
  i += 1
end

print answer_arry
# => [44, 58, 80, 26, 50, 72, 85, 107, 62, 54]
````
この様にして、繰り返し処理をしてもらって自動で格納してもらえるのは便利ですね❗️
しかも、格納される直前で条件分岐すると、一定の条件のものが格納することもできますので是非やってみてください😌

クイズとか問題とかやっているとこういう処理が必要になってくることは多々ありますので重宝です😌
ぜひ、遊んでみてください☺️
ちなみにこれを使ってこんなふうにするとちょっとしたおみくじみたいなゲームとか作れそうですね☺️



# おまけ

````ruby

a = [rand(100),rand(100),rand(100),rand(100),rand(100),rand(100),rand(100),rand(100),rand(100),rand(100)]
b = [1,2,3,4,5,6,7,8,9,10]

answer_arry = []

i = 0
while i < a.length do
  ans = a[i] + b[i]
  answer_arry << ans
  i += 1
end

print answer_arry
````

randを使うことで数字がランダムになって出てくるので「ゾロ目の数が多い方が勝ちな！」みたいなゲームだったり、
randメソッドについてはPCとジャンケン対戦ができる様なゲームに応用ができたり楽しいです😊

それではまた❗️
ありがとうございましたm(_ _)m✨
Linux kernel version の確認

git から clone してきた linux kernel のソースコードのカーネルバージョンがなんだっけ？ってなった時に確認する手順のメモ。

git clone した kernel code の ディレクトリ直下にある Makefile の先頭(SPDX License の記述があるので 2 行目から)の VERSION, PATCHLEVEL, SEBLEVEL を確認する。

```
$ cd linux
$ cat Makefile
#SPDX-License-Identifier: GPL-2.0
VERSION = 5
PATCHLEVEL = 8
SEBLEVEL = 0
EXTRAVERSION =
:
```
Ubuntuに過去のnvidia-driverを導入

## nouveauの無効化
```bash
cd etc/modprobe.d/
touch blacklist-nouveau.conf
```
``blacklist-nouveau.conf``に以下の2行を記述  

```conf
blacklist nouveau
options nouveau modeset=0
```
## 再読み込み & 再起動
```baqsh
sudo update-initramfs -u
reboot
```

## CUDA10.1リポジトリの導入
```bash
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-repo-ubuntu1804_10.1.105-1_amd64.deb

```
## CUDA10.1リポジトリのインストール
```bash
sudo apt install ./cuda-repo-ubuntu1804_10.1.105-1_amd64.deb 
```
## パプリックGPGキーの取得
上記コマンドから``sudo apt-key adv --fetch-keys...``を叩く  

```bash
The public CUDA GPG key does not appear to be installed.
To install the key, run this command:
sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/comput
```
## リポジトリのアプデ
```bash
sudo apt update
```
## 機械学習リポジトリの導入
```bash
wget http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/nvidia-machine-learning-repo-ubuntu1804_1.0.0-1_amd64.deb
```
```bash
sudo apt install ./nvidia-machine-learning-repo-ubuntu1804_1.0.0-1_amd64.deb
```
```bash
sudo apt update
```
## インストール可能nvidia-driverの確認
```bash
ubuntu-drivers devices
```
## 特定のnvidia-driverのインストール

```bash
sudo apt install nvidia-418
```
DockerイメージをビルドしてECRにpushするshell script

いちいちビルドしてタグ付けしてecrにログインしてpushするのが面倒だったので、1コマンドでやってくれるスクリプト書きました。

普段そんなに書かないのでShell書くときのConventionみたいなの知らなくて、変な書き方してる部分もあるかも。
気が向いたらご指摘いただけると嬉しいです。

# 書いたやつ

```shell
#!/bin/sh

# Returns boolean indicates whether designated tagged-image exists.
  # arg1: repository name
  # arg2: tag name
function image_exists() {
  image=$(docker image ls -a | grep $1 | grep $2)

  if [ "$image" ]; then
    return 0;
  else
    return 1;
  fi
}

# Builds new image.
  # arg1: tag in the form like ${repository}:${tag}
  # arg2: Path to Dockerfile
function build_image() {
  docker build -t $1 -f $2 .
}

# Work on master branch
git checkout master

# Get latest master revision
revision=$(git rev-parse --short HEAD)

echo "Current master revision is ${revision}\n"

# Set constants
readonly repository=your-repository-name
readonly ecr_repository=************.dkr.ecr.<region>.amazonaws.com
readonly revised_repository=$repository:$revision
readonly ecr_revised_repository=$ecr_repository/$revised_repository
readonly path_to_dockerfile=<relative-path-to-dockerfile>

echo "local-repository: ${repository}
ecr-repository: ${ecr_repository}
local-revised-repository: ${revised_repository}
ecr-revised-repository: ${ecr_revised_repository}\n"

# Build current source if revision not exists
if image_exists $repository $revision; then
  # Do nothing.
  echo "local-revised-repository already exists. Skip build.\n"
  true;
else
  echo "Start building local-revised-repository."
  build_image $revised_repository $path_to_dockerfile;
fi

# Generate ecr-repository-tagged image if not exists
if image_exists $ecr_repository $revision; then
  # Do nothing.
  echo "ecr-revised-repository already exists. Skip tagging.\n"
  true;
else
  docker tag $revised_repository $ecr_revised_repository;
fi

# 必要に応じてこのへんでAWSの認証情報を設定する

# Login to ECR
aws ecr get-login-password --region <region> \
  | docker login --username AWS --password-stdin $ecr_repository

# Push new image to ECR
docker push $ecr_revised_repository

echo "Done.\n"

```

# 実装要件

- latestっていうタグ付けをすると、あとから見た時にいつのビルドなんだか分からなくなるので、リリース時点のgitリビジョンを利用する
    - 注意点: リリースブランチのリビジョンを取るべきなので、必要に応じて`master`部分を変更してください
- 指定されたリビジョンがタグ付けされたイメージがまだ存在していなければビルドする
    - 存在していればビルドをスキップする
- 指定されたリビジョンがタグ付けされたECR向けのイメージがまだ存在していなければタグ付けする
    - 存在していればタグ付けをスキップする
- ECRにログインする
    - 注意点: ECRログインする前に、そのECRが存在するAWSアカウントを操作できる認証情報を取得しておくこと。
    - profileがあるならそれを読み込む。
    - 自分の場合、MFAで一時的な認証情報を取得する必要があるため、その部分を書いてある
- ビルドされたイメージをECRにpushする

# おまけ: MFA認証
これはこれでめんどくさかったので、誰かの役に立てば。

```shell
# 標準入力からmfaコード入力を受け付ける
read -p "Input mfa code: " mfaCode

result=$(aws sts assume-role \
  --role-arn arn:aws:iam::************:role/<role-name> \
  --role-session-name <session-name> \
  --serial-number <mfa-serial> \
  --token-code $mfaCode --profile <profile-name>)

export AWS_ACCESS_KEY_ID=$(echo $result | jq ".Credentials.AccessKeyId" -r)
export AWS_SECRET_ACCESS_KEY=$(echo $result | jq ".Credentials.SecretAccessKey" -r)
export AWS_SESSION_TOKEN=$(echo $result | jq ".Credentials.SessionToken" -r)
```
JavascriptでFirebaseのrealtimeDatabaseを使う時のセキュリティを考える

Firebaseを使うと簡単にデータベースを使う事ができる。という事はしっていた。
realtimeDatabaseなどに関しては、SQLみたいな知識もほとんどいらない状態だった。

好きなjsonを作ってそのままの形で内部のjsonに吊り下げていける。というイメージで、javascriptで階層をいくらでも深くほれる。が、ここで問題がある

#好きなようにデータベースをいじれる→おもいっきり突っ込まれる→従量課金→破産。

このサービスの利点であり、欠点は従量課金である事。従量課金であれば、スパムみたいのにアタックされたら、金額もかなりが吹っ飛ぶとは思う。

#問題点:大量にデータをつっこまれると破産

ここでから、できる事を整理をすると

###ユーザーに認証をさせる。
認証はドメインなどで認証ができるので、アップロードするサーバーのドメインで認証をすると変なアクセスをはじける。
authorizedで出来る。（匿名ログイン）

###認証情報がないとデータベースへ投稿をできなくする。
これは割とrulesっていうので、出来る。

###認証情報を元にIDを発行してIDに紐付いた構造だけをいじれる
これもrulesで対応ができる。

ここまでで、投稿したユーザーがtable/userID/***のみしかいじれないようになるので、他の人の情報を消したり、変更したりってできないようにする事ができた。

#ユーザーの特定はできても、データを突っ込まれる可能性はまだある。
ここからは少しひらめきを書いていく。

###createを使わないでupdateを使う
{name:aaa,old:17}みたいのを変更はできても{name:aaa,old:17,sex:male}みたいに項目は追加できない。一つの情報量は一定以上には入らないはずなので、データを大量に突っ込まれる可能性は少なくなる

###createはユーザー登録時に行う
データを入力するエリアを作るにはどうしたらいいかと言うと、Functionと言う機能がある。functionはイベントをトリガーにして内部でプログラムを実行する事ができるので、ユーザーが認証をしたら、その段階で、そのユーザーの情報を{name:'',old:0}みたいのをcreateする。これは内部的な処理になるので、データベースのcreateがfalseでも作れるはず。もしくは、作れるように設定ができるはず。


#１ユーザーから、大量のデータをつっこまれなくても、大量のユーザーからデータを突っ込まれる可能性はまだある。
同時並行で大量の認証をするアカウントを作って、それを書き込みまくる。みたいな事をされない限り問題はなくなる。

ここで、authorizeを見ると
###同一IPからの新規作成の数を制限
30に変更などもできるので、大量の認証アカウントを同一IPから発行する事もできなくなる。

-----

ここまででが、現状javascriptで出来るであろうセキュリティ対策の内容で、ここで更に出来ることといえば、
各データの入力できる値の制限ができるのであれば（例えば文字数20までとか）

が対応方法としては有力かなと思います。

あとは、予算を設定している場合には、予算に対してのどれくらいの予算が消化されているかでアラート通知が来るようにはなっているが、一晩で気づかぬウチにアタックをくらっていたら、終わりじゃないかとは思ってるが、予算のアラートをいれておくのも、それなりに有効な手ではあると思う。

#追記

[FIREBASE](https://firebase.google.com/docs/rules?hl=ja "タイトル")

ここにある手順でいい感じのルール設定ができた。

##格納するKEYを設定ができる。

".validate": "newData.hasChildren(['A','B','C'])", みたいにして、A、B、Cが揃ってないと生成できませんよ。っていう事ができた。これだとA,B,C,Dも可能になるが、A,Cなどは不可能になる


##格納する値の種類を設定ができる。
"A": { ".validate": "newData.isString() && newData.val().length < 20" },Aは文字列であり、２０文字以内である。みたいに条件の設定をできる。

##条件を設定してないのは、セキュリティではじく
"$other": { ".validate": false }と設定すると、条件を設定してない、値が格納されようとしてもはじく事ができる。

これで、
【Ruby on Rails】初回ログイン時・jQueryを使用した、画面を真っ二つに割る方法

# 目標
![split.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700999/05b7d05d-73c7-dce6-92e4-efd53e674732.gif)


# 開発環境
ruby 2.5.7
Rails 5.2.4.3
OS: macOS Catalina

# 前提
[【Ruby on Rails】初回アクセス時に一度だけ表示（jquery.cookie.js使用）](https://qiita.com/japwork/items/229af214e928937c5c45)
こちらに少し手を加えた形となりますので、
コードをそのまま使うとcookieがなくなるまでは表示出来ません。

# 実際のコード

```erb:app/views/layouts/application.html.erb
<div class="indication-left"></div> # 追加
<div class="indication-right"></div> # 追加
<div class="box">
  <p>下記の表示終了ボタンを押すと、<br>更新しても見ることは出来ません。<br>
    新しいブラウザを立ち上げると表示されます。
  </p>
  <button>表示終了</button>
</div>
```
```css:app/assets/stylesheets/application.css
/* 追加 */
/* ここから */
 .indication-left, .indication-right{
  position: fixed;
  top: 0;
  width: 100%;
  height: 100vh;
  background-image: url("image1.jpg");
  background-size: cover;
  background-position: center;
  z-index: 1040;
  transition: 3s;
}
.indication-left{
  left: 0;
  clip: rect(0px 50vw 100vh 0px);
}
.indication-right{
  right: 0;
  clip: rect(0px 100vw 100vh 50vw);
}
.leftslide{
  transform: translateX(-100%);
}
.rightslide{
  transform: translateX(100%);
}
/* ここまで */


.box{
  position: absolute;
  top: 40%;
  left: 35%;
  width: 400px;
  height: 200px; 
  background-color: #ffffff;
  z-index: 1050; /* 変更 */
}
.box p{
    padding: 15px;
}
.box button{
  display: block;
  margin: 0 auto;
}
```
```js:app/assets/javascripts/application.js
$(function(){
  $(".indication").show();
  if($.cookie('Flg') == 'on'){
    $(".box").hide(); // indicationの子ではなくなったので追加
    $(".indication-right").hide(); // 追加
    $(".indication-left").hide(); // 追加
  }else{  
    $(".box").show(); // 追加
    $(".indication-right").show(); // 追加
    $(".indication-left").show(); // 追加
  }
  $(".box button").click(function(){
    $(".indication-right").addClass("rightslide"); // 追加
    $(".indication-left").addClass("leftslide"); // 追加
    $(".box").fadeOut(); // 追加
    $.cookie('Flg', 'on', { expires: 1, path: '/' });
  });
});
```

## z-indexについて
bootstrapを使用する場合、今回のような機能の実装では
.fixed-topよりも高い位置に表示する必要があったため、
1030より高い数値を指定しております。

```css:bootstrap.css
.fixed-top {
  position: fixed;
  top: 0;
  right: 0;
  left: 0;
  z-index: 1030;
}
```


## clip: rect(　);　について
clip要素とは画像などの要素について、切り抜き領域の外にある内容を表示せず、
切り抜き領域を指定するプロパティです。
指定方法はrectととなり、rectの長さには
rect(上端からの距離, 右端からの距離, 下端からの距離, 左端からの距離)のように、
上から時計回りの順でコンマで区切って4つの値を指定します。

右側の画像```clip: rect(0px 50vw 100vh 0px);```
左側の画像```clip: rect(0px 100vw 100vh 50vw);```

# まとめ
jqueryを使用せず、cssのinputを使用した方法もあるため、
両方の知識を入れておくのは大事だと思います。
近々更新できればと思います。

またtwitterではQiitaにはアップしていない技術や考え方もアップしていますので、
よければフォローして頂けると嬉しいです。
詳しくはこちら　https://twitter.com/japwork
【Python】クリップボード内の改行を削除するプログラムを作る+windowsでショートカットに登録する

## 経緯

* PDFファイルの論文からコピペしてgoogle翻訳に通したい時、余計な改行が入るのが邪魔。
* コピペ時の改行を削除するシンプルな方法として、以下のもの↓が既にqiitaに投稿されている。ぶっちゃけこれでいい。

[PDFをコピペした時の改行を消す方法](https://qiita.com/amata525/items/7cda251abb65acc972c8)


* 自分の使っているマウスのマクロボタンにこの機能を登録したかったため、pythonで実装を行った。
* .pyファイルを.exe化、さらにショートカットキーに登録した。ここで多少詰まったため、以下にその手順をまとめておく。

## コードを書く

```python
import pyperclip

s = pyperclip.paste()
s = s.replace("\n", "")
s = s.replace("\r", "")
pyperclip.copy(s)
```

`pyperclip`というモジュールを導入して、クリップボードの操作を行う。`pyperclip.paste()`でクリップボードの取得。
`replace()`を用いて改行コードの削除。もし削除する文字が`"\r"` `"\n"`の二種類だと不都合があるなら適宜調整する。
`pyperclip.copy()`でクリップボードに貼り付け。

なお、`pyautogui`を用いてペーストまで自動で行うのも試してみたが、実行速度が倍以上かかって使い物にならなかったのでボツ。クリップボードの操作だけできればいいとした。

## exe化する

`pyinstaller`を用いて実行形式に変換する。コマンドプロンプトから導入する。

```
pip install pyinstaller
```

続けて以下のコマンドを打ち込んで実行。

```
pyinstaller ファイル名 --onefile
```

distフォルダの中にexeファイルが作られる。

## ショートカットキーに登録する

[参考: プログラムを素早く起動する方法（ショートカット・キーを設定する）](https://www.atmarkit.co.jp/fwin2k/win2ktips/150use_shortcut/use_shortcut.html)

* 作成したexeファイルを右クリックし、ショートカットを作成する。
* ショートカットファイルはデスクトップ(もしくはスタートメニューフォルダ、もしくはその下のProgramsフォルダ)に配置する。

* ショートカットのプロパティを開く。ショートカットキーの項目があるので、そこに任意のキー(ctrl+alt+数字など)を入力する。
* ついでに実行時にウィンドウがいちいち開くと邪魔なので「実行時の大きさ」を選んで「最小化」に設定する。

これで完了。登録したキーで動かなかったら一度再起動する。

## 終わり
マウスのマクロボタンに登録して目標達成。
なお、実行完了に三秒くらいかかったので実用性がそこまで高いわけではない。それなら[先人](https://qiita.com/amata525/items/7cda251abb65acc972c8)の方法でいいやとも言える。

後は外部のマクロ機能に依存するなら別にコマンド一つで完結させる必要はないので、ショートカットのファイル名を一文字にしてpathの通ったフォルダに置く→「win+R, ファイル名, エンターを打ち込んで実行する」マクロとして登録しちゃうってのもアリ。何ならタスクバーに配置してwin+数字のショートカットで起動するのもアリ。これらの方が実行が早い説がある。

あとはもっと普通に効率よく改行を消す手段もあるかもしれません。
[Java] PDFバージョンを変換する

日常生活や仕事の中では、私たちの使ってるデバイスが、PDFバージョンに
厳しい条件が必要だという場合はよくあるんでしょう？こういう時なら、PDFバージョンを変換して、そのデバイスに合わせる必要があると思います。だから、この記事では、Free Spire.PDF for　Javaを使用してPDFバージョンを変換する方法を説明します（PDFバージョン1.0-1.7　変換可能）

**JARパッケージのインポート**
**方法1：** [Free Spire.PDF for Java](https://www.e-iceblue.com/Download/pdf-for-java-free.html)をダウンロードして解凍したら、libフォルダーのSpire.Pdf.jarパッケージを依存関係としてJavaアプリケーションにインポートします。

**方法2：** Mavenリポジトリから直接にJARパッケージをインストールしたら、pom.xmlファイルを次のように構成します。

```xml
<repositories>
   <repository>
      <id>com.e-iceblue</id>
      <name>e-iceblue</name>
      <url>http://repo.e-iceblue.com/nexus/content/groups/public/</url>
   </repository>
</repositories>
<dependencies>
   <dependency>
      <groupId>e-iceblue</groupId>
      <artifactId>spire.pdf.free</artifactId>
      <version>3.9.0</version>
   </dependency>
</dependencies>
```

**Javaサンプルコード：**

```java
package com.spire.pdf;

public class ChangePdfVersion {

    public static void main(String[] args) {

        //PdfDocumentオブジェクトを作成します
        PdfDocument document = new PdfDocument();

        //PDFドキュメントを読み込みます
        document.loadFromFile("test.pdf");

        //PDFバージョンを1.6に変更します
        document.getFileInfo().setVersion(PdfVersion.Version_1_6);

        //ドキュメントを保存します
        document.saveToFile("ChangePdfVersion.pdf", FileFormat.PDF);
        document.close();
    }
}
```

**完成例：**
![ch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/b86f56fe-23b2-852e-6456-bacfb41ffaa3.png)
Pythonでリストのコピーをする

# はじめに
Python3.8.3で実行した結果を記載しています。

# リストのコピー
「リストのコピーを作り、値を変えて元のものと比較したい」と思うことがある。その場合、次のようにcopyモジュールのdeepcopyメソッドを使って書く必要がある。

## 1次元リスト
リストが1次元のときは、`deepcopy()`、スライス、`list()`などでコピーできる。

```python:list_copy_example_1.py
import copy
list_1 = [0,1,2]
list_2 = copy.deepcopy(list_1) #deepcopy()を使う
list_3 = list_1[:] #元のリストをスライスする
list_4 = list(list_1) #list()を使う

list_2[0] = 1000
list_3[0] = 2000
list_4[0] = 3000
print(list_1)
print(list_2)
print(list_3)
print(list_4)
```

出力はこのようになる。

```
[0, 1, 2]
[1000, 1, 2]
[2000, 1, 2]
[3000, 1, 2]
```
## 2次元リスト
リストが2次元(以上)のときは、`deepcopy()`でコピーできる。スライスや`list()`ではうまくいかない(後述)。

```python:list_copy_example_2.py
import copy
list_1 = [[0,1,2], [3,4,5]]
list_2 = copy.deepcopy(list_1)

list_2[0][0] = 1000
print(list_1)
print(list_2)
```

出力はこのようになる。

```
[[0, 1, 2], [3, 4, 5]]
[[1000, 1, 2], [3, 4, 5]]
```

# うまくいかないパターン
## =で代入
リストの参照自体をコピーしているため、元のリストの値も変更されてしまう。

```python:anti_pattern_1.py
#=で代入する
list_1 = [0,1,2,3]
list_2 = list_1

list_2[0] = 1000
print(list_1)
print(list_2)
```

出力

```
[1000, 1, 2, 3]
[1000, 1, 2, 3]
```

## スライス、list( )でコピー
[Pythonのリストで参照渡しでないコピーを作成する話](https://qiita.com/hrs1985/items/4e7bba39a35056de4e73) には、スライスでコピーするのが手軽だとあるが、これは**リストが1次元のときのみ**うまくいく。

リストが2次元以上になると、次のようになる。途中で参照渡しが起こるのでうまくいかないようだ。

```python:anti_pattern_2
#元のリストをスライスでコピーする(2次元)
list_3 = [[0,1,2], [3,4,5]]
list_4 = list_3[:]

list_4[0][0] = 1000
print(list_3)
print(list_4)
```
出力

```
[[1000, 1, 2], [3, 4, 5]]
[[1000, 1, 2], [3, 4, 5]]
```

また、スライスの代わりに`list()`メソッドを使っても同じ結果になる。

# 解説
リストを普通に複製すると、値ではなく参照自体がコピーされる。これを**浅いコピー**という。逆に、値のみをコピーすることを**深いコピー**という。Pythonでは、リストや辞書のような複合オブジェクトには、特に指定がない限り浅いコピーが適用される。多次元リストをスライスでコピーしたときに参照渡しになっていたのも、スライス内部での2次元目のコピーが浅いコピーだったからだろう。
そして、`copy.deepcopy()`メソッドは「深いコピーをして」という指示である。これを使うと、多次元リストのコピーでも、すべての要素に深いコピーをしてくれる。
詳しくは、公式の[copy --- 浅いコピーおよび深いコピー操作](https://docs.python.org/ja/3/library/copy.html)を参照。

# まとめ
1次元リストならスライス、`list()`、`copy.deepcopy()`
多次元リストなら`copy.deepcopy()`
Git, GitHub用語をざっくり理解する。

##Gitとは
ファイルのバージョンを管理するツール。
いつ、誰が、どのような変更を行ったのかを管理する。

##GitHubとは
Gitで公開した他人の作品をブラウザで見ることのできるウェブサービス。

##リポジトリ
ファイルや設定情報を保管する場所。

##リモートリポジトリ
サーバーにあるリポジトリ。

##ローカルリポジトリ
自分のPCにあるリポジトリ。

##コミット
ファイルの追加や変更の履歴をローカルリポジトリに記録すること。

##プッシュ
ローカルリポジトリの変更をリモートリポジトリに反映させること。

##ブランチ
履歴管理を枝分かれさせてたもの。

##クローン
リモートリポジトリをコピーしてローカルリポジトリを作成すること。


##フェッチ
リモートリポジトリの変更をローカルリポジトリに持ってくる。

##マージ
変更をローカルリポジトリに反映させること。

##プル
リモートリポジトリの変更をローカルリポジトリに反映させること。
フェッチとマージをまとめてやってくれる。

##プルリクエスト
自分が行った変更をオリジナルのものに反映させたいというときに使う通知。
vercel/og-imageをフォークして自分だけのOGP画像生成サービスを作ろう

動的にOGP画像を生成するのに [Vercel](https://vercel.com) が良いらしいという話を何度か聞いた。動的サイトの配信が出来て、画像もキャッシュしてくれるのでとても良い。しかも無料プランまである。

動的OGP生成サービス、作りたい。

## vercel/og-image とは
そんなわけであれこれ調べていたら Vercel 公式のリポジトリが出てきた。

* リポジトリ：https://github.com/vercel/og-image
* サイト：https://og-image.vercel.app

なんと Vercel 公式が動的にOGPを生成するサービスを作っていた。
しかも実際に公式ドキュメントやブログに使われているようで、https://vercel.com/docs の `og:image`は

```html
<meta property="og:image" content="https://og-image.now.sh/Introduction%20to%20Vercel.png?
theme=light&
md=1&
fontSize=75px&
images=https%3A%2F%2Fassets.vercel.com%2Fimage%2Fupload%2Ffront%2Fassets%2Fdesign%2Fzeit-black-triangle.svg">
```

となっている(パラメータごとに改行した)。

さらに README.md を眺めていると

>You'll want to fork this repository and deploy your own image generator.
>https://github.com/vercel/og-image/blob/main/README.md#deploy-your-own

と書かれているではないか。

そういうわけなので、君も vercel/og-image をフォークして自分だけのOGP画像生成サービスを作ろう！

## 作り方
前置きはこれくらいにして作り方を紹介します。

詳細はREADME.md の [Deploy your own](https://github.com/vercel/og-image#deploy-your-own) と、[CONTRIBUTING.md](https://github.com/vercel/og-image/blob/main/CONTRIBUTING.md) を読みましょう。以下にざっくりとまとめます。

1. [vercel/og-image](https://github.com/vercel/og-image) を フォーク
2. `$ npm install -g vercel` で`vercel`コマンドを使用可能に
3. `$ vercel login` でログイン( https://vercel.com でのアカウント作成が必要)
4. アカウントが無料プランであれば`vercel.json`の`rewrites`意外の設定を削除する
5. `$ vercel dev` で動作確認
6. 変更を加える
7. `$ vercel` でデプロイ

注意点としては4.に記載の通り無料プランで使用できない設定を削除する必要があることです。
無料プランで動作確認して、さらに高性能なプランを利用したい場合はプランを変更してから再度設定を戻すと良いでしょう。

また、開発の上での主要なファイルはだいたい以下の通りです。基本的に TypeScript で記述されています。

* `/api/index.ts`
  * OGP画像を生成するAPI
  * テンプレートは`/api/_lib/template.ts`
* `/web/index.ts`
  * メインページのフロントエンド用コード(出力先は`/public/dist`)
  * CDNから読み込んだ [dotdom](https://github.com/wavesoft/dot-dom) を使用しています

### Windows での不具合？
`$ vercel dev`を使用したところ、ビルドした`public/dist/web/index.js`が読み込めずフロントエンドが真っ白になっていました。

いろいろ試したんですが`public/a/b.txt`など`public`よりも深いところにあるファイルが配信されませんでした。WSL2 で試したところ動作したので、Windows 特有の問題かもしれません。

## 作ってみたもの
実際にフォークしてデプロイまでやってみました。

* リポジトリ：https://github.com/mkizka/og-image
* サイト：https://ogi-api.vercel.app

変更したのは以下の通り。

* 日本語に対応させた
* ロゴの選択肢を無くした
* 背景画像を追加出来るようにした

こんな感じになります(背景は https://unsplash.com から持ってきたいい感じの画像)↓
![](https://ogi-api.vercel.app/!%5B%5D(https%3A%2F%2Fgithub.com%2Fmkizka.png)%0A%0A%E3%81%93%E3%82%93%E3%81%AA%E6%84%9F%E3%81%98%E3%81%AB%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%99.png?theme=black&md=1&fontSize=100px&background=https%3A%2F%2Fimages.unsplash.com%2Fphoto-1511406239133-2c1130a2d754)
viコマンドの備忘録

とりあえずこれだけ知ってれば使えるやつ。
（ってかこれしか使いこなせてない

| コマンド |操作|
|:-----------|:------------:|
| i    | 挿入モード| 
| :w| 書込| 
| :q| 終了| 
| :wq| 書込 +終了|
| :w !sudo tee %| 読取専用ファイル書込|
| :q!| 強制終了|
| u| 変更取消|
| /文字列   | 検索|
| dd    | 行削除| 
| ctrl + f    | 次ページ     |
| ctrl + b    | 前ページ     |
【Rails】人気投稿をランキング形式で表示させる

個人開発アプリを作成していて、人気投稿順に見られると使いやすくなると思い、
基本的に[こちらの記事](https://qiita.com/mitsumitsu1128/items/18fa5e49a27e727f00b4m)を参考にしながら実装しました。

#routes.rb
```ruby:routes.rb
get 'rank' => 'shops#rank'
```
私の場合はshopsコントローラーのrankアクションに設定しました。

#shops_controller.rb
```ruby:shops_controller.rb
 def rank
    @all_ranks = Shop.find(Favorite.group(:id).order('count(shop_id) desc').limit(5).pluck(:shop_id))
 end
```
shopsコントローラーにrankメソッドを定義。いいねが多い投稿順に表示させます。

#rank.html.slim
```ruby:rank.html.slim
- @all_ranks.each.with_index(1) do |shop, i|
  h5.col-md-5
    .card.shadow
      | No.
      = i
      |　
       = link_to shop.name, shop_path(shop)
       = link_to((image_tag shop.picture.url), shop_path(shop.id), class: 'shop-picture') if shop.picture.url.present?
```
viewファイルを作成し、表示させます。例として抜粋しました。
後はCSSで外観を修正します。

```ruby:
@all_ranks.each.with_index(1) do |shop, i|
```
上記より、いいねが多い順に表示させることができます。

#完成
お手軽にランク形式での表示が完成しました。
Your URL didn't respond with the value of the challenge parameter.

slack APIを使っていたら、flaskのエンドポイントが使えないというエラーが出ました。
これはchallenge parameterを返すようなapiになっていないとokをださないよというもの。
だから、以下のようにpostでくれたchallenge parameterをそのまま返してあげるapiを作ればok!


```python
@app.route("/slack/sample", methods=["POST"])
def slack_sample():
    return request.json["challenge"]
```
【StereoDepth】 MC-CNN : CNNを用いたマッチングコスト計算法

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/da884df1-76f0-268a-f324-6c088b72176f.png)

昔ながらのSemi Global MatchingにMatching Costの計算をNetworkに学習させるというかなり初期の論文である。



<h1>Matching Costの計算</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/52864818-2c7d-d6b0-fdf1-12aa5bdb1f51.png)

このネットワークはRight ImageのPatchとLeft ImageのPatchを入力し特徴のSimilarityを学習する。

L1のみCNNにを使いそれ以外のそうではFully Connected Layerを使う。

L3ではLeftのFeature MapとRightのFeature Mapを結合する。

L8ではGood MatchとBad Matchの2つのScoreをoutputする。

<h1>結論</h1>
だいたい理解出来たのだが、Good MatchとBad Matchの２つを出力する理由が分からなかった。


<h1>参考文献</h1>
Computing the Stereo Matching Cost with a Convolutional Neural Network
https://arxiv.org/pdf/1409.4326.pdf
サイコロの作り方

### javascriptでのサイコロ作成
javascriptでサイコロを作る方法です。

```
<body>
  <button onclick="dice()">サイコロ</button>
  <p id="result"></p>
</body>
```

ボタンタグをクリックすると1〜6の数字がpタグに表示されます。
onclick属性をbutton要素に記述することでボタンをクリックしたときにjavascriptに作成したdice関数を起動させます。

```
<head>
  <script>
    function dice() {
      let d = document.getElementById("result");
      let r = Math.ceil(Math.random()*6);
      d.textContent = r;
    }
  </script>
</head>
```

dice関数には変数dとrを定義します。dにはサイコロを振った結果を表示するためにp要素に指定したid属性のresultを取得させます。
rには1〜6のどれかの数字がランダムに取得できるようにします。

「Math.ceil( )」メソッドは引数に指定した値を小数点以下繰り上げしてくれるメソッドです。（仮に1.34という少数なら2に繰り上げてくれます。）

「Math.random( )」メソッドは0より大きく1より小さい値をランダムに返してくれるメソッドです。「Math.random( )*6」とする事で0より大きく6より小さい数値を返してくれます。

この2つのメソッドを組み合わせることで1〜6のランダムな数値を取得できるのでサイコロが完成します。

「d.textContent = r;」で1〜6の結果をid属性でresultを持つp要素に表示することができます。

### 修正
上記の内容に間違いがあったようなので、修正します。
「Math.random()」メソッドは0より大きく１より小さい値を返すのではなくて、【0以上1未満の値を返す】ようなので、script要素内は下記になります。

```
  <script>
    function dice() {
      let d = document.getElementById("result");
      let r = Math.floor(Math.random()*6+1);
      d.textContent = r;
    }
  </script>
```

「Math.floor()」メソッドは引数に指定した値を小数点以下切り捨てしてくれるメソッドです。「Math.floor」の引数内は1以上７未満になるので、1〜６の値をランダムに変数rに代入してくれます。

```
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <title>dice</title>

  <script>
    function dice() {
      let d = document.getElementById("result");
      let r = Math.floor(Math.random()*6+1);
      d.textContent = r;
    }
  </script>
</head>

<body>
  <button onclick="dice()">サイコロ</button>
  <p id="result"></p>
</body>
</html>
```
上記のコードをhtmlファイルにコピーすれば試すことができます。
「独学プログラマー」を読んでみてのレビュー

#はじめに
筆者はシステムエンジニアとして9年近く働いてきている。
実際にコーディングをするのは3,4年まともにやっていなく、最近はもっぱらwebシステムのSE業（PJ管理、要件定義、設計）を行ってきていました。
ふとしたきっかけからデータサイエンスよりの職種にジョブチェンジしたいと思い、改めて1から「学ぶ」ということをしてみようと思い、今回その手始めに「独学プログラマー」を読んだのでそのレビューをしていきます。


#参考書について
タイトル：独学プログラマー Python言語の基本から仕事のやり方まで
著者　　：中川慶一郎(編著) (著), 小林佑輔(編著) (著)
Amazon URL:
https://www.amazon.co.jp/%E3%83%87%E3%83%BC%E3%82%BF%E3%82%B5%E3%82%A4%E3%82%A8%E3%83%B3%E3%83%86%E3%82%A3%E3%82%B9%E3%83%88%E3%81%AE%E5%9F%BA%E7%A4%8E%E7%9F%A5%E8%AD%98-%E6%8C%91%E6%88%A6%E3%81%99%E3%82%8BIT%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AB-%E4%B8%AD%E5%B7%9D%E6%85%B6%E4%B8%80%E9%83%8E-%E7%B7%A8%E8%91%97/dp/4897979536

#概要
本書はデータサイエンティストの入門書という扱い。
・データサイエンティストってそもそも何？
・具体的にどういったことをやるの？
という部分を丁寧に説明してくれている。

プログラミング言語としてはR言語を用いて、各業務のケーススタディ付きで説明してくれるため業務イメージも付きやすかった。
本書のざっくり流れは↓のような感じ。

・分析とは？
　　分析についての概要、その中でデータサイエンティストとは？の部分を説明
・データ分析に必要なスキル
　　業務知識であったり、IT技術であったり、どの部分が求められるかを説明
・ケーススタディ
　　要因分析編、予測編　と分けて実例を交えながら説明

#レビュー
※あくまで個人的な感想です。
###Good
* 実務を行っていない人からすれば、まずは読むべき一冊。
* ケーススタディが実例を交えながら説明してくれるのでイメージが付きやすい
* ポイント解説　があり、細かい説明も助かる

###Bad（というほどでも無いけど気になった点）
* R言語をベースに説明が行われている点。。。
　　→あくまで筆者がRを触ったことがないというだけだが、Pythonベースで書かれていれば私としてはとても助かった


以上
ZenHubとスプリントプランニング

- 今回のスプリントで行う内容を決める
- 開発チームとプロダクトオーナーで合意する

---

## スプリントの作成

- ZenHub（GitHub）のマイルストーンを作成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/ca6b0924-5b2f-6446-9b52-dfbb455e592f.png)

---

## 期間を決める

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/2ba04b47-9f3e-4e23-17ff-6ba1822b46f3.png)

---

## スプリント名を決める

- スプリント開始日

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/d7b50e04-c142-6bdc-da22-404259af2b1f.png)

---

## 優先したいEpicを決める

- Epicの洗い出し、確認
- Issueの内容確認

---

## Issueの確認

- 内容の確認
- SPの確認

---

## タスクのサイズ

- スプリント内に終えられるタスクにする
- 終えられない場合にはタスクを分割する

---

## （残っていれば）先週からの付け替え

---

## 着手するIssueの確認

Issueにチェックを入れ、「Set Milestone」で今週のマイルストーンに設定する

---

## 合計SPの確認

---

## スプリントの作業の合意

---

# 参考

- スクラムガイド p9-p10 スプリントプランニング[^1]
- アジャイルのセレモニーとは? スプリント計画[^2]
- IPA アジャイル開発の進め方 スプリントプランニング[^3]
- エッセンシャル スクラム スプリントプランニング[^4]

[^1]: https://www.scrumguides.org/docs/scrumguide/v2017/2017-Scrum-Guide-Japanese.pdf

[^2]: https://www.atlassian.com/ja/agile/scrum/ceremonies

[^3]: https://www.ipa.go.jp/files/000065606.pdf

[^4]: https://www.amazon.co.jp/dp/4798130508

---

```
スプリントプランニング
スプリントの作業はスプリントプランニングで計画する。これはスクラムチームの共同作業である。
スプリントが 1 か月の場合、スプリントプランニングのタイムボックスは最大で 8 時間である。スプリ
ントの期間が短ければ、スプリントプランニングの時間も短くすることが多い。スクラムマスターは、
参加者に目的を理解してもらうようにする。スクラムマスターは、スクラムチームにタイムボックスを
守るように伝える。
スプリントプランニングでは、以下の質問に答える。
• スプリントの成果であるインクリメントで何を届けることができるか？
• インクリメントを届けるために必要な作業をどのように成し遂げるか？
トピック 1：スプリントで何ができるか？
開発チームは、スプリントで開発できそうな機能を予想する。プロダクトオーナーは、スプリントで達
成すべき目的と、完成すればスプリントゴールを達成できそうなプロダクトバックログアイテムにつ
いて検討する。スクラムチームはみんなで協力して、スプリントの作業を理解する。
スプリントプランニングのインプットは、プロダクトバックログ、最新のプロダクトインクリメント、開発チ
ームが予想するキャパシティと過去の実績である。プロダクトバックログから選択するアイテム数に
ついては、開発チームが責任を持つ。スプリントで何を達成するかを評価できるのは、開発チーム
だけである。
スプリントプランニングでは、スクラムチームがスプリントゴールを設定する。スプリントゴールとは、
プロダクトバックログを実装することで実現するスプリントの目的であり、開発チームがインクリメント
を開発する指針となるものである。
トピック 2：選択した作業をどのように成し遂げるか？
プロダクトバックログアイテムを選択し、スプリントゴールを設定したら、開発チームはスプリントでそ
れらの機能を「完成」したプロダクトインクリメントにする方法を決める。選択したプロダクトバックログ
アイテムとそれらを届ける計画を合わせて、スプリントバックログと呼ぶ。

開発チームは、プロダクトバックログを動作するプロダクトインクリメントに変えるために必要なシス
テムと作業の設計から着手する。作業の規模や工数はバラバラであっても構わないが、開発チー
ムが次のスプリントで実現できそうなものを計画する。開発チームがスプリントの最初の数日間で
行う作業については、スプリントプランニングで作業に分解する。作業の単位は 1 日以下にするこ
©2017 Ken Schwaber and Jeff Sutherland. Offered for license under the Attribution Share-Alike license of Creative Commons,
accessible at http://creativecommons.org/licenses/by-sa/4.0/legalcode and also described in summary form at
http://creativecommons.org/licenses/by-sa/4.0/. By utilizing this Scrum Guide, you acknowledge and agree that you have read and
agree to be bound by the terms of the Attribution Share-Alike license of Creative Commons.
Page | 10
とが多い。開発チームは自己組織化して、スプリントバックログの作業を引き受ける。これはスプリ
ントプランニングだけでなく、必要であればスプリントでも行う。
プロダクトオーナーは、選択したプロダクトバックログアイテムの明確化やトレードオフを支援する。
開発チームの作業が多すぎたり少なすぎたりした場合は、選択されたプロダクトバックログアイテム
について、開発チームとプロダクトオーナーで話し合う。あるいは、技術やドメインに詳しい人を招
待してアドバイスを求めることもできる。
スプリントプランニングが終了するまでに、開発チームは自己組織化したチームとして、どのように
スプリントゴールを達成し、どのように期待されるインクリメントを作成するかをプロダクトオーナーと
スクラムマスターに説明できなければいけない。
```
switch文を理解しよう！

今回は、switch文について学習したので、アウトプットしていきます
※以下の内容は、学習内容のアウトプット用のため、誤りがある場合があります。予めご了承ください

#switch文とは？
***switch文を一言でいうと、パターンを利用して制御式の値に応じて実行文を切り替える制御構文です。***

基本的な書き方は以下の通りです


```swift:qiita.rbvar 
switch 制御式 {
case パターン１:
制御式がパターン1にマッチした場合に実行される文

case パターン2:
制御式がパターン2にマッチした場合に実行される文

default:
制御式がいずれのパターンにもマッチしなかった場合に実行される文
}
```

switch文は、一度マッチして実行文を実行するとマッチングを終了し、それ以降のパターンはスキップするという特徴を持ちます。
if文やguard文は成立するか否かの２つのケースへの分岐でしたが、***switch文はさらに多くのケースに分岐できます。***

次は簡単な例を見ていきましょう

```swift:qiita.rbvar 
let a = -2
switch a {

case Int.min..<0:
print("aの負の値です")

case 1..<Int.max:
print("aは正の値です")

default:
print("aは０です")

}

実行結果:aは負の値です
```

#whereキーワード
whereキーワードを利用すると、ケースにマッチする条件を追加できます。
これだけと、なんのことかさっぱりなので、早速、基本構文を見ていきましょう！


```swift:qiita.rbvar 
switch 制御式 {
case パターン 制御式:
制御式がパターン1にマッチし,かつ,条件式を満たす場合に実行される文

default:
制御式がいずれのパターンにもマッチしなかった場合に実行される文
```

次は、簡単な例です。

```swift:qiita.rbvar 
let optionalA: Int? = 5

switch optionalA {

case .some(let a)where a > 10:
print("10より大きい値\(a)が存在します")
default:
print("値が存在しない,もしくは10以下です")

実行結果: 値が存在しない,もしくは10以下です
```
上記の例では、定数optionalAは値を持っているため、***case .some(let a)***の部分にはマッチしますが、where a > 10という条件を満たしません。

#break文
break文は、switch文のケースの実行を中断する文です。
簡単な例を見ていきましょう。

```swift:qiita.rbvar 
let a = 1
switch a{
case 1: 
print("ログインに成功しました")
break
print("ログインに失敗しました")
default:
break
}
実行結果:ログインに成功しました
```
上記の例では、マッチするけーすcase1:内に２つのprint（）関数が書かれていますが、２つ目のprint関数の前にbreak文が書かれているため、２つ目のprint関数は実行されません。

#ラベル
ラベルはbreak文の制御対象を指定するための仕組みです。
switch文が入れ子になっている場合など、break文の対象となるswitch文を明示する必要があるケースで利用します。

入れ子・・・プログラミング用語で、***あるモノの中にそれと同じモノを入れた構造という意味。***

基本構造を見ていきましょう！

```swift:qiita.rbvar 
ラベル名: switch文
break ラベル名
```
では、今度は、ラベルが必要となる例を見ていきましょう。

```swift:qiita.rbvar 
import UIKit
let value = 0 as Any

outerSwitch: switch value{
case let int as Int:
    let description: String
    switch int {
    case 1,3,5,7,9:
        description = "奇数"
   case 2,4,6,8,10:
        description = "偶数"
　　default:
        print("対象外の値です")//ここが読まれる
        break outerSwitch
    }
print("値は\(description)です")

default:
    print("値がInt型ではありません")
}

実行結果:対象外の値です
```

上記の例では、Any型の値が１から１０までのInt型であれば、その値が奇数か偶数かを出力するプログラムです。
指定された値0なので、対象外の値ですと出力されています。

***では、今度はlet valueの指定を"aaa"に変更してみます。***

```swift:qiita.rbvar 
import UIKit
let value = "aaa" as Any

outerSwitch: switch value{
case let int as Int:
    let description: String
    switch int {
    case 1,3,5,7,9:
        description = "奇数"
   case 2,4,6,8,10:
        description = "偶数"
default:
        print("対象外の値です")
        break outerSwitch
    }
print("値は\(description)です")

default:
    print("値がInt型ではありません")//ここが読まれる
}

実行結果:値がInt型ではありません
```
このように指定された値がInt型ではないため、２つ目のprint関数が呼ばれます。

#fallthrough文
　fallthrough文は、switch文のケースの実行を終了し、次のケースを実行する制御構文です。

```swift:qiita.rbvar 
let a = 1
switch a{
case 1: 
print("ログインに成功しました")
fallthrough
case 2:
print("ログインに失敗しました")
default:
print("default")
}

実行結果:
ログインに成功しました
ログインに失敗しました
```
上記の例では、fallthrough文によって、実行が次のケースであるcase2に移ります。したがって、case1とcase2が出力されます。
IPアドレスを変更するバッチファイル


# はじめに
ネットワークの機器の設定をするために、頻繁にPCのIPアドレスを変更する事があります。会社で使っているPCは社内LANに入っており、IPアドレスはDHCPから割り当てるようにしているため、コンパネから都度、GUIでIPアドレスを変更するのは結構手間です。なので、バッチを作って、サクッとIPアドレスを変更するようにしました。

# 環境
Windows10

# コマンド作成

```ip_1.bat
@echo off
netsh interface ip set address "ローカル エリア接続" static 192.168.1.100 255.255.255.0 192.168.1.1
ipconfig
pause
```

エクスプローラーからバッチファイルを右クリックして、「管理者として実行」するとIPアドレスが「192.168.1.100/24」に、サブネットマスクが「192.168.1.1」に変更されます。
Catalinaにアップデートしたらanacondaが使えなくなった話

# 概要
今更ながらmac high sierraからcatalinaにアップデートしたのですが、その際にanacondaが使えなくなったので解決方法をメモる

## 参考記事
**修復について**
① https://qiita.com/akinko/items/1909c8d0145d9ba530b9

**bashからzshへの移行**
② https://qiita.com/shionit/items/31bfffa5057e66e46450
**zshでanacondaの記述が通るようにする**
③ https://qiita.com/github-nakasho/items/aed4b29ae88f035970bb



## 方針
修正を①の記事を参考に試したのだが

```
conda init zsh

>> zsh: conda: command not found
```

となってしまい詰まったので再インストールする方法を取ることにした。
なさけない。

そのため

1.anacondaの公式サイトよりanacondaをインストール
2.bashからzshへ移行　←お好み
3.zsh_profileにcondaを通す記述をする

でanacondaの再スタートを目指す。

## 1. anacondaのインストール

検索エンジンで` anaconda mac `と調べれば公式サイトに飛べるのでgui操作で以下の記事に従ってダウンロードをすすめる。

https://sukkiri.jp/technologies/ides/anaconda-mac_install.html

## 2. bashからzshへの移行

catalinaではzshにメインのシェルが変更されるため、bashのときにあったpathが通らなくなる。
そんため、anacondaに限らず他の環境変数もなくなっているのでbashの設定を引き継ぐ必要がある。

※ただしbashのまま使い続ける場合はこの設定は必要ないので飛ばしてもらって構わない。

まずはuserのいちまでディレクトリを移動して以下をターミナルで実行する。

```:ターミナル
cat ~/.bash_profile >> ~/.zprofile
cat ~/.bashrc >> ~/.zshrc
```

これでbashの設定がzshに引き継がれる。

## 3.anacondaのPATHを通す
大体の人の場合、２で動くらしいのが自分の場合まだ`conda command not found`のままだったので③の記事の方法を試した。

```:ターミナル
echo "source ~/anaconda3/etc/profile.d/conda.sh" >> ~/.zshrc　#pathを通す

source .zshrc #反映
```

これで

```
% conda --version
>> conda 4.8.3
```
となり、condaが使えるようになった。
ATOK 2017 for Mac での「うぉ」の入力

ATOK（2017）で、ATOKキー・ローマ字カスタマイザの設定が「ATOK 2017スタイル」になっていると "who"で「うぉ」になりません。ATOKキー・ローマ字カスタマイザで「OS X 標準風スタイル」に変更すると"who"で「うぉ」が入力できるようになります。

#設定
メニューバ右上にある入力モードの部分をクリックしてキーボード・ローマ字カスタマイザを選択。

![スクリーンショット 2020-10-16 13.56.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396687/2ae624fb-6ada-e616-3dca-affe1a08dc31.png)

キーボード・ローマ字カスタマイザで「OS X 標準風スタイル」を選択。

![スクリーンショット 2020-10-16 13.58.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396687/b9000b85-e2f8-d0e1-3763-31ceee92efa2.png)

これで"who"で「うぉ」が入力できるようになります。カタカナの「ウォ」にしたければcontrol+k、またはスペースバーを数回叩けば変換できます。
Homebrew の アップデートを自動化

# 環境
:::note
M1 macに対応しました。
:::
macOS Catalina




# plistファイルを作成します


~/Library/LaunchAgents/に下記ファイルを作成します。


ファイル名はlocalhost.homebrew-autoupdate.plistとしました。

このplistで前回のアップデートから8時間経過または起動時に自動的に

brew update

brew upgrade

brew cleanup

の三つのコマンドが実行されるようにしました！

## Intel mac

```

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
 <key>Label</key>
 <string>localhost.homebrew-autoupdate</string>
 <key>ProcessType</key>
 <string>Background</string>
 <key>ProgramArguments</key>
 <array>
   <string>/bin/sh</string>
   <string>-c</string>
   <string>/usr/local/bin/brew update &amp;&amp;
     /usr/local/bin/brew upgrade &amp;&amp;
     /usr/local/bin/brew cleanup &amp;&amp;
     /usr/local/bin/terminal-notifier -title 'Homebrew' -message 'Homebrew upgraded'
   </string>
 </array>
 <key>RunAtLoad</key>
 <true/>
 <key>StandardErrorPath</key>
 <string>/tmp/localhost.homebrew-upgrade.stderr</string>
 <key>StandardOutPath</key>
 <string>/tmp/localhost.homebrew-upgrade.stdout</string>
 <key>StartCalendarInterval</key>
 <dict>
   <key>Hour</key>
   <integer>8</integer>
 </dict>
</dict>
</plist>
```

## M1 mac

```

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>localhost.homebrew-autoupdate</string>
  <key>ProcessType</key>
  <string>Background</string>
  <key>ProgramArguments</key>
  <array>
    <string>/bin/sh</string>
    <string>-c</string>
    <string>
      /opt/homebrew/bin/brew update &amp;&amp;
      /opt/homebrew/bin/brew upgrade &amp;&amp;
      /opt/homebrew/bin/brew cleanup &amp;&amp;
      /opt/homebrew/bin/terminal-notifier -title 'Homebrew' -message 'Homebrew updated!'
    </string>
  </array>
  <key>RunAtLoad</key>
  <true/>
  <key>StandardErrorPath</key>
  <string>/tmp/localhost.homebrew-upgrade.stderr</string>
  <key>StandardOutPath</key>
  <string>/tmp/localhost.homebrew-upgrade.stdout</string>
  <key>StartCalendarInterval</key>
  <dict>
    <key>Hour</key>
    <integer>8</integer>
  </dict>
</dict>
</plist>

```


# 動作確認

下記コマンドを実行してOKと表示されることを確認してください！

```
plutil -lint ~/Library/LaunchAgents/localhost.homebrew-autoupdate.plist​
```
launchdに登録

```
launchctl load ~/Library/LaunchAgents/localhost.homebrew-autoupdate.plist
```

launchctl list でlaunchdに登録されているリストを表示して`localhost.homebrew-autoupdate`
があることを確認

```
launchctl list | grep home
```
CentOS8をVirtualBoxでインストールしたあと、再起動するとエラーが出る件

#CentOS8をインストールするまで

こんにちは。プログラミングを始めて半月ほどのSayaです。
右も左も分からないのですが、エンジニアのOSはLinuxが当たり前？という噂を聞き、
Progateで満足している場合じゃない！と焦って、CentOS8をMacbookairにVirtualBoxを使ってダウンロードとインストールを行いました。

これまでYoutube等でたくさんあったプログラミングの情報がCentOSと検索した瞬間にほとんど何も出てこなくなるのはなぜなのでしょうか？
Linuxと検索すれば良かったのでしょうか？

私は何か間違えているのか？と不安になりながらも、先輩方がお勧めしている、Linux標準教科書を読み、CentOSをダウンロードすることを決意しました。

[Linux標準教科書](https://linuc.org/textbooks/linux/ "Linux標準教科書")

しかし、全て見様見真似で行うことしかできない私には大きな壁が...
何と最近CentOS８というのにバージョンアップしたらしく、上記の教科書にはバージョン８については書いてありませんでした...
もう何もかも分からないけど、とりあえずバージョン変わったくらいでどうってことないだろうと、腹をくくり、ダウンロードをすることを決意しました！

わかりやすく手順がまとまっているサイトがないか探しました。
いくつかあったのですが、参考にさせていただいたものをご紹介します。

・[【ISOイメージ】CentOS【GUI】をVirtualBoxで起動さしてみた！！！]
(https://note.com/tango9512357/n/n6372aeb653db "【ISOイメージ】CentOS【GUI】をVirtualBoxで起動さしてみた！！！
")
・[Mac上でVirtualBoxにCentOS 8をインストールして学習環境を構築する](https://bbbbruno.qrunch.io/entries/bIPvvDW3wwQ7LNsO "Mac上でVirtualBoxにCentOS 8をインストールして学習環境を構築する")

無事ダウンロードを終えて（後述しますが実は終えていなかった）、VirtualBoxで仮想マシンを立ち上げていこうと思ったのですが...

CentOSダウンロード後にVirtualBoxで仮想マシンを作成し起動ハードディスクを選択するのですが、起動ハードディスクが無いという問題にぶつかりました。

何でだろうと思って、ダウンロードファイルを開いてみようと思ったら、それが空でした...
まずダウンロードがちゃんとできていませんでした。
ダウンロードに30分弱かかることを今回初めて知りました...
しかもダウンロード途中で「失敗」と出てくるのですが、それを再開と自分で押さないと、そのままダウンロードしないまま終わってしまうんですね。
パソコンの仕様の問題でしょうか？

それでも何とかインストールまでたどり着き、やっと終わりだと一安心しかけた時に...
インストール後再起動するのですが、そうすると下記のエラーメッセージが出ました。

「You must specify a machine to start, using the command line.

Usage: VirtualBoxVM --startvm <name|UUID>
Starts the VirtualBox virtual machine with the given name or unique identifier (UUID).」

いろいろ調べたのですが、解決方法分からず...
ちなみに下記のページに行き着いたのですが、回答を見ても、どうすればいいのか私には分かりませんでした（泣）

[virtualboxが起動できません。。。](https://teratail.com/questions/252236 "virtualboxが起動できません。。。")


#解決方法
それでも諦めず、検索しまくっていたところ、下記ページを見つけました!!!!

[MacでVirtualboxの仮想マシンが作成できない。](https://teratail.com/questions/295572 "MacでVirtualboxの仮想マシンが作成できない。")

こちらの回答どおり、
**VM設定でオーディオを無効にする**
ということを行った結果、無事CentOSを使うことができました!!!

質問された方、回答された方、ありがとうございます!!!!!!

#なぜこの記事を書いたのか
上記の解決に至った記事もCentOSではなくUbuntuを使われているんですよね。
あまり大差無いのかもしれないですけど、これだけ情報が溢れているのに、答えまでたどり着くの難しいなと思いました。

こんなに答えにたどり着くまで苦労するんだなということを、初学者の私は初めて体験したので、同じ悩みで苦労されている初学者の方を一人でも救えたらという思いで、この記事を書きました。
先輩方からするとレベル低すぎるかもしれませんが（笑）
もっと成長して、技術をアウトプットしていこうと思います!!!

ちなみにこのQiita記事書くのも少し苦労しました(笑)
文字サイズを変える方法ありますよね？
普通に検索しても出てこないのは私だけでしょうか？
文字サイズを変えるというのは次の課題にしようと思います...
データの探し方 探索アルゴリズム 基本情報技術者 用語解説

# はじめに
探索アルゴリズムとは、大量にあるデータの中から特定のデータを探し出す方法のことです。
今回は代表的なアルゴリズムである線形探索法、二分探索法、ハッシュ法について解説します。

[【YouTube動画】 線形探索法、二分探索法、ハッシュ法について 基本情報技術者試験](https://youtu.be/exsRf1Xufgc)
[![Collation](https://img.youtube.com/vi/exsRf1Xufgc/0.jpg)](https://www.youtube.com/watch?v=exsRf1Xufgc)

# オーダー (計算量, O)
ここでいうオーダーは、処理する数が多くなるに従い、どの程度計算量が多くなるのかという目安のことです。
記号 Oで表記します。

要素の数が増えるにしたがって、一次関数的に増加する場合O(n)、二次関数的ならO(n^2)と表記します。
また、どんなに要素が増えても、定数回で処理が終わる場合はO(1)になります。

# 線形探索法 O(n)
線形探索法は順々に要素を確認していく方法です。
要素数がnならば、最悪全部確認すれば、目的の要素が見つかるので、O(n)になります。

例えば、以下の7つの数値から特定の数値を探すとします。
左から1を見つけるまでには3回確認作業が必要です。

```plaintext
8 4 1 3 5 9 6
```

# 二分探索法 O(log n)
二分探索法は要素が最後の1つになるまで、要素を半分にしていく確認方法です。
ソートと組み合わせて使うと、威力を発揮します (ソートは別記事で解説します！)。

例えば、以下のソートされた7つの数値から11を探すとします。

まず、真ん中の数値をみます。
7は11より小さいので、7より左側の数値は無視します。

```
2 4 5 7 8 10 11 
```

次の真ん中の数値は10です。
10は11より小さいので、さらに左側の数値を無視します。

```
8 10 11
```

数値が1つだけになり、11を見つけることができました。

```
11
```

この二分探索法の計算量は log nになります。

## 計算量の計算
計算量は1個の要素を何回2倍にすると、全要素数と一致するかと考えます。

```
1 -> 2 -> 4 -> 8 -> 16 -> 32 -> ...
```

全要素数が8であれば、3回2倍すれば一致します (2^3 = 8)。
一般化すると、全要素数nに対して、m回2倍すれば一致します。

```
n = 2 ^m
```

対数を取ると、計算量が求まります (底2)。

```
m = log n
```

# ハッシュ法 O(1)
ハッシュ法はハッシュ関数を使って探索していく方法です。
データを保存する前に、数値化し、数値化した場所にデータを保存します。

`調べたい値 -> 対応表を確認 -> データにアクセス` と進むので、データ量に関わらず計算量は増えません。

# まとめ
今回は代表的な探索アルゴリズムを紹介しました。
二分探索の方で出てきたソートについては、別記事で紹介します！

[twitter](https://twitter.com/yassun_youtuber)や[youtube](https://www.youtube.com/channel/UCajrdoGzHzDogrNrLYYmGsg/featured?view_as=public)でのコメントもお待ちしています！
TwitterOAuthを使用してフォロー,RT,いいねをする


#前提
https://twitteroauth.com/
のドキュメントを参考にcomposerからインストール
https://developer.twitter.com/
から申請しAPIキーを取得


#(最低限の)前提知識
スクリーンネームとユーザーID
・スクリーンネーム -> @hogehoge 的なID,いつでも変更できる
・ユーザーID ->　絶対に変えられないID　　※今回はユーザーIDを利用する
・API（アプリケーションインターフェース） ->　認可サーバーのID
・アクセストークン ->twitterが出した「ここまでの範囲なら利用していいよ！」ってやつ
詳しくはhttps://booth.pm/ja/items/1296585
の書籍を参考にしてください



```php:test.php
<?php
require "vendor/autoload.php";
use Abraham\TwitterOAuth\TwitterOAuth as TwitterOAuth;

$consumerKey       = "#########";
//APIキーを記述
$consumerSecret    = "######################################";
//シークレットAPIキーを記述
$accessToken       = "############################################";
//自分もしくは他人のアクセストークン
$accessTokenSecret = "###########################################";
//自分もしくは他人のシークレットアクセストークン

$twitter = new TwitterOAuth($consumerKey, $consumerSecret, $accessToken, $accessTokenSecret);



$id ='################';
//いいね、RT対象のstatusIDを記述
$user_id ='#####################';
//フォローする対象のユーザーIDを記述

$retweet = $twitter->post('statuses/retweet',['id' => $id]);
//RTする
$favorites = $twitter->post('favorites/create', ['id' => $id]);
//いいねする
$follow = $twitter->post('friendships/create', ['user_id'=> $user_id]);
// フォローする
IBMCloud CIS mTLS小ネタ

##小ネタ
CISでmTLSを実施する際に、CA証明書をアップロードするがこのフォーマットに制限があった。
ぱっとみどこにも書いてないので、記載する。

**ibmcloud cis access-certificate-create**の下記でCA証明書を指定する部分
IBMCloud Docs:[Access certificate](https://cloud.ibm.com/docs/cis?topic=cis-cli-plugin-cis-cli&locale=en#access-certificate-cli-ref)

```
--ca-cert-file CERT_FILE
```

**crt**ファイルを指定するとエラーになる。
どうやら**pem**でエンコーディングしておかなければならない。
エラーメッセージからは、どうやら証明書が悪いようだというのしかわからない。

```
【Error message】
FAILED
Error response from server. Status code: 400; message: {"trace": "xxxx", "errors": [{"code": "CIS-BKD-xxx", "message": "access.api.error.invalid_certificate"}],
```

opensslで変換する時

```
openssl x509 -in AAA.crt -inform DER -out AAA.pem -outform pem
```
CakePHP 4 の UPDATE 文で 数値をインクリメントしたい場合

こんな UPDATE 文を書きたいときにどうすればええんじゃー！となって解決したので書いときます。

## UPDATE 文
よくある `set hoge = hoge+1` 的なやつです。

```sql
UPDATE 
  borad_members 
SET 
  unread_count = unread_count + 1, 
  changed = '2020-10-16 13:17:48' 
WHERE 
  borad_id = 1 
AND user_id != 3
```

## 要件
メッセージをやり取りする board があったとします。
新規メッセージが投稿された際に、投稿されたメッセージの未読数を各ユーザーごとにインクリメントしたかったりするかもしれません。

別にこの要件でなくてもいいんですが、なんかより現実味のあるものにしたくて実際にサンプルコードを書いて動かしました。

## コード
`src/Model/Table/BoardMembersTable.php` があるとします。
QueryExpression オブジェクトを予め組み立ててクエリを作っていきます。
Carbon 大好きなので日付処理はほとんど Carbon 任せです。

```php
$query = $this->query();
$increment = $query->newExpr()->add('unread_count + 1');

$result = $query->update()
    ->set([
        'unread_count' => $increment,
        'changed' => Carbon::now(),
    ])
    ->where([
        'board_id' => $boardId,
        'user_id !=' => $userId,
    ])
    ->execute();
```

## 所感
CakePHP 2 だと別の書き方でできてた気がするんですが（忘れた）、現在僕が開発に使用している CakePHP 4 では使えなかったので「一体どうやるんじゃー」となって「あ、そういえば between したかった時に QueryExpression オブジェクト使ったわ」って思い出して書いたのでした。

ググってもサンプルが見つからなかった（QueryExpression オブジェクトの使い方は [公式](https://book.cakephp.org/4/ja/orm/query-builder.html) 含めいろいろあった）のでエントリーにしてみました。

参考になれば幸いです。

## 所感2
`!=` も厳密にいえば `notEq()` 使うべきなのかも。

## 参考
https://book.cakephp.org/4/ja/orm/query-builder.html
python C++ メモ

#python
##最大公約数
Q: 51と15の最大公約数は？
1. 51÷15 = 3 あまり6
2. 15÷6 = 2あまり3
3. 6÷3 = 2あまり0
A: ３！！

```python
def GCD(m,n):
    if n==0:
        return m
    return GCD(n,m%n)
print(GCD(51,15))
```

```c++
#include <bits/stdc++.h>
using namespace std;
int GCD(int m, int n){
    if (n==0) return m;
    return GCD(n,m%n);
}
int main() {
    cout << GCD(51,15);
}
```

##フィボナッチ数列
出力
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155, 165580141, 267914296, 433494437, 701408733, 1134903170, 1836311903, 2971215073, 4807526976, 7778742049]

```python
fibo = [None]*50
fibo[0]=0
fibo[1]=1
for i in range(2,50):
    fibo[i]=fibo[i-1]+fibo[i-2]
print(fibo)
```

```c++
#include <bits/stdc++.h>
using namespace std;
int main() {
    std::vector<long long> fibo(50);
    fibo[0] = 0, fibo[1]=1;
    for (int i=2;i<50;++i){
        fibo[i]=fibo[i-1]+fibo[i-2];
    }
    for (int i=0;i<50;++i) cout << fibo[i] << "," << " ";
}
```
メモ化すると↓

```python
memo = [-1]*50
memo[0] = 0
memo[1] = 1
def fibo(n):
    if n==0:
        return 0
    elif n==1:
        return 1
        
    if memo[n] != -1:
        return memo[n]
    memo[n] = fibo(n-1)+fibo(n-2)
    return memo[n]

fibo(49)
print(memo)
```

```c++
#include <bits/stdc++.h>
using namespace std;
std::vector<long long> memo;
long long fibo(int n){
    if (n==0) return 0;
    else if (n==1) return 1;
    
    if (memo[n] != -1) return memo[n];
    return memo[n] = fibo(n-1)+fibo(n-2);
}
int main() {
    memo.assign(50,-1);
    fibo(49);
    for (int n=2;n<50;++n){
        cout << memo[n] << ","<< " ";
    }
}
```