OmniAICreator/Qiita-1.07M huggingface dataset:
DataFrame 行・列の追加


#行を追加
DataFrame型のdfに対して下記を実行

```python
df.append("Series型のデータ", ignore_index = True)
```


```python
import pandas as pd

fruits = ["apple", "orange", "banana", "strawberry"]
data1 = [10, 5, 8, 12]
data2 = [30, 25, 12, 10]
data3 = [30, 12, 10, 8, 3]
series1 = pd.Series(data1, index = fruits)
series2 = pd.Series(data2, index = fruits)

fruits.append("pineapple")
series3 = pd.Series(data3, index = fruits)

df = pd.DataFrame([series1, series2])
df = df.append(series3, ignore_index = True)

df.index = ["1", "2", "3"]
display(df)
```
![スクリーンショット 2021-07-14 21.29.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1736279/84e5c9da-5782-d9af-08b4-f1eacbc250ae.png)


#####補足
元々のカラムと追加するSeries型のデータのインデックスが一致しない場合は、値が存在しない要素にNanが埋め込まれる。


#列を追加

DataFrame型の変数dfに対して下記を実行

```python
df["新しいカラム”] = "Seriesもしくはリスト"
```

```python
import pandas as pd

fruits = ["apple", "orange", "banana", "strawberry"]
data1 = [10, 5, 8, 12]
data2 = [30, 25, 12, 10]
series1 = pd.Series(data1, index = fruits)
series2 = pd.Series(data2, index = fruits)

new_colum = pd.Series([15, 7], index = [0, 1])

df = pd.DataFrame([series1, series2])
display(df)

df["mango"] = new_colum

display(df)
```

![スクリーンショット 2021-07-14 21.22.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1736279/23a36178-3382-799a-e20a-9553188cdcc2.png)
文系新卒エンジニアが研修を受けてみた所感

文系卒未経験エンジニアとしてとある会社に新卒で入社し、先日新人研修が終了しました。
色々と思うところがあったので、備忘録がわりにつらつらと書いていきたいと思います。

* 未経験からエンジニアとしての就職が決まった方
* 文系卒だけどどんな感じの研修が行われるのか気になる方
* 初心を思い出したい方
* 理解力低くて何考えてるかわからない部下をお持ちの方  

などに読んでいただければ幸いです。

 
まず簡単に研修の概要についてお伝えします。 
・ 最初の1ヶ月間半はサーバー側の研修 
・ 次の1ヶ月はアプリ研修 
・ 同期はほぼおらず、他の同期は文系卒ながらも自分で前から勉強していたレベル
私は未経験かつ、内定者課題のウェブアプリもギリギリになって追い込んだというごみかすな状態から始めました。入社2ヶ月前に焦ってようやくプログラミングに手をつけたレベルです。 
(こんなモチベ低いのになんでエンジニアになったのか等はまた別の記事でおいおい書いていこうと思います)

## 全体を通しての率直な感想
* めっちゃしんどい
* 自尊心が打ち砕かれる
* 教えてもらってもわからない

早速ネガティブな始まりになってしまいました。1つずつ説明していきます。

### めっちゃしんどい
大きい会社ではないせいか、研修といっても基礎からみっちりやってもらえるようなものではなく、課題を出されてそれをこなすというようなものでした。 
内定者課題もあったので、文法などは当然理解できている前提で進んでいきます。
 さらに周りの先輩たちはみんな情報系や理系出身な上、研修制度があまり整っていない時代を生き抜いた猛者たちばかりです。
先輩たちは自分がどのレベルで躓いているのかを想像できない様子でした。

そんなつよつよなメンバーに囲まれてしまった自分はまともに質問すらもできず、「何がわからないのかわからない」期間へと突入します。
 最初は歓迎してくれていた先輩たちも、次第に「こいつ無能やんけ」という目で見てくるという被害妄想に苦しむ日々です。

こんなことを言いましたが、会社の人は引くぐらいいい人です。わからないことを聞けばめちゃくちゃ教えてくれます。ほんといい人です。悪いのは全部ごみかすな自分です。

### 自尊心が打ち砕かれる
自分で言うのもなんですが、今までの人生は「何事もそんなに努力しなくてもそこそこできる」ことが多かった気がします。

それだけで慢心してしまったんでしょうね、勉強好きな人が向いていると言われるプログラミングならなんとかなるだろうと甘く見ていました。 
現実はもちろん優しくなく、研修では自尊心という自尊心をボッキボキに折られました。

まず研修課題を進めようにも課題文の意味がわからない。わからない単語をググっても説明文がわからない。そうこうしているうちに優秀な同期はどんどん先に進んでいく。焦る。もう一回調べて理解しようとしても焦っているから文字が目を滑る。焦る。 せめて自分の時間は勉強しようと、帰宅後や休みの日も勉強してみるが、いざ会社に行くとレベルが違いすぎて何も役に立たない。余計焦る。同期が先に進んでいく。もう嫌だ…

研修期間中ずっとこんな感じで、同期の動きを気にしてしまい、本当にやるべきことを疎かにしていました。

 「周りなんて気にせずじっくり理解いくまで自分のペースでやればいいじゃん」というのはもっともです。自分でもそれは痛いほどわかっていたのですが、隣から聞こえてくる凄まじいタイピングの音やどんどん増えていくslackの分報を前にするとどうしてもそんなこと言ってられなくなるんですよね。

### 教えてもらってもわからない
とはいえ同期はとても優秀です。優秀なだけでなくめちゃくちゃ優しいのです。

 私が行き詰まっていると察して声をかけてくれて、わかりやすく教えてくれました。こんなにもいい同期に恵まれて本当に私は幸せだったと思います。

 ですがここでうまくいかないのがごみかすの運命(さだめ)。 
同期に教えてもらうと、今まで考えていたペースの4倍くらいのペースで事が進んでいきます。

そんなペースに理解は追いつかず、臆病な自尊心が「それってどういうこと？」と逐一聞くことを許さず、とりあえず形になればいいや〜感覚で一刻も早く課題の完成を待つ人間に成り下がってしまいました。 

今までの勉強ではそんなに躓いたことないのになんでこんなに理解できないんだろう？私ってエンジニア向いてないんだなと思いながら、自分のキャリアも迷走していくのを感じました。

## 研修を終えて
研修が終わり、ずっと同じペースで課題に取り組んでいた同期とは配属が別になりました。
あんなに教えてくれていた同期と別れてどうなるかと思いましたが、なんやかんや今の方が心が楽な気がします。 

研修が終わってから案件に入るまでの間に追加課題を出してもらったのですが、一人で取り組むと思いの外集中できます。周りのペースを気にしなくていいので、気になることはじっくりと調べられるし、slackの分報も思い通りに書けます。
 まだ課題は完成していませんが、研修期間より多くのことを腹落ちしながら理解できている感覚があります。

## 初心者にとって大事なことは
「周りを気にせずじっくり進める」 
これに尽きると思います。特に私みたいに臆病な人間は尚更。 
先輩に聞ければ聞くのが一番ですが、なかなか初心者にとってはそれすらハードルが高いと思います。

まずは自分としっかり向き合い、集中して「ゾーンに入る感覚」を掴みたいところですね。
そうするとだんだんプログラミングの魅力というものがわかってきて、先輩に聞くだったり自分で学習を深めるといった次のステップへ進むことができるのではないかと思います。 

もしどうしても周りが気になって集中できない場合、1人になれる時に今やってるトピックを心ゆくまで調べてみるといいかもしれません。半歩遅れでも理解できれば上々です。

## これからについて
とにかく反省点だらけでしたが、ほんの少しだけコツが掴めました。それは、

* **わからないことがあったら「その道の博士になる」ぐらいの勢いで調べまくる** 
  →なあなあで記事を読み飛ばして使えない知識ばかりになっていくのを防げます、
* **わからない説明があったら品詞分解する **
 →中学とかの古文で品詞分解やったの覚えてますか？あれです。文節の中でわからない単語があったら逐次調べるようにすると、どこで理解できないのかがわかるようになるかと思います
 →焦っているとわかった気になって記事を読み飛ばしてしまうこともあるのですが、そうした事態を防ぐことにも繋がります。

これらを踏まえ、1日でも早く強いエンジニアになれるよう精進していきたいです。 もしここまで読んでくださった方がいらっしゃったらありがとうございます。一緒に頑張りましょうね。
mermaid.js ガントチャート サンプル

# 目的

- mermaid.jsで記載するガントチャートのサンプルを下記に記載する。

# 情報

- mermaid.jsでは`%%`の後ろはコメントとして扱われる。

# サンプル

- 休日を登録する方法もあるが、休日作業する人も居る場合を加味してセクションとして「休日」を設定してみた。

    ```mermaid
    gantt
        title ガントチャートタイトル
        %% 登録するタスクの日にち情報のフォーマット指定
        dateFormat  MM-DD
        %% 出力する日にち情報のフォーマット設定
        axisFormat  %m/%d
        section 休日区分
            休日                           :crit, h1, 07-17, 2d
            休日                           :crit, h2, 07-22, 4d
            休日                           :crit, h3, 07-31, 2d
        section Aさん
            a機能の作成                     :a1, 07-15, 1d
            aa機能の作成                    :a2, after b1, 1d 
            aaa機能追加                     :a3, after b1, 3d
        section Bさん
            設計                           :b1, 07-15, 2d
            b機能の作成                     :b2, after h1, 2d
            リリース                       :b3, after h3, 1d
        section Cさん
            単体検証                       :c1, after b2, 1d
            単体検証                       :c2, after h2, 1d
            結合検証                       :c3, after d1, 1d
        section Dさん
            単体検証                       :d1, after c2, 2d
            総合検証                       :d2, after c3, 1d
    ```

