OmniAICreator/Qiita-1.07M huggingface dataset:
【令和最新版】Array#sample と Random#rand ってどっちが速いんかな

## 背景
以前に `sample` と `rand` についてベンチマークを比較した[記事](https://qiita.com/kurashita/items/e1ef4604cb0a4f5e5a85)を書きましたが、いくつか見直すべき点があったため改めて投稿したいと思います。

## 検証
### `Kernel.#rand` より `Random.rand`

前記事では `Random.rand` と言いながら `Kernel.#rand`（つまり単に `rand`） を混同して使っていました。
なので改めて以下のように `Kernel.#rand` と `Random.rand` を比較してみます。

```ruby
num = 10000
count = 1000000

Benchmark.bm 20 do |r|
  r.report 'Kernel.#rand' do
    count.times do
      rand(num)
    end
  end

  r.report 'Random.rand' do
    count.times do
      Random.rand(num)
    end
  end
end
```

```txt:結果
                           user     system      total        real
Kernel.#rand           0.190434   0.000193   0.190627 (  0.190932)
Random.rand            0.084481   0.000194   0.084675 (  0.084819)
```

`Random.rand` のほうが2倍以上高速でした。


### `range` より `+1`

`rand` の引数には `Range` オブジェクトを受け取ることが出来ますが、1以上10000以下のような範囲なら `1..10000` の `Range` より `10000` の `Ingeger` を与えて `+1` するほうが高速です（`rand(10000)` は `0〜9999` の値をランダムで返すため）。

```ruby
Benchmark.bm 20 do |r|
  r.report 'Random.rand(range)' do
    num.times do
      Random.rand(range)
    end
  end

  r.report 'Random.rand(+1)' do
    num.times do
      Random.rand(10000) + 1
    end
  end
end
```

```txt:結果
                           user     system      total        real
Random.rand(range)     0.243092   0.000319   0.243411 (  0.244819)
Random.rand(+1)        0.084825   0.000072   0.084897 (  0.085032)
```

3倍近く早くなってます。


### 結果
以上を踏まえて `Array#sample` も加えてベンチマークを取ってみます。

```ruby
num = 10000
range = (1..num)
array = range.to_a
count = 1000000
　
Benchmark.bm 20 do |r|
  r.report 'Array#sample' do
    count.times do
      array.sample
    end
  end

  r.report 'Kernel.#rand(range)' do
    count.times do
      rand(range)
    end
  end

  r.report 'Kernel.#rand(+1)' do
    count.times do
      rand(num) + 1
    end
  end

  r.report 'Random.rand(range)' do
    count.times do
      Random.rand(range)
    end
  end

  r.report 'Random.rand(+1)' do
    count.times do
      Random.rand(num) + 1
    end
  end
end
```

```txt:結果
                           user     system      total        real
Array#sample           0.143643   0.000186   0.143829 (  0.144033)
Kernel.#rand(range)    0.137866   0.000146   0.138012 (  0.138163)
Kernel.#rand(+1)       0.194007   0.000154   0.194161 (  0.194374)
Random.rand(range)     0.244600   0.000151   0.244751 (  0.244960)
Random.rand(+1)        0.086753   0.000071   0.086824 (  0.086926)
```

結果的には `Random.rand` に `+1` するのが予想通り最速でしたが、`Array#sample` もそこまで遅いわけではないようです。
また、`Range` オブジェクトを渡す場合は `Random.rand` より `Kernel.#rand` のほうが速いというのは意外でした。もし1始まり以外の範囲を使いたい場合は `Kernel.#rand` を使っても良さそうです。それと `range.to_a` はループの度にやると非常に遅いので事前に用意しておくのが重要です。

## 最後に

ランチェスターではパフォーマンスにうるさいサーバーサイドエンジニア社員を募集しております！
まずはざっくばらんにお話しさせてください。下記からご応募お待ちしております。
▼https://herp.careers/v1/lanchester/Bucw0mXRKogc
▼https://www.wantedly.com/companies/lanchester
▼採用動画について：https://moovy.jp/job/651
Windows10でGitHubを始める～④リモートリポジトリの作成（GitHub）

個人学習メモ。

# 1.GitHub上にリモートリポジトリを作成する

右上の＋から「New Repository」、もしくは左メニューの「New」をclick。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/4b917936-e70c-c394-8c4d-f5ef680ce8d8.png)
Create a new repository 画面が開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/e45e3070-b47f-0540-5caa-eaf8104890f7.png)

 - Repository template：`No template`のままでよい
 - Owener：`＜自身のアカウントユーザ名＞`のままでよい
 - Repository name：自由に入力（画像の例では`qiita-test`としている）
 - Description：リポジトリの利用用途がわかる説明を入れておくとよい。空欄のままでもよい。（画像の例では`Create remote repository test.`としている）
 - 公開範囲を`Private`にしておく。（リポジトリを全世界に公開したい場合は`Public`にする）

今回はその他のチェックはしないで「Create repository」をclickする。
以下のような画面が表示され、「qiita-test」という名前のリモートリポジトリが作成された。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/56d77f01-7c7b-7814-5847-985b0d247b20.png)

