OmniAICreator/Qiita-1.07M huggingface dataset:
[100%] OddOccurrencesInArray (codility lessons)

> _Painless_
> ### [OddOccurrencesInArray](https://app.codility.com/programmers/lessons/2-arrays/odd_occurrences_in_array/)
> 奇数の要素で発生する値を見つけます。

#### タスクの説明
N個の整数で構成される空でない配列Aが与えられます。配列には奇数の要素が含まれており、配列の各要素は、ペアになっていない1つの要素を除いて、同じ値を持つ別の要素とペアにすることができます。

たとえば、配列Aでは次のようになります。

```
  A [0] = 9 A [1] = 3 A [2] = 9
  A [3] = 3 A [4] = 9 A [5] = 7
  A [6] = 9
```
* インデックス0と2の要素の値は9です。
* インデックス1と3の要素の値は3です。
* インデックス4と6の要素の値は9です。
* インデックス5の要素の値は7であり、ペアになっていない。

関数を書く：

class Solution {public int solution（int [] A）; }

上記の条件を満たすN個の整数で構成される配列Aが与えられると、対になっていない要素の値を返します。

たとえば、次のような配列Aが与えられます。

```
  A [0] = 9 A [1] = 3 A [2] = 9
  A [3] = 3 A [4] = 9 A [5] = 7
  A [6] = 9
```
上記の例で説明したように、関数は7を返す必要があります。

次の仮定のための効率的なアルゴリズムを記述します。

* Nは[1..1,000,000]の範囲内の奇数の整数です。
* 配列Aの各要素は、[1..1,000,000,000]の範囲内の整数です。
* Aの値の1つを除くすべてが、偶数回発生します。

---
#### 解く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196344/fa4d3e28-e0f5-d37b-cf1c-1df21ac75789.png)

Detected time complexity:
`O(N) or O(N*log(N))`

