OmniAICreator/Qiita-1.07M huggingface dataset:
viewとは


# はじめに
Djangoを使っていく上で絶対に知っておかないとエラーが起きますし、起きた時に対処できません。ですので今回はviewについてまとめたいと思います。

# viewとは
Viewとは、ユーザーからHTTPリクエストを受けて、それに応じたHTML形式のレスポンスを返すことです。
具体的に説明するとHTTPリクエストされた時にプロジェクトルーティング→アプリケーションルーティング→ビューと進んでいきます。ビューで記述された処理からフォーム・モデル・テンプレートとやり取りをしてレンダリングしHTTPレスポンスとして返します。下記の図を見ていただくとイメージしやすいと思います。
![スクリーンショット 2022-03-03 9.21.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1184823/567a476d-e67c-22a9-cd7d-e2d4373e592e.png)

なのでviewというのは司令塔のような役割を持っています。

- HTTPリクエスト
WebブラウザからWebサーバーに対する要求のこと。
あなたが開いているWebページで別のページへのリンクを押したときに、WebページからWebサーバーへリンク先のhtmlを渡すように要求します。 この要求をHTTPリクエストと言います。 

- HTTPレスポンス
HTTPリクエストに応じてWebサーバーからWebブラウザに返すことをHTTPリクエストと言います。
WebサーバーはHTTPリクエストを受けて、違うページなどを表示させます。 

- レンダリング
何らかのデータを元にして表示内容を作ることです。
WebサーバーはHTTPリクエストを受けて、 受け取った情報を元にWebページを作成します。 このWebページをHTTPレスポンスとして返します。この受け取った情報を元に表示することをレンダリングと言います。
AWS CDKコマンドについて試行錯誤したことメモ


###cdk bootstrapコマンド
```
cdk bootstrap
```

このコマンドは、cdk initでプロジェクトを作成した直後に実行するやつです。

>Deploying AWS CDK apps into an AWS environment (a combination of an AWS account and region) may require that you provision resources the AWS CDK needs to perform the deployment. These resources include an Amazon S3 bucket for storing files and IAM roles that grant permissions needed to perform deployments. The process of provisioning these initial resources is called bootstrapping.