- 下記の様に出力される。

    ![gantt_md_—_j-project.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/312c256e-8d60-e231-8dfe-06529d1be5bb.png)
40 代おっさん ELBを勉強してみた

## 本記事について

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

## ELBの概要

![ELBEC2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641940/3191088f-b362-0572-cdbb-6c5e79b8ba39.png)


上の図だとEC2が一台のため、単一障害点になります。
そのため例えば AZ 1c にもう一台EC2を置いたとします（下の図）
そうするとまた違った問題点が起きます。

![ELBEC2構成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641940/3772b52b-6166-7c89-c5a8-3041866ffc11.png)

その問題点とは
・アクセスポイントが分かれてしまう（ユーザーから見るとアクセスポイントが２つになる）
・サーバーが正常かチャックをしないといけない（異常が出た場合、そのサーバーを停止させないといけない）
・セキュリティーの問題（直接、webサーバーにアクセスさせるのはセキュリティー上あまりよろしくない）
・セキュリティーの処理の負荷（HTTPSをHTTPに複合化するのは多少の負荷がかかり、本来コンテンツを提供するwebサーバーに通信の複合化の処理までさせるのは、あまりお勧めできません。）

上の問題点はDNS仕組み、監視仕組みを作りこむことはできますが、そこで代わりになるものがELBです。（下の図）

![ELBEC2ELB構成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641940/703694a3-c10c-787b-da12-4f85e8aeda8d.png)

## ELBの機能の特徴


### ロードバランサーにはDNS名のアクセスポイントが付与される

![ELBエンドポイント.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641940/c7f29e17-e8ad-8ad2-0142-c5a13ed6137f.png)

ユーザーからのアクセスポイントを一つにして、ELBが自動でEC2の負荷状況を見て自動でリクエストを分散してくれます。（オートスケールと連動してEC2の平均のCPU使用率を見て、EC2を増やしたり、減らしたりすることも対応可能）

### ヘルスチャック機能がある

定期的にELBが対象のファイルに通信を流し、正しいレスポンスが返ってくれば通信を流し、正しくないレスポンスがくれば通信をストップする。（この動きをロードバランサー切り離すという）
上の動きを、何秒ごとにチャックするかなどの設定もできる。

### ELBに証明書を付与することでSSL通信の終端となる

![ELBHTTPS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641940/7c2dc6e3-712a-c9cf-e97a-e91020e16e0c.png)

HTTPS通信をするためには証明書が必要になります。（AWS Certificate Manager で無料でとれる）この証明書をELBに配置することでその先がHTTP通信で通信がすることができる。
これをSSLターミネーションと言うみたいです。

## ALB,NLB,CLBについて

ALB,NLB,CLBはELBのロードバランサー種類になります。

### ALB

アプリケーションレイヤー（L7）HTTP,HTTPSの負荷分散に使えます。
※L7 とはOSI参照モデルで第７層のこと

### NLB

トランスポートレイヤー (L4) TCP,UDPの負荷分散に使えます。
※L4 とはOSI参照モデルで第４層のこと

### CLB

こちらは古い規格であり、今後は機能追加もないことからあえて使う必要がないとのことでした。

##ELBの使用例

![ELB使用例１drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641940/1dda5115-ef62-5169-448d-5ad299cfc4a9.png)

上の図のようにELBをPublic subnetに置き、あとはPribate subnetに置くとセキュリティーレベルが高まるようです。
あとこれだとEC2のメンテナンスができないため別途、踏み台サーバーを用意してメンテナンスを行います。

![ELB使用例2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641940/44c88d0b-ab73-cb8f-b7f3-285d25ef46b4.png)

上の図はアプリケーションによってですが、フロントとAPIを担うサーバーをわけることがあるようです。
こちらだとEC2横並びで繋がっているだけですからEC2同士が単一障害点になってしまいます。
ですので下の図のように

![ELB使用例3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641940/98273472-72fd-ac82-9d0e-1f0421cdc477.png)

このように内部でELBを使用してわけることができます。

![ELB使用例4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641940/ed9b99e1-822d-6502-15b8-81e6e5f40cc2.png)

なおもう少し踏み込んで話すと上の図のように外部向けはALBを使用して内部向けはNLBを使用する。理由はNLBは処理速度が速いみたいですのでアーキテクチャよりますが、内部はL7まで求めたものを使用しなくても良いみたいです。

## 最後に
少し訓練校でバランサーなどを実機で触ったおかげでなんとか概要はつかめた気になりましたが、本当に分かったか微妙です＞＜
次は手を動かしながらもっと勉強していきます！！

またこの記事は AWS 初学者を導く体系的な動画学習サービス「AWS CloudTech」の課題カリキュラムで作成しました。
<https://aws-cloud-tech.com/>
【PHP】関数のnullable宣言は デフォルト値(= null)ではなくハテナ(?)を使おう

# はじめに
こんにちは。ブログいろいろいじっていたらAMPページが壊れて、いろいろ大変な事態になってしまいました、筆者です :innocent: 

さて、今回は**PHP 8.0.0**から非推奨になった機能をご紹介しようと思います。

# これ見たことないですか？
というか超お世話になってますし、よく見るし、よく書いてました :sweat: 

以下`test関数`使用時には、引数を渡さないで実行した場合は、デフォルト値の`null`が`$a`に代入されて処理されます。
`null`をデフォルト値とすることで、型が暗黙のうちに`nullable`であることを示しています。

```php
<?php
    function test(string $a = null) {} // 非推奨
```

# 推奨される書き方
素直に`nullable`と表記します。

```php
<?php
    function test(?string $a) {} // 推奨
```

# おわりに
この機に改めて自分の書いたコード見返したら、以下のようになっていて、両方書いておりました :bow: :bow: :bow:

```php
<?php
    function test(?string $a = null) {}
```

これはこれでよくないですね...。ちゃんと理解せず書いておりました。
以後気を付けます:pray:

それでは！

# 参考文献

https://www.php.net/manual/ja/migration80.deprecated.php
【Rails】簡単に投稿数を表示する方法！

####My Profile
プログラミング学習歴②ヶ月目のアカウントです！
プログラミングスクールで学んだ内容や自分が躓いた箇所等のアウトプットの為に発信しています。
また、プログラミング初学者の方にわかりやすく、簡潔にまとめて情報共有できればと考えています。
もし、投稿した記事の中に誤り等ございましたら、コメント欄でご教授いただけると幸いです。　



#対象者

* 投稿数を表示させたい方
* 数を数えるcountメソッドを使いたい方


#目的

* 投稿数を表示して記録を取る！！

#実際の手順と実例
###1.モデルを関連付ける
前提として本の投稿をするアプリケーションの作成をしています。
１人のユーザーが何回も投稿が可能なので関係性は以下の通りです
user:book = 1：N

```user.rb
 has_many :books, dependent: :destroy
````

```book.rb
 belongs_to :user
````


###2.投稿数を表示しよう
投稿数を表示するviewは以下の通りです。
今回はuserのshowにcountを載せます。

