OmniAICreator/Qiita-1.07M huggingface dataset:
【初心者でもわかる】HTML・CSSで「 >（逆くの字矢印）」の5つの作り方

# どうも、7noteです。今回は矢印（>）を作る５つの方法を解説。

どうも7noteです。
この記事は以下へ引っ越しました。

https://naruweb.com/coding/arrow/
Azure App Service - Web Apps 一定間隔で謎のリクエストが発生する

ローンチ前のクローズドな環境にもかかわらず、出所不明のリクエストにより多数のセッションファイルが生成されていた
また、当該ファイルのタイムスタンプは 2～3分間隔で規則性があった

# 調査

サーバー変数よりリクエストのログを取得

```
REQUEST_URI     = /
REQUEST_METHOD  = GET
SERVER_PROTOCOL = HTTP/1.1
REMOTE_ADDR     = ::1
REMOTE_PORT     = 21353
REMOTE_HOST     = ::1
HTTP_REFERER    =
HTTP_USER_AGENT = AlwaysOn
HTTP_CONNECTION = Keep-Alive
```
リクエスト元が自身
ユーザーエージェントも独特で怪しい

# 結論

一定間隔でのリクエストの正体は、常時接続（Always On）の設定によるもの

Web Apps の仕様として 20分間リクエストが無いとアイドル状態となり、次回アクセス時のレスポンスが低下する
また、Web ジョブを設定している場合、実行の確実性に不安が残る

それらを回避する為に利用される設定である

## 関連する公式ドキュメント

https://docs.microsoft.com/ja-jp/azure/app-service/configure-common
> トラフィックがない場合も、アプリを読み込まれたままにします。 継続的な Web ジョブや、CRON 式を使用してトリガーされる Web ジョブに対して有効にする必要があります。

https://docs.microsoft.com/ja-jp/azure/app-service/webjobs-create
> Web アプリは、20 分間アクティビティがないとタイムアウトする可能性があります。


## 挙動について
https://stackoverflow.com/questions/36955571/azure-website-always-on

> Always On が行う唯一のことは、アプリのルートに数分ごとに ping リクエストを送信することです。
> 同じ間隔で同じようなリクエストを自分で送信することとそれほど変わりません。

なお、ユーザーエージェントの値 `AlwaysOn` でリクエストの種類を判断可能
https://social.msdn.microsoft.com/Forums/office/en-US/77398e8a-2045-4309-b910-24d601642f11/azure-websites-always-on

サンキューデビッド




# 参考
https://blog.shibayan.jp/entry/20200113/1578920798#Always-on-%E3%82%92%E6%9C%89%E5%8A%B9%E5%8C%96%E3%81%99%E3%82%8B
https://poke-dev.hatenablog.com/entry/2019/03/17/232201
Wavefrontで学ぶHorizontal Pod  Autoscaler ~概要編


この文章は、WavefrontでHorizontal Pod Autoscaler　シリーズの第一回目です。

# シリーズ

第一回　：　概要編　**← いまここ**
第二回　：　Wavefront情報からスケールする
第三回　：　サーバーレスもどきを実装する

# Wavefrontとはなんぞや？

WavefrontとはいうのはSaaSベースのクラウドおよびアプリケーションの監視プラットフォームです。
現在はVMwareに買収されており、Tanzu Observabilityと呼ばれています。
このシリーズでは、旧称のWavefrontを多用しますが同じものです。

# Horizontal Pod Autoscalerとはなんぞや？

Horizontal Pod Autoscaler(HPA)とは、KubernetesでデプロイしたPODを負荷をモニターしてスケールアウトする機能です。

https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/

# HPAを普通に使って何が悪いの？

さて、この機能でよく勘違いされるのが、k8sをインストールした直後にOOTB（Out of the Box)で使えないという点です。

通常はHPAを使えるようになるためには、なんらかのメトリクスを収集する別のツールが必要です。
有名なのが、metrics-serverです。

https://github.com/kubernetes-sigs/metrics-server

ただし、かかれている通り、CPU、Memoryにのみの対応です。
さらによくある問題として、「ほんとうにCPUがそのとき高かったの？」問題です。結局のところOpsチームはモニターダッシュボードをみていて、そのCPU、MemoryがうまくAutoScaleの事象に合わないといらぬコミュニケーション問題に発展しかねないです。

# Prometheusは？

PrometheusをHPAのソースとして使うというのは昨今外国のブログで紹介されています。
例えば以下です。

https://towardsdatascience.com/kubernetes-hpa-with-custom-metrics-from-prometheus-9ffc201991e

ただし、これも注意しないといけないのが、Prometheusを本番業務に影響を与えるコンポーネントに昇格させてしまう点です。Prometheusの運用に慣れていない場合やHAの構成をとれていない場合、あまりお勧めができない構成となってしまいます。

# じゃあどうするの？

そこでWavefrontですよ。
Wavefrontでは昨今のTanzu情勢から、kubernetesの連携を強めており、正式にHPAのアダプターをサポートしています。

https://github.com/wavefrontHQ/wavefront-kubernetes-adapter

英語ですが以下の動画でも取り上げて説明されています。

