OmniAICreator/Qiita-1.07M huggingface dataset:
うちのESXi環境

#はじめに
たまには自分の開発環境について書いてみようかなと思ったので、今回は誤自宅のESXi環境について綴ってみます。

**2021/11/16 追記: HP Prodesk 600 G1 SFを手に入れたので、
ESXi環境を移行した話を追加しました。**

#ハードウェア構成
2020年前半までは使い古したノートパソコンにESXiを入れて遊んでいたのですが、
8月の終わりぐらいに近所のハードオフでHP ProLiant MicroServer N54Lが5,500円で鎮座していたので買って帰り、内部清掃をしてからパーツを追加したりしてすぐにESXiを入れて、現在も運用しています。
あのときの嬉しさと感動は忘れることはないでしょう…(笑)

**追記:**
またまた近所のハードオフでHP Prodesk 600 G1 SFが5,000円ぐらいで売られてたので、
N54Lを退役させてESXi 7.0.3を入れました。

##いまのESXiホスト構成
マシン: MicroServer N54L
メモリ: 8GB+4GB (追加した)
記憶域: HDD×2、SSD×1
NIC: 内臓NIC+おなじみのEXPI9301CT
ESXi 6.5

メモリは8GB上限らしいですが、4GBの足してもちゃんと認識してくれました。
NICは内臓の蟹チップもESXi側で認識してくれましたが、やっぱりIntelほしいっ！となったので追加しました。
肝心のESXiは最新の7.0を入れたかったのですが、CPUのサポートしてない的なエラーが出たので(6.7も同様)、6.5で我慢してます。

**追記:** 最新のホスト構成
マシン: HP Prodesk 600 G1 SF
CPU: intel Core i3-4170
メモリ: 8+8+8+4GB (大盛りになった)
記憶域: HDD×1、SSD×1
NIC: 内臓NIC+おなじみのEXPI9301CT
ESXi 7.0.3

グーンとパワーアップしましたね。
特にメモリが多く乗るようになったので、たくさんVM建てられます。

#ESXiでなにしてるの
主に実験用です。
Linuxはもちろんのこと、pfSenseでネットワーク作ってみたり、BSD系で色々やってみたりなどしています。
あと、宅内システムのサーバとしてVM動いてたりなど、なにかと多用途です。
学校でもESXiの運用を担当していたので、自宅でもその知識が役に立ってます。

#たのしい
ESXi環境が自宅にあるとたのしいですよ。
2コア、12GBメモリしかない限られた構成ですが、それを駆使していろんなVMを立ててみるのもおもしろいです。

#みなさんも…
今回は自分のESXi環境について書かせていただきましたが、みなさんの開発環境もぜひ聞いてみたいです！
~~タグ「自分の開発環境」を勝手に作らせていただいたので、よろしければみなさんも書いてみてくださいね！~~
(2021/5/10追記:)タグを"開発環境"に統合させていただきました。
編集リクエストいただいた方、ありがとうございました。

---

以上になります。
長ったらしい話でしたが、ご覧いただきありがとうございました！
京セラプログラミングコンテスト2021(AtCoder Beginner Contest 200) 参戦記

# 京セラプログラミングコンテスト2021(AtCoder Beginner Contest 200) 参戦記

2回前に3桁パフォを取ったレーティングダウンから回復する前に、また3桁パフォを取ってしまうとは…….

## [ABC200A - Century](https://atcoder.jp/contests/abc200/tasks/abc200_a)

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

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

