OmniAICreator/Qiita-1.07M huggingface dataset:
svgMap.js を使ってみた



世界地図を描きたい。というわけで、地図の描画ライブラリを試している。
今回試してみたのは svgMap.js。

* **svgMap.js** - https://www.cssscript.com/interactive-svg-world-map/
(公式サイトはここでいいのだろうか...)

ここから、 **svgMap-master.zip** をダウンロードし、利用してみた。

## 簡単メモ

1. 準備する HTML タグは div １つ
2. その div の後ろで script タグで svgMap.js を読み込む必要がある (div の前に読み込むとダメ)
3. データは js 内でいろいろ準備する
4. サンプルでは、マウスオーバーで国の情報を tooltip 的に表示してくれる。
5. 国より粒度の小さいデータ (日本でいうと「県」とか) が含まれているかどうか、は調べきれなかった。
6. 国情報内の国旗データは https://cdn.jsdelivr.net/gh/hjnilsson/country-flags@latest/svg/us.svg などから取得するようになっている。~~単体で完結しないのはちょっと不便かも (インターネットがない環境とか)。~~
    * 国旗データの供給元は、オプションで変更できるようだった。

```
new svgMap({
  targetElementID: 'svgMapExample',
  data: svgMapDataGPD,

  // here !!!
  flagURL: 'https://cdn.jsdelivr.net/gh/hjnilsson/country-flags@latest/svg/{0}.svg',
});
```


## 試した結果

アフガニスタンだけ詳細データが表示されるのは、後述する `my-worldmap.js` にて、データを入力しているため。

![sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603093/318cbe6a-5c4a-8783-0bf3-7fd03aca03da.gif)


## 試したコード

### index.html
```html
<html>
  <head>
    <title>svgMap のサンプル</title>
    <link href="svgMap-master/dist/svgMap.css" rel="stylesheet"> <!-- svgMap-master.zip に入っているファイル -->
    <script src="svgMap-master/dist/svgMap.js"></script> <!-- 同上 -->
    <link href="my-worldmap.css" rel="stylesheet">
  </head>
  <body>
    <div id="svgMapExample"></div>
    <script src="my-worldmap.js"></script>
  </body>
</html>
```

### my-worldmap.css
(これは適当。なくてよい)

```css
#svgMapExample:before {
  content: "my worldmap";
  border-bottom: 1px solid #999;
  display: block;
  text-align: center;
  font-family: consolas;
  padding: 7px;
  background-color: #f9f9f9;
  border-radius: 7px 7px 0 0 ;
}

#svgMapExample {
  border-radius: 7px;
  border: 1px solid #999;
  min-height: 100px;
}
```

### my-worldmap.js
https://www.cssscript.com/interactive-svg-world-map/ 内のサンプルコードをただ写経した感じ。

```javascript
// GDP data
var svgMapDataGPD = {
    data: {
      gdp: {
        name: 'GDP per capita',
        format: '{0} USD',
        thousandSeparator: ',',
        thresholdMax: 50000,
        thresholdMin: 1000
      },
      change: {
        name: 'Change to year before',
        format: '{0} %'
      },
      gdpAdjusted: {
        name: 'Purchasing Power Parity',
        format: '{0} USD',
        thousandSeparator: ',',
        thresholdMax: 50000,
        thresholdMin: 1000
      },
      changeAdjusted: {
        name: 'Change to year before',
        format: '{0} %'
      }
    },
    applyData: 'gdpAdjusted',
    values: {
      AF: {gdp: 587, change: 4.73, gdpAdjusted: 1958, changeAdjusted: 0.02},
      // ...
    }
}

new svgMap({
  targetElementID: 'svgMapExample',
  data: svgMapDataGPD,
});
```

## さらなるオプションは？

https://www.cssscript.com/interactive-svg-world-map/ にある通り。
svgMap のコンストラクタとして渡してあげればよい様子。
strpos()の挙動に気をつける

# TL;DR
- 第二引数には**文字列**を渡すこと
- 扱うPHPのバージョンによって挙動に差異があるので、自身が扱うPHPのバージョンを把握すること

# 前提
- PHP ver：**7.3.13**
- strposの第一引数を**haystack**、第二引数を**needle**と以降では記載する
- 検証環境は、CakePHPのconsoleを利用する

