OmniAICreator/Qiita-1.07M huggingface dataset:
【Java文法】例外処理

こんにちは、コイキングです。

本記事では'例外処理'について、説明したいと思います。

******

# 1. 例外処理とは?
例外処理はプログラムの実行中に予想されていない結果が発生した際の対応を言います。

例えるとコンソールからユーザー入力で'数字データ'を入力するべきものを'文字列データを入力してもらい'、文字列のデータを数字変数に代入しようとする場合
プログラムは例外を発生させます。

上記のような状況で **1) 例外発生の理由をログなどで知らせたり、2) 例外が発生した際に必要なロジックを実行すること**などを例外処理で担います。

# 2. try-catch構文
try-catch構文は **例外が発生が予想されたり、必ず例外処理をしないといけないコード囲み例外を処理**します。

例外発生が予想される所のコードをtry構文で囲んで、catch構文に例外を処理するロジックを記載します。

```
File file = new File("newFile.txt");
//file.createNewFile(); // ファイル作成時に例外処理をしないとコンパイルエラーが発生
try {
    file.createNewFile(); // 例外発生がよそされるところをtry構文に囲む
} catch (Exception e) {
    e.printStackTrace();
}
```

# 3. メソッドにthrowsを宣言する
メソッドにthrowsを宣言すると、メソッド内部では別途try-catch構文をセットする必要はありません。
しかし、メソッドにthrowsを宣言するだけで終わりません。
**throws宣言の意味は例外処理をメソッドを呼出した所で行うという意味で**メソッドを呼出した所でtry-catch構文を使い例外処理をする必要があります。

```
// メソッドにthrowsを付けると例外処理をメソッドの呼出した所で行える。
try {
    writeFile(file);
} catch (Exception e) {
    e.printStackTrace();
}

// 呼出した所で処理する例外の種類は複数セットできます。
// ex) throws IOException, Exception {...
public static void writeFile(File file) throws IOException {
    List<String> list = new ArrayList<String>();
    list.add("ArrayList-String01");  // Index 0 
    list.add("ArrayList-String02");  // Index 1
    list.add("ArrayList-String03");  // Index 2
		
    BufferedWriter wr = null;
    wr = new BufferedWriter(new FileWriter(file, true));
    for (String var : list) {
        wr.append(var);
        wr.append("\n");
    }
    wr.flush();

    if (wr != null) {
        wr.close();
        wr = null;
    }
}
```

# 4. throwにて例外を発生させる
throwを使うとわざと例外を発生させることができます。

```
try {
    if (file.exists()) {
        System.out.println(file.getCanonicalPath());
        throw new Exception("file exist!!");
    }
} catch (Exception e) {
    e.printStackTrace();
    System.out.println("file delete!!");
    file.delete();
}
```


******
※ 例示コード
https://github.com/leeyoungseung/algorithmBasic/blob/master/algorithm/src/basic/B_14_Exception.java

※ 韓国語のポストは以下のURLで確認できます。
https://koiking.tistory.com/86?category=1068655
VSCodeを日本語化にする

# はじめに
Visual Studio Code（以下、VSCode）を日本語化する手順をまとめた

　※VSCodeのインストール手順は下記参考

https://qiita.com/wooooo/items/c2e6254b1fb9a6eefff8

# 手順
1.VSCodeを起動
![スクリーンショット 2022-01-10 17.54.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/39f22238-b26d-c911-7f1f-107c25ea96e6.png)


2.左メニューの「Extensions」を押下
![スクリーンショット 2022-01-10 17.45.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/857398ec-8b7d-1842-e3e2-2d2e73f7fa0e.png)

3.検索ボックスに「japanese」を入力
![スクリーンショット 2022-01-10 17.49.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/99a8806b-651a-c845-13b3-91305fb23606.png)

4.「Japanese Language Pack for VS Code」を選択して「Install」を押下
![スクリーンショット 2022-01-10 17.50.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/eb5c4c0e-eeb9-990d-e80f-061f1937879b.png)

5.インストールされると、右下にRestartするか聞かれるので、「Restart」を押下
![スクリーンショット 2022-01-10 17.51.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/92753e2d-b7a2-88c2-2206-1355cf0b63b2.png)


日本語化されてますね〜
![スクリーンショット 2022-01-10 17.55.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/1de2c446-c43c-143a-3724-1c564ae25745.png)

拡張機能を追加していきましょう！！
2次元で座標を回転させる

# 概論
座標(x,y)は、複素数で $x+jy$ で表すことできる。

$x+jy$ から $\theta$ [rad]回転させるには、 $e^{jθ}$ をかければよい。

$e^{jθ}=cosθ+jsinθ$ である。
また、

```math
\begin{align}
&cosθ+jsinθ　\equiv \;\; 
\end{align}
\begin{pmatrix}
cosθ & -sinθ   \\
sinθ & cosθ
\end{pmatrix}
```
である。

したがって、
複素数の場合は　$(cosθ+ jsinθ)$　を、
行列の場合は

```math
\begin{pmatrix}
cosθ & -sinθ   \\
sinθ & cosθ
\end{pmatrix}
```
を用いればよい。

※3次元の場合は、クォータニオン（四元数）や行列を使って回転させる。

# 虚数単位
$x^2+1=0$を解くと、$x=±\sqrt-1$となる。
この$\sqrt-1$を虚数単位として、jで表す。
$j^2 = -1$となる。

(-1)をかけることは反時計回りに180度回転である。
$j^2 = -1$であるから、jをかけることは反時計回りに90度回転である。
jを使うことで、2次元を扱うことができる。

# 1に当たる行列
 5 × 1 = 5である。

行列の場合で考えると


```math
\begin{pmatrix}
a & b \\
c & d 
\end{pmatrix}
\times
\begin{pmatrix}
1 & 0 \\
0 & 1 
\end{pmatrix}
=
\begin{pmatrix}
a & b \\
c & d 
\end{pmatrix}
```
である。

ゆえに、次の行列は1に相当する。

```math
\begin{pmatrix}
1 & 0 \\
0 & 1 
\end{pmatrix}
```


# -1に当たる行列
(-1)×1 = (-1)である

行列の場合で考えると

```math
(-1)
\times
\begin{pmatrix}
1 & 0 \\
0 & 1 
\end{pmatrix}
=
\begin{pmatrix}
-1 & 0 \\
0 & -1 
\end{pmatrix}
```
である。

ゆえに、次の行列は(-1)に相当する。

```math
\begin{pmatrix}
-1 & 0 \\
0 & -1 
\end{pmatrix}
```


# jに当たる行列
$j×j = (-1)$である。

行列の場合で考えると

--------
```math
\begin{pmatrix}
0 & -1 \\
1 & 0 
\end{pmatrix}
\times
\begin{pmatrix}
0 & -1 \\
1 & 0 
\end{pmatrix}
=
\begin{pmatrix}
-1 & 0 \\
0 & -1 
\end{pmatrix}
```
である。

ゆえに、次の行列は$j$に相当する。

```math
\begin{pmatrix}
0 & -1 \\
1 & 0 
\end{pmatrix}
```

# 複素数
複素数$x+jy$は、$x×1\;+\;y×j$である。


行列で考えると

```math
x
\times
\begin{pmatrix}
1 & 0 \\
0 & 1 
\end{pmatrix}
+ \; y
\times
\begin{pmatrix}
0 & -1 \\
1 & 0 
\end{pmatrix}
=
\begin{pmatrix}
x & -y \\
y & x 
\end{pmatrix}
```
である。

ゆえに、次の行列は複素数$x+jy$に相当する。

```math
\begin{pmatrix}
x & -y \\
y & x 
\end{pmatrix}
```

# 回転の例
## 例1
$2+j3$ を45度反時計回りに回転させる。

![２＋ｊ３.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154307/81cc1ad7-a841-869d-ec90-0f11e295d3be.jpeg)


＜計算＞
(1) 45度
180度がπ　[rad]だから、45度は$\frac{4}{π}$ [rad]である。
(2) 回転させる
$(2+j3) \times \; e^{\frac{4}{π}}$
$=\;(2+j3) \times  (cos({\frac{4}{π}}) + jsin({\frac{4}{π}}))$ 
$\fallingdotseq -0.71 + j3.5$

![45度回転.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154307/ff635df8-beaf-044c-e355-1763a48c5776.jpeg)


## 例2
$2+j3$ を60度反時計回りに回転させる。

＜計算＞
(1) 60度
180度がπ　[rad]だから、60度は$\frac{3}{π}$ [rad]である。
(2) 回転させる
$(2+j3) \times \; e^{\frac{3}{π}}$
$=\;(2+j3) \times  (cos({\frac{3}{π}}) + jsin({\frac{3}{π}}))$ 
$\fallingdotseq -1.6 + j3.2$

![60度回転.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154307/1ddc25ce-e0c5-79d8-eb36-a88cf2ee5cd1.jpeg)
SpringBoot Bean Validation：フィールド名を出力する

