OmniAICreator/Qiita-1.07M huggingface dataset:
Web開発の基本知識（メモ用）

#背景
フロントサイドのソースを見たら、なんじゃこれ？のこれをメモする目的

#jQuery
- **$から始まる**
- **ready(function(){})関数**

  内側の関数は：HTMLの読み込みが終わった後に、実行される。

```javascript:例
$(document).ready(function() {
　　ここに処理記述
});
```
  readyが省略可能 

```javascript:上記の例の省略形
$(function() {
　　ここに処理記述
});
```

- **各種セレクター**

1.要素セレクター：`$("li").css("color", "blue");`

```html:要素セレクター
<ul>
  <li>要素</li>
</ul>
```

2.IDセレクター：`$("#myID").css("color", "blue");`

```html:IDセレクター
<ul>
  <li id="myID">IDセレクターの場合、"#"を使う</li>
</ul>
```

3.クラスセレクター：`$(".myClass").css("color", "blue");`

```html:クラスセレクター
<ul>
  <li class="myClass">クラスセレクターの場合、"."を使う</li>
</ul>
```

4.子孫セレクター：`$(".myClass strong").css("color", "blue");`

```html:クラスセレクター
<ul>
  <li class="myClass"><strong>子孫セレクター</strong>の場合、"space"を使う</li>
</ul>
```

5.ユニバーサルセレクター：`$(".li *").css("color", "blue");`

```html:ユニバーサルセレクター
<ul>
  <li><strong>ユニバーサルセレクター</strong>の場合、"*"を使う</li>
  <li><span>ユニバーサルセレクター</span>の場合、"*"を使う</li>
</ul>
```

6.グループセレクター：`$("#myId1", #myId3).css("color", "blue");`

```html:グループセレクター
<ul>
  <li id="myId1">IDセレクターの場合、","を使う</li>
  <li id="myId2">IDセレクターの場合、","を使う</li>
  <li id="myId3">IDセレクターの場合、","を使う</li>
</ul>
```