# 概要
- [strpos()](https://www.php.net/manual/ja/function.strpos.php)の挙動について注意点を紹介する
    - 主に文字列と数値を渡した場合の挙動について紹介する
    - その他の値を渡した場合の挙動は紹介しない

※ [strpos()](https://www.php.net/manual/ja/function.strpos.php)については下記の引用を参考に
>strpos
>(PHP 4, PHP 5, PHP 7)
>
>strpos — 文字列内の部分文字列が最初に現れる場所を見つける
>
>パラメータ ¶
>haystack
>検索を行う文字列。
>
>needle
>needle が文字列でない場合、 数値に変換され、文字の通常の値として扱われます。 この振る舞いは PHP 7.3.0 以降では推奨されないので、 この機能を使用しないことを強く推奨します。 意図した動作に依存する場合、 needle を string に明示的にキャストするか、 明示的に chr() 関数を呼び出すべきでしょう。
>
>offset
指定すると、文字列内での検索開始位置がその位置になります。 負の数を指定すると、文字列の末尾からこの数だけ戻った場所から検索を開始します。
>
>返り値 ¶
>needle が見つかった位置を、 haystack 文字列の先頭 (offset の値とは無関係) からの相対位置で返します。 文字列の開始位置は 0 であり、1 ではないことに注意しましょう。
>
>needle が見つからない場合は FALSE を返します。

引用元：https://www.php.net/manual/ja/function.strpos.php

# 検証
## 1. haystack ・ needleに "文字列" を渡す

```php
>>> $haystack = '100';
=> "100"
>>> $needle = '100';
=> "100"
>>> strpos($haystack, $needle)
=> 0
```

- strpos()の実行結果が0を返してるので、needleが見つかった事が確認できる

## 2. haystackは "文字列" 、needleは "数値" を渡す

```php
>>> $haystack = '100';
=> "100"
>>> $needle = 100;
=> 100
>>> strpos($haystack, $needle)
PHP Deprecated:  strpos(): Non-string needles will be interpreted as strings in the future. Use an explicit chr() call to preserve the current behavior in /var/www/hoge.jpeval()'d code on line 1
=> false
```

- strpos()の実行結果がFALSEを返してるため、needleが見つからなかった事が確認できる
- また、PHP Deprecatedというエラーが表示されている
    - needleに対して文字列ではない値を渡している事によるエラー
    - [PHPドキュメント](https://www.php.net/manual/ja/function.strpos.php)に記載されてるように、PHP 7.3以降では、needleに渡された値を文字列に変換するという処理は行われない

## 3. haystackは "数値" 、needleは "文字列" を渡す

```php

>>> $haystack = 100;
=> 100
>>> $needle = '100';
=> "100"
>>> strpos($haystack, $needle)
=> 0
>>>
```

- strpos()の実行結果が0を返してるので、needleが見つかった事が確認できる

# 所感
- この検証を実施するきっかけとなったのが、[検証2](https://qiita.com/tatsuo-iriyama/items/eec32ff0a659492de898#2-haystack%E3%81%AF-%E6%96%87%E5%AD%97%E5%88%97-needle%E3%81%AF-%E6%95%B0%E5%80%A4-%E3%82%92%E6%B8%A1%E3%81%99)が発生したからなんだが、そもそもstrpos()がそこまで型に厳格な関数だと初めて知った（PHPという言語自体そこまで型に厳格な言語ではないという認識もあったので）
- また、PHPドキュメントを見る限りhaystackには文字列を渡さなければならない感があるんだが、[検証3](https://qiita.com/tatsuo-iriyama/items/eec32ff0a659492de898#3-haystack%E3%81%AF-%E6%95%B0%E5%80%A4-needle%E3%81%AF-%E6%96%87%E5%AD%97%E5%88%97-%E3%82%92%E6%B8%A1%E3%81%99)にあるように、文字列以外の値（今回でいうと数値）を許容してるのは何故なのか・・・？
- 言語という大枠で見るべきか、関数という枠で見るべきなのか、ちょっとわからないが、型に対して厳格さと寛容さの狭間にあるこの状態に気持ち悪さを感じるのは致し方ない事なのか・・・？

以上
Tabulatorでツールチップをカスタマイズしてみた

# 前提条件
http://tabulator.info/ 　⇒ V4.5

# 内容
Tabulatorでツールチップを実装するのは簡単だが
カスタマイズしたい機会があったので備忘録として。
（Tabulatorの標準ツールチップ機能はカスタマイズができない。。。）

# 参考
https://so-zou.jp/web-app/tech/programming/javascript/event/handler/mouse/
http://tabulator.info/

# 実装

・標準のツールチップ
ツールチップの実装はここを参考に
http://tabulator.info/docs/4.5/format#tooltips


```javascript

    var table = new Tabulator("#example-table", {
      height: 205,
      data: table_data,
      layout: "fitColumns",
      columns: [
        {
          title: "Name", field: "name", width: 64,
          // これだけでツールチップが実装される
          tooltip: true
        },
        { title: "Age", field: "age", align: "left", formatter: "progress" },
        { title: "Favourite Color", field: "col" },
        { title: "Date Of Birth", field: "dob", sorter: "date", align: "center" },
      ],
    });
```

<br>
<br>

・ツールチップのカスタマイズ
※jQueryを導入しています。

ツールチップ用のタグを追加

```html

  <!-- Bodyの中に追記 -->
  <div class="tabulator-tooltip">
    <table class="tooltip-style">
      <tr>
        <td id="tabulator-tooltip-value"></td>
      </tr>
    </table>
  </div>
  <!--  -->
```
<br>
headタグにCSSを追記
※ もちろん別ファイルに追記でOK

```html

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>Tabulator-test</title>
  <style>
    /* ここを新規に追加 */
    .tabulator-tooltip {
      opacity: 0;
      background-color: #fff;
      min-width: 150px;
      width: auto;
      height: auto;
      position: absolute;
      max-width: 330px;
      border-radius: 5px;
      padding: 10px;
      color: black;
      border: 1px solid black;
    }
  </style>
</head>
```
<br>
先ほどのTabulatorの生成コードを変更

```javascript

    var table = new Tabulator("#example-table", {
      height: 205,
      data: table_data,
      layout: "fitColumns",
      tooltips: function (cell) {
        var cellElement = $(cell.getElement());
        cellElement.on('mouseover', function () {
          $('.tabulator-tooltip #tabulator-tooltip-value').text(cell.getValue());
        });
        cellElement.on('mousemove', function (e) {
          $('.tabulator-tooltip').css('opacity', 1);
          $('.tabulator-tooltip').css('left', e.pageX + 30 + 'px');
          $('.tabulator-tooltip').css('top', e.pageY - 10 + 'px');
        });
        cellElement.on('mouseleave', function (e) {
          $('.tabulator-tooltip').css('opacity', 0);
        });
        return '';
      },

      columns: [
        {
          title: "Name", field: "name", width: 64,
        },
        { title: "Age", field: "age", align: "left", formatter: "progress" },
        { title: "Favourite Color", field: "col" },
        { title: "Date Of Birth", field: "dob", sorter: "date", align: "center" },
      ],
    });
```

<br>
完成♪
これでCSSを変えれば、カスタマイズとフォントサイズとかを変えれる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260251/193b3ce1-b555-7ea9-00cc-1e32bac35a97.png)
C言語　素数判定のコード

- nが素数の場合は、1を返し、そうでない場合は0を返す。
- intの範囲で考える
- 2秒以内に返す

##参考にしたコード

```c
int ft_is_prime(int nb)
{
    int i;

    i = 2;
    if (nb <= 1)
        return (0);

    while (i <= nb / i){
        if (nb % i == 0)
            return (0);
        i++;
    }
    return (1);
}
```

##問題を見て考えたこと
######実装
- 素数の定義の確認
    - ２が最小
    - intの最大値である2147483647は素数だが、何番目なのかは調べても出てこなかったため、計算量がわからない。→実際試してみて２秒以上かかるのかチェック。
- 基本
    - intの範囲限定なので、素数を順に比較していく
- 実装
    - 素数と一致すれば1を返す
    - 素数で割れると終了 0を返す
    - nが比較する素数より大きくなったら、終了 0を返す

######テストケース
- intの中で最大の素数と最大-1の計算結果
- 最小の素数2の結果
- 0,1
- マイナスを与えたときの挙動
- 素数の一覧を出して軽く比較


##実装コードを見て所感
- ループのコストを高く見積もり過ぎた。
    - 2147483647の素数判定でも2秒もかからない
- 単純に2147483647までの整数で割っていく方法で十分。
- もっとも単純な方法から、順に思考してくようにする。
iPhoneで取得可能な磁気の種類


# Core Motion
## CMMotionManagers > CMMagnetometerクラス > magneticFieldプロパティ

`地球の磁場 + 周囲の磁場 + デバイスのバイアス`

- 磁力計からの生のデータを読み取る
- デバイス自体で生成される磁場の影響を大きく受ける
- 希土類磁石を近づけない限り、何にも反応しない。デバイス内の磁場は、局所的な外部の磁場や地球の磁場よりもはるかに重視される。

## CMDeviceMotion > CMCalibratedMagneticFieldプロパティ
`地球の磁場 + 周囲の磁場 - デバイスバイアス`

- デバイスバイアス（オンボード磁場）に対して補正された磁力計の読み取り値
- iPhone内部の磁場の影響の除去

# CoreLocation
## CLLocationManager > CLHeading

`地球の磁場 - 周囲の磁場 - デバイスバイアス`

- フィルタリングしてローカルの外部磁場を除去
- 多くの種類の電子機器に見られる固定磁石から発生する磁場など、局所的な磁場の影響を受ける可能性がある。
- 局所的な外部磁場というのに、建物の鉄骨による影響の除去も含まれる。
- 他のセンサーからのデータを使用して、磁力計データを安定させてる。
- 磁場 x、y、zの生のデータは得られない。

# 参考
[In iOS, what is the difference between the Magnetic Field values from the Core Location and Core Motion frameworks? - Stack Overflow](https://stackoverflow.com/questions/15380632/in-ios-what-is-the-difference-between-the-magnetic-field-values-from-the-core-l)
TypeScriptで契約プログラミングしてみた！🥺


```ts
    assert(0 < age && age < 100);
```


😒...(assertコードってあまり見かけない？)



## 契約プログラミングしてみる

**契約プログラミング**は変数や関数の仕様をアサートコードで記述するプログラミングのことです。

例として、下記のソースコードの年齢を表す変数を用います。

```ts
let age: number = parseInt($('input#age')[0].text());
```

、この変数には以下の仕様があります。

- **1以上かつ100未満**

この仕様について、**コメント**で追記してみましょう。

```ts
// 年齢は1以上100未満
let age: number = parseInt($('input#age')[0].text());
```

しかしコメントではageに9999の代入のような仕様から外れる値の代入を防ぐことができません。
この場合に辛いのが、後々にageに9999が代入されたことが遠因のエラーが発生しても、**この行にスグにたどり着けない**ことです。

そこで、代入した後に`assert関数`でageの値が仕様に反していないか確認してみましょう。

```ts
import {assert} from 'assert';

// 年齢は1以上100未満
let age: number = parseInt($('input#age')[0].text());
assert(0 < age && age < 100);
```

このコードならageに9999が代入されたとしてもassert関数の行でエラーが発生し、ageに仕様に反する値が入ったことに気付けます。

これが契約プログラミングです。

## まとめ

### 契約プログラミングのメリット

1. アサートコードがない場合と比べ、エラーが早い段階で見つかる
1. アサートコードはドキュメントにもなる

今回説明しませんでしたが、契約プログラミングには事前条件・事後条件・責務明確化などの概念がありますので、興味ある方は調べてみてください。

ただ、この記事のような簡単なアサートコードでも契約プログラミングのメリットを享受することができるので、ぜひ試してみてください。
intellij-haskellの設定方法 (2020/03/15時点)

※ 筆者環境は OSX Catalina 10.15.3

Intellij IDEAでHaskell開発したい場合のプラグインとして `intellij-haskell` があるが、素朴にインストールするだけではコードジャンプなど解析が効かずに困った。

# 結論

- intellij-haskell プラグインの最新版 (v1.0.0-beta64) をインストールすると解決する
- 上記バージョンをインストールするには Intellij IDEA 2020.1系 を使う

# 最新版インストール手順

IDEAのPreferences->Pluginsから普通にインストールすると v1.0.0-beta53 が入ってくる。
これを最新版の v1.0.0-beta64 にしたい (最新版確認は [releases](https://github.com/rikvdkleij/intellij-haskell/releases) を見る) 。

リポジトリの[README](https://github.com/rikvdkleij/intellij-haskell/blob/master/README.md)に

> Installing latest beta of the plugin

の説明があるのでこれを読む。

## 方法1 (最新版取得できず)

> To try out the latest beta version one can install the plugin by adding https://plugins.jetbrains.com/plugins/alpha/8258 as Custom plugin repository in Settings/Plugins/Browse repositories/Manage repositories.

![スクリーンショット 2020-03-15 12.45.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176237/e6841201-181a-a19a-5f5e-6e88a8ae66fb.png)

Plugins の歯車 から Manage Plugin Repositories を選択するとその設定画面が出てくるので、左下の `+` から `https://plugins.jetbrains.com/plugins/alpha/8258` を追加する。

これを行うと v1.0.0-beta58 まではインストールできるようになった。
しかし beta63 は取れなかった。


## 方法2 (最新版取得できた)

> Alternative way to install the latest beta version is to download intellij-haskell.zip from releases and apply Install plugin from disk in Settings/Plugins.

直接ソースを落としてきて入れるみたいなやり方。

まず [releases](https://github.com/rikvdkleij/intellij-haskell/releases) から `intellij-haskell.zip` をダウンロードする。

そして Plugins の歯車から `Install Plugin from Disk...` を選択。

<img width="975" alt="スクリーンショット 2020-03-15 12.50.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176237/26476e9b-5101-f3ee-10eb-c82500a5e24c.png">

ダウンロードしたzipファイルを選択。
この時、最初 Intellij IDEA 2019.4 を使っていたのだが

> Plugin 'Intellij-Haskell' is incompatible with this installation

というエラーが発生した。

[このissue](https://github.com/rikvdkleij/intellij-haskell/issues/517) によると2020.1系の最新を使うということだったのでそのバージョンのIDEAをインストールし再度試すと、プラグインインストールできた。

![スクリーンショット 2020-03-15 12.47.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176237/d170445a-3a4d-d10d-4080-bf1f9ae4bab8.png)

この状態に持っていくと解析が効いた状態で開発できるようになった。
Laravel5系をHerokuにあげたらTrying to access array offset on value of type nullが出た

## 概要・対象読者
### 概要
Heroku上で動いているLaravelプロジェクトで更新したら「Trying to access array offset on value of type null」というエラーがLaravelログに出ていたのでこのエラーを解決する方法を書きます。
ローカル環境ではエラーにならなかったので焦りました。

### 対象読者
2020/2/20以降からこのエラーが発生した方。

## 環境
以下の環境で当エラーが出ました。Laravel6系より前のバージョンを使用している方は該当すると思われます。
・Laravel5.8
・Heroku

## 原因
PHPバージョンが違うことによって起こった。
2020/2/20にHerokuのPHPバージョンが7.4にアップグレードされていたため。

##解決策
Laravelのバージョンを6系にアップグレードする。
アップグレードは要検討だと思いますが以下を見る限り大きな影響はなさそうです。

[
Laravel 6.x アップグレードガイド](https://readouble.com/laravel/6.x/ja/upgrade.html)

現に私も6系にアップグレードしたわけですが一部ヘルパー関数が使えなくなっていただけで5分程度の
修正で動くようになりました。Laravel5.8はサポート期限が2020/02/26ということもアップグレードをした理由の１つです。

修正は以下１点になります。

・Laeavelアップグレード

## Laravelアップグレード
まずプロジェクト配下のcomposer.jsonを開き、 "laravel/framework"を"^6.4"に変更します。

```json:composer.json
"require": {
        "php": "^7.1.3",
        "ext-intl": "*",
        "fideloper/proxy": "^4.0",
        "itsgoingd/clockwork": "^4.0",
        "laravel/framework": "^6.4",
        "laravel/tinker": "^1.0",
        "league/flysystem-aws-s3-v3": "^1.0",
        "tymon/jwt-auth": "1.0.*"
    },
```

変更したら以下のコマンドを実行します。

```terminal:
$ composer update
```

以上でLaravelアップデートは完了です。

後はローカルで動作を確認、デバックしてHerokuにアップロードします。

拝読ありがとうございました。
Qiitaに10秒で画像を追加する

Windows10向け
Snipping Toolが割と便利になっていた事に今更気づいたので備忘として投稿

# Qiitaの画像投稿について

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451150/bfb64abf-3c9e-8f28-b935-248426fead49.png)

Qiitaの編集画面では画像ファイルのアップロードの他にも
クリップボードに保存されている内容を貼り付け[Ctrl+V]するだけで自動的にアップロードしてくれる素敵仕様だったぽい

# スクショのクリップボード保存

標準機能のSnippetToolが進化しておりいつの間にかショートカットから矩形選択ができるようになっていたのでだいぶ捗るように(\*´ω｀\*)

|ショートカット|キャプチャ範囲|
|---|---|
|Windows+Shift+S → 範囲選択|矩形(選択範囲)|
|Alt+PrintScreen|アクティブウィンドウ|
|PrintScreen|全画面|

# 画像の編集

ここまで楽になったぜって内容ですが...
少し編集したいとなった時にはWindows標準のツールはイケテナイ...

[Screenpresso](https://screenpresso.com/ja/)とか入れておくと
アイコン強調とかの簡単な編集内容であれば
1枚目の画像アイコン強調は20秒位で↑使って行って
そのままクリップボードに保存してくれるので更に捗ります。

他にも良いソフトいくらでもありそうだけど個人利用無料なので暫くこれ使ってるかも
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451150/f4c8a41a-3399-1ca2-2272-f741f28c9294.png)
要素を順番にアニメーションさせる方法【CSS,JS】

#順番にアニメーションさせる。
この記事では、javascript(ES6)を使い要素に順番にアニメーションさせるソースの紹介しています。

##完成形
最初に完成形を見せておきます。

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="wd30gsrc" data-slug-hash="poJLqKX" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="for animation">
  <span>See the Pen <a href="https://codepen.io/wd30gsrc/pen/poJLqKX">
  for animation</a> by wd30gsrc (<a href="https://codepen.io/wd30gsrc">@wd30gsrc</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

##HTML
まずはhtmlから

```html:index.html
<ul class="list">
  <li class="item">BOX_01</li>
  <li class="item">BOX_02</li>
  <li class="item">BOX_03</li>
  <li class="item">BOX_04</li>
  <li class="item">BOX_05</li>
</ul>
```

##CSS
.itemは最初、opacity:0で非表示にさせて、jsで.activeクラスをあとから付ける。

```css:style.css
.list {
  display: flex;
  justify-content: center;
}

.item {
  width: 100px;
  height: 100px;
  background: orange;
  margin: 3px;
  text-align: center;
  line-height: 100px;
  opacity: 0;
  transition: all 1s;
}
.active {
  opacity: 1;
}
```

##js
今回は即時関数を使っています。
実際に使用する場合はスクロールイベント等で要素が見えたときに動くようにすることが多いかと思いますが、そこは適宜調整が必要です。

```js:app.js
(()=> {
  const items = document.querySelectorAll('.item');
  items.forEach((item,index)=> {
    const order = index + 1;
    const delay = order * 300;
    setTimeout(()=> {
      item.classList.add('active');
    }, delay);
  });
})();
```

以上です。
【React】npxでのReactの環境構築までのステップについて


##create-react-appコマンドを使用

※注意事項：事前にnode.jsをインストールしてください。

まだインストールされていない方はこちらから！
→[node.js](https://nodejs.org/ja/)

##1.ターミナルでコマンドを実行
①"ls"コマンドを入力してディレクトリがすでに存在しているかの確認をします。
　例）react-directory(お好きな名前)をディレクトリ名とする。

②"npx create-react-app react-directory"と入力をします。

```console
komorioBookpuro:~ komorishuhei$ npx create-react-app react-directory
npx: 99個のパッケージを5.733秒でインストールしました。

Creating a new React app in /Users/komorishuhei/reac-directory.

Installing packages. This might take a couple of minutes.
Installing react, react-dom, and react-scripts with cra-template...
```

##2.実行結果を確認
実行完了後、"ls"コマンドを入力して"react-directory"が実行できていることを確認します。

```
Success! Created react-directory at /Users/komorishuhei/react-directory
Inside that directory, you can run several commands:

  npm start
    Starts the development server.

  npm run build
    Bundles the app into static files for production.

  npm test
    Starts the test runner.

  npm run eject
    Removes this tool and copies build dependencies, configuration files
    and scripts into the app directory. If you do this, you can’t go back!

We suggest that you begin by typing:

  cd react-directory
  npm start

Happy hacking!
```


##3.packge.jsonを確認
①ダウンロードされたディレクトリにpackage.jsonがあることを確認します。
<img width="769" alt="スクリーンショット 2020-03-15 12.13.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602592/c5e5ebf7-53f3-8279-c411-e4d9eabeb6ec.png">

②package.jsonの中身をエディターで確認します。

```package.json
{
  "name": "react-directory",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.5.0",
    "@testing-library/user-event": "^7.2.1",
    "react": "^16.13.0",
    "react-dom": "^16.13.0",
    "react-scripts": "3.4.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

```

#4."npm start"でReactアプリを起動

エディタで"npm start"を入力してURLを出力する。

```
Compiled successfully!

You can now view project in the browser.

  Local:            http://localhost:3000
  On Your Network:  http://

Note that the development build is not optimized.
To create a production build, use npm run build.

```

#5.環境構築成功
エディタで出力されたURLをクリックして画像のように表示されれば成功です。
お疲れ様でした！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602592/ae32eca5-53fd-e9e2-e1d0-9ac59bc74ee8.png)
第3回 Google Colaboratoryで始める機械学習のための特徴量エンジニアリング - スケーリング

## はじめに

本記事ではスケーリングと正規化について解説しています。本記事は主に「[機械学習のための特徴量エンジニアリング](https://www.amazon.co.jp/dp/4873118689/ref=cm_sw_em_r_mt_dp_U_lRGxEbH5KBJJX)」を参考とさせて頂いておりますので、気になる方は是非チェックしてみてください。

※本記事で解説するプログラムは全て[こちら](https://colab.research.google.com/drive/1r1gAfK_ZpO6085jjp7DZWzxr8LGoAhv-)にあります。


## スケーリングとは
数値データの取りうる範囲は決まっているものと決まっていないものがあります。カウントデータは基本的にデータの取りうる範囲が決まっておらず、線形回帰などの特徴量のスケールに敏感なモデルの場合外れ値や特徴量間でスケールの差異により学習が上手く出来ない場合があります。そのような場合に尺度を統一することをスケーリングといいます。スケーリングにはMin-Maxスケーリング, 標準化, L2正規化などがあるので順番に紹介していきましょう。スケーリングについてもっと詳しく知りたい方は[こちら](https://qiita.com/ttskng/items/2a33c1ca925e4501e609)の記事を見てみてください。

## Min-Maxスケーリング

Min-Maxスケーリングでは最小値を0最大値を1にします。外れ値が含まれる場合、その外れ値の影響で正常値の取りうる範囲が狭くなりすぎる場合があるので、基本は標準化を使う。

```math
\tilde{x} = \frac{x - min(x)}{max(x) - min(x)}
```

```python
import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler

##乱数固定
np.random.seed(100)
data_array = []
for i in range(1, 100):
  s = np.random.randint(0, i * 10, 10)
  data_array.extend(s)
data_array.extend(np.zeros(100))
data = pd.DataFrame({'Listen Count': data_array})

print(data.max()) # 977.0
print(data.min()) # 0

scaler = MinMaxScaler()
data_n = scaler.fit_transform(data)
data_n = pd.DataFrame(data_n)

print(data_n.max()) ## 1.0
print(data_n.min()) ## 0

```

## 標準化

標準化では平均を0, 分散を1とします。元の特徴量が正規分布の場合標準化された特徴量は標準正規分布になります。

```math
\tilde{x} = \frac{x - mean(x)}{sqrt(var(x))}
```

```python
import numpy as np
import pandas as pd
from sklearn.preprocessing import StandardScaler

##乱数固定
np.random.seed(100)
data_array = []
for i in range(1, 100):
  s = np.random.randint(0, i * 10, 10)
  data_array.extend(s)
data_array.extend(np.zeros(100))
data = pd.DataFrame({'Listen Count': data_array})

scaler = StandardScaler()
data_n = scaler.fit_transform(data)
data_n = pd.DataFrame({'Listen Count': data_n.ravel()})

print(data_n.var()) ##1.000918
print(data_n.mean()) ##6.518741e-17

```

## L2正規化

L2正規化はL2ノルムで割ることで特徴量を正規化します。

```math
\tilde{x} = \frac{x}{||x||_2} \\
||x||_2 = \sqrt{x_1^2 + x_2^2+ ...+x_m^2 }
```

```python
import numpy as np
import pandas as pd
from sklearn.preprocessing import normalize

##乱数固定
np.random.seed(100)
data_array = []
for i in range(1, 100):
  s = np.random.randint(0, i * 10, 10)
  data_array.extend(s)
data_array.extend(np.zeros(100))
data = pd.DataFrame({'Listen Count': data_array})

##L2正規化
data_l2_normalized = normalize([data['Listen Count']],norm='l2')
data_l2 = pd.DataFrame({'Listen Count': data_l2_normalized.ravel()})

print(np.linalg.norm(data_l2_normalized,ord=2)) ## 0.999999999

```

## 最後に
YouTubeでITに関する動画を上げていこうと思っています。
YoutubeとQiita更新のモチベーションに繋がるため、いいね、チャンネル登録、高評価をよろしくお願い致します。
YouTube: https://www.youtube.com/channel/UCywlrxt0nEdJGYtDBPW-peg
Twitter: https://twitter.com/tatelabo
MySQLでdatetime型の演算をする

以下のようなテーブルがある．

```sql
MariaDB [staging]> desc guests;
+---------------+----------------------+------+-----+---------+----------------+
| Field         | Type                 | Null | Key | Default | Extra          |
+---------------+----------------------+------+-----+---------+----------------+
| id            | smallint(5) unsigned | NO   | PRI | NULL    | auto_increment |
| department_id | smallint(5) unsigned | YES  | MUL | NULL    |                |
| user_id       | varchar(10)          | YES  |     | NULL    |                |
| comment       | varchar(255)         | YES  |     | NULL    |                |
| entered_at    | datetime             | NO   |     | NULL    |                |
| updated_at    | datetime             | NO   |     | NULL    |                |
| exited_at     | datetime             | YES  |     | NULL    |                |
+---------------+----------------------+------+-----+---------+----------------+
7 rows in set (0.036 sec)
```

現状では，JSTでdatetime型のカラムに記録されている．

```sql
MariaDB [staging]> select * from guests;
+----+---------------+----------+-----------------------------+---------------------+---------------------+---------------------+
| id | department_id | user_id  | comment                     | entered_at          | updated_at          | exited_at           |
+----+---------------+----------+-----------------------------+---------------------+---------------------+---------------------+
|  3 |             1 | C0117123 | これはテストです〜          | 2019-08-08 02:41:20 | 2019-08-08 20:41:20 | 2020-03-02 23:00:09 |
```

ここでは `entered_at` カラムの時刻をUTCへ修正する．

```sql
UPDATE guests SET entered_at=entered_at - INTERVAL 9 HOUR
```

修正されたことが確認できる．

```sql
MariaDB [staging]> select * from guests;
+----+---------------+----------+-----------------------------+---------------------+---------------------+---------------------+
| id | department_id | user_id  | comment                     | entered_at          | updated_at          | exited_at           |
+----+---------------+----------+-----------------------------+---------------------+---------------------+---------------------+
|  3 |             1 | C0117123 | これはテストです〜          | 2019-08-07 17:41:20 | 2019-08-08 20:41:20 | 2020-03-02 23:00:09 |
```
Visual Studio Code内でターミナルを起動する方法

何回もググっては忘れてしまう。忘れないぞという思いを込めてメモ。

## 方法

`` control + shift　+　` ``を実行すると解決できる。

ちなみに
Problems は  `` control + shift　+　M ``
Debug Console は `` control + shift　+　Y ``
Output は  `` control + shift　+　U ``

あと、何回打てば覚えられるのだろうか。。。。。。。
2020年におけるnamedtupleのドキュメントの書き方

とある PR がきっかけで、namedtuple の属性には "Alias for field number xx" という docstring が自動的に設定されるということを知りました。

```python
$ python
Python 3.8.1 (default, Feb 13 2020, 13:34:23)
[Clang 11.0.0 (clang-1100.0.33.17)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from collections import namedtuple
>>>
>>> Coordinate = namedtuple('Coordinate', 'X Y')
>>> Coordinate.__doc__
'Coordinate(X, Y)'
>>> Coordinate.X.__doc__
'Alias for field number 0'
>>> Coordinate.Y.__doc__
'Alias for field number 1'
```

このクラスを Sphinx(autodoc) で処理してドキュメントを生成すると次のようなドキュメントが生成されます。
<img width="279" alt="スクリーンショット 2020-03-15 11.40.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57661/68445eb3-ff98-dbb9-d844-e5f2aac31139.png">

情報量が少ない割には紙面を使うドキュメントができてしまいました。

## 振り返り

### docstring を消すアプローチ

この問題への対策としては [Removing namedtuple docstrings for Sphinx](https://chrisdown.name/2015/09/20/removing-namedtuple-docstrings-from-sphinx.html) で紹介されているコードがあります。namedtuple の属性を見つけたら消去するというものです。これを入れることで冗長なドキュメントをシンプルにできます[^1]。

[^1]: 一方、このアプローチは autodoc は何も指定しないと属性をアルファベット順に並び替えてしまうので、namedtuple の位置と属性名のマッピングがわかりづらくなるという弱点もあります。Sphinx本体でどうようの対応を行うべきかはちょっと迷っています。

### docstring で属性のドキュメントを書くアプローチ

また、[namedtupleのドキュメントをsphinxで作成するためのdocstringの書き方](https://qiita.com/vmmhypervisor/items/c1a46db1c1e3b83b22b3) では、生成したクラスの docstring で各属性のドキュメントを記述するというアプローチが紹介されています。

```python
class NamedTupleWithDocstring2(namedtuple("NamedTuple", "aaa bbb ccc")):
    """
    hogehoge

    .. py:attribute:: aaa

        Description of the ``aaa``.

    .. py:attribute:: bbb

        Description of the ``bbb``.

    .. py:attribute:: ccc

        Description of the ``ccc``.
    """
```

なるほど、これなら任意の説明文を差し込めますね。

## いまならどう書く?

docstring でいろいろ書くやりかたは自由にドキュメントをコントロールできるのですが、コードとしては冗長です。
もしあなたが Python3.6 以上と Sphinx 2.4 を利用できるのであれば、もう少しシンプルに書けます。

Python 3.6 から導入された変数アノテーションを利用すると、namedtuple とそのドキュメントが次のように書けます。

```python
from typing import NamedTuple

class Coordinate(NamedTuple):
    """A 2-dimension coordinate."""

    X: float  #: the coordinate on X-axis
    Y: float  #: the coordinate on Y-axis
```

そして、Sphinx 2.4 を利用するとこの変数アノテーションについた `#:` コメントを docstring として解釈するので、上記のコードを Sphinx で処理すると次のように変換されます。
<img width="254" alt="スクリーンショット 2020-03-15 12.02.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57661/f97b74f8-effc-6cca-0ac9-b3798f11076e.png">


新しい機能を使ってスマートなコード、スマートなドキュメントを目指していきましょう。
C言語　平方根を返すコードを自作する

- 数値の平方根を返す。
- 平方根が無理数の場合は0

##コード

```c
int ft_sqrt(int nb)
{
    int raiz;

    raiz = 0;
    while (raiz * raiz < nb){
        raiz++;
        if (raiz * raiz == nb)
            return raiz;
        if (raiz * raiz > nb)
            return 0;
    }
    return 0;
}
```

##所感
nb <= 0
とか挟まなくても
whileの最初の条件のところで、判定するような書き方をする。

if文を多様するのではなく、whileの条件式で判定できないのか、考えてから書く。

while直後にraiz++で１からスタートさせる書き方も良いと思う。
Drupal8「新しいテーマをインストール」ボタン表示されない

#Drupal8で[テーマ]「+新しいテーマをインストール」ボタンが表示されない場合があります。

[drupal.org](https://www.drupal.org/) に英文で問題が上がっていましたが、やってみて解決しましたのでご参考までに。
[https://www.drupal.org/project/drupal/issues/3033480](https://www.drupal.org/project/drupal/issues/3033480)

1.Enable Update Manager >> Core

[機能拡張]-コア の「Update Manager」にチェックが入っていることを確認


2.Go to "admin/appearance" to select Seven as admin theme.

[テーマ]の 管理用テーマ を「Seven」にする


3.Clear cache, and revisit the page.

[環境設定]-[開発]-[パフォーマンス]で「キャッシュをクリア」すべてのキャッシュをクリアします
[React]Hooks を使って無限スクロールを実装する

Reactでいろんなサンプルを作って理解しようとしてるんですが、その中で無限スクロールを作ってみたので Memo :pencil: 

サンプルは [こちら](https://curiosity-driven.web.app/tools/infinite-scroll)

サンプルの API はこちらの API を使わせてもらいました。
https://punkapi.com/

```jsx
import React, { FC, useEffect } from 'react';
// setPageNumber でページを変えると fetch してくる hook。取得してきたものは beers にたまっていく
import useBeers from 'hooks/useBeers';
import lodash from 'lodash';

const InfiniteScroll: FC = () => {
  const { beers, setPageNumber } = useBeers();

  // 一番下に到達したら setPageNumber でページを更新
  const handleScroll = lodash.throttle(() => {
    if (
      window.innerHeight + document.documentElement.scrollTop !==
      document.documentElement.offsetHeight
    ) {
      return;
    }
    setPageNumber(prev => prev + 1);
  }, 200);

  useEffect(() => {
    window.addEventListener('scroll', handleScroll);

    return () => {
      window.removeEventListener('scroll', handleScroll);
    };
  }, []); // eslint-disable-line react-hooks/exhaustive-deps

  return (
    <>
      <ul>
        {beers.map((beer: any) => (
          <li key={beer.id}>
            <img src={beer.imageSrc} />
            <div>{beer.title}</div>
          </li>
        ))}
      </ul>
    </>
  );
};

export default InfiniteScroll;
```
【feature】Rspecで作成したテストデータに引数を渡す方法 let! (   ) {create(     )}

基本的なRspecの書き方についてはこちらに全て記載してあるので書きません。
https://qiita.com/jnchito/items/607f956263c38a5fec24


###順序
・テストデータhoge_product、hoge_caetgoryを作成する
・hoge.categoryを持っているページにアクセスする
・カテゴリと紐づいた商品が表示されるテストを行う

##コードに落とし込む


```test_spec.rb
require 'rails_helper'

RSpec.feature "Categories", type: :feature do


let!(:hoge_caetgory) { create(:caetgory) } 
let!(:hoge_product) { create(:product ,caetgory: [caetgory]) } #caetgoryと言う引数（属性）を持ったproductを作成し、hoge_productというインスタンス変数に代入

  before do
    visit hoge_category_path(category)
  end

it カテゴリと紐づいた商品が表示される do
expect(page).to have_content hoge_product.category #caetgoryと言う引数（属性）を持ったhoge_productが表示されるテスト
end

```

```let!(:hoge_product) { create(:product ,caetgory: [caetgory1]) }```だったら、
categoryがcategory1であるproductを作成してくれます。

```let!(:変数) { create(:データ ,引数) }```のイメージです。



書き方のみの説明記事のため、コントローラについては割愛。


間違いがありましたらコメントください。

関連記事はこちら。
https://qiita.com/kojiro3/items/b0957813695ca61fa3aa
現場についていくための数学備忘録 #2

## 集合とは
第2回も引き続き集合についてまとめていきます。

## 集合の種類
代表的なもの(これが全てなのか？)に以下の物があるらしいです。

- 部分集合

```
# 部分集合 大きな集合Uの中に、Aは含まれる
>>> U = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
>>> A = {2, 3, 9, 10}
>>> A <= U
True
```

- 補集合(部分集合から弾かれたもの？) 後述の差集合で求めらる
- 積集合

```
# 積集合 ２つ集合の共通要素
>>> U = {1, 2, 6, 10}
>>> A = {7, 3, 6, 9}
>>> U & A
{6}
>>> 
```

- 和集合

```
# 和集合 集合の合算
>>> U = {1, 2, 6, 10}
>>> A = {7, 3, 6, 9}
>>> U | A
{1, 2, 3, 6, 7, 9, 10}
# 同じ要素は1つとしてカウントされる
```
- 差集合

```
# 差集合 一方の集合から共通の要素を引く
>>> U = {1, 2, 6, 10}
>>> A = {7, 3, 6, 9}
>>> U - A
{1, 2, 10}
```
- 対象差

```
# 対象差 2つ集合から共通した要素を取り除く
>>> U = {1, 2, 6, 10}
>>> A = {7, 3, 6, 9}
>>> U ^ A
{1, 2, 3, 7, 9, 10}
```
- 空集合

```
# 空集合 演算の結果要素が１つもないこと
>>> U = {1, 2, 3}
>>> A = {4, 5, 6}
>>> U & A
set()
```

上記のような集合を明確な条件のもとグループすることを__集合演算と言います。__
[golang]rake db:migrateみたいな事をgoでできるgooseを使ってみた

Go言語でマイグレーションどうやんの…というところで色々試したうちの1つ。
Railsの`rake db:migration`みたいな事ができるので、Railsに慣れている人には比較的使いやすいのではないかと思う。

- [pressly/goose: Goose database migration tool - fork of https://bitbucket.org/liamstask/goose](https://github.com/pressly/goose)

## 環境

go 1.13.4

## gooseが記事執筆時点で対応しているデータベース

- postgres
- mysql
- sqlite3
- mssql
- redshift

## gooseのインストール

```sh
go get -u github.com/pressly/goose/cmd/goose
```

## 各種コマンド

### databaseを作る

db:create相当のコマンドは無い

### マイグレーションファイルを作る

```sh
$ goose mysql "user:password@/testdb?parseTime=true" create AddColumnToTestTable sql
2020/03/15 11:10:29 Created new file: 20200315111029_AddColumnToTestTable.sql
```

すると以下のようなファイルが出力されるので、中身のSQL文は自分で書く。
Railsほどいい感じにテンプレート出力されるわけではない。

```sql
-- +goose Up
-- SQL in this section is executed when the migration is applied.

-- +goose Down
-- SQL in this section is executed when the migration is rolled back.
```

### マイグレーションを実行する

`-- +goose Up` セクションに記載された内容が実行される。

```sh
# 1つだけ実行
goose mysql "user:password@/testdb?parseTime=true" up-by-one

# まだ実行してないものを全部実行
goose mysql "user:password@/testdb?parseTime=true" up

# 特定のバージョンまで実行
# そのバージョンも含む
goose mysql "user:password@/testdb?parseTime=true" up-to 20200315111029
```

### 巻き戻し

`-- +goose Down` セクションに記載された内容が実行される。

```sh
# 最初まで巻き戻し
goose mysql "user:password@/testdb?parseTime=true" down

# 特定のバージョンまで巻き戻し
# 指定したバージョンは含まない
goose mysql "user:password@/testdb?parseTime=true" down-to 20200315111029
```

### 再実行

特定のマイグレーションを`down`してから`up`する。

```sh
goose mysql "user:password@/testdb?parseTime=true" redo 20200315111029
```

# 欠点

コマンドラインにパスワードを含むのでDBのパスワードがコマンド履歴に残る。
[BitBucketのほうのGoose](https://bitbucket.org/liamstask/goose/src/master/)は設定ファイルに書けるらしい。
僕のCSS

自分用の備忘録

##基本の形

```css
@charset "UTF-8";
セレクタ{
    プロパティ:値
}
```
#####セレクタ別指定の仕方
```css
要素名{}
.class名{}
#id名{}
セレクタ1 > セレクタ2{}  /*子セレクタ*/
セレクタ1 セレクタ2{}  /*子孫セレクタ*/
セレクタ1, セレクタ2{}/*複数の要素に*/
```

#####セレクタの優先順位
1:`!important`
2:`タグのstyle属性`
3:`idセレクタ`
4:`classセレクタ`
5:`要素セレクタ`
6:`全称セレクタ` *{}ってやつ
7:ブラウザ初期値



##設定
 - `backgroud`:背景
  - 例`backgroud:url(../img.jpg) no-repeat center center/cover`
 - `background-color`:背景色
 - `border-bottom`:下線
 - `color`:文字色
 - `display`:表示形式
  - block
 - `font-family`:字体
 - `font-size`:文字サイズ
  - rem
  - px
 - `font-weight`:文字の重さ
 - `left`:左の位置
 - `line-height`:行の高さ。1.0とか2.0とか
 - `margin`
 - `margin-bottom`:下の外余白
 - `max-width`:最大幅の指定。
 - `padding`:内余白
 - `position`:要素の位置
  - `static`:初期指定。特に位置指定なし。
  - `relative`:staticを指定したときの位置が基準位置。
  - `absolute`:親要素がstatic以外の時に親要素の左上が基準になる。
  - `fixed`:基本はabsoluteと同じだけど。スクロールしても固定される。
 - `text-align`:文字揃え
 - `top`: 上の位置
 - `transform`:要素の位置を移動。
  - `translate(0,-50%)`:元の位置から要素の高さ50%分上に移動
 - `width` :幅
  - px
  - %　
 - `z-index`:要素を重ねて表示する際の優先順位を指定。数字大きい方が上。


##フォントサイズ
[CSSのfont-sizeが%とかemとかremとかvwで指定されてると、ビビっちゃう君と僕を救う2分](https://qiita.com/39_isao/items/e8242901ba1aadb75676)
現場についていくための数学備忘録 #1

## はじめに
現在、やや機械学習よりな現場に派遣されているが、プローパーの方々が言ってることが全くわからん....

と、言うわけで自分が勉強した数学を備忘録として適当にまとめていこうかと思います。
__ほんと適当かつ、ざっとしか理解できないので、優しい目で見てもらえれば嬉しいです。__

## 機械学習で使用する数学
- 線形代数(行列)
- 微分
- 確率・統計

などですかね？

現在書籍を使って高校数学を勉強しているので、学んだことをoutputしていきます~


## 集合と確率

今回は集合についてです。
集合とは数学の正解で、「はっきりと区別できて、同じ性質を持ったデータのあつまり」だそうです。
正直よくわかりませんでしたが、例で言うと

```
自然数 = {1, 2, 3, 4, 5}
```

これは集合で、

```
今年の暑い日 = {28℃, 30℃, 29℃, 32℃, 31℃}
```

これは集合ではありません。

この違いですが、
__無限にある数の中から1 ~ 5は誰がどうやっても、取り出すことはできますが、__
__今年の暑い日などの人によって判断が曖昧になるものは(27℃を暑いと言う人もいるかも)集合とは言えません。__

また、集合の特徴としては、以下の物があります。
- 重複した要素はない。
- 順番は関係ない

```
>>> A = {1, 2, 3, 4, 5}
>>> B = {5, 4, 3, 3, 2, 1}
>>> print(B)
{1, 2, 3, 4, 5}

>>> print(A == B)
True

# 重複はカウントされない(Bの集合に3が2つあるが1つとカウントされている)
# AとBの集合の順番が異なっても同じ集合として認識される
```

※ちなみに、pythonでは集合を 変数名 = {要素1, 要素2.....}といった形で定義出来ます。
※データは__set型__と言うそうです。
CakePHP4 で phpstan を使えるようにする

[CakePHP4 を docker-compose で動くようにする](https://qiita.com/katsuhiko/items/f18c488457af33abdf66)

の続きです。

静的解析を行う phpstan を使えるようにします。


# この記事でわかること

- CakePHP4 プロジェクトへ phpstan (静的解析)を使えるようにします。
- この記事内のソースは以下で公開しています。
    - https://github.com/katsuhiko/cakephp-vue-study

※ 最適な phpstan の設定はこの記事ではわかりません。作りながら phpstanの設定 (phpstan.neon) を見直す予定です。

僕の Mac の各種バージョンは以下です。

|  | バージョン |
|:-----------------|:------------------|
| docker           | Docker version 19.03.8, build afacb8b |
| docker-compose   | docker-compose version 1.25.4, build 8d51620a |
| CakePHP4         | 4.0.4 |
| Vue.js           | 2.6.11 |
| laravel-mix      | 5.0.1 |


# PHPStan の導入

コンテナを使って、開発のみで利用するライブラリとして phpstan を導入します。

※ 「Use PHPStan via Docker」 というコンテナ経由で phpstan を実行する方法も提供されていますが、今回は開発ライブラリとして取り込む方法を採用します。現時点の phpstan (v0.12.14) は依存がぜんぜんなくてツールとしてバッチシな作りなので。

```sh
docker-compose up -d
docker exec -it app php composer.phar require --dev phpstan/phpstan
```


# phpstan.neon の作成

プロジェクトのカレントディレクトリへ ` ./phpstan.neon ` を作成します。
レベルは最大:max（現時点では 8）として、最初からエラーとなってしまう２つのファイルを解析対象からはずしました。

```yaml:phpstan.neon
parameters:
    level: max
    excludes_analyse:
        - src/Console/Installer.php
        - src/Controller/PagesController.php
```


# composer.json の変更

` ./composer.json ` へはすでに phpstan を実行する script が設定されています。
` composer check ` したときに phpstan も実行したいので、その部分のみ追記します。

check の処理順も 静的解析 > コード規約チェック > テスト っという順番に変えました。
テストの前にできる範囲でのチェックはしたいなっという考えです。

```json:composer.json
{
    // ...
    "scripts": {
        // ... "@stan" を追加します。
        "check": [
            "@stan",
            "@cs-check",
            "@test"
        ],
        // ...
    },
```


# 動作確認 (実行)

コンテナを使って実行します。

```sh
docker exec -it app php composer.phar check
```

空なプロジェクトなので、結果は下のような感じでした。

```sh
> phpstan analyse src/
Note: Using configuration file /var/www/html/phpstan.neon.
 6/6 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%


 [OK] No errors                                                                 

> phpcs --colors -p --standard=vendor/cakephp/cakephp-codesniffer/CakePHP src/ tests/
........... 11 / 11 (100%)


Time: 4.61 secs; Memory: 10MB

> phpunit --colors=always
PHPUnit 8.5.2 by Sebastian Bergmann and contributors.

............                                                      12 / 12 (100%)

Time: 3.98 seconds, Memory: 14.00 MB

OK (12 tests, 29 assertions)
```


たぶんですが、CakePHP4 の開発では、だいぶ緩めないと（許容するエラーを増やす）エラーが出まくる気がしてます。
対応は、作りながら考えます。
心配ばっかりして先に進めないのはつまらないですからね。
大小文字区別しない辞書機能を作ってみました

※特殊メソッドをオーバーライドで実現します。

```python:dictex01.py
class PcInformation:
    def __init__(self):
        self.pc_dict = {}

    def __getitem__(self, key):
        return self.pc_dict.get(key.upper(), '---未設定---')  # キーは大文字で統一

    def __setitem__(self, key, value):
        self.pc_dict[key.upper()] = value  # キーは大文字で統一

    def __delitem__(self, key):
        del self.pc_dict[key.upper()]  # キーは大文字で統一

    def __len__(self):
        return len(self.pc_dict)


pc_inf = PcInformation()
pc_inf['wpc001'] = '192.168.1.33'
pc_inf['Wpc001'] = '192.168.1.39'  # 大小文字区別しないことにしているから、更新できる
pc_inf['WPC010'] = '192.168.1.11'
pc_inf['wpc022'] = '192.168.1.22'
pc_inf['WPC_010'] = '192.168.1.100'
print(pc_inf['wpc010'])  # 大小文字区別しないことにしているから、取得できる
print(pc_inf['wpc999'])  # wpc999は辞書にない
del pc_inf['WpC_010']  # 削除

print('端末数：{}'.format(len(pc_inf)))
print('端末一覧：')
for i, item in enumerate(pc_inf.pc_dict.items()):
    print('{:>5})  PC Name: {:<12}    IP: {}'.format(str(i + 1), item[0], item[1]))

```

実行結果：
192.168.1.11
---未設定---
端末数：3
端末一覧：
&nbsp;&nbsp;&nbsp;    1)  PC Name: WPC010          IP: 192.168.1.11
&nbsp;&nbsp;&nbsp;    2)  PC Name: WPC022          IP: 192.168.1.22
&nbsp;&nbsp;&nbsp;    3)  PC Name: WPC001          IP: 192.168.1.39
Pythonを実行しているプラットフォーム識別(Kaggle / Colab / Windows) 

# 目的
コンペなどで、ローカルとクラウドで、ファイルの読み込み処理やimportモジュールなどが、変わるので自動で切り替えられるようにする。
Kaggle, Google Colaboratory, ローカル(Windows10)

# 実行環境 (2020/3/15現在)
- Windows 10 Home(64bit)
- kaggle
- google Colaboratory


# 概要/方法
判別方法、
1.ローカル(Windows)とクラウド判定は、os.nameでOSから判定
2.Kaglle/Colabは、Kaggle固有の環境変数の'KAGGLE_DATA_PROXY_TOKEN'の有無で判定

もっと賢い判定方法があったら、ぜひ教えてください。

### 各プラットフォームの処理内容
- Windows:
    - ローカルフォルダから読み込み
    - matplotlibの日本語設定
- Kaggle:
    - kaggleクラウドフォルダから読み込み
- Google Colaboratory:
    - Google Driveから読み込み
    - セッション時間の表示(残り時間の確認) 

# 判別

```.py
import os

# windows
if os.name == 'nt':
    path = '../input/data/'

    import japanize_matplotlib
    sns.set(font="IPAexGothic")

elif os.name == 'posix':
# Kaggle
    if 'KAGGLE_DATA_PROXY_TOKEN' in os.environ.keys():
        path = '/kaggle/input/'

# Google Colab
    else:
        from google.colab import drive
        drive.mount('/content/drive')
        !ls drive/My\ Drive/'Colab Notebooks'/xxx # xxx 書き換える
        path = "./drive/My Drive/Colab Notebooks/xxx/input/data/" # xxx 書き換える
        # セッションの残り時間の確認
        !cat /proc/uptime | awk '{print $1 /60 /60 /24 "days (" $1 / 60 / 60 "h)"}'

print(os.name)
print(path)
```
【GNOME】日本語変換時に変換候補文字が消えずに残ってしまう不具合の回避方法

LinuxのウィンドウマネージャであるGNOMEで日本語変換する際に、変換候補の最後の文字が消えずにカーソル位置に表示され続ける問題の回避方法です。

いくら検索しても出てこないので特殊な環境下でしか発生しないのかもしれませんが、同じ症状に遭遇している人と将来の自分のために記事にしました。

# 環境

ローカルインストールのUbuntuにGnomeを入れ、標準で入っていたibus-mozc（「Google日本語入力」）を使用して日本語入力した際に発生しました。

Ubuntu 18.04.4 LTS
GNOME 3.28.2
ibus                                       1.5.17-3ubuntu5.2
ibus-mozc                                  2.20.2673.102+dfsg-2ubuntu0.18.04.1

# 症状

ターミナル上などで日本語変換しようとして、例えば「にほんご」と入力し、思い直してバックスペースで全ての文字を削除すると、なぜか最後の「ご」だけ消えずにカーソル位置に表示されたままになってしまいます。

# 対処方法

IMEをmozc登場前に主流だったAnthyに変更します。
(私は長いことCannaを使っていましたが)

Anthyのインストール

```sh
sudo apt install ibus-anthy
```

IMEを変更
次の順にメニューを選択して変更します

```
設定　ー＞　地域と言語　ー＞　入力ソース　「＋」　ー＞　日本語　ー＞　日本語(Anthy)
```

私の環境では、上記で解消しました
pyplotではxticks()、Axesではset_xticklabels()を使うんだって。

（matplotlib ver3.2.0）

matplotlibで描画したグラフの目盛り文字列を変更したい場合、タイトルの通り使い分けます。
ちょっと使い方にクセがあるのでまとめました。

### 基本的な構文

```python
#pyplot.xticksは、目盛りの座標値を第一引数、置き換え文字列を第二引数とする
plt.xticks([1, 2, 3, 4, 5], [ "A", "B", "C", "D", "E"])

#axes.set_xticklabelsは、置き換え後の文字列だけ指定する
axes.set_xticklabels(["A", "B", "C", "D", "E"])
```

同様に、pyplot.yticks()も、axes.set_yticklabels()で置き換えられます。


### axes.set_xticklabelsの注意すべき点
axes.set_xticklabels()では、目盛りを全体の文字列を順次指定する必要があるため、目盛りがたくさんあると、一部の目盛りだけを変更したい時などに面倒です。

例えば、次のようにプロットすると細かい目盛りが付いてしまい、全ての文字列を設定するのがとても手間だったりします。

```python
fig, ax = plt.subplots()
ax.plot([1,2,3,4,5] , [3,4,5,6,7])
```
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254095/8e65b2ca-4578-5c5d-f974-d5e8618bec17.png">

この状態で次のように指定しても、下のグラフのように0.5〜2.5の位置に指定文字が配置されてしまうイメージです。

```python
ax.set_xticklabels(["A", "B", "C", "D", "E"])
```

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254095/bb0192cc-afcc-9417-4860-159562bddf4d.png">

素直にがんばって設定するならば次のように書けます。

```python
ax.set_xticklabels(["", "A", "", "B", "", "C", "", "D", "", "E"])
```
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254095/021326a9-cea1-e454-2359-8f0f68a6023f.png">

設定を多少簡略化できそうな方法を、試行錯誤して次項にまとめました。

### axes.set_xticklabelsの設定を簡略化する方法
#### あらかじめ目盛り表記を限定する
axes.set_xticks()で、文字列に置き換えたい座標に限定してから置き換えます。

```python
ax.set_xticks([1,2,3,4,5]) 
ax.set_xticklabels(["A", "B", "C", "D", "E"])
```

<img width=400 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254095/1f23adde-25cb-1b09-7ba0-fca890953ae0.png">

#### axes.get_xticklabels()を使って置き換える
axes.get_xticklabels()で現状の目盛りを取得できるため、それを基に必要な箇所だけ新たな文字列で置き換えます。

なお、axes.get_xticklabels()はTextオブジェクトのため少し工夫が必要です。
目盛りの文字列そのものには、次のようにアクセスできます。

```python
for item in ax.get_xticklabels():
    print(item.get_text())

#出力結果
0.5
1.0
1.5
2.0
2.5
3.0
3.5
4.0
4.5
5.0
5.5
```

上記より、次のように書くことで目盛り文字列を置き換えます。

```python
fig, ax = plt.subplots()
ax.plot([1,2,3,4,5] , [3,4,5,6,7])
fig.canvas.draw() #座標値などを決めるために呼び出しておく
                  #これを呼び出さずに、get_xticklabels()を読んでも文字列が取れない
                  #ちなみにplot.show()だとプロットがFixしてしまうのでダメ

d = {1:"A", 2:"B", 3:"C", 4:"D", 5:"E"} #置き換える座標と文字列を辞書で定義しておく

#辞書に登録した座標の位置を置き換えていく
#それ以外の位置は空白とする
#（ここはちょっとテキトー。やりたい文脈に応じて書きかえが必要ですね。）
l = []
for item in ax.get_xticklabels():
    k = float(item.get_text()) 
    if k in d:
        l.append(d[k])
    else:
        l.append("")
ax.set_xticklabels(l)

plt.show()
```

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254095/83e39b0a-559e-2894-c3cd-2f0fe46ce3ff.png">

ちなみにこちらの方法では、マイナー目盛り線も消さずに残すことができます。
まあ、、上のaxes.set_xticklabelsの設定を簡略化する方が良いですね。
Angularのagm-polygonをngForで使う方法

■やりたかったこと
agm/coreのagm-polygonでポリゴン毎にfillColorを変えたかったのでagm-polygonタグでngForを使ってTS側でポリゴンを作成してバインドする

■HTML側
`<agm-map [longitude]="135" [latitude]="35" [zoom]="16">
  <agm-polygon
    *ngFor="let polygon of polygonList"
    [fillColor]="polygon.fillColor"
    [fillOpacity]="polygon.fillOpacity"
    [paths]="polygon.paths"></agm-polygon>
</agm-map>`

```typescript
import { Component, OnInit } from "@angular/core";
import { LatLngLiteral } from "@agm/core/services/google-maps-types";

@Component({
  selector: "app-map-sample",
  templateUrl: "./map-sample.component.html",
  styleUrls: ["./map-sample.component.css"]
})
export class MapSampleComponent implements OnInit {
  constructor() {}

  polygonList: polygon[];

  ngOnInit(): void {
    this.polygonList = [];
    this.polygonList.push({
      fillColor: "red",
      fillOpacity: 0.1,
      paths: [
        { lat: 34.999, lng: 135 },
        { lat: 35, lng: 134.999 },
        { lat: 35, lng: 135.001 }
      ]
    });
    this.polygonList.push({
      fillColor: "blue",
      fillOpacity: 0.1,
      paths: [
        { lat: 35.0, lng: 134.999 },
        { lat: 35.001, lng: 135.0 },
        { lat: 35.001, lng: 135.002 }
      ]
    });
  }
}

interface polygon {
  fillColor: string;
  fillOpacity: number;
  paths: Array<LatLngLiteral>;
}
```
paizaレベルアップ問題集　連休を伸ばす1 (paizaランク B 相当)

[paizaのレベルアップ問題集を解いた](https://paiza.jp/works/mondai/dateset/extend_holidays_1?language_uid=c-sharp&t=ecd596ebc3c0b667e5417fa4eb1e8e40)
#####自力で解いたコード
```c#
    class Program
    {
        static void Main(string[] args)
        {
            string[] input = Console.ReadLine().Trim().Split(' ');
            int N = int.Parse(input[0]), L = int.Parse(input[1]); //N日のリスト、L日まで連休が使える
            input = Console.ReadLine().Split(' '); //1なら休業日、0なら営業日
            int max = 0;
            //連休の初日を１日ずつずらしながら、取れる休みを求める
            for(int i = 0; i < N; i++)
            {
                int temp = 0;
                int paidHolidays = L;
                for(int j = i; j < N; j++)
                {
                    if(input[j] == "1")
                    {
                        temp++;
                    }else if(paidHolidays > 0) { //有休が残っている場合
                        temp++;
                        paidHolidays--;
                    }
                    else
                    {
                        break;
                    }
                }
                if(temp > max)
                {
                    max = temp;
                }
            }
            Console.WriteLine(max);
        }
    }
``````
#####[youtubeの解説動画](https://www.youtube.com/watch?v=yudu6zB7XKI)を視て書いたコード
```c#

    class Program
    {
        static int howManyHolidays(int firstDay,int N,int L, int[] list)
        {
            //元々休みの日と有休をとった日の合計を求める
            int one = 0;
            int zero = 0;
            while(firstDay + one + zero < N)
            {
                if(list[firstDay + one + zero] == 1)
                {
                    one++;
                }
                else
                {
                    if(zero == L)
                    {
                        break;
                    }
                    zero++;
                }
            }
            return one + zero;
        }
        static void Main(string[] args)
        {
            string[] input = Console.ReadLine().Trim().Split(' ');
            int N = int.Parse(input[0]), L = int.Parse(input[1]); //N日のリスト、L日まで連休が使える
            input = Console.ReadLine().Split(' '); //1なら休業日、0なら営業日
            int[] list = new int[N];
            for(int i = 0; i < N; i++)
            {
                list[i] = int.Parse(input[i]);
            }
            int max = 0;
            for(int firstDay = 0; firstDay < N; firstDay++)
            {
                int temp = howManyHolidays(firstDay, N,L,list);
                if(temp > max)
                {
                    max = temp;
                }
            }
            Console.WriteLine(max);
        }
    }
````
競技プログラミング(AtCoder)コーナーケース事例記録

# 概要
[AtCoder](https://atcoder.jp)に参加して暫く経つがコーナーケースに時間取られたり、そのせいで解けなかったりすることが無くならない。パフォーマンス上がらないのは基本的に知識が足りないところが大きいのだが、コーナーケースにも脚を引っ張れている（しかも気分悪くなる）のでコーナーケースを記録分類してみることにする。
随時追記予定

# コーナーケース事例

| 種類      | 問題  | メモ（どういうコーナーケースだったか）    |
|:-----------------|:--|:------------------|
| 値が小さい時の例外  | [panasonic2020-B Bishop](https://atcoder.jp/contests/panasonic2020/tasks/panasonic2020_b) | H=1, W=1のとき角行が移動できないので例外となる。問題は一見非常に簡単なため却って気付くのに時間かかった。 |       
| 数式変形（両辺二乗）  | [panasonic2020-C Sqrt Inequality](https://atcoder.jp/contests/panasonic2020/tasks/panasonic2020_c) | 不等式の両辺を二乗するさい、正負の条件チェックをさぼると失敗する。 |