引用:[AWS Cloud Development Kit (CDK)Developer Guide](https://docs.aws.amazon.com/cdk/latest/guide/bootstrapping.html)

要は、AWS CDKアプリをAWS環境（AWSアカウントとリージョンの組み合わせ）にデプロイするために必要なリソース（S3バケットやIAMロール）を用意するプロセスをブートストラップというらしいです。

それで、cdk bootstrapコマンドで作成されたS3バケットってどれよって話なのですが、CDK-Toolkitってやつですね。
こいつとCloudformationのCDKToolkit云々ってやつはbootstrapコマンドで作られたものなので触らない方が吉っぽいです。

cdk bootstrapコマンドはこっそりcdk deployコマンドと同じようにCloudformationスタック作ってS3をデプロイしちゃうみたいですね。


###cdk synthコマンド

そうそう、Cloudformationのテンプレート（yaml）を標準出力で出してくれるのがcdk synthコマンドです。
yamlとしておかしかったらエラー吐いてくれるのでdeployの前にやっておくといい感じですね。
このコマンド打ったからってCloudformationにスタックができるとかそういうことは特になかったです。ローカルで確認するためのコマンドなのかな？


###cdk deployコマンド

Cloudformationにスタックを作って実際にAWS環境にリソースをデプロイするコマンド。
環境を分けられるようにするために、-c オプションで環境プレフィックスを受け取ってスタックのidを分けられるようにしておくといいですね。

```
cdk deploy -c target=dev
```

参考:[AWS CDKのContextを切り分けて１つのソースから３ランドスケープを作る](https://qiita.com/tetsuya-zama/items/4335f639650d6ec1e00c)

ちなみに、AWS IoT CoreのIoTポリシーとかみたいに、一回作ったら消さないとエラーが出たりするものもあったりします。

```
CloudFormation cannot update a stack when a custom-named resource requires replacing.Rename 'MYResourceXXX' and update the stack again.
```


https://aws.amazon.com/jp/premiumsupport/knowledge-center/cloudformation-custom-name/
https://seed.run/docs/serverless-errors/cloudformation-cannot-update-a-stack-when-a-custom-named-resource-requires-replacing.html
これなんですけど、Lambdaのメモリを増やすだとか、そういった更新だけだったら出ないエラーなんですが、AWSリソースを作り直す必要があるものはこのエラーから逃れられないような気がします。
Mac(m1チップ)でPostgreSQLをインストール方法

こんにちは。
今日は、MacbookAir(m1チップ)でPostgreSQLをインストール方法を紹介します。（2021/06/26）
使用PCは、MacbookAir M1チップです。

※基本はターミナル上で叩いていきます。

また、***Homebrewはインストールされている前提***で進めます。
もし、**わからない方はこちらから**↓

https://qiita.com/kushiyama0225/items/1e32fcfc8e3ba40c8d76



自分の場合は、Go言語でアプリケーション開発しないといけないので、
***Goの設定を最初にします。***
※Go言語との組み合わせで使う人は必要です。

######PostgreSQL用のドライバをインストール
```
go get github.com/lib/pq
```

#インストール手順

####1. PostgreSQLのインストール
```
brew install postgresql
```

####2. Postgresのバージョンチェック
```
postgres --version
```
####3. PostgreSQLサーバの起動
```
brew services start postgresql
```

and

```:サーバ起動時
pg_ctl -D /opt/homebrew/var/postgres start
```

####4. psql -lでデータベース一覧を取得

```
psql -l
```

#注意点

###１
インストール中に

![スクリーンショット 2021-06-26 14.16.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1174366/3353b3cb-4d92-8925-a452-1b5679c21003.png)
下記の英文が表示されます。

![スクリーンショット 2021-06-26 14.16.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1174366/c065d620-f447-5b6e-2146-a7e4883fe3e4.png)
**最初からフォーマットがUTF-8になってる**ので他のサイトに**UTF−８**への変換のコマンドするように
説明されていますが不要です。



```:不要
initdb /usr/local/var/postgres -E utf8
```


###2

PostgreSQLサーバの起動ですが、
ここも注意です。

他のサイトでは確認したところ、
下記のコマンドで、PostgreSQLサーバ動いてたみたいです。

```
postgres -D /usr/local/var/postgres
```

しかし、動きませんでした。（ディレクトリへのアクセスができないと言ってますね。。。）

![スクリーンショット 2021-06-26 14.29.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1174366/065de371-fe35-8063-c548-485f1100fa66.png)


再度、インストール中に出ている画面に手がかりがないか確認しました:thinking:

**こんなメッセージを発見！！！！**

![スクリーンショット 2021-06-26 14.33.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1174366/c4100d17-a187-6d48-ee87-e3e3d5cb35aa.png)


#####訳：
To have launchd start postgresql now and restart at login
起動するには、今すぐpostgresqlを起動し、ログイン時に再起動します

```
brew services start postgresql
```

Or, if you don't want/need a background service you can just run:
または、バックグラウンドサービスが必要ない/必要ない場合は、次のコマンドを実行できます。

```
pg_ctl -D /opt/homebrew/var/postgres start
```

postgresqlのスタートコマンド変わったのか。。。。
バックグラウンドサービスが必要ない場合のコマンドもあるみたいですね。。。。

![スクリーンショット 2021-06-26 14.41.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1174366/ddf5dc1c-76bb-7c65-5b97-663620e9e196.png)

動いたーーー:relaxed:


あとは確認で、でデータベース一覧確認してみてください。
![スクリーンショット 2021-06-26 14.46.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1174366/fbc63476-9827-5779-b748-07ab2ecbc840.png)

一覧が確認できれば動いている証拠です:v:

終わり
backlogAPIの特に課題の追加、編集でハマる所

# backlogAPIのドキュメント、分かりづらくない？
ディスってすいません。なんかやろうとすると、いつも細かいところで躓く。
明文化されていないことが多くない？？
あとエラーの返却が全て400のBad Requestなのも萎える。

## URLについての注意事項

### APIキー
GET、POST、PATCH、DELETE全てにおいて、GETパラメータでapikey=XXX が必要。
POST、PATCH、DELETEの場合もそうなので注意。

### URLの正確性
URL全般、URLの最後に"/" がつくとエラーになるので注意。
例）
課題の追加API(POST）

```
NG： https://XXX.backlog.jp/api/v2/issues/?apiKey=XXXX
OK： https://XXX.backlog.jp/api/v2/issues?apiKey=XXXX
                                      ^^^←ここ
```

## 課題の追加、編集のハマり点

### 全般
ドキュメントに書かれているリクエストパラメータ以外がパラメータに含まれると400 BadRequestエラー。

### 課題の追加API（POST)
https://developer.nulab.com/ja/docs/backlog/api/2/add-issue/#

#### URL
/api/v2/issues 
※もちろんパラメータにapiKey=XXX が必要です。

#### 必須項目

| パラメーター名 | 型 | 内容 |
| --- | --- | --- |
| projectId (必須) | 数値 | 課題を登録するプロジェクトのID |
| summary (必須) | 文字列 | 課題の件名 |
| issueTypeId (必須) | 数値 | 課題の種別のID |
| priorityId (必須) | 数値 | 課題の優先度のID |

priorityIdは、全バックログで共通の値"3"（中）が使えるのでまだいい。
issueTypeIdは、各プロジェクトごとに違うので気合で探す必要がある。
しかも、課題一覧の取得APIでissueTypeId、priorityIdは返却されない。
issueType.id、priority.idという形で返却される。INとOUTしっかりしてほしい。
というかそもそもそれら必須である意味あるか？？

![スクリーンショット 2021-06-26 14.32.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42110/67f83d9d-0f8f-e311-0c62-60b5e32f2fb4.png)


### 課題情報の更新API（PATCH)
https://developer.nulab.com/ja/docs/backlog/api/2/update-issue/#

#### URL
/api/v2/issues/:issueIdOrKey 
※もちろんパラメータにapiKey=XXX が必要です。

この:issueIdOrKeyが厄介。ドキュメントにはこう書かれています。

URLパラメーター

| パラメーター名 | 型 | 内容 |
| --- | --- | --- |
| issueIdOrKey | 文字列 | 課題のID または 課題キー |

~~まず、こういう書き方するのならapiKeyのことをgetパラメータで必須って書いてほしいよね。~~
このドキュメントで「課題のID」、「課題キー」という言葉は多分出てきていないんですよね。
課題一覧の取得で取れるは取れるのですが、そちらでもレスポンス情報の解説が無いから
どれがIDでどれがキーかはひと目では分からない。
レスポンスのidが、課題のID、issueKeyが、課題キーのようです。

![スクリーンショット 2021-06-26 14.42.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42110/b10d5d89-50bb-9093-7fec-3ee68e3ef924.png)

#### 課題情報の更新API、最大の注意点
なんと、「更新する情報が無かった場合はエラー：400 BadRequestを返却する」!!!!!!!
普通正常終了じゃない？


## 追記、その他知ってたら良い情報

### 改行ってどうやって入れるの？
本文に改行を入れる場合は、```\n```ではなく```<br>```を入れるとうまく改行されました。

### VSCodeのRestClientで便利な記述

こんなhttpの設定作っておけば後でいつでもAPI叩けるから便利。

```
@SPACEID=hoge
@PROJECTKEY=HOGEHOGE_PROJECT
@PROJECTID=123456789012
@apikey=zyF0ER***************************************jTJ

https://apg.backlog.jp/api/v2/statuses?apiKey={{apikey}}

###

https://apg.backlog.jp/api/v2/projects/{{PROJECTID}}/issueTypes?apiKey={{apikey}}


###
https://apg.backlog.jp/api/v2/priorities?apiKey={{apikey}}

###

https://apg.backlog.jp/api/v2/rateLimit?apiKey={{apikey}}
```




# まとめ
みんなもAPIを作る時はドキュメントをしっかり書こうね。
この本がとてもタメになりました。
この想い、バックログの中の人に届けー

https://www.oreilly.co.jp/books/9784873116860/
docker イメージの作成（DockerFile）

# 背景
環境構築を楽にするために、docker の勉強をしております。
今回はDockerFile からイメージを作成する方法を手順として残します。

DockerFile については別記事で紹介しているので以下をご参照ください。

https://qiita.com/hamburg-love/items/11780cfd09277b0e1f8d

# 環境
Amazon Linux release 2 (Karoo)
Docker version 20.10.4

# 手順
## コンテキストディレクトリの作成
DockerFile を配置するディレクトリを作成します。

```
sudo mkdir ApacheDocker
cd ApacheDocker
```

## DockerFile 作成
今回は Apache をインストールして、Webサーバとして動作するイメージを作成します。

```
sudo vi Dockerfile
```

DockerFile は以下のように記述しました。

```
# ベースイメージの指定
FROM centos:centos7

# Apache のインストール
RUN yum install -y httpd

# Apache の起動
ENTRYPOINT ["/usr/sbin/httpd", "-DFOREGROUND"]
``` 

## イメージの作成
`docker build` を使って、DockerFile からイメージを作成します。
`-t` でイメージ名を指定して、最後の `.` は DockerFile の場所を示しています。

```
sudo docker build -t apache .
sudo docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
apache       latest    3645b469f543   27 seconds ago   360MB
```

イメージの作成に成功しました。

## コンテナ作成
記述通りのイメージが作成されたかコンテナを作成して確認します。
`/opt/app/`に表示したいHTMLファイルを配置してから、`docker run`を使ってコンテナを作成します。

```
sudo docker run -d -p 80:80 -v "/opt/app/:/var/www/html/" --name Apache apache 
```

配置したHTMLファイルが表示されたらOKです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184532/bca2418c-4b14-66e3-419c-719e87345393.png)

# 最後に
最近、docker を勉強し始めたのですが、たった三行のファイルから Apache の環境が作成されるのは驚きました。

今回はイメージ作成までの流れを勉強するために簡単な DockerFile にしてありますが、LAMP環境を複数のコンテナから作成することをやってみたいと思っております。

最後まで読んでいただきありがとうございました。
rails既存アプリにCircleCIでCI/CDを構築するまでの道程で遭遇したエラー

### やりたいこと
既存アプリに対してCircleCIを導入し、CI/CDを構築する

### 環境
Ruby 2.6.5
rails 6.0
MySQL 5.6
M1チップ搭載MacOS

### 目次
[1.CI構築](#1-CI構築)
[2.CD構築](#2-CD構築)
[3.まとめ](#3-まとめ)

###1.CI構築

**発生したエラー**

```
Failure/Error: <%= javascript_pack_tag 'application'%>

       ActionView::Template::Error:
         Webpacker can't find application in /home/circleci/sample_app/public/packs-test/manifest.json. Possible causes:
         1. You want to set webpacker.yml value of compile to true for your environment
            unless you are using the `webpack -w` or the webpack-dev-server.
         2. webpack has not yet re-run to reflect updates.
         3. You have misconfigured Webpacker's config/webpacker.yml file.
         4. Your webpack configuration is not creating a manifest.
         Your manifest contains:
         {
         }
```
![06dfd6550709d3eadcb8f9e28ea861b5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143942/75cc9cb6-0044-c340-c080-b01b4ea678a1.png)


circleciが用意するdockerイメージでrub系でyarnないしnodejs系のコマンドを利用したい場合には、-node がついているイメージを利用する必要がある。

```config.yml
docker:
  - image: circleci/ruby:2.6.5-node
```

```config.yml
- run:
    name: yarn Install
    command: yarn install
```

###2. CD構築

**発生したエラー**
![0f88118e8d78d63e5194ad700e49f3ff.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143942/484b5065-b8bc-a142-8f28-370e30c4bfa2.png)

**修正後**

```config.yml
    name: database setup
              command: heroku run bundle exec rails db:migrate RAILS_ENV=production -a $HEROKU_APP_NAME
```

ようやくconfig.ymを書上げ、CircleCIもbuild,test,deployと実行され、いざheroku openすると


![c5001d6e92fd9c48f7424431d9d9fe1b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143942/ee5ae817-4e7b-b55a-daa0-2e4daa5b1b60.png)

heroku logs --tailをしてみると

```
ActionView::Template::Error (Webpacker can't find application in /fridge_app/public/packs/manifest.json. Possible causes:
 1. You want to set webpacker.yml value of compile to true for your environment
    unless you are using the `webpack -w` or the webpack-dev-server.
 2. webpack has not yet re-run to reflect updates.
 3. You have misconfigured Webpacker's config/webpacker.yml file.
 4. Your webpack configuration is not creating a manifest.
    Your manifest contains:
```

```config.yml
 - run:
      name: webpacker compile
      command: bundle exec rails webpacker:compile
```
webpackerを入れてなくて読み込みができていなかった。



###3. まとめ
config.ymlの記述の仕方が難しかったです。インデントやタイポなど単純ミスもありまして、調べながら何度も何度も修正しながら作りました。
Pythonでバケットソートをとっても簡単に説明してみる

# バケットソート（ビンソート）
### 概要
あらかじめデータがとりうる値を入れる容器（バケット）を用意しておき、値を対応する容器に移すことでソートを行うアルゴリズムです。

データがとりうる値がわかっていなければソートのための容器を準備することができないので、このアルゴリズムは使えません。

### 使用例
#### 1.数字を昇順に並べる 
0~9の範囲で数字がいくつか与えられるので、それを昇順に並べるアルゴリズムを書いてみます。

##### コード
```python
def bucket(num_list):
    bucket = [0] * 11
    ans = []

    for i in num_list:
        bucket[i] += 1

    for i in range(1, 11):
        ans.extend([i] * bucket[i])
    
    return ans

num_list = [1, 9, 8, 1, 3, 2, 8, 6, 1, 6]
print(bucket(num_list))
# [1, 1, 1, 2, 3, 6, 6, 8, 8, 9]
```
##### 解説
- - -

1. 0~9の数字を入れるためのリスト（`bucket`）を用意する
1. `bucket`に値を入れていく
1. `bucket`の中身を順に出力する

- - -

まず、0~9の数字を入れることのできるリストを準備します。![bucket_sort_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1233166/ba5aecb7-8ec7-462d-ebd1-cd570e2eef92.jpeg)


与えられた数字のリスト（`num_list`）でfor文を回し、どの数字が何回登場しているかを数えます。![bucket_sort_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1233166/c432a180-d68c-70a0-f182-23d1d0b69908.jpeg)


数え終わったら、登場した数字をその回数分出力すれば終了です。
#### 2.Ringo's Favorite Numbers 2（ABC200_C）

https://atcoder.jp/contests/abc200/tasks/abc200_c

N個の正整数からなる数列Aが与えられた時、`1 <= i < j <= N`かつ$A_i$-$A_j$が200の倍数である`(i, j)`の組の個数を求めなさい。

##### 入力形式

```
N
A1 A2 ... AN
```

##### 入力例

```
6
123 223 123 523 200 2000
```

##### コード
```python
# 入力の読み込み
n = int(input())
a = list(map(int, input().split()))
# バケットを用意
bucket = [0] * 200
ans = 0

# バケットに数値を入力
for i in a:
    bucket[i % 200] += 1

# 解答を計算
for i in bucket:
    ans += i * (i - 1) // 2

print(ans)
```

##### 解説
- - - 

1. 0~199（200で割った余り）の数字を入れるためのリスト（`bucket`）を用意する
1. 与えられた数字のリストをfor文で回し、200で割った余りをリストに入力していく
1. 求めたい場合の組の個数を計算する

- - -

前提として、「$A_i$-$A_j$が200の倍数である」というのは**「$A_i$を200で割った余りと$A_j$を200で割った余りが一致する」**ということと同値になります。
したがって、求めたい数値は**「$A_i$を200で割った余りと$A_j$を200で割った余りが一致する組の個数」**と言い換えることができます。

それではコードの説明をしていきます。

まず、問題1と同じように、数字を入れるためのリスト（`bucket`）を用意しておきます。
今回は、**「正の整数を200で割った余り」**を入れるためのリストなので、`0~199`の数字を入れるリストになります。

与えられた正の整数のリスト（`a`）をfor文で回し、200で割った余りを`bucket`に追加していきます。

n個の要素から2個の要素を選び取る場合の数は`n(n-1)/200`なので、`bucket`をもとに答えを得ることができます。

# 他のアルゴリズムに関する記事
- [動的計画法（DP）をとっても簡単に説明してみる](https://qiita.com/myumura/items/d4fcba49444f9251e445)
- [Pythonで深さ優先探索（DFS）をとっても簡単に説明してみる](https://qiita.com/myumura/items/141dafed1f34b03413f9)

# 筆者より
アルゴリズム初心者なので、間違っている点や説明不足な点は教えていただけるとありがたいです！

# 参考にさせていただいたサイト
- https://www.codereading.com/algo_and_ds/algo/bucket_sort.html
- https://atcoder.jp/contests/abc200/editorial/1245
Java ファイルの作成日時を更新日時にする


```
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.FileTime;

public class Main {
    public static void main(String[] args) {
        new Program();
    }
}

class Program {
    public Program() {
        String dirPath = "C:\\testDir";
        File dir = new File(dirPath);
        File[] files = dir.listFiles();
        if (files == null) {
            return;
        }

        for (File file : files) {
            try {
                Path path = Paths.get(file.getAbsolutePath());
                FileTime fileTime = Files.getLastModifiedTime(path);
                Files.setAttribute(path, "creationTime", fileTime);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
```
（レポート）Scrum Fest Osaka 2021 金沢『コミュニティ活動で得られた知識と希望～オンライン勉強会に半年で200回参加して感じたこと～』

# [Scrum Fest Osaka 2021 Day 2](https://www.scrumosaka.org/)

2021/06/26に開催された[Scrum Fest Osaka 2021 Day 2](https://www.scrumosaka.org/)のイベントレポートです。
金沢トラックの @Aki_Moon_ さんのセッション「[コミュニティ活動で得られた知識と希望～オンライン勉強会に半年で200回参加して感じたこと～](https://confengine.com/conferences/scrum-fest-osaka-2021/proposal/15347/200)」の内容を・感想を記事化しています。

# チーム参加してきました

[aslead Agile](https://aslead.nri.co.jp/solution/aslead_agile.html) のチーム「[オキザリス](https://speakerdeck.com/viva_tweet_x/huesudeyong-qi-wode-taxin-gui-timugashi-yan-wozao-rifan-sitejin-nizhi-rumadefalsewu-yu?slide=3)」にて参加してきました。
チーム4人で参加して、その場で実況しつつ、記事も作っています。
私は一人で金沢トラックに一日いました。
この記事では、お話をきいたうえで私が感じたことをまとめていきたいと思います。

# 200回コミュニティに参加して

コミュニティに参加しまくって、ブログ発信も続けた。
個人の感覚でも、自分にとっていい変化が生まれていた。

## 生まれた変化はどこから？

知識なのか？

一番は**プロダクト開発に対して希望を持てるようになった**こと。

## コミュニティに参加する前

希望とは無縁の生活をしていた。
社会人になるまえはプロダクト開発や、そもそもSNSにもなじみのない生活をしていた。
勉強も嫌いで、走っているかゲームをしているかの生活をしていた。

ちょっとしたきっかけでITに飛び込んだが、厳しい状況に。
毎日スクリプトとテストをたたいて、上司やお客様に毎日怒られて。
なんでITに入ろうって思ったんだろう、と毎日後悔。

上司にコミットしたスケジュールも遅延して、最後に爆発して、他の人に迷惑をかけて。
とても苦しかった。

## 未来の自分に対する不安

何をしてもよくなる気がしなかった。

今度こそはうまくいくんだ、と要件定義やヒアリングなどをしにいって、「こうやったら絶対できる」と思っていっても、
絶対にうまくいかない。

社内からも社外からも物凄いプレッシャーがかかって。
色んなチームメンバーが退職したり休職したり。そんな状況だった。

体にも心にもダメージを受けて、製品を納品しても、
お客様の反応はそっけないもの。

私が作ったプロダクトに意味はあったのかな？

数値から見てもよくない状況だった。

## スクラムを始めたチームがいたけれど…

社内でスクラムを初めて大成功した話を聞いた。
お客様からもいい評価を得られて、新しいチャレンジもしているチームで。
自分とはなんで違うんだろう、と思っていた。

「どうしたらそうした人たちにたどり着けるのか？考えたほうがいい」と言われて、
毎日考えて。

でも、一向に差は埋まる気配はなくて。

絶望している状態だった。

なりたい姿と今の自分。ギャップに不安を抱えていた。

## コミュニティとの出会い

ふとしたきっかけでコミュニティに参加してみた。

かすかな手ごたえだったけど、自分が進む道が見えた気がするし、でも小さな小さな感覚だった。

それを放したくなくて。
イベントに参加し続けた。

そうして芽生えたのが、プロダクト開発に対する希望だった。

「もっといいプロダクトを作れるかもしれない」「もしかしたらその光を覗くことができるかもしれない」
それは、コミュニティにいる人たちが、「現実」に強く目を向けている気がして、それがとても大きいと感じた。

## 現実から一歩前に

コミュニティに参加すると、これを強く感じるようになった。
参加する前は「うまく言った事例」が本に書いていても、自分には適用できない、自分の能力が低いせいだ、と思っていた。

コミュニティでは、本に書いてあることやプラクティスも、最初からうまくいっているわけでもないし、何度も何度も自分の中ではありえないと思う回数を繰り返していたり、本に書いてあることとはもう離れ切ってしまっていても、うまくチームに適応しているのを見た。

本に書いてある「理想的な姿」を現実にあてこむのではなく、それぞれの現実から、ほんの小さな変化を繰り返すことで、いい方向に向かうことができるんだ、と思った。

ちょっとよく分からないけど話してみる。
そういうところからスタートなんだな、と思ったら、少しずつうまくいくようになってきた。

本に書いているものをそのまま適応して、なんとなくうまくいった、という人もいるけど、
私には少しずつ変えていくのがあっているなと思った。

## 今を楽しむ

コミュニティにいる人たちと一緒にいると、終わった後に「楽しかったな」と自分もみんなもなる。
みんなは「今楽しんでいるか」にフォーカスしている。

今みたい動画を見たり、今したい話をしたり。
分散アジャイルチーム勉強会で、テーマも決めないで、毎日夜まで話す。

未来にこういう姿を持っているからコミュニティに参加する、ではない。
今、楽しむ。

## 未来や過去よりも現実に目を向ける

自分にとっては、未来を見つめたり、過去を見つめるのはつらかった。
未来のなりたい自分、過去の苦しい自分。ギャップに苦しんでしまう。

それよりも、現実を見て、その場その場を楽しむって考えるようになったら、少しずつうまくいくようになってきた。

## 希望は遠くではなく近くにある

遠くにあると思っていたけど、意外と近くにあった。
積読していた本だったり、これまで過ごしてきた何でもない日々だったり。

どこかに希望は転がっていて、近くの希望をみて、今を少しずつでもよくしていこうと思ってコミュニティに参加して前に進んでみたり。

いつの間にか、半年に200回、本も80冊読むようになった。
仕事もうまくいくようになって、いい感じになっていった。

## 考えてみてほしい

今をほんの少し楽しむためになにしよう？
仕事をほんの少し楽しむためになにをしよう？

苦しんでいる人がいたら、そして将来届きそうにない未来や過去に絶望した時、このセッションが少しだけ前に進むきっかけになればいいなと思う。

# 感想

染み入る。
何か書くと、陳腐なものになってしまう感じ。
映画を見たような読後感でした。
phpからpythonを呼び出す方法のメモ

#概略
本記事は、phpからpythonを呼び出そうと思ったときの話で、
MAMPでサーバーを立て、その上でphpからpythonを呼び出すって感じです。
MAMP, php, python それぞれで行った設定を順に書いていきます。

#MAMPの設定
多分、初期設定では.pyがハンドラーに設定されてないので追加しときます。
変更するファイルはこれ→ ~/MAMP/conf/apache/httpd.conf
AddHandolerに.pyを追加する。

```ruby:http.conf
AddHandoler cgi-script .cgi .pl .py #←これ追加
```

#pythonの設定
とりあえず適当な .pyファイルを作る。

```python:test.py
print("Hello world")
```
作った.pyの先頭にpythonまでのパスを追加。
とりあえず、ターミナルで which python3 を叩く。

```terminal:ターミナル
which python3
~/python3 #←(環境によって内容が変わるので注意)
```
ターミナルの結果を元に.pyに追記。

```python:test.py
#!~/python3 ←(環境によって内容が変わるので注意)
print("Hello world")
```

.pyをサーバーで動かすために謎の呪文を追加。（#!〜行の下くらいが良さそう）

```python:test.py
#!~/python3 ←(環境によって内容が変わるので注意)
print("Content-type: text/html; charset=Shift_JIS\n\r\n")#←謎の呪文
print("Hello world")
```

権限の変更をする。

```terminal:ターミナル
chmod 755 test.py
```
#phpの設定
commandには呼び出す.pyファイルを指定する。
(pythonをコマンドラインから呼び出す時に記述する内容を記載)
$outputには、.pyでprint文で書き出した結果がリスト形式で入る。

```php:test.php
  <?php
  $command="python ./test.py ";
  exec($command,$output);
  print_r(]$output);#$outputに格納されたインデックスと値の関係の一覧を表示
  echo $output[1];#表示したい要素が一つだけの場合の指定方法
  ?>
```

ブラウザで.pyの出力と同じ結果を確認できたらOKってとこですかね。
最後まで読んでいただきありがとうございました。
また気が向いたら投稿しようかな〜・・・
（レポート）Scrum Fest Osaka 2021 Day2 『スクラムマスター こそ考えたい、言葉 のアウトカム』

# [Scrum Fest Osaka 2021 Day 2](https://www.scrumosaka.org/)

2021/06/26に開催された[Scrum Fest Osaka 2021 Day 2](https://www.scrumosaka.org/)のイベントレポートです。
KANEさんのセッション[スクラムマスター こそ考えたい、言葉 のアウトカム
](https://confengine.com/conferences/scrum-fest-osaka-2021/proposal/15301)の内容を・感想を記事化しています。

# チーム参加してきました

[aslead Agile](https://aslead.nri.co.jp/solution/aslead_agile.html) のチーム「[オキザリス](https://speakerdeck.com/viva_tweet_x/huesudeyong-qi-wode-taxin-gui-timugashi-yan-wozao-rifan-sitejin-nizhi-rumadefalsewu-yu?slide=3)」にて参加してきました。
チーム4人で参加して、その場で実況しつつ、記事も作っています。
この記事では、お話をきいたうえで筆者が感じたことをまとめていきたいと思います。


# 言葉のアウトプット、アウトカム

- アウトプット
    - 文章を書く
    - 相手に話す
- アウトカム
    - 文章が影響を与える
    - 相手の行動が変わる、など成果が変わる


# なぜこのテーマ？
スクラムマスターは言葉を使うロールだと考えている。
だからこそスクラムマスターが考えたいアウトカム

## なぜ大事か

- ただ話すことは誰にでもできる
- 言葉を投げっぱなしにする人が多い

**あなたの言葉は良いアウトカムを生み出していますか？**


# 言葉のアウトカムを最大化する特訓方法

自分の言葉とその反応をふりかえり
自分の言葉をカイゼンする

## 日常的にできない、という人へのおすすめのふりかえり方法

- 特訓~テキスト編~
    - テキストの場合は簡単
    - 書いたテキストを読めばいい
        - 「この伝え方もいいな」はあってもいい
        - 「この伝え方の**方が**いいな」をなくしていく

- 特訓 ~対話篇~
    - Podcast
        - 対話が中心のコンテンツ
            - 対話の練習になる
        - 収録→編集というプロセス
            - このプロセスの間に自分の声を聞き直す
        - 失敗もできる砂場
            - 編集する際にカットしまえばいい

# 感想

- いろんな場面でふりかえりは活きてくるんだなと感じました。
- 「ちょっと伝え方まずかったかな、、、」と思うことも日常的にありますが、それだけでなくその後の相手の行動が変わっているか？次はどんな伝え方ができるか？にきちんと目を向けないと、自身の成長につながらないなと感じました。
React Component の Props を  Generic にする。

# 背景

特定の型を持たないPros1で指定した値の型を、別のProps2でも活用したいという場面は、たまにあると思います。型アサーションで解決できなくもないけど、毎度 `as` していくのも手間なので、Genericで解決できないかと実装してみた

# やりたいこと

`onChange` の引数で受け取る `meta` に自動で型をつけたいと思います。

```ts
<MyList 
  items={[
    { 
      id: id,
      meta: meta // <- 特定の型を持たないメタ情報
    }
  ]}
  onChange={
    ({meta}) => {
      console.log(meta)  // <- itemsで指定したmetaの型として扱いたい
    }
  }
/>
```


# 実現方法

```ts

type Items<MetaType> = {
  id: string;
  meta: MetaType; 
};

type Props<MetaType> = {
  items: Items<MetaType>[];
  onChange: (data: {　meta: MetaType}) => void;
};

export function MyList<MetaType>(props: Props<MetaType>) {
 return props.items.map(item) => (
   <div
    key={item.id}
    onChange={props.onChange}
   >
     {item.id}
   <div>
 )
}

```

### 備考

以下のようにアロー関数で書こうとすると、 `<MetaType>` の部分でJSXの構文エラーがでてしまうので注意

```ts
export const MyList = <MetaType>(props: Props<MetaType>) => {
return props.items.map(item) => (
   <div
    key={item.id}
    onChange={props.onChange}
   >
     {item.id}
   <div>
 )
}
```
CORSについて（1）

###CORSとは
EN：Cross-origin resource sharing (CORS)
JA：オリジン間リソース共有

下記サイトではこのように定義されている
https://developer.mozilla.org/ja/docs/Web/HTTP/CORS
> オリジン間リソース共有Cross-Origin Resource Sharing (CORS) は、追加の HTTP ヘッダーを使用して、あるオリジンで動作しているウェブアプリケーションに、異なるオリジンにある選択されたリソースへのアクセス権を与えるようブラウザーに指示するための仕組みです。


補足）originについて
https://developer.mozilla.org/ja/docs/Glossary/Origin
<hr>

###実際触ってみよう

pythonのtornadoというライブラリーを使って、色々検証する
https://www.tornadoweb.org/en/stable/
下記コードをtest.pyに書いて、python test.pyを実行すると、簡易のウェブサーバーが起動される。

```python
import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()
```

試しに、ブラウザから設定したURLにアクセスしてみると、無事に表示された。
http://localhost:8888/
![スクリーンショット 2021-06-26 12.49.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1693500/7e1dc3c9-b14e-0f4d-640d-4de1a0edca0b.png)


開発者ツールのコンソールのところに、試しに下記のコマンドを打ってみると、無事に内容が取得できた。

```js
fetch('http://localhost:8888').then(a => a.text()).then(console.log)
```
![スクリーンショット 2021-06-26 12.50.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1693500/44d59bb6-f798-6f8c-528e-25219722ac1d.png)


同一オリジンからのgetリクエストなので、取得できるのは当たり前のような感じだね。

Googleのホームページを開いて、同じことをやったら、どうなるかを検証してみよう。
取得できなかった。
![スクリーンショット 2021-06-26 12.48.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1693500/a37ef1cf-408e-e90d-ee06-aedf29d8abf4.png)


~~~
クロスオリジン要求をブロックしました: 
同一生成元ポリシーにより、http://localhost:8888/ にあるリモートリソースの読み込みは拒否されます 
(理由: CORS ヘッダー ‘Access-Control-Allow-Origin’ が足りない)。
~~~
リクエストに**'Access-Control-Allow-Origin'**の指定が必要であることが分かった。

test.pyのgetに下の一行を足して、プログラムを再起動してみた。
>self.add_header("Access-Control-Allow-Origin","https://www.google.com")

```python
import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.add_header("Access-Control-Allow-Origin","https://www.google.com")
        self.write("Hello, world")

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()
```
前と同じように、googleからgetのリクエストを送ってみると、無事テキストを取得できるようになった
![スクリーンショット 2021-06-26 12.53.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1693500/ca14912a-e3ef-6630-750e-5350be76aa8a.png)

つまり、オリジンAからオリジンBへ何かしらのリクエストを送る時、オリジンB側でオリジンAからのリクエストを許可する設定をしない限り、オリジンAからオリジンBの内容を取得することができない。

逆に言うと、オリジンB側でオリジンAからのリクエストに対して事前許可してあげると、オリジンAからオリジンBのコンテンツを取得できるようになるってことだ。


###今回のまとめ
1.CORSはオリジン間リソース共有の時に使うポリシー的なもの
2.訪問先のオリジン側で事前に*Access-Control-Allow-Origin*を設定しておくと、訪問元のオリジンから訪問先のリソースを取得できるが、設定がない場合、取得できない。
[JavaScript] Ajaxとは　

##はじめに
クライアント側から送られてきたリクエストに対して、ページを読まこまずして、ページの一部分が更新されるように、非同期通信を実装することができるのはJavaScriptの大きな魅力だと思います。

そのような機能を実現する技術「Ajax」について少し深掘りしてみました。
ちなみに今まで僕は「アジャックス」と読んでいましたが「エイジャックス」だそうです。
今まで「アジャックス」と言いながら人と話してる時に、「エイジャックスなのにな 笑」とか思われてたのかと思うと、穴を掘って入りたいです。

よろしくお願いします。


##Ajaxとは

ちなみにAjax(Asynchronous JavaScript + XML)です。

Ajaxは非同期通信を利用して、ブラウザ上でリロードを行うことなく、ページの一部分を更新できたりする通信技術のことを言います。

いちいち、全画面を読み込み直す必要がないので、ユーザーにとってもストレスフリーです。

##XMLHttpRequestオブジェクト
JavaScriptにあらかじめ定義されているオブジェクトで、ブラウザ上からサーバーにHTTP通信を行うときに使います。

##XML
Ajaxの名前にXMLとあったので気になっていました。
実はこれマークアップ言語の一つでした。マークアップ言語といえばHTMLなんかもマークアップ言語でした。

 Extensible Markup Language　の略で拡張可能なマークアップ言語という意味になります。

特徴としてはその名の通り、拡張性が高いことだそうです。要素の名前やデータの構造を自由に定義できるためデータの管理に向いていると言えます。

データの交換手段としても用いられます。
Ajaxではレスポンスとして返すときにこのXML形式できます。
しかしながら、現在はXML形式で返すことはあまりなく、Jsonという形でレスポンスを返す方が主流のようです。
AjaxにXMLって入っているのに、XMLじゃなくてもいいみたいです 笑


##Json
JavaScript Object Notionの略です。
異なるプログラミング言語間の橋渡しをしてくれるデータフォーマットです。かつてXMLがAjaxでその役割を担っていたけど、JsonはJavaScriptの記法をもとにしているので、JavaScriptに慣れている人からすれば非常にわかりやすいし現在開発には必ずと言っていいほどJavaScriptは使われるので、そのような背景からXMLにとって変わってJsonが使われるようになったのでは？と勝手に考察してみます。

##DOM
Document Object Modelの略です。
HTMLなどの構造を解析しデータを作成する仕組み(API）です。
解析されたHTMLは階層構造のデータと変換されます。この階層構造のデータをDOMツリーと言います。DOMツリーのように階層構造になってることによってCSSやJavaScriptで、idやclass名を指定し一部を加工することができます。


##Ajax処理の流れ
これまででできた用語で処理の流れを説明すると

まず、ブラウザ上でクライアントがイベントを発火させます（何かクリックするとか）

→JavaScriptでそれに対する処理を行い、XMLHttpRequestを使ってHTTP通信を行いサーバーにリクエストを送信します。

→サーバー側で受け取った情報（◯◯の情報が欲しいとか、保存するとか）を処理します。

→結果をJsonやXML形式で返してあげます。

→それを受け取って、DOMの仕組みを使って一部分だけを更新する。

これが、**Ajax**!!

##最後に
Ajaxとは様々な技術を組み合わせて実現された技術のことを言うのですね。
一つの技術や概念を構造から理解していくことはすごく大切かなと思います。できるだけブラックボックスはなくしていきたいです。
テストコードエラー

<エラー文>

``` ターミナル
Failures:

  1) 職員による自分のアカウント管理 更新 email属性を変更する
     Failure/Error: expect (staff_member.email).to eq("test@example.com")
     
     ArgumentError:
       bad value for range
     # ./spec/requests/staff/my_account_management_spec.rb:21:in `block (3 levels) in <top (required)>'

Finished in 2.61 seconds (files took 7.83 seconds to load)
3 examples, 1 failure
```




<修正前>

```my_account_management_spec.rb
example "email属性を変更する" do
      params_hash.merge!(email: "test@example.com")
      patch staff_account_url,
        params:{id: staff_member.id , staff_member: params_hash}
      staff_member.reload
      expect (staff_member.email).to eq("test@example.com")
    end
```
<修正後>

```my_account_management_spec.rb
example "email属性を変更する" do
      params_hash.merge!(email: "test@example.com")
      patch staff_account_url,
        params:{id: staff_member.id , staff_member: params_hash}
      staff_member.reload
      expect(staff_member.email).to eq("test@example.com")  #ここを変更
    end
```
python で Photoshop形式のファイル（.psd）を読み込む

#はじめに
pytoshop の利用に関する記事が少なかったので，PSD形式のファイルに対して各レイヤーの画像を Numpy形式で取り出す方法を共有しておきます．

#やりたいこと
pytoshop というライブラリを使って PSDファイルを読み込み，各レイヤーの画像データを Numpy配列の形式で読み込みます．
そして，全てのレイヤー画像を jpg形式で出力します．
今回は行っていませんが，得られた Numpy配列に操作を加えることで OpenCV による処理を加えることができます．
また，文字化け対策として imwrite関数を定義しておくと良いようです．
同様に imread関数についても，このリンク先に記述があります．
https://qiita.com/SKYS/items/cbde3775e2143cad7455

#スクリプト
```python
#! env python
# -*- coding: utf-8 -*-

import numpy as np
import cv2
import pytoshop

def imwrite(filename, img, params=None):
    try:
        ext = os.path.splitext(filename)[1]
        result, n = cv2.imencode(ext, img, params)

        if result:
            with open(filename, mode='w+b') as f:
                n.tofile(f)
            return True
        else:
            return False
    except Exception as e:
        print(e)
        return False

def main():
    read_file_path = 'test.psd'

    with open(read_file_path, 'rb') as rfd:
        psd = pytoshop.read(rfd)
        
        for i in range(len(psd._layer_and_mask_info._layer_info._layer_records)):
            write_file_name = psd._layer_and_mask_info._layer_info._layer_records[i]._name + ".jpg"
            # アルファ値は psd._layer_and_mask_info._layer_info._layer_records[i]._channels[-1].image
            layer_R = psd._layer_and_mask_info._layer_info._layer_records[i]._channels[2].image
            layer_G = psd._layer_and_mask_info._layer_info._layer_records[i]._channels[1].image
            layer_B = psd._layer_and_mask_info._layer_info._layer_records[i]._channels[0].image
            # image に画像データが含まれており，OpenCV などで加工可能
            image = np.stack([layer_R,layer_G,layer_B], axis=2)
            imwrite(write_file_name, image)

if __name__ == '__main__':
    main()
```

#参考
pytoshop を利用する上で参考にしたサイトもまとめておきます．
https://qiita.com/mm_sys/items/ba139c9f4dcc0ac38156
https://pytoshop.readthedocs.io/en/latest/api.html
Debian10 on WSL2 にDocker Engineをインストールする方法

# 背景
Windows 10 HomeでDockerが必要になったが、Docker Desktop on Windowsは使いたくないため、WSL2で[DockerをサポートしているLinux](https://docs.docker.com/engine/install/#server)をインストールし、そこへDocker Engineをインストールすることにした。

## 本稿の記述範囲
具体的には、以下の作業を実施した。
1. WSL2を有効にする
2. Microsoft StoreからDebianをインストールする
3. DebianにDockerをインストールする

Debian on WSL2のインストールまでは問題なく実施できたが、Dockerのインストールでつまずいたため、本稿では問題の内容と解決方法を記す。

## 環境
- Windows
  - エディション : Windows 10 Home
  - バージョン : 20H2
  - OSビルド : 19042.1052
- Debian `cat /etc/os-release`により確認した
  - PRETTY_NAME="Debian GNU/Linux 10 (buster)"
  - NAME="Debian GNU/Linux"
  - VERSION_ID="10"
  - VERSION="10 (buster)"
  - VERSION_CODENAME=buster
  - ID=debian
- Docker
  - Docker version 20.10.7
  - build f0df350

# Debian on WSL2にDocker Engineをインストールする方法
Dockerの公式ページにDebianへDocker Engineをインストールする方法が書かれた[ページ](https://docs.docker.com/engine/install/debian/)がある。今回は、[推奨された方法](https://docs.docker.com/engine/install/debian/#install-using-the-repository)であるDocker公式リポジトリからインストールすることにした。

## 問題発生
公式ページに従ってDockerをインストールした後、起動しようとすると、以下のようなエラーが発生し、起動できなかった。

```bash
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
```
デーモンを起動しようと思い、以下を実行したが、解決できなかった。

```bash
$ sudo service docker start
grep: /etc/fstab: No such file or directory
[ ok ] Starting Docker: docker.
```


## 解決策
WSLの公式GitHubのDiscussionの[とあるページ](https://github.com/microsoft/WSL/discussions/4872#issue-560014606)に解決策が載っていた。
どうやら`iptable`をレガシーモードで動かさないといけないらしい。

以下のコマンドでインストールすれば、無事にDocker Engineが動いた。

```bash
$ sudo apt install apt-transport-https  ca-certificates  curl gnupg-agent software-properties-common iptables
$ sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
$ /sbin/iptables --version
$ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
$ sudo apt-key fingerprint 0EBFCD88
$ sudo add-apt-repository    "deb [arch=amd64] https://download.docker.com/linux/debian \
   $(lsb_release -cs) \
   stable"
$ sudo apt update
$ sudo apt install docker-ce docker-ce-cli containerd.io
$ sudo service docker start
$ sudo docker ps -a
$ sudo docker run --rm hello-world
```

# まとめ
Debian10 on WSL2にDocker Engineをインストールする場合、Dockerの公式ページの手段では不十分なため、追加でiptablesに関する設定変更が必要だ。

# 参考ページ
- Docker公式ページにおけるDebianへDocker Engineをインストールする方法：https://docs.docker.com/engine/install/debian/#install-using-the-repository
- GitHubのWSLの公式ページにおける本問題の解決策のページ : https://github.com/microsoft/WSL/discussions/4872#issue-560014606
Macで [ npm install -g npm-check-updates ]  が実行できない

自分用メモなので、ざっくりと書きます。

#前書き
Mac上で`npm install`を実行したときに下記エラーが発生
どうやら諸々古くて脆弱性が発生しているから直せとのこと。

```
7 high severity vulnerabilities
```
ちなみにどのパッケージが古いのか教えてくれるコマンドはこちら

```
$ npm audit
```
パッケージが古ければ諸々アップデートを行えばいい
というのが今回の本編までの経緯

#本編
[この記事](https://laboradian.com/update-npm-packages/)を参考にNPM内パッケージをアップデートしようとしたときにエラー発生

```実行コマンド.
npm install -g npm-check-updates
```

発生したエラー

```
local@Local sample % npm install -g npm-check-updates
npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142
npm WARN deprecated har-validator@5.1.5: this library is no longer supported
npm WARN deprecated uuid@3.4.0: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
npm WARN checkPermissions Missing write access to /usr/local/lib/node_modules
npm ERR! code EACCES
npm ERR! syscall access
npm ERR! path /usr/local/lib/node_modules
npm ERR! errno -13
npm ERR! Error: EACCES: permission denied, access '/usr/local/lib/node_modules'
npm ERR!  [Error: EACCES: permission denied, access '/usr/local/lib/node_modules'] {
npm ERR!   errno: -13,
npm ERR!   code: 'EACCES',
npm ERR!   syscall: 'access',
npm ERR!   path: '/usr/local/lib/node_modules'
npm ERR! }
npm ERR! 
npm ERR! The operation was rejected by your operating system.
npm ERR! It is likely you do not have the permissions to access this file as the current user
npm ERR! 
npm ERR! If you believe this might be a permissions issue, please double-check the
npm ERR! permissions of the file and its containing directories, or try running
npm ERR! the command again as root/Administrator.

npm ERR! A complete log of this run can be found in:
```

どうやら原因としては、アップデート用のPKG?をインストールを試みたが、インストールディレクトリに**書き込み権限がないよ** ということらしい。

**sudo** コマンドを使えば解決o(≧▽≦)o 

もう一度コマンド実行

```実行コマンド.
$ sudo npm install -g npm-check-updates
```

今度は成功したようだ?

```
local@Local sample % sudo npm install -g npm-check-updates
npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142
npm WARN deprecated har-validator@5.1.5: this library is no longer supported
npm WARN deprecated uuid@3.4.0: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
/usr/local/bin/ncu -> /usr/local/lib/node_modules/npm-check-updates/bin/cli.js
/usr/local/bin/npm-check-updates -> /usr/local/lib/node_modules/npm-check-updates/bin/cli.js
+ npm-check-updates@11.7.1
added 314 packages from 166 contributors in 13.642s
```

※WARNとなっている箇所は書いてないので他を当たってくれると助かる。
【LeetCode】就活に向けたコーディングテスト対策 #15

#はじめに
こんばんは．
M1就活生が[LeetCode](https://leetcode.com/)から，easy問題を中心に**Python**を用いて解いていきます．

https://leetcode.com/

↓では，解いた問題のまとめを随時更新しています．
[まとめ記事](https://qiita.com/halpi/items/43761b89a1873dcc9a5c)

https://qiita.com/halpi/items/43761b89a1873dcc9a5c

#問題
今回解いたのは，難易度easyから [問題67のAdd Binary](https://leetcode.com/problems/add-binary/) です．
問題としては，2つの2進数からなる文字列`a`と`b`が与えられたとき，それらの合計を2進数文字列として返すというもの．
入力例と出力例は以下の通りです．

Example 1:

```python
Input: a = "11", b = "1"
Output: "100"
```

Example 2:

```python
Input: a = "1010", b = "1011"
Output: "10101"
```

#書いたコード
書いたコードが以下になります．

```python
class Solution:
    def addBinary(self, a: str, b: str) -> str:
        i = len(a) - 1
        j = len(b) - 1
        result = ""
        carry = 0
        while any([i >= 0, j >= 0, carry != 0]):
            if i >= 0:
                carry += int(a[i])
                i -= 1
            if j >= 0:
                carry += int(b[j])
                j -= 1
            result = str(carry % 2) + result
            carry //= 2
        return result
```

2進数の合計は，桁上がりも意識する必要があるため，`a`，`b`それぞれ，一番下の位から計算していきます．また，位が上がったときの桁も加算する必要があるため，桁上がり用の変数`carry`を`0`で初期化しておきます．`carry`に`a`と`b`をそれぞれ加算し，`carry`の値によって`result`に結果を追加します．

```python
carry = 0 → result = '0', carry = 0
carry = 1 → result = '1', carry = 0
carry = 2 → result = '0', carry = 1 # 桁が上がる
carry = 3 → result = '1', carry = 1 # 桁が上がる
```

この計算を，`a`の桁数，`b`の桁数，`carry != 0`まで続けることでバイナリ計算を行うことができます．

Pythonでもっと簡単に解くことができないか探してみたところ，`int()`を使って，2進数，8進数，16進数表記の文字列を数値に変換することができるということを知りました．

```python
>>> int('10')
10
>>> int('10', 2)
2
>>> int('10', 8)
8
>>> int('10', 16)
16
```

これを使うと，2進数表記の文字列同士を計算することができます．

```python
>>> int('11', 2) + int('1', 2)
4
```

しかし，結果は10進数の数値として返ってくるため，再び2進数に変換する必要があります．そこで組み込み関数`bin()`を使います．すると，このように簡単に2進数の計算を行うことができます．

```python
>>> bin(int('11', 2) + int('1', 2))
'0b100'
```

2進数を表すプレフィックス（`0b`）は，スライスや書式化指定文字列などを使うと取り除くことができるため，今回の問題は以下のように1行のコードで記述することもできます．

```python
class Solution:
    def addBinary(self, a: str, b: str) -> str:
        return bin(int(a, base = 2) + int(b, base = 2))[2:]

class Solution:
    def addBinary(self, a: str, b: str) -> str:
        return format(int(a, base = 2) + int(b, base = 2), 'b')

class Solution:
    def addBinary(self, a: str, b: str) -> str:
        return f"{int(a, base = 2) + int(b, base = 2):b}"
```

#おわりに
LeetCodeの問題には，高評価・低評価の仕様があります．比較的高評価の多い問題はやはり，アルゴリズム力が問われる良問が多い気がします．より良い問題に巡り会うため，できるだけこの評価も参考にして問題を選ぶことをオススメします．

今回書いたコードはGitHubにもあげておきます．

https://github.com/halpi17/LeetCodeStudy/blob/master/067/addBinary.py

[前回](https://qiita.com/halpi/items/d82ce980a10829455748)　[次回]()
TypescriptでNext.jsを使ってHPを作ってみた

# はじめに
仕事でWEBページの作成を行うことになり、デザインの共通化や勉強がてらにTypeScriptとNext.jsを使って開発することにした。
そのときに参考にしたページや、悩んだことなどを記載したいと思う。

# 開発環境
* Windows10
* Node.js
* TypeScript
* next.js
* VSCode
* Chrome

# 環境構築
## VSCodeのインストール
もともとVSCodeが入っていたのでそのまま使用。
拡張機能も特に追加していないが、Chromeを見ながらのHP作成程度なら特に問題なくできる。

参照：[Visual Studio Code](https://code.visualstudio.com/)

## Node.jsのインストール
まずは[node.js](https://nodejs.org/ja/)にアクセスすると早速洗礼が。
LTS版か最新版どっちがいいのかの選択で悩むが、一応仕事で使うし、最新版を使うならローカルではなくDocker上で開発したほうが何かといいと思ったので今回はローカル上で開発するのでLTS版を選択。

## TypescriptとNext.jsのインストール
[Next.jsではじめるTypescript環境](https://qiita.com/Gma_Gama/items/9df765e00d7fda733222)を参考というか、書いてあることを無心で行い無事環境をつくれた。

# 悩んだこと
## 1. 共通デザインをどうやって作るか
ヘッダーとフッターを全ページ共通にしたいのに、いちいちコードを書くのは面倒なので共通化の方法をググってみるも、
やれレイアウト用コンポーネントを作れだの、_app.jsに書くんだだの、いやいや_document.jsだのといろいろ出てきて悩んだ。　　
結局どうしたかというと_app.jsに共通デザインを作成して各ページの内容は各jsに記載した。
理由としてはレイアウト用コンポーネントだと結局各ページに意識的にそのコンポーネントを記載しないと行けないので面倒。
_document.jsではない理由は、StackOverflowやいろんなブログを見てみると共通デザインは_app.jsと書いてあったのでそれにならう事にした。

## 2. 画像等の静的コンテンツをどこに置くか
next.jsでは静的コンテンツをpublicフォルダに置く事になるが、[Next.jsではじめるTypescript環境](https://qiita.com/Gma_Gama/items/9df765e00d7fda733222)を参考にした環境にはsrcフォルダがあり、ソースコードはその中に置くことになる。  
通常であればプロジェクトのフォルダの直下に作成するPublicフォルダを、そのまま直下で作成していいものなのか、srcフォルダ配下に作成するべきなのかで悩んだ。
結局のところsrc配下にpublicフォルダを作成してその中に画像を配置したが、普通に参照/表示できたので問題ないと思う。  

## 3. CSSの書き方
各ページやコンポーネントのCSSの書き方で何回も試行錯誤することになった。
正直書き方がいろいろありすぎて何が正解かはわからないが、最終的に落ち着いた方法を記載する。  
1. 全ページ共通のデザインはglobal.cssに記載する
全ページ共通はglobal.cssというのを作成して、_app.jsでimportすれば全ページに反映されるのでオススメ。

参考:[Nextjs-Built-In CSS Support](https://nextjs.org/docs/basic-features/built-in-css-support)　　  
2. 各ページやコンポーネントのCSSは\<style jsx>に書く
各ページやコンポーネントに反映するスタイルは[コンポーネント・ページ名].module.cssでもできるみたいだが、
ググるとなくなるかもという記載があるところもあり、今推奨は\<style jsx>に書くらしいのでこちらにした。
スタイルをDictionaryで書いて変数に代入して各タグのStyleプロパティに設定する方法もあるが、こちらは細かいのができないのと、プロパティ名の置き換えなどが面倒くさい。
細かいことは例えばhoverやbeforeの設定の仕方がわからなかったり、下位タグへの設定もやりづらいので普通にCSSがかける方がやはり楽。  
3. １つしか反映とかちょっとしたものはstyleプロパティに直書きする
上の2でStyleプロパティに書くのは細かいことができないと書いたが、例えば”text-align：center”だけ置きたいときなどはいちいちクラス名を書いたりするのが面倒なのでこういうのはStyleプロパティに直書きしたほうが楽。
でもソースの各場所にCSSが点在するのは後のメンテナンスコストが上がるのでできればglobal.cssと\<style jsx>で完結する方がいいと思う。  

# おわりに
まだまだNext.jsやTypescriptに慣れていないのでもしかしたらもっといい方法があるかもしれないし、間違っていることもあるとは思うのでコメントやご指摘を頂ければと思います。
まだまだNext.jsやTypescriptでの開発の記事が少ないのでやりたくてもわからないという方が多いでしょうが（私も同じですが。）、これを参考にいろんな人が開発してそのノウハウが広まっていってほしいと思います。
create-react-appができなかった話

# はじめに
Reactでもやってみようかと試したところエラーが出ました。
その内容と解決法についてです。

# どこでエラーが発生したのか
```sh
npm install -g create-react-app
```

は成功

```sh
create-react-app my-app
```

でエラー

エラー内容は

```sh
error A:\work\my-app\node_modules\ejs: Command failed.
Exit code: 1
Command: node ./postinstall.js
Arguments:
Directory: A:\work\my-app\node_modules\ejs


Aborting installation.
  yarnpkg add --exact react react-dom react-scripts cra-template --cwd A:\work\practice\react-practice\my-app has failed.

Deleting generated file... package.json
Deleting generated file... yarn.lock
Deleting generated file... node_modules
Deleting my-app/ from A:\work\
Done.
```

だそう

# 解決策

nodejs, npmのアップデートしてもエラー

そして、create-react-appはyarnでreactなどをインストールしてるらしいです。
ふと「そういえば前からyarnでインストールできないものあったな」と思い出しました。

そこで

```sh
create-react-app my-app --use-npm
```

としてみると

```sh
Success! Created my-app at A:\work\my-app
Inside that directory, you can run several commands:

  npm start
    Starts the development server.

  npm run build
    Bundles the app into static files for production.

  npm test
    Starts the test runner.

  npm run eject
    Removes this tool and copies build dependencies, configuration files
    and scripts into the app directory. If you do this, you can’t go back!

We suggest that you begin by typing:

  cd my-app
  npm start

Happy hacking!
```
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1053860/c5f04144-1845-ffec-d408-cc59779238f8.png)
でけた
破壊的メソッドとミュータブル・イミュータブル[React,Javascript]

私は破壊的メソッドへの理解が乏しかったために何度かReactで苦しんだことがあります。
自分の思考整理と同じく苦しんでいる人のために解説していきたいと思います。

#そもそも破壊的メソッドとは？
配列オブジェクトを変更するメソッドで、そのまま使用することは推奨されていないメソッドです。
破壊的メソッドの例を以下に挙げたいと思います。

・push
・pop
・splice
・reverse
・shift
これらが破壊的メソッドの一例になります。
詳しくは下記を見てみてください。
https://qiita.com/Shokorep/items/929e2e66908eaa915286

##なぜ破壊的メソッドがいけないのか。
プログラミングにはミュータブルとイミュータブルという概念があります。
（javascriptにフォーカスを当てて記載しています）

・ミュータブルとは値を設定した後に、その値を変更できること。
例）配列、オブジェクト
・イミュータブルとは値を設定した後に、その値を変更できないこと。
例）文字列、数値

```
const num = [1, 2, 3]
num.push(4)

console.log(num)
//1,2,3,4
//値が変更されてしまっている。
```

これらの破壊的メソッドは意図せぬ副作用を与えてしまうことがあり、昨今のJavascriptでは破壊的メソッドは避けて、イミュータブルな書き方をする必要があります。

#ではどうすれば良いのか？
解決策はスプレッド構文を使うことです。
（immerなどのライブラリーを使うというのも手です）

```
const num = [1, 2, 3]
num.push(4)
//これは破壊的メソッドになるのでNG
const newNum = [...num, 4]
//これは非破壊的メソッドなのでOK
//スプレッド構文を使うことでnumはミュターブルではなくイミュータブルなものとして扱われます。

```

#Reactでどのようにハマったのか。
useStateの更新関数内で破壊的メソッドを使用して意図した挙動になりませんでした。

どうして破壊的メソッドを使用してはいけないのかを説明する前にReactにおいて再レンダリングされるタイミングを整理しておきたいと思います。
・stateが更新されたコンポーネントは再レンダリング
・propsが変更されたコンポーネントは再レンダリング
・再レンダリングされたコンポーネント配下の子要素は再レンダリング

ではどうして、useStateの更新関数内で破壊的メソッドを使用してはいけないのか。
それは再レンダリングする条件として「stateが更新されたコンポーネントは再レンダリング」が必要、つまりはstateを更新する必要があります。

```
 const [num, setNum] = useState([0])

  const addNum = () => {
    setNum((preNum) => {
      const newNum = preNum
      newNum.push(1)
　　　　　　　　　　　　//破壊的メソッド
      console.log(newNum)
     //ボタンを押すとconsoleでは値が増えていく。
      return newNum
    })}

  return (
    <>
      <button onClick={addNum}>1増えるよ</button>
      <p>{num}</p>
      //ここの値はいくらボタンを押しても更新されない
    </>
  );
```
上のようにnumの値は増えていきません。
これは、newNumとpreNumの値を比較した時に同じ値だと認識されてしまい、再レンダリングが起きず、numが更新されていないことが原因です。

Reactでもイミュータブルが求められています。
前の値をそのまま変更してもダメで、新しい値を生成して返す必要があるので下記のようにスプレッド構文で書き直す必要があります。

```
 const [num, setNum] = useState([0])

  const addNum = () => {
    setNum((preNum) => {
      const newNum = [...preNum, 1]
      //非破壊的メソッド
      console.log(newNum)
　　　　　　　　 //ボタンを押すと値が増えていく。
      return newNum
    })

  }
  console.log(num)

  return (
    <>
      <button onClick={addNum}>1増えるよ</button>
      <p>{num}</p>
　　　　　　　　　//ボタンを押すと値が増えていく。
    </>
  );
```

#最後に
破壊的メソッドを使う時には細心の注意を払って使っていきたいと思います。
kotlinで大文字小文字の違いを無視した文字列の比較方法

# 概要

kotlinで大文字小文字の違いを無視した文字列の比較を行う方法を記載する。

# 大文字小文字の違いを無視した文字列の比較方法

equalsメソッドのignoreCaseをtrueに設定することで大文字小文字の違いを無視して文字列の比較をすることができる。

```kotlin
// 先頭が大文字
val str1 = "String"

// 先頭が小文字
val str2 = "string"

val isSame = str1.equals(str2)
val isSame2 = str1.equals(str2, ignoreCase = true)
Log.d("equalsResultCheck", "$isSame , $isSame2")
```

出力されたログを見てみると以下の様になっており、ignoreCaseがtrueの場合はequalsの結果がtrueになっている。

```
D/equalsResultCheck: false , true
```
video要素を使った際にメモリリークが発生した際のメモ

## 概要

Vue.jsでシングルページの中で`v-if`を使ってvideo要素を表示したり、非表示にしたりしていたが、その際に`MediaStream`に追加したビデオトラックが適切に削除されていなかったため、メモリリークが発生していた。

## 不具合箇所

```JavaScript
mounted() {
  this.stream = await navigator.mediaDevices.getUserMedia({ video: true })
}
```

こんな風に`v-if`で作られるたびにメディアストリームを生成して`stream`にセットし、video要素のsrcObjectで参照していたが、`v-if`でDOMから取り除かれてもメディアストリームに追加されたビデオトラックが削除されていなかったため、メモリリークが発生した？

## 対策

コンポーネントが破棄される前にちゃんとリソースを解放しておく（下記のような感じ）。

```JavaScript
beforeDestroy() {
  // video要素
  const videoEl = document.querySelector('video')
  // ビデオトラックを削除
  if (videoEl.srcObject) {
    videoEl.srcObject.getVideoTracks().forEach(track => {
      track.stop()
      videoEl.srcObject.removeTrack(track)
    })
  }
  this.stream = null
  videoEl.pause()
  videoEl.removeAttribute('srcObject')
  videoEl.load()
}
```

## 備考

- Chromeではメモリリークっぽいものは発生せず、Safariでだけ発生していた。
Git 基本コマンド


# 新しいレポジトリ作成
```
git init
git add [filename]
git commit -m "first commit"
git remote add origin [git@github.com:username/filename.git]
git push origin HEAD
```

# branchの作成からpushまで
```
git branch -a #今いるブランチを確認 (-a:リモートブランチも含めたすべて)
git branch [branchname]
git checkout [branchname]
git add [filename]
git commit -m "comment"
git push origin [branchname]
```

# addのオプション
```
git add . 
git add *.py
git add -n #追加されるファイルを調べる
git add -u #変更されたファイルを追加する
```

# コミットコメントの書き方
- fix：バグ修正
- add：新規機能追加
- update：機能修正
- remove：削除

 - Fix wrong markdown
 - Add function
 - Remove some dead code

# ファイル、ディレクトリの削除
```
git rm [filename]
git rm -r [dirname]
git add [filename]
git commit -m "Remove filename"
git push origin HEAD
```
英数字混合パスワードのテストの仕方

#概要
RSpecでモデルの単体テストを行う際に英数字混合のpasswordをFactoryBotでどのようにしてダミーデータを作成するか、考案に時間が掛かった為備忘録として書き留めておきます。

**実装したいpasswordの条件**
- 6文字以上であること
- 英数字混合であること

**設定したvalidation**

```models/user.rb
validates :password, format: { with: /\A(?=.*?[a-z])(?=.*?\d)[a-z\d]+\z/i }
```

**最初に設定したFactorybot**

```spec/factories/users.rb
factory :user do
 password {Faker::Internet.password(min_length: 6)}
```

**結果**
このダミーデータでも単体テストは成功するが、まれに失敗します。
特に縛りがないパスワードの為、まれに整数のみになってしまうからです。

#結論
Factorybotを下記のように修正することで整数のみになることを防ぎました。

```spec/factories/users.rb
factory :user do
 password {'1a' + Faker::Internet.password(min_length: 4)}
```

#最後に
自分のような初学者の方で、ダミーデータ作成時のひとつの例として参考になれば幸いです。
Ruby on Rails 環境構築 Cloud9



#目次
[1.Railsのインストール](#1-railsのインストール)
[2.Railsのバージョン確認](#2-railsのバージョン確認)
[3.sqliteのバージョン確認](#3-sqliteのバージョン確認)
[4.プロジェクト作成](#4-プロジェクト作成)
[5.gemのインストール](#5-gemのインストール)
[6.gemのsqlite3のバージョンを明示的に指定](#6-gemのsqlite3のバージョンを明示的に指定)
[7.データーベースの作成](#7-データーベースの作成)
[8.railsサーバの立ち上げ](#8-railsサーバの立ち上げ)
[9.RailsProjectsのwelcomePageを表示](#9-railsprojectsのwelcomepageを表示)

#1. Railsのインストール
まずは、Railsのインストールをします。下記のようにターミナルに入力してください。
ドキュメントが不要な場合は、`--no-document`と入力してください。（インストール時間を短縮できます。）
<br>

```

gem install rails --version="5.1.4" --no-document

```

#2. Railsのバージョン確認
次に、インストールしたバージョンの確認をします。
<br>

```

rails -v

```
<br>

`Rails 5.1.4`と出力されれば完了です。

#3. sqliteのバージョン確認
次にデーターベースとして使うsqliteのバージョン確認をします。
sqliteはcloud9にインストールされているのでインストール作業は省略します。
3系のバージョンを使用します。

```

sqlite3 --version

```

#4. プロジェクト作成
次に新規railsプロジェクトの作成をします。
1. プロジェクト用のディレクトリをCloud9のenvironment直下に作成してください。
2. ターミナルにて作成したディレクトリへ移動してください。(`cd 作成したディレクトリ名`)
3. 次にprojectsという名でプロジェクトを作成します

```
rails _5.1.4_ new projects
```

- ディレクトリの直下にprojectsが生成されたので移動します(`cd projects/`)

#5. gemのインストール
次にgemのインストールを行います。ターミナルにて下記のコマンドを入力してください。

```
bundle install
```

#6. gemのsqlite3のバージョンを明示的に指定
こちらはエラー回避の為に行います。
1. projectディレクトリ内のgemfileを開いてください。
2. `gem 'sqlite3'`の行の後に続いて追記して保存してください。`gem 'sqlite3', '~> 1.3.6'`
3. ターミナルでインストールされるgemをアップデートします。

```
bundle update
```

#7. データーベースの作成
以下のコマンドを実行してください。

```
rails db:create
```

#8. railsサーバの立ち上げ
以下のコマンドを実行してください。

```
rails s
```

#9. RailsProjectsのWelcomePageを表示
Cloud9の仮想サーバのURLをブラウザに入力します。
Cloud9->menu->Preview->Preview Running Application->pop out new windowこの順でクリックしてください。
Welcome Pageが表示されたら完了です。

#　最後に
記事をご覧いただきありがとうございました。
何か、間違いや不明点がありましたらコメントにてご指摘をお願いいたします。