print((N + 99) // 100)
```

## [ABC200B - 200th ABC-200](https://atcoder.jp/contests/abc200/tasks/abc200_b)

3分で突破. K≤20 なので素直に実行するだけ.

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

for _ in range(K):
    if N % 200 == 0:
        N //= 200
    else:
        N *= 1000
        N += 200
print(N)
```

## [ABC200C - Ringo's Favorite Numbers 2](https://atcoder.jp/contests/abc200/tasks/abc200_c)

10分で突破. 似たような問題が過去問にありましたね. 200で割った余りが同じA<sub>i</sub>同士の組み合わせの数の合計.

```python
N, *A = map(int, open(0).read().split())

d = {}
for a in A:
    t = a % 200
    d.setdefault(t, 0)
    d[t] += 1

result = 0
for k in d:
    result += d[k] * (d[k] - 1) // 2
print(result)
```

## [ABC200D - Happy Birthday! 2](https://atcoder.jp/contests/abc200/tasks/abc200_d)

突破できず. バックトラックが無限ループしまくっていた.

```python
N, *A = map(int, open(0).read().split())


def backtrack(n):
    result = []
    while dp[n] is not None:
        pn = n
        result.append(dp[n] + 1)
        n -= A[dp[n]]
        n %= 200
        if n == pn:
            break
    return list(reversed(result))


def finish(B, C):
    print('Yes')
    print(len(B), *B)
    print(len(C), *C)
    exit()


dp = [None] * 200
for i in range(N):
    a = A[i] % 200

    if dp[0] is not None:
        B = backtrack(0) + [i + 1]
        C = [i + 1]
        finish(B, C)

    if dp[a] is not None:
        B = backtrack(a)
        C = [i + 1]
        finish(B, C)

    ndp = dp[:]
    ndp[a] = i
    for j in range(1, 200):
        if dp[j] is None:
            continue
        k = (j + a) % 200
        if dp[k] is not None:
            B = backtrack(k)
            C = backtrack(j) + [i + 1]
            finish(B, C)
        ndp[k] = i
    dp = ndp
print('No')
```
AtCoder Beginner Contest 200(京セラプログラミングコンテスト2021)のABC問題をPythonで解答

久しぶりにAtCoderコンテストに参加したので、自分が書いたPythonのコードを共有します。
Atcoderの解答は基本C++の解答コードが掲載され、Pythonの解答コードはないので、参考になれば幸いです。
残念ながら、解くことができたのはABC問題で、DやE、Fまでは解けていません。

# A - Century 
## 問題設定
問題文：西暦N年は何世紀ですか？
入力：西暦N年のNを標準入力
出力：何世紀が整数で出力
[問題URL](https://atcoder.jp/contests/abc200/tasks/abc200_a)

## ABC200のA問題のPythonの解答コード

```
N = int(input())
N = int((N - 1)/100) +1;
print(N)
```

##ABC200のA問題のPythonの解答コード解説
1行目で西暦N年を整数としてint型で標準入力し、変数Nに格納
2行目で何世紀か計算
3行目で出力

西暦N年から何世紀か計算する問題。
つまづきポイントは1世紀＝西暦1年～西暦**100**年までという点。
単純に100で割るだけだと、西暦100年や西暦200年が次の世紀にカウントされてしまうため、先に1引くことで対処している

# B - 200th ABC-200
## 問題設定
問題文：整数Nが与えられます。以下の操作をK回行った後の整数Nを出力してください。

* 整数Nが200の倍数であれば、Nを200で割る。
* そうでなければ、整数NをNの後ろに文字列として200を付け加えた整数に置き換える。

入力：整数Nと整数Kを入力
出力：問題に記載された操作を行った後の整数Nを出力
[問題URL](https://atcoder.jp/contests/abc200/tasks/abc200_b)

## ABC200のB問題のPythonの解答コード

```
N,K = map(int,input().split())
for i in range(K):
    if N % 200 == 0 :
        N = int(N /200)
    else :
        N = N *1000 + 200
print (N)
```

##ABC200のB問題のPythonの解答コード解説
1行目で整数Nと整数Kを入力。mapを使った入力
2行目でKの回数forループを実行
3,4行目で200で割り切れる(200の倍数)の場合は200で割る
5,6行目で200の倍数でない場合に数字の末尾に200加える
7行目で操作した結果を出力

問題の記載された通りの操作を実装。
除算をすると、整数が小数点を含むようになるため、int型に変換処理を施しておく。
200の倍数でない場合に、末尾に200足す処理は、整数Nを1000倍し、200足せばOK。

# C - Ringo's Favorite Numbers 2

##問題設定

問題文：200という整数が大好きなりんごさんのために、次の問題を解いてください。N個の正整数からなる数列Aが与えられるので、以下の条件をすべて満たす整数の組(i,j)の個数を求めてください。

**Ai − Ajは 200の倍数である。**

入力：数列数Nと数列Aを入力
出力：問題に記載された条件を満たす個数を整数で出力
[問題URL](https://atcoder.jp/contests/abc200/tasks/abc200_c)

**※C問題から計算量を考慮しないといけなくなります。そのまま条件通りに解を求めても、TLEになってしまいます。**

##ABC200のC問題のPythonの解答コード(TLE解答)

```
N = int(input())
A = [int(e) for e in input().split()]
count = 0
for i in range(N):
    for j in range(i+1,N):
        if (A[i]- A[j])%200 == 0:
            count = count + 1
print(count)
```

##ABC200のC問題のPythonの解答コード解説(TLE解答)

問題文の通りにコードを実装した結果、計算量がO(N^2)になってしまい、TLE出力してしまいます。

##ABC200のC問題のPythonの解答コード(正答)

```
N = int(input())
A = [int(e) for e in input().split()]
B = [0 for i in range(200)]
count = 0
for i in range(N):
    B[A[i]%200] = B[A[i]%200] + 1
for i in range(200):
    count = int(count + B[i]*(B[i]-1)/2)
print(count)
```

##ABC200のC問題のPythonの解答コード解説(正答)
計算量を少なくするために発想の転換が求められます。
条件である「(Ai-Aj)が200の倍数になる」をどう読み替えられるかが試される問題です。
上記条件は「Ai(mod 200)とAj(mod 200)が等しい」という形に置き換えられます。

**例)  「201と601は余りがともに1」→601-201=400で200の倍数**

数列すべてに対し、200で割った余りを求め、余りの個数が同じになったものを数えます。
200で割った余りなので、0~199までの200個のどれかに分類されます。
0-199の余り200パターンをforループで処理し、余りの個数Xから2組の数列のペアを抽出します。
X個ある中から2つ取り出す場合の数の計算の計算はxC2となるため、X(X-1)/2で計算します。
この方法であれば、計算量はO(N)となるため、TLE解答のO(N^2)よりも短時間で計算でき、時間内に解答を導くことができます。

#終わりに
ここまでC問題を解説したものの、実は時間内にC問題は解けていません(汗)
計算量O(N^2)でTLEに陥ることには気づいたものの、「Ai(mod 200)とAj(mod 200)が等しい」に読み替えることができませんでした。
解答を読んで、場合の数まで出てきたことにアハ体験を受けたので、自分なりの理解をまとめてみました。
Mayaで頂点のx座標だけ全部0にするだけのMEL

Autodesk Mayaでモデリングしていると
何故かXキーを押してスナップモードにしていても頂点のx座標が微妙に0になってくれないことが時々ある。
何故なのかよく分からない…。

![mayaのゴミ野郎.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492401/86ff61f0-d827-d005-dfb0-af5f4613eb16.jpeg)


標準機能で直せるのかもしれないけど、直し方がよく分かららないのでいつも、自分は頂点を選択した状態で以下のようなMELを実行して解決している。
どこかに保存して置いて毎度毎度忘れてしまうのでQiitaに投稿しておこう。

```c
string $vtxName[] = `ls -sl`;
string $vtxNo[] = `filterExpand -selectionMask 31 $vtxName`;
for($n in $vtxNo)
{
  float $pos[] = `xform -q -ws -t $n`;
  xform -t 0 $pos[1] $pos[2] $n;
}
```
[AWS_04]構成図作成

##環境
MacBook Pro (13-inch, 2016, Four Thunderbolt 3 Ports)
Visual Studio Code Version: Version: 1.56.0
Draw.il Integration 1.4.0

##構成図の準備
1. VisualStudioCode の拡張機能で`Draw.io`をインストールする。
1. 拡張子を`.drawio`にしてファイルを作成すると自動的にツールが使用できるようになる。
1. `+その他の図形...`から`AWS19`を追加するとAWS公式アイコンが使用できるようになる。
LookerのLiquid変数の仕様変更に対応する

# 前提
Lookerではフィルタの内容をLiquid変数として参照することができます([参照](https://docs.looker.com/ja/reference/liquid-variables))。
リンク先にあるように使用の際には`sql_quote`を使用することが推奨されているため、`if`文で使う時には以下のように記述していました。

```liquid
{% if _filters['view_name.field_name'] contains 'Tokyo' | sql_quote %}
 'Tokyo'
{% endif %}
```

#アップデート以降の警告内容
　ゴールデンウィーク明けから、以下のような警告が出るようになりました。

>This liquid does not conform to the Liquid language spec and will produce warnings or errors in a future version of Looker. Parse error was: Error parsing liquid: Liquid parse exception: parser error "mismatched input '|' expecting {TagEnd, '.', NEq, '==', '>=', '>', '<=', '<', '[', '?', 'contains', 'and', 'or'}" on line 000, index 000

Liquid文の中で`|`を使うなということのようですが、先述の通りLookerからはフィルタの内容を参照する時には`sql_quote`を推奨されており、一見矛盾となってしまいます。

#解決方法
警告文を調べたところ、[Looker公式のこちらの記事](https://help.looker.com/hc/en-us/articles/360049663734-Looker-Liquid-Syntax-Parser)がヒットし、下記の記述を見つけました。

>Assigning the output of the function chain to a variable and including that variable in the   if  conditional should resolve the warning.

`if`文の中で直接フィルタ内容を参照するのではなく、一旦別の変数に`assign`してから`if`文で使うように、と解釈したので、先ほどのコードを下記のように書き換えたところ、警告がなくなりました。

```liquid
{% assign filtered_dimension = _filters['view_name.field_name'] | sql_quote %}
{% if filtered_dimension contains 'Tokyo' %}
 'Tokyo'
{% endif %}
```

#コメント
上記の記事に解決法そのものが書いてはあるのですが、Liquid記法に不慣れなこともあり具体的なコードに落とし込むところで試行錯誤してしまったため、備忘録として記録します……
VisualForceで２度目の保存をしたときに、画面のリダイレクト後にVisualForceページでデータが表示されないという問題

## 動作環境
* Salesforce Lightningを使っている。
* SalesforceでVisualForceを使ったページである。
* カスタムコントローラを拡張したApexのクラスを利用したVisualForceのページでタイトルの問題が発生する。

## 問題の症状
* 保存のメソッド（ここではsaveメソッドを上書きしている）を実行したときに、１度目は問題ないが、2度目の保存を実行した際に、画面のリダイレクト後にVisualForceページでデータが表示されない。
  * この際、リダイレクトをさせないようにすれば解決するが、どうしてもリダイレクトをさせいたい。

## 原因
* 結論を書くと、この原因はカスタムオブジェクトのIDがnullになっていることで、VisualForceページでデータが表示されないという、この記事のタイトルのトラブルが発生している。

## 前置き
* 以下、自分の考えた解決方法ですが、自分の作成した「カスタムコントローラを拡張したApexのクラス」特有の問題なのかもしれません。とりあえず、同じような症状で悩んでいるプログラマもいると思いますので、(及び、自分の備忘録のために)以下の解決方法を記録します。
* 検証のための全体コードは書きません。解決した方法は書いています。

## うまく行かないコード その１
* `setRedirect(true)` を利用して、ただリダイレクトをさせるコードです。
* Web上で「カスタムコントローラを拡張したApexのクラス」などの記事を参考にしてコードを書くと、保存のメソッドは以下のようなコードになると思われます。

```apex
  /*
   * saveメソッドの上書き
   */
  public PageReference save() {
    this.stdController.save();
    PageReference p = ApexPages.currentPage();   // ←これだと、2度目の保存ボタン(saveメソッド)のを実行した際に、データが表示されないという問題が発生する。
    p.setRedirect(true);
    return p;
  }
```

* saveメソッドの2回目の実行時にエラーが起きる原因は、カスタムコントローラのオブジェクトのIDがnullになってしまうことです。(しかし、なぜnullになってしまうのかについては、よくわからない。)
* 1回目のリダイレクト時は、idはnullにならないので、うまくデータが表示されますが、2回目のリダイレクト時は、再びコンストラクタを通った際に、オブジェクトのIDがnullになってしまい、Visualforceのページのデータが表示されなくなってしまいます。そのため、次に以下の一行を追加してみます。

```apex
Id projectId = ApexPages.currentPage().getParameters().get('id');
```

## うまく行かないコード その２
* 上記の１行を追加します。

```apex
  /*
   * saveメソッドの上書き
   */
  public PageReference save() {
    this.stdController.save();
    PageReference p = ApexPages.currentPage();
    Id projectId = ApexPages.currentPage().getParameters().get('id');  // 追加
    p.getParameters().put('id', projectId);
    p.setRedirect(true);
    return p;
  }
```

* `ApexPages.currentPage().getParameters().get('id')`でページのパラメータを取得すれば良いだろうと思ったが、やはりうまく行きません。
* そこで、以下のサイトを発見しました。
- https://salesforce.stackexchange.com/questions/254568/how-to-redirect-to-external-url-from-apex-from-callout-response
* このWebサイトに書かれているstdController.getId()を利用します。その結果、idがnullにならずに、うまく表示されてタイトルの問題が解決しました。

## うまくいくコード
* `stdController.getId()`として、ページのIDパラメータを取得するのがポイントです。

```apex
  /*
   * saveメソッドの上書き
   */
  public PageReference save() {
    this.stdController.save();
    PageReference p = ApexPages.currentPage();
    p.getParameters().put(‘id’, this.stdController.getId());  // 修正
    p.setRedirect(true);
    return p;
  }
```

* 言い換えると、`ApexPages.currentPage().getParameters().get('id')` では、idを取得出来ませんが、`stdController.getId()` だとうまくidを取得できるという結論です。
* ついでに言うと、上記のコードでsaveなどのSOQLを更新する箇所はtry~catch文を使った方が良いですが、簡単に表示するために省略しております。

## 感想
* Salesforceにおいて、今後はVisualforceより、LWCを利用してコンテンツを作成するべきです。
* そのため、データベースの編集をする場合は、LWCでやった方が良いので、LWCで作成すれば、この問題に遭遇しないと思います。(つまり、VisualForceでデータを編集した場合、かつ、リダイレクトをして保存時に画面を更新させたい場合特有の問題です)
* しかし、印刷が必要な画面や、すでにVisualforceで作成された編集ページがある場合、「カスタムコントローラを拡張したApexのクラス」を利用することが考えられ、今後も今回の問題に遭遇してしまうプログラマが発生すると思われます。今回の記事は、そのような内容なので、ニッチなトラブルに関する記事ですが、Web上に中々、解決する方法のヒントが見つからなかったので、この記事を書きました。
Qiitaを始める時の基本コマンド

#記事を投稿しようと思ったら、Qiitaの記事の書き方がわからなかったので、まずは記事の書き方をメモ
#1. 見出し作り
見出しを作るには＃を使う。見出しにしたい文章の先頭に＃をつけましょう。

#2. コードの挿入
下記のようなコード挿入は記事作りに必須です。

```
rails s
```

方法は至って簡単（知っていれば）コードの上下の列にバッククオート　`　←こういうやつを３つ入れましょう。
、、、
rails s
、、、
で上記のようにコードの挿入ができます。
余談ですがバッククオートは「shift + @」で入力できます。
普段使わないので馴染みがないですよね。
あと勝手にシンタックスハイライトというコード見やすく色付けしてくれる機能も付くみたいです。

バッククオート３つの後に「言語名:ファイル名」を記入するとより見やすいですね。

```ruby:terminal
rails s
```

#３. リンクの挿入
[Qiita]（http://qiita.com/）
のように書くと下記のようなリンク付きの挿入ができます。
[Qiita](http://qiita.com/)

#4. 引用
＞を書くだけです。
ただし、改行するときはその度に>を書く必要があるので注意です。
下記の通りになります。
>引用文はこんな感じで出てきます。
>改行のたびに>を入力してます。

#5. リストの作成
リストの上下に空白を入れないと正しく表示されないので注意です。
記号と文の間に半角スペースを入れます。

✳️ 順序なしリスト
文頭に「*」「+」「-」のいずれかを入れる。

* abcdefg
* hijklmn
* opqrstu

#6. 水平線
「*」か「-」を3つ以上一行に書きます。以下のような感じになります。
***

#7. テーブルの挿入
基本は「|」でくくります。
2行目がポイント。2行目のコロンの位置によってセル内の文字の配置が変わります。
|左揃え|中央揃え|右揃え|
|:---|:---:|--:|
|align-left|align-center|align-right|
|セルの左揃えです|セルの中央揃えです|セルの右揃えです|

|左揃え|中央揃え|右揃え|
|:---|:---:|--:|
|align-left|align-center|align-right|
|セルの左揃えです|セルの中央揃えです|セルの右揃えです|

#8. ページをマークダウンで見る
どう書いているのか手法が機になる記事を見つけたときにはMarkdown記法で見ると良いそうです。
見たいURLの最後に.mdをつければ見ることが出来ます。とっても便利ですね。

#9. 投稿欄の横にある「？」ボタンをクリックすると記事の書き方について詳しく書いてある
コメントをいただきまして本項目を追記させていただきました！
実は投稿欄の横に「？」のマークがありましてクリックすると Qiitaで記事を書くときの基本がちゃんと載ってました。
全然気付かず意気揚々と、この記事書いてました笑

コメントで教えていただいた方、ありがとうございます。またお願いします！
ここまで読んでいただいた方、ありがとうございます。最初に言えとか言わないでください。

#参考　
[Qiita Markdown 書き方 まとめ](https://qiita.com/shizuma/items/8616bbe3ebe8ab0b6ca1)
高校物理『ma=F』を考える

　高校で物理を選択すると、大体3回目くらいの授業で黒板に書かれる謎の式　ma=F 。これは受験で必ず使う重要な公式とだけ言われたのを覚えている。

　時が進み、受験を意識するようになるとネットで評判の良かった物理の参考書をテキトーに買って読み、解法を身につけ、そして受験を終えた。高校物理がお世辞にも面白いとは感じなかったものの、いわゆる本場の『物理学』というものに憧れを抱いていたのと、物理学を学んでいるという自分に酔いしれたいという単純な理由で物理学科に入学した。理工系の学問を専攻すると、大体の人は1年生の必修で力学や数学の基本的なものから始めていくだろう。筆者も力学、微積、線形代数をまず最初に学んだものである。

　力学の教科書を読み進めていくと、高校物理がただの算数パズルだったのだと気付かされる。

　そもそも物理学とは、現実の自然界の複雑な世界によく似た『世界』を、数学を用いて表して、その『世界』のなかで物質などの動きを考えるものであるということを踏まえると、高校物理で考える『世界』は現実世界と比べて、非常に解像度が低いのである。1年生で学ぶ力学では、より解像度が高い『世界』をより高度な数学を使って表している。世の中の事象が、たいていこの力学で説明できるということは、現実世界と力学の『世界』がかなり近似的であろうことは何となく理解できる。

　ただこの力学にも弱点がある。とてつもない小さな世界を考えると誤差が生じてしまう。つまり、現実世界と力学の『世界』の解像度が、ミクロの世界になると落ちてしまうことになる。ここでより解像度の高い『世界』を考え出すために生まれたのが、古典力学と対をなす量子力学の創設となる。この量子力学の『世界』では、今までの力学では解像度が低くて表すことのできなかった事象を説明できるようになる。つまり物理を発展させるということは、現実世界により似た『世界』を表現することであると考える。

　その点、高校物理ではかなり単純なルールのみで構成された『世界』での動きを学ぶ。このことに高校生の時に気付けなかった。なぜ質点は運動方程式に従って動くのかなどを考えたりをして、本質を見誤っていたのである。そもそも、昔の先人が、現実の世界での物質の動きを観察した結果、何らかの『力』というものがあり、全ての物質にはその特定の量（＝質量）が存在し、力が働くと物質を加速させるという『世界』を考えた時、周りの現象をかなり精度良く説明ができるということを発見し、そのルールを数式で表したものが運動方程式であり、高校風に書くと ma=F ということである。

　勉強を進めていくと現実世界で長らく生きていたせいか、高校物理の『世界』に違和感を覚え、何となく腑に落ちないことが多々あった。例えば、摩擦がない滑らかな表面上の物質の動きである。摩擦がない床の上に置かれた物質の上に、置かれた物質(この物質の上部には摩擦が存在する）を動かした時、この下の物質の挙動を問う問題である。現実世界で生きてきた自分にとって、全く想像も付かず手が動かなかったのを覚えている。物理は実証科学ならば、実際に仮想実験をしてみようと脳内で考えても、解が出なかった。

　それもそのはず、実際の世界とは区別した『世界』での動きを高校物理では取り扱っていたからである。高校物理を苦手、もしくは面白くないと感じる人間（自分を含めて）がいたならば、おそらく高校物理を難しく考えすぎているのかもしれない。そもそも高校物理で考えている『世界』は現実世界の複雑なものを排除した簡易的なものであるということ。その中で、何個かの特徴的なルールに基づいて動く物質を考えてみようねという学問が高校物理である。改めて高校物理を思い出してもあまり好きになれない科目であることは間違いない。でも『物理』は面白い。
【Java】AtCoderのABC-200に参加しました（レート：278→264）。

こんばんは。

2021/5/8に、AtCoderのABC-200に参加しました。
レートは以下の通りとなっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402487/a41487df-8815-e9da-b035-30fee5faa7d3.png)


C問題でつまづきました。
レートは278→264にダウン！順位は6646/8577でした。
おーっ、あーっ、ぐぅーっ、という感じですね。


###A問題
世紀を求めるプログラム。念入りにテストしてしまいましたが、まあ何とか。

```Main.java
import java.util.Scanner;

public class Main{

public static void main(String args[]){
  Scanner sc = new Scanner(System.in);
  int n = sc.nextInt();
  System.out.println((n-1)/100+1);
 
}
}

```


###B問題
ある数字、Nについて、K回以下の処理を繰り返す。
・Nが200の倍数だったら、200で割る。
・200の倍数でなかったら、末尾に200を付与する（123だったら、123200にする）

ここは言われたとおりに、まあなんとか。
でも、200を付与するのに、文字列型に変換して付与するのはださいですね。
1000倍して、200を足す方がスマートですね。
後で振り返るのも大事です。


```Main.java
import java.util.Scanner;

public class Main{

public static void main(String args[]){
  Scanner sc = new Scanner(System.in);
  long n = sc.nextLong();
  long k = sc.nextLong();
  long nwk = n;
  String nwks = String.valueOf(n);
  for(int i=0;i<k;i++){
    if(nwk%200==0){
      nwk = nwk/200;
    }else{
      nwks = nwks + "200";
      nwk = Long.parseLong(nwks);
    }
    nwks = String.valueOf(nwk);
  }
  System.out.println(nwk);
 
}
}
```



###C問題
Nこの文字列Ai~Anを入力。
Ai-Ajが200の倍数、が成り立つ組み合わせはいくつあるか。
タイムアウトだってわかってはいたけれど、いいロジックが思いつかず・・入力時に、入力済みの全文字列を比較する処理をまずは組んでみました。
当然TLE。

次に、下2桁が同じものは、「条件が成立する可能性がある組み合わせ」と考え100個の配列に、下2桁が同じものを分類し、最期にまとめて計算する方法を取ってみましたが、タイムアウトに加え実行時エラーで発生し終了3分前に敗北。
でした。


###感想

解けなかったC問題を、例えば明日解説を参考に解いてみるとか、もっとした方が良いんだろうなと思うのですが、時間も限られているので気の向くまま学習を進めます。
会社でも、競技プログラミングの本をおすすめされていたので、やっぱり読んでみようかな。

ではまた。
PHPとjavascriptでよくあるクロスドメインエラーについて

##クロスドメインエラーについて

jsなどからPHPに対して、Ajaxやaxiosなどを使い、リクエストを送ったときにCROSSドメインのエラーが出ることがあります。

```text:Chrome
Access to XMLHttpRequest at 'http://test1/test.json' from origin 'http://test2' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
```

```text:Firefox
クロスオリジン要求をブロックしました: 同一生成元ポリシーにより、http://test1/test.json にあるリモートリソースの読み込みは拒否されます (理由: CORS ヘッダー ‘Access-Control-Allow-Origin’ が足りない)。
```

このエラーの原因はブラウザのセキュリティによって、CORSヘッダがセットされていため、別のサーバーからのデータの取得ができないというエラーです。
このエラーはPHP側に、HTTPヘッダのCROSヘッダ設定に「Access-Control-Allow-Origin」をレスポンスにセットすることで解決します。
具体的な記述方法は以下の記述になります。

```
header("Access-Control-Allow-Origin: *");
```
こちらをPHP側に挿入することで解決できます。

##
React + Docker + Typescript + ESlint + Prettier (初学者向け)

#前提
dockerのインストール、ホスト環境へのnode.js,typescriptのインストールは完了しているものとする。エディタはvscodeを用いる。
#はじめに
以下のようなディレクトリを作成

```
react/
　├ front/
　├ docker-compose.yml
　├ Dockerfile
```

#Dockerfileを編集

```Dockerfile:Dockerfile
#LTSである偶数のnodeイメージを取ってくる
FROM node:16.1.0-stretch-slim 
#ホストのfrontの中身をコンテナのフロントへコピーする。コンテナでのディレクトリも同時に作成される。
COPY ./front /front
#作業ディレクトリの移動
WORKDIR /front
#パッケージインストール
RUN yarn install
#コンテナのポートを指定
EXPOSE 3000
#コンテナスタート時に実行
ENTRYPOINT [ "yarn", "start" ]
```
#docker-compose.ymlを編集
```docker-compose.yml
version: "3.7"
services: 
  front:
    build: 
      context: .
      dockerfile: Dockerfile
    volumes: 
#ホストのfrontの中をコンテナのfrontの中で共有
      - ./front:/front
    working_dir: /front
    ports: 
#ホストの3000ポートをコンテナの3000ポートに繋ぐ
      - 3000:3000
```
#create-react-appの実行
frontディレクトリの中に入り下記を実行

```
npx create-react-app . --template typescript
```
frontの中にファイルが作られるので

次のコマンドを実行

```
yarn start
```
そしてブラウザでlocalhost:3000を入力すればよく見る画面が現れる。

#docker-composeの実行
reactディレクトリで

```
docker-compose up
```
を実行

ターミナルをもう一つ開き下記コマンドを実行すればコンテナに入ることができる。

```
docker-compose exec front bash
```


#ESlint Prettierの導入

###保存したときにコード整形されるようにします

VS Codeの拡張機能としてESlintをインストール
![eslint.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461885/af32c85c-2f45-457d-78a0-28abe51fc4a0.png)

Prettierもインストール
![prettier.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461885/ba99d814-4243-3a3d-1505-e1d9c3e66dbb.png)

次に
**[code] ＞ [基本設定] ＞ [設定]**　の順序で設定画面を開きます。

検索ボックスに **『format』** と入力すると、
**『Editor: Format On Save』** があるので、これにチェックを入れます。

![https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_525820_3a11d554-acf3-4860-d1b7-5d16b9f1cd2f.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461885/63e1a541-39c5-1a0b-649e-065d433da2a6.png)

そしてエディタ上で

**[Alt] + [Shift] + [F]**

を押すとフォーマッター（Prettier）を選択するように促されます。
それ以降保存でコードが整形されます。
32GB以上のUSBメモリをFAT32でフォーマットする手順

「ゼロからのOS自作入門」[^1]の第１章を参考に、UEFIからUSBメモリをブートしようとしたところ、私の環境ではexFAT形式でフォーマットされたUSBメモリを起動できませんでした。
FAT32形式でフォーマットすれば起動できるという Issue[^2] もあったのですが、使用したUSBメモリ容量の64GBではエクスプローラのフォーマット機能では変換できなかったため、`diskpart`を使ったフォーマット手順を記録します。

[^1]: ゼロからのOS自作入門 (http://zero.osdev.jp/)
[^2]: exFATでは動かなかったがFAT32では動いた (https://github.com/uchan-nos/os-from-zero/issues/17)

# 作業環境

OS: Windows 10 - バージョン 20H2
PC: ONE-NOTEBOOK OneMix3S
USBメモリ: Transcend USBメモリ 64GB USB 3.1 - TS64GJF790KBE

# USBメモリの作成

パーティションが32GBよりが大きい場合、エクスプローラからはFAT32でフォーマットできないため、`diskpart`ツールを使って作業を行います。
ショートカットキー`Win+R`で「ファイル名を指定して実行」から`diskpart`を実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8721/10914603-4ff1-d95d-8053-fc88cd0e4301.png)

`list disk` コマンドで選択するディスクを確認します、今回はサイズが56GBと表示されてる「ディスク 2」が対象です。

```
DISKPART> list disk

  ディスク      状態           サイズ   空き   ダイナ GPT
  ###                                          ミック
  ------------  -------------  -------  -------  ---  ---
  ディスク 0    オンライン           931 GB  1024 KB        *
  ディスク 1    オンライン           238 GB      0 B        *
  ディスク 2    オンライン            56 GB    55 GB
```

`select disk` コマンドで選択したあと`clean`コマンドを実行します。

```
DISKPART> select disk 2

ディスク 2 が選択されました。

DISKPART> clean

DiskPart はディスクを正常にクリーンな状態にしました。
```

`create partition` コマンドでプライマリパーティションを作成します。サイズは32GB以下の適当な容量を指定します。

```
DISKPART> create partition primary size=1000

DiskPart は指定したパーティションの作成に成功しました。

DISKPART> list partition

  Partition ###  Type                Size     Offset
  -------------  ------------------  -------  -------
* Partition 1    プライマリ             1000 MB  1024 KB
```

`format` コマンドでFAT32形式にクイックフォーマットします。

```
DISKPART> format fs=fat32 quick

  100% 完了しました

DiskPart は、ボリュームのフォーマットを完了しました。

DISKPART> exit
```

教本「1.1 ハローワールド」の手順に従い、EFIファイルを所定のディレクトリに格納してUSBメモリの作成は完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8721/24347cee-5493-3c4b-9c97-77d41eb9fcf6.png)

# UEFIから起動

作成したUSBを刺した状態でPCを起動、DELキーを連打するとUEFIが起動します。
うまくUSBメモリが認識されると "Save & Exit - Boot Override" の一覧に "UEFI: ＜USBメモリ名＞" が表示されるのでこれを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8721/471137d9-4e66-e45c-c6c1-b02db61e24f7.png)

無事に "Hello, world!" が表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8721/aeb758bf-164a-13e8-1717-0d8f69c5a5ad.png)
Dockerのimage作成ファイル(dockerfile)の書き方メモ

ちょくちょくDockerのイメージを作るためのDokcerfileを書くのですが毎回書き方を忘れるためメモとして残しておきます。



## FROM 
使うイメージを指定します。
指定方法は 以下の通り

```yml
# FROM: <イメージ名>:<タグ名>
FROM node:12
```

なお`linux/amd64`のようにプラットフォームも指定できます。


## COPY
localにあるファイルをイメージの中にコピーします。
自分がdocker化したいファイルやディレクトリを指定するときに使います。

```yml
# COPY: <ローカルでコピーするファイル> <コピーしたファイルの配置先>
COPY . /app
```

## RUN
コマンドを実行する時に使います。注意点ですが、RUNで指定されたコマンドはイメージのビルド時に実行されます。
なので、アプリケーションサーバーの起動などのコマンドを実行したら永遠にイメージビルドが終わらなくなります。

```yml
# RUN コマンド
RUN apt-get update
```

## CMD
コマンド実行する時に使います。CMDは完成したイメージからコンテナを作成し実行するときにコマンドが走ります。
なので、アプリケーションサーバーの起動など、コンテナが作成されてから即座に動いて欲しいコマンドを記載します。

```yml
# CMD ["<コマンド１>","<コマンド2>",...]
CMD ["apt-get", "update"]
```



## WORKDIR
RUN,CMDなどに記載されたコマンドを実行する際に、どのディレクトリで実行するかを指定します。

```yml
# WORKDIR 絶対パス
WORLDIR /app
```

## ENV 
文字通り環境変数を指定します

```yml
# ENV <key>=<value>
ENV NODE_VERSION=12
```

## EXPOSE
指定したポートを開けます。プロトコルを指定することもできます。

```yml
# EXPOSE <port> [<port>/<protocol>...]
EXPOSE 3333
EXPOSE 3333/udp
```

# 特定ファイルをビルド対象から外す
.dockerignoreというファイルを作れば、ビルドする際にそのファイルを除外できます。

例えば、npmにあるnode_modulesなどをCOPYに含めておくと、ローカルのOSとイメージのOSが違う場合エラーになる場合があります。
このような場合に、特定のファイルやディレクトリを除外するときに使います。

```.dockerignore
# comment
*/temp*
*/*/temp*
temp?
```

# docker-composeのイメージ指定
本筋からそれますが、docker-composeでイメージを指定する際に、dockerfileを指定できて便利なので記載しておきます


```
version: "2.4"
services:
  webapp:
    build:
      context: ./dir
      dockerfile: Dockerfile-alternate
      args:
        buildno: 1
```

contextでディレクトリを指定し、dockerfileでdockerfileのファイル名を指定します。
map()とfilter()の比較（備忘録）

<h4>TodoAppの作成時に、mapメソッドとfilterメソッドの違いがいまいちピンとこなかったので、
改めて調べなおした備忘録です。</h4>

[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map)によると、
 ***map( )***:  与えられた関数を配列のすべての要素に対して呼び出し、その結果からなる新しい配列を生成  
***filter( )***: 提供された関数によって実装されたテストに合格したすべての要素を含む新しい型付き配列を生成

<h4> 例：Todoアプリでイベントで発火する関数内でmap(),filter()を使用。  </h4>

```javascript
const tasks = 
[
     {
      id: 1,
      title: "買い物",
      completed: false
     },
     {
      id: 2,
      title: "英語の課題",
      completed: false
     },
　   {
      id: 3,
      title: "筋トレ",
      completed:true
     },
]
```


<h4>完了したtaskに、打ち消し線をひく時</h4>
同じ数の要素を返すが、要素の中のvalueは変化する（ここでは、completedプロパティのfalseとtrueが入れ替わっている） 

```javascript
toggleCompleted(id) {
      this.tasks = this.tasks.map((task) =>
        task.id === id ? { ...task, completed: !task.completed } : task
      );
    },

```

<h4>taskを削除する時</h4>
同じ数または、それより少ない数の要素を返す。要素内の変化はなし。

```javascript
deleteTask(id) {
        this.tasks = this.tasks.filter((task) => task.id !== id);
    },
```
ラジオボタンで全て選択されてしまう時

プログラミング初心者です

ラジオボタンを作ってる時写真のような状態になり、どうしてだろうと苦戦しました

![スクリーンショット 2021-05-08 22.34.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1362518/7bcadd97-182d-4c64-43f5-85c5bc1961b9.png)


原因は・・・
name属性が違っていたのです
name = 同じ値にしなければいけなかったんですね・・・

これに1時間くらい格闘してたんで、分かった時の感動すごかったです。
obd-python-gan-chapter2.2

# chapter2-2.py

```python
import chainer.optimizers as Opt
import chainer.functions as F
import chainer.links as L
from chainer import Variable, Chain, config

import numpy as np
#import matplotlib.pyplot as plt

### Generate data
np.random.seed(123)
D=100
N=2

xdata = np.random.randn(D*N).reshape(D,N).astype(np.float32)

def f(x):
    y=x*x
    return y

tdata = (xdata[:,1] > f(xdata[:,0])).astype(np.int32)

### Neural network
C=2
#NN_ver1 = Chain(l1=L.Linear(N,C))
NN = Chain(l1=L.Linear(N,4), l2=L.Linear(4,C))

"""
def model_ver1(x):
    y=NN.l1(x)
    return y
"""

def model(x):
    h=NN.l1(x)
    h = F.sigmoid(h)
    y = NN.l2(h)
    return y

optNN = Opt.SGD()
optNN.setup(NN)

loss_series = []
acc_series  = []

T = 20000
for time in range(T):
    config.train = True
    optNN.target.zerograds()
    ydata = model(xdata)
    loss = F.softmax_cross_entropy(ydata, tdata)
    acc = F.accuracy(ydata, tdata)
    loss.backward()
    optNN.update()
    loss_series.append(loss.data)
    acc_series.append(acc.data)

for time in range(0,T,100):
    print(time, loss_series[time], acc_series[time])
```

Result (20 seconds on obd)

0 0.6227948 0.77
100 0.5632122 0.77
200 0.54191923 0.77
300 0.5280521 0.77
400 0.51627535 0.77
...
19600 0.15089221 0.95
19700 0.15005276 0.95
19800 0.1492205 0.95
19900 0.14839555 0.95
【Swagger】オブジェクトの中に配列を書く方法

## はじめに

実務で `Swagger UI` を使用したときにレスポンスの形式で詰まった箇所がありましたので同じく詰まった方の参考になれば幸いです。

`Swagger` については、他にも多くの記事があるので今回は触れません。
参考にさせていただいた記事は参考文献として載せさせていただきました。

## レスポンス形式

基本的に **[Swagger Editor](https://editor.swagger.io/)** を参考にしております。

下のように `{}` の中で `[]` を入れ子にしております。

#### 想定しているレスポンス

```yml:swagger
{
  "pets": [
    {
      "pet_id": 1,
      "name": "ポチ"
    }
  ]
}
```

#### swaggerの記述例

```yml:swagger
paths:
  /pet:
    get:
      tags:
      - "pet"
      summary: "使用例"
      description: ""
      consumes:
      - "application/json"
      produces:
      - "application/json"
      responses:
        '200':
          description: "オブジェクトの中で配列の使用"
          schema:
            $ref: '#/components/schemas/pet'

components:
  schemas:
    pet:
      type: object
      properties:
        pets:
          type: array
          items:
            type: object
            properties:
              pet_id:
                type: integer
                format: int64
                description: ペットの識別ID
                example: 1
              name:
                type: string
                description: petの名前
                example: ポチ
```

## 参考文献

- [Swagger Editor](https://editor.swagger.io/)
- [Swaggerの記法まとめ](https://qiita.com/rllllho/items/53a0023b32f4c0f8eabb)
- [OpenAPI (Swagger) 超入門](https://qiita.com/teinen_qiita/items/e440ca7b1b52ec918f1b)
DjangoでviewsからHTML(templates)への値の渡し方

#概要
djangoの値をhtmlに渡すために必要なviewsの書き方を調べてきたので、よければお役に立ててください。また、ある程度djangoを触ってる人向けに書いてあります。

#開発環境
Mac
djagno=3.2.1
python=3.9.1

#きっかけ
viewsからhtmlに値を渡す際に、querysetが表示されてしまって、なかなか自分の思い通りにならなかったので、忘備録兼、記事にしたいと思います。

#views.pyの書き方
まずは、関数での値の渡し方
()の中の数字はそれと同じものを指しています。

```
views.py
def hello(request):
    hello(①) = "Hello World"
    context = {
        'hello'(②): hello(①)
    }
    return render(request, 'hello.html', context)

hello.html
<!DOC...
<body>
<h1>{{ hello(②) }}</h1>
</body>
```


このcontextというのに入れるのが基本系だと思います。また、辞書型で渡さないとエラーになってしまうため、このような書き方をしています。公式ドキュメント通りだとこの書き方だと思います。また、models.pyを作って、簡単にadmin.pyで表示、編集。それの値を受け取り、関数を使って、値を渡してみます。
admin.pyで保存したのは
id = 1 = Hello World
id = 2 = Goodbye World
の2つです。1つしか表示しない場合はfor文はいらないですが、せっかくなので、同時に紹介したいと思います。

```
models.py
class Greetings(models.Model):
      greeting = models.CharField(max_length=20)

views.py
def greeting(request):
    greetings = Greetings.objects.all()
    context = {
        'greetings'(①): greetings,
    }
    return render(request, 'greeting.html', context)

hello.html
{% for greeting(②) in greetings(①) %}
<h1>{{ greeting(②) }}</h1>
{% endfor %}

```
次は汎用ビューでの値の渡し方です。greeting.htmlの中身は上のものと一緒です。

```
models.py
class Greetings(models.Model):
      greeting = models.CharField(max_length=20)

views.py
class GreetingView(TemplateView):
    model = Greetings
    template_name = 'greeting.html'
    
    #この関数が、classからhtmlに値を渡すおまじないになります。２行目まではほとんど一緒だと思います。
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['greetings'] = Greetings.objects.all()
        return context
```

こうすると、Hello World と GoodBye World が一緒に表示されます。
また、汎用ビューのDetailViewを使う際は、id毎に別々のgreetingを呼ぶことができます。
自分でも確認ができてよかったです。次は、modelのフィールドについて話してみようと思います。
Python ネストされたzipを全て解凍する

# 2021/05/14 追記
### 既に解凍済のzipは解凍しないように制御処理を追加

# Pythonでネスト(入れ子)されたzipファイルを全て解凍する

## 環境
- Windows
- Python3

## コード
``` Python3
import os
import zipfile


PATH = 'path'


def extract(zipFile, dst):
    with zipfile.ZipFile(zipFile) as z:
        z.extractall(dst)


def func(path):
    # ///// point 1 /////
    for pathname, dirnames, filenames in os.walk(path):
        for filename in filenames:
            if filename.endswith('.zip'):
                if not os.path.exists(pathname + '/' + os.path.splitext(filename[0]):
                   zipFile = pathname + '/' + filename
                   dst = pathname + '/' + os.path.splitext(filename)[0]
                   extract(zipFile, dst)
                   # ///// point 2 /////
                   func(dst)


def main():
    func(PATH)


main()
```

## コードのポイント
### point 1
- os.walkを使い, 指定パス以下を再帰的に探索. 記述量が少ない

### point 2
- zipファイル解凍後は, 解凍後のパスを再帰処理しネストされたzipやディレクトリも全て解凍/探索する
【初心者向け】メモ帳でwebサイトを作るとなぜ作りにくいのかを解説

#どうも7noteです。メモ帳でwebサイトが作りにくい理由を徹底解説。初心者よ有名エディタを使え！

コーディングやプログラミングをする際に必須ともいえるのが**「エディタ」**。
もちろんメモ帳でもコーディングやプログラミングができますが、エンジニアとして働いている人やyoutubeなどの動画で解説している人たちはそれぞれエディタを使っているのでしょうか？

それはメモ帳ではコーディングがしにくいからです。
特に今回はweb制作に焦点を当てて、メモ帳の使いにくさを解説。

## なぜメモ帳だとwebサイトを作りにくいのか。

### 「単色だから識別しにくい」

メモ帳では白背景に黒一色です。（設定でかえれるかもですが。）
しかし大概のエディタはHTML要素やCSSに色が付いて識別しやすくなっています。

（他エディタの例）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/61f50e11-c0c1-1982-e86c-ec8fb1643978.png" width="300">

### 「不可視文字が見えない」

「` `(半角スペース)」
「`　`(全角スペース)」
「`	`(TAB)」
「` `(改行位置)」

これらの要素が全く見えません。真っ白です。そのため余計なスペースが入っているなどに気づかず表示が崩れてしまい、原因がわからないまますっと悩んでしまうみたいなことになってしまいます。

### 「拡張ツールが使えない」

- インデントも自動で揃わない
- 好きなようにカスタマイズもできない
- Emmentで短縮入力できない（「div」のあとにTABキーを押すと`<div></div>`が自動入力される等）

こんなエディタ使えません（泣）

## メモ帳を卒業したいならこのエディタがオススメ！

https://twitter.com/DRECOM_TECH/status/1119505630845255680?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1119505630845255680%7Ctwgr%5E%7Ctwcon%5Es1_c10&ref_url=https%3A%2F%2Fpublish.twitter.com%2F%3Fquery%3Dhttps3A2F2Ftwitter.com2FDRECOM_TECH2Fstatus2F1119505630845255680widget%3DTweet

好みにもよりますが、様々な調査やTwitterアンケートで人気なのは**「Visual Studio Code」**ですね。
他のアンケートなんかを見てもほとんど1位は**「Visual Studio Code」**でした。
いろいろ試してみて、自分なりに納得のいくエディタを使いましょう！

## 結論

**「メモ帳でもweb制作はできる。・・・が、既存の有名ブラウザよりも開発しにくいので開発ストレスがたまるし効率も悪い。」**

メモ帳でも開発やweb制作はできます。はじめうちはお試しでメモ帳で作成するところから初めて見るのは全然OKだと個人的には思います。

ただずっとメモ帳で開発し続けている人にはまだあったことがないのでやはり本格的に取り組んでいくのであれば何かしらのエディタは必要になってくると思います。

経験者さんがもし読まれていましたら、オススメのエディタなどぜひコメントください。誰かの助けになるかもしれません。

#### おそまつ！
~ Qiitaで毎日投稿中!! ~
[【初心者向け】WEB制作のちょいテク詰め合わせ](https://qiita.com/7note)
Vue.jsの基本的なこと

#ディレクティブ
ディレクティブとは接頭辞 v- が付いた属性のこと
今回は基本的なディレクティブについてまとめます。

##v-text

```html:index.html
  <body>
    <div id="text">
      <div v-text="message"></div>
    </div>
  </body>

<script>
  var text_hello = new Vue({
    el: '#text',
    data: { message: 'Hello World!' }
  })
</script>
```

上記のソースのスクリプトでtext要素にmessageデータを定義し、
html内でv-textを使用しmessageを呼び出すことで定義したmessageの内容が表示されます。


##v-for

```html:index.html
  <body>
    <div id="text">
      <li v-for="(msg, key) in message">
        {{ key }}:{{msg}}
      </li>
    </div>
  </body>

<script>
  var text_hello = new Vue({
    el: '#text',
    data: { message: {
              sample1:'hello',
              sample2:'world',
              sample3:'hello_world'
      }
    }
  })
</script>

```
v-forで配列の内容をループします。
今回keyとvalue両方を出そうと思い
```
<li v-for="(msg, key) in message">
```
とすると想定の結果とは逆でしたので今後気を付けたいところ

![WS000001.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588477/223c05b9-b898-a74d-1def-8c83c72d4fab.jpeg)

##v-if
```html:index.html

  <body>
    <div id="text">
      <input type="checkbox" @click="change" checked>
      <span v-if="seen">
        <li v-for="(msg, key) in message">
          {{ key }}:{{msg}}
        </li>
      </span>
    </div>
  </body>

<script>
  var text_hello = new Vue({
    el: '#text',
    data: { message: {
              sample1:'hello',
              sample2:'world',
              sample3:'hello_world'
            },
            seen: true
    },
    methods: {
    change: function(e) {
      this.seen = e.target.checked
      }
    }
  })
</script>
```
上記ではチェックボックスの値でtrue,falseを認識し、messageを表示するかを制御します。
###チェックあり
![WS000002.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588477/80a62db2-fe3b-8e25-d818-e16801302508.jpeg)

###チェックなし
![WS000003.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588477/c0a396a8-8511-9bb4-569e-a82065fc7e91.jpeg)




#参考
[Vue.js入門](https://www.tohoho-web.com/ex/vuejs.html#directive)
Nullish coalescing を今更ながら知ったという話

#初めに

最近になってNullish coalescing というのを知りました。。今更ですいません。

最近までこう書いていた。

```typescript
type FetchData = {
  data?: any
}
// API等から取得したデータを想定
const fetchData: FetchData = {
  data: null 
}
// 今までこう書いていた。
const result = fetchData.data ? fetchData.data : "";

```

これでよくなってた。

```typescript
type FetchData = {
  data?: any
}
const fetchData: FetchData = {
  data: null
}
const result = fetchData.data ?? ""; // この場合に右辺にくるのは、null、もしくはundefindのとき

```

ちなみにの話

```typescript
type FetchData = {
  data?: any
}
const fetchData: FetchData = {
  data: false
}
const result = fetchData.data ?? "";
console.log(result) // false 

```
この場合の結果はfalseになります。あくまでもnullとundefindの時に右辺になると覚えておきましょう。
なお、JavaScriptのES2015に変換をされた結果は下記になります。

```javascript
"use strict";
var _a;
// API等から取得したデータを想定
const fetchData = {
    data: false
};
const result = (_a = fetchData.data) !== null && _a !== void 0 ? _a : "";
console.log(result); // false 

```
参考記事

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator
ドラッグアンドドロップでxlsファイルを読み込む

``` python:ddExcel.py
import pandas as pd
import os
import io
import sys

def MojibakeTaisaku():
    # 出力の文字化け対策
    sys.stdin = io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8')
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
    sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')


def main(wbName):
    MojibakeTaisaku()
    print(pd.__version__)

    # pyファイルのあるフォルダに移動する
    os.chdir(os.path.dirname(os.path.abspath(__file__)))

    df = pd.read_excel(wbName, index_col=0)
    print(df)

if __name__ == '__main__':
    # ドラッグアンドドロップでxlsファイルを読み込む
    wbName = sys.argv[1]
    main(wbName)
    input() # ターミナルが勝手に閉じるの防止用　何か入力すれば閉じる


```
redashを使うときのsecurity groupの設定

redashというBIツールがある。
これからAWS RDSへのアクセス許可は```52.71.84.157```を許可すれば良い。

![スクリーンショット 2021-05-08 21.30.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283557/66a60219-7b67-df56-eb58-d7d7be97fef4.png)


https://redash.io/help/user-guide/getting-started

めっちゃサラッと書いてあって見つけらなかった。
【Docker】コンテナの停止・削除、イメージの削除、ディスク容量の圧縮方法に関して

Dockerのおすすめコマンドの紹介をします。
以下の4つはよく使うので覚えておくと便利です！

## 全コンテナの停止
```terminal:ターミナル
docker stop $(docker ps -q)
```

## 全コンテナの削除
```terminal:ターミナル
docker rm $(docker ps -q -a)
```

## 全イメージの削除
```terminal:ターミナル
docker rmi $(docker images -q)
```

## 全ネットワークの削除
```terminal:ターミナル
docker network prune
```

## ディスク容量の圧縮
こんな感じのエラーが出ました。

```
ERROR: Service 'test' failed to build: failed to copy files: failed to copy directory: Error processing tar file(exit status 1): write test/..... no space left on device
```

デバイス内のディスク容量不足とエラーが出ますが、「容量不足じゃないぞ」となることがあります。
溜まったボリュームとキャッシュをすべて消してくれる以下のコマンド2つで解決します。

```terminal:ターミナル
docker volume rm `docker volume ls -q -f dangling=true`
docker builder prune
```
Docker Imageをリポジトリにアップする

Docker Imangeをリポジトリに登録する方法をメモしておきます。

# 前提条件
`docker.com` にアカウントが作成済みであること
Docker Desktop for windowsがインストール済みであること

# 1. docker imageを作成
docker-compose、もしくはDockerfileを利用し、docker imageを作成します。

`docker image build -t my-node `

[参考] Dockerfile (nodeのDockerファイル)

``` Dockerfile:dockerfile
FROM node:14-alpine
WORKDIR /opt/app

# apk setup
RUN apk update && \
 apk --no-cache add bash curl && \
 apk --no-cache add nmap && \
 apk --no-cache add make gcc g++ python2 && \
 apk --no-cache add git 

# Copy package.json to container and install
COPY package.json /opt/app
RUN npm install

# Copy current source to the image
COPY . /opt/app

CMD ["npm", "start"]
```

# 2. 作成されたDocker Imageに名前、タグをつける
Dockerリポジトリにアップするには、`docker.com`の**アカウント名をImage名に付ける**必要があります。

` docker tag node:my-node [docker.comのアカウント名]/node:my-node `

# 3. ローカルPCより、docker.comにログインする

``` command
> docker login
Authenticating with existing credentials...
Login Succeeded
```

# 4. DockerHubへリポジトリ登録
``` command
> docker push [docker.comのアカウント名]/node:my-node 
The push refers to repository [docker.io/[docker.comのアカウント名]/node:my-node]

7: digest: sha256:285bc***************************** size: ooo
```

# 5. Docker Desktop for Windowsで登録を確認
無事に登録されていれば、`REMOTE REPOSITORY`にイメージが表示されるはずです。
![2021-05-08_14h29_13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626057/245b814d-e0cf-26bd-2218-0fb7f2ba7d09.png)
Dockerfileにfrourioのインストールを組み込む - volumes + Webpackの問題

DockerfileにfrourioのCLIインストールを記載してビルドしました。
その際、出来上がったコンテナでWebpackの監視が正常に動作していないことに気づきました。

:::note info
結論から記載すると、Webpackの公式サイトに記載がありますがNFS上の変更イベントは受け取れません。
docker-compose.ymlのvolumes上のファイルを監視する場合、ポーリングで変更を監視することになります。
:::

```docker-compose.yml
version: '3.7'
services:
  app:
    # volumes上のファイルをWebpackで監視する場合はポーリングになります
    volumes:
      - /test/:/var/www/html/
```

frourioのwebpackの設定に下記を追加します。
※下記はfrourioでのインストール後に設定する場合のパスになります

```server/webpack.config.js
  // 下記を追加
  watchOptions: {
    ignored: ['**/node_modules'],
    aggregateTimeout: 200,
    poll: 1000
  },
```

Next.js を選択している場合、プロジェクトルートに「next.config.js」を追加します。

```next.config.js
module.exports = {
  webpackDevMiddleware: config => {
    config.watchOptions = {
      ignored: ['**/node_modules'],
      aggregateTimeout: 200,
      poll: 1000
    }

    return config
  }
}
```

除外設定に「node_modules」を追加していますが、監視が必要な方は除いてください。

:::note info
※Dockerfileにfrourio自体のインストールを組み込む場合、いろいろ面倒な処理が必要になります。
:::
【Vue.js】v-ifとv-showの違い

## はじめに
仕事で使う事になったので1からVue.jsについて学んだ（元々Angularでプロダクト開発をやっていた事はあるがAngularはだめか・・・）。
ちゃんと覚えておかないとまずそうな事を備忘録として1つ1つ残しておく。

## v-ifとv-showの違い
これまた見た目の動きは同じ（真偽値の条件で表示・非表示を切り替える）だが、動きには大きな違いがあるのでちゃんと使い分けないといけない。
それぞれの違いは以下の表のとおりで、使い所も違っている。

| # | 内部の動き | デメリット | 使い所 |
|:-:|---|---|---|
| v-if | HTMLに要素を描画する・しないで表示・非表示を切り替える | 表示・非表示が変わるたびに再描画されるのでレンダリングのコストが高くなる | 初期時の表示制御など頻繁でない表示切替に用いる |
| v-show | 常にHTMLには描画されるが、styleに"display: none;"を付与する・しないで表示・非表示を切り替える | ・初期時に必ず描画されるので初期時のレンダリングのコストが高くなる<br>・template構文が使えない<br>・elseに相当するものがないので自前で真偽値の逆バージョンを用意する必要がある | 高頻度な表示切替に用いる |

※レンダリングのコストが高くなる＝Webサイト動作が遅くなる

実際の動きは以下の通り。
![ezgif.com-gif-maker.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/3908f480-79ab-3d97-93db-4f702373f6c5.gif)
動画のソースコードは以下。

```html:sample.html
<body>
    <div id="app">
        <button @click="ok = !ok">ボタン</button>
        <p v-if="ok">If</p>
        <p v-show="ok">Show</p>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                ok: true
            }
        })
    </script>
</body>
```

※v-showのデメリット「template構文が使えない」について、実際にtemplate構文を使うと以下のように`templateタグ`が`display: none;`になるだけで、template内部は表示されてしまうので使えない。**（templateタグは実際には描画されないので見えないが）。**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/75bb0ca5-048c-d0fe-81d9-4671737d7d9c.png)

```html:sample.html
<body>
    <div id="app">
        <template v-show="ok">
            <p>隠したい</p>
        </template>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                ok: false
            }
        })
    </script>