##まとめ
| セレクター | サンプル | 備考 |
|:-:|:-:|:-:|
|  要素 | $("li").css("color", "blue");  |   |
|  ID |  $("#myID").css("color", "blue"); |"#"を使う|
|  クラス |$(".myClass").css("color", "blue");|"."を使う|
|  子孫 |$(".myClass strong").css("color", "blue");|spaceを使う|
|  ユニバーサル |$(".li *").css("color", "blue");|"*"を使う|
|  グループ |$("#myId1", #myId3).css("color", "blue");|","を使う|
Python API通信時の例外処理 

仮想通貨の自動売買BOTを作成した際に、
取引所のAPIを利用したところ取引所側で頻繁にエラーが検知されるため
対策として例外処理を実装しました。
忘れないために自分用のメモとして残します。

## 例外処理とは
簡単に`サーバーエラー`などの対策です。
自分の書いたコードが正しい場合でも、実行時にエラーが発生することがあります。
例えば、外部サーバーにリクエストした時に、サーバーが混雑していたり、
一時的にメンテナンス中でサーバーが動いていない場合など、
レスポンス結果としてサーバーエラー(エラーコード)などが返ってきてしまいます。
特に自動売買BOTの様な自動で動く様なプログラムは
サーバーエラーが原因で毎回停止されてしまうと困ります。。。(もはや自動売買BOTではない)

対策として`try-except文`(例外処理)を記述することで予期せぬエラーを未然に防ぐことができます。


## HTTPステータスコード
リスクエストに対して正しいレスポンスが得られたかどうかというのはHTTPステータスコードで参照できます。
下記はHTTPステータスコードの一部で、大分類はこの様になっています。
私はよく500番台のエラーが返ってきていました。

- 100番台：処理中
- 200番台：成功
- 300番台：リダイレクト
- 400番台：クライアントエラー
- 500番台：サーバーエラー


```python:sample.py
response = requests.get("https://***********")
print(response.status_code)
```
HTTPステータスコードは上記コードの様に`レスポンスオブジェクト.status_code`で確認できます。
## try-except文
```python:sample.py
try:
    response = requests.get("https://***********")
    response.raise_for_status() # 
    print(response.status_code)
except requests.exceptions.RequestException as e:
    print("エラー : ",e)
```
`try:`部分に例外が発生する可能性があるが、実行したい処理を
`except:`部分に例外が発生したときの処理を記述。

上記のコードの場合、外部サーバーにGET方式でリクエスト通信をしレスポンス結果に対して
`raise_for_status()`メソッドでHTTPステータスコードを確認し200番台であれば`try:`部分のみ実行されます。
反対にHTTPステータスコードが200番台以外であれば例外が発生したとみなし
`except:`部分が実行されます。

`raise_for_status()`メソッドは、HTTPステータスコードが200番台か確認し、
200番台以外であれば、例外を起こす、つまりエラーを吐き出して停止します。

exceptは、`except 例外型 as 変数名:`という書き方をすることで、
変数に例外オブジェクト(エラーメッセージなど)を格納して使用することができる。
変数名は任意の名前を指定できるが、`e`や`err`と書くことが一般的である。
変数を出力することでエラーの内容を確認できる。
また例外型については「ライブラリ名　例外処理」、「ライブラリ名 error handling」などで検索すると
大抵の場合は知りたいことがしれます。


##else節
```python:sample.py
try:
    response = requests.get("https://***********")
    response.raise_for_status()
except requests.exceptions.RequestException as e:
    print("エラー : ",e)
else:
    print("正常に処理されました")
```
`else:`部分に、例外が発生せず正常終了したあとに行う処理を記述。
例外が発生し、`except:`部分が実行された場合は、`else:`部分は実行されない。

##finally節
```python:sample.py
try:
    response = requests.get("https://***********")
    response.raise_for_status()
except requests.exceptions.RequestException as e:
    print("エラー : ",e)
else:
    print("正常に処理されました")
finally:
    print("終了時に常に処理します")
```
`finally:`部分に、例外の発生に関わらず必ず最後に行いたい処理を記述。
`else:`と`finally:`を同時に使うこともできる。
正常終了時は`else:`の処理が実行されたあとに`finally:`の処理が実行される。
Apple Mach-O Linker Errorやlinker command failed with exit code 1で困ってる人へ

<br>
### 困っていた人、まさに私です。

# どうすりゃいいのよ？
とりあえず先人の知恵をかりましょう。
[【クソ食らえ】CocoaPodsとApple Mach-O Linker Errorとlinker command failed with exit code 1でどハマり](https://qiita.com/sussan0416/items/0a78042261ca3f0a7d91)

# 全部の項目は実施済みだけど治らないって？
キャッシュをきれいにしてみよう。
[React Native キャッシュの削除方法](https://qiita.com/sekitaka_1214/items/4f13400eabf7a4250700)

# それでも直らねーよ！
[ここ](https://stackoverflow.com/questions/26665196/ld-file-not-found-linker-command-failed-with-exit-code-1)のAnswerにある設定を試してみよう。

### 動きました。
やったね！

# 他の人のビルドはHost Applicationいじらなくても動いてるみたいだけど変更して大丈夫？

今のところ、ipaファイルを作って実機デバッグまでは問題ないです。
そのさきはまだ試してないです（誰か教えて）
【Python】アメリカ式の週番号の取得

# この記事の目的

週番号を取得しようとしていたときに, 
以下のような現象を確認したので, 原因と対策メモ

```python
import datetime
datetime.date(year=2017, month=1, day=1).isocalendar()

> (2016, 52, 7)
```
なんで2017年の元日が2016年なの！？

# 原因

次の記事によると, [Pythonで週番号を計算する](https://water2litter.net/rum/post/python_datetime_isoweekday/)

>ISO8601の週番号の定義
>    最初の木曜日を含む週を第1週とする. 週の始まりは月曜日. 
>アメリカ式の週番号の定義
>    1月1日を含む週を第1週とする. 週の始まりは日曜日.  

ということ. 
つまり```ISO8601```の形式だと, 上の結果で正しいみたい. 
しかし, 今回は```アメリカ式```の結果が欲しい...

# 対策

調べても, ```isocalendar()```を```アメリカ式```に変更する方法などは見つからなかったので, 自分でコードを書きました. 

2020/03/27追記：コードが間違っていたので修正しました.

```python
def american_calendar(year, month, day):
    #入力年のdatetime.date型データを作成
    inp = datetime.date(year=year, month=month, day=day)
    #入力年の元日のdatetime.date型データを作成
    first = datetime.date(year=year, month=1, day=1)

    #まず, 曜日の計算
    inp_how = (inp.weekday()+1) % 7 #+1は曜日を日曜始まりに変更するため
    first_how = (first.weekday()+1) % 7
    
    #以下, 週番号の計算
    #カレンダーの左上(最初の日曜日)の日付を取得
    upper_left = first - datetime.timedelta(days=first_how)

    #基準日との日数差を計算して週番号を取得
    inp_week = (inp - upper_left).days // 7
    
    return year, inp_week, inp_how
```

動作を確認すると

```python
american_calendar(year=2017, month=1, day=1)

> (2017, 0, 0)
```

希望通りの値を返してくれるようになりました. 

以上！

# 参考
某エンジニアのお仕事以外のメモ：[Pythonで週番号を計算する](https://water2litter.net/rum/post/python_datetime_isoweekday/)
Pythonドキュメント：[date.isocalendar()](https://docs.python.org/ja/3/library/datetime.html#datetime.date.isocalendar)
pandas.DataFrameへSeriesを列として代入する時には注意が必要

pandasのデータフレームにシリーズを追加しようとするとjoinに近い挙動となるので気を付けましょうという記事。

# まえおき
pandasでデータ処理を行なっているとき、データフレームに列を追加する処理は頻出です。
デーフレームに列を追加する時には大きく分けて二つのやり方があります。
1. 列名を指定して列追加
2. `pd.DataFrame.assign`メソッドで追加

**1. 列名を指定して列追加**

```python
df['new_col'] = data
```

**2. assignメソッドを用いて列追加**

```python
df.assign(new_col=data)
```

いずれの場合においても、値、サイズの等しいリスト・`np.array`・`pd.Series`などを渡すことができます。

# シリーズを代入したときに起こる直感に反した挙動
任意のデータフレームと、同じレコード数のシリーズを用意します。

```python
df = pd.DataFrame(
    [[1,2,3], [4,5,6], [7,8,9]],
    columns=['a', 'b', 'c'],
    index=[1,2,3]
)
sr = pd.Series([-1, -2, -3])

df
#   	a 	b 	c
# 1 	1 	2 	3
# 2 	4 	5 	6
# 3 	7 	8 	9

sr
# 0   -1
# 1   -2
# 2   -3
# dtype: int64
```

`df`に対して、新しい列`'d'`として`sr`のデータを追加したいとき、以下のようにすると思います。

```python
df = df.assign(d=sr)
```

このようなテーブルが作られることを期待します。

|   | a | b | c | d |
|:--|--:|--:|--:|--:|
| 1 | 1 | 2 | 3 |-1 |
| 2 | 4 | 5 | 6 |-2 |
| 3 | 7 | 8 | 9 |-3 |      

ところが実際はこのようなデータフレームが返ってきます。

|   | a | b | c | d |
|:--|--:|--:|--:|--:|
| 1 | 1 | 2 | 3 |-2 |
| 2 | 4 | 5 | 6 |-3 |
| 3 | 7 | 8 | 9 |NaN|

## 何が起こっているのか
改めてデータフレームとシリーズを見比べてみると、両者のindexが一致していません。
このようなデータでは、代入の場合においても結合のような挙動になっていることがわかりますね。

# 回避策
np.arrayとして渡すことで回避が可能です。

```python
df.assign(new_col=new_series.values)
```

補足：[公式ドキュメント](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.values.html)を見る限り、`values`メソッドより`to_numpy`メソッドを使用する方が推奨されるとのことです。
pandasの0.24にて追加された`ExtensionArary`をはっきりと区別するためにこのようになっているみたいですね。



# なぜこうなるのか

まず、`pd.DataFrame.assign`メソッドは、渡した値がcallableでない場合は、冒頭に示した1の処理が内部で呼び出されているだけです。したがって、今回のような現象はいずれの方法においても起こります。

（ちなみに「渡した値がcallableである」ときというのは、`lambda`式などでデータフレーム自身の列を呼び出す場合などが該当します。）[^callable]

`df['X'] = hogehoge`のように代入しようとすると、`pd.DataFrame.__setitem__()`が呼び出されます。コードをたどっていくと、以下のようなdocstringを発見しました。[^setitem]

```
        """
        Add series to DataFrame in specified column.
        If series is a numpy-array (not a Series/TimeSeries), it must be the
        same length as the DataFrames index or an error will be thrown.
        Series/TimeSeries will be conformed to the DataFrames index to
        ensure homogeneity.
        """
```

つまり、渡したデータが、

* データフレームとサイズの等しいnumpy-arrayである
    - そのままの並びで追加される
* Seriesである
    - そのindexがデータフレームのものと一貫性を保つように追加される

というように処理されると述べられています。
さらにコードを追ってみると、データが追加される前にデータフレームのindexに沿うように並び替えられていることがわかります。[^reindex]

今回の現象は、シリーズを配列と同じように考えてしまっていたのが原因でした。
下記のように、そもそもシリーズのサイズは加えるデータフレームのレコードと一致させる必要すらなく、リストや配列と全く別物であることもわかりました。

```python
df.assign(
    x=pd.Series([3], index=[2])
)
#  	 	a 	b 	c 	x
# 1 	1 	2 	3 	NaN
# 2 	4 	5 	6 	3.0
# 3 	7 	8 	9 	NaN
```

# まとめ
同じサイズの1次元データだからといって、リストや配列と同じようにデータフレームに追加しないようにしましょう。
シリーズをデータフレームの列に代入する場合は、サイズが異なる場合でもエラーにならずに処理が進んでしまうため、気づかぬうちにバグを生んでしまっている危険性が高まりそうです。必ずnumpy-arrayに変換して代入処理を行おうと自戒しました。

※この検証はpandas 1.0.3で行っていますが、以前のバージョンでも同様の挙動でした。


[^callable]: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.assign.html

[^setitem]: https://github.com/pandas-dev/pandas/blob/v1.0.3/pandas/core/frame.py#L2988

[^reindex]: https://github.com/pandas-dev/pandas/blob/v1.0.3/pandas/core/frame.py#L3599
【Ruby on Rails】Webpackerでcocoonを導入方法

cocoonを使うなら、jQueryが必要なので、WebpackerでjQueryを導入方法はこちらです：
[【Ruby on Rails】WebpackerでBootstrap、jQueryを導入方法](https://qiita.com/YutoYasunaga/items/9a7eaa0a4ca898535912)

```ruby:Gemfile
gem "cocoon"
```

以下のファイルをダウンロードして、`app/javascript/src/`に保存する。
https://github.com/nathanvda/cocoon/blob/master/app/assets/javascripts/cocoon.js

```javascript:app/javascript/packs/application.js
require("../src/cocoon");
```
N予備校を始めて20日間の成長記録

『N予備校を始めて10日間の成長記録』( https://qiita.com/Molly95554907/items/8f602badc11116084485 )の続きです。

プログラミングど初心者がN予備校を始めて10日経ちました！
３月２２日にN予備校３章をまで終えたけれども、それまでのアウトプットをまとめてやっていたら結構時間がかかってしまって、まだN予備校４章を始めれていない…。アウトプットはマメに（戒め

11日目（3/13）
○進捗
3章3節「集計処理を行うプログラム」を練習問題を除き終える（残業で勉強時間があまりとれず…）

○所感
３時間格闘してやっと軽くわかった程度なのでやばみ…。3章で難易度が一気に上がった気がする。
今までテキスト中心にやっていたけれど、詰まったらビデオを見る方向に切替え。ビデオの進度が割と速いので、0.8倍速とかが欲しくなる。
gitでブランチをクローンして、作業して、コミットして、プルリク送って…ってサイクルを何回も回して定着させられるところがありがたい。

○重要概念
<h5>連想配列</h5>
数字だけでなく、文字列も添字にできる。

・連想配列名.set('第一引数（key)', '第二引数(値)');
「set」でデータの追加ができる

・連想配列名.get('第一引数(key)');
「get」でデータの参照ができる。上の式を出力すると、
'第二引数'が返ってくる。

12日目(3/14)
○進捗
3章8節の途中まで。明日はHTTPサーバーのところまで行きたい！

○学んだこと
・csvのデータを分析する３項の内容が面白かった。データ分析の原始的なことができたような？
コンピュータサイエンスと歴史学を合わせた「人文情報学」と言う学問分野があると知る。歴史学畑出身なので、こういうの聞くとプログラミング学習にまた別の視点からのモチベーションが持てて面白い。

・gitの扱い方は２章でやったから完璧と思っていても、間違ったブランチをクローンしたり、「git checkout master-2019」を忘れてコミットでつまったりして勉強になった。やはり数をこなし実際に扱ってみないとマスターできない…！

・Hubotを用いたSlackbotの開発。便利と話題だけど使う相手がいないのでインストールしたことがなかったSlackをこの機会にさわれて嬉しい。
Hubotのプログラム制作では、「>hello」には反応するボットが、何故か「おみくじ」に反応してくれず詰まる。
質問を活用、答えて下さった方のアドバイスもみたけどすぐには解決できず寝かせていた…。なるはやで復習しよう。次こそ解決できるはず。

○重要概念
・Array.from(連想配列名）
連想配列を普通の配列に変化させる。

・Map関数
要素のそれぞれに指示ができるようになる。
例
[1,2,3]map((i)=> {return i * 2});
を実行すると、
[2,4,6]が返ってくる。

・オブジェクトのライブラリを確認するくせをつける、先人が作ってくれたライブラリを賢く活用する

13日目(3/15)
○進捗
3章11項の途中まで

○学んだこと
・try-catch文
テストの時に活躍する文。

try{}
catch('発生したエラー'){'エラー文。 fileName + 'から復元できませんでした''}

try-catch文とエラーメッセージのことを「例外処理」

14日目(3/16)
○進捗
N予備校、3章13項終了

○学んだこと
・HTTPのメソッドは全８種類。そのうち４つはCRUD（要件定義の時にも使う、Read,Cerate,Update,Deleteのこと）に対応している。

メソッド：
GET　：取得　：Read
Post: 追加　：Create
Put：　更新・追加　：Update,Create
Delete: 削除　：Delete

○疑問と課題
HTTPの理解を深める為に、Linux標準教科書と、HTTPの教科書を近いうちに読みたい
メソッドって詰まるところ何…？

15日目(3/17)
○進捗
N予備校、三章16項のほぼ終わりまで

○学んだこと
・パイプ関数
rs.pipe(res);

resはレスポンスのオブジェクト。
Node.jsでは、Sream形式のデータは「読み込み用Stream」と「書き込み用　Stream」をつないでデータを渡すことができる。
これを繋ぐのがパイプ関数。

・テンプレートエンジンに一つがpug
簡易的に、早く、とじカッコなしでHTMLが書ける。

・Herokuにデプロイ、H10エラーがでがち。
ローカルでは正しく作動しているか確認。
もう一度全てgitに上げ直す
Herokuの再起動

などが有効なエラー対策？？


16日目(3/18)
○進捗
N予備校１８章、Cookieまで

○学んだこと
Cookieに情報が残ることで、認証ができる。管理人の認証ができる。


17日目(3/19)
○進捗
N予備校、三章20項まで完了

○学んだこと
・Bootstrapの使い方解説がすごくサラッとだった。
どんなフォーマットを使いたいか探したり、それをどうやてローカル開発環境に持ってきたりするのかいまいちわからないのが残念。
自分で公式ドキュメントを読むのが一番かな？

18日目(3/20)
○進捗
N予備校２５項まで終了。
「スラスラ読める　JavaScriptふりがなプログラミング」、３章まで読む。基礎的な書籍を使って、今やってる勉強の足場がためがしたい。

○学んだこと
アプリを作る際は、要件定義と、何をどうファイルわけし運用するかが大切。
HTTPのファイルパスとそのモジュールの役割について、学べて良かった。

19日目(3/21)
○進捗
N予備校三章30項まで終了！

○学んだこと
自分で作ったアプリケーションをハッキングしてみて脆弱性を確かめる、という学習方法が面白かった。
実際の判例も扱っていたので実践的な教育だった。

20日目(3/22)
○進捗
N予備校三章３３項まで終了。
三章を完走！
Paizaに手を出すも、正規表現がよくわからなくてパイザチャレンジ失敗。node.jsを用いた正規表現について学んでから出直し予定。
「スラスラ読める　JavaScriptふりがなプログラミング」５章の途中まで読む。

<h5>20日を終えて</h5>
振り返って見ると、当時わからなかったことが、今ではもう慣れていること、
少しづつ仕組みがわかってきたもの等になってきているので、短期間ながらも成長を感じます。

1回目で完全に理解できなくてもいいので先に進めて、概要の理解に努めます。４章もがんばるぞー
[Rails]active_hash

#はじめに
現在個人で作成しているアプリで都道府県のデータをテーブルに持たせて使用していたのですが、調べたところ
どうやらactive_hashなる便利なものがあると知ったため、実際にその導入するまでを書きたいと思います。

#active_hash
gemをインストールすることで使用ができます。
モデルにハッシュでデータを持たせることで、そのデータをActiveRecordと同じような感覚で使えます。
つまり都道府県など静的データを扱う際、わざわざテーブルを作成する必要がなくなります。
便利ですね。

##Gemインストール
Gemfileに以下を記載して,bundle installをします。

````Gemfile.
gem 'active_hash'
````


##モデル作成

今回はLetterモデルとPrefectureモデルを作成し、Prefectureモデルに都道府県データを持たせます。
letterモデルには都道府県のデータを保存するカラムprefecture_idを作成します。

````
rails g model letter prefecture_id:integer  #letterモデル作成

rails db:migrate  #letterテーブルの作成
````


これでletterモデルは作成できました。
次にPrefectureモデルですが、これはテーブルを持たないためrails g modelで作成するのではなく、自分で作成します。
なおその際、ActiveHash::Baseを継承させます。
モデルを作成したら使用する都道府県のデータをハッシュの形で記述します。
すると以下のようになります

````app/models/prefecture.rb
class Prefecture < ActiveHash::Base
  self.data = [
      {id: 1, name: '北海道'}, {id: 2, name: '青森県'}, {id: 3, name: '岩手県'},
      {id: 4, name: '宮城県'}, {id: 5, name: '秋田県'}, {id: 6, name: '山形県'},
      {id: 7, name: '福島県'}, {id: 8, name: '茨城県'}, {id: 9, name: '栃木県'},
      {id: 10, name: '群馬県'}, {id: 11, name: '埼玉県'}, {id: 12, name: '千葉県'},
      {id: 13, name: '東京都'}, {id: 14, name: '神奈川県'}, {id: 15, name: '新潟県'},
      {id: 16, name: '富山県'}, {id: 17, name: '石川県'}, {id: 18, name: '福井県'},
      {id: 19, name: '山梨県'}, {id: 20, name: '長野県'}, {id: 21, name: '岐阜県'},
      {id: 22, name: '静岡県'}, {id: 23, name: '愛知県'}, {id: 24, name: '三重県'},
      {id: 25, name: '滋賀県'}, {id: 26, name: '京都府'}, {id: 27, name: '大阪府'},
      {id: 28, name: '兵庫県'}, {id: 29, name: '奈良県'}, {id: 30, name: '和歌山県'},
      {id: 31, name: '鳥取県'}, {id: 32, name: '島根県'}, {id: 33, name: '岡山県'},
      {id: 34, name: '広島県'}, {id: 35, name: '山口県'}, {id: 36, name: '徳島県'},
      {id: 37, name: '香川県'}, {id: 38, name: '愛媛県'}, {id: 39, name: '高知県'},
      {id: 40, name: '福岡県'}, {id: 41, name: '佐賀県'}, {id: 42, name: '長崎県'},
      {id: 43, name: '熊本県'}, {id: 44, name: '大分県'}, {id: 45, name: '宮崎県'},
      {id: 46, name: '鹿児島県'}, {id: 47, name: '沖縄県'}
  ]
end
````

##アソシエーションの定義
prefecture.rbに記述は必要ないのですがletter.rbにのみアソシエーションの定義をします。その際active_hashのbelongs_to_active_hashメソッドを使用して定義をします。そして、active_hashを使用するためextend ActiveHash::Associations::ActiveRecordExtensionsも追記します。すると以下のようになります。

````app/models/letter.rb
class Letter < ApplicationRecord
  extend ActiveHash::Associations::ActiveRecordExtensions
  belongs_to_active_hash :prefecture
end
````
これで使用できるようになります。
Prefectureモデルのテーブルはありませんがテーブルのデータを扱う感覚で以下のように書くことで使用することもできます。

````active_hash.html.haml
= f.collection_select :prefecture_id, Prefecture.all, :id, :name
````

#おわり
静的データのためにテーブルをもつ必要がなく、かつハッシュに格納したデータをテーブルのデータのように扱うこともできるという利点はとても魅力的ですよね。
最後まで読んでいただきありがとうございました。
Laravel-admin で アバターを非表示にする

#やりたいこと
Laravel-adminをいれるとデフォルトで管理者ユーザーにアバターが振られていて
しかも、管理者編集から画像を消そうにもデフォルトでセットされる

<img width="166" alt="スクリーンショット 2020-03-26 0.25.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174757/05f82875-6948-55dc-fac7-6884a9cc5a0a.png">

うざいので消します

#やりかた
下記のように管理者ユーザーテーブルのアバターはnullを許可されているので問題有りません

```php
 Schema::create(config('admin.database.users_table'), function (Blueprint $table) {
            $table->increments('id');
            $table->string('username', 190)->unique();
            $table->string('password', 60);
            $table->string('name');
            $table->string('avatar')->nullable();
            $table->string('remember_token', 100)->nullable();
            $table->timestamps();
        });
```

次に、`Administrator`という管理者のモデルをみると
下記のように`avatar`のアクセサが定義されているのですが
そこでnullだとlaravel-admin側で用意した画像を使うようになっています

```php:vendor/encore/laravel-admin/src/Auth/Database/Administrator.php
    /**
     * Get avatar attribute.
     *
     * @param string $avatar
     *
     * @return string
     */
    public function getAvatarAttribute($avatar)
    {
        if (url()->isValidUrl($avatar)) {
            return $avatar;
        }

        $disk = config('admin.upload.disk');

        if ($avatar && array_key_exists($disk, config('filesystems.disks'))) {
            return Storage::disk(config('admin.upload.disk'))->url($avatar);
        }

        $default = config('admin.default_avatar') ?: '/vendor/laravel-admin/AdminLTE/dist/img/user2-160x160.jpg';

        return admin_asset($default);
    }
```

なのでこいつを編集してやります
`app/Admin/Models/Administrator.php`を作成
中身をコピーし、下記のように書き換えます。また、一つ`getPlainAvatarAttribute`というアクセサを追加してやります。

```php

    public function getPlainAvatarAttribute()
    {
        return $this->getOriginal("avatar");;
    }

    /**
     * Get avatar attribute.
     *
     * @param string $avatar
     *
     * @return string
     */
    public function getAvatarAttribute($avatar)
    {
        if (URL::isValidUrl($avatar)) {
            return $avatar;
        }

        $disk = config('admin.upload.disk');

        if ($avatar && array_key_exists($disk, config('filesystems.disks'))) {
            return Storage::disk(config('admin.upload.disk'))->url($avatar);
        }

        $default = config('admin.default_avatar') ?: null;

        return admin_asset($default);
    }
```

その後`admin.php`の
`Encore\Admin\Auth\Database\Administrator::class,`となっているところを
`App\Admin\Models\Administrator::class,`に変更します

これだけだと、画面で画像ありませんマークがでてしまうので
view側もいじります。

`vendor/encore/laravel-admin/resources/views`を丸々コピーし
`resources/views/laravel-admin`というディレクトリを作成し格納します。

`app/Admin/bootstrap.php`に下記の一文を追加し、viewの参照を変更。

```php:app/Admin/bootstrap.php
app('view')->prependNamespace('admin', resource_path('views/laravel-admin'));
```

sidebarとheaderの修正をします

```html
@if(Admin::user()->plainAvatar)
<img src="{{ Admin::user()->avatar }}" class="img-circle" alt="User Image">
@endif
```

これで、きえました

<img width="1274" alt="スクリーンショット 2020-03-26 0.43.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174757/0694b7d6-2a95-5080-eee6-952390f08892.png">
【Ruby on Rails】WebpackerでFontAwesomeを導入方法

## Gemのインストール
必須ではないですが、Viewで`icon`メソッドを使うならば、Gemをインストールする必要です。

```ruby:Gemfile
gem "font-awesome-sass"
```

## FontAwesomeの導入
```
yarn add @fortawesome/fontawesome-free
```

```javascript:app/javascript/packs/application.js
import "@fortawesome/fontawesome-free/js/all"
```

```css:app/javascripts/src/application.scss
@import "@fortawesome/fontawesome-free/scss/fontawesome";
```

### [>>> FontAwesome free icons](https://fontawesome.com/icons?d=gallery&m=free)
pipenv + pyenv の開発環境でdjangoがインストールできない件


```
 pipenv --python 3.6
```
した後に

```
 pipenv install django
```
すると

```
 ModuleNotFoundError: No module named 'pip._internal.download'
```
とかが出て、インストールできない。
ちなみにpipenvのバージョンは

```
% pipenv --version
pipenv, version 2018.7.1
```

pipenvのバージョンが最新だとpyenvが使えないとのことだったので、わざと古いバージョンのものを入れていた。

■解決策
pipenvを最新のものに入れ直したらなぜか解決。

```
sudo pip3 install pipenv --force-reinstall
```
を実行するだけ。

理由はわからないがなぜか解決した。
推測だがインストールする順番が影響するのかも（？）
pipenv(最新版) → pyenv → pipenv（旧版）→ pipenv(最新版)
の順番だった。
自分の Qiita の投稿を markdown で全て手元に落とす

何らかの事情で Qiita に書いた自分の投稿は手元に残したいときのスクリプト

## 環境
- macOS 10.15.3
- zsh 5.8 (x86_64-apple-darwin19.3.0)

## 落とすやつ

```bash
❯ user_id=<your_qiita_id>
❯ curl -s "https://qiita.com/api/v2//users/${user_id}/items?per_page=100" \
  | jq -r ".[].url" \
  | xargs -n1 -I{} bash -c "curl -s  {}.md > \$(echo {} | awk -F / '{print \$NF}').md"
```

100記事以上投稿している場合は`&page=2` とかで遷移させればよさそう
https://qiita.com/api/v2/docs#%E3%83%9A%E3%83%BC%E3%82%B8%E3%83%8D%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3

## memo
何らかの事情が起きた時にこの記事が消える可能性もあるので dev.to にも投げた
https://dev.to/nekottyo/qiita-markdown-5dbp
【Ruby on Rails】WebpackerでBootstrap、jQueryを導入方法

## Webpackerのインストール

```ruby:Gemfile
gem "webpacker"
```

`bundle install`

```
rails webpacker:install
```

## Bootstrapの導入

```
yarn add bootstrap@4.3.1 jquery popper.js
```

```javascript:webpacker/environment.js
const { environment } = require('@rails/webpacker')

// ↓↓↓
const webpack = require('webpack')
environment.plugins.append(
    'Provide',
    new webpack.ProvidePlugin({
        $: 'jquery',
        jQuery: 'jquery',
        Popper: ['popper.js', 'default']
    })
)
// ↑↑↑

module.exports = environment
```

```ruby:app/javascript/packs/application.js
import "bootstrap"
import "../src/application.scss"

require("jquery")
```

```ruby:app/javascript/src/application.scss
@import "~bootstrap/scss/bootstrap";
```

```html:app/views/layouts/application.html.slim
html
  head
    == javascript_pack_tag "application"
    == stylesheet_pack_tag "application"
```

#### Webpacker導入後、data-remoteやdata-confirmが動かなくなった場合

```
yarn add rails-ujs
``` 

```javascript:app/javascript/packs/application.js
import Rails from "rails-ujs";
Rails.start();
```


#### Webpacker導入後、*.js.erbファイルが動かなくなった場合

```javascript:app/javascript/packs/application.js:

import $ from "jquery";
global.$ = jQuery;
```
5分でできる、Git For Windowsで、gccやobjdump (MinGW)使えるまでの方法

## 文章の目的
1.これは、私が以下の説明「https://qiita.com/pengincoalition/items/2bc1e0a80b114d6c49a6」 を読んでも、数々の勘違いによって、***構築に3時間かかってしまった憂さ晴らしに書く***
2. 誰かが同じように導入するときに、勘違いや思い込みを防ぐようにする。

## 読む対象
1. Windows環境で、bashOnWindowsを使って、C言語を書いたり、アッセンブリとしてみたい、という人。
2. bashに、`gcc`や`objdump`とコマンドを売ったら、"command not found"といわれてびっくりした人。
2. bashの知識やMinGWの構築の知識がに疎い人。


## 前提

1. bashOnWindowsを既に導入していること(私の場合は、GitForWindowsのbash.exe)
2. ***この方法は、bashのコマンドラインからのダウンロードを使わない。***bashをよく知らないなら、コマンドラインからダウンロードを挑戦すると、逆に時間がかかる。

## 1. まずは、mingw-get-setup.exeをダウンロードして、mingw-get-setup.exeで選択したパッケージをダウンロードをする。
1. 以上の詳細は、この記事に詳細に書かれています。「https://qiita.com/pengincoalition/items/2bc1e0a80b114d6c49a6」
2. 理解のポイント
    3. 「gcc」や「objdump」は、「mingw32-base」に***まとめられているexeファイルです。***
    4. よって、***「「gcc」や「objdump」は別々にダウンロードする」という心配は必要ありません***。このパッケージをダウンロードをすることで、これらは一気に獲得できます。

## 2. パスを通す。
1. パスの通し方は、いくつかあります。
    2. Windows側で設定する
        3. これは、先ほどのサイトで説明されています。「https://qiita.com/pengincoalition/items/2bc1e0a80b114d6c49a6」
    4. bashForWindowsの.bashrc設定する。
        5. bashのホームディレクトリにある`.bashrc`に書き込む方法があります。
       
```bash

export PATH=$PATH:/c/MinGW/bin/ 
```
EC-CUBE4 プラグインの作り方 ~ セットアップからインストールまで

## EC-CUBE4向けプラグインの作り方
プラグインは、`composer.json`だけあれば作れる。

まずは`MyPlugin`というフォルダを作って、その中に`composer.json`ファイルを入れる。

必要な設定項目は、name、version、desctription、codeのみ。他は固定。

`app/Plugin/MyPlugin/composer.json`

```json
{
  "name":"ec-cube/MyPlugin",
  "version":"1.0.0",
  "description":"my plugin",
  "type":"eccube-plugin",
  "require": {
    "ec-cube/plugin-installer": "~0.0.6"
  },
  "extra":{
    "code":"MyPlugin"
  }
}
```

## 作成したプラグインをインストールする
プラグインをインストールするにはコマンドラインを使うか、いったん圧縮して管理画面からインストールする。

```
// コマンドラインからインストール
bin/console eccube:plugin:install --code=MyPlugin

// いったん圧縮
cd app/Plugin/MyPlugin
tar --exclude  ".git" --exclude ".DS_Store" -cvzf ../MyPlugin.tar.gz *
```

インストール後はこんな感じ。

<img width="855" alt="plugin1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549249/8bf4ab30-2bfe-9c60-8f43-12f351dca5c9.png">
少し奇妙なPHPの不等号

ひょんな拍子に、PHPの不等号に関する恐ろしい事実を発見してしまいました。

## まずは穴埋め

```php
$a = (略);
$b = (略);

if($a < $b && $b < $a) {
  echo 'まさかこんなところには来ないよね';
}
```

実は、`$a < $b && $b < $a`という式を成立させてしまう方法が存在します。

## 配列の比較

ふつうの変数であれば比較基準は1通りなので、`$a < $b && $b < $a`なんていう事態に陥ることはないのですが、そうは問屋が卸さないのがPHPです。PHP標準で、**配列**にも比較基準を用意しています（[PHPマニュアル](https://www.php.net/manual/ja/language.operators.comparison.php)）。

* 配列の要素数が異なる場合、要素数が少ないほうが小さい
* 要素数が同じ場合、キーを順に比較していって中身の大小で比較する（同じキーがなければ判定不能）

そして、PHPの連想配列はキーの順序が保存される、ということで、「同じキーがあるけど順番の違う」配列を用意して比較を行えば、パラレルワールドに突入です。

## 実際にやってみた

```php
$a = ['foo' => 2, 'bar' => 5];
$b = ['bar' => 4, 'foo' => 3];

if($a < $b && $b < $a) {
  echo 'まさかこんなところには来ないよね';
}
```

[3v4lでの実行結果](https://3v4l.org/TH8on)

この場合、`$a < $b`では`foo`のキーが、`$b < $a`では`bar`のキーが先に比較されます。
NoSQLとは

# 他のデータベースと比べる

- Key Value Store
    - キーとバリューが対になっている
    - 例) ファイル、S3
- SQL
    - 表形式でのデータベース
    - 例) RDS
- NoSQL
    - 例) DynamoDB


| 一般的な名称       |       AWS |
|:-----------------|:------------------|
| Key Value Store  |              S3 |
| NoSQL            |            DynamoDB |
| RDB             |              RDS |


# NoSQL(DynamoDB)

## できること

- バックアップやリカバリが簡単
- 以下の型が取り扱い可能
    - 文字列
    - 整数
    - Set
        - 順番を期待しない&値はユニークでなければならない
        - 例) [1,3,5]
    - List
        - 順番を期待する&値はかぶってもよい
        - 例) [1,3,5,5]
    - MAP
        - 例) [A:1,B:2]
    - バイナリデータ
    - 値が欠けててもよい(NULLは入れられないのでメモリ自体存在しないイメージ)

## できないこと

- 集計、件数カウント
- スキーマ定義
- 入力必須項目の作成
- NULLのセット
- 日付型、BOOL型のセット
  
    プライマリーキーの役割が2つある
        パーティションキー
            1意制約あり
            データの更新などに使う
        ソートキー
            Index(日付け等、ある意味被ってもよい)

## キーの種類

- プライマリーキー
- パーティションキー
    - 更新, 削除に使用
- ソートキー
    - 表示順序に使用
- セカンダリーキー

# AppSync + DynamoDB

- できること
    - graphqlが利用可能になる
    - スキーマ定義
        - 例) 日付定義、入力必須項目の定義


# awsアーキテクチャパターン

- フロント(js + dynamoAPI with role/dynamo) => dynamo
- フロント(js + REST API + role/apigateway) => api gateway => dynamo
- フロント(js + REST API + role/apigateway) => api gateway => lambda(js + dynamoAPI + role/dynamo) => dynamo
- フロント(js + graphql API + role/apigateway) => api gateway => appsync(role/dynamo) => dynamo
Qiitaの退会方法まとめ

この記事も少ししたら見れなくなります。

### 1. 右上の自分のアイコンをクリックし、 `マイページ` を開きましょう
<img width="255" alt="スクリーンショット 2020-03-26 0.05.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520792/d1b313f6-4575-3fde-26fe-6f3faa29723c.png">

### 2. マイページが開いたら左上のカード部分の中央辺りにある `プロフィール編集` をクリック
<img width="397" alt="スクリーンショット 2020-03-26 0.15.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520792/df05370a-8961-6701-9039-45dc1d8b6226.png">

### 3. 左上の選択カードで `アカウント` をクリック
<img width="418" alt="スクリーンショット 2020-03-26 0.06.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520792/eeb317b8-0fbf-06b7-527c-e9750bff1fdc.png">

### 4. 一番下までスクロールし、 `アカウントを削除する` をクリックしましょう。
<img width="1228" alt="スクリーンショット 2020-03-26 0.06.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520792/1b5d92a5-82b7-11f8-f213-6cb86c01c98f.png">
Educational Codeforces Round 84 (Rated for Div. 2) B. Princesses and Princes

https://codeforces.com/contest/1327/problem/B

解くだけ問題。

# 概要
- n 人の姫と n人の王子ががいる
- 姫はそれぞれ結婚したい王子がk人おり、それをリストで持つ(順序性がある)
- 仲介人(王)は1番目の姫から順に、姫の王子リストを順に見て結婚を試行する
- 結婚の試行は王子がすでに結婚していた際に失敗し、次の王子との結婚を試行する
- 姫は結婚しない場合もある。(つまり王子も結婚しない場合もある)
- 全員が結婚したか判定し、そうでない場合は結婚していない姫と王子をの番号を示せ。

# こう考えた
問題が長く、ぱっと見、組み合わせ問題に見える。が、実は単に最も若い番号の王子と結婚を試みるためシミュレーション問題。

既に結婚したかのフラグを姫と王子でそれぞれでn個持っておき、各姫に対して、リストを頭から探索し、結婚できる王子がいれば結婚してフラグを立てる。

このフラグの数を姫か王子について数え、nであれば全員が結婚できている(つまりOPTIMAL)

そうで無い場合、結婚できていない人を1ペアでも出せば良い。つまり結婚したかのリストをOnで探索すれば良い。

# コード

```Python
import sys
input = sys.stdin.readline
from pprint import pprint
q = int(input())
for _ in range(q):
    n = int(input())
    target = []
    usedg = [0] * n # gen
    usedl = [0] * n # lady
    for i in range(n):
        l = []
        dat = list(map(int, input().split()))
        num = dat[0]
        for j in range(1, num + 1):
            dat[j] -= 1 # 0 origin
            if usedg[dat[j]] is 0:
                usedg[dat[j]] = 1
                usedl[i] = 1
                #print("marry", i, dat[j])
                break
 
    if sum(usedg) == n:
        print("OPTIMAL")
    else:
        print("IMPROVE")
        a,b = -1,-1
        for i in range(n):
            if usedl[i] == 0:
                a = i + 1
            if usedg[i] == 0:
                b = i + 1
        print(a,b)
```
https://codeforces.com/contest/1327/submission/74128020
Novaエディターを触ってみて

# Novaとは

**※Novaは2020/3/26現在ベータ版であり、この記事はあくまでベータ版のNovaを触った感想です**

**https://panic.com/jp/nova/**
<img width="892" alt="スクリーンショット 2020-03-25 23.04.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213719/616e68c7-b588-af69-1614-5b4a240df466.png">

Codaというエディターをご存知でしょうか。

https://panic.com/jp/coda/

HTMLコーダー界隈だと有名っぽく？（僕はITエンジニア界隈の人間なので、実際に有名かどうかはわかりません）、Macネイティブで動く、良さげな雰囲気をまとったエディターでした。

Codaはそこそこ古いエディターで、なおかつ数年前にPanicがCodaの名称をほかの会社に譲ってしまいました。そこで別のエディターを開発すると宣言したのが昨年ぐらい。その結果産まれたのがNovaです。

https://panic.com/jp/nova/

ベータテスターの募集が始まったときに応募していたのですが、昨日ようやくベータテスターになれました。（2020/3/25現在、ベータテスターの募集は閉めているようです）

# どんな感じのエディターなのか

## 良さげな雰囲気をまとっている

<img width="1050" alt="スクリーンショット 2020-03-25 23.15.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213719/ef8ace98-0cb9-f80f-8da3-3c1f1b077148.png">

前身？のCodaに続き、すごく良さげな雰囲気をまとっています。上のスクリーンショットで使っているのは**Neon**テーマというものなのですが、すごいです、文字が光ってます。

<img width="330" alt="スクリーンショット 2020-03-25 23.16.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213719/9fafe57d-dd74-8b28-491f-35dcab4aa72a.png">

うわーネオンだ！文字がネオンだ！

…まぁ実際文字が光ることが生産性にどのくらい寄与するかは不明ですが、個人的に好きです。光り物大好き。

あとはとにかくMacネイティブであることを意識してると思うので、動作が軽いです。スクロールがスムーズです。

## 最低限の機能はある

軽く小一時間触った感じ、現代のエディターに求められる最低限の機能は備えているように感じます。

- ファイルブラウザ
- 色んなプログラミング言語に対応したシンタックスカラーリング
- 柔軟な検索
- プロジェクト機能
- ミニマップ
- 拡張機能作成
- アプリ内ターミナル
- コーダーさん向けのもろもろ
    - サーバーへのアップロードとか
    - プレビューとか

普段VSCodeを使っているので、正直やはり足りないと感じる機能は多いです（特にコード補完周りはまだまだかなと。もちろんまだベータなので今の時点で評価を下すべきではないです。）ただ、Coda2に比べると大幅に使いやすくなったなという感じはかなりありました。

## 拡張機能がJSで書ける

個人的にはこれが一番大きい発展ですね。Coda2のときは基本ネイティブで書かないといけなかったはずで（一部スクリプトで書くこともできたのかな？）、サンプルもObjCしかなくて辛いなぁという感じだったのですが、NovaはJSで拡張機能を書けます。やったね。

https://novadocs.panic.com

ただし、JSが動くランタイムはNode.jsではないらしく（なんでやねん）、Node.jsのAPIは使えません。じゃあNPMとか全滅や…と思ったんですが、下のドキュメントを読む限り、NPMのライブラリを拡張機能内に別途インストールして、それをプロセスとして叩くことで起動してください、ということのようです。

https://www.notion.so/Using-NPM-Packages-in-Nova-Extensions-1dbbd0be3a63456fb1d3490b4006a562

https://dev.panic.com/ashur/nova-npm-executable

なるほどな…という気持ちです。ただ個人的にはNode.jsがそのまま動いて欲しかった。

## 全体的にはCodaの方向性と合わせてそう

あくまで想定しているユーザーはCodaでHTMLコーディングしていたユーザーなのかなという感じがします。ただ、拡張機能のエコシステムが成熟して、色んな言語を使えるようになれば僕のようなITエンジニアでも仕事で使えるかもしれません。何れにせよ、まだベータなので今後に期待です。

## 期待します

Codaは仕事で使うことはほぼなかったのですが、UIの作り込みが好きでプライベートではなんとかがんばって使おうとしていた時期もありました。ただ、拡張機能の作り方が難しく、そのエコシステムが広がりにくい→有用な拡張機能があまり出てこない→ユーザーがあまり増えないという状況になっていたかなと思います。（個人的な観測）

今度はJSで拡張機能が書けるので、拡張機能を作れるユーザーが増える→有用な拡張機能が増える→Novaユーザーが増える、という良い流れになっていくような気がしてます。

そうなれば、VSCode一強のここ最近のエディター界隈で、存在感を出せるのではないかなと、だいぶ上から目線で申し訳ないですが、思ったりします。

とりあえず、自分も何か拡張機能を作ってみたいと思います。それでは。
CloudFormationでECSタスクのスケジュールに異なる複数の実行時間を指定したい

# やりたいこと

CloudFormationでECSのタスクスケジュール定義をしたい。
時・分ともに異なる複数の実行時間を指定したい。
例えば毎日7:45と13:50に実行されるように指定したい。

### 1つのcron式だとうまく収まらない
`cron(45 07 * * ? *)`
これだけだと7:45だけになっちゃうし
`cron(45,50 07,13 * * ? *)`
これだと7:45,7:50,13:45,13:50に実行されちゃうし

crontabだと2行に分けて書いているけど
CloudFormationではどう書くの？？？
もしかしていいかんじに1行で書けたりする？？？
と悩んだのでメモしておきます。

*※これのScheduleExpressionの指定の話です*
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-events-rule.html


# まず結論

ワンライナーでがんばるとこじゃなかったっぽい。
無理せずcfnのTaskSchedule部分の定義を7:45実行回分と13:50実行回分のそれぞれ書きます。

# 書き方
cfnでのecsタスクの定義は
どんなecsタスクかを定義する `AWS::ECS::TaskDefinition` の定義があり、
そしてそれをいつ実行するかを定義する `AWS::Events::Rule` の定義があります。
ここではその後者の定義だけ抜粋します。


```sample.yml

Resources:

# 抜粋

  TaskScheduleHoge:
    Type: AWS::Events::Rule
    Properties:
      Name: task_schedule_hoge
      State: ENABLED
      ScheduleExpression: cron(45 07 * * ? *)
      Targets:
        - Id: task_schedule_hoge
          Arn: !GetAtt Cluster.Arn
          RoleArn: !Sub arn:aws:iam::${AWS::AccountId}:role/ecsEventsRole
          EcsParameters:
            TaskDefinitionArn: !Ref taskDefinition
            TaskCount: 1
            LaunchType: FARGATE
            PlatformVersion: LATEST
            NetworkConfiguration:
              AwsVpcConfiguration:
                AssignPublicIp: DISABLED
                SecurityGroups: !Ref ServiceSecurityGroup
                Subnets: !Ref Subnets

  TaskScheduleHuga:
    Type: AWS::Events::Rule
    Properties:
      Name: task_schedule_huga
      State: ENABLED
      ScheduleExpression: cron(50 13 * * ? *)
      Targets:
        - Id: task_schedule_huga
          Arn: !GetAtt Cluster.Arn
          RoleArn: !Sub arn:aws:iam::${AWS::AccountId}:role/ecsEventsRole
          EcsParameters:
            TaskDefinitionArn: !Ref taskDefinition
            TaskCount: 1
            LaunchType: FARGATE
            PlatformVersion: LATEST
            NetworkConfiguration:
              AwsVpcConfiguration:
                AssignPublicIp: DISABLED
                SecurityGroups: !Ref ServiceSecurityGroup
                Subnets: !Ref Subnets
```

実行するのは同じ内容のECSタスクなのでTarget部分に書く内容が繰り返しになるのが気になるものの、cfnを実行した結果、スケジュールがそれぞれ登録できていることを確認しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210788/28555197-1db4-8412-5f1c-2fab53d12db6.png)

# おまけ
YAMLのハッシュのマージなど活用すれば重複して書いているところももっとすっきりするかなと思ったのですが、やってみたところ

`An error occurred (ValidationError) when calling the CreateChangeSet operation: Template error: YAML aliases are not allowed in CloudFormation templates`

というエラーが出たのでやはりこつこつ書くしかないのかなと思います。

# 参考
- [ECS(Fargate)のバッチをCloudFormationで作成する](https://qiita.com/yktakaha4/items/f5a32d5f2e7a6263faa4)　👉　今回抜粋したECS定義の全体的な話はこちら
- [公式ドキュメント　AWS::Events::Ruleについて](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-events-rule.html)
【今日のアブストラクト】 NLNL: Negative Learning for Noisy Labels【論文 DeepL 翻訳】

1 日 1 回 論文の Abstract を DeepL 翻訳の力を借りて読んでいきます.

この記事は自分用のメモみたいなものです.
ほぼ [DeepL](https://www.deepl.com/home) 翻訳でお送りします.
間違いがあれば指摘していだだけると嬉しいです.

翻訳元
[NLNL: Negative Learning for Noisy Labels](https://arxiv.org/abs/1908.07387)

# Abstract

### 訳文

畳み込みニューラルネットワーク (CNNs)は, 画像分類に用いると優れた性能を発揮する. 従来の CNNs の学習方法は, "入力画像はこのラベルに属する" (正の学習 (Positive Learning); PL) のように, 教師付きの方法で画像にラベルを付ける方法であり, ラベルがすべての画像に正しく割り当てられていれば, 高速かつ正確な学習が可能である. しかし, 不正確なラベルやノイズの多いラベルが存在する場合, PL を用いた学習は間違った情報を提供してしまい, 性能を著しく低下させる. この問題に対処するために, 我々は負の学習 (Negative Learning) (NL) と呼ばれる間接的な学習方法から始める．NL は補ラベルとして真のラベルを選択する可能性が低いため, 誤った情報を提供するリスクを減らす. さらに, 収束性を向上させるために, PL を選択的に採用することで手法を拡張する. PL を選択的に用いることで, NL の進行に伴ってその選択が可能となり, ノイズの多いデータのフィルタリングに優れた性能を発揮する. 簡単な半教師付き学習手法を用いて, ノイズデータの分類に対して最先端の精度を達成し, SelNLPL のノイズデータフィルタリング能力の優位性を証明した.


### 原文

Convolutional Neural Networks (CNNs) provide excellent performance when used for image classification. The classical method of training CNNs is by labeling images in a supervised manner as in "input image belongs to this label" (Positive Learning; PL), which is a fast and accurate method if the labels are assigned correctly to all images. However, if inaccurate labels, or noisy labels, exist, training with PL will provide wrong information, thus severely degrading performance. To address this issue, we start with an indirect learning method called Negative Learning (NL), in which the CNNs are trained using a complementary label as in "input image does not belong to this complementary label." Because the chances of selecting a true label as a complementary label are low, NL decreases the risk of providing incorrect information. Furthermore, to improve convergence, we extend our method by adopting PL selectively, termed as Selective Negative Learning and Positive Learning (SelNLPL). PL is used selectively to train upon expected-to-be-clean data, whose choices become possible as NL progresses, thus resulting in superior performance of filtering out noisy data. With simple semi-supervised training technique, our method achieves state-of-the-art accuracy for noisy data classification, proving the superiority of SelNLPL's noisy data filtering ability.
誤差逆伝播法(バックプロパケーション)

#3日目
##誤差逆伝播法(バックプロパケーション)
今日は少し時間がなかったので、NeuralNetworkの一歩手前の実装までをやろうと思います。

1日目に実装したロジスティック回帰分析では線型的な回帰が得意でしたが、非線形のものはうまく対応できません。
そんなときに、ニューラルネットワークであれば、XORなどの非線形でも回帰することができます。

この分野は機械学習にめっちゃ入ってくるので、バイアスについての明確な根拠がありません。目的に合わせて、バイアスは変化させたり、固定したりします。

##モデル
今回は2入力、中間１層、出力の3層で作っていきます。

イメージはロジスティック回帰と同じで、それの組み合わせのようなものです。

##誤差関数
```python:誤差導出
'''
入力 : x1,x2
隠れ層 : O1,O2
出力 : Output
誤差 : Error
バイアス : b
重み : w[どの層, どこから, どこへ]
E = (y - Output)^2
'''
#Forward Propagation
Z1 = b11 + x1*w111 + x2*w121
Z2 = b12 + x1*w112 + x2*w122

O1 = Sig(Z1)
O2 = Sig(Z2)

Z = b21 + O1*w211 + O2*w221

Output = Sig(Z)

Error = (y - Output)**2
```
##微分してバイアスを調節
```python:バイアス調整
#differential
dw111 = 2*(y - Output)*Sig(Z)*(1 - Sig(Z))*Sig(Z1)*(1 - Sig(Z1))*x1
dw121 = 2*(y - Output)*Sig(Z)*(1 - Sig(Z))*Sig(Z1)*(1 - Sig(Z1))*x2
db11 = 2*(y - Output)*Sig(Z)*(1 - Sig(Z))*Sig(Z1)*(1 - Sig(Z1))
dw112 = 2*(y - Output)*Sig(Z)*(1 - Sig(Z))*Sig(Z2)*(1 - Sig(Z2))*x1
dw122 = 2*(y - Output)*Sig(Z)*(1 - Sig(Z))*Sig(Z2)*(1 - Sig(Z2))*x2
db12 = 2*(y - Output)*Sig(Z)*(1 - Sig(Z))*Sig(Z2)*(1 - Sig(Z2))
dw211 = 2*(y - Output)*Sig(Z)*(1 - Sig(Z))*O1
dw221 = 2*(y - Output)*Sig(Z)*(1 - Sig(Z))*O2
db21 = 2*(y - Output)*Sig(Z)*(1 - Sig(Z))

#Gradient Descent / Steepest Descent
w111 -= alpha(dw111)
w121 -= alpha(dw121)
b11 -= alpha(db11)
w112 -= alpha(dw112)
w122 -= alpha(dw122)
b12 -= alpha(db12)
w211 -= alpha(dw211)
w221 -= alpha(dw221)
b21 -= alpha(db21)
```

##コード
[day3.py](https://github.com/HinataAoki/Everyday-AI-life/blob/master/day3.py)

##3日目も終了！
今日は少し忙しかったですが、一応最低限のことができました！
こんな感じですこしでもキャッチアップできるといいのかなと思います
Udemyにはお世話になってます。感謝です。
-これからポートフォリオを作成する方へ-　使用したrails newを実行時のオプションを紹介

railsチュートリアルで学習した後にポートフォリオの作成に当たる方も一定数いらっしゃるかと思います。そこで、railsチュートリアルと評価されやすいポートフォリオの差を比較し、不要なファイルを生成しないためのrails_new実行時のオプションを紹介します。

#●railsチュートリアルと異なる点
###1.データベース
railsチュートリアルでは、特にデータベースの設定を行わず、デフォルトのまあSQliteを使用しています。
しかしポートフォリオを作成する際には、何らかのデータベースを選択し設定するかと思います。（MySQLかPostgreSQLが良いと思います。）

そこで実行すべきコマンドが下記です。

```ruby
rails new アプリケーション名 -d データベース名
```
これにより使用するデータベースを任意の物に設定することができます。
もちろん後からでも変更できますが、工数を削減することができます。

### 2.テスト
railsチュートリアルではminitesを使用していましたが、ポートフォリオして評価されるのであればRspecでテストを実装する必要があります。

そこで実行すべきコマンドが下記です。

```ruby
rails new アプリケーション名 -T
```

これによりminitestの作成をスキップできます。そしてrspecも自動生成ファイルを調整することができます。

```ruby:config/application.rb
require_relative 'boot'
require 'rails/all'

Bundler.require(*Rails.groups)

module アプリケーション名
  class Application < Rails::Application
    config.load_defaults 5.1

    # 省略

    config.generators do |g|
      g.test_framework :rspec,
       fixtures: false, # テストDBにレコード作成するファイルの作成をスキップ（初めだけ、のちに削除）。
       view_specs: false, # ビューファイル用のスペックを作成しない。
       helper_specs: false, # ヘルパーファイル用のスペックを作成しない。
       routing_specs: false # routes.rb用のスペックファイル作成しない。
    end
  end
end
```

詳細な設定方法は下記を参考に実装すると良いです。
[Everyday Rails - RSpecによるRailsテスト入門](https://leanpub.com/everydayrailsrspec-jp/read)

少し情報が古い点もありますが、とても参考になります。
具体的にはcontroller_specやfeature_specは現在あまり使用されておらず、request_specやsystem_specを使用されています。詳細はここでは省略させて頂きます。

#●まとめ
面倒に感じますが、初期設定をしっかりと整えることでトータルで見ると工数をかなり減らすことができ、おすすめです。
Windowsでpythonを実行してもMicrosoft Storeが開いてしまう時の対処法

## はじめに

会社で使用しているwindowsにpythonをインストールしたところ、
powershellなどでpythonコマンドを実行しても、Microsoft StoreのPythonページが開いてしまうという問題に遭遇しました。
この問題は、[python.org](https://www.python.org/downloads/windows/)のインストーラを使用して、インストールの途中で「Pathに追加」オプションを選んだ場合は発生しないようです。
ただ、選択せずにインストールしてしまった場合、正しい手順を踏まないとpythonコマンドを使えないので、備忘録として残しておきます。

## 手順
pythonのインストール自体は終わっている前提です。

### 1.  python実行ファイルのpathを確認する
スタートボタン横の検索窓から、「python」と入力し、表示されたpythonのコマンドラインアプリの選択肢から、「ファイルの場所を開く」を選択します。
ファイルエクスプローラが開き、pythonがインストールされた場所が表示されるので、インストールされた場所のパスをコピーします。

### 2. 環境変数にpathを追加する

[参考 : [環境変数PATHを設定する](https://www.javadrive.jp/python/install/index3.html)]などを参考に環境変数にpathを追加してください。

### 3. アプリ実行エイリアスからpythonを見つけてオフにする
スタートボタン横の検索窓から、「アプリ実行エイリアス」と入力し、表示された「アプリ実行エイリアスの管理」を選択します。
「アプリ実行エイリアスの管理」に表示された、python.exeとpython3.exeの項目をOFFにします。

## 参考
* [Windows での Python の使用についてよく寄せられる質問](https://docs.microsoft.com/ja-jp/windows/python/faqs)
* [環境変数PATHを設定する](https://www.javadrive.jp/python/install/index3.html)
Alfred4 + emoj｜Alfred4で簡単に絵文字が入力できるらしい！→alfred-emojiに変更

Alfred4で簡単に絵文字が入力できるらしい！

しかも無駄にディープラーニングやってるとか（alfred-emoj）

　↓

違うワークフロー（alfred-emoji）に変更
こっちのほうが新しい、インストール簡単、使い方もわかりやすい


## やったこと

- Alfred4インストール、PowerPack登録
- Node.jsのインストール
- npm -g install xxxに失敗するので、npmのデフォルトディレクトリを作成する
- alfred-emojのインストール
- Alfred Preferences > Workflows > Emoj > Copy to Clipboard > [x]Automatically paste to front most app

これはおもしろい！😆

　↓

- aflred-emojiのインストールに変更
- 


## 参考リンク
Alfred3 おすすめワークフロー 7選 + 1
https://qiita.com/ryo2132/items/ef392999d32732fa0455

alfred-emoj
https://github.com/sindresorhus/alfred-emoj?ref=producthunt

Node.js®
https://nodejs.org/en/

【備忘録】npm -g install に失敗する
https://qiita.com/NaokiIshimura/items/cc07441939b226e779c6

　↓

【Mac向け】よく使うAlfred Workflowを晒してみます【絵文字入力、FontAwesomeアイコン検索、エンコード/デコード、数値の基数変換】
https://blog.ttskch.com/mac-alfred-workflow-introducing/

alfred-emoji
https://github.com/jsumners/alfred-emoji
研究室のサーバを自宅から使えるP2P型VPNの紹介

# はじめに

大学や職場からロックアウトされて、自宅で研究開発をしている人も多いのではないかと思います。
自宅にはノートPCしかなく、研究室のGPUを搭載したハイスペックなサーバを遠隔でよいので使いたい、、、ということも多いと思うので、それを可能にするP2P型のVPN（zerotierとtailscale）を紹介します。

# 注意

この文書では、「UDPパンチホーリング」を使ったP2P型のVPNを紹介します。特に大組織では、**セキュリティポリシーとしてP2P型のVPNの利用が禁止されている場合もあります**。使う前に確認しておきましょう。

# 通常のVPN

通常のVPNでは、VPNゲートウェイにグローバルIPアドレスを割り当てる必要があります。しかし、大学の研究室のように組織全体でNATが設置してあると、グローバルIP上でゲートウェイを公開できません。

![Normal VPN](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8035/e942a17a-54ba-bc9e-a694-31c3a0fea278.png)

# P2P型のVPNとは？

P2P型のVPNは、VPNクライアントだけでなくサーバもNATの下に設置して直接通信できる「**NAT越え**」の機能が備わっています。

![NAT Traversal](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8035/8401427c-f964-e517-e2b2-f9aed80012f4.png)

P2P型のVPNはNAT越えを実現するために「UDPパンチホーリング」という技術を使います。

NATはパケットを通過させる際にパケットのヘッダに格納されたクライアントのポート番号を書き換え、その対応をしばらく記憶しています。これによって、NATの下に複数のクライアントがあった場合でも、各クライアントが同時に外部のサーバと通信できるのです。

UDPパンチホーリングでは、まず、NATの下に接続されたクライアントとサーバが、仲介サーバに対してUDPパケットを送ります（図中①）。
仲介サーバ上では、クライアントとサーバの変換後のポート番号が見えるので、それをそれぞれに教えてあげます。
クライアントは、サーバの変換後のポート番号に対してパケットを送ります。すると、NATでパケットが逆変換されて、NATの下にあるサーバに対してパケットが直接届きます(図中⑤)
。

![P2P VPN](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8035/8dde8370-f10f-912c-7dc7-53e1e7922454.png)

P2P型のVPNでは、その後、仲介サーバに登録されたサーバの公開鍵を使って、クライアントからサーバに暗号化鍵を送ります。この暗号化鍵は、UDPパンチホーリングを使って直接送られるだけでなく、公開鍵を使って暗号化されているため、秘密鍵を持ったサーバにしか復号化できません。
この鍵を使って「エンドツーエンド暗号化」が行われるため、通信の秘密は仲介サーバからも守られます。

以下、P2P型のVPNサービスを2つ紹介します。

# ZeroTier

https://zerotier.com/

P2P型VPNの定番サービスです。有料オプションもありますが、ほとんどの機能を無料で使うことができます。

## つかいかた

1. My ZeroTier（ https://my.zerotier.com/ ）を開いてアカウント登録する。Google Accountを使ってアカウント登録するのがおすすめです（Google Accountには二要素認証を設定しておきましょう）。
2. 「Networks」>「Create a Network」をクリックして、ネットワークを作成する。ネットワークを作成するとIDが表示されるのでコピーしておく。
3. ダウンロードページ（ https://www.zerotier.com/download/ ）から、各OS用のクライアントをダウンロードしインストールする。
4. WindowsやOSXではGUI上で「Join Network」をクリックして、2でコピーしたネットワークIDを入力してください。Linuxでは、コマンドライン上で`sudo zerotier-cli join [ネットワークID]`と入力します。
5. **[重要]** この時点では、まだネットワークに接続されていません。My Zerotier（ https://my.zerotier.com/ ）を開いて「Networks」>「Joinしたネットワーク」をクリックして、下の方にある「Members」にクライアントが表示されていることを確認し、**「Auth?」チェックボックスをチェック**してください。

「Members」の「Managed IPs」に表示されているIPアドレスが各クライアントのIPアドレスです。sshなどを使って接続してみましょう。

ネットワークIDがあれば、複数のPCを同一のネットワークに所属させることができます。IDを皆に共有して研究室のネットワークを作ってしまいましょう。

# tailscale

https://www.tailscale.com/

2020年4月に公開されたP2P型VPNの新星です。

暗号化プロトコルとしてWireGuardプロトコルを使っており、非常に高速で安定した接続を実現しています。

## つかいかた

以下のページを参照してください。tailscaleには非常に良くできたGUIが付属しており、説明なしで使えると思います。

https://www.tailscale.com/kb/1017/install


# おわりに

P2P型VPNで快適な在宅研究ライフを！
musdb18　ダウンロードメモ

#musdb18をダウンロードする

##musdb18とは

音源のデータセット,学術目的に限り使用可能。
[MUSDB18]()
[ダウンロードページ](https://zenodo.org/record/1117372#.XpXEnvj7Q2w)



>musdb18 は、異なるジャンルの150のフルレングスの音楽トラック（10時間程度）を、孤立したドラム、ベース、ボーカル、その他のステムと一緒に収録したデータセットです。
musdb18には2つのフォルダがあります。100曲で構成された "train "とテストセットのフォルダです。50曲で構成された "test "というフォルダがあります。教師付きアプローチは、トレーニングセットで訓練し、両方のセットでテストする必要があります。
すべての信号はstereophonicで、44.1kHzでエンコードされています。
[deeplで翻訳]

##ダウンロード方法

1. HPの「Download MUSDB18 (4.4 Gb)」をクリック
2. 遷移先のページの下，「Request access」をクリック
3. 入力フォームに名前，メアド，使用したい理由を書く
4. 送信する
5. メールがくるのでリンクを押す。
6. その後認証完了メールがくる。
7. メールのリンクを押すとページがダウンロードページが変わっていて，zipファイルをダウンロードする項目が増えている
8. クリックすれば，ダウンロードできる


##注意書き

- 手動で認証していると書いてあった。
- リクエストを短時間に何回おくっても意味ないらしい。

自分用のメモをシェアしています。ダウンロードするときは自己責任でお願いします。

#その他のリンク

- [MUSDB18の使い方を紹介したGoogle Colab](https://colab.research.google.com/drive/1Zo6iSPIi6SjOAL7wg8yzVWkS9mjLgjI-)
[覚書] MVVM の定義

## はじめに

忘れないように戒めの覚え書き。

以下、すべて独学のオレオレ MVVM で、原理原則から逸脱している部分もあるはず...
あくまで個人的にはですが、使えるなら細かい定義は気にしない考えでいます。

## 本文

### MVVM とは

"Model", "View", "ViewModel" の頭文字をとって "MVVM" で、描画ロジックとビジネスロジックを切り分けるための手法の一つです。WPF や UWP など最近の Microsoft の開発プラットフォームでは、このデザインパターンの適用を前提としているようです。

※それ以前の Windows Forms などではイベントドリブン方式が推奨されていました。ロジック同士が癒着しがちですが、努力である程度は解消でき、直感的なコードになるため追いやすい点が長所だと思います。

| 階層 | 依存関係 | 役割 |
|---|---|---|
| Model     | -                | データを保持するオブジェクトと単体で動作する処理 |
| ViewModel | Model            | 画面に表現されるデータの実体とコマンド |
| View      | ViewModel, Model | ViewModel, Model が保持するデータの表示と機能の提供 |

![The MVVM classes and their interactions](https://docs.microsoft.com/en-us/previous-versions/msp-n-p/images/gg405484.333d7f906287fb8887d43c85a4a8fc08%28en-us%2cpandp.40%29.png)
 出典：Prism 5 - Developer's Guide to Microsoft Prism Library 5.0 for WPF

### Model

独立したデータや単体で動作するロジックが置かれる層です。
DAO やエンティティや API コマンドなど、ビジネスロジックを構築するうえで必要になる要素を納めます。そのほかコネクション確立や API 通信をサービスクラスとして独立させ置いたりもしています。

### ViewModel

UI に表現されるデータや実行されるコマンドの保管庫となる層です。
原則として、ViewModel は Model を参照しますが、View を直接参照してはいけません。どのように描画するかは View に任せる格好になります。もちろん View を意識した実装になることは問題ありません。描画ロジックが割り込まないため、単体テストの自動化がしやすくなります。

怒られるかもしれませんが、上記の原則を守っていれば実装に制約はないと考えています。ViewModel はウィンドウと１対１になる場合もあれば、ウィンドウ内の登録フォームや検索条件欄に対応する場合もあります。ただし ViewModel は幅を利かせ過ぎて肥大化することもしばしばです。Model と作業分担するなり、汎用処理はサービス化するなり工夫が必要です。

### View

ウィンドウやユーザーコントロールが配置される所謂 UI 層を指します。
ViewModel で宣言されたプロパティやコマンドをバインド（紐づけ）させて機能を実装していきます。ロジックは一切書かないのか？といえば決してそうではなく、フォーカス制御やアニメーションなどの描画ロジックはこの層に記述します。

View を語るうえでいつも議論になるのが「コードビハインドでの実装を許すかどうか」という問題で、無理せずに解禁して良いというのが私の考えです。原理原則を貫くことは大切ですが、それによって極端に複雑化する場合は、分かりやすさを優先したいです。（なんでもここに書いて良いとは言ってません！）


## おわりに

MVVM の定義と各層の役割をまとめました。
このデザインパターンに当てはめるのは、初めてでは結構キツイと思われます。とりわけイベントドリブンに慣れていると、その経験が悪い意味の先入観をもたらし、習得をより難しくさせます。
しかしながら、構築を補助するフレームワークも存在しており、以前に比べれば実装のハードルは下がってきていると感じます。実装方法がつかめれば、ロジックの分離による開発やテストの容易さなど、徐々に恩恵が受けられるようになっていくでしょう。

---

とりあえずここまで。
細かい要素とか MVVM フレームワークとか DI については別の機会で。
【今日のアブストラクト】A Metric Learning Reality Check【論文 DeepL 翻訳】

1 日 1 回 論文の Abstract を DeepL 翻訳の力を借りて読んでいきます.

この記事は自分用のメモみたいなものです.
ほぼ [DeepL](https://www.deepl.com/home) 翻訳でお送りします.
間違いがあれば指摘していだだけると嬉しいです.

翻訳元
[A Metric Learning Reality Check](https://arxiv.org/abs/2003.08505)

# Abstract

### 訳文

過去 $4$ 年間のディープメトリック学習の論文は, 一貫して精度の大きな進歩を主張しており, 多くの場合, $10$ 年前の手法の性能を $2$ 倍以上に向上させてる. この論文では, これが実際に本当なのかどうかを確認するために, この分野を詳しく見ていく. また, これらの論文の実験的セットアップに欠陥があることを発見し, メトリック学習アルゴリズムを評価する新しい方法を提案する. 最後に, 時間の経過に伴う改善はせいぜいわずかであることを示す実験結果を提示する.


### 原文

Deep metric learning papers from the past four years have consistently claimed great advances in accuracy, often more than doubling the performance of decade-old methods. In this paper, we take a closer look at the field to see if this is actually true. We find flaws in the experimental setup of these papers, and propose a new way to evaluate metric learning algorithms. Finally, we present experimental results that show that the improvements over time have been marginal at best.
投稿したコメントに機能を追加させる。(自分用メモになっているかもしれない）

#実装機能
・ログアウト状態でも投稿詳細ページを見ることができる。
・投稿者にしか投稿の情報編集、削除のリンクが踏めないようになっている。

---
##ログアウト状態でも投稿詳細ページを見ることができる。

config/routes.rbにshowを追加していく。

```
Rails.application.routes.draw do
  root to: 'posts#index'
  resources :posts, only: [:new, :create, :show]
end
```

ターミナルでrails routes　で表示させたいパスを確認していく。

```
Prefix    Verb  URI Pattern           Controller#Action
root      GET   /                     posts#index
posts     POST  /posts(.:format)      posts#create
new_post  GET   /posts/new(.:format)  posts#new
post      GET   /posts/:id(.:format)  posts#show
```



showアクションをコントローラーで設定していく。
app/controllers/posts_controller.rb

```
  def show
    @post = Post.find(params[:id])
  end
```


showファイル作成（ビュー）をコントローラーと同じ名前のpostフォルダ内に作成したあと、中身を記述
show.html.erb

```
<div class="postTitle">
  <%= @post.title %>
</div>
<div class="postText">
  <%= simple_format @post.content %>
</div>
```

*simple_formatメソッドは投稿時に改行を含むデータを送信したときに、その改行を反映してくれる役割です。

index.html.erb下記を記述していく。(トップページから詳細ページに遷移させるために記述）

```
<div>
  <%= link_to post.title, post_path(post.id) %>
</div>
```

###＜ここまでの実装＞
リンク先を踏んで詳細を表示することができる。


##投稿者のみ投稿の情報編集、削除のリンクが踏めるようにしていく。(gemのdeviseが必要になります。）

Showファイル変更する。(ログインしているかつログインuserと投稿userが一致）している時のみ表示
app/views/posts/show.html.erb

```
<div>
  <%= @post.title %>
</div>

<% if user_signed_in? && current_user.id == @post.user_id %>
  <div>
    <%= link_to "編集", edit_post_path(@post.id) %>
    <%= link_to "削除", post_path(@post.id), method: :delete %>
  </div>
<% end %>

<div>
  <%= simple_format @post.content %>
</div>
```

これでLoginUserかつLoginUserと投稿Userが一致の時のみ表示できるようになる。
＜補足＞
論理演算子を調べると様々な条件をつけることが出来る。
---
感想
初めて書いた記事です、意味不明な箇所は徐々に直していきます。