OmniAICreator/Qiita-1.07M huggingface dataset:
第10回 レイヤ1 リピータ・ハブ

リピータの機能
---
信号は抵抗によって減衰する。さらには、ノ
イズによって信号の形が崩れてしまう。

メディアには最長距離があるように、信号を
送っても届かない場合がある。これを避ける
ためにリピータによって増幅や整形すること
により、元の信号と同じ強さ、同じ形に戻す。


ハブ
---
ハブは別名マルチポートリピータという。多
くのケーブルを差し込むことができるリピー
タのこと。

通常、リピータは入口と出口の2本のケーブル
をつなぐことしかできない。

![Untitled (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602995/a284c455-8369-e652-b2da-df91adeffcb0.png)


多くの機器をつなぐときに使用され、LANで
用いられる一般的な機器である。LANの中心
点メディアの接続地点として使われる。


共有メディア環境
---
ハブを介しても、役割としてあくまで増幅や
整形のみであるため、通過する信号という観
点でみれば、全ての機器は同じメディアを使
用している。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602995/131dc2b5-2e1e-11a1-2468-2e51cc1ded66.png)


このように、同じメディアを複数の機器が使
用している環境を共有メディア環境という。


衝突ドメイン
---
このような環境では、信号の衝突が発生する
可能性がある。同軸ケーブルであれツイスト
ペアケーブルであれ、結局ハブ内が1つの伝送
路しか持たないため衝突の可能性がある。

この衝突の可能性がある範囲のことを衝突ド
メインという。衝突を防ぐためにスイッチや
ルータを用いている。


リピータ・ハブ同士の接続環境
---
リピータによる増幅を行う際に実は多少のラ
グが発生する。数多くのリピータを使用する
と、その遅延時間が多くなりすぎるため、制
限が設けられている。

10BASE-Tなら4つ、100BASE-Tなら2つと設け
られている。

参照URL：
<a href="http://www5e.biglobe.ne.jp/~aji/3min/">3分間ネットワーキング</a>
第9回 ネットワーキングメディアの種類

ネットワーキングメディアの種類
---
数あるネットワーキングメディアの中でも
主にLANで使われるメディアを話す。

特に3種類のネットワーキングメディアを
ご紹介。銅線1種類と光ファイバ2種類。


ネットワーキングメディアの規格団体
---
ネットワーキングメディアは3つの規格団体
が影響力を持っており、IEEEとEIA/TIA、UL
の3種。

3種のネットワーキングメディアとは
・同軸ケーブル
・ツイストペアケーブル
・光ファイバケーブル


同軸ケーブル
---
同軸ケーブルはLANケーブルだけでなく、TV
アンテナ線などに使われている。

![09141157_5b9b23b797313.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602995/358befd9-e2af-0eea-eebf-029cefd3ac43.jpeg)

中央の茶色が導体となり、ここを信号が通
る。銅線の上にあるのはプラスティックの
絶縁体、一番外にあるのはプラスティック
製の皮膜(ジャケット)。黄色の網状のもの
は銅もしくは金で作られた網状の素材でシ
ールドという。外部からの干渉を防ぐ楯の
ようなもの。

シールドのおかげで、同軸ケーブルは干渉
に強く、干渉に強いため、長距離まで信号
が届く。

ツイストペアケーブル
---
ツイストペアケーブルは8本の細い銅線をま
とめた構造をしている。絶縁体となるプラス
ティックが外をコーディングしている構造。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602995/57f636af-3f36-40ab-390a-fdac4ee2f882.png)


8本を2本ずつ4つの組にして、お互いをより合
わせている。これにより、電流が流れた際に
2本の銅線から発生する磁場が互いに打ち消し
あい消滅する構造。

これが外部からの干渉も消すことができ、
キャンセレーションという。

ツイストペアにもシールドのないものもあり、
それを非シールドツイストペア(UTP)という。

特徴としては、シールドほど干渉に対する防
御が強くなく、長距離に向いていない。


光ファイバケーブル
---
中央の線が反射率の高いガラス製の信号が
通る部分。

![Untitled.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602995/6c984749-d903-94f0-df5e-37a0d6350005.jpeg)


周りをプラスティックが覆っている構造で、
外のピンクが干渉保護材として機能している
。ケブラーという防弾チョッキにも使われる
繊維でガラスを保護している。

1本の協力なレーザー光を通すタイプをシン
グルモード、複数の弱い光を反射させるタイ
プをマルチモードという。

特徴としては、一切の電波的な干渉を受け
ない。かつ高速である。


ネットワーキングメディアの規格
---
これらのケーブルはIEEEやEIA/TIAによる標準
化がされている。

<table>
<tr>
<th>規格名</th>
<th>ケーブルの種類</th>
<th>備考</th>
</tr>
<tr>
<td>10BASE5</td>
<td rowspan=2>同軸</td>
<td>別名：Thicknet(シックネット)</td>
</tr>
<tr>
<td>10BASE2</td>
<td>別名：Thicknet(シックネット)</td.
</tr>
<tr>
<tr>
<td>10BASE-T</td>
<td rowspan=3>UTP</td>
<td>最長距離：100m</td>
</tr>
<tr>
<td>100BASE-TX</td>
<td>最長距離：100m</td>
</tr>
<tr>
<td>1000BASE-T</td>
<td>最長距離：100m</td>
</tr>
<tr>
<td>100BASE-FX</td>
<td rowspan=3>光ファイバ</td>
<td>最長距離：ﾏﾙﾁﾓｰﾄﾞ412m または2Km

　　 　　　　ｼﾝｸﾞﾙﾓｰﾄﾞ20km</td>
</tr>
<tr>
<td>1000BASE-SX</td>
<td>最長距離：ﾏﾙﾁﾓｰﾄﾞ550m</td>
</tr>
<tr>
<td>1000BASE-LX</td>
<td>最長距離：ﾏﾙﾁﾓｰﾄﾞ･ｼﾝｸﾞﾙﾓｰﾄﾞﾞ5Km</td>
</tr>
</table>
[Table09-02:IEEEによるケーブルの規格]

規格名の数字はデータ転送量を示し、単位は
M(メガ)bps。「BASE」はベースバンド転送、
通信を直接多重化しないで送る方式。

ディジタル信号のように、信号の強弱で送る
方式であるため、複数の信号を同時に銅線上
に流せない。これが現在のLANでの主流な方
式。

逆に同軸ケーブルのように1本しか銅線がな
い場合、同時に流せる信号は1つだけとなる。
ツイストペアならば1組ずつで4つの信号を
流すことが可能。

同軸の場合、10BASE5や10BASE2などがある
が「10」「5」という数字が最長距離を示し
ており、今回でいえば、500mとなる。

参照URL：
<a href="http://www5e.biglobe.ne.jp/~aji/3min/">3分間ネットワーキング</a>
[React]Material UIでレスポンシブ対応

# 本記事の目的
Material UIが@mui/materialからインポートするようになってから、
useStyles,makeStylesの組み合わせの使用が非推奨になりました。
それに伴い、レスポンシブ対応をするには、以前まではtheme.breakpointsを使用するケースが大半だったと思うのですが、それ以外のやり方でレスポンシブ対応させるやり方を調べましたのでまとめます。



やり方は以下の通りです。

①media queryを使用する場合
②useMediaQueryを使用する場合


## ①media queryを使用する場合

``` box.tsx

<Box component="div" sx={{
    fontSize: "1rem",
    "@media screen and (min-width:600px)": {
        width: "40%",
    },
}} >
    sample box
</Box>

```

```box.tsx

import { styled } from "@mui/material/styles"
import Box from "@mui/material/Box

const StyledBox = styled(Box)(() => ({
  fontSize: "1rem",
    "@media screen and (min-width:600px)": {
        width: "40%",
    },
}))

```
sx内に直接書く、ないしはstyledのなかに上記のように書き記すやり方です。

## ②useMediaQueryを使用する場合

``` box.tsx

import useMediaQuery from "@mui/material/useMediaQuery"

const SampleBox = () => {
  const matches: boolean = useMediaQuery("(min-width:577px)")
  {matches ? (
     <Box component="div">
            Sample Box
     </Box>
  ) : (
    <Box></Box>
  )}
}
```

また、Material UIのブレイクポイントを使用しても記載ができます。

``` ts
const matches: boolean = useMediaQuery(() => theme.breakpoints.up("sm"));
```
ただ、このやり方だと記述量が非常に多くなってしまうため、おすすめではありません。

#### 参考記事

