OmniAICreator/Qiita-1.07M huggingface dataset:
Pull Request を安全に受け取る方法（Backlog版）

# はじめに
新しく会社に入社する人に向けた Git および Github の勉強会をすることになったので、重要なポイントを確認するために下記の本を読みました。
その時に話をしたいと思うことをいくつかまとめたいと思い投稿することにしました。

Github については本でもまとめられていたり、他の人がまとめられていたりするので、
"Pull Request を安全に受け取る方法" の Backlog 版を書きました。参考にしていただけると嬉しいです。

Github実践入門
https://www.amazon.co.jp/GitHub%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80-Pull-Request%E3%81%AB%E3%82%88%E3%82%8B%E9%96%8B%E7%99%BA%E3%81%AE%E5%A4%89%E9%9D%A9-PRESS-plus/dp/477416366X

#### 関連リンク
関連リンクを下記に載せておくので、必要であれば参考にしてください。。

* Pull Request を送る方法（Backlog版）
    * https://qiita.com/syukan3/items/6b8c1050a10076ff6d70



# Pull Request を安全に受け取る方法
## 全体フロー
Pull Request を安全に受け取るまでの全体のフローを下にまとめました。
上から順に作業していくことで、Pull Request を安全に受け取ることができます。

1. Pull Request のコードに問題がないかどうかを確認する
    * clone もしくは pull により、リポジトリを最新の状態にする
    * Pull Request送信者のリモートリポジトリを取得する
    * 確認用のブランチを作成する
2. マージする（２パターンあり）
3. 1.で作成したブランチを削除する



## Pull Request のコードに問題がないかどうかを確認する
Pull Request のコードに問題がないかどうかを確認するために、
自分の手元の環境にPull Requestのコードを落として安全確保のためにブランチを作成してそのブランチにてコードの確認をします。

### clone もしくは pull により、ローカルリポジトリを最新の状態にする

```
$ git clone ${Pull Requestの元のリポジトリ}
```

### Pull Request送信者のリモートリポジトリを取得する
Pull Request送信者のリモートリポジトリを取得します。

```
// リモートリポジトリにPull Request送信者のリポジトリを登録
$ git remote add ${Pull Request送信者} ${Pull Requestされたリポジトリリンク}

// Pull Request送信者のリポジトリのデータを取得
$ git fetch ${Pull Request送信者}
```

### 確認用のブランチを作成する
下記コマンドにて確認用のブランチを作成し、手元の環境にてPull Requestのコードが問題なく動くかどうかを確認する。
ここはコード内容によって確認項目が異なるかと思うので、各自確認を進めてください。

```
$ git checkout -b pull_request_1
```

## マージする（２パターンあり）
### Backlog の画面からマージする方法

パターンの１つ目です。

__work__欄をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308256/757035d1-9b5f-1d53-6224-0ce08f322de1.png)

印をつけたところを__master__に変更して、マージボタンを押します。
これで__work__ブランチを__master__ブランチにマージをすることができました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308256/37042a5a-d345-a931-f104-3244357b29ce.png)

最後に、マージができていることを確認します。
色々と方法はありますが、コミット履歴タブを押すと、下の添付画像の通り "Merge pull request..." と確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308256/d5c46ccb-5143-d82d-15ff-d476d5985162.png)


### CLI （ターミナル）からマージする方法
パターンの２つ目です。

```
// Pull Requestを取り込むmasterブランチへ切り替え
$ git checkout master

// masterブランチへ${Pull Request送信者}/workの内容をマージする
$ git merge ${Pull Request送信者}/work

// 変更内容を確認して、意図しない変更が含まれていないかを確認する
$ git diff origin/master

// 変更内容に問題がなければ、pushをすることでPull Requestを取り込む
$ git push
```



## ブランチを削除する
不要になったブランチは残しておくと、後で見返したときに何かわからなくなるため、使い終わったら削除するようにします。
（"確認用のブランチを作成する"の項目で作成したブランチを削除します。）

下記のコードを実行してください。

```
$ git branch -D pull_request_1
```

# まとめ
Backlog 版として記事をまとめましたが、Pull Requestを安全に受け取る方法の全体的なフローに変わりはありません。
Github と Backlog で UI に差があることから少し操作方法に差があるだけですが、この記事をみて誰かの役に立てば嬉しく思います。

---
### 会社紹介

**株式会社 Mosaica**  
最先端テクノロジーで社会課題を解決し、持続可能な未来を創造する IT カンパニー。
AI ソリューション、クラウド統合、DX 推進、経営コンサルティングなど包括的なサービスでビジネス変革を支援しています。  