```user.show.html.erb
<%= current_user.books.where('created_at > ?', Date.today).count %>
````
* current_user：deviseを使用しているのでそのまま使います
* books：アソシエーションを組んでいるので「現在のユーザーが投稿した本」になります
* where：[whereの使い方はこちら](https://qiita.com/nao0725/items/b201e560fa304efe9b52#3where)
* 'created_at > ?':ちょっと自分にもわからない、、、、、
* Date.today:「今日」を表しているクラスです。Date.newで週、月、年を表示できます。
* .count：これが数を数ええるメソッドです。



###3.完成！！！！

![スクリーンショット 2021-07-14 21.01.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1681213/9548627f-2953-0542-d84d-dd1043bf1f32.png)

左下の４と書かれた場所が表示箇所です。
まだ完成途中なので、気が向いたら追加で更新します！笑




#参照

>　[countについて](https://pikawaka.com/rails/count)
>　[時刻や日付を扱うメソッドの基本情報まとめ](https://fuchiaz.com/ruby-rails-time-date/#Date)
npm_config_arch, npm_config_target_arch, そして npm_config_* 環境変数について

`npm_config_` で始まる環境変数は `npm` コマンドによって解釈される。 `npm_config_foo=bar` とセットすると npm のコンフィグ `foo` を `bar` にセットしたのと同じ意味になる。 https://docs.npmjs.com/cli/v7/using-npm/config#environment-variables

この環境変数の名前は大文字でも小文字でもいいが、 npm は scripts を実行するとき名前が小文字バージョンの環境変数を独自にセットする。それは（ユーザーによってセットされた）名前が大文字の環境変数よりも優先されることに注意。ユーザーによって名前が小文字の環境変数がセットされたらそれが最優先される。

`npm_config_` で始まる環境変数は `npm` コマンド以外にも認識されることがある。中でも Node のネイティブ拡張を扱うライブラリ node-gyp と node-pre-gyp に関する環境変数は覚えておくといい。

https://github.com/nodejs/node-gyp/blob/v8.1.0/README.md#configuration

https://github.com/mapbox/node-pre-gyp/blob/v1.0.5/README.md#options

タイトルにも書いた `npm_config_arch` は node-gyp がビルドするネイティブ拡張のアーキテクチャを指定する。 `npm_config_target_arch` は node-pre-gyp がダウンロードするコンパイル済みネイティブ拡張バイナリのアーキテクチャを指定する。

M1 Mac では node-pre-gyp がネイティブ拡張をダウンロードできずにエラーを出すことがときどきある。その場合は `export npm_config_target_arch=x64` してから `npm install <pkg>` を実行するといい。 `yarn` や `pnpm` でも node-gyp や node-pre-gyp が認識する環境変数は使える。

---

関連記事：

https://qiita.com/uasi/items/93ccbde60b4397a83da9
pythonを便利に使おう第五回！ 数学編!

#初めに
　数学というのは「数学」というルールに基づいて式を組みたてていく、言わばパズルのようなものです。木組みのパズルとは違い、これほどまでに難しいのは、3つほどの理由があるでしょう。
　まず1に、素材が大きすぎるのです。そりゃ、自然と並走するような形で数学という概念を成り立たせているわけなのですから、木組みのパズルよりも大きくないということはないのです。なんせ比較対象たる木組みのパズルさえも、自然の集合の要素に過ぎないのですからね。
　そして2に、パズルの複雑さでしょう。木組みのパズルは、どれがハマりどれがはまらないのかを見ずとも、パターンをたった数百通り組み合わせるというのに、自然という正解の形に数学を整えるには、何億も何兆も複雑なパズルを解かなくてはいけないのです。
　最後の３は、記憶の難しさでしょうか。上2つの例を納得していただいた方なら解ると思いますが、パズルというのは大きくなるほど、また複雑になるほど頭を使い、なお何かしらを記憶しなくてはいけないのです。
　それで、数学の難しさを解いて何がしたいのかというと…。
　ただ難しいなと感じた問題を解きたかっただけなんですよね^^;(どうしよ)
###そ、そんなことはともかく！
　今回は数学を解き明かすという数学の難しさを払拭してくれるコンピューターという名の偉大な発明品を利用して、とにかく難しい(というには役不足だけれど)問題を解いて行こうと思います。

#数学 IIIα
　積分の教科書に存在している問題から数問引っ張ってきます。
##第一問　次の定積分を解け
```math
\int_{2}^{3} \sqrt{4x-x^2}dx\
```

　これを数学で普通に計算しようと思ったら、定数の2乗引くf(x)の2乗という形にルートの中を変形させて、積分の公式を使用することで求めることが出来ます。しかしそんな途中計算ミスってしまいそうな問題も、pythonを使うことでなんと！

```python
>>> from sympy import *
>>> init_printing()
>>> x=Symbol('x')             
>>> y=sqrt(4*x-x**2)
>>> integrate(y,(x,2,3))
```

```
√3   π
── + ─
2    3
```

 という風に簡単に求めることが出来ます。ただ、やはり仕事が多いみたいで、処理完了までに時間がかかるみたいです。

##第二問　次の不定積分を求めなさい。
　三角関数の積和の公式などは公式を覚えないとどうしても計算として使うのは難しいです。ピタゴラスの定理などは導出を覚えるのが簡単ですが、三角関数の積和の公式は導出を覚えるのが難しいですからね。

```math
\int \cos4xsin3xdx\qquad\int \cos3xcos2xdx\
```

```python
>>> from sympy import *
>>> init_printing()
>>> x=Symbol('x')  
>>> y=cos(4*x)*sin(3*x)
>>> integrate(y)
```

```
4⋅sin(3⋅x)⋅sin(4⋅x)   3⋅cos(3⋅x)⋅cos(4⋅x)
─────────────────── + ───────────────────
         7                     7         

```

```python
>>> from sympy import *
>>> init_printing()
>>> x=Symbol('x')  
>>> y=cos(3*x)*cos(2*x)
>>> integrate(y)
```

```
  2⋅sin(2⋅x)⋅cos(3⋅x)   3⋅sin(3⋅x)⋅cos(2⋅x)
- ─────────────────── + ───────────────────
           5                     5  
```

　という風に求めることが出来ます。
　ただこれは本来を求めようとしている答えとは違うんですが、しかし、三角関数というのは色んな形に変形できるもんですし、多分合ってるんでしょう！(ちゃんと確認してない)

##第三問　次の不定積分を求めなさい。
　先と続いて三角関数の積分です。

```math
\int \frac{1}{sinx}dx\qquad\int \frac{1}{cosx}dx\
```

　左の問題を本来求めようとすると、(僕が知っているものでは)分子と分母にsinxをかけて、分母のsinxの2乗を1ーcosxの２乗と書き換えて、媒介変数t=cosxと置き、積分をtについての積分に変更して、部分分数分解をして、定積分を求める、と。それはlogーlogという形になるのでlogの中身が分数になる結果に収まります。こうして文として打ってみても、中々にめんどくさい処理をしなくてはいけないのがわかりますね。

```python
>>> from sympy import *
>>> init_printing()
>>> x=Symbol('x')  
>>> y=1/sin(x)
>>> integrate(y)
```

```
log(cos(x) - 1)   log(cos(x) + 1)
─────────────── - ───────────────
       2                 2       
```

```python
>>> from sympy import *
>>> init_printing()
>>> x=Symbol('x')  
>>> y=1/sin(x)
>>> integrate(y)
```

```
  log(sin(x) - 1)   log(sin(x) + 1)
- ─────────────── + ───────────────
         2                 2       
```

　答えはこのとおりです。

#最後に
　今回はどれも都合よく求めることが出来ましたが、しかし、sympyというのも完璧というわけではないので、数式を求められないことがあります。それはやはり、自分でsympyを拡張するか、自分でsympyとは違うプログラムを作るか、それか紙とペンを持って自身でやってみるか、などが必要だということです。
　しかし、実際に自分で理論値を出してみようというところにも、matplotlibなどで近似値をプロットして理論値の目印にする使い方も出来るでしょう。やはりpythonは便利ということです。
　今回は時間がなくて適当な仕上がりですが、今後は夏休みが来るので、そのときにはwebサイトの本格的な運用とか、人工知能の研究とか、ドローンの操作するためのraspberrypiでプログラムを組んだりとかしたいです。すべてを一人では出来ないのがほんとに悔しい…人生というのは「何もかもをなすには短すぎる」とはよく言ったものです。
MQTTのsession (セッション) とは

# セッションとは
クライアントからサーバーへのMQTT接続要求が開始されてから、接続が終了するまでのメッセージのやりとりをセッションと呼びます。セッションは1つのネットワーク接続で完結する場合もあれば、（セッションが切れる前にクライアントが接続を再確立できれば）セッションは複数のネットワーク接続にまたがって存在する場合もあります。

MQTT v5では、セッションの有効期限は、クライアントのCONNECTパケット中にある`Session Expiry Interval`で設定されます。v5以前のプロトコルでは、セッションの有効期限に制限はなく、MQTTサーバーが実際の有効期限を決定していました。

# セッションステートとは

MQTTでは、クライアントとサーバーは、クライアントIDに関する状態をセッションの有効期間中は保持する必要があり、これをセッションステートと呼びます。

クライアントは以下のセッションステートを保存している必要があります：

- サーバーに送信したが、受信確認が完了していないQoS 1/2のメッセージ
- サーバーから受信したが、受信確認が完了していないQoS 2メッセージ

サーバーは以下のセッションステートを保持している必要があります：

- セッションが存在するかどうか（他のセッションステートが存在しない場合も、このセッションステートは存在する）
- あるクライアントがsubscribeしているtopic
- クライアントに送信したが、受信確認が完了していないQoS 1/2のメッセージ
- 配信を待機しているQoS 0/1/2メッセージ(QoS 0はoptional)
- クライアントから受信したが、受信確認が完了していないQoS 2メッセージ、`Will`、`Will　Delay Interval`
- セッションの有効期限

# セッションステートが存在する理由

クライアントがネットワークの障害などで一時的に接続を中断し、セッションの有効期限が切れる前にサーバーとの接続を再確立した場合、クライアントは前回の接続で確立したsubscriptionを継続して使用することができます。低帯域で不安定なネットワーク環境では、ネットワークの中断が頻繁に起こる可能性があります。セッションステートを保存しておくことで、接続するたびにsubscriptionすることを避けることができ、再接続時のクライアントとサーバーのリソース消費を抑えることができます。サーバーは、クライアントが切断している間、クライアントに対する受信確認などが完了していないメッセージを保持します。これにより、メッセージが失われることを防ぐことができ、ユーザーがネットワークの障害に影響されにくくなります。

# セッションの開始と終了

MQTT v5.0とv3.1.1では、セッションに大きな変更があります。MQTT v3.1.1には、接続時にクライアントが指定する`Clean Session`というフィールドのみ存在しています。このフィールドの値が1に設定されている場合、クライアントとブローカーはそれまでのセッションを破棄して新しいセッションを作成しなければならず、セッションのライフサイクルは一回のネットワーク接続に紐づけられることになります。値が0の場合、サーバーはクライアントとの通信を回復する際に、クライアントIDに紐づけられたセッションを使用しなければなりません（セッションが存在しない場合を除く）。この場合、クライアントとサーバーは、切断が起きた際にセッションステートを保持する必要があります。

MQTT v3.1.1では、保持されているセッションをいつ終了させるかは規定されていません。プロトコルレベルでは、セッションは永遠に存在します。しかし、これではサーバーのリソースを非常に多く占有することになるため、現実的ではありません。そのため、MQTTサーバーは通常、プロトコルに従って無限に保持するのではなく、設定からセッションの有効期限を制限することができるようになっています。

MQTT 5.0では、この問題が解決されています。`Clean Session`フィールドが、`Clean Start`と`Session Expiry Interval`という二つのフィールドに分かれています。`Clean Start`フィールドでは、セッションを新しく作るかを指定し、`Session Expiry Interval`フィールドでは、セッションの有効期限を指定します。これらは接続時に指定されますが、クライアントは接続の終了時にSession Expiry Intervalフィールドを更新することができます。したがって、ネットワーク接続の異常によりクライアントが切断した場合はセッションを保持し、クライアントが正常にオフラインになったときにはセッションを終了させるということが簡単に実装できます。

# クライアントはどのようにしてセッションが再開されたことを知るのか

クライアントが、以前に確立されたセッションの再開を期待して接続を開始する場合、サーバーに対応するセッションが存在するかどうかを知る必要があります。MQTTプロトコルはv3.1.1からCONNACKパケットにSession Presentというフィールドを用意しました。このフィールドは、現在使用しているセッションが新しいものかどうかを表すためのもので、クライアントはこのフィールドの値によって判断することができます。新しいセッションの場合、クライアントは接続確立後に再びトピックにsubscribeします。

# 注意

MQTTを使ったサービスを作る場合、クライアントIDとセッションの関連性に注意する必要があります。同じクライアントIDを異なるアプリケーションやユーザーが複数回使用する場合は、接続するたびに新しいセッションを要求するようにする必要があります。

セッションの保持が不要な場合は、サーバーによるリソースの占有を減らすために、セッションを即時失効に設定するべきです。

セッションの保持が必要な場合、セッションの有効期限を適切に設定します。時間を短く設定しすぎると、セッションの状態を保存する意味がなくなってしまいます。有効期限が長すぎると、サーバーのリソースを過剰に消費する可能性があります。
pythonによる二分探索

## 概要
atcoderなどで二分探索の問題が出た際に、さらっと参照するための記事です。
細かな説明は、[アルゴリズムの解説サイト](https://algo-logic.info/binary-search/)などを見た方が良いと思います。

## 二分探索について
二分探索とは、集合{1,2,3,...,N}が線形的に変化する際に、端から順に調べるのではなく、
真ん中を探索していく方法です。

例えば、[1, 3, 5, 7, 9]の配列から4より大きい数の個数を求める場合、配列の数字は単調に増加しているため、真ん中（インデックス2）の5が
4より大きければ、5より右側は全て4より大きいことが分かります。
そうすると、今度は5より左側のみを調べればよいので、[1, 3, 5]の真ん中の3を調べて4より小さいから...
といった流れで、わずか2回の計算で配列のどこからどこまでが4より小さいのかが分かります。

今回の場合は、配列の長さが5だったため、全探索の回数**5**に対して、二分探索では**2**と差が少なかったですが、
Nが大きければ大きいほどその差は歴然です。

以下から、実際の利用方法を見ていきましょう。

## 利用方法
使い方は非常に簡単で、端と端を定義し、真ん中を調べた時の結果に応じて右端もしくは左端を再定義します。
実際に問題を見た方が早いと思いますので、以下から早速、一緒に解いていきましょう。

引用元：[典型アルゴリズム問題集](https://atcoder.jp/contests/typical-algorithm/tasks/typical_algorithm_a)

上の問題は、すでにソート済みの数列の中から、K以上である、最小のものをみつける問題です。

#### 入力
> N K
A0 A1 ⋯ AN−1


```python:sample.py 
# 入力を受け取る
N, K = map(int, input().split())
A = list(map(int, input().split()))