[Material UIでのレスポンシブサイト作成](https://zenn.dev/tns_00/articles/material-ui-styling "Material UIでのレスポンシブサイト作成")
"コンポジション"を知らなかったので軽く調べてみた

# コンポジションとは
日本語で「混合物」を意味したもので、`あるクラスの機能を持つクラス`のことを指しています。

特定クラスの機能を、自分が作るクラスにも持たせたい場合に、継承を使わずにフィールドとしてそのクラスを持ち、そのクラスのメソッドを呼び出すメソッドを持たせることで、クラスに他のクラスの機能を組み込むことができる。

## メリット

- 「機能の継承」はクラスの関連図をイメージする際の分かりにくさを回避できる
- メソッドをワンクッション置くことで融通を効かせられる
- コンポジションの対象となるクラスは、そのサブクラスも使用できる

## デメリット
- 同じメソッドを作らなければならない
- コンポジションの対象となるクラスに変更があった場合には同じように変更しなければならない。

## 継承とコンポジションの使い分け
厳密なオブジェクト指向では、継承は「機能の継承」を目的とせず`「スーパークラスはサブクラスの一種である」`といういわゆる「is-aの関係」を持たなければならないため、単に機能を持たせたい場合には、`継承ではなくコンポジションとすることが推奨`される。

使い分けるために、一般的な物の考え方の一つに「分類」と「分割」がある。

分類とは、「is-aの関係」のことであり`AはBである`ということです。
例えば、「犬は動物である」「人間は動物である」・・・など、これらは分類で表現することが出来る。
is-aの関係で表せるものは、`継承で表現する`のが都合がいい。

分割とは、「has-aの関係」のことであり`AはBを含んでいる`ということです。
例えば、「学校は先生を含んでいる」「自転車はサドルを含んでいる」・・・など、これらは分割で表現することが出来る。
has-aの関係で表せるものは、`コンポジションで表現する`のが都合がいい。

# まとめ
- 再利用には継承よりもコンポジションを使うべき
    - 継承は「それを継承したオブジェクトは同じものとして扱える」ことを保証するためであり、コンポジションは「合成したものは部品に分解できる」ことを保証するものなので、部品のほうが再利用しやすい。

- なるべくコンポジションを使ったほうが良さそう
    - 部品が単純かつ不変な値オブジェクト(文字列や数など)は「属性」にまとめたほうがスッキリする。
zipコマンドでディレクトリをパスワード付きで圧縮する

納品のたびに毎回検索しているので備忘録として残しておく。
環境はMac。

## パスワード無しで圧縮
```
$ zip -r 圧縮後の名前 圧縮するディレクトリ名
```

## パスワード付きで圧縮
```
$ zip -e -r 圧縮後の名前 圧縮するディレクトリ名
```

# 参考
https://www.server-memo.net/tips/zip_password.html
Shopify CLIで「shopify theme serve」実行時のエラー「 Make sure you are a user of that store, and allowed to edit themes.」の対処法

* 環境
    * Mac M1
    * ブラウザ　Crome
    * Vs code
    * shopify version  2.10.2

# 対処法
Shopify　CLIを利用して、ローカルで開発するタイミングでターミナルで「shopify theme serve」といコマンドを実行時に「 Make sure you are a user of that store, and allowed to edit themes.」というエラーが出たときの対処法は以下になります。

### ターミナル上でログアウト
```
shopify logout 
```
上記エラーが出ている場合、既にログインしているはずなので一旦ログアウトします。

### 対象ストア画面で別メールアドレスを習得してユーザーを追加
対象のストア画面でスタッフユーザーを作成して、以下の画面のようになるように追加します。
管理者権限を持つパートナーアカウントを介してログインしていても、対象ストアでスタッフアカウントの作成が必要です。
メールアドレスがない場合は、無料の使い捨てメールアドレスサービスを利用すれば良いです。
そして、作成したスタッフアカウント宛に届いたメールから一度ログインまで進め、ログアウトしてください。

![スクリーンショット 2022-03-23 16.58.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603875/4409f072-b0ef-af8e-bf0b-60ecc5395225.png)

### ストア画面からログアウト
ブラウザ上でログアウト後、Macなら「shift+command+R」でキャッシュクリアしてください。
（キャッシュクリアしないことで、後の認証時にエラーになるようです） 

### ログアウト後、ログインするURL
https://｛xxxxxxx｝.myshopify.com/admin/
このように対象ストアURLの後ろにadminを加えて、ブラウザ上からアクセスします。
{}の中は適宜変更してください。
ログイン画面でも念のために「shift+command+R」でキャッシュクリアしました。

###　ログイン後は、ターミナルに切り替えて、再度ログイン
```
shopify login --store [ストアURL]
```
そして、再度以下を実行
```
shopify theme serve
```


これでダメなときは3回程度、ターミナル上でログアウトして再度ログインからserveを繰り返し実行してください。
私の場合は2回でうまくいきました。

#### 注意点
上記の紹介は、概ねは合っていると思いますが、記憶に頼って書いている部分もあります。


#### 参考
* https://github.com/Shopify/shopify-cli/issues/1412
* https://masa-engineer-blog.com/shopify-cli-getting-started/
【オブジェクト指向】ダックタイピング/ポリモーフィズムを簡単にまとめてみた

# ダックタイピングとは
ダックタイピングについて、ある有名な格言があります。

```
"If it walks like a duck and quacks like a duck, it must be a duck"
（もしもそれがアヒルのように歩き、アヒルのように鳴くのなら、それはアヒルである）
```

これをオブジェクト指向的に言い直すと、、、
`「誰か」ではなく「何をするか」によってオブジェクトを見分ける`ということです。
どのクラスに属しているオブジェクトなのかということは意識しないです。

# ポリモーフィズムとは
単純な言葉の意味は`「多態性」「多様性」`という意味です。「同じメソッド名が異なる複数のオブジェクトに属す」ということです。メソッド名が同じでも、オブジェクトによって処理結果が変化します。

## 例
まずは以下のコードを見てください。

```ruby
str = 'test'
puts str.slice(1)
# => "e"

arr = [1, 2, 3]
puts arr.slice(1)
# => 2
```

同じメソッド(slice)ですが処理しているオブジェクトは違います。
メソッド側からすると文字列でも配列でも変わらず処理を行える、これこそが`「ダックタイピング/ポリモーフィズム」`ということです！
Laravelのバリデーションの基本【個人的なお勉強アウトプット】

## 参考図書
https://www.amazon.co.jp/dp/B07CLLW4MX/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1

## バリデーションルールの設定
ValidateRequestsというコントローラクラスにあるメソッドを利用する。
```app/Http/Controllers/HelloController.php
public function post(Request $request){
$validate_rule = [
            'name' => 'required',
            'mail' => 'email',
            'age' => 'numeric|between:0,150',
        ];
$this->validate($request, $validate_rule);
}
```
validateアクションメソッドは配列の形で、項目名、検証ルールをセットする。
検証ルールが複数ある場合は`|`でつなぐ。

## ルートの設定
```routes/web.php
Route::post('hello', 'App\Http\Controllers\HelloController@post');
```

## ビューでエラーメッセージの表示
```resources/views/hello/index.blade.php
@section('content')
    <p>{{$msg}}</p>
    @if(count($errors) > 0)
    <p>入力に問題があります。再入力してください。</p>
    @endif
    <form action="/hello" method="post">
        <table>
            @csrf
            //hasはエラーが発生しているかをチェックするメソッド
            @if($errors->has('name'))
　　　　　　　　　　　　　　　　　　　　　　　　
　　　　　　　　　　　　　　　　　　　　　　　　//firstというメソッドは指定した項目の最初のエラーメッセージを取得するもの
            <tr><th>ERROR</th><td>{{$errors->first('name')}}</td></tr>
            @endif
　　　　　　　　　　　　　　　　　　　　　　　　//oldメソッドで引数に指定した入力項目の前回送信した値を返す
            <tr><th>name: </th><td><input type="text" name="name" value="{{old('name')}}"></td></tr>
            @if($errors->has('mail'))
            <tr><th>ERROR</th><td>{{$errors->first('mail')}}</td></tr>
            @endif
            <tr><th>mail: </th><td><input type="text" name="mail" value="{{old('mail')}}"></td></tr>
            @if($errors->has('age'))
            <tr><th>ERROR</th><td>{{$errors->first('age')}}</td></tr>
            @endif
            <tr><th>age: </th><td><input type="text" name="age" value="{{old('age')}}"></td></tr>
            <tr><th></th><td><input type="submit" value="send"></td></tr>
        </table>
    </form>
@endsection
```
$errorsはバリデーションで発生したエラーメッセージをまとめて管理するオブジェクト。バリデーション機能によって勝手に組み込まれる。

## エラーメッセージを取得するメソッド

|  メソッド |  内容  |
| ---- | ---- |
|  all  |  すべてのエラーメッセージを配列で取得  |
|  first  |  指定した項目の最初のエラーメッセージを文字列で取得  |
|  get  |  指定した項目の最初のエラーメッセージすべてを配列で取得  |



getの使い方はfirstと同じで`$変数 = $errors->get('項目名');`
Cloud Functionsのエラー通知

# エラーに会いに行く
Cloud Functionsでエラー検知したいときありますよね。
その仕組みを今回作ります。

# トピック作成
まずは、Pub/Sub→トピックから通知用の「トピック作成」をします。
コンボ開始です。

# シンク作成
次にロギング→ログルーターでシンクを作成します。
名前と説明を決め、シンクの宛先で「Cloud Pub/Sub トピック」を選択します。
「シンクに含めるログの選択」で下記のように入力します。
タイミングはそこまでシビアではないので、落ち着いて入力してもらえればと思ってます。
内容はfunction_name以外はそのままでいいと思います。

```
resource.type="cloud_function"
resource.labels.function_name="SampleFunction"
severity>=ERROR
```

# CloudFunctions作成
あとは、起き攻めよろしく、エラー通知用にトリガーのタイプを「Cloud Pub/Sub」にしたCloudFunctionsを作成します。
単純にSlack通知します。

```
// Package p contains a Pub/Sub Cloud Function.
package p

import (
	"context"
	"crypto/tls"
	"fmt"
	"log"
	"net/http"
	"net/url"
)

const WebHook = "Slack WebHook Url"

// PubSubMessage is the payload of a Pub/Sub event. Please refer to the docs for
// additional information regarding Pub/Sub events.
type PubSubMessage struct {
	Data []byte `json:"data"`
}

// HelloPubSub consumes a Pub/Sub message.
func HelloPubSub(ctx context.Context, m PubSubMessage) error {
	err := slackNotify(WebHook, string(m.Data))
	if err != nil {
		log.Printf("err %v",err)
		return err
	}
	return nil
}

func slackNotify(webhook string, data string) error {
	payload := fmt.Sprintf("{'text': '<!channel> \n```%s```'}", data)
	values := url.Values{}
	values.Add("payload", payload)
	http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
	_, err := http.PostForm(webhook, values)
	if err != nil {
		return err
	}
	return nil
}
```

現場からは以上です。
WebブラウザはDELETEリクエストを発行できない

# ハマったこと
下記のようにdeleteリクエストを指定して送信したがGETメソッドになってしまう。
``` ruby: _header.html.erb
<%= link_to "Log out", logout_path, method: :delete %>
```
#### 出たエラーメッセージ
Routing Error
No route matches [GET] "/logout"

# 原因
どうやらブラウザからDELETEリクエストを送ることができないみたいです。

# 対策
link_toメソッドではなく、button_toメソッドで解消できるみたいです。
もっといいやり方ないんだろうか、、、
``` ruby _header.html.erb
<%= link_to "Log out", logout_path, method: :delete %>   # 削除した
<%= button_to "Log out", logout_path, method: :delete %>   # 追加した
```
button_toタグを使用すると、生成されるHTMLによりデザインが変わってしまいます。
jsを正しく、読み込めばlink_toメソッドのままdeleteリクエストを送れるみたいです。

# 参考にした記事
[railsのdeleteリクエストについて納得できない](https://teratail.com/questions/305773)
理由も乗ってます。
【Docker】WSL 2 installation is incomplete.の対処方法

<h2>環境</h2>
windows11

<h2>症状</h2>
Docker desktopをインストールしたところ、下記のエラーが表示されました。
翻訳すると、「WSL2のインストールが不完全です」と言われていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927880/68fcf9e9-f220-1638-5dac-9aa24c328bd5.png)

拡大

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927880/f889c2db-37bc-40d8-cd21-ad6ad93ebe5b.png)


