OmniAICreator/Qiita-1.07M huggingface dataset:
[マニプロ]初めてのIo編

<b><a href="https://kyobankatu.hatenablog.com/about">はてなブログ</a>の記事をそのまま写しています</b>

マニアックプログラミング略してマニプロの３つ目の記事です！
マニプロでは不定期で、数日かけて有名では無いプログラミング言語の基礎の基礎を習得して皆さんに使いやすさなどを書いていこうと思ってます。
<b>注：ちょっと触ったくらいなので、誤った情報が混ざっている可能性があります</b>

#雑談(飛ばして構いません)
前回の記事からはや２ヶ月。。。
今世界がコロナで大変なことなってますね。株が大暴落したのが非常に怖いです。しかも特定の国とかではなく全世界でなので、、、
ただ、ここ数日は3/19辺りと比べると回復はしてるっぽいですがまだまだ低いです。
あと、志村けんさんの訃報も驚きました。

#本編
３回目の言語はIoです！
入出力を思い出すような名前ですが、なんか入出力に特徴があるんかと思ったんですが特に無いようです(笑)

#そもそもIoとは
オブジェクト指向型言語で、Steve Dekorteという方が友人と共にプログラミング言語の仕組みを勉強するために作った小さな言語らしいです。

因みに公式サイトがあるんですが、このサイトの雰囲気がめっちゃ好みです(笑)
[公式サイト](https://iolanguage.org/)

#Ioの特徴

###アクター
初め見たときナニソレオイシイノ状態だったんですが、調べたらなんとなく分かったような気がします。
アクターという処理を行うことで、親→子→その子・・・という風にオブジェクト(?)らしきものを沢山作り、それぞれにはメールボックスとアドレスがあります。そして、大量のメッセージ(命令)を一気に受け取ると溜まった分を子に送って処理させるんです。
つまり、並行処理に凄い向いている"仕組み"のことを言います。

#Ioを使ってみた
[実行環境構築](https://iolanguage.org/guide/guide.html#Introduction-Installing:title)
ここのDownloading,Installingから実行環境を入れてください。手順は物凄く少ないのでやり易い。あと、実行する時はターミナルで$io ほにゃららら.io で実行出来ます。

###まずはHello World
```io:Sample.io
"Hello World!" println
```
printlnが後ろにくると中々な違和感を感じますねw
あと、はてなブログはIoに対応してなかったのですが、Qiitaは対応してるんですね(笑)
すげー(小並感)

###1~5まで足す
```io:Sample.io
ans := 0
for(i,1,5,ans=ans+i)
ans println
```
forに{}が存在しないだとっ！？ 初めて見ましたw
これくらい簡単なプログラムならむしろJavaとかCとかよりも見易い？

###おみくじ
```io:Sample.io
rand := 0.5

if(rand<=0.3,"凶" println,
    if(rand<=0.8,"吉" println,"大吉"println)
)

/*
(rand<=0.3) ifTrue("凶" println) ifFalse(
    (rand<=0.8) ifTrue("吉" println) ifFalse("大吉" println)
)
こういう書き方もあります。
*/
```
乱数作ろうと思ったんですが、Ioは小規模にするのがモットーらしいので元からライブラリが殆ど入っていない状態らしいです。
Git HubからIoのアドオン(ライブラリ)を入れる手順がRead.mdに書いてあったのでやったんですが、明らかにアドオンはインストールされてるはずなのに実行しても「そんなオブジェクトはないゾ」って言ってくるんですよね。。。(多分俺が悪い) なので仕方なくrandには0.5を入れておきました。

で、肝心の書き心地ですが{}が無い分何重にも重なったifが出てくるとかなり見にくい。しかも処理を()内に書くのが特徴的。
でも、下のコメントの方はifTrueとかifFalseとか書いてるので分かりやすいかも。複雑になるとごっちゃごちゃになっちゃうけど(笑)

###リストで色々
```io:Sample.io
list := List clone append(10, 6, 15, 3 ,20) //list作成

list := list sort //ソートします
list println //list(3,6,10,15,20)

list remove(20) //20を消します(因みにリストに存在しない値を入れてもエラーとかは出ません)
list println

list := list(30, 10, 5, 20) select(%3==0) //3の倍数のみ抽出
list println

list := list map(i,i*2+1) //全ての要素を２倍して１足す
list println
```
めっちゃ色々出来るやん！！！ cloneでlistを作成するとは驚きです((((；ﾟДﾟ)))))))
あと、map,selectとかはかなり有能。foreach,filterが簡略化された感じですね。

#Ioを使ってみて
Ioの基礎だけやってみました。
想像してた以上のクオリティーでビックリしました(笑) 
あと、{}が無いだけでこんなにもスッキリするのか、、

という事で今回はこれで終了！ 最後に評価を書いておきます。
記事を読んで頂きありがとうございましたm(_ _)m

#評価
<b>注：自分が感じた評価ですので、酷評しても怒らないでください</b>
習得のしやすさ★★★★★☆☆☆☆☆(日本語の文献は無いので難しいが、tutorialは英語を読まなくても出来るので若干評価をあげました)

理解のしやすさ★★★★★★★★☆☆(C,Java・・などの有名言語とほぼ変わらないので、Io初見でも何をやりたいかくらいは分かる)

読みやすさ　　★★★★★★☆☆☆☆(スッキリ感と読みやすやは別で、{}が無いので見た目はスッキリしてるがどこに処理が書かれているかがちょっとわかりにくい)

書きやすさ　　★★★★★★★★☆☆("()"とか"{}"が最低限しか無いので、割と早く書けるかと)

実用性　　　　★★★☆☆☆☆☆☆☆(マニプロの評価の項目になぜこれを入れたのか過去の自分に問いかけたくなる。。ただ、この言語は環境構築も楽で見た目もスッキリしてて取っ付きやすいので初心者に「これがプログラミングだよ！楽しいでしょ？」って言うには丁度よさそうなので星３)

面白いか　　　★★★★★★☆☆☆☆(独特の書き方に面白さを感じました)

またやるか　　★☆☆☆☆☆☆☆☆☆(初心者に紹介する時は使うかも。でも個人では使わないかな。。)

#参考にしたサイト
https://ja.wikipedia.org/wiki/Io_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E8%A8%80%E8%AA%9E)
Nuxt.js で markdown-it 使用時にプラグインを導入して改行やリンクのターゲットをカスタマイズする

# 前提
- Nuxt.js で `@nuxtjs/markdownit` を導入して markdown 対応している
  - https://github.com/markdown-it/markdown-it
  - https://github.com/nuxt-community/modules/tree/master/packages/markdownit

# 動作確認
- 以下ページで動きを確認できます
  - https://yoshihiro-hirose.github.io/nuxt-vuetify-sample/samples/md

# やりたいこと
## テーブル内で改行したい!
- \<br> タグで改行するようにしたい
- markdown-it の標準機能にはないのでプラグイン導入で対応する
  - markdown-it-br を使う
  - https://www.npmjs.com/package/markdown-it-br
- `yarn add markdown-it-br` でモジュール追加
- markdown-it のドキュメントにもあるが use で使用するプラグインを設定する

```typescript:nuxt.config.ts
  markdownit: {
    省略: ...
    use: [
      'markdown-it-br'
    ]
  },
```

## リンクを別タブで開くようにしたい
- `linkify: true` でリンクを自動判別してくれる
- デフォルトは同じページに開くようになっている
- target=_blank のようにして別タブで開かせたい
- ~~markdown-it-external-links を導入して、設定を加える。~~
  - IE11 対応のため markdown-it-link-attributes を使うようにしました
  - https://www.npmjs.com/package/markdown-it-link-attributes
- `yarn add markdown-it-link-attributes` でモジュール追加
- ドキュメントにあるようにリンクの target を設定する。nuxt でのプラグインへのオプション設定方法は以下

```typescript:nuxt.config.ts
  markdownit: {
    省略: ...
    linkify: true,
    use: [
      'markdown-it-br',
      [
        'markdown-it-link-attributes',
        {
          attrs: {
            target: '_blank',
            rel: 'noopener'
          }
        }
      ]
    ]
  },
```

# サンプル
https://github.com/Yoshihiro-Hirose/nuxt-vuetify-sample
コンテナにリモートデスクトップ接続しようとしてlogin failed for display 0となった時の対応方法

- 環境
    - 接続元 : Windows10 64bit バージョン1909
    - 接続先 : Dockerで作ったコンテナ
        - ホスト : CentOS Linux release 7.6.1810 (Core)
        - コンテナ : CentOS Linux release 7.6.1810 (Core)

# 事象 : リモートデスクトップ接続しようとしたらダイアログが表示されてログインできない
```text:ダイアログのメッセージ
connectiong to sesman ip 127.0.0.1 port 3350
sesman connect ok
sending login info to session manager, please wait...
login failed for display 0
```