# 配列の右端をok, 左端をngと設定する。それぞれ端から１ずれているのは、両端が未判定のため。
ok = N
ng = -1

# while文で繰り返し真ん中の値を調べていく。while文を抜け出す条件は、okとngが隣り合う（差が1になる）まで
while abs(ok - ng) > 1:

# 真ん中の値をmidに代入
  mid = (ok + ng) // 2

# 真ん中の値がK以上ならokにmidを、そうでなければ、ngにmidを代入
  if A[mid] >= K:
    ok = mid
  else:
    ng = mid

# whileの処理により、okに入っている値は、K以上を満たす最小の値。
# okが最初の値と変わっていない時、条件をみたすものがない。
if ok != N:
  print(ok)
else:
  print(-1)

```

## 終わりに
二分探索は長さ**N**の配列を**logN**で計算できる非常に強力なアルゴリズムです。
※例えば、10^9の計算がわずか20回程で終わります。

それゆえに、様々な活用方法があり、今回の記事では、最初から与えられた数列がソートされていましたが、
場合によっては自身でソートしたり、単調に変化するものを見出して二分法を活用する場合もあります。

ぜひ、この記事を読まれた方は、@e869120さんが書かれた[分野別　初中級者が解くべき過去問精選 100 問](https://qiita.com/e869120/items/eb50fdaece12be418faa#2-3-%E5%88%86%E9%87%8E%E5%88%A5%E5%88%9D%E4%B8%AD%E7%B4%9A%E8%80%85%E3%81%8C%E8%A7%A3%E3%81%8F%E3%81%B9%E3%81%8D%E9%81%8E%E5%8E%BB%E5%95%8F%E7%B2%BE%E9%81%B8-100-%E5%95%8F)などで練習問題をこなし、活用の幅を広げてみてください。

ここまで、お読みいただきありがとうございました。
M1 Mac で grpc-tools を npm install できない問題の回避策

**TL; DR:** 環境変数 `npm_config_target_arch=x64` をセットしてから `npm install` なり `yarn install` なりを実行するとよい。

---

この記事を書いた2021年7月14日の時点で、 grpc-tools (1.11.2) をインストールしようとすると node-pre-gyp がエラーを出してインストールに失敗する。（追記：2022年10月リリースの1.11.3で対応済み）

このエラーは node-pre-gyp が grpc-tools の arm64 向けコンパイル済みバイナリをダウンロードしようとして失敗することに起因する。 arm64 向けバイナリはまだ配布されていない[^1]。

エラーを回避するには環境変数 `npm_config_target_arch=x64` をセットしてから `npm install` や `yarn install` を実行する。これをセットすると node-pre-gyp が `--target_arch=x64` 引数を指定されたかのように振る舞い[^2][^3]、 x64 向けコンパイル済みバイナリをダウンロードするようになる。

x64 向けバイナリは Rosetta 2 によるエミュレーションで M1 Mac でも動く。

## エラーログ

```
% yarn add -D grpc-tools
yarn add v1.22.10
info No lockfile found.
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...
error /Users/uasi/tmp/t/node_modules/grpc-tools: Command failed.
Exit code: 1
Command: node-pre-gyp install
Arguments: 
Directory: /Users/uasi/tmp/t/node_modules/grpc-tools
Output:
node-pre-gyp info it worked if it ends with ok
node-pre-gyp info using node-pre-gyp@1.0.5
node-pre-gyp info using node@14.17.0 | darwin | arm64
node-pre-gyp info check checked for "/Users/uasi/tmp/t/node_modules/grpc-tools/bin/grpc_tools.node" (not found)
node-pre-gyp http GET https://node-precompiled-binaries.grpc.io/grpc-tools/v1.11.2/darwin-arm64.tar.gz
node-pre-gyp ERR! install response status 404 Not Found on https://node-precompiled-binaries.grpc.io/grpc-tools/v1.11.2/darwin-arm64.tar.gz 
node-pre-gyp ERR! install error 
node-pre-gyp ERR! stack Error: response status 404 Not Found on https://node-precompiled-binaries.grpc.io/grpc-tools/v1.11.2/darwin-arm64.tar.gz
node-pre-gyp ERR! stack     at /Users/uasi/tmp/t/node_modules/@mapbox/node-pre-gyp/lib/install.js:67:15
node-pre-gyp ERR! stack     at processTicksAndRejections (internal/process/task_queues.js:95:5)
node-pre-gyp ERR! System Darwin 20.5.0
node-pre-gyp ERR! command "/Users/uasi/.nodebrew/node/v14.17.0/bin/node" "/Users/uasi/tmp/t/node_modules/grpc-tools/node_modules/.bin/node-pre-gyp" "install"
node-pre-gyp ERR! cwd /Users/uasi/tmp/t/node_modules/grpc-tools
node-pre-gyp ERR! node -v v14.17.0
node-pre-gyp ERR! node-pre-gyp -v v1.0.5
node-pre-gyp ERR! not ok 
response status 404 Not Found on https://node-precompiled-binaries.grpc.io/grpc-tools/v1.11.2/darwin-arm64.tar.gz
info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command.
```

[^1]: https://github.com/grpc/grpc-node/issues/1405
[^2]: https://github.com/mapbox/node-pre-gyp/blob/9267e525efba4e4dc20829d5bb4b25dcee116a2d/README.md#options
[^3]: https://github.com/mapbox/node-pre-gyp/blob/9267e525efba4e4dc20829d5bb4b25dcee116a2d/lib/node-pre-gyp.js#L187-L211
DataFrameでインデックスとカラムを設定する


##概要
DataFrameでは、行の名前をインデックス、列の名前をカラムと呼ぶ。



######indexを指定なしで作成した際、インデックスは0から割り当てられる。

```python
import pandas as pd

fruits = ["apple", "orange", "banana", "strawberry"]
data1 = [10, 5, 8, 12]
data2 = [30, 25, 12, 10]
series1 = pd.Series(data1, index = fruits)
series2 = pd.Series(data2, index = fruits)