[![IMAGE ALT TEXT HERE](http://i3.ytimg.com/vi/nZnbdNHFNyU/hqdefault.jpg)](https://www.youtube.com/watch?v=nZnbdNHFNyU)
https://www.youtube.com/watch?v=nZnbdNHFNyU


これを使うことのメリットとして

* Opsが見ているダッシュボードと同じメトリクスでHPAができる
* CPU、Memory以外の好きなメトリクスで自由に定義できる
* SaaSならではの、可用性(%99.95 Availability）とパフォーマンス保証

# このシリーズはなんぞや？

HPAというものを長らく存在を知っておきながら、いまだkubernetesの飛び道具的存在であり、手を出すの躊躇していたのはきっと私だけではないはず。

このシリーズでは、WavefrontというSaaSモデルでサポートされているシステムでHPAを構成してみて、今一度HPAがどのように動くものなのか理解を深めるというものです。

次回は「[Wavefront情報からスケールする](https://qiita.com/hmachi/items/cfeeb53ea37f12ac27af)」です。
【orderメソッド】Railsで、データの並び順を設定する

#参考対象者
- Railsで、アプリ作ってるけど、あるデータの並び替えをしたいなと思っている方

#特定の状況下で、データを並び替えたいとき

###基本形

```
Model.order(Column: :DESC)
Model.order("Column DESC")
```

デフォルトでは、ASC（昇順）になっているので、DESC（降順）にすることができる

###実際に、並び替えしたデータ群を取得してみる

```feed_controller.rb
#データベース上の全てのデータを取得
feeds = Feed.order(id: :DESC)

#現在ログイン中ユーザーの全てのデータを取得
feeds = current_user.feeds.order(id: :DESC)
```

今回は、Feedモデルというデータを取得してみた。
上は、データベース上の全てのデータを取得し、
下は、現在ログイン中ユーザーの全てのデータを取得している。

こうすることで、降順になったデータ群を取得することができる。


#デフォルト設定を変更して、並び替えしたいとき

###モデルファイルに並び順を設定する

```models/feed.rb
default_scope -> { order(created_at: :desc) }
```

今回も、Feedモデルというデータの並び替え設定をした。
この記法は、ラムダ関数というもので、特殊である。

こうすることで、作成した日時(created_at)の降順で、並び替えするようにデフォルト設定を行うことができる。
Arduino as ISPでAVRプログラミング

- 目的  
AVRマイコン勉強のための環境を用意したい。そのためArduinoをAVRマイコン化したい。  
さらにライターもケチって、別のArduinoをライター化して使いたい。

- 使用した環境
    - Arduino Uno R3 (ライター用)
    - Arduino Uno R3 (書き込み対象)
    - Arduino IDE (Ver 1.8.12)
    - Atmel Studio 7.0 (Ver 7.0.2397)

- 手順
  - Arduinoのライター化 (Arduino as ISPスケッチを書き込む)  
Arduino IDEを用いて、下記より選んだスケッチをArduinoに書き込む。  
(Arduino IDEを用いたスケッチの書き込み方法自体は本記事では省略)  
これでArduinoがAVRライタとして使えるようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633134/84c4a575-4bb7-4c7a-c254-369f2bfefc62.png)

  - AVRマイコンへの書き込み  
Atmel studioでArduino as ISP をライターとして登録  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633134/8b4683e2-f378-76b2-e61b-3064f6087192.png)  
Argumentに入力したのは下記。COMや書き込み対象マイコン(m328p)は必要に応じて変える必要があります。  
`-c avrisp -P COM3 -b 19200 -p m328p -U flash:w:$(ProjectDir)Debug\$(TargetName).hex:i -U lfuse:w:0xff:m -U hfuse:w:0xde:m -U efuse:w:0x05:m`  
最終的に書きのとおり登録します。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633134/e4f396a6-bfbb-2059-7d2c-3c9698b6278e.png)


    - 書き込み  
別途用意したcファイルをAtmel Studio上でビルドして、上記にて登録したArduino as ISPを選択して書き込む。


- 参考にしたサイト
  - https://synapse.kyoto/hard/bootloader_writer/page001.html  
このサイトを参考にArduino UNOをArduino as ISPとして、ブートローダを書き込むことは成功した。
(手持ちのhttp://akizukidenshi.com/catalog/g/gK-04590/ に書いた)  
ただし、Arduino IDE経由でできるのはブートローダの書き込みだけ。
  - https://synapse.kyoto/tips/ArduinoISP_AVRWriter/page001.html#index6  
それ以外のhexファイルを書くには、Atmel studio経由で書き込まなければならない。  
(ライターとしては上記と同じArduino as ISPでいいらしい)
  - http://elec-studio.eco.coocan.jp/AVR_C-Program04.html  
ここにある.cファイルをAtmel studioにてビルドして上記方法によりArduino ISPで書き込んだ。  
ブレッドボードでLED繋いだらちゃんと点滅してたし、時間も変えられた。
bashでcsvを簡単に１行ずつ処理する

# 経緯

仕事でよくbashを使うのだが、csvを整形して1行ずつ取り出し、sql作って投げる必要が出てきた。
久しぶりだったので、「そういえばいつもやってる方法で１行ずつ処理なんて出来るんだっけ？」と不安になり、検証しながらググってみたら意外に私のやり方でやってる人が少ないっぽいので此処に記す

whileとreadlineとか使っている人が多いようだが、慣れてないからか覚えられない＆可読性低いと感じてしまう
自分がよくやる方法はbashのループ処理（forは良いぞ）と変数化で割と応用が利くやり方なので、覚えて損はないと思う

# やってみる

対象のcsvファイルはこんな感じ

```bash
$cat list.csv 
name,num,mail
name1,1,sample1.com
name2,2,sample2.com
name3,3,sample3.com%                  
```

このcsvファイルを$(cat list.csv)と変数にしてforに渡す
これで```cat list.csv```の結果をそのまま渡すことができる
バッククォートを使って\`cat list.csv`として同じことができるけど、ダブルクォーテーションとかシングルクォーテーションが入ってくると途端に可読性が落ちるし、変数展開とかエスケープとか色々面倒なので私はいつも$()を使う

```bash
count=0
for I in $(cat list.csv);do 
    echo "開始$((++count))"
    echo $I
    echo "終了${count}"
done
```

実行結果

```bash
開始1
name,number,email
終了1
開始2
name1,0001,example1.com
終了2
開始3
name2,0002,example2.com
終了3
開始4
name3,0003,example3.com
終了4
```

書式

```bash
for I in $(cat file.csv);do 
    何か処理（＄Iにはfile.csvの１行目が入り、１ループ毎に次の行の内容になる）
done
```

# おまけ

$(cat file.csv)の部分はイテレータ的なものであればなんでも良いらしい

よく使うのはここら辺か

連番処理(表示するだけなら```echo {1..5}```とかで済む)

```bash
for I in {1..5};do 
    echo "私は${I}番目です"
done
```

結果

```bash
私は1番目です
私は2番目です
私は3番目です
私は4番目です
私は5番目です
```

数字じゃなくても良い

```bash
for I in A B C;do 
    echo "私は${I}番目です"
done
```
結果

```bash
私はA番目です
私はB番目です
私はC番目です
```

lsの結果を渡してカレントディレクトリのファイルを1つずつ処理するとか

```bash
$ls
a	b	c	d
```

```bash
for I in $(ls);do
 echo "私は${I}です"
done
```

結果

```
私はaです
私はbです
私はcです
私はdです
```
【超初心者的】Railsアプリ作成 Part.2 コントローラとルーティングの設定

Part.1でデータベースのデータ登録をrails consoleで行いましたが、実際にはデータの登録はアプリの画面で行われます。ここではアプリの画面からデータベースのデータ登録や更新を行うための準備を行います。

##コントローラ作成

MVCのCです。
コントローラ名は複数形にします。ここではmenusにしています。

```terminal:ターミナル
% bin/rails g controller menus index
```

##☆コントローラ削除

コントローラ名を間違ってしまった場合に

```terminal:ターミナル
% bin/rails destroy controller menus
```

##ルーティング設定

〜〜〜doとendの行の間は削除して、1行追加します。これだけでいろいろなルートが設定されます。Progateと全然違うやん！！ってとまどいました。

```ruby:config/routes.rb
Rails.application.routes.draw do
  resources :menus
end
```

##ルーティング確認

Progateの時は1行ずつパスを書いてたのに、たった1行でこれだけのルーティング設定がされました。これについては後のPartに記載します。（私は最初これを見ても意味不明だったのですが、アプリを作っていく中でなんとなくわかってきて、ちょっとうれしくなりました。）

```terminal:ターミナル
% bin/rails routes
    Prefix Verb     URI Pattern                 Controller#Action
     menus GET      /menus(.:format)            menus#index
           POST     /menus(.:format)            menus#create
  new_menu GET      /menus/new(.:format)        menus#new
 edit_menu GET      /menus/:id/edit(.:format)   menus#edit
      menu GET      /menus/:id(.:format)        menus#show
           PATCH    /menus/:id(.:format)        menus#update
           PUT      /menus/:id(.:format)        menus#update
           DELETE   /menus/:id(.:format)        menus#destroy
```

実はこのURLにアクセスしても確認することが出来ます。
http://localhost:3000/rails/info/routes

##コントローラ設定基本形

```ruby:app/controllers/menus_controller.rb
class MenusController < ApplicationController
  def index
    @menus = Menu.all
  end

  def show
    @menu = Menu.find(params[:id])
  end

  def new
    @menu = Menu.new
  end

  def edit
    @menu = Menu.find(params[:id])
  end

  def create
    @menu = Menu.new(params[:menu])
    if @menu.save
      redirect_to menus_path, notice: "作成しました"
    else
      render "new"
    end
  end

  def update
    @menu = Menu.find(params[:id])
    @menu.assign_attributes(params[:menu])
    if @menu.save
        redirect_to menus_path, notice: "更新しました"
    else
        render "edit"
    end
  end

  def destroy
    @menu = Menu.find(params[:id])
    @menu.destroy
    redirect_to menus_path, notice: "削除しました"
  end
end
```

defの右側に書かれているindexやnewはメソッドと呼ばれます。
Part.1で Menu.new(name: "ラーメン" 〜〜〜) というコマンドでデータを登録しましたが、このコマンドのnewがまさにそれです。newはデータを新規登録するためのメソッドなので、Menuのデータベースにデータを新規登録（new）するという意味になります。

他のメソッドはだいたい以下のような感じの意味です。アプリケーションの基本動作って感じがしますね。とりあえずこの設定があればアプリが作れます。

| メソッド名 | 役割 |
|---------|---------|
|index|データの一覧表示|
|show|データの詳細表示|
|edit|データの編集|
|create|newで登録したデータを保存する|
|update|editしたデータを上書き保存する|
|destroy|データを削除する|


[【超初心者的】Railsアプリ作成 Part.3 ビューの設定](https://qiita.com/masarashi/items/7e62c3e93ae5d92973c5) に続く。
【超初心者的】Railsアプリ作成 Part.1 モデルの作成

次は土台づくりです。このパートは何回かに記事を分けます。

まずはデータベースにデータを登録できるようにします。なお、一度にいくつも覚えられないのでバリデーションは考慮していません。

##モデルの作成

MVCのMです。
モデル名は単数形にします。テーブルなどの名前は自動的に複数形で作成されます。
（ramenみたいな日本語は複数形にならなかった。。。）

ここではモデル名をmenuにしています。

```terminal:ターミナル
% bin/rails g model menu
```

カラムも最初に作成したい時

```terminal:ターミナル
% bin/rails g model menu title:string body:text
```

##☆モデルの削除

名前を間違ってしまった場合に

```terminal:ターミナル
% bin/rails destroy model menu
```

##テーブルの作成

自動的にファイルが作成されるので編集。カラムはname, price, descriptionの3つ。

```ruby:db/migrate/20200702105514_create_menus.rb
class CreateMenus < ActiveRecord::Migration[6.0]
  def change
    create_table :XXXXX do |t|
      t.string :name
      t.integer :price
      t.text :description
```

##マイグレーション

```terminal:ターミナル
% bin/rails db:migrate
```

##ストロングパラメータ無効化

勉強不足で説明はできないのですが、これが有効だとDBへのデータ登録がうまくいかないことがあるので、無効にします。記載後はたしかサーバ再起動が必要だったはずです。

28行目あたり（タイムゾーン設定の下に記載しました）

```ruby:config/application.rb
    config.time_zone = "Tokyo"
    config.action_controller.permit_all_parameters = true
```

##テスト：データ登録

コンソールでデータ登録をしてみます。最初にrails consoleを起動します。データ登録のコマンドはProgateでやった気がします。

```terminal:ターミナル
% bin/rails c
```

```ruby:ターミナル
irb(main):001:0> menu = Menu.new(name: "ラーメン", price: 600, description: "おいしい")
irb(main):002:0> menu
=> #<Menu id: 1, name: "ラーメン", price: 600, description: "おいしい", created_at: "2020-07-12 00:09:04", updated_at: "2020-07-12 03:25:51">
```

入力した内容が表示されたら成功です。saveしてrails consoleを終了します。

```ruby:ターミナル
irb(main):003:0> menu.save
irb(main):004:0> quit
```

[【超初心者的】Railsアプリ作成 Part.2 コントローラとルーティングの設定](https://qiita.com/masarashi/items/b7a29021fe5883e588b4) に続く
コピペで使える＋－トグルアイコン

自分用チートシートです。
※JQuery必須

#HTML
```html
<span class="icon"></span>
```
これだけ。

#CSS
```scss
.icon {
	display:block;
	position:relative;
	width:30px;  //正方形推奨
	height:30px; //正方形推奨
}
.icon:before,
.icon:after{
	content:'';
	display:block;
	position:absolute;
	top:50%;
	transform:translate(0,-50%);
	width:100%;
	height:3px; //線の太さ
	background-color:pink; //線の色
}
.icon:after {
	transform:translate(0,-50%) rotate(90deg);
}

.icon.minus:before {
    opacity: 0;
}
.icon.minus {
	transform:rotate(90deg); 
}

.icon,
.icon:before {
	transition: .4s; //トグルする時のアニメーション速度
}
```

#JQuery
```js
$('.icon').on('click', function(){
    $(this).toggleClass('minus');
});
```

以上です。
スマホで情報量多めのページ作る時けっこう便利です。
大抵はトグル表示するコンテンツと合わせてdivで囲って使うと思うので、toggleClassは親divに対して行った方がいろいろとスマートにいけるかもです。
React HooksでStackな構造を扱うカスタムフック

(2020.08.12更新)
こちらで公開しました。
https://github.com/nariakiiwatani/react-use-stack-ref
https://www.npmjs.com/package/react-use-stack-ref
少し修正加えてるのでもし使われる際はこちらを使ってください。

`npm i react-use-stack-ref`
または
`yarn i react-use-stack-ref`
でインストールできます。

---

[useStackRef.ts](https://gist.github.com/nariakiiwatani/a28c9c025fe148c3baa60331dfb50062)

スタック構造を持ったデータをスッキリ扱いたかったので作った。
作ってみてわかったのは、これはもうほとんどArrayにスタックのインターフェースを被せただけものになったということ。
それでも使う側はだいぶスッキリするから、ないよりはあった方が良くはある。

```ts:useStackRef.ts
import { useRef } from "react";

export interface Stack<T> {
	value: T | null
	size: number
	push: (t: T) => number
	pop: () => T
	reset: () => void
	clear: () => void
}

export const useStackRef = <T>(init: T | T[] | (() => T) | (() => T[]) = []): Stack<T> => {
	const initial: T[] = ((value) => Array.isArray(value) ? value : [value])(init instanceof Function ? init() : init)
	const stackRef = useRef<T[]>(initial)

	const push = (t: T): number => stackRef.current.push(t)
	const pop = (): T => stackRef.current.pop() || null
	const reset = (): void => { stackRef.current = initial }
	const clear = (): void => { stackRef.current = [] }

	return {
		value: stackRef.current.slice(-1)[0] || null,
		size: stackRef.current.length,
		push, pop, reset, clear
	};
};
```

ちなみに、useRefでなくuseStateのスタックを作って紹介している記事はこちら。
[React Hooksのカスタムフックが実現する世界 - オブジェクト指向とOSS](https://qiita.com/sonatard/items/617f324228f75b9c802f)
==(同一性)とequalsメソッド(同値性)の違い、オーバーライドしよう

javaには二つの「同じ」がある。
#==(同一性)
==演算子は、同一であることを判定する。つまり、複数の変数が同じインスタンスを参照していることを判定する。

```java

A a = new A(); // A型というインスタンスを生成
A b = a; // aのインスタンスごとそのままbへコピー
System.out.println(a == b); 
```
```
true
```
###例題

```java

public class Sample {
	private int num;
	public Sample(int num) {
		this.num = num;
	}
}
```
```java
public class Main {
	public static void main(String[] args) {
		Sample s0 = new Sample(5); // Sample型のインスタンス生成
		Sample s1 = s0; // s1にコピー
		s0 = new Sample(5); // 新たにSample型インスタンス生成
		System.out.println(s0 == s1);
	}
}
```
```
false
```
`Sample s1 = s0;`でコピーした時点では、同じインスタンスを持っていたが、次の行で`s0`が新たにインスタンスを生成し、`s0`と`s1`は違うインスタンスになった。

#equalsメソッド(同値性)
equalsメソッドは、同値であることを判定する。つまり、インスタンスはことなるが、同じ値を持っているか判定する。

デフォルトのObjectクラスに定義されているequalsメソッドは、

```java
public boolean equals(Object obj){
  return (this == obj);
}
```
と定義されており、同一性を確認する仕様になっているため、

***オーバーライドして使用することを前提としている。***

さらに！！

***equalsメソッドをオーバーライドする時は、セットでhashCodeもオーバーライドしないといけない。***
※ hashCodeとは、インスタンスが持っている値をハッシュ関数に変換して、確認できるメソッド

>[Object(Java SE 11 & JDK 11)](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/lang/Object.html
)
>>equals
通常、このメソッドをオーバーライドする場合は、hashCodeメソッドを常にオーバーライドして、等価なオブジェクトは等価なハッシュ・コードを保持する必要があるというhashCodeメソッドの汎用規約に従う必要があることに留意してください。


###例題

```java

public class Sample {
	private int num;
	private String name;
	public Sample(int num, String name) {
		this.num = num;
		this.name = name;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result + num;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Sample other = (Sample) obj;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (num != other.num)
			return false;
		return true;
	}


}

```
```java

public class Main {
	public static void main(String[] args) {
        // 引数(num, name)が同じ
		Sample a = new Sample(5, "xxx"); 
		Sample b = new Sample(5, "xxx");
		System.out.println(a.equals(b));
        // それぞれのhashCodeを出力
        System.out.println(a.hashCode());
        System.out.println(b.hashCode());
	}
}
```
```
true
3694926
3694926
```
equalsメソッドとhashCodeメソッドをオーバーライドしている。

もし、numかnameが一つでも違えば以下のようになる。

```java

public class Main {
	public static void main(String[] args) {
        // 引数(name)が違う
		Sample a = new Sample(5, "xxx");
		Sample b = new Sample(5, "yyy"); 
		System.out.println(a.equals(b));
        // それぞれのhashCodeを出力
        System.out.println(a.hashCode());
        System.out.println(b.hashCode());
	}
}
```
```
false
3694926
3725709
```
equals判定は`false`になり、hashCodeも違う値が出力されている。
Linuxコマンド#4

linuxコマンド#4です。


#grepコマンド
文字を検索する
gerep [オプション] <検索パターン> <ファイル名>
<ファイル名>から<検索パターン>に一致する行を取り出す。

```sh
[wataru@localhost work]$ cat work.02.txt 
2020/07/17
test?cat
123445

[wataru@localhost work]$ 
[wataru@localhost work]$ grep 17 work.02.txt 
2020/07/17
```

```sh
[wataru@localhost work]$ grep -n test work.02.txt 
#-nを指定すると行数を出力できる
2:test?cat
```

```sh
[wataru@localhost work]$ grep -i test work.02.txt 
#-iを指定すると大文字小文字の区別をしない
test?cat
TEST?CAT
test
testcat
```

```sh
[wataru@localhost work]$ grep -v test work.02.txt 
#-vを指定すると一致しなかった行を表示する
2020/07/17
123445
TEST?CAT
```

```sh
[wataru@localhost work]$ grep 't[ef]*' work.02.txt 
#特定の文字列を指定したい場合は、[]というメタ文字を使用する
test?cat
test
testcat
tfst
```

```sh
[wataru@locsalhost work]$ grep 'test[01-10]' work.02.txt 
#test01~10までを検索指定している
test01
test02
test03
test04
```

#sedコマンド
ストリームエディタ（非対話型エディタ）

```sh
[wataru@localhost work]$ cat work.02.txt 
#work.02.txtの全量
2020/07/17
test?cat
123445
TEST?CAT
test
testcat
tfst
test01
test02
test03
test04

[wataru@localhost work]$ sed 1d work.02.txt 
#1dで1行目を削除する意味
test?cat
123445
TEST?CAT
test
testcat
tfst
test01
test02
test03
test04
```

```sh
[wataru@localhost work]$ sed 1,5d work.02.txt 
#,[カンマ]で「n行目～m行目まで」と指定可能
testcat
tfst
test01
test02
test03
test04
```

```sh
[wataru@localhost work]$ sed '4,$d' work.02.txt 
#$を指定することで最終行まで削除することが可能
#4行目～最終行目
2020/07/17
test?cat
123445
```

```sh
[wataru@localhost work]$ sed -n 2p work.02.txt 
#行を表示するpに-nオプションを追加すると、特定の行を出力する
test?cat
```

#awkコマンド
パターン検索
テキストの検索、抽出・加工などの編集処理をする

```sh
[wataru@localhost work]$ ls -l
total 8
drwxrwxr-x. 2 wataru wataru   6 Jul  5 04:38 gogodur
drwxrwxr-x. 3 wataru wataru 156 Jul 17 04:25 testgo
-rw-rw-r--. 1 wataru wataru  83 Jul 29 05:56 work.02.txt
-rw-rw-r--. 1 wataru wataru   0 Jul  5 04:09 work.03.txt
-rw-rw-r--. 1 wataru wataru  25 Jul 21 04:32 work.04.txt
-rw-rw-r--. 1 wataru wataru   0 Jul  5 04:09 work.05.txt
-rw-rw-r--. 1 wataru wataru   0 Jul  5 04:09 work.06.txt
-rw-rw-r--. 1 wataru wataru   0 Jul  5 04:09 work.07.txt
-rw-rw-r--. 1 wataru wataru   0 Jul  5 04:09 work.08.txt
-rw-rw-r--. 1 wataru wataru   0 Jul  5 04:09 work.09.txt

[wataru@localhost work]$ ls -l | awk '{print $1}' 
#awkでよく使用される処理は、特定のフィールドを抽出して表示する、列選択
#フィールド1番を抽出している
total
drwxrwxr-x.
drwxrwxr-x.
-rw-rw-r--.
-rw-rw-r--.
-rw-rw-r--.
-rw-rw-r--.
-rw-rw-r--.
-rw-rw-r--.
-rw-rw-r--.
-rw-rw-r--.

[wataru@localhost work]$ ls -l | awk '{print $1,$9}' 
#フィールドを複数選択することも可能
total 
drwxrwxr-x. gogodur
drwxrwxr-x. testgo
-rw-rw-r--. work.02.txt
-rw-rw-r--. work.03.txt
-rw-rw-r--. work.04.txt
-rw-rw-r--. work.05.txt
-rw-rw-r--. work.06.txt
-rw-rw-r--. work.07.txt
-rw-rw-r--. work.08.txt
```

```sh
[wataru@localhost work]$ echo 100 300 | awk '{print $1}'
100

[wataru@localhost work]$ echo 100 300 | awk '{x=$1*$2; print x}'
#awkは計算も可能
#計算結果をx変数に格納して、その結果を出力することも可能
30000

[wataru@localhost work]$ seq 1 10 | awk '{x=x+$1; print x, $1}'
#seqコマンドで1～10までの数字を出力します
#awkコマンドで入力の1～10までの数字を足してその結果を出力
1 1
3 2
6 3
10 4
15 5
21 6
28 7
36 8
45 9
55 10
```
[swift5]エラーNo such module 'ライブラリ名'

## エラー状況
画像のようにXcodeでビルドを行うと`No such module 'ライブラリ名'`というエラーが発生する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643372/bc049112-f057-ea15-74c1-0b4225ed76f7.png)

## 対応したこと

①Xcodeの再起動
②Macの再起動
③podfileの確認と`pod install`を再度実行

①〜③全て不発...
検索を行い色々と模索していると解決しそうな記事に遭遇！
https://qiita.com/doge_kun55/items/26ac2fa2031ddbeee879

## 解決方法
Xcodeのツールバーにある`Product/Scheme/ManageSchemes/`を選択。
すると以下のようにページが開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643372/6dc41079-445a-8c0b-431b-fe11b44691e7.png)

今回の場合はデフォルトで`Swift5Bokete`にチェックがついており、その他にはチェックはついていませんでした。
なので全ての項目の`show`と`shared`にチェックをつけて`Close`をクリック。

**そのあと、再ビルドを実行すると無事ビルドされました。**

## 最後に

ちなみに、今回エラーの解決はしていますが、**何が原因で、どういう理由で解決に至ったか**ということが理解できておりません。もし、この記事を見た方の中に原因をわかる方がおられましたらご教授の程宜しくお願い致します。
UnityのC#からGitを叩く

# UnityのC#からGitを叩く

UnityのC#のEditor拡張スクリプトからGitコマンドを叩く機会があったので、忘れない内にまとめます。



## サンプルコマンド

今回、例として、UnityのC#から以下のコマンドを叩いてみます。

```bash
git config core.autocrlf
```

改行コードを自動で変換する機能が有効になっているか確認できるコマンドです。



## サンプルコード

以下がサンプルコードです。外部から `GetAutocrlf` を叩けばコマンドが実行されます。

```c#
using System;
using System.Diagnostics;
using System.IO;
using UnityEditor;
using UnityEngine;
using Debug = UnityEngine.Debug;

public class GitCommandPractice
{
    /// <summary>
    /// Gitのautocrlfを確認する。
    /// </summary>
    public void GetAutocrlf()
    {
        // gitのパスを取得する。
        string gitPath = GetGitPath();
        
        // gitのコマンドを設定する。
        string gitCommand = "config core.autocrlf";

        // コマンドを実行して標準出力を取得する。
        string autocrlf = GetStandardOutputFromProcess(gitPath, gitCommand).Trim();
        
        Debug.Log(autocrlf);
    }

    /// <summary>
    /// Gitの実行ファイルのパスを取得する。
    /// </summary>
    /// <returns>Gitのパス</returns>
    private string GetGitPath()
    {
        // Macのとき
        if (Application.platform == RuntimePlatform.OSXEditor)
        {
            // パスの候補
            string[] exePaths =
            {
                "/usr/local/bin/git",
                "/usr/bin/git"
            };

            // 存在するパスで最初に見つかったもの
            return exePaths.FirstOrDefault(exePath => File.Exists(exePath));
        }

        // Windowsはこれだけで十分
        return "git";
    }
    
    /// <summary>
    /// コマンドを実行して標準出力を取得する。
    /// </summary>
    /// <param name="exePath">実行ファイルのパス</param>
    /// <param name="arguments">コマンドライン引数</param>
    /// <returns>標準出力</returns>
    private string GetStandardOutputFromProcess(string exePath, string arguments)
    {
        // プロセスの起動条件を設定する。
        ProcessStartInfo startInfo = new ProcessStartInfo()
        {
            FileName = exePath,
            Arguments = arguments,
            WindowStyle = ProcessWindowStyle.Hidden,
            UseShellExecute = false,
            RedirectStandardOutput = true,
        };

        // プロセスを起動する。
        using (Process process = Process.Start(startInfo))
        {
            // 標準出力を取得する。
            string output = process.StandardOutput.ReadToEnd();

            // プロセスが終了するかタイムアウトするまで待つ。
            process.WaitForExit(TimeoutPeriod);

            return output;
        }
    }
}
```



## 解説

C# の `Prosess` を使って、Gitコマンドを叩き、その標準出力を読み取るという仕組みです。

`GetGitPath()` では、Gitの実行ファイルのパスを取得しています。

Gitの実行ファイルのパスは、環境変数Pathに登録されていることが一般的だと思うので、単に `git` と記述してもほとんどの場合、問題ないと思います。

ただし、私のMac環境ではそれではうまく行かなかったので、 `/usr/local/bin/git` と `usr/bin/git` の2種類を明示的にハードコーディングし、どちらか見つかった方を実行ファイルとして利用するようにしました。



## さいごに

本記事作成にあたり、以下を参考にしました。ありがとうございました。

- [子プロセスの標準出力を取得する方法](https://csharp.keicode.com/topics/capture-stdout.php)
【AWS SAA】ゲートウェイ に関する備忘録

#はじめに
AWS SAAの問題でゲートウェイの理解を問うような問題が頻出だが、様々なゲートウェイがあり構成がわかりにくいため、この記事を通してゲートウェイに対する理解を深めたい。

#そもそもゲートウェイとは？
英語で「出入り口」を意味する。コンピュータネットワークにおいて、通信プロトコルが異なるネットワーク同士がデータをやり取りする際、中継する役割を担うルータのような機能を備えた機器やそれに関するソフトウェアのこと。AWSでは物理的なルーターではなく、ソフトウェア的にルーティングを行なっている。ルーティングはルートテーブルに従って行われる。

#試験に出題されるゲートウェイ  
ゲートウェイにはインターネットゲートウェイ・仮想プライベートゲートウェイ・カスタマーゲートウェイ・NATゲートウェイが主にある。その中でも試験に出題されるものとして「インターネットゲートウェイ」と「NATゲートウェイ」が挙げられる。

<h2>・インターネットゲートウェイ </h2>
インターネットと接続するためのゲートウェイ。例えばVPC内にあるEC2インスタンスがプライベートIPアドレスしか設定できない場合、インターネットゲートウェイがリクエストとEC2インスタンスの結びつきの情報を持ち、宛先をパプリックIPアドレスからプライベートIPアドレスに変換し、該当のEC2インスタンスにリクエストを送る。

## ・NATゲートウェイ 
プライベートサブネットからインターネットにアクセスする際に、プライベートIPアドレスからパブリックIPアドレスにアドレス変換を行う。サブネットからインターネットに接続できるが、インターネットからサブネットに接続できないようにすることが可能。

[この記事](https://milestone-of-se.nesuke.com/sv-advanced/aws/internet-nat-gateway/)のようにインターネットゲートウェイの配置場所=VPC, NATゲートウェイの配置場所=サブネットのように覚えるとわかりやすいかも。

#ちなみに...NATインスタンスとNATゲートウェイの違い 
## ・NATインスタンス
EC2>コミュニティAMI>ami-vpc-natを選択してインストールすると、NAT機能付きEC2インスタンスが作成できる。NATゲートウェイとは違い、通常のEC2インスタンスのように利用していない時は停止が可能。

## ・NATゲートウェイ 
NAT専用に構成された仮想的なコンポーネント。配置するサブネットを選ぶだけで構成できる。NATインスタンスとは違って負荷に応じてスケールアップする。
 

#参考
この１冊で合格！　AWS認定ソリューションアーキテクト - アソシエイト テキスト&問題集
AWS　しくみと技術がしっかりわかる教科書
Amazon Web Services 基礎からのネットワーク&サーバー構築 
https://ejje.weblio.jp/content/gateway
https://www.keyence.co.jp/ss/general/iot-glossary/gateway.jsp
【超初心者的】Railsアプリ作成 Part.0 はじめにやること

Railsの勉強を初めて約4ヶ月（Bootstrapとかに寄り道した時期もありました）、Progateを終えた後は参考書で勉強をしていましたがモチベーション低下してきたので、自分なりにアプリを作り始めました。これまでやってきたことをメモ帳に書いていましたが、せっかくなので記事にしていきます。

##執筆時点のスキルレベル

- Progate Ruby/Railsコース完了
- ドットインストール Railsコース完了
- [書籍]Ruby on Rails 5 速習実践ガイド（途中まで。ちょっと難易度高め。）
- [書籍]基礎 Ruby on Rails 改訂4版（途中でモチベーション低下。笑）

Progateが終わったけど何しようという方が、最短でとりあえず動くアプリの原型を作れるような記事に出来ればと思っています。

##どんなアプリか

私の好きなラーメンの食べログ風（ぶっちゃけ劣化）アプリです。

##主な機能

- ラーメン管理
- 店舗管理
- ログイン（ユーザ管理）
- レビュー投稿

##OS

Catallina 10.15.6

##バージョン

```ruby:ターミナル
% rbenv -v
rbenv 1.1.2

% ruby -v
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-darwin19]

% rails -v
Rails 6.0.3.2

% psql --version
psql (PostgreSQL) 12.3
```

##PostgreSQL起動

```terminal:ターミナル
% brew services start postgresql
```

##アプリケーション新規作成

メールの機能は使わないのでオプションをつける

```terminal:ターミナル
% rails new appname -d postgresql --skip-action-mailer --skip-action-mailbox
```

##データベース設定

17行目あたり

```yml:database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  # For details on connection pooling, see Rails configuration guide
  # https://guides.rubyonrails.org/configuring.html#database-pooling
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: XXXXX
  password: XXXXX
  host: localhost
```

##データベース作成

```terminal:ターミナル
% bin/rails db:create
```

##タイムゾーン

27行目あたり

```ruby:config/application.rb
config.time_zone = "Tokyo"
```

##サーバ起動

```terminal:ターミナル
% bin/rails s
```

ポートを変更したい時。ローカルで複数アプリを作っている場合などに。

```terminal:ターミナル
% bin/rails s -p 3001
```

バックグランドで実行させたい時

```terminal:ターミナル
% bin/rails s -d
```

バックグラウンドで実行した場合、サーバ停止する際は puma の PID を確認して kill する。

```terminal:ターミナル
% ps aux | grep puma
XXXXX             1134   0.0  0.3  4553888  48736 s000  S+   水08PM   1:39.24 puma 4.3.5 (tcp://localhost:3000) [appname]  

% kill 1134
```

##アクセス
http://localhost:3000/


[【超初心者的】Railsアプリ作成 Part.1 モデルの作成](https://qiita.com/masarashi/items/f7703cb8a6d9f79d1c7a) に続く。
Minikube入門

# インストール
Amazon EC2で、Minikubeを動かしてみた。

```bash
sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl gnupg-agent     software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key  add -
sudo add-apt-repository     "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
sudo apt install -y docker-ce
sudo apt install -y conntrack
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64   && chmod +x minikube
sudo mkdir -p /usr/local/bin/
sudo install minikube /usr/local/bin/
sudo minikube start --driver=none
sudo cp -r /root/.kube /root/.minikube $HOME
sudo chown -R $USER $HOME/.kube $HOME/.minikube
sudo cp .minikube/cache/linux/v1.18.3/kubectl /usr/local/bin/kubectl
```

# この環境で動いたソフト
- [optuna](https://github.com/optuna/optuna/)


# 参考資料
- [Install Minikube](https://kubernetes.io/docs/tasks/tools/install-minikube/)
   - AWS EC2の場合、`--driver=none`でインストールする。
   - [Install Docker Engine on Ubuntu](https://docs.docker.com/engine/install/ubuntu/)
- [Deploy using MiniKube on Linux](https://www.kubeflow.org/docs/started/workstation/minikube-linux/)

## トリック
Ubuntu 19.10以降は、`--driver=none`で入れると、`root`権限でしか、kubectlは動かない。ただし、以下の記事にあるトリックを使うと、外すことができる。

- [Minikube won't work after Ubuntu upgrade to 19.10](https://stackoverflow.com/questions/58541104/minikube-wont-work-after-ubuntu-upgrade-to-19-10/58557265#58557265)
- [none: minikube should be able to be run by a non-root user (use sudo when necessary) #3760](https://github.com/kubernetes/minikube/issues/3760)
heroku(無料プラン)で独自ドメインサイトにする方法

herokuの無料プランは、**無料**でサイトを公開できる素晴らしいサービスです。
でも、[appname]herokuapp.comはダサいし、**独自ドメイン**が欲しい。。

そんな人のために、今回僕が行った方法をメモ代わりに残しておきます。

##開発環境
・MacbookAir
・python(3.6.5)
・wagtail(2.9.2)
##今回お世話になったサービス
・heroku
・cloudflare
・Freenom

##　前提条件
・herokuにサービスをアップしている。
・独自ドメインを所有している(今回はFreenomを使用しました)。

## 参考サイトとの相違点
**[車輪の再発明](https://ja.wikipedia.org/wiki/%E8%BB%8A%E8%BC%AA%E3%81%AE%E5%86%8D%E7%99%BA%E6%98%8E#:~:text=%E8%BB%8A%E8%BC%AA%E3%81%AE%E5%86%8D%E7%99%BA%E6%98%8E%EF%BC%88%E3%81%97%E3%82%83,%E6%8C%87%E3%81%99%E3%81%9F%E3%82%81%E3%81%AE%E6%85%A3%E7%94%A8%E5%8F%A5%E3%80%82)**を避けるために参考文献と重複する場所が多々あるのでサラッと行きます。
まずは、参考文献と同様に、
1.cloudflareにアカウント登録し、独自ドメイン後のサイト名でFreeプランを選択。
2.[初期に入っているもの](https://qiita.com/healing_code/items/0e334606709fb9deae87)を全て削除し、以下のように設定する。(画像は以下の参考文献から拝借しました)
![https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_346533_85d72494-9277-5ff0-a782-8f69ee6a391c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407666/2774f418-d559-b6b8-850b-7d434088a6ac.png)

3.今回は、Freenomなので、Freenom上でNameServer(Mydomain>Managing domain>ManagementTools)よりNameServerをcloudflareに記載されているものに変更
**今回の相違点**
4.herokuに変更を適用させる。参考文献では、「Personal>'appName'>Setting>Domains and cerfificates 」とありましたが、私の方ではDomains and cerfificatesは確認できず、別個でした。
そのため、Personal>'appName'>Setting>Domains」から独自ドメインを適用しました。


##参考文献
・[【無料】Cloudflareを使ってHerokuで独自ドメインで運用する方法](https://qiita.com/healing_code/items/0e334606709fb9deae87)
example.com にメール送信しても、メールサーバーにメールキューはたまりません（Null MX対応なら）

# 1つの疑問が出る
本当にexample.comにメール送信して良いのか？メールサーバーに負荷をかけてしまうのではないか？

https://qiita.com/jnchito/items/198a2561a36c2c2ef5e3#comment-2cd3a46f7148d25bbca9
> メールサーバのメールキューがたまっちゃう問題はどうしていますか？

テストのときはhoge.comとかだと実在するドメインなので、メール送信先としては良くないのでexample.comを使いましょう！ということですが、メールキューがたまるのでは？という疑問が出ました。

メール送信の仕組み上、実在しないドメイン、または実在してもメールサーバーが無いドメインへメールを送信すると、メールサーバーは該当サーバーが落ちているという認識して、再送信するためのメールキューに登録して一定時間後にメールを再送信します。
これを、数回繰り返して、本当にメール送信ができないときに、bounceメールとしてメールを戻してきます。
bounceメールとして判定するまでの間が**メールキューにたまる問題**です。

実は、ちょっと前まで、example.comにはメール送信先情報であるMXレコードが引けないために、example.comにメール送信したメールサーバーには再送信のためのメールキューがたまってしまいました。
そのため、メールサーバーを管理するインフラチームに迷惑をかけてしまう懸念がありました。
※ちなみに、**今でも負荷テストならメール送信先を/dev/nullに落とすのが礼儀**です。

しかし、今はexample.comには**Null MXというMXレコードが設定**されています。
意外と知られてないので記事を書きます。

# Wha't Null MX?
Null MXはRFC7505で定義されています。
https://tools.ietf.org/html/rfc7505

3章に、そのことが書かれています。
Null MXを定義をするとき、DNSの設定には.（ピリオド）を使用します。

```shell:Shell

nslookup -type=mx example.com
```
上のようにexample.comのMXレコードをnslookupで確認してみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77441/d1deef7b-b2d6-cf96-6149-c9be91cd3440.png)
`example.com     mail exchanger = 0 .`とNull MXである.（ピリオド）が設定されています。

# メールサーバーの振る舞い
Null MX非対応のメールサーバーだと、メールキューがたまる可能性はあります。
メールサーバーの実装によりますが.（ピリオド）ホストだと不正なドメインとなるので、一時的なエラーとして判定され再送信のためのメールキューにたまってしまうと思います。
まあ、今の時代、**Null MXに対応してないメールサーバーなんて、セキュリティ的にガバガバなんで、そんなのを使うな**と声を大きくして言いたいけどね。


Null MX対応しているメールサーバーなら、**応答コード556**の**拡張ステータスコード5.1.10（Permanent failure: Recipient address has null MX）**を返すように規定されています。
そのためメールサーバーは**bounceメール**として送り返してきます。
つまり、**メールキューにはたまりません**。

みんなも大好きなGmailもNull MX対応なので、**気軽にexample.comを使って良い**と思います！

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77441/cb258414-3c08-d3fb-b502-85bff9a7e51a.jpeg" width=50%>

# spfレコードは？
example.comのspfレコードは、どのようになっているでしょうか？

```shell:Shell

nslookup -type=txt example.com
```
上のようにexample.comのTXTレコードをnslookupで確認してみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77441/4f51de3e-f45a-474f-e59b-275c4954fa2c.png)

`v=spf1 -all`と出ました。
-allは**全てのドメインからメール送信しない**という意味で、送信するドメインやIPアドレスが記述されていないので、メール送信しないドメインですと宣言していることになります。

# DNS設定してますか？
貴殿の所有しているドメイン、メールサーバーが動いていないなら、**Null MXとspfレコードの設定**をしておきましょう。
Null MXは設定しなくても実害は低いですが、spfレコードは未設定だと、どこかのスパマーが貴殿のドメインを勝手に名乗って迷惑メールを送信するかもしれません。

spfレコードを上の項目のようにメール送信しない宣言をしておくだけで、スパマーが迷惑メールを送信しても、spfレコードの判定ステータスはFailになり、**送信元のドメインを偽称している可能性が非常に高いと見なすことができます**、そのためスパマーは、貴殿のドメインを勝手に名乗らなくなります。

結果として**貴殿のドメインを守る**ことになります。

# 関連記事
こちらも参考にお読みください。
2020年8月の時点でNull MXに関する話が3記事しかない・・・そりゃNull MXが認知されない気がするね。

[メールを受け取らないドメイン名に"Null MX"のリソースレコードを登録してみる](https://heartbeats.jp/hbblog/2016/12/null-mx.html)
[DNS MXレコードのpreference違いによるメール動作確認。特にpreference 0設定](https://blog.putise.com/dns-mx%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AEpreference%E9%81%95%E3%81%84%E3%81%AB%E3%82%88%E3%82%8B%E3%83%A1%E3%83%BC%E3%83%AB%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D%E3%80%82%E7%89%B9%E3%81%ABpref/)
[世界と日本のメール送信ドメイン認証](https://eng-blog.iij.ad.jp/archives/1234)
16bit INT or 32bit INT/FP の画像編集のメモ

## 背景

16bit や 32bit の HDR 画像をちょこちょこ編集したい. スケーリングや回転, 合成とか.

opencv とかでやるてもあるが, 見た目で調整したいときもある.


## gimp

gimp 自体は, 32bit float まで対応しているようです.

16bit PNG : OK
16bit TIFF : OK
32bit fp TIFF : ものによっては OK っぽい? 

TIFF の場合, multichannel 画像だと, multi page TIFF としてページ単位で読み込みなのでめんどい.

# Blender

Blender の画像編集でもいけるかもです.

あとは, シーンセットアップが少しめんどうですが,
texture としてよんで, ライティング off でレンダーして, EXR で保存とか.
Firebase Cloud FunctionsのCIで親ディレクトリのeslint設定を見に行ってしまう問題の対処

# はじめに
フロントをVueやReactで、バックエンドをFirebase Cloud Functionsで開発しているとき、同一リポジトリで管理していると以下のようなディレクトリ構造になり、`.eslintrc`がダブる。

```
frontend
├── .eslintrc <- 設定ファイル1
└─┬ functions
  └──  .eslintrc <- 設定ファイル2
```
ここで、GitHub ActionsなどのCIツールで、functionsディレクトリにのみlintを走らせるとする。

```yaml:GitHubActionsの設定
name: Pull Request Backend
on:
  push:
    pull_request:
    paths-ignore:
    - 'src/**'
    - '.github/**'
    - 'README.md'
    - 'docs/**'
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - uses: actions/setup-node@v1
      with:
        node-version: 10.x
    - working-directory: functions
      run: npm ci
    - working-directory: functions
      run: npm run lint:ci
    - working-directory: functions
      run: npm test
```

すると、設定ファイル2だけでなく、親ディレクトリの設定ファイル1まで見ていってしまう。設定ファイル1でフロント特有のeslintプラグインを導入していると以下のようなエラーがでる

```
Oops! Something went wrong! :(

ESLint: 7.6.0

ESLint couldn't find the plugin "eslint-plugin-vue".
```

# functionsディレクトリにのみlintを走らせたい
https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy
ここが参考になった。どうやら、functionsディレクトリにlintを走らせると設定ファイル2→設定ファイル1の順で参照されるのは仕様らしい。設定ファイル2のみを参照したい場合は、設定ファイル2に`{ "root": true }`を設定すれば良いらしい。

```
frontend
├── .eslintrc <- 無視される
└─┬ functions
  └──  .eslintrc <- { "root": true }
```

```json:.eslintrc
{
  "root": true, <- ここ
  "env": {
    "browser": true,
    "commonjs": true,
    "es2020": true
  },
  "extends": "eslint:recommended",
  "parserOptions": {
    "ecmaVersion": 11
  },
  "rules": {
    ...
  }
}
```

# さいごに
そもそもリポジトリを分けたほうが良い説もある🤔
[Laravel]環境変数、サーバーから見るか？ファイルから見るか？

Laravelをお使いのみなさんは.envで環境変数を設定しているかと思いますが、もちろんサーバーの環境変数や実行時にコマンドで環境変数を指定することも可能です。

さて、.envとサーバー環境変数で同じキーを指定した場合にLaravelはどちらの値を優先するか、という記事です。

# Laravelでの環境変数
Laravelではphpdotenvというライブラリを利用して環境変数を取得しています。
https://github.com/vlucas/phpdotenv

以下で各種Adapterが登録されます。
※Laravel v7系
※phpdotenv v4系

```php:Illuminate\Support\Env
public static function getRepository()
{
    if (static::$repository === null) {
        $adapters = array_merge(
            [new EnvConstAdapter, new ServerConstAdapter],
            static::$putenv ? [new PutenvAdapter] : []
        );

        static::$repository = RepositoryBuilder::create()
            ->withReaders($adapters)
            ->withWriters($adapters)
            ->immutable()
            ->make();
    }

    return static::$repository;
}
```

ここで`EnvConstAdapter`,`ServerConstAdapter`,`PutenvAdapter`の順に登録しています。

## Adapter
先程登録されていた各種Adapterは以下のような仕組みになっています。

#### EnvConstAdapter
PHPのスーパーグローバル変数`$_ENV`から値の取得・登録をします。
`$_ENV`は現在のスクリプトに渡された環境変数を取得します。

#### ServerConstAdapter
PHPのスーパーグローバル変数`$_SERVER`から値の取得・登録をします。
`$_SERVER`はサーバーに定義された環境変数を取得します。

#### PutenvAdapter
PHPの組み込み関数`getenv`と`putenv`を利用して値の取得・登録をします。

## 環境変数の取得
`env('string')`が呼び出される先は以下のように先程登録したAdapterを順に参照して、定義されている場合に値を返します。
定義がなければnullが返されます。

```php:Dotenv\Repository\AdapterRepository
protected function getInternal($name)
{
    foreach ($this->readers as $reader) {
        $result = $reader->get($name);
        if ($result->isDefined()) {
            return $result->get();
        }
    }

    return null;
}
```

# 結局優先順位はどうなってるの？

.envファイルが登録される際の挙動を見るとわかります。

```php:Dotenv\Repository\AbstractRepository
public function set($name, $value = null)
{
    if (!is_string($name)) {
        throw new InvalidArgumentException('Expected name to be a string.');
    }

    // Don't overwrite existing environment variables if we're immutable
    // Ruby's dotenv does this with `ENV[key] ||= value`.
    if ($this->immutable && $this->get($name) !== null && $this->loaded->get($name)->isEmpty()) {
        return;
    }

    $this->setInternal($name, $value);
    $this->loaded->set($name, '');
}
```

ここのガート節で

```php
if ($this->immutable && $this->get($name) !== null && $this->loaded->get($name)->isEmpty()) {
    return;
}
```
とありますね。
つまり、`EnvConstAdapter`,`ServerConstAdapter`,`PutenvAdapter`のどれらにも未定義の場合は値を新たに追加しています。

なので優先される値は

1. **実行時の環境変数**
1. **サーバー環境変数**
1. **.envファイルの変数**

になるかと思います。（違ったらご指摘ください）
aws s3 cp コマンドでファイル結合する

s3に置いてあるファイルについて、複数ファイルをまとめたい時があります。
ファイルをダウンロードせずにファイル結合をできないものかとやってみました。

結論から言うと cp の標準入力と標準出力を駆使してみました。

```
aws s3 cp - s3://... : 標準入力から書き込める
aws s3 cp s3://... - : 標準出力から表示できる
```

こちらのclassmethod様の記事を大いに参考にさせていただいております。
https://dev.classmethod.jp/articles/aws-cli-s3-streaming/

以降にサンプルコードを書いたので参考にしてみてください。

# サンプルファイル
分割されたファイルとしてこのようなファイルがあるとします。

```
aaa.text
aaa
aaa
aaa

bbb.txt
bbb
bbb
bbb

ccc.txt
ccc
ccc
ccc
```

上記のファイルが下記にあるとします。

```
aws s3 ls s3://hoge.bucket/concatenate_test/
2020-08-05 18:44:01         12 aaa.txt
2020-08-05 18:44:10         12 bbb.txt
2020-08-05 18:44:18         12 ccc.txt
```

# ファイル結合
そんでこんなシェルスクリプトを実行してみます。

```
#!/bin/bash
(
aws s3 cp s3://hoge.bucket/concatenate_test/aaa.txt -;
aws s3 cp s3://hoge.bucket/concatenate_test/bbb.txt -;
aws s3 cp s3://hoge.bucket/concatenate_test/ccc.txt -;
) | aws s3 cp - s3://hoge.bucket/concatenate_test/abc.txt
```

中身を見てみると結合できてます。

```
aws s3 cp s3://hoge.bucket/concatenate_test/abc.txt - 
aaa
aaa
aaa
bbb
bbb
bbb
ccc
ccc
ccc
```

# ファイル結合して圧縮
それでは圧縮しながらコンカチもやってみます。

```
#!/bin/bash
(
aws s3 cp s3://hoge.bucket/concatenate_test/aaa.txt -;
aws s3 cp s3://hoge.bucket/concatenate_test/bbb.txt -;
aws s3 cp s3://hoge.bucket/concatenate_test/ccc.txt -;
) | gzip | aws s3 cp - s3://hoge.bucket/concatenate_test/abc.txt.gz
```

```
aws s3 cp s3://hoge.bucket/concatenate_test/abc.txt.gz - | zcat
aaa
aaa
aaa
bbb
bbb
bbb
ccc
ccc
ccc
```

# 圧縮ファイルをファイル結合
もともとのファイルがgz圧縮されていればそのままパイプしてしまえばいですね。

```
#!/bin/bash
(
aws s3 cp s3://hoge.bucket/concatenate_test/aaa.txt.gz - ;
aws s3 cp s3://hoge.bucket/concatenate_test/bbb.txt.gz - ;
aws s3 cp s3://hoge.bucket/concatenate_test/ccc.txt.gz - ;
) | aws s3 cp - s3://hoge.bucket/concatenate_test/abc.txt.gz
```
【備忘録】Chocolatyのインストール方法と、自動更新

##Get Started
```:code
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
```

##ソフト一斉インストール
```powershell
cinst a.config
```
```config:a.config
<?xml version="1.0" encoding="utf-8"?><packages><package id="googlechrome" />
<package id="jre8" />
<package id="javaruntime" />
<package id="7zip" />
<package id="git" />
<package id="visualstudio-installer" />
<package id="teamviewer" />
<package id="vscode" />
<package id="steam" />
<package id="python" />
</packages>
```

##自動アップデート
1. ChocoUpdate.batを作成


```:ChocoUpdate.bat
cup all -yes
```
2. Win+R
3. taskschd.mscを入力
4. タスクの作成→操作に「ChocoUpdate.bat」を入れる。
5. トリガー等は適当に
帰宅時の快適な空間を作る (Nature Remo × iPhoneショートカット)

#自宅の環境
Nature Remo Miniを使用中。シーリングライトやエアコンのリモコンを覚えさせてリモコンフリーな環境を実現。iPhoneのショートカットアプリにRemoの操作を登録させておくことで、iPhoneからワンタップで操作できるようにしてある。

#最近の不満
梅雨が明けようやく夏がやってきた。家に帰ると日中の太陽によって部屋がサウナ状態になっている。仕事を終え帰宅して満身創痍な体にこれはよろしくない。
そこで、仕事場を離れるときにNature Remoを遠隔で操作してエアコンをつけておくことで、帰宅したらエアコンの効いた快適空間が出来上がっている状態にしたい。これはRemoのアプリとショートカットのアプリの連携さえできていれば簡単にできる。仕事場を出たときにiPhoneショートカットボタンを押すだけ。しかし、室内の仕事場からは外気温がわからないため、仕事場の建物を離れ外に出るまで今日はエアコンが必要かどうか知る術がない。

#解決策
Nature Remoには温度センサーが内蔵されている。今回はそれを利用して、
1.iPhoneショートカットをタップ
2.Nature RemoがAPI経由で現在の室温を取得
3.28℃以上だったら冷房を入れる
4.冬用に18℃以下だったら暖房を入れる
というショートカットを組むことにした。この記事ではそのやり方を説明する。
作るのが面倒くさいと感じる人は、記事の最後に今回作成したショートカットの共有リンクを貼っておくのでそれを利用されたし。

##1.Nature Remoのアクセストークンの取得
下記の記事を参考にアクセストークンの取得まで行う。
https://blog.yuu26.com/nature-remo-api-tutorial/

##2-1.iPhoneショートカットの作成と概要
仕組みだが、
1.URLの内容取得でNature Remoの情報を取得
2.テキスト化
3.温度に関する項目を抽出
4.温度の数値のみを抽出
5.小数点第二位を四捨五入
6.28℃以上だった場合、現在の室温を表示し、冷房をつけるか尋ねる
 　-はいだったら、冷房をつける、終了
 　-いいえだったら、何もしない、7へ
7.18℃以下だった場合、現在の室温を表示し、暖房をつけるか尋ねる
 　-はいだったら、暖房をつける、終了
 　-いいえだったら、何もしない、8へ
8.現在の室温を表示する
とした。

##2-2.ショートカットの中身
以下の順番でショートカットの構築を行う。
スクリーンショットも載せておくが、どんなアクションを使用しているのかわからないことがよくあるので、以下に文章でまとめておく。
タイトル：アクションの名前
！！で囲んである文字：マジック関数(ショートカット編集画面で青色になってる文字)

```txt:URLの内容を取得

URL:　https://api.nature.global/1/devices
方法：　GET
ヘッダ：　
- キー：　Authorization
- テキスト：　Bearer {取得したアクセストークン、このカッコは不要}
```

```txt:一致するテキスト
!URLの内容! で !"val":[\w/:%#\$&\?\(\)~\.=\+\-]+! に一致
```

```txt:テキストを分割
!一致! を !カスタム! !：! で分割
```

```txt:スクリプティング：リストから項目を取得
!テキストを分割! から !項目のインデックス! の !2! を取得
```

```txt:端数を処理
!リストからの項目! を !10分の1! に四捨五入
```

```txt:変数を設定
変数 !室温! を !端数処理済みの数値! に設定
```

```txt:スクリプティング：if文
もし !室温! !値がない! ならば
```

```txt:アラート
アラート !再試行しますか？! を表示
タイトル: Error: value is null.
キャンセルボタンを表示: オン
```

```txt:ショートカットを実行
!帰宅します! を実行
```

その他の場合
次の場合に終了

```txt:スクリプティング：if文
もし !室温! !次より大きい! !28! ならば
```

```txt:テキスト
お疲れ様でした。
現在の室温は !室温! ℃と大変暑いです。
冷房をつけますか？
```

```txt:スクリプティング：メニューから選択
プロンプト：　!テキスト!
はい
いいえ
```

はい

```txt:ショートカット(各自設定したショートカットを割り当て)
!冷房28℃! を実行
```
いいえ
メニューの終了

その他の場合

```txt:スクリプティング：if文
もし !室温! !次より小さい! !18! ならば
```

```txt:テキスト
お疲れ様でした。
現在の室温は !室温! ℃と大変寒いです。
暖房をつけますか？
```

```txt:スクリプティング：メニューから選択
プロンプト：　!テキスト!
はい
いいえ
```

はい

```txt:ショートカット(各自設定したショートカットを割り当て)
!暖房20℃! を実行
```
いいえ
メニューの終了

その他の場合

```txt:テキスト
お疲れ様でした。
現在の室温は !室温! ℃です。
ご帰宅お待ちしています。
```
次の場合に終了
次の場合に終了

##2-3.ショートカットのスクリーンショット
<img width="350" alt="Screenshot at Oct 27 18-00-47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/330454/75615339-488b-6fa1-65e5-5d0350cbb60f.jpeg">

#配布用ショートカット 
以下のリンクから今回作成したショートカットがインストールできます。アクセストークンの項目は空欄になっているので各々で埋めてください。
https://www.icloud.com/shortcuts/ecfa584665c04bf2b265fcac56b54794

[追記:2020-08-16]
外出先だと通信環境によって室温が取得できない時がよくある(2回ショートカットを起動させないと使えない)ので、室温取得時の値が無かった場合のフィードバック機能を追加しました。具体的には室温の四捨五入処理後にif文を追加することで、nullだったら再びショートカットを起動、値があったらそのまま次へ、と条件分岐させました。

#終わりに
後半のエアコンの操作過程をなくせば現在の室温を表示するだけという使い方もできます。
Nature Remoの場合、湿度や照度も取得できるので除湿機やスマートカーテンと組み合わせると面白いかもしれません。

#参考文献
Nature Remo API で部屋の温度・湿度を取得する
https://blog.yuu26.com/nature-remo-api-tutorial/
IFTTT経由で、Redditに投稿された物をWebhook経由でDiscordに投稿する

# なぜ開発したのか
Twitterは取得して投稿があるのに、Redditは無いんだな〜って思って自作しました。
# 手順
※IFTTTの登録とwebhookの取得は省略します。

1：画面右上にあるcreateをクリック

2：Choose service でRedditを選択

3：Any post…を選択

4：ここに取得したい物を選択する。/r/Twitchだったら、Twitchと入力

5：Choose action service でWebhookを選択

6：Make web…を選択

7：必要事項の入力
　　　Method:POST
     Content type:application/json
     Body:

```json:Body
{ "embeds": 
 [ 
   { 
     "title": "<<<{{Title}}>>>", 
     "url": "<<<{{PostURL}}>>>", 
     "description": "<<<{{Content}}>>>",
     "thumbnail": { 
       "url": "<<<{{ImageURL}}>>>"
     }, 
     "footer": { 
       "icon_url": "https://www.redditstatic.com/desktop2x/img/favicon/favicon-32x32.png", 
       "text": "/u/<<<{{Author}}>>> | <<<{{PostedAt}}>>>" 
     } 
   } 
 ] 
}
```
※iconurlはなんでもOK
8：完了をクリック

これで完成です。
# 注意事項
・IFTTTの仕様変更で一つのアカウントで３つまでしかwebhookなどを登録できませ
　ん！！
　３つ以上登録したい場合はアカウント複数用意する必要があります。

・レートリミットがあるので投稿される数は制限があります！

・一時間に一回しか投稿されません！

# あとがき

これが作成手順です。長々と書いてますが、IFTTT側ではGUI化されてるので簡単だと思います。
jsonを一から勉強したので割とはげましたｗ
参考になれば、LGTMお願いします！
それでは、皆さんもよいDiscordLifeを。
【正規表現】後方参照は繰り返しではなく再利用

[初めてのPerl 第7版](https://www.amazon.co.jp/%E5%88%9D%E3%82%81%E3%81%A6%E3%81%AEPerl-%E7%AC%AC7%E7%89%88-Randal-L-Schwartz/dp/4873118247)の p131 で少し混乱したのでメモします。

# 用語の整理

|記号|名称|意味|
|---|---|---|
|/ /|マッチ演算子|
||パターン|マッチ演算子に囲まれた部分|
|( )|グループ|パターンをまとめる|
||キャプチャグループ|グループの中にマッチしたテキストを参照|
|\1、\2...|後方参照|マッチの際にキャプチャグループを利用|

# 例

``bb``にマッチ

```pl
$_ = "abba";
if (/(.)\1/) {
    print "It matched same character next to itself!\n";
};
```

``yabba dabba``にマッチ

```pl
$_ = "yabba dabba doo";
if (/y(....) d\1/) {
    print "It matched the same after y and d!\n";
};
```

``\2``は、2番目のグループ、すなわち``b``にマッチ
よって、``yabba``にマッチ
量指定子と混同して、繰り返しだと思ってしまったのが個人的ハマりポイント

```pl
$_ = "yabba dabba doo";
if (/y(.)(.)\2\1/) {
    print "It matched!\n";
}
```

``\3``は``b``、``\2``は``a``にマッチ
よって``\1``は``abba``にマッチ
したがって``yabba dabba``にマッチ

```pl
$_ = "yabba dabba doo";
if (/y((.)(.)\3\2) d\1/) {
    print "It matched!\n"
}
```
掲示板投稿機能の作成の確認ポイント

自分用です！

掲示板作成時はアソシエーションを活用して、処理を短く記載していること、

 ・GOOD アソシエーションを活用
  @board = current_user.boards.build(board_params)

 ・BAD 初期化した後に値を代入
  @board = Board.new(board_params)
  @board.user_id = current_user.id

  ・BAD 初期化する際のパラメータをmerge
  Board.new(board_params.merge(user_id: current_user.id))

フォームのテキストエリアの入力幅はstyleで指定するのではなく、rows:で設定すること styleは個別のHTMLに直接記載しせずに、cssファイルから適用させる形式の方が管理しやすいため

・BAD styleで高さを指定して、入力幅を設定している
<%= f.text_area :body, class: 'form-control', style: 'height: 200px', row: 10 %>

・GOOD styleを使用せずに、rows:オプションで入力幅を設定している
<%= f.text_area :body, class: 'form-control', rows: 10 %>
【備忘録】shape[0], shape[1], shape[2]の中身

#忘れやすいから注意！
a.shape[0]はaの行(row)の数、a.shape[1]は列(col)の数、a.shape[2]はチャンネル数

![unnamed.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517859/866932c5-360f-3514-78fa-4abeb0f6c120.png)
【備忘録】特徴点検出の前処理

AKAZE, SIFT,  SURFに関しては、事前にフィルタリングなどが施されているので、GrayScaleにするだけで良い
ORBはそれらが施されてないっぽい(?)ので、前処理しなくてはいけない。

結論：基本的に場合分けでAKAZE, SIFT, SURFを使っときゃいい。
でも、自分専用のシステム作るなら、ORB使ってフィルタ等をカスタマイズしたらええんちゃう？
defaults.message

自分用です！

ja.ymlのdefaults.messageに定義したものを呼び出します。

```
ja:
  defaults:
    login: 'ログイン'
    register: '登録'
    logout: 'ログアウト'
    create: '登録する'
    message:
      require_login: 'ログインしてください'
      created: "%{item}を作成しました"
      not_created: "%{item}を作成できませんでした"
```

```
ja:
  activerecord:
    models:
      user: 'ユーザー'
      board: '掲示板'
```

```

t('defaults.message.created', item: Board.model_name.human)
```

modelのboardから引っ張るには、Board.model_name.humanとかく。

itemという変数を定義することによって、itemの中身を変えるだけで使いまわせる。
Unchecked runtime.lastError: The message port closed before a response was received. を回避した一例

#初めに
自作chrome拡張機能の制作中、とある処理をすると必ずこのエラーが出て気になっていたのですが、一行追加したら出なくなったので記念に残しておきます。

どんな処理かざっくり言いますと、
アクティブページで得た情報を、ポップアップメニューを介して拡張機能専用ウィンドウへ送信するものです。
完了したタイミングで、ポップアップ側にてエラーが出てました。


#エラーを出していたコード
アクティブページ側は省略。

```javascript:popup.js
const sendMessage = (id, msg) => new Promise( r => chrome.tabs.sendMessage( id, msg, s => r(s) ) );
//アクティブページの情報を取得
const res = await sendMessage( tab_id, { ... } );
//受け取ったデータを専用ウィンドウへ送信
sendMessage( window_tab_id, res );
```

送信後に行う処理も無いので投げっぱなし

```javascript:app_window.js
chrome.runtime.onMessage.addListener( (message, sender, sendResponse) => {
	doSomething(message);
	return;
});
```
#エラーが出なくなったコード
popup.jsは変更なしなので省略。
受信側に一行追加します。

```javascript:app_window.js
chrome.runtime.onMessage.addListener( (message, sender, sendResponse) => {
	doSomething(message);
	sendResponse();	// new
	return;
});
```
特に何もなくても返信はしましょう、という事でしょうか。

#最後に
あくまで一例です。