OmniAICreator/Qiita-1.07M huggingface dataset:
iOS端末でWiFi接続パスワードを共有する3つの方法

## はじめに

この記事では、macOSおよびiOS端末でWiFiの接続パスワードを共有する方法を紹介します。

このような場合にお役立てください。

- 職場、学校、家庭などで多くの端末にWiFiパスワードを設定する必要がある
- WiFi設定を配布するプログラムを製作する

個別の方法を解説する記事はありましたが、方法をまとめて比較している記事がありませんでした。
どの方法がどのような場面に適しているのか、比較検討していただければ幸いです。

### 想定する環境

この記事は以下の環境を想定しています。

-   iOS 13.5
-   macOS 10.15

記事を読む前に、お手元の環境をご確認ください。

## 方法1 : iCloudキーチェーン

同一のAppleIDでサインインしている端末同士なら、iCloudキーチェーンで接続パスワードを共有できます。

[Apple - iCloud キーチェーンを設定する](https://support.apple.com/ja-jp/HT204085)

> iCloud キーチェーンには、クレジットカード番号と有効期限日 (セキュリティコードの保存や自動入力はされません)、パスワードとユーザ名、Wi-Fiのパスワード、インターネットアカウントなどが保存されます。

### 使いどころ

自分自身が所有する複数の端末で、接続パスワードを共有および更新するのに適しています。

### 共有の手順

iCloudキーチェーンで接続パスワードを共有している場合、WiFiアクセスポイントに接続するだけでパスワードが自動入力されます。特別な手順は必要ありません。

### 注意点

iOSの設定からネットワーク設定を削除すると、iCloudキーチェーン上の接続パスワードも同時に削除されます。パスワードを共有している端末で再設定が必要になるのでお気をつけください。

![](https://www.evernote.com/l/AAkbbb8yTZBHRY1oz9w3dsgHP16dv1sIKscB/image.jpg)

## 方法2 : Bluetooth

一定の条件を満たしたiOS端末同士なら、Bluetoothで接続パスワードを共有できます。

[Apple - iPhone、iPad、iPod touchでWi-Fiのパスワードを共有する方法](https://support.apple.com/ja-jp/HT209368)

### 使いどころ

家族、友人、職場などで限定した相手に接続パスワードを共有、配布するのに適しています。

### 準備

パスワードを送信する端末を`端末A`、受信する端末を`端末B`と呼びます。それぞれの端末で以下の準備が必要です。

#### 端末ABで共通

-   AppleIDにサインインしている（インターネットはオフラインでもOK）
-   WiFiがONになっている
-   BluetoothがONになっている
-   インターネット共有がOFFになっている
-   `連絡先`アプリに相手のAppleIDと紐付けられたメールアドレスが登録されている

#### 端末A

-   画面ロックが解除されている
-   共有したいWiFiアクセスポイントに接続している

#### 端末B

-   端末AのBluetoothが届く範囲にいる

### 共有の手順

端末Bで共有したいWiFiアクセスポイントに接続します。すると端末Aに以下のダイアログが表示されます。

![](https://support.apple.com/library/content/dam/edam/applecare/images/ja_JP/iOS/ios13-iphone-xs-share-wifi-password-animation.gif)

画像出典 - [Apple](https://support.apple.com/ja-jp/HT209368)

端末Aのダイアログで許可をすると、端末Bにパスワードが共有されます。

## 方法3 : QR Wi-Fi

QRコードでもWiFiのSSIDとパスワードが共有できます。

[QR Code Recognition on iOS 11](https://developer.apple.com/videos/play/tech-talks/206/)

こちらの動画の3:30から、QR Wi-Fiが触れられています。

### 使いどころ

OSの異なるスマホ同士で接続パスワードを共有するのに適しています。また、イベント会場など一時的に不特定多数の人に接続パスワードを配布するのにも適しています。

### 準備

まず、以下の構文にしたがって文字列を作ります。

    WIFI:S:【SSID名】;T:【WEP or WPA】;P:【パスワード】;;

`S`と`P`はSSID名と接続パスワードです。`T`はWiFiの暗号化方式を指定します。最近のWiFiアクセスポイントはほぼWPAを使用しています。S,T,Pの順番は入れ替えても動作します。

たとえばSSIDが`TEST-A-789`、パスワードが`wifi-password`の場合

    WIFI:S:TEST-A-789;T:WPA;P:wifi-password;;

となります。

次に、この文字列をQRコード化します。QRコードは以下の方法で生成できます。

[iPhoneで書いた住所やURLなどの短い文章・文字列はQRコード化して他のスマホへ](https://news.mynavi.jp/article/20200113-ipadiphonehacks/)

この記事では、ダイアログで入力された文字列をQRコード化しています。
ショートカットを変更して、入力元をクリップボードにするのもオススメです。

### 共有の手順

iOS端末のカメラを起動し、このQRコードを読み取ると通知がポップアップします。この通知をタップすれば、端末がWiFiアクセスポイントに接続されます。

また、このQRコードはAndroid端末でも読み込めます。

### 注意点

WebサービスでQRコードを生成すると、サービスのオーナーに接続パスワードが暗号化されない状態で渡ります。接続パスワードを含んだQRコードはネットワークを介さず、端末内で生成することをオススメします。

QRコードには接続パスワードが平文で格納されています。そのため撮影した写真からも簡単にパスワードが復号できます。イベントなどで不特定多数がQRコードを撮影した後は、接続パスワードを変更しましょう。

## 参考記事

[iPhone で QR コードからの Wi-Fi 接続が意外と知られていなかったので補足](https://note.com/jp_pancake/n/n2c5d8d8aa868)
[QRコードでお手軽設定](https://news.mynavi.jp/article/androidnow-28/)

以上、ありがとうございました。
カブトムシを様々な種類にトランスフォームさせたくなったときの簡単なTIPS


###【 完成形 】
<p class="codepen" data-height="448" data-theme-id="light" data-default-tab="html,result" data-user="daisukeibi" data-slug-hash="MWKXrmO" style="height: 448px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="MWKXrmO">
  <span>See the Pen <a href="https://codepen.io/daisukeibi/pen/MWKXrmO">
  MWKXrmO</a> by daisukeibi (<a href="https://codepen.io/daisukeibi">@daisukeibi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

まず初めにGSAPのライブラリを読み込む。

```index.html
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/gsap-latest-beta.min.js?r=2314"></script>
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/MorphSVGPlugin3.min.js"></script>
```


使いたいSVGをダウンロードしてコードエディタで開き、
svgタグのviewBoxとpathタグのd属性をコピーして貼り付ける。

```index.html
<svg id="svg" viewBox="（viewBox属性を貼り付ける）" fill="#4F392B">
  <path id="icon1" d="（一匹目のカブトムシのd属性を貼り付ける）">
  <path id="icon2" d="（二匹目のカブトムシのd属性を貼り付ける）">
  <path id="icon3" d="（三匹目のカブトムシのd属性を貼り付ける）">
</svg>
```


cssで初期表示しないpath要素を隠す。

```style.css
#icon2,#icon3{
visibility: hidden;
}
```

jsで動かす。

```script.js
var tl = gsap.timeline({repeat:-1});

tl.to("#icon1", 1,{
  morphSVG: "#icon2"
}).to("#icon1", 1,{
  morphSVG: "#icon3"
}).to("#icon1", 1,{
  morphSVG: "#icon1"
})
```

以上で完成です！

**morphSVGPlugin**は有料ですが、他にも**Anime.js**や**snap.svg**など無料で使えるのもいっぱいあるので、「SVG モーフィング」で調べてみてください。（モーフィング時の滑らかさとか実装の難しさに差があって面白いです）

JS苦手な方や手っ取り早く動かしたいという方には短い記述で簡単に実装できるので、有料にはなりますが**morphSVGPlugin**がおすすめです。

---
使用ライブラリ：https://greensock.com/morphsvg/
DIの起源

DI(Dependency Injection)という言葉自体の起源は、2004年にMartin Fowlerが書いた以下の記事だと思われる。

[Inversion of Control Containers and the Dependency Injection pattern](https://martinfowler.com/articles/injection.html)

ただ、この記事にもある通り、DIのアイデア自体は当時の既存のフレームワーク（SpringやPicoContainer）に既に実装されていた。Martin Fowlerはそのアイデアを整理し、それを名指すための名前を付けたということである。

## 参考

翌年の2005年には日経XTechでDependency Injectionの効用について伝える記事が出ており、Martin Fowlerについても書かれている。→「[Java開発を変える最新の設計思想「Dependency Injection（DI）」とは](https://xtech.nikkei.com/it/free/ITPro/OPINION/20050216/156274/?P=2)」
【Laravel】usersテーブルにカラムを追加する

# 内容
はじめにマイグレーションを行うと、usersテーブルにnameとemailなどができるが、プロフィールを作成しようとすると、性別や年齢、自己紹介文などが欲しくなります。
そこで、既存のusersテーブルにカラムを追加する作業を行います。

# 前提
laravel7で行います。
すでにマイグレーションを行っているものとします。

```zsh
% php artisan migrate
```

#　方法
1. マイグレーションファイルを作成
2. カラムを追加
3. マイグレーション
4. User.phpの編集

## マイグレーションファイルの作成
```zsh
% php artisan make:migration add_column_to_users_table --table=users
```

どういう操作をするかわかりやすいファイル名にすると良いでしょう。
--tableオプションでどのテーブルを編集するか指定します。


## カラムを追加
```php:20XX_00_00_000000_add_column_to_users_table.php
class AddColumnToUsersTable extends Migration
{
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->string('body')->nullable();
        });
    }

    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn('body');
        });
    }
}
```

up()に追加処理を書き、down()にロールバック処理を書きます。

## マイグレーション
```zsh
% php artisan migrate
```

## User.php
```php:app/User.php
    protected $fillable = [
        'name', 'email', 'password', 'body'
    ];
```

User.php内の\$fillableに追加カラムを追加します（ここではbodyを追加）
これをしておかないと、更新時など
　　　　\$user->fill(\$request->all())->save();
のfill()で追加カラムが弾かれてしまいます。

# おわり
これでおわりです。
テーブルをいじるときは新しくマイグレーションファイルを作成するようにしましょう。
そうしないと、ロールバックする時正しく動作しなかったり、テーブルが崩れたりします。

# おまけ
カラムを削除するときなど、カラムを変更する際、以下のコマンドを実行する必要があります。

```zsh
% composer require doctrine/dbal
```

テーブルのカラムを調べたいときは、tinkerでSchema::getColumnListing('table_name');を実行すると良いでしょう。
Mac+DockerでphpStormを使いWordPressテーマを一から作る（1/3）

先日、2009年から愛用していた懐かしの白いMacBook(Early 2009)を卒業して、MacBook Air2020(1,1GHz i5クアッドコア+SSD 512GB+16GB RAM)に乗り換えました。

先代はメモリを8GBまで増設して内臓HDDもSSDに換装してなんとか延命をしており、普段使用するアプリケーション（Photoshop CCの最新版とかphpStormとかableton Liveとか）はほぼストレス無く使えていました。

現在はうつ病の療養中で無職のためこれまでやってきてなかった事をしたいと思い、今更ながらSassなどこれまで業務の中で触れなかった技術を学ぼうと思い、まずはVirtualBox+CentOSで環境を作ってみたのですが、公式リポジトリのCentOSのバージョンが7系でphpも5.4系とかなり古いものでした。

そこでDockerを使ってみようとしたところ、旧マシンではOSのアップデートがSierra(10.12)で止まってしまっており現行バージョンのDocker Desktopが使えなかったので、例の一人10万円給付金を使ったMacBook Air2020の購入へと至りました。

...と前置きが長くなりましたが本題に入りたいと思います。
本稿は長くなるので３回に別けて投稿したいと思います。

# ゴール
Docker Desktop for Mac でWordpress環境を作り、スターターテーマのunderscores(_S)を使ったテーマ開発ができるようにする。
cssはSassを使い、phpStorm側でコンパイルが出来るようにする。
ついでにphpMyAdminも使えるようにする。

# 前提条件
- MacOS Catalina(10.15)　※セットアップとデータ移行が済んだ状態
- phpStorm(2020.1)

#ステップ
- XCodeのインストール(1/3)
- Homebrewのインストール(1/3)
- node(npm)+node-sassのインストール(1/3)
- Docker Desktop for Mac のインストール（(2/3)
- Docker-composeによるコンテナの構築（2/3）
- underscores(_s)でのスターターテーマの作成とファイルの設置(3/3)
- phpStormでのSassウォッチャーの登録(3/3)

## Xcodeのインストール
まずはXCodeをインストールします。
これは後にHomebrew経由でnodeを導入し、さらにnode-sassを導入するための前準備です。

AppStoreからXcodeを検索してポチればOKです。
![2020-07-10-11.18.20.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671352/52441058-7056-4a90-4bc0-275022a8e369.jpeg)

インストールにはそこそこ時間が掛かるので、しばらく放っておきましょう。自分は1時間くらい掛かったような。

もしくはターミナルから以下のコマンドでもインストールできるようです。


```sh
$ xcode-select --install
```

## Homebrewのインストール
インストールが完了したら次はHomebrewのインストールを行います。
HomebrewをはMacOS向けのパッケージマネージャーで必要なものをコマンドで簡単にインストールできる、というものです。
これにより後のnodeのインストールを行います。


[公式サイト](https://brew.sh/index_ja.html)によれば以下のコマンドでインストールが可能なようです。

```sh
＄ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
```
インストールが完了したらバージョンを確認し、以下のようにバージョンが表示されればOKです。

```sh
$ brew --version
Homebrew 2.4.3
Homebrew/homebrew-core (git revision 06581; last commit 2020-07-07)
```

## node(npm)+node-sassのインストール
続いてHomebrew経由でnode(npm)をインストールします。
npmとはnodeのパッケージ管理ツールの事です。

```sh
$ brew install -g node
```

インストールが済んだらバージョンが正常に表示されるか確認しましょう。

```sh
$ node -v
v14.5.0
```

無事、インストールできたようです。
npmのバージョンは以下のコマンドで確認できます。

```sh
＄ npm version
{
 npm: '6.14.5',
 ares: '1.16.0',
 brotli: '1.0.7',
 cldr: '37.0',
 icu: '67.1',
 llhttp: '2.0.4',
 modules: '83',
 napi: '6',
 nghttp2: '1.41.0',
 node: '14.5.0',
 openssl: '1.1.1g',
 tz: '2019c',
 unicode: '13.0',
 uv: '1.38.0',
 v8: '8.3.110.9-node.23',
 zlib: '1.2.11'
}
```
私の環境では以上のような結果になりました。
npmのインストールが確認できたら、今度はnpmでnode-sassをインストールします。

```sh
＄ npm install --global --save-dev node-sass
```
特にエラーらしきものが出ていなければOKでしょう。

``

~~以降は次のエントリーに続きます。~~
> 2回目書きました。
[Mac+DockerでphpStormを使いWordPressテーマを一から作る（２/3）][1]
[1]:https://qiita.com/jszk/items/053bd5cc36f14268fcaf
多項式の関数を組み合わせる

```
from IPython.display import HTML

HTML('''
<script>  
code_show=true; 
function code_toggle() {
  if (code_show){
    $(\'div.input\').hide();
  } else {
    $(\'div.input\').show();
  }
  code_show = !code_show
}  
$( document ).ready(code_toggle);
</script>
<form action="javascript:code_toggle()">
    <input type="submit" value="Toggle code">
</form>
''')
```

```
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
plt.rcParams['font.size']=15

def plt_legend_out(frameon=True):
    plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0, frameon=frameon)
```

# 1次式

```
def f(x):
    return x

x = np.linspace(-10,10,100)

plt.plot(x,f(x))
plt.axvline(x=0,color='gray',lw=0.5)
plt.axhline(y=0,color='gray',lw=0.5)
plt.show()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278468/9a41305b-3849-0b2a-499f-bed247a22369.png)


# 2次式

```
def f(x):
    return -x**2

x = np.linspace(-10,10,100)

plt.plot(x,f(x))
plt.axvline(x=0,color='gray',lw=0.5)
plt.axhline(y=0,color='gray',lw=0.5)
plt.show()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278468/5387d12f-d4e5-27fb-0532-f2be673972e1.png)

# 4次式

```
def f(x):
    return x**4

x = np.linspace(-10,10,100)

plt.plot(x,f(x))
plt.axvline(x=0,color='gray',lw=0.5)
plt.axhline(y=0,color='gray',lw=0.5)
plt.show()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278468/6219a873-07fe-aea4-1cd5-6675d26a755f.png)

# 組み合わせ

```
def f(x):
    return 0.9*x**4 - (50*x**2) + 50*x + 200

x = np.linspace(-10,10,100)

plt.plot(x,f(x))
plt.axvline(x=0,color='gray',lw=0.5)
plt.axhline(y=0,color='gray',lw=0.5)
plt.show()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278468/d46ba387-f398-f73f-ba03-bb97c86fc657.png)
手書きメモの DegiNote を使ってみた

# はじめに
ちょくちょくセミナーにいくが、手持ちのノートPCは古く1時間ぐらいしかバッテリー持たないしで手書きを保存できるデバイスが欲しいと思っていた。

##主目的
以下が達成できること
* 手書きで複数のページが保存できること
* 1日ぐらいのセミナーでも電池が持つこと
* PCに転送できること


##副目的
* zoomとかライブ配信したい
* OCRでテキスト変換してほしい
* ネットにつながってほしい


#DegiNote 購入

最初に考えたのは iPad ＋ iPencel 。
ノーマルiPadでも4万円するし、合計で5万円強かかるのでお父さんとしては痛い。

そこで、手書き保存してPCに転送できるものを探していた。

ところが、あまりないんだよねー。。。
あることはあるんだけど、数万円するので、結局 iPad と同じぐらいというか、iPadより高い値段となってしまう
https://www.sony.jp/digital-paper/products/DPT-RP1/


これでは、お父さん呑みに行けないよｗｗｗ

少なくとも1万以内でなんとかならんもんか。。。と探していた。

そうすると、[DegiNote](
https://www.amazon.co.jp/STOK-%E3%82%B9%E3%83%9E%E3%83%BC%E3%83%88%E3%83%8E%E3%83%BC%E3%83%88-DigiNote-10%EF%BC%88%E4%BF%9D%E5%AD%98%E3%81%A7%E3%81%8D%E3%82%8B%E9%9B%BB%E5%AD%90%E3%83%A1%E3%83%A2%E3%83%91%E3%83%83%E3%83%89%E3%80%81PC%E7%94%A8%E3%83%9A%E3%83%B3%E3%82%BF%E3%83%96%E3%83%AC%E3%83%83%E3%83%88%E3%81%A8%E3%81%97%E3%81%A6%E3%82%82%E4%BD%BF%E3%81%88%E3%81%BE%E3%81%99%EF%BC%89/dp/B08B4Z37HN/ref=sr_1_1?adgrpid=88513448052&dchild=1&gclid=Cj0KCQjwo6D4BRDgARIsAA6uN19STBW_tBbufwKV_H80ymlMt3_Xo-3hhJqNfaDYcrjefvj2JC-ZLDcaAsALEALw_wcB&hvadid=396200919242&hvdev=c&hvlocphy=1009292&hvnetw=g&hvqmt=e&hvrand=18226775405125838854&hvtargid=kwd-841362514769&hydadcr=7992_11094197&jp-ad-ap=0&keywords=diginote&qid=1594428884&sr=8-1&tag=googhydr-22) というものを見つけた


<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304109/05ee6b75-f175-f5e4-0ef5-30048d60e855.jpeg">

amazonで約1万円だった。ちょっと青っぽいので色が気に入らないが、背に腹変えられんので購入した。


#DegiNoteを使ってみた
主目的はほぼ100%果たせました。

##電池
電池は申し分なし。とりあえず1日使ってみたけど特に問題なし。

##保存機能
フロッピーディスクマークが保存ってところが理解しやすい年代であるところｗｗｗ
長押しで保存して、新しいページとなる仕様。

そして 10 ページ分ぐらいは軽く内蔵メモリに保存できるようでした。
最大でどれぐらい行くのかわからないけど、1日ぐらいのセミナーや会議ぐらいでは埋まらない気がする。

##PCとの連携
PCとの連携はできない。。。残念
iPad／iPhone、Andrond の eDraw というソフトに連携はできるので、PCにメモを移行するためには経由しないといけない。
ちょっと面倒だけど、まぁ5万払うぐらいなら、これぐらいやりますよｗｗｗ

bluetooth経由で、リアルタイムに見えるのはいいと思う。
以下の画面で 「DegiNote接続」を選択すると bluetooth 接続画面がでるので、接続すると同期が始まる。

<img width="300" alt="IMG-9746.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304109/e862c562-18e1-fd07-8c15-a82786af8512.png">


##削除
記載途中のメモを部分的に削除することはできないので取り消し線とかで我慢する

一番残念なのは1ページだけ消したいとかはできない
このボタン長押しで、保存しているメモをすべて削除する仕様。
なので、スマホに連携しないでこのボタンを押してしまうと泣くことになる。


## OCR 機能
OCR機能はなし

## zoomでの配信
まだやっていない

##ネット接続



#カバー＆画面保護
iPad用でも買ってきて張ろうと思っているが大きさ合うんだろうか。。。。
カバーはなし。なんか作るかとおもっている。
Pythonの予約語

# Pythonの予約語
## 予約語 
変数,関数で予約語を使っちゃいけません
予約語一覧表:

```
['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
```
Rails6・unicorn、nginx、postgresのdockerコンテナを別々で立てる

## 紹介する内容
- dockerコンテナを三つ(Rails6とunicorn一緒に、nginx、postgres)にして立てます
- nginxのUNIX-domain socketとdocker composeのvolume活用します


## 結論
### Rails6コンテナはunicornをforegroundで起動、nginxのUNIX-domain socketをdocker composeのvolumeマウントしたら動きます
- Rails6コンテナはunicornをforegroundで起動させて、nginxの通信を待ちながらコンテナが落ちない（exit 0）ようにします
- nginxのUNIX-domain socketをdocker composeのvolumeを使って、Rails6コンテナのunicornに共有させます
   - UNIX-domain socket使いますからportはnginxとpostgresだけ開けば十分です

### AWS ECSなどに活用できます
- dockerコンテナを別々に立てる予定のECSに`このコンテナ構成動くか？`の事前試しができます


### priでデバックしずらくなりますから、開発環境ならRailsコンテナ一つ立てて`bundle exec rails s`することを推奨します
- binding.pryはかかりますが、ユーザーが値を入力できるところがよく分かりません
   - Railsコンテナにdocker attachしてもだめでした



## 紹介始めます
### ディレクトリ構成
全体ソースコードは https://github.com/cheekykorkind/qiita-example/tree/master/rails/6/unicorn-nginx で確認できます

- 全体図
![allD.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247584/12ffc307-8f01-d882-7701-3cafd0d92b9d.png)


- Rails6とunicorn dockerファイルデレクトリー
- nginx dockerファイルデレクトリー
![dockerD.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247584/65d1dd60-5eef-200c-e2f9-3e6edde46af3.png)




### nginx confファイル説明
いろいろ書かれてますが、必要な部分だけ書きます

- `./docker/nginx/nginx.conf`ファイルです
   - `include /etc/nginx/conf.d/*.conf;` によって、`./docker/nginx/web.conf` が読み込めます
- `./docker/nginx/web.conf`ファイルです  
   - 全てのrequestが `location /` に入ります
   - `proxy_pass http://unicorn;` によって `upstream unicorn` に行きます
   - `unix:/workspace/myapp/tmp/unicorn.todo.sock` に来たらUNIX-domain socketで通信します
      - UNIX-domain socketを簡単に説明すると`ファイルを持って通信できる`です。
         - ですから、docker composeのマウントだけでnginxとunicornが連携できます
         - https://en.wikipedia.org/wiki/Unix_domain_socket

```
upstream unicorn {
  server unix:/workspace/myapp/tmp/unicorn.todo.sock fail_timeout=0;
}

server {
  listen       80;

  location / {
    ...省略

    proxy_pass http://unicorn;

    ...省略
  }
  ...省略
}
```

### unicorn設定ファイル説明
- `./config/unicorn/development.rb` ファイルです
- `listen "#{RAILS_ROOT}/tmp/unicorn.todo.sock"` をnginxのconfファイルの内容と同じパスを書くことでUNIX-domain socketの通信ができます


### docker周り実装説明
- `./docker-compose.yml` ファイルです
- `bundle exec unicorn -c ./config/unicorn/development.rb`でunicornをforegroundで起動します
- UNIX-domain socketの専用volumeを作ります

```
volumes:
  nginx_socket:
    driver: local
```

そして、`nginx_socket:/workspace/myapp/tmp`でdockerコンテナ中でマウントするパスを設定します。
unicornとnginxが同じファイルをマウントできるように各々のコンテナに同じく書きます。


### 試し順番です
1. docker composeがあるデレクトリーに移動します 
  - `cd qiita-example/rails/6/unicorn-nginx`
2. dockerコンテナをバックグラウンドで起動します
  - `DOCKER_UID=$(id -u $USER) DOCKER_GID=$(id -g $USER) docker-compose up -d`

![unicorn.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247584/35ee8980-36c3-c7be-6360-80c76ab46d87.gif)
3分間ネットワーク備忘録 第１０回

## 概要
引き続き[３分間ネットワーク](http://www5e.biglobe.ne.jp/aji/3min/)について、
学習の備忘録を書いていきます。


今回は、
- [第２３回](http://www5e.biglobe.ne.jp/aji/3min/23.html)
- [第２４回](http://www5e.biglobe.ne.jp/aji/3min/24.html)
- [第２５回](http://www5e.biglobe.ne.jp/aji/3min/25.html)
- [第２６回](http://www5e.biglobe.ne.jp/aji/3min/26.html)

あたりをまとめていきたいと思います。


### プライベートアドレス
前回の記事で`IPアドレス`には`ネットワーク部分`と`ホスト部分`が
あるということを話しました。

この`ネットワーク部分`はネットワーク上で一意出ないといけないという話もありましたが、
このアドレスの中、勝手に使って良い`プライベートアドレス`という範囲があります。
このアドレスに関する通信は、ルータが外のネットワークには出さない、という仕様になっているため、
ローカル内のアドレスとして勝手に使って良いというふうになっています。


### サブネットマスク
実際はホスト部を一つずつデバイスに振っていくのは現実的ではないため、
ホスト部を`サブネット番号`と`ホスト部`と分けることで階層構造を作り管理をしやすくしています。

このとき、どこまでがサブネットなのかを宣言するのが`サブネットマスク`です。

サブネットマスクは例えば
`11111111 11111111 11111100 00000000`
みたいな感じになっており、１が立っているところがネットワーク部として扱われます。


### 通信時に必要な４つのアドレス

少しおさらいが入りますが、例えば使用プロトコルは`IP`、使用アーキテクチャは`イーサネット`とします。
この構成でのLANでのデータ転送におけるカプセル化は、

レイヤ４ー＞レイヤ３へのデータの`セグメント化`、
レイヤ３ー＞レイヤ２への`パケット化`（セグメントにIPヘッダをつけること）
レイヤ２ー＞レイヤ１での、`イーサネットヘッド`と`トレーラ`を付加すること。

からなっています。

この時、`IPヘッダ`は

- 送信元の`IPアドレス`
- 送信先の`IPアドレス`

`イーサネットヘッダ`は、

- 送信元の`MACアドレス`
- 送信先の`MACアドレス`

を持っています。

これらが少なくともデータのやりとりに必要な`４つのアドレス`になります。


### これらのアドレスをどうやって取得するか

#### 送信元の`MACアドレス`
これは簡単です、`NIC`に書いてあるのでそれを取得します。

#### 送信元の`IPアドレス`
静的アドレスとして打ち込む、もしくは動的アドレスを聞きます。
このとき、動的アドレスを聞く時は通信を発生させて聞くことになるが、
この通信を`DHCP`と呼びます。

#### 送信先の`MACアドレス`
`ARP`というプロトコルをつかいます。

#### 送信先の`IPアドレス`
`DNS` サーバに要求します。


### DHCP
`DHCP`サーバが`DHCP`クライアントに対して`動的IPアドレス`を振っています。
先ほど出てきたプライベートアドレスである、
`192.168.1.1 ~ 192.168.1.254` に関しては使って良い、というように`DHCP`サーバが取り決め、
この範囲から各ホストに対してIPアドレスを割り当てます。

`DHCPサーバ`に対して自身のIPアドレスを聞くときに送るメッセージを`DHCPメッセージ`と呼びますが、
これは`ブロードキャスト通信`です。つまり全員に送ります。

理由はクライアントは誰に送れば良いか知らないからです。`ブロードキャスト通信`では宛先を
`ブロードキャストアドレス`である`255.255.255.255`に送ります。

#### ARP
先ほど少し言及したように、`ARP`は`宛先のMACアドレス`を知るための通信でした。
流れとしては後で出てくる`DNS`が`宛先IPアドレス`を教えてくれた後、これを用いて`宛先IPのMACアドレス`を
取得するのがこの`ARP`になります。
`ARP`に関しても先ほどの`DHCP`と同じように`ブロードキャスト送信`を行います。

ここで、`ルータ`は`ブロードキャスト通信`をフィルタリングし、外のネットワークに出ていかないように
`フィルタリング`を行う働きがありましたが、ではどうやってルータの先にあるMACアドレスを取得するのでしょうか？

これは先で記述される`デフォルトゲートフェイ`
によって解決されます。




### まとめ
今回はレイヤ３、レイヤ２がLANで通信を行うときに必要となる
`４つのアドレス`について書きました。
その後、それらのアドレスがどのように通信時に取得されるのかを

- `DHCP`
- `ARP`

という二つのプロトコルで解説しました。
（`DNS`についてはもっと詳しく後で出てきます。）


今回はこの辺で。


終わり。
Power Automate でOffice365の各グループにメンバーを追加できるか検証してみた

Microsoft365のグループにユーザーを追加するフローを作りたい、という相談を受けたので、どのグループなら利用できるのか、何ができないのか、検証してみた。

先に書いてしまうけど、できるグループ、できないグループがある。
各グループはこちらの[【備忘録】Office365の各グループの機能まとめ　その１](https://qiita.com/hisssa0102/items/1a75c39d5d18cb20386a)にまとめてみました。



#■検証に利用したフロー

アクション Azure ADを利用してみた。
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237698/2b358a26-15af-0a9f-a0b8-e3804f6324be.png)

対象グループのグループ ID を調べて入力する必要あり。
Azure AD 管理センターでグループIDを調べなきゃならない。(後述)

#■検証してみた

各グループを入れて検証してみた。

##1.Office365グループ
問題なく、追加できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237698/9c3c2cdd-359f-304f-2ec9-1e7053d7b976.png)

##2.セキュリティグループ
Office365グループへの追加同様、追加できました。

##3.配布リスト

追加できず、エラーになりました。

Unable to update the specified properties for objects that have originated within an external service.
別サービスの固有の属性があるからアップデートできない、とな。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237698/6aae6ced-6c22-23d0-537b-2de4396b742b.png)


##4.メールが可能なセキュリティグループ
配布リストへの追加同様、追加できませんでした。

##5.ここまでの集計

|グループ種類|可否|
|:--|:--|
|365グループ|可|
|セキュリティグループ|可|
|配布リスト|　不可|
|メールが可能なセキュリティグループ|　不可|




#■前提条件

検証結果からわかったこと。

##1.アクション Azure AD で扱えるグループはAzure ポータルでメンバーを追加できるグループのみ。

Azure AD 管理センターでは、配布リストやメールが可能なセキュリティグループのメンバー追加はできない。これらは、Exchnage管理センターか、Microsoft365管理センターでなければ変更できないので、Power Automateでもこの影響を受けてしまう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237698/dd36aed3-7333-0593-f05b-edfd546a6277.png)


##2．Azure Portalへのアクセス権がないユーザーは、アクション Azure AD が利用できない。

Azure AD管理センター自体を操作するものになるので、管理者しかほぼ使えない。セキュリティを考えれば当然なんだけど、管理者専用のアクションと思ったほうがいいかもしれない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237698/46a8b915-c08e-f616-5fe5-4c4e57aab0fb.png)


#■一般ユーザーがOffice 365 グループにユーザーを追加するフローは使えないの？

アクション Office 365 グループ　- グループへのメンバーの追加、を使う。

こちらなら、Azure AD 管理センターへのアクセス権は不要で、グループの所有者ならOK。
グループ ID と表示はあるもののIDを知らなくても、表示名から検索できるので簡単。




![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237698/90ab3c00-fd12-2447-fe02-5da8ba72d3a6.png)


#■まとめ

ブラウザからならGUIで設定できるけど、Power Automateでは全部ができるわけではない。

|グループ種類|アクション Office 365 グループでの設定|アクション Azure ADでの設定※Azure AD管理センターに許可あるユーザーのみ|ユーザーでのGUIでの設定|
|:--|:--|:--|:--|
|365グループ|可|可|可（Teamのメンバーの追加削除など）|
|セキュリティグループ|　不可|可|　不可|
|配布リスト|　不可|　不可|可（Outlookの設定）|
|メールが可能なセキュリティグループ|　不可|　不可|可（Outlookの設定）|

おなじような要望は上がっているようです。興味ある方はVoteしてください。

https://powerusers.microsoft.com/t5/Power-Automate-Ideas/Add-users-to-Outlook-365-distribution-groups/idi-p/141286?collapse_discussion=true&search_type=thread
GitHubから来た脆弱性警告メールに感動した件

# 発端

> Your Dependabot alerts for the week of Jun 30 - Jul 7

というメールがGitHubから届いた。

# 内容確認

また以前書いた記事（ [GitHub から脆弱性警告メールが来て、対応に苦労した話](https://qiita.com/silverbox/items/f2b2c16aa2b86f82a69c) )と同じかと思っていたら、どうも様子が違っていた。
確かに前述メールも届いたのだが、別途幾つかメールが届いていた。
差出人は「From: "dependabot[bot]" <notifications@github.com>」
中身を見ると次の一文が。

> This automated pull request fixes a security vulnerability (low severity):

自動的に修正用プルリクエスト作った？？？と半信半疑でGithub見てみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530376/c94dfbdd-1608-8402-103a-6e5c71f615a2.png)

出来てるよ！

ちなみに、デフォルトブランチをdevelop以外にしているプロジェクトにも同様の内容が来ていたが、そのブランチに対してプルリクエストが出来ていた。このプルリクエストはデフォルトブランチに対して作成されているらしい。
なので、リリースブランチとかがある場合には、この情報をキャッチして必要な分のブランチに修正をCherryPickするのが良いと思われる。

# 作業

※前述画像とは別プロジェクトなのでブランチ名異なります。

```console:
git fetch --all
git checkout dependabot/maven/mysql-mysql-connector-java-8.0.16
mvn package
```

でビルドに問題が無い事確認。Githubのwebコンソール上でマージ。
※まぁ、厳密には動作確認もすべきですが、自分用の重要でないプロジェクトなので。

```console:
git checkout develop
git pull origin develop
```

で修正反映。終わり！

# 感想

メールだけだと見逃しちゃったりするけど、プルリクエスト作ってあれば後で管理者以外の人も気づけるし、進歩してるな、と感じた今日この頃です。（以前修正した時にはこのメールとか自動プルリクエストとか無かったと思う）
【PHP】画面にエラー表示させる方法（デフォルト設定方法も説明）

MAMP等を立ち上げてPHPファイルをブラウザで閲覧した時に、エラーが発生して
画面が真っ白になることありますよね。
そんな時は、コードのどの行でエラーが発生しているのかを突き止められるよう
エラーメッセージを画面に表示するように設定すると便利です。

そのためには、主に以下の２つの方法があります。

***
**①PHPファイルにコードを１行追加する方法**
　→ファイル毎に追加する必要があります

**②PHPの設定ファイルを変更する方法**
　→一度設定すると、①のように毎回コードを追加する必要がなくなります
***

それでは、それぞれの方法について説明させていただきます。

# ①PHPファイルにコードを１行追加する場合

こちらは至ってシンプルで、エラーを表示させたいPHPファイルに
以下のコードを１行追加します。
これでエラーが表示されるようになります。

~~~php
<?php
ini_set('display_errors', 'On' );
~~~

しかし、ファイル毎にいちいち記載するのが面倒だ！という場合は、
PHPの設定を変更して常にエラーが表示されるようにすると楽です。

#②PHPの設定ファイルを変更する場合

こちらは、PHPの設定ファイルである　php.ini　を編集します。
（今回はMacPCを使用しています）
現在使用しているPHPのバージョンによって編集する設定ファイルが異なるので、
まずはPHPのバージョンを確認します。
ターミナル等で**「php -v」**コマンドを入力します。

```
$ php -v
PHP 7.4.2 (cli) (built: Feb 17 2020 12:56:02) ( NTS )
Copyright (c) The PHP Group
```
私の場合、PHPのバージョンは7.4.2でした。

次に設定ファイル「php.ini」がどこにあるのかを調べるために、**「php -i | grep php.ini」**コマンドを入力します。

```
$ php -i | grep php.ini
Configuration File (php.ini) Path => /Applications/MAMP/bin/php/php7.4.2/conf
Loaded Configuration File => /Applications/MAMP/bin/php/php7.4.2/conf/php.ini

```
私の環境の場合、一番下の行にあるように、
**/Applications/MAMP/bin/php/php7.4.2/conf/php.ini**　が、php.ini　のパスになります。
こちらの部分は皆さんの環境によって異なると思うので、コマンドの出力結果をご確認ください。

それでは、先ほど確認したパスを辿って php.iniを編集していきます。
念のため、ファイルをコピーしてバックアップを残しておくと安心です。

<img width="904" alt="スクリーンショット 2020-07-11 9.12.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613419/6abd0c3b-a6fd-4f0a-870c-6b2e6ab86e65.png">



php.iniをエディターで開いたら、command + F　で検索モードにして、
「display_errors」 で検索してください。
この時、**display_errors = Off** となっている行がありましたら、
こちらを**display_errors = On** に変更します。


![スクリーンショット 2020-07-11 9.21.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613419/9c77091a-32c5-8924-b987-b6434855f5c8.png)

これで設定は完了です！
XAMPPやMAMPを起動している場合は、Apacheを再起動すれば
自動で画面にエラーが表示されるようになります。
2020-07-11 PYNQ > HDMI出力で線を引く (pynq.lib.video Moduleのwriteframe()使用 + frameのRGB値を変更)

```txt:動作環境
Windows 10 Pro (v1909) 
PYNQ-Z1 (Digilent) (以下、PYNQと表記)
```

### 概要

- bitstreamはbase.bitを使う
- [pynq.lib.video Module](https://pynq.readthedocs.io/en/v2.5.1/pynq_package/pynq.lib/pynq.lib.video.html)にあるAPIでHDMI入力とHDMI出力を行う
- readframe(), writeframe()を使う
- writeframe()の前にframeの値を変更することで、線を引く

### 接続

PCのHDMI出力をPYNQに読み取らせる。

- A. PCのHDMI端子 <-> PYNQのHDMI IN
- B. PYNQのHDMI OUT <-> モニタのHDMI

### 手順

- [PYNQ-Z1 > HDMI > HDMI入力とHDMI出力を試す (内蔵のJupyter Notebookサンプル)](https://qiita.com/7of9/items/00f823b9085ee6078f1f)

上記で実行したbase/videoのvideoサンプルを使う。

実際には下記を実行する。

### 準備

```py
from pynq.overlays.base import BaseOverlay
from pynq.lib.video import *

base = BaseOverlay("base.bit")
hdmi_in = base.video.hdmi_in
hdmi_out = base.video.hdmi_out
```

```py
hdmi_in.configure()
hdmi_out.configure(hdmi_in.mode)

hdmi_in.start()
hdmi_out.start()
```

ここまででHDMI入力とHDMI出力の準備ができる。

### 線を引く

frameの一部のRGB値を0にすることで黒の線を引く。

```py
aframe = hdmi_in.readframe()
print(aframe.shape)

for idx in range(100):
    aframe[idx][100][0] = 0
    aframe[idx][100][1] = 0
    aframe[idx][100][2] = 0

hdmi_out.writeframe(aframe)
```

```
(720, 1280, 3)
```

27インチ縦置きのモニタで線を引くことができた。

![IMG_1893.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/5e403fe3-e9b4-1d23-e051-58619aca93f9.jpeg)


### frame

今回試した設定ではframeのサイズは(720, 1280, 3)。単純なRGB値のnumpy ndarrayのようだ。
これであれば、HDMI OUTで任意の図形描画（と文字）ができる気がする。

座標は、右上が(0,0)になるようだ。

frame[column][row][RGB]

RGBは下記のようになるようだ。
0: blue
1: green
2: red

### HDMI INなし

HDMI INをつなげずに出力だけの場合は下記のようにする。
黒い背景に赤色の線が見える。

```py
frame2 = hdmi_out.newframe()
for idx in range(700):
    frame2[idx][100][0] = 0  # blue
    frame2[idx][100][1] = 0 # green
    frame2[idx][100][2] = 255
    
hdmi_out.writeframe(frame2)
```

### 遅い

frame2(numpy ndarray)への代入は遅い。
70 * 700 の代入で13秒程度かかる。
np.zeros()などを使った場合、flush()がない、などのエラーとなる。
単純なnumpy ndarrayでもないのかもしれない。
Flashを2021年1月12日 以降も使うには XP〜7は32.0.0.371を使い、10は時計をずらす

* Flash player `32.0.0.387` (以下`387`) では `2021年1月12日` からflashを動かないようにされた。
* Flash player`32.0.0.371` (以下`371`) まではそれ以降も使える。

![スクリーンショット_2020-07-11_09-42-23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/905c8569-6521-bf0d-238c-089b3448aa4f.png)

## 方法

* PCの日付を`2021年1月12日`より前にすれば`387`でも動く。
* windows XP 〜 7 までは [アンインストーラー](https://helpx.adobe.com/jp/flash-player/kb/uninstall-flash-player-windows.html#main_Download_the_Adobe_Flash_Player_uninstaller) でアンインストールし [Flash player 32.0.0.371](https://helpx.adobe.com/jp/flash-player/kb/archived-flash-player-versions.html) (以下`371`) を入れれば`2021年1月12日`以降も動く。(`flashplayer32_0r0_371_winax.exe`はIE向けActiveX)




以下メモ

----

## Flash Player 32.0.0.387

* `387`ではついにPCの時計が `2021年1月12日 00:00:00` になるとflashが見れなくなる。
* `371`ではその制限はない。
* windows xp 〜 7 まで は、普通に `387` をアンインストールし`371`を入れることができる。
* windows 8 や 10 ではその方法が利用できない。

![スクリーンショット_2020-07-11_08-29-23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/ab270cf3-55c7-e425-0727-69a7e993eca0.png)

## IE11 で使用される Flash.ocx の実体

64bit の windows10 で確認。

* 32bit版の IE11
    * `C:\Windows\SysWOW64\Macromed\Flash\Flash.ocx`
* 64bit版の IE11 (未確認)
    * `C:\Windows\System32\Macromed\Flash\Flash.ocx`

試しに `C:\Windows\SysWOW64\Macromed\Flash\Flash.ocx` の名前を変更すると32bit版のIE11で以下のようにFlashが再生されなくなった。

![スクリーンショット_2020-07-11_09-00-13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/ce2f0eaa-43dc-aed1-e0a7-c1551399830b.png)
![スクリーンショット_2020-07-11_09-00-42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/1bde09d3-27c8-1b30-9f59-b3e6b2c5045b.png)


※ IE11は、起動時にFlash.ocxを読み込むため、IE11が起動している時にFlash.ocxの名前を変更してもIE11を閉じて起動し直すまでは動作する。

----

## レジストリ値

`\HKEY_LOCAL_MACHINE\SOFTWARE\Macromedia\FlashPlayerActiveX\Version` の値を見ると現在のバージョンがわかる。

`32.0.0.387`

![スクリーンショット_2020-07-11_09-50-38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/d14aecde-5342-b6be-1134-cdeba2aed691.png)


## (メモ) SubInACL

レジストリ値を変更するときに、権限が無いと言われることがある。
今回レジストリ値の変更は意味がなかったがメモとして残しておく。


* [SubInACL.exe
](https://www.microsoft.com/en-us/download/details.aspx?id=23510) のダウンロード
* `C:\Program Files (x86)\Windows Resource Kits\Tools\subinacl.exe` はコピーして他のPCでも動く。

```sh
cd "C:\Program Files (x86)\Windows Resource Kits\Tools"

subinacl ^
 /keyreg HKEY_LOCAL_MACHINE\software\macromedia\FlashPlayer ^
 /setowner=%username%
```

* [Windows レジストリのアクセス権に関連する Flash Player のインストール問題をトラブルシューティングする](https://helpx.adobe.com/jp/flash-player/kb/flash-player-windows-registry-permissions.html)

![スクリーンショット_2020-07-11_08-26-35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/cb3f7687-c2af-0428-3f0f-7253be61eb1c.png)
rails サーバー途中から立ち上がらない

$cd アプリ名
$rails s
でいつも立ち上げているのですが立ち上がらなくなりました。
どうしたら立ち上がりますか？<img width="1440" alt="スクリーンショット 2020-07-11 9.09.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671572/87ea6f83-4651-264a-0d15-f3cc1ceb8f90.png">
Splunk JSONを後から入力する

https://community.splunk.com/t5/Getting-Data-In/Why-is-the-null-value-in-a-JSON-event-not-being-parsed-properly/m-p/508466/highlight/true#M86507
を見てびっくりしたので。

#やり方

```sql:no_makeresults.spl
index=_internal
| head 1
| fields _raw _time
| eval _raw ="{\"administrativeState\":\"Unlocked\",\"apGroupId\":\"7954abec-de25-4758-bb5e-0d87be2f0254\",\"approvedTime\":\"1435500193785\",\"clientCount\":\"0\",\"configState\":\"newConfig\",\"connectionState\":\"Disconnect\",\"countryCode\":\"XX\",\"cpId\":\"15e2811e-a24f-4570-bd58-8f18c7e6ed91\",\"description\":\"\",\"dpId\":\"\",\"externalIp\":\"xxx.xx.xx.xx\",\"externalPort\":\"55540\",\"ip\":\"xxx.xx.xx.xx\",\"ipType\":\"Static\",\"ipv6\":\"\",\"ipv6Type\":null,\"isCriticalAP\":\"false\",\"lastSeenTime\":1454078438291,\"latitude\":null,\"location\":\"XXXXXXXXX\",\"longitude\":null,\"mac\":\"F0:B0:52:3B:F2:10\",\"meshHop\":0,\"meshRole\":null,\"model\":\"T300\",\"name\":\"XXXXXXXXX\",\"provisionMethod\":\"Discovered\",\"provisionStage\":null,\"registrationState\":\"Approved\",\"serial\":\"491484101277\",\"uptime\":\"81630\",\"version\":\"3.1.1.0.349\",\"wifi24Channel\":2,\"wifi50Channel\":104,\"zoneId\":\"d41a3397-b859-42cd-9332-e308a48069b2\"}"
```

`index=_internal | head 1 | fields _time _raw`で入れ物を作って、そこにJSONを放り込むだけ。

これまでは`| makeresult`でやっていたので、どうしてもStatistics表示になっていたけど、これで、JSONからの展開を模擬しやすくなった。

_Show syntax highlighted_表示だと

赤：　<font color="red">フィールド名</font>
緑：　<font color="green">文字列</font>
紫：　<font color="purple">数字</font>
橙：　<font color="orange">null値</font>

になっている。　`externalPort`と`lastSeenTime`の色が違うのはそのせい。

#まとめ
これまでは`| makeresults`からやっていたけど、これからはこの手段でいこうと思う
pumaの起動・停止・再起動

### pumaの起動方法  
  
```
bundle exec puma -C <puma設定ファイルのパス>  
```

### pumaの再起動方法  
  
```
bundle exec pumactl restart
```  

### pumaの停止方法
* pumaのプロセス確認  

```
ps aux | grep puma
```

* pumaのプロセスkill  
  
```
kill -9 <プロセスpid>
```
3分間ネットワーク備忘録 第９回

## 概要
引き続き[３分間ネットワーク](http://www5e.biglobe.ne.jp/aji/3min/)について、
学習の備忘録を書いていきます。


今回は、
- [第２１回](http://www5e.biglobe.ne.jp/aji/3min/21.html)
- [第２２回](http://www5e.biglobe.ne.jp/aji/3min/22.html)

について補足も入れながら書いていこうと思います。
この３つの３分間ネットワークの記事は、主に`IPアドレス`についての内容になっています。


### MACアドレスとIPアドレス

`MACアドレス`は、`IEEE`からのベンダーコードであり、`NIC`に割り当てられています。
したがって変更は不可です。

一方`論理アドレス`とよばれる`IPアドレス`はネットワーク管理者が必要に応じて自由につけます。
`NIC`煮付けるのではなく、各デバイスのネットワークとの接続点につけます。

`MACアドレス`は４８ビットで構成され、１６進数１２桁でよく表記されます。
`IPアドレス`は３２ビットであり、８ビットずつの`オクテット`と言う単位に分けられて表記されることが多いです。

### IPv4とIPv6
３分間ネットワークの中では３２ビットのIPアドレス、（`IPv4`と呼ばれる形式）しか出てきませんでしたが、
その拡張である`IPv6`では１２８ビットを使います。
これによって実質的に振ることのできるIPが無限（無限ではないですがmore than enoughという意味）となり、
家庭内の様々な機器をインターネットに接続することが可能であると言われています。

異なるのは単にIPアドレスに使えるビット長の違いだけではなく、通信方式が異なるので、
`IPv６`に対応したルータなどの機器が必要となりますし、オンラインゲームで遊ぶ時は、
そのゲームのサーバが`IPv6`に対応しているかどうか確かめる必要があります。
しかし、`IPv4　over IPv6`と呼ばれる方式を使うことができ、基本的に`IPv６`
の環境で通信を行うものの、`IPv4`での通信も行えるようにすることで、両者を使い分けることもできるようです。


### PPPoE と IPoE
`PPPoE` や`IPoE`は３分間ネットワークには出てきていませんでしたが、
`IPv6`などに言及したのでこちらも知っておくといいと思います。

そもそも`PPP`とは（Point to Point Protocol）という通信方式の機能を、`イーサネット`情で
利用できるようにしたものです。モデムを使ってパソコンをインターネットに接続するときや、
ルーター同士を接続するとき使用されるプロトコルです。
先ほどの`IPv６`を使うと、`IPoE`と呼ばれる次世代型の接続方式を使うことができます。
この`IPoE`を使うと、`PPPoE`が混雑している状態でも、混雑ポイントを回避してインターネットに接続できるため、
回線速度の向上が見込めると言うことです。

### クラスフルアドレッシング
`IPv4`のIPアドレスに話を戻して、３２ビットで構成されたIPアドレスに対し、
それを８ビット（オクテット）ごとに区切ったもので表現されることが多いという話でしたが、
その４つの`オクテット`のうち、どこを`ネットワーク番号`、`ホスト番号`にするかを、決められたクラスによって
指定しているのが`クラスフルアドレッシング`という方式です。

#### ネットワーク番号
`ネットワーク番号`は接続されている全てのネットワークでユニークである番号で、`ICANN`という団体で管理されています。
その団体の下についている各地域や各国にある`NIC`とよばれる団体がこの`ネットワーク部分`を管轄しています。
`クラスフルアドレッシング`では、第一オクテットの先頭ビットにより、`A〜E`までのクラスに分割し、それぞれに
決められた量のホストを割り当てることができるようにしています。

これにより、大きい団体はたくさんのホストをアサインされますし、小さい団体は少ない数のホスト部分を持つことになります。


### クラスレスアドレッシング
`クラスフルアドレッシング`はわかりやすいですが、その分無駄なIPが予約されてしまうこともあり、
そこを最適化しようとしたのが`クラスレスアドレッシング`です。

`クラスレスアドレッシング`では、ホストをどのくらい割り振るかを柔軟に決めることができるようにし、
それの表記を`CIDR`という表記方法で纏めています。
これにより、IPの割り振りにおいて無駄が起きにくくなっています。



### まとめ

今回は`IPアドレス`についての３分間ネットワークの部分でした、
次回も少しだけIPアドレスの話を続けて、そのあとは通信時に必要な
`４つのアドレス`の話に移っていきます。


今回はこの辺で。


おわり。
Splunk 新しいSplunk Answersで自分の質問の一覧をだす

https://community.splunk.com/t5/Feedback/How-to-find-my-old-questions/m-p/507319/highlight/true#M44

の質問への回答をこちらに転記

#やり方

https://community.splunk.com/t5/forums/recentpostspage/post-type/thread/user-id/184221

#解説

https://community.splunk.com/t5/forums/recentpostspage/post-type/thread/user-id/
に

https://community.splunk.com/t5/user/viewprofilepage/user-id/184221
自分のプロファイルのユーザIDをくっつければOK

#まとめ
新しい[Splunk>Answers](https://community.splunk.com/t5/Splunk-Answers/ct-p/en-us-splunk-answers)になって、とくに昔の質問がかなり探しづらくなっているので、回答があってよかった。
dockerでWhalesayイメージがpull(run)できない時の対処法

#はじめに
今回は、MacPCで
Dockerのバージョン19.03.8を使用しました。

```
$ docker --version
Docker version 19.03.8, build afacb8b
```

<br>
某動画学習サイトの講義に沿って
DockerHubからWhalesayイメージを取得してプログラムを実行しようと
以下のコマンドを入力したところ、エラーメッセージが出力されてしまいした。
どうやらイメージの信頼性に関するエラーのようです。

```
$ docker run docker/whalesay cowsay Hello!
docker: Error: remote trust data does not exist for docker.io/docker/whalesay: notary.docker.io does not have trust data for docker.io/docker/whalesay.
See 'docker run --help'.

```

#解決策
原因は、Dockerのセキュリティ機能である
DOCKER_CONTENT_TRUST（DCT）が有効になっている点でした。
これは、作成されたDockerイメージが第三者によって改ざんされていないか等を
検証する機能です。
Whalesayイメージを取得するには、この設定を無効にする必要があります。

そのために、以下のコマンドを入力します。

######【DCTの無効化】

```
$ export -n DOCKER_CONTENT_TRUST

もしくは

$ export DOCKER_CONTENT_TRUST=0
```

設定完了後に、Whalesayイメージを取得・プログラム実行すると・・

```
$ docker run docker/whalesay cowsay Hello!

~~~中略〜〜〜

 ________ 
< Hello! >
 -------- 
    \
     \
      \     
                    ##        .            
              ## ## ##       ==            
           ## ## ## ##      ===            
       /""""""""""""""""___/ ===        
  ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ /  ===- ~~~   
       \______ o          __/            
        \    \        __/             
          \____\______/   

```

無事にプログラムが実行できました。
なお、今回無効にしたDOCKER_CONTENT_TRUST（DCT）を再度
有効にしたい時は、以下のコマンドを入力しましょう。

######【DCTの有効化】

```
export DOCKER_CONTENT_TRUST=1
```
windowsでiverilog その51

#概要

windowsでiverilogやってみた。
polyphonyで浮動小数点やってみる。
加算やってみた。

#計算手順

①符号、指数、仮数に分ける。
②計算する値の指数部を合せる。(結果は仮数部に反映させる。)
③仮数部同士を足す。（２進数の加算）
④仮数部のbit数をオーバー(オーバーフロー)したら指数部にそれを反映させる。
⑤32bitに組み立てる。

#サンプルコード


```
import polyphony
from polyphony import testbench, module, is_worker_running
from polyphony.io import Port
from polyphony.typing import bit, bit32, bit23, bit24, bit25

@module
class add:
	def __init__(self):
		self.a = Port(bit32, 'in')
		self.b = Port(bit32, 'in')
		self.c = Port(bit32, 'out')
		self.append_worker(self.worker)
	def float2b(self, a:bit32):
		a_sig:bit = (a >> 31) & 0x1
		a_exp:bit8 = (a >> 23) & 0xff
		a_fra:bit24 = a & 0x7fffff | 0x800000
		return (a_sig, a_exp, a_fra)
	def b2float(self, a_sig:bit32, a_exp:bit32, a_fra:bit32):
		return (a_sig << 31) | (a_exp << 23) | a_fra
	def worker(self):
		while is_worker_running():
			a0:bit32 = self.a.rd()
			b0:bit32 = self.b.rd()
			(a_sig, a_exp, a_fra) = self.float2b(a0)
			(b_sig, b_exp, b_fra) = self.float2b(b0)
			if a_exp > b_exp:
				(a_sig, b_sig) = (b_sig, a_sig)
				(a_exp, b_exp) = (b_exp, a_exp)
				(a_fra, b_fra) = (b_fra, a_fra)
			if a_exp != b_exp:
				a_fra >>= (b_exp - a_exp)
			fra:bit23
			frac:bit25 = a_fra + b_fra
			if frac & 0x1000000:
				frac = frac >> 1
				b_exp += 1
			fra = frac
			c0:bit32 = self.b2float(b_sig, b_exp, fra)
			self.c(c0)

m = add()

@testbench
def test(m):
	m.a.wr(0x3f000000)
	m.b.wr(0x3f800000)
	print ("0.5 + 1.0") #3fc00000
	c = m.c.rd()
	print('{:08x}'.format(c))
	m.a.wr(0x3f000000)
	m.b.wr(0x40800000)
	print ("0.5 + 4.0") #40900000
	c = m.c.rd()
	print('{:08x}'.format(c))

test(m)



```

#python実行結果


```


0.5 + 1.0
3fc00000
0.5 + 4.0
40900000


```

以上。
collections.OrderedDict

#OrderedDict順番を覚えています

```py
import collections

d = {'apple': 4, 'banana': 3, 'pear': 1, 'orange': 2}

# アルファベット順で並び替える、値の順番で並び替えたい場合はt[1]とする
od = collections.OrderedDict(sorted(d.items(), key=lambda t: t[0]))
print(od)

# 最後に追加されます
od['cc'] = 100
print(od)
```
実行結果：

```txt
OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])
OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1), ('cc', 100)])
```
collections.namedtuple

#名前付きタプル
ドキュメント読みましたが、よくわからず

```py
import collections
import csv

with open('names.csv', 'w') as csvfile:
    fieldnames = ['first', 'last', 'address']
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
    writer.writeheader()
    writer.writerow({'first': 'Mike', 'last': 'Jackson', 'address': 'A'})
    writer.writerow({'first': 'Jun', 'last': 'sakai', 'address': 'B'})
    writer.writerow({'first': 'Nancy', 'last': 'Mask', 'address': 'C'})

with open('names.csv', 'r') as f:
    csv_reader = csv.reader(f)
    Names = collections.namedtuple('Names', next(csv_reader))
    for row in csv_reader:
        names = Names._make(row)
        print(names.first, names.last, names.address)

p = (10,20)
print(p[0])

Point = collections.namedtuple('Point', ['x', 'y'])
p = Point(10, y=20)
print(p.x)
# p.x = 100

p1 = Point._make([100, 200])
print(p1)
print(p1._asdict())

p1._replace(x=500)
print(p1)
p2 = p1._replace(x=500)
print(p2)

class SumPoint(collections.namedtuple('Point', ['x', 'y'])):
    @property
    def total(self):
        return self.x + self.y

p3 = SumPoint(2, 3)
print(p3.x, p3.y, p3.total)
```
実行結果：

```txt
Mike Jackson A
Jun sakai B
Nancy Mask C
10
10
Point(x=100, y=200)
OrderedDict([('x', 100), ('y', 200)])
Point(x=100, y=200)
Point(x=500, y=200)
2 3 5
```
autocd ならぬ autocat (備忘録)

# やろうとしていること
 bashからzshに乗り換えてみて，autocd(ディレクトリ名のみでcd)がとても便利だと感じた。だったら，ディレクトリ名だけじゃなくて，ファイル名でcatもできるようにしたいと思って試してみた。

# 設定ファイル追記
一応，zshの場合とbashの場合を書いておく。
## zshの場合
以下を~/.zshrcに追記する。

```shell:.zshrc
#command not foundのとき
function command_not_found_handler() {
  #そのファイルが存在したら
  if test -e $1;    then
    #バイナリファイルなら
    if [ "$(file --mime-encoding -L $1 | awk '{print $2}')" = 'binary' ];  then
      #元々のステータスを表示
      echo "zsh: command not found: $1"
    #バイナリファイル以外なら
    else
      #catで中身を表示
      cat "$1"
    fi
  #ファイルが存在しなかったら
  else
    #元々のステータスを表示
    echo "zsh: command not found: $1"
  fi
}
```
command_not_found_handler(){}の中に書いた処理が，コマンドが存在しない時に実行される。

## bashの場合
以下を~/.bashrcに追記する。

```shell:.bashrc
#command not foundのとき
function command_not_found_handle() {
  #そのファイルが存在したら
  if test -e $1;    then
    #バイナリファイルなら
    if [ "$(file --mime-encoding -L $1 | awk '{print $2}')" = 'binary' ];  then
      #元々のステータスを表示
      echo "bash: $1: command not found"
    #バイナリファイル以外なら
    else
      #catで中身を表示
      cat "$1"
    fi
  #ファイルが存在しなかったら
  else
    #元々のステータスを表示
    echo "bash: $1: command not found"
  fi
}
```

zshとは違い，command_not_found_handle(){}となる。

# 終わりに
これを使えばcatだけじゃなくてvimにするなど色々な処理が可能でかなり便利だ。しかし，あまり使わない。
Windowsにgit-secretsをインストール

# 内容
git-secretsリポジトリ内の
`git-secrets`
`git-secrets.1`
の2つのファイルを
`C:\Program Files\Git\ユーザ名\bin`
へコピーすることでインストールできる。

# 補足
おま環（自分の環境だけ）かもしれないけど、公式のやり方でインストールしてもgit secretsなんてないよと言われて使えない。

```sh
$ ./install.ps1
$ git secrets
git: 'secrets' is not a git command. See 'git --help'
```

かなしい。
SWI-Prologによるツリー操作

# お題

ツリーの要素を全て9に置換する。

# 解答

述語を動的に定義

```
?- assertz(replace_to_nine(X,9)).
```

genutilsパッケージにあるtreeライブラリをインストール

```
?- pack_list(genutils).
?- consult('/Applications/SWI-Prolog.app/Contents/swipl/pack/genutils/prolog/data/tree.pl').
```

要素を全て9に置換

```
?- maptree(replace_to_nine, node(3, [node(1,[node(4,[]), node(1,[])]),node(5, [node(9,[node(2, [])]), node(6,[node(5,[])])])]), node(B, BX)).
B = 9,
BX = [node(9, [node(9, []), node(9, [])]), node(9, [node(9, [node(9, [])]), node(9, [node(9, [])])])].
?- 
```
フォルダ内のcsvファイルを全て読み込む方法3選

# はじめに
フォルダ内にあるcsvファイル(txtなども可)を順番に読み込む方法をまとめました．
任意のファルダ内にある大量のcsvファイルを全部読み込む際にファイルを読み込む命令を一個ずつ書くのではなく，自動で順番に読み込める方法を知りたい方向けに書きました．
個々のcsvファイルを読み込む方法は知ってる前提です．

全3種類のやり方を掲載しています．

# 目次
1. 全ファイルの名前を読み込むパターン
2. 全ファイルのパスをcsvファイルに貼り付けるパターン
3. [globlモジュール](https://docs.python.org/ja/3/library/glob.html)を用いたパターン(一番簡単)

# 1. 全ファイルの名前を読み込むパターン
まずは，インポートします．

```python
import os 
import pandas as pd
```

次は，読み込みたいcsvファイル達が格納されてるフォルダのパスをコピーしてきます．


```python
csv_file=os.listdir('C:/Users/水悟老/Documents/Qiita')
print(csv_file)
>['1日目.csv', '2日目.csv']
print(csv_file[0])
>1日目.csv

#一個目のファイルの読み込み
file1=pd.read_csv('C:/Users/水悟老/Documents/Qiita/'+str(csv_file[0]),engine='python')
```
以上の操作で，大量のcsvファイルの中で一個目のファイルを読み込めました．
中身を確認してみると，

```
print(file1)
>   列1  列2  列3  列4
>0  A君  B君  C君  D君
>1   1    2    3    4
>2   9   10   11   12
```
ちゃんと読み込めてました．

for分を使うことで，順番にcsvファイルを読み込んで処理をするコードが書けます．
簡単な例を以下に示しておきます．
### 実例
A君の合計点を計算

```python
A_sum=0
for i in range(len(csv_file)): #csvファイルの数だけfor分を回す.
  file =pd.read_csv('C:/Users/水悟老/Documents/Qiita/'+str(csv_file[i]),engine='python')
  A_sum += file.iloc[1][0] + file.iloc[2][0]
```

# 2. 全ファイルのパスをcsvに貼り付けるパターン

１．フォルダ内で，csvファイルを全て選択して下さい．
２．「Shift」を押しながら右クリックします．
３．「パスのコピー」をクリック．
４．プログラムを動かしてるフォルダ内に新しくcsvファイル(txtでも可)をつくって貼り付け．

私の場合はこんな感じになりました．

C:￥Users￥水悟老￥Documents￥Qiita￥1日目.csv
C:￥Users￥水悟老￥Documents￥Qiita￥2日目.csv

ここで，「￥」を「/」に全置換(Ctrl+F)します．するとこんな感じ

C:/Users/水悟老/Documents/Qiita/1日目.csv
C:/Users/水悟老/Documents/Qiita/2日目.csv

```python
csv_adress=pd.read_csv('パスを貼り付けたcsvファイル.csv',engine='python')

print(*csv_adress.iloc[0])
> C:/Users/水悟老/Documents/Qiita/1日目.csv
```
では，中身を見てみると

```python
file2=pd.read_csv(*csv_adress.iloc[0],engine='python')
print(file2)
>   列1  列2  列3  列4
>0  A君  B君  C君  D君
>1   1    2    3    4
>2   9   10   11   12
```
ちゃんと開けました～

# 3. globモジュールを用いたパターン(一番簡単)
この記事のコメント欄に[@u1and0](https://qiita.com/u1and0)さんから，もっと簡単なやり方を教えていただいたのでさっそくやってみました．
この方法では[globlモジュール](https://docs.python.org/ja/3/library/glob.html)を使用します．

```python
import glob
glob.glob('C:/Users/水悟老/Documents/Qiita/*.csv')
#['Qiita\\1日目.csv', 'Qiita\\2日目.csv']
```
となりました．
「*.csv」と書くことで，フォルダ内の全csvファイルのパスを得られました．

さっそくcsvファイルを開けてみたいと思います．

```python
file3=pd.read_csv(glob.glob('任意のフォルダ/*.csv')[0],engine='python')
print(file3)
>   列1  列2  列3  列4
>0  A君  B君  C君  D君
>1   1    2    3    4
>2   9   10   11   12
```

上手にできました～～


お疲れさまでした！！!
コードレビューしよう

ソースコード読んでますか？

## コードを読もう

### メリット

- [コードレビューの際に気をつけること](https://qiita.com/awakia/items/8344ba751426e386e0f5) 参照

> 実は初心者ほどコードを読むことが仕事になった方がレベルが上がる
> 特にその後、経験者が別の問題を指摘してしまった時、最もレベルが上がる
> 実は初心者の方が丁寧にレビューするので、**忙しい事が多い経験者エンジニアの負荷も軽減**し、全体として効率が上がる

**忙しい事が多い経験者エンジニアの負荷も軽減!!!**


## コードレビューは難しくない

### 「質問する場」

> 自分がよくわからない部分は質問的に聞いてみる
> 
> よくわからないなと思った部分は大体コードも怪しいです。
> 読みにくい部分を指摘してあげるだけでも十分意味があります。
> 
> この中でも「質問的に聞く」という行為は、初心者じゃなくてもかなり大事です。実際バグを発見するのは聞かれた本人であることも多いです。どんどん質問しちゃいましょう。

### 「質問は難しい？」

- [[あるある]「詰まったら、すぐに質問してください」の克服法](https://qiita.com/yasuX/items/bca386bc47322f22072a)

> わからないことが発生した！
> 「すぐに」質問してと言っていたので、文意のまま即座に質問した・・・
> ( ﾟдﾟ) <「少しは自分で調べたのか！」1 と一蹴！！！チーン(´・ω・｀)
> （すぐ質問してって言ってたのに・・・(´；ω；｀)）

しかし、わからないを積極的に言うことはメリットしか無い。

- [わからないを積極的に言おう - ペパボテックブログ](https://tech.pepabo.com/2020/07/06/say-i-do-not-know/)
- [何がわからないのかわからないはなにもわからない - Qiita](https://qiita.com/e99h2121/items/84f9b97df07e3f943176)
- [質問できるひとは強い - Qiita](https://qiita.com/e99h2121/items/72132c392c072d4ab097)

### 質問力を上げよう

- [質問は恥ではないし役に立つ - Qiita](https://qiita.com/seki_uk/items/4001423b3cd3db0dada7)
- [効果的に質問をしたい人のための質問テンプレート、不吉なワードチェックリスト、15分ルール - Qiita](https://qiita.com/e99h2121/items/95129fe0e94d2ed1120b)


### まずは「自分ごと」にする

できることが増えるのは楽しい。

> ソースコードはプロジェクトの共同所有物である
> 誰かだけが触れるコードを無くす
> 自分だけが持っているコードを無くす
> 自分だけが触っている時間を短くする

> コードレビューは...
> 相互学習型のプロセスである
> メンバが成長することが大事

> 質問することで学ぼう
> 一番できる誰かだけが教えるのではない
> 知識や経験の少ない人が何に躓いているのか学ぼう
> メンバの成長
> 同じミスをチーム内で繰り返さないことが成長
> 
> 本人の問題にしない
> 明日はわが身

- 参考: [コードレビューの基本](https://gist.github.com/taichi/b36c135001c161aeb1b240327ed044d6)
- [無理をしないコードレビュー](https://techlife.cookpad.com/entry/2018/06/19/110000)


## ほか参考資料

[Code Conventions for the Java Programming Language: Contents](https://www.oracle.com/java/technologies/javase/codeconventions-contents.html)

以上、チームでソースコードレビューをもっと効果的にできないかなと思い、書いたもの。
Rubyのクラスとインスタンスについて

# プログラミングの勉強日記
2020年7月11日　Progate Lv.175
RubyⅣ

#クラスとインスタンス
　ここでは簡単にクラスとインスタンスについて説明する。プログラミングでメニューという「もの」を作るためには、まずその設計図が必要でとなる。設計図をクラス、「もの」をインスタンスという。（設計図（クラス）をもとに「もの」（インスタンス）を生成）なので、インスタンスを生成するためにはクラスを用意し、クラスからインスタンスを作成、そしてインスタンスに情報を追加する。

#クラスの定義
　クラスは`class クラス名`で定義できる。<font color=blue>クラスは必ず大文字ではじめ、`end`を忘れずに書く。</font>

```ruby:index.rb
class Menu
end
```

#attr_accessor
　インスタンス変数を直接変更して操作ができるようにするもの。情報を持たせるために`attr_accessor シンボル`と書く。1つのクラスに対して複数のインスタンス変数を使うこともできる。

```ruby:index.rb
class Menu
  attr_accessor :name
end
```

#インスタンスの生成
　クラスを元に新しくインスタンスを生成するためには`クラス名.new`とする。`変数名=クラス名.new`とすることで生成したインスタンス変数を代入できる。
　インスタンスに情報を持たせるためには、クラスで用意したインスタンス変数に値を代入する。`インスタンス.変数名=値`でインスタンス変数に値をセットすることができる。

```ruby:index.rb
class Menu
  #処理
end
#変数menu1にMenuクラスからのインスタンスを生成し、代入する
menu1=Menu.new
menu1.name="すし"
```

#クラスの中でメソッドを使う
　クラスの中で定義したメソッドはインスタンスに対して使うようにして呼び出す。`インスタンス.メソッド名`で呼び出す。クラスの中で定義したメソッドを呼び出すものをインスタンスメソッドという。

```ruby:index.rb
class Menu
  attr_accessor :name
  attr_accessor :price
  #クラスの中でメソッドを定義
  def show
    puts "menu"
  end
end
menu1=Menu.new
#クラスの中で定義したメソッドの呼び出し
menu1.show
```

```:コンソール
menu
```

#インスタンスメソッド
　クラスの中で定義したインスタンスに対して呼び出すメソッドのこと。引数を受け取ったり戻り値を返したりすることができる。インスタンスが持つ情報である「インスタンス変数」とインスタンスに対して呼び出すインスタンスメソッドはクラスの中で定義する。

```ruby:index.rb
class Menu
  #処理
  def show(data)
    return "#{data}です"
  end
end
menu1=Menu.new
puts menu1.show("メニュー")
```

```:コンソール
メニューです
```

#インスタンスメソッドの中でインスタンス変数を使う
　インスタンスメソッドの中では特殊な変数`self`を用いて`self.変数名`とすることで、インスタンス変数を扱える。インスタンスメソッドでは変数`self`に呼び出したインスタンス自身が代入されている。

```ruby:index.rb
class Menu
  #処理
  def show_name
    puts "#{self.name}です"
  end
end
menu1=Menu1.new
menu1.name="すし"
#インスタンスメソッドの呼び出し
menu1.show_name
```

```:コンソール
すしです
```

#initializeメソッド
　インスタンスを生成した直後に処理を実行できる。`クラス名.new`でインスタンスを生成した直後に自動で呼び出される。

```ruby:index.rb
class Menu
  #処理
  def initialize
    puts "メニュー"
  end
end
#Menu.newが実行されると自動でinitializeメソッドを呼び出す
menu1=Menu.new
```

```:コンソール
メニュー
```

　インスタンスメソッドの中では`self.変数名`でインスタンス変数を扱うことができ、`self.変数名=値`でインスタンス変数に値を代入する。

```ruby:index.rb
class Menu
  #処理
  def initialize
    self.name="すし"
  end
end
menu1=Menu.new
puts menu1.name
```

```:コンソール
すし
```

##initializeメソッドの変数
　initializeメソッドにも引数を渡すことができる。`クラス.new`に対して引数を渡すことでその値を渡せる。もちろんキーワード引数を用いることもできる。

```ruby:index.rb
class Menu
  #処理
  def initialize(message)
    puts message
  end
end
menu1=Menu.new("Hello")
```

```:コンソール
Hello
```

#require
　ファイルの読み込みを行う。(main文がわかれていて、別のファイルのクラスを読み込みたいときに使う）

```ruby:index.rb
requie "./menu"
menu1=Menu.new(name: "すし"
```

```ruby:menu.rb
class Menu
  attr_accessor :name
  attr_accessor :price
end
```

#gets.chomp
　入力を受け付けるときに使う。このコードが実行されるとコンソールが入力待機状態になる。`変数=gets.chomp`とすることでエンターキーを押されるまで入力された値を変数に代入できる。

```ruby:index.rb
puts "名前の入力"
name=gets.chomp
puts "あなたの名前は#{name}です"
```

```:コンソール
名前の入力
田中（入力する）
あなたの名前は田中です
```

　数値を受け取る場合は、`gets.chomp.to_i`とすることで入力された内容を数値に変換できる。

```ruby:index.rb
puts "数字の入力"
number=gets.chomp.to_i #入力された内容を数値に変換
puts "#{number}の2倍は#{number*2}です"
```