df = pd.DataFrame([series1, series2])

display(df)
```
![スクリーンショット 2021-07-14 20.34.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1736279/48c5d64e-1826-4fdf-2b4f-e9e9d2a73359.png)



#####indexの指定あり

```python
df.index = ["name1", "name2"]
```

![スクリーンショット 2021-07-14 20.33.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1736279/7a3d8133-3436-9f9a-b9a9-8c2f1145297b.png)


######補足
・カラムは元データのSeriesのindexや辞書型のキーになる。
・インデックスはdf.indexに行数と同じ長さのリストを、カラムはdf.columnsに列数と同じ長さのリストを、それぞれ代入する事が可能。
0.5秒後にシーン遷移

ボタンを押した時に音がならない問題に遭遇したため、
0.5秒後に遷移する方法を書きました。

```C#:   
   float time; 
   bool flg;

    void Start()
    {
        time = 0;  //初期値を設定
        flg = false;  //初期値はfalse
    }

    public void StartClick()
    {
        flg = true;  //StartClickが押された時にfalseからtrueになる
    }

    void Update()
    {
        if (flg == true)  //flgがtrueになったら実行される
        {
            time = time + Time.deltaTime;  //0にTime.deltaTimeを足す
        }

        if (time >= 0.5f)  //timeが0.5秒経ったらGameMainに遷移される
        {
            SceneManager.LoadScene("GameMain");
        }
    }
```

これで0.5秒後に遷移されるようになりました！
群集心理

#以前読んだ本について

書名：群集心理
著者：ギュスターヴ・ル・ボン さん

#読んだ感想

一言でいうと面白かった。
この本を読むと、演説、プレゼンテーションなどの人前で話をすることが上手な人達の
プレゼン、演説をより細かく分析できるようになると思います。
人前で発表する仕事を行う人にも役に立つ知識であると思いますので、一度読んでみてはいかがでしょうか。

#とりあえず、amazonのURLを張っておきます

https://www.amazon.co.jp/%E7%BE%A4%E8%A1%86%E5%BF%83%E7%90%86-%E8%AC%9B%E8%AB%87%E7%A4%BE%E5%AD%A6%E8%A1%93%E6%96%87%E5%BA%AB-%E3%82%AE%E3%83%A5%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%B4%E3%83%BB%E3%83%AB%E3%83%BB%E3%83%9C%E3%83%B3/dp/4061590928
【Git】一時的に過去のcommitに戻りたい

# はじめに

不具合等が発生した際に、発生個所を突き止めるため一時的に過去のcommitに戻って操作したい場合は無いだろうか？今回は、その方法を以下に記載する（最新のcommit状態に戻す方法も併せて記載する）。

# 結論

ブランチを過去のcommitに戻す手順と、最新の状態に戻すコマンドを記載する。

### ■ ブランチを過去のコミットに戻す

```
$ git checkout <コミット名>
```

### ■ 最新の状態に戻す

```
$ git checkout <ブランチ名>
```


# 詳細

### ■ 操作するブランチを確認

まず初めに、操作するブランチを確認する。
現在のブランチは`feature/test`である。

```
$ git branch 

master
* feature/test
```

### ■ 戻りたいcommit名を探す

次に、戻りたいcommit名を探す。
この場合、commit名は以下の通りである。

* `13gsd8g9skegjaosdjgnaewiura7g`
* `ckawijsgs863462wijngoasgeni1a`

```
$ git log

commit 13gsd8g9skegjaosdjgnaewiura7g (HEAD)
Author: name <name@google.com>
Date:   Tue Jul 13 13:00:00 2021 + 0900

commit ckawijsgs863462wijngoasgeni1a
Author: name <name@google.com>
Date:   Tue Jul 13 10:00:00 2021 + 0900
```

### ■ 過去のcommitに戻る

次に、戻りたいcommit名を指定してコマンドを実行する。
今回は`ckawijsgs863462wijngoasgeni1a`に戻る。

```
$ git checkout ckawijsgs863462wijngoasgeni1a
```

因みに、先頭4文字（今回ならckaw）までなら省略可能である。

```
$ git checkout ckaw
```

以上で、過去のcommitに戻ることが出来た。

### ■ 過去のcommitに戻した状態で現在のブランチを確認する

```
$git branch 