#### Program 
[OddOccurrencesInArray.java](https://github.com/yp2211/algorithm/blob/main/src/codility/lessons/Lesson2_Arrays/OddOccurrencesInArray.java)

```java:OddOccurrencesInArray.java
    public int solution(int[] A) {
        int goal = 0;

        java.util.Arrays.sort(A);
        for (int i = 0; i < A.length -1; i++) {
            if (A[i] != A[i + 1]) {
                goal = A[i];
                break;
            }
            i++;
        }

        if (goal == 0) {
            goal =  A[A.length - 1];
        }

        return goal;
    }
```

#### jUnit 
[OddOccurrencesInArrayTest.java](https://github.com/yp2211/algorithm/blob/main/test/codility/lessons/Lesson2_Arrays/OddOccurrencesInArrayTest.java)

#### Report
[Candidate Report: training66EE8T-EUB](https://app.codility.com/demo/results/training66EE8T-EUB/)

***
### See also: [CodilityのLessonsをすべて解く（更新中）](https://qiita.com/yp2211/items/537f733060bb0f2aba8f)
npx create-react-app で大文字の名前が使えなかった

TodoApp（Todoアプリ）を作成しようと思い、

create-react-appで環境構築をしました。


```コマンド
$ npx create-react-app TodoApp
```

しかし、こんなエラーが。。。

```
Cannot create a project named "TodoApp" because of npm naming restrictions:

  * name can no longer contain capital letters

Please choose a different project name.
npm ERR! code 1
npm ERR! path /Users/sakatsumemasato/TodoApp
npm ERR! command failed
npm ERR! command sh -c create-react-app TodoApp

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/sakatsumemasato/.npm/_logs/2020-12-19T02_39_26_426Z-debug.log

```

翻訳すると
npmの翻訳制限のため、
「TodoApp」という名前でプロジェクトを作成できないみたいです。

そこでプロジェクトの名前を全て小文字にしました。
```
$ npx create-react-app todoapp2
```

```
Happy hacking!
```

作成できました。大文字はダメで、数字はオッケーみたいですね。
【初学者向け】個人的に考えるエラーの原因特定〜解決策までの考え方

# 概要

エラーの原因特定〜解決策に至るまでの考え方についてまとめてみました。

先日エンジニアの方に、ポートフォリオのエラーを見ていただく機会がありました。
その時学んだこと、普段の体験をもとに、書いていきます。

本記事の目的は以下の通りです！

- 自分のアウトプットのため
- 同じ境遇の方にとって、何か参考になればと思ったため

前提として、
原因の特定の仕方はたくさんあると思います。
また、本記事の通り行えば、必ず原因が特定できるとも限りません。
そこはご了承ください。

なお、プログラミング初学者の方向けに書いています。（そして筆者も初学者です）
まだまだ至らぬ点もあるかもしれません。
こうした方がいいよ！などあれば、コメントをいただけると嬉しいです！

# 環境

- macOS (Catalina 10.15.7)
- ruby (2.6.5)
- rails (6.0.0)
- MySQL (5.6)

# 原因の特定方法

[前提]
ここでいう原因の特定方法とは、筆者が学んだこと、体験をもとにした方法を指します。

原因の特定方法は以下の通りです。
特定できるまで繰り返します。

1. エラー文を表示させ、悪さしている箇所を予測する。
2. 該当するコードのどこが悪さをしているか突き止める。

では、それぞれについて詳細を記載していきます。

### 1、エラー文を表示させ、どこが悪さしているか予測する。

エラー文は以下の方法で確認できます。

- ブラウザに表示される赤いやつ（うわぁとかんじるやつ）
- コンソール上で出す


コンソールでエラー文を表示させるには、以下のメソッドを使用します。

- .valid? (正しく保存されるかを確認するメソッド。trueもしくはfalseが返ってくる。)
- .errors（エラーを表示させる）
- .full_messages（エラー文を表示させる）

以下の例を用いて、上記メソッドの使い方を記載します。

**例）hogeモデルとfugaモデルで中間テーブルを組み、保存できるか確認する。**

```console
pry(main)> hoge = Hoge.create(name:"ほげ", fuga_ids:[1,2]) #変数hogeに作成した物を代入。

pry(main)> hoge.valid?                                    #hogeはバリデーションに引っかからず保存できたか確認する。
=> false                                                  #True もしくは Falseが戻り値で返ってくる。

pry(main)> hoge.errors.full_messages                      #.errors.full_messagesと使用することで、エラー文が表示される。
=> fugas is invalid
```

流れとしては、valid?で保存できるか確認する
↓
falseなら、errors.full_messagesを使ってエラー文を表示させる。
と言った感じです。

今回は、fuga is invalidというエラー文を確認できました。

### ２、該当するコードのどこが原因か突き止める。

ここでは、以下の順番で原因を突き止めます。
1. エラー文から、原因はどのあたりか予測する。
2. 仮説検証する。

それぞれについて、記載していきます。

**エラー文から、原因はどのあたりか予測する。**

まずはエラー文から、エラーの原因はおそらくこのあたりだろうな、と予測します。
イメージとしては、進む方向をざっくり決める感じです。（西に進むのか北に進むのかレベルで大丈夫です。）

個人的には、以下のどれっぽそうか考えます。

- コントローラー
- モデル
- ルーティング
- ビューらへん

先の中間テーブルの例を使って予測すると、モデルが怪しいのではないか？となります。
怪しいと考えたプロセスは以下の通りです。

1. 「is invalid」とググってみる。
2. ふむふむ、バリデーションに関する記事が多く出てくるぞ？
3. railsガイドのバリデーションのエラー文にて、「is invalid」を発見
4. バリデーションてことは、**モデル**なのかな？

と言った感じです。

**仮説検証する**

先ほど予測した箇所のどこが悪さをしているか突き止めていきます。
個人的に仮説検証は以下のように考えています。

- 原因を突き止めるまでとにかくやりまくる
- あれこれ考えすぎず、エラー文から素直に考える。
- 途中詰まってしまったら、A4用紙を使って思考を整理する。


先の中間テーブルの例を使って仮説検証するとしたら、

- そもそも、各テーブルのレコードは作成できるだろうか？（コンソールを使って作ってみる）
- バリデーションが悪さしているなら、消してみたらどうなるか？（バリデーションの記述を消してみる）

といった感じです。

ちなみに、A4用紙を使って思考を整理する方法は
[こちら](https://studyhacker.net/a4-memo)をご覧ください。

# 解決策の考え方

ここでは、解決策の考え方について記載します。

以下の考え方を使い、解決策を考えると学びました。

1. 原因を取り除く
2. 原因を迂回する


**原因を取り除く**
原因となっている箇所を変更して、取り除いてみるといった感じです。
基本的には、これをもとにして解決策を考えます。

**原因を迂回する**
原因を迂回してエラーを発生させないようにするといった感じです。
時には、原因不明のエラーが出てしまうこともあります。
そういったどうしようもないときには、原因を迂回します。

ちょっと極端ですが、
先の中間テーブルの例を使ってみると、

原因を取り除く
→例）他のやり方に変更する。

原因を迂回する
→例）validates:falseを使ってスキップする。

と言った感じです。

# さいごに

最後まで読んでいただき、ありがとうございました！

読んでいただいた方の中で、

- こうしたらうまくいったよ！
- 自分はこうしているよ！

などあればコメントいただけると幸いです！
[100%] CyclicRotation (codility lessons)

> _Painless_  
> ### [CyclicRotation](https://app.codility.com/programmers/lessons/2-arrays/cyclic_rotation/)
> 配列を指定されたステップ数だけ右に回転させます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196344/9642812d-b3b7-5541-f121-6f621fbcbcca.png)

#### タスクの説明
N個の整数からなる配列Aが与えられます。配列の回転とは、各要素が1つのインデックスだけ右にシフトされ、配列の最後の要素が最初の場所に移動されることを意味します。たとえば、配列A = [3、8、9、7、6]の回転は[6、3、8、9、7]です（要素は1つのインデックスだけ右にシフトされ、6は最初の場所に移動されます）。

目標は、配列AKをK回回転させることです。つまり、Aの各要素は右にK回シフトされます。

関数を書く：

クラスSolution {public int [] solution（int [] A、int K）; }

これは、N個の整数と整数Kで構成される配列Aが与えられた場合、K回回転した配列Aを返します。

たとえば、与えられた

    A = [3、8、9、7、6]
    K = 3
関数は[9、7、6、3、8]を返す必要があります。 3つのローテーションが行われました。

    [3、8、9、7、6]-> [6、3、8、9、7]
    [6、3、8、9、7]-> [7、6、3、8、9]
    [7、6、3、8、9]-> [9、7、6、3、8]
別の例として、

    A = [0、0、0]
    K = 1
関数は[0、0、0]を返す必要があります

与えられた

    A = [1、2、3、4]
    K = 4
関数は[1、2、3、4]を返す必要があります

と仮定する：

* NとKは、[0..100]の範囲内の整数です。
* 配列Aの各要素は、[-1,000..1,000]の範囲内の整数です。

あなたの解決策では、**正しさ**に焦点を合わせます。ソリューションのパフォーマンスは、評価の焦点にはなりません。

---
#### 解く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196344/80e317d7-4251-5fbf-1507-0f3e02f223f8.png)

#### Program
[CyclicRotation.java](https://github.com/yp2211/algorithm/blob/main/src/codility/lessons/Lesson2_Arrays/CyclicRotation.java)

```java:CyclicRotation.java
    public int[] solution(int[] A, int K) {
        int N = A.length;
        int[] B = new int[N];

        if (N > 0 && K > 0) {
            ArrayList<Integer> arrayB = new ArrayList<Integer>();

            for (int i = 0; i < N; i++) {
                arrayB.add(A[i]);
            }

            for (int j = 0; j < K; j++) {
                arrayB.add(0, arrayB.get(arrayB.size() - 1));
                arrayB.remove(arrayB.size() - 1);
            }

            for (int k = 0; k < arrayB.size(); k++) {
                B[k] = (int) arrayB.get(k);
            }
        } else {
            B = A;
        }

        return B;
    }
```

#### junit
[CyclicRotationTest.java](https://github.com/yp2211/algorithm/blob/main/test/codility/lessons/Lesson2_Arrays/CyclicRotationTest.java)

#### Report
[Candidate Report: training6HJBYX-26F](https://app.codility.com/demo/results/training6HJBYX-26F/)

***
### See also: [CodilityのLessonsをすべて解く（更新中）](https://qiita.com/yp2211/items/537f733060bb0f2aba8f)
apex:selectList等でブラウザの必須チェックを行う

`<apex:page>`に`docType="html-5.0"`をつけなかった場合をつけた場合、ブラウザでも必須チェックが行われますが、一部の標準コンポーネントはrequired属性がレンダリングされず、必須チェックが働かないようです(サーバー側のチェックは行われます)。

![VFREQUIRED_2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125621/6bbe9e45-b937-f179-6b3c-60e1f4c6216d.png)

上の図のように、下記の標準コンポーネントはブラウザで必須のチェックが行われていません。

* inputCheckbox (サーバー側の必須チェックも行われない)
* inputFile
* inputHidden (そもそもinput[type=hidden]がrequiredをサポートしていない)
* inputSecret
* selectList
* selectCheckboxes

`html-require='true'`を使用することもできません。

> コンポーネント \<apex:inputSecret\> の属性「required」は上書きできません

inputCheckbox、inputFile、inputSecret、selectListは下記のようにjavascriptでrequired属性をつけることでブラウザで必須チェックが行われるようになります。
`rerender`で入力フォームを再描画する場合、`<script>`も再描画範囲に含める必要があります。含めない場合、再描画後にrequired属性が消えてしまいます。

```html
<apex:form>
  <apex:selectList value="area" styleClass="form-required">
    <apex:selectOption itemValue="AP" itemLabel="アジア太平洋"/>
    <apex:selectOption itemValue="EU" itemLabel="ヨーロッパ"/>
    <apex:selectOption itemValue="NA" itemLabel="北アメリカ"/>
  </apex:selectList>
</apex:form>

<script>
  window.onload = function(){
    Array.from(document.getElementsByClassName('form-required')).forEach(element=>{element.required=true;};
  }
</script>
```

![VFREQUIRED_3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125621/3d8076f8-cf1f-cbf4-f300-7a84ef4b724d.png)




<!--
入力フォームの標準Visualforceコンポーネントのrequiredの挙動が気になったので調べてみました。

### HTML4
`<apex:page>`に`docType="html-5.0"`をつけなかった場合をつけた場合、ブラウザでの必須チェックは行われず、データ送信時にサーバ側でも必須チェックが行われます。

このときのエラーメッセージは、`j_id0:j_id3:inputText`のようなSFで自動で設定されるIDが使用されます。Visualforceでlabel属性を設定していれば、label属性の値で置き換えられます。

Labelを指定した場合でも不親切なUIなので、標準のrequired属性はつけずに、Apexのコントローラで必須チェックを行ったほうが良いと思います。

* `<apex:inputCheckbox>`
    * Visualforceでrequired属性をつけても必須にはなりません。
* `<apex:inputFile>`
    * label属性を指定できないため、エラーはIDで表示されます。
* `<apex:inputHidden>`
    * label属性を指定できないため、エラーはIDで表示されます。

![VFREQUIRED_1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125621/0899633c-b57a-6dfc-4488-d92135a282b2.png)

### HTML5
`<apex:page>`に`docType="html-5.0"`をつけた場合をつけた場合、一部の入力フォームでブラウザの必須チェックが行われ、データ送信時にサーバ側でもapexアクションが実施される前に必須チェックが行われます。サーバ側の必須チェックはHTML4と同等です。
ブラウザで必須チェックがされる標準コンポーネントは`<apex:inputText>`、`<apex:inputTextarea>`、`<apex:input>`です。



### 標準でブラウザ必須チェックが行われない入力フォームで必須チェックを行う
プルダウン、パスワード、ファイル添付などは標準コンポーネントではブラウザで必須チェックが行われません。また、`html-required="true"`を追加することもできません。
> コンポーネント \<apex:inputSecret\> の属性「required」は上書きできません

javascriptでrequired属性を追加します。

```html
<apex:form>
  <apex:selectList value="area" styleClass="form-required">
    <apex:selectOption itemValue="AP" itemLabel="アジア太平洋"/>
    <apex:selectOption itemValue="EU" itemLabel="ヨーロッパ"/>
    <apex:selectOption itemValue="NA" itemLabel="北アメリカ"/>
  </apex:selectList>
</apex:form>

<script>
  window.onload = function(){
    Array.from(document.getElementsByClassName('form-required')).forEach(element=>{element.required=true;};
  }
</script>
```
-->
閏年か判断するプログラム

西暦の年数および月を入力し、その月の日数を求めるプログラムを書きます。
その場合、閏年について考慮する必要があります。

閏年は以下の判断基準で決まります。

①その西暦が4で割り切れたら閏年である
②ただし、例外として100で割り切れる西暦の場合は閏年ではない
③ただし、その例外として400で割り切れる場合は閏年である

つまり、西暦2000年は閏年であり、西暦2100年は閏年ではありません。

**出力例**
1990年2月 =>"1990年2月は28日間あります"
2000年2月 =>"2000年2月は29日間あります"
2100年2月 =>"2100年2月は28日間あります"
2000年3月=>"2000年3月は31日間あります"

**模範回答**

```ruby
def get_days(year, month)
  month_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
  if month == 2
    if year % 4 == 0
      if year % 100 == 0 && year % 400 != 0
        days = 28
      else
        days = 29
      end
    else
      days = 28
    end
  else
    days = month_days[month - 1]
  end

  return days
end

puts "年を入力してください："
year = gets.to_i
puts "月を入力してください："
month = gets.to_i

days = get_days(year, month)
puts "#{year}年#{month}月は#{days}日間あります"
```

**解説**
2月以外は各月の日数が決まっています。したがって、まずは以下のようにコードを記述します。

```ruby
def get_days(year, month)
  month_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] # 各月の日数は配列で管理
  return month_days[month - 1]
end

puts "年を入力してください："
year = gets.to_i
puts "月を入力してください："
month = gets.to_i

days = get_days(year, month)
puts "#{year}年#{month}月は#{days}日間あります"
```
そして、2月の時だけ条件式を用いて出力をします。

```ruby
def get_days(year, month)
  month_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
  if month == 2 # 2月のとき
    # 閏年のときはdaysに29を代入
    # それ以外はdaysに28を代入
  else
    days = month_days[month - 1]
  end

  return days
end

puts "年を入力してください："
year = gets.to_i
puts "月を入力してください："
month = gets.to_i

days = get_days(year, month)
puts "#{year}年#{month}月は#{days}日間あります"
```
閏年か判定します。閏年の条件は3つありましたが、以下のようにまとめることができます。

① その年が4で割り切れること
② ただし、年が100で割り切れて400で割り切れない場合は閏年ではない

したがって、以下のような条件分岐を設けることができます。
[例]

```ruby
if year % 4 == 0  # 年が4で割り切れること
  if year % 100 == 0 && year % 400 != 0  # 年が100で割り切れて400で割り切れない場合
    # 閏年でない
  else
    # 閏年
  end
end
```
上記のロジックを反映させると

```ruby
def get_days(year, month)
  month_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
  if month == 2
    if year % 4 == 0  # 年が4で割り切れること
      if year % 100 == 0 && year % 400 != 0  # 年が100で割り切れて400で割り切れない場合
        days = 28 # 閏年でない
      else
        days = 29 # 閏年
      end
    else
      days = 28   # 閏年でない
    end
  else
    days = month_days[month - 1]
  end

  return days
end

puts "年を入力してください："
year = gets.to_i
puts "月を入力してください："
month = gets.to_i

days = get_days(year, month)
puts "#{year}年#{month}月は#{days}日間あります"
```
fastbookのサンプルコード(02_production.ipynb)をGoogle Colabで試してみた Part 2

[前回](https://qiita.com/kumagorou/items/6c9b92c1a9536cec888e)は画像サンプルの検索でちょっとうろたえましたが、気を取り直して、今回から何回か最初から順に探っていきます。

## ライブラリのインストールとGoogle driveのマウント
まず、最初のセルですが、fastbookのライブラリをインストールして何か環境の初期設定を行って、Google driveをマウントしているようです。

```python:
#hide
#!pip install -Uqq fastbook
import fastbook
fastbook.setup_book()
```
このまま実行してライブラリのインポートでエラーになった場合は2行目のコメントを外してもう一度実行してください。次のような表示になるので、まずURLをクリックして認証コードを取得します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407748/3fd7e3a9-fd9e-583c-8232-2f0e095c8182.png)
### 認証コードの取得
Google driveへのログインに使うアカウントの選択が求められるのでどれか選択します。
<img width="30%" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407748/df083fd4-7a5c-2930-044b-7d6f8014759e.png">
次はGoogle driveからのGoogleアカウントへのアクセスを許可します。
<img width="30%" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407748/40f5c8a1-2a14-6839-81ea-f81f33e16c12.png">
ここでやっと入力すべき認証コードが得られたので、右のアイコンをクリックしコピーして、元の画面に戻って四角いボックスの入力欄にペーストします。
<img width="30%" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407748/278fdcda-ac13-ba79-5320-6f1cb70f790e.png">
認証コードを入力すると下のように「Mounted at /content/gdrive」と表示されました。
<img width="60%" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407748/008f40da-842c-de96-9e40-392eb92ae95b.png">
そこで左上の三本筋のアイコンをクリックして、左側一番下にあるフォルダーアイコンをクリックすると「gdrive」というフォルダーが存在することが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407748/27434ecc-c7f5-1c71-e5b7-d2f1bdc7836d.png)
ここで次のシェルコマンドを実行するとカレントディレクトリがどこになっているかを確認できます。そうすると「/content」がカレントであることが分かるはずです。

```
!pwd
```
※理由はわかりませんが「gdrive」ディレクトリが表示されない場合もあります。その場合、次のシェルコマンドを実行して正常に表示されるか確認してみてください。

```
!ls gdrive
```
## Google driveへのアクセス
さらにみると、「/content」の直下には「gdrive」と「sample_data」という2つのフォルダーがありますね。そして「gdrive」の下には「MyDrive」というフォルダーがあります。次に「MyDrive」の下を見ると、そこはGoogle driveの内容があることに気づきます。Google driveにログインして確認できますから是非やってみてください。
<img width="80%" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407748/d5615481-0f07-9cae-b03e-0d89ccba0851.png">
実は、Google driveをマウントすれば、ColabのコードからGoogle driveのファイルに直接アクセスできます。たとえば「%cd gdrive/MyDrive/Colab\ Notebooks」でカレントディレクトリを移動すれば、ローカルなディレクトリにアクセスする感覚でColabから使えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407748/efd1d04d-4564-6eb6-122c-017387a000da.png)

今回はこれくらいにして、次回は画像サンプルを使った本体の部分に入っていきます。

## 関連記事
[fastbookのサンプルコード(02_production.ipynb)をGoogle Colabで試してみた Part 1](https://qiita.com/kumagorou/items/6c9b92c1a9536cec888e)
[fastbookのサンプルコード(02_production.ipynb)をGoogle Colabで試してみた Part 3](https://qiita.com/kumagorou/items/3d547cae6b41d1ea90d3)
[Colabからfastbookのサンプルコード・リポジトリをGoogleドライブにclone/pullする](https://qiita.com/kumagorou/items/4a1bccd311eb1eb62cdb)
初期化からの復帰方法（メモ）

# 最初に

####自分は初心者なので何回も初期化したのでそのときの困る点などをメモ書き程度にしていきます。

#1, 初期化する方法
左上のappleのマークをクリックします。
システム終了をクリックしていきます。
（そのときに終了していないアプリケーションがあると強制終了しますか？と聞かれるので、強制終了すると予期しないバグなどが起こるのできちんとアプリケーションを終了しときましょう。）
#2,再び電源を入れる
ここが重要です。
電源ボタンを押すとすぐに`command + R`を同時押しをする。
（同時押しをするタイミングは電源ボタンを押したと同時に押すと良いかと。）
#3,Mac os復旧の設定
![2002497C-1B4A-46D7-B67B-81EBDCB3D951.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763535/a136a721-fd7c-e488-1d97-84c88ac76d66.jpeg)
👆このような画面が表示されると思います。
（この先は起動ディスクの削除方法を知っていたらスキップしても問題なし）
このときに下から１つめにある『Disk Utility』(ディスクユーティリティー)と書かれている部分をクリックします。
![4070832D-8773-4510-A225-BFEF4C1BFED7_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763535/35a45cbd-8cfa-b6a8-e6bd-0ab845e23e43.jpeg)
このような画面が表示されると思います。
Macintosh　HDをクリックします。![BE8739E5-38E8-4223-9238-1D778168E756_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763535/dfd2091c-3861-50e4-0e31-a78bbc5ca40a.jpeg)

上の画像の消去をクリックします。そうすると、![5ADD54DD-3996-4004-9099-C6F8DECBE75C_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763535/7c81cd8c-153e-f8fc-868a-5cdedaacc9d4.jpeg)
このときフォーマットと方式は何もいじらなくて大丈夫です。
これで消去が完了です。
#4,自分が入れたいosをインストールする。
先ほどのmac os復旧の画面に戻る。
（戻り方　左上のDisk utilityをクリック　Disk utilityを終了をクリックするとよい。）
#5,基本の設定をして、終了
ここまでお疲れ様でした！！ここからは自由に設定していきましょう。

#番外編
基本の設定のその後にダウンロードすると便利かな？と思うアプリケーション
####google chrome
####vscode
####homebrew
####git

ここら辺のものはダウンロードしていても悪くないかとおもいます。
Exposedで外部キー制約がないテーブルでもInner Joinしたい

KotlinのExposedでつまづいたときのお話です。
[ここ](https://github.com/JetBrains/Exposed/issues/566)を参考に。

#問題
外部キー制約がないテーブル同士を`innerJoin`で結合しようとするとエラーになってしまう
(`there is no matching primary key/foreign key pair and constraint missing`)
#解決方法
`innerJoin`メソッドではなく、`join`メソッドを使用します。
##詳細
以下のようにします。

```kotlin
UserTable.join(TodoTable, JoinType.INNER, UserTable.id, TodoTable.userId)
```
上記のコードを見ていただければ使い方は大体わかると思いますが、引数は以下のようになっています。
`(結合するテーブル、結合のタイプ、結合条件に使用するカラム１、結合条件に使用するカラム２)`
上記のコードを実行すると、以下のSQLが生成されます。

```sql
SELECT `user`.id, `user`.`name`, Todo.id, Todo.title, Todo.done, Todo.user_id FROM `user` INNER JOIN Todo ON `user`.id = Todo.user_id

```
また、5つ目の引数として、追加条件を渡すことも可能です。

```kotlin
        UserTable.join(TodoTable, JoinType.INNER, UserTable.id, TodoTable.userId) {
            UserTable.name eq TodoTable.title
        }.selectAll().toList()
```
上記を実行すると以下のようになります。

```sql
SELECT `user`.id, `user`.`name`, Todo.id, Todo.title, Todo.done, Todo.user_id FROM `user` INNER JOIN Todo ON `user`.id = Todo.user_id AND  (`user`.`name` = Todo.title)
```

#原因
Exposedの`innerJoin` `leftJoin` `rightJoin`は、使用する際にテーブル結合するテーブル同士に存在する外部キー制約にのっとった結合条件を使用するようです。つまり、以下のようなテーブルで`innerJoin`をしようとすると、

```kotlin
object UserTable : Table("users") {
    val id = uuid("id")
    val name = varchar("name", 20)
}

object TodoTable : Table() {
    val id = integer("id")
    val title = varchar("title", 50)
    val done = bool("done")
    //ユーザーテーブルへの外部キーを持つ
    val userId = uuid("user_id").references(UserTable.id)
}

//innserJoinをやってみる
TodoTable.innerJoin(UserTable).selectAll().toList()
```

以下のようなSQLを生成しようとします。

```sql
SELECT Todo.id, Todo.title, Todo.done, Todo.user_id, `user`.id, `user`.`name` FROM Todo INNER JOIN `user` ON `user`.id = Todo.user_id
```
`TodoTable.innerJoin(UserTable).selectAll().toList()`では特に条件を指定しなくとも、外部キーによる結合条件が自動的に入っていることがわかると思います。
ここで、仮に結合テーブルに外部キー制約がないと、結合条件がわからないということで`there is no matching primary key/foreign key pair and constraint missing`が発生して落ちてしまうわけですね。
[Rails] <%= link_to %>の使い方

<%= link_to %>とは 
==================
・リンクを作成できるrailsのヘルパーメソッド
・記述先はviewsファイル


使い方
=====
```言語:基本形
<%= link_to "テキスト", "リンク先のパス" %>
```

```言語:Googleリンク
<%= link_to "Google", "https://www.google.com/" %>
```
```言語:コンパイル後のコード
<a href="https://www.google.com/">Google</a>
```
ブラウザ上の結果
<a href="https://www.google.com/">Google</a>


オプション
=======
|オプション名|	機能
|---------|----------------------|
|method	  |httpメソッドの指定        |
|target	  |リンク先のウィンドウの指定    |
|class	  |スタイルシートのclassの指定|


```言語:methodオプション
<%= link_to “削除”, video_path(params[:id]), method: :delete %>
```
```言語:本当に削除しますか？ver
<%= link_to “削除”, video_path(params[:id]), method: :delete, data: { confirm: "本当に削除しますか？" } %>
```
**:classオプションの場合**
`<%= link_to "トップページ", "/", class: :top_btn %>`
このように記述すると下記のようにコンパイルされます。

`<a href="/" class="top_btn">トップページ</a>`

ブラウザ上の結果
<a href="/" class="top_btn">トップページ</a>



-----------------------------------------------------------------------------------
この記事は以下の情報を参考させていただきましました。

参考: https://pikawaka.com/rails/link_to
Lubuntuをインストールした

X205TAにLubuntuをインストールした。
本当はArchをインストールしようとしたのだけれどうまく行かなかったので、Lubuntuにした。

デスクトップ環境がLXDEからLXQtになったらしく、情報が見つからない感じ。
使い勝手は良いが、困ったときにLubuntuで探しても、LXDEとLXQtのどちらなのか? 参考になるのか? を判定する必要がある。

## インストールメディア作成

概略は以下、Windowsで行っている

- Lubuntuのインストールメディアをダウンロード
- 32bit UEFI用のブートローダーをダウンロード
- RufasでUSBメモリスティックに書き込む

基本的に https://roy.naturum.ne.jp/e3287155.html のとおりにやればよい。

Xubuntuではなく、LubuntuにしたのはWikipediaでこっちのが消費リソース少ないって書いてあったから、20.04LTSも割と最近だったので、20.10の最新と悩んで最新にした。

## インストール

LiveUSBが起動さえすれば無線も使える。
タッチパッドがつかえないので、マウスは用意しておく必要がある。
インストール画面は https://ameblo.jp/gokurakuhaze/entry-12633383409.html のスクショ通り

## タッチパッド設定

synapticsをいれると動くようになる。

```sh
sudo apt install xserver-xorg-input-synaptics
```

## キーボード

「キーボードとマウス」を開き、Keyboard Layoutで `asus_laptop`を設定する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19245/007dded9-5731-4716-cb0d-841bcf4c0bf1.png)

CtrlとCapsを入れ替えるのは、ここでは設定できなかった。
こちらは設定ファイル($HOME/.config/lxqt/session.conf)に直接書き込む

```$HOME/.config/lxqt/session.conf
[Keyboard]
layout=jp
model=asus_laptop
variant=
options=ctrl:swapcaps
```

## タッチパッドの切替

Fn + F9 でタッチパッドの切替があるが、これはうまく動かない。
synclientコマンドで切り替えることができるので、スクリプトを作って、ショートカットキーに登録する

```/usr/local/bin/x205ta_touchpad_toggle.sh
#!/bin/sh

# This Shell script is PUBLIC DOMAIN. 
# ASUS X205TA

TOGGLE=$HOME/.touchpadtoggle

if [ ! -e $TOGGLE ]; then
    touch $TOGGLE
    synclient TouchpadOff=1
else
    rm $TOGGLE
    synclient TouchpadOff=0
fi
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19245/ca81064b-ad80-1333-dea3-f6441ac63317.png)

## 日本語入力

https://report.hot-cafe.net/lubuntu-2010-11010 に従って何も考えずmozcにした。
そのうち入力をAZIKにするかも

## Chromeインストール

debファイルをダウンロードして、aptでインストール。
既定のブラウザにするのはxdg-mimeで登録するらしい

```shell
sudo apt install -y ./google-chrome-stable_current_amd64.deb 
xdg-mime default google-chrome.desktop x-scheme-handler/http
xdg-mime default google-chrome.desktop x-scheme-handler/https
xdg-mime default google-chrome.desktop text/html
```

## VSCodeインストール

debファイルをダウンロードして、aptでインストール

```shell
sudo apt install -y ./code_1.51.1-1605051630_amd64.deb
sudo apt install -y apt-transport-https
sudo apt update
```

参考 : https://qiita.com/grgrjnjn/items/85aa7cab1475bf1aea54


## ログイン画面

ディスプレイマネージャはsddmが使用されている。
テーマの変更はsddm-theme-*を探してapt等でインストールしたあと、`update-alternatives`で設定する。GUIではできない

```sh
sudo apt install sddm-theme-maldives
update-alternatives --config sddm-ubuntu-theme
```
## ロック画面 / スクリーンセーバー

スクリーンセーバーは特に不満がないけれど、ロック画面から復帰するときの画面がsddmとは全然違うので、それをあわせたいがやり方がわからない。

画面ロックを`xdg-screensaver --lock`で行うらしいのでxdg側でやるのか?
それともxscreensaver側でやるのかがわかっていない
Mac Google Chromeキャッシュをクリアしてリロードする。

# 目的

- フロントエンドの開発時にキャッシュをクリアしてブラウザのタブをリロードしたい時のショートカットを紹介する（ほぼ個人メモ）

# 方法

- リロードしたいブラウザのタブを選択した状態で「command」 + 「shift」 + 「R」を同時に押下するとキャッシュが削除されてリロードすることができる。
アプリケーションの作成方法

1．アプリケーションの作成
rails new sample_app(データベース名) -d mysql

2.GemFileを修正
gem 'bootsnap', '1.4.5', require: false

3.Database.ymlファイルにMysqlのパスワード入力

4.Railsアプリケーションに移動
cd sample_app

5.データベース作成
rails db:create


$ rails db:create
rails aborted!
Errno::ENOENT: No such file or directory - bs_fetch:open_current_file:open
bin/rails:4:in `<main>'
(See full trace by running task with --trace) 

↑
これが出た場合

1.GemFileに下記の表記を修正
gem 'bootsnap', '1.4.5' , require: false
2.tmp/cache/配下にあるbootsnapと書いてあるファイルを削除
3.bundle install
VSCode Macのショートカット キー

##はじめに

作業短縮のためにVSCode Mac版で使用できるキーボードショートカットキーをメモに取っていたのですが、ある程度溜まってきたのでまとめてみようと思います。


##カーソル・行の編集
| 動作内容　　　　       　　 | ショートカットキー              |
|:-------------------------|--------------------------:|
| 指定した行へ移動する         | control + G               |
| 前に表示していた場所に戻る     | control + -               |
| カーソルを追加する            | option + クリック           |
| カーソル行をインデント         | command + ]              |
| カーソル行をアンインデント      | command + [              |
| コメントアウトする             | command + /               |
| 選択した行を上の行と入れ替える  |   option + ↑             |
| 選択した行を下の行と入れ替える  | option + ↓               |
| 上に行を追加する   　　　　　　|  command + shift + enter |
| カーソル行を上にコピーす        | option + shift + ↑       |
| カーソル行を下にコピーする       | option + shift + ↓       |



##検索・置換
| 動作内容　　　　       　　 | ショートカットキー              |
|:-------------------------|--------------------------:|
|  ファイルを検索して開く        |command + P                |
| ファイル内を検索する          | command + F               |
| プロジェクト内を検索する        | command + shift + F      |
| 置換する                   | command + option + F      |
| すべて置換する              | command + option + enter  |


##その他
| 動作内容　　　　       　　 | ショートカットキー              |
|:-------------------------|--------------------------:|
|  サイドパネルの表示/非表示     |command + B               |
| ファイルを新規ウインドウで開く    | command + O              |
| ターミナル        　　　　　　| control + shift + @      |
| 設定                   　　|　command + ,|

##おわりに
まだまだショートカットキーを覚えられていないので、どんどん覚えていき時間短縮を目指します。
また、今後も便利なショートカット キーがあれば追加していきたいと思います。
【MySQL】Nuxt.jsにSequelizeを導入時遭遇したDB周りのエラー【Nuxt.js】

Nuxt.js,Vuetifyにてスクレイピングアプリを作成中。
MySQLを導入し、Node.jsのライブラリであるSequelizeを導入している際のエラー。
どちらかというとSequelizeというよりはMySQLのエラーなのですが、備忘録かつ一助となればと思い、記します。
※**Sequelize**...MySQL等のDBに簡単にアクセスできるNode.jsのライブラリ。


# エラー１　「ERROR: connect ECONNREFUSED 127.0.0.1:3306」
```ruby:local
$ npx sequelize-cli model:generate --name User --attributes name:string,itemName:string,price:integer,material:string,brandStyleId:string

$ New model was created at /Users/../Desktop/nuxt-scraping-app/models/user.js .
New migration was created at /Users/../Desktop/nuxt-scraping-app/migrations/20201218120926-create-user.js .
```

上記によりテーブルとカラムを正常に作成した。そして、

```ruby:local
$ npx sequelize-cli db:migrate
```

によりmigrateしようとすると、

```ruby:local
ERROR: connect ECONNREFUSED 127.0.0.1:3306
```
接続エラーが発生。

```ruby:local
$ mysql -u root -D database_development -p -P 3306
$ ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (38)
```

?...なぜか接続できない。
初歩的なミスに気づく。そもそもMySQLサービスをスタートさせていない。

```ruby:local
$ sudo mysql.server start
Starting MySQL
 SUCCESS! 
```

#エラー2　 「ERROR: Access denied for user 'root'@'127.0.0.1' to database 'database_development」
こうしてようやくMySQLにログインできたので、再度migrate実行。

```ruby:local
$ npx sequelize-cli db:migrate
$ ERROR: Access denied for user 'root'@'127.0.0.1' to database 'database_development'
```

接続が拒否される。何故だろうと思ったが、以前に同じようなエラーに遭遇し、権限関連のエラーと判定したため権限確認。

```ruby:local
mysql> show grants for root@'127.0.0.1';
+------------------------------------------+
| Grants for root@127.0.0.1                |
+------------------------------------------+
| GRANT USAGE ON *.* TO `root`@`127.0.0.1` |
+------------------------------------------+
1 row in set (0.00 sec)
```
config.jsonのユーザー・hostで権限確認するとやはりアクセス権限が付与されていないことを確認。

```ruby:local
mysql> GRANT ALL PRIVILEGES ON database_development.* TO root@'127.0.0.1';# 当該DBへのアクセス権限付与
mysql> show grants for root@'127.0.0.1';
+------------------------------------------------------------------------+
| Grants for root@127.0.0.1                                              |
+------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `root`@`127.0.0.1`                               |
| GRANT ALL PRIVILEGES ON `database_development`.* TO `root`@`127.0.0.1` |
+------------------------------------------------------------------------+
2 rows in set (0.00 sec)
```
アクセス権限が付与されたことを確認。これでOKなはず！

```ruby:local
$ npx sequelize-cli db:migrate
Sequelize CLI [Node: 14.4.0, CLI: 6.2.0, ORM: 6.3.5]

Loaded configuration file "config/config.json".
Using environment "development".
== 20201218120925-create-user: migrating =======
== 20201218120925-create-user: migrated (0.023s)
```
Done！

# 学び
MySQLでのエラーは権限関連が多いと感じました。実務に駆け出したばかりのエンジニアは自分を含め、DB周りに弱いと聞きます。積極的にMySQLに触れていくことで、慣れると考えます。実務に入る前に再度MySQLに慣れていくことが必要だと感じました。
fatal: remote origin already exists. の対処法

## 背景
既存のレポジトリにあるファイルを、他のレポジトリにpushしようとした時に、このエラーが出ました。

## 解決方法

```bash
git remote rm origin
```

これで、新しいレポジトリ に、git remote add, pushができるようになります。
アナログ回路 その11

# 概要

circuit sandboxをplunkerでホスティングした。
アナログ回路をシュミレーションで、説明してみる。

# オペアンプ・反転増幅回路

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/1b0b624b-8da1-2371-eac4-b3a78e1e513a.jpeg)


# 結果

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/59002ed8-fb8a-be6e-cb7b-fa3931fe4107.jpeg)

# 説明

増幅率は、R1 ÷R2で1.5倍です。

# 成果物

https://embed.plnkr.co/plunk/5EJGpdntKlnWxIR2


以上。
500 Internal Server Errorとは何か・解決方法

#プログラミング勉強日記
2020年12月19日
検証ツールで500 Internal Server Errorが表示されて正しく表示されない状況に陥ったので、500 Internal Server Errorの意味と解決方法を簡単に紹介する。

#500 Internal Server Errorとは
　簡単に言うと、サーバー側に問題があるときに表示されるエラーである。プログラム自体へのアクセスはできるが、実行ができない・処理が完了しない場合に発生するエラーで、考えられる要因として以下のようなものがある。

- CGIやPHPの同時接続数が多くなり、アカウント単位のリソース制限となっている
- スペルミス等のプログラムの記述内容に誤りがある
- .htaccessの記述に誤りがある
- パーミッションに誤りがある

([参考文献](https://support.xserver.ne.jp/faq/service_hp_trouble_500.php))

#解決方法
　詳しいエラーは、ログファイルからエラーログで確認するとわかるので、エラーログをみて確認する。スペルミスのようなプログラムの記述内容に誤りがあることが大半だと思う。
　私の場合は、IntelliJ IDEAを利用していて起きたエラーだったのでその解決方法を残しておく。

##IntelliJ IDEAを使用してGradleプロジェクトを扱っている場合
　私の場合は、WindowsでIntelliJ IDEAを使用するときに文字化けを直すために`File`→`Settings`メニューから`Build and run using`と`Run tests using`を`IntelliJ IDEA`にしていた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/a7d66e9d-39ed-aa78-4b77-14ddaf38f39d.png)

　この設定が500 Internal Server Errorを引き起こしていた。なので、デフォルトの`Gradle`に戻すことでエラーは解消された。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/a7ede2ae-b77e-8c1e-3d24-040639223b87.png)


#参考文献
[「500 Internal Server Error」というエラーが表示されてホームページが見られません。](https://support.xserver.ne.jp/faq/service_hp_trouble_500.php)
[JQuery Ajax Postで500内部サーバーエラーが発生する](https://www.it-swarm-ja.tech/ja/javascript/jquery-ajax-post%E3%81%A7500%E5%86%85%E9%83%A8%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%8C%E7%99%BA%E7%94%9F%E3%81%99%E3%82%8B/967049070/)
VSCodeでのjupyterとvimの共用

#拡張機能、jupyterとvimを使おうとしたが、
escキーが衝突する。jupyterではセルのエディットモードからコマンドモードに変わる機能が、vimではノーマルモードに変わる機能が割り当たっている。そのままではvimのコマンドが優先されて、jupyterのエディットモードから抜けられない。
そこでsetting.jsonに次のコードを追加する。

```javascript:setting.json
"vim.normalModeKeyBindings": [
        {
            "before": ["<Esc>"],
            "after":[],
            "commands":[
                {
                    "command":"notebook.cell.quitEdit",
                    "when":"vim.active && vim.mode == 'Normal'"
                }
            ]

        }
    ]

```
これでinsert-modeから2回Escを押すと、jupyterのコマンドモードに移行できる。
#こんなことを書きつつ
vimは全然わかっていない。すべてキーボードで完結したいと思って勉強中。
#参考にしたURL
https://github.com/VSCodeVim/Vim/issues/5238
アナログ回路 その10

# 概要

circuit sandboxをplunkerでホスティングした。
アナログ回路をシュミレーションで、説明してみる。

# オペアンプ・非反転増幅回路

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/1fa0a2c4-9e1d-9bf4-5a4a-bf69b7ace6ca.jpeg)


# 結果

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/94f5d3d7-ce77-51ae-0ce0-1059369ce695.jpeg)


# 説明

増幅率は、（R1+R2）÷ R2で、1.5倍です。


# 成果物

https://embed.plnkr.co/plunk/VwFe39LmizNlUymP


以上。
RDS ProxyをsharedVPC上で作る時にハマった話

この記事は [**セゾン情報システムズ Advent Calendar 2020**](https://qiita.com/advent-calendar/2020/sisco) 19日目の記事です。

#2021/8/16追記

本件の事象ですが、
2021年8月6日のアップデートにより解消されました!
この記事は忘備として残させていただきます。


https://aws.amazon.com/jp/about-aws/whats-new/2021/08/amazon-rds-proxy-created-shared-virtual-private-cloud-vpc/

#はじめに



RDS ProxyをsharedVPCより、サブネット共有されたAWSアカウントから作成しようとした際につまったお話です。

以後、
sharedVPCより、**サブネット共有されている**AWSアカウントを**子アカウント**。
sharedVPCより、**サブネット共有している**AWSアカウントを**親アカウント**と呼びます。

RDSproxy公式ドキュメント
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/rds-proxy.html#rds-proxy.howitworks
#つまったところ

結論からお話すると、
子アカウントからRDSproxyを作成することはできません。
子アカウントからの作成を試みても、画像のエラーが表示されます。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500436/eee319a5-cc48-bb76-c519-3eec4981448e.png)
>DBプロキシ　作成のリクエストが失敗しました。
DBProxy cannot be created in shared VPC

IAMポリシーを中心にいろいろと見てみましたが原因がわからず、AWSサポートへ確認しました。

AWSサポートからの回答は、
所有者アクセス権限を持った親アカウントからのみ作成できる内部制約が存在するとのこと。
謎が解けました。

ちなみに、
2020/12/18現在、[AWS公式ドキュメント](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/rds-proxy.html#rds-proxy.howitworks)にsharedVPC上の制約を記述されてはおりません。
ご注意くださいませ。

#対応したこと
親アカウントにリソースを立て、子アカウントから利用可とする方針にしました。

###1.RDSproxy関連リソースを親アカウント上に作成する。
RDSproxyから接続させたいDB・シークレット・CMKを親アカウント上に作成しました。
IAMロールやセキュリティグループも必要であれば事前に用意しましょう。
※RDSproxy作成時のパラメータとして選択可能とするため。



###2.RDSproxyを親アカウント上から作成する。
通常通り、AWSコンソールからRDSproxyを作成してみました。

###3.子アカウントからシークレットを使用できるようにする。
このままでは子アカウントからシークレットを利用できないため、追加設定が必要です。
下記リンクより、シークレットとCMKのポリシーを改修しました。
[**AWS アカウント間で AWS Secrets Manager のシークレットを共有するにはどうすればよいですか?**](https://aws.amazon.com/jp/premiumsupport/knowledge-center/secrets-manager-share-between-accounts/)

##まとめ
上記3ステップにて、RDSproxyを利用できるようになりました。
最後に、
2020/12/18現在、RDSproxy自体にタグをつけることができません。
コスト配分タグ等、管理を別途考慮する必要がありそうです。

##その他参考
RDS ProxyがGAされました！！
https://dev.classmethod.jp/articles/rds-proxy-ga/
祝GA‼︎【Go】Lambda + RDS 接続にRDS Proxyを使ってみた
https://qiita.com/maika_kamada/items/6eb6a40c17b4b8995acb
Dockerよく使うコマンド

コンテナに入る

```
$ docker-compose exec #{container} bash 
```


停止・削除

```
#全コンテナ停止
docker stop $(docker ps -q)
#全コンテナ削除
docker rm $(docker ps -q -a)
#全イメージ削除
docker rmi $(docker images -q)
```

コンテナファイルローカルにコピー

```
docker cp 【コンテナID】:アプリ名/ディレクトリ名/ファイル名 コピーしたいディレクトリ名/つけたいファイル名
```

ビルド

```
docker build [ -t ｛イメージ名｝ [ :｛タグ名｝ ] ] ｛Dockerfileのあるディレクトリ｝
```

起動

```
$ docker run [オプション] イメージ[:タグ|@ダイジェスト値] [コマンド] [引数...]

#rm:コンテナ終了時にイメージ自動削除
#name:コンテナに名前をつける
$ docker run --rm --name test -it image:tag bash
```
ホストとコンテナ間のコピー

```
docker cp (ID or コンテナ名):(コンテナ内のパス) (ホストのパス)

(ex)docker cp aabade1747be:/usr/local/apache2/conf/httpd.conf ./
```

docker volumeは同一ファイルが存在する場合上書きされる

#DockerFile
####sed
http://hydrocul.github.io/wiki/commands/sed.html

```
// abc→ABCに置換される
//sコマンド:置換
//g全行を置換する
sed　-e 's/abc/ABC/g'
```

```
// iコマンド:ファイルを標準出力せずに上書き
//eコマンド:拡張正規表現
//特定の文字列以降に追加
RUN sed　-i -r 's/;?([^\.]default_charset=).*/\1 "UTF-8"/g' /etc/php.ini
```
echo

```
// ファイル追記
RUN echo "export ORACLE_HOME=$ORACLE_HOME" >> /etc/sysconfig/httpd
```


#その他

mysql入る

```
mysql -h host -u root -pmypass
```

ターミナル別タブで開く

command + t
Nuxt.js の使い方

次のような画面を表示するまでの方法です。
![nuxt_dec1901.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/90c43bb2-fd5d-fa6e-9766-d056f7313a85.png)

インストール

```bash
sudo npm install -g vue-cli
sudo npm install -g @vue/cli-init
```

作成

```bash
mkdir sample04
cd sample04
mkdir sample04/pages
```

```json:package.json

  "name": "sample02",
  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "generate": "nuxt generate",
    "start": "nuxt start"
  }
}
```

```html:pages/index.vue
<template>
<blockquote>
<h1>Hello World!</h1>
<h2>こんにちは。</h2>
<blockquote>
        sample04
</blockquote>
<blockquote>
        Dec/19/2020 AM 10:00
</blockquote>
</blockquote>
</template>
```

nuxt のインストール

```bash
yarn add nuxt
```

起動

```bash
yarn dev
```

ブラウザーで
http://localhost:3000/
にアクセス

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

```text
$ yarn --version
1.22.17
```
Phantom.jsを使用し、Vue.jsで作成されたページにログインする

#概要
Phantom.jsを使用し、ログイン後のページでスクリーンショットを撮りたいことがあり、jQueryでフォームを埋めて、送信ボタンをクリックさせて送信する。

バリデーションエラー!!「フォームを入力して下さい。」
Value値埋めてるやん。。。なんで。。。とハマったので、書き留めておきます。

ログインページのソースコードの見るとinputタグに「v-model」とある。

なにこれ？？

Vue.jsの記法である。
v-modelは入力されたデータを入力されたタイミングで、Valueではなく別の変数？に格納している。。。とのこと。。。わからん。。
## 解決策
フォームに「打ち込んだぞー！！！！」と教えてあげる必要がある。
参考コード

```
$('input[name="email"]')[0].dispatchEvent(new Event('input'));
```



##参考コード


```
var page = require('webpage').create();
var url = 'ログインページURL'

page.open(url, function(status) {
    if(status === "success") {
　　　　　//ここはおまじない（なくても動くと思う。）
        page.includeJs("https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js", function() {
            // jqueryを使いたいので読み込み
            page.includeJs('https://code.jquery.com/jquery-3.5.1.slim.min.js', function() {
                    setTimeout(function() {
                        $('input[name="email"]').attr('value', 'メールアドレス');
                        $('input[name="password"]').attr('value', 'パスワード';
                    
                        $('input[name="email"]')[0].dispatchEvent(new Event('input'));
                        $('input[name="password"]')[0].dispatchEvent(new Event('input'));

                        var btn = document.getElementsByClassName('btn-dark')[0];
                        btn.click();
                    },3000);
                });
            });
        });
    }
    
    setTimeout(function() {
            //記念撮影
            page.render('test.png');
            phantom.exit();
    },5000);
});

```

##あとがき
ログインページがVue.jsで作られていて、ハマる。みたいなことは今後増えて来ることは間違いないので知っておいて損は無いと思います。頭の片隅にでも置いていてください。
「なんで、Phantom.jsを使ってんの？サポート切れてね？jQuery脱却しないの？」というツッコミは勘弁して下さいね。苦笑
Serverless FrameworkでNode.jsのサーバーレスAPIをGCPにデプロイしてみた

![](https://day-journal.com/memo/images/try-055_01.gif)

<br>

![](https://day-journal.com/memo/images/logo/serverless-framework.png)

<br>

この記事は、「[Google Cloud Platform Advent Calendar 2020](https://qiita.com/advent-calendar/2020/gcp)」の19日目の記事です。

### Serverless FrameworkでNode.jsのサーバーレスAPIをGCPにデプロイしてみました :tada:  

<br>

事前準備

- Serverless Frameworkの環境構築
[環境構築](https://day-journal.com/memo/serverless-framework-001)

- GCPの設定
[GCP事前準備](https://day-journal.com/memo/serverless-framework-003)

<br>

事前設定ができていれば**3コマンド**でデプロイできます！  

<br>

はじめに、Node.jsテンプレートでプロジェクトを作成します。

```shell
sls create -t google-nodejs -p sample
```

![画像](https://day-journal.com/memo/images/try-055_02.png)

<br>

次に、対象プロジェクトに移動しパッケージをインストールします。

```shell
cd sample
npm install
```

![画像](https://day-journal.com/memo/images/try-055_03.png)

<br>

作成されたプロジェクトを確認します。今回は、「serverless.yml」のみ変更します。

#### package.json

```json
{
  "name": "sample",
  "version": "0.1.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "serverless.com",
  "license": "MIT",
  "devDependencies": {
    "serverless-google-cloudfunctions": "*"
  }
}
```

<br>

#### index.js

```javascript
'use strict';

exports.http = (request, response) => {
  response.status(200).send('Hello World!');
};

exports.event = (event, callback) => {
  callback();
};
```

<br>

#### serverless.yml

```yml
service: sample

provider:
    name: google
    stage: dev
    runtime: nodejs10
    region: us-central1
    project: GCPのプロジェクト名
    credentials: ~/.gcloud/keyfile.json

frameworkVersion: '2'

plugins:
    - serverless-google-cloudfunctions

package:
    exclude:
        - node_modules/**
        - .gitignore
        - .git/**

functions:
    first:
        handler: http
        events:
            - http: path
```

対象のGCPのプロジェクト名に変更。

```yaml
project: GCPのプロジェクト名
```

<br>

プロジェクトが完成したらGCPにデプロイします。

```shell
sls deploy
```

![画像](https://day-journal.com/memo/images/try-055_04.png)

<br>

デプロイ後に、GCPのコンソールでCloud Functionsが作成されているのを確認してみます。

![画像](https://day-journal.com/memo/images/try-055_05.png)

<br>

「allUsers」を割り当ててAPIにアクセスできるように設定します。

![画像](https://day-journal.com/memo/images/try-055_06.png)

![画像](https://day-journal.com/memo/images/try-055_07.png)

<br>

表示されました :tada:  

![画像](https://day-journal.com/memo/images/try-055_08.png)

<br>

#### Serverless FrameworkでNode.jsのサーバーレスAPIをGCPにデプロイできました :thumbsup: 

Serverless Frameworkを利用することで、手軽にGCPにサーバーレス環境をデプロイできました :bulb: 色々と設定できそうなので今後も試していきたいと思います :grinning: 

以前にZappaでためした記事、「[ZappaでDBもパッケージしたサーバーレスAPIを構築してみた](https://day-journal.com/memo/try-015)」もあるので比較してみて頂ければと思います。 

<br>

Serverless Frameworkについて、他にも記事を書いています。よろしければぜひ :bow:
<a href="https://day-journal.com/memo/tags/Serverless-Framework"" target="_blank">tags - Serverless Framework</a>

やってみたシリーズ :grinning:
<a href="https://day-journal.com/memo/tags/Try" target="_blank">tags - Try</a>

<br>
<br>

<a href="https://dayjournal.booth.pm" target="_blank"><img src="https://day-journal.com/memo/images/etc/book.png" alt="book"></a>
Azure CLI で Windows 仮想マシンを作成するの備忘録

#はじめに
Azureドキュメントの「Azure CLIでWindows仮想マシンを作成するをやってみる」で作成しようとしたが、上手くいかなかった箇所を備忘録として残したい。

#手順
検索バーの直ぐ右のボタンをクリックし、CLIのウインドウを開き、Azure CloudShellを立ち上げる。
![スクリーンショット 2020-12-18 9.52.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/bf34cb1f-eaed-5803-3da7-20f710a3d2e3.png)

下記コマンドでリソースグループを作成

```
az group create --name myResourceGroup --location eastus
```

仮想マシンの作成において、ドキュメントではバックスラッシュを使って行の継続を行なっていたが、それだと上手くいかないためバックスラッシュなしでコマンドを入力したら上手く言った。

```
az vm create --name myVM --resource-group myResourceGroup --image win2016datacenter --admin-username azureuser
```

https://docs.microsoft.com/ja-jp/azure/virtual-machines/windows/quick-create-cli#code-try-0
複数オリジンからのアクセスをHTTP Access-Control-Allow-Originヘッダーで許可する方法

HTTP Access-Control-Allow-Originヘッダーを用いて、複数の別オリジンのフロントエンドアプリから、APIを呼び出すためのCORS設定方法をまとめる。

## ユースケース

* 以下のようなApacheをWebサーバーとして配置する構成のアプリ(API)を、複数の別オリジンのフロントエンドアプリから呼び出したい場合

![apache_cors.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/200833eb-c260-d06b-020d-8ef644312a82.png)


## 実現手段

* Apacheの設定ファイルを、許可するオリジンからのリクエストである場合に`Access-Control-Allow-Origin`ヘッダーを付与するように記述する。

```http
SetEnvIf Origin "^http(s)?://(www\.)?(domain-x\.com|domain-y\.com|domain-z\.com)" ALLOWED_ORIGIN=$0
Header set Access-Control-Allow-Origin %{ALLOWED_ORIGIN}e env=ALLOWED_ORIGIN
```

1. リクエストの`Origin`ヘッダーを正規表現判定する。※判定ルールは環境変数として外出ししても良い。
2. マッチしたOriginを変数`ALLOWED_ORIGIN`に代入する。
3. レスポンスの`Access-Control-Allow-Origin`ヘッダーに`Origin`ヘッダーの値がセットされる。


## 参考情報

* [Access-Control-Allow-Origin Multiple Origin Domains?](https://stackoverflow.com/questions/1653308/access-control-allow-origin-multiple-origin-domains)
Jetson nanoで tensorflow + Jupyter notebook

## コンテナ nvcr.io/nvidia/l4t-ml:r32.4.2-py3 を使いたい場合

NVIDIAの提供している方法。普通はこちらを使っていればいいと思う。

コンテナは https://ngc.nvidia.com/catalog/containers/nvidia:l4t-ml に色々と

    sudo docker run -it --rm --runtime nvidia --network host nvcr.io/nvidia/l4t-ml:r32.4.2-py3

```http://<hostname>:8888``` パスワード nvidia を入力すると、JupyterLab を使うことができる。


## こちらも
[Jetson nanoで「現場で使える!TensorFlow開発入門」のサンプルを動かす](https://qiita.com/Nunocky/items/c1ce3163d78d14bd9dbd)
MAMPでMySQLをPDOで接続する時にちょいハマった話

# はじめに
ちょー久しぶり(多分10年ぶりぐらいw)にPHP,MAMP,MySQLをやる必要が出たので、すっかり忘れてしまっているので、調べながらPDOで接続してみようとしたら、小１時間ハマってしまったので、メモメモ_φ(･_･

# 更新履歴
2020.12.19 初回投稿

# 環境
- macOS Catalina(10.15.7)
- MAMP 6.0.1(985)
- PHP 7.4.9
- MySQL 5.7.30

# 現象
PHPでPDO接続しようとすると「[2002] No such file or directory」というエラーが表示され、接続できない。

```
new PDO('mysql:dbname=mydb;host=localhost;charset=utf8','root', 'root');
```
# 解決方法
・調べてみると、unix_socketを追加しろとあり、以下のようにしてみたけど接続失敗

```
new PDO('mysql:dbname=mydb;host=localhost;charset=utf8;unix_socket=/tmp/mysql.sock','root', 'root');
```

・んで、MAMP起動時に出てくるページ見るとunix_socketの場所が書いてあるやん
![SS_ 2020-12-19 9.05.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9961/1d700288-62d0-4acc-7b75-45885e18ae16.png)

unix_socketを追加してあげる。

```
new PDO('mysql:dbname=mydb;host=localhost;charset=utf8;unix_socket=/Applications/MAMP/tmp/mysql/mysql.sock','root', 'root');
```

これで接続できた。


## 参考サイト
- https://qiita.com/RyosukeSomeya/items/f400534281c9176f1310
- https://blog.codecamp.jp/programming-php-pdo-mysql-1
- https://xn--t8j3bz04sl3w.xyz/mysql/php-mysql-connection/6793/
Google Colaboratoryで訓練したモデルがローカルで動かない

#何が起こった？


Googole Colaboratory（以下Colab）でうまくいっている機械学習モデルが、ローカルにコピーしてmodel_loadしたところ、エラーが出て動かなかなかった。

#原因は

Colabで読み込まれるtensorflowのバージョンと、ローカルにインストールしていたtensorflowのバージョンが違っていました

```python:colaboratory
print(tf.__version__)

2.4.0
```

```terminal:local
$ python3 -c 'import tensorflow as tf; print(tf.__version__)'

2.3.1
```

#解決は

```terminal:local
$  pip install --upgrade tensorflow   
```
ローカルのtensorflowを最新にアップデートしてcolabと合わせました

#エラーメッセージをわからないなりにも読まないと
エラーメッセージが出て止まっているのですが、英語でブワァーーーーっと流れるので、完全にスルーしていました

自分の想像力だけで解決しようと、動かない原因にモデルのサイズが大きすぎた？とか、モデルのファイル名に記号が混ざっているから？とか、いろいろ右往左往しました。結局、エラーメッセージに書かれていたlayerが定義されていないっぽいことに気づいて、tensorflowに標準で組み込まれているlayerが読み込めていないのだろう気配を感じることができ、そこからバージョンアップによる機能追加に想像が及びました

2.3から2.4と小数点以下のバージョン変更でも、コードが動かなくなるものなんですね

クラウド環境で最新のライブラリを使っていると、ローカルとの環境差が知らないうちに開いているということを知りました
Webのフロントエンドにおけるドメイン・モデルクラスの必要性

# １．APIから受け取るオブジェクトリテラル（JSON）は未知のもの

　サーバサイドのAPIからJSONを受取、JS内ではそれをオブジェクトリテラルとして最初は扱います。
　オブジェクトリテラルはただの値の集合であり、プロパティ値がなくundefinedになりエラーになることがあります。

　これを防止するには、独自のドメイン・モデルクラスを作り、確実に**プロパティを「管理」**する必要があると思います。
　あくまでも、「管理」なので期待通りの値が取得できるかは別ですが、少なくともundefinedになることを防ぐことはできます。

　そして、なによりクラスで定義することで、プロパティが何であるのかの補完が効くのでコーディングの効率があがります。Typescriptならなおのことですが、JavascriptのままでもVScodeなら十分補完が効きます。

　オブジェクトリテラルをクラスに変換する方法は以下。

▶ [JavascriptのES6以降のクラスでイミュータブルプロパティを定義](https://qiita.com/SFITB/items/5d45ddb0162d34562d0e)


# ２. ドメイン・モデルクラスを通してAPIのデータを読み込む

　前述の通り、オブジェクトリテラルのままだとundefinedのチェックを都度しないといけず、いろいろなコンポーネントで使うとき、それらすべてでチェックすることになります。

　これは無駄です。最低限、ドメイン・モデルクラスで１度チェックして、それを受け取るほうがコードがすっきりします。

　またドメインクラスとして、ある程度決まった値の加工などをしておくと、その分コードのムダがへります。
　そして、HelperやUtilのような汎用的なクラスに値の処理を分散させず、関心に沿ったドメインクラスに閉じ込めることで、呼び出ししやすくなります。
　勿論、可読性もあがります。


# ３．ドメイン・モデルオブジェクトはリポジトリクラスで管理

- ドメイン・モデルクラスは、APIから取得したオブジェクトリテラルをプロパティの諸元としてインスタンス化されます。
- ドメイン・モデルオブジェクトをインスタンス化するのはリポジトリクラスにが行い、Windowオブジェクトへの格納もリポジトリクラスが行います。
- Storeやコンポーネントなど他のモジュールはドメイン・モデルオブジェクトを取得する際には、このリポジトリクラスから取得するようにします。
- APIへの問い合わせもリポジトリクラスで適宜行い、他のモジュールはAPIへの接続は全く行いません。

# ４．ドメイン・モデルオブジェクトは不変オブジェクトにする

- ドメイン・モデルオブジェクトのプロパティは、**Object.defineProperties**を使い不変として定義します。
- 変更が必要な場合、それは別途変更用としてディープコピーしたオブジェクトとして管理するのがよいと思います。

# ５．サーバサイドと同じくドメイン・モデルクラスを使うことで可読性・保守性を上げる

　フロントエンドはコンポーネントなど個々のパーツ作りの議論が盛んですが、サーバサイドと同様にドメインロジックへの設計の配慮も必要です。
　
　JSONをオブジェクトリテラルのまま使うのではなく、ドメイン・モデルを定義し、より可読性・保守性の高いコーディングをすべきかと思います。
【Go言語】0から"0"の変換って、実際どうやっているの？

これは [Go 4 Advent Calendar 2020](https://qiita.com/advent-calendar/2020/go4 "https://qiita.com/advent-calendar/2020/go4") の19日目の記事です。

# 0. まえがき
数値から文字列に変換する関数として、strconv.Itoaがありますが、ソースコードの中身が気になったので、見てみます

# 1. 実行環境
- Windows10 Home
- go version go1.14.4 windows/amd64

# 2. 数値を文字列に変換する関数 strconv.Itoa
int型の任意の数値を、string型に変換する関数
[https://golang.org/pkg/strconv/#Itoa](https://golang.org/pkg/strconv/#Itoa "https://golang.org/pkg/strconv/#Itoa")

## 2-1. 0を"0"に変換して表示する
```golang:itoaExample.go
package main

import (
    "fmt"
    "strconv"
)

func main() {
    var n int = 0
    nString := strconv.Itoa(n)

    // nString: 0 と表示される
    fmt.Printf("nString: %s\n", nString)
}
```

# 3. 実際何やっているの？
strconv.Itoaの動作が分かったところで、実際の処理を見ていきます
strconv.Itoaのソースコード：[https://golang.org/src/strconv/itoa.go](https://golang.org/src/strconv/itoa.go "https://golang.org/src/strconv/itoa.go")

## 3.1 func Itoa(i int) string
まずは、関数の本体（？）を見ます

```golang:funcItoa.go
func Itoa(i int) string {
    return FormatInt(int64(i), 10)
}
```
なるほど、関数FormatIntに「int64型にキャストしたi」と「10」を渡していますね。今回は、iは0になります。

## 3.2 func FormatInt(i int64, base int) string
次に、FormatIntを見ます

```golang:formatInt.go
func FormatInt(i int64, base int) string {
    if fastSmalls && 0 <= i && i <= nSmalls && base == 10 {
        return small(int(i))
    }
    _, s := formatBits(nil, uint64(i), base, i < 0, false)
    return s
}
```

まずは、以下のif文についてですが、

```golang
if fastSmalls && 0 <= i && i <= nSmalls && base == 10 {
    return small(int(i))
}
```

fastSmalls は、ソースコード中で定義されており、「true」となります。

```golang
const fastSmalls = true
```

また、nSmallsは、ソースコード中で定義されており、「100」となります。

```golang
const nSmalls = 100
```

今回、iは0, baseは10となっているので、それぞれの変数に値を当てはめると、if文は以下のようになります。

```golang
if (true && 0 <= 0 && 0 <= 100 && 10 == 10) {
    return small(int(i))
}
```

よって、if文がtrueになるため、次の関数のsmall(int(i))に行きます。

## 3.3 func small(i int) string

smallは以下のようになります。

```golang
func small(i int) string {
    if i < 10 {
        return digits[i : i+1]
    }
    return smallsString[i*2 : i*2+2]
}
```

iは0なので、if文に入ってdigits[0 : 0+1]を返します。digitsはソースコード中で以下のように定義されています。

```golang
const digits = "0123456789abcdefghijklmnopqrstuvwxyz"
```

digits[0 : 0+1]より、"0"が返ってきます。

# 4. 結論
0をstrconv.Itoaに渡すと、digits[0 : 0+1]より、"0"が返ってくる

# 5. まとめ
今回は0を"0"に変換するということでソースコードの一部しか見ていませんが、もっと大きな数値になると変換の処理が変わってきます。そちらの処理の中身の確認は皆さんにおまかせします。普段何気なく使っている関数でもそのソースコードを見ることは少ないと思います。とても勉強になるので皆さんも、普段使う関数のソースコードを読んでみてはいかがでしょうか。