# 原因1 : 指定するポートが誤っていたから
コンテナには2つポートを開けていて`8082->8080`がリモートデスクトップ接続用だった。

```bash
$ docker ps
CONTAINER ID  IMAGE        COMMAND          CREATED       STATUS        PORTS                                             NAMES
123456789012  host-ponsuke "/usr/sbin/init" 9 months ago  Up 14 minutes 0.0.0.0:8082->8080/tcp, 0.0.0.0:8083->8081/tcp    ponsuke
```

そこで、リモートデスクトップ接続時に`ホストのIPアドレス:8080`を指定していた・・・コンテナ設定時に描いた絵を見て気が付いた・・・ポートがホストとコンテナで逆だ・・・
> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159761/3edd52cb-05fe-0659-f331-34da0f514ed2.png)
> [Dockerコンテナ上のTomcatに外部のブラウザからアクセスする方法 - Qiita](https://qiita.com/ponsuke0531/items/f75650d697a5b5329da8)

## 対応方法 : 正しいポートを指定してリモートデスクトップ接続する
1. `ホストのIPアドレス:ホストのリモートデスクトップ用ポート`(今回の場合`ホストのIPアドレス:8082`)でリモートデスクトップ接続する
2. 接続できる

# 原因2 : その他
- パスワードが誤っているときにもこのメッセージが出る
    - 正しいパスワードを忘れてしまった場合は、コマンドを使って`root`でコンテナにログインしてパスワードを変更してあげる
- `/var/log/xrdp.log` や `/var/log/xrdp-sesman.log` などのログを見てみる
- よくわからないときはとりあえずコンテナを再起動してみる
MS-Accessから、HerokuのPostgreSQLに、ODBC接続する

# 環境
Windows10
Access2010

# はじめに
Heroku上のPostgreSQLに、GUIで参照したい場合、PostgreSQLのクライアントツールであるpgAdminを使えばいいのだが、長年、SIerでエンジニアをしていた人であれば、MicrosoftのAccessでODBC接続して使えないものだろうかと考えるのは、全然不思議な話ではないのである。ググっても殆ど情報が見当たらなかったため、希少情報かも。


# Herokuでデータベース接続情報を確認する
- 先ずは、Herokuにログインして、データベースの接続情報を参照する。

- Herokuにログインした後、アプリの一覧から、参照したいアプリを選択する。

- 上にあるメニューから、**Resources**ボタンを選択する。

- **Add-ons**の中にある**Heroku Postgres**を選択する。

- 上にあるメニューから、**Settings**を選択する。

- **View Credentials**を選択すると、データベースの接続情報が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94029/d9d99c94-d2f1-caf7-e6c6-39bb70998b90.png)

# WindowsでODBCの設定を行う

- Windowsのコンパネから、**ODBCデータソース(32bit)**を選択する。

- ユーザーDSNのタブから追加ボタンを選択する。

- ドライバーの一覧から、**PostgreSQL ANSI**を選択する。
※Unicode版、ANSIx64版では上手く接続ができませんでした。
※PostgreSQLのドライバーが一覧のなければ別途インストールして下さい。

~~https://www.postgresql.org/ftp/odbc/versions/~~
https://www.postgresql.org/ftp/odbc/versions.old/msi/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94029/ee144178-0df7-b750-1c5a-0f091346d571.png)

- Herokuのデータベースの接続情報を、コピペで設定します。
　※PostgreSQLは標準でSSL接続をサポートしているため、**SSL Modeを無効**にすると上手く行きません。
　※オプション（高度な設定）で、データソース、全体設定の箇所はデフォルトのままでOK。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94029/cd4c6933-27e6-a536-0495-2f317e3a851d.png)

- テストボタンを押して、Connection Successfulが出てくればOK。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94029/b501bfd7-b8e2-c3f4-7c33-30fe24c02d23.png)

# Accessから接続する

- Accessを起動します。

- 外部データから、ODBCデータベースを選択する。

- 「リンクテーブルを作成してソースデータにリンクする」にチェックを付けてOK。

- コンピュータデータソースのタブから、herokuを選択してOK。

- Heroku上のPostgreSQLのテーブル一覧が表示されるので、リンクを張りたいテーブルを選択してOK。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94029/7ab343c5-fee7-d223-ae65-9bbc0e24ceb4.png)

- このように、リンクテーブルが張れました。中身もちゃんと参照できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94029/66cc5fcb-cb2d-5b35-a33c-9521022f4203.png)

# 補足
ODBC接続して、Herokuのテーブル一覧は表示されるが、その後、OKボタンを押すとエラーになる場合は、ODBCドライバーのバージョンが影響している場合があります。因みに、バージョン11ではエラーになりましたが、バージョン13のドライバーをインストールすると上手くいきました。
最新バージョンのドライバーはここからインストールして下さい。

~~https://www.postgresql.org/ftp/odbc/versions/msi/~~
https://www.postgresql.org/ftp/odbc/versions.old/
[jackson]JSONの値「0」「1」をbooleanとして受け取りたい

## 動機
* JAVA SpringBootを利用したWEBシステム
* JSON文字列を入力として用い、データを保持するオブジェクトに変換する
* JSONにおける「0」の値をfalse、「1」の値をtrueとしてbooleanに変換して受け取りたい。

## 参考
* https://stackoverflow.com/questions/34297506/how-can-i-serialize-de-serialize-a-boolean-value-from-fasterxml-jackson-as-an-in

## 概要
* JsonDeserializer<Boolean> を継承したデシリアライザクラスを作る
  * public static class になる
* @JsonDeserialize(using=作成したデシリアライザクラス.class) で指定する

### シリアライズとデリシアライズ
* シリアライズ
  * ソフトウェアが扱うオブジェクトを、文字列表現に変換すること。
  * オブジェクト→JSON。
* デシリアライズ
  * 文字列表現のデータを、ソフトウェアが扱うオブジェクトに変換すること。
  * JSON→オブジェクト


## サンプルコード

### パースしたいJSON
```json
{
    "name": "サンプルアイテム",
    "required": "1"
}
```

### データオブジェクト
* JSONが解釈、変換されてこのオブジェクトになる

```java
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
public class SampleItem {

  private String name;

  @JsonDeserialize(using=NumericBooleanDeserializer.class) // 下記で作成するデシリアライザクラス
  private boolean required;  // ここは boolean でよい。JSONに該当の値がない場合FALSEになる。
}
```

### デシリアライザ

```java
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;

import java.io.IOException;

/**
 * JSON文字列変換時の設定（Boolean）。
 * - 0 → false
 * - 1 → true
 */
public static class NumericBooleanDeserializer extends JsonDeserializer<Boolean> {
  @Override
  public Boolean deserialize(JsonParser parser, DeserializationContext context) throws IOException {
    return !"0".equals(parser.getText());
  }
}
```
ESLintで禁止構文を設定する

## はじめに

eslintで禁止構文を設定することで、CIでeslintを実行することで自動的に禁止構文を検出できるようにする

### 設定例

なにを禁止するかは個人や開発チームの方針などによっても変わってくることもあるはずなので、これは例です

```json:.eslintrc.json
{
  "rules": {
    "no-restricted-syntax": [
      "error",
      "TSEnumDeclaration",
      "TSInterfaceDeclaration",
      "ForInStatement",
      "ForOfStatement",
      "LabeledStatement",
      "WithStatement",
      "VariableDeclaration[kind='let']"
    ]
  }
}
```

### TSEnumDeclaration

enum使わなくてもとunion typeで足りるため
https://www.kabuku.co.jp/developers/good-bye-typescript-enum

### TSInterfaceDeclaration

typescriptの型定義を基本的にType aliasで統一する方針にしてるため

### ForInStatement, ForOfStatement, LabeledStatement, WithStatement 

https://github.com/airbnb/javascript/blob/master/packages/eslint-config-airbnb-base/rules/style.js#L334-L352

を参考にした

### VariableDeclaration[kind='let']

ES2015から変数定義は基本的にはconstが推奨されて、letを使う機会はほぼないため

## 禁止したい構文がある場合の構文の名前の調べ方

https://unpkg.com/browse/@babel/types@7.9.0/lib/index.d.ts

でbabelの型定義がみれる
Laravel ユーザIDを取得しようとしたらエラーが出た話

## 〜宣伝〜

:::note info
個人開発でエンジニア専門マッチングサービスを開発しましたので、是非未経験からエンジニア目指している人！現役エンジニアで教えたい人！使ってみてください！

β版リリース記念キャンペーン中です！

10名様限定、抽選でお好きな技術本1冊プレゼント！
🎉当選者にはメッセージ差し上げます(送付の際に住所はお聞きしません)
詳しくはこちらから↓

https://x.com/dokupro01/status/1796837336145436846
:::
https://dokupro.dev/

