OmniAICreator/Qiita-1.07M huggingface dataset:
curlコマンドを用いてCRUD処理を行う

# はじめに
- 本稿はHTTP(S)を用いてAPIと通信を行うためにcurlを使いたいものの、毎度curlの使い方を忘れてしまう自分が備忘録的にまとめたものです。
- 間違っている箇所や至らない点についてはコメントの方で指摘していただけると幸いです。

## curlって
以下、[公式ページ Who makes curl?](https://curl.haxx.se/)より日本語訳
> curlは、データを転送するためにコマンドラインまたはスクリプトで使用されます。 自動車、テレビ、ルーター、プリンター、オーディオ機器、携帯電話、タブレット、セットトップボックス、メディアプレーヤーなどにも使用されており、毎日何十億もの人間に影響を与える何千ものソフトウェアアプリケーションのインターネット転送バックボーンです。

一言でまとめると`URLを使用してデータ転送するためのコマンドラインツール`と言えます。

## CRUDって
HTTPメソッドの中で`POST・PUT・GET・DELETE`が行う、データ操作の基本となる4つの処理のことを言います。
HTTPメソッドの詳細な内容については[こちらの記事](https://qiita.com/r_fukuma/items/a9e8d18467fe3e04068e)で丁寧にまとめているので、詳しく知りたい方はそちらを参照するといいと思います。

# 各コマンド
curlが持つオプションの詳細について知りたい場合は[こちら](https://curl.haxx.se/docs/manpage.html)(英語)を参考にするといいです。
日本語では[こちら](https://www.setouchino.cloud/blogs/99)の記事が分かりやすくまとめられてたので、一度確認してみるといいでしょう。

以下が、今回用いた`オプションについての補足`と`CRUDを行うためのコマンド`になります。
コマンドの例に際して[Qiita API v2ドキュメント - Qiita:Developer](https://qiita.com/api/v2/docs)を用いました。

## オプション

```shell
$ curl -X GET # -X 以下にHTTPメソッドを指定することで任意のメソッドで通信を行うことができます。
$ curl -X POST -d '{"token":"xxxxxx"}' # -d パラメータの指定を行うことができます。
```

```shell
$ curl -H 'Content-Type:application/json' # -H HTTPヘッダを記述することができます。
```

## Create(POST)
```shell
# 記事に対してコメントを投稿する場合の例
$ curl -X POST -H 'Content-Type:application/json' -d '{"body":"コメント"}' https://xxxx/api/v2/items/:item_id/comments
```

## Read(GET)
```shell
# コメントを取得する場合の例
$ curl -X GET https://xxxx/api/v2/comments/:comment_id
```

## Update(PUT)
```shell
# ユーザーをフォローすｒ場合の例
$ curl -X PUT https://xxxx/api/v2/users/:user_id/following
```

## Delete(DELETE)
```shell
# コメントを削除する場合の例
$ curl -X DELETE http://xxxx/api/v2/comments/:comment_id
```


# 参考
[HTTPメソッド(CRUD)についてまとめた](https://qiita.com/r_fukuma/items/a9e8d18467fe3e04068e)
[curl.haxx](https://curl.haxx.se/)
[逆引きcurlコマンドのオプション一覧](https://www.setouchino.cloud/blogs/99)
[Qiita API v2ドキュメント - Qiita:Developer](https://qiita.com/api/v2/docs)
Unity iOSアプリで、Firebaseの最新ライブラリを使っているのにプッシュ通知を受け取れない問題の解決

#結論

unitypackage展開後、iOS用SDKには権限チェックを入れる必要がある模様。

Firebase Unity SDK をインポートする際に導入される。
.a 拡張子ファイル全てについて、下記2点をONにしたら動いた。
~~必要ないファイルもあったかもしれないが、面倒だったので放置しました。~~

1) FrameworkDependencies の Gamekit
2) Rarely used frameworks の SafariService

出典：
https://forum.unity.com/threads/firebase-issue.645127/

##実行環境
Mac Unity2018.2.21f

##経緯
1) Android64bit対応のため、2018.1.9f2からアップデート。
2) Firebaseのライブラリも置き換えないと64bit対応が完遂できないこと発覚。
3) しかたなくライブラリを更新したら、iOS側のほうが大変なことになった。
4) 多分これが一番楽だと思います。

##余談
UnityEditorではなくJenkins＝コマンドラインで実行したのだが
`[Unity] Error (Not a directory) occured whilst enumerating /BUILD_PATH/.../Pods/Headers/Private/Firebase/Firebase.h`
みたいなエラーログが大量に発生。
このエラーログでググって出典ページを見つけたのだが、
このエラー自体は何か問題になるものではなさそうである。

なぜ問題にならないと言い切れるのか。
どうもこれ、Unityのコマンドライン起動中に「pod install」が走ると表示される模様。
どうせUnityでは使用せず、Xcodeで開くまで参照しない。
少なくとも自分の環境では、Unityが終了してXcodeでworkspace開く段階までには生成されていた。

エラー出てるのに実害はない、というのは変な感じがする。
なんかこう、GooglePlayとかFirebase系の処理、
コマンドライン実行されることを意識してないっぽいですね。勘弁して？
Pythonでリストの作成・編集をしてみよう

#はじめに


未来電子テクノロジーでインターンをしている宮﨑です。
pythonでハッカーランクに挑戦中なのですが、easyレベルでも苦戦中…
めげずに頑張ります…！

今回はリストの基本的なところをまとめました。
もし誤りがあれば修正するのでどんどん指摘してください。


リストの作成・編集


####リストからリスト（複数の要素）を取り出す
リスト[インデックスの始点:インデックスの終点+1]と記述する。


（例1）インデックス2~4の要素を取り出す
`リスト名[2:5]`

（例2）インデックス2~終点
`リスト名[2:]`

（例3）始点～インデックス5
`リスト名[:6]`

（例4）インデックス3~終点の2つ前
`リスト名[3:-1]`

####リストの要素を上書きする

`リスト名[インデックス] = 値`

####要素を追加する

`リスト名.append(追加する要素)`

####要素を削除する

`del リスト名[インデックス]`

####２次元配列
リストの要素をリストにする。

`[[1,2,3],[4,5,6]]`

#まとめ
リストの書き方はわかってきました。
次回はエラーの原因をまとめてみようかなと思っています。
chromium-chromedriverでinput type="date"やtype="time"で値がおかしくなった時

個人的にハマったのでメモ代わりに

`Rspec`でE2Eテストをしているときに`input type="date"`の項目に`2019-08-01`と入れて送信したときに
コントローラー側に`90801-02-01`のような値が渡ってきた。

https://bugs.chromium.org/p/chromedriver/issues/detail?id=295
に丁度同じ質問があったが、どうやら
`chromedriver`では`mm/dd/yyyy`の形式らしい。
`2019-08-01`にしたい場合は`08012019`(`08/01/2019`, `08-01-2019`でも可)と入れるとOKだった。

`input type="time"`も同様に形式が異なり、
`10:00`ではなく`10:00 AM`のように`HH:MM am/pm`の形式だった。
`10:00 AM`ではなく、`10:00AM`(`10:00 1`のように`am = 1` `pm = 2`で置き換えての入力でも可)と入れるとOKだった。

E2Eテストの途中でキャプチャを取れば
![スクリーンショット 2019-07-29 23.38.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13210/1c231084-cd24-d106-9a47-e64bf60a380c.png)
のように見て分かったが、`chromium`でも`yyyy/mm/dd`形式で表示されたので、
`chromedriver`の挙動のようだが、これをリアルタイムで確認する方法があれば…
Regex　正規表現まとめ

#はじめに
[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしている<小栗>です。
「プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。

正規表現まとめ
===
Pythonの正規表現をまとめます。
ちなみに、今回初めてマークダウンでテーブルを作成しました。

|メタ文字 |意味 |
|--------|-----|
|^ |文字列の先頭にマッチ|
|$|文字列の末尾にマッチ|
|.|任意の文字にマッチ|
|[ ... ]|[と]で囲まれた中に並べた1文字にマッチ|
|[^ ... ]|[^ と ]で囲まれた中で並べた文字以外の任意の1文字にマッチ|
|*|【繰返し指定子】直前に記述した文字が0文字以上連続していることを指定し、後続の繰返し指定子よりも優先して可能な限り最大数マッチさせようとする。|


おわり
=====
まだまだあるので追加していきます。
MVVMパターンを使ってみる

以前、DataBindingを使ってみて、その延長でMVVMパターンを使ってみました。
おそらく今後も使うと思うので、手順を残したいと思います。
ベースは下記の記事の実装を使います。

[DataBindingを使ってみる](https://qiita.com/kumas/items/571c4d2633eeaaca4729)

今回はListViewで行います。
ModelViewは
一覧に表示するデータのリストを保持して、Adapterに適用させます。
そのAdapterをListViewに適用させるイメージです。

###①ライブラリの追加
ModelViewを使うために、ライブラリを追加します。

```kotlin:build.gradle
dependencies {
    // 追加
    implementation 'android.arch.lifecycle:extensions:1.1.1'
}
```

###②ModelViewの作成

次にModelViewを作成します。
ModelViewではデータのリスト(画面に表示させるもの)を保持します。

```kotlin:ListViewModel
class ListViewModel: ViewModel() {

    private lateinit var realm: Realm

    fun loadData(): List<TaskDetail> {
        realm = Realm.getDefaultInstance()
        val tasks = realm.where<Task>().findAll().sort("id")
        val taskList = mutableListOf<TaskDetail>()

        // タスク一覧に表示するタイトルと期限をリスト化
        tasks.forEach { taskList.add(TaskDetail(it.title,
                DateFormat.format("yyyy/MM/dd", it.date).toString() + "  " + DateFormat.format("HH:mm", it.time).toString(), it.id)) }

        return taskList
    }
}
```

###③Activityの修正

Activityを修正します。
今まではActivityでデータを取得して、Adapterと紐づけを行っていましたが、
今回はModelViewで定義したデータを取得する関数を呼び出し、Adapterと紐づけするだけなので、かなりコード量が減りました。

```kotlin:MainActivity
class MainActivity : AppCompatActivity() {
    private lateinit var realm: Realm

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(toolbar)
        realm = Realm.getDefaultInstance()
        val binding : ActivityMainBinding

        // MainActivityをDataBinding化する
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        val listViewModel = ListViewModel()
        // ViewModelでデータを取得するロジックを記載
        val taskList = listViewModel.loadData()
        val listAdapter = TaskAdapter(applicationContext, taskList)
        binding.listview.adapter = listAdapter

// 省略
```

###実際に使ってみて

感想を書きます。学習コストは少し高いと思いますが、便利でした。(DataBindingの知識やRxJavaの知識が必要などの学習コストは必要かと思います)

####目的がわかりやすい

Activity、ViewModel、Modelのそれぞれが明確な役割を持たせられるので、修正箇所がわかりやすい、コードを見て、他の人と認識合わせがしやすいなどのメリットがあると思います。
それぞれにどこまでの責務を持たせるかは考える必要があると思いますが、便利です。
まだまだ、改善の余地があるので、ブラッシュアップはしていきたいと思います。

####参照

[Android MVVM 設計 2](http://nekojarashi.hatenablog.jp/entry/2018/01/19/Android_MVVM_%E8%A8%AD%E8%A8%88_2)
【Heroku】デプロイ時のエラーまとめ

# Herokuで発生したエラーメモ
Herokuで出たエラーメモです。
書かないと忘れてしまいそうなのでメモとして書きます。
※解決できない場合のgitでの戻し方の方が長くなってしまいました…

![download.png](https://qiita-image-store.s3.amazonaws.com/0/260345/cae3b1b0-23e0-35e6-dc22-8b4c73aa8979.png)

## 1. リポジトリ無いみたいなエラーが出る
`heroku fatal: repository　~~~ dose noe exist`

リネームなどした場合に発生するかもしれません。


### サイト名(アプリ名)リネームしたからかも
testappにするとしたら

```
$ heroku rename testapp
```

↓のように変更される
`https://testapp.herokuapp.com`


リポジトリ間違ってますので再設定しましょう。`testapp`のところにサイト名入ります。

```
$ git remote set-url heroku https://git.heroku.com/testapp.git
```

#### heroku git push先確認

```
$ git remote -v
```

```
heroku  https://git.heroku.com/sampleapp.git (fetch)
heroku  https://git.heroku.com/sampleapp.git (push)
origin  git@bitbucket.org:sampleuser/sampleapp.git (fetch)
origin  git@bitbucket.org:sampleuser/sampleapp.git (push)
```

`git push`や`git push heroku master`などでpushする先を確認できます。違っていたら
`$ git remote set-url heroku https://git.heroku.com/testapp.git`のように変更。

## 2. 前のバージョンに戻してしまう

```
$ heroku rollback v6
```

### バージョン確認

```
heroku releases
```

下記のような表示される

```
v7  Deploy a3525aaa         samplemail@gmail.com  2019/01/19 15:52:18 +0000 (~ 5m ago)
v6  Deploy 44cf704a         samplemail@gmail.com  2019/01/19 15:17:20 +0000 (~ 40m ago)
...
``` 

使うかわからないですけどバージョン確認して戻すことが可能です。確認してv7が最新のようだったらv6にしたら前の状態に戻せます。

## 3. 原因不明のApplicationError
とりあえずHeroku再起動してみましょう

```
$ heroku restart --app application_name
```
参考記事
https://qiita.com/Oakbow/items/1565922ddcdea0ce9ab5



## 4. Cloud9でherokuコマンド使えない
```
$ source <(curl -sL https://cdn.learnenough.com/heroku_install)
$ heroku --version
```

`heroku --version`は確認です。バージョンが出たらOK

## 5.ActiveSupport::MessageEncryptor::InvalidMessage

Encrypted Credentialsでキーなどを秘匿化できる。
TwitterのAPIキーをベタで書くわけにもいかないので
素晴らしい記事を参考にやりました。Rails 5.2以降で使えるようになり、Encrypted secretsよりも推奨されている。

[secrets.ymlや環境変数をRails 5.2のEncrypted Credentialsに移行する](https://qiita.com/d-mato/items/aab2b6b2f587a8582631#%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4)

### 解決手順

先ほどのリンク先で確認していただければいいですが

```
$ EDITOR=vim bin/rails credentials:edit
```

これを打つと秘匿情報ファイルと鍵ファイルを生成。vimで開く
私はtwitter API書いたので↓のように追記してます

```.rb
twitter:
  twitter_api_key: 1234567891011121314
  twitter_api_secret: 345678910111213141516

# aws:
#  access_key_id: 123
#  secret_access_key: 345

# Used as the base secret for all MessageVerifiers in Rails, including the one $
secret_key_base: aaaaaaaaaaadddddddddddgggggggaaaaaaaaaaaaaaaaaaaaaaaaaa
```

蛇足でしょうがvimで保存して閉じるのは`Esc` `:` `wq`です。

herokuはmaster.keyをコピーしておけばいいというわけにはいかないので、環境変数で設定。

```
$ heroku config:set RAILS_MASTER_KEY=`cat config/master.key`
```

git addしてコミットして

```
$ git push heroku
```
WordPressにはREST APIが用意されているので、サービスにブログ機能を組み込むのに便利

## WordPressにはREST APIが用意されているので、サービスにブログ機能を組み込むのに便利
タイトルの通りです。APIの公式解説サイトはこちらです。
https://developer.wordpress.org/rest-api/

サービスにブログ機能を組み込みたい方にとって、この記事が参考になれば幸いです。
私の運営しているサービスも、ブログ部分にWordPress REST APIを使用しています。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
DockerでRailsの環境構築

# はじめに
Railsチュートリアルをはじめました。その第１章で環境構築をしていて、チュートリアルではクラウド上の環境で実行していましたが、私は、Dockerで環境構築を行いました。
以前、Udemyの講座で勉強したのですが、正直よくわかっていなかったので、この際ちゃんと勉強したいと思い、調べた内容をまとめます。
Udemyの講座：[フルスタックエンジニアが教える 即戦力Railsエンジニア養成講座](https://www.udemy.com/rails-kj/)

# 環境
macOS Mojave 10.14.5
Ruby : 2.5.0
Rails : 5.1.6
PostgreSQL

# 用意するファイル
DockerでRailsの環境構築を行うために必要なのは、以下の４ファイルです。

```
DockerFile
docker-compose.yml
Gemfile
Gemfile.lock
```
## ファイルの説明
### DockerFile
DockerFileは、Docker上で動作するコンテナの構成情報を記述するファイルです。
ビルドすることで実行されます。
以下のように記述します。

```dockerfile:DockerFile
# ベースとなるイメージの指定　rubyのバージョン2.5.0を指定しています
FROM ruby:2.5.0
# パッケージのインストール
RUN apt-get update -qq && apt-get install -y build-essential nodejs
# コンテナ上の作業ディレクトリの作成
RUN mkdir /app
# 作業ディレクトリの指定
WORKDIR /app
# ローカル上のファイルをコンテナ上の作業ディレクトリにコピー
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
# gemのインストール
RUN bundle install
# ローカルのファイルを全部コンテナにコピー
COPY . /app
```
FROMで記述した箇所でイメージのベースの指定、RUNでコマンドの実行を意味します。

### docker-compose.yml
docker-compose.ymlは複数のコンテナの定義や実行手順などを記載して簡単に管理できるようにするファイルです。
以下のように記述します。

```yml:docker-compose.yml
# バージョンの指定
version: '3'
services:
# Railsのコンテナ
  web:
    # DockerFileのパス
    build: .
    # コンテナ起動時に実行されるコマンド
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    # ローカルとコンテナの紐付け
    volumes:
      - .:/app
    # 公開ポート番号:コンテナ内ポート番号
    ports:
      - 3000:3000
    # dbコンテナを先に起動する
    depends_on:
      - db
    # デバッグ用
    tty: true
    stdin_open: true
# sqlite3のコンテナ
  db:
    # イメージの指定
    image: postgres
    # PC上にDBの内容を保持する設定
    volumes:
      - db-volume:/var/lib/postgresql
    # 環境変数
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
    # ポート番号
    ports:
      - '5432:5432'
# dbのvolumes用
volumes:
  db-volume:
```
webのコンテナ情報とdbのコンテナ情報を記述します。

### Gemfile/Gemfile.lock

```:Gemfile
source 'https://rubygems.org'
gem 'rails', '5.1.6'
```
記載はこの2行だけです。
1行目はgemのインストール元のURL、2行目はrailsとそのバージョンです。
gemのインストールをすると自動で追記されます。

Gemfile.lockは空のファイルを用意します。gemのインストールをした際に、そのインストール内容が追記されます。

# コマンドの実行
以下のコマンドを実行して、railsのプロジェクトを作成します。

```
docker-compose run web rails new . --force --database=postgresql --skip-bundle
```
`docker-compose run web`はコンテナ上で以降のコマンドを実行することを表します。

次に、コンテナをビルドします。

```
docker-compose build
```
これで、設定等がコンテナに反映されます。
次に、データベースの設定を修正します。
修正するファイルは`./config/database.yml`です。
以下のように、passwordとhostを修正します。

```yml:config/database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  host: db # コンテナのサービス名
  username: postgres # docker-composeのPOSTGRES_USERと同じ内容
  password: password # docker-composeのPOSTGRES_PASSWORDと同じ内容
```
次に、コンテナを起動します。

```
docker-compose up -d
```
以下のコマンドで、データベースを作成します。

```
docker-compose run web bundle exec rails db:create
```
これで、環境は整ったはずなので、`localhost:3000`でデフォルトのページにアクセスできます。

<img width="1191" alt="rails.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311225/f14b74d8-de5b-d824-d676-411d305e12fa.png">

# 参考
以下の方の記事がわかりやすかったです。
[丁寧すぎるDocker-composeによるrails + MySQL on Dockerの環境構築(Docker for Mac)](https://qiita.com/azul915/items/5b7063cbc80192343fc0)
DV BV

# DV / BV
コントラストの定量評価
- Detail Variance 詳細分散
- Background Variance 背景分散

各画素における近傍領域の濃度分散を求め、
その値が閾値以上の場合前景、閾値未満の場合背景とみます。

そのうえで、

- DV 前景の全画素の濃度分散の平均値
- BV 背景の全画素の濃度分散の平均値

となる。


DV/BV比が大きいほどコントラストの改善効果が高い

つまり、
DVが上がり、BVが変わらなければ、コントラストが改善できた！
といえるらしい。原著は読んだことない。

あんまり使われているところを見ないが、実際どうなんでしょう。
AWS EC2上でVimを使わず、VScodeで開発したい

#はじめに
AWS EC2でNodeをインストールし、Node.jsで開発を始めたいがリモートサーバでどうやって開発していいものか、、、

方法としては、2つ

1. ターミナルで「Vim」コマンドを使い、その都度ファイルを開いて書き込んでいく。
2. VScodeの拡張機能を使い、EC2上のファイルをローカルのVSCodeと同期し、そのまま編集、保存する

1は何か面倒そう、、VScodeの方が慣れているし2で行こう！

#SFTP

今回はVScodeのSFTPという拡張機能を使うことにします。
まず、AWSでEC2インスタンスを立ち上げて、ターミナルからSSH接続させておきます。

![スクリーンショット 2019-07-29 23.10.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449631/029500e8-8e07-ec3f-e242-1dcaf6979d96.png)

今度はVScodeの方へ行き、SFTPをインストールします。

![スクリーンショット 2019-07-29 23.12.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449631/925a7659-c3fd-3094-99e8-bc30cee5dc65.png)

インストールし終わったら、Windowsなら「Ctrl + Shift + P」、Macなら「Cmd + Shift + P」を入力し、「SFTP: config」を選択してください(SFTPのUsageにも書いてあります。)。そうするとExplolerにsftp.jsonというファイルが出てきます。そこにEC2の場合、以下のように入力してください。

![スクリーンショット 2019-07-29 23.14.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449631/71128535-87c2-bea4-7dac-0fcf806513eb.png)

中身を簡単に説明します。

- name ⇨ なんでも良い
- host ⇨ EC2インスタンスのパブリックIPアドレス
- protocol ⇨ 転送するためのプロトコル。sftpかftp。安全性が高いのはsftp
- port ⇨ SSH接続で使っているポート番号。22
- username ⇨ EC2インスタンスのログインユーザー名(ec2-user)
- privateKeyPath ⇨ SSH接続の秘密鍵の配置場所
- remotePath ⇨ サーバーを保存する階層
- uploadOnsave ⇨ ここをtrueにしておくと保存した時に自動的にサーバーにアップロードされる。

EC2インスタンスで開発する場合、上と同じ設定にしてもらえれば大丈夫かと思います。

入力、保存し終わったらWindowsなら「Ctrl + shft + P」、Macなら「Cmd + Shft + P」を入力して「SFTP：List ALL」から編集したいインスタンス上のディレクトリまで進んでください。

![スクリーンショット 2019-07-29 23.16.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449631/805175e0-3a8c-fd3d-bdb4-292c7cac7bc4.png)

そこで「.choose current folder」をクリックすると、自分のExplorerに編集したいフォルダーが現れ、編集可能になります。

![スクリーンショット 2019-07-29 23.16.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449631/5c835e87-9af9-d5e7-b536-92f10262b54a.png)

今回下の二つの記事を参考にさせていただきました。ありがとうございました。

参考資料①https://www.karelie.net/vscode-sftp/
参考資料②https://qiita.com/humuhimi/items/7d8d49c88a8d306df89f


他の主な機能の「ファイルのアップロード」「差分表示」「同期」については参考資料①を見てください。

これで大分開発が捗るはず、、
私が初めてウェブサイトをつくって苦労したこと

## はじめに
私は、2019年7月からプログラミングサークル「[ゆうとクラブ](https://www.yutoclub.org)」に入会し、
フロントエンジニアになるべく修行をしています。
本記事では、ゆうとクラブ入会約一ヵ月目の成果を報告します。

## Vim矯正ギプス
今までVimを使ったことがありませんでしたが、最速でVimをマスターするために、次のことを実施しました。

* チートシートをパソコンの壁紙に設定
* トイレの壁にチートシートを貼る
* 方向キーでの移動を禁止
* 効率の良いコマンドを叩かないと、怒られて何度もやり直し

そして結果……

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">最近なんのソフト使ってても、 :w で保存しようとしている自分がいるwwww<a href="https://twitter.com/hashtag/%E3%82%86%E3%81%86%E3%81%A8%E3%82%AF%E3%83%A9%E3%83%96?src=hash&amp;ref_src=twsrc%5Etfw">#ゆうとクラブ</a><a href="https://twitter.com/hashtag/Vim?src=hash&amp;ref_src=twsrc%5Etfw">#Vim</a></p>&mdash; めい@ゆうとクラブ (@mei_9961) <a href="https://twitter.com/mei_9961/status/1152863064087121921?ref_src=twsrc%5Etfw">July 21, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## CUI強制でGit再入門
今まで、Visual StudioのGitで使っていましたが、bashのみに切り替えました。
Gitのことをあまり理解してなかったということが思い知らされました。

しかし、bashでGitを使うようになってから、多くの便利な機能を知りました。

* ブランチ
* `git commit --amend`
* `git add -p`

そして適切な粒度でコミットすることとコミットメッセージの重要性を知りました。
最初は、大きなコミットを作ってしまいどこでバグが発生したかわからない事態もありました。

## ユニバーサルデザイン
![ルビトグル.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416392/ebf45fbb-a06b-e40f-69aa-9c9a86e5d559.png)


[ゆうとクラブ](https://www.yutoclub.org) はユニバーサルデザインのとっかかりとして、ひらがなルビに対応しました。
まだ対応していませんが、文字のサイズも変更できるようにしたり外国語の対応をしようと思っています。

## レイアウトに苦戦
今まで、ゲームのプログラミングをしていたので、絶対位置の指定に慣れていました。
しかし、HTMLのレイアウトは、floatやflexbox、gridを使い分けて、なるべく画面サイズに依存しないことが大事だとわかりました。

1. めろちゃんからデザイン案をもらいました。
![めろちゃんデザイン案](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416392/f96230f1-2c66-5db4-4c98-ca0038b83244.png)

1. まず、装飾なしで、レイアウトしました。
![レイアウト](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416392/c92f3a59-8d0c-af96-5f91-dae5cf56a3c5.png)

1. 装飾など、細かい部分を作りこんで完成！
![完成版](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416392/cff88d5c-334d-5c4b-00c6-0a0ddc8d6f41.png)



## 協力者への感謝
同会の会員である、めろちゃんにウェブサイトのデザイン案を作ってもらいました。
彼女もまた、私と同じく初学者ですが、色使いのセンスが良く、一緒に制作していて、やりがいを感じました。

## これからやること
来月からは、即戦力を身につけるために下記の事柄に取り組んでいきます。

* かんばんを使ったチーム開発
* KPTで振り返り
* Windowsを捨て、Arch Linux入門
* VueJS,NuxtJSを使ってより動的なウェブサイト作り

チーム開発では、まだチームメンバーが足りていません。
興味のある方がいたら、ぜひ[ゆうとクラブ](https://www.yutoclub.org)の門を叩いてみてください。
raspberrypi + netatalk にアクセスできない

RaspberryPi に限らず、Mac からネットワーク経由で簡単に Linux のファイルにアクセスできるようになる **netatalk**. TimeMachine のバックアップ先にできたりもする。

```
sudo apt-get install netatalk
```

だけで、あとは

Finder > Go > Connect to server...

で afp:// の後に RaspberryPi のIPアドレスを書けば接続できるという説明もあるけれども、私は接続できなかった。

<img width="484" alt="Screen Shot 2019-07-29 at 16.06.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63210/561dfe42-b5ef-e153-2a83-8729573cb8df.png">


## 症状

* ユーザー名とパスワードの入力を求められる。ユーザー名は `pi`.
* パスワードは認識されている。つまり、間違ったパスワードを入力すると入力ボックスが振動して拒否される。
* 正しいパスワードを入力すると

> There was a problem connecting to the server.
> There are no shares available or you are not allowed to access them on the server.

と言われる。

## 解決策

設定ファイルによる設定が必要だった。

```
/etc/netatalk/afp.conf
```

を編集する。

```
[Global]

[Homes]
basedir regex = /home
```

`[Homes]` とその次の行を非コメント化、`/home` と書く。

これで接続できた。netatalk 再起動は不要。

Finder の左のパネルの shared の部分にも raspberrypi と表示される。便利 😆


#### 蛇足

```
sudo systemctl status netatalk
```

で `active (running)` と表示されていれば動いている。

```
sudo service netatalk start
sudo systemctl restart netatalk
```

あたりは使ったけど不要かな。

## 環境

* Raspberry Pi 4 Computer Model B 2BG RAM
* Raspbian GNU/Linux 10 (buster)
* netatalk Version: 3.1.12~ds-3
Postfixのセキュリティ設定について

# Postfixのセキュリティ強化

# はじめに
Redhat Enterprise LinuxやCentOSのデフォルトSMTPサーバであるPostfixのセキュリティ設定を調べたのでメモ

# 想定するPostfixの役割
* 外部からのSMTPを受け取りローカル保存
* 内部からのSMTPを受け取ってインターネット上に配送

# 設定

## MTA情報の隠蔽
```bash:/etc/postfix/main.cf
# デフォルト値
smtpd_banner = $myhostname ESMTP $mail_name

# 特定のミドルウェアバージョンや種類を狙った攻撃を防ぐため、特定できない固定値を入れる
smtpd_banner = ESMTP MTA
```

## 内部ユーザの隠蔽
```bash:/etc/postfix/main.cf
# デフォルト値
disable_vrfy_command = no

# SMTPのEXPN,VRFYコマンド（ユーザの存在確認）コマンドを無効にし、内部ユーザの情報を隠蔽する
disable_vrfy_command = yes
```

## HELO コマンドを必須にする
```bash:/etc/postfix/main.cf
# デフォルト値
smtpd_helo_required = no

# スクリプト化された迷惑メール等はSMTPのHELOコマンドを使用しないケースがあるため、それらのメールを拒否するために設定
smtpd_helo_required = yes
```

## HELOコマンド受信時のホスト名による受信制限
```bash:/etc/postfix/main.cf
# デフォルト値
smtpd_helo_restrictions =

# 相手のホスト名が DNS に登録されていない、FQDNが解決できない、ホスト名の文法が不正の場合に拒否
smtpd_helo_restrictions = permit_mynetworks, reject_unknown_hostname, reject_non_fqdn_hostname, reject_invalid_hostname, permit
```

## 送信者ドメインによる受信制限
```bash:/etc/postfix/main.cf
# デフォルト値
smtpd_sender_restrictions =

# ドメインが解決できない、FQDNが解決できない場合に拒否
smtpd_sender_restrictions = permit_mynetworks, reject_unknown_sender_domain, reject_non_fqdn_sender
```

# おわりに
Postfixのセキュリティ設定をまとめました。
まとめてみると、情報が外部に見えないようにするとか、必要最低限の操作しか許さないとか、どんなミドルウェアでもやるべきことは一緒なんだなーと思いました。
Googleスライド+iMovieでコマ送り的な動画を作ってみた

# 概要
Googleスライド+iMovieでコマ送り的な動画を作る方法です。
手軽にサクッと作りたい人向けです😸

## 対象者でない人
・**Adobe Premiere**など高機能な動画編集ソフトを持ってる人
-> ガンガン編集しましょう。確か作成後1ヶ月無料とかもあったのでそれ使うのもいいかも。
・**Microsoft PowerPoint**を持ってる人
-> ムービー作成機能があります。プレゼンテーションの設定で切り替え速度なども変更できます。
・他に**良いフリー動画編集ソフト**を知ってる人
-> 教えてください。笑

## 対象者
・今あるソフトで手軽に動画編集したい人
・Googleスライドが既に存在していてそれを動画にしたい人

# 手順

### 1. Googleスライドでコマとなる素材や字幕を作る

こんな感じです。
<img width="1384" alt="スクリーンショット 2019-07-29 22.17.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140953/6188a98d-d884-4784-f5d9-47093a0cfa26.png">

iMovieの**文字入れ機能は貧弱**なのでこの時点で字幕を作っておくのが良いです。

### 2. PNGファイルにエクスポートする
**ファイル > 形式を指定してダウンロード > PNG画像** でファイル出力します。
残念ならが1枚ずつしかできないので、ショートカットキーを駆使しながら出力していきます。
解像度を気にしなければPDFで出力してiMovieでコマをカットする方法もあります。
<img width="1387" alt="スクリーンショット 2019-07-29 22.17.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140953/f1c143b0-a030-1891-3d5d-f3d13f7c63d9.png">

### 3. iMovieで読み込んで編集する
MacならデフォルトでiMovieは入っています。
<img width="147" alt="スクリーンショット 2019-07-29 22.14.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140953/fc0ddb43-3cd6-1592-a727-6519e6721a7f.png">

左上の 下矢印ボタン で出力したPNGファイルを読み込みます。
<img width="1440" alt="スクリーンショット 2019-07-29 22.24.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140953/ab7e704e-13de-b16c-0a53-30228470b4e3.png">

あとはドラッグ&ドロップで下のトラックにいい感じに並べていきます。

注意したいのが、iMovieは映像が2トラック、音声が1トラックしか追加できません。。😖
（それ以上追加しようとしても上書きされます）

完了したら右上の 共有ボタン > ファイル でファイルに保存できます。
<img width="1440" alt="スクリーンショット 2019-07-29 22.34.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140953/303c056a-9640-f6df-5cd0-6d976e24085e.png">

完成〜！

# 作成した動画
上記の方法で作った動画です。
替え歌の映像として載せました😇楽しかったです。笑

[【替え歌】エンジニアの日常 - YouTube](https://www.youtube.com/watch?v=zNbebzSyee8)
[エンジニアの日常 - Speaker Deck](https://speakerdeck.com/mgmgmgmi/enziniafalseri-chang) （スライド）

おしまい。

追記：掲載ありがとうございます！
[【Programming News】Qiitaまとめ記事 Weekly August 1st week, 2019 Vol.3 - Qiita](https://qiita.com/promari/items/b9898845bdac7216f374#_reference-79acabac164ac1211376)
新卒3ヶ月の僕が自社サービスのインフラを移行した話② ~移行編~

こんにちは
taskey Railsエンジニアの田代です。

この記事は「新卒3ヶ月の僕が自社サービスのインフラを移行した話① ~勉学編~」の続き、移行編です。AWSのロードマップがほしいなという方は前編をご閲覧下さい。

移行の前準備、負荷テスト、移行時の手順等を書かせていただきました。こちらだけでも完結出来るように心がけております。

対象者: Rails(Puma) on ECSでの起動タイプFargateを検討しているエンジニア、負荷試験を検討している皆様

社内マガジンに載せる都合上noteにまとめました。
[内容はこちらをご閲覧下さい。](https://note.mu/tashiro_rb/n/nf1c7e72fbece)
新卒3ヶ月の僕が自社サービスのインフラを移行した話① ~勉学編~

こんにちは
taskey Railsエンジニアの田代です。

サーバエンジニアと言えど、スタートアップではRailsだけを書いていたら良いという訳には行きません。
今回は、突然インフラ移行をしてくれと頼まれ、当時ECS？EC2？Fargate？なにそれ？Herokuでええやん？状態の僕が、どのように自社サービスECSのFargateへの移行を終え、インフラエンジニア(仮)になったのかを書かせていただきました。長くなりそうなので勉学編、移行編で分けます。こちらは勉学編となっております。
移行の様子を知りたい方は「新卒3ヶ月で自社サービスのインフラ移行をした話② ~移行編~」をご閲覧下さい。

社内マガジンに載せる都合上noteにまとめました。
[内容はこちらをご閲覧下さい。](https://note.mu/tashiro_rb/n/n72fe680e8e75)
Heroku Review Apps - 簡単で快適なPR検証環境 -

こんにちは
taskey Railsエンジニアの田代です。

モバイルエンジニア、フロントエンジニア、PM、テックリード、その他大勢の機能検証をする皆様。

サーバエンジニアが作ってくれた機能をデバッグするときはどうしていますか？
`git checkout -b feature/hoge origin/feature/hoge` => `docker-compose up`なんて手間をかけていませんか？

リリース前のAPIを元に新規アプリ機能開発をしている時、見ているエンドポイントはstaging環境１つだけですか？追い越しリリースに対応出来ますか？
平行で機能開発、リリースをするのにステージング環境が1つだけ？

その都度ブランチの競合等気にするのはとてもめんどくさいです。

スタートアップや、スピード感のある開発現場では上記問題が多発するとおもいます。弊社もついこのあいだまで、上記問題に悩まされておりました。

対応策はいろいろあると思いますが、あくまで柔軟さを重視する為にtaskeyが導入した、Heroku Review Appsを今回はご紹介させて頂きます。

社内マガジンに載せる都合上noteにまとめました。
[内容はこちらをご閲覧下さい。](https://note.mu/tashiro_rb/n/ne203f81cc0b4)
僕が選んだモダンな分析環境※2019年5月現在

こんにちは
taskey Railsエンジニアの田代です。

サーバエンジニアと言えど、スタートアップではRailsだけを書いていたら良いという訳には行きません。
今回は、突然データ分析基盤を作ってくれと頼まれ、当時BIツール？何それ？美味しいの？状態の僕が、どのように数多のツール群から技術選定をして社内のデータ基盤を作り上げ、データ基盤エンジニア(仮)になったのかを書かせていただきます。

対象者: データ可視化に関して悩んでいるマーケター、BIサーバ、集計DB構築に関して悩んでいるエンジニア

※実際のデータは出せません。分析基盤設計の参考となるよう僕が選んだツールを問題意識とPOINTを踏まえてご紹介させて頂きます。

社内マガジンに載せる都合上noteにまとめました。
[内容はこちらをご閲覧下さい。](https://note.mu/tashiro_rb/n/ndb4cfe06b7f7)
Google App Engineスタンダード環境でRubyが使えるようになったので早速挑戦してみた

# はじめに

ご存知かもしれませんが、Google Cloud PlatformでRubyアプリをデプロイする方法として、
- App Engine フレキシブル環境
- Compute Engine
- Kubernetes Engine
などがあります。

今回は新しく **App Engine スタンダード環境** がベータで加わったので、スタンダード環境での環境構築とデプロイをしてみました。

二つのApp Engine環境についてですが、スタンダード環境だと無料枠があるのが特徴です。詳しくはリンクを張っておきます。
https://cloud.google.com/appengine/docs/the-appengine-environments?hl=ja

まだベータなのでドキュメントが少かったのですが、今回は承知の上でRuby on Rails 5のアプリをデプロイしてみました。

# 準備
ローカルからデプロイするにしても、Cloud Shellからするにしても、色々と準備をします。

**注意**: スタンダード環境ではRuby 2.5のバージョンしか使えないので移行する必要があるかもしれません。

まず、シークレットキーを作ります。

```
$ rails secrets:setup
```

assetsもコンパイルしておきます。

```
$ bundle exec rake assets:precompile RAILS_ENV=production
```

ここらへんはRuby on Railsの手順通りです。

# .gcloudignoreの設定
Rubyと一緒にnodejsなどを使っていたので、`node_modules`の中のファイルが多すぎてエラーになってしまいました。きちんと必要ないものはイグノアしましょう。

```.gcloudignore:.gcloudignore
.gcloudignore
.git
.gitignore
node_modules
```

# app.yamlの設定
`runtime`を`ruby25`に設定します。
また、`entrypoint`を正しく設定しないと動きませんでした。

```yaml:app.yaml
runtime: ruby25
entrypoint: bundle exec rails s -e production
```

# 完成

あとはデプロイするだけです。

```
$ gcloud app deploy
```

これでひとまず動作するようになりました。まだ、ベータなので色々と変わると思いますが、Ruby on Railsを気軽にデプロイできるようになったことはうれしいです。
Herokuだと３０分リクエストが来ないとスリープしてしまったり、Azureだと自分のドメインを使うのに結構費用がかかったりするので、やはりGoogle Cloud Platformのサービスは良心的だと思います。ありがとうございました！
協働ロボットの導入が会社の人事問題を解決する5つの方法

上の世代（団塊世代）が定年退職する、もしくは定年退職が近づくにつれて技能格差が拡大し、世界中の製造業に大きな影響を与えます。Hays Global Skills Indexが実施した2016年の調査によると、技能格差は急速に溝が深くなっており、若者がけがをしやすく、退屈で、流れ作業の工場仕事を好まなくなってきていることで製造業者は工場における役職や仕事のポストを埋める事が困難になってきています。
例えば、ウィスコンシン州に本拠を置くある会社では、生産ラインで募集した132個の役職を埋める事ができず、同社の人事部長はこの状況をエベレストの登山と比較し、雇用方針を緩和し、賃金を引き上げても役職を埋める事ができなかったとしています。
期間労働が多くの製造業において選択肢であったとしても、そのアプローチには困難が付きまといます。期間従業員は仕事内容が思っていたものと違う場合や、退屈な場合急に出社しなくなったり、初日から姿を消すことがよくあります。実際それ以外にも期間労働者にはアルコールやドラッグの問題も付きまといます。そのため、期間労働者という選択肢にはリスクが常に存在し、彼らは仕事へのやりがいや会社への忠誠心を持つことはほとんどないため、生産目標という面で大きな貢献を期待するのは不可能です。
人間と共同で働くよう設計された協働ロボット は、即時かつ長期的な問題解決策を提供するだけでなく、工場における危険で退屈な流れ作業をすべて取って代わって行う事ができます。Cobotが人事問題を解決する主な理由は次の通りです。

信頼できる
製造業において信頼性は第一優先事項であり、協働ロボットはその信頼性を提供します。協働ロボットは、休憩を取らずに24時間対応できるだけでなく、最小限のメンテナンスやアップデートで稼働します。もちろん早退したり遅刻する事はありません。
流れ作業による反復運動過多損傷が起こりえない
人間が行う場合怪我の危険が伴う仕事でも協働ロボットは姿勢を変えたり、ストレッチする必要がありません。さらに人間が協働ロボットの作業スペースに入ってきた場合には、ロボットアームを停止または減速する安全装置が内蔵されているため、人間の同僚を事故や怪我から安全に保護する事ができます。
人間の同僚に会社内でより活躍できる場を与える
人間の労働者が比較的好まない流れ作業の仕事を協働ロボットが行う事で、会社は人間労働者をより高いスキルや器用さ、および意思決定が必要とされる仕事に再配属させる事ができます。そうする事で、これまで働いてきた従業員をロボットプログラマやロボットオペレータなど、より責任がありやりがいを感じる職務に従事できるような再配属活動に積極的に取り組むことが可能になります。
素早い作業
協働ロボットは、組み立て、機械の手入れ、ねじ回しなどの基本的な繰り返し作業を高速で行う事ができます。ティーチペンダントは、プログラミングやロボット工学に関する知識や経験がこれまでになくても、ロボットを直感的に訓練できる1つの素晴らしい選択肢です。
すぐに仕事に取り掛かるのはもちろん、さらに協働ロボットは軽量であるだけでなく、新しいタスクに対してすばやく簡単に再展開する十分な柔軟性を持ち併せています。
お手頃な価格
人事問題を解決するために協働ロボットを導入するべき大きな理由の一つがこのお手ごろな価格設定です。協働ロボットは期間従業員1人の年収と同等の前払いコストで手に入れる事ができ、追加コストも微々たるものです。協働ロボット1台を様々な用途で使いたい場合でも、別のグリッパおよびエンドエフェクタの追加費用しかかかりません。
協働ロボットは、人間の労働者ができるほとんどの流れ作業に適応する事ができ、そのアプリケーションのほとんどは、リスク評価を通過した後の安全保護を必要としません。さらに協働ロボットを採用すれば自動的に自ら成果と稼ぎをあげてくれるので、数カ月もすればあなたの会社における人事問題を解決するだけでなく、コスト削減にもつながるのです。
SQLを学びたいあなたへ

こんにちは
taskey Railsエンジニアの田代です。

サーバエンジニアと言えど、スタートアップではRailsだけを書いていたら良いという訳には行きません。
今回は、突然データ分析をしてくれと頼まれ、当時ActiveRecordに頼りきりだった僕が、どのようにSQLを習得して社内のデータ分析エンジニア(仮)になったのかを書かせていただきます。

社内マガジンに載せる都合上noteにまとめました。
[内容はこちらをご閲覧下さい。](https://note.mu/tashiro_rb/n/n1db65c886751)
RStudio Addinsから、スタイルガイドに沿ったコードに置換しよう。

#はじめに
Rにも次のようにコーディングのスタイルガイドがあります。
- [Google's R Style Guide](https://google.github.io/styleguide/Rguide.xml)
- [Style guide(Advanced R by Hadley Wickham)](http://adv-r.had.co.nz/Style.html)

はじめからこれらを守ってコードを書くに越したことは無いのですが、
ついつい破ってしまうときもあるかもしれません。
そんな時は、RStudioのAddinsのstylerを使ってさっと置換してしまいましょう！

#方法
やり方は簡単です。RStudio AddinsのメニューからStylerの必要なコマンドを実行するだけです。

※追記
Addinsでstylerのメニューが表示されない場合は、install packagesからstylerをインストールしてください。

##選択した箇所のみをstylerで変換した例
下記のように対象の箇所を選択状態にして、Style selectionを選べばOK
![gif1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187459/7ac31381-11c3-ca81-a657-287db50c97da.gif)

##選択されているファイル全体をstylerで変換した例
下記のように対象のファイルをアクティブにして、Style active fileを選べばOK![gif2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187459/97c1f834-0751-1235-2778-137a43981baa.gif)



##最後に
これで、見づらいコードとはおさらばになるはずです。
（とはいえ、Style Guideを勉強して、はじめから守ったコードを書くのに越したことはありません。）

##環境
- R version 3.6.1 (2019-07-05)
- RStudio Version 1.2.1335
- styler 1.1.1

##参考
- [styler](http://styler.r-lib.org)
- [Google's R Style Guide](https://google.github.io/styleguide/Rguide.xml)
- [Style guide(Advanced R by Hadley Wickham)](http://adv-r.had.co.nz/Style.html)
window.openで開いたウィンドウの状態監視

`window.open`で別ウィンドウを開いたときに、そのウィンドウの開閉を監視しようとしたら少しハマりました。

## シンプルにやろうとする→失敗

まずは、`unload`イベントで検出しようとしました。

```js:失敗例
const w = window.open('/path/to/somewhere');
w.addEventListener('unload', () => {
  console.log('unload');
}, false);
```

このようにすると、ウィンドウは開いたままでも`unload`が出力されてしまいます。

### どうしてこうなった？

じつは、`window.open`を実行した場合、いったん`about:blank`が開いて、それを指定のパスに置き換える、という形で処理が進んでいきます。そして、`about:blank`を上書きする際に`unload`イベントが発生してしまうのです。

## じゃあ、どうしようか

### タイマーで監視する

`window.closed`というプロパティがありますので、タイマーでこの変化を監視するような方法も考えられます。

```js:タイマー
const w = window.open('/path/to/somewhere');
const timer = setInterval(() => {
  if(!w.closed) return;
  clearInterval(timer);
  console.log('closed');
}, 100);
```

半ば無理やりな方法ですが、この方法の利点として**クロスドメインでも使える**ということがあります（同一生成元でない場合、`w.addEventListener`を行うことはできません）。

### `unload`イベントでチェック

1回目の`unload`は、`location.href`が`about:blank`で発生しますので、それをチェックする方法も考えられます。

```js
const w = window.open('/path/to/somewhere');
w.addEventListener('unload', () => {
  if(w.location.href==='about:blank') return;
  console.log('unload');
}, false);
```

ただし、この方法の欠点として、指定されたページが表示される前にページを閉じてしまうと、`about:blank`のままで`unload`イベントが発生するため、そちらと区別がつかない、ということがあります。

* ページの読み込み前に閉じた場合→`about:blank`で`unload`（終わり）
* ページの読み込み後に閉じた場合→`about:blank`で`unload`→本来のページで`unload`

ということで、ページが開く前の検知は、タイマーで監視するのがいちばんわかりやすい、という印象です。
機械学習を使った故障予知用の学習データと教師データ（扇風機の振動[3軸加速度データ]）

#機械学習を使った故障予知用の学習データと教師データ
自分の機械学習用にデータがほしいなぁ、、、面白いデータないかなぁって考えてて結局自分でデータ取りました笑

使い方によっては面白いかもなので使いたい人使ってみてください。基本的にはデータ加工はせずそのままですので、
自由につかいたいように加工してくださーい。

使い難いだとかデータが足りないなどあればコメントおねがいしまーす。
感想もあるとうれしいかな笑

データダウンロードURL:
https://drive.google.com/file/d/1K1bFj4OGwSxtmHck45B3tZSZ7o_q4a8n/view?usp=sharing

##**データに関して**
測定対象　　　：2018年に買った扇風機
計測データ　　：3軸加速度（振動値に変化がないところは停止しています）
測定位置　　　：扇風機のモータ裏にねじ止め
計測期間　　　：約1週間
データ測定時間：一時間に一回1分間
データ単位　　：ADコンバータに入力されたときの電圧値
形式　　　　　：CSVファイル

##**センサーに関して**
供給電流　　　　：4mA
電圧感度＠160Hz：0.999mV/(m/s2)
バイアス電圧　　：12.7VDC
周波数　　　　　：XY軸1~5khz　Z軸1~8000Khz  (±10％)
共振　　　　　　：15KHz以上

##**扇風機モータに関して**
ポール数　　　：4本
消費電力　　　：42W
電圧　　　　　：100V
電流　　　　　：0.42A
回転数　　　　：1050rpm
寸法　　　　　：軸140mm、縦横80mm

##CSVの説明
データは左からｘ軸、ｙ軸、ｚ軸の順に縦に右へと並んでます。マイナスの電圧があるのは振動なので基準値から逆方向になるとマイナスの値になってます。
通常動作が一週間分データがあり、一点だけモータ軸にごみを詰まらせて微小な異常データを作ったのでそれはわかりやすいように別ファイルにしてまーす。

![csvの記載.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469375/bbecf098-2fad-d872-9b21-85746d671dc3.png)
時系列データでフラグが立っている範囲を可視化する

時系列データでこういうグラフをプロットしたいときのやり方メモ。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16369/9316e2a6-0fd0-41d3-3dcd-97a7cb4b963c.png)

## 2019年7月の東京の気候データ
2019年7月の東京は雨の日が多かったらしい。
気温も例年より低くて :beer: が全然売れなかったとかなんとか。

今回は 2019-07-01 から 2019-07-28 までの東京の気候データを扱うことにする。

``` python
import pandas as pd

df = pd.DataFrame(
    {
        '最高気温': [24.3, 28.1, 29.1, 25.2, 24.5, 23.7, 20.8, 24.8, 21.8, 24.8, 23.6, 21.9, 27.3, 22.5, 25.0, 22.1, 28.7, 29.7, 31.4, 29.5, 28.2, 24.0, 29.3, 31.6, 32.4, 33.1, 31.4, 32.3],
        '最低気温': [21.0, 21.5, 22.2, 23.4, 19.0, 19.2, 18.7, 17.7, 18.5, 18.5, 18.7, 17.9, 20.0, 20.2, 19.8, 19.0, 20.3, 22.2, 23.0, 24.8, 24.0, 21.6, 22.4, 23.7, 24.4, 25.6, 25.1, 25.0],
        '雨が降った': [bool(v) for v in [1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0]],
    },
    index=pd.date_range(start='2019-07-01', end='2019-07-28')
)
```

|  | 最高気温 | 最低気温 | 雨が降った |
|---|---|---|---|
| 2019-07-01 | 24.3 | 21.0 | True |
| 2019-07-02 | 28.1 | 21.5 | False |
| 2019-07-03 | 29.1 | 22.2 | False |
| 2019-07-04 | 25.2 | 23.4 | True |
| 2019-07-05 | 24.5 | 19.0 | False |

「最高気温」「最低気温」に加えて、「雨が降った」かどうかを表す bool 型のカラムがある。

とりあえず「最高気温」「最低気温」だけプロットしてみるとこんな感じ。

``` python
import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(12, 4))
ax.plot(df['最低気温'], label='最低気温')
ax.plot(df['最高気温'], label='最高気温')
ax.legend()
ax.set_title('2019年7月の東京の気候')
plt.show()
```

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16369/dd9330dd-6fe7-6381-0be8-fbfc2d7066f6.png)

## フラグが立っている範囲を塗りつぶす
「雨が降った」列データを使って、上記のグラフに加えて「この日からこの日までは雨だった」という範囲を塗りつぶしたい。

面倒なので結論だけ書いてしまうと、以下のような関数を作っておくと便利。

``` python
import pandas as pd

def fill_flag_area(ax, flags, label=None, freq=None, **kwargs):
    """ フラグが立っている領域を塗りつぶす
    params:
        ax: Matplotlib の Axes オブジェクト
        flags: index が DatetimeIndex で dtype が bool な pandas.Series オブジェクト
        freq: 時系列データの1単位時間, 指定しない場合は flags.index.freq が使われる
              flags.index.freq が None の場合には必ず指定しなければならない
              (例: 1日単位のデータの場合) pandas.tseries.frequencies.Day(1)
    return:
        Matplotlib の Axes オブジェクト
    """
    assert flags.dtype == bool
    assert type(flags.index) == pd.DatetimeIndex
    freq = freq or flags.index.freq
    assert freq is not None
    diff = pd.Series([0] + list(flags.astype(int)) + [0]).diff().dropna()
    for start, end in zip(flags.index[diff.iloc[:-1] == 1], flags.index[diff.iloc[1:] == -1]):
        ax.axvspan(start, end + freq, label=label, **kwargs)
        label = None  # 凡例が複数表示されないようにする
    return ax
```

基本的には `diff()` を使って境界のインデックスを見つけていくのだけど、`0` のパディングを追加することで隅までフラグが立っているケースを取りこぼさないようにしたり、`axvspan` で範囲を塗りつぶす際に `end` に1単位時間 (`flags.index.freq`) を加える必要があったりと、地味にハマりポイントを回避している。

使うときはこう。

``` python
import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(12, 4))
ax.plot(df['最低気温'], label='最低気温')
ax.plot(df['最高気温'], label='最高気温')
fill_flag_area(ax, df['雨が降った'], label='雨の日', alpha=0.2)  # 追加
ax.legend()
ax.set_title('2019年7月の東京の気候')
plt.show()
```

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16369/9316e2a6-0fd0-41d3-3dcd-97a7cb4b963c.png)

めでたしめでたし。
底辺プログラマがサーバ管理者を目指す　その３ Dockerイメージの作成

# Dockerイメージの作成
今回は前回の通りhelllo-worldイメージを自作していく

## イメージの作成方法
Dockerイメージを作成する方法は以下の２通りある。

### １．Dockerfileで作成する方法
Dockerfileと呼ばれるスクリプトファイルを作成し、
それをDockerに実行させることによってDockerイメージが作成される

### ２．コンテナからイメージを作成する方法
存在するコンテナに対して変更を行いそれをイメージとして保存する。
Dockerfileでイメージを作成するのが難しい場合などこちらの方法が使用される。

### どちらにするか？
基本はコンテナで作業しながらうまく行ったのをDockerfileに書くのが良さそう。
参考）[効率的に安全な Dockerfile を作るには](https://qiita.com/pottava/items/452bf80e334bc1fee69a)

## hello-worldイメージの作成
まずはDockerfileを作成する

```bash
# Dockerfileを作成
$ touch Dockerfile
```

次に作成したDockerfileにコードを書いていく

```dockerfile:Dockerfile
# ベースにするイメージの指定
FROM ubuntu

# hello world!のメッセージを表示する
CMD ["echo", "hello world!"]
```

あとはこれをビルドするだけ

```bash
# カレントディレクトリにあるDockerfileを元にイメージhelloを作成する
$ sudo docker image build -t hello .

# 実行結果
Sending build context to Docker daemon  3.072kB
Step 1/2 : FROM ubuntu
 ---> 3556258649b2
Step 2/2 : CMD ["echo", "hello world!"]
 ---> Using cache
 ---> 9db3c91189ab
Successfully built 9db3c91189ab
Successfully tagged hello:latest

# イメージ作成されているか確認
$ sudo docker image ls

# 実行結果
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello               latest              9db3c91189ab        26 hours ago        64.2MB
ubuntu              latest              3556258649b2        5 days ago          64.2MB
hello-world         latest              fce289e99eb9        6 months ago        1.84kB
```
そして正しくイメージが作成されているか確認

```bash
# 作成したhelloイメージをコンテナとして起動
$ sudo docker run hello

# 実行結果
hello world!
```
hello world!が無事表示された。
次回はとりあえずhttpサーバを動かしてみようと思う。
Pythonで同じ文字（列）を複数回出力する

いろいろ方法あるみたいなので一例をメモ。

#環境
Python 3.7.2
Windows10 Home 1809
[WSL] Ubuntu 18.04.2 LTS (bash 4.4.20)


#実践
##ノーマルかつスタンダード
文字列にそのまま数字を掛ける。

```python
>>> print('無駄'*10 + 'ァッ！'))
無駄無駄無駄無駄無駄無駄無駄無駄無駄無駄ァッ！
```

##場所取りはしておきましたよ
`str.format()`で後ろから入れる。

```python
>>> print('{}ァッ！'.format('無駄'*10))
無駄無駄無駄無駄無駄無駄無駄無駄無駄無駄ァッ！
```
##ぱーせんと......？
`%` 以降のものを `%s` に同じ手口で入れる。

```python
>>> print('%sァッ！' % ('無駄'*10))
無駄無駄無駄無駄無駄無駄無駄無駄無駄無駄ァッ！
```

##ここまでやる必要はないと思う
リスト内包表記な`for`に`if`で分岐させる。

```python
>>> print(''.join([s if s != '無駄' else s*10 for s in '無駄,ァッ！'.split(',')]))
無駄無駄無駄無駄無駄無駄無駄無駄無駄無駄ァッ！
```

##上のやつなんか簡略化できた

```python
>>> print(''.join(['無駄' for s in range(10)]) + 'ァッ！')
無駄無駄無駄無駄無駄無駄無駄無駄無駄無駄ァッ！
```

##代入してみるのはいかがでしょう
`[:2]`とかの文字抜き出すときの指定が未だに覚えられない。

```python
>>> muda = '無駄ァッ！'
>>> print(muda[:2]*10 + muda[2:])
無駄無駄無駄無駄無駄無駄無駄無駄無駄無駄ァッ！
```

##10という数字を絶対に打ちたくない
`len`によるゴリ押し

```python
>>> muda = '無駄ァッ！'
>>> print(muda[:2]*int((len(muda)/len(muda)+len(muda)/len(muda))*len(muda))+muda[2:])
無駄無駄無駄無駄無駄無駄無駄無駄無駄無駄ァッ！
```

##筋肉は全てを解決する
コピー＆ペーストだッ！

```python
>>> print('無駄' + '無駄' + '無駄' + '無駄' + '無駄' + '無駄' + '無駄' + '無駄' + '無駄' + '無駄' + 'ァッ！')
無駄無駄無駄無駄無駄無駄無駄無駄無駄無駄ァッ！
```

##無限ループには気を付けよう！
一行で使う変数を準備できるのは便利ですね

```python
>>> muda, t = '', 0                                                                               
>>> while t != 10:
...     muda += '無駄'
...     t += 1
...
>>> print(muda + 'ァッ！')
無駄無駄無駄無駄無駄無駄無駄無駄無駄無駄ァッ！
```

##pythonから飛び出してmecabを使う(bash)
なんかコード量が3倍ぐらいになった

```bash
$ echo '無駄ァッ！'| mecab -Owakati | python3 -c "import sys; muda = sys.stdin.read().split(' '); print(muda[0]*10 + muda[1] + muda[2])"
無駄無駄無駄無駄無駄無駄無駄無駄無駄無駄ァッ！
```
API Gatewayで「Lambda プロキシ統合の使用」をしてる時のステータスコード指定

#統合レスポンスなんか選択できないんだけど！！！
#<img width="1415" alt="統合レスポンス" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430774/742203ec-11a9-6b3e-b5e8-4306d4fe987c.jpeg">
はい。大変困りました。統合レスポンスが無いとエラーコードを正規表現で仕分けできません。
原因はLambda プロキシ統合の使用です。
<img width="841" alt="統合レスポンス2" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430774/c75c7b05-3d7d-8dce-0160-c82fda4f08a1.jpeg">
原因がわかれば、一端それを切って見ましょう。
切りました
(望んでいないステータスで)***エラーでました***
<img width="792" alt="Gateway error" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430774/be31bbf9-cab0-6bc4-cb6b-3cd1b8de56e5.jpeg">
戻しましょう。
**プロキシ統合がなんか頑張ってくれてたおかげて私のAPIはエラー以外上手く言ってた事がわかりました**。できればそのままにしたいです。
#そもそもLambda側でエラーの出し方が間違ってるのでは?
<a href="https://qiita.com/_mogaming/items/3ea0bc1d93f6f5204d69">Amazon API Gatewayで適切なHTTPステータスコードを返す方法</a>や<a href="https://qiita.com/naoki_koreeda/items/5351f8ab803db655b0b4">[AWS] Lambda + API Gatewayでサーバレスを始める ２</a>、さらには<a href="https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/handle-errors-in-lambda-integration.html">API Gateway で Lambda エラーを処理する(公式ドキュメント)</a>を見た結果,

```index.js(lambda/nodejs/抜粋)
exports.handler = function(event, context, callback) {
    (略)
    callback(new Error(エラー文"));
};
```
みたいな事にするとエラーが作られるとの事。さっそく試してみましょう。
<img width="792" alt="Gateway error2" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430774/ea2781ec-f273-0ce1-63f2-5967406a5179.jpeg">
**だめでした**。また、このエラーで一緒に出ることを望んでいたエラー文も出ていません。
#解決
```index.js(lambda/nodejs)
(略)
let response = {
        statusCode: 400,
        headers: {"Access-Control-Allow-Origin" : "*"},
        body:"エラー文",
    };
}
callback(null,response);
```
シンプルにこれでOKでした。
<img width="792" alt="done" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430774/89ea5ada-18d9-471e-229f-92c66c484c63.jpeg">
ちゃんと400で返ってきてます。

エラーもプロキシ統合がなんか上手いことやってくれてるんでしょうね。便利！
計算量O(n)の画期的なソートアルゴリズムであるスターリンソートをHaskell で実装してみた #Haskell

皆さん、ソートは好きですか？
僕はHaskellerのクセにボゴソートが好きです。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ソートされていない要素を粛清することでO(N)でソートできるスターリンソートとかいうのを見て爆笑してる</p>&mdash; やんぎん (@4116You) <a href="https://twitter.com/4116You/status/1155619860027547648?ref_src=twsrc%5Etfw">July 28, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

なにやらTLでスターリンソートなるものが流行っていました。

まず`O(n)`とは何かという事なんですが、これはビッグ・オー記法と言ってアルゴリズムの性能の指標を表すものです。
`O(n)`の他に`O(1)`とか`O(log(n))`とか`O(nlog(n))`とか`O(n^2)`とかがありますが、詳しくは割愛します。[この辺](https://qiita.com/cotrpepe/items/1f4c38cc9d3e3a5f5e9c)を参考にするとよく分かると思います。ともかく、`O(n)`はむっちゃ速い、というか[ソートアルゴリズムではまず有り得ない](http://prpr.hatenablog.jp/entry/2015/06/04/ソートアルゴリズムが最善でO(nlog(n))になる話（笑）)です。

にも関わらず、スターリンソートはその壁を打ち破って、`O(n)`で並べ替えを実現しちゃうんですよね。

というわけでHaskellで実装

```StalinSort.hs
module StalinSort where

stalinSort              :: Ord a => [a] -> [a]
stalinSort []           =  []
stalinSort [x]          =  [x]
stalinSort (x : y : zs) |  x < y     = x : stalinSort (y : zs)
                        |  otherwise = stalinSort (x : zs)
```

こんな具合です。
実行結果は以下の通り。

```実行結果.hs
> stalinSort  [1, 2, 1, 1, 4, 3, 9]
[1,2,4,9]
```

どうですか？見事にソートされてますね。
ん？ `length xs == length $ stalinSort xs` が `False` になる？
知りませんよそんな事。言うこと聞かない方が悪いんです。


追記

どうやら[公式実装](https://github.com/gustavo-depaula/stalin-sort)を見ていると、前の要素と同じ場合は粛清しないみたいですね。

てなわけで修正版↓

```StalinSort.hs
module StalinSort where

stalinSort              :: Ord a => [a] -> [a]
stalinSort []           =  []
stalinSort [x]          =  [x]
stalinSort (x : y : zs) |  x <= y    = x : stalinSort (y : zs)
                        |  otherwise = stalinSort (x : zs)
```



<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">これ全部粛正すればO(1)では？ / “計算量O(n)の画期的なソートアルゴリズムであるスターリンソートをHaskell で実装してみた <a href="https://twitter.com/hashtag/Haskell?src=hash&amp;ref_src=twsrc%5Etfw">#Haskell</a> - Qiita” <a href="https://t.co/1S47ZL781D">https://t.co/1S47ZL781D</a></p>&mdash; ruichi (@ruicc) <a href="https://twitter.com/ruicc/status/1155827977923379200?ref_src=twsrc%5Etfw">July 29, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

なるほど、確かにそうすればO(1)という画期的なソートアルゴリズムができますね！

```StalinSort.hs
purgeAllStalinSort   :: [a] -> [a]
purgeAllStalinSort _ =  []
```

実行結果

```実行結果.hs
> purgeAllStalinSort [1..100000]
[]
```

できましたね。
Flutter upgradeでgit関連のエラーが出た場合の対処方法

#はじめに
Flutterの環境作成が終わったので少し動かしてみようかと思い、別のアプリで`flutter run`を実行したところ新しいバージョンが出たのでupgradeしてくれとの表示が出てきました。
その指示に従い`flutter upgrade`を実行したところ下記のエラーが発生しました。
このエラーを解決するまでに調べたことを備忘録として残そうと思います。
<img width="815" alt="upgradeエラー.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456358/52ccda21-d965-e144-da2b-7e34ee5fc1ef.png">

#環境
MacBook Pro 2018
macOS Mojave 10.14.5
Xcode 10.2.1
Android Studio 3.4.2
Flutter 1.7.8 (upgrade後のバージョンです...upgrade前のバージョンメモし忘れたorz)

#解決策
Flutter SDKを解凍したディレクトリで`git stash save` or `git checkout .`を実行し、環境をクリーンした後で再度`flutter upgrade`を行うと正常に動作します。

#なぜエラーが発生したのか？
##現状把握
Flutter SDKのディレクトリで`git status`を実行すると、身に覚えのない差分が表示されます。
Flutter SDKのインストールから`flutter upgrade`を実行するまでに行なった操作としては、Flutterのセットアップとエミュレータでのアプリ起動のみです。

##検証１(セットアップ作業の影響？)
セットアップ作業の影響で差分が発生しているなら差分をクリアした後に`flutter doctor`を実行すると出力が変わるかと思い試してみます。
コマンドとしては下記の順に実行しました。

```
$ git stash save
$ flutter doctor
```

結果としては`flutter doctor`の出力は変わりませんでした。
##検証2(アプリ起動時の影響？)
セットアップ作業の影響はなさそうという事が分かったので、次にエミュレータでアプリ起動をしてみます。
この予測は当たっておりアプリ起動後にFlutter SDKディレクトリ内で`git status`を実行すると差分が表示されるようになりました。
差分のパスをよく見てみると下記のようになっておりアプリ起動の影響でキャッシュのようなもの作成されたと考えられます。
...差分のパス最初からよく見ればよかった。
`dev/integration_tests/アプリ名`
#終わりに
Flutter SDK内の差分はアプリ起動時に作成されるキャッシュのようなので心置きなく`git checkout .`でクリーンできるようになりました。
キャッシュ的なものをSDK内部に作成するのあまりイケてない気がするので何とかならんものか...

余談ですが、`git stash save`で保存した差分をupgrade直後にpopするとコンフリクトしました。
キャッシュならupgradeと関係しないはずなのでぶつかる事もない気がするのですが何なんでしょうね...
popしなくてもアプリ起動は出来たのでこれ以上は調べませんが。
DjangoのUserPassesTestMixinを使って柔軟にアクセス制御する

## やりたいこと
Djangoでログインしたユーザーの情報を、自分自身のみが編集できるようにしたい。

Django組み込みのPermissionモデルを活用しようとしても、ログインしたユーザー自身に動的に制限をかけるのは相当難しそう。
そこで活用できるのが **UserPassesTestMixin** です。

## UserPassesTestMixinとは？
Django 1.9でリリースされた **Permission mixins for class-based views** に内包されている機能のこと。
公式ドキュメントでも丁寧に解説されています。
[Djangoの認証システムを使用する | Django ドキュメント | Django](https://docs.djangoproject.com/ja/2.2/topics/auth/default/)

## UserPassesTestMixinを使ってみる
百聞は一見にしかずということで例として、UserPassesTestMixinを使って **gmail.comドメインのユーザーのみがアクセスできるビュー** を定義してみます。

### UserPassesTestMixinの拡張
まずは下記のようにカスタムミックスインを定義します。

```python3
# mixins.py
from django.contrib.auth.mixins import UserPassesTestMixin

class OnlyGmailUserMixin(UserPassesTestMixin):
    raise_exception = True

    def test_func(self):
        return self.request.user.email.endswith('@gmail.com')
```

`test_func` というメソッドをオーバーライドして、そのメソッド内で条件分岐式を記述しておきます。
`test_func` の返り値で制限をかけるかかけないかが決まります。


### ビューの定義
そして、先ほど作成したカスタムミックスインを継承したクラスビューを定義します

```python3
# views.py
from django.contrib.auth.models import User
from django.views.generic import TemplateView

from .mixins import OnlyGmailUserMixin


class OnlyGmailUserView(OnlyGmailUserMixin, TemplateView):
    model = User
    template_name = "home.html"
```

以上です。めちゃ簡単！！！

## 自分自身のみが編集できるビューを定義する
当初の「Djangoでログインしたユーザーの情報を、自分自身のみが編集できるようにする」は UserPassesTestMixin を使うことで簡単に実装ができます。

```python3
# mixins.py
from django.contrib.auth.mixins import UserPassesTestMixin


class OnlyYouMixin(UserPassesTestMixin):
    raise_exception = True

    def test_func(self):
        user = self.request.user
        return user.pk == self.kwargs['pk']
```

```python3
# views.py
from django.contrib.auth.models import User
from django.views.generic import UpdateView

from .forms import UserForm # 別途フォームを定義しておく
from .mixins import OnlyYouMixin


class UserUpdateView(OnlyYouMixin, UpdateView):
    model = User
    template_name = "users/update.html"
    form_class = UserForm

    def get_success_url(self):
        return resolve_url('users:update', pk=self.kwargs['pk'])
```

## まとめ
最近になって初めてUserPassesTestMixinを使ってみましたが、簡単で応用の効くMixinで面白いですね。
ただ、複数のUserPassesTestMixinを継承できないようなので、その点は注意が必要です。

また、最後のOnlyYouMixinですが、これをUserモデル以外のモデルで使おうとするとPKが違ってうまくいかないので、もう少し処理を抽象化する必要がありそうです。
Laragonでウェブページを外部からアクセスできるようにする

* Laragon [download](https://laragon.org/download/index.html)

* 参考 [Nginx 403 Error (FIXED) | Laragon](https://forum.laragon.org/topic/448/nginx-403-error-fixed/6)

## ウェブページを外部からアクセスできるようにする

```diff:./laragon/etc/nginx/sites-enabled/00-default.conf
    # Access Restrictions
    allow       127.0.0.1;
-   deny        all;
+   #deny        all;
```

![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/6e36cb7f-9c45-1958-5035-e3c6cb8b197c.png)
![b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/a12ae4d1-2be9-ae16-6472-ffed06061b3e.png)
1人COBOL再研修〜INDEX〜

今まで書いた「1人COBOL再研修」という記事の目次です。自分がアクセスしやすいように作っただけです。

1. [基礎編](https://qiita.com/zama_8722/items/65935680e157de2c7927)
2. [基本構文編](https://qiita.com/zama_8722/items/90febb1e27c73aa20809)
3. [データ項目のあれこれ編](https://qiita.com/zama_8722/items/adf22305cbd9033dc87e)
4. [データ入出力編](https://qiita.com/zama_8722/items/e59f2f62aa921407b442)
5. [テーブル編](https://qiita.com/zama_8722/items/1e98148d1278c450c469)