* (HEAD detached ckawijsg)
master
feature/test
```

先ほどまで、`feature/test`が現在操作しているブランチであったが、`(HEAD detached ckawijsg)`に変わっている。このことから、過去のcommitに戻ると、操作しているブランチとは異なるブランチを一時的に作成していることが分かる。そのため、最新のcommit状態に戻したい場合には、ブランチを変更してあげれば良い。

### ■ 最新のcommitに戻す

```
$ git checkout feature/test
```

これで、過去のcommit状態に戻った後に、再度現在のcommit状態に戻すことが出来た。ちなみに、現在のブランチを`feature/test`にすると、`(HEAD detached ckawijsg)`は消える。
Gitのやり直し系コマンド

「やり直し系コマンド」は私の造語です。gitの操作は常にやり直せます。
「打ち消す」、「リセットする」、「削除する」、「クリーンする」など、「やり直す」ためのgitのコマンドやオプションを紹介します。

本投稿では一つ一つのコマンドやオプションの詳細には踏み込みません。
<code>git rebase --abort</code> (リベースの破棄) を説明するためには、リベースとは何ぞやから説明しなければならないため説明の一部を端折ります。

「変更を破棄する」という日本語化されたGUIメニューが表示されたときに、以下のいずれのgitコマンドが実行されるか確信が持てないのであれば、怖くてボタンを選択できません。 「日本語化したgitアプリは怖いですよ！」、「GUIのgitアプリは便利なようでクセがありますよ！」ということを啓蒙するためのポエムです。

# 1. revert (打ち消す)

## 1.1. 最後のコミットを打ち消すコミットを追加する

```sh
$ git revert HEAD
```

HEAD(≒カレントブランチの末端)のコミットを打ち消すコミットを追加する。

## 1.2. 特定のコミットを打ち消すコミットを追加する

```sh
$ git revert 286dc77
```

コミット 286dc77 を打ち消すコミットを追加する。
※ いつ、誰が、どういう変更をした＆変更を打ち消した(revertした)かキチンと変更履歴に残る行儀の良い方法です。

# 2. reset (リセットする)

## 2.1. ひとつ前のコミットにコミットだけをリセットする

```sh
$ git reset HEAD^
```

最後のコミット(HEAD)をなかったことにする。
ステージングとワークはコマンド実行前後で変化しません。コミットをなかったことにするだけで修正途中のファイルは手元に残ります。

## 2.2. ひとつ前のコミットに全てをリセットする

```sh
$ git reset --hard HEAD^
```

最後のコミット(HEAD)をなかったことにする。
ステージングとワークもリセットします。前々回のコミット以降の変更が一切合切（＝ステージングからもワークからも）消えてなくなります。

## 2.3. resetの注意点

resetコマンドを使うと「コミットをなかったこと」にできます。しかしリモートサーバーにpushしたあと（変更履歴をメンバーと共有した後）に「なかったこと」にすると、同じリポジトリを共有している他のメンバーの新たな変更もなかったことになります。「なかったこと」にされたメンバーに謝罪して歩く気がないのであれば、push後のresetや force push は控えましょう。

# 3. restore (復元する)

## 3.1. ワークを復元する

```sh
$ git restore hello.c
```

ワークに対する変更を破棄して、ステージングからワークへhello.cを復元する。

## 3.2. ステージングを復元する

```sh
$ git restore --staged hello.c
```

ステージングに対する変更を破棄して、コミットからステージングへhello.cを復元する。
<code>git add hello.c</code> や <code>git rm hello.c</code> などステージングに対する操作を破棄する。

# 4. rm (削除する)

## 4.1. 追跡対象から削除する

```sh
$ git rm hello.c
```

ファイル "hello.c" を追跡対象（＝今後のバージョン管理の対象）から外す。ファイルエクスプローラーでhello.cを削除しただけでは最新コミットの中にhello.cが残り続ける。ゆえに rm コマンドで追跡対象から外すことができる。

# 5. abort (中止する)

## 5.1. コンフリクトが発生したマージを取り止める

```sh
$ git merge --abort
```

## 5.2. コンフリクトが発生したリベースを取り止める

```sh
$ git rebase --abort
```

# 6. clean (掃除する)

## 6.1. カレントフォルダーの未追跡のファイルをワークから削除する

```sh
$ git clean -f .
```

たとえば *.bak などの一時ファイルをカレントフォルダから一気に削除するときに使う。

# 7. amend (修正する)

## 7.1. 直前のコミットを修正する

```sh
$ git commit --amend
```

直前のコミットをなかったことにして、新しいコミットを作る一連の流れを１コマンドで実行する。

1. コミットとステージングに差異が生じていなければ、コミットコメントを修正するだけ。ちなみにコメントを変更するだけではあるが、新しいコミットはハッシュ(SHA-1)値が異なる似て非なるコミットである。</li>
2. <code>git add</code> や <code>git rm</code> により、コミットとステージングに差異が生じていれば、新しいコミットは全く異なるコミットである。

# 8. prune (切り払う)

## 8.1. リモートリポジトリに存在しないリモート追跡ブランチを削除する

```sh
$ git fetch --prune
```

## 8.2. ワークツリー情報を削除する

```sh
$ git worktree prune
```

# 9. drop (落とす)

## 9.1. 最新のstashを削除する

```sh
$ git drop stash
```

ワークからstash(退避)した内容をワークに戻さずに破棄する。
対戦ゲームを作る。 その3

#概要

対戦ゲームを作る。
送信データの説明。

#送信データ

```
{
id: 17aa4b810dc1,
state: 0,
iro: 0,
ban: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 1, 1, 1, 1, 1, 1, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
te: 0
}
```

#id

ユニークなIDです。

#state

現在の状態です。

#iro

白か黒です。

#ban

８×８の盤を表現してます。
０は黒
２は白

1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 0, 2, 1, 1, 1, 
1, 1, 1, 2, 0, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1

#te

次の一手です。

以上。
AWS超絶初心者がSESを使ってメール送受信やってみた

#前回のあらすじ
SES使ってDynamoDBに登録したメールアドレス宛でメールを一斉送信することができたよ

https://qiita.com/ostost/items/9ca90fd98393c631fbdc

#今回やりたいこと
・独自ドメインを取得してみる
・送ったメールに「amazonses.com 経由」がついてしまうのがかっこ悪いから直す
・メール受信＋S3に保存を試してみる

#独自ドメインを取得してみる
色々ググってみたけど、gmailとかの独自ドメインじゃないものは認証設定ができないぽいので、
独自ドメインを取得する。
本当はRoute53で発行しちゃえばよかったけど、とりあえず試しでやるのでお金が発生して、
そのまま使わずに忘れると嫌なので、無料でドメイン取得して、Route53に登録。
こちらの記事の通りにやればできる。

https://note.com/dafujii/n/n406f385651e2


#amazonses.com 経由にしない

同じ方が続き記事で、Route53でドメイン管理＋メール送信まで書いてくれていたので、
この通りに進める。
今でもメールはサンドボックス内で送信できるけど、gmailで受信すると「amazonses.com 経由」が画面に出ちゃう。
このやり方なら「amazonses.com 経由」が出ないみたい。

https://note.com/dafujii/n/n12bb564081f1

https://note.com/dafujii/n/n0365dc0a89af



よ〜し、これでDKIMの設定も完璧やし、受信画面の「amazonses.com 経由」が消えるはず！
![スクリーンショット 2021-07-14 19.34.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760697/531309e0-68b2-58cf-3c65-128b43ca3b65.png)

消えてへん！！！
というわけでもうちょいググってみる。


https://dev.classmethod.jp/articles/ses-send-mail-best-practices-summary/

https://dev.classmethod.jp/articles/amazon-ses-try-sending-email-in-sandbox-environment/

https://zenn.dev/seyama/articles/61c5fac91ff4f2

>2. SPFを介したDMARCへの準拠のため、カスタムMAILFROMドメインを設定

どうもカスタムMAILFROMドメインも設定しないといけないようだ。
上記の記事に沿って、Set MAIL FROM Domain　の項目から、mailをサブドメインに設定。
ちょっとこの辺理由が曖昧なので、分かる方いれば教えてください。

そして無事消えました。やったね！
![スクリーンショット 2021-07-14 19.56.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760697/72d137b7-1434-4ef8-91fa-438c8a62af67.png)


#メール受信＋S3に保存を試してみる

本日最後に、メール受信してS3に保存するところまでやってみる。以下の記事に沿って行う。
リージョンは東京を選択している。

https://note.com/dafujii/n/n77b8956db708

>SESの左側メニューから「Rule Sets」を選択し、「Create a Receipt Rule」ボタンを押します。

いきなりここでつまずく。「Create a Receipt Rule」が押せない。

というわけでまたもやググる。

https://teratail.com/questions/311707

東京リージョン送信機能対応してへん！！！（仰け反る）
言い訳をすると、
「SESって最近東京リージョン対応したんよな、2020年くらいの記事でも、東京は対応してませんって書いてるの多いけど、
実際は対応してるやろし、東京にしよ」
という安易な考えで東京リージョンを選んでいました。
東京リージョンはまだ送信のみ。心に刻んでオレゴンでやり直したら、記事の通りにできました。

ちなみにこれは自分がアホな話ですが、S3に保存された文字列を見ようとして

>Base64デコードすると以下の文字列が現れます。

だけ読んで、DLして全部デコードしたら動きませんでした。本文は、一番下のとこだけね。
（疑問：これタイトルは保存されてないのかな、、、）

#かかった時間
5時間弱くらい

#次やりたいこと
次はLambdaで転送設定してみる

https://dev.classmethod.jp/articles/ses-lambda-mail-transfer/

gmailに転送

https://zenn.dev/seyama/articles/2786ee5f73b314

添付ファイルの取得もやりたい

https://dev.classmethod.jp/articles/ses-get-attachfile-lambda/
PowerShellで一瞬日本語が映るが文字化けしてしまう件について

# はじめに

最近はWindows updateの頻度がとても多く感じます。
updateはしたほうが良いですが、それが原因でいままで使えたものがエラーになったりすることがあります。

今回もいままで使えていたPowerShellが文字化けするようになりました。
解決方法が見当たらなかったため、記事にしたいと思います。

# 問題

Powershellを起動すると日本語がすべて□の中に？が入ったような文字になってしまいます。
いままでそんなことはなかったので、おそらくWindows updateが原因だと思われます。

また、ネットで調べたところ多くは文字コードを`shift-jis`に変更しましょうなどが解決方法になっており、今回の原因とは異なりそうです。

また、ネットを調べたところ同じ症状の方をTwitterでみつけました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">PowerShell一瞬文字反応するのに<br>文字化けする <a href="https://t.co/phXm20JqoS">pic.twitter.com/phXm20JqoS</a></p>&mdash; Binary number (@Binary__number) <a href="https://twitter.com/Binary__number/status/1411631007510372359?ref_src=twsrc%5Etfw">July 4, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

(こちらのツイートのおかげで解決できました)

# 解決方法

文字コードの問題でした。

Powershellの上を右クリックして`プロパティ`→`フォント`→`MSゴシック`を選択

することで解決します。

![bandicam 2021-07-14 19-55-32-025.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/cc328294-5c2b-6f06-3a6c-6feaef418a52.jpeg)

# おわりに
ちなみに、Dockerも動かなくなりました。
そちらに関しては、Enable integration with additional distrosを選択することで解決しました。

![bandicam 2021-07-14 19-57-43-269.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/2526a7ab-9bf6-1b35-30a4-c71352b70906.jpeg)

いままで利用できたのが突如使えなくなるのは、宿命ですね。。一日が溶けてしまいました。
対戦ゲームを作る。 その2

#概要

対戦ゲームを作る。
通信サーバーをテストする。
２つ、開いて、送信データが両方に送られれば成功。
chatとしても、利用可能なのです。
テスト中に、知らない人、来るかも。

#サンプルコード

```

function getUniq() {
  var strong = 3;
  return new Date().getTime().toString(16) + Math.floor(strong * Math.random()).toString(16)
}
var id0 = getUniq();
var out = document.getElementById("out");
var src = document.getElementById("src");
src.value = "{\n";
src.value += "id: " + id0 + ",\n";
src.value += "state: 0,\n";
src.value += "iro: 0,\n";
src.value += "ban: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 1, 1, 1, 1, 1, 1, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n";
src.value += "te: 0\n";
src.value += "}";
var url = "wss://ohiapp0.herokuapp.com/pub";
var ws = new WebSocket(url);
ws.onopen = function() {
  out.innerHTML += "<p>> CONNECTED</p>"; 
  //send("open");
};
ws.onmessage = function(e) {
  out.innerHTML += "<p style='color: blue;'>> RECV: " + e.data + "</p>";
  //var json = JSON.parse(e.data);
};
ws.onerror = function(e) {
  out.innerHTML += "<p style='color: red;'>> ERROR: " + e.data + "</p>";
};
function send() {
  var m = src.value;
  out.innerHTML += "<p>> SEND: " + m + "</p>";
  ws.send(m);
}