## はじめに
Bean Validationのエラーメッセージにフィールド名を出力させるために、プロパティファイルに {0} を追記したが、「{0}を入力してください。」と表示される。
message.propertiesに記述していたのをValidationMessages.propertiesに変えてみたり、@Validを@Validatedに変えたりしたのだが、改善せず。
当たり前に使っていたのに、いざ上手くいかないと、何が原因なのか検討がつかず。解決するまでに、結構は時間を使った・・・。

どうようにお困りの方もいるかと思い記録しておきます。

## 不足していたのはMessageSourceの利用
bindingResultに登録された時点で、{0}にフィールド名が置き換わると思い込んでいたが、MessageSourceを使って置き換える必要がありました。（フォームだと自動的にやってくれていたのかも？）

### Controller（抜粋）
```java
import org.springframework.context.MessageSource;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("sample/api")
public SampleController {

  @Autowired
  private MessageSource messageSource;

  SampleResponse index(@Validated @RequestBody SampleRequest request, BindingResult bindingResult) {
    if (bindingResult.hasErrors()) {
      bindingResult.getAllErrors().stream()
        .map(m -> messageSource.getMessage(m, Locale.getDefault()))
        .forEash(System.out::println);
    }
    return new SampleResponse();
  }
}
```

### ValidationMessages.properties
```java
javax.validation.constraints.NotNull.message={0}を入力してください。
```

### messages.properties
``` java
name=名前
```

## References
* https://kntmr.hatenablog.com/entry/2017/09/11/233032
【競プロ典型90問】006の解説（python）