urlを発火させると、ここに飛びました。

https://docs.microsoft.com/ja-jp/windows/wsl/install-manual#step-4---download-the-linux-kernel-update-package



<h2>解決方法</h2>
下記からLinuxカーネル更新プログラムをインストールします。

https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi

Linuxアップデートセットアップウィザードが表示されるので「Next」を押下。
そのまま、「finish」を押下して完了させます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927880/81c52e1f-c37e-b3b8-90b4-582ba7bb7096.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927880/4ba82c1b-6963-34e6-68ca-ae7ec9bc0a22.png)

そのあと、さっきのダイアログに戻って「Restart」を押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927880/f889c2db-37bc-40d8-cd21-ad6ad93ebe5b.png)

すると、エラーが解消されました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927880/ca117571-f922-513a-bd85-9e26d36c7080.png)


<h2>参考</h2>

https://www.docker.com/get-started/

https://takabus.com/tips/326/
第8回 レイヤ1 信号と回線

信号
---
信号には2種類あり、ディジタルとアナログで
ある。

アナログ信号は波を指し、ディジタルはON/OFF
のようなイメージ。

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602995/d9fb33f5-757e-176c-10ba-2f33bc4a4b4a.png)


回線
---
2種の信号をどちら使うかは通信回線に依存
する。

余談だが、一般電話回線がまさにアナログで
あり、あれはモデム(MODEM)を用いている。
モデムはコンピューターのディジタル信号を
電話用のアナログ信号に変換してくれる装置
である。

一般的に有名なディジタル信号はISDNである。