</body>
```

## Vue.jsの勉強メモ一覧記事へのリンク
Vue.jsについて勉強した際に書いた勉強メモ記事のリンクを集約した記事。

- https://qiita.com/yuta-katayama-23/items/dabefb59d16a83f1a1d4
laravel-adminでDashboardにbladeを表示する

備忘録。

```diff_php:app/Admin/Controllers/HomeController.php
        return $content
            ->title('Dashboard')
-           ->description('Description...')
-           ->row(Dashboard::title())
-           ->row(function (Row $row) {
-
-               $row->column(4, function (Column $column) {
-                   $column->append(Dashboard::environment());
-               });
-
-               $row->column(4, function (Column $column) {
-                   $column->append(Dashboard::extensions());
-               });
-
-                $row->column(4, function (Column $column) {
-                    $column->append(Dashboard::dependencies());
-                });
-            });
+           ->view('welcome');
```
[VirtualBox/CentOS Stream 8]VirtualBox をインストールして、iso ファイルをダウンロードする流れ

この記事では、VirtualBox をインストールして、そこに入れる OS の iso ファイル（ここでは例として、CentOS Stream 8）をダウンロードする流れについて記載します。

# 前提事項

- VirtualBox バージョン
    - 6.1.22
- ダウンロードする iso ファイルの OS
    - CentOS Stream 8
- 本記事でインストールおよびダウンロードを行う端末の OS
    - Windows 10（ただ、mac でもそこまで大きく流れは変わらないと思います）

# VirtualBox のインストール

下記のダウンロードページにアクセスします。

https://www.virtualbox.org/

「Download VirtualBox 6.1」をクリックします

![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1435607/5871db41-972c-e9ef-d152-ba81e85b18ad.png)

自端末の OS を選択し、VirtualBox のインストール用ファイルをダウンロードして、実行します。

![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1435607/2a759274-8ce3-12b8-cc96-3bed5630b9da.png)

VirtualBox のインストールを開始します。
「Next」をクリックします。

![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1435607/2b747cde-1fc2-9f9f-2219-1d8f6e01589a.png)

インストール先を確認し、「Next」をクリックします。

![004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1435607/4db8a0fa-4000-714d-57ea-8a49dc24231f.png)

「Next」をクリックします。

![005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1435607/7051f106-d415-459a-d94f-ec5880630085.png)

「Yes」をクリックします。

![006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1435607/c58c44fd-125c-15f7-0892-53cc983edae3.png)

「Install」をクリックします。

![007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1435607/c5ed5ba0-2d9b-f3db-96fc-8799704e2569.png)

「インストール」をクリックします。

![008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1435607/43fdc6cc-ddab-2001-5c28-0965f0e1e575.png)

チェックボックスのチェックを外し、「Finish」をクリックします。

![009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1435607/9ee9c4b8-ed90-82c6-afaa-44962ef8eb84.png)

以上で VirtualBox のインストールは完了となります。


# iso ファイルのダウンロード

VirtualBox をインストールした後は、VirtualBox 上で動かしたい OS の iso ファイルをダウンロードしましょう。
CentOS や Ubuntu 等であれば、「CentOS iso download」とか、「Ubuntu iso download」などと検索すれば、ダウンロードページが出てくると思います。
ここでは例として、CentOS Stream 8 の iso ファイルをダウンロードしてみたいと思います。

まず、CentOS の iso ダウンロードページにアクセスします。

https://www.centos.org/download/

CentOS Stream 8 の x86_64 を選択します。

![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1435607/47c117fb-bd7f-7faa-41ee-739f6bb9ae54.png)

各種ダウンロード先のリンクが表示されるので、好きなところを選択しましょう。（場所によってはダウンロードが遅い等あるかもしれません）

![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1435607/debc1d95-f64e-ae3d-7980-887837b662b0.png)

dvd の iso のファイルをダウンロードしましょう。

![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1435607/9ab1259e-21e6-ad4a-0c25-2d7ad6aa46ec.png)

以上で、iso ファイルのダウンロードは完了となります。

# おわりに

いかがでしたでしょうか。
本記事では、VirtualBox をインストールして、そこに入れる OS の iso ファイル（ここでは例として、CentOS Stream 8）をダウンロードする流れについて解説しました。
検索すればすぐに出てくる内容かもしれませんが、私の他の記事で参照したいと考えており、今回記事にさせていただきました。
mkdocsをお試し利用


# mkdocsとは

マークダウンで書かれたドキュメントからサイトを生成するツール
> [https://www.mkdocs.org/](https://www.mkdocs.org/)
> Overview
MkDocs is a fast, simple and downright gorgeous static site generator that's geared towards building project documentation. Documentation source files are written in Markdown, and configured with a single YAML configuration file. Start by reading the introduction below, then check the User Guide for more info.

皆で編集するwiki的な使い方には向いてないかもしれないが、
README的なドキュメント公開方法としては便利かもしれない。git管理もできそう。

# install

以下の環境にインストールする

```
OS: ubuntu18.04
CPU: corei5
Memory: 8GB
```

コマンド

```
pip install mkdocs
```

myprojectを作成

```
mkdocs new my-project
cd my-project
```

実行

```
$ mkdocs serve
INFO    -  Building documentation...
INFO    -  Cleaning site directory
[I 160402 15:50:43 server:271] Serving on http://127.0.0.1:8000
[I 160402 15:50:43 handlers:58] Start watching changes
[I 160402 15:50:43 handlers:60] Start detecting changes
```

その後、[http://127.0.0.1:8000](http://127.0.0.1:8000)にブラウザアクセスするとマークダウン形式のドキュメントが表示される。


# 参考
[https://www.mkdocs.org/](https://www.mkdocs.org/)
Python 環境構築 obd

obdのマシンでの練習のための備忘録

(1)

```shell
$ conda create -n py37_GAN python=3.7 anaconda
```

(2)

```shell
$ conda activate py37_GAN
```

```
(py37_GAN) $ conda install -c anaconda chainer