```

#成果物

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

以上。
GitLab Omnibusで、GitLab PagesをワイルドカードDNSを使わずにサブディレクトリで運用する。かつ、アクセスコントロールも使えるようにする。

## やること

GitLab Omnibusで、GitLab PagesをワイルドカードDNSを使わずにサブディレクトリで運用する。かつ、アクセスコントロールも使えるようにする。

## ほうしん

- なるべくApache2の設定でなんとかする。
- GitLab自体を改造しない。

## このほうしんでできないこと

- GitLabのGUIで表示されているGitLab Pagesへのリンクは、いずれもサブドメインのURLになっているので、クリックしてもアクセスできない。
- `gitlab_pages['artifacts_server'] = true` にしても、上記と同じ理由で、アーティファクトからGitLab Pagesのお目当てのページに飛べない。
- かなしい。

## しょうち

非公式の方法なのでいつまで通用するか分からない。

## よんだ

- [GitLab Pages without DNS wildcard - MVC (#17584) · Issues · GitLab.org / GitLab · GitLab](https://gitlab.com/gitlab-org/gitlab/-/issues/17584)
  - そのままではダメだった。

## かんきょう

- Debian 10
- apache2 v2.4.38-3+deb10u5
- gitlab-ee v14.0.5-ce.0
- GitLabのFQDN: gitlab.example.net
- GitLab PagesのFQDN: pages.example.net

## GitLab GUIでのせってい

Admin Area > Applicationsでアプリケーションを追加する。以下の設定でアプリケーションを追加する。Application IDとSecretは自動生成される。Callback URLの本来の値は https://projects.pages.example.net/auth だが、サブディレクトリで運用するので以下のようにする。GitLab Pagesでアクセスコントロールを有効にするのに必要になる。Scopesはデフォルトは api だが read_api に下げても良い。

- Name: GitLab Pages
- Application ID: ???
- Secret: ???
- Callback URL: https://pages.example.net/projects/auth
- Trusted: N
- Confidential Y
- Scopes: read_api (Read Api)

## GitLabのせっていふぁいる

- 以下の設定を追記する。`gitlab_id`と`gitlab_secret`には上記で追加したアプリケーションのApplication IDとSecretを書く。
- 以下の設定を行っていると、それぞれの設定項目に応じてGitLabのGUIにGitLab Pagesの設定メニューが現れる。

```/etc/gitlab/gitlab.rb
pages_external_url 'https://pages.example.net'
gitlab_pages['enable'] = true
gitlab_pages['external_http'] = []
gitlab_pages['external_https'] = []
gitlab_pages['access_control'] = true
gitlab_pages['auth_redirect_uri'] = 'https://pages.example.net/projects/auth'
gitlab_pages['gitlab_id'] = '???'
gitlab_pages['gitlab_secret'] = '???'
gitlab_pages['auth_scope'] = 'read_api'
```

以下のコマンドで設定を反映させる。

```sh
$ sudo gitlab-ctl reconfigure
```

## Apache2のせってい

- つらい。

```apache
<VirtualHost *:80 *:443>
  ServerName pages.example.net
  # Let's Encryptの設定
  SSLEngine on
  Include               /etc/letsencrypt/options-ssl-apache.conf
  SSLCertificateFile    /etc/letsencrypt/live/pages.example.net/fullchain.pem
  SSLCertificateKeyFile /etc/letsencrypt/live/pages.example.net/privkey.pem
  # OAuth2関連の書き換え
  RewriteEngine On
  RewriteCond %{QUERY_STRING} (.*domain=http:\/\/)(?:[^.]*\.)(.*)$
  RewriteRule ".*" http://127.0.0.1:8090/auth?%1%2 [P,S]
  RewriteCond %{QUERY_STRING} (.*code=.*)$
  RewriteRule ".*" http://127.0.0.1:8090/auth?%1 [P,S]
  # リダイレクト先の書き換え
  Header edit Location http://(.*).(pages.example.net)/(.?) https://$2/$1/$3
  # リクエストの書き換え  
  RewriteCond %{REQUEST_URI} ^/(.*?)/(.*)/?
  RewriteRule ".*" "http://127.0.0.1:8090/%2/" [P,QSA,E=PAGESUSER:%1]
  RewriteCond %{REQUEST_URI} !^/(.*?)/(.*)/?
  RewriteRule ".*" "http://127.0.0.1:8090/" [P,QSA]
  <If "-T reqenv('PAGESUSER')">
    # eを忘れずに
    RequestHeader set Host "%{PAGESUSER}e.pages.example.net"
  </If>
</VirtualHost>
```

## Apache2のさいきどう

```sh
$ sudo systemctl restart apache2
```

## きぼう

- サブディレクトリ運用公式対応してほしい。
navigation設定したら真っ白になってしまった(初心者向け)

プログラミング始めて4ヶ月、kotlin始めて1ヶ月の超初心者の投稿です。ちなみに初投稿。(スマホから書いてるので後ほど加筆修正するかもです)

さて、android studioでnavigationを使って実装しようとした時、プレビューでは見れているのにビルドすると真っ白になってしまうという現象が発生した。
プレビューで見れているのにエミュレーターで表示されてない時は大体インスタンスを複数作ってるとかのパターンだったが、今回はめちゃくちゃシンプルなことが原因だった。

問題のnavigationをDesignモードで見ると、左側に
no navhostFragments found. This nav graph must be referenced from a NavHostFragment in a layout in order to be accessible
という文字が表示されていた。
これはナビゲーションホストが見つからないと言われているので、ナビゲーションを組み込んでいるxmlファイルを見ると原因がわかるはず。
今回はnavigationをMainActivityに組み込もうとしていたのだが、MainActivityのレイアウトファイル「main.xml」に「android:name= androidx.navigation.fragment.NavHostFragment」が抜けているという凡ミスだった。

凡ミスなくせに何回かやらかしてしまったので備忘がわりに記しておく。
Larastan使ってるとControllerのメソッド戻り値未指定で怒られる has no return typehint specified

# これはなに

Larastan使ってlevelをMAXにするとControllerの戻り値が未設定で怒られる

```terminal
Method App\Http\Controllers\ExampleController::index() has no return typehint specified.  
```

なのでそのエラーの解消法

## ControllerのメソッドでViewを返すときの戻り値

`Illuminate\View\View` を返す 

```php
<?php

declare(strict_types=1);

namespace App\Http\Controllers;

use Illuminate\View\View;

class ExampleController extends Controller
{
    /**
     * @return \Illuminate\View\View
     */
    public function index(): View
    {
        return view('example');
    }
}
```

## そもそも戻り値必須を無視

`phpstan.neon` の `ignoreErrors` に以下を記述

```
includes:
    - ./vendor/nunomaduro/larastan/extension.neon
parameters:
    paths:
        - app/
        - database/
        - tests/
    level: max
    excludePaths:
        - ./*/*/FileToBeExcluded.php
    ignoreErrors:
        # has no return typehint　を無視
        - '#Method [A-Za-z0-9\\]+::[A-Za-z0-9_]+\(\) has no return typehint specified#'
    checkMissingIterableValueType: false

```

めでたしめでたし
C言語で苦しんでいる： `char (*[])[]`と `char *[][]`の違い

今日、C言語 `char (*[])[]`と `char *[][]`の違いに苦しんだ。
言葉にしてもわからないよ。

#### `char ( * capa [2] ) [6]`
サイズ６のCharの配列（文字列）へのポインタのサイズ２の配列。

#### `char   * cpaa [2]   [6]`
Charへのポインタのサイズ６の配列のサイズ２の配列。

#### 考え方
識別子から優先度に従って矢印を書くと良さそう。

```c
char     (*     capa    [2])     [6]  // capaから始まる。
char     (*     capa -> [2])     [6]  // `[]`が優先。capaは配列(2)を指す。
char     (* <- (capa -> [2]))    [6]  // `（）`が優先。配列(2)はポインタが入る。
char     (* <- (capa -> [2])) -> [6]  //　ポインタは配列(6)を指す。
char <- ((* <- (capa -> [2])) -> [6]) //　配列はcharが６個入る。
```

```c
char    *     cpaa    [2]    [6]  //　cpaaから始まる。
char    *     cpaa -> [2]    [6]  //　cpaaは配列（２）を指す。
char    *     cpaa -> [2] -> [6]  //　配列（２）は配列（６）が入る。
char    * <- (cpaa -> [2] -> [6]) //　配列(６)はポインタが入る。
char <- * <- (cpaa -> [2] -> [6]) //　ポインタはcharを指す。
```

慣れてくると楽しくなってくる。

```c
  char *(*(*x[4])[5])[6];     // x  = [4]*[5]*[6]*char
  char *(*(*(*xp)[4])[5])[6]; // xp = *[4]*[5]*[6]*char
  char ***y[4][5][6];         // y  = [4][5][6]***char
  char ***(*yp)[4][5][6];     // yp = *[4][5][6]***char
```



#### Sample code

https://onlinegdb.com/IgPBcDh__

```c
#include <stdio.h>