## 目的

- 初歩的であるがこれからもうっかり発生させそうなエラーなので解決方法を含めてまとめる

## 実施環境

- ハードウェア環境

| 項目 | 情報 | 備考 | 
| --- | --- | --- |
| OS | macOS Catalina(10.15.3) ||
| ハードウェア | MacBook  Air (11-inch ,2012) ||
| プロセッサ | 1.7 GHz デュアルコアIntel Core i5 ||
| メモリ | 8 GB 1600 MHz DDR3 ||
| グラフィックス | Intel HD Graphics 4000 1536 MB ||

- ソフトウェア環境

| 項目 | 情報 | 備考 |
| --- | --- | --- |
| PHP バージョン | 7.4.3 | Homwbrewを用いて導入 |
| Laravel バージョン | 7.0.8 | commposerを用いて導入 |
| MySQLバージョン | 8.0.19 for osx10.13 on x86_64 | Homwbrewを用いて導入 |

## エラー内容

- 下記の手順にしたがってAuthによるログイン機能を実装した。
    - [Mac Laravel 7 Authを用いたユーザ登録 ログイン ログアウトなどの機能を作成する
](https://qiita.com/miriwo/items/5d4a94e8d2aa06b61530)
- コントローラで現在ログインしているユーザのユーザIDを取得し紐づいているビューファイルで表示する処理を記載した。
- 下記にコントローラの内容を記載する。(名前領域userにあるhome.blade.phpのビューファイルを呼び出している。)

    ```php
    <?php
    
    namespace App\Http\Controllers;
    
    use Illuminate\Http\Request;
    
    class UserController extends Controller
    {
        public function home() {
            $user_id = Auth::id();
            return view('user.home', compact('user_id'));
        }
    }
    ```
- ブラウザで確認したところ下記のエラーが出力された。
    - 「Error Class 'App\Http\Controllers\Auth' not found」

        <img width="1791" alt="スクリーンショット 2020-03-30 13.58.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/6adbe345-3774-e98f-ba79-0183585b6988.png">
- not foundと言われているので確認してもAuthディレクトリは存在していた。

## 原因

- コントローラにて`Auth::id();`を用いてログイン中のユーザIDを取得する場合は当該コントローラの冒頭に下記の記載がないとユーザIDを取得するとこはできない。

    ```php
    use Illuminate\Support\Facades\Auth;
    ```

## 解決方法

1. コントローラのの冒頭部分に`use Auth;`の記載を追加する。
    - 下記に追加したあとのコントローラファイルの例を記載する。

        ```php
        <?php
    
        namespace App\Http\Controllers;
    
        use Illuminate\Http\Request;
    
        //下記の内容を追記する
        use Illuminate\Support\Facades\Auth;

        class UserController extends Controller
        {
            public function home() {
                $user_id = Auth::id();
                return view('user.home', compact('user_id'));
            }
        }
        ```
RaspberryPi Model 3B 上でpython3.8.1のgrovepi moduleがインストールできなかった（解決）


IoTなシステムを作ってて、RaspberryPi Model 3Bに挿したGrovePi+でセンサーやアクチュエータをpythonから操作する、という仕組みを作ろうとしたときに、つまずいたgrovepi moduleがインストール方法についてのメモ。

まず先に結論
 
#解決方法
 
```sh
$git clone https://github.com/DexterInd/GrovePi
$cd GrovePi/Script
$sudo chmod +x install.sh
$sudo ./install.sh
```

#以下試したことのログ

`pip install grovepi` だと以下のエラーになった

```sh
（略）
  error: Command "g++ （略）" failed with exit status 1
  ----------------------------------------
  ERROR: Failed building wheel for scipy
```

ここを参考に https://github.com/pydata/bottleneck/issues/281 したが同様のエラー

```sh
$pip install grovepi --no-use-pep517
（略）
    RuntimeError: Running cythonize failed!
    Cythonizing sources
    ----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
pip install --upgrade pip setuptools wheel
 （略）
Successfully installed setuptools-46.0.0 wheel-0.34.2

$pip install grovepi
同様のエラー
```

ここを参考に　https://teratail.com/questions/239230　したが同様のエラー

```sh
$sudo apt install libopenblas-dev
$sudo pip install pybind11
$pip install grovepi
同様のエラー
```

で、最初の結論に行き着いて解決した

## 補足

RPi moduleが無いというエラーが出るが、それは以下で解決

```sh
$pip install rpi.gpio

Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Processing /home/pi/.cache/pip/wheels/e9/28/be/151b023b334391106527be123557a1a9b99f6b19cbd1ce8b48/RPi.GPIO-0.7.0-cp38-cp38-linux_armv7l.whl
ERROR: grovepi 1.0.4 requires scipy, which is not installed.
Installing collected packages: rpi.gpio
Successfully installed rpi.gpio-0.7.0
```
【今日のアブストラクト】Squeeze-and-Excitation Networks【論文 DeepL 翻訳】

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

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

翻訳元
[Squeeze-and-Excitation Networks](https://arxiv.org/abs/1709.01507)

# Abstract

### 訳文

畳み込みニューラルネットワーク (CNNs) の中心的な構成要素は畳み込み演算子であり, 各層の局所的な受容野内の空間情報とチャネル情報の両方を融合させることで, ネットワークが情報量の多い特徴を構築することを可能にしている. 先行研究では, この関係の空間的要素を幅広く研究し, 特徴階層全体の空間エンコーディングの質を高めることで CNN の表現力を強化しようとしてきた. 本研究では, チャネル間の相互依存性を明示的にモデル化することで, チャネルごとの特徴応答を適応的に再調整する "Squeeze-and-Excitation" (SE) ブロックと呼ばれる新しいアーキテクチャユニットを提案する. これらのブロックを一緒に積み重ねて, 異なるデータセット間で非常に効果的に一般化する SENet アーキテクチャを形成できることを示す. さらに, SE ブロックがわずかな計算コストで既存の最先端 CNN の性能を大幅に向上させることを示す. Squeeze-and-Excitation Networks は, ILSVRC 2017 年分類の我々の提出物の基盤を形成し, $1$ 位を獲得し, トップ $5$ の誤差を $2.251\%$ に減少させ, 2016 年の受賞作品を $25\%$ 程度の相対的な改善で上回った. モデルとコードは[こちらの https URL](https://github.com/hujie-frank/SENet)で公開されています.


### 原文

The central building block of convolutional neural networks (CNNs) is the convolution operator, which enables networks to construct informative features by fusing both spatial and channel-wise information within local receptive fields at each layer. A broad range of prior research has investigated the spatial component of this relationship, seeking to strengthen the representational power of a CNN by enhancing the quality of spatial encodings throughout its feature hierarchy. In this work, we focus instead on the channel relationship and propose a novel architectural unit, which we term the "Squeeze-and-Excitation" (SE) block, that adaptively recalibrates channel-wise feature responses by explicitly modelling interdependencies between channels. We show that these blocks can be stacked together to form SENet architectures that generalise extremely effectively across different datasets. We further demonstrate that SE blocks bring significant improvements in performance for existing state-of-the-art CNNs at slight additional computational cost. Squeeze-and-Excitation Networks formed the foundation of our ILSVRC 2017 classification submission which won first place and reduced the top-5 error to $2.251\%$, surpassing the winning entry of 2016 by a relative improvement of ~$25\%$. Models and code are available at [this https URL](https://github.com/hujie-frank/SENet).
[GCS]よく使う gsutil コマンドメモ

Google Cloud Storageを操作で使用するgsutilコマンドの一覧です。
オプションなどの詳細は公式で確認されたし！

## バケットを作成する - mb
https://cloud.google.com/storage/docs/gsutil/commands/mb

##  デフォルト設定でバケットを作成する

```shell
gsutil mb gs://[BUCKET_NAME]
```

### ストレージクラスとロケーションを指定してバケットを作成する 

```shell
gsutil mb -c standard -l us-east1 gs://[BUCKET_NAME]
```

## バケットを削除する - rb
https://cloud.google.com/storage/docs/gsutil/commands/rb

```shell
gsutil rb gs://[BUCKET_NAME]
```

## オブジェクトのコピー - cp
https://cloud.google.com/storage/docs/gsutil/commands/cp

### オブジェクトのバケットへのアップロード
```shell
gsutil cp [OBJECT_NAME] gs://[BUCKET_NAME]
```

### バケットからオブジェクトをダウンロードする
```shell
gsutil cp -r gs://[BUCKET_NAME]/[OBJECT_NAME] .
```

## バケット内のフォルダにオブジェクトをコピーする

```shell
gsutil cp gs://[BUCKET_NAME]/[OBJECT_NAME] gs://[BUCKET_NAME]/folder-name/
```

## 一覧取得 - ls
https://cloud.google.com/storage/docs/gsutil/commands/ls

### バケットの一覧を取得する
```shell
gsutil ls
```

### バケットまたはフォルダの内容の一覧表示
```shell
gsutil ls gs://[BUCKET_NAME]
```

### オブジェクトの詳細を表示する
```shell
gsutil ls -l gs://[BUCKET_NAME]/[OBJECT_NAME]
```

## オブジェクトの削除 - rm 

### オブジェクト/フォルダを指定して削除する
```shell
gsutil rm gs://[BUCKET_NAME]/[OBJECT_NAME]

gsutil rm gs://[BUCKET_NAME]/[FOLDER_NAME]
```

### 指定フォルダ配下のオブジェクトを削除する
```shell
gsutil rm gs://[BUCKET_NAME]/*
```
サブフォルダ、サブフォルダ配下は削除されない。

### 指定フォルダ配下を全て削除する
```shell
gsutil rm gs://[BUCKET_NAME]/**
```

## バケット/オブジェクトのACLを設定する - acl
https://cloud.google.com/storage/docs/gsutil/commands/acl

### aclを取得する
```shell
gsutil acl get gs://[BUCKET_NAME]/[OBJECT_NAME]

gsutil acl get gs://[BUCKET_NAME]
```

### aclを設定する
```shell
gsutil acl set [FILE] gs://[BUCKET_NAME]
gsutil acl set [CANNED_ACL_NAAE] gs://[BUCKET_NAME]
```

### オブジェクトのaclを変更する - acl ch

#### アクセス権を付与する (全てのユーザにREADのロールを付与)
```shell
gsutil acl ch -u AllUsers:R gs://[BUCKET_NAME]/[OBJECT_NAME]
```

#### 付与したアクセス権を削除する
```shell
gsutil acl ch -d AllUsers gs://[BUCKET_NAME]/[OBJECT_NAME]
```

## 参考
https://cloud.google.com/storage/docs/gsutil
Laravel5.8:Passprot パーソナルアクセストークンのトークン持続時間が指定可能になっていた

# はじめに
LaravleでAPI認証を行うときにPassportを使用すると簡単に実装できます。
その中でアクセストークンは、ユーザー自身がトークンを発行してAPIを利用する仕組みです。

トークンの発行も[フロントエイド・クイックスタート](https://readouble.com/laravel/5.8/ja/passport.html#frontend-quickstart)が用意されているので簡単に実装できます。

# トークン接続時間が変更できない
ただ、トークンの持続時間には制限がありLaravel5.7までは1年間となっていました。
こちらに関してはドキュメントにも[パーソナルアクセストークン](https://readouble.com/laravel/5.7/ja/passport.html#personal-access-tokens)の箇所で説明されています。

>Note: パーソナルアクセストークンは常に長期間有効です。tokensExpireInやrefreshTokensExpireInメソッドを使用しても、有効期間を変更できません。

ここで、長期間有効とありますがこちらは、[トークン持続時間](https://readouble.com/laravel/5.7/ja/passport.html#token-lifetimes)のところでデフォルト一年間と記載されています。

Laravel5.7までは、有効期間を変更したくても出来ず1年間のうちにトークンの再発行が必要でした。

#Laravel5.8から指定が可能に
Laravel5.8になってからは、**personalAccessTokensExpireIn**メソッドを使用することで有効期限を自由に設定出来るようになりました。

**AuthServiceProvider**の**boot**メソッドで**personalAccessTokensExpireIn**メソッドを呼び出すだけです

```
public function boot()
{
	$this->registerPolicies();

    Passport::routes();
	// 10年間トークンを持続させる
    Passport::personalAccessTokensExpireIn(now()->addYears(10));
}
```

これで期間を気にすることなくAPIを利用することが可能になります。

ちなみに **oauth_access_tokens** テーブルに**expirse_at**というカラムに期限がありますが変更しても期限には影響がありません。
トークンのハッシュ内に期限が含まれていると思われます。
独自プロパティリスト（plist）を利用する

iOSアプリで独自plist(プロパティリスト）を作って使いたい時のメモ。
※よくある、APIのURLとかその他アプリに特化した設定などに使用
※他の方がわかりやすく書いてくれているのもあるのでメモ程度

## plistの作成
まずはお目当てのplistを作成します。

* File→New→File（cmd+N)で新規作成画面を表示
* Property Listを選択、名前(今回はApp.plist)を決めて作成

作成できたら、適当に値を設定しましょう。
今回はよくあるURLを記載します

## 作ったplistの読み込み
先程作ったApp.plistを読み込むコードが以下になります。

```swift
var property: Dictionary<String, Any> = [:]
// App.plistのパス取得
let path = Bundle.main.path(forResource: "App", ofType: "plist")
// App.plistをDictionary形式で読み込み
let configurations = NSDictionary(contentsOfFile: path!)
if let datasourceDictionary: [String : Any]  = configurations as? [String : Any] {
    property = configurations
}
// キーを指定して、値の取得
let url = property["url"] as! String
print(url)
```

## データ取得部分も含めてクラス化
読み込み、データ取得を毎度書くのは無駄よってことで
クラス化します。

```swift:App.swift
class App {
    var property: Dictionary<String, Any> = [:]
    init() {
        // App.plistのパス取得
        let path = Bundle.main.path(forResource: "App", ofType: "plist")
        // App.plistをDictionary形式で読み込み
        let configurations = NSDictionary(contentsOfFile: path!)
        if let datasourceDictionary: [String : Any]  = configurations as? [String : Any] {
            property = datasourceDictionary
        }
    }

    /// 指定されたキーの値を取得する
    /// - Parameter key: plistのキー
    func getString(_ key: String) -> String? {
        guard let value: String = property[key] as? String else {
            return nil
        }
        return value
    }
}
```

さて、これで利用できるようになりました。
では実際に呼び出してみましょう。

```swift
var app = App()
print(app.getStirng("url"))
```

## Appクラスをシングルトンにしてみる
シングルトンにすることで、読み込みを一回だけにしてあとはインスタンス再利用する形にします。
以下コードを追加

```swift
static let shared: App = {
    let instance = App()
    return instance
}()
```
全体

```swift:App.swift
class App {
    var property: Dictionary<String, Any> = [:]
    static let shared: App = {
        let instance = App()
        return instance
    }()
    private init() {
        // App.plist取得
        let path = Bundle.main.path(forResource: "App", ofType: "plist")
        let configurations = NSDictionary(contentsOfFile: path!)
        if let datasourceDictionary: [String : Any]  = configurations as? [String : Any] {
            property = datasourceDictionary
        }
    }

    /// 指定されたキーの値を取得する
    /// - Parameter key: plistのキー
    func getString(_ key: String) -> String? {
        guard let value: String = property[key] as? String else {
            return nil
        }
        return value
    }
}
```
さて、これで利用方法を変更します。

```swift
var app = App.shared
print(app.getStirng("url"))
```

これでアプリ独自プロパティも怖くない！！
次回は、これを環境別に設定できるようにしたいと思います。

## 参考
[Swift で簡単なシングルトンの実装方法](https://qiita.com/codelynx/items/a936afe0a45d4cf5abfb)
[Swiftでplistを読み込む](https://qiita.com/nameless_aspen/items/40e8f92308e062644a43)
JavaScriptの配列とオブジェクト操作


# 配列操作


```javascript

  const a = [1, 2, 3, 4, 5];
  const b = [6, 7, 8, 9, 10];

  //配列の結合
  const c = [...a, ...b];
  
  //分割代入
  const [d, e, f] = a
  
  //rest構文
  const [g, h, ...i] = a
  
  
  console.log(...a); // 1 2 3 4 5
  console.log(c); // [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
  console.log(d, e, f); // 1 2 3
  console.log(g, h, i); // 1 2 [ 3, 4, 5 ]
  
  
  //値の交換
  let [x,y,z] = [1,2,3]
  console.log(x,y,z); // 1 2 3
  
  [x, y, z] = [y, z, x];
  console.log(x, y, z); // 2 3 1
 
```

## 参照渡したくない場合

```javascript
  const a = [1, 2];
  
  const b = a;
  const c = [...a];
  
  a[0] = 3;
  
  console.log(b); // [3, 2]
  console.log(c); // [1, 2]
```

## 配列操作のメソッド

![2020-04-01_09h18_38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/cd7697e5-2ab9-9c61-0848-bc2ffa39b0f7.png)


splice(開始する位置, 削除数 [, 追加する要素, ...])




# オブジェクト操作


```javascript

  const a = {c: 1, d: 2, e: 3};
  
  //オブジェクトの結合
  const b = {...a, f: 4, g: 5};
  
  //分割代入,存在しないキーを指定するとエラーになる
  const {c, d, ...h} = b;
  
  console.log(b); // { c: 1, d: 2, e: 3, f: 4, g: 5 }
  console.log(c, d, h); // 1 2 { e: 3, f: 4, g: 5 }
  
  //キーを取り出す方法
  const i = Object.keys(b);
  console.log(i); // [ 'c', 'd', 'e', 'f', 'g' ]
  
  //キーと値を表示
  for(let key of i)　console.log(`key:${key} value:${b[key]}`);
  /*
  key:c value:1
  key:d value:2
  key:e value:3
  key:f value:4
  key:g value:5
  */
```
Jamstack　Docker + Nuxt + Contentful + Vuetify + Netfliyでポートフォリオ作成①

# やりたいこと
- Nuxtでフロントを作成
- Dockerで環境構築
- Contentfulでポートフォリオ情報の取得
- Vuetifyで見た目整形
- Netfliyで公開

# 前提
・Nuxt環境
　参考：https://blog.cloud-acct.com/posts/blog-nuxtjs-settings/

・Docker環境
　参考：https://qiita.com/kurkuru/items/127fa99ef5b2f0288b81

###それでは行ってみよう！
## Nuxtでフロントを作成

```
npx create-nuxt-app my_portfolio
✨  Generating Nuxt.js project in my_portfolio
? Project name my_portfolio
? Project description My kryptonian Nuxt.js project
? Author name Naoya Moriguchi
? Choose programming language TypeScript
? Choose the package manager Npm
? Choose UI framework Vuetify.js
? Choose custom server framework None (Recommended)
? Choose the runtime for TypeScript @nuxt/typescript-runtime
? Choose Nuxt.js modules Axios, Progressive Web App (PWA) Support, DotEnv
? Choose linting tools ESLint
? Choose test framework None
? Choose rendering mode Universal (SSR)
? Choose development tools (Press <space> to select, <a> to toggle all, <i> to invert selection)

```

## Dockerで環境構築
```
# Dockerfile
FROM node:12
ENV HOST 0.0.0.0
COPY . /app
WORKDIR /app
```
今回はnode12に設定

```
# docker-compose.yml
version: '3'

services:
  nuxt:
    build:
      context: ./
    container_name: node12_portfolio
    volumes:
      - ./:/app
    ports:
      - "3000:3000"
    command: bash -c "npm install && npm run dev"

```

はい。これで、

```
docker-compose up
```

これで、環境完成！！
http://localhost:3000/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166346/3583fd52-c12d-a761-d265-4a3dc6450be9.png)

#Contentfulでポートフォリオ情報の取得
- Content Model
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166346/52246951-538c-4728-bfc5-e221743deb4d.png)

---
- Category
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166346/5bb9c1a8-0a41-be75-76c2-a6a0c00c2f07.png)

---
- Tags
- ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166346/c3a42abc-3e60-6c7d-98f1-336628af0f59.png)

---
- Tasks
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166346/4eebeda0-54ee-f891-78b9-6d175ed5581e.png)

---
- Works
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166346/5db8d577-326c-2a7d-46df-1b20cb6f285c.png)



## 次回は、、、
- NuxtとContentfulの連携部分
- Vuetifyで見た目整形
- Netfliyで公開
#Rails / ActiveRecord / 複数形の validates メソッドと 単数形の validate メソッドの違いは？ 前者が標準のvalidatorで後者がカスタムのvalidator。

びっくりするぐらい分かりにくいが、きっと命名的に苦慮の末だったのだろう。

# validates (標準)

おなじみのやつ。

![image](https://user-images.githubusercontent.com/13635059/77970201-91c85c00-7326-11ea-86e2-25e2c63c85b0.png)

# validate (カスタム)

こちらは自分でModelにメソッドを作って、ちっちゃなカスタムバリデーターを作る。


[Active Record Validations — Ruby on Rails Guides](https://guides.rubyonrails.org/active_record_validations.html#custom-methods)

![image](https://user-images.githubusercontent.com/13635059/77970138-647bae00-7326-11ea-888e-62d589810171.png)


# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/3057








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
ソフトウェアテスト技法練習帳 ~知識を経験に変える40問~の練習問題①

#元ネタ
[ソフトウェアテスト技法練習帳 ~知識を経験に変える40問~](https://www.amazon.co.jp/%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%83%86%E3%82%B9%E3%83%88%E6%8A%80%E6%B3%95%E7%B7%B4%E7%BF%92%E5%B8%B3-%E7%9F%A5%E8%AD%98%E3%82%92%E7%B5%8C%E9%A8%93%E3%81%AB%E5%A4%89%E3%81%88%E3%82%8B40%E5%95%8F-%E6%A2%85%E6%B4%A5-%E6%AD%A3%E6%B4%8B/dp/429711061X)

#①チワワ用の温度計の問題


寒いと表示：24度以下
快適と表示：24度～26度以下
暑いと表示：26度以上

##自分の答え
境界値
・寒い＝24.0度と23.9度
・暑い＝25.9度と26.0度

有効同値
・快適＝25.5度

快適の境界値は暑いと寒いで担保出来る認識



#②キッチンスケールの問題

0～2000gまで1g単位で測れる
それ以上・マイナスだとエラーが表示される

##元々の勘違い
何故かマイナスを小数点と勘違いしていた
　⇒何でや:thinking:

##自分の答え
境界値
☆2000gと2001g
☆0gと-1g(最初は勘違いして0.1gと書いた)

有効同値
☆0g以下＝-50g(最初は勘違いして0.5gと書いた)
☆0～2000g＝1000g
☆2001g以上＝2050g
EdgeHTML の browser API 不具合集 (2020年4月)

#概要
EdgeHTM エンジン版 Edge の browser/chrome API の不具合の覚え書き。
Chrome (V8 8.0.426 / Blink 80) で普通に動作するかどうかを基準に判断。
Chromium エンジン版 Edge は未検証。
<FONT COLOR=#ccc>~~どうせ Chromium に移行するつもりだったからなのか EdgeHTML は色々ガバガバ。~~</FONT>
※ browser/chrome API のほぼ全ての非同期関数は、最終引数に関数を渡せばコールバック型で利用できる。また、Chrome でも「Promise を return する事になっているが実はコールバック型でしか使えない関数」が幾つか存在する (具体例要追記)。MDN (英語版しか読んでいないが) ではそれらに関する記述がほぼ皆無なので要注意。

##検証環境
- 2020年4月時点
- Windows 10 Pro x64
- Microsoft Edge 44.18362.449.0 (EdgeHTML 18.18363 / ChakraCore 1.11.15)
- 下記のモンキーパッチ(?)を適用.
- `chrome` は `browser` と同義

```javascript:background.js/content.js
if(/edge/i.test(window.navigator.userAgent)){
    window.chrome = window.browser;
    console.log('EdgeHTML SUCKS!!!');
}
```

##Microsoft Edge の長所
ブラウザ拡張機能開発において Edge を使う利点は **content script の変更が即時反映される**点。ただこの一点に尽きる。
Chrome では拡張機能自体を「更新」しなければ content script の変更が反映されない上、「更新」しても content script や各種リソースの変更が反映されないバグがある為、変更を加える度にブラウザを再起動する必要がある。
これに対して Edge は、content script を変更してから対象URLのページをリロードすれば即座に新しい content script が適用されるのでデバッグが非常に楽。

#非同期関数は Promise ではなく undefined を返す
見出しの通り。なので、Chrome では then でチェーン出来る関数(メソッド)でも、Edge では **絶対に** 直接チェーン出来ない。
本来 Promise を返すことになっているメソッドは、最後の引数にコールバック関数を入れて使う。
(失敗判定は `try...catch` や `chrome.runtime.lastError` または `chrome.extension.lastError` などで行う。)

```javascript:background.js
// [エラーになる例]
chrome.tabs.query({'url':'https://qiita.com/*'})
    .then(tabs=>console.log(tabs.length));
//"Error: Invocation of form tabs.query(object) doesn't match definition tabs.query(object queryInfo, function callback)."

// [上手くいく例]
chrome.tabs.query(
    {'url':'https://qiita.com/*'},
    tabs=>console.log(tabs.length)
);
 //1
```

#background script が cross origin 非対応
例えば background script で WebSocket を開こうとすると「Access-Control-Allow-Headersがないです～:stuck_out_tongue_winking_eye: べろべろば～:stuck_out_tongue:」などのエラーを吐く。
Fetch や XHR は未検証だが同じだろう。
Chrome では問題なく接続できる。
<FONT COLOR=#8bd>_generated_background_page.html のヘッダーを生成しているのは Edge の拡張機能管理機能なので、恐らく回避は不可能。</FONT>

#比較的重要なメソッドが初めから存在しない
- `chrome.tabs.connect` がない為、background script → content script の port 接続ができない.

他にもあったけど忘れたので後日追記.

#native messaging が異常に難しい
普通の (Edge 以外の) ブラウザでは比較的容易に 拡張機能 <―> ネイティブアプリ間通信 (native messaging) を実装できる。
いくつかの設定ファイルを用意して少しレジストリを弄るだけなので、テキストエディタさえあればいい。
これに対して Edge で native messaging を実装するには、**絶対に最新の Visual Studio を使わなければならない**。
<FONT COLOR=#8bd>Edge では、拡張機能とネイティブアプリの通信は特別なプロトコル (AppService) を用いる。そのプロトコルに対応するアプリケーション (UWP application) は Visual Studio でしか作成できない (Visual Studio でセキュリティートークンを発行しないと AppService を起動できない)。</FONT>
ネイティブアプリの代わりにローカルサーバーを立てて WebSocket や Fetch で通信しようとしても、前述のように「cross origin access forbidden :hugging:」とか言われる。
**EdgeHTML 版 Edge での native messaging は潔く諦めた方がいい**。
どうしてもやりたいなら Chromium 版 Edge に切り替えよう。
最終決定！「でも」とか「やっぱり」は許さん！二度と試すな！EdgeHTML SUCKS!!!!
ソースと出力が同じC#プログラム

# 初めに

エイプリルフールだけどネタを準備していなかったので 10年前にやったネタの再掲。

# ソースと出力が同じ C#プログラム

``` FixedPoint.cs
using System;

namespace FixedPoint
{
    class Program
    {
        static void Main(string[] args)
        {
            string strX = @"using System;

namespace FixedPoint
{
    class Program
    {
        static void Main(string[] args)
        {
            string strX = @""[X]"";
            Console.Write(strX.Replace(""["" + ""X"" + ""]"", strX.Replace(@"""""""",@"""""""""""")));
        }
    }
}
";
            Console.Write(strX.Replace("[" + "X" + "]", strX.Replace(@"""",@"""""")));
        }
    }
}
```

# 解説っぽくない解説

このプログラムは再帰定理(再帰関数は再帰を使わない形で記述できる)の証明を参考にして作ったと記憶している。


# 発表元

[「NaruTo の 御家」-「計算機譜表工房」-「ソースと出力が同じプログラム at C#」](https://miko.org/~naruto/Artifact/CSharpFixedPoint.html)
Ubuntu 20.04 で 古いサーバーにssh接続がエラーで接続できない場合

## 参考

* [macでssh接続をしたときno matching key exchange method found. Their offer: diffie-hellman-group1-sha1と言われて接続できない - しまむーの備忘録](http://shsm385.hatenablog.com/entry/2018/10/17/161258)

## 対応

> Unable to negotiate with UNKNOWN port 65535: no matching key exchange method found. Their offer: diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1

```diff
 Host oldserver
+    KexAlgorithms +diffie-hellman-group1-sha1
Visual Studio設定 メソッド毎に線で区切る

# 設定箇所

`ツール` - `オプション`でオプション画面を開く。
左のツリーを`テキストエディター` - `C#` - `詳細`と展開して`アウトライン`グループの
`プロシージャ行の区切り記号を表示する`にチェックを入れる。

![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/1673a2ef-c391-f8a1-9084-a72e14732a5f.png)

# チェックOFF/ON

![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/bd430bbb-80eb-712a-33c6-a5870d3bad17.png)
メモ: certbot

* [実サーバー無しでLet's Encryptの証明書を発行する - APC 技術ブログ](https://techblog.ap-com.co.jp/entry/2019/03/26/113446)

## DNSサーバーレコードを編集できる場合 (manual)

```shell:manual
sudo docker run -it --rm \
 --name certbot \
 -v "/etc/letsencrypt:/etc/letsencrypt" \
 -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
 certbot/certbot certonly \
 \
 --manual \
 --domain *.mydomain.jp \
 --email root@mydomain.jp \
 --agree-tos \
 --manual-public-ip-logging-ok \
 --preferred-challenges dns \
 --server https://acme-v02.api.letsencrypt.org/directory
```

## DNSサーバーレコードを編集できない場合 (standalone)

```shell:standalone
sudo docker run -it --rm \
 --name certbot \
 -v "/etc/letsencrypt:/etc/letsencrypt" \
 -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
 certbot/certbot certonly \
 \
 --standalone \
 --domain *.mydomain.jp \
 --email root@mydomain.jp \
 --agree-tos \
 --manual-public-ip-logging-ok \
 --preferred-challenges dns \
 --server https://acme-v02.api.letsencrypt.org/directory
```
position：relative・absoluteの使い方

###position→要素の位置を決めるためのもの

###:shamrock:relative：
現在の位置を基準に相対的な位置を決める


###:shamrock:absolute：
親要素を基準に絶対的な位置を決める
:arrow_forward:絶対的というのは他の要素や余白の有無など他のものに影響されることなく、
その位置に絶対に配置されるということ



##＜使い方＞
①親要素をposition:relativeにして、現在の位置に堂々といてもらう

②動かしたいやつをposition:absolute;にして、親要素基準の位置をtopとかできめる
ブランドストーリーとは何ですか？


ブランドストーリーは、コンテンツと物語以上のものです。ストーリーは、ウェブサイトのコピーで書かれたもの、パンフレットのテキスト、または投資家や顧客に売り込むために使用されるプレゼンテーションを超えています。あなたのストーリーは、あなたが他の人に伝えるものではなく、ブランドが発信するシグナルに基づいて、彼らがあなたを信じていることでもあります。ストーリーは、事実、感情、解釈で構成された完全な絵です。つまり、ストーリーの一部はあなたによっても語られていません。

パッケージや名刺の色や質感から、採用するスタッフまで、ビジネスやブランドの各要素を行うすべてのことは、ブランドストーリーの一部であり、すべての要素は、ブランドについての真実を聴衆に反映させる必要があります。

成功し、持続可能なビジネスと忠誠心を獲得するブランドを構築したい場合、そして幸運に愛されたなら、ストーリーから始める必要があります。

伝えるストーリーが必要な理由
ストーリーがない場合は、あなたは単なる別の商品です。消費機の交換可能な歯車。ブランドやビジネスを差別化する方法はありません。ブランドストーリーを作成することは、単に目立ち、注目を集めることではありません。それは、人々が気にして買いたいものを構築することです。それはあなたの不足をフレーミングし、あなたの価値を決定することです。それは、製品とサービスの実用性と機能性を超えて考え、顧客との忠誠心と有意義な絆を築くために努力することです。

ブランドストーリーは、1〜2週間注目を集めるために看板に貼り付けられるキャッチーなキャッチフレーズではありません。あなたのストーリーはあなたのブランドの基礎であり、将来の成長のための戦略です。

ストーリーは、スターバックスがまったく新しいコーヒーカテゴリを作成し、競合他社を上回った方法です。その話が、私のクライアントであるケリーが4キロを走り、ダンキンドーナツとセブンイレブンを通過して、毎朝1杯のコーヒーに3回以上支払うための理由です。



スターバックスは単にコーヒーをプレミアム価格で販売するだけではなく、その使命を「3位」にすることでした。スターバックスやアップルのようなブランドは、それらの製品の実用性と仕様以上のものに基づいて構築されています。あなたの製品は物語のほんの一部です。潜在的な顧客とブランドとの関係は、実際に製品を購入する前に始まる可能性があります。
OracleからPostgreSQLへの移行（#NULLと空文字の違い）

# 空文字の扱い 	

Oracleでは自動的に空文字（""）を nullに変換しますが、PostgreSQLではnullに変換しません。
つまり、PostgreSQLでは空文字（""）とnullは別の値として扱われます。
そのため、システムが使用するDBをOracleからPostgreSQLに変更する場合は、その違いを意識してSQLを修正する必要があります。

実際にどのような動きをするか、Oracle、PostgreSQLの場合それぞれで試してみます。

# Oracleの場合

まず、null, '', 文字列の3レコードを作成します。

```sql
SQL> create table test_oracle (
  kind varchar2(10),
  txt varchar2(10)
);
表が作成されました。
SQL> insert into test_oracle values('null', null);
1行が作成されました。
SQL> insert into test_oracle values('empty', '');
1行が作成されました。
SQL> insert into test_oracle values('aaa', 'aaa');
SQL> commit;
コミットが完了しました。
```

以下のように検索すると
　is null：2件
　is not null: 1件
　= '': 0件
となります。

Oracleでは''はと同じ扱いになるので、is nullが2件になっています。

```sql
SQL> select * from test_oracle where txt is null;

KIND       TXT
---------- ----------
null
empty

SQL>  select * from test_oracle where txt is not null;

KIND       TXT
---------- ----------
aaa        aaa

SQL> select * from test_oracle where txt = '';

レコードが選択されませんでした。
```


# PostgreSQLの場合

Oracleの場合と同様にnull, '', 文字列が3レコードを作成します。

```sql
postgres=# create table test_postgres (
  kind varchar(10),
  txt varchar(10)
);
CREATE TABLE
postgres=# insert into test_postgres values('null', null);
INSERT 0 1
postgres=# insert into test_postgres values('empty', '');
INSERT 0 1
postgres=# insert into test_postgres values('aaa', 'aaa');
INSERT 0 1
```

以下のように検索すると検索すると
　is null：1件（Oracleは2件）
　is not null: 2件（Oracleは1件）
　= '': 1件（Oracleは0件）
となります。

Oracleと結果が異なることが分かります。

```sql
postgres=# select * from test_postgres where txt is null;
 kind | txt 
------+-----
 null | 
(1 row)

postgres=# select * from test_postgres where txt is not null;
 kind  | txt 
-------+-----
 empty | 
 aaa   | aaa
(2 rows)

postgres=# select * from test_postgres where txt = '';
 kind  | txt 
-------+-----
 empty | 
(1 row)
```

# SQLの変更

PostgreSQLでOracleと同じ結果を得るためには以下のようなSQLとなります。

```sql
postgres=# select * from test_postgres where coalesce(txt::text, '') = '';
 kind  | txt 
-------+-----
 null  | 
 empty | 
(2 rows)

※coalesce：NULLを別の値に置換する。

postgres=# select * from test_postgres where txt is not null and txt::text <> '';
 kind | txt 
------+-----
 aaa  | aaa
(1 row)

もしくは

postgres=# select * from test_postgres where nullif(txt, '') is not null;
 kind | txt 
------+-----
 aaa  | aaa
(1 row)
```
【Day41】積み上げ日記

##予定
■JavaScript
−アロー関数

##完了
■JavaScript
−アロー関数（途中）

■CSS
−transform
-transition
-hover

##学習時間
２h

##学習ポイント
・getElementByIdとは？
－この要素を取得しますよ→（id名)

・addEventListenerとは？
－このターゲットが（id名）された時に、次のアクション指定

■アロー関数
function の代わりに用いる時もある。

ダブルクオーテーションでOK

■JSが上手く反映されない時は、デヴェロッパーツールのコンソールで確かめる。

■transform
○よく指定される値
・trasnlate（移動）
・scale（縮尺）
・rotate（回転）

■transition
・hoverと一緒に使う！
→処理が終わったら（hoverの場合はマウスが離れたら）、元の状態に戻る。

■hover
・マウスを置いたら、処理される。
・hover後にどういう変化をさせたいかをstyle指定する。

■疑問点
・配列とは？
−情報を記憶するための箱である変数の1つ
−最も利用頻度が多いのは、繰り返し処理

・windowとDocument

##計画通り進んだか？
進んだ。JSの全体像→中身に取り組む順序で進めているが、大枠はざっくり理解できた。
【Day40】積み上げ日記

##予定
■JavaScript
−Ajax
−JSON
−DOM操作

##完了
■JavaScript
−Ajax
−JSON
−DOM操作

##学習時間
２h

##学習ポイント
■バックエンドの仕事
WEBAPIを作ること

■JavaScriptの仕事
①データのやり取り
②DOMの操作

①データのやり取り
・パース：JSON→HTMLに変換すること
－JSON状態だとWEBに反映されない→HTML状態にする
・パースをしていく作業：DOM操作

②DOM操作
・HTML上の［０］→１としてカウントされる

■プロパティやメソッドにアクセスする方法
・ドットを用いたアクセス（推奨）
・角括弧を用いたアクセス

■”use strict”;
ブラウザが厳密なエラーチェックをしてくれる

■scriptからdivを指定したい時
・div に id をつける

■疑問点
・配列とは？
−情報を記憶するための箱である変数の1つ
−最も利用頻度が多いのは、繰り返し処理

・windowとDocument

##計画通り進んだか？
進んだ。JSの全体像→中身に取り組む順序で進めているが、大枠はざっくり理解できた。
初心者によるプログラミング学習ログ 278日目

#100日チャレンジの278日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
278日目は、

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>278日目　1.0h<br>・xdデザインカンプからのサイト模写<br>・お問い合わせフォーム<a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a><a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1245078667283185664?ref_src=twsrc%5Etfw">March 31, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Rust でぽりもーふぃずむった

trait でオブジェクト指向っぽいことをしよう

```rust
use std::io;

trait Animal {
  fn get_num(&self) -> u64;
}

struct Cat {
  num: u64,
}

struct Dog {
  num: u64,
}

impl Animal for Cat {
  fn get_num(&self) -> u64 {
    println!("Cat");
    self.num
  }
}

impl Animal for Dog {
  fn get_num(&self) -> u64 {
    println!("Dog");
    self.num
  }
}

fn main() {
    println!("1:Cat, 2:Dog");
    let mut input = String::new();
    io::stdin().read_line(&mut input).expect("failed");
    let input = input.trim();

    let cat = Cat{num: 1};
    let dog = Dog{num: 2};

    let animal: &dyn Animal = match input.as_ref() {
      "1" => &cat as &dyn Animal,
      "2" => &dog as &dyn Animal,
      _=> panic!("error"),
    };

    println!("num: {}", animal.get_num());
}
```
WebFluxのセッションを実装してみる

引き続きWebFluxの話です。
今回はWebFluxでのSessionの使い方を紹介します。
なお、ここで紹介するのは最小構成のRedisを使わないインメモリの実装例です。

# サンプルの環境
- Java 8
- Spring Boot 2.2.6

# プロジェクトのビルド構成
Mavenの場合、[基本編のビルド構成](https://qiita.com/kilvis/items/fb18be963da6cac03ee9#%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E4%BD%9C%E6%88%90)に以下のdependencyを追加します。

```xml:pom.xml
〜　省略　〜
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-core</artifactId>
</dependency>
```
Gradleの場合は以下のdependenciesを参考にしてください。

```gradle:build.gradle
〜　省略　〜
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-webflux'
    implementation 'org.springframework.session:spring-session-core'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
}
```

# セッションを使うための設定
まずWebFluxでセッションを使うためにSessionRepositoryのDIの設定を行います。

```java:InMemorySessionConfig.java
@Configuration
@EnableSpringWebSession    // 1
public class InMemorySessionConfig {

  @Bean
  public ReactiveSessionRepository reactiveSessionRepository() {

    ReactiveMapSessionRepository repository =
        new ReactiveMapSessionRepository(new ConcurrentHashMap<>());    // 2

    repository.setDefaultMaxInactiveInterval(60 * 30); // 3

    return repository;
  }

}
```
ポイントはコメントの3点
1. `@EnableSpringWebSession` アノテーションを付与しWebSessionの有効化
2. `ReactiveSessionRepository` のBean登録
3. セッションの有効期限（秒）の指定　（例では 60秒*10 = 10分）

# セッションを利用してみる
それでは、実際にセッションを使った簡単なカウンタの実装例を見てみましょう。


```java:CountController.java

@RestController
public class CountController {

  @GetMapping("count/{increments}")
  public Mono<Integer> count(@PathVariable Integer increments, WebSession webSession) {    // 1
    return Mono.fromSupplier(
        () -> {
          Integer total =
              Optional.ofNullable((Integer) webSession.getAttribute("count"))
                  .map(current -> current + increments)
                  .orElse(0);    // 2
          webSession.getAttributes().put("count", total);    // 3
          return total;
        });
  }
}
```

WebFluxでセッションにアクセスするには、`WebSession`を使います。
ただし、Servletの `HttpSession` のようなフィールドインジェクションは行えないため、以下のような実装になります。

1. エンドポイントのメソッド引数に `WebSession` を指定
2. セッションから現在のカウントを取り出し、あればincrementsを加算し、なければ初期値0をtotalにセット
3. 計算結果のtotalをセッションに詰める

以上の実装で、
`localhost:8080/count/1`
に連続でアクセスするたびに1ずつカウントアップする動作が確認できます。
また、1０分間アクセスがなかった場合は、初期値の0に戻ります。

# ちょっと使いづらい・・・
セッションの値を使いたい場合、ControllerでWebSessionを取得し、後続処理（Serviceなど）へ値を渡していかなければならず、

- Servletの実装のようにSessionScopeのBeanを定義したり、
- 任意のComponentのフィールドやコンストラクタでHttpSessionをDIしたり、

といった使い方ができないので、セッションを扱うComponentの設計には注意が必要です。

（そもそも、SessionScopeやRequestScopeはThreadLocalに依存しているので、WebFluxで同様に扱えないのは仕方がないのかもしれません＾＾；）

## 参考
https://docs.spring.io/spring-session/docs/current/reference/html5/#websession
→公式にRedisとWebSessionの連携方法も載っていますので参考まで。
『リーダブルコード』読書メモ

いつかは読むべきだなーと思っていた『リーダブルコード』、ようやく読んだので内容をまとめておきます。

## 第I部 表面上の改善
### 名前
変数やメソッド、クラスの名前は明確で具体的、かつ誤解のないようにすべき。

メソッドの戻り値となる変数の名前を安易に`result`や`retval`などにしがちだが、その変数に入る値の具体的な内容を表す変数名のほうが良い。そうしないと、途中で間違った値を代入していても気づきにくいからである。

別の人が読んだ時に違う解釈の余地がある名前は誤解を生む恐れがある。私がちょうど先日「描画されたグラフを消す」メソッドの名前に`clear`と`reset`のどちらがいいかと相談されたのだが、`reset`の場合、例えば「色などの設定を元に戻す」メソッドだという解釈もできそうだと感じ`clear`を勧めた。こちらのほうが明確で誤解を招きにくそうだ。

### コメント
コメントすべきこと：その実装を選択した理由、定数の値を決めた背景、将来的に直すべきTODO
コメントすべきでないこと：見ればわかる（コメントがなくても理解にかかる時間が変わらない）こと、わかりにくい（改善の余地がある）コードの補足

「優れたコード＞ひどいコード＋優れたコメント」である。

## 第II部 ループとロジックの単純化
### 制御フロー
#### ifとelseの並びは、肯定の単純な目立つ条件を先に持ってくるべき
個人的には「単純な」が重要だと感じている。以下のようなコードを見るとき、elseにたどり着いた頃には条件が何だったか覚えていられないからだ。

```
if (条件) {
  50行にわたる
  とてもとても
  長い処理
} else {
  3行の処理
}
```

#### ネストを浅くする
そのために関数内のreturnや、for文やwhile文のcontinueを活用する。

実際にfor文の中に長いif文があり、ネストが深いコードに何度か出会ったことがあるが、かなり読みづらかった。

### 変数
一度しか使われない値でも、変数に代入することで変数名がコメントの役割を果たす（説明変数）。一方で説明変数を使わなくても十分明確な場合、必要以上に変数を使うことはコードを複雑にすることになる。

## 第III部 コードの再構成
### "無関係の下位問題"の抽出
ある関数の中で、「その関数の目的」に直接は関わらない処理の塊を別関数に切り出す。これは以下のメリットがある

- 関数の可読性が上がる
- 抽出した関数を再利用できる
- 抽出した関数の改善がしやすくなる

### 一度に1つのことを
1つのコードで行うタスクを箇条書きにしてみて、その項目を1つずつ解決するようなコードを書く。1つ目と2つ目の項目を並行で処理しようとすると複雑になってしまう。

### 短いコードを書く
不要なコードを削除する、標準ライブラリを活用するなどして、プロジェクト全体のコード量を小さくする。コード量と保守や機能追加の労力は比例する。

## まとめ
第1章にある「コードは他の人が最短時間で理解できるように書かなければいけない」という一文が、この本の内容を最もよく表した言葉でしょう。これを達成するためのテクニックが1冊かけて説明されているわけです。

コーディングを行う際には**「このコードは他の人が最短時間で理解できるか？」**を常に問う必要があるでしょう。
自分的よく使うGitコマンドまとめ

Git 使い始めてしばらく経ったけどしょっちゅうコマンド忘れて調べてるので、自分がよく使ってたり、いざという時わからなくて調べたものをまとめる。

# 基本的なもの

## ローカルリポジトリの作成
`git init`

## リモートリポジトリをクローン
`git clone リモートリポジトリのアドレス`

## ブランチ系
### 表示
* ローカルブランチ
`git branch`

* リモートブランチ
`git branch -r`

* 全部
`git branch -a`

* マージ済ブランチ
`git branch --merged`

### 作成
* 現在のブランチから切る
`git branch ブランチ名`

* 切るブランチを指定
`git branch ブランチ名 元にするブランチ名`
元にするブランチ名のところをコミットハッシュにすればその位置から作成できる。

### 移動
* ブランチの移動
`git checkout ブランチ名`

* 新しくブランチを作ってそこに移動する
`git checkout -b ブランチ名`
`git branch ブランチ名`と同様に元にするブランチやコミットを指定できる。

### 名前の変更
* 現在のブランチ名を変える
`git branch -m 変更後の名前`

* 名前を変更するブランチを指定する
`git branch -m 元の名前 変更後の名前`

### 削除
* マージ済ブランチ
`git branch -d ブランチ名`

* まだマージされていないブランチ
`git branch -D ブランチ名`

## ブランチの状態
`git status`

## 差分の確認
* 現在のHEADとの差分
`git diff`

* コミット間の差分
`git diff コミット1 コミット2`

* 変更されたファイルの名前
`git diff --name-only`

## ファイルを追加
* すべて
`git add .`

* 変更があったファイル
`git add -u`

* 指定したディレクトリやファイル
`git add ディレクトリ名 or ファイル名`

（`node_modules`や`.DS_Store`なんかの入れなくていいものが入らないように`.gitignore`に書こう）

## コミット
* エディタを開かずにコミット
`git commit -m "コメント"`

* コミットログを見る
`git log`
`--oneline`オプションでログを1行ずつで見る

## 作業を退避
コミットせずにブランチを変えたいときに使う
`git stash`
`git stash save "コメント"`

* 退避した作業の一覧
`git stash list`

* 作業を戻す
`git stash apply`

* 作業を指定して戻す
`git stash apply stash@{戻したい作業の番号}`

* 戻したあとリストから消す
 `git stash pop`

* 退避した作業を消す
`git stash drop`

* リストを全部消す
`git stash clear`

## リモートと同期
* リモートブランチの内容を取り込む
`git pull --rebase origin リモートブランチ名`

* リモートブランチに変更を反映する
`git push origin リモートブランチ名`
初回 push 時に`-u`オプションを付けて対応するリモートブランチを登録すれば、次回以降`git push`のみで push できる。
`-f`オプションはできるだけ使わない。

# 設定系
* 現在の設定の確認
`git config --list`
 * `--system` システムの設定
 * `--global` ユーザーの設定
 * `--local`  リポジトリごとの設定

* 設定する
例えば、`git config --global user.name "ユーザー名"`

* リモートリポジトリを設定
`git remote add origin リモートリポジトリのアドレス`

* リモートリポジトリの変更
`git remote set-url origin 変更後のアドレス`

* 現在設定されているリモートリポジトリ
`git remote -v`


# やっちまったとき

## コミット内容の変更
* 直近のコミットを編集
`git commit --amend`
コメントの編集や add し忘れた変更を含めたりできる。

* まとめて編集
`git rebase -i`
主にコミットの粒度が小さすぎて見にくいときにコミットを一つにまとめるのに使っている。

## 取り消し
* add の取り消し
`git reset`

* 直前のコミットの取り消し
`git reset HEAD^`

* ファイルに変更を加える前に戻す
`git reset --hard`

### 戻したい場所を調べる
`git reflog`
作業の一覧が表示されるので戻したい場所が見つかったら、
`git reset --hard HEAD@{戻したい場所の番号}`でそこまで作業を戻すことができる。


---


自分用のメモみたいなものだけど、新人プログラマ応援タグ付けてみたので新入社員で初めて Git に触れる人だったりの参考になれば幸い。
バリバリ使ってる人は間違いの指摘や、よく使ってるコマンド、便利なコマンドがあればぜひ教えてください。
日本の市井のコロナ感染者数を推定する(2020/3/30)

日本の市井のコロナ感染者数をざっくり推定して見る。
本当に雑な推定である。

現在日本でコロナで亡くなった人は2020/3/31において56人。
カウント漏れがかなりありそうだが、少なめに70人としておく。
[まあ単なる異常値かもだけれど](https://www.niid.go.jp/niid/ja/flu-m/2112-idsc/jinsoku/1852-flu-jinsoku-7.html)

感染者が死亡する率は0.5%-1.0%という[BBCの記事](https://qiita.com/fgatherlet/items/be4539e47bbbd0041846)を元に推定する。

国内の感染者数を概算してみる。
感染後、亡くなるまでのタイムラグを[8日](https://www.cnn.co.jp/world/35151165.html)と仮定する。

8日前の感染者数は、7000人-14,000人である。
日々、指数関数的に増えているわけだから、今現在はもっと多い。

[世界の感染者数のグラフ](https://www.worldometers.info/coronavirus/coronavirus-cases/)をもとに大まかな推定をすると、
**2020/3/31、3万人から4万人のコロナ感染者が存在するということになる。**

日本の総人口は12,600万程度である。

## 結論

2020/3/31、**3600人に1人**の割合でコロナに感染している人がいることになる。

前提となる数字は信頼性が低く、モデルも単純化しすぎているため、
信頼性は低い。

ただ、今すぐにでもロックダウンしないと今後なくなる人の数が大きくなるばかりなので、
なるべく早いロックダウン を祈るばかりである。