OmniAICreator/Qiita-1.07M huggingface dataset:
タップされるたびにnodeを置き換える方法

##はじめに
タップされるたびにnodeを新しく配置するのではなく、二回目以降のタップでnodeを置き換える方法を共有します。replaceChildNodeなどの方法があるようですが、理解できなかったため他のやり方で代替しています。
アドバイス等があれば是非コメントください。
Instead of placing a new node on every tap, I'll share how to replace the node on the second and subsequent taps. replaceChildNode and other methods seem to be available, but I didn't understand them, so I'm using other methods to replace them.
If you have any advice, please comment.

##大まかな前提・流れ
- nodeには名前をつけることが可能で、その名前を持つnodeがsceneにあるかどうか判定することができる
- nodeを削除するメソッド -> nodeを作成するメソッドを一つの関数に入れることで、置き換えを表現することができる。

###nodeに名前をつける方法

```Swift
let box = SCNBox(width: 0.05, height: 0.05, length: 0.05, chamferRadius: 0)

let boxNode = SCNNode(geometry: box)
        boxNode.name = "box" //"box"という名前をつけた
        print(boxNode.name ?? "") //box
        self.sceneView.scene.rootNode.addChildNode(boxNode)

```

boxというgeometryを作成し、boxNodeに入れています。
`boxNode.name = "box"`で名前をつけています。
一応テストとして名前を標準出力させています。

###sceneにboxという名前のnodeがある場合のみ行われる処理

```Swift
if (self.sceneView.scene.rootNode.childNode(withName: "box", recursively: true) != nil) {
            self.sceneView.scene.rootNode.enumerateChildNodes{ ( node,stop )in
                node.removeFromParentNode()
                }
            //2回目以降呼ばれる
        }
```
childNode(withName: )につけた名前を設定することで、sceneにnodeがあるかどうか判定してくれます。
そしてそのifの中に、nodeを消去する処理を書いています。

####上記を一つの関数として記述する

```Swift
 func createBox(hitTestResult: ARHitTestResult){
       
        if (self.sceneView.scene.rootNode.childNode(withName: "box", recursively: true) != nil) {
            self.sceneView.scene.rootNode.enumerateChildNodes{ ( node,stop )in
                node.removeFromParentNode()
                }
            //2回目なら呼ばれる
        }
        
        let box = SCNBox(width: 0.05, height: 0.05, length: 0.05, chamferRadius: 0)
        
        let boxNode = SCNNode(geometry: box)
        boxNode.name = "box"
        print(boxNode.name ?? "")
        self.sceneView.scene.rootNode.addChildNode(boxNode)
    }
```
写真から木の線画を抽出しよう

# 概要
この記事では、イラストではなくフリーの写真から線画を抽出しようとしました。
正直言うとあまりうまくいっていませんが、とりあえず途中経過ということで記事にしておきます。
先にソースコードと結果を載せておきます。
ソースコード：https://github.com/FujibayashiYuya/Image-To-Line-Drawing/blob/master/Sorce.cpp