## 概要
[競プロ典型90問](https://atcoder.jp/contests/typical90)の解説記事です。
解説の画像を見ても分からない（~~理解力が足りない~~）ことが多々あったので、後で解き直した際に確認できるようまとめました。

※順次、全ての問題の解説記事を挙げていく予定です。
※★6以上の問題は難易度的に後回しにしているため、投稿時期が遅くなる可能性があります。（~~代わりに丁寧に解説してくれる方いたらぜひお願いします~~）

## [問題006-Smallest Subsequence](https://atcoder.jp/contests/typical90/tasks/typical90_f)

### 問題
英小文字のみからなる、長さ N の文字列 S が与えられます。
長さが K である S の部分列のうち、辞書順で最小であるものを出力してください。

### 解き方
まず初めに、部分列を全列挙してから辞書順最小を得る方法が考えられますが、この考えではn文字からk文字を選んだ時の取り出し方 $nCk$ の全列挙になるため、k = 1, n 以外の時は、$O(N^2)$以上となりTLEになってしまいます。

ここで辞書順というのは、先頭の文字から順に順番が決まっていくため、先頭の文字が決まっているときにその後の文字はどうでも良いことが分かります。
（1文字が"a"の文字列Aと"b"の文字列BがあったらAの２文字目以降が全部"z"だろうが関係ない。）
そのため、この問題は前側から貪欲に辞書順最小の文字を採用していけば良い問題ということが分かりました。

実装の流れとしては、
1. アルファベットの出現箇所をメモする
2. aから順番に出現箇所と残りの文字数が妥当か※を確認し、問題なければ採用する。また、i回目で採用した文字の出現箇所 < i+1回目の出現箇所にならなければいけないため、その確認に今回は二分探索を用いた。
※例えば、"bbbbab"という文字列から３文字選択するときに、aを先頭にすることは出来ないため。
3. 2をK文字になるまで繰り返す

![参考画像](https://raw.githubusercontent.com/E869120/kyopro_educational_90/main/editorial/006.jpg "公式解説画像")

引用元：[競プロ典型90問 Github](https://github.com/E869120/kyopro_educational_90)

### 実装

```python:answer.py
import string
import bisect

# 入力の受け取り
N, K = map(int, input().split())
S = input()

# アルファベットのリスト
alphs = list(string.ascii_lowercase)

# アルファベットの位置をs_idxに格納
s_idx = {}

for a in alphs:
  s_idx[a] = []

for i in range(len(S)):
  s_idx[S[i]].append(i)

# 答えとなる文字列をans, 出現箇所をメモするmemoを定義
ans = ""
memo = 0
while K > 0:
  for a in alphs:
    # アルファベットの存在の確認
    if len(s_idx[a]) == 0:
      continue
    # 二分探索でmemoより後に出現箇所を探索
    j = bisect.bisect_left(s_idx[a], memo)
    # jが範囲外の場合、除外
    if j >= len(s_idx[a]):
      continue
    # 出現箇所と残りの文字数の確認
    if K + s_idx[a][j] <= N:
      memo = s_idx[a][j]+1
      ans += a
      K -= 1
      break

print(ans)
```

## 最後に
問題の解説を読んでも他の人のコードを見てもさっぱり分からないという方の
力に少しでもなれれば幸いです。
コードの改善点やその他、ご意見などあれば、気軽にコメントください。
また、この記事を読んで理解できた方はぜひLGTMを押していただけると嬉しいです。
（~~記事投稿のモチベになります。~~）

ここまでお読みいただきありがとうございました。
M1 MacにVSCodeをインストールする方法

# はじめに
Apple silicon（以下、M1）のMacにエディターのVisual Studio Code(以下、VSCode）をインストールする手順をまとめた

今までのIntel版ではスムーズにインストールできましたが
M1版では同じようにいかないため、その追加点を記載した

※ターミナルからコマンドでインストールできるみたいです

https://qiita.com/c60evaporator/items/aef6cc1581d2c4676504

# 手順
1.下記を開く

https://code.visualstudio.com/download

ここで注意して欲しいのが
一番右側のMacにある下記の写真の箇所
![スクリーンショット 2022-01-10 17.14.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/9c84798c-5fe5-5a17-5417-60639fded3af.png)
「↓ Mac macOS 10.11+」ではなく

その下の
".zip"から続く青い3つのオブジェクトの
「Apple Silicon」を選択すること

2.インストールしたzipを解凍
![スクリーンショット 2022-01-10 17.32.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/f1ef6348-b878-0394-fc42-37f82a5349c6.png)

3.解凍して出てきたappをアプリケーションへドラッグ&ドロップ
![スクリーンショット 2022-01-10 17.34.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/31074a92-c9e8-6f46-4337-adac42d99e1f.png)


開くと
![スクリーンショット 2022-01-10 17.36.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/1742c050-9c6b-a1e4-db0d-1156f6ae585c.png)

英語表示...(>_<)

次回、VSCode日本語化！！
CCENTが無くなってるみたいだからCCNA取るよ('ω')

##__お久しぶりです。__

皆様2022年いかがお過ごしでしょうか。

2年前に記事を書いた時には予想ができないくらい忙しい日々を過ごしています。
おかげ様で資格勉強する時間が作れません。

仕事内容の詳細は書けませんが、それなりにやってます。

##__これから__
今の現場に入ってもう丸2年経ち３年目に突入してますが、
そろそろ次のステップに進むために勉強を再開したいと思います。

そのためにはやっぱり資格の取得が必要だと感じているので今自分の仕事と勉強を両立できる資格は何かと言ったら
やっぱりCCNAでしょってことです。

業務内容的に、NW機器に実際に触れて動作の確認が行える現場なので、
勉強にはマジで適してる環境です。

__そんな素晴らしい環境で勉強してないんですけどね('ω')__

##__最後に__
今度は本気(ﾏｼﾞ)で資格勉強します。
そんで勉強にはアウトプットが良いそうなので、
週１目標で勉強した内容をアウトプットさせていただきます。

ご興味があれば覗いて行ってくださいな。
デバイスファイルについてまとめてみました〜ブロックデバイスとキャラクターデバイスの違いとランダムアクセス〜

#本記事について

Linuxの学習を進める中で出てくるデバイスファイル。
デバイスファイルには、ブロックデバイスとキャラクターデバイスに分けられるとありますが、
参考書を読んでもピンとこなかったので、自分の言葉でまとめてみました。

※LPIC level２の学習中に気になった内容にはなりますので、
同じ資格勉強をしているかたや初学者の方に参考していただくと幸いです。

参考URL
https://qiita.com/angel_p_57/items/1faafa275525469788b4
→普通のファイルシステムとデバイスファイルについての違い（反映のされ方とか）について、
わかりやすくまとめられておりました！

https://wa3.i-3-i.info/word19512.html
→ランダムアクセスについて図を用いてわかりやすく説明がされています。
イメージを掴むには最適です！

https://kb-jp.sandisk.com/app/answers/detail/a_id/8980/~/%E3%82%B7%E3%83%BC%E3%82%B1%E3%83%B3%E3%82%B7%E3%83%A3%E3%83%AB%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%A8%E3%83%A9%E3%83%B3%E3%83%80%E3%83%A0%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%AE%E6%93%8D%E4%BD%9C%E3%81%AE%E9%81%95%E3%81%84
→ランダムアクセスについてそれぞれの特徴が解説されており、より深く理解ランダムアクセスについて理解をすることができました！


#デバイスファイルとは
どうやらそんな難しく考えず、シンプルに
**「認識されているデバイスを操作（データの読み書き）するファイル」**
という認識で○

ここでいうデバイスというのは、HDDやCPUなど実際のハード機器と、
OSで認識している仮想的なデバイスを含んでの意味とのこと。

配置ファイルとしては`/dev`以下に配置されることとなります。
HDDディスクであれば/dev/sdaといった形ですね。

#ブロックデバイスとキャラクターデバイス

ざっくりまとめると下記表のようの感じ

|デバイス名|特徴|ファイルタイプ|例|
|--|--|:--:|--|
|ブロックデバイス|ブロック単位でデバイスにアクセス・バッファーがある・ランダムアクセスが可能|b|ハードディスク・RAMディスク・RAIDボリューム
|キャラクターデバイス|文字単位でデバイスにアクセス・ランダムアクセスができない|c|キーボード・マウス・プリンター

まずそれぞれ名前の通り、ブロック単位・文字（キャラクター）単位でデータを扱うかが大きな違い。
そしてもう一つ、**「ランダムアクセスができるかできるか」**
これが大きな違い。

さてそもそもランダムアクセスとはなんぞやとなります。。
本当のところこれをまとめたくてこの記事を書いたというのもあります。笑

#ランダムアクセスとは

「記憶装置などのデータへアクセスする技法の一つ」

一言でまとめるとこういうことでしょうか。

技法の一つと書きましたがもう一つ、シーケンシャルアクセスというのがあります。
これら照らし合わせながらまたまとめていきたいと思います。

###ランダムアクセス
・特定のデータへピンポイントでアクセスできる

###シーケンシャルアクセス
・データ領域へ順番にアクセスし、対象データを特定していく。
→ハードウェアが直接動作するため、アクセス速度をこちらの方が高い。

#まとめ

キャラクターデバイスはランダムアクセスできないのか。。
勝手にマイナスな印象を持っていましたが、速度に優れているということなのでそんなことはなさそうでした。

ブロックデバイスの例にある通り、RAMディスクなど記憶装置はやりとりするデータの容量がそもそも多くなっているので、なるべくデータを特定するランダムアクセスを使うことで、効率的なデータアクセスができるようになっているのかなという印象を受けました。（推測ですが。。）

こうしてまとめてみるとまだまだ自分の知識が浅いことを再認識しました。。
今年はアウトプットを意識していこう。。。
【Java文法】セット(Set)

こんにちは、コイキングです。

本記事では'セット(Set)'について、説明したいと思います。

******

# 1. セット(Set)とは?

Setは**重複されていないデータの集まりを格納するため**のデータ構造です。
Setを実装したクラスはHashSet, LinkedHashSet, TreeSetなどがあります。

# 2. HashSet
ハッシュセットはHashMapの**Keyの値がユニークである特性を利用して実装**されています。
そのため、**HashMapの特性と長・短所を共有します。**

## 1) データの挿入

```
Set<String> set = new HashSet<String>();

set.add("HashSet-value-01");
set.add("HashSet-value-02");
set.add("HashSet-value-02"); // 重複された値は挿入できない。
set.add("HashSet-value-03");
set.add("HashSet-value-04");
```

## 2) データの出力

```
for (String str : set) {
    System.out.println("Set value : "+str);
}
```

## 3) データの削除
### 値を指定して削除

```
set.remove("HashSet-value-01");
```

### 全体データ削除

```
set.clear();
```

# 3. LinkedHashSet
リンクドハッシュセットはLinkedHashMapの特性を共有しています。
セットに格納する各データの順序が重要な場合使います。

※ データのCRUD機能はHashSetの機能を共有するため省略。

# 4. TreeSet
ツリーセットはTreeMapの特性を共有します。
セットに格納するデータの順序が重要で、格納するデータの数が多い場合使います。

※ データのCRUD機能はHashSetの機能を共有するため省略。


******
※ 例示コード
https://github.com/leeyoungseung/algorithmBasic/blob/master/algorithm/src/basic/B_13_Set.java

※ 韓国語のポストは以下のURLで確認できます。
https://koiking.tistory.com/85?category=1068655
Typescriptでinputフォームの値を取得する

Typescriptの勉強を最近始めたのですが、stringとかarrayとかの変数の型周りは他にも静的型付け言語をやっていたので特に問題なくは入れたものの、イベント周りの型が結構鬼門でタイトル通りの簡単なことをしたいだけなのに割とハマってしまい、ベストプラクティスが分かりませんでした...

そんなTypescriptを同じく始めたばかりのどなたかに刺されば幸いです。

```App.tsx
import { useState, useEffect, useRef, ReactEventHandler } from "react";

type TodoType = {
  id: number;
  todo: string;
  isDone: boolean;
};

const App: React.FC = () => {
  const [text, setText] = useState<string>("");
  const [todos, setTodos] = useState<TodoType[]>([]);

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>): void => {
    setText(e.target.value);
  };
  const handleClick = (): void => {
    setTodos([
      ...todos,
      { id: todos.length++, todo: text, isDone: false }
    ]);
  };

  return (
    <>
      <input
        onChange={(e: React.ChangeEvent<HTMLInputElement>) => handleChange(e)}
        type="text"
      />
      <button onClick={(): void => handleClick()}>Click me</button>
      {todos.map((i) => (
        <li key={i.id}>{i.todo}</li>
      ))}
    </>
  );
};
export default App;
```

`onClick`については別にイベントから値を受け取っているわけではないので特に問題ではないのですが、`onChange`については`event.target.value`からの値を受け取ってstateに保存したかった場合に、イベント型として`ChangeEvent<HTMLInputElement>`を渡せばいけるのですが、なぜかこれにたどり着くまでに数時間溶かしました...(とはいえTypescript周りは親切なので、xxの型はoo型に渡せません、というエラーが出ればoo型に修正して渡してやれば良いだけなので大分分かりやすいです。)

イベントは`React.イベント型`としてやればインポートも必要なく使えます。
単回帰の信頼区間と予測区間

単回帰において信頼区間と予測区間というものがあります.それの違いの説明は感覚的なものが多いため数式化しておきます.

# 問題設定

```math
\begin{align}
y|_x &\sim \mathcal{N}(f(x|w),\epsilon)\\
w &\sim \phi_1(w),\epsilon\sim\phi_2(\epsilon) 
\end{align}
```

そして,n個の(X,Y)のデータを観測したとする.

# 1-αの信頼区間(A)

```math
P_{w\sim\phi(w|X^n,Y^n)}(L(x)\leq f(x|w)\leq U(x))=1-\alpha.
```

# 1-αの予測区間(B)

```math
P_{w\sim\phi(w,\epsilon|X^n,Y^n)}(L(x)\leq y|_x \leq U(x))=1-\alpha.
```


ともに事後分布による確率の範囲です.

そのため,通常の信頼区間と異なります([信頼区間と信用区間 by @making111](https://qiita.com/making111/items/8475a6fbf683d20b0be5)).


# 何が違うのか

- (信頼区間A)と(予測区間B)の違いはノイズ項を含めるかどうかです.
- そのため,一つのx座標に対して複数の値を散らばりを持っている場合Aの方がBに比べて細張った形になります.

- 逆にBは長方形を代表的な平均の直線に軸を合わせて,回転させて得られる形となることが多いです.
- 意味合いとしては,[信頼区間と信用区間](https://qiita.com/making111/items/8475a6fbf683d20b0be5)は明確な差異がありましたが,(信頼区間A)と(予測区間B)は**ノイズを含めているかどうかだけの違いです**.

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417525/d5c2bf79-3772-100b-afa7-c5a7d5a6ed4a.jpeg)


# 感想

- 通常の信頼区間と言葉がかぶっているので,『モデル区間』とか『ノイズなし予測区間』とかに改名した方がわかりやすい気がしました.

# 参考:

- [松浦健太郎,『StanとRでベイズ統計モデリング』,共立出版(2016)](https://www.kyoritsu-pub.co.jp/bookdetail/9784320112421)
- [信頼区間と予測区間の違い（よくあるご質問）株式会社 日本科学技術研修所 ](https://www.i-juse.co.jp/statistics/support/faq/80025.html)
- [おっと危ない：信頼区間と予測区間を混同しちゃダメ Take a Risk：林岳彦の研究メモ](https://takehiko-i-hayashi.hatenablog.com/entry/20110204/1296773267)
MacにHomebrewをインストールする方法

# はじめに
M1チップのMacbookにHomebrewをインストールする方法をまとめた
PATHでつまづいたので、Intelではなく、2020年以降販売のM1チップのMacbookをお使いの方は参考してください

# 手順
1.Homebrewのサイトを開き、ダウンロードコマンド取得（下記サイトの「インストール」の下側のコマンド）

https://brew.sh/index_ja

2.ターミナルを開き、1でコピーしたコマンドを貼り付ける
![スクリーンショット 2022-01-09 15.44.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/ca563cbf-6547-d5e8-12e0-75bd46a9590b.png)


3.パスワードの入力が求められるので入力

4.下記の表示が出たら、RETURNキーを押下
![スクリーンショット 2022-01-09 15.44.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/37acd2f6-bd9f-da5c-290f-e0e4496bba0e.png)

5.下記の表示が出ますが、xcodeのインストールが完了されるまでしばらく待ちます
![スクリーンショット 2022-01-09 15.46.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/e901576b-8c2a-6d50-6172-90c4c6e1fbb5.png)

6.「installation successful!」が表示されたら完了
![スクリーンショット 2022-01-09 16.39.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/8ef558fa-d0eb-21ed-8a98-d52067d64759.png)

ですが、"Warning"が出ています
###### Warning: /opt/homebrew/bin is not in your PATH.

とりあえず
brew -vを入力してインストールされていることの確認をしてみましょう

```
userAir ~ % brew -v
zsh: command not found: brew
```

brewが見つからないそうです


先ほどのWarningを見てみましょう
/opt/homebrew/bin is not in your PATH.
PATHが通っていないみたいですね

### PATHの追加
PATHを設定してみます

```
export PATH="$PATH:/opt/homebrew/bin/"
```

設定されているPATHを確認してみます

```
userAir ~ % $echo $PATH                           
zsh: no such file or directory: /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin/
```

もう一度「brew -v」を試してみます

```
userAir ~ % brew -v
Homebrew >=2.5.0 (shallow or no git repository)
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
Homebrew/homebrew-core (no Git repository)
```

PATHが通り、brewコマンドが使えるようになりました！
【Java文法】マップ(Map)

こんにちは、コイキングです。

本記事では'マップ(Map)'について、説明したいと思います。

******

# 1. マップ(Map)とは?
マップは**Key-Value構造に構成されているデータを格納**するデータ構造です。
Keyを使った**データ検索に最適化されたデータ構造で、 **Key値は重複できない**という特徴があります。
Mapを実装したのはHashMap, LinkedHashMap, TreeMapなどがあります。

# 2. HashMap
## 1) HashMapとは?
ハッシュマップとはハッシュテーブルを使ってマップを実装したデータ構造で、
Key値をハッシュ関数を通してデータの参照値が格納されているバーケット(bucket)のインデクスに変換し、バーケットのインデクスを用いてデータにアクセスします。

※ 長所
- Key値でデータを検索するため、 **検索速度が速い**です。

※ 短所
- バーケットの長さ調整が必要な場合、 **処理速度の遅延が発生する可能背があり**ます。
- データの格納時に**配列やリストより多めのメモリーを使います。**
- Key値が**ソートされてない**です。

※ 主に使っている所
- **ユニークなKey値を利用したデータの活用**が必要な場合
- データの**入力・削除が頻繁**な場合

## 2) データの挿入
put()メソッドを用いてデータの格納ができます。
putメソッドの引数としてKeyの値と、Value（格納する値）を渡してデータを格納します。

```
Map<String, String> map = new HashMap<String, String>();

map.put("HashMap-key-01", "HashMap-value-01");
map.put("HashMap-key-02", "HashMap-value-02");
map.put("HashMap-key-03", "HashMap-value-03");
map.put("HashMap-key-04", "HashMap-value-04");
map.put("HashMap-key-05", "HashMap-value-05");
```

## 3) データの出力
### get()メソッドとKey値を使う。

```
System.out.println(map.get("HashMap-key-02"));
```

### 全体データ出力(keySetメソッドを使う)

```
for (String key : map.keySet()) {
    System.out.println(String.format("Using keySet key : [%s], value : [%s]", key, map.get(key)));
}
```

### 全体データ出力(key値のIteratorを使う)

```
Iterator<String> keys = map.keySet().iterator();
while(keys.hasNext()) {
    String key = keys.next();
    System.out.println(String.format("Using Iterator key : [%s], value : [%s]", key, map.get(key)));
}
```

### 全体データ出力 (entrySetメソッドを使う)

```
for (Map.Entry<String, String> obj : map.entrySet()) {
    System.out.println(String.format("Using entrySet key : [%s], value : [%s]", obj.getKey(), obj.getValue()));
}
```

## 4) データの更新
### putを使う ※ 同じキーを用いてデータを格納すると値が上書きされ、更新が行われる

```
map.put("HashMap-key-02", "HashMap-value-02_updated");
```

### replaceメソッドを使う

```
map.replace("HashMap-key-02", "HashMap-value-02_updated_new");
```

## 5) データの削除
### removeメソッドを使う

```
map.remove("HashMap-key-02");
```

### 全体データの削除

```
map.clear();
```

# 3. LinkedHashMap
## 1) LinkedHashMapとは?
リンクドハッシュマップはハッシュマップを継承して実装されたデータ構造で、
Key値の順序を保存するため、 **Keyを順次ソートする必要がある場合使います。**

※ データのCRUD機能はHashMapのメソッドを共通で使えるため省略。

# 4. TreeMap
## 1) TreeMapとは?
ツリーマップはツリー(木)構造基盤で実装されたマップです。

※ 長所
- メモリー使用量がHashMapより少ないです。
- データのKey値がソートされています。

※ 短所
- データの入力・削除時にHashMapより処理速度が遅いです。(TreeのNode再配置が行われる可能性があり)

※ データのCRUD機能はHashMapのメソッドを共通で使えるため省略。

******
※ 例示コード
https://github.com/leeyoungseung/algorithmBasic/blob/master/algorithm/src/basic/B_12_Map.java

※ 韓国語のポストは以下のURLで確認できます。
https://koiking.tistory.com/84?category=1068655
Deep Learning に関する私の記事

# Deep Learningに関する記事をまとめています。
## 目的
今後記事を掲載していく中で自分ですぐに見返せることを目的として作成します。

#資格

###E資格

+ [【E資格】　応用数学](https://qiita.com/seiji1997/items/9cbf4c96d06d924857c7)

+ [【E資格】　機械学習](https://qiita.com/seiji1997/items/3e1f5475319df4996b16)

+ [【E資格】　深層学習day1](https://qiita.com/seiji1997/items/f74323109b4107dc2334)

+ [【E資格】　深層学習day2](https://qiita.com/seiji1997/items/298e29bd7bdbaf4f9ba6)

+ [【E資格】　深層学習day3](https://qiita.com/seiji1997/items/85b587e87b79c80a2042)

+ [【E資格】　深層学習day4](https://qiita.com/seiji1997/items/60e5c023551dee1efa85)
gem acts_as_list の使い方

## acts_as_listとは

indexページなどで一覧表示しているデータの並び替えを簡単の実装できるgemのことです。このgemを利用することで各データごとに　”↑”、”↓”　などのリンクを表示させクリックすることでそれぞれの並びを一つ上、一つ下と変更することが簡単になります。

## acts_as_list使い方

・Gemfileに以下を追加し、bundle install

```ruby
gem 'acts_as_list'
```

・”position”カラムの追加

acts_as_listで並び替えをする際の基準となるカラムは、”id”ではなく”position”というカラムです。これはもちろん元々モデルにあるものではないため、もしモデルを作成済みであれば新くmigrationファイルを作り、カラムを追加する必要があります。

・migrationファイルの作成

Taskモデルにカラムを追加したい場合以下のmigrationファイルを作成します。

```ruby
class AddColumnPositionToTasks < ActiveRecord::Migration[5.2]
  def change
    add_column :tasks, :position, :integer
  end
end
```

こちらのファイルを作成した後 rails db:migrate 。

（もし既存のデータがある場合、positionカラムにデータを入れておかなくてはいけません。自分の場合はrailsコンソールで各データのidを初期のpositionの値としました。）

・modelファイルにacts_as_listを利用するためのコードを追加する

カラムを用意しただけではgemの機能を使えるようにはなりません。並び替えの機能をモデルに追加するために、modelファイル内に”acts_as_list”というコードを追加してください。これで並び替えの機能を利用できるようになります。

```ruby
class Task < ApplicationRecord
  acts_as_list #この一行を追加
end
```

・viewページに並び替えのリンクを追加する

一覧表示されているデータに並び順を変更するアクションへのリンクを書きます。

```haml
%h1 データ一覧
%table
  - tasks.each do |task|
    %tr
      %td= task.title
      %td= task.body
      %td= link_to "↑", move_higher_task_path(task) # 並び順をひとつ上へ
      %td= link_to "↓", move_lower_task_path(task) # 並び順をひとつ下へ
```

・ルーティングの追加

viewに追加したリンクを並び替えのアクションに紐付けるためのルーティングを記述します。

```ruby
resources :tasks do
  member do
    get :move_higher
    get :move_lower
  end
end
```

・actionの追加

最後に、並び変えの機能を利用できるようになったのでcontroller内で実際の並び替えをするコードを書いていきます。

```ruby
def index
  @tasks = Task.all.order(:position) # Task.allだけだとIDの順番でデータが表示されてしまうため"position"カラムを基準に並べ替えをする必要がある
end
  
def move_higher
  Task.find(params[:id]).move_higher # viewで選択したtaskを一つ上の並び順に変更する
  redirect_to tasks_path
end
 
def move_lower
  Task.find(params[:id]).move_lower # viewで選択したtaskを一つ下の並び順に変更する
  redirect_to tasks_path
end
```

これだけでデータを一覧表示する際の並び順を簡単に変更することができます。

タスク管理など優先順位の入れ替えなどをしたいときに便利なgem “acts_as_list”の使い方でした。
【簡単】pgAdmin4でcsvファイルをインポートする方法

pgadmin4でcsvファイルをインポートする方法です。

所要時間：２、３分（行数や制約に依存する）
手順：①テーブルの作成　②csvファイルのインポート

<h1>①テーブルの作成（分かる人は飛ばしてOK）</h1>

データベースを選択した状態で「ツール」→「クエリツール」を選択する。
![スクリーンショット 2022-01-10 16.08.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2258874/d2e5ebe9-a218-b787-4879-ee01a2c1dd4a.png)

クエリエディタにてテーブルを作成する。

例：

```
CREATE TABLE t1(
	Entity varchar(30),
	Code char(3),
	Year integer,
	Productivity decimal
);
```
今回私が使用したのは、Our World in Dataよりダウンロードした[時間毎労働生産性に関するデータ](https://ourworldindata.org/grapher/labor-productivity-per-hour-pennworldtable)です。
データの中身はこんな感じ。
![スクリーンショット 2022-01-10 16.18.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2258874/b59f4d88-bf37-9e79-04f5-db38365a41b5.png)

ご自身がインポートするデータに合わせて、行名ないし制約を設定してください。


この時点ではテーブルの中身は空っぽです。


※テーブルの中身を確認する方法
「スキーマ」→「public」→ テーブル名をダブルクリック →「データを閲覧/編集」

<h1>csvファイルのインポート</h1>

先ほど作成したテーブル名をダブルクリックし、「インポート/エクスポート」を選択する。
![スクリーンショット 2022-01-10 16.30.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2258874/ad24e609-8785-18c1-672e-407e24ebd4ce.png)

下のようなウィンドウが展開される。

![スクリーンショット 2022-01-10 16.33.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2258874/3f6d1f0c-5f00-2923-1fec-40f206c2f7fe.png)

「インポート」を選択した上で、
ファイル名・エンコーディング・ヘッダの有無・区切り文字などを選択する。
（個人的にヘッダ「はい」の選択を忘れがちなため赤丸に...）


これで、csvファイルのインポートが完了しました。
テーブルの中身を確認したい方は、先ほどと同様、以下の方法でデータを閲覧してください。
>「スキーマ」→「public」→ テーブル名をダブルクリック →「データを閲覧/編集」


以上。
Ruby attr_reader, attr_writer, attr_accessorについて

# 結論
attr_readerを用いるとアトリビュートを**読み取る**メソッドが定義される。
attr_writerを用いるとアトリビュートを**書き込む**メソッドが定義される。
attr_accessorを用いるとアトリビュートを**読み取る**メソッドと**書き込む**メソッドの両方が定義される。

# 公式リファレンス
**attr_reader**
https://docs.ruby-lang.org/ja/latest/method/Module/i/attr_reader.html
**attr_writer**
https://docs.ruby-lang.org/ja/latest/method/Module/i/attr_writer.html
**attr_accessor**
https://docs.ruby-lang.org/ja/latest/method/Module/i/attr_accessor.html

# attr_reader
```ruby
class User
  attr_reader :id, :name
  def initialize(id, name)
    @id = id
    @name = name
  end
end
```

この表記で以下のメソッドが定義されます。

```ruby
def id
  @id
end

def name
  @name
end
```

これによりインスタンスを作成した後、アトリビュートを以下のように読み取ることができます。

```ruby
user = User.new(1, 'kot')
=> #<User:0x00007fd644997218 @name="kot", @id=1>
user.id
=> 1
user.name
=> "kot"
```


# attr_writer
```ruby
class User
  attr_writer :id, :name
  def initialize(id, name)
    @id = id
    @name = name
  end
end
```

この表記で以下のメソッドが定義されます。

```ruby
def id=(id)
  @id = id
end

def name=(name)
  @name = name
end
```

これによりインスタンスを作成した後、アトリビュートを書き込むことができます。

```ruby
user = User.new(1, 'kot')
=> #<User:0x00007fa0678aaea8 @id=1, @name="kot">
user.name = 'kotkot'
=> "kotkot"
```

読み取りはできないので以下のように両者(attr_reader, attr_writer)を表記することで読み取りと書き込みができるようになります。

```ruby
class User
  attr_reader :id, :name
  attr_writer :id, :name
  def initialize(id, name)
    @id = id
    @name = name
  end
end
```

```ruby
user = User.new(1, 'kot')
=> #<User:0x00007fa0678aaea8 @id=1, @name="kot">
user.name
=> "kot"
user.name = 'kotkot'
=> "kotkot"
```

# attr_accessor
attr_readerやattr_writerを記述するだけで以下のように簡単にメソッドが定義されます。

```ruby
def hoge
  @hoge
end

def hoge=(hoge)
  @hoge = hoge
end
```

しかし両方を用いること場合にはattr_accessorを用いることでさらに簡単にメソッド定義できます。

```ruby
class User
  attr_accessor :id, :name
  def initialize(id, name)
    @id = id
    @name = name
  end
end
```

## 補足
各アトリビュートの読み取りメソッドが定義されるので以下のようにnameメソッドを他のメソッド内で用いることもできます。

```ruby
class User
  attr_accessor :name
  def initialize(name)
    @name = name
  end
  def greet
    "Hello #{name}"
  end
end
```

```ruby
user = User.new('kot')
=> #<User:0x00007fa0648e9d18 @name="kot">
user.greet
=> "Hello kot"
```

# おわりに
学び始めたときはなんとなくで書いていましたが、それぞれのメソッドが何をしているのかを公式リファレンス見ながら一つずつ理解することが定着への近道だと改めて感じました。
初めてのコードレビューで指摘されまくったコメントの書き方を改善する


先日初めてコードレビューをしていただけました。
その際コメントの書き方についての指摘が多かったので、指摘事項を備忘録としてまとめておきたいと思います。

## はじめに
コメントを書く際の注意点については「[プログラマが知るべき97のこと](https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%81%8C%E7%9F%A5%E3%82%8B%E3%81%B9%E3%81%8D97%E3%81%AE%E3%81%93%E3%81%A8-%E5%92%8C%E7%94%B0-%E5%8D%93%E4%BA%BA/dp/4873114799/ref=sr_1_1?adgrpid=121577874136&hvadid=536041735659&hvdev=c&hvqmt=e&hvtargid=kwd-1268462898664&hydadcr=23104_13451920&jp-ad-ap=0&keywords=%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%83%BC%E3%81%8C%E7%9F%A5%E3%82%8B%E3%81%B9%E3%81%8D97%E3%81%AE%E3%81%93%E3%81%A8&qid=1641453710&sr=8-1)」にも掲載されています。

・[コメントについてのコメント](https://xn--97-273ae6a4irb6e2hsoiozc2g4b8082p.com/%E3%82%A8%E3%83%83%E3%82%BB%E3%82%A4/%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%81%AE%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88/)
・[コードに書けないことのみをコメントにする](https://xn--97-273ae6a4irb6e2hsoiozc2g4b8082p.com/%E3%82%A8%E3%83%83%E3%82%BB%E3%82%A4/%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AB%E6%9B%B8%E3%81%91%E3%81%AA%E3%81%84%E3%81%93%E3%81%A8%E3%81%AE%E3%81%BF%E3%82%92%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88%E3%81%AB%E3%81%99%E3%82%8B/)

私はこのエッセイをレビューしていただいたコードを書き始める前に読んでいましたし、内容は頭の片隅に入っていたので、多少意識してコメントを書いていたつもりでした。
しかし、いざレビューを受けると、エッセイで紹介されているような駄目なコメントばかり書いてしまっていました。。

書いている最中は「**これは必要なコメントだろう**」と思って書いていたのですが、いざレビューを受けると、そのコメントのほとんどが「**全く必要のない、むしろ邪魔にすら感じるコメント**」になってしまっていたのです。

私の書いたコメントは「コードに書けないことのみをコメントにする」にもあった、「**ノイズ**」になっていました。

## どこがいけなかったのか？
結論的には、コメントのほとんどが「**自分のために書いたコメント**」になっていました。

基本的に、自分の書いたコードやコメントを読むのは自分以外の他の誰かです（数週間後の自分かもしれませんが）
他の人が見てわかりやすいようなコメントを書かなければいけません。
そして、他の人が見て不要だなと感じるようなコメントは「**書かないようにしなければいけません**」

私の場合、実装が少し複雑になった部分には、数週間後に見返しても何をしているかがすぐに分かるように
「受け取った値を～し、hogeと結合して～、fooに～して渡す」
のようにして、長文で２行にもなるコメントを書いていました。

**これは自分のためのコメントです**。

そもそもコードを見て、何をしているのか考え込まなければいけないようなコードは改善しなければいけません。実際そのコードはコメントをつけなくても理解できる、すっきりとしたコードにできました。

私のようにプログラミングの経験が浅い初心者は、分かりやすく、丁寧なコメントを書こうと心がけます。
少しでも「理解しずらいかな？」と思ったコードにはコメントを書きがちです。

自分の学習用のコードならコメントをどれだけ書いても良いですが、上級者からすれば、コードを見れば理解できるような事をコメントで書かれると、うっとうしく感じると思います。
さらに、そのコメントの内容が間違っている可能性だってあります。
余計に混乱させてしまうことになり、それこそノイズになってしまうのです。

## Docコメントの書き方

PHPDocについても指摘された点がありました。

コードを修正し、変数名の変更があった箇所のコメントを訂正し忘れていたり、例外処理があるのに@throws句を書き忘れていたり、引数の説明に動詞（〜を受け取る。などの動詞はいらない）を書いていたりと、、、

コメントが間違っていたり、コメントに無駄な説明があったりすると、むしろコメントが無い方がマシという状態になってしまうので

**コメントの内容に誤りがないか？冗長になっていないか？書き漏れはないか？**
細かい部分にも注意して書かなければいけません。

https://qiita.com/motoyan-qwt/items/ee973666f1105435822c


VSCodeのようなIDEで、PHPの組み込み関数を使う時、関数名にカーソルを持って行くとPHPDocが表示されます。
そこで引数の型や使い方を確認しますが、とても簡潔に書かれていて、その関数を使うために本当に必要な情報だけが書かれています。
urlをクリックして日本語のページを見てもそうで、関数の用途が簡潔に書かれています。
余計な情報が無いので、すぐに理解できて使えます。

私は自分の書いたPHPDocを見直して、同じように簡潔に書けていなかったので、改めて見直して不必要だと感じた部分は削除しました。

本当に必要な情報のみを残してあとは切り捨てるだけで、すっきりとしたコメントになり、文字数も減り、内容が頭にすんなりと入ってくるようになりました。

***

### まとめ

**コメントはできるだけ簡潔に、コードに書けないことのみを書く！！**

>コメントを通常のコードとまったく同じように考えて扱うことが重要になってきます。すべてのコメントを読む人にとって価値のあるものにし、そうでないものは即座に削除するか書き直すべきであるということです。
コードに「書いていないこと」ではなく、コードに「書けないこと」のみをコメントにするのです。
ゲームの完成：すいのゲームを作ろう（第6回）

#ゲームの完成
![スクリーンショット 2022-01-10 162113.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/c20c3709-f66e-76e2-f39c-f99b5a640a6d.png)
![スクリーンショット 2022-01-10 160134.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/84260db6-7342-666c-d3d0-790723571996.png)
![proposal.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/f9aee9ce-6fc6-6847-9adc-990436bf0417.jpeg)


タイトル画面を作ってゲームを完成させました。どうでしょうか企画書と比べてイメージ通りのゲームができたと思いませんか？
？
ボーンアニメーションを利用した、くだものが走っていく姿は意外と面白いです。丸太を吹き飛ばす際の爽快感も実装することができました。今回は3種類のくだものの実装でしたが、さまざまなものの名前を学ぶことに応用ができると思います。

こんな単純なゲームでもすべて自分で作ろうと思うと大変です。木や花などはアセットを利用しています。使えるものは使っていきましょう。

ゲーム作りは簡単ではないです。様々なスキルを必要とします。はじめはとにかく簡単なゲームを作り、遊べるまで完成させてから、面白い要素を足していきます。自分が納得いくまで足したところで完成できるようにするのです。
【AWS】ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた！マルチAZ編

# はじめに
「ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた！ELB編」の続きになります。前回の記事をご覧になっていない方はぜひそちらもご覧ください！

以下に分けて記事を作成しているので、上から順にご覧ください。
[・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた！VPC編](https://qiita.com/onishi_820/items/728ef2c6fd640dc07c65)
[・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた！EC2編](https://qiita.com/onishi_820/items/d8125a703e7a4eb456bd)
[・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた！RDS編](https://qiita.com/onishi_820/items/c18c3bf1a2ff586f264c)
[・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた！ELB編](https://qiita.com/onishi_820/items/08040fdc3f9852079a9e)
[・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた！マルチAZ編](https://qiita.com/onishi_820/items/8532ba3de47ca733e8fe)

# 前提
・コンソールの最低限の操作ができること
・各サービスについての最低限の知識があること
・VPCが作られていること（前回作成したVPCで構築することを前提に記載しています。）
・EC2インスタンスが作成されていること
・RDS（MySQL）が作成されていること

# Multi-AZ配置
RDSをマルチAZ配置にすることにより、複数のAZにデータベースを配置することが可能です。そのような冗長構成を取ることにより、可用性を高めることができます。

前の作業で作成したRDSをマルチAZ配置にしていきます。

**RDS → データベース → test-database-1 → 変更**の順でクリックします。

**可用性と耐久性**で、「**スタンバイインスタンスを作成する**」を選択し続行をクリックします。
![スクリーンショット 2022-01-10 14.37.10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/e4b0998b-e8d5-e9b2-3901-03e77e13faf8.jpeg)

変更のスケジューリングを「**すぐに適用**」に変更してください。（反映されるまでに１０分程度かかりました。）
![スクリーンショット 2022-01-10 14.40.28.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/cfad9f27-669a-296e-b145-c45605f47cb7.jpeg)

ステータスが利用可能になればOKです。
![スクリーンショット 2022-01-10 15.56.59.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/707c14f3-928a-c0f1-419c-a428233cd2d2.jpeg)

#動作確認

現在はAZ-aで起動しているデータベースを再起動することにより、スタンバイのデータベースがプライマリに昇格することを確認します。

想定される結果としては、リージョンが「ap-northeast-1a」から「**ap-northeast-1c**」に変わる結果になるはずです。

対象のデータベースを選択後、アクションから再起動を実行します。
![スクリーンショット 2022-01-10 16.01.32.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/ea3dfbc1-5ec2-ff28-9c7c-6786e7922b58.jpeg)

**フェイルオーバーで再起動しますか？**にチェックをつけて確認をクリックします。
![スクリーンショット 2022-01-10 16.01.48.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/5264981a-d8fb-90fd-5bce-61ab3b3b79ed.jpeg)

再起動後にフェイルオーバーがされているので、AZがap-northeast-1cに変わっています。
これで動作確認はOKです。
![スクリーンショット 2022-01-10 16.09.27.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/46150e99-632a-0f10-607d-50ce8e257f33.jpeg)


#さいごに

以上でシステムの構築が完了になります！
記事数が5つになる程長引いてしまい申し訳ございません。

必要のない方はEC2インスタンスやRDSなどのリソースの削除を忘れずに！

最後までご覧いただきありがとうございました。
python:requestsでニコニコ動画APIを使う

#目的・理由
・APIを使ってみたかった。
・本APIは登録など不要ですぐ使用可能だった。
・久しぶりにニコニコ動画を見たら楽しかった。

#参照リンク先
・[APIのURL](https://site.nicovideo.jp/search-api-docs/snapshot)
　※使い方などの詳細
・[requestsとcurlコマンド](https://intellectual-curiosity.tokyo/2019/08/31/python%E3%81%A7curl%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%A8%E5%90%8C%E7%AD%89%E3%81%AE%E5%87%A6%E7%90%86%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/)
　※curlコマンドをpythonのrequestsで実行
#コード

```python:code
import requests
import json
import pandas as pd

#APIのエンドポイント
url = "https://api.search.nicovideo.jp/api/v2/snapshot/video/contents/search"
#検索結果をまとめる辞書（普段はリストでやりますがなんとなく辞書型でやってみた）
results = {}

#関数--------------------------------------------
def nico(year,start,end):
  
  global results
  
#検索結果の取得可能な最大数は１００件なので、日付期間で分けてデータを取得する
#(fromとtoで期間を指定)
  filter = json.dumps(
    {
      "type": "or",
      "filters": [
      {
        "type": "range",
        "field": "startTime",
        "from": f"{year}-{start}T00:00:00+09:00",
        "to": f"{year}-{end}T00:00:00+09:00",
        "include_lower": True
      }
      ]
    }
  )
#qは検索キーワード、タグを検索対象とし、動画タイトルとタグを取得する
  param = {
    "q":"検索したい単語を入力、検索のORやAND条件などは本APIサイトを参照",
    "targets":"tags",
    "_sort":"-viewCounter",
    "fields":"title,tags",
    "_limit":100,
    "jsonFilter":filter
    }

#上記のfilterとparamsでAPIを使って検索実施
  data = requests.get(url,params=param).json()["data"]
    
  for i in data:
    result= {i["title"]:i["tags"]}
    results.update(result)

#----------------------------------------------
#実際に関数を使って、API検索開始
#日付の分け方は適当です、検索結果を見ながらお好みで調整
dates = {"01-01":"04-01","04-02":"07-01","07-01":"10-01","10-02":"12-31"}
years = range(2012,2023)
for y in years:
  for d1,d2 in dates.items():
    nico(y,d1,d2)

#結果件数の出力
print("件数は : " + str(len(results)))

#pandasを使ってデータ保存
df = pd.DataFrame(results.values(),index=results.keys())
df.to_excel("nico_api.xlsx")
```
#所感
・APIというかプログラミングでのデータ収集能力はやはり凄いと実感。（早い！）
・pythonのrequestsがcurlと同等というのを知った。
・curlコマンドを食わず嫌いしていたが、ちょっと親身に感じた。
・filterや検索結果の取得の際、jsonデータの勉強になった。
・なんだかんだでjsonデータ不慣れでしたのでいい勉強になりました。
・検索結果のタグを見てたらやっぱりタグの秀逸さには笑わせていただきました。

以上。
Unityで子要素をすべてListに入れる

```C#
public List<GameObject> _Objects;

void Start()
{
    //子要素がある時のみ
    if (GetChild(gameObject.transform))
    {Debug.Log("取れたよ");}
}

bool GetChild(Transform _transform)
{
    if (_transform.childCount <= 0){return false;}

    for (int i = 0; i < _transform.childCount; i++)
    {
        _Objects.Add(_transform.GetChild(i).gameObject);
        GetChild(_transform.GetChild(i));
    }
    return true;
}
```
MacにChromeをインストールする方法

# はじめに
MacbookにWebブラウザのChromeをインストールする方法をまとまた

# 手順
1.googleサイトからChromeのexeをダウンロード
   https://www.google.com/intl/ja_jp/chrome/

2.ダウンロードした.dmgファイルを実行
![スクリーンショット 2022-01-10 16.20.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/95efcdf6-61a4-8d74-9cb0-0cf8aaad8d9b.png)

3.Chromeのアイコンを下にドラッグ
![スクリーンショット 2022-01-10 10.49.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/ff229047-bc67-1f82-c7c9-0677a38b70b7.png)

4.「開く」を押下
![スクリーンショット 2022-01-10 10.50.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/bfda664e-8f78-5f1f-62d6-f498c7578658.png)

5.任意で選択してChromeを起動
![スクリーンショット 2022-01-10 10.51.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/54da6fbd-941b-e26a-cbc6-37305ef5679e.png)

6.お好みでデフォルトのWebブラウザを変更
![スクリーンショット 2022-01-10 10.51.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/24028301-5f1d-33e2-a54e-f76acea27db1.png)
YOLOXやーる（Python3.6、Windows10）

# はじめに
YOLOXやっていくー

# 開発環境
- Windows 10 PC
- Python 3.6

# 実装
1．YOLOXをクローンする

https://github.com/Megvii-BaseDetection/YOLOX

2．ライブラリのインストール

~~~shell
conda activate py36
pip install -r requirements.txt
pip install cython
pip install "git+https://github.com/philferriere/cocoapi.git#egg=pycocotools&subdirectory=PythonAPI"
~~~

3．[yolox_x.pth](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_x.pth)をダウンロード

4．tools/demo.pyの上部に下記を追記し、yoloxフォルダへのパスを追加する

~~~python
import sys
import os
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
~~~

5．実行

~~~shell
python tools/demo.py image -n yolox-x -c yolox_x.pth --path assets/dog.jpg --conf 0.25 --nms 0.45 --tsize 640 --save_result --device gpu
~~~

![dog.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/5002d358-bbe2-e0ff-b36c-fe14ae699d1c.jpeg)


# 追記

Webカメラから実行した場合、6fpsほど
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">YOLOX webcam test<a href="https://twitter.com/hashtag/Python?src=hash&amp;ref_src=twsrc%5Etfw">#Python</a> <a href="https://twitter.com/hashtag/OpenCV?src=hash&amp;ref_src=twsrc%5Etfw">#OpenCV</a> <a href="https://twitter.com/hashtag/AI?src=hash&amp;ref_src=twsrc%5Etfw">#AI</a> <a href="https://twitter.com/hashtag/DeepLearning?src=hash&amp;ref_src=twsrc%5Etfw">#DeepLearning</a> <a href="https://twitter.com/hashtag/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92?src=hash&amp;ref_src=twsrc%5Etfw">#機械学習</a> <a href="https://t.co/Vmi1u7M6KZ">pic.twitter.com/Vmi1u7M6KZ</a></p>&mdash; がちもとさん@メタバース熊本 (@sotongshi) <a href="https://twitter.com/sotongshi/status/1480559896898990082?ref_src=twsrc%5Etfw">January 10, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


# 参考文献
- [【物体検出】YOLOシリーズ最新版のYOLOXを試してみる　〜デモから学習まで〜](https://qiita.com/hkwsdgea_ttt2/items/970f34e1aa59059f7c69?fbclid=IwAR2KKCNJ9XOcu02VsEXKKEGFF-omOn3TlpA2yKMYLJ5fW7uYwcXgf5afBaA)
UIとゲームバランス：すいのゲームを作ろう（第5回）

#UIについて
![スクリーンショット 2022-01-10 160134.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/9676231b-5371-76ee-2a2c-2c511088eebb.png)

実装したゲーム画面です。企画時、上空にある文字はなかったですが、テストプレイで流れてくる文字を読み取るのが難しいことに気が付きました。そのため、次に出てくる文字を上空に表示するようにしました。テストプレイは大切で個人でゲームを開発するには何度も自分でテストプレイを行い、楽しいと思う要素を追加していくやり方がおすすめです。
またUIについては、森やくだものということで、丸太をモチーフにしたものにしました。

ゲームを作るとＵＩの難しさに気が付きます。一般的に市販されていゲームのＵＩは開発者ではない人は気にも止めないことも多いですが、この気にならないを作り出すことに技術が必要です。今回はシンプルなゲームなので簡単に作られていますが、それでもメインの果物の邪魔にならない彩度を調整しています。少しボタンの彩度を下げています。またボタンらしく作ることで、これは押せるのだと認識させています。

＃ゲームバランスについて
ゲームは人の感情をより大きく動かすことが大切です。そのために難易度に波があると面白く感じます。
![スクリーンショット 2022-01-10 160940.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/5de09c97-b0e2-7c1a-f7cd-02ce092479b1.png)
これは果物の速度変化を表した曲線です。始めは一定に速度がありますが、途中で変わらなくなります。ここでプレイヤーはゲームに慣れることができます。そのあとまた速度は上昇し、その後また、変わらなくなります。体験してみるとわかりますが、難易度に波を作ることでゲームが面白くなります。
qittaの記事を見てぱっと見謎だったfilter, reduceに渡すアロー関数を理解した

qittaの記事を見てぱっと見謎だったソースが以下。

```index.ts
function sumOfPos(arr: number[]): number {
  return arr.filter(num => num >= 0).reduce((acc, num) => acc + num, 0);
}
```

まず以下の部分

```index.js
arr.filter(num => num >= 0)
```

javascriptのfilter関数の公式を見てみると

```index.js
let newArray = arr.filter(callback(element[, index, [array]])[, thisArg])
```

そうかfilter関数の引数にコールバック関数を渡すのか。
とすると無名関数を渡しているので以下と同義。

```index.js
arr.filter(function(num){
   return num >= 0;
});
```

続いて以下の部分

```index.js
reduce((acc, num) => acc + num, 0)
```

これもjavascriptのreduce関数の公式をみると
第一引数にコールバック関数を渡すみたい。なので、
(第2引数は初期値)

```index.js
reduce(function(acc, num){
 return acc + num;
}, 0);
```

つまり

```index.ts
const data: number[] = [-1, 5, -3, 4, -2, 5];
function sumOfPos(arr: number[]): number {
    return arr.filter(num => num >= 0).reduce((acc, num) => acc + num, 0);
}
console.log(sumOfPos(data));  //5 + 4 + 5 = 14
```
Aurora (Amazon RDS for PostgreSQL) でスロークエリを出力する方法


## はじめに
担当しているWebサービスがなぜ遅いのか特定するために、時間のかかるクエリを確認する必要がありました。
今日は、その時に知ったAurora (Amazon RDS for PostgreSQL)で、スロークエリを発行する方法について書きます。

PostgreSQLはMySQLと違って、設定が少しだけ面倒なんです...

## 最初に結論
パラメータグループに以下を設定します。

```tex:1000ms以上かかったクエリが出力される
log_statement mod
log_min_duration_statement 1000
```

## 前提
RDSへの接続がされていることを前提としています。

## パラメータグループの作成
1.新規パラメータグループを作成
![スクリーンショット 2022-01-08 11.11.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573011/16817a2c-0cdc-775c-7b02-2c8989824d24.png)

2.タイプ「DB Cluster Parameter Group」を選択
DB Parameter Group ･･･ 特定のインスタンスにのみ適用できる
DB Cluster Parameter Group ･･･ クラスター全体に適用できる
![スクリーンショット 2022-01-10 13.38.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573011/fe1bfe6a-24ee-0c6d-d8d5-1c09cd9a7132.png)


3.作成したパラメータグループを編集
以下の設定で、実行に1000ms以上かかったクエリがログに出力されます。

```
log_statement mod
log_min_duration_statement 1000
```

適応タイプ`dynamic`は、パラメータの変更をデータベースの再起動なしに変更することができます。
> log_statement･･･
> ddlは、CREATE、ALTER、およびDROP文といった、データ定義文を全てログに記録します。
> modは、全てのddl文に加え、INSERT、UPDATE、DELETE、TRUNCATE、およびCOPY FROMといった、データ変更文をログに記録します。 
https://www.postgresql.jp/document/12/html/runtime-config-logging.html

> log_min_duration_statement･･･
>文の実行に少なくとも指定した時間かかった場合、それぞれの文の実行に要した時間をログに記録します。 この値が単位なしで指定された場合は、ミリ秒単位であるとみなします。
https://www.postgresql.jp/document/12/html/runtime-config-logging.html

![スクリーンショット 2022-01-08 11.23.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573011/4a464981-1092-f71c-1d75-018931a7c4e4.png)
![スクリーンショット 2022-01-08 11.24.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573011/b53d0f4e-eb58-07dc-00cb-d96da0e5d9aa.png)

4.DBクラスターのパラメータグループに作成したパラメータグループを設定
![スクリーンショット 2022-01-10 15.33.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573011/bc058114-8b0f-a8a2-3953-e22f427dfb02.png)

5.PostgreSQL ログにチェック
CloudWatchにスロークエリが出力されるようになります。
![スクリーンショット 2022-01-08 11.26.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573011/ebac17db-e2ef-c6c9-706e-be4557b20e52.png)



## 実行してみる
1. 2分待つクエリを発行する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573011/26ed6274-f351-cfde-5e85-43a046962b02.png)

2. ログを確認する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573011/7edffa07-f330-b154-e0a2-6d0b8a99a140.png)

以下のログが出力されるようになりました🎊
あとはログはフィルターして、slackに通知したりアレンジしてみてください。

```
2022-01-10 04:31:25 UTC:10.0.0.96(50174):postgres@postgres:[21202]:LOG:  duration: 2004.674 ms  statement: select pg_sleep(2);
```

## 注意
- デフォルトのパラメータグループを使ってデータベースを起動していた場合、変更できないパラメータが存在します。その場合、カスタムパラメータへの変更が発生するため、データベースの再起動が必要です。なので、RDS起動時にカスタムパラメータを使用することをおすすめします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573011/6a4c27b4-3c01-0967-1568-2da109ffabdd.png)



## 参考
https://aws.amazon.com/jp/premiumsupport/knowledge-center/rds-postgresql-query-logging/
【Project Euler】Problem 19: 日曜日を数える

* 本記事は[ProjectEuler](https://projecteuler.net/about)の「100番以下の問題の説明は記載可能」という規定に基づいて回答のヒントが書かれていますので、自分である程度考えてみてから読まれることをお勧めします。

### 問題 19. 日曜日を数える

原文 [Problem 19: Counting Sundays](https://projecteuler.net/problem=19)

**問題の要約：20世紀の日曜日の数を数えよ**

問題には親切に、2月は普通28日、うるう年は29日、ただし100年に一度は違うけど400年に一度はうるう年、等の説明があるので自力で書けと言うことだと思いますが、、ここはpythonの**datetime**を使って簡単に、、、weekday()メソッドの出力は**6**が日曜日のようです。

```python
import datetime
print([datetime.date(year,month,1).weekday() 
        for month in range(1,12+1) 
        for year in range(1901,2000+1)].count(6))
```

（開発環境：Google Colab）
【Project Euler】Problem 18: 経路の合計の最大値 （その１）

* 本記事は[ProjectEuler](https://projecteuler.net/about)の「100番以下の問題の説明は記載可能」という規定に基づいて回答のヒントが書かれていますので、自分である程度考えてみてから読まれることをお勧めします。

### 問題 18. 経路の合計の最大値 （その１）

問題の原文 [Problem 18: Maximum path sum](https://projecteuler.net/problem=18)

**問題の要約：上から下まで数字をたどった経路の合計の最大値を求めよ**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1922159/df5a3b49-4cae-6f4c-a436-334e1b599d08.png)

一番下の行から順に値の大きい方を足して行くことによって最後に最大値が求まります。この例題の場合の推移を表のステップ#1-3で示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1922159/3369575d-78d2-ee7f-f638-28507ec306c6.png)

||ステップ1|ステップ2|ステップ3|
|:---:|:---:|:--:|:--:|
|3|3|3|**23**|
|7 &ensp;4|7 &ensp;4|**20 19**|20 19|
|2 &ensp;4 &ensp;6|**10 13 15** |10 13 15 |10 13 15 |
| 8 &ensp;5 &ensp;9 &ensp;3 | 8 &ensp;5 &ensp;9 &ensp;3 | 8 &ensp;5 &ensp;9 &ensp;3 | 8 &ensp;5 &ensp;9 &ensp;3 | 

プログラムにすると以下のようになります。三角形の配列**triarr**を作るコードは長いので下に載せました。

```python
for y in range(len(triarr)-2,-1,-1):
  for x in range(y+1):
    triarr[y][x] += max(triarr[y+1][x],triarr[y+1][x+1])
print(f"Answer: {triarr[0][0]}")
```

```python
import numpy as np

s = "75 "\
"95 64 "\
"17 47 82 "\
"18 35 87 10 "\
"20 04 82 47 65 "\
"19 01 23 75 03 34 "\
"88 02 77 73 07 63 67 "\
"99 65 04 28 06 16 70 92 "\
"41 41 26 56 83 40 80 70 33 "\
"41 48 72 33 47 32 37 16 94 29 "\
"53 71 44 65 25 43 91 52 97 51 14 "\
"70 11 33 28 77 73 17 78 39 68 17 57 "\
"91 71 52 38 17 14 91 43 58 50 27 29 48 "\
"63 66 04 68 89 53 67 30 73 16 69 87 40 31 "\
"04 62 98 27 23 09 70 98 73 93 38 53 60 04 23 "
N = 15
nums = s.split()
triarr, top = [], 0
for i in range(N):
  top += i 
  triarr.append(list(map(int,nums[top:top+i+1])))
```
【Project Euler】Problem 17: 数字を英語で書いたときの文字数

* 本記事は[ProjectEuler](https://projecteuler.net/about)の「100番以下の問題の説明は記載可能」という規定に基づいて回答のヒントが書かれていますので、自分である程度考えてみてから読まれることをお勧めします。

### 問題 17. 数字を英語で書いたときの文字数

原文 [Problem 17: Number letter counts](https://projecteuler.net/problem=17)

**問題の要約：１から1000までの数字を英語で書いたときの文字数の合計を求めよ（スペースやハイフォンは除く）**

結構面倒くさいですが、地道に各桁ごとに英語に直すプログラムを作りました。

```python
nname1 = ["zero", "one", "two",  "three", "four", "five", "six", "seven", "eight", "nine",\
         "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eithteen", "nineteen"]
nname10 = ["", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"]
def digit19(n):
  return nname1[n]

def digit99(n):
  if n < 20: return digit19(n)
  return nname10[n//10]+" "+nname1[n%10]

def digit999(n):
  if n < 100: return digit99(n)
  if n%100 == 0: return nname1[n//100]+" hundred"
  return nname1[n//100]+" hundred and "+digit99(n%100)

def digit9999(n):
  if n < 1000: return digit999(n)
  if n%1000 == 0: return nname1[n//1000]+" thousand"
  return nname1[n//1000]+" thousand and "+digit999(n%1000)
```

これらを使って1000までの文字数（スペースは削除）の合計をだします。

```python
print(sum([len( digit9999(i).replace(" ","")) for i in range(1,1001)]))
```

しかしその後いろいろ調べたらpythonに**num2words**というモジュールがあることが分かりました。Google Colabには標準で入っていないのでインストールする必要があります。

```python
!pip install num2words
from num2words import num2words
print([num2words(i) for i in [14, 21, 99, 115, 299]])
['fourteen', 'twenty-one', 'ninety-nine', 'one hundred and fifteen', 'two hundred and ninety-nine']
```

これを使えば1行で完成。ハイフォンもあるので正規表現モジュールの**re.sub**を使って削除しました。

```python
import re
print(sum([len(re.sub('[ -]','', num2words(i))) for i in range(1,1001)]))
```

（開発環境：Google Colab）
【Project Euler】Problem 16: 2のべき乗の数字和

* 本記事は[ProjectEuler](https://projecteuler.net/about)の「100番以下の問題の説明は記載可能」という規定に基づいて回答のヒントが書かれていますので、自分である程度考えてみてから読まれることをお勧めします。

### 問題 16. 2のべき乗の数字和

原文 [Problem 16: Power digit sum](https://projecteuler.net/problem=16)

**問題の要約：2の1000乗の数字和を求めよ**

この問題も桁数制限のないPythonでは簡単です。数字和は今後もよく使うので**digitsum**という関数にしておきます。

```python
def digitsum(n):
  return sum(map(int,str(n)))

print(f"Answer : {digitsum(2**1000)}")
```

（開発環境：Google Colab）