# 参考
[Windows10でGitHubを始める～⓪Gitの概念とインストールソフトの種類](https://qiita.com/emiki/items/5c8e52cf6b8506015462)
[Windows10でGitHubを始める～①Gitインストール](https://qiita.com/emiki/items/c0aa0b4da4b63921b153)
[Windows10でGitHubを始める～①'おまけGitホームディレクトリ変更](https://qiita.com/emiki/items/d3f7c054b70171218f64)
[Windows10でGitHubを始める～②GitHubアカウント作成](https://qiita.com/emiki/items/dadf77e9ae1e2b192323)
[Windows10でGitHubを始める～③GitHubでのメールアドレス設定とGitクライアントでのユーザ名・メールアドレス設定](https://qiita.com/emiki/items/4103150a5d7a7cfbff24)
[Windows10でGitHubを始める～③'おまけユーザ名・メールアドレス設定について詳細](https://qiita.com/emiki/items/24212696b54fd16e8af8)
[Windows10でGitHubを始める～④リモートリポジトリの作成（GitHub）](https://qiita.com/emiki/items/5080d948af4a2d0febf5)
[Windows10でGitHubを始める～⑤Githubにプッシュする](https://qiita.com/emiki/items/a2871ab626396e95d9ec)
[Windows10でGitHubを始める～⑥-0.Git～GitHub間の認証について](https://qiita.com/emiki/items/eeaf77d51aadef98aea9)
[Windows10でGitHubを始める～⑥-1.Git操作時のGitHub認証HTTPS（Git Credential Manager）](https://qiita.com/emiki/items/3f2ebda7280374fb3bb7)
[Windows10でGitHubを始める～⑥-2.Git操作時のGitHub認証HTTPS（Personal access token）](https://qiita.com/emiki/items/498b05ede19eee3ad916)
[Windows10でGitHubを始める～⑥-3.Git操作時のGitHub認証SSH編](https://qiita.com/emiki/items/1f1fc0bf0c2c4347148d)
[Windows10でGitHubを始める～⑦GitHubへのPullRequest](https://qiita.com/emiki/items/8619441dca761869177f)

GitHub無料プランでもリポジトリが非公開にできるようになったのは最近ぽい

https://forest.watch.impress.co.jp/docs/news/1161195.html
【PWA】PWAについて

## はじめに
　本記事は、プログラミング初学者が、学習を進めていて疑問に思った点について調べた結果を備忘録も兼ねてまとめたものです。
　そのため、記事の内容に誤りが含まれている可能性があります。ご容赦ください。
　間違いを見つけた方は、お手数ですが、ご指摘いただけますと幸いです。

## PWA　について
### PWAとは
PWAとは、「Progressive Web Apps」の略で、Webアプリをネイティブアプリのように使用するための技術です。
以下のような特徴があります。

- Push通知可能
- インストール不要
- アイコンのホーム画面への追加
- プリキャッシュ機能による表示速度の高速化
- データキャッシュによるオフライン動作が可能
- ネイティブアプリのようなUI（アドレスバー等を非表示）
　　　　　　　　　　　　　　　　　　　　　　等

### PWA開発に使用する言語
主な言語は、JavaScriptです。
React、Vue、Angularといったライブラリやフレームワークで作成されることが多いです。

### PWAのメリット
**1. 開発が容易**
最も少ない場合で１つのファイルを追加するだけで開発をすることができる。
また、PWAはウェブサイトの技術を基本にしたクロスプラットフォームであるため、一度開発をしてしまえば他のデバイスのために開発する必要がありません。

**2. アプリ審査が不要**
ネイティブアプリではないためアプリ審査が不要で、Webアプリと同じようにスムーズに公開することができます。

**3. ユーザーとの接触機会増加が期待できる**
ユーザーがアプリケーションをアプリストアを経由してインストールをする必要はなく、容易に利用することができます。
また、プッシュ通知も可能であるため、接触頻度が増えることが期待できます。

**4. 読み込みが速い**
プリキャッシュ機能により、通常のWebアプリよりも初期表示を早くすることができます。
読み込みが速いことで、ユーザーが利用しやすいだけでなく、SEO対策にも効果的です。

### PWAのデメリット
**1. ハードウェアベースの機能を使用することはできない**
ネイティブアプリと違い、PWAはハードウェアベースの機能（ジャイロセンサー等）を使用することはできません。

**2. SSL化が必要**
PWAは、httpsを前提にした技術であるため、HTTPで構築されているWebアプリであれば、httpsにする必要があります。


### 導入事例
- [Twitter](https://mobile.twitter.com/?lang=ja)
- [日経電子版](https://www.nikkei.com/)
- [Suumo](https://suumo.jp/)
　　　　　　等

上記のサイトをsafariで開き、「ホーム画面に追加」をするだけです。

以下の画像はTwitterPWAの画面です。
アドレスバーが表示されていません。

![IMG_F91810FB5098-1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/1c662616-03c2-68e4-015a-156e10f1187e.jpeg)
LANケーブル規格の通信速度

こんにちは。
LANケーブル規格の通信速度を調べました。

短距離（3m以下）
・CAT 5e[^1]: 2.5Gpbs
・CAT 6[^1]: 10Gpbs

長距離・屋内配線（100ｍ以下）
・CAT 5e: 2.5Gpbs
・CAT 6a UTP: 10Gpbs

[^1]: 規格上の最大通信速度は 1Gbps。
【AWS】IAMロールの特徴(メモ)

- 複数のIAMロールを１つのインスタンスにアタッチすることはできないが、１つのIAMロールを複数のインスタンスにアタッチすることはできる。

- IAMロールはユーザに対してもアタッチできるがインスタンスに対してもアタッチできる。

- IAMロールにポリシーを追加したら即時反映される（サーバ再起動は不要）
【G検定対策】人工知能の現代史 (第3次AIブーム)

自分のG検定対策として，まだ覚えられていない部分をまとめました．自己満です．修正コメントお待ちしております．

# 第3次AIブーム
「機械学習と特徴表現の時代」といわれている．


|年|出来事|
|:--|:--|
|1998|ヤン・ルカンにより**LeNet**(CNNモデル)が考案された．|
|2010|**ILSVRC**（ImageNet Large Scale Visual Recognition Challenge）開始．ImageNetを用いた画像認識の精度を競うコンペティション．|
|2011|IBMが開発した**Watson**が，アメリカのクイズ番組ジョパディーに出演し，歴代人間チャンピオンに勝利．<br>日本では，「**東ロボくん**プロジェクト」が開始（〜2016年）|
|2012|ILSVRC2012にて，**ジェフェリー・ヒントン**率いるチームが開発した**SuperVision**が圧勝．用いられたニューラルネットワークは**AlexNet**（8層）．<br>⇢DeepLearningが一気に脚光を浴びる|
|2014|ILSVRC2014にて，**GoogLeNet**（22層）が優勝<br>**VGG**が提案された．|
|2015|ILSVRC2015にて，**ResNet**（152層）が優勝|
|2016/06|進研模試で偏差値57.8をマーク(ほろんどの私大に合格できるレベル)．同年に開発が凍結される．|
|2016|DeepMind社が開発した人工知能の囲碁プログラム**AlphaGo**が，韓国のプロ棋士イ・セドル氏に4勝1敗と勝ち越した．|
|2017/10|AlphaGo Zero発表|
|2017/12|これまでトップクラスであった将棋AI"elmo"が，Alpha Zeroに100戦8勝90敗2分で敗退|
|いつ？|トップクラスのチェスAI”Stockfish”がAlpha Zeroと対局し，白(先手)で25敗，黒(後手)で3敗，残り72局で引き分けた．|


# シンギュラリティー(技術的特異点)に関する発言まとめ
シンギュラリティーとは，人工知能が賢くなり，いつしか人間を超える知が誕生するのではないかという仮説のこと．

|人名|内容|
|:-:|:--|
|レイ・カーツワイル|「2045年にシンギュラリティが到達する」(自著『The Singularity is Near』より)<br>人工知能，遺伝子工学，ナノテクノロジーの3つが組み合わさり，生命と融合した人工知能が実現すると考えている．|
|スティーブン・ホーキング|「完全な人工知能を開発できたら，それは人類の終焉を意味するかもしれない．」|
|イーロン・マスク|「人工知能にはかなり慎重に取り組む必要がある．結果的に悪魔を呼び出していることになるからだ．」ペンタグラムと聖水を手にした少年が悪魔に立ち向かう話を例に挙げている．|
|ビル・ゲイツ|「私も人工知能に懸念を抱く側にいる1人だ」|
|オレン・エツィオーニ|「たとえば100万年後，特異点を迎える可能性はあるが，賢いコンピュータが世界制覇するような終末論論的思想は『馬鹿げている』としか言いようがない」|
|ヒューゴ・デ・カリス|シンギュラリティは21世紀の後半に来ると予測し，その際人工知能は人間の知能の10^24倍と主張．|
|ヴァーナー・ヴィンジ|著書にて「シンギュラリティは，機械が人間の役に立つフリをしなくなること」と定義．|
新卒2年目までにコミュニケーション能力を上げるためにしてきたこと

## プロフィール
- 現在新卒2年目で開発部に所属
- コミュニケーション能力は低く、自分からなかなか話しかけないタイプ

## コミュニケーションとは
- コミュニケーションは社会生活を営む**人間の間**に行われる**知覚・感情・思考の伝達**
- コミュニケーションは大きく口頭伝達と文書伝達の2つに分けることが可能
    - 口頭伝達
        - 直接会話したり、オンライン会議など直接口で伝えること
    - 文書伝達
        - メールやチャットなど書面で伝えること
- 目的
    - 情報のやりとり
    - 人間関係を築く
    - 行動を促すこと

### :star:ビジネスにおいて大切なこと
- 「伝わる」こと
    - 「伝えたつもり」ではなく、「伝わる」コミュニケーションをすることが大事

## コミュニケーションの目的を達成するために
- コミュニケーションの目的を達成するために必要な能力は3つ
    - 伝える力
        - 物事を伝える力は、コミュニケーション能力の基本
    - 理解する力
        - 会話を引き出すことや内容を理解することも重要
    - 非言語でやりとりする力
        - 表情や声のトーン、視線やジェスチャーなど

この3つの能力がすべてが足りていないと感じ、1年半程試行錯誤しながら改善してきました。

### コミュニケーション改善にしてきたこと
#### 1. ラーニングエージェンシー
https://www.seminar.learningagency.co.jp/app/gate

ラーニングエージェンシーでは主に3つの分野を受講しました。
- ビジネス・ライティング
- ビジネス・トーキング
- プレゼンテーション

業務でチャットベースのコミュニケーションを取ることが多いことからまずはライティングから学び、次にトーキングについて学びました。プレゼンテーションについては課会でLTをすることがきっかけで受講しました。
振り返るとどれが大事というよりかは、目的に合ったものを受講することが良いと思っています。

#### 2. 課会でのLT
LTは去年の3月から数回行っており、主にラーニングエージェンシーの内容をまとめて発表していました。大勢の前で発表することが苦手だったため、少人数(6～7名)の課会で慣れていくことができました。
個人的にこのLTが一番話すことの自信につながったと思います。

#### 3. 社員インタビュー
今期取り組んでいた内容で、主に技術部のメンバーへ社員インタビューを行っていました。他人に興味を持つためにはじめ、コミュニケーション能力の向上を目指しました。インタビューをした上で、自分には何が足りていないかを実感したり、お相手の方からアドバイスをいただいて現在実践中です。特にリアクションがあまりできていない状態が続いています。。
この社員インタビューで普段話さない方と話すきっかけになり、面白い企画でした。

## 今後について
まだコミュニケーション能力があるとは思っていません。特にその場の対応力が足りていないことを実感しているため、改善していこうと思います。目標としては大きく、営業のようにコミュニケーション能力が高い人を目指していきます！
コミュニケーション能力向上のために他に良い方法がありましたらご教授いただけますと幸いです。
40 代おっさんGAS使ってLINE Botで値をスプレッドシートに書き込みしてみる！

## 本記事ついて

本記事は プログラミング初学者の私が学習していく中でわからない単語や概要をなるべくわかりやすい様にまとめたものです。
もし誤りなどありましたらコメントにてお知らせいただけるとありがたいです。

## 目標

・セルにとりあえず何かの値を突っ込む‼
・まだ考えていないが、ケアマネ業務で外に出たときにLIENから簡単なことをスプレッドシートに入れれるようにする‼
＊PCあれば問題ない、ケアマネならノートPCを持っていない人も居るかもしれない‼
そんな人を助けるのだ‼

## スプレッドシートに書き込みする

### スプレッドシートを用意

前回のを使いまわし
前回が気になる方は

<https://qiita.com/kou1121/items/d9fb96bea9bfa5d125b8>

![スプレッドシート２.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641940/55b54778-1908-050a-19a6-d9ee7855b6d2.png)

### コードを用意

```javascript
// LINE Message API チャネルアクセストークン
const ACCESS_TOKEN = "[チャネルアクセストークン]";
// リプライ用のLINE API
const REPLY        = "https://api.line.me/v2/bot/message/reply";

// GoogleスプレッドシートをID取得
const File = SpreadsheetApp.openById('[GoogleスプレッドシートのID]');
//シートをシート名で取得
const baseSheet = File.getSheetByName('シート1');
//行の最期を取得
const lastRow = baseSheet.getLastRow();

/** 
 * ユーザーからのアクションに返信する
 */
function doPost(e) {
  const json = JSON.parse(e.postData.contents);

  //返信するためのトークン取得
  const replyToken = json.events[0].replyToken;
  if(typeof replyToken == 'undefined') {
    return;
  }

  //送られたメッセージを取得
  const message = json.events[0].message.text;
  //LINEメッセージを改行で分割
  const messageParameter = message.split(/\r\n|\n/);

  //セルへの書き込み
  baseSheet.getRange('A' + (lastRow + 1)).setValue(messageParameter[0]);
  baseSheet.getRange('B' + (lastRow + 1)).setValue(messageParameter[1]);

   //リクエストヘッダ
    const headers = {
      "Content-Type" : "application/json; charset=UTF-8",
      'Authorization' : 'Bearer ' + ACCESS_TOKEN //'Bearer 'スペース忘れずに
    };

    //POSTオプション作成
    const options = {
      'method'  : 'POST',
      'headers' : headers,
      'payload' : JSON.stringify(postData)
    };

    return UrlFetchApp.fetch(REPLY, options);
}
```

![新規登録.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641940/e2ac4322-d763-449f-8b69-c3339dddc142.png)

![新規登録受けて.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641940/e1c94a70-1840-c855-db6e-cc6f9a2002ef.png)

このように増えています。

## 参考資料

<https://www.amazon.co.jp/%E8%A9%B3%E8%A7%A3-Google-Apps-Script%E5%AE%8C%E5%85%A8%E5%85%A5%E9%96%80-%E7%AC%AC3%E7%89%88/dp/4798064742>

<https://qiita.com/rechiba3/items/6e999d1e360442f4f38a>
RDSが「Storage-full」になった時の対応方法

## 概要

急にサイトが500エラーを発生してつながらなくなったので調査して見ると
RDSのステータスが「Storage-full」、つまりデータ容量がいっぱいになったことが原因でつながらなくなっていた。

<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308656/fdd99ef0-efdc-3d81-9e80-daf07cc22abc.png">

## 対処方法

前提として、「Storage-full」になるとインスタンスが停止するので、DBに繋げてデータを削除することができない。
そのため`RDSのストレージ容量を拡張する`をする必要がある。


以下、手順です。

１．RDSの画面から拡張したいDBを選択した状態で「変更」ボタンを押す
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308656/3438eeb7-2520-3a4a-53c1-51f02f3ae428.png">

２．ストレージを増やす（例だと20GBから30GBに増やしている）
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308656/86a97b43-f080-bec8-4bf1-3e015b0499c5.png">
↓↓↓
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308656/8b40a2b8-8cf3-8883-d8bc-b857ce2b8efe.png">

### 拡張する時の注意
RDSのストレージ容量を増やすと後から減らすことはできない。
どうしても減らしたい場合は、一度拡張した後にデータを削除した後にdumpを取ってから別のRDSインスタンスを作る必要がある。

ちなみに10GB増やすだけならそんなに金額は掛からない。
例：
リージョン：東京リージョン
ストレージタイプ：汎用 (SSD) ストレージ
＄0.138/GB × 10GBとなるので、＄1.38/月となる。
1ドル=115円と計算すると約160円くらい。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308656/65283d36-b53a-3691-d827-83d79f23b2bb.png">

[参考：RDS料金](https://aws.amazon.com/jp/rds/mysql/pricing/?pg=pr&loc=2)

## 今後の対策

取れる方法は２つ

１．CloudWatchでストレージ容量を監視し、容量がいっぱいになったら消す
不要なデータを消すことができるならこれが一番お金がかからない。

２．RDSのオプションで容量をスケーリングさせる
RDSのオプションで容量を自動拡張させることができる
そもそもデータ消すことができないのであれば、こっちで対応した方がいい。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308656/40c36e43-8e93-8a25-2b47-2ec070ae69a3.png">

私の場合は、コストの関係上「１」で対応することになったが、CloudWatchなどの設定はそんなに難しくなく数分で対応できた。

[CloudWatch設定方法はこちら](https://qiita.com/chin-zabro/items/3197ddb17b2c694546d7)


以上となります。
Jetpack ComposeでMaterial


# はじめに

こんにちは。Anroidエンジニア歴約二年のgottieです。
業務ではAndroid Classic Viewを触れていますが、個人ではせっせとJetpack Composeで遊んでいます。
今回は`Jetpack Compose`でのMaterial Colorの決め方を紹介します。

Android Classic Viewでもそうですが、いつも適当に色を決めていって、Darkモードなどを考慮すると収集がつかなくなっていたいたのですが`JetPack Compose`はMaterial Colorとの親和性が高く、簡単にプロダクトに取り込むことができます。

# 方法

1.色を定義

- アプリで使用するメインの色(primary)として一色決めます。色の濃さは中間が推奨されているで500とします。([こちら](https://materialui.co/colors/))  
-  メインのサブ(primaryVaiant)も必要ですが、ライトテーマとダークテーマに備えてメインの色より濃いものと薄いものを準備します。
-  アプリで使用するサブの色(secondary)として一色決めます。こちらもメインの色と同じで濃さが中間のものを一つ選び、そのサブとして濃いものと薄いものを準備します。
-  Gray系の色は何種類も使用してよいので、白から黒まで一通り準備します。
-  エラーは赤色(`0xBFF00020`)を使用しましょう。アプリのテーマとして赤を使用する場合はエラー色の検討が必要です。

```kotlin:Color.kt
// PRIMARY
val LightBlue300 = Color(0xFF4FC3F7)
val LightBlue500 = Color(0xFF03A9F4)
val LightBlue700 = Color(0xFF0288D1)

// Secondary
val LightGreen200 = Color(0xFFC5E1A5)
val LightGreen500 = Color(0xFF8BC34A)
val LightGreen800 = Color(0xFF558B2F)

val White = Color(0xFFFFFFFF)
val Gray100= Color(0xFFCFD8DC)
val Gray300 = Color(0xFFE0E0E0)
val Gray500 = Color(0xFF9E9E9E)
val Gray700 = Color(0xFF616161)
val Gray900 = Color(0xFF212121)
val Black = Color(0xFF000000)

val Error = Color(0xBFF00020)
```
2.ライトテーマとダークテーマで使用する色を定義する。
- `Color.kt`で定義した色をライトテーマ用、ダークテーマ用として定義します。
- ダークテーマにはより薄い色を、ライトテーマにはより濃い色を適用するとよさげです。(個人の見解)
- `background`と`surface`のカラーは微妙に変えておくことで多重ダイアログなどのときに背景が重なることを避けらると思います。
```kotlin:Theme.kt
private val DarkColorPalette = darkColors(
    primary = LightBlue500,
    primaryVariant = LightBlue300,
    secondary = LightGreen500,
    secondaryVariant = LightGreen200,
    background = Gray900,
    surface = Gray700,
    error = Error,
    onPrimary = White,
    onSecondary = White,
    onBackground = White,
    onSurface = White,
    onError = White
)

private val LightColorPalette = lightColors(
    primary = LightBlue500,
    primaryVariant = LightBlue700,
    secondary = LightGreen500,
    secondaryVariant = LightGreen800,
    background = Gray100,
    surface = Gray300,
    error = Error,
    onPrimary = Black,
    onSecondary = Black,
    onBackground = Black,
    onSurface = Black,
    onError = Black
)
```



# 終わり

ダークテーマにしたら文字が見えない！！！
ダイアログが背景色と被る！！！
などの不具合から解放されました。
Jetpack Compose楽しい～

# 参考
[Material Design](https://materialui.co/colors/)
[The color system](https://material.io/design/color/the-color-system.html#color-theme-creation)
[公式ドキュメント](https://developer.android.com/jetpack/compose/themes/material?hl=ja)
去年(2021)の2月にSAAを合格した話

## プロフィール
- 現在新卒2年目で、当時は新卒1年目
- 開発部に所属しており、業務ではAWSはあまり触っていない
- サービスの名前と役割が紐づいていないぐらい知識はなかった
- 
## 勉強期間
- 期間: 2020/10～2021/02の約半年間
- 内容: 主に以下の3つ
    - 社内の研修
    - Udemy
    - AWS WEB問題集で学習しよう

## 社内の研修
- 隔週で約2時間の講義が全10回程
- 問題演習が多めでその場で解説を受けていた
- 合計20時間

## Udemy
- 以下の講座を受講
    - 【2022年版】これだけでOK！ AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座

https://www.udemy.com/course/aws-associate/

- この講義では20サービス以上のハンズオンと3回分の模擬テストを受けることが可能
- ハンズオンの前にサービスについての説明があるためそこまでハードルは高くなくおすすめ！
- 勉強期間は3週間で模擬テストは3周程
- 1日の勉強時間は平日は業後に2時間程度、休日は6～8時間程度
- 合計約50時間

## AWS WEB問題集で学習しよう
https://aws.koiwaclub.com/

- 効率的な2つのポイント
    - 効率的にAWSをマスターできること
        - 全11科目、3000問以上の実践的な問題集を使用して学習可能
        - 問題は順次更新されていくため最新の問題を解くことも可能
    - 隙間時間の有効活用
        - スマートフォンにも対応しており通勤時間を有効活用ができる
        - 7問1セットとなっており、ワンクリックで回答がすぐに表示されることが特徴
- 注意事項
    - 1度解いた問題の正解/不正解を記憶する機能がない
- :star:ポイント
    - 数字が大きいものが最新の問題のため、後ろの問題から絶対に解くこと
- 期間は1ヶ月程度で全問題を1周し、その後は#91以降を2、3周程
- 1日の勉強時間は平日は業後前・昼休憩・業務後含めて2～3時間、休日は6時間程度
- 1日49問7セットを目標に取り組んでいました。
- 何時間勉強したか覚えていない

## 勉強テクニックと解答のコツ
### 1. 学習計画を立てる
<details><summary>受験日を最終日として逆算して学習計画を作成する</summary>受験日から逆算して学習計画を立てる必要があります。受験日を決めることで目標が明確になり、限られた時間内で集中することができます。受験日を決めないと目標が明確にならずだらだらしてしまうため、まずは受験日を決めると良いです。

また、毎日の勉強計画はおおまかに立て、て挫折しないために余裕を持った計画を立てることがコツです。学習記録をして進捗の管理や調整・修正を行ってもいいと思います。</details>

### 2. 記憶に定着させるために問題を解く
<details><summary>覚えるよりも思い出すことで記憶に定着する</summary>暗記という目的においては、思い出すことが重要です。覚えることよりも思い出すことで記憶に定着するからです。ただテキストを読み返すより問題に答える方が圧倒的に復習効率は良いです。そのため問題演習でアウトプットしていくことがおすすめです。間違った問題は正解できるまで解き直すことが大切です。</details>

### 3. 継続して勉強する
<details><summary>はじめの勉強の敷居を低くする</summary>勉強する習慣をつけることがとても大事です。継続するためにはじめの勉強の敷居を低くすることです。

例えば先程紹介したUdemyの動画を聞き流すことです。聞き流すことであれば他のことをしながらできますし負担は少ないと思います。
とにかく実績を作り達成感を得ることが重要です。最初は分からないところは飛ばしていき、最後まで終えた後分からなかったところを重点的に勉強していきます。この繰り返しによって分からなかったところが次第にわかるようになります。知的な欲求が満たされると勉強に楽しみを覚え、ますます継続できるようになり一気に知識の定着が上がります。</details>

### 4. 問題文から要件を抽出する
<details><summary>文中から問題を解くために必要な情報だけを理解するように努める</summary>問題文が長いため文中の情報を全て理解しようとせず、文中から問題を解くために必要な情報だけを理解するように努めるのがよいです。文末から現状のシステムと要件を切り分けることが可能です。また解ける問題を多くするためによく出るキーワードは覚えるようにした方が良いです。</details>

## さいごに
- 1年前のことだが振り返ってまとめてみた
- SAAを取得したことによって業務の幅が広がったことは実感している
- クラウドに注目されている今、AWSの資格はキャリアアップに有利とされている
- 別の資格も取得したいと思っているため、お互い勉強頑張りましょう！
Laravel/Vueの練習アプリをHerokuに公開する ver.2

こんばんは！

前回の続きとなります。
今日は「HerokuのDBに接続し、マイグレートする」までの手順です

## 前回まで
https://qiita.com/takapon21/items/32630a6ed8b948b053b0

こちらをご覧いただけますと幸いです
前回はデプロイするまで実施いたしました


## ① DBのアドオンを設定する （Webでやる場合）
まずはwebのherokuにログインします

タブの「Resources」をクリックすると、 **Add-ons**という項目が見えているはずです
![スクリーンショット 2022-02-28 22.26.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1422262/86330145-47f9-3f88-bfa7-b35fa9a01ed1.png)


ではpostgresqlを紐づけていきましょう！
下記の画面右側、「**Find more add-ons**」をクリックします
![スクリーンショット 2022-02-28 22.28.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1422262/8e8ce34e-795f-b873-d648-57da48e47d34.png)

すると別タブでストアーが開きますので、「heroku postgres」などと検索してみてください

![スクリーンショット 2022-02-28 22.28.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1422262/b2938a21-e8a7-50d5-7af6-246358abf654.png)

紫に光っているのが、今回インストールするDBです。
これをクリックすると別の画面に遷移するので、「**Install Heroku Postgres**」をクリックしてください
![スクリーンショット 2022-02-28 22.28.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1422262/baac9edc-94dd-5c64-9e67-fd5871981e78.png)

どのアプリにインストールするのか聞かれるので、アプリ名を入力すると最終確認画面が出ます

![スクリーンショット 2022-02-28 22.29.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1422262/590b0305-85ed-64b3-e9dc-44e8d425e582.png)

「**Submit Order Form**」をクリックするとインストール完了です

下記のようにインストールされている事を確認しておきましょう！
![スクリーンショット 2022-02-28 22.29.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1422262/1bfa0591-e06e-e060-818a-334936636424.png)

※個人学習用なので、料金はかかりません

## ② DBのアドオンを設定する（CLIでやる場合）
上記の動作をCLIで実施される方は、
```
$ heroku addons:create heroku-postgresql:hobby-dev
```

これでインストールができますので、お好きな方で設定してくださいね


**※注意点**
無料のアドオンでもクレジットカードの登録が必要なので、そちらの設定も済ませておいてくださいね


## ② 環境変数を設定する
前回はデプロイした際にenvファイルも一緒に取り込んでいると思いますが、herokuだけの設定が必要です

**まずは下準備**
```
$ heroku config:get DATABASE_URL
```

これを入力してください
すると、↓↓のような形式のレスポンスが届きます

```
postgres://αααα:ββββ@ec2-qq-qq-qqq-qq.compute-1.amazonaws.com:PORT/γγγγγγγγ
```

これを言い換えますと
```
postgres://USERAME:PASSWORD@HOST:PORT/DATABSE
```
という形式になっているので、それぞれ分解して登録をしてあげます


## ②-1 Webで設定する場合
Webで設定する場合は、「**Settings**」のタブを開きましょう
![スクリーンショット 2022-02-28 22.52.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1422262/7ed6fe63-f5d6-e1b0-cb47-352e78346632.png)

2段目に、「**Config Vars**」という項目がありますので、紫のボタン「**Reveal Config Vars**」をクリックして追加ができます
![スクリーンショット 2022-02-28 22.52.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1422262/3508aabc-fc53-8748-2e03-ca00f82e7b21.png)

## ②-2 CLIで設定する場合
では、CLIで設定する方法は以下の通りです
```
$ heroku config:set DB_CONNECTION=pgsql
$ heroku config:set DB_HOST=ec2-333-90-222-44.compute-1.amazonaws.com
```

②-3 設定するもののリストはコチラ
それでは、設定して欲しいもの配下の通りになります
```
・ DB_CONNECTION=pgsql
・ DB_HOST=ec2-qq-qq-qqq-qq.compute-1.amazonaws.com
・ DB_DATABASE=γγγγγγγγ
・ DB_USERNAME=αααα
・ DB_PASSWORD=ββββ
```

また、上記で表示されたPORT番号が正しいかも確認しておきましょう

## Migrate！
ではいよいよマイグレートですね

コマンドは以下の通りです
```
$ heroku run php artisan migrate
```

これでうまくできましたでしょうか？
テストを兼ねて、rollbackもやってみてくださいね



今日の作業はここまでです！

## 参考文献
https://qiita.com/takapon21/items/32630a6ed8b948b053b0
しばらくさぼっていたLINEBOTを久しぶりに動かした話

だいぶ前に試してみたものに再度チャレンジしたら、バージョンが古くて振り回された。
ログが長い部分はほげほげしてます。

## コマンドプロンプトからherokuログイン
```ruby:コマンドプロンプト
$ heroku login
heroku: Press any key to open up the browser to login or q to exit:
ほげほげ
Logging in... done
Logged in as メールアドレス
```

## 先にHerokuアプリを作る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683664/6bd66b87-0709-47d4-85c8-3b049a1ea340.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683664/bcc4875b-facf-b64f-da9e-efca4d5e5f81.png)

## アプリへデプロイ
```ruby:コマンドプロンプト
$ heroku git:remote -a アプリ名
set git remote heroku to https://git.heroku.com/アプリ名.git

$ git add .

$ git commit -m "コメント"
On branch master
nothing to commit, working tree clean
```

## push失敗
```ruby:PushFailed
$ git push heroku master
ほげほげ
remote:  !     Push rejected, failed to compile Python app.
remote:  !     Push failed
remote: Verifying deploy...
remote: !       Push rejected to アプリ名.
remote:
To https://git.heroku.com/アプリ名.git
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'https://git.heroku.com/アプリ名.git'
```

## logを確認
```ruby:heroku logs
$ heroku logs
ほげほげ
2022-02-28T12:55:40.000000+00:00 app[api]: Build failed -- check your build output: dashboard.herokuのURL
```
アプリのActivityからも確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683664/60be169e-f468-4e75-e260-6d1ca1b35594.png)

どうやらpython-3.6.3は古いらしい。
他のライブラリに影響がでると嫌なので、とりあえず3.6で使えるやつにした。
```:runtime.txt
python-3.6.15
```

## HerokuへPush
```ruby:コマンドプロンプト
$ git add .
$ git commit -m "fix: python-version"
[master cced326] fix: python-version
 1 file changed, 1 insertion(+), 1 deletion(-)

$ git push heroku master
Enumerating objects: 54, done.
Counting objects: 100% (54/54), done.
ほげほげ
remote: Verifying deploy... done.
To https://git.heroku.com/アプリ名.git
 * [new branch]      master -> master
```

## JSONでエラー
```ruby:500が返ってくる
$ heroku logs
ほげほげ
2022-02-28T13:05:37.103869+00:00 app[web.1]: json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
2022-02-28T13:05:37.104156+00:00 app[web.1]: 10.1.91.183 - - [28/Feb/2022 13:05:37] "POST /callback HTTP/1.1" 500 -
```

## line-bot-sdkが古いらしい
line-bot-sdkを[最新](https://github.com/line/line-bot-sdk-python/tree/78bc3201cf01d9ef918e506abeee5b380c3cafa1/linebot)にした
```:requirements.txt
line-bot-sdk==1.19.0
```

## Pushする
```ruby:コマンドプロンプト
$ git add .
$ git commit -m "fix: line-bot-sdkのversion変更"
[master 1db1bdf] fix: line-bot-sdkのversion変更
 1 file changed, 1 insertion(+), 1 deletion(-)
$ git push heroku master
ほげほげ
remote: Verifying deploy... done.
To https://git.heroku.com/アプリ名.git
   cced326..1db1bdf  master -> master
```

## やっと動いた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683664/5fb418b4-cd42-654a-8623-af31768ac07e.png)

古いアプリはバージョン確認が大事だねというお話。

## 参考
[Heroku の Python サポート](https://devcenter.heroku.com/ja/articles/python-support)
[herokuにデプロイする際に、エラーがでてしまう](https://teratail.com/questions/339870)
jq の使い方

## インストール
`$ brew install jq`
## 説明
Jsonを整形して返してくれるらしい

```ターミナル
% curl -H "Accept: application/json" https://icanhazdadjoke.com/ 

{"id":"ItWSnbUfVnb","joke":"Why did the teddy bear say \u201cno\u201d to dessert? Because she was stuffed.","status":200}
```

```ターミナル
% curl -H "Accept: application/json" https://icanhazdadjoke.com/ | jq

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   112  100   112    0     0    176      0 --:--:-- --:--:-- --:--:--   176
{
  "id": "exXSCtkOKe",
  "joke": "Why do pirates not know the alphabet? They always get stuck at \"C\".",
  "status": 200
}
```

便利そう。
問「awk で \ を \\ に置換せよ」⇒答「gsub(/\\/, "\\\\")」・・・はい残念、間違いでーす。答えは「gsub(/\\/, "\\\\\\\\")」 でーす。けどこれも動きませーん。

## はじめに

困ったもんだよ awk さん

## こんなふうになるよ

**補足** 以下の動作確認環境である Ubuntu では `original-awk` は `nawk` のことです。

```console
$ printf '%s\n' '\' # printf は問題なく \ が出力されていることの確認
\

$ # 以下は全部 \ ４つ

$ printf '%s\n' '\' | gawk '{ gsub(/\\/, "\\\\"); print }'
\\
$ printf '%s\n' '\' | gawk --traditional '{ gsub(/\\/, "\\\\"); print }'
\\
$ printf '%s\n' '\' | gawk --posix '{ gsub(/\\/, "\\\\"); print }'
\

$ printf '%s\n' '\' | original-awk '{ gsub(/\\/, "\\\\"); print }'
\\
$ printf '%s\n' '\' | busybox awk '{ gsub(/\\/, "\\\\"); print }'
\\
$ printf '%s\n' '\' | mawk '{ gsub(/\\/, "\\\\"); print }'
\
```

はい、~~mawk は正しく動きません。~~ mawk と gawk --posix は POSIX の規定通り正しく動いています。

もう一つおまけで gawk の~~謎挙動~~互換性を保つための涙ぐましい挙動

```console
$ printf '%s\n' '\' | gawk '{ gsub(/\\/, "\\"); print }' # \ ２個
\
$ printf '%s\n' '\' | gawk '{ gsub(/\\/, "\\\\"); print }' # \ 4個
\\
$ printf '%s\n' '\' | gawk '{ gsub(/\\/, "\\\\\\"); print }' # \ 6個
\\\
$ printf '%s\n' '\' | gawk '{ gsub(/\\/, "\\\\\\\\"); print }' # \ 8個
\\
```

## 正解は？

POSIX 的な正解は[こちら](https://qiita.com/ko1nksm/items/53abc144558b9bb5629f#-%E3%81%B8%E3%81%AE%E7%BD%AE%E6%8F%9B%E3%81%AE%E4%BA%92%E6%8F%9B%E6%80%A7%E5%95%8F%E9%A1%8C)によるとこれらしいです。ってホントかいな？（まあ自分の記事なんですが・・・）

awk 文法上のエスケープと置換文字列のエスケープで、8 の 半分の半分で 2 なわけですね。

```console
$ printf '%s\n' '\' | gawk --posix '{ gsub(/\\/, "\\\\\\\\"); print }'
\\
```

でもこうなるのでご注意を

```console
$ # 以下は全部 \ 8つ

$ printf '%s\n' '\' | gawk '{ gsub(/\\/, "\\\\\\\\"); print }'
\\
$ printf '%s\n' '\' | original-awk '{ gsub(/\\/, "\\\\\\\\"); print }'
\\\\
$ printf '%s\n' '\' | busybox awk '{ gsub(/\\/, "\\\\\\\\"); print }'
\\\\
$ printf '%s\n' '\' | mawk '{ gsub(/\\/, "\\\\\\\\"); print }'
\\
```

## どうすりゃいいのさ？

`\` を `\\` にするだけならこれが簡単。（これ以外のパターンではどうするのがいいんでしょうかね？・・・）

```console
$ printf '%s\n' '\' | awk '{ gsub(/\\/, "&&"); print }'
\\
```

`&` はパターンにマッチした文字（つまり`\`）に展開される特別な意味を持つ文字です。

さて、では `&` という文字に置換したい場合はどうすればいいでしょうか？⇒ `\&` という文字列にします。ただし `\` という文字を使うためにはエスケープしなければいけないので・・・

```console
$ printf '%s\n' '\' | awk '{ gsub(/\\/, "\\&"); print }'
&
```

これが正解となります。gawk では間違えて `gsub(/\\/, "\&")` と書くと警告してくれるのですが、他の awk では警告なしで `&` となったり `\` （!?） となったりするので、この仕様を知らないと混乱します。このように awk の文法のエスケープとは別に、置換文字列の中でも特殊な文字（`&`）が使えるという仕様があるために二重にエスケープをしなければならず `\` が8 個も必要になるわけですね。

## さいごに

ひさびさに昔書いたコードを変更していたらバグってるのを見つけて、自分が前に書いた記事読み返してみて、こんなんわかるかとムカムカしたので新たに記事にしました。

これだから POSIX 標準規格書だけを眺めてたって、POSIX に準拠して書いたって、どこでも動くシェルスクリプトなんか作れやしないって言うんだ。実際の環境で動作確認しないと動くかどうかなんてわからないのが現実だ。
git commit --allow-empty -m "empty commit"

何も変更をしていないけれども、コミットをしたいことありますよね！
私はあります。
PaaS（Platform as a Service）のアレをナニするときですよ。
これ以上は言いますまい。

```
git commit --allow-empty -m "empty commit"
```

これです。



# ヘルプ

`--allow-empty`とはどういう意味なのかを調べてみます。

```
git help commit
```

上記のコマンドを実行して出てきたヘルプの中から、`--allow-empty`を抜粋しておきます。

```
--allow-empty
  Usually recording a commit that has the exact same tree as its sole parent commit is a mistake, and the
  command prevents you from making such a commit. This option bypasses the safety, and is primarily for use
  by foreign SCM interface scripts.
```

# 記事にした背景

```
git commit --allow-empty -m "empty commit"
```

上記を私は覚えられません。
アウトプットをすることで脳が大事なことだと記憶してくれるんです。

[elixir.jp](https://join.slack.com/t/elixirjp/shared_invite/zt-ae8m5bad-WW69GH1w4iuafm1tKNgd~w)というSlackワークスペースの`#autoracex`というチャンネルで、以前の私の書き込みが役に立ったよ〜　という方がいらっしゃっいました。

![スクリーンショット 2022-02-28 22.55.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131808/e9a81ac0-e32c-7564-81ca-8f02ccbb5215.png)

それで他の方の役に立つことがあるかもしれないとおもいまして、記事にしておきました。

自分自身の記憶のためと、まだ知らないあなたのために書いています。
つまりは
<font color="purple">$\huge{愛💜}$</font>
です。

# この記事は


Advent Calendar 2022 58日目[^1]の記事です。
I'm looking forward to 12/25,2022 :santa::santa_tone1::santa_tone2::santa_tone3::santa_tone4::santa_tone5:
私の[Advent Calendar 2022 一覧](https://docs.google.com/spreadsheets/d/1HQvFjagQLRPjOYAjDVzWp9S4b8dKixxvvaz_TtbZWto/edit#gid=1723448955)。

[^1]: @kaizen_nagoya さんの「[「@e99h2121 アドベントカレンダーではありますまいか Advent Calendar 2020」の改訂版ではありますまいか Advent Calendar 2022 １日目　Most Breakthrough Generator](https://qiita.com/kaizen_nagoya/items/49ebebee3a0377f3b59b)」から着想を得て、模倣いたしました。 

次回もお楽しみに〜。


**花の色はうつりにけりないたづらにわが身世にふるながめせしまに**
[Python] takes 0 positional arguments but 1 was givenエラーの解消


### 経緯
Pythonでtakes 0 positional arguments but 1 was givenとエラーが出た。

直訳すると「引数は0のはずなのに一つ渡されている」とのこと。一つも渡していないはずなのに...。

```python
class Test:
  def test_method():
    print("test")

t = Test()
t.test_mothod() # Test.test_method() takes 0 positional arguments but 1 was given 
```


### 原因と解決方法
Pythonのクラス内で定義した関数を外から呼び出す場合、自動的に第一引数にレシーバーが渡される。それを引き取るための引数を定義してあげる必要がある。慣習的にはselfを使う。

```python
class Test:
  def test_method(self): # selfを追記
    print("test")
```

### ちょっと確認
__selfの中には何が入っているのか？__
```python
class Test:
  def test_method(self):
    print(self) # <__main__.Test object at 0x10ca28b80>

t = Test()
print(t) # <__main__.Test object at 0x10ca28b80>
t.test_method()
```
同じオブジェクトが出力されているのが確認できる。selfの中にはレシーバのインスタンス自身が格納されていることが確認できる。

__self以外でもいいのか?__
```python
class Test:
  def test_method(okame):
    print(okame) # <__main__.Test object at 0x10ca28b80>

t = Test()
t.test_method()
```
全く問題ない。わざわざ変える必要もないけど。

```python
class Test:
  def test_method(self, second):
    print(self) # <__main__.Test object at 0x10ca28b80>
    print(second) # 2

t = Test()
t.test_method(2)
```
第2引数は第1引数のように呼び出す。非常にややこしい。
`t.test_method(2) ≒ t.test_method(t, 2)`のようなものと考えればわかりやすいか。
AtCoder ABC241 D - Sequence Query を __gnu_pbds::treeで解く

https://atcoder.jp/contests/abc241/tasks/abc241_d
を__gnu_pbds::treeで解きます。
<b>これはtreeでないとできない操作ではないです</b>。自分のtreeメモの意味合いが強いです。(treeでも解けるよね。くらいで読んでください)

# (ここで使う)treeの特徴

- treeはほぼsetとして使えます。lower_boundや、[]でのindexアクセスが可能です
- order_of_key(x) x以上が何個存在するか？ を$O(logN)$でクエリ可能です
- find_by_order(x) x番目に大きな要素(0-indexedに注意) の イテレータを$O(logN)$でクエリ可能です
- treeはsetでmultisetではありません

ここでは上記の特徴を使って解いていきます。

# こう考えた
- それぞれの問合せを`上から何番目か？`のクエリに言い換えます。簡単に言い換えることができます
    - クエリ2は、xよりも大きい最初の数字(の最初)の順位から+kした順位です
    - クエリ3は x以上の数字(の最初)の順位から + k - 1した順位です。
- treeはsetなので、複数の同一要素を持てません。このため、ある数$x$を$a_i$に対して$x<<18 + i$などと持つことにします。
    - これは要素数が少ない(1e5や1e6程度)からできることです。クエリによって管理すべき要素数が多い(1e9など)場合はBITなどを使った二分探索を行うべきです

# 実装
```C++
tree<__int128, null_type, less<__int128>, rb_tree_tag, tree_order_statistics_node_update> dat;
```
で定義します。`__int128`を使うのは、入力の数字が1e18のため、`<<18`したいからです。
クエリの結果が`-1`となるか、つまり値が存在しなかった時の処理ですが、これは、クエリ2,3で順位だけを計算し、共通で$0 \leq x < tree.size()$かどうかを判定すればよいです。

取り出した値は、`<<18 + i`されているので、`>>18`して出力します。この時、`+i`の分はビットシフトで消えるので考慮しなくて良いです。

尚、`__int128`はostreamの<<演算子に対応していないです。自分で定義するか、今回の場合は結果の出力は64bit以内であることが自明なので、`long long`に変換して出力します。

```C++
int main() {
    FASTIOpre();
    // treeはsetでmultisetでないため、int64をmultisetとして使うなら、__int128に乗せて<<18 + i + 1などする
    // 　取得した値を使うときは、 >> 18する。このtreeから取得した値を再度クエリするときは >> 18 と << 18する。
    // 以下のクエリはless<T>で問題ない
    // order_of_key(x) x以上が何個存在するか？
    // find_by_order(x) x番目に大きな要素(0-indexedに注意) の イテレータ
    // 順位   6  5    4   3   2   1 (1indexed)
    // 順位   5  4    3   2   1   0 (0indexed)
    // order 5  4    3   2   1    0 (で返す値。つまり、順位を返している)
    // 値    a1  a2  a3  a4  a5  a6 (が、昇順に並んでいるとする)
    
    tree<__int128, null_type, less<__int128>, rb_tree_tag, tree_order_statistics_node_update> dat;
    int q; cin >> q;
    vector<ll> l;
    REP(i, q){
        ll t; cin >> t;
        int target = -1; // 何番目の数がほしい？
        if(t == 1){
            ll x; cin >> x;
            dat.insert(((__int128)x << 18) + i + 1);
            continue;
        } else if(t == 2) {
            ll x, k; cin >> x >> k;
            auto tmp = dat.order_of_key((__int128)(x+1) << 18); // xよりも大きい数
            target = tmp - k; // x以上の数はtmp - 1からなので、 -k したのがほしい番号
        } else if(t == 3){
            ll x, k; cin >> x >> k;
            auto tmp = dat.order_of_key((__int128)x << 18); // x以上の数
            target = tmp + k - 1; // x以上の数はtmpから始まっているので-1する
        }
        if(target < 0) cout << -1 << "\n";
        else if(target >= dat.size()) cout << -1 << "\n";
        else {
            // __int128はostreamに<<できないのでlong longにキャストする。この際、__128の間に>>18すること
            cout << (long long)(*dat.find_by_order(target) >> 18)<< "\n";
        }
    }
}

```

https://atcoder.jp/contests/abc241/submissions/29717537
Adoptium OpenJDK を windows環境へインストールする

# 概要
Adoptium OpenJDKをwindows環境へインストールする方法を紹介します。

# Adoptium OpenJDKとは
AdoptOpenJDKが[Eclipse Foundation](https://www.eclipse.org/)に移行し、[Eclipse Adoptium](https://projects.eclipse.org/projects/adoptium)が誕生しました。
[infoq](https://www.infoq.com/jp/news/2020/06/adoptopenjdk-eclipse-adoptium/)に詳しい記事がありますのでそちらを参照ください。

# ダウンロード
[adoptium](https://adoptium.net/index.html
)のサイトにて、Latest releaseをクリックしmsi形式のファイル（OpenJDK17U-jdk_x64_windows_hotspot_17.0.2_8.msi）をダウンロードします。

<img width="500" alt="adoptium" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221056/606259ff-5f0d-883b-5aa3-e1221afd1cc2.png">

# インストール
ダウンロードしたmsi形式のファイルを実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221056/8563ad3a-85b0-9a0c-37bb-eb7604249b1b.png)

[こちら](https://dan-chan.com/java-update-04/)にもインストール方法の詳細な記事があります。
「Uncaught SyntaxError: Unexpected token '<'」Next.jsとNuxt.jsを同じドメインでデプロイ後にハマったこと 

## 状況
ECSでのデプロイ
SPAのNuxt.jsのアプリが元からあり、SSRのNext.jsを同じドメインでホスティングする。

## デプロイ時の問題
Next.jsのJSとImageが反映されていなかった
`Uncaught SyntaxError: Unexpected token '<'`のエラーが出ていた。

## 結論
ALBでJSのパスとImageのパスを指定しないとJSのファイルとImageを読み込んでくれない。
元からあるNuxt.jsを呼んでしまう。
ALBの設定↓↓↓

![ルール___EC2_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2422935/d9b16078-23a1-fc3b-6942-375371a6821b.png)

## 調べかた
検証でElementを確認。headの中を見る。

```html
<script src="/_next/static/chunks/pages/history/list-xxxxxxxx.js" defer=""></script>
```
URLが `https://sample.com/history/1` であれば、
`https://sample.com/_next/static/chunks/pages/history/list-xxxxxxxx.js`でjsファイルが表示されていなければ、パスが通っていない。

## 感想
検索するとjsのミスで出るエラーという記事が多いが、こんなこともある。次からは自分で解決できるようになりたい。
Raspberry Pi4 画面スリープ停止、コマンドラインから HDMI ON/OFF、USB自動マウント

## 動作確認環境
Pi4B 4G、64 bit Raspberry Pi OS with desktop（bullseye）

## 画面スリープ停止
`sudo raspi-config` -> `2 Display Options` -> `D4 Screen Blanking` -> `Would you like to enable screen blanking?`で`<いいえ>`選択。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/39ec43b4-c241-f6a4-133e-a8c2ea842e05.png" width=50%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/c85c2484-e764-ff42-6aa3-492a1c05e05b.png" width=50%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/a1b8625b-bb93-d5f0-f3a6-4227751c7207.png" width=50%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/d0ab6806-cf34-ad19-d759-b9343af665d7.png" width=50%>

尚、スクリーンセーバー`xscreensaver`とは機能がぶつかるようなので注意。その他の方法等、詳細は以下公式参照。
[Raspberry Pi Documentation - Configuration](https://www.raspberrypi.com/documentation/computers/configuration.html#configuring-screen-blanking "Raspberry Pi Documentation - Configuration")

## HDMI ON/OFF
コマンド例は以下。
```shell
pi@raspberrypi4:~ $ vcgencmd display_power      <- ON / OFF 確認
display_power=1
pi@raspberrypi4:~ $ vcgencmd display_power 0    <- OFF
display_power=0
pi@raspberrypi4:~ $ vcgencmd display_power 1    <- ON
display_power=1
pi@raspberrypi4:~ $
```

文法的には以下。

```shell
vcgencmd display_power [0 | 1 | -1] [display]
```

| Display | ID |
| ---- | ---- |
| Main LCD | 0 |
| Secondary LCD | 1 |
| HDMI 0 | 2 |
| Composite | 3 |
| HDMI 1 | 7 |

CEC系のツールと言えば、`cec-client`や`tvservice`等もあるが、HDMI ON/OFF に関して現在は`vcgencmd display_power`が公式でも推奨されている。ナウなヤングにもバカウケですよ。

参考URL：
[vcgencmd](https://www.raspberrypi.com/documentation/computers/os.html#vcgencmd
 "Raspberry Pi Documentation - Raspberry Pi OS")

## USB自動マウント
ぐぐるとよく`usbmount`や`autofs`が出てくるけど、デスクトップ環境なら`ファイルマネージャ`のメインメニュー`編集` -> `設定`で表示される`設定`画面`ボリューム管理`タブの自動マウント設定でいいんじゃないの？
自分が勘違いしている？
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/27c39fa7-8f47-03a8-fb79-f90b41f282cb.png" width=70%>

因みに`usbmount`は公式パッケージから削除された模様。
[STICKY_ Bullseye - Comments and bug reports thread.](https://forums.raspberrypi.com/viewtopic.php?t=323281&start=725#p1974318 "STICKY_ Bullseye - Comments and bug reports thread. - Page 30 - Raspberry Pi Forums")
> usbmountは、長い間未解決のバグと何年にもわたるメンテナンスの欠如により、Debianから永久に削除されました。

[#1002945 - RM_ usbmount -- RoQA; unmaintained, dead upstream, RC-buggy - Debian Bug report logs](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1002945 "#1002945 - RM_ usbmount -- RoQA; unmaintained, dead upstream, RC-buggy - Debian Bug report logs")
> 親愛なるftpマスター、
> 
> usbmountを引退する時が来たと思います：2014年（＃774149）以来RCバギーであり、
2015年にテストから削除されました。安定したリリースになったことはありません。

それと`autofs`は昔入れてみたことがあるけど、前述ファイルマネジャーの自動マウント設定機能とバッティングするのか、上手く動かなかった記憶が。
標準入力で受け取った文字列を数値配列化【Stream.of().mapToInt】

# Paizaのスキル問題に挑むためのコピペ

[参考記事](https://qiita.com/takahirocook/items/51265073d04958250b12)
私の初心者レベルでは一発理解が出来なかったので、私なりの解説をメモ代わりに記載しておく。

## Paizaのスキルチェックはすべて標準入力

なのでまずは受け取って、配列に入れて、配列を数値化して、そうして初めて変数XだYだのに入れ込める。

## @takahirocook 氏のコード

~~~java
import java.util.Scanner;
//Stream APIのインポート
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        // scannerのインスタンス化
        Scanner sc = new Scanner(System.in);

        // 空白区切りに文字型で要素ごとに配列に分割
        String[] stringArray = sc.nextLine().split(" ");
        // String型配列 を int型配列 に変換
        int[] intArray = Stream.of(stringArray).mapToInt(Integer::parseInt).toArray();
~~~

とあるが、肝心なところは２点ある。一つ一つ解説をしよう。

### まずは配列への格納

~~~java
        String[] stringArray = sc.nextLine().split(" ");
~~~

標準入力（Paizaの課題が入力してくる数値）が入っている変数**SC**に対して**split()** をあてることで配列化する。
課題によって区切りがカンマだったり半角スペースだったりするので問題文をよく読んで引数に入れよう。

### そのままだと文字列配列なので数値配列にする

~~~java
        int[] intArray = Stream.of(stringArray).mapToInt(Integer::parseInt).toArray();
~~~

私はこの段階で右辺のメソッドが一切わからなかった。APIで調べてもなんのこっちゃである。
順に調べてわかったことを書く（多分厳密に考えると指摘される箇所が多そう・・・）。

## Stream.of()
**for each**だったり**for(String a : b)** の処理に近い。
**of()** の引数に入っている配列を順に取り出すというもの。
当然これには処理（メソッド）がないので次に続く。

## mapToInt(クラス名::メソッド名)
入力したクラスに用意されたメソッドを**Stream**で指定した引数に実行するもの。
今回行いたい処理は**Integer**クラスに用意された**parseInt()** メソッドなので**mapToInt(Integer::parseInt)** になる。

## toArray()
左２つで生み出されたリストを配列化するメソッド。

# 配列に入れた後は
[@takahirocook 氏の記事](https://qiita.com/takahirocook/items/51265073d04958250b12)
入れた配列の出力や活用は氏の解説を参照。

***
以上。
AtCoder ABC241C - Connect 6 を解く O(N^2)解法

https://atcoder.jp/contests/abc241/tasks/abc241_c
２つの解法で解きます。<font color=red>この問題では6マス続けるか？ですが、あえて、`Kマス続くことができるか？`ということを考えたときに</font>

- 解法1: 全マスからの直線的な6マスを全探索 $O(KN^2)$
- 解法2: two-pointerでの$O(N^2)$解法
で解説します。(繰り返しになりますが、この問題では$K=6$固定です)

# 解法1: 全マスからの全探索
特に面白味はなく、すべてのマスから、
```Python
    dw = [-1, 0, 1, -1,  1, -1, 0, 1, ]
    dh = [-1, -1, -1, 0,0, 1,1,1]
```
の8方向に対して6マスのうち4マスが黒かを判定する方法です。

## 工夫(8方向ではなく4方向で十分)

```Python
    dw = [  1, 1, 0, 1 ]
    dh = [ -1, 0, 1,1]
```
の4方向で十分です。なぜなら、
```
0 1 2
3 + 4
5 6 7
```
という方向があったとき、全マスを探索するのであれば、あるパターンが条件を満たすなら、0と7, 1と6, 2と5, 3と4のどれかで必ずマッチします。例えば、`.####.`があった際に、これは3でも4でもマッチします。

## 実装
そのまま実装するだけです。１点気を付けるとすると、普段、迷路の問題などだと四方を`#`の壁などで囲うことが多いですが、今回は、`#`は特殊な意味を持ちます。私は`!`で四方を囲い、これを壁相当と扱いました。

https://atcoder.jp/contests/abc241/submissions/29774778

# 解法2: スライディングウィンドウでO(N^2)で解く
まず、小問題を考えます。この問題が`ある１次元の配列があって、横に6マス並べたい`だったとすると、範囲6を順番に見れば良いので、以下のように、要素数aとするとO(a)で解けます。
```Python
def doTry(l, k, canfloor=2):
    # lの中で、連続するk個の"#"があるか？ただし、canfloor個までは"."が合っても良い O(N)
    l = list(l)
    if len(l) < k: return False
    cnt = 0
    for i in range(k):
        if l[i] == "#": cnt += 1
    if cnt >= (k - canfloor): return True
    for i in range(k, len(l)): # 今から読み込むindex
        if l[i] == "#": cnt += 1
        if l[i-k] == "#": cnt -= 1
        if cnt >= (k - canfloor): return True
    return False
```
常に、k文字の`#`の数を持ちながら、$O(N)$で条件を満たすかを走査しています。縦の場合も、配列を縦に見て、配列にすればこの手法でよさそうです。

さて、斜めの場合、工夫が必要です。次のような関数を作ります。
```Python
"""
 1  2  3  4
 5  6  7  8
 9 10 11 12
 があったとき、toLeftは
 [[1], [2, 5], [3, 6, 9], [4, 7, 10], [8, 11], [12]]
 を返す
"""
def diagonalListFromLeft(maze):
    ans = []
    hsize = len(maze)
    wsize = len(maze[0])
    for w in range(wsize):
        h = 0
        l = []
        while 0 <= w < wsize and 0 <= h < hsize:
            l.append(maze[h][w])
            h, w = h + 1, w - 1
        ans.append(l)
    for h in range(1, hsize):
        w = wsize - 1
        l = []
        while 0 <= w < wsize and 0 <= h < hsize:
            l.append(maze[h][w])
            h, w = h + 1, w - 1
        ans.append(l)
    return ans
```
つまり、四角形を斜め45度に切っていき、、配列で返す関数です。この関数は左下向きの配列を作りますが、右下向きに返すdiagonalListFromRightも作ります。これらは盤面のマス数が縦hマスで横wマスなら$O(HW)$で動作します。これらがあれば、
```Python
n = int(input())
maze = []
for h in range(n):
    maze.append(list(input()))
for h in range(n): # 横方向
    if doTry(maze[h], 6): return True
for w in range(n): # 縦方向
    l = []
    for h in range(n): l.append(maze[h][w])
    if doTry(l, 6): return True
for l in diagonalListFromLeft(maze):
    if doTry(l, 6): return True
for l in diagonalListFromRight(maze):
    if doTry(l, 6): return True
return False
```
で解くことができます。ソースコード全体は以下のリンクを見てください。。(True/FalseでYes,Noを返してください)
計算量はこの盤面のサイズとなるため、6マス並んだ文字、でなく何文字であっても$O(N^2)$です。


https://atcoder.jp/contests/abc241/submissions/29775739
Python pandasを利用し、CSVをPDFの表に変換する (matplotlib)


matplotlibを使うので、あんまり速い変換ではないです。。

これを使うよりも、おそらく pandasからHTML tableを出力し、WeasyPrintでPDF変換したほうがいいかも。。

- https://qiita.com/t_koba/items/8c04c87f8b564d4c7e7c


# 準備するもの

* python
* CSVデータに日本語を使う場合、以下から「Noto Sans Japanese」をWindowsにインストールしておく。<br> https://fonts.google.com/noto/specimen/Noto+Sans+JP?subset=japanese

# コード
入力されるCSVファイルは、utf-8エンコードにしておきます。

```python:csv2pdf.py

import sys
import pandas as pd
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages

#フォントキャッシュをクリア
matplotlib.font_manager._rebuild()

df = pd.read_csv( sys.argv[1] , encoding = "utf-8")
print(df)

fig, ax =plt.subplots(figsize=(12,4))
plt.rcParams['font.family'] = 'sans-serif'
plt.rcParams['font.sans-serif'] = ['Noto Sans JP']

ax.axis('tight')
ax.axis('off')
ax.table( cellText=df.values, colLabels=df.columns, loc='center', fontsize=9 )

pp = PdfPages("out.pdf")
pp.savefig(fig, bbox_inches='tight')
pp.close()
```

# コマンドライン

```
python.exe csv2pdf.py hoge.csv
```

out.pdf が出力されました。

# 改ページする
80行ごとに改ページしたいなら、こんな感じ。

```
import sys
import math
import pandas as pd
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages

#フォントキャッシュをクリア
matplotlib.font_manager._rebuild()

df = pd.read_csv( sys.argv[1] , encoding = "utf-8", header=None)
pp = PdfPages("out.pdf")

PER_PAGE = 80

pages = math.ceil( len(df) / PER_PAGE)
for i in range(pages):
	start = i* PER_PAGE 
	end = (i+1)* PER_PAGE
	if end > len(df) :
		end = len(df)
	
	print(start +1 , end -1)
	df2 =df.iloc[start : end]

	fig, ax =plt.subplots(figsize=(12,4))
	plt.rcParams['font.family'] = 'sans-serif'
	plt.rcParams['font.sans-serif'] = ['Noto Sans JP']

	ax.axis('tight')
	ax.axis('off')
	ax.table( cellText=df2.values, loc='center', fontsize=9 )

	pp.savefig(fig, bbox_inches='tight')
	fig.clf()

pp.close()

```
Anaconda Tips

# 通常の PowerShell から conda を使う設定

スタートメニューから、「Anaconda Powershell Prompt」を起動して、下記コマンドを実行

```powershell
PS> conda init powershell
```

# (base)の解除
conda 環境を終了
```powershell
(base) > conda deactivate
```
デフォルトで conda 環境にしない
```powershell
(base) > conda config --set auto_activate_base False
```

https://qiita.com/rainline00/items/1606d4a6f479df33c408

# YAML ファイルの作成
```powershell
(openai) > conda env export > openai.yml
```

https://helve-blog.com/posts/python/conda-virtual-environment/#yaml%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E5%87%BA%E5%8A%9B
【G検定対策】人工知能の歴史(第1次，第2次AIブーム)

自分のG検定対策として，まだ覚えられていない部分をまとめました．自己満です．修正コメントお待ちしております．

# 第1次AIブーム
「推論・探索の時代」といわれている．

|年|出来事|
|:--|:--|
|1946|ENIAC（エニアック）誕生|
|1950|Turing Testが，Alan Turingにより考案される．ある機械が人工知能かどうかを判断するためのテスト．([映画：イミテーション・ゲーム](http://imitationgame.gaga.ne.jp/))|
|1956|Dartmouth Conference（**ダートマス会議**）<br><br> **John MacCarthy** <br> **Marvin Minsky** <br> **Claude Shanonn** <br>Ray Solomonoff <br>**Oliver Selfridge** <br>**Nathaniel Rochester** <br>Trenchard More <br><br>"Logic Theorist" をデモ<br>**Allen Newell** <br>**Herbert Simon**<br><br>【提唱】<br>**Arthur Samuel** <br>"Field of study that gives computers the ability to learn without being exaplicitly programmed" 「明示的にプログラムしなくても学習する能力をコンピュータに与える研究分野」と定義，提唱． |
|1966|ELYZA（イライザ）|
|1972|[**PARRY**](https://ja.wikipedia.org/wiki/PARRY)<br>1972/09/18 **RFC439** <br> ⇢ELIZAと会話した**最初の**記録<br>1972/10 下旬 **ICCC1972** <br>⇢ARPANET上の別ノード上で行われたELIZAとの会話 |

迷路や数学の定理証明のような **toy problem** は解けるようになったが，複雑な現実問題は解けない．

# 第2次AIブーム
「知識の時代」と言われ，**エキスパートシステム**により問題を解くシステムが多く作られた．

|年|出来事|
|:--|:--|
|1960年代|**DENDRAL**（デンドラル）<br>⇢エドワード・ファイゲンバウムが開発した，未知の有機化合物を特定するエキスパートシステム|
|1970年代|**MYCIN**（マイシン）<br>⇢血液中のバクテリアの診断支援をするルールベースでのプログラム|
|1984年〜|**Cycプロジェクト**<br>全ての一般常識をコンピュータに取り込むことで，人間のように柔軟な知的能力を実現することを目指す．ダグラス・レナードによりスタート．|

人間の専門家からの知識を得ることや，定式化する上で限界があった．
Pythonでいい感じに書く

## 背景
最近、Pythonでソースコードを書くようになったのですが、
書き始めて半年ということでまだまだキレイな書き方、
効率的な書き方ができておりません。

一緒に開発しているベテランエンジニアさんのソースコードを見て、
あぁ〜こういう風に書くのか〜、と勉強になったので
メモがてら記事にしてみます。


## 通常のif文
通常は下記のように書きます。
```
if a == 'a':
    return True
else:
    return False
```
なんてことないif文ですが、単純なif、elseの場合は
あまりこういう風には書かないようです。


## １行にまとめたif文
上のif文は１行にまとめられます。
```
return True if a == 'a' else return False
```
要は三項演算子です。
ただ、JSやPHPなどの言語とは違って最初に（True）の時の処理が来て、
その後に条件式が来るんですよね。
これまでJS、PHPをメインで書いていたので、少し戸惑いましたw


## 通常:for文でlistに追加
続いてはfor文です。
```
arr = []
for i in range(5):
    arr.append(i*2)

print(arr)　 // [0, 2, 4, 6, 8]
```
こちらも通常通り書いたらなんてことないです。


## リスト内包表記
上の処理は下記のように簡単に書けるようです。
```
arr = [i*2 for i in range(5)]
print(arr)
```
最初見た時、何をしているかわかりませんでしたw


## 終わりに
Pythonを書き始めてまだまだ日が浅いため、大した内容では
ないですが、他の言語から移ってきた人間の視点で「こういう書き方あるんだ〜」
というものをまとめてみました。

また気になるものがあればメモがてら記載してみようと思います！