OmniAICreator/Qiita-1.07M huggingface dataset:
.Gemfile .Gemfile.lock まとめ

# 概要

- railsアプリを作成するにあたり、最初に理解しておきたいgemfileとgemfile.lock
- だいぶ昔に勉強したこともあり内容をぼんやりとしか覚えていなかった
- まとめていた内容が稚拙で、見てもわからなかったので、再度まとめて将来の自分が一発で理解できるようにする

### 参考資料：[Gemfile](https://ruby.studio-kingdom.com/bundler/gemfile/)
### 参考資料２：[Gemfile?bundler?Rails開発するなら理解しておきたいgem管理の基礎知識](https://nishinatoshiharu.com/fundamental-gem-knowledge/)
### 参考資料３：[Bundler, Gemfile, Gemfile.lock について](https://qiita.com/privativealpha/items/169833d4c8baf79e1b52)

# gemとは

以下参照

https://qiita.com/Islanders-Treasure0969/items/654c4182f8dec9bc2055#gemとは

# gemfileとは

- gemの依存関係を記述するファイルのこと
- gemfileに記載してある内容に従ってbundlerが供給元(gemfileの`source`に指定するリソース。ほとんどが[rubygems](https://rubygems.org)からgemを探してくる

# gemfile.lockとは

- bundler[^1]によってインストールされた全てのgemとそのgemのバージョンが記載される
- gemfileに記載されているgemと依存関係を持っているgemも含めてインストールし、それらすべての情報が記載される

gemfileに記載したgemは他と依存関係を持っているgemもたくさんあり、それらも含めてインストールされる必要がある


# ルール

- プロジェクトのルートディレクトリに配置する(Railsアプリであれば、そのルートディレクトリ)

# 記載する内容

### 1. gemの供給元

```.Gemfile
source <供給元URL> #e.g. "https://rubygems.org"
```

### 2. rubyバージョン

- アプリケーションで必要になるRubyのバージョン情報を記載

```.Gemfile
ruby "2.6.6"
```

### 関連【Rubyエンジン】

- Rubyのエンジン(処理系)[^2]も指定できる
- エンジンを指定するならそのバージョン情報も記載する必要がある

```.Gemfile
ruby "1.8.7", :engine => "jruby", :engine_version => "1.6.7"
```

### 3. Gem

- 必要なGemを記載する
- バージョンを指定できる

##### Gemのバージョン指定方法

https://qiita.com/morioka1206/items/19410fe414f441583998

```.Gemfile
gem 'rails', '5.0.0' #railsバージョン5.0.0固定
gem 'rails', '>=5.0.0' #railsバージョン5.0.0以上
gem 'rails', '>=5.0.0', '<6.0.0' #railsバージョン5.0.0以上6.0.0未満
gem 'rails', '~>6.0.0' #railsの6.0.x マイナーバージョンまで固定
gem 'rails', '~>6.0' #railsの6.x.y メジャーバージョンまで固定
```

### 4. 特定の環境のみでの利用

- groupを指定する(:test,:development,:production)

```.Gemfile
group :test do
  gem 'faker'
  gem 'rspec'
end
group :test, :development do
  gem 'capybara'
  gem 'rspec-rails'
end
```


[^1]: gem同士の依存関係を解決しながら管理できるライブラリ。gemで公開されている。[参照](wip:参照を追加する)
[^2]: Rubyにも処理系があり、デファクトスタンダードは[CRuby](https://ja.wikipedia.org/wiki/CRuby)(だよね？)であるが他にも[JRuby](https://ja.wikipedia.org/wiki/JRuby)などがあるみたい
リセットCSSについて

#　　　リセットCSSについて
今回は、リセットCSSについて簡単に解説して行きます！
リセットCSSとは、デフォルトのCSSの設定を無効化して
ブラウザ（Safari、GoogleChrome、FireFox）等の、
出力内容を同じにさせる事が出来る、ありがたい機能です！
## 　リセットCSSを適用させないと？？？
リセットCSSを適用させないと、Safariで閲覧した時は、
綺麗に表示されるのにGoogleChromeでは、レイアウトが
崩れてしまう等の困った事になってしまいます（泣）

いつもありがとう、リセットCSS！
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1405238/d80568d8-2bed-3b66-68c5-702a5ef001eb.png"width=40%>
bundler, gem,RubyGemsまとめ

# 概要

- gemの依存関係解決を行うためのライブラリ(実態はgem)という認識を持っている
- 使用方法とかで毎回詰まるため、仕組みや使い方を調べた内容をまとめる
- ついでにbundlerやRubyGemsについても簡単にまとめてみる

### 参考資料：[Bundler入門](https://ruby.studio-kingdom.com/bundler/guides/getting_started)
### 参考資料２：[ライブラリ? gem? bundler? -- Rubyのgem管理に関するあれこれまとめ](https://qiita.com/3no3_tw/items/8c1e3e95c75edae1036d)

# bundlerとは

- gemの1つ
- 依存性地獄から抜け出すためのもの
- ライブラリが他方のライブラリの特定のバージョンに依存しているとき、これを考慮する必要がある
- このような関係性はライブラリにはつきもので、それを人が一つ一つ毎回解決するのは大変骨が折れる(てかする気が起きない)
- 上記の問題を解決するためのgemである
- gem同士の依存関係を解決しつつパッケージの種類やバージョンを管理してくれるツール

# gemとは

bundlerと解説順序がおかしい気もしますが。。。

- rubyのライブラリのこと
- 公開する場所として有名なのは https://rubygems.org がある
- 他のソースを指定する場合はGemfileの中の`source`で任意のRubyGemサーバを指定する

# RubyGemsとは

[Wikipedia](https://ja.wikipedia.org/wiki/RubyGems)先生曰く

>RubyGemsは、Ruby言語用のパッケージ管理システムであり、Rubyのプログラムと（"gem" と呼ばれる）ライブラリの配布用標準フォーマットを提供している。gemを容易に管理でき、gemを配布するサーバの機能も持つ。Rubyバージョン1.9以降では標準ライブラリの一部となっている。

とのこと

- gemの管理、配布用のサーバーとしての役割も持つ

# gemとRubyGems

- rubyの個々のライブラリはgemとして公開され
- それらを束ねる仕組み(パッケージ管理)としてRubyGemsがある感じ
ScapyでWARNING: Calling str(pkt) on Python 3 makes no sense!が出たとき

## ソースコード

```python
from scapy.all import *

data = sniff(filter="icmp", count=1)
print(data[0])
```

## 出力結果

```
WARNING: Calling str(pkt) on Python 3 makes no sense!
b'\xc4<...(続く)'
```

## 改善方法

```python
print(data[0])
```

を

```python
data[0].show()
```

に変える
OpenSSL まとめ

# 概要

- OpenSSLについて、あるフレームワークのインストールでハマったときに出てきたワードだったが、知らなかった
- 調べた内容をまとめる

### 参考資料：[「OpenSSL」とは何ですか？「Heartbleed」はどのような問題でしょうか？](https://eset-info.canon-its.jp/malware_info/qa/detail/141204_1.html)

# OpenSSLとは

[Wikipedia先生曰く](https://ja.wikipedia.org/wiki/OpenSSL)

> OpenSSL（オープン・エスエスエル）は、SSLプロトコル・TLSプロトコルの、オープンソースで開発・提供されるソフトウェアである。中心となっているライブラリ（C言語で書かれている）は基本的な暗号化関数と様々なユーティリティ関数を実装している。様々なコンピュータ言語でOpenSSLライブラリを利用できるようにするラッパーもある。OpenSSLはEric A. YoungとTim HudsonによるSSLeay（1998年12月に開発者がRSA Securityに異動したため開発は終了されている）を基にしている。

とのこと。

。。。何言ってるか分からない

# SSL/TLSとは　[参考](https://www.kagoya.jp/howto/rentalserver/ssl/)

ここで、上記で出てきたSSL/TLSプロトコルについて復習すると

- インターネット上でデータを暗号化して送受信する仕組み（プロトコル）
- そもそもは通信の暗号化のためにSecure Sockets Layerが開発された
- SSLに脆弱性が見つかった
- SSLの脆弱性に対応するようにTLSが開発された
- このため、SSL/TLSと呼ばれてはいるが、現行で使用されているのはほぼTLS

### では、OpenSSLでは何ができるのか

- OpenSSLは暗号化通信のプロトコルであるSSL/TLSを実装した**プログラムのうちの一つである**
- OpenSSLをソフトウェアに組み込むことで通信の暗号化を行うことができる

# 導入の流れ

## 1. インストール

```
$ brew install openssl
$ brew link openssl #opensslにシンボリックリンクを貼る
$ echo 'export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"' >> ~/.zshrc #path追加
$ source ~/.zshrc #設定ファイル読み込み
```

## 2. 使えるようになっているか確認

```
$ which openssl #opensslのパス確認

$ openssl version #バージョン確認
```

# その他情報

## 1. 過去に見つかった脆弱性(以下以外でもたくさんあります)

調べていて頻出したワードが**Heartbleed問題**という脆弱性の問題

### Heartbleedとは

参考：[Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%8F%E3%83%BC%E3%83%88%E3%83%96%E3%83%AA%E3%83%BC%E3%83%89)

- OpenSSLに見つかった重大な脆弱性であるソフトウェアバグにつけられた名称のこと
- 元は[Heartbeat](https://en.wikipedia.org/wiki/Heartbeat_(computing))というOpenSSLに対する拡張機能から生まれたバグ
- このバグではHeartbeatを使った発信をするとメモリ上にあるデータが１回につき64キロバイトずつ漏洩する可能性があったとのこと
- 現在では修正パッチが当てられているのでそれにアップデートすれば大丈夫だが、OpenSSLの再コンパイル、サイトなどで証明書を発行している場合は新しいサーバー証明書を発行するなどの対応に追われた

## 2. フォークされたOpenSSL

### LibreSSLとは

参考：[LibreSSL の意義](https://qiita.com/kinichiro/items/3108e950b056963c33ad)

- SSL/TLS通信用ソフトウェアとしてのシェアNo.1を誇っているOpenSSLからフォークされたSSL/TLS通信用ソフトウェア
- OpenSSLのシェア率に対してのサポート体制の弱み、様々な問題に目をつぶれなくなったOpenBSDが、専用のSSL/TLS通信用ソフトウェアをOpenSSLからフォークしてメンテすることにした
- 必要ないコード等を大量に削除したらしい(90000行以上削除したとか！)

# 力尽きた。。。

- ここから先は必要になったときに調べることとする

## リンク集

- [LibreSSL の意義](https://qiita.com/kinichiro/items/3108e950b056963c33ad)
- [Wikipedia/LibreSSL](https://ja.wikipedia.org/wiki/LibreSSL#cite_note-zdnet_fork-9)
- [Homebrew brew linkしてもリンクしたopensslを使ってくれない。](https://qiita.com/halo57/items/e7511f3befbcb9fedd6a)
自作PCにwsl2で開発環境を整える～Postgre SQL導入編～

# Abstract
[前回](https://qiita.com/SatoshiNonomura/items/a84dc7ee6740e4a5b41a)に引き続き、Railsを使うための環境を作っていきます。
今回はDBです。
Postgre SQLを使っていこうと思います。

# Postgre SQLの導入
## keyのインポート
インストールするために必要なkeyを取得します。

```sh
sudo apt install curl ca-certificates gnupg
```

```sh
curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
```

## リストへの追加
```sh
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
```
ここまで終わったらアップデートしてリストに追加しましょう。

```sh
sudo apt update
```

## インストール
```sh
sudo apt install postgresql
```
pgadmin4を入れろ的な記事もありますが勝手に入るはずなのでいらないと思います。

## 確認
以上で導入自体は完了したはずなので確認します。

```sh
psql --version
```

# セッティング
## 起動
```sh
sudo service postgresql start
```

`* Starting PostgreSQL 13 database server`って出た横に`[OK]`って出れば起動できたってことです。

## ロールの作成
現状だとpsqlコマンドはpostgresというユーザーでないと使えないので調整していきます。

まず、postgreユーザーでログインします

```sh
sudo -u postgres psql
```

`postgres=#`みたいに出てきたらログインできています。

### Ubuntuのユーザーでのログインを許可
```sql
create role <USERNAME> with login createdb; 
```


### postgresユーザーのパスワード変更
```sql
alter user postgres password 'pass';
```

ここまで終わったらログアウトしましょう

```sql
\q
```

## 確認
```sh
psql -l
```
これでデータベースの一覧が出てきたら成功です。

# バックナンバーと次回予告
[初回：WSL導入編](https://qiita.com/SatoshiNonomura/items/1b23107b2ab9c28b5f2a)
[前回：ruby導入編](https://qiita.com/SatoshiNonomura/items/a84dc7ee6740e4a5b41a)
[次回：Rails導入編](https://qiita.com/SatoshiNonomura/items/2b0bf78be2df1fe298b3)

# 参考
[WSL2上のUbuntu20.04にPostgreSQL13をインストール](https://rowingfan.hatenablog.jp/entry/2020/11/07/135110)
[Windows10のWSL(Ubuntu)にPostgreSQLをインストールしたときのメモ @syutaro ](https://qiita.com/syutaro/items/d08c5c7cc24cddf7694c)
pythonを便利に使おう第三回！ 数学編!

#初めに
　積分というのは原理を理解しなければ使用するときに困ります。積分といえば不定積分と定積分があって、定積分はある範囲の数値を足し合わせることで面積を出します。学校での積分は、作業量に付き段々と本来の目的を失うように思います。数学のドリルをとけば、不定積分、不定積分…という風に公式を利用しなければテストで高い点数なんて取れないでしょう。
　レベルを上げるということは理解を深めることと作業の効率化にあると思います。理解には自分の脳みそを頑張らせないといけませんが、効率化にはパソコンを使用してもいいと思います。
###とかいう言い訳はさておき！
　試験でパソコンを持っていけるわけはないけれど、pythonのsympyを使って積分をしてみようと思います。

#数学 IIIα
　僕の学校で数学のテストが行われたのですが、そこから適当に問題を出してきます。因みにですが死ぬほど簡単でした。つまり言えることといえば、パソコンなんて必要ありません…が、僕は80点しか取れなかったので、ミスをなくすという意味ではパソコンは100%必要ですね。

##第一問　次の定積分を求めよ。(ただし積分定数Cは省いてよい)

```math
\int \frac{2}{5x}dx\qquad\int 4x\,logxdx\qquad\int sin6x\,sin3x \\
```

(一応)部分積分の問題でした。

```math
\int \frac{2}{5x}dx\\
```

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

```
2⋅log(x)
────────
   5 
```

```math
\int 4x\,logxdx\\
```

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

```
   2           2
2⋅x ⋅log(x) - x 
```

おお、何も指定せずとも部分積分もしてくれるんですね。できるかな？と予想はしていましたが、本当に出来るとは。

```math
\int sin6x\,sin3x \\
```

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

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

流石にちょっとだけ時間がかかりました。と言っても5秒もかかりませんでしたが。しかしこれ…本当にあってるのか？と少し不安になったため三角関数の積を和などに変換する公式を利用してこねくり回してみれば、答えと合ってることを確認できました。さすがsympy!さすがpython!

##第二問　次の不定積分を求めよ。(ただし積分定数Cは省いてよい)

```math
\int_{2}^{3} \sqrt{4x-x^2}dx\qquad\ \int_{0}^{2} 2\sqrt{16-x^2}dx\qquad\ \int_{-1}^{0} \sqrt{x^2+2x+3}dx\ \\
```

定積分は少しだけ関数に渡す値を増やすだけです。

```math
\int_{2}^{3} \sqrt{4x-x^2}dx\
```

```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_{0}^{2} 2\sqrt{16-x^2}dx\
```

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

```
       8⋅π
4⋅√3 + ───
        3 
```

```math
\int_{-1}^{0} \sqrt{x^2+2x+3}dx\
```

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

```
0                      
⌠                      
⎮     ______________   
⎮    ╱  2              
⎮  ╲╱  x  + 2⋅x + 3  dx
⌡                      
-1 
```

おや？今までとは違う挙動を見せましたね。これはどういうことでしょう。定積分ではなく不定積分として書き直してやってみました。

```
⌠                      
⎮     ______________   
⎮    ╱  2              
⎮  ╲╱  x  + 2⋅x + 3  dx
⌡                      
```

ふむ…これは、sympyの限界とかそういうことなのでしょうか。予想される処理が大きすぎるため、ストッパーが発動したとか？調べてみましょう。
と、息こんで色々と調べてみたは良いものの、どうしてこうなっているのかよくわかりませんでした。代数計算として利用する際にはこの形の方が便利だとでも言うつもりなのでしょうか。
わかる方がいればコメントで教えていただければ幸いです。

#最後に
　*SNSを作る息抜きにするpythonは楽しいなぁ！*
　webサイトを何か一つ作ってみても良いのですが、初めに作るのはSNSが良いと考えて幾星霜、依頼を出したり受けたりするためのSNS作りをしているのですが、これが一人では中々に辛い！
依頼をするためのSNSを作り終わる前に、色んな人に対して依頼を出すかもしれません。特にCSSとか、javascriptsとか、jqueryとか。
　フロントエンドの開発にまで手を回してたら今度はテスト勉強が出来なくて単位を落としてしまう！
ラズパイにLINE beacon機能を持たせる

設定手順

今回はラズパイにLINE beacon機能を持たせます。
設定はこちらの記事(この方法を真似るだけで設定できます。一部現状に合わせて修正しています。)

https://qiita.com/torisankanasan/items/e258ee0ecfc10fb442a7

他のデバイスは以下リンク参照

https://qiita.com/poruruba/items/a28476ad53b2232c789d

概要

ビーコンとは近距離圏内で無線通信できる位置特定技術およびその機能を利用したデバイスのことで、LINEではBluetoothの機能を使ってビーコンを設定できます。


## ラズパイ側設定

まずこちらのリンクの「LINE Simple BeaconのハードウェアIDを発行」をクリックし、アカウントリストを表示させます。※引用記事だとLINE OFFCIAL ACCOUNT MANAGERにリンクされますが、現在OFFCIAL ACCOUNT MANAGERは廃止され、LINE DEVELOPERSに統合されています。

https://manager.line.biz/beacon/register

アカウント一覧が表示されるので、Beaconを設定したいアカウントを選択します

そうしますと、ハードウェアIDの発行が出ますので、「ハードウェアIDを発行」をクリックしてください。(この数字IDはフェイクです)
スクリーンショット 2019-11-24 9.38.52.png

次にRaspberry Pi Zero Wをセットアップします
Linux向けのBluetoothのプロトコルスタックであるbluezおよび関連するパッケージをインストールします。

``````
pi@raspberrypi.local $ sudo apt-get install bluetooth bluez libbluetooth-dev libudev-dev
最初のコマンドのHWIDを適宜変える以外、全てコピペです
(ここではHWIDが01234g6s89の場合)

# 発行されたHWIDを2桁ごとにスペースで区切ったものを指定
HWID='01 23 4g 6s 89'

ADVERTISE_DATA="13 02 01 06 03 03 6F FE 0B 16 6F FE 02 ${HWID} 7F 00"

# Bluetooth HCIを有効にし、初期化します
sudo hciconfig hci0 up

# LE Controller Commands(OGF: 0x08), HCI_LE_Set_Advertising_Data(OCF: 0x0008) を実行し、
# 出力データを設定します
sudo hcitool -i hci0 cmd 0x08 0x0008 ${ADVERTISE_DATA}

#  Non connectable undirected advertising(3)で、Bluetooth LEのアドバタイズを有効にします
sudo hciconfig hci0 leadv 3

``````
複数リポジトリを一括でgit pullするShellを書いてみた

#背景
リポジトリを数十個に分割して相互に依存関係があるコードを開発しており、毎日数十個のリポジトリを一つ一つgit pullするのが手間だったので、同一ディレクトリ内にgit cloneしているリポジトリを一括でgit pullするShellを書いてみた。

#やったこと
以下のShellを書いた。

```shell:git-pull.sh
#!/bin/sh

# 処理したいgitリポジトリ一覧を置いているディレクトリパス+リポジトリ名のプレフィックスを保持する変数dir_pathを定義
dir_path="/path/to/directory/repository-name-prefix*"

# $dir_pathに合致するgitリポジトリのディレクトリをforループで処理
for dir in $dir_path;
do
  (
    # 処理対象のgitリポジトリを表示
    echo $dir
    # gitリポジトリのトップディレクトリへ移動
    cd $dir
    # git pullコマンドでリモートリポジトリの変更を取得
    git pull
  )
done
```

以下のshellコマンドでも同じことができる。

```shell
ls -1 | while read repo; do (cd $repo; echo $repo; git pull); done
```
import segmentation_models_pytorchでエラー

# 環境
Windows 10 Pro
GPU: NVIDIA RTX 3090
CUDA: 11.0
Python version: 3.8.8
Pytorch version: 1.9 (記事中で <b>1.7.1</b>に変更)
# エラー
UNet++を実装する際、

```python:examin.py
import segmentation_models_pytorch
```
を実行したところ、

```
ImportError: cannot import name 'container_abcs' from 'torch._six'
```
とエラーが発生した。
# 対処法
いろいろ調べてみると、（参考→https://github.com/NVIDIA/apex/pull/1049）
Pytorchのversionがよくなかったらしい。
<b>version==1.8</b>よりも前のversionでしか```_six.py```から```container_abcs```をインポートできないらしい。
現在のversionを調べた。

```python:examin2.py
import torch
print(torch.__version__) # 1.9であった
```
これだ。versionを1.7.1に下げる。
まずは、現在の<b>Pytorch</b>と<b>segmentation_models_pytorch</b>を```pip uninstall```する。
https://pytorch.org/
の```previous```にアクセスして、自分のGPUやCUDAに合わせてpytorchを選択し、```pip install```で再インストールする。（もちろん、<b>segmentation_models_pytorch</b>も再インストール。）

```python:examin3.py
import torch
print(torch.__version__) # 1.7.1になってる！
print(torch.cuda.is_available) # True! OK!!
import segmentation_models_pytorch # OK! 2021/6/29 追加
```
ということで、何とかなりました！
# コメント
初心者なので、versionという初歩的なところでこけてしまいました。
よかったら、参考にしてみてください。

何か、コメント等ありましたら、お願いします！！
抽象化ランキング

抽象化について調べたときに参考になった記事

#第1位
https://qiita.com/yamauchi_k/items/51f62c54aba2419e5a19
#第2位
https://qiita.com/jkr_2255/items/f2a5961997a37b42ac9d
#第3位
https://qiita.com/akiyama924/items/d26545a30b94734d6ddc

いつもわかりやすい記事ありがとうございます。
Amazon Connect とは

## 勉強前イメージ

なにか Direct Connect となにか関係ある？

## 調査

### Amazon Connect とは

オムニチャネルクラウドコンタクトセンターです。
オムニチャネルとは店舗やオンライン、SNSなど何でも接点からでも買えるようになっている
問い合わせ窓口のようなもののことで、
簡単にCTI(電話統合)を構築するサービスです。

### メリット

- 設定・変更が簡単

スタッフの管理や指標の管理も簡単にGUIで出来、設定も簡単です。
なので、自社で構築・運用が出来ます。

- コストのカット

クラウド上にコールセンターを設置するので、専用機器は必要ありません。
使用分だけなので前払いも不要です。
PCの専用ソフトを使用しているのでコスト削減も可能です。

- 拡張性がある

システムと連携をとることが出来ます。
通話はs3に保存したり、lambdaと連携できたりAWSサービスとの連携が安易です。

### デメリット

- 日本では既存の電話番号の移行が出来ない

既存の電話番号が移行できなくて、
使用できても `050` `03` `0120` `0800` の4つのの番号からなので
市外局番は東京しか使用できません。

## 勉強後イメージ

全然違うかった！
コールセンターを構築するサービスかー
今の所あまり接点はないかもだけどそんなんあんねんなーくらいは覚えておこう


## 参考

- [Amazon Connect（アマゾンコネクト）とは](https://www.acrovision.jp/service/aws/?p=1476)
- [【2019年7月時点】Amazon Connectのメリット・デメリットを纏めてみました！](https://dev.classmethod.jp/articles/amazonconnect_comparison_201907/)
CloudWatch Logs に出力された AWS Glue のログを S3 にエクスポート

glueのエラーログなどをテキストベースで確認したいときの方法になります。
通常のエクスポート方法と何も変わりませんが、要はエクスポートしたいログのプレフィックスを入力すればいいだけです。

cloudwatch のマネコン上で「アクション」→「データをS3にエクスポート」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463831/635b4e57-5669-37a4-b785-4516b8c876fd.png)

先ほどの画面で検索していたログストリームのプレフィックスを入力し、出力先のS3バケットを選択して完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463831/3a807554-7a21-b3bc-42ff-d93df32552b1.png)
Gitlabテンプレート作成方法の簡易まとめ

# Gitlabテンプレートの使い方

[公式](https://docs.gitlab.com/ee/user/project/description_templates.html)みれば大丈夫ですが、簡易版をメモ

## issueのテンプレート作成

1. プロジェクトのデフォルトブランチに`.gitlab/issue_templates`ディレクトリを作成
1. ディレクトリ以下に`Bug.md`などテンプレートにしたい内容をマークダウン形式で作成

## マージリクエストのテンプレート作成

1. プロジェクトのデフォルトブランチに`.gitlab/merge_request_templates`ディレクトリを作成
1. ディレクトリ以下に`Bug.md`などテンプレートにしたい内容をマークダウン形式で作成

# Tips

[Quick actions](https://docs.gitlab.com/ee/user/project/quick_actions.html#:~:text=Quick%20actions%20are%20text%2Dbased,%2C%20merge%20requests%2C%20and%20commits.)というものがあり、テンプレートに記載しておくと実行されるので便利

例えばタイトルを変えたい場合`/title テスト`などと記載しておくと設定したタイトルに変更できる
【備忘録】Githubで最低限必要な開発フローをまとめてみた


#概要

実務開始前にGitの基本的なフロー/コマンドを復習し、備忘録として書き残す。

###前置き
記載する用語によって混乱してしまうのを防ぐため、本記事では

追跡ブランチ = ローカルリポジトリで作成/保持し、リモートリポジトリとデータのやりとりを行う際に仲介役として使用するブランチ
上流ブランチ = 追跡ブランチと紐づいているリモートリポジトリ側のブランチ
メインブランチ　= ローカルリポジトリで一番メインとなるブランチ(デフォルトだとmain)
作業ブランチ = メインブランチから分岐する各作業用のブランチ

として記載する


##開発作業の事前準備

Githubのリモートリポジトリからファイルを取得する

```
git clone https://github.com/アカウント名/リポジトリ名.git
```

プロジェクトでforkを使用する場合、githubブラウザ上でforkに必要な作業を行ってからcloneする(割愛)

git clone = リモートリポジトリをローカルリポジトリに複製すること

git fork = 他人のリポジトリを自分のアカウントのリモートリポジトリにコピーすること

つまり、forkは誰かのリポジトリに対して、何らかの追加機能の実装やバグ改修を行いたい場合使用するもの

####プロジェクト全体のリポジトリを確認

```
git branch -a        <-- -a オプションでローカル/リモートリポジトリ全て表示させ、プロジェクト全体の構成を確認 -->
```

####作業ブランチを切る

```
git checkout -b 作業ブランチ名
```
その後開発作業を開始する

##作業内容をリモートリポジトリにmergeするまで

ファイルの差分を確認する

```
git diff HEAD <-- 最新のコミット地点との差分を表示 -->
```

差分をステージ(インデックス)に追加する

```
git add ファイル名         <!-- 指定したファイルのみ追加 -->

or

git add .               <!-- ワーキングツリーのファイル全て(カレントディレクトリ配下のファイルのみ) -->

or

git add -u              <!-- ワーキングツリーのファイル全て(新規作成ファイルは無視) -->

or

git add -A              <!-- ワーキングツリーのファイル全て -->
```

ステージングされているファイルの差分を確認(commit前の２重チェック)

```
git diff --cached
```

差分をcommit

```
git commit -m "コメント"
```

コミットが正しく出来ているかログで確認

```
git log

or

git log --oneline (推奨)   <-- コミットを１行に縮小して表示 -->
```

####commit後に作業内容の間違いが見つかった場合
commit内容を訂正(<font color="red">push済みの場合は厳禁!</font>)
push済みの場合は[git revert](#git-revert)を使用

ログでコミットを確認し、どこまで修正するかを確認する
必要に応じ、戻したい地点のコミットID(or タグ名等)を控える

####git reset

```
git reset オプション名 HEAD^     <-- 直前のコミットまで戻す -->

or

git log  <--  --onelineオプションではコミットIDが一部省略されてしまうためここでは使用しない -->
git reset オプション名　戻したい地点のコミットID(タグ名)
```
オプション
--soft : commitのみ削除
--mixed : commitとaddした内容を削除
--hard : commit,addに加え作業内容も削除する(指定したコミットの状態に戻す)

最後にリモートリポジトリへpush

```
git push リモートリポジトリ名　HEAD              <-- 最新のコミットをpush -->

or

git push リモートリポジトリ名 pushするローカルブランチ名    <-- リポジトリ、ブランチ名を明示してpush -->
```

その後Githubブラウザ上でPullRequestを作成し、確認者のOKが出たら変更内容をローカルのメインブランチへ取り込む(デフォルトの場合mainブランチ)

```
git checkout メインブランチ名 
git merge 取り込みたい作業ブランチ名
```
   
補足: 任意のブランチに『 git push 』出来る設定をかける方法
リモートリポジトリに追跡ブランチがあるか確認

```
git branch -vv
--------------
feature/first-task  [追跡ブランチ名] ec41dd3 変更完了　<-- ない場合[...]の部分は表示されない -->
--------------
```

```
git push --set-upstream リモートリポジトリ名 作業ブランチ名 <-- ローカルブランチ名をもとに、リモートリポジトリに同名のブランチを作成しデフォルトの上流ブランチとして設定する -->
```
以後『 git push 』でpush出来る

#### git revert

```
git revert　 戻したい地点のコミットID(タグ名)
```

コミットIDの地点まで戻しコミットし直す処理が走る。
新しく作るコミットのコミットメッセージを入力したら、必要な修正作業を行う
完了後、リモートリポジトリへpushする

##リモートの最新情報を取り込む


追跡ブランチへ、リモートリポジトリの内容を取り込む

```:ローカルのメインディレクトリ
git fetch リモートリポジトリ名 取得する上流ブランチ名

or

git fetch -p リモートリポジトリ名 取得する上流ブランチ名 (推奨)     <-- ローカルリポジトリ と fetchしたリモートリポジトリの情報を比較し、ローカルリポジトリにしかないブランチを削除 -->

git merge リモートリポジトリ名 取り込む追跡ブランチ名
```

その後作業ブランチを切って作業開始

以上、基本的な開発フローをまとめた記事でした。
実務に入ったら実務ベースで再度書き直していきたいと思います。
インタープリタを作る その30

#概要

インタープリタを作ってみた。
avrインタープリター書いてみた。
アセンブラで数値表示bin2ascii書いてみた。

#考え方

8bitなので、０から２５５を表示する。
100で、割れるなら、割って、カウント
もう一回、やる。
カウントに0x30足して、出力。
10で、割れるなら、割って、カウント
９回、やる。
カウントに0x30足して、出力。
残った数に0x30足して、出力。
レジスタ１７、１８、１９は、破壊する。
入力は、レジスタ１６。

#サンプルコード


```
avr.ldi(16, 255)
avr.ldi(17, 0x00)
avr.ldi(19, 0x30)
avr.cpi(16, 100)
avr.brcc(2)
avr.inc(17)
avr.subi(16, 100)
avr.cpi(16, 100)
avr.brcc(2)
avr.inc(17)
avr.subi(16, 100)
avr.cpi(17, 0x00)
avr.breq(2)
avr.add(17, 19)
avr.out(0, 17)
avr.ldi(17, 0x00)
avr.ldi(18, 0x00)
avr.cpi(16, 10)
avr.brcc(2)
avr.inc(17)
avr.subi(16, 10)
avr.inc(18)
avr.cpi(18, 0x09)
avr.brne(-7)
avr.add(17, 19)
avr.out(0, 17)
avr.add(16, 19)
avr.out(0, 16)



```

#成果物

https://embed.plnkr.co/plunk/7rhAs7XcvwO66O7G


以上。
Unity Animator最適化に関して、あう可能性のある問題ーーAnimator編

##キーワード
メモリリーク
アセット作成

---
##一、メモリリーク
Q1:私たちのテストでは、Animator Controllerが掛けるアクションが比較的に多い場合、別の動きの少ないAnimator Controllerに切り替えても、タスクのアクション情報は解放しません。ヒーローをAssetBundleにパッケージし、カスタマイズされたRuntime Animator Controllerをロードして取り替えます。ヒーロー自有のRuntime Animator Controlleではすべてのアクションが掛けられます。Runtime Animator Controllerを取り替えてみた後に、前のRuntime Animator ControllerをDestroyしても、メモリが解放されていないようでした。
![1-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/9a41849a-378d-5028-87c4-4dde52cd6e37.png)
>Animator Controllerを廃棄しても中に引用したAnimationClipアセットを解放しませんから、メモリが大幅に低下することは確かにありません。下記の方式で実験をやってみることをお勧めします。
1）Animator Controllerを廃棄した後、Unity Profilerを使用してすぐに実機でTake Sampleをし、Animation ClipのRef countは0であるかどうかを確認します。
2）そうでない場合は、さらにこれらのアセットのインデックスソースを確認する必要があります。0の場合は、UnloadUnusedAssetsまたはUnloadAssetによってメモリから削除できます。

---
##二、アセット作成
Q1: Optimize Game Objectsは、以前バージョンのAnimationシステムに効果ありませんか？
>無効です。Optimize Game Objects機能は、Unity4.3から導入された機能であり、Mecanimアニメーションシステムにのみ有効です。できれば、開発チームにMecanimをプロジェクトアニメーションシステムの解決案として使用することをお勧めします。

---
Q2: UWAパフォーマンスレポートでは、Optimize GameObjectを選択してMecanimアニメーションモジュールの実行性能を向上するとお勧めされましたが、この機能がキャラーのボーンを隠しますので、このボーンに掛けるポイントは照会できません。何かこの問題を解決する方法ありませんか？
>そうです。Optimize GameObjectをオンにすると、デフォルトでアニメーションメッシュのすべてのボーンノードを非表示になさせます。しかし、「Extra Transform to Expose」を使ってプラグインを介して取りたいボーンノードを確認できます。これで、キャラクターのアニメーションモジュール性能を向上しながら、特定のキーノードを取得するための要件を満たすこともできます。
![2.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/dde7b44c-6bb6-869d-9164-16675f217026.jpeg)

---
Q3: SkinnedMeshRenderer.BakeMeshという関数は通常いつコールされますか？Instantiateの後にコールされますか？
>SkinnedMeshRenderer.BakeMeshの機能は次とおります。スキニングアニメーションのある時点の動きをスキンなしのメッシュにベイク処理します。これにより、アニメーションをカスタムサンプリング間隔でMeshシーケンスフレームのセットに変換できます。次に、アニメーションを再生するときに、最も近いサンプリングポイント（つまりメッシュ）を選択して値を与えれば良いです。これにより、ボーン更新とスキニング計算にかかる時間を節約できます。
>
この方法の利点は、計算時間をメモリに取り替えることです。シーンに１つの動画のあるモデルが大量に表示されると、効果は非常に明白です。欠点は、メモリの占用がモデル頂点数、動画合計時間、およびサンプリング間隔によって大幅に制限されることです。したがって、この方法は、頂点の数が少なく、アニメーションの合計時間が短いモデルにのみ適しています。同時に、ベイクには時間がかかるため、シーンがロードする時に完了する必要があります。
>
より典型的な適用シーンは、MOBAゲームの兵士です。

---
Q4: UWAが提供するレポートでは、Animatorが高すぎる問題が分かりました。そのうち、UIとキャラクターが別々に半分を占めます。以前は常にCullUpdateTransformsを選択していましたが、Unity公式ドキュメントを読むと、CullCompletelyが現在の状況により適用することがわかりました。CullCompletelyを選択した場合、隠れた危険性は何ですか？
>RootMotionがオンにしている場合、CullCompletelyを使用することに注意する必要があります。たとえば、キャラクターにRootMotionによって作成されたパトロールアニメーションがある場合、キャラクターが画面から出た後、アニメーションは停止し、画面に戻リません。

---
Q5: アート制作中に40本のボーンを作成しましたが、アクションで使用されたのは30本だけでした。このやり方は、30本のボーンを作って使用したことと比べて、スキニング計算が大幅に増加しますか？（Animationは圧縮処理をしました）
>理論的には増加があります。ボーン計算はすべてのボーン階段のMatrixを乗算して得るものですから、理論的にはオーバーヘッドが発生します。Optimize GameObjectオブジェクトを使用することをお勧めします。不要なCPUコストを一部減らすことができます。

---
UWA Technologyは、モバイル/VRなど様々なゲーム開発者向け、**パフォーマンス分析**と**最適化ソリューション**及び**コンサルティングサービス**を提供している会社でございます。

今なら、UWA GOTローカルツールが**15日間に無償試用**できます！！
よければ、ぜひ！

UWA公式サイト：https://jp.uwa4d.com
UWA GOT OnlineレポートDemo：https://jp.uwa4d.com/u/got/demo.html
UWA公式ブログ：https://blog.jp.uwa4d.com
【VSCode】【mypy】パッケージをimportすると発生するエラーを無視する

# 問題
自作パッケージ等をimportすると発生するエラーを無視したい。

```python
from my_class import MyClass  # Cannot find implementation or library stub for module named 'my_class'

# 実行できるのに、エラーが表示される
```

# 解決方法
作業環境に`mypy.ini`を作成して、`ignore-missing-imports = True`を設定する。
この時、セクションを`[mypy-*.*]`とすることで、全てのモジュールに対して設定できる。

## 例

```
current_dir/
   ┗━.vscode/
         ┣━ settings.json
         ┗━ mypy.ini
```

```json:settings.json
{
  "mypy.configFile": ".vscode/mypy.ini",
}

```


```ini:mypy.ini
[mypy-*.*]
ignore_missing_imports = True
```

# 解決できなかった方法
本問題についてググると「mypyの実行引数に`--ignore-missing-imports`を設定する」と出てくる。
VSCodeの設定の中に`python.linting.mypyArgs`があるので、ここに`--ignore-missing-imports`を設定すれば解決できると考えた。
しかし、この方法では解決できなかった。
![mypyArgs.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1690625/8d013e34-f727-591a-6e71-d60f07a2bb1b.png)


# 環境

```
mypy 0.910
VSCode バージョン: 1.57.1
```
ちょ、、待てよ、、NGINX/html編集できないじゃん（前編：盛大な失敗）

#はじめに
前回までにGCP上にUbuntuインスタンスを構築し、その中でDockerを動かすことに成功。
その後、Docker上でNGINXイメージをインストール。
Welcome to nginx!の文字に思わず興奮し求婚してしまうのだった。

#NGINXデフォhtmlを編集してみた
Welcome to nginx!の感動は一晩で過ぎ去り、冷静に「この表記変えてえ」と思った筆者。
htmlやCSSを遊びで書いたことがある筆者は「今の俺なら書き換えられる！」と意気込み、htmlファイルを編集しにDocker/nginx環境に忍び込むのであった。
**・・・今思えばこの過信が後の「ちょ、、待てよ、、編集できないじゃん」に繋がるのである・・・**

#実践
もう頭の中が「htmlフォルダにたどり着けばvimで編集」しかない私はまずインスタンスにアクセスし、
現在のDocker環境を再確認するのである。

```
$ sudo docker ps
```

![スクリーンショット 2021-06-22 21.11.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1578917/f8375192-712c-c0ea-9652-79d3f7b4aea9.png)

NGINXイメージを保持したコンテナ環境があることを確認。
コンテナIDが表示されているため、このIDを指定してコンテナ環境に潜り込む。

```
$ sudo docker exec -it container-id sh
```
環境に入れたら、状況確認をすべく「ls」コマンド！
![スクリーンショット 2021-06-22 21.29.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1578917/f5ffef03-1724-248a-c077-676f343e5a9e.png)

この中にNGINXがなく、不安と「？」が多発する中、
「そうだ、ドキュメントを見よう！」ということでNGINXのデプロイガイドを参照する。
参照先：https://www.nginx.com/blog/deploying-nginx-nginx-plus-docker/

こちらを見ると、nginxファイルパスは、**usr/share/nginx**であることがわかり、cdコマンドで移動していく。
するとhtmlの文字を発見。
![スクリーンショット 2021-06-22 21.30.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1578917/854c6e1d-4a66-7320-70f9-7633e66bce61.png)

**ｷﾀ – .∵･(ﾟ∀ﾟ)･∵. – ｯ!!**
よし、この中にあるファイルを編集できれば、「Welcome to nginx!」を書き換えられる！！
さらにフォルダに潜り込んで、index.htmlに辿り着こう。
![スクリーンショット 2021-06-22 21.31.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1578917/51266a99-dede-dabf-8c94-93dbcb5b0ce1.png)

ここが私の聖地、index.html
さあ、開け、開くのだ！必殺編集「Vim！！！！！」　

```
$ vim index.html
```

![スクリーンショット 2021-06-22 21.33.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1578917/df5ab8ab-1111-fa43-f2b3-1063f77bdfb4.png)

**（ﾟ〇ﾟ；）なぬ？？？？？**
ああ、なるほど、権限問題だよね、きっと、、sudoで再度入れたら大丈夫でしょ（ﾟ〇ﾟ；）

```
$ sudo vim index.html
```

![スクリーンショット 2021-06-22 21.34.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1578917/14610309-bc3c-39f8-175f-6446a4a755a4.png)


**(ﾟДﾟ≡ﾟДﾟ)ｴｯﾅﾆﾅﾆ?**
ちょ、、待てよ、、編集できないじゃん。
公式見てなかったけど、正規の方法ではないのだろうか。。
意気消沈しながら公式を確認しに行くのであった。

**後編へと続く**

#次回
ちょ、、待てよ、、NGINX/html編集できるじゃん（後編：成功の架け橋）
Windows10 PC上の Salome-Meca2018 で嵌った話

# はじめに
Salome-Mecaによる構造解析 入門と初級 を受講することになりましたので、[Windows10 PC上へ Salome-Meca2018を インストール](https://qiita.com/superrino130/items/a921fe864a0e20f7a1ae)して操作したところ嵌ってしましました。
# 失敗
![20210625a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538241/de1f507a-cfcd-abc3-c5e7-5104803861c1.png)
ぐぬぬ

とにかく解析が失敗ばかり。
グーグル先生によりますと、[こちらの方](https://www.noboyu.com/install-salome-meca-2019/) も苦労された様子。
~~マイナーな~~ オープンソースはこういうところが怖いですね。
# 成功
![20210625b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538241/180d3653-f5ff-6086-fec6-7888872f1563.png)
とにかくヨシ！

やはり、頼りになる先輩諸氏がいると助かります。
# 解決？
失敗：sm-2018-w64-0-3.zip　からインストール
成功：SetupSalome-Meca-2018-0.3sx1.exe　からインストール
# まとめ
+ OpenCAE さんありがとう
+ Salome-Meca さんありがとう
+ F先生 ありがとう
【OpenWeatherMap】天気予報アプリ（React × TypeScript）

https://ichi.pro/react-to-javascript-o-shiyoshite-tenki-apuri-o-sakuseisuru-250340153444055

こちら↑↑の記事を参考にしました。

```Weather.tsx
import React, { useState } from "react";
const APIKEY = process.env.REACT_APP_API_OPEN_WEATHER_API_KEY;

const Weathre = () => {
  const [city, setCity] = useState("");
  const [result, setResult] = useState<any>({});
  const getWeather = async (e) => {
    e.preventDefault();
    if (!city) {
      return;
    }
    const res = await fetch(
      `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${APIKEY}`
    );
    const { main } = await res.json();
    setResult(main);
  };
  return (
    <div>
      <form onSubmit={getWeather}>
        <div>
          <label>city</label>
          <input value={city} onChange={(e) => setCity(e.target.value)} />
        </div>
        <button type="submit">get weather</button>
      </form>
      {result && (
        <div>
          <p>feels like: {result.feels_like}</p>
          <p>humidity: {result.humidity}</p>
          <p>pressure: {result.pressure}</p>
          <p>temperature: {result.temp}</p>
          <p>high: {result.temp_max}</p>
          <p>low: {result.temp_min}</p>
        </div>
      )}
    </div>
  );
}

export default Weather;
```

`API_KEY`は`.env`ファイルにて管理しています。
[プリンシプルオブプログラミング] UNIX思想

# UNIX思想
UNIX思想とは、UNIXの文化で育まれたプログラミングの経験に基づいた実践的な技の集合体です。
以下の17個の原則があります。

- モジュール化原則
- 明確性の原則
- 分離の原則
- 単純性の原則
- 倹約の原則
- 透明性の原則
- 安定性の原則
- 表現性の原則
- 驚き最小の原則
- 沈黙の原則
- 修復の原則
- 経済性の原則
- 生成の原則
- 最適化の原則
- 多様性の原則
- 拡張性の原則

## UNIXの設計判断の正しさ
1969年にUNIXは生まれ、今なお使われ続けているこのソフトウェアのプログラミングから生まれた思想は、UNIXの堅牢さを見れば分かるとおり、このような設計判断は正しいことがわかります。

### モジュール化の原則

- 肥大したモジュールは作らない
    - 控えめなモジュールを心がける
- クリーンなインターフェースを持つ
- モジュールの入り口を狭くする
    - 余分な他のモジュールと関係を持たない

### 明確性の原則

- 巧妙なコードより、明確なコード
    - パフォーマンスではなく読みやすさ
- 明確なコードでなければ改善する

### 組み立て部品の原則

- フィルターにして組み立てる
    - ソフトウェアは、他のソフトウェアと組み合わせられるように作成する
- 独立性を高くし、相互接続を簡単にする

### 分離の原則

- メカニズムからポリシーを話す
    - メカニズム
        - ソフトウェアに依存しない独立した部分
    - ポリシー
        - ソフトウェアに依存した部分

### 単純性の法則

- コードをシンプルにする
    - コードは自然状態で複雑になる
        - 技術を誇示しようとするプログラマの気持ち
        - 機能に対する外部からの要求
- シンプルなコードを美しいとする文化を育てる

### 倹約の原則

- 大きなコードは書かない
    - 大きなコードは制御不能
- コードは継ぎ足し続けない

### 透明性の原則

- ソフトウェア動作の見える化
    - 透明性
        - ソフトウェアの動作を見てすぐに動作内容が理解出来ること
    - 開示性
        - ソフトウェアの内部状態を監視、表示出来ること
- デバッグが簡単に行える状態にする

### 安定性の原則

- ソフトウェアを安定させる
    - 堅牢なコードを書く
        - 透明性と単純性を保つコードを書く

### 表現性の原則

- 情報はデータを寄せて表現する
    - データはロジックよりも御しやすい
- 複雑さをデータに寄せる

### 驚き最小の原則

- 予想通りのコードやインタフェースを作成する
    - 学習コストが下がる
- ユーザーの既知を活用した表現をする

### 沈黙の原則

- 重要な情報のみを表示する
- 不必要なデータは出力しない

### 修復の原則

- エラーを起こした時には処理を停止させる
- エラー通知はすぐに気づくように派手にする

### 経済性の原則

- プログラマの時間の使い方
    - プログラマに投資する
        - ハードウェアやソフトウェアなど
        - インターネット環境
### 生成の原則

- 次のコードが書きやすいようなコードを書く
- 生成コードは安価で高品質
- コードジェネレータを作成する

### 最適化の原則

- 早く動くコードより正しいコードを書く
- 動くプロトタイプを作る
- 正しい動作を確定させて早くする

### 多様性の原則

- 選択の多様性を受容する
- 正しい方法などは場面によって変わることを意識する
- よりよいやり方を求め続ける

### 拡張性の原則

- 拡張できる設計にしておく
- ソフトウェアは成長していく
- プラガブルな設計をする
    - ブラガブル　接続可能
[プリンシプルオブプログラミング] UNIX哲学

# UNIX哲学
UNIX開発の根底にある哲学です。
9個の定理でまとめられています。

- 小は美なり
- 一つ一つ仕事
- 速行プロトコル
- 効率性より移植性
- データはテキスト
- レバレッジ・ソフトウェア
- シェルスクリプト活用
- 対話インターフェース回避
- フィルタ化

## 小は美なり

- 小さいソフトウェアは扱いやすく、美しい
    - 理解しやすい
    - 保守がしやすい
    - マシンリソースを食わない
  
## １つ１仕事

- ソフトウェアをピュアに保つ
- １つのソフトウェアに１つの仕事を集中して行わせる

## 速行プロトタイプ

- できるだけ早くプロトタイプを作成する
    - プロトタイプで確度を高める
        - 方針を決めることでコードを作成しやすくする
        - 要件不備を早い段階で見つけやすい
   
## 効率性より移植性

- 効率性より移植性の高いコードを書く
- ソフトウェアの価値を持続させるコードを書く
- ハードウェアに依存しない

## データはテキスト

- バイナリで持つよりテキストファイルで持つ
    - バイナリでは理解しづらく扱いづらい
- テキストファイルは万能
    - 標準規格を使うようにする
        - json,xml,yml...

## レバレッジ・ソフトウェア

- ソフトウェアを梃子の原理のように扱う
    - 少ない労力で巨大な成果
- 手作業を自動化する


## シェルスクリプト活用

- シェルスクリプトでソフトウェアを接着する
    - シェルスクリプトをグルー言語として活用する

## 対話インターフェイス回避

- ユーザーの入力を待つような処理を避ける

## フィルタ化

- ソフトウェアをフィルターとして設計する
    - ソフトウェアは入出力を扱うフィルター
アプリ名やサブタイトルなどで使えない単語


## 再びリジェクト
前回に引き続き、別のアプリを公開しようと思い、申請したところ、リジェクトされました。
早速ですが、リジェクト理由は以下の通りです。
### リジェクト理由
> Guideline 5.2.5 - Legal - Intellectual Property
Your app does not comply with the Guidelines for Using Apple's Trademarks and Copyrights. Specifically, your app includes:
- iPhone in the subtitle

簡単に言うと、「アプリのサブタイトルに、Appleが商標登録しているiPhoneという単語が含まれているから」という理由でした。
##### App Storeに公開するんだからよくない？ 
っていうのが僕の意見なんですが、Apple的にはアウトみたいです。
ではでは、実際にどのような単語がいけないのか見ていきましょう。

## アプリ名やサブタイトルなどで使えない単語
以下の単語は単体で使えないだけでなく、```Appletree```のように単語を組み合わしたり、Jackintoshのようにちょっともじったりしてもリジェクト対象です。
ディズニーにしろ、Appleにしろ、アメリカの企業は商標や著作権に関してかなりうるさい印象です。

### 会社名
もちろん、```Apple```という会社名を使うと、リジェクトされます。
### 製品名
```iPad``` ```iPhone``` ```iMac``` ```Mac Book```などの製品名を入れるとリジェクトされます。
今回僕は、サブタイトルに「iPhoneで管理できる」のように真っ当な入れ方をしていてもダメでした。
### サービス名
サービス名もダメみたいなので、```iTunes ``` ```App Store``` ```Apple Music```などもリジェクト対象です。

## 他にリジェクトされるApple関連のもの
会社名やサービス名などの単語の使用以外にも、Appleは禁止にしているものがあります。
### ロゴやシンボル
これは当たり前ですが、許可なしにAppleのロゴやシンボルを使うことは禁止です。
ただし、Appleから正式に許可されているものはOKです。
### 模倣したもの
Apple関連のものを模倣してもダメです。
具体的には、ロゴ、書体、webサイトのデザインなど、Appleがこだわっている部分を模倣するとダメなようです。

## 最後に
Appleが商標や著作権に関して、禁止にしていることはまだまだありますが、僕みたいな初心者が気にせずやってしまうのはこの辺だと思います。
もしもっと詳しく見たい人は以下の記事から確認してみてください。
全て英語の記事ですが、元の英語がしっかりしているからか、Google翻訳しても十分読めます。
[Guidelines for Using Apple Trademarks and Copyrights](https://www.apple.com/legal/intellectual-property/guidelinesfor3rdparties.html)

### 正直、最初の申請ってリジェクトされることを前提にして出した方が良い？
HTMLのa要素にping属性...？

# W3CがHTMLの主導権を失う
少し前ですが、これまでW3Cが策定・勧告してきたHTMLがついに終了し、これからはWHATWG（Google、Apple、Microsoft、Mozillaが主導するブラウザベンダーの組織）が主導するHTML Living StandardがHTMLの標準になりました。

確かにW3Cは長い間HTML標準化の任務を担ってきましたが、W3Cはブラウザを開発しているわけはないため、W3Cの勧告を具現化しているのは実際は各ブラウザベンダーでした。どうやらこのブラウザベンダー各社が「W3Cはわかってねえ」となったらしくWHATWGを立ち上げてW3Cに圧力をかけ、そこで生まれたのが2014年勧告のHTML5でした。

このまま良い感じに進むかと思いきや、W3C側がHTML5に独自の要素を詰め込み始めたことで再びWHATWGが若干キレてしまい、改めてW3Cの主導権を事実上取り上げたような状態のようです。W3Cがいくら口先で規格を決めていようと、ブラウザ側でそれらがパースできなければ意味がないので明らかに力関係はWHATWGのほうが強いです。今後はWHATWGが主導しているHTML Living Standard([https://html.spec.whatwg.org/multipage/ ](https://html.spec.whatwg.org/multipage/))がHTMLの標準になります。

ただしHTML5がなくなるのかというとそうではなく、そもそも公式見解として「端的に言えば、HTML Living Standard = HTML5である」と書かれています。「より厳密には、HTML5はWebの根幹を担う技術のバズワードであり、ほとんどはWHATWGが開発している」とも書かれています。要は広義にはHTML5はWeb技術そのものであり、特定の製品や規格ではないと。
>1.2 Is this HTML5?
This section is non-normative.
In short: Yes.
In more length: the term "HTML5" is widely used as a buzzword to refer to modern web technologies, many of which (though by no means all) are developed at the WHATWG. This document is one such; others are available from the WHATWG Standards overview.


# HTML Living StandardとHTML5.2は何か違う？
というわけで気になったのですが、HTML Living StandardとW3C最後のHTMLであるHTML5.2（便宜上そう呼びます）は何か差分があるのかリサーチしてみたところ、面白いものを見つけました。

## a要素にping属性
HTML Living Standardではa要素にping属性が定義されています。
公式ドキュメント：https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-a-element

```html
<a href="fugafuga.example/index.html" ping="hogehoge.example/log">Click me!</a>
```
ページ遷移とは別にアクセスログを取りたい時などに活用する意図だと思われますが、ドキュメントに正確に書かれていないので憶測になります。確かに同様のことをするのであれば非同期通信をするか、アクセスログを取ってからページ遷移をする等の処理が必要になるため、便利といえば便利なのでしょう。pingされる側のWebサーバを立てて動かしてみたところ、以下のようなアクセスログが取れました。GETではなくPOST送信されているようです。

```
[25/Jun/2021:05:25:14 +0000] "POST / HTTP/1.1" 200 3380 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36"
```

# 今後も...
WHATWG管轄になったことで、これまでのようにある程度更新が溜まってからナンバリングタイトルとして勧告される流れではなく、各要素や機能単位で徐々にリリースされていく、まさに"Living"な形式になっていくと思われます。したがってこれまでのような新バージョン勧告時だけではなく、継続的に最新情報を取り入れるようにしていく必要があると考えられます。
YouTube Data APIで取得したデータを閲覧できるwebアプリケーションをRailsで作った話

休日とかに、ちょこちょこプログラムを書いていたら個人的に使えるレベルまでになったので、ご紹介しようと思います(自己満)
本業はC#とwinformで基幹システム作ってるんですが、webの方はまともに触ったことがなかったのでいい勉強になった。

# 環境
+ ruby 2.6.6
+ Rails 5.2.6
+ Python 3.7.9
+ MySQL 8.0.25


# 何を作ったか
まず構成図はこちら
![dev.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469729/769f731d-f063-a792-a848-2a281a16707b.png)

具体的にそれぞれが何をしているかというと

+ python → データ取得のバッチとして使用

開発環境はwindowsなので、タスクスケジューラーで.batファイルを毎日午前4時に実行してます。
データの取得はYouTube Data APIを使用、取得するデータは対象チャンネルの登録者, 総再生数, 投稿動画一覧、取得した投稿動画一覧をもとに各動画の再生数を取得しそれらをDBへ格納。

+ Ruby on Rails → YouTube Data APIから取得してきたデータの閲覧に使用

スクリーンショットのように、テーブルへ吐き出しています。

データ取得対象チャンネル一覧
![channels.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469729/0a15eb98-9af5-8691-3172-255f48068ede.png)

チャンネル情報履歴
![channelInfo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469729/4aef3d8f-61d5-c9cc-d0cd-fb69bec18e17.png)

投稿動画一覧
![VideoList.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469729/d4390953-a10c-03fd-9c2b-120b5f29033b.png)

動画情報履歴
![VideoInfo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469729/29e9020e-38b2-d7ea-072a-ea6d196e959f.png)

# ハマった箇所
Rubyをまともに勉強したことない状態でRailsの開発を始めたため、RubyとRailsどっちも調べながらだったので微妙に時間を食った、Ruby自体は他の言語を扱えるのだったらそんなに学習コスト高くないと思うので、基礎くらいは頭に入れておけばよかったと思う。Rubyのエラー(文法とか)なのかRailsのエラーなのかわからんくなったりした。

あとMVCも、「MVCね、ふーん」みたいな具体的なことはなにも答えられない知識しかなかったので設計にすごい悩んだ、てか今も悩んでる。コントローラーとモデルどっちに書けばいいかあやふやなのでご教授願いたい。

# 今後追加したい機能
+ 対象チャンネルの追加削除<br>現在、対象チャンネルはDBへ直に書きに行ってるので、編集機能が欲しい。

+ データ取得に使用するAPIキーを選べるようにする<br>YoutubeDataAPIはデータ取得にquotaなるリソースを使用するんですが、デフォルトだと10000quota/日しか割り当てられないので、複数のチャンネルからデータを取得するとquotaが枯渇してデータが途中で切れてしまう。<br>なのでチャンネルごとに使用するAPIキーを編集できるようにしたい。

+ データの表示のバリエーションを増やす<br>総再生数の前日比を表示したり、新着動画はこれですよ、みたいなデータとして見やすくなるよう表示周りは拡張したいですね。

# あとがき
初めてqitaに投稿するんですが、書き終わった今改めて読み返してみると、やったタスクの整理とToDoリスト書いただけになったような...
それはさておき、最終的にはWebサービスとして公開したいと思っていますので、フィードバックやサービスとして欲しい機能などがあればコメントしていただけると幸いです。
今後もちょくちょく進捗を報告したいと思いますので、よろしくお願いいたします。
文字列内に特定の単語以外が含まれているかどうかの確認[js]

タグを指定できるが、特定の単語しか含まれていない場合は、
別操作をしたいということでロジックで悩んだので、確認

対象の文字列を削除しても文字が残るかどうかを基準に判断。

```
const tag = '<ignore>■</ignore>'
const onlyReplacementText = [`${tag}`];
const onlyReplacementText2 =[`${tag}${tag}`];
const onlyReplacementText3 =[
  `${tag}`,
  `${tag}`
];
const withReplaceMeantText = [`${tag}を食べたいです。`];
const withReplaceMeantText2 = [`美味しい${tag}`];
const withReplaceMeantText3 =[
  `${tag},${tag}`,
  `${tag}`,
  `${tag}`
];

const withReplaceMeantText4 =[
  `${tag},${tag}があるみたいです。`,
];


const withReplaceMeantText5 =[
  'こんにちは',
];

const ignoreTag = '<ignore>.</ignore>';

const hasTranslateText = (array) => {
  const result = array.map(sentence => sentence.replace(/<ignore>.<\/ignore>/g, "")).filter(e => e !== '');
  return result.length > 0
};

console.debug('1Expect false:',hasTranslateText(onlyReplacementText));
console.debug('2Expect false:',hasTranslateText(onlyReplacementText2));
console.debug('3Expect false:',hasTranslateText(onlyReplacementText3));

console.debug('1Expect true:',hasTranslateText(withReplaceMeantText));
console.debug('2Expect true:',hasTranslateText(withReplaceMeantText2));
console.debug('3Expect true:',hasTranslateText(withReplaceMeantText3));
console.debug('4Expect true:',hasTranslateText(withReplaceMeantText4));
console.debug('5Expect true:',hasTranslateText(withReplaceMeantText5));
```

追記

@947lj さんからより簡潔な下記の書き方を教えて頂きました。
ありがとうございます。




```
const hasTranslateText = (array) => {
  return array.join('').replace(/<ignore>.<\/ignore>/g, '') !== '';
};
```



失敗談：
`String.prototype.match()`
を最初使おうとして失敗したのも記念に(?)残しておきます

```
// タグ+文章
const regex = new RegExp(`${ignoreTag}.`, 'g');
// 文章＋タグ
const regex2 = new RegExp(`.${ignoreTag}`, 'g');
// タグ＋タグ(タグの連続)
const regex3 = new RegExp(`${ignoreTag}${ignoreTag}`, 'g');


const hasTranslateText = (array) => {
  let hasTranslateText = true;
  for (const sentence of array) {
    let isTag = false;
    if (sentence.match(regex) || sentence.match(regex2)) {
      isTag = false;
    }

    if (sentence.match(regex3)) {
      isTag = true;
    }

    if (isTag === true) {
      hasTranslateText = false;
    }
  }
  return hasTranslateText;
};

```




にしても全くもって上手く行かなかったのですが、
戒めのために残しておきます。


もし、より良い方法がございましたら是非ともご提案いただければ幸です。
docker イメージの作成（コンテナをイメージに変換）

# 背景
環境構築を楽にするために、docker の勉強をしております。
今回はコンテナをイメージに変換することでイメージを作成する方法を手順として残します。

# 環境
Amazon Linux release 2 (Karoo)
Docker version 20.10.4

# 手順
## docker インストール
以下の記事に手順を残してありますので、ご参照ください。

https://qiita.com/hamburg-love/items/6b5e5091764753b5e229

## ベースにするイメージをダウンロード
まずは特に何もインストールされていないイメージからコンテナを作成します。
ベースにするイメージは使い慣れている centos を使用します。

```
sudo docker pull centos:centos7
sudo docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
centos       centos7   8652b9f0cb4c   7 months ago   204MB
```

## ベースコンテナ作成
先ほどダウンロードしたイメージからコンテナを作成します。

```
sudo docker run -tid --name httpd centos:centos7 /bin/bash
sudo docker ps
CONTAINER ID   IMAGE            COMMAND       CREATED          STATUS         PORTS     NAMES
d53dfa8d379d   centos:centos7   "/bin/bash"   10 seconds ago   Up 9 seconds             httpd
```

コンテナの中に入ります。

```
sudo docker exec -ti httpd bash
```

コンテナの中で今回は試しに Apache をインストールします。

```
yum install -y httpd
```

インストール後、`exit`でコンテナから出ます。

## イメージ作成
作成したコンテナを元にイメージを作成します。

```
sudo docker commit httpd new-httpd

sudo docker images
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
new-httpd    latest    b8f1cc489fd4   3 minutes ago   360MB
```

ベースのコンテナを削除します。

```
sudo docker stop httpd
sudo docker rm httpd
```

これで完成です。

## 確認
作成したイメージからコンテナを作成します。
htmlファイルを配置するディレクトリを作って、ドキュメントルートにマウントします。

```
sudo docker run -d -p 80:80 -v "/opt/app/:/var/www/html/" --name newHttpd new-httpd /usr/sbin/httpd -DFOREGROUND
```

URLをブラウザに入力して、配置したhtmlファイルが表示されていれば大丈夫です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184532/dfa49f17-6701-cfec-8e2c-f176ff3dfca5.png)

# 最後に
この程度であれば、DockerFile を作った方が早いと思いますが、ミドルウェアに色々設定したい場合は今回の方法もありかもしれません。

しかし、DockerFile の方が何をしたのか一目で分かるのと変更点もわかりやすいので、DockerFile で作成する方法をおすすめします。

DockerFile からイメージ作成する方法は別記事にまとめましたので、以下をご参照ください。

https://qiita.com/hamburg-love/items/a90405c385bf78c2ca46

最後まで読んでいただきありがとうございました。
ダイエット＋食品管理アプリ構築の道程（３）

```rb:FormObject
class CookingFoodstuff
  include ActiveModel::Model
    
end
```
####include ActiveMedel::Modelとは

モジュールをincludeするのとクラスを継承する[クラスを引き継ぎたい＝クラスの継承]
*車の設計図のような概念で、インスタンスを作るためにあるものがクラス

```terminal
モデル名の調査/変換/翻訳/バリデーションが使えるようになります。
また、ActiveModel::Modelをincludeするクラスでは、Active Recordの場合と同様に
form_forやrenderなどのAction Viewヘルパーメソッドを使えるようになります。 
（Active Model の基礎 - Rails ガイド）
```

####attr_accessorとは
    
まずアトリビュート 【attribute】 attr / 属性
アトリビュートとは、特性、特質、性質、～に要因を求める、～に帰する、などの意味を持つ英単語。ITの分野では対象の性質や設定などを示す付加情報などを指すことが多く、「属性」と訳される。


```rb
             属性名　　　　　　       型
  attribute :title,        :string
  attribute :body,         :string
  attribute :draft,        :boolean, default: false
  attribute :published_at, :datetime
  attribute :tags
  *tagは配列なので型はなし
```

####インスタンスメソッドattributes
「属性名 => 値」のハッシュが取り出せます

```rb
form.attributes
#=> {"title"=>"Foo", "body"=>"bar", "draft"=>false, "published_at"=>2019-12-15 15:40:00 +0900, "tags"=>["Ruby", "Rails"]}
```

####インスタンスメソッドまたはクラスメソッドのattribute_names
属性一覧が取り出せます（Rails 6で追加）。

```rb
form.attribute_names
#=> ["title", "body", "draft", "published_at", "tags"]
```

以上のことから

```rb:db/migrate/20160304060143_create_users.rb
class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :name
      t.string :description

      t.timestamps null: false
    end
  end
end
```

RubyはDBもなく、フレームワークでないただの言語なのでattributeはクラス内で
扱う（変数の）属性名（カラム名）とデータの型を決定している。

Railsではmigrationとしてデータの属性名、型、Nullの制約やデフォルト値を決めたりできます。
しかも事前に決めておき、保存前のバリデーション（保存情報の制約）を行う機能もありとても便利です。


#####インスタンスって何でしたっけ？
クラスから生成されたオブジェクトをインスタンスと呼びます。クラスとはなんだったでしょうか？クラスはいわばインスタンスを作るための型です。

```rb
p = User.new
```

newでインスタンス化されたオブジェクトは、厳密には無効データであってもエラーは出力されない。これは、createやsaveメソッドなどによってオブジェクトが保存されるときのみ、null:falseなどのバリデーションが実行されるためです。

```rb
 User.new
=> #<User id: nil, name: nil, email: nil, created_at: nil, updated_at: nil>
```

####あらためてattr_accessorとは
コンソールで以下を実行すると

```rb
class User
  attr_accessor :name, :description

  def print_upcase
    puts name.upcase
  end
end
```

```rb
user = User.new
=> #<User:0x007fb7f9bbd2b8>

user.name = "hassan"
=> "hassan"

user.description = "将来有望"
=> "将来有望"

user.name = true
=> true　　　＊更新も可能

user.name = 12
=> 12　　　　＊更新も可能

user.name = "hassan"
=> "hassan"　　　＊更新も可能

user.print_upcase
=> HASSAN
```
migrationみたいに事前に設定していいないのいで型は動的（可変）。

###attrは略語で元はattributeです。

attr_accessorで指定したフィールドはform_with内で使用できるフィールド名になります。
自作PCにwsl2で開発環境を整える～ruby導入編～

# Abstract
[前回](https://qiita.com/SatoshiNonomura/items/93f05aaf0113bb714786)anyenvを導入しました。
次は、Railsを動かすため、rbenvを入れてrubyを導入します。

# rbenvの導入
```sh
anyenv install rbenv
```
必要であればPATHを通してください。
前回紹介した方法でanyenvを導入すればPATHを通す必要はないはずです。

## 導入の確認
```sh
rbenv -v
```

## インストール可能なものの確認
```sh
rbenv install --list-all
```
allをつけないとstableな最新版しか出てきません。

# ruby導入
それではrubyを入れます。
結論から言うと、ここで`rbenv install <VERSION>`をしても、エラーを吐くはずです。
まずは必要なパッケージをインストールします。

## C Compiler
C/C++のコンパイラがないと以下のようなエラーを吐きます。

```nginx
user@host:<directory>$ rbenv install 3.0.0
Downloading ruby-3.0.0.tar.gz...
-> https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0.tar.gz
Installing ruby-3.0.0...

BUILD FAILED (Ubuntu 20.04 using ruby-build 20210611-1-g1b477ae)

Inspect or clean up the working tree at /tmp/ruby-build.20210625134041.169.hZmhg7
Results logged to /tmp/ruby-build.20210625134041.169.log

Last 10 log lines:
checking target system type... x86_64-pc-linux-gnu
checking for gcc... no
checking for clang... no
checking for cc... no
checking for gcc... no
checking for cc... no
checking for cl.exe... no
configure: error: in `/tmp/ruby-build.20210625134041.169.hZmhg7/ruby-3.0.0':
configure: error: no acceptable C compiler found in $PATH
See `config.log' for more details
```

というわけで、rubyのインストールのために必要なC/C++のコンパイラを準備します。
おすすめはbuild-essentialです。

```sh
sudo apt install build-essential
```

## libssl-devとzlib1g-dev
ここで実行すると、以下のエラーが出ました。

```nginx
user@host:<direcotry>$ rbenv install 3.0.0
Downloading ruby-3.0.0.tar.gz...
-> https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0.tar.gz
Installing ruby-3.0.0...

BUILD FAILED (Ubuntu 20.04 using ruby-build 20210611-1-g1b477ae)

Inspect or clean up the working tree at /tmp/ruby-build.20210625134444.5800.6HNitQ
Results logged to /tmp/ruby-build.20210625134444.5800.log

Last 10 log lines:
The Ruby openssl extension was not compiled.
The Ruby zlib extension was not compiled.
ERROR: Ruby install aborted due to missing extensions
Try running `apt-get install -y libssl-dev zlib1g-dev` to fetch missing dependencies.

Configure options used:
  --prefix=/home/ennean/.anyenv/envs/rbenv/versions/3.0.0
  --enable-shared
  LDFLAGS=-L/home/ennean/.anyenv/envs/rbenv/versions/3.0.0/lib
  CPPFLAGS=-I/home/ennean/.anyenv/envs/rbenv/versions/3.0.0/include
```

で、入れろと言われたので入れます。

```sh
sudo apt-get install -y libssl-dev zlib1g-dev
```

## ruby本体
ここまで来れば、やっと本体を導入できるはずです。

```sh
rbenv install 3.0.0
rbenv local 3.0.0
```

## 確認
```sh
ruby -v
```

バージョンが返ってきたら導入成功です。

# バックナンバーと次回予告
[初回：WSL導入編](https://qiita.com/SatoshiNonomura/items/1b23107b2ab9c28b5f2a)
[前回：anyenv導入編](https://qiita.com/SatoshiNonomura/items/93f05aaf0113bb714786)
[次回：Postgre SQL導入編](https://qiita.com/SatoshiNonomura/items/80a1a606f0750f3dcd11)

# 参考
[configure: error: no acceptable C compiler found in $PATHエラー解消方法](https://blue-bear.jp/kb/configure-error-no-acceptable-c-compiler-found-in-path%E3%82%A8%E3%83%A9%E3%83%BC%E8%A7%A3%E6%B6%88%E6%96%B9%E6%B3%95/)
[rbenvでrubyをインストールできなかった。 @mnbdyunan ](https://qiita.com/mnbdyunan/items/cff70fc747e5d6761ea3)
[rbenvでRubyをインストールする @ryoyakawai ](https://qiita.com/ryoyakawai/items/f06a59aeea2bc86a0a46)
yarn installのパッケージ解決の挙動(の予想)

以下確認は取れていない。予想されることをメモる。


## 背景

yarn install時に、grpcパッケージのインストールでこけた。
https://qiita.com/koinori/items/18dd11bae20e008a8532 に従って対応することで以下のように対処できた。


(1) `yarn install`を走らせ、grpc のインストールでこけることを確認した。この時のnodeはv14.17.1 で、エラー内容は以下。

```
Error: Failed to load /Users/xxxxxx/repos2/visit-api-node/node_modules/grpc/src/node/extension_binary/node-v88-darwin-x64-unknown/grpc_node.node.
Cannot find module '/Users/xxxxxx/repos2/visit-api-node/node_modules/grpc/src/node/extension_binary/node-v88-darwin-x64-unknown/grpc_node.node'
```

(2) nvmで、nodeを v8.17.0に切り替える
(3) `sudo npm install -g --unsafe-perm=true grpc@1.10.1`を実行し、**グローバルに**パッケージをインストール。
(4) nvmで、nodeをv14.17.1に戻す
(5) `yarn install`する。こけなくなった。


## 考察

- nodeのバージョンを切り替えると、使用されるnpmのversionも切り替えられる
    - まあ、当たり前。
- npm のversionによって、同じパッケージがインストールできる場合とできない場合がある。
- 同一のパッケージが、違うnode(npm?)のバージョンから使用されることがある。
    - まあ、当たり前。
- グローバルに特定のパッケージが存在するならば、`yarn install`を実行しても、プロジェクト内のnode_modulesディレクトリ内にインストールされない。
- `yarn start`を実行して際、プロジェクト内のnode_modulesにあるパッケージが存在しなかったら、グローバルに存在するかを見にいく。存在すればそれを使用する。
    - プロジェクト内に存在したら、それを優先して使う？？？

ここまで書いて、プロジェクトの設定依存なのかな、と思ったりもした。わからん。
rails ajax通信のアプリを作成していたときにSweetalert2 : Unknown parameter type

https://sweetalert2.github.io/

https://keizokuma.com/sweetalert2-dialog/

要はjsでアラートを表示してくれるライブラリです。
導入方法も簡単で、ajaxアプリにはもってこいです。

で、実際にサーバーを立ち上げると、

```
Sweetalert2 : Unknown parameter type
```

というアラートが。

https://gitmemory.com/issue/sweetalert2/sweetalert2/1803/550996865

この記事を見るとtypeというのは古いバージョンで今はtypeは使用しておらず、iconにする必要があるようです。

```app/assets/javascripts/posts.js.erb
        swal.fire({
          icon: 'success',

```

このように記述して完了