![Untitled (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602995/40ac3505-b9a2-a50d-a3e4-eacd8c7b5bfa.png)

ケーブルモデムは、CATVで使用されているケ
ーブルとの接続に使用されるモデムである。

ADSLモデムとケーブルモデムの特徴は、普通
のモデムと違い、パソコンとLANケーブルで
接続される箇所である。

普通のモデムは「EIA/TIA-232」という規格で
作られたケーブルで接続する。これは非常に
普及している規格で、パソコンならばシリア
ルポートという名前で接続口がある。

ADSLは普通の電話で使う音声信号と、通信用
のデータ信号の2つの信号が同じ回線に流れて
いる。音声信号は電話機へ、データ信号はADS
Lモデムへと振り分ける装置がスプリッタであ　
る。


信号に起きる障害
---
ディジタル信号にしろアナログ信号にしろ、
電気信号にしろ、問題がよく起こる。特に問
題となるのが、減衰、ノイズ、衝突だ。

まずは減衰だが、ケーブルに使われる銅線に
は抵抗が存在する。その抵抗によって、電
気信号が弱まる、つまり減衰する。

次にノイズ。これは何らかの原因により、
電気信号の形が崩れてしまうことを指す。

※原因の一例
```
すぐ隣の銅線に信号が流れている(クロストーク)
熱雑音
AC電源がそばにある
雷や無線、蛍光灯などがそばにある(EMI/RFI)
クロストーク→漏話という意味で、
　　　　　　 隣の信号が影響すること
EMI→電波干渉
RFI→無線周波干渉
```

参照URL：
<a href="http://www5e.biglobe.ne.jp/~aji/3min/">3分間ネットワーキング</a>
"デメテルの法則"とは何かを知っておく必要がありそうだな

# デメテルの法則(Low of Demeter)とは？
最小知識の原則（principle of least knowledge）とも呼ばれる、「ソフトウェアの設計(特にオブジェクト指向プログラムの設計)」におけるガイドラインのことで、基本的な考え方は`「任意のオブジェクトが自分以外（サブコンポーネント含む）の構造やプロパティに対して持っている仮定を最小限にすべきである」`というモノです。

分かりやすくいうと、、

```ruby
「親クラス.子クラス.子クラスのメソッド」 # これはNG
```

## デメテルの法則に則った場合に呼び出せるメソッドは？
オブジェクト＝Object
メソッド＝オブジェクトが使えるメソッド
とする。

```ruby
- オブジェクト自身
- メソッドの引数に渡されたオブジェクト
- メソッドの内部でインスタンス化されたオブジェクト
- オブジェクトを直接的に構成するオブジェクト（オブジェクトのインスタンス変数）
- 呼び出し用のメソッドまたは属性として同じクラス内で宣言されたオブジェクトのメソッド
```

## メリット
- テストや修正が楽になる。

## デメリット
- 密結合になり、子クラスでメソッドやプロパティを削除したときに親クラスまで参照して直さないといけない。
- テストがしづらい。
第7回 LANの機器

LANで使われるもの
---
LANを構築する際に必要なものとして、パソ
コンやパソコンをつなぐケーブルなどがある
。

パソコンやプリンタなどをホスト、ケーブル
をネットワーキングメディアという。

他に必要なものとして、NICもある。これは
パソコンとケーブルとつなげる機械を指す。


ネットワーキング・デバイス
---
上記の説明はあくまで1対1の話であり、複
数のパソコンとの接続には通信を制御する
機器が必要となる。

この制御機器は、通信伝送における信号の
役割や案内看板の役割も行う。


レイヤ別 ネットワーキング・デバイス
---
役割ごとに大きく分けて3種類あり、レイヤ
1・2・3の各レイヤに従った役割を持つ。

レイヤ1・物理層では、電気・機械的な規則
の層であり、制御を行う機器はリピータと
ハブ。

これらはケーブルを流れる電気信号を、増
幅したり分配したりする。

レイヤ2・データリンク層では、ブリッジと
スイッチ。スイッチはスイッチング・ハブ
と呼ばれることが多い。

ブリッジ・ハブは信号の役割をしていて、
とあるルールにのっとり、データを通す・
通さないの制御を行う。

レイヤ3・ネットワーク層では、ルータ。
宛先までのルートを決定する役割を持つ。

これらの制御機器をネットワーキングデ
バイスという。

参照URL：
<a href="http://www5e.biglobe.ne.jp/~aji/3min/">3分間ネットワーキング</a>
第6回 OSI参照モデルとカプセル化

OSI参照モデルでのデータの流れ
---
データの流れは下記の通り。
「送信元→宛先」

通信では運びたいものをデータ、そこに
入れた段ボール全体をデータユニットと
いう。

通信に限らず、運びたいもの(データ)以外
にも必要なものが存在する。宛先、送信
元アドレス、通信制御用データなどなど。


カプセル化
---
OSI参照モデルでは、上の層から順番に制御
データをつけていく。最下層のレイヤ1まで
行くと電気信号化され、相手に送られる。

レイヤ4の制御情報が付随したデータをセグ
メント、レイヤ3の制御情報がつくとパケッ
トという。

データユニットは通信に使うデータ、セグ
メント、パケット、フレームの総称を指す
。

このようにデータに制御データをつけて、
データグラムに仕上げることをカプセル化
という。

参照URL：
<a href="http://www5e.biglobe.ne.jp/~aji/3min/">3分間ネットワーキング</a>
VSCodeでcommand+[が使えない

## 環境
MacBook Air (M1, 2020)
MacOS Monterey 12.2.1
VisualStudioCode 1.65.2

## 症状
コマンドキーと`[`（左角かっこ）の同時押しがVSCodeに認識されない。インデント解除が簡単にできなくて地味に不便。
`command`+`shift`+`[`とかも認識しないが、`command`+`]`（右角かっこ）とかは認識する。  
FinderやChromeでは使えるのでVSCode側の問題らしい。  

## 対応方法
`command`と`[`と同時に`fn`を押すと認識されるそう。  
https://github.com/microsoft/vscode/issues/136934  
`command`+`shift`+`[`とかも同じようにちゃんと認識させられた。

毎回そんなことしてられないので、Karabinerで設定する。  
https://gist.github.com/fukayatsu/c93d036e0b6cc010289facb67fc325e8  
似たようなことしている人がいたのでそれを使わせてもらったが、この人は同時押しをcapslockで挟んでいた。  
それでも動いたけどなんとなく気持ち悪いので先に見つけた`fn`との同時押しに変えて使っている。  
```JSON
"to":[
  {
    "key_code":"open_bracket",
    "modifiers":[
      "command",
      "fn"
    ]
  }
]
```
こう置き換えても問題なく動いた。
【Java】「Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty」の対処方法

# まえがき

環境構築時にこの問題にでくわし、4時間ほど時間とられたので記録として残しておく( ´_ゝ`)

# 参考

https://www.komina.info/archives/612

# 原因
・OpenJDK8では`trust store($JAVA_HOME/lib/security/cacerts)`が空。

# 対処方法
・OpenJDK11からとってくる。
Chaiでオブジェクトのキーが存在するかチェックする方法


# chaiとは
**chai**とは、アサーションライブラリのこと。
JavaScriptのテストフレームワークである**mocha**のように、アサーションの機能がない場合に**chai**などのアサーションライブラリを使用する。
**chai**のインストールも``npm``を使ってできる。

# オブジェクトにキーが存在するかチェックする方法
**chai**でオブジェクトにキーが存在するかチェックするための``assert``を5つまとめておく。

■ **.hasAllKeys**
指定されたキーだけが全て存在するかチェックする。
■ **.doesNotHaveAnyKeys**
``.hasAllKeys``の否定。

■ **.hasAnyKeys**
指定されたキーの内、少なくとも1つ存在するかチェックする。
■ **.doesNotHaveAllKeys**
``.hasAnyKeys``の否定。

■ **.containsAllKeys**
指定されたキーが全て含まれているかチェックする。

ここで、**.hasAllKeys**は指定されたキーに対してオブジェクトに存在するキーが多くても少なくてもダメだが、**.containsAllKeys**は指定されたキー以外のキーが含まれる（指定さえれたキーより多くキーが存在する）可能性がある。

それぞれの基本的な書き方は、同じで以下のようになる。

```javascript
// 基本的な書き方
asseert.hasAllKeys(<オブジェクト>,<チェックしたいキーの配列>)

//例
const obj = {
    id: 1,
    class:1,
    name: ryota,
};

asseert.hasAllKeys(obj,["id", "class", "name"]);
```

# 参考
[https://www.chaijs.com/api/assert/](https://www.chaijs.com/api/assert/)
Javaのclassを逆コンパイルする

# 公式
https://github.com/skylot/jadx

# 動作環境
- MacOS BigSur
- Java8


# Jadのインストール

```terminal
brew install jadx
```

# 使い方

```terminal
jadx hello.class
```

# オプション

|オプション|概要|
|:--|:--|
|-d, --output-dir|出力先|
グローバルミドルウェアとミドルウェアのグループ登録【個人的なお勉強アウトプット】

## 参考図書
https://www.amazon.co.jp/dp/B07CLLW4MX/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1

## グローバルミドルウェア
すべてのアクセスで自動的にミドルウェアが実行されるようにしたい場合、グローバルミドルウェアに登録する
```app/Http/kanel.php

protected $middleware = [
...
...
\App\Http\Middleware\HelloMiddleware::class,
];

```

## ミドルウェアのグループ登録
複数のミドルウェアをまとめて扱える。
```app/Http/kanel.php
'web' => [
...ミドルウェアクラス
],

'api'=> [
...ミドルウェアクラス
],

'helo' => [
\App\Http\Middleware\HelloMiddleware::class,
].
```

### ルートにグループミドルウェアを登録
```/routeeb.php
Route::get('hello', 'App\Http\Controllers\HelloController@index')->middleware('helo');
```
オブジェクト指向を理解するために"SOLID原則"を理解しよう！

# SOLID原則とは？
5つのソフトウェア開発原則の頭文字をとったソフトウェア構築時に従うべきガイドラインで、ソフトウェアの拡張性や保守性を高めるためのものです。
これはソフトウェアエンジニアのRobert C. Martin氏が提唱したモジュール間の接続概念です。

## S：Single Responsibility Principle(単一責任の原則)
クラスが複数の責任を持っているとバグ発生の可能性が高くなります。なぜかというと`責任のうち一つが変更されると他への影響が出る可能性がある`からです。複数の責任を持つクラスは再利用性が無いので、アプリケーションを予期せず壊す可能性が高まってしまいます。

この原則は、何らかの変更でバグが発生しても他の無関係な動作に影響を与えないように、`動作を分離することを目的`としています。

- Transparent（見通しが良い）
- Reasonable（合理的）
- Usable（利用性が高い）
- Exemplary（模範的）

単一な責任を持つためには`将来的なニーズを満たすために変更しやすい"TRUEなコード"を書く`必要があります。
以下のポイントを押さえるようにしましょう。

## O：Open Closed Principle(解放閉鎖の原則)
クラスの現在の動作を変更してしまうと、そのクラスを使用するすべてのシステムに影響を与えてしまいます。クラスでより多くの関数を実行したい時、理想的な方法は、`既存の関数に追加することであり、変更しないこと`です。

この原則は、クラスの既存の動作を変更することなく、クラスの動作を拡張することを目的としており`「変更が発生した際に、なるべく既存のコードを修正せずにコードの追加だけで対応できるようにすべき」`という考え方です。これは、そのクラスが使用されている場所でバグが発生するのを避けるためです。

- 新しく種類が増えるとき、既存コードを修正しないといけないか？

もし既存コードを修正しないといけない場合、オープン・クローズドの原則に違反している可能性がある。

## L：Liskov Substitution Principle(リスコフの置換原則)
子クラスが親クラスと同じ動作を実行できない場合バグになる可能性があるため`「子クラスは親クラスと置換可能でなければいけない」`という考え方の原則です。親クラスやその子クラスがエラーなしで同じ方法で使用できるように`一貫性を保つこと`を目的としています。

子クラスでオーバーライドしたメソッドは、親クラスのメソッドと同様の引数を取り、同じ型の返り値を返さなければいけない。
親クラスで例外を返さないにも関わらず、子クラスで例外を返してはいけない。

- 子クラスでオーバーライドしたメソッドが親クラスと同様の引数を取っているか？
- 子クラスでオーバーライドしたメソッドが親クラスと同様の型の返り値を返しているか？
- 子クラスでオーバーライドしたメソッド内で例外を返していないか？

子クラスがこれらの要件を満たさない場合、子クラスが大きく変更され、この原則に違反することになったということです。

## I：Interface Segregation Principle(インターフェイス分離の原則)
この原則は、動作のセットをより小さく分割して、クラスが必要なもののみを実行することを目的としており`「そのクラスにとって必要なメソッドだけを定義しよう」`という考え方です。

言い換えると「不要なメソッドは定義してはいけない」ということです。クラスに使用しない動作を実行させようとするのは無駄が多く、クラスにその動作を実行する機能がない場合、予期しないバグが発生する原因にも成り得ます。

クラスは「その役割を果たすために必要な動作のみを実行」する必要があります。
それ以外の動作は`「完全に削除する」「別の場所に移動する」`ようにしましょう。

- そのクラスにとって不要なメソッドを定義していないか？
- そのクラスがそのメソッドを持つのは不自然ではないか？

これらの要件を満たさない場合、この原則に違反することになったということです。

## D：Dependency Inversion Principle(依存性逆転の原則)
この原則は`インターフェイスを導入することにより、上位レベルのクラスが下位レベルのクラスに依存するのを減らす`ことを目的としており、両方とも抽象に依存すべきであるという考え方です。

これによりオブジェクトの`「再利用性」「保守性」「柔軟性」`が高まります。
MIPSのアーキテクチャ

ここに資料があります。

https://en.wikipedia.org/wiki/List_of_MIPS_architecture_processors

gccは-march=hogeで設定します。gcc4では以下のような設定が可能です・

> The ISA names are: 'mips1', 'mips2', 'mips3', 'mips4', 'mips32', 'mips32r2', 'mips64' and 'mips64r2'. 

以前から気になっていたのですがZRouterでビルドするとへんてこな状態でした。

```
% file Onion_Omega_kernel
Onion_Omega_kernel: ELF 32-bit MSB executable, MIPS, MIPS32 version 1 (FreeBSD), dynamically linked, interpreter /red/herring, not stripped
% file Onion_Omega_rootfs/bin/ls
Onion_Omega_rootfs/bin/ls: ELF 32-bit MSB executable, MIPS, MIPS-III version 1 (FreeBSD), dynamically linked, interpreter /libexec/ld-elf.so.1, FreeBSD-style, for FreeBSD 12.3 (1203506), stripped
```

[SIMD](https://qiita.com/yamori813/items/4c0ca93390e08eb0854a)のサポートを調べていてリンクできないので確認しなおしました。

MIPSの互換性の高さと、FreeBSDのコードが古いアーキテクチャで作られたもので、新しいアーキテクチャの機能を使っていないので、問題が起きないのだと思います。

これはkernelはsys/conf/Makefile.mipsでmips32が指定されるのでmips32になりますが、ユーザーランドはgccのデフォルトでビルドされるためこうなってしまいます。

いとしのRT3050はmips32r2です。

> - MIPS32 Enhanced Architecture (Release 2) Features

直しました。

```
% file Fon_FON2305E_FDT_kernel
Fon_FON2305E_FDT_kernel: ELF 32-bit LSB executable, MIPS, MIPS32 rel2 version 1 (FreeBSD), dynamically linked, interpreter /red/herring, not stripped
% file Fon_FON2305E_FDT_rootfs/bin/ls
Fon_FON2305E_FDT_rootfs/bin/ls: ELF 32-bit LSB executable, MIPS, MIPS32 rel2 version 1 (FreeBSD), dynamically linked, interpreter /libexec/ld-elf.so.1, FreeBSD-style, for FreeBSD 12.3 (1203506), stripped
```

もちろん問題なく起動できました。

socのmkでTARGET_CPUTYPEを指定してARCH_FLAGSを無効化しました。

portsもどきの方にも効くようです。よく分かってないのですが、rayが作り込んでいたところが機能しているんだと思われます。

kernelだけmarchを設定する仕組みは最初のようなおかしな状態を作り出すので正しくありません。kernel,userland共通のTARGET_CPUTYPEを使うのが正しいです。

古参のコミッターのjhbさんがレビューD22030でいじっているのですが、あまり良い修正ではないです。

FreeBSDはmips32以降しかサポートしてないので、本当はクロスとセルフのgccのデフォルトをmips32にするのが正解なのですが、もはやgccをいじりたくないというのもあるので、小手先で対応する事になります。

セルフでgccがある場合、コンパイルでライブラリとオブジェクトのABIが違っているとリンクできなくなるので、ユーザーランドをデフォルトのMIPS-IIIにしておくのは間違いではありません。

とはいえセルフでgccを持たないなのであれば、デフォルト以外に変更しても問題ありません。

buildworld,buildkernelのクロスコンパイルの仕組みは非常によく出来ていると思いますが、分かれてしまっているのでZRouterのようにまとめるラッパーは正解だと思います。

mips32とmips32r2がの分水嶺がよくわかりません。

mips32r3,r5などもあるようですが、ほとんど実在して無いと思います。
IISでSSIを設定する

※メモ※この記事は続きでもあります。
「まだちゃんと表示されないんだけど編」➅「まだ画像表示されないんだけどIISで【SSI】設定が必要だった！」にあたります。
→前記事から来たかたは[ここの作業から開始！](https://qiita.com/kusaharajiji/items/d2f827e1c7bbfee8f55a#iis%E3%81%AE%E3%83%8F%E3%83%B3%E3%83%89%E3%83%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%83%94%E3%83%B3%E3%82%B0%E3%81%ABssi%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%99%E3%82%8B)
※➆読む方はバックで戻ってください～

単体で確認用に読んでもらってもOK！

<br>

#### 【この記事を読むのは、こんなことに困った時】

 ・IISでSSIが設定されていない！
 ・画像ちゃんと用意したのに表示されない！
 ※画像表示のhtmlに遅延対策「遅延ロード（Lazy Load）」の記述がある。

```
 <img data-src="/img/hogehoge.jpg"
           src="/img/common/placeholder.gif">
```

<br>

---

#### 【環境構築手順メモ　ー応用】

###### ＜前提＞
PC：Windows
Webサーバー：IIS
言語：html css C# PHP
作成：HP
その他：アクセスファイラーを使用したサイト構成

###### ＜きっかけ＞
サイト引継ぎの際の環境構築。
画像表示がされなくて構築の手順を見直しをした。

###### ＜実際のここまでの流れ＞
➀リモートからデスクトップにクローン
➁Soucetreeで追跡をUI管理できるようにする
➂npm install　（コマンド）
➃npx gulp　（コマンド）
➄サイトは立ち上がったが画像など表示されない部分がある。◀今ここ！問題発生！

###### ＜問題＞
『画像が表示されない！』


###### ＜原因＞
サーバーサイドインクルード（SSI）の設定がIISで設定されていなかった。
その為、以下の記述が読み込めていなかった。

```html
  <!--#include virtual="/common/test.html" -->
```

<br>

---

#### 【解決手順】
#### 「IISのハンドラーマッピングにSSIの設定を追加する」

<br>

###### ➀WindowsでIISを開く
　※以下の２方法（◆）どちらかを実行で可能

　◆モニター下左端の「ここに入力して検索」に「IIS」と入力
　　↓ 「インターネット インフォメーション サービス (IIS) マネージャー」と出てくるのでそれをクリック

　◆モニター下左端の「Windowsロゴ」をクリック
　　↓アルファベットごとの一覧が表示されるので Wまでさがり「Windows管理ツール」をクリック
　　↓「インターネット インフォメーション サービス (IIS) マネージャー」と出てくるのでそれをクリック


###### ➁対象のサイトまで移動

 1. 左のリスト欄「接続」➡「DESKTOP-xxxx（DESKTOP-xxxx￥XXXXXXXX）」➡「サイト」➡
　　「対象のサイト名（例：XXXXX.com）」➡右の欄に「（XXXXX.com）ホーム」と表示されると対象サイトの設定ホーム画面に移動できている


###### ➂ハンドラーマッピングへSSIの設定を追加する

 1. 「（XXXXX.com）ホーム」のしたのアイコン欄から「ハンドラーマッピング」をダブルクリック

 2. 「モジュールマップの追加」をクリック
　　　　※以下の２方法どちらかを実行で可能
 　　　・ハンドラーマッピングの表の上で右クリック表示される
 　　　・右端「操作」欄から選択

 3. 以下画像と同じ設定を「モジュールマップの追加」で記入し「OK」

> 要求パス：　　　　*html
>モジュール(M)：　　ServerSideIncludeModule
>名前(N)：　　　　　SSINC-html

![モジュールマップの編集.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661441/4481d49f-f279-920d-e12d-ad82bab3eb28.png)

 4.OKすると追加が完了する
![ハンドラーマップ編集２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661441/d955e682-9b43-927f-cd5d-52d141ccb28f.png)


#### 【完了！】

再度、サイトを開きなおし
立ち上げなおしてみてください。

<br>

---

#### 【参考】
 - [情報処理技術](https://msyk.net/keio/past/it2000/r08.htm)

---

#### 【気になるワード】---記事内でより理解を深めたいワード
 - 「 [遅延ロード（Lazy Load）](https://technical-seo.jp/lazy-load-javascript-library/#outline__2)」
 - 「[サーバーサイドインクルード（SSI）](https://lpeg.info/html/ssi.html#m1)」
　　※今回筆者の担当したサイトはJSのタグを各ページに毎回書き込むと追加や変更があった際に手間や変更漏れが発生する可能性があるので、そのためJSタグの書かれたHTMLファイルを一つにして、SSIを使って各ページに埋め込んでいます。

<br>

 - IISとSSI？何それ？➡[IISとは](https://qiita.com/kusaharajiji/items/8147f36e597c3439a919)
ABC001メモ

# ABC001 メモ
## [A - 積雪深差](https://atcoder.jp/contests/abc001/tasks/abc001_1)

問題文通り、答えは$H_1-H_2$。

```python:001A.py
H_1 = int(input())
H_2 = int(input())

ans = H_1 - H_2
print(ans)
```

## [B - 視程の通報](https://atcoder.jp/contests/abc001/tasks/abc001_2)

入力は単位がメートル(m)で与えられるが、判定条件は単位がkmで与えられているため、少々複雑になる。<br>
今回は判定条件をmに統一して計算した。

```python:001B.py
m = int(input())

if m < 100:
    VV = '00'

elif m <= 5000:
    if len(str(m)) == 4:
        VV = str(m)[:2]
    else:
        VV = '0' + str(m)[0]

elif m <= 30000:
    VV = str(m//1000+50)

elif m <= 70000:
    VV = str((m//1000-30)//5+80)

else:
    VV = '89'

print(VV)
```

## [C - 風力観測](https://atcoder.jp/contests/abc001/tasks/abc001_3)
問題文通り実装した。場合分けが煩雑なのと、小数を扱う場合には誤差に注意が必要。小数の扱いについては、整数で扱えるように条件式を加工した。<br>
具体的には、風速は分速のまま扱えるようにした。今回の場合、風速$0.2$m/s以下という条件は、$0.25$m/s未満と同値なため、これを60倍して$15$m/min未満、というようにすることで、小数の計算を避けた。<br>
公式の解説にあるように、場合分けを手動でたくさん書くのはあまり望ましくないのだが…

```python:001C.py
Deg, Dis = map(int, input().split())

if Deg <= 112:
    Dir = 'N'
elif Deg <= 337:
    Dir = 'NNE'
elif Deg <= 562:
    Dir = 'NE'
elif Deg <= 787:
    Dir = 'ENE'
elif Deg <= 1012:
    Dir = 'E'
elif Deg <= 1237:
    Dir = 'ESE'
elif Deg <= 1462:
    Dir = 'SE'
elif Deg <= 1687:
    Dir = 'SSE'
elif Deg <= 1912:
    Dir = 'S'
elif Deg <= 2137:
    Dir = 'SSW'
elif Deg <= 2362:
    Dir = 'SW'
elif Deg <= 2587:
    Dir = 'WSW'
elif Deg <= 2812:
    Dir = 'W'
elif Deg <= 3037:
    Dir = 'WNW'
elif Deg <= 3262:
    Dir = 'NW'
elif Deg <= 3487:
    Dir = 'NNW'
else:
    Dir = 'N'

if Dis < 15:
    Dir = 'C'
    W = 0
elif Dis < 93:
    W = 1
elif Dis < 201:
    W = 2
elif Dis < 327:
    W = 3
elif Dis < 477:
    W = 4
elif Dis < 645:
    W = 5
elif Dis < 831:
    W = 6
elif Dis < 1029:
    W = 7
elif Dis < 1245:
    W = 8
elif Dis < 1467:
    W = 9
elif Dis < 1707:
    W = 10
elif Dis < 1959:
    W = 11
else:
    W = 12

print(Dir, W)
```


## [D - 感雨時刻の整理](https://atcoder.jp/contests/abc001/tasks/abc001_4)
時間の区間を扱う問題だが、今回は最小の単位が分であり、最長でも1440分なので、配列で保持しても十分高速に計算できそう。<br>
入力を00:00からの分に計算し直し、配列に保持する。この時、区間全てに対して計算を行う必要はなく、始まった時と終わった時に対して計算を行う、いわゆる「いもす法」で扱えば十分である。<br>
計算量は$N$が大きい時でも$O(N)$程度であるため、十分高速。

```python:001D.py
def adj(num):
    h = str(num//60)
    m = str(num%60)
    time = h.zfill(2) + m.zfill(2)
    return time


N = int(input())

lst = [0]*1442

for i in range(N):
    S, E = input().split('-')
    S = 60*int(S[:2]) + int(S[2:])
    E = 60*int(E[:2]) + int(E[2:])


    if S%10 < 5:
        S -= S%10
    else:
        S -= S%10
        S += 5

    if 0 < E%10 < 6:
        E -= E%10
        E += 5
    else:
        E += 5
        E -= E%10

    lst[S] += 1
    lst[E+1] -= 1

tmp = 0
S = -1
E = -1
for i in range(1442):
    tmp += lst[i]
    if tmp and S == -1:
        S = i

    if tmp == 0 and S != -1:
        E = i-1
        S = adj(S)
        E = adj(E)
        print(S + '-' + E)
        S = -1
```
EC2でNGINX Unitを使う

# NGINX Unitについて

1. PythonをNGINXで使用したいときに中継サーバーとして使用
1. Python,PHP,Go,Perl,Ruby,Node.js,Javaなどに対応
1. 同じ言語の複数バージョンを同時に運用可能
1. サーバー停止せずに設定変更可能
1. 公式ドキュメント
https://unit.nginx.org/installation/

# インストール
```bash
$ sudo vi /etc/yum.repos.d/unit.repo
[unit]
name=unit repo
baseurl=https://packages.nginx.org/unit/amzn2/$releasever/$basearch/
gpgcheck=0
enabled=1
```

```
$ sudo yum install unit
$ sudo yum install unit-devel unit-go unit-jsc8 unit-perl  \
      unit-php unit-python27 unit-python37
```

# 自動再起動設定
```
sudo systemctl enable unit
```
# 再起動
```
sudo systemctl restart unit
```

# ログファイル
/var/log/unit/unit.log

# 設定確認
```sh
# sudo curl --unix-socket /var/run/unit/control.sock http://localhost/
{
	"certificates": {},
	"config": {
		"listeners": {},
		"applications": {}
	}
}
```

# 設定変更
プログラマブルかつノンストップであることが特徴で、PUT通信してコンフィグを反映する

・/vaw/www/python/wsgi.pyを作成
```python
def application(environ, start_response):
    start_response("200 OK", [("Content-Type", "text/plain")])
    return (b"Hello, Python on Unit!")
```

・/var/www/python/config.jsonを作成
```json
{
  "listeners": {
    "*:8080": {
      "pass": "applications/python_app"
    }
  },
  "applications": {
    "python_app": {
      "type": "python",
      "path": "/var/www/python/",
      "module": "wsgi"
    }
  }
}
```

・設定を反映
```sh
# cd /var/www/python/
# curl -X PUT --data-binary @config.json --unix-socket /var/run/unit/control.sock http://localhost/config/
{
	"success": "Reconfiguration done."
}
```

・実際に通信して確認
```sh
# curl http://localhost:8080
Hello, Python on Unit!
```
asdfでNode.jsの環境設定

たまに Ubuntu の新しい環境で Node.js を入れることがあるので、メモ代わりに環境設定法を書いておく。

ネットで検索するとMacだったり、yarnを入れてなかったりするので。

# asdf インストール

基本は[公式サイト](http://asdf-vm.com/guide/getting-started.html)に従う。
非常に丁寧に書いてある。

## インストール
```shell
$ apt install curl git
$ git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.9.0
```

## .zshrcに設定追加
```text:~/.zshrc
. $HOME/.asdf/asdf.sh
```

## 既存のバージョンファイルも有効にする
これで .node-version も有効になる。プロジェクトによっては .node-version を使っているものもあるので。
```text:$HOME/.asdfrc
legacy_version_file = yes
```

# プラグインインストール

## nodejs

https://github.com/asdf-vm/asdf-nodejs
`latest` のところは使う Node.js のバージョンに合わせる。

```shell
$ asdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs.git
$ asdf install nodejs latest
$ asdf global nodejs latest
```

## yarn

(2022/04/26 追記)
今は corepack を使った方が良さそう。

### corepack を使う場合

```shell
$ corepack enable
$ asdf reshim nodejs
```

package.json に yarn のバージョンを書くだけでOK。
yarn コマンドを実行すると自動的に yarn がインストールされる。

```text:package.json
{
  "packageManager": "yarn@3.2.0"
}
```

### asdf で yarn をインストールする場合

https://github.com/twuni/asdf-yarn
yarn は asdf でインストールするのが楽かなと思う。
npm でインストールすると新しい Node.js を入れた時に競合して面倒なことになる(過去に何度もあったので)。

```shell
$ asdf plugin add yarn
$ asdf install yarn latest
```
Rubyではシフト演算 `1 << k` より配列参照 `lookup[k]` のほうが速い

AtCoderの問題をRubyで復習していて、どうしても時間制限超過（TLE）してしまうものがあった。

他の方の解答を見たりして試しているうちに、どうも**シフト演算の実行回数が多いとTLEしやすい**ということがわかった[^bit-op]。計算したいのは `1 << k` という単純なもの（を最大3000万回ほど）なので、これを事前に計算しておき配列参照 `lookup[k]` に置き換えたところ無事に通過した。

そんなに速度差があるのか気になったので、ベンチマークしてみた。

[^bit-op]: 他の演算なども遅い可能性はあるが、削減しやすいのはシフト演算だけだった。

## ベンチマーク
AtCoderのコードテストを利用。その結果、配列参照のほうが**約1.3倍**速く、3000万回計算すると0.3秒ほど短くなった。

```ruby:shift-vs-lookup.rb
puts RUBY_DESCRIPTION
puts

require 'benchmark'

n = 30
lookup = Array.new(n) { |i| 1 << i }

m = 30_000_000
ary = Array.new(m) { rand(n) }

Benchmark.bmbm do |x|
	x.report("shift")  { ary.each { |k| 1 << k } }
	x.report("lookup") { ary.each { |k| lookup[k] } }
end
```

```text:標準出力
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]

Rehearsal ------------------------------------------
shift    1.528244   0.000037   1.528281 (  1.528378)
lookup   1.152500   0.000020   1.152520 (  1.152588)
--------------------------------- total: 2.680801sec

             user     system      total        real
shift    1.260826   0.000017   1.260843 (  1.260900)
lookup   0.958101   0.000000   0.958101 (  0.958157)

```
【UE4】UEnumで範囲ベースforを行うメモ

:::note info
確認したバージョンはUE4.27.2です。
:::

ググれば出てくるのだが、よく忘れるので自分用メモ。

# 宣言側 (.h)

```C++
#include "Misc/EnumRange.h"

UENUM()
enum class EElementType : uint8
{
	Earth,
	Fire,
	Wind,
	Water,
	Count	UMETA(Hidden)
};

ENUM_RANGE_BY_COUNT(EElementType, EElementType::Count);
```

- ENUM_RANGE_BY_COUNT()マクロの他に ENUM_RANGE_BY_FIRST_AND_LAST()などがある。
    - EnumRange.h
    - 内部的には static const な変数を宣言するだけ。なので変な負荷はないだろう。

# 定義側 (.cpp)

```C++
for (EElementType ElementType : TEnumRange<EElementType>())
{
	SettingArray.Add(LoadInitialSettings(ElementType));
}
```

# 参考URL

- [Iterate over UENUM with TEnumRange<T>](https://benui.ca/unreal/iterate-over-enum-tenumrange/) 
- [［UE4］C++ で enum の foreach を行う方法](https://qiita.com/jden/items/ab4eecb899ad6c0ede52)
【Ruby】みんな理解出来てる？テンプレートメソッドパターンのこと。

# テンプレートメソッドパターンとは？
テンプレートメソッドパターンは[GoF](https://gimo.jp/glossary/details/gang_of_four.html)のデザインパターンの一種です。

このパターンは、基底クラスに不変の部分を記述し、変わる部分はサブクラスに定義するメソッドにカプセル化するというモノです。
`変わるものと変わらないものを分離する`という設計の考えに基づいています。

つまり次の2つのオブジェクトによって構成されます。

```ruby
- 骨格となる「抽象的な基底クラス」
- 実際の処理を行う「サブクラス」
```

## メリット
- 基底クラス側に、「不変の基本的なアルゴリズム」を配置可能になる。
    - 「高レベルの処理を制御すること」に集中できる。
- サブクラス側に、「変化するロジック」を置ける
    - 「詳細を埋めること」に集中できる
- 似通った部分を共通化して「サブクラスに対してスーパクラスで実装されている抽象メソッドを実装する」という責任を与えることが可能になる。

## 実装例

### 基底クラス

```ruby
class Test
  def open()
    raise NotImplementedError.new("#{self.class}##{__method__}")
  end

  def close()
    raise NotImplementedError.new("#{self.class}##{__method__}")
  end

  def output()
    raise NotImplementedError.new("#{self.class}##{__method__}")
  end

  def display
    open()
      5.times do
        output()
      end
    close()
  end
end
```

### サブクラス

```ruby
class SubTest < Test
  def initialize(string)
    @string = string
  end

  def open
    print 'open!'
  end

  def close
    print 'close!'
  end

  def output
    print @string
  end
end
```

### 実行例

```bash
sub_test = SubTest.new('テスト')

sub_test.display
#=> open!
#=> "テスト"
#=> "テスト"
#=> "テスト"
#=> "テスト"
#=> "テスト"
#=> close!
```
Jekyllをdockerで使ってみました

今までVirtualBoxで仮想環境を作り、LAMPなどを構築していました。
仮想化の勉強をしている中でdockerは、VirtualBoxよりも早いと知りました。
そのためMacにdockerをインストールして、環境を作りました。

そして静的なウェブサイトを作るジェネレーターとして関心があったJekyllを、dockerで試してみました。

ちゃんとdockerに、Jekyllがありました。

https://hub.docker.com/r/jekyll/jekyll/

今回は、下記の記事を参考にしました。

https://zenn.dev/daikichidaze/articles/f499df5317335b

https://nprog256.net/post/2019/01/build-jekyll-environment-by-docker-compose/

https://cardano.github.io/blog/2016/11/29/creating-an-engineering-blog

## 環境を作る中で、備忘録で書き加えます。

指定のディレクトリを作るときは、親フォルダの下に

```bash
mkdir -p ./app/_site/
```

と作ると一度にディレクトリを作ることが出来ます。

私は、htmlappとして、親フォルダを作りました。
このフォルダの中に、docker-compose.ymlを作りました。

## ディレクトリは、このような形になります。

![スクリーンショット 2022-03-23 15.36.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20977/89a38596-8f37-94ff-a9fd-d85d1d4bba67.png)

これから変換する拡張子mdファイルは、
./app/_site/
に配置しましょう。

先に
```bash
docker-compose up
```
を実行してから、変換したいファイルを配置しましょう。

## 感想
Jekyllを使うための環境を作らなくても良いので、手軽にJekyllを使うことができると思いました。
静的なサイトを作る案件が出たときに、このコンテナーを実行して生産性の向上を図りたいと思います。
tftpクライアントで大きなファイルを送信出来るWindowsクライアントって無いのかな……

なんかルーターに送るのにtftpを使用しているとの事で
ちょっと調べて見たけど
TFTPDとTftpd64ぐらいしか見つけられず……

でもこれらはサイズが小さいんだよな……

やっぱりLinuxをインストールしてみるしか無いのかな……
【Flutter】table_calendarのヘッドの部分をカスタマイズする

# はじめに
Flutterのパッケージでtable_calendarというものを最近使ってアプリ開発をしているのですが、見た目のカスタマイズが複雑でやりにくい上に日本語の記事が少ないようなので、自分が実装するついでにやり方をまとめてみます。




# 告知
この記事に書いてある`table_calendar`を使用している、
`タスクカレンダー`というアプリをリリースしました！
（まだ改善の余地がたくさんありますが、、）


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2567243/6f68b123-0d4f-4a9d-b128-c68608c7d625.png" width="550">

コンセプトは、めちゃめちゃ手軽なカレンダー兼タスク管理アプリです。
普段は、めんどくさくてカレンダーアプリを使わないが、たまにある美容室の予定は忘れられない時など、ちょっとしたことを最低限の機能でストレスなく行えます。

`table_calendar`を使ってこんなアプリができるんだという参考にもなれば幸いです。

ぜひ一度、アプリを手に取ってみてください！！！

ダウンロードは下から可能です。

<a href='https://play.google.com/store/apps/details?id=com.app.taskManagement&pcampaignid=pcampaignidMKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Google Play で手に入れよう' src='https://play.google.com/intl/ja/badges/static/images/badges/ja_badge_web_generic.png' width="220" height="120"/></a>　　　　<a href="https://apple.co/3HcoulN"><img src="https://tools.applemediaservices.com/api/badges/download-on-the-app-store/black/ja-jp?size=250x83&amp;releaseDate=1659139200&h=0e6cd676b88181534f9150591ccc8dcd" alt="Download on the App Store" width="210"></a>







# 実装前の画面と実装後の画面
![before.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2567243/a5b123d4-a04d-a7dd-bca8-1d4770a86ec8.png)
実装前の画面です。
今回は上の画像の赤線で囲ってある部分の見た目を変えていきたいと思います。
![after.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2567243/26d274ba-5730-b3fe-eb5c-5ed9ccfdf11b.png)
実装後の画面です。カレンダーの上部分の見た目がスッキリしましたね。
それではやっていきましょう。
# ステップ１
まずカレンダー上部、右側にある`2weeks`と書いてあるものはなんなのかというと、
フォーマットボタンと呼ばれるもので、その名の通り、カレンダーの表示のフォーマットを変えれるようにするものです。
`2weeks`というボタンを押すとこのように二週間分のカレンダーが表示されるようになります。
ですが、カレンダー自体の大きさを先に設定してあると下の画像のようにレスポンシブに上に短くなることはないので注意してください。

カレンダー自体の大きさを変更したい方は[こちら](https://qiita.com/mqkotoo/items/c0352840173a26c48697)の記事をご覧ください。
![スクリーンショット 2022-03-23 14.52.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2567243/eaa08316-350e-faaa-19ba-f6115443ebd4.png)

自分は一ヶ月分だけのカレンダーを使うのでフォーマットボタンは要らないため、カットしていきたいと思います。
```dart:calendar.dart
TableCalendar(
    // カレンダーの上の部分のスタイルを変えるためのやつ
    headerStyle: HeaderStyle(
        formatButtonVisible: false,
    ),
),
```
このようにカレンダーの中に`headerStyle`というものをつけてその中にコードを追加してください。
`formatButtonVisible: false`を指定するとフォーマットボタンの表示を無くすことができます。
![スクリーンショット 2022-03-23 15.08.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2567243/81df02c5-e5d4-0f5d-fe63-eef14221f8de.png)
これだと月と西暦が書いてあるところが左側によってバランスが悪くなるので次はそれを真ん中に持っていきます。
# ステップ２
次は`March 2022`の表示を真ん中に配置したいと思います。
そのためには`titleCentered`プロパティを指定してあげる必要があります。
```dart:calendar.dart
TableCalendar(
    // カレンダーの上の部分のスタイルを変えるためのやつ
    headerStyle: HeaderStyle(
        formatButtonVisible: false,
        titleCentered: true,  //この行を追加
    ),
),
```
このように指定してあげると`March 2022`の表示を真ん中に配置することができました。
![after.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2567243/1658569b-ae98-8268-3dac-b59cbf22a3c4.png)
完成です！！

# 最後に
`headerStyle`に`formatButtonVisible`と`titleCentered`を指定してあげることで
簡単に見た目をスッキリさせることができました。
もし参考になったらいいねしていただけると嬉しいです！
VSCode 備忘録

:::note info
VSCodeの設定等を備忘録的に記載していきます。
:::


## cmd+pで検索した時、Laravleのvender配下のファイルも検索対象にしたい
デフォルト設定では`"search.useIgnoreFiles": true`になっているはずなので、`"search.useIgnoreFiles": false`に変更する。
```settings.json
"search.useIgnoreFiles": false
```
## ウインドウ最上部に表示される編集中ファイル名の表示を変更する
デフォルトではファイルパスがわかりづらいので、編集中ファイルを、ワークスペースフォルダーからの相対パス表示にする。
```settings.json
 "window.title": "${activeEditorShort}${separator}${activeEditorMedium}"
```

window.titleには以下の変数を設定できる。
```
'${activeEditorShort}': ファイル名 (例: myFile.txt)。
${activeEditorMedium}: ワークスペース フォルダーに対して相対的なファイルのパス (例: myFolder/myFileFolder/myFile.txt)。
${activeEditorLong}: ファイルの完全なパス (例: /Users/Development/myFolder/myFileFolder/myFile.txt)。
${activeFolderShort}: ファイルが含まれているフォルダーの名前 (例: myFileFolder)。
${activeFolderMedium}: ファイルを含むフォルダーの、ワークスペースフォルダーからの相対パス(例: myFolder/myFileFolder)。
'${activeFolderLong}': ファイルが格納されているフォルダーのフルパス (例: /Users/Development/myFolder/myFileFolder)。
${folderName}: ファイルが含まれているワークスペース フォルダーの名前 (例: myFolder)。
${folderPath}: ファイルが含まれているワークスペースの絶対パスです (例: /Users/Development/myFolder)。
${rootName}: 開かれたワークスペースまたはフォルダーの名前 (例: myFolder または myWorkspace)。
${rootPath}: 開かれたワークスペースまたはフォルダーのファイル パス (例: /Users/Development/myWorkspace)。
${appName}: 例: VS Code。
${remoteName}: 例: SSH
${dirty}: アクティブなエディターの変更が保存されていない場合を示すインジケーター。
${separator}: 値か固定のテキストで囲われたとき、条件付きの区切り記号 (" - ") を表示します。
```








* * *

# 参考にさせていただきました
https://lighthouse-dev.github.io/tools/vscode-search-setting/
AutoHotKeyスクリプト例



# はじめに
いまさらながらAutoHotKeyの便利さに気が付いたのでメモ

# 環境
Microsoft Windows [Version 10.0.14393.5006]
\(2022年3月23日時点)
AutoHotKey 1.1.33.10

# AutoHotKeyとは
キーボードのキーの割り当てを変更するアプリケーション。
スクリプトも書けるので、自動処理のようなこともできる。

# ダウンロード
こちらから(https://www.autohotkey.com/)

# ソース
```batchfile:sample.ahk
;←→↑↓
;無変換＋hlkj
vk1D & h::send,{Blind}{Left}
vk1D & l::send,{Blind}{Right}
vk1D & k::send,{Blind}{Up}
vk1D & j::send,{Blind}{Down}

;Home,End
;無変換＋,.
vk1D & vkBC::send,{Blind}{Home}
vk1D & vkBE::send,{Blind}{End}

;pageup,down
;無変換＋u,o
vk1D & u::send,{Blind}{PgUp}
vk1D & o::send,{Blind}{PgDn}

;yyyy/mm/dd
^;::Send, %A_YYYY%/%A_MM%/%A_DD%

;hh:mm:ss
^vkBA::Send, %A_HOUR%:%A_Min%:%A_Sec%

; Excel使用時のみ有効
#ifWinActive ahk_exe EXCEL.EXE
    ;Excelで行選択（Shift + Space）を有効にする
	$+Space::
	    Flag := IME_Get()
	    
	    If (Flag)
	    {
	        Send,{vkF3sc029}
	        Sleep,30
	    }
	    
	    Send,+{Space}
	    Sleep,30
	    
	    If (Flag)
	    {
	        Send,{vkF3sc029}
	        Sleep,30
	    }
	    Return
	
	^+e::Send,!hac		;センタリング
	^+l::Send,!hl1		;左寄せ
	^+r::Send,!hr		;右寄せ
	^+0::Send,!wj		;拡大率100%に変更
	^vkBC::Send,!hk     ;位取り

#ifWinActive
    
; メモ
;特殊キー
;全角/半角						vkF3 または vkF4
;変換							vk1C
;無変換							vk1D
;カタカナ/ひらがな/ローマ字		vkF2

;修飾キー
;windows		#
;Alt			!
;Ctrl			^
;Shift			+

;IMEの状態取得
IME_Get()
{
	WinGet, vcurrentwindow, ID, A
	return  DllCall("user32.dll\SendMessageA", "UInt", DllCall("imm32.dll\ImmGetDefaultIMEWnd", "Uint", vcurrentwindow), "UInt", 0x0283, "Int", 0x0005, "Int", 0)
}	
```

# 使用方法
AutoHotKeyをインストーラから入れている場合は、任意の場所に保存して、xxxx.ahkファイル（スクリプトファイル）をダブルクリックすることで常駐する。常駐後はタスクトレイにアイコンが増えるので、それで確認できる。
zip版の場合、手動で関連付ける必要がある。関連付け後は、スクリプトファイルをダブルクリックすることで常駐する。
Python 複数スレッドから同時アクセスされたときに前回のアクセス時間よりも２秒以上経過していなければ待機して、経過後にアクセス時間を記録して、この値をreturnする処理

以下は、複数スレッドから同時アクセスされたときに前回のアクセス時間よりも２秒以上経過していなければ待機して、経過後にアクセス時間を記録して、この値をreturnする処理

```python
import time
import threading

lock = threading.Lock()

access_time = time.time()


def task():
    while True:
        print(concurrent_access())
        pass


def concurrent_access():
    """複数スレッドに同時にアクセスされるかもしれない処理"""
    # 前回のアクセス時間より2秒以上経過して "いる"
    #   access_timeを現在時刻にしてから
    #   access_timeをreturn
    # 前回のアクセス時間より2秒以上経過して 'いない"
    #   2秒経過するまで待機
    #   2病経過したら上と同じ処理
    global access_time
    try:
        # 現在のスレッド名を表示
        print(threading.current_thread().name)
        lock.acquire()
        while True:
            if access_time + 2 < time.time():
                access_time = time.time()
                return access_time
    finally:
        lock.release()


ths = []
for i in range(3):
    th = threading.Thread(target=task, name=f'thread{i}')
    th.start()
    ths.append(th)
for th in ths:
    th.join()

```

```:実行結果
thread0
thread1
thread2
1648015757.6682205
thread0
1648015759.6691394
thread1
1648015761.6700594
thread2
1648015763.6702552
thread0
1648015765.671093
thread1
1648015767.6731405
thread2
```
【Ruby】構造体クラスを使いこなしたい。

# 概要
みなさん。「構造体クラス」使ってますか？
たくさん利用してる人もいれば、聞いた事もない人がいるかと思います。
便利なRubyのクラスなのでぜひ頭の隅にでも置いておいてください！

## Sturctとは
Rubyにおける構造体クラス(Struct)は簡易的なクラスのようなものです。
明示的にアクセスメソッドを定義しなくても、構造体クラス外でメンバの参照・更新は可能です。

以下のような場面で使えます。
- まとまったデータを扱いたいが、クラス定義式を使ってクラスを作るまでもない場合。
- クラス内で特定のデータのまとまりを表現する場合。

### 定義方法

以下のように定義することで構造体クラスを使えるようになります。

```ruby
# Struct.new('構造体クラス名', メンバ)
Struct.new("User", :name, :age)

# 第一引数を省略する事も可能
User = Struct.new(:name, :age)

# クラスのように定義する事も可能(非推奨)
class User < Struct.new(:name, :age)
end

puts Struct::User.new('山田太郎', 25)
#=> #<struct Struct::User name="山田太郎", age=25>
```

参照や更新は以下のように簡単に行えます。

```ruby
Struct.new('User', :name, :age)
user = User.new('山田太郎', 25) 

# 参照
puts user.name #=> "山田太郎"

# 更新
user.name = "山田二郎"
puts user.name #=> "山田二郎"
```

クラス定義式のようにメソッドを設定する事も可能です。

```ruby
User = Struct.new('User', :name, :age) do
  def introduction
    "私の名前は#{name}です"
  end

  def greet(word)
    word
  end
end

user = User.new('山田太郎', 25)
p user.introduction #=> 私の名前は山田太郎です
p user.greet('こんにちは') #=> こんにちは

```

### 注意点
- 指定されたメンバ数以上の引数を与えるとエラーとなる。
- 指定されたメンバ数以下のの引数の場合はnilが入る。
- インスタンスのメンバの値が同じであれば比較した際に`true`を返す。

## こういったものがある
`OpenStruct`というRubyの標準ライブラリがあります。
これは要素を動的に追加・削除できる手軽な構造体を提供するクラスです。 

### 使い方

```ruby
require 'ostruct'

# 構造体を作って動的にpropertyを追加
ostruct = OpenStruct.new
ostruct.name = '山田太郎'
ostruct.age = 25

puts ostruct.name
#=> "山田太郎"

puts ostruct.age
#=> 25

# ハッシュを使用することも可能
ostruct = OpenStruct.new({ name: '山田太郎', age: 25 })

puts ostruct.name
#=> "山田太郎"

puts ostruct.age
#=> 25
```
【小ネタ】「アイテムが作成または変更されたとき」トリガーでPowerAutomateフローで起こる無限ループを回避

以下画像のようなSharePointリストでアイテムを作成または変更があったときに項目を更新するPowerAutomateのフローがあった場合、
「項目を作る」⇒「トリガーが起動してフローを実行する」⇒「項目を変更する」⇒「トリガーが起動してフローを実行する」⇒「項目を変更する」・・・
というように無限ループが発生します。
私がこれをトリガーの条件を追加することで解決した手順を紹介します。
![001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2480832/2eb0d304-c1be-3f28-5ece-5252344b586f.jpeg)
## フローによる更新時間列を追加
SharePointリストにフローによる更新時間列を追加します。
元から非表示にされている更新時間列を使うと、手動で更新したときの時間も登録してしまうためフローが1回も起動しません。
そのためフローで更新したときの時間を登録する列を追加します。
以下画像ではtime1列がフローによる更新時間列となっています。
![002.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2480832/fbabb5d6-83b6-2cb2-e2c4-5266c9e982c6.jpeg)
## トリガーの条件を追加
結論から言うとトリガーの条件に以下の式を追加することで無限ループが発生しなくなります。
```
@if(equals(triggerBody()?['time1'],null),true,less(triggerBody()?['time1'],addToTime(utcNow(), -3,'Minute')))
```
実際に使うときは「time1」の部分を自分が使っている列名に変更する必要があります。
列名を日本語で設定している場合はOData形式で設定する必要あり、こちらをご参照。

https://qiita.com/ssc-ksakamaki/items/83e40f0d3e7487793a36

トリガーの条件はトリガーの設定を開いて一番下にスクロールして追加を押すことで設定できます。
![003.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2480832/88e8124d-07ce-dfae-dc74-6ac8fd0c7e37.jpeg)
![004.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2480832/949d1b90-1b35-f671-9009-32e5743617f7.jpeg)
## 追加した条件式について
ざっくりとですが追加した条件式について紹介します。
まずトリガーの条件に追加する論理比較関数の先頭には「@」が必須です。
```
@if(equals(triggerBody()?['time1'],null),true,
```
前半のこの部分はtime1列が空欄の場合はtrueを返す、つまりtime1列が空欄の場合はトリガーを起動するということを言っています。
```
less(triggerBody()?['time1'],addToTime(utcNow(), -3,'Minute')))
```
後半のこの部分はtime1列が空欄ではない場合、その値が現在時刻の3分前よりも前であればtrueを返す、
つまりtime1列（前回のフローによる更新時間）が3分前以内であればトリガーを起動しないとすることで無限ループするのを防いでいます。

3分としているのはアイテムが作成または変更されたときにフローを起動するまでのラグが1～2分あるためです。
論理式をいじることで条件を自由に設定できるので必要に応じて条件式をいじってみてください。
Mac (Intel cpu)でEigenがコンパイルエラー

C++の数値計算コードの中で Eigen を利用しているが、最近からエラーがでてビルドできなくなった。(エラーはNumTraits.h, Complex.h, MathFunctions.h, XprHelper.h などに。)
```
Use of overloaded operator '*' is ambiguous (with operand types 'int' and 'Eigen::GenericNumTraits<float>::(unnamed enum at /usr/local/Cellar/eigen/3.4.0_1/include/eigen3/Eigen/src/Core/NumTraits.h:154:3)')
...
No matching function for call to 'pload'
...
Cannot take the address of an rvalue of type 'typename Eigen::internal::real_ref_retval<typename Eigen::internal::global_math_functions_filtering_base<complex<float>>::type>::type' (aka 'int')
...
Multiple overloads of 'run' instantiate to the same signature 'const Eigen::internal::real_ref_impl<const std::complex<float>>::RealScalar &(const std::complex<float> &)' (aka 'const std::complex<float> &(const std::complex<float> &)')
...
No viable conversion from 'const Eigen::SparseMatrix<double, 1>' to 'OtherCopy' (aka 'int')
```

**現象**
Intel CPUの Mac でこの問題が発生して、M1 Macでは問題なくビルドできた。おそらく clang-1316.0.21.2 にアップデートされた後の現象。

**解決策**
Eigenのヘッダファイルを先に読み込むように順番を入れ替えたら解決した。(SuiteSparse や MersenneTwister なども使っていて、何らかの干渉があるのだろうけどまだ原因を特定できていない）

Eigen のFAQにそのような記述があった。
https://eigen.tuxfamily.org/index.php?title=FAQ#Compilation