int main() {
  char hello[6] = "hello";
  char world[6] = "world";
  char(*capa[2])[6] =  // capa = [2]*[6]char = [2]*string(6)
      {&hello, &world};

  printf("%p -> %s\n", capa[0], *capa[0]);  // `hello`
  printf("%p -> %s\n", capa[1], *capa[1]);  // `world`

  char a1 = 'a';
  char a2 = 'b';
  char a3 = 'c';
  char a4 = 'd';
  char a5 = 'e';
  char a6 = 'f';

  char b1 = 'g';
  char b2 = 'h';
  char b3 = 'i';
  char b4 = 'j';
  char b5 = 'k';
  char b6 = 'l';

  char *cpaa[2][6] = {// cpaa = [2][6]*char
                     {&a1, &a2, &a3, &a4, &a5, &a6},
                     {&b1, &b2, &b3, &b4, &b5, &b6}};

  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 6; j++) {
      printf("%p -> %c\n", cpaa[i][j], *cpaa[i][j]);
    }
  }

  return 0;
}
```




参考：
http://kmaebashi.com/programmer/pointer.html
K&R本：　https://amzn.to/3ySLZZV
AiZynthFinderで逆合成

# はじめに
このページでは
- AiZynthFinderとは？
- AiZynthFinderの使い方
に焦点を当ててご説明いたします。

# AiZynthFinderとは？

>AiZynthFinder is a tool for retrosynthetic planning. The algorithm is based on a Monte Carlo tree search that recursively breaks down a molecule to purchasable precursors. The tree search is guided by a policy that suggests possible precursors by utilizing a neural network trained on a library of known reaction templates.
>
>An introduction video can be found here: https://youtu.be/r9Dsxm-mcgA

**AiZynthFinder（読み方：エーアイジィンスファインダー？）は逆合成解析を行うオープンソースのツール**です。既知の反応テンプレートのライブラリで訓練されたニューラルネットワークを利用して、ZINCデータベースにある化合物に分解されるまで逆合成を行います。ZINCはバーチャルスクリーニングのために特別に準備された市販の化学物質のデータベースであり、製薬会社やバイオテクノロジー企業、大学の研究者らが使います。

## その他の逆合成解析ツール
- [ASKCOS](https://askcos.mit.edu/)：オープンソース？、情報少ない
- [IBM RXN](https://rxn.app.accelerate.science/rxn/sign-in)：フリーで使える、[参考サイト](https://netdekagaku.com/reactionpredictionibm/)
- Reaxys：高価（らしい）
- SciFinder：導入している企業も多い
- Synthia：情報は多い
- [GRRM23](https://www.hpc.co.jp/chem/software/grrm23/qcara-samples/)：量子化学的逆合成解析(QCaRA) が可能

# AiZynthFinderのインストール方法
- [オープンソースで逆合成解析 ~AiZynthFinder~ part 2. 遊んだ](https://magattaca.hatenablog.com/entry/2020/10/12/005441)
- [逆合成ちゃんを支える技術](https://zenn.dev/retrosynthchan/articles/9283f3e8dd8dac)
上記の2つのサイトを参考にインスールしました。結構苦戦した記憶があります…


# AiZynthFinderの使い方
Anacondaを使ってAiZFという名前で仮想環境を作り、実行致しました。Anaconda Promptで以下を実行してJupyter notebookを立ち上げます。

```
conda activate AiZF                     # 仮想環境(AiZF)を有効にする
cd aizynthfinder                        # aizynthfinderのディレクトリに移動
aizynthapp --config model/config.yml    # AiZynthFinderを立ち上げる
```

立ち上げたJupyter notebookには以下のコードが既に書いているので実行する。***はユーザー名です。

```python
from aizynthfinder.interfaces import AiZynthApp
configfile=r"C:\Users\***\aizynthfinder\model\config.yml"
app = AiZynthApp(configfile)
```

ここでは、例として医薬品であるドネペジル(アリセプト)を逆合成解析してみます。SMILESの欄にドネペジルのSMILES（COC(C(OC)=C1)=CC2=C1CC(C2=O)CC(CC3)CCN3CC4=CC=CC=C4）を打ち込むと自動的に構造式が表示されます。Run Searchを押すと解析が始まります。

![AiZynthFinder.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1057114/ad2d64c8-4477-7f34-ff93-e73bb158dea1.png)


解析終了後Show reactionsを押すと解析結果が表示されます。

![AiZynthFinder2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1057114/227fbb33-b9a3-85db-30c0-210392acfeac.png)


RoutesでOptionを変更すると別の逆合成経路が表示されます。

![AiZynthFinder3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1057114/f7439989-7916-323c-bcd0-a152452d8354.png)



## 参考
- [GitHub](https://github.com/MolecularAI/aizynthfinder)
- [オープンソースで逆合成解析 ~AiZynthFinder~ part 2. 遊んだ](https://magattaca.hatenablog.com/entry/2020/10/12/005441)と
- [逆合成ちゃんを支える技術](https://zenn.dev/retrosynthchan/articles/9283f3e8dd8dac)
- [アラート ≠ 禁止　〜ZINCデータベースの医薬品にPAINSフィルターをかけてみた話〜](https://magattaca.hatenablog.com/entry/2021/12/12/011109)
- [論文紹介: AiZynthFinder](https://zenn.dev/retrosynthchan/articles/a8fe673c97172e)
[Rails]RspecにてKeyError: Factory not registered

##はじめに
Rspecにてテストコードを記述していたところ```KeyError: Factory not registered```というエラーが出ました。
悩んだ割にはさくっと解決できました。一応記事に残しておきます。



##解決法
まず、私の場合、FactoryBotで定義していたのがこちらになります↓

```ruby
FactoryBot.define do
  factory :progress do
    progress_page       {300}
    comment             {"◯◯と◯◯がよくわからなかったから次回詳しく教えて欲しい" }
    association :students_textbook
  end
end
```

こちら実際のターミナル上のエラー↓
![スクリーンショット 2021-07-13 19.15.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1552346/eb1c8646-98f1-36f6-b8e3-96dd39048b8d.png)

これアソシエーションで```students_textbook```という中間テーブルのモデルと繋がっているのですが、このときspecフォルダの中のmodelsフォルダの中にstudents_textbookモデルは作成していません。

しかしながら実際のテストじゃない方では存在するモデルです。
ただ、これは中間テーブルなので特にテストすることもないと思い、作成していませんでした。

しかしエラー文をみるとどうやらfactorybotの方で定義したアソシエーションがどうやら怪しいと思い、```rails g rspec:model```で作成しました。

するとうまいこといきました。

##最後に
おそらくアソシエーションで組んでいるモデルがないぞ！というエラーだったのかと思います。実際では存在しますし、これはテストなので一応associationで記載したモデルが存在しないとおかしいよねっということを知らせてくれているのでは？という結論に行きつきました。

ちなみに、specフォルダの中のstudents_textbookモデルは何も記載していません。

もし私の仮説や考え方が間違っている場合指摘していただけると幸いです。
N-BASICで機械語

N-BASICから機械語のルーチンを呼び出すUSRを使ってみます。

何もしないサブルーチンを機械語で保存します。

monでRET(C9)を書いておきます。

```
mon
* SE800
E800 FF-C9 FF-
*
```

コントロール+BでN-BASICに戻ります。

N-BASICで

```
DEF USR=&HE800
```

しておくとUSRが使えるようになります

```
? USR(0)
0
```

引数が数値の場合2バイトの値がHLレジスタの示すメモリに保存されています。また返り値も同じアドレスになるので、0が返ってきます。

インクリメントの関数を書いてみます。

```
   1:				;
   2:				; PC-8001 assembra
   3:				;
   4:				
   5:				
   6:     -	E800'         		ORG	0E800H
   7:     -	E800'         	USR:
   8:    0+7	E800' 4E      		LD	C,(HL)
   9:    7+4	E801' 0C      		INC	C
  10:   11+7	E802' 71      		LD	(HL),C
  11:   18+10	E803' C9      		RET
  12:				
```

HLの先のアドレスには下位バイト、上位バイトが保存されていて、下位バイトしか処理していないので、255までになります。

```
? USR(0)
1
? USR(255)
0
```
JavaScriptの存在チェック（〜を含む）まとめてみた


JavaScriptで存在チェック（〜を含む）を書く機会があったので、メモ。

## 変数

変数宣言

```javascript
const string = "abcdefg";
```


### match

```javascript
/* match
文字列が含まれれば配列、文字列が含まれなければnullが返る
console.log(string.match(/abc/)) => (1) ["abc"]
console.log(string.match(/hoge/)) => null
*/

console.log(string.match(/abc/));
// => true
```

`match(//)` の部分は、変数ではなくて`string`として認識されるので、変数を使いたい場合は、「正規表現オブジェクト」を使う。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/RegExp


#### RegExpオブジェクト

```javascript
const target = "a";

const reg = new RegExp(target, "ig");
console.log(string.match(reg));
// => (1) ["a"]

console.log(reg.test(string));
// => true
```

RegExp オブジェクトのコンストラクタ関数を呼び出して 正規表現を記述
RegExpの第二引数にある`i`と`g`は検索パターンのオプション。

- `g` マッチしたもの全てを返す
- `i`　　大文字と小文字を区別しない

結果のコメントを見てもわかるように、　`match`と`test`では返ってくる値が違います。単純に、値を含むかどうかを調べるには、`test`を使うといいのかも。

- [RegExp.prototype[@@match]()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/RegExp/@@match)
- [RegExp.prototype.test()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test)



### indexOf

```javascript
const target = "a";

console.log(string.indexOf(target) != -1);
// => true
```

`indexOf` 
文字列が見つかれば文字列が見つかった場所が。
文字列が見つからなければ-1が返ってくる

```javascript
/*
console.log(string.indexOf('hoge')) => -1
console.log(string.indexOf('世界'))  => 5
*/
```



## 配列

配列を定義

```javascript
const array = ["abc", "def", "ghi", "jk", "lmn", "opqr", "stu"];
```

### indexOf

```javascript
const target = "ghi";
console.log(array.indexOf(target))
// => 2

console.log(array.indexOf(target) !== -1)
// => true
```

文字列と一緒で、
配列の場合、一致するindex を返す
見つからなければ、-1が返ってくる



### includes

```javascript
const target = "ghi";

console.log(array.includes(target));
// => true

```

`includes`
特定の要素が配列に含まれているかどうか

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/includes


### some

```javascript

const target = "abc";

console.log(array.some((c) => c === target));
// => true

```

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/some


`Array.some` と `Array.includes`の違いはこちらの記事がわかりやすかったです。

https://qiita.com/Nossa/items/4a425e57ec4b7eedb7cb


## オブジェクト配列

```javascript

const arrayOject = [
  {
    id: 1,
    name: "abc",
    description: "abc",
    price: 1000
  },
  {
    id: 2,
    name: "def",
    description: "def",
    price: 3000
  },
  {
    id: 3,
    name: "ghi",
    description: "ghi",
    price: 2000
  }
];

```

### some

```javascript
console.log(
  arrayOject.some((c) => c.name === target)
);
// => true
```


### findIndex

```javascript
// findIndex
console.log(
  arrayOject.findIndex((c) => c.name === target) != -1
);
// => true
```

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex



## 参考リンク

https://www.wakuwakubank.com/posts/485-javascript-include-array-string/

https://qiita.com/shirokuman/items/d81e9c812003dfa15176

https://qiita.com/kazu56/items/557740f398e82fc881df