Collecting package metadata (current_repodata.json): done
Solving environment: done


==> WARNING: A newer version of conda exists. <==
  current version: 4.9.2
  latest version: 4.10.1

Please update conda by running

    $ conda update -n base -c defaults conda



## Package Plan ##

  environment location: /home/[user_name]/.pyenv/versions/anaconda3-5.2.0/envs/py37_GAN

  added / updated specs:
    - chainer


The following packages will be downloaded:

    package                    |            build
    ---------------------------|-----------------
    ca-certificates-2020.10.14 |                0         128 KB  anaconda
    chainer-6.3.0              |             py_0         671 KB  anaconda
    libprotobuf-3.13.0.1       |       hd408876_0         2.3 MB  anaconda
    openssl-1.1.1h             |       h7b6447c_0         3.8 MB  anaconda
    protobuf-3.13.0.1          |   py37he6710b0_1         700 KB  anaconda
    typing-3.7.4.3             |           py37_0          12 KB  anaconda
    ------------------------------------------------------------
                                           Total:         7.6 MB

The following NEW packages will be INSTALLED:

  chainer            anaconda/noarch::chainer-6.3.0-py_0
  libprotobuf        anaconda/linux-64::libprotobuf-3.13.0.1-hd408876_0
  protobuf           anaconda/linux-64::protobuf-3.13.0.1-py37he6710b0_1
  typing             anaconda/linux-64::typing-3.7.4.3-py37_0

The following packages will be SUPERSEDED by a higher-priority channel:

  ca-certificates                                 pkgs/main --> anaconda
  openssl                                         pkgs/main --> anaconda


Proceed ([y]/n)? yy
Invalid choice: yy
Proceed ([y]/n)? y


Downloading and Extracting Packages
typing-3.7.4.3       | 12 KB     | ########################################################################################## | 100% 
ca-certificates-2020 | 128 KB    | ########################################################################################## | 100% 
libprotobuf-3.13.0.1 | 2.3 MB    | ########################################################################################## | 100% 
openssl-1.1.1h       | 3.8 MB    | ########################################################################################## | 100% 
protobuf-3.13.0.1    | 700 KB    | ########################################################################################## | 100% 
chainer-6.3.0        | 671 KB    | ########################################################################################## | 100% 
Preparing transaction: done
Verifying transaction: done
Executing transaction: done
```

(3)

```shell 
$ conda install -c anaconda chainer
```