詳しくは [公式サイト](https://mosaica.co.jp/) までお気軽にご相談ください。
公式サイト： https://mosaica.co.jp/
「正しいものを正しくつくる」を読んで（第3章まで）

## はじめに
[「正しいものを正しくつくる」](http://www.bnn.co.jp/books/9859/)を三章まで読んだ。
読んで感じたことをいくつか挙げる。

読んだ人は次のような人。
- SIerでSESとしての経験が長い
- アジャイル開発の経験がない
- Rubyの学習を始めた（現在チュートリアル9章の途中）
- 「カイゼン・ジャーニー」を読んだ

## アジャイルが適する領域と、適さない領域がある

アジャイルはSoEに向いている。SoRには向いていない。
これだけだと二項対立に見えてしまうが、90ページで紹介されていた次のスライドを読んで理解が深まった。

[フロー効率性とリソース効率性、再入門 #devlove #devkan](https://www.slideshare.net/i2key/devlove-devkan-103489350)

## 不確実性に適応する

アジャイルによって不確実性への適応が期待できる。
不確実性とは要件が・仕様が・認識が定まっていないという意味ではなく、次のようなこと。

- プロダクトオーナーが当初は自覚していない期待
- 開発を進めながら学習をして始めて分かる要件

アジャイルではない場合は不確実性を切り捨てる必要が出るため、利害関係者に不満が残る原因になる。

## ゴールデンサークル

アジャイルを目的にするのではなく、自分たちが向き合う開発そのものをしっかりと見る。
ゴールデンサークルの考え方が参考になる。

[優れたリーダーはどうやって行動を促すか](https://www.ted.com/talks/simon_sinek_how_great_leaders_inspire_action?language=ja#t-19434)

## TDD、クラウドサービスとの関係

私個人の経験としてRailsチュートリアルを実施しながらテストコードを書きHerokuにデプロイすることで、それぞれの利便性を知ることが出来た。
TDDとHerokuなどのクラウドサービスの利用（またはDevOps）はアジャイル開発の場面ではむしろ必須なのだろう。
Railsチュートリアルは3章から一つのアプリケーションに徐々に機能追加をしていく構成になっている。それぞれの章を一つのスプリントと捉えて進めるのも良さそう。
文字を変換したいだけだけど・・・

競プロやっててA問題で時間くったのでメモっとく

# 一文字ならchar型の操作でできる

## 一文字次の文字に変換する
```java
char c = 'a';
c++;
System.out.println( c ); // b
```

## 大文字小文字の変換
```java
char c = 'a';
c -= 32;
System.out.println( c ); // A
```
小文字から大文字の変換は-32
大文字から小文字の変換は+32

## その他

引数の上で計算すると文字コードが出力されてしまうからおとなしく1行増やした方がいいかも

```java
char c = 'a';
System.out.println( c - 32 ); // 65
System.out.println( (char)( c - 32 ) ); // A　キャストすればOK
```

# 躓いた問題

https://atcoder.jp/contests/abc151/tasks/abc151_a

## A - Next Alphabet
### 問題文
zでない英小文字Cが与えられます。アルファベット順でCの次の文字を出力してください。
### 制約
Cはzでない英小文字

### 回答

```java
import java.util.*;

public class Main {

    public static void main(String[] args) {

        Scanner in = new Scanner(System.in);
        char c = in.nextLine().charAt(0);
        System.out.println( ++c );

    }

}
```

すっきり

### 実際の回答

```java
import java.util.*;
 
public class Main {
 
    public static void main(String[] args) {
 
        Scanner in = new Scanner(System.in);
        String c = in.nextLine();
        String base = "abcdefghijklmnopqrstuvwxyz";
 
        for( int i = 0 ; i < base.length() ; i++ ){
            if( c.charAt(0) == base.charAt( i ) ){
                System.out.println( base.charAt( i + 1 ) );
                return;
            }
        }
 
    }
 
}

```

？？？？？？？？？？？？？？？？？？？？？
ま、ままま、まぁ間違ってないし
ACだし
kaage流！ABC-A問題FA奪取術！

こんにちは。kaageです。
ABC151-AのFA(First AC)を取りました。僕には、ABC146,ABC151と2度のFA経験があります。（ほんとは多分3回あるんですが、いつのABCか忘れました）あと、Second ACは5回くらい取ってます。ちなみに、この時はほぼ毎回うしさんに負けています。
さて、一つの問題のACを世界で一番早く取る、という行為は非常に気持ちいいものです。
そこで、自分がいつも心がけている素早い提出のコツを記事にしようと思います。
ここはこの記事を通して強調しておきたいのですが、**FAを取るのは初心者にも、決して難しくありません。**
# FA争いの基本
FAが取られる時間は、大抵の場合次のようになることが多いです。
・2行や3行で実装が終わり、if文なども使わない場合、20秒弱。
・if文を2-3回使い、条件が非常に単純な場合（整数の定数倍と、他の整数の大小を比較する、など）、30秒程度。
・面倒な場合分けをさせられる場合（7つの曜日を文字列で場合分けする場合などがあります）、1分弱。
ここで、一番初心者でもFAが狙いやすいのは、一番上の、2行や3行で実装が終わる場合です。
他の場合は、1度でもタイプミスをしたりしたら負けも同然なので、慣れていないとかなり厳しいです。自分も、このような場合にFAを取ったことはありません。このような場合は、FAを取りに行くよりサンプルをきちんと通してペナルティを極力出さない努力をしたほうがいいかもしれません。
# FAを取るためにすること
### コンテスト前
エディタを開いておきましょう。これは当たり前です。
また、エディタを開いたら、コードを書き始めるところまでカーソルを持ってきておきましょう。
C系の言語ならmain関数の中、Pythonならimportなどやライブラリが終わったすぐ下、という具合です。
コーディングをしたいときにカーソルを動かす時間は決して馬鹿になりません。最悪2秒くらいはかかってしまうでしょう。**1秒単位で争われるFAの世界で、この2秒が命取りになります。**
また、これはFAを狙っていなくてもする人は多いと思うのですが、A問題のURLを先に打って、そのページを開いておきましょう。当然、コンテスト前は問題を見られませんが、コンテスト開始直後にページを更新すれば、一切のタイムロスなしで問題が見られます。
もうひとつ言っておくとすると、コンテスト1分前から、質問タブを利用することで問題名が見られるようになります。これを利用して問題をエスパーするのもひとつの手ですが、コンテスト前1分は、少なくとも自分の場合は、落ち着くなり精神統一するなりしたほうが有益には違いないです。
### コンテスト開始時
[ABC151-A](https://atcoder.jp/contests/abc151/tasks/abc151_a)を例に解説します。
まず、上で述べたように、開始5秒前くらいからF5キーを連打するなどして、開始と同時に問題を閲覧します。ここまでで2秒とします。
問題が目に入ってからエディタでの実装に入るまでの猶予は、多くて3秒と思ってください。実際、上に挙げた問題は非常に単純です。目全体で文章を捉えれば、趣旨を理解するのは一瞬で終わるはずです。問題を見て、ウィンドウを切り替え、エディタ画面でキーボードの上に指が載るまででどれだけ多くても3.5秒は切ってほしいです。逆に、これが切れないとFAは結構絶望的になります。
また、これは個人の好みが分かれると思いますが、変数を先に定義しておいて変数定義を書く手間を省略する、という戦法もあるらしいです。
ただ、問題点として、問題文中の変数と名前が異なる場合に混乱しやすい、というのが考えられます。( @e869120 さんに教えていただきました、ありがとうございます。)
### コーディング
さて、ついにコーディングに入ります。しかし、ここまでしっかり準備をしておけば、多少のコーディングの速度の差で勝敗が決することはあまりないでしょう。
実際に、[自分のFA提出](https://atcoder.jp/contests/abc151/submissions/9440102)を書くのに、少なくとも8秒はかかっています。赤コーダーなどの方々と比べれば決して早くはありませんが、これでも多少の余裕をもってFAが取れるのです。
タイプミスだけはなるべくしないようにしたいところですが、してしまったら仕方ないです。諦めずになるべく早くリカバーするようにするのみです。
### 提出
さて、コーディングが終わったらいよいよ提出です。
意外かもしれませんが、自分は、自動提出をするコマンドツールなどは一切使っていません。使ってもいいとは思うのですが、気に入ったエディタを離れたくないというのと、コマンドラインが起動するまでに最大1秒程度のラグは存在し、これはどうにもならないというのを理由に使っていません。ブラウザからフォームにコピペして素直に提出しています。
では、どうすればブラウザからでも素早い提出が可能になるのでしょうか。答えはただ一つ。[コレ](https://greasyfork.org/ja/scripts/378760-atcoder-submit-keyboard-shortcut)です。
Osmium_1008氏（実は僕の同期です）が作った、AtCoderの提出ボタンをCtrl+Enterで代わりにクリックできるスクリプトです。なんのことはない、と思うかもしれませんが、これ、死ぬほど便利です。
マラソン課題でN分間の提出制限がうっとうしいとき、画面をスクロールするのが面倒なとき、…。
いつでも使えるうえ、FAを取るのには欠かせないツールです。ぜひみなさん自分のブラウザに導入しましょう。Osmiumくんに感謝感謝。
これを使えば長くても2秒で提出ができます。
ここまでで2+3.5+8+2=15.5秒。今回の自分のFAは16秒なので、提出がサーバーまで届く時間を考えても、これくらいが基本的な動きだとわかるでしょう。
### 提出後
提出後することは特にありません。（当たり前）
ジャッジを待っている間に次の問題の考察なり実装なりに移るのが得策でしょう。
ジャッジ結果を早く見たい、という方のためにChrome拡張のこちらも紹介しておきます。
[Comfortable AtCoder](https://chrome.google.com/webstore/detail/comfortable-atcoder/ipmmkccdccnephfilbjdnmnfcbopbpaj)
こちらはdrafearさんの作ってくださった拡張機能で、ジャッジ結果をポップアップで表示してくれるので、コーディング中などでも前の提出の結果が見られます。便利ですね。他にもいろいろ機能があります。FAにはあまり関係ないですがあまりにも便利なので紹介しました。
# おわりに
みなさん楽しいFAライフを！！！
AtCoder 第6回 ドワンゴからの挑戦状 予選 参戦記

# AtCoder 第6回 ドワンゴからの挑戦状 予選 参戦記

## [A - Falling Asleep](https://atcoder.jp/contests/dwacon6th-prelims/tasks/dwacon6th_prelims_a)

4分で突破. 書くだけ.

```python
N = int(input())

total = 0
p = 0
d = {}
for _ in range(N):
    s, t = input().split()
    t = int(t)
    total += t
    d[s] = total
print(total - d[input()])
```

## [B - Fusing Slimes](https://atcoder.jp/contests/dwacon6th-prelims/tasks/dwacon6th_prelims_b)

敗退.
AtCoder Beginner Contest 150 参戦記

# AtCoder Beginner Contest 150 参戦記

## [ABC150A - 500 Yen Coins](https://atcoder.jp/contests/abc150/tasks/abc150_a)

5分で突破. 書くだけ. 問題文が中々表示されなかったせいで時間がかかった.

```python
K, X = map(int, input().split())

if 500 * K >= X:
    print('Yes')
else:
    print('No')
```

## [ABC150B - Count ABC](https://atcoder.jp/contests/abc150/tasks/abc150_b)

2分半で突破. 書くだけ.

```python
N = int(input())
S = input()

result = 0
for i in range(N):
    if S[i:i+3] == 'ABC':
        result += 1
print(result)
```

## [ABC150C - Count Order](https://atcoder.jp/contests/abc150/tasks/abc150_c)

26分で突破. C問題にしては難しいというか、最初は解ける気がしなかった. 素直に積算すればよかったんだなと…….

```python
N = int(input())
P = list(map(int, input().split()))
Q = list(map(int, input().split()))

fac = [0] * 8
fac[1] = 1
for i in range(2, N):
    fac[i] = i * fac[i - 1]

a = 0
l = list(range(1, N + 1))
for i in range(N):
    a += l.index(P[i]) * fac[len(l) - 1]
    l.remove(P[i])

b = 0
l = list(range(1, N + 1))
for i in range(N):
    b += l.index(Q[i]) * fac[len(l) - 1]
    l.remove(Q[i])

print(abs(a - b))
```

## [ABC150D - Semi Common Multiple](https://atcoder.jp/contests/abc150/tasks/abc150_d)

敗退.

追記: PDF の解説どおり書いてみた.

```python
from fractions import gcd

N, M = map(int, input().split())
A = list(map(int, input().split()))

a = A[0]
n = 1
while a % 2 == 0:
    n *= 2
    a //= 2

lcm = 1
for a in A:
    if a % n != 0 or a % (2 * n) == 0:
        print(0)
        exit()
    lcm = lcm * a // gcd(lcm, a)
    if lcm // 2 > M:
        print(0)
        exit()

print((M - lcm // 2) // lcm + 1)
```
書評：ソフトウェア・ファースト

# はじめに
書籍「ソフトウェア・ファースト」を読みました。
最新のエンジニア組織についての提言をわかりやすく示してくれるとてもいい本でした。
カテゴリ的にはビジネス書なんですが、読むべきはやはりエンジニアだと思います。
書籍だけの学びはすぐ流れてしまうので、感想文を残しています。
(ネタバレに当たる内容があるかもしれないので、ご注意願います。)

# 第1章 ソフトウェア・ファースト
1章はビジネス、サービスの変化についてソフトウェアを中心に説明をした感じです。
この章はこの後の章の話のための導入のようです。

## 印象に残った言葉、部分
*本書のタイトル「ソフトウェア・ファースト」とは、IT（とそれを構成するソフトウェア）活用を
核として事業やプロダクト開発を進めていく考え方です。
決してソフトウェアがすべてということではありません。
ソフトウェアは一つの手段です。ただ、ここまでの説明でお分かりのように、
使い方次第では既存の産業構造や製品・サービスのあり方を根底から覆すような破壊力を持っています。
P35*

# 第2章 IT・ネットの"20年戦争"に負けた日本の課題と光明
日本に焦点を当てて、日本のIT産業の課題、原因を解説しています。

## 印象に残った言葉、部分
*日本企業はソフトウェアを「設計パターンにしたがって複製可能な工業製品」とみなし、
米国企業は「ビジネスであり商売の重要な武器」、
欧州企業は「ソフトウェアの標準化に代表される美」を提言するものとして捉えていると分析します。
P77*

# 第3章 ソフトウェア・ファーストの実践に必要な変革
2章を踏まえて、各企業がどの方向に向かうか、正しく向かうためにどのような手法があるか
解説しています。中心は会社組織という単位だと思います。

## 印象に残った言葉、部分
*DXで肝になるのはIT活用を「手の内化」できるかどうかです。
手の内化・・・自社プロダクトの進化にかかわる重要な技術を自分たちが主導権を持って企画・開発し、
事業上の武器にしていくことを「手の内化する」と言うのでしょう
P109*

*1. ハードウェアはソフトウェアのためにある
2. ソフトウェアはユーザーエクスペリエンスのためにある
3. ユーザーエクスペリエンスは人々の感情を満足させるためにある
P145 アップルに学ぶ*

# 第4章 これからの「強い開発組織」を考える
ソフトウェア・ファーストを実践する中心になる開発組織に焦点を当てています。
実際に開発組織を作るときは開発部以外の部（特に人事、営業）との協力・協調が不可欠だと思いますが、
営業力の源泉にもなる開発組織の構築について解説しています。

## 印象に残った言葉、部分
*ソフトウェア開発に必要な職種
- プロダクトマネジャー
- ソフトウェアエンジニア
- エンジニアリングマネジャー
- デザイナー
- QAエンジニア*

*これらはあくまで筆者が一般的な開発にあてはめて職種と役割を言語化したものなので、当然、
企業や開発するプロダクトの性質によって細かい役割の違いがあっても構いません。
P231*

# 第5章 ソフトウェア・ファーストなキャリアを築くには
個人がソフトウェア開発の中でどのようなキャリアを進むか筆者なりのテンプレ？ロードマップを示してくれています。
時代の流れで各種開発組織における役割や名称は変更していますが、
大枠はエンジニア、エンジニアリングマネジャー、プロダクトマネジャーから変わらないのかなと思いました。

## 印象に残った言葉、部分
*T型のスキル構築 -> T型からπ(パイ)型へ
P287*

*ソフトウェアエンジニアのキャリア３大分類
1. エンジニア を極める（技術）
2. エンジニアリングマネジャーを志向する（人・組織）
3. プロダクトマネジャーを志向する（プロダクト・ビジネス）
P305*

# まとめ
各部ごとに印象に残った部分のキーワードや感想をまとめました。
ソフトウェア・ファースト...ボリュームと学びが半端なくて全然まとまりませんでした...
章が進むごとに対象が 社会(主に日本) -> 業界・企業 -> 組織 -> 個人 と
スコープが狭くなるので必然後半の方が刺さる内容や共感を得る部分が多いです。
しかし、この本の前半の部分ほど刺さるようになったときに
自分自身がエンジニア、ビジネスマンとして意識する世界が変わるのかなぁとも思いました。

少なくとも今の自分にとって近いのは4~5章ですが、
早く3章以前の内容が自分自身の強い関心ごとにならないといけないとも感じました。

まずは、プロダクト志向な個人・チームの育成からチャレンジする2020年にしようかと。
gatsbyビルド時に起きるmaterial-uiのスタイル崩れを直す

#gatsbyビルド時にmaterial-uiのスタイルが崩れてしまった
gatsbyで開発したwebアプリをリリースしたらmaterial-uiで構成したコンポーネントのスタイルが崩れていました。どうやらプラグインを入れないとmaterial-uiのスタイルが崩れてしまうようです。
修正法がわかったので、共有しようと思います。

#スタイル崩れの修正法
1、**gatsby-plugin-material-uiをインストール**

`npm install gatsby-plugin-material-ui @material-ui/styles`

もしくは

package.jsonに以下のように**gatsby-plugin-material-ui**を加える
その後、`npm install`を実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/467535/ce435e0b-0917-3b15-429a-bfeb53aec5ca.png)

2、**gatsby-config.jsにgatsby-plugin-material-uiプラグインの情報を入力する必要がある**

gatsby-config.jsに以下のように**gatsby-plugin-material-ui**を加える
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/467535/e12318c1-b9d7-69af-21f5-82bf43a1ebe8.png)


これで、再ビルドするとmaterial-uiのcssなどのスタイルが整った。


`gatsby develop`で立ち上がる開発環境でスタイルが崩れてない人も`gatsby serve`でビルド時の（本番）環境が立ち上がるのでリリース前には試しておいたほうがいいと思います。

#参考にしたサイト
https://translate.googleusercontent.com/translate_c?depth=1&hl=ja&prev=search&rurl=translate.google.com&sl=en&sp=nmt4&u=https://github.com/mui-org/material-ui/issues/18197&xid=17259,15700022,15700186,15700191,15700256,15700259,15700262,15700265,15700271,15700283&usg=ALkJrhgdCMg8T0L8dnElpPSADj4XICpmHQ
vagrant upでエラー（No usable default provider could be found for your system）

Kubernetesを勉強するためにVagrantを使ってVirtualBoxで仮想サーバーを構築しようと「vagrant up」したら以下のエラーが発生して起動に失敗しました。


```
$ vagrant up
No usable default provider could be found for your system.

Vagrant relies on interactions with 3rd party systems, known as
"providers", to provide Vagrant with resources to run development
environments. Examples are VirtualBox, VMware, Hyper-V.

The easiest solution to this message is to install VirtualBox, which
is available for free on all major platforms.

If you believe you already have a provider available, make sure it
is properly installed and configured. You can see more details about
why a particular provider isn't working by forcing usage with
`vagrant up --provider=PROVIDER`, which should give you a more specific
error message for that particular provider.
```

↑のエラーをググると、以下のqiitaの記事があって、どうやらインストールしているVagrant（2.2.6）がインストールしている最新のVirtualBox（6.1.0）に対応していなかったのが原因らしい。
[【Mac】vagrant upでエラー](https://qiita.com/mtake6212/items/de7b26da8b283213f12a)

以下の記事を参考にVirtualBoxをアンインストールして5.2.34をインストールしました。
[MacのVirtualBoxをアンインストール](https://pc-karuma.net/mac-virtualbox-uninstall/)

再び「vagrant up」を実行したら、無事起動することができました。
AtCoderに参加してみたお話

## はじめてAtCoderに参加してみた

Qiitaに記事を書くようになったり、仕事のことでいろいろ調べているうちに
「競技プログラミング」が流行っていることを知りました。
Twitterなんかでもはてブの記事がTLに流れてきたりするので興味本位でアカウントを作成。
いろいろ調べていると、コンテストが金曜日の夜や休日の夜に開催されるらしく、
そこに参加して問題を解いていくそう。

年末年始で忙しく、アカウント作成だけで終わっていたのでやっとコンテストに参加することができました。
初めて参加したのが[AtCoder Beginner Contest 151](https://atcoder.jp/contests/abc151)。
最近はkintoneをいじることが多く、jsでやってみようと思ったものの
おすすめはされていないみたいなので、数ヶ月前に少しだけ勉強したPythonで参加しました。

## 初回なので何がなんだかパルプンテ

どきどきしながらPCの前で待機し、時間ピッタリにスタート。
画面の右下にカウントダウンが表示されます。
問題はAからFの6題があって、問題ごとに配点が違いました(Aは100点で100点ずつ増える)。

問題がズラッと並べられているし、よくわからないけどAが初心者向けだろうということでAの問題を選択。
実行制限時間とか書いてるけどとりあえず無視…。

###解いた問題 [ABC 151 A-Next Alphabet](https://atcoder.jp/contests/abc151/tasks/abc151_a)
>**【問題文】**
> $z$ でない英小文字 $C$ が与えられます。
> アルファベット順で $C$ の次の文字を出力してください。
>**【制約】**
> $C$ は $z$ でない英小文字
>**【入力】**
> 入力は以下の形式で標準入力から与えられる。
>$C$
>**【出力】**
> アルファベット順で $C$ の次の文字を出力せよ。
>**【入力例】**
>a
>**【出力例】**
>b

## 参加してみて
・まず標準入力という言葉に詰まる。
・Pythonの知識が抜け落ちている。
・JavaScriptからPythonの配列の考え方にシフトするのが大変だった。

とりあえず解けたものの、ダサいコードになったので戒めとして貼っておくことにします。
ライブラリやメソッドを調べればよかったのかなと反省。

```python:alpha.py
a = input()
alpha = ["a", "b", "c", "d", "e", "f", "g",
        "h", "i", "j", "k", "l", "m", "n",
        "o", "p", "q", "r", "s", "t", "u",
        "v", "w", "x", "y", "z"]

for i in range(len(alpha)):
    alphabet = alpha[i]
    if a == alphabet:
        s = i + 1
        alphabet = alpha[s]
        print(alphabet)
        break
```

実行制限時間が2secと書いているのに対してこのコードは17msかかっていました。
完全にアウト。これはハマるなあ、と終わった瞬間に思いました。

## 終わりに
AtCoderは過去問なども公開されているので休日など時間のある際に
書く練習をしてみようと思います。
まずは毎週何かしらのコンテストに参加して慣れることも大切なんじゃないかなと感じました。
次回は実行時間も気にしながら解けるようにコードを書いてみようと思います！
全画面キャプチャー(Chrome)コマンド一覧

## 全画面キャプチャー(Chrome)コマンド一覧
windows
【1】Ctrl+Shift+I      任意のページでデベロッパーツールを開きます。
【2】Win Ctrl+Shift+P  詳細機能を呼び出します。
【3】Win「full」→Enter 「full」と入力すると候補が絞られる
Mac
【1】Mac command+option+I  任意のページでデベロッパーツールを開きます。
【2】Mac command+shift+P   詳細機能を呼び出します。
【3】Mac「full」→return   「full」と入力すると候補が絞られる
初心者による DOM イベントを使った処理

#概要
ブラウザ上では、さまざまなイベントが発生します。クライアントサイドのjavascriptでは、それらのイベントに応じて処理をします。これをイベント駆動型モデルという。

#イベント一覧
javascriptがキャッチするイベントを一覧にしてみる

###読み込み関係

```
abort : 画像の読み込みを中断した時
load : ページ/画像の読み込みが終了した時
unload : ほかのページに移動するとき
```

###マウス関係

```
click : クリック時
dbclick : ダブルクリック時
mousedown : マウスボタンを押したとき
mouseup : マウスボタンを離したとき
moousemove : マウスポインターが移動した時
mouseover : マウスポインターが要素に乗った時
mouseout : マウスポインターが要素から外れた時
mouseenter : マウスポインターが要素に乗った時
mouseleave : マウスポインターが要素から外れた時
contextmenu : コンテキストメニューが表示される前
```

要素がネストしている場合に注意！
mouseover/mouseroutは親要素から子要素への出入りで反応する。
mouseenter/mouseleaveは親要素から出ない限り反応しない。

###キー関係

```
keydown : キーを押した時
keypass : キーを押している時
keyup : キーを離した時
```

###フォーム関係

```
change : 内容が変更されたとき
reset : リセットボタンが押されたとき
submit : サブミットボタンが押されたとき
```

###その他

```
resize : 要素のサイズを変更した時
scroll : スクロールした時
```

#イベントドリブンモデル(イベント駆動型モデル)
イベント駆動型モデルをなすためには、

1. どの要素で発生したのか
2. どのイベントが発生したのか
3. どのハンドラー/リスナーに関連付けるか

を定義しておく必要がある。
javascriptでは3の関連付けを行うために以下の方法を提供している。

1. タグ内の属性として宣言する
2. 要素オブジェクトのプロパティとして宣言する
3. addEventListenerメソッドを使う

#タグ内の属性として宣言する
一番シンプルな実装方法。宣言方法は

```
<タグ名 onイベント名="Javascriptのコード" />
```
となる。一般的にはコードを直接書くのではなく関数を別で定義して呼び出す形となる。

```html:sample.html
<input type="text" value="" onClick="on_click()" />
```

```javascript:sample.js
function on_click() {
 alert('クリックされました！')
}
```
なるべく、htmlファイルとjsファイルで分けたほうが良い。

##要素オブジェクトのプロパティとして宣言する
htmlファイルには一切書かず、jsファイルで設定する方法。

```javascript:sample.js
obj.onEvent = function() {
 //コード
}
 //obj : windowオブジェクトもしくは要素オブジェクト
 //Event : イベント名

obj.onEvent = func
 //func : 関数の定義はべつにしてある場合
```

関数の定義をその場でするか、別にしてあるかの違いで二種類の書き方がある。

```html:sample.html
<button id="btn" value="">ボタン</button>
```
```javascript:sample.js
//windowがロードされたときにイベントハンドラーを定義
window.onload = function() {
 document.getElementById("btn").onclick = function() {
  window.alert("ボタンがクリックされました！")
 }
}
```
この書き方には注意点が３つある。
１つ目は、onClickのようにイベント名を大文字にするのではなく、onclickのように小文字にする必要があるということ。
２つ目は、プロパティとして登録するのは関数オブジェクトである必要があるため、window.load = get のように関数呼び出しにしてはいけない。
３つ目は、要素を取得する場合、window.loadの配下ではないといけない。ページが読み込まれる前に探してしまう場合がある。

##addEventListeneメソッドで宣言する
onClickのようなイベントハンドラーでは、「同一の要素/同一のイベントに対して複数のイベントハンドラーを紐づけられない」という問題があります。
ここで登場するのが、イベントリスナーです。イベントリスナーは「同一要素の同一イベントに対して、複数のイベントハンドラーを紐づけできるイベントハンドラー」です。
イベントリスナーを登録するのは、addEventListenerの役割です。

```javascript:sample.js
elem.getElementById(type, listener, capture)
 //elem : 要素オブジェクト type : エベントの種類
 //listener : イベントに対して実行すべき処理
 //capture : イベントの方向
```
で実装することができる。

```html:sample.html
<input id="btn" type="button" value="ダイアログ表示" />
```

```javascript:sample.js
//ページがロードされたタイミングで処理しなさい
document.addEventListener('DOMContentLoad', function() {
 document.getElementById('btn').addEventListener('click', function() {
  window.alert('ボタンがクリックされました')
 }, false)
}, false)
```

ここで使われている、onloadイベントハンドラーはコンテンツ本体とすべての画像がロードされたところで実行、DOMContentLoadedイベントリスナーはコンテンツ本体がロードされたところで実行、という違いがある。
画像が使われているというような特別な理由がない限り、DOMContentLoadedイベントリスナーで表すのが基本となっている。

#参考資料
山田祥寛様　「javascript本格入門」
Jupyter学習ノート_006

##データを地図に見る
 [google colab](https://colab.research.google.com/)にデータを地図上で表示するライブラリ[folium](https://github.com/python-visualization/folium/)を使ってみる。

 - サンプル１（東京駅の地図を見る）
   - parm1: location[緯度, 経度]
   - parm2: zom_start=18 (0から18まで拡大／縮小可能です）
 
```folium_01.py
import folium
map_ = folium.Map(location=[35.681384, 139.766073], zoom_start=18)
map_
```
- 実行結果
![folium_01 result](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/45969660-d279-45b0-f35b-e5298ff2564a.png)

- サンプル２（京急線の駅をマックする）
 
```folium_02.py
import folium

#京急線の泉岳寺〜横浜までの緯度と経度を定義する
kk_ekis = [
           ['泉岳寺',35.638692,139.74002],
           ['品川',35.630152,139.74044],
           ['北品川',35.622716,139.739152],
           ['新馬場',35.61762,139.741366],
           ['青物横丁',35.609351,139.742905],
           ['鮫洲',35.605144,139.742547],
           ['立会川',35.598453,139.738803],
           ['大森海岸',35.587695,139.735465],
           ['平和島',35.579074,139.734996],
           ['大森町',35.572622,139.732169],
           ['梅屋敷',35.567042,139.728341],
           ['京急蒲田',35.560685,139.723731],
           ['雑色',35.549911,139.715199],
           ['六郷土手',35.540893,139.707789],
           ['京急川崎',35.532833,139.700896],
           ['八丁畷',35.523113,139.691488],
           ['鶴見市場',35.51783,139.686592],
           ['京急鶴見',35.50729,139.678098],
           ['花月園前',35.500413,139.67301],
           ['生麦',35.495297,139.666969],
           ['京急新子安',35.487106,139.65554],
           ['子安',35.484959,139.645635],
           ['神奈川新町',35.481462,139.640158],
           ['仲木戸',35.477312,139.634489],
           ['神奈川',35.471399,139.627467],
           ['横浜',35.466188,139.622715]]

#駅ごとのマックを地図につける
for kk_eki in kk_ekis:
    folium.Marker([kk_eki[1], kk_eki[2]], popup=kk_eki[0]).add_to(map_)   
map_
```
- 実行結果  
![kk_ekis](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/6bb81c09-3f4b-e79b-e782-34efbe019358.png)
lambda

```py:先頭を大文字に1
l = ['Apple', 'banana', 'orange', 'Strawberry', 'cherry']

def change_words(func, words):
    for word in words:
        print(func(word))

def capit_func(word):
    return word.capitalize()

change_words(capit_func, l)
```

```:先頭を大文字に1の実行結果
Apple
Banana
Orange
Strawberry
Cherry
```

capi_func関数は、引数wordの先頭を大文字にする関数である。
これをlambdaを使えば、コード量を減らすことができる。

```py:先頭を大文字に2
l = ['Apple', 'banana', 'orange', 'Strawberry', 'cherry']

def change_words(func, words):
    for word in words:
        print(func(word))

capit_func = lambda word: word.capitalize()

change_words(capit_func, l)
```

わざわざ、
capit_funcを定義しないで、
change_words関数の引数に直接書く事も可能で、
更にコード量を減らすことが可能である。

```py:先頭を大文字に3
l = ['Apple', 'banana', 'orange', 'Strawberry', 'cherry']

def change_words(func, words):
    for word in words:
        print(func(word))
        
change_words(lambda word: word.capitalize(), l)
```

このlambdaは、
ファンクションがcapit_func関数だけでなく、
複数ファンクションが必要な場合に威力を発揮する。

```py:複数ファンクション
l = ['Apple', 'banana', 'orange', 'Strawberry', 'cherry']

def change_words(func, words):
    for word in words:
        print(func(word))

change_words(lambda word: word.capitalize(), l)
change_words(lambda word: word.lower(), l)
```

```py:複数ファンクションの実行結果
Apple
Banana
Orange
Strawberry
Cherry
apple
banana
orange
strawberry
cherry
```

もし、
lambdaを使わなかったら、

```py:複数ファンクション2
l = ['Apple', 'banana', 'orange', 'Strawberry', 'cherry']

def change_words(func, words):
    for word in words:
        print(func(word))
        
def capit_func(word):
    return word.capitalize()

def low_func(word):
    return word.lower()
    
change_words(capit_func, l)
change_words(low_func, l)
```
と書かねばならない。
capit_func関数とlow_func関数の2つの関数を定義する事が必要となる。
Gnome-tweaks と xmodmap は併用できなかった

# 目的

無変換 → Ctrl

# 方法

xmodmapに追加する

```
clear control
[...]
!keycode 102 = Muhenkan NoSymbol Muhenkan
keycode 102 = Control_L NoSymbol Control_L
[...]
add control = Control_L Control_R
```

# エラー

```
$ xmodmap ~/.Xmodmap 
X Error of failed request:  BadValue (integer parameter out of range for operation)
  Major opcode of failed request:  118 (X_SetModifierMapping)
  Value in failed request:  0x17
  Serial number of failed request:  260
  Current serial number in output stream:  260
```

# 解決法

Gnome-tweaksで、CapslockキーをShiftと同時押しをする設定をしていた。

Gnome-tweaksの設定を解除したら、xmodmapの設定が反映されるようになりました。

# あとがき

ubuntuのキーマップを変えるのはxmodmapが一番楽だと思う。

というか、xkbの設定いじったり、xkeysnailだったり、いろんな方法があるけど、やりたいことがシンプルならxmodmapが良いと思いました。
Web系案件に携わって思ったこと

#前書き
Web系の案件に1年半関わって入る前にイメージしていたものと、今思うことを備忘録としてまとめておきます
あくまで個人の主観です

#1個前の現場(いわゆるSier)
- 誰も技術に興味がなく、いかに仕事として開発を終わらせるかのみを考える
- 設計書に書かれている通りにコーディングをする
- 設計書が間違っていたら記載者に確認、記載者は上に、そのまた上に確認で時間がかかる
- テストは事細かに仕様書を書いて、膨大な人の数でゴリ押す
- 納期が最初に決まって、その後に要件が決まる

#入る前のイメージ
- 新しい技術をガンガン取り入れている
- テストは自動化され一瞬
- リリースまでのフローが短く速い
- サービスに直接関係しない無駄なことはしない
- エクセル方眼紙は存在しない

#実際に入った直後に感じたこと
- 新しい技術を使ってみようという心意気はあるが、実際にサービスとして有用なのかは疑問
- 自動テストはあるが、内容に関しての決まりがなくレベル感バラバラで実際に何を書けばいいのかわからない
- 開発者にかなり近い立場の人がリリース承認かつ実行権を持つために、かなり速い
- サービスに直接関係しない無駄なことをしたくないから実際にしない
- エクセル方眼紙は存在しなかった

#予想していなかったが強く感じたこと
- 技術志向の人が多く、他人には興味が無い
- そのためにマネジメント業を行うことを皆嫌がる
- 結果、全ての知見が頭の中にしかない
- 新規入室者は状況が全く掴めずキャッチアップが大変


#自分の中でのプラス経験
- gitの使い方の取得(今までチーム開発で使ったことなかったので、PRすら知りませんでした。。)
- わからないことを検索を駆使して独力で解決する経験を積んだ
- 技術志向の人達に興味や日常の習慣を垣間見ることができた
- アジャイルでの開発のフローの経験
- 本番機を触って運用する機会を得た
- 錯綜している情報をまとめて残すことができた
- 小さいプロジェクトだが調査から開発までを一気通貫で行えた


今思いつくことをざっと書きました。
また追記修正します。
macOSにMinikubeをインストール

Kubernetesを勉強するためにmacOSにMinikubeをインストールしようと、「[Minikubeのインストール](https://kubernetes.io/ja/docs/tasks/tools/install-minikube/)」にしたがってインストールしようとしたが、以下のエラーでインストールできなかった。


```
$ brew cask install minikube
...（中略）...
Error: Cask 'minikube' is unavailable: No Cask with this name exists.
```

調べたら、いつの間にか以下のPRでインストールコマンドが変わっていました。
[change minikube install cmd on macOS](https://github.com/kubernetes/website/pull/17296)

```
$ brew install minikube
...（中略）...
Bash completion has been installed to:
  /usr/local/etc/bash_completion.d

zsh completions have been installed to:
  /usr/local/share/zsh/site-functions

$ minikube version
minikube version: v1.6.2
commit: 54f28ac5d3a815d1196cd5d57d707439ee4bb392
```

無事MinikubeをmacOSにインストールできました。
JavaScript で現在開いているページのドメイン・ホスト名を取得する

JavaScript で、現在開いているページのドメイン・ホスト名を取得する。

## 例

- `Document`インターフェイスの`domain`プロパティを利用して取得する。

```js
const domain = document.domain;
```

- `location`オブジェクトの`host`プロパティを利用して取得する。

```js
const domain = location.host;
```
レビュー可能な状態になったらコメントする GitHub Actions


現状の GitHub の通知だと、下記のアクション（プルリクエストをレビュー可能なステータスへ変更するアクション）は他人に通知されません。

- Draft pull request を通常のプルリクエストへ変更する（[Ready for review]ボタンの押下）
- プルリクエストのタイトルから「WIP」または「wip」を外す
    - Draft pull request を利用しない旧来の運用をしている場合
    - 要はプルリクエストのタイトルや説明文の変更は他人へ通知されない

<img width="800" alt="スクリーンショット_2020-01-12_22_24_36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35733/40479797-f3d2-1804-337f-ef922e7599c8.png">

準備できたよ〜と自分でコメントでもすればいいのですが（コメントは他人に通知される）、忘れる場合もあったり毎回手間であったりするので、そういうものは自動化してしまいましょう。これを実現する GitHub Actions は次のとおりです。

```yml:.github/workflows/comment-ready-for-review
name: pull request CI

on:
  pull_request:
    types: [ready_for_review, edited]

jobs:
  comment:
    name: Comment ready for review
    runs-on: ubuntu-18.04
    if: (contains(github.event.pull_request.title, 'wip') == false && github.event.pull_request.draft == false) && (github.event.action != 'edited' || (github.event.action == 'edited' && contains(github.event.changes.title.from, 'wip') == true))
    steps:
      - name: Run GitHub API
        run: |
          curl -X POST \
               -H "Content-Type: application/json" \
               -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
               -d "{ \"body\": \"Ready for review :rocket:\" }" \
               https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments
```

`if` が結構 長くなってしまっていますが、`(` `)` で複雑な論理グループ化をしても正しく動いてくれます。

このアクションが動くと次のようにプルリクエストへコメントが追記されます。

<img width="800" alt="スクリーンショット 2020-01-12 22.32.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35733/301094bf-d052-053b-4891-750e6555789d.png">
参考リンク集

# 参考リンク集
参考リンク集です。


## 目次
* [1. Qiita投稿関連](#1-qiita投稿関連)

---
### 1. Qiita投稿関連
[markdown記法について](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)
Debian with Raspberry Pi DesktopとRaspbian

Debian with Raspberry Pi Desktopは、 WindowsやMac、仮想マシンなどにインストールして使うためのもの。
https://www.raspberrypi.org/downloads/raspberry-pi-desktop/


Raspbianは、SDカードにインストールして使うRaspberry Piでデスクトップを使うためのもので、インストールの仕方が違います。
https://www.raspberrypi.org/downloads/raspbian/

私は、この違いに気がつかず、ダウンロードしたRaspbianのzipファイルを解凍して出来るimg形式のファイルをISO形式に変換しないといけないのかなと調べるなど混乱していました。

私は、Raspberry Pi（ラズベリーパイ）をまだ所有していないです。
早くRaspberry Pi（ラズベリーパイ)を購入して、色々試したいと思っています。

なんで、Raspberry Pi（ラズベリーパイ）を持っていないのに、このOSに興味を持ったかというと、インストールするマシンのディスク容量を小さく出来るからです。
私は、仮想マシンで作業することがあるので、ホストのパソコンに負担をかけないように、軽いOSを使いたいと思い始めました。
そして、このDebian with Raspberry Pi Desktopを知りました。

MacBookAirにインストールしているvirtualboxを使って仮想マシンを作り、試したいと思います。

この記事は、とても参考になりました。
https://qiita.com/mt08/items/8c5fc9c754b5eeee447c

私の場合virtualboxの拡張CD-ROMのパスは、このようになりました。

/media/cdrom1/VBoxLinuxAdditions.run

私は、virtualboxのクリップボードの機能が上手く機能しなかったので、目的のファイルで、右クリックして、パスのコピーを使いました。
そして、ターミナルで、参考にしたページで紹介されていたコマンドを使いインストールしました。

```
sudo bash /media/cdrom1/VBoxLinuxAdditions.run
```

それから、仮想マシンを作るときのディスクの要領は、32GB位で作った方が良さそうです。
OSのインストール終わると、空き容量が7GB位に減っていたので。
何かアプリをインストールしたり、プログラミングしたりするなら、32GB位はあった方が良いと思いました。
AWS AmplifyのAuth.signUpでNoUserPoolError: Authentication Error

# 前提
AWS Amplifyでamplify add authした後に、Auth.signUp呼んだらエラー起きた場合。

# エラー内容
<pre>ConsoleLogger.js?36de:84 [ERROR] 59:18.392 AuthError - 
            Error: Amplify has not been configured correctly.
            This error is typically caused by one of the following scenarios:

            1. Make sure you're passing the awsconfig object to Amplify.configure() in your app's entry point
                See https://aws-amplify.github.io/docs/js/authentication#configure-your-app for more information
            
            2. There might be multiple conflicting versions of aws-amplify or amplify packages in your node_modules.
                Try deleting your node_modules folder and reinstalling the dependencies with `yarn install`
        
ConsoleLogger._log @ ConsoleLogger.js?36de:84
ConsoleLogger.error @ ConsoleLogger.js?36de:150
AuthError @ Errors.js?13ca:41
NoUserPoolError @ Errors.js?13ca:50
AuthClass.rejectNoUserPool @ Auth.js?bf82:1795
AuthClass.signUp @ Auth.js?bf82:202
onclick1 @ App.vue?234e:21
invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854
invoker @ vue.runtime.esm.js?2b0e:2179
original._wrapper @ vue.runtime.esm.js?2b0e:6917</pre>
<pre>Errors.js?13ca:34 Uncaught (in promise) NoUserPoolError: Authentication Error
    at NoUserPoolError.AuthError [as constructor] (webpack-internal:///./node_modules/@aws-amplify/auth/lib-esm/Errors.js:39:24)
    at new NoUserPoolError (webpack-internal:///./node_modules/@aws-amplify/auth/lib-esm/Errors.js:55:28)
    at AuthClass.rejectNoUserPool (webpack-internal:///./node_modules/@aws-amplify/auth/lib-esm/Auth.js:1806:31)
    at AuthClass.signUp (webpack-internal:///./node_modules/@aws-amplify/auth/lib-esm/Auth.js:213:25)
    at VueComponent.onclick1 (webpack-internal:///./node_modules/cache-loader/dist/cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/App.vue?vue&type=script&lang=js&:22:56)
    at invokeWithErrorHandling (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:1853:26)
    at HTMLButtonElement.invoker (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:2178:14)
    at HTMLButtonElement.original._wrapper (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:6907:25)</pre>

# 原因と対処
エラーメッセージが親切で、書いてあるURL
https://aws-amplify.github.io/docs/js/authentication#configure-your-app
を開いてみると、main.jsに下記を追加しろって書いてありました。

<pre>
import Amplify, { Auth } from 'aws-amplify';
import awsconfig from './aws-exports';
Amplify.configure(awsconfig);
</pre>

自分のアプリの場合、この未使用変数はエラーでダメだったので、Authを削除して、

<pre>
import Amplify from 'aws-amplify';
import awsconfig from './aws-exports';
Amplify.configure(awsconfig);
</pre>

で無事通りました。
修正後のmain.jsの全体像は下記の通りです。

<pre>
import Vue from 'vue'
import App from './App.vue'
import Amplify from 'aws-amplify';
import awsconfig from './aws-exports';
Amplify.configure(awsconfig);

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')
</pre>

# 補足
FRAMEWORK SUPPORT(Vue)のところに詳しく書いてありますね。
https://aws-amplify.github.io/docs/js/vue
Action Text(Trix Editor)でdivタグをpタグに、H1をH2に変更する方法

`/app/javascript/packs/application.js`などを編集します。

```
var Trix = require("trix")
require("@rails/actiontext")

//divなのをpタグに
Trix.config.blockAttributes.default = {
  tagName: "p",
  breakOnReturn: true
}

//h1タグをh2タグに
Trix.config.heading1.subHeading = {
  tagName: "h3"
}
```

本当は`breakOnReturn: true`で、文字を入力中にEnterを押すと新しい段落が始まるはずなのですが、私の環境ではそうなりません。わかる人がいれば教えていただきたいです

そのほかのブロック要素については、[trix/block_attributes.coffee at 3ec7bac3bcef51b134e284a2c0c79c9e9350e75b · basecamp/trix](https://github.com/basecamp/trix/blob/3ec7bac3bcef51b134e284a2c0c79c9e9350e75b/src/trix/config/block_attributes.coffee)などを見るとわかります。
AWS AmplifyでVue.jsを使いたいときに読むべきドキュメント

# AWS Amplifyとは
mBaaSサービスの一つ。Firebase使ったら負けかなと思ったので手を出してみました。が、しかし、いきなりハマったので早速記事として残しておく。

# 結論
FRAMEWORK SUPPORTという章があるが、それをいきなり読むのは地雷。
Getting Startedで手を動かしながら理解を深めたのち、次に、FRAMEWORK SUPPORT(Vue)を読むとよい。
（Getting Startedだけ読んでもダメということが分かったので、Getting Started => FRAMEWORK SUPPORTの順に読むべしという内容に変更しました。）

## Getting Started(Vue)
https://aws-amplify.github.io/docs/js/start?platform=vue
Vue.jsのプロジェクトの作り方から、AWS Amplifyの初期化、APIモジュールの追加、デプロイしてAWS環境上で動作させるところまで一通り学べる。ここから始めるのが良い。

ドキュメントのトップ
https://aws-amplify.github.io/docs/
からは、

- iOS
- Android
- Web
- React Native

の4種類しか選べない（2020/1/12現在）が、4つのうちどれかを開いた後、右上の「Select your framework」からVueを選ぶとVue対応のドキュメントが表示されます。いや分かんなかったわ・・・
まあ、mBaaSなんでWebよりネイティブってことでしょうし、Vueが英語圏ではマイナーってこともあるんでしょうね、きっと。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184997/8968834c-7769-deb4-6634-fe0e7a219c01.png)

## FRAMEWORK SUPPORT(Vue)
https://aws-amplify.github.io/docs/js/vue
もろもろ端折られているので、ここから始めるのはよくない。Getting Startedを読んだ後に読む。
pythonで16進数を10進数に変換するプログラムを作成してみた

pythonの学習のため16進数を10進数に変換するプログラムを作成してみました。

下記のようにint関数を使えば一発で変換できるので、あくまでも学習です。

```python:main.py
print(int('3b',base=16))
```
```terminal:terminal
59
```

実際に作成したコードは下記の感じです。

```python:main.py
base_num = '0123456789ABCDEF'
count_num = 3
def hex_to_int(hex_str):# HEX文字列を数値へ変換
    i = len(hex_str)
    value = 0
    digits = 0
    while i > 0:
        value += base_num.find(hex_str[i - 1]) * (len(base_num) ** digits)
        i -= 1
        digits += 1
    return value

if __name__ == "__main__":
    num_list = []
    while len(num_list) < count_num:
        input_num = input('16進数を入力してください：')
        input_num = input_num.upper()

        # HEX文字列チェック
        is_num_check = True
        for num in input_num:
            if not num in base_num:
                is_num_check = False

        if is_num_check:
            input_val = hex_to_int(input_num)
            num_list.append(input_val)
        else:
            print('16進数ではありません')

    print(*num_list)
```
入力した16進数の値を10進数に変換して返します。

内包表記を使えばもっと短く書けそうです。
macOS Keychainを使ってdotfile内のsecretsを管理しよう

### 背景
VimのプラグインでたまにAPI Tokenを必要とするのがあります。いちいちそのプラグインを使うたびにTokenをパスワードマネージャーからコピペするなんて、面倒くさすぎる！しかもdotfileにsecretsをそのまま書き込んだらどこにもアップロードできなくなります。ググったら良さげな方法が見つかったのでシェアしておきます。また他にいい方法を知ってる人がいたらコメお願いします。

### KeychainにSecretsを追加
まずはコマンドラインからKeychainに必要なSecretsを追加しましょう。（自分は試してないですが多分GUIからでもできると思います）

```
security add-generic-password -a "$USER" -s 'Qiita Api Token' -w '321hogehoge123'
```

`-s`でSecretの名前を決めます。これはのちに必要になるのでメモっておきましょう。`-a`のargumentでどのアカウントに追加するかを指定できます。そして`-w`が実際のToken(か何かしらのString)になります。



#### Secretsを環境変数に定義する
そしたらどこでも使えるように、自分の使っているshell（zsh, bash, fish...etc)のenvironment variableにexportしましょう。自分はZSHを使っていたので、このようにしました。

```zsh:~/.zshrc
export QIITA_API_TOKEN=$(security find-generic-password -s "Qiita Api Token" -w)
```

`find-generic-password`のコマンドは`-s`でSecretの名前（先ほどメモした"Qiita Api Token")を指定します。`-w`はどうやらパスワード以外のメタデータを除外するオプションっぽいです。

### .vimrcから読み込む
Environment variableは`.vimrc`からアクセスできるので、

```vim:~/.vimrc
let g:some_plugin = { user: 'hoge', password: $QIITA_API_TOKEN }
```

ってな感じで安全にdotfileからSecretsを読み込めます。以上です！

良かったところ、改善して欲しいところ、もしよかったら感想コメント残してください！ありがとうございました。

##### 参考記事：
https://coderwall.com/p/5ck85g/storing-secrets-in-the-macos-keychain
reduxでTypeError: _useSelector is undefinedと言われた時

# ある日

:sun_with_face::sun_with_face::sun_with_face:

お勉強用react製web appをいじっていたら `TypeError: _useSelector is undefined` というエラーが！ :anger: 

![20200112_220045.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73816/4591781d-dd79-b535-252f-4d398653cfe1.png)

しかし普通にbuildは通る :thinking: そしてググっても出てこない(気がする) :sob: 

↓ばーじょん↓

- `react@16.12.0`
- `react-redux@7.1.3`
- `redux@4.0.5`
- `reselect@4.0.0`

# こんなコード書いてた

:poop::poop::poop: 

```tsx
// src/containers/App.tsx
const appSelector = createSelector(
  (state: { init: AppState }) => state.init,
  init => init
)

export const AppContainer: React.FC = () => {
  const dispatch = useDispatch()
  const { loading, loaded, error } = useSelector(appSelector)
  const loadDispatcher = (): void => {
    dispatch(initOp())
  }
  return (
    <AppView
      loading={loading}
      loaded={loaded}
      error={error}
      loadDispatcher={loadDispatcher}
    />
  )
}

// src/reducers/index.ts
export default combineReducers({
  app: appReducer,
  todos: todoReducer,
  visibilityFilter: visibilityFilterReducer,
})

// src/reducers/app.ts
export const appReducer = reducerWithInitialState({
  loaded: false,
  loading: false,
  error: null,
} as AppState)
  .cases(...
```

と、こうやって書けば一目瞭然で(実際はファイルが別れているのでそこそこ時間を取られた)

- `appSelector()`では`init`から`AppState`を取得しようとしている
- `combineReducers()`では`app`に`appReducer`として結合されている

このため、上記エラーが出たようだった。

実際には`useSelector()`の引数にダミーの(`() => true`的な)selectorを使うなどしてエラー原因の特定を行った。

以上よりappSelectorを以下のように修正することでエラーは解消した。

```ts
// reselect使っている理由は特に無いです(使ってみたかった)
// この程度ならワンライナーで
// const appSelector = ({ app }: { app: AppState }): AppState => app
// の方が分かりやすいですね
const appSelector = createSelector(
  (state: { app: AppState }) => state.app,
  app => app
)
```

### 所感

:notebook_with_decorative_cover::notebook_with_decorative_cover::notebook_with_decorative_cover:

reducerが無いと`_useSelector()`が未定義状態になるのかーというのが一番の収穫:hugging:

当初`InitState`として定義していたが名前的に微妙だな思いAppStateに変えたのだが、この修正が一部漏れていた:innocent: 

selector周りでtypescriptの型チェックが微妙な感じになってしまうのは予想外で、もう少し丁寧に書くべきだったと反省:muscle:
Yoctoでrecipeの追加(ファイルのコピーのみをするレシピの追加)

# はじめに

Yoctoを使っていて、「単純にファイルをroot fsにコピーするだけのレシピってどうやって書くの？」と思って調べ、作ったレシピを記載します。

# やりたいこと

ファイル、ディレクトリをroot fsにコピーしたい。
ここで言うファイル、ディレクトリはレシピでビルドされるコードではない。
単純にコピーをしたいただのファイル。

# 環境準備

zeusを使用します。
https://git.yoctoproject.org/cgit/cgit.cgi/poky/log/?h=zeus

[参考 Release Activity](https://wiki.yoctoproject.org/wiki/Releases)

## conf/local.conf

MACHINEもなんでもいいのですが、qemu用の環境を選択。
ここではarm64環境としています。

```conf
MACHINE ?= "qemuarm64"
```

## 作成するレシピ

```
$ tree meta-mylayer/
meta-mylayer/
├── COPYING.MIT
├── README
├── conf
│   └── layer.conf
└── recipes-myhellobin
    └── myhellobin
        ├── myhellobin
        │   ├── hello.bin    <------- 適当なファイル(コピーするだけのファイル)
        │   └── hoge.tar.gz  <------- 適当なファイル(コピーするだけのファイル)
        └── myhellobin.bb
```

## hoge.tar.gz

hoge.tar.gz の中身は以下。適当なテキストファイルがあるのみ。

```
$ tree hoge
hoge
├── hoge01.txt
└── hoge02.txt
```

## 参考にしたレシピ

既存のレシピを探したら /etc にファイルをコピーするようなレシピがあったのでこちらを参考にした。
[base-files_3.0.14.bb](https://git.yoctoproject.org/cgit/cgit.cgi/poky/tree/meta/recipes-core/base-files/base-files_3.0.14.bb?h=zeus)


## myhellobin.bb


[base-files_3.0.14.bb](https://git.yoctoproject.org/cgit/cgit.cgi/poky/tree/meta/recipes-core/base-files/base-files_3.0.14.bb?h=zeus) を参考にした myhellobin.bb がこちら。

hello.bin を /home/rootに、
hoge ディレクトリを /home/root, /etc, /usr/lib にコピーするのみ。

```shell
SUMMARY = "copy files"
SECTION = "BASE"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

SRC_URI = "file://hello.bin \
file://hoge.tar.gz \
"

S = "${WORKDIR}"
INHIBIT_DEFAULT_DEPS = "1"

do_install() {
    install -d ${D}/home/root
    install -d ${D}/etc
    install -d ${D}/usr/lib

    install -m 0755 ${WORKDIR}/hello.bin ${D}/home/root
    cp -r ${WORKDIR}/hoge ${D}/home/root
    cp -r ${WORKDIR}/hoge ${D}/etc
    cp -r ${WORKDIR}/hoge ${D}/usr/lib
}

FILES_${PN} = "/"
```

最初、hogeディレクトリのコピーはtarコマンドで

```conf
    tar vxf ${WORKDIR}/hoge.tar.gz -C ${D}/home/root
```

とか書けばのかなと思ったのですが、bitbakeのデフォルトの動作(?)で勝手にworkディレクトリ内に展開されてしまうのでcpコマンドを使用。

# メモ

## INHIBIT_DEFAULT_DEPS 

https://www.yoctoproject.org/docs/latest/ref-manual/ref-manual.html#var-INHIBIT_DEFAULT_DEPS


> Prevents the default dependencies, namely the C compiler and standard C library (libc), from being added to DEPENDS. > This variable is usually used within recipes that do not require any compilation using the C compiler.
> 
> Set the variable to "1" to prevent the default dependencies from being added.

コンパイラを使用しないレシピでは 1 を設定する、ということですかね。
docsifyで数式を書けるようにする

## はじめに
[docsify](https://docsify.js.org/)は、ドキュメントWebページを作成するツールです。静的なHTMLをジェネレートするのではなく、Markdownをパースして表示するSPAのように動作します。

## セットアップ
macOS Catalina 10.15.2 で作業しました。docsifyは、npmでインストールできます。

```sh
$ npm i docsify-cli -g
```

initコマンドで、ドキュメントの雛形を作ります。

```sh
$ docsify init hoge
```

serveコマンドで、ローカルにサーバーが立ち上がりプレビューが見ることができます。もととなるMarkdownファイルが変更されると、スグに反映されます。

```sh
$ docsify serve hoge

Serving /Users/yoshoku/hoge now.
Listening at http://localhost:3000
```

## 数式を書けるようにする
数式の表示には、[docsify-katex](https://github.com/upupming/docsify-katex)を利用します。[KaTeX](https://katex.org/)は、WebページでTeXによる数式をレンダリングするライブラリで、有名なMathJaxよりも速く動作するそうです。docsify-katexは、このKaTeXをdocsifyで利用できるようにしたものです。

### セットアップ
利用は簡単で、initコマンドで作成されたindex.htmlに、scriptタグをbodyタグ内の末尾などに追加するだけです。

```html
... 省略

  <!-- CDN files for docsify-katex -->
  <script src="//cdn.jsdelivr.net/npm/docsify-katex@latest/dist/docsify-katex.js"></script>
  <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/katex@latest/dist/katex.min.css"/>
</body>
</html>
```

これでOKです。

### 数式の書き方
\$でくくります。\$が一つであれば行内に、\$が二つであれば改行して、数式をレンダリングします。

```markdown
改行する感じの数式
$$\mathbf{x}\in\mathcal{R}^{d}$$
です。

改行しない感じの数式 $\mathbf{x}\in\mathcal{R}^{d}$ です。
```

これが、以下のようになります。

<img width="514" alt="math.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212625/74cb4354-271d-8d31-9086-9f989ccbe7d3.png">

## おわりに
docsifyは気軽に書けていいですね。
【axios】HTTPリクエストメソッド別の引数一覧表（エイリアスを使用した場合）

## はじめに
PromiseベースのHTTPクライアントである**axios**のHTTPリクエストメソッド別の引数一覧表を作成しました。（エイリアスを使用した場合）

## 環境
```yaml
OS: macOS Catalina 10.15.1
Vue: 2.6.10
vuex: 3.1.2
axios: 0.19.0
```
## 結論：まとめ
[公式ドキュメント](https://github.com/axios/axios)
> For convenience aliases have been provided for all supported request methods.

axiosにはHTTPリクエストを簡単に投げられるように以下のようなエイリアスが用意されています。

```javascript:sample.js
axios.エイリアス(第1引数, 第2引数, 第3引数)
```

|エイリアス|第1引数|第2引数|第3引数|
|:-:|:-:|:-:|:-:|:-:|
|request(省略可)|config|-|-|
|get|url|(config)|-|
|delete|url|(config)|-|
|post|url|data|(config)|
|put|url|data|(config)|
|patch|url|data|(config)|

※1 `config`には、オブジェクトで任意のHTTPリクエストに必要な情報を渡すことが出来ます。
※2 `(config)`は必須ではありません。

### 使用例
```javascript
axios.request({ //axios({ のように.request省略可
  method: 'post',
  url: '/user/12345',
  data: {
    firstName: 'Fred',
    lastName: 'Flintstone'
  }
});
```

```javascript
axios.get('anyUrl')
```

```javascript
axios.post('anyUrl', anyParams)
```

## 余談：なぜ書こうと思ったか

`DELETE`リクエストにparamsを渡したい状況になり、以下コードを書きました。

```javascript:sample.js
axios.delete('/api/v1/any', anyParams)
```

その前にaxiosを使って以下`POST`リクエストを投げるコードが動いており、そのまま流用すればうまくいくと思っていたものの、`DELETE`リクエストのBodyに`params`が入ってくれませんでした。

```javascript:sample.js
axios.post('/api/v1/any/create', anyParams)
```


### 【解決】
以下のように修正して解決しました。

```javascript:sample.js
//これではanyParamsが、paramsとして認識されない
axios.delete('/api/v1/any', anyParams)
```

↓

```javascript:sample.js
//これでconfig扱いとなり、anyParamsをparamsとしてDELETEリクエストに含めて渡すことが出来るようになる
axios.delete('/api/v1/any', {params: anyParams })
```

`post`と`delete`、同じ書き方で大丈夫と考えていたので問題の対象と捉えておらず、ハマってしまい反省です:sweat_smile:

## おわりに
最後まで読んで頂きありがとうございました:bow_tone1:

どなたかの参考になれば幸いです:relaxed:

## 参考にさせて頂いたサイト（いつもありがとうございます）
- [GitHub - axios/axios: Promise based HTTP client for the browser and node.js](https://github.com/axios/axios)
【Jest】Vueのテストを書こう！

# Vueのテストを書こう！

Vue.jsのコンポーネントのテストについてナレッジを貯めていきます。(随時追加)


1. [テキスト表示についてのテスト](#テキスト表示についてのテスト)
2. [DOM要素についてのテスト](#DOM要素についてのテスト)
3. [子コンポーネントをスタブにしてテスト](#子コンポーネントをスタブにしてテスト)
4. [コンポーネントのfactory関数を定義する](#コンポーネントのfactory関数を定義する)

## テキスト表示についてのテスト

```js
import { mount } from '@vue/test-utils'
import HelloWorld from '@/components/HelloWorld.vue'

describe('HelloWorld.vue', () => {
  it('renders a HelloWorld', () => {
    const wrapper = mount(HelloWorld)

    expect(wrapper.text()).toMatch("HelloWorld!!")
  })
})
```

## DOM要素についてのテスト

```js

import { mount } from '@vue/test-utils'
import HelloWorld from '@/components/HelloWorld.vue'

describe('HelloWorld.vue', () => {
  it('renders a HelloWorld', () => {
    const wrapper = mount(HelloWorld)
    expect(wrapper.html()).toMatch("<div><p>HelloWorld!!</p></div>")
  })
})

```

## 子コンポーネントをスタブにしてテスト

`shallowMount`メソッドで子コンポーネントをスタブ（代替えの偽物）としてマウントします。
※`mount`だと子コンポーネントまですべてマウントされます。

```js
const shallowWrapper = shallowMount(Parent)
console.log(shallowWrapper.html())
```

- ログの結果

子コンポーネントが`<vuecomponent-stub />`とスタブとなって出力されています。

```html
<div><vuecomponent-stub></vuecomponent-stub></div>
```

## コンポーネントのfactory関数を定義する

一番上に`values`オブジェクトをまとめて`data`にして、新しい`wrapper`インスタンスを返すファクトリ関数を宣言します。

このようにすると、すべてのテストで`const wrapper = shallowMount（Foo）`を複製する必要がありません

```js
import { shallowMount } from '@vue/test-utils'
import Foo from './Foo'

const factory = (values = {}) => {
  return shallowMount(Foo, {
    data () {
      return {
        ...values
      }
    }
  })
}

describe('Foo', () => {
  it('welcome メッセージを描画する', () => {
    const wrapper = factory()

    expect(wrapper.find('.message').text()).toEqual("Welcome to the Vue.js cookbook")
  })

  it('usernameが7未満のときエラーを描画する', () => {
    const wrapper = factory({ username: ''  })

    expect(wrapper.find('.error').exists()).toBeTruthy()
  })

  it('usernameが空白のときエラーを描画する', () => {
    const wrapper = factory({ username: ' '.repeat(7) })

    expect(wrapper.find('.error').exists()).toBeTruthy()
  })

  it('usernameが7文字かそれ以上のとき、エラーが描画されない', () => {
    const wrapper = factory({ username: 'Lachlan' })

    expect(wrapper.find('.error').exists()).toBeFalsy()
  })
})
```

## 参考URL

[Vue.js 公式サイト](https://jp.vuejs.org/v2/cookbook/unit-testing-vue-components.html)

[vue-test-utils 公式サイト](https://vue-test-utils.vuejs.org/ja/)

[vue-testing-handbook](https://lmiller1990.github.io/vue-testing-handbook/)
➡︎より実践的な使い方がわかる
[備忘録] AWS認定資格試験テキスト AWS認定 ソリューションアーキテクト-アソシエイト（SBクリエイティブ刊）

この記事は[AWS認定資格試験テキスト AWS認定 ソリューションアーキテクト-アソシエイト（SBクリエイティブ刊）](https://www.sbcr.jp/product/4797397390/)読了時の備忘録です。
正誤に関する情報が含まれていますが、公式の正誤表に反映されるまでのラグを考慮してQiitaでも公開しています。（出版社にはこのページのURLを送付しています）

## 底本

2019年5月30日 初版第2刷発行のデータを元にした2019年7月1日 電子版第2版を底本としています。

## 気になった点

| ページ | 元の記述 | 訂正やメモ |
|:--|:--|:--|
| 28 | DyanamoDB | DynamoDB |
| 55 | 0.95USD | 前述の0.129USDより価格が上がってしまっているので0.095USD? |
| 116 | 通信の暗号化; | 通信の暗号化: (めちゃ細かい) |
| 134 | （表の2つ目の）max_execution_time | [Redshiftのドキュメント](https://docs.aws.amazon.com/ja_jp/redshift/latest/mgmt/workload-mgmt-config.html)によると`WLM タイムアウト (max_execution_time) は廃止されました。`とあるのでquery_execution_timeが正？ Redshiftを使ってないので詳細不明 |
| 161 | 拡張認証（EV)：OVより厳格な審査で認証する。アドレスバーに組織名が表示される。 | 刊行時点でも表示されない方向になっているのでそれに触れてもよいのでは、と思ったけれども、2019/09/10リリースのChrome 77、2019/10/22リリースのFirefoxで表示がなくなったので全然刊行後の最近の話だった |
| 282 | CloudWatch Log | CloudWatch Logs |