元画像(http://gahag.net/000312-tree-landscape/)
![tree2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683219/138688e1-c6cf-31de-0b24-9f1e05c81218.jpeg)
線画![result3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683219/102c18f4-af8a-d40c-22f6-9a2c9c06010b.jpeg)

線画というにはちょっと薄すぎない？とか、雲が消えてるよ？とかいろいろ不備はありますが、今回は木の線画に注目したので少し多めに見ていただければと思います。

#詳細
###参考にしたサイトの手法の見直し
まず画像から線画を抽出するにあたり、こちらのサイトの手法を試しました。
https://www.mathgram.xyz/entry/cv/contour
このサイトにもあるようにイラストのような画像だとうまくいくのですが、写真になると必要以上に線が増えてしまい、イラストほどうまくはいきません。それは元の画像が画素値の細かい変化を含むような画像だと、差分をとった時にその細かな部分が線画として抽出されるからだと考えられます。
試しに同じ手法を今回の木の画像で行うと下のようになりました。葉っぱの部分が必要以上に線が多いですね。
![median.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683219/9a68f434-7908-ff7b-28e6-52c7c976c686.jpeg)

参考にしたサイトはPythonなので、C++で書いたものを下に載せておきます。

```c++
Mat Median1(Mat img) {
	Mat gray, blur, dila, diff, edge;
//メディアンフィルタをかけると画素値の変化が緩やかになるので若干線画の数を調節できる
	medianBlur(img, blur, 3);
	//画像をグレースケール化
	cvtColor(blur, gray, COLOR_BGR2GRAY, 1);
	//黒い箇所を狭める
	dilate(gray, dila, Mat(), Point(-1, -1), 1);
    //差分をとる
	absdiff(gray, dila, diff);
    //白黒反転
	bitwise_not(diff, edge);
	return edge;
}
```
上のコードでメディアンフィルタの範囲を広くすると線画になる箇所が大まかになっていくのですが、薄っすらと線が入っていたりしてちょっと汚い感じになりました。(下は範囲を5*5画素にしたものです)
![metest55.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683219/4632252e-20ac-58f9-1643-cd01d1157904.jpeg)

###Kmeans法を試してみた
そこで画素値の変化を緩やかにするんじゃなくて、ある程度近い値なら同じにしようと思いKmeans法を試してみました。
C++,OpenCVを用いたKmeans法のコードはこのサイトがとても参考になりました。
https://tora-k.com/2019/11/28/anime_filter/

クラスの数を６にした場合の結果が下のようになりました。
![kmcol.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683219/6ad2733b-d608-69fc-8e3f-7592f8fc85da.jpeg)
木の葉っぱの細々した感じは若干緩和されましたが、保険をかけて３＊３画素でメディアンフィルタをかけてから線画をとってみましょう。
![km.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683219/cbfe8ee2-aa9b-589f-9e6d-272115acefbf.jpeg)
葉の部分に関しては、葉のチクチク感あるシルエットを残しつつ[最初の線画](#詳細)より程よい情報量になったのではないでしょうか。ただ、空の部分に余計な線が増えたのでこれをどうにかしないと。

そこで、他のサイトを参考にした線画とKmeans法で求めた線画をbitwise_and()関数で論理積を行ってみました。
![km_and_median.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683219/add28ff5-45ef-ce25-b886-b2d9bba26365.jpeg)
空の線はなくなりました。（雲もないですが...）木の葉っぱの部分もごちゃごちゃ感は少しマシになりましたが、全体的にパッとしない感じに...
そこで、試しにCanny法で得たエッジとKmeans法の論理積を行ってみました。![result3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683219/abb6e484-23e1-fd5f-9a60-ca10b006af09.jpeg)
若干くっきりしたような...してないような...
写真の完全な線画化は難しいですね
うまくいく方法が見つかったらその時はまた記事を書きます。

最後にソースコード(ページ上部と同じ)載せておきます。
https://github.com/FujibayashiYuya/Image-To-Line-Drawing/blob/master/Sorce.cpp



#参考文献
線画の抽出手法について
①https://tadaoyamaoka.hatenablog.com/entry/2017/02/19/172744
②https://www.mathgram.xyz/entry/cv/contour
③http://azp2.sakuraweb.com/photo/rinkaku/index.html

その他プログラムなど
・Kmeans法. . . https://tora-k.com/2019/11/28/anime_filter/
・Canny法. . . https://algorithm.joho.info/image-processing/canny-edge-detecter/
Microserviceをわかった気になりたい人へ


Microservicesをもっと理解したい！
筆者はインフラエンジニア出身なので、まだまだ勉強中の身ですが、自分の理解の役に立ったリンクをこのページにまとめます。（随時更新）


# おすすめ動画
私は、本読むのは苦手です。今はいい時代で、Youtubeでかなりの知識が得られます。
ただし、下記、英語かなり多めのなのは許してください。翻訳などを駆使ししてがんばってください。

なお、この順番で見るのをお勧めします。

## Domain Driven Designを理解する

巨匠Eric Evansが語るDomain Driven Design
https://www.youtube.com/watch?v=pMuiVlnGqjk

DDDの次のステップ、Bounded Contextを理解する
https://www.youtube.com/watch?v=ZEJ2Vyk1HA0

上のをみた後におすすめ、巨匠Eric Evansが語るちょっとだけ高尚なBoundry Context
https://www.youtube.com/watch?v=xyuKx5HsGK8

## MicroServiceを実装する

モノリスをマイクロにするジャーニー
https://www.infoq.com/presentations/microservices-principles-patterns/

巨大なモノリスからの移行の失敗例と直しかた
https://www.youtube.com/watch?v=U6CeaA-Phqo

# おすすめ本

繰り返しですが、本は苦手です。
それでも役にたった本です。

## DDDを理解する

Domain-Driven Design Distilled
https://www.amazon.com/Domain-Driven-Design-Distilled-Vaughn-Vernon/dp/0134434420

# おすすめWeb記事

Web記事はさくっとよめて、ふんふんとなれる記事を紹介します。

そういやSOAってどうなった？
https://rancher.com/microservices-make-soa-irrelevant
ora2pgを使用してOracleのSQLをPostgreSQLへ変換する

# はじめに

ora2pgはOracle(とMySQL）からPostgreSQLへの移行を支援するためのツールです。
今回はSQLの変換を試してみます。

以下の投稿で構築した環境を利用します。

- [ora2pgを使用してOracleからPostgreSQLへ移行する](https://qiita.com/mkyz08/items/89771d11b73d2a2d58f3)


# OracleのSQLをPostgreSQLへ変換する

input.sqlを準備して、ora2pgコマンドでoutput.sqlに変換後のSQLを出力します。

```
# ora2pg -c config/ora2pg.conf -i input.sql -o output.sql -t QUERY
```

### DUAL表

DUAL表を定義するという対応もあります。

```sql
[変換前]
select 1 from dual
[変換後]
select 1
```

### 外部結合

全てLEFT OUTER JOINになりました。

```sql
[変換前]
select * from test01 t1, test02 t2 where t1.id(+) = t2.id;
[変換後]
select * FROM test02 t2
LEFT OUTER JOIN test01 t1 ON (t2.id = t1.id);
```

```sql
[変換前]
select * from test01 t1, test02 t2 where t1.id = t2.id(+);
[変換後]
select * FROM test01 t1
LEFT OUTER JOIN test02 t2 ON (t1.id = t2.id);
```

### ROWNUM

```sql
[変換前]
select * from test01 where rownum <= 10;
[変換後]
select * from test01 LIMIT 10;
```

### MINUS

```sql
[変換前]
select * from test01 minus select * from test02;
[変換後]
select * from test01 EXCEPT select * from test02;
```


### シーケンス

```sql
[変換前]
select seq_test.nextval from dual;
[変換後]
select nextval('seq_test');
```


### 日付

```sql
[変換前]
select current_timestamp from dual;
select current_date from dual;
select systimestamp from dual;
select sysdate from dual;
select localtimestamp from dual;
[変換後]
select current_timestamp;
select current_date;
select CURRENT_TIMESTAMP;
select LOCALTIMESTAMP;
select localtimestamp;
```

### 正規表現

```sql
[変換前]
select * from test01 where regexp_like(txt, '[a-zA-Z]');
[変換後]
select * from test01 where txt ~ '[a-zA-Z]';
```


### 日付計算

```sql
[変換前]
select add_months(sysdate, 1) from dual;
[変換後]
select LOCALTIMESTAMP + '1 month'::interval;
```


### DECODE関数

```sql
[変換前]
select
  decode(txt,'1', '01', '2', '02')
from
  test01 t;
[変換後]
select
  CASE WHEN txt='1' THEN  '01' WHEN txt='2' THEN  '02' END
from
  test01 t;
```

### NVL関数

```sql
[変換前]
select nvl(abc, 0) from test;
[変換後]
select coalesce(abc, 0) from test;
```

### from句の副問い合わせ

```sql
[変換前]
select * from (select * from test01);
[変換後]
select * from (select * from test01) alias0;
```


# Oraface

Orafaceの関数を使用する場合はora2pg.confの設定を修正します。有効にするとadd_month等の関数は変換の対象外になります。

```
# Orafaceを使用する場合は"1"に設定（デフォルト"0"）
USE_ORAFCE      1
```

# その他

今回は紹介しませんが、ora2pgの他にもAWS Schema Conversion Tool (AWS SCT) を使用してSQLを変換することができます。
SCTの場合は独自のOracle互換関数を使用するように変換されます。

# 参考

- [ora2pg（公式サイト）](http://ora2pg.darold.net/index.html)
FetchAPIでReadableStreamからMP4を読みながらvideoタグで再生する

# やりたいこと

認証がかかったストレージのAPIからJavaScriptで動画データを取得してvideoタグで再生したかった．

FetchAPIやXHRでMP4ファイルにアクセスはできるので，これをブラウザ上で再生したいだけだけなのだけど．．．

- 普通にvideoタグのsrcにAPIのURLを突っ込む → リクエストヘッダ等をセットできなくて認証できない
- FetchAPIでデータを読んでblobを再生する → ファイル全体を読まないと再生開始できない(動画は数百MBある) ([参考記事](https://qiita.com/tomoyukilabs/items/cb9dd1d3e7eb0cc7f58a))
- MPEG-DASH等のFragmented MP4を読み込んでMSEで再生する → 事前にサーバ側に置くデータを変換しないと再生できない ([参考記事](https://qiita.com/tomoyukilabs/items/54bd151aba7d3edf8946))

意外とめんどう.

# JavaScriptでFragmented MP4を作る

```
+------------+    +-----------+    +----------------+                             +-------------+    +-----------+
| 動画データ | → | Fetch API | → | ReadableStream | → (なんか良い感じの変換) → | MediaSource | → | videoタグ |
+------------+    +-----------+    +----------------+                             +-------------+    +-----------+
```

この`(なんか良い感じの変換) `の部分が欲しい．

MediaSourceは通常のMP4ではなくて，Fragmented MP4を入れる必要がある．

良さげなライブラリが無いか探しているけど，https://github.com/gpac/mp4box.js くらいしか見当たらない．(探し足りないのかもしれないけど)
やりたいことに対してライブラリが大きすぎるのと，ダウンロードしたデータを入れるとsegmentができたときにコールバックが呼ばれる感じなので，必要な量だけStreamから読むという挙動にしにくい．

Fragmentedが付いても所詮はMP4なので簡単に変換できるだろうと思って，とりあえずライブラリ使わず再生してみた．

とりあえず動いたやつ： https://github.com/binzume/mp4player-js

再生するだけで意外と面倒くさかったので，必要だった作業をメモ．

## 変換方法のメモ

https://www.w3.org/TR/mse-byte-stream-format-isobmff/ この辺の説明と実際のMP4のデータを見ながら適当に変換していけばよい．

MP4とかISOBMFFのドキュメントは大きくて真面目に把握するのはめんどいので，なるべく元のMP4のBox構造を触らずに書き換えが必要なBoxだけ触ることに．
最初，比較用にffmpegで生成したfragmentを見てたけど，どういうわけかffmpegで生成したやつはChromeのMediaSourceで読めなかった．

以下はMP4の構造は知っている前提の記述です．

### initialization Segment

最初にinitialization Segmentを一度だけ渡す必要がある．内容は以下のような感じ．

- ftyp
- moov
  - moovの下はMP4からコピーして少し修正
  - mvex
     - trex 

元がMP4なら，ftyp + moovのうち各tracのstbl下のboxのうちstsd以外を空にして，mvexを追加すればよいだけ．
trexにはトラック番号だけ書いておけば良さそう．

### media segment

普通のmp4ならmoovに入っていた情報を複数のmoofに分割して格納する必要がある．

moov → moof，trac → traf等対応しているBoxは名前でわかりやすいが，中身の格納方法は別物なので変換は地味に面倒．

- moof
  - mfhd
  - traf
     - tfhd
     - tfdt
     - trun
- mdat

### 生成しなければいけない主なBox

trakとかmoofとか単に他のboxを持つだけの親は省く．

#### trex

基本的に各fragmentのtfhdに入れれば良いので少しでもバイト数削りたい場合以外は気にしなくて良さそう．
ただボックス自体は省略できないので，トラック番号だけ入れておく．

#### fthd,ftdt,trun

trunがサンプルの在り処を指す．stco,stsc,stsz,stts,stss,cttsから生成できる．
trunが持てる情報色々あって難しく感じるけど，生成するときは必要なやつ以外は書き込まなければよいので割とシンプル．

#### mdat

元のMP4のmdatから必要な範囲をコピーしてくる．どのサンプルがどの場所にあるかはstco,stsc,stszを見る．

### MediaSource.addSourceBuffer() に渡す mimeType

`video/mp4; codecs="avc1.42e01e,mp4a.40.2"` みたいな文字列を渡すのだけどど，Chromeとかだとcodecsの指定が必須．
(多くのサンプルコードで特に説明無くハードコードされてて，残念な雰囲気がある)

MP4のstsd boxからconfiguration recordを取り出して中身を見る必要がある．`avc1`とか`mp4a`のコーデック名はstsdの先頭あたりにそのまま入ってるが，後ろの数字はコーデックごとのパラメータを見ないといけない．
手抜き実装をするなら，h264のパラメータはavcCの後にある固定位置の3バイトを16進にして，aacは40.2固定にしてもほとんどの場合は良さそう．

# 雑感

- https://github.com/gpac/mp4box.js とかあるけど，単純に再生するのに使いやすそうなのが見当たらない
- ちゃんと動くの作るのは色々めんどう
- バイト列の扱いだるいのでwasmでやるのが良さそう
- MediaSourceとReadableStream，変なことしなくても普通につながってほしい
そこらへんにいるフリーターがdevise使ってみた。

どうも、

未経験からエンジニアを目指しているフリーターです。










今回は初心者でも簡単に、

ゼロからユーザー管理機能を作れることで有名なgem

devise

について、

ところどころ解説をはさみながら、

簡単に紹介させてもらいたいと思います。










まず最初はrailsアプリを作りましょう



```
rails _6.0.0_ new （ご自身の作りたいアプリ名) -d mysql

(最後の-dはオプションなのでいらない人はつけなくて大丈夫です）
```






インストールが終わったら、今作成したフォルダに移りましょう

ターミナルを開き以下のコマンドを実行してください



```
% cd  （ご自身が作成したアプリ名）

```


とりあえずデータを入れるためのデータベースを作ります。

ターミナルを開き以下のコマンドを実行してください



```
% rails db:create
```






次はdeviceのジェムをGemfileにて追加していきます






```
gem 'devise'
```


Gemfileにて追加したら忘れずに

bundle installをしてください！！
(rails sで起動も！！)



続いて、ターミナルを開いた状態で
次のコマンドを打ってください



```
rail g devise:install
```


このコマンドによりdeviceが始動し始めます
個人的な感想としてはこのコマンド打った時が一番気持ちいです笑






コントローラーも忘れずに作成します。



```
%　rails g devise:controllers users
```
このコマンドはdeviceのユーザー関係のコントローラーを
一気に作成してくれます










コレによりuserのマイグレーションファイルが生成されるので

送り出す工程を忘れてはいけません。



```
rake db:migrate

```








そしてこのコマンドです



```
rails g devise:views
```
device関係のviewを全部一気に
作ってくれます！！




僕最初コレ知らなくて、

全部自分で書いてしまってました、、、




もうあの経験はしなくていいんだ！




と考えると心が安らぎます。







以上でdevice関連のコマンド紹介は終わりです！




こんなに簡単に誰もがユーザー管理機能作れちゃうなんて、、、




gemの能力恐るべし、、




ユーザー登録機能に、sns認証を入れたい！




という方は

https://developers.facebook.com/

というところにアクセスして

色々と登録した上で、



```
gem 'omniauth-facebook'
```



というgemを使うと

Facebookでの認証が可能になります！

（他にもやることあります、、）




ぜひこの機会に一度調べてみてはどうでしょう！！
再帰関数をデバッグしようとしたらDebug.logの表示が逆だった

メモです_φ(･_･


```elm

hoge x y =
    let
        dx =
            Debug.log "x" x

        dy =
            Debug.log "y" y
    in
    if x + y < 20 then
        hoge (x + 5) (y + 2)

    else
        ()
```
```
> T.hoge 1 2
y: 2
x: 1
y: 4
x: 6
y: 6
x: 11
y: 8
x: 16
() : ()
```
このようなときズラーッとくっついてしまって見にくいなぁと思い、空行で区切ってみたのですが変なふうに区切られてしまい、それはDebug.logの表示が逆順であったりするからだと気づきました。

どうやって解決するのがメジャーな方法なのかわからずいい方法が知りたいのですが、ちょっとしたコードで見やすくはなりました。

```elm
type alias DBG =
    String


nextD : DBG -> DBG
nextD dbg =
    "    " ++ dbg


printD : DBG -> String -> a -> a
printD dbg str =
    Debug.log (dbg ++ str)


printDS : (a -> b) -> DBG -> String -> a -> a
printDS f str dbg a =
    printD dbg str (f a)
        |> always a
```

```elm

hoge x y dbg =
    let
        dx =
            printD dbg "x" x

        dy =
            printD dbg "y" y
    in
    if x + y < 20 then
        hoge (x + 5) (y + 2) (nextD dbg)

    else
        ()
```
```
> T.hoge 1 2 ""
y: 2
x: 1
    y: 4
    x: 6
        y: 6
        x: 11
            y: 8
            x: 16
() : ()
```

他にも


```elm

_ = Debug.log "x" x
_ = Debug.log "y" y
```
このように変数にいれなければ、逆順にならなそうでした。

追記: みやもさんに他の方法を教えてもらいました。
ありがとうございます。

```elm

hoge x y =
    let
        dx =
            Debug.log "x" x

        dy =
            Debug.log "y" y
    in
    if x + y < 20 then
        (Debug.log "---------" hoge) (x + 5) (y + 2)

    else
        ()
```
`(Debug.log "---------" hoge) (x + 5) (y + 2)`
思いつけませんでした。

```elm

hoge x y =
    let
        _ = Debug.log ""---" "---
    in
    let
        dx =
            Debug.log "x" x

        dy =
            Debug.log "y" y
    in
    if x + y < 20 then
        hoge (x + 5) (y + 2)

    else
        ()
```
`let...in let...in`
これも思いつけませんでした。
CSSでヘッダーメニューを上部に固定する方法

# 概要
ウェブサイトを作る上で欠かせないメニューですが、上部に固定する時に思いの外てこずったので、改めて調べたことをまとめて残しておきたいと思います。

これまで上部固定は`position: fixed;`が多く使われていましたが、CSS3でより使い勝手の良い`position: sticky;`が登場し、[ブラウザ対応状況](https://caniuse.com/#search=sticky)もだいぶ良くなってきたようなので、今回は後者で挑みます。
できるだけシンプルに実装したつもりです。誰かのお役に立ちますように。

**キーワード**
*position: sticky; display: flex;*


# サンプル

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="css,result" data-user="tamamotch" data-slug-hash="xxVrpxB" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="ヘッダーメニューを上部に固定">
  <span>See the Pen <a href="https://codepen.io/tamamotch/pen/xxVrpxB">
  ヘッダーメニューを上部に固定</a> by Tamamotch (<a href="https://codepen.io/tamamotch">@tamamotch</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


# 解説

## 前処理

```css
* {
  margin: 0;
  padding: 0;
}
```

デフォルトCSSの関係であちこちに隙間ができてしまうので上書きする。
指定した覚えのない謎の隙間がある場合はデフォルトCSSを疑うべし。


## header

```css
header {
  position: sticky;
  top: 0;
  z-index: 100;
}
```

`position: sticky;`
**header**要素をスティッキーアイテムにする。
自動的に親要素である**body**要素がスティッキーコンテナになる。
これにより、**header**要素が貼り付く。
なお、スティッキーコンテナ内に兄弟要素がないときちんと貼り付かない仕様とのことなので、兄弟要素**main**も用意する。
試しに**main**要素を丸っと削除すると、スクロールと共に**header**要素が流れていってしまうのが分かる。

`top: 0;`
貼り付く場所を最上部に固定する。

`z-index: 100;`
スクロールした時に全要素の上に重なるよう、適当な大きさを指定しておく。


## ul

```css
.ul-menu {
  display: flex;
  list-style-type: none;
  text-align: center;
}
```

`display: flex;`
**ul**要素をflexコンテナにし、子要素**li**をflexアイテムにする。
これにより、子要素**li**が横並びになる。

`list-style-type: none;`
リストのマーカーを削除する。

`text-align: center;`
テキストを左右中央寄せにする。


## li

```css
.li-menu {
  flex: 1;
}
```

`flex: 1;`
flexアイテムである**li**要素の横幅を均等にする。
試しにこれを削除すると、**li**要素の横幅がそれぞれのテキスト幅になるのが分かる。


## a

```css
a {
  display: block;
  text-decoration: none;
  padding: 10px 0 10px 0;
}

.a-1 { background-color: pink; }
.a-2 { background-color: moccasin; }
.a-3 { background-color: lightblue; }
```

`display: block;`
表示形式をblockにする。
これにより、**a**要素のクリック範囲が親要素**li**のサイズと同じになる。

`text-decoration: none;`
見栄えのために、テキストの装飾（リンクの下線）を行わない。

`padding: 10px 0 10px 0;`
見栄えのために、上下に10px太らせる。

`background-color: xxx;`
分かりやすいように各範囲に色を付けておく。


## main

```css
main {
  height: 500px;
}
```

`height: 500px;`
ある程度スクロールできるよう、高さを持たせておく。


# 応用
応用技として、[CSSでヘッダーメニューを上部に固定する方法（多階層メニュー）](https://qiita.com/Tamamotch/items/efc4ab95574e95b9c850)も公開しました。
サブメニューも持たせたい人はこちらも覗いてみてください。
特定のページ(URL)のみベーシック認証をかける（アドレスでベーシック認証）

ワードプレスを使って商品一覧ページを作っているけれど、
商品ページが変更になった、商品がなくなった。

商品一覧ページから該当ページを削除すればよいのですが、・・・・・
やり方がわからない。
理由：作った人がやめた。ワードプレスよくわからない。
※依頼理由のNO1です。

で、
1 商品一覧ページのうち、すでにない商品のページをクリックしたときだけ、ベーシック認証をかけてほしい
2 商品一覧ページのうち、作成中のページをクリックしたときもベーシック認証をかけてよしい


こんなときは
特定のURLを含むページのみベーシック認証をかけるで対応しました。

前提
・環境はさくらのレンタルサーバー
・.htaccessを使う
・ワードプレスでURLが自動生成されている

結論
URLにmenuとdevが含まれているときはベーシック認証がかかる

```:.htaccessベーシック認証　
1 DirectoryIndex index.html index.htm index.shtml index.php index.cgi
2 Options -Indexes
3 AuthUserFile /home/〇〇〇/www/〇〇〇/ridirect/.htpasswd
4 AuthType Basic
5 AuthName "Web access"
6 Require valid-user
7 SetEnvIf Request_URI "(menu|dev)" auth_chk
8 Satisfy any
9 Order deny,allow
10 Deny from env=auth_chk

```

<b>③と⑦を変えれば動きます。<b>

## ①～⑥
さくらのレンタルサーバーの初期値なのでこちらの説明を参考に

https://qiita.com/apple123/items/cc7d458ba98febd6038f

##7 SetEnvIf Request_URI "(menu|dev)" auth_chk
URLにmenuかdevが含まれていたら、変数auth_chkに1を設定する

###7-1　SetEnvIfの使い方
####SetEnvIt ①　②　③
<b>①ここには リクエストを表す値を設定します。</b>
設定できる値は決まっていて、値は↓記載の公式サイトで確認できます。

今回はURLを取得したいので
<b>Request_URI</b>になります。

その他、
Remote_Addr・・・リクエストを行なっているクライアントの IP アドレス
などたくさんあります。

参考：SetEnvIf Apache公式サイト
http://httpd.apache.org/docs/2.2/ja/mod/mod_setenvif.html#setenvif

<b>②ここには正規表現を書きます。</b>
今回は単純に menuかdevが含まれている場合なので(menu|dev)　にしました。

<b>③　①と②の条件を満たす場合　変数を設定する</b>
今回はURLにdevもしくはmenuが含まれる場合変数auth_chkに1を設定しています。
・変数名は自由
・変数に値を設定していない場合は1が設定される
※auth_chkが決まった変数名に思えますが、これは自由に設定した変数名です。

##8 Satisfy any
AuthUserFile /home/〇〇〇/www/〇〇〇/ridirect/　以下にアクセスしてもベーシック認証のダイアログがでてこないようにする。

###8-1 Satisfy any
ホストによる制御
ユーザー認証による制御
どちらかを満たしていればOKということ

今回はさくらのレンタルサーバーなので、
ホストによる制御→海外からのIPアドレス制限
ユーザー認証による制限→特になし
↓
国内からのアクセスのためホストによる制限を満たしている
→ホストによる制御をみたしている
→ホストによる制御、ユーザー認証による制御のどちらか一方を満たしているということで
ベーシック認証のダイアログがでてこなくなります。

※初期値Satisfy all　のままだと、ベーシック認証のダイアログがでてきます。

Satisfy Apache公式サイト：
https://httpd.apache.org/docs/2.4/ja/mod/mod_access_compat.html#satisfy

##9 Order deny,allow
すべてのアクセスをOKにする。
ここはベーシック認証のダイアログがでてくる、でてこないの話ではなく、
アクセスする権限があるかどうかということ。

ここは混乱しました。
アクセスする権限があるけれど、
あなたはベーシック認証のダイアログにIDとパスワードをいれてね、
あなたはベーシック認証無しでアクセスできるよ
という話のようです。

###10 Deny from env=auth_chk
auth_chkの値が1の人はベーシック認証のダイアログを表示する
URLにmenuもしくはdebが含まれている人はauth_chkの値が1です。⑦参照

<b>Q ここででてくるenvってなんんでしょう</b>
これも勝手につかっていいのでしょうか。

<b>A これはDeny、Allowの引数で
環境変数 の存在によりアクセスの制御を行なえるようにするものです。</b>
env=環境変数の形式で使います。
envとは決まった名前です。

今回の場合、 環境変数 auth_chkが存在した場合にリクエストはアクセスを拒否されます。
なので、


Apacheの公式サイト　Allowのところに詳しくのっています。
https://httpd.apache.org/docs/2.4/ja/mod/mod_access_compat.html#allow
https://httpd.apache.org/docs/2.4/ja/env.html#using


現在この記述は別のサイトでもコピペされて大活躍しています。
めでたし、めでたし。
Satisfy　anyのところはなんとなくの記述なので、ご指摘があればお願いいたします。

■参考サイト追記
https://www.magata.net/memo/index.php?Apache2.4%20%A4%CERequire%A5%C7%A5%A3%A5%EC%A5%AF%A5%C6%A5%A3%A5%D6%A4%C7%A5%A2%A5%AF%A5%BB%A5%B9%C0%A9%B8%E6%A4%F2%B9%D4%A4%A6
めちゃくちゃ今更ビットとバイト

エンジニアとして働き初めて２年、当たり前すぎて気にもとめてなかったのですが
ふと「ビットとバイトってなんぞや？」と思いましたので調べてみました。
業務の中、また日常生活でも登場するビットとバイト。
なんとなくデータの容量を表しているんだろうなー程度できちんと理解している人って少ないのではないでしょうか。

#ビットとバイトとは
**ビットやバイトはデータの記憶容量などを表すときに用いられる表現です。**
そしてビットはコンピュータ内部における情報表現の最小単位とされており、
コンピュータの世界では、**1バイト（Byte）= 8ビット（bit）**と定義されています。
コンピューターでは、2進法と呼ばれるすべてのデータを0と1の2つの数字の組み合わせで表現し計算していますので、1ビットでは**"0"または"1"**が格納されています。

#情報表現数
上記で説明したように1ビットでは**“0”または“1”**が格納されています。
ですので表現できる情報の数は、**"2"`**となります。
同じように2進法に則ると、2ビットでは、"00","01","10","11"`の4種類の情報表現が可能となります。
この情報の表現できる数を情報表現数と呼びます。
1ビットでは2種類、2ビットでは4種類というのは、2*1=2種類、2*2=4種類と求めたもので、nビットにおける情報表現数は、2n種類となります。

#補助単位
日常生活において1000gを1k表現したり、1,000mlを1lと表現したりするかと思います。
この"k"や"m"のような数値の倍率を表すものを補助単位と呼びます。

![補助単位.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532362/f3728655-f7a2-1dc7-14b5-37fd4e2256b2.png)

普段目にしているKB（キロバイト）MB（メガバイト）GB（ギガバイト）TB（テラバイト）はこれら
**補助単位**を用いた表現だったんですねぇ。
ちなみに書く補助単位の関係はこんな感じです。

KB（キロバイト）：1024B（バイト）のこと
MB（メガバイト）：1024KBのこと
GB（ギガバイト）：1024MBのこと
TB（テラバイト）：1024GBのこと

#おわりに
当たり前ですが今までなんとなくしか理解できていなかったのでなんかスッキリしました。
疲れたマン
【備忘録】覚えにくい用語

何回見ても、なんやったっけ？ていう用語を無理やり覚える方法
※個人的な覚え方で、解釈は適当です。

touch【ファイルを作成する】
=>なぜ、ファイルを作成するのにmkfilとかでなくtouchなのか。
元々存在しないファイルは、触れない（touch）できない。ファイルを作成することにより、そのファイルに触れる(touch)できるようになる。

mv【ファイル名を変更する】
=>パスは、コンピューターがファイルにアクセスする住所みたいなもの。
「東京/千代田区/1丁目/ハイツ リナックス」　というファイル（住所）があったとする。

マンション名が「ハイツ　リナックス」から　「マックマンション」　に変わったとする。
「東京/千代田区/1丁目/マックマンション」

↑  コンピューターから見たら、ファイル名変更ではなく住所移動に見える。

【比較演算子が　=< なのか　<=なのか（順番）】
=> イコールが先だと　以上の時　=>　アロー演算子となってしまう。
だから、イコールが後。

【asc　と　desc】
ascは　A　から始まっている。よって通常の並び⇨昇順
画像のエッジ抽出（ラプラシアンフィルタ）



境界（エッジ）抽出例



![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107418/2c306a28-38a5-9353-996b-7522abc96b75.png)

ディジタル画像処理の基礎と応用
p.45
ラプラシアンフィルタ




```c#:Laplacian1.cs

//c:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe Laplacian1.cs

using System.Drawing;
using System.Drawing.Imaging;
using System;

public class Laplacian1
{
 public static void Main(string[] args)
 {
    if(args.Length==2){
    string path1;//in file name
    string path2;//out file name

    path1 = @".\" + args[0];
    path2 = @".\" + args[1];

    Bitmap image1;
    image1 = new Bitmap(path1, true);

	int i,j,nx,ny;
	int gray;
	Color col;
	//int[,] f = new int[256,256];//←　書籍のソースは誤り

	nx = (int)image1.Width;
	ny = (int)image1.Height;

	int[,] f = new int[nx,ny];


	Bitmap bmp = new Bitmap(image1);

	for(j=0;j<ny;j++){
		for(i=0;i<nx;i++){
			col = bmp.GetPixel(i,j);
			f[i,j] = (int)((col.R+col.G+col.B)/3);
		}
	}

	Console.WriteLine(" _1 ");

	for(j=1;j<ny-1;j++){
		for(i=1;i<nx-1;i++){
			gray=f[i,j-1] + f[i-1,j] - 4*f[i,j] + f[i+1,j] + f[i,j+1];
			gray += 128; 
			if(gray>158){ //閾値は、適当に
				gray=0;
			}else{
				gray=255;
			}
			bmp.SetPixel(i,j,Color.FromArgb(gray,gray,gray));
		}
	}

	Console.WriteLine(" _2 ");
    bmp.Save(path2, System.Drawing.Imaging.ImageFormat.Png);
	Console.WriteLine(" _3 ");
	return;

    }
 }

}

```
LinuxでNATルーター

# 概要

LinuxでNATルーターを構成し、2つのVLANの一方のアドレスをNATし通信させる方法です。
内容は検証目的のため、セキュリティ等一切考慮しておりません。本番運用の際にはご注意ください。

# 想定シナリオ

以下の2つの組織が運用するVLANが存在するとします。

VLAN1: 192.168.1.0/24
VLAN2: 10.0.0.0/24

ここで VLAN1 の 192.168.1.100 から VLAN2 の 10.0.0.100 にアクセスしたいとします。
VLAN1 側組織は10.0.0.0/24のアドレスが他の用途に利用されているとし、VLAN1側では10.0.0.100のアドレスは192.168.2.100に見えるようにします。
一方VLAN2側では、192.168.1.100 をアドレス変換なくアクセスできるようにします。

# 設定手順

1. CentOS 8 をインストールし、VLAN1とVLAN2に接続します。VLAN1をeth1とし、VLAN2をeth2とします。
2. いろいろと面倒なので、SELinuxは無効化しておきます。```/etc/selinux/config```で```SELINUX=disabled```にすればよいです。
3. また、firewalldも無効化しておきます。```systemctl disable firewalld```
4. ルーティング機能を有効化します。```/etc/sysctl.conf```に```net.ipv4.ip_forward=1```を追加してください。
5. 有効化するため、再起動します。
5. ```iptables```でNAT設定を行います。

```
# iptables -t nat -A POSTROUTING -d 192.168.1.100 -j SNAT --to-source      192.168.2.100
# iptables -t nat -A PREROUTING  -d 192.168.2.100 -j DNAT --to-destination 10.0.0.100
```

1行目は、宛先が192.168.1.100のパケットを受信した場合に、ソースアドレスを192.168.2.100に変換。
2行目は、宛先が192.168.2.100のパケットを受信した場合に、宛先アドレスを10.0.0.100に変換。PREROUTINGを指定することで、宛先アドレスを変換した後にルーティングされるようにします。
この設定は再起動すると消えてしまうので、起動毎に実行してください。（永続化の方法がわかりませんでした）
初投稿・自主学習について

#はじめに
はじめまして。しがない若手SEです。

大学卒業後SEとして働き出し、はや数年経ちます。ここ数年は業務をただこなすことに追われ、業務時間外に勉強することも一切無くなってしまいました。

最近、自分をふと省みる機会があり、その中で

「もっと色々な技術・知識を得て技術者として成長したい」

そんなことを強く思うようになりました。

そのためにも積極的に自主学習し、その内容をアウトプットしようと考え、今に至ります。

#今後の展望について

ネットワーク、セキュリティの基盤系に関わることを主にやっていきたいと思っています。
あとは、それらの途中で生じた設定等の備忘録とかをここに書けたらと。

#最後に
少しずつでも停滞することなく、前に進めるように頑張っていきたいと思います。
Androidっぽい見た目のトースト通知を作ってみた(非jQuery依存)

かなり前に、Androidっぽい見た目のトースト通知(数秒で消える通知メッセージ)のjsライブラリを作成して、[投稿した](https://qiita.com/negi3d/items/4d4531af66774f503659)のですが、がっつりJQueryを使っていたため、jQuery非依存に書き換えました。
またコードをGitHubに公開し、npmでinstallできるようにもしてみました。

## 今回作った物：a-toast
![atoast.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27057/c12fefb9-1860-dd30-0566-99a6b730333a.gif)

Androidっぽい見た目のトースト通知なので、その**a**です。

#### GitHubリポジトリ:
https://github.com/negi141/a-toast

#### デモページ
https://negi141.github.io/a-toast/

## 使い方
``npm install negi141/a-toast``でインストール。
または、/build/内のjsとcssを手元に持ってくる。

```html:html
<link rel="stylesheet" href="a-toast.css" />

<script src="a-toast.js"></script>
```

```javascript:js
var toast = new aToast();

// スピードや表示位置の設定 (任意)
//   speed : 表示時間. millisecond. default=4000.
//   position : 表示位置. 'top' or 'bottom'. default='top'.
toast.setOption(speed, position);

// 通知を表示
//   message : 表示するテキスト
//   style : 通知の色. '' or 'success' or 'warn' or 'danger'. default=''. 
toast.show(message, style);
toast.success(message);
toast.warn(message);
toast.danger(message);
``` 

## その他：jQuery⇒jQuery非依存にあたって
fadeIn()はjQueryを使わない場合、どう書くのかなーと思いましたが、以下のようにCSSのtransition-（時間的変化）で書き換え可能でした。

```javascript:js
$('.a-toast').hide().fadeIn('fast');
```
　↓　↓　↓

```javascript:js
t.classList.add("a-toast-show");
```

```css:css
.a-toast {
  transition-property: opacity; 
  transition-duration: 0.8s;
  opacity: 0;
}
.a-toast-show {
  opacity: 1;
}
```

## ※メジャーなトースト通知ライブラリも紹介
- Toaster ※jQuery必須
  - https://codeseven.github.io/toastr/
- Bootstrap Notify 
  - http://bootstrap-notify.remabledesigns.com/
- Bootstrap Toasts
  - https://getbootstrap.com/docs/4.3/components/toasts/
- iziToast
  - https://izitoast.marcelodolza.com/
AtCoderBeginnerContest177復習＆まとめ（前半）

# AtCoder ABC177
2020-08-29(土)に行われたAtCoderBeginnerContest177の問題をA問題から順に考察も踏まえてまとめたものとなります．
前半ではABCまでの問題を扱います．
問題は引用して記載していますが，詳しくはコンテストページの方で確認してください．
[コンテストページはこちら](https://atcoder.jp/contests/abc177)
[公式解説PDF](https://atcoder.jp/contests/abc177/editorial)

## A問題　Don't be late
> 問題文
> 高橋君は青木君と待ち合わせをしています。
> 待ち合わせ場所は高橋君の家から$D$メートル離れた地点であり、待ち合わせの時刻は$T$分後です。
> 高橋君は今から家を出発し、分速$S$メートルで待ち合わせ場所までまっすぐ移動します。
> 待ち合わせに間に合うでしょうか？


```python:abc177a.py
d, t, s  = map(int, input().split())
if d <= t * s:
    print("Yes")
else:
    print("No")
```

## B問題　Substring
> 問題文
> $2$つの文字列$S, T$が与えられます。
> $T$が$S$の部分文字列となるように、$S$のいくつかの文字を書き換えます。
> 少なくとも何文字書き換える必要がありますか？
> ただし、部分文字列とは連続する部分列のことを指します。例えば、'xxx' は 'yxxxy' の部分文字列ですが、'xxyxx' の部分文字列ではありません。

$S,T$は$1$文字以上$1000$文字以下なので，全部の可能性を時間内に計算することができます．
例えば，7文字の'abcdefg'と3文字の'efh'を考えると，'abc'，'bcd'，'cde'，'def'，'efg'の各々に対して，何文字書き換える必要があるか計算し，最小のものが答えとなります．

```python:abc177b.py
s = input()
t = input()
min_count = 1000
for i in range(len(s) - len(t) + 1):
    count = 0
    for j in range(len(t)):
        if s[i+j] != t[j]:
            count += 1
    min_count = min(count, min_count)
    if min_count == 0:
        break
print(min_count)
```


## C問題　Substring
> 問題文
> $N$個の整数$A_1,…,A_N$が与えられます。
> $1 \leq i < j \leq N$を満たす全ての組$(i,j)$についての$A_i×A_j$の和を$mod(10^9+7)$で求めてください。

求める和は，$A_1×(A_2+...+A_N) + A_2×(A_3+...+A_N) + ... + A_{N-1}×(A_N)$となるので，個別に全て計算するよりも，計算量を抑えることができる．

```python:abc177c.py
n = int(input())
a_list = list(map(int, input().split()))
ans = 0
total = 0
mod = 10 ** 9 + 7
for i in range(n):
    total += a_list[i]
    if total >= mod:
        total = total % mod
for i in range(n - 1):
    total -= a_list[i]
    if total < 0:
        total += mod
    ans += a_list[i] * total
    if ans >= mod:
        ans = ans % mod
print(ans)
```

前半はここまでとなります．
最近は公式の解説がとても丁寧に記述してあったので，詳しい解法はそちらを参考にしてもらえたらと思います．
前半の最後まで読んでいただきありがとうございました．

後半はDE問題の解説となります．
[後半に続く](https://qiita.com/takaito0423/items/f58fcef5e2254be03bb0)．
「語尾に自動でやんすをつけてくれるアプリ」を作ってみた


[ポートフォリオや個人開発で使えそうなアイデア](https://qiita.com/MasatoraAtarashi/items/eec4642fe1e6ce79304d)

こちらで色々面白いアイディア並んでて何かできるかな・・と眺めてたけど
Webアプリが多くて出来そうにもない・・と、そこに光明の光が！ｗ

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189193/88cdfb4a-6855-2de1-80b7-30bf40660d9d.png)

# つくってみたわ

<a href="https://github.com/yasutakatou/goBi"><img src="https://github-link-card.s3.ap-northeast-1.amazonaws.com/yasutakatou/goBi.png" width="460px"></a>

![yannsu.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189193/674efbbe-eb9a-454e-6c86-d126d7d26396.gif)

#### v0.2 途中まで入力したものを、訂正して違う語尾ルールへ変換できるようにしました (追記)

![yannsu2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189193/6d40725c-3089-154d-5d87-96cfc256186d.gif)

途中から"ました"→"です"のルールに変えて変換しています。

#### v0.3 実行した時のオプションをコンフィグファイルとして保存するようにしました (追記)

デフォルトで".goBi"に**実行した時のオプションを保存**します。**起動時にコンフィグがあれば読み込み**ます。
これで再実行時に毎回同じ語尾が使える！やったね！！


つかいかた：

バイナリに変換前と、変換したい単語を"@"(デフォ)で区切って渡してください

```
>goBi.exe desu@deyannsu masita@tadeyannsu 190@yannsu
```

こう指定すれば”です”、”ました”、”。”が入力されると”やんす系”に変換します。
数字一個の指定は対応しているASCIIコードが一個来たら変換するモードです

※v0.3 からコンフィグファイルに対応していますので、オプション無しでもコンフィグから
　前回の設定を読み込んで動くようになりました！よって毎回オプション指定しなくてOK 

### うごくOS (追記)

動作環境は今のところ**Windows系OS**のみです。
キー入力している**ウィンドゥが変わったら、それまで入力してたカウンターをリセットする**処理にWindowsのAPIを使用しているためです。
途中まで入力したのが、他の窓で暴発しないようにしたためで、それでも良いなら簡単に他OSへ移植できます。

# あとがき

アプリじゃねー！ｗｗ
でもTwitterでキャラ作ってるとか、うっかり設定崩さない時に使えます。

つか、これrm -rfとか入力したら無効化してくれるみたいな実用的な使い方も無くもないな。
以外と使い道あるかもしれん。

ひとまず、今はここまで。でも一日もかからず、ここまでパッと書ける言語ガチで凄くね？

### サンキューGo言語！！
AtCoder：Python：サンプルテストをパパっとする。

以下のように記載してINPUTのところにテストケースの入力をコピペすると楽。ついでに実行時間を測れる。

```python:test.py
import io
import sys
import time
_INPUT = """\
#ここに入力をコピペ
"""
StartTime = time.time()
sys.stdin = io.StringIO(_INPUT)
# --------------------------------------------------------
#ここに処理を記載
# --------------------------------------------------------
print ("[Sec]"+str(time.time() - StartTime))
```

例：

```python:example_ABC177_A.py
import io
import sys
import time
_INPUT = """\
1000 15 80
"""
StartTime = time.time()
sys.stdin = io.StringIO(_INPUT)
# --------------------------------------------------------
d,t,s=map(int, input().split())
 
if d<=s*t:print("Yes")
else:print("No")
# --------------------------------------------------------
print ("[Sec]"+str(time.time() - StartTime))
```

出力

```python:example_ABC177_A.py
Yes
[Sec]0.0009970664978027344
```

提出は点線の中だけ行う。
［学習記録］Gitを習得する

# 目的
Gitを理解して使いこなせるようになること

# 達成度の目安
* 何に使うかわかる
* （個人的に）使える
* 分かる
* 教えられる
* 展開できる
* 問題解決できる

# 習得方法
## 1つ目　『サルGit』で学ぶ
有名なGit解説のページ：　[サル先生のGit入門](https://backlog.com/ja/git-tutorial/)

### もちろん入門編から
2020.8.30

インストールしてるGitのバーション：　2.17.1
主に使用しているPCのOS：　Ubuntu 18.04.5 LTS

<<何に使うか分かる>>

* ファイルのバージョン管理を簡単に効率よく行うために使う。
* 複数人で編集しているときも間違いが起きにくい
* 古いファイルを保存するのではなく、履歴を残す
* ファイルの管理をする場所がリポジトリ
* ローカルPC上には作業用のローカルレポジトリ、サーバー上には共有用のリモートレポジトリ
* コミット(commit)すると変更点が保存される
* 作業フォルダがワークツリー、コミット準備用フォルダがインデックス。
* プッシュ(push)するとリモートレポジトリで共有できる
* クローン(clone)するとリモートリポジトリをコピーしたローカルレポジトリを作れる
* プル(pull)するとリモートレポジトリの最新の更新履歴をダウンロードできる
* 他の変更履歴がある場合はマージ(merge)しないとプッシュできない
* マージすると、Gitが自動的に変更箇所を統合する
* 自動的に統合できなかった箇所はコンフリクト(conflict)になる　-同じ部分を変更してるときとか
* 


<<（個人的に）使える>>

* インストールする
* 設定ファイルの操作　（細かい設定は後で）
* 新しいリポジトリの作成  ローカルレポジトリはフォルダを作って、コンソールで```git init```
* ```git status```でディレクトリの状態確認
* ```git add <ファイル名>```でファイルをインデックスに登録
* ```git commit -m <コメント>```でコミットする
* サルGitではBacklogでリモートレポジトリを作成しているけど、GitHubで作った。
* ```git remote add <リモートレポジトリの名前> <リモートレポジトリのURL>```でリモートレポジトリを登録
* **プッシュやプルの実行時にリモートレポジトリの名前を省略するとoriginが指定されるので、特別事情がなければリモートレポジトリの名前はoriginにする**
* ```git push <指定するリモートレポジトリ> <ブランチ>```でpush。ブランチについては後で。
* ```git clone <リモートレポジトリのURL> <複製に使うディレクトリ名>```でリモートレポジトリをローカルにクローン
* 競合の解決: プルして、競合部分を編集して、プッシュする

---
### 次は発展編

<<何に使うか分かる>>

* ブランチ(branch)で変更を分岐させる　<作業毎、目的毎、人毎>　-無駄な競合を避けられる
* ブランチの運用　『統合ブランチ』とトピックブランチ

![branch](https://backlog.com/ja/git-tutorial/assets/img/stepup/stepup2_1.png "サルGitから転載")

* ブランチを移動するとときはチェックアウト(Checkout)
* 現在のブランチの先頭がヘッド(Head)
* 変更内容の一時退避(Stash)

![stash](https://backlog.com/ja/git-tutorial/assets/img/stepup/stepup3_3.png "サルGitから転載")

* ブランチを統合するときはマージ(merge)とリベース(rebase)を使い分ける
* ブランチの運用が大事！　[A successful Git branching model](http://keijinsonyaban.blogspot.com/2010/10/a-successful-git-branching-model.html)
* リベースで統合するときは統合元にcheckout
* リベースしたらmergeしてfast-forward
* リモートレポジトリからプルしたときに、プルしてくるローカルのブランチに変更がなければfast-forwardになる
* リモートレポジトリからプルしたときに、変更がローカルのブランチのほうが進んでいるとマージ（競合があれば解消必要）
* リモートレポジトリの変更内容確認するだけのときはプルせずにフェッチ（fetch)する
* フェッチで確認した内容をローカルに取り込むときは改めてプルする
* リモートレポジトリにプッシュするときはfast-forwardでマージされなければならない　(プルしとけってことかな？）

<<（個人的に）使える>>

* ブランチを作るときは```git branch <ブランチ名>```
* ブランチを乗り換えるときは```git checkout <ブランチ名>```
* ```git checkout -b <ブランチ名>``でブランチの作成とチェックアウトが一発でできる
* マージするときは取り込み側のブランチにいること
* ```git merge <取り込みたいブランチ>```
* ```git branch -d <削除するブランチ>```  -d　オプションでブランチを削除
* ```git rebase master``` で支流をマスターにリベース　**支流にチェックアウトしておくこと！！**
* リベースできたら、マスターにチェックアウトしてからリベースした支流をマージ（fast-forward)
Mozilla Hubs の対応環境と基本操作など

以下の [Mozilla Hubs](https://hubs.mozilla.com/) を[とりあえず試してみるという話の記事](https://qiita.com/youtoy/items/36c66b1ad55c317ea552)を前に書いたのですが、今回は操作方法などを見てみたので、その時のメモです。
　●Hubs - Private social VR in your web browser
　　https://hubs.mozilla.com/
（今年6月ごろに下書きを作っていて、書きかけのままにしていたものだったのですが、ちょっと手を加えて公開してしまおうかと）

## 対応環境
[Hubs](https://hubs.mozilla.com/) を利用可能な環境の情報を、まずは書いておきます。
参照元は以下の公式情報です。
　●Welcome to Hubs · Hubs by Mozilla
　　https://hubs.mozilla.com/docs/welcome.html

### サポートされているブラウザ
公式ドキュメントの[Supported Browsers](https://hubs.mozilla.com/docs/welcome.html#supported-browsers) に書かれた 2020/6/5時点での情報で、対応プラットフォームとブラウザの組み合わせが表で書かれています。

| プラットフォーム | ブラウザ |
:----------|:--------|
| Windows | Firefox, Chrome, Edge (version 79+) |
| Mac OS | Firefox, Chrome, Safari |
| Linux | Firefox |
| Android | Firefox, Chrome |
| iOS | Safari |
| Standalone VR（**※**） | Oculus Browser, Firefox Reality |
**※ 上記の「Standalone VR」は、複数の VRヘッドセットが該当するようで、以下で少し補足します。**

### Standalone VR（VRヘッドセット）の補足
公式ドキュメントの以下の別ページで「[For VR experience](https://hubs.mozilla.com/docs/hubs-create-join-rooms.html#for-vr-experience)」という記載があり、「Standalone VR」に該当する VRヘッドセットの名前が書いてありました。
　●Create and Join Rooms · Hubs by Mozilla
　　https://hubs.mozilla.com/docs/hubs-create-join-rooms.html
2020/6/5時点での情報では「**Pico Neo 2, Oculus Quest and Oculus Go**」の 3つが記載されていました。
自分は、この中で Oculus Quest ＋ Firefox Reality の組み合わせで試したりしました。
（なお、VR環境以外のものは Mac と iOS で試しています）

また、デスクトップVR について記載があり、「Oculus Rift, Windows Mixed Reality, or HTC Vive」の名前が挙がっていました。デスクトップVR は、「Oculus Desktop App (Oculus rift)」か「SteamVR(Windows Mixed Reality, HTC Vive)」を使う形のようです。
自分はこれらのデバイスを持っていないため、実際の動作は確認できていません。

## 基本操作
[公式ドキュメントで操作方法が書かれたページ](https://hubs.mozilla.com/docs/hubs-controls.html)を一部抜粋してみます。

### タッチスクリーンでの操作

|アクション|操作方法|補足|
|:------|:------|:------|
|移動|ピンチイン・ピンチアウト||
|回転|一本指でのドラッグ||
|移動・回転|スクリーン上のジョイスティックでの操作||
|ペンの出し入れ|ペンボタンをタップ||
|オブジェクトを回転させる|指でドラッグ|オブジェクトのメニューの「回転ボタン」を押しっぱなしにした後で操作|
|メニューの切り替え|二本指でのタップ||

### キーボード・マウスでの操作

|アクション|操作方法|補足|
|:--|:--|:--|
| 移動 | 矢印キー、または、W・A・S・D |  |
| 回転 | Q・E、または、マウスの左ボタン |  |
| テレポート | マウスの右ボタン |  |
| 高速移動 | Shiftキー |  |
| メニュー表示 | スペースキーを押しっぱなし |  |
| メニューの切り替え | Tabキー |  |
| マイクのミュートのON/OFF | M |  |
| チャットにフォーカスをあてる | T |  |
| オブジェクトを回転させる | マウスの移動 | オブジェクトのメニューの「回転ボタン」を押しっぱなしにした後で操作 |
| オブジェクトの大きさを変える | Shiftキー ＋ マウスホイール | オブジェクトをホールドした状態で操作 |
| オブジェクトを近く/遠くに移動させる | マウスホイール | オブジェクトをホールドした状態で操作 |
| ペン・カメラを出す | マウスの右ボタン、または、エスケープキー | ペン・カメラをホールドした状態で操作 |
| ペンの色を次/前のものにする | Shiftキー ＋ E, Shiftキー ＋ Q | ペンをホールドした状態で操作 |
| ペンのサイズを変更 | Shiftキー ＋ マウスホイール | ペンをホールドした状態で操作 |
| ペンストロークの取り消し | Ctrl + Z | ペンをホールドした状態で操作 |
| 写真を撮る | マウスの左ボタン | カメラをホールドした状態で操作 |
| メディアのボリュームの上げ下げ | マウスホイール | マウスカーソルをメディアにのせた状態で操作 |
| カメラのミラーモードから出る | Escape |  |
| Web検索をする | Ctrl-[1-7] |  |
| Spawn from Chat | Ctrl-Enter | チャットボックスへの入力中に操作 |
| I'm Feeling Lucky | Ctrl-Enter | コンテンツ検索中に操作 |

## その他の操作「飛行（Fly mode）」
移動に関して「Fly mode」というものもあるようです。
以下に「Use the "/fly" command in the chat box to toggle fly mode.」という記載があります。
●Hubs in-room experience | Hubs Help
　https://support.mozilla.org/en-US/kb/hubs-room-experience#w_fly-mode

## おわりに
Hubsに関して、調べ切れてないものがいろいろありそうなので、また公式ドキュメントなどを見ていければと思ってます。
Azure Kubernetes Service を使用して、クラスターのデプロイ

この記事は「いのべこ夏休みアドベントカレンダー2020」の26日目の記事です。本記事の掲載内容は私自身の見解であり、所属する組織を代表するものではありません。

<Azure Kubernetes Service を使ってみたわけ>
特にWeb アプリのコンテンツがあるわけではいが、インフラエンジニアとしては基盤から入る方が取り掛かりやすいので、Azure Kubernetes Service から入っていきたいと思います。

■Azure Kubernetes サービス(AKS)
![スクリーンショット 2020-08-30 10.19.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674747/e6cb0123-37a3-9745-c2aa-0ae9d82b4221.png)
コンテナーベースのアプリケーションをオーケストレーションしてくれるサービス。
AKSを使用すれば、クラスタマスタはMicrosoftが管理してくれるため、監視や冗長化等を行う必要がありません！
しかも、クラスタの管理については無償という太っ腹（SLAがないことについては要注意）。
※AAzure 可用性ゾーンを使用するクラスターに対しては、Kubernetes API サーバーの 99.95% のアップタイムを保証しています。

なお、ノードのスペックはAzureのVMサイズから選ぶことが可能。


<目次>
1.AKSクラスターの作成
2.クラスターに接続
3.アプリケーションの実行
4.正常性の確認

<実装>
1.AKSクラスターの作成
Azure Portalにて、[リソースの作成]から[Azure Kubernetetes Service]を選択し、Kubernetes　クラスターを作成していきます。

まずは、クラスターの名とリージョンを選択します。
![スクリーンショット 2020-08-30 10.29.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674747/d89956cc-2937-daef-af13-ab45a17cd073.png)

次にノードプールの作成します。
今回は、特にリクエストがあるわけではなく、あまり多くリソースを必要としないので以下のように設定しました。
OS：Linux
ノード数：3（最低数）
VMサイズ：DS2_V2
![スクリーンショット 2020-08-30 10.33.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674747/9a50fbd1-a865-cbea-5ef6-a461f9122390.png)

2.クラスターに接続
先ほど作成したAKSクラスターに接続して、ノードの状態を確認します。
![スクリーンショット 2020-08-30 10.55.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674747/6f9ad962-cd9d-b234-7ecb-0271bb7b3f67.png)
3台のノードが作成され、いずれのノードも”Ready”となっていることがわかります。

3.アプリケーションの実行
YAML形式で定義をし、Cloud Shellから定義ファイルを流します。
（今回はMicrosoft様の提供しているサンプルを使用することに。）
![スクリーンショット 2020-08-30 11.12.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674747/e4433665-e28f-9a7f-1c1d-92d52280861d.png)


4.正常性の確認
Azure Portalにて、[Kubernetesインスタンス]の[インサイト]から、コンテナーの正常性を確認することができます。
![スクリーンショット 2020-08-30 12.39.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674747/52c90ab4-c46b-12db-7fe6-8da3f6577329.png)



今回は、以下のMicrosoft の記事を元にAKSのクラスターをデプロイしてみました。
今後は、Azure Services Web Apps やAzure Functions などを活用してWeb システムの作成などにも挑戦してみようと思います。

<参考>
クイック スタート:Azure portal を使用して Azure Kubernetes Service (AKS) クラスターをデプロイする
　<https://docs.microsoft.com/ja-jp/azure/aks/kubernetes-walkthrough-portal>
【Laravel実践】リクエストパラメータ名をスネークケースに変換する方法

# Version
- Laravel 5.7
- PHP 7.2.31

# 前提
LaravelでAPIを開発する際、キャメルケースとして書かれたリクエストパラメータ名をスネークケースに変換したい、という要望を想定します。たとえば、SPA開発においてReact.jsやVue.jsにより非同期通信でLaravelのAPIにリクエストを送信する際、フロント側としてはキャメルケースで統一したいがバックエンド側としてはスネークケースで統一したい、というケースです。

Laravel側で簡単に変換する方法をググったのですが、ベストプラクティス的な方法が出てこなかったのでここに共有します。

# 早速、変換してみよう。
結論だけ述べると、以下の方法で実現できます。

`$request->all()`でリクエストパラメータを受け取り、リクエストパラメータ名（`$key`）に大文字が含まれる場合にスネークケースに変換・挿入、`offsetUnset()`で元のプロパティ名を消す、ということをやっています。

```php
foreach ($request->all() as $key => $value) {
    if(preg_match('/[A-Z]/', $key)){
        $new_key = Str::snake($key);
        $request->merge([$new_key => $request->$key]);
        $request->offsetUnset($key);
    }
}
```

たとえば、TestControllerのindexで受け取ることを考えてみましょう。バリデーションを一旦無視すれば、以下のように書けるはずです。

```TestController.php

class TestController
{
    public function index(Request $request)
    {
        // スネークケースに変換する処理
        foreach ($request->all() as $key => $value) {
            if(preg_match('/[A-Z]/', $key)){
                $new_key = Str::snake($key);
                $request->merge([$new_key => $request->$key]);
                $request->offsetUnset($key);
            }
        }
        // hogehoge処理
        ...
        return $request;
    }
}
```

# 応用: スネークケース変換用のクラスを作成

色々と応用する方法はあると思いますが、最終的に以下の方法で落ち着きました。

- FormRequestクラスでバリデーション処理（※1）
- Controllerクラスを継承する形でスネークケースに変換するクラスを作成（※2）
- indexのController側でスネークケース変換用のメソッドを呼び出し（※3）

```NormalizedController.php
// ※2
class NormalizedController extends Controller
{
    /**
     * Change request parameter from camel case to snake case
     *
     * @param object $request
     * @return object
     */
    protected function normarize_request(Object $request) : object
    {
        foreach ($request->all() as $key => $value) {
            if(preg_match('/[A-Z]/', $key)){
                $new_key = Str::snake($key);
                $request->merge([$new_key => $request->$key]);
                $request->offsetUnset($key);
            }
        }
        return $request;
    }
}
```

```TestController.php
// FormRequestクラス（※1）
use App\Http\Requests\Test\GetRequest;

class TestController extends NormalizedController
{
    public function index(GetRequest $request)
    {
        // 呼び出し（※3）
        $this->normarize_request($request);

        // hogehoge処理
        ...
        return $request;
    }
}
```

# 参照
- [LaravelのRequestいろいろ](https://qiita.com/engineerYodaka/items/21f906ed94660508e6dc)
- [PHP: ArrayObject::offsetUnset - Manual](https://www.php.net/manual/en/arrayobject.offsetunset.php)
ESP-WROOM-02(ESP8266)の基本回路


毎回、ブレッドボードを組むときに構成を調べないで済むようにするための忘備録です。

#接続
####説明
| PIN | 説明 |
|:---:|:---|
| 3V3 | 電源のプラスライン（＋）に接続  |
| GND | 電源のマイナスライン（－）に接続  |
| EN  | プルアップ抵抗(10KΩ)を通してプラスライン（＋）に接続  |
| IO0 | プルアップ抵抗(10KΩ)を通してプラスライン（＋）に接続<BR>併せてFLASHスイッチを経由してマイナスラインにも接続  |
| IO2 | プルアップ抵抗(10KΩ)を通してプラスライン（＋）に接続  |
| IO15| プルダウン抵抗(10KΩ)を通してマイナスライン（－）に接続  |
| RST | RESETスイッチを経由してマイナスライン（－）に接続  |
| TXD | UARTコントローラのRXDと接続  |
| RXD | UARTコントローラのTXDと接続  |

####回路図

![ESP8266基本回路.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476879/a008f80c-df36-e8f3-a2c7-548fa4ffd5b1.png)

####RESETスイッチの使い方
本稿のRESETスイッチはPUSHで通電するPUSH型のタクトスイッチを想定している。

| モード | 操作 |
|:-:|:--|
| プログラム実行モード  | FLASHスイッチをOFF(押さない)状態でRESETスイッチをON(押す)/OFF(離す)する。<BR>RESETスイッチ離した瞬間にリセットがかかり、プログラムが実行される。 |
| プログラム書込モード  | FLASHスイッチをON(押す)状態でRESETスイッチをON(押す)/OFF(離す)する。<BR>FLASHスイッチがONのままRESETスイッチ離した瞬間にプログラム書き込みモードでリセットがかかる。<BR>プログラムはシリアルインタフェイス(UART)経由で流し込む  |
AtCoderBeginnerContest176復習＆まとめ（後半）

# AtCoder ABC176
2020-08-22(土)に行われたAtCoderBeginnerContest176の問題をA問題から順に考察も踏まえてまとめたものとなります．
後半ではE問題を扱います．[前半はこちら](https://qiita.com/takaito0423/items/f65321815797e9dc3c11)
問題は引用して記載していますが，詳しくはコンテストページの方で確認してください．
[コンテストページはこちら](https://atcoder.jp/contests/abc176)
[公式解説PDF](https://atcoder.jp/contests/abc176/editorial)

## E問題　Bomber
> 問題文
> $H×W$マスの二次元グリッドがあります。この中には$M$個の爆破対象があります。 
> $i$個目の爆破対象の位置は$(h_i,w_i)$です。
> 高橋君は$1$つのマスを選び、そのマスに爆弾を設置し、起爆します。爆弾と同じ行または同じ列に存在する爆破対象が爆破されます。爆破対象が存在するマスに爆弾を設置することも出来ます。
> 高橋君は、爆破する爆破対象の数を最大化しようとしています。最大でいくつの爆破対象を爆破出来るか答えてください。

コンテスト本番時は，爆破対象を勝手に爆弾だと勘違いして，ボンバーマン的な話かと思って苦戦してしまいました．
行$j$の爆破対象の個数を$Hcount_j$,行$k$の爆破対象の個数を$Wcount_k$とすると，最大で爆破出来る数は，$max(Hcount) + max(Wcount)$ または， $max(Hcount) + max(Wcount) - 1$のいずれかである．

なぜなら，設置する位置の候補は，$max(Hcount)$となる行と，$max(Wcount)$となる列の交点であり，交点に爆破対象があれば，$max(Hcount) + max(Wcount) - 1$爆破でき，交点に爆破対象がなければ，$max(Hcount) + max(Wcount)$爆破できるため，対象となる交点を探索し，交点に爆破対象がない場合が一つでもあるかどうかで答えを求めることができる．

```python:abc176e.py
h, w, m = map(int, input().split())
bom_set = set()
h_dict = {}
w_dict = {}
for i in range(m):
    hh, ww = map(int, input().split())
    bom_set.add(tuple([hh, ww]))
    if hh in h_dict:
        h_dict[hh] += 1
    else:
        h_dict[hh] = 1
    if ww in w_dict:
        w_dict[ww] += 1
    else:
        w_dict[ww] = 1
h_max_count = max(h_dict.values())
w_max_count = max(w_dict.values())
hh_dict = {}
ww_dict = {}
for hh in h_dict:
    if h_dict[hh] == h_max_count:
        hh_dict[hh] = h_max_count
for ww in w_dict:
    if w_dict[ww] == w_max_count:
        ww_dict[ww] = w_max_count
flag = 0
for hh in hh_dict:
    for ww in ww_dict:
        if tuple([hh, ww]) not in bom_set:
            flag = 1
            break
    if flag == 1:
        break
if flag == 1:
    print(h_max_count + w_max_count)
else:
    print(h_max_count + w_max_count - 1)
```

後半も最後まで読んでいただきありがとうございました．
git push をしたら reject されるときの解決法

# やったこと

1. GitHubのアカウントを作る
1. ローカルとリモートをリンクさせる
2. ローカルで適当なファイルを作る
3. コミットしたあとに`git push origin master`を叩く

# エラー内容

```
To https://github.com/○○○○/○○○○.git
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'https://github.com/○○○○/○○○○.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
```

# 解決方法

先に以下のコマンドを実行することでリモートの内容をローカルに反映させる

```
git merge --allow-unrelated-histories origin/master
```

# なぜ起きたか

GitHubで新しいリポジトリを作る時にREADME.mdを同時に作るとリモートとローカルに差分がでる
↓
先にリモートの内容をローカルにマージしてからpushしてね、となる
laravel 別のMYSQLに動的接続、切り替え

laravel で 別のデータベースに切り替えたい時がある。
例えば、古いDBから新しいDBにデータを以降する時など。


今回は、database twiski に切り替たい

```database.php

//色々と略
'connections' => [

'mysql' => [
    'driver' => 'mysql',
    'url' => env('DATABASE_URL'),
    'host' => env('DB_HOST', '127.0.0.1'),
    'port' => env('DB_PORT', '3306'),
    'database' => env('DB_DATABASE', 'forge'),
],


'old' => [
    'driver' => 'mysql',
    'url' => env('DATABASE_URL'),
    'host' => env('DB_HOST', '127.0.0.1'),
    'port' => env('DB_PORT', '3306'),
    'database' => 'twiski',//接続したいDBに書き換える
],


```


これで twiski に切り替えられる

```HogeContorller.php

$model = new User;

$res = $model
    ->orderBy('id', 'ASC')
    ->first();

$res = $model
    ->setConnection('old')//これが味噌
    ->orderBy('id', 'ASC')
    ->first();


```

DBファサードを使う


これで `old` の `users` テーブルのデータ取得できる

```HogeController.php

//use DB;

$profiles_tags = DB::connection('old')
    ->table('users')
    ->limit(5)
    ->get();


```


以上
「Vercel + freenom + Getform.io」構成で「爆速 + 管理費完全無料」のポートフォリオをGatsbyJSで作ったら幸福度が高まった話

こんにちは(๑╹ω╹๑ )

つい先月の[エントリ](https://qiita.com/huuya/items/2028ec526e14b031b17e)でGatsbyJSの魅力をお伝えしたばかりですが、
今日はそのGatsbyJSで開発したポートフォリオサイトの構成を紹介します🤗

↓ 開発した[ポートフォリオサイト](https://huuya.ga/)です

![huuya.ga.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560692/bb81344a-fc60-4144-7a87-7f6217c5eaae.png)


今回のエントリとは関係ないですが、
技術構成は下記のとおりです🤝

- React
- GatsbyJS
- Less

## ポートフォリオサイトの構成について☺️

### 管理費完全無料は本当？🤔

本当です👨‍💻

- SPAサイトの静的ホスティング
- 独自ドメイン
- お問い合わせ管理

全ての管理費が無料です✨
※ 2020年8月30日現在
※ 詳細は以降に説明

### 静的ホスティングサービスのVercelって何が無料？🥺

[Vercel](https://vercel.com/)

- 満載のDevOps
	- [Git Integrations](https://vercel.com/docs/git-integrations)で自動ビルド
		- GitHub（プライベートリポジトリ可
		- GitLab
		- Bitbucket
	- [Integrations Marketplace](https://vercel.com/integrations)の利用も無料
		- VercelイベントをSlackに通知する
		- ビルド後にLightHouseで自動レポーティング
- Starterから簡単にプロジェクトを開始できる
	- Gatsby.js
	- Nuxt.js
	- Angular
	- Next.js
	- Vue.js
- カスタムドメイン（50個まで
- 1ヶ月あたり100GBまでの転送量
- 自動でSSL化
	- デプロイしたら自動でhttpsになっていた😮
- Serverless FunctionsでAPIの実装
	- 所謂FaaS

↑全てが無料です😂
※ 個人利用プランの場合

[Vercelの料金ページ](https://vercel.com/pricing)

### freenomで独自ドメインを無料で取得・更新する

[freenom](https://www.freenom.com/ja/index.html?lang=ja)

`ga`という独自ドメインを無料で取得できました🎉

（個人開発ではいつも利用しています笑

正確には下記の制限があります😢

- `.tk`、`.ml`、`.ga`、`.cf`、`.gq`ドメインが対象
- 1〜12ヶ月の範囲でないと登録・更新できない（でも永久無料
- ネームサーバーの登録 or URL転送のみ

[freenomの料金ページ](https://www.freenom.com/ja/freeandpaiddomains.html)

### Getform.ioでお問い合わせの管理

[Getform.io](https://getform.io/)

お問い合わせフォームのエンドポイントになって、
それを管理できるサービスです😌

フォームを作成するたびにエンドポイントを発行してくれます！

個人利用の無料プランでは下記が無料です😄

- 1フォーム
- 一ヶ月あたり100件のお問い合わせ
- 単一ファイルのアップロード
- 100MBのファイルストレージ
- デフォルトのThanksページ
- チームメンバーを1人招待する
- スパム保護
- Zapierとの統合
- Getform API

[Getform.ioの料金ページ](https://getform.io/pricing)


## まとめ

個人のポートフォリオサイト規模の利用であれば、
不便なく、管理費も考えること無く利用できました🙌

制作過程で[Glitch](https://glitch.com/)という、静的ホスティングとペアプログラミングでコラボレーションが出来るサービスを見つけました！

- RAM：512MB
- ディレスク容量：200MB

の範囲であれば無料で利用できるみたいです🧐

[Glitchの料金ページ](https://glitch.com/pricing)

近い内に少し触ってみようと思います🌏
データ前処理による相関関係

機械学習のデータ前処理における相関関係について大体の目安をメモします。

参考になれば嬉しいです。

※ train = トレーニングデータ

```python
train_corr = train.corr()
print(train_corr)

#-1.0から-0.7・・・強い負の相関
#-0.7から-0.4・・・負の相関
#-0.4から-0.2・・・弱い負の相関
#-0.2から+0.2・・・ほとんど相関がない
#+0.2から+0.4・・・弱い正の相関
#+0.4から+0.7・・・正の相関
#+0.7から+1.0・・・強い正の相関

```
macOSで初めてGitを使おうとした時に出るエラーの対処法

# Mac のバージョン

Catalina 10.15.6


# エラー内容

```
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
```

# やったこと

以下のコマンドを叩くとポップアップが表示されるため許可をするとGitが使えるようになる

```
xcode-select --install
```