OmniAICreator/Qiita-1.07M huggingface dataset:
【Spring Batch】ExecutionContextにたくさんデータを入れるのはやめようね！

この記事は「[ゆめみ その2 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/yumemi2)」の6日目の記事です。

<img width="335" alt="スクリーンショット 2019-12-05 23.40.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391127/08e9dd54-6551-44da-a1f8-87d105c46be5.png">



# ExecutionContextとは

ExecutionContextはSpring BatchでJobに使用するデータを保管するためのクラスです。
JobやStepの実行ステータスなどの様々なデータが保管されており、デフォルトではメタテーブルに、BatchConfigurerなどを使用して設定を変更すればメモリ上で管理することが可能です。

ExecutionContextにはJob用とStep用で２種類あります。


## JobExecutionContext

通常Step間でデータを受け渡すことはできませんが、JobExecutionContextを使用するとステップの処理の結果やステータスを別のステップに受け渡したり、jobBuildFactory内で呼び出したりすることができます。

<img width="858" alt="スクリーンショット 2019-12-05 23.36.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391127/861179d3-fb8e-a2a2-045b-9bca14ca9871.png">





## StepExecutionContext

StepExecutionContextは主にチャンクの実行回数やリスタートのための情報を管理するために使用します。
Spring BatchではItemReaderなどのチャンク関連のクラスにはデフォルトで設定されています。
ただしJobExecutionContextとは異なり、他のステップからは参照できない仕組みになっています。

<img width="782" alt="スクリーンショット 2019-12-05 22.47.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391127/869e2d42-cddb-a2b7-fbc6-5e1af676a2d7.png">




# 何が問題か

バッチ処理を実装するにあたって、外部から取得したCSVファイルを加工してDBに保存するなんて処理はよくあるものかと思います。

しかしながら何万行とあるCSVデータをそのまま直接他のチャンクやステップに受け渡すとなると話は変わってきます。

## メタテーブルのカラムサイズ

設定がデフォルトの場合、ExecutionContextはSpring Batch実行時に自動生成されるメタテーブルにJson形式でインサートされます。

ただこのカラム、保存できる容量が2500バイト程度なのでそれ以上の長さの文字列を保存することはできません。
要するにどんなに頑張っても2500文字までしか保存できないと言うことです。

またSpring BatchではXstreamでJavaのPOJOをシリアライズするため、それで変換できないオブジェクトは保管することはできません。

後者の問題に関しては予めjacksonなどを使用してJson文字列に変換することで回避はできますが、前者に関してはどうしようもありません…


## メモリに保存する

じゃあメタテーブルなんか使わなければいいじゃん！

Spring Batchでは[こちらの記事のように](https://qiita.com/sengoku/items/801c7b44cb38a635060e)メタテーブルを使わずにオンメモリでデータを管理するように変更することができます。

これによってどんな長さの文字列だろうがメモリの容量ある限り無限に保存することができます。


# 話は変わり、とある本番環境

こうして外部から取得したCSVをStepExecutionContextに保存して他のチャンクに受け渡し、DBを更新するバッチ処理を作ったAさん。

彼はそのまま保守を任されることになります。

彼は毎日変わりなく流れ続けるログを眺めつつ、「最近なんかバッチ処理の実行時間が長くなったかな？」なんて感じつつも、特に問題がないためそのまま放置してました。

## そしてある日…

Aさんが呑気にログを眺めている裏ではそれなりに大変なことが起きつつありました。

開発時は数千行程度だったCSVも時間が経つにつれて増えていき、最終的には数十万行もの膨大なファイルに変貌していたのです。

それでもメモリの続く限り、サーバは唸りを上げて処理し続けます。

そしてある日HEEPが全てのメモリを食い潰した時、ついに**それ（障害）**が訪れます…

<img width="436" alt="スクリーンショット 2019-12-05 23.29.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391127/452256dc-64e8-37b2-2efc-a17ee245a83c.png">


# こうならないためには

こうならないためには主に二つの解決方法があります。

1. 処理がステップ内で完結するようにし、データを他のステップに渡さなくても済むように設計する。
2. バイナリファイルとして一時保存し、必要なStepで読み込むようにする。

どちらも設計レベルでの話になりますが、間違っても直接ExecutionContextに大量のデータを入れたりしないように工夫しましょう。




## 参考文献
[[Java][Spring][Spring Batch] Spring Batchのメタデータテーブルを作らせない/使わせない](https://qiita.com/sengoku/items/801c7b44cb38a635060e)
Maplat Coreの設定を設定ファイルから行う

Maplat Advent Calendar 4日目は、Maplat Coreの設定を設定ファイルに外出しする方法です。

昨日まではMaplatアプリの動作設定を、コードの中に書き込んで動かしていました。
具体的には、`option`オブジェクトの中の`setting`属性の下に、動作設定を書いていた形です。
ですが、これだとアプリの構成に変更があるたびごとに、JSコードファイルを修正しないといけなくなるので、嫌な感じですよね。
できれば設定は設定ファイルとして外出ししたいので、その方法について解説します。

今日の内容が動くバージョンは、CodeSandBoxのこちらで公開されています。 => [CodeSandBox Maplat Advent Calendar day 4](https://codesandbox.io/s/maplat-advent-calendar-day4-wpkuz)

設定を外出ししたロジックは以下のような感じになります。

```app.js
import "@maplat/core/dist/maplat_core.css";
import { MaplatApp } from "@maplat/core";

var option = {
  appid: "maplat_ac_day4"
};

var app = new MaplatApp(option);
app.waitReady.then(function() {
  console.log("Maplat App Ready");
});
```

単純に`setting`を全部無くしただけですね。
`option`は`appid`の指定だけになり、とてもシンプルになりました。
しかし、設定ファイルの読み込み元らしきものは指定されていません。
どこから読み込むのでしょうか。

答えは、`index.html`と同じ階層に配置された`apps`という名前のフォルダに、`{appid}.json`という名前のファイルを探しにいき、その内容を設定ファイルとして読み込みます。
ここでは`appid`は`maplat_ac_day4`ですので、`apps/maplat_ac_day4.json`を探しに行くということです。
その中身は次のようになります。

```apps/maplat_ac_day4.json
{
  "home_position": [139.5321, 36.249302],
  "default_zoom": 17,
  "start_from": "tatebayashi_ojozu",
  "sources": [
    {
      "mapID": "tatebayashi_ojozu",
      "setting_file":
        "https://s.maplat.jp/r/tatebayashimap/maps/tatebayashi_ojozu.json"
    },
    "osm"
  ]
}
```

純粋に、昨日までJSファイルに書かれていた`setting`の内容が書かれているだけですね。
ただし、JSONファイルとして読み込むので、JSONの書式を満たしていないといけないので（ハッシュキーの値を""で囲むなど）、その点だけ気をつけて。
すると、昨日までの例と同様、普通に動作します。
動作内容は同じなので、画面キャプチャなどは省略します。

以上のような方法で、Maplatアプリの動作設定をJSコードの外に設定ファイル化することができました。
残念ながら今対応しているのは`apps/{appid}.json`を見に行く形だけで、URLを指定して遠隔の設定ファイルを取りに行くと言ったようなことは現状できません。
この辺はおいおい対応していきたいと思います。

明日は地図の枚数を2枚増やし、いよいよAPIを使って、地図表示の切り替え方法などを述べたいと思います。
【5日目】シンプルデータベース実装③

# まえがき
本日はテーブルを作成・削除する部分の実装について記載していきます。

* テーブルを作成する(←今回)
* データを挿入する(Done)
* データを取得する(Done)
* データを更新する(Done)
* データを削除する(Done)
* テーブルを削除する(←今回)

## テーブルを作成する
テーブルの作成は、テーブル名とカラム名のみ指定できます。カラムのドメインやPK、制約などは設定できません。テーブル作成時は、テーブル名やカラム名をあとから参照したりできるようシステムテーブルに登録します。Oracleを真似て、ms_tablesとms_tab_columnsにテーブル名とカラム名をそれぞれ登録します。
したがって、テーブル作成は下記の手順になります。

1. データを入れるためのオブジェクトを作成する
2. ms_tablesというシステムテーブルに登録する
3. 各カラムごとにカラムインデックスを入れるためのオブジェクトを作成する
4. ms_tab_columnsというシステムテーブルにカラムを登録する

## テーブルを削除する
テーブルの作成とは反対に、テーブル削除は下記の手順になります。

1. ms_tablesからテーブル情報を削除する
2. テーブルデータを入れるオブジェクトを削除する
3. 削除するテーブルに定義されたカラムを全てms_tab_columnsから削除する
4. カラムインデックスを削除する

# まとめ
テーブルの作成・削除は特に難しいところはないですね。
明日はシンプルデータベースのソースを公開します。Erlang得意な人はぜひ指摘をお願いします。
明後日はシンプルデータベースに対して命令を出すクライアントソースについて説明し、シンプルデータベースのテストをし、性能を測っていきたいと思います。
Laravelで画像サイズを変更して保存する方法がめちゃめちゃ簡単だった話



はじめまして！qiita初投稿です😆

最近Laravelで開発することが増えてきて、その中でも便利だなーと思った「画像サイズの圧縮」について書きます。

随時間違っている部分などは訂正していくと思います。ご指摘もいただけると嬉しいです🙌


# 開発環境

PHP 7.3.11
Laravel Framework 6.5.1
Composer version 1.9.1

## Laravelで画像処理をする。
今回自分は「interventionImage」というパッケージを利用して、画像サイズを小さくして保存を実装しました。

interventionImageはphpの画像処理ライブラリGD LibraryとImagickをサポートしています。

自分はGD Libraryを使用して実装しました。

GD Libraryのインストール方法は環境によっても変わってくると思うので、お使いの環境に合わせてインストールしてください。

## 実装までの流れ

interventionImageの公式はこちら
http://image.intervention.io/getting_started/installation#laravel

実装の流れとしては、
1.パッケージのインストール。
2.Laravelで使用できるようにセットアップ。
3.実際に画像サイズを変更してみる。

## 1.Laravelにintervention/imageをインストールする。
composerを使ってintervention/imageをインストール。

```composer require intervention/image```

## 2.セットアップ

InterventionImageをインストールしたら、Laravel構成ファイル`config/app.php`を開き、providers配列とaliases配列に次の行を追加します。

providers配列に、このパッケージのサービスプロバイダーを追加。
```Intervention\Image\ImageServiceProvider::class,```

このパッケージのファサードをaliases配列に追加。Imageだとモデルとして定義したクラスと被りそうだったので、InterventionImageとしてaliasを保存。
```'InterventionImage' => Intervention\Image\Facades\Image::class,```

```php:config/app.php
~前略~

'providers' => [

  ~中略~

  // Add Intervention Image.
  Intervention\Image\ImageServiceProvider::class,
],
'aliases' => [

  ~中略~

  'Hash' => Illuminate\Support\Facades\Hash::class,
  // Add Intervention Image.
  'InterventionImage' => Intervention\Image\Facades\Image::class,

~後略~
```



### 3.実際に画像サイズを変更してみる。
今回は画像のアスペクト比をそのままで保存しつつ、横幅を1080pxにしました。

```php:config/PostsController.php
//エイリアスに追加したファサードを呼び出す。
use \InterventionImage;

~中略~

//formからの画像リクエストはimagefileで受け付けしたのでimagefileを設定しています。formに合わせて変更してください。
$file = $request->file('imagefile');
$name = $file->getClientOriginalName();
//アスペクト比を維持、画像サイズを横幅1080pxにして保存する。
InterventionImage::make($file)->resize(1080, null, function ($constraint) {$constraint->aspectRatio();})->save(public_path('/images/' . $filename ) );;
```


ちなみに、横幅と高さを指定する場合はもう少しシンプルにできます。

```php:
InterventionImage::make($file)->resize(1080, 700)->save(public_path('/images/' . $filename ) );;
```

`resize`で画像の大きさを指定するだけだったので、めっちゃ簡単だなーと思いめっちゃ感動しました。

## まとめ

少し面倒だと思ってた画像のresizeが、かなりシンプルな書き方で実装できて感動しました😭

とはいえqiitaの初投稿もできたので、これきっかけでqiitaへの投稿を増やして行けたらいいなーと思いました！
FontFamilyでフリーフォントを使いたい

#経緯
FontFamilyで宣言できるFontの種類ってどれも似たり寄ったりでつまんない！！
シャレオツな文字使いたい！！
フリーフォント表示してくれ！！
#手順
###1.使いたいフリーフォントをダウンロードする
まずは自分の気に入ったフォントをダウンロードします！
僕が検索に使ったサイトはこれ
[フォントフリー](http://fontfree.me/)
（今回僕は「切り絵字フォント」をダウンロードしました）
ダウンロードしたフォントファイルはttf形式になっていると思いますが、これをwoff形式に変換します。
ちなみに、woffとはWeb Open Font Formatのことで、Webページ埋め込み用フォーマットでWebフォントとして使われるために作られたフォントファイル形式です。ほとんどのブラウザで使用できるようです。
###2.ダウンロードしたフォントファイルをwoff形式に変換する
以下のサイトで公開しているWOFFコンバータをダウンロードして、先ほどダウンロードしたttf形式のフォントファイルをwoff形式に変換します。

[WOFFコンバータ](https://opentype.jp/woffconv.htm)
###3.CSSでフォントを指定する
あとは先ほど変換したフォントファイルをCSSで指定するだけ！
`@font-face{
  font-family: 'SyareotuFont';
  src: url('./kirieji.woff') format('woff');
}`

@font-faceで読み込むフォントを指定します。
次にそのフォントファミリーを好きな名前に名付けたら完成です！

あとは適用させたいタグやIDにチョチョイとフォントファミっちゃってください⭕️
Python3 + mysql-connector-pythonで実行したSQLを知りたい時

あれ？なんで出力結果が期待値通りじゃないんだ？ってときにSQLを確認したいときはよくありますが、Python入門したばかりでやり方がわかりませんでした。Google先生に質問してみるも、意外と探すのに苦労したので備忘のためまとめておきます。

## バージョン
Python：3.7.3
mysql-connector-python：8.0.18

## 本題

```
cur.execute("select * from tables where id = (%s)", (id,))
print(cur._executed)
```

これでOK。
Windows Server 2019 からNASにつながらないとき

# きっかけ
以前から使っているNASにいろいろデータ（インストールモジュールとか）入れてるが、
Windows Server 2019からアクセスできなかったので、そのときの対応メモ


# ファイル共有のゲストアクセスを許可する
## 発生したエラー
ID,パス無しで自由にアクセスできるNASに繋いだところアクセス不可
※IPアドレス間違えたわけでもなく、別のPC,サーバ(Win2016)からは普通にアクセス出来できる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/5a093011-6848-78bd-4c9a-d3a5d873909d.png)

## イベントログによると。。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/83a0726c-0091-f9c8-f765-6ae3ba94e9f7.png)

## 対処法
ググると速攻出てくる
https://support.microsoft.com/ja-jp/help/4046019/guest-access-in-smb2-disabled-by-default-in-windows-10-and-windows-ser


1. gpedit.msc
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/ae966ea3-d6d1-4117-3eb0-5619567eaab3.png)

2. 「安全でないゲストログオンを有効にする」を有効にする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/d1009964-e4aa-bdf4-784d-80c3265cf520.png)

3. つながったよ！（再起動不要）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/8b981920-95a7-2a50-7582-05ca7f671b10.png)
ファイル共有のバージョン

# 対応しているバージョンの確認
## Windows Server 2016の初期状態
```
PS C:\Users\Administrator> Get-WindowsFeature FS-SMB1

Display Name                                            Name                       Install State
------------                                            ----                       -------------
[X] SMB 1.0/CIFS ファイル共有のサポート                 FS-SMB1                        Installed


PS C:\Users\Administrator>
PS C:\Users\Administrator> Get-SmbServerConfiguration | Select EnableSMB1Protocol

EnableSMB1Protocol
------------------
              True


PS C:\Users\Administrator>
PS C:\Users\Administrator> Get-SmbServerConfiguration | Select EnableSMB2Protocol

EnableSMB2Protocol
------------------
              True
```

## Windows Server 2019の初期状態
```
PS C:\Users\Administrator> Get-WindowsFeature FS-SMB1

Display Name                                            Name                       Install State
------------                                            ----                       -------------
[ ] SMB 1.0/CIFS File Sharing Support                   FS-SMB1                        Available


PS C:\Users\Administrator>
PS C:\Users\Administrator> Get-SmbServerConfiguration | Select EnableSMB1Protocol

EnableSMB1Protocol
------------------
             False


PS C:\Users\Administrator>
PS C:\Users\Administrator> Get-SmbServerConfiguration | Select EnableSMB2Protocol

EnableSMB2Protocol
------------------
              True


PS C:\Users\Administrator>


```

### 諸事情でSMB1.0を使いたい場合
ササっと役割と機能の追加ウィザードで
SMB 1.0/CIFS File Sharing Supportにチェックを入れインストール
再起動要求があるのでOS再起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/e72f605d-240f-061e-058d-dbc5eb508840.png)

こんな結果になるよ

```
PS C:\Users\Administrator> Get-WindowsFeature FS-SMB1

Display Name                                            Name                       Install State
------------                                            ----                       -------------
[X] SMB 1.0/CIFS File Sharing Support                   FS-SMB1                        Installed


PS C:\Users\Administrator> Get-SmbServerConfiguration | Select EnableSMB1Protocol

EnableSMB1Protocol
------------------
              True


PS C:\Users\Administrator> Get-SmbServerConfiguration | Select EnableSMB2Protocol

EnableSMB2Protocol
------------------
              True


PS C:\Users\Administrator>
```

# 繋いでいるバージョン
```
PS C:\Users\Administrator> Get-SmbConnection

ServerName    ShareName UserName           Credential             Dialect NumOpens
----------    --------- --------           ----------             ------- --------
192.168.0.*** IPC$      W131\Administrator ***\***                3.1.1   0　←Windows Server 2016に繋いだ時
192.168.0.*** IPC$      W131\Administrator ***\***                3.1.1   0　←Windows Server 2019に繋いだ時
192.168.0.*** IPC$      W131\Administrator ***\***                2.1     1　←Windows 7に繋いだ時
192.168.0.*** IPC$      W131\Administrator ***\***                3.1.1   1　←Windows 10に繋いだ時
192.168.0.*** share     W131\Administrator ***\***                2.1     2　←BUFFALOの個人向けNASに繋いだ時


PS C:\Users\Administrator>
```
Office365のプロフィール写真をPowerAppsに表示する

#はじめに
引き続き、PowerAppsで実装した箇所を記事にしました。
今回は、Office365の顔写真をPowerAppsで使う方法です。

- 躓き編<br>
https://qiita.com/pefume/items/e00e3167765bd2f7f115
- PowerAppsからSkype通話へ飛ばす<br>
https://qiita.com/pefume/items/8fcc5785d9d7cab01fba

#やりたいこと
例えば、PowerAppsでユーザー一覧を作った時、
下図の赤枠箇所に顔写真を表示したい。そんな時の実装方法です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223202/11594467-b657-ec95-a178-6421d8bf990b.png" width=40%>

#実装方法
PowerAppsユーザーはOffice365を使用している事前提なので、
顔写真としてはOffice365のプロフィール画像を使用したいと思います。
![アプリの一覧イメージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223202/e855f484-a8d0-c684-baea-c99e5c45c7f3.png)

## 1. データソースに"Office 365 ユーザ"を追加
自分が所属する組織内のユーザ情報を使用する為に、
まずは"Office 365 ユーザ"の接続を追加します。
PowerAppsのデータソースで、"Office 365 ユーザ"を検索して接続の追加。
![マイアカウントの写真](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223202/5d1321e7-4a03-11a0-7b81-6bd8b8528d73.png)

## 2. メディアから"画像"コントロールを追加
挿入メニュー、メディアから画像を選択して、"画像"コントロールを画面に追加します。
この時、挿入先が一覧の各行になるように、
左のツリービューで、挿入するギャラリーを選択してから追加しましょう。
今回の例では"BrowseGallery1"です。
![画像コントロールの作成](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223202/49cea21b-b47b-7edb-ffe0-11fc78133cde.png)


## 3. 各ユーザーのプロフィール画像を表示する
Office365ユーザー.UserPhoto関数を使用する事で、
各ユーザのプロフィール画像を表示できるようになります。
"画像"コントロールのImageに以下を指定。

```
Office365ユーザー.UserPhoto(ThisItem.メールアドレス)
```
今回はギャラリーのリソースであるテーブルに、
カラム"メールアドレス"があったので、これを引数に設定しています。
UserPhotoの引数には、各ユーザに割り当てられているOffice365のid等も指定できるのですが、
一番使いやすいのはメールアドレスですかね。
![メールアドレスを元にプロフィール画像表示](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223202/15c9ef49-ba04-4f24-d4c3-5564f4d97297.png)

## 4. 罫線をつける
中にはプロフィール画像を設定していない人もいるはずです。
この場合は画像を引き込めず、アプリ上では顔写真部分が真っ白になってしまう。
最低限、画像のプロパティから罫線を付けてあげます。
![をつける](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223202/04ec3768-5e43-f8d4-7773-136a56532790.png)

## 5. できあがり
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223202/b9ede339-2028-7da4-00cf-b797bba06143.png" width=40%>
Figmaデスクトップアプリでプラグインが使えなくなった時に試したこと

#はじめに
普段、業務でFigmaをバリバリ使っているのですが、先週末頃からデスクトップアプリでプラグインを使おうとするとエラーが発生するようになりました。
ブラウザで利用する分には使えたので放置していたのですが、プラグイン開発にはデスクトップアプリが必須なので調査することにしました。

結論を言っておくと
「バージョンを変更したら何故か直った」
ということになります。


#現状分析
##エラー内容
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44990/cd308fcf-560f-3a22-6397-d39ae723a706.png)
ERR_CONTENT_DECODING_FAILED...何故デコード処理が？
触れることもできない部分なので、更新漏れやキャッシュなどで古いコードが動いている？？

##発生条件
* Macのデスクトップアプリで発生
* バージョン 77.7.0
* 全てのプラグインで発生（公開されているもの&開発したもの）

ブラウザでは発生しないし、周りの人のデスクトップアプリでは発生しないので、私のPCに原因がありそうでした。

#コードを更新してみよう
エラー内容と発生条件を合わせて考えると、私のPC上に古いコードが存在していそうだったので更新方法を調べていきました。

##メニューからUpdateしてみる
まずはFigmaのUpdateを試しました。
<img width="263" alt="スクリーンショット 2019-12-05 22.35.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44990/3ea298ff-d274-8ba9-5eb3-e1694deac375.png">
<img width="421" alt="スクリーンショット 2019-12-05 22.36.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44990/dfedc804-344e-3d97-0699-7d57fa9349ab.png">
アプリは最新のようでした。Reload All Tabsしても特に変わらずでした。


##キャッシュを調べてみる
次にキャッシュについて調査しました。
同じくFigmaのキャッシュの在処を探している人は見つかったのですが、キャッシュの有無と在処の確かな情報は見つかりませんでした。
一応上記の人が言っていたブラウザのキャッシュは削除しましたが、特に変わらずでした。


##アプリを入れ直してみる
次に考えたのが、アプリ内にキャッシュしている可能性でした。
アプリを一度削除し、ダウンロードし直しました。
しかし、これも特に変わらずでした。別の場所に保持しているかも...


##Forumで検索してみる
次にFigmaのCommunityで検索をかけました。
[Figma Community](https://spectrum.chat/figma?tab=posts)

探しているとデスクトップアプリのベータテスト版を見つけました。
[Figma Desktop App Beta Testing (November)](https://spectrum.chat/figma/announcements/figma-desktop-app-beta-testing-november~4a32d53e-3ef3-4b4f-96e5-a826f810c423)
もしかしたらエラーに関連している箇所が修正されているかも。
とダウンロードしてみたところプラグインが動くようになりました！

アップグレード
77.7.0→83.3.0

##ダウングレードしてみる
動くようになったものの何故直ったのか分からなかったため、元のバージョンに戻してみることにしました。

ダウングレード
83.3.0→77.7.0

動かなくなるのかと思いきや、バッチリ動きました...。
バージョンが変わると何かが破棄されるのでしょうか？

#おわりに
スッキリしないまま解決してしまったのですが、誰かの役に立てば幸いです！
明日からはプラグイン開発していくぞ！
htmlをReactコンポーネントにぶちこんでやるぜ〜〜！！

# はじめに

[いなたつアドカレ](https://qiita.com/advent-calendar/2019/allinatatsu)の五日目の記事です。

今回はReactで生のhtmlを扱うための方法とその時の注意について少し、、、

## ざっくりいうと

- dangerouslySetInnerHTMLを使おう
- XSS に気をつけよう
- markdownから変換して表示も可能だよ

## dangerouslySetInnerHTMLを使う

```jsx
<span dangerouslySetInnerHTML={{ __html: html}} />
```

dangerouslySetInnerHTML属性に__html(あんだーばーあんだーばーへいちてぃーえむえる)に展開したいhtmlを設定する **オブジェクト**　を渡すことで指定したhtmlをタグ内部に展開することができます。

## dangerouslyやねん

XSSの危険がつきまとってくるんですよね。

XSSってのはクロスサイトスクリプティングといって、テキストボックスにhtmlを埋め込み、予期せぬ動作をさせようとすることです。

これの何がdangerouslyかというと
- テキストボックスにスクリプトを入力し、javascriptを実行させることで、クッキーなどを盗みなりすましができる
- 同様に、アプリケーションの機能を悪用されるかもしれない
クッキーでセッションIDなんかを保持しているとなりすましの温床になりかねないですね。。。。
dangerouslyって名前についてるのはこういうところからなので、まあ、あまり使わない方がいいですね。
## じゃあどーやって対策すんの
** サニタイズ **

## markdownがうんぬんかんぬん
markdownを生のhtmlに変換してここにぶちこんでやるぜーしたらmarkdownエディタのプレビューっぽいことできるって話
次回reactとmarkedのお話を書きます。。。。
DB( データベース) 設計をしよう！！ 制約あれこれ！！

#はじめに

この記事は、2019/11/1からプログラミング学習を始めた学生がプロのプログラマーになるまでのアウトプットする為の書き込みの場である。

##not null制約

テーブルの制約に空の値を入れる事ができなくなります

## 一意性制約

一意性制約はテーブル内で重複するデータを禁止する制約です
Railsでは、カラムに対してadd_indexメソッドを用いることで一意性制約を付けることができます

```
add_index :テーブル名, :カラム名, unique: true
```
##主キー制約
Not null と　一意性制約を両方設定するのと同意

##外部キー制限

外部キー制約は、外部キーの対応するレコードが必ず存在しなくてはいけないという制約です。
外部キーのカラムに値があっても、その値を主キーとして持つ他のテーブルのレコードがなければいけません。

##感想
ずっと座ってキーボードを叩いて居ると首と腰が痛くなってきます
何か対策は、ないのでしょうか、、、


##終わりに

もっとこうした方が良いよなどご指摘頂けると幸いです
ドットインストールのfirebaseでチャットアプリ作るやつの、わからないところを調べてみた

とりあえずわからない単語調べて書いてみます。

### querySelector()

- DocumentのquerySelecto()メソッドは、指定されたセレクターまたは、グループに一致する、文書ないの最初のElementを返す。一致するものが見つからない場合はnullを返す

- 対象要素の子孫のうち、引数に指定したCSSmセレクタにマッチする最初の要素を返す

- JavaScriptから、任意のHTML要素を検出、取得することができるメソッド

- getElementById()とかgetElementByClassName()とかと似てるけど、id属性、class属性値など意識せずに、jQuery感覚で、HTML要素をセレクタ指定することができる
(idなしでもいける）

- getElementByIdの方がアクセスは素早い

```JavaScript
element = document.querySelector(selections);
```

#### 引数
#####selectors
一つまたは複数のセレクターを含むDOMString。この文字列は妥当なCSSセレクターでなければならず、そうでない場合は、SYNTAX_ERRが投げられる。セレクターとその管理の方法の詳細について、セレクターをしようしたDOM要素の指定を参照してください。


[【JavaScript入門】querySelector()によるHTML要素の取得方法まとめ！](https://www.sejuku.net/blog/70581)
[MDN web docs](https://developer.mozilla.org/ja/docs/Web/API/Element/querySelector)


## removeChild
DOMから子ノードを取り除く

##firstChild
ノードツリーの中で、最初の子ノード、もしくは子ノードがなければnullを返す。ノードがDocumentの場合は、その直接の子のリストの内の最初のノードを返す

## ノードとは
節、交点という意味
四角がノード
ハンドメイド感溢れる図ですみません






![Scannable の文書 2 (2019-12-02 22_18_59).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486722/fa4b072a-5de8-18e5-62b9-c623135ca186.jpeg)



## addEventListener
特定のイベントが対象に配信されるたびに呼び出される関数を設定する。対象としてよくあるものは、Element,Document,Windowであるが、イベントに対応したあらゆるアブジェクトが対象になる。

### 構文
***target.addEventListener(type,listener,options);***

- type：対象とするイベントの種類を表す文字列
    - submitとか
- listener：指定された型のイベントが発生する時に通知(Eventインターフェースに準拠しているオブジェクト）を受け取るオブジェクト。
- option：対象のイベントリスナーの特性を指定する、オプションのオブジェクト。次のオプションが使用できる
    - capture:Boolean値で、listenerの呼び出しを一回のみとしたいかどうかを値で指定する。trueを指定すると、listenerは一度実行された時に自動的に削除される
    - passive:Boolean値で、trueならば、listenerで指定された関数が、preventDefault()を呼び出さないことを示す。呼び出されたリスナーがpreventDefault()を呼び出すと、ユーザーエージェントは何もせず、コンソールの警告を出力する。


随時調べて追加します
今後のShizuoka.phpについて

これは、[静岡 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/shizuoka)の5日目の記事となります。


静岡でPHPの勉強会なかったので、今年から[Shizuoka.php](https://shizuokaphp.connpass.com/)をはじめました。
JavaScript, Python, Go, Haskell, Rubyの勉強会は開催されているのにPHPがない・・・。
そんな危機感をもってから5年ぐらい経って、やっと今年#1を開催できました🎉

## 定期的に続けて行きたい
3 ~ 4ヶ月に一度開催できればいいのかなと。
頻度そんなに多くはできませんが、定期的に開催していこうと思っています。
だから来てね！

## ロゴできたよ！
refs: https://twitter.com/planpot/status/1201411166162931712?s=20

@planpot先生にロゴを作ってもらいました🎉
爆速で作っててマジで感動しました！！！！


## 静岡で勉強会を主催する事について
僕は今東京に住んでいます。  
みんな勘違いされますが、静岡には住んでいません。脱藩しました。
僕は東京に住んでいます。大事なのでもう一度言います、東京に住んでいます。
(まあ毎週のように静岡に行くのでアレですが・・・ｗ)

そんな僕が地元で勉強会を主催するのは2つの理由があります。

### つながりの場を提供したい
[静岡JavaScript勉強会 #1](https://togetter.com/li/195145)に参加して、地元静岡のエンジニアと知り合いになれました。
あれから8年も立つにに未だに交流がある人がたくさんいます。
やっぱそういうつながりがあると、嬉しいし、楽しいし、技術的に学べることもたくさんあります。
あとは[勝手に勉強会作られたり](https://polidog.connpass.com/)とかｗｗｗｗ

同じようにShizuoka.phpで出来たらなと思っています。

### 地元に帰るという選択肢を持てる
勉強会に参加してみると、意外とIT企業があるんだということに驚かされました。
8年ほど前僕が求人情報で探したら、ぜんぜん見つからなかったのに・・・。

勉強会に参加することで、地元のIT企業を知れるというメリットもあり、地元に帰りたいエンジニアの手助けになればと。

### 地元が好き
静岡のエンジニアの雰囲気というか、やはり同じ地元の人と話すの楽しいし、地元の人達とPHPの話するのが楽しいです。
静岡最高です！！！！！

## これからの取組みについて
当日LT枠を用意します。
勉強会でよくある「あーやっぱLT枠申し込めばよかったなあー」っていう人いますよね？
そんな人の為に宣伝枠(当日LT枠)を用意しようと考えています。

ちょっとした発表でいいので少しでもみんなに喋ってもらい、発表の敷居を少しでも下げたいという気持ちや、当日LTしたくなっちゃう気持ち。
そんな人のために枠を設けようと思っています。

## スタッフの皆さんありがとうございます。
僕が勝手にスタッフと言っている @tomofさん, @toniokatanuki先輩には本当に感謝しきれないぐらい感謝しています。
僕はイベント運営が苦手な人間なので、かなり支えてもらっています。ありがとうございます。最高です。

## いずれは主催者を変えたい
本来は東京に住んでいる僕が主催者をやるべきではないと考えています。
今は僕が主催者としてがんばりますが、そのうち誰かに引き継げたらと思っています。

## 次回開催予告
次回#2は2/8開催予定です。
場所は三島になります。
細かいことが決まり次第connpass立てます。

## 最後に
静岡は東京からも近いし、気候も良いし、自然も多いし、富士山は静岡のものだし、本当に良いところです。
そんな静岡でもっとITが盛り上がったらいいのにと常日頃から思っています。
すこしでも力になれればと思い、これからも継続てShizuoka.phpを開催していければと思います。

## 最後の最後に
ちょっとでもShizuoka.phpが気になった方は気軽に参加してください！
SASSについて学んだことまとめ

## 目次
1. SASSとは
2. SASSの書き方

## 今回の学習のゴール
- SASSとは何か、何ができるかを知る
- 実際の使い方について知る

## 1. SASSとは
- Syntactically Awesome StyleSheetの略
- CSSを便利に使えるように拡張した言語
- 何がすごい(Awesome)か
    - セレクタやプロパティのネストで記述量が減る
    - 一度定義したスタイルのセットを簡単に呼び出せる
    - 変数で値を使いまわすことができる
    - 四則演算ができる
    - 関数が使える
- SASS記法とSCSS記法という2種類の書き方がある
    - ※ 以降の章でとりあげるexampleコードはSCSS記法をメインとする
- CSSへコンパイルが必要

## 2. SASSの書き方

### ネスト
- セレクタのネスト

```css:style.css
nav ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
nav li {
  display: inline-block;
}
nav a {
  display: block;
  padding: 6px 12px;
  text-decoration: none;
}
```
```scss:style.scss
nav ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
nav li {
  display: inline-block;
}
nav a {
  display: block;
  padding: 6px 12px;
  text-decoration: none;
}
```
```sass:style.sass
nav
  ul
    margin: 0
    padding: 0
    list-style: none

  li
    display: inline-block

  a
    display: block
    padding: 6px 12px
    text-decoration: none
```

- プロパティのネスト

```css:style.css
h2 {
  border-top: 1px solid orange;
  border-bottom: 2px dotted black;
}
```
```scss:style.scss
h2 {
  border: {
    top: 1px solid orange;
    bottom: 2px dotted black;
  }
}
```
- 親セレクタの参照

```css:style.css
a {
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
}
```
```scss:style.scss
a {
  text-decoration: none;
  &:hover {
    text-decoration: underline;
  }
}
```

### 変数

```css:style.css
body {
  color: #333;
  width: 960px;
}
```
```css:style.scss
$primary-color: #0066FF;    /* 変数の宣言 */
$main_width: 960px;    /* 変数の宣言 */

body {
  color: $primary-color;
  width: $main_width;
}
```
```css:style.sass
$primary-color: #0066FF;    /* 変数の宣言 */
$main_width: 960px;    /* 変数の宣言 */

body
  color: $primary-color
  width: $main_width;
```

### 演算
- 四則演算や文字列の連結などを行うことができる

```css:style.css
.test-box {
  width: 886px;
}
p {
  content: "hoge hoge";
}
```
```css:style.scss
$main_width: 900px;
$border_width: 2px;
 
.test-box {
  $padding: 5px;
  width: $main_width - $padding * 2 - $border_width *2;
}
p {
  content: "hoge " + hoge;
}
```

### mixin
- 同じ処理を一つにまとめることができる

```css:style.css
.box_orange {
  margin: 5px;
  padding: 10px;
  color: orange;
}

.box_yellow {
  margin: 5px;
  padding: 10px;
  color: yellow;
}
```
```css:styles.scss
@mixin basebox {
  margin: 5px;
  padding: 10px;
}
.box_red {
  @include basebox;
  color: #f00;
}

.box_blue {
  @include basebox;
  color: #00f;
}
```

### 継承
- クラスの継承ができる

```css:style.css
.box_red, .box_blue {
  margin: 10px;
  padding: 10px;
}

.box_red {
  color: red;
}

.box_blue {
  color: blue;
}
```
```css:styles.scss
%box-base {
  margin: 10px;
  padding: 10px;
}

.box_red {
  @extend %box-base;
  color: red;
}

.box_blue {
  @extend %box-base;
  color: blue;
}
```


## 参照
- [Sass Basics - Sass](https://sass-lang.com/guide)
- [SASS (scss) の基本的な使い方](http://www.webdesignleaves.com/pr/css/css_basic_08.html)
- [Sassメモ - Qiita](https://qiita.com/tomoyuki_okawa/items/b7c0d970f45435eab7c3)
MsLearnで　Azureの海に溺れる

[Azure Advent Calendar 2019](https://qiita.com/advent-calendar/2019/azure)　の　5日目です。

### 追記
MsLearnで自分のLVを把握して、
学習するのに最適なレベルを把握できる方法(英語のみ)

pluralsightは有料サイトですが、Azure関連は無料で受講できるようです。
自分も登録しましたが、無料でサインイン行けました。

https://app.pluralsight.com/library/

参考：Ms odashoさんのtwitter
https://twitter.com/MS_odasho/status/1203323826307653632

---


12/3　に本日急遽空いていた枠を見つけたので
投稿させていただくことにしました。

Azure 初心者の　yamuuunです。

リリース前のプロダクトを .net core で作っていますが
いよいよAzure上で動かす上で、やはり学習せねばならないという時期に差し掛かりました。

AzureについてはIgniteで　クラウドサービスについてのセッションを
翻訳したこの記事が分かりやすいです。
https://qiita.com/chomado/items/032454af29e3eb6a2c57


**最近、本家ＭＳの人も（何故か）急に推し始めた**
Mslearnについて書きたいと思います。




https://docs.microsoft.com/ja-jp/learn/browse/
12/5現在　現在　981のセクターが登録されてます


https://docs.microsoft.com/ja-jp/learn/browse/?products=azure
12/5現在　Azure のセクターは　356


https://docs.microsoft.com/ja-jp/learn/browse/?products=azure%2Cdotnet-core&levels=beginner
初級レベルは　238 

https://docs.microsoft.com/ja-jp/learn/browse/?products=azure&levels=intermediate
中級レベルは　135

https://docs.microsoft.com/ja-jp/learn/modules/principles-cloud-computing/
クラウドコンぴゅーてぃんぐという基礎な内容から


https://docs.microsoft.com/ja-jp/learn/modules/ai-strategy-in-government/
**官公庁/自治体において価値を生み出す AI 戦略を定義する**

といった　MsLearnという名前から想像も付かないコースもあります。


現在MSlearnでは、どの項目を勉強したらいいか分からなくなる
迷子になる人もいるという声から



ラーニングパスという形で　おすすめの学習内容を提示してくれるそうです。
https://docs.microsoft.com/ja-jp/learn/browse/?resource_type=learning%20path


なんかここ1か月でまた増えてない？
ＭＳＬＥＡＲＮのadventcalenderというものもあります。

https://adventar.org/calendars/4507

azureに興味ある方はのぞいてみてみてはいかがでしょうか(´ω`)？

**Azureの資格ラーニングパスとか増えると嬉しいですね**



個人的には
**ラーニング環境は　AWS GCPの方がまだ多くあるというイメージがあります**

個人で気には動画ハンズオンとか増えるとうれしいかな・・
youtubeのようなサービス増えてるし
https://www.qwiklabs.com/focuses/2794?locale=ja&parent=catalog
BEM(CSS設計)について

#はじめに

この記事は、2019/11/1からプログラミング学習を始めた学生がプロのプログラマーになるまでのアウトプットする為の書き込みの場である。

#BEMとは？

BEMとは、多くの開発者が取り入れているCSS設計です

#CSS設計

CSS設計は、CSSを記述する時のルールです

#BEMを使うメリット

•　**クラスの命令が簡単になる**

BEMでは、ページを構成する要素をBlock、Element、Modifierの3つに分類して考えます。
これら3つの要素を使うことで、クラス名に悩むことなくなります

**補足** :　CSS設計において、命名規則が最も難しいとされています

•　**要素の再利用がしやすくなる**

共通の要素を別の場所で再利用しようとしても、要素がHTMLに依存していると同じCSSを2つ書かなければなりませんでした。
しかし、BEMを使用することで、クラスの命名がHTML構造に依存しなくなります
HTML構造に依存しないことで、要素の再利用がしやすくなります

#BEMを使った命令

- **Black**
 - Blockとは、ある要素の大元となるブロック要素です。Blockの命名には名詞を使用します。ElementやModifierは、このBlockを起点に命名されます。
- **Element**
 - Elementとは、Blockに属する子要素です。1つ以上のElementにより、Blockは構成されています。Elementの命名には名詞を使用します。
- Modifier
 - Modifierとは、Blockまたは、Elementに特別な修飾をする要素です。Modifierの命名には形容詞を使用します。

#命令規制

* BlockとElementをつなぐ場合は、アンダースコア2つ(__)でつなぐ

* Modifierにつなぐ場合は、ハイフン2つ(—)でつなぐ

##感想
最近chatspaceというラインのようなメッセージでやりとりができるwebページの作成をしてるのですが。
今日、やっとchatspceのDB設計が終わりました
初歩的なところで、かなり時間がかかってしまいました


##終わりに

もっとこうした方が良いよなどご指摘頂けると幸いです
GroupbyしたGroupに関して条件抽出(条件を満たすGroupの要素を全て取得)する方法

# Groupbyしたgroupに関して条件抽出したい。
Pythonでgroupbyしたgroupの中から条件を満たすgroupの要素を全て取得する方法を解説する。

例えば、以下のデータがあり、最高スコアが80以上だった場合その人のデータを全て取得するということを目指すとする。

```Python
import pandas as pd
import numpy as np

df = pd.DataFrame({"name":["Yamada","Yamada","Yamada","Suzuki","Suzuki","Hayashi"],
                   "score":[60,70,80,60,70,80]})
print(df)

#       name  score
# 0   Yamada     60
# 1   Yamada     70
# 2   Yamada     80
# 3   Suzuki     60
# 4   Suzuki     70
# 5  Hayashi     80
```
（19/12/05修正）このような時は```groupby.filter```を用いると一行で書くことができる。

```Python
new_df = df.groupby('name').filter(lambda group: group['score'].max() >= 80)
print(new_df)

#       name  score
# 0   Yamada     60
# 1   Yamada     70
# 2   Yamada     80
# 5  Hayashi     80
```

　```filter()```の中身は条件に関するラムダ式となる。
 


ちなみに、私はQiitaで教えていただく前は以下のようにして、条件抽出を行なっていた。
groupbyをしたgroupごとに条件を満たすキーを取得して、そのキーに元々のデータフレームを左外部結合すれば良い。
具体的には、以下のコードとなる。

```Python
group_df = df.groupby('name').max().reset_index()
key = group_df[group_df['score'] >= 80]['name']
new_df = pd.merge(key, df, on = 'name', how = 'left')
print(new_df)

#       name  score
# 0  Hayashi     80
# 1   Yamada     60
# 2   Yamada     70
# 3   Yamada     80
```

条件を満たすキーを取り出し、そこからgroupbyの操作で消してしまったスコアの情報を復元するために、左外部結合をするという一連の流れが一行で書くことができるようになり感動しました。
07. テンプレートによる文生成

## 07. テンプレートによる文生成
引数x, y, zを受け取り「x時のyはz」という文字列を返す関数を実装せよ．さらに，x=12, y="気温", z=22.4として，実行結果を確認せよ．

###Go
```go
package main

import "fmt"

func template(x,y,z string) string {
	return fmt.Sprintf("%s時の%sは%s",x,y,z)
}

func main() {
	fmt.Println(template("12","気温","22.4"))
}
```


###python
```python
# -*- coding: utf-8 -*-

def template(x,y,z):
    return '{0}時の{1}は{2}'.format(x,y,z)

print template(12,"気温",22.4)
```


###Javascript
```Javascript
function template(x,y,z) {
    return "x時のyはz".replace("x",x).replace("y",y).replace("z",z);
}

console.log(template(12,"気温",22.4));
```

## まとめ

これは、こんなでいいのかしら？。


[トップ](https://qiita.com/naoshin1984/items/3d7814e2f8eb01eea8dd)
Redmine plugin開発 2019年個人的振り返り

## 概要

[Redmine Advent Calendar 2019](https://adventar.org/calendars/4221)の5日目の記事です。
本当は新規開発したプラグインを乗せたかったのですが、間に合わなかったので総集編とさせていただきます。

## 2019年の取り組み

### 1. 2019-04-28 Redmine.orgへプラグインリリース

https://github.com/aki360P/redmine_member_location_board
プロジェクトメンバー行先表示板pluginを公開しました。自分にとって初のredmine.orgへの投稿となる記念すべき一歩となりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434780/c789dfce-8d2a-2c48-0ef7-197acd3f9b8f.png)

下のプラグインのほうが着手はずいぶん昔から行っておりましたが、こちらは自分で一から書いたプラグインで、なんとかコードすべて理解できています。redmine4.x系列にも早いうちに対応できたので公式サイトへは先のリリースとなりました。
公開して1か月経たないうちに☆頂きました！開発者にとってお気に入り追加のなんとありがたいことか！





### 2. 2019-05-17 リソース予約システムplugin

https://github.com/aki360P/redmine_resource_booking_system

redmine_meeting_room_calendarプラグインをforkさせて頂き、がらっと内容を変えたため、新規プラグインとして登録させていただきました。JavaScriptのFullCalendarというモジュールを使って色々な物品貸し出しに使えるプラグインを作成しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434780/f47c0217-92ec-14f1-be70-16db631e3d0f.png)

こちらのプラグインはアクセス数が安定してあり、リリース直後は毎日20人の方が見てくれていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434780/31979245-23d9-0ded-07e3-e08168192738.png)

いまでも5ビュー/日くらいあり、皆さんの期待の高さを感じます。
早めにメンテナンス(バグ修正)しなければ…


### 3. 2019-06-10 Qiita初投稿！

Bitnami Redmineをdevelopmentで起動する https://qiita.com/aki360P/items/02d3c8924c386c36a39c
プラグインの開発通して敷居の高さを上げていた環境構築についてまとめました。自分のようなプログラマじゃないけど、redmine pluginを開発したい初心者向けの記事です。


### 4. 2019-06-17 Qiitaへ2つめの記事投稿

Bitnami Redmineをdevelopmentで起動する(VSCode編) https://qiita.com/aki360P/items/bbfdf28d17fb35c0d9bb
IDE導入で数年困ってしまってしまったので、この点も是非皆さんにお伝えせねばと思って、VScodeでプラグインを書く方法をまとめました。できてしまえば何ともないことですが、ここまでくるのが本当に長かった…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434780/cbc40a97-e25c-357f-03e5-1228404df2d5.png)



### 5. 2019-10-02 プロジェクトメンバー行先表示板plugin Ajax化

リリースしてからもさらに数か月かけて、ようやくAjax実装しできました。世の中では当たり前に動いているwebページ達ほんとうにすごいな…と感心しました。javascriptありがとう！


### 6. 2019-10-20 空プラグインリリース

https://github.com/aki360P/redmine_empty_plugin
サンプルプラグインから自作プラグインまでは結構な障壁がありますが、その点を改善するため、基本的な要素を備えた"空プラグイン"を公開しました。次のような機能があります。

- Project module and project setting tab
- Load global setting and project setting
- Redmine 4.x and 3.x compatible

プラグイン書くときこれ難しいですよね！？


### 7. SNS活動

偉人達を見習って、自分の持っている知識は積極的に発信したり、twitterなどで直接アドバイスするようにしました！少しはRedmine Communityの役に立っていることを祈るばかりです。自分の拙いコードでも他の方の助けになると信じて、今後も発信させていただきますので、コメント等お待ちしております。



## 次の目標

現在、開発をおこなっているプラグイン達です。
1. WIP board plugin (twitterで頂いたものの3.x対応と機能追加です)
2. default watcher plugin (Discordコミュニティで要望出ているものです)

redmineの普及に向け、他のプロジェクト管理ソフトではできない機能(主に組織固有のプロセスに合うもの)を作成していきたいと思っています。

できればリリース済みのプラグインは月1でひとつづつメジャーアップデートしたいと思っています。
サボり癖さえ直れば…
roo gemを使ってExcelからデータを読み込む

こんにちは、マイナビでエンジニア兼マネージャーをしている柴垣と申します。
[マイナビ学生の窓口](https://gakumado.mynavi.jp)というメディアを担当しています。

# きっかけ
[マイナビ学生の窓口](https://gakumado.mynavi.jp)というメディアは大学生に対してキャリアのきっかけを届ける記事がたくさんあります。
ある日ディレクターから、「記事のカテゴリを更新して」というチケットが届きました。
対象の記事はidで指定されていて、現在のカテゴリ、変更後のカテゴリが記載されていました。
その数、約**5,000**！
最初は気づかずに、1行ずつ、手作業で、マッピング用のHashを作っていましたが、その数に気づいた時、これはあかん！となり、excelをcsvに変換してマッピング用のHashを作るtaskを作成しようと思っていました。
そこへ、あるアドバイスが
「xlsxなどから読み込んで処理するなら roo gem を使えば、ある程度自動化できそうです。」
ありがとうございます！

# rooを使う
## rooとは
https://github.com/roo-rb/roo
Excelやその他類似のファイルを読み込むためのgemです

## インストール
githubのREADMEにあるようにGemfileに追記します

```ruby:Gemfile
gem 'roo', '~>2.8.0'
```
bundle installします。
現時点では2.8.2がインストールされました

## Excelファイルを読み込む
ではExcelファイルを読み込みます。読み込むExcelファイルを`new`の引数に指定します。

```ruby:load_excel.rake
excel = Roo::Excelx.new('Excelのファイルパス')
```

## Sheetを指定する
Sheetの指定は先ほど作成した`Roo::Excelx`のインスタンスに`sheet`メソッドで指定します。

```ruby:load_excel.rake
sheet = excel.sheet('Sheet名')
```

## 指定したカラムのデータを読み込む
Sheetを指定したら、データを読み込みます。
データを読み込むメソッドはいくつかあるようですが、わたしは`parse`メソッドがオススメです。
ヘッダーも取り除かれます（必要な場合は`headers:true`を指定）、取得したいカラムの文字列を指定するだけです。
ExcelのSheetが以下のようになっていたとします。

|id|old_category_name|new_category_name|
|:--:|:--:|:--:|
|1|カテゴリー1|カテゴリー2|
|2|カテゴリー1|カテゴリー3|

そのときの指定方法は以下のようになります。

```ruby:load_excel.rake
rows = sheet.parse(id: 'id', old_cname: 'old_category_name', new_cname: 'new_category_name')
```

rowsを出力することで正しく読み込めていることがわかります

```ruby:load_excel.rake
rows.each { |row| puts row.inspect }
=> {:id=>1, :old_cname=>"カテゴリー1", :new_cname=>"カテゴリー2"}
{:id=>2, :old_cname=>"カテゴリー1", :new_cname=>"カテゴリー3"}
```

とてもカンタンですね！

# 番外編
今回はカテゴリの更新ということで、oldとnewが同じ記事のIDは配列にまとめる必要がありました
例えば

|id|old_category_name|new_category_name|
|:--:|:--:|:--:|
|1|カテゴリー1|カテゴリー2|
|2|カテゴリー1|カテゴリー3|
|3|カテゴリー1|カテゴリー2|
|4|カテゴリー1|カテゴリー2|
|5|カテゴリー1|カテゴリー3|

となっていた場合、期待する結果は以下のようになります。

```ruby
[
  {old_cname: 'カテゴリー1', new_cname: 'カテゴリー2', ids: [1, 3, 4]},
  {old_cname: 'カテゴリー1', new_cname: 'カテゴリー3', ids: [2, 5]}
]
```

最初は、`Array#find`を使って、`old_cname`, `new_cname`が結果の配列に存在していたら`ids`に追加という処理にしていました。
すると、レビュー時にまた神の声が聞こえてきました。

**基本的にはコンテナオブジェクト(ArrayやHashなど)はHashのキーにしない方が良いのですが、ここは Array#find ではなく〜（略）**

教えていただいた内容は`old_cname`と`new_cname`の配列をHashのkeyにして、そのvalueにidを突っ込んでいけばよいということでした。

そのために、まずHashのデフォルト値を指定します

```ruby
output = Hash.new{|h, k| h[k] = []}
```
こうすることで、デフォルト値が`[]`になりました
あとはもう突っ込んでいくだけです

```ruby
rows.each do |row|
  output[[row[:old_cname], row[:new_cname]]] << row[:id]
end

ouptput
=> {["カテゴリー1", "カテゴリー2"]=>[1, 3, 4], ["カテゴリー1", "カテゴリー3"]=>[2, 5]}
```

結果がHashになったことにより、カテゴリーの取得は少し工夫が必要で

```ruby
output.each.each do |(old_cname, new_cname), ids|
end
```
とすることで`old_cname`, `new_cname`, `ids`それぞれの変数に代入ができます
三井住友信託銀行プログラミングコンテスト2019 バーチャル参加を記録

*PythonだけできるからC++より実行時間が長いことがわかる。*
https://atcoder.jp/contests/sumitrust2019
####A - November 30

```python

M1, D1 = [int(i) for i in input().split()]
M2, D2 = [int(i) for i in input().split()]

if D1 > D2 and M2 > M1:
    print(1)
else:
    print(0)
```

###B - Tax Rate

整数×1.08と小数部の桁数が２に超えられないから勝手に0.99を足した。

```python

N = int(input())
if int(int((N + 0.99) / 1.08) * 1.08) != N:
    print(':(')
else:
    print(int((N + 0.99) / 1.08))
```

###C - 100 to 105
Xが2000超えると下二桁を何とか満たせる。
100以下, 106~199, 211~299, …, 1996~1999の買い方が存在しない。

```python

X =int(input())
if X >= 2000:
    print(1)
    quit()
lst = []
for i in range(20):
    lst.append([i * 105 + 1, i * 100 + 99])
for item in lst:
    if X >= item[0] and X <= item[1]:
        print(0)
        quit()
print(1)
```

###D - Lucky PIN

最初は野蛮にnC3(4C3=4, 5C3=10のことです)回検索し可能なpinを全部lstに入れて、最後に`len(set(lst))`で計算したがやはりTLEになったが、
よく考えると可能なpinが1000つしかない。

```python

N = int(input())
S = input()
lst = []
count = 0
for i in range(1000):
    num = str(i).zfill(3)
    if num[0] in S:
        a1 = S.index(num[0])
        if num[1] in S[a1 + 1:]:
            a2 = S[a1 + 1:].index(num[1]) + a1 + 1
            if num[2] in S[a2 + 1:]:
                count += 1
print(count)
```

###E - Colorful Hats 2

[kmjp's blog](http://kmjp.hatenablog.jp/entry/2019/12/01/0900) を参考にした。ありがとうございます。

###F - Interval Running

FがEより簡単である場合は自分にとっては二回目だった。
紙面で簡単な例を挙げたら規則性をすぐ分かった。

```python

T1, T2 = [int(i) for i in input().split()]
A1, A2 = [int(i) for i in input().split()]
B1, B2 = [int(i) for i in input().split()]

d1 = T1 * (A1-B1)
d2 = T2 * (B2-A2)

if d1 == d2:
    print('infinity')

if d1 * (d2 - d1) < 0:
    print(0)

if d1 * (d2 - d1) > 0:
    if d1 % (d2 - d1) != 0:
        print(d1 // (d2 - d1) * 2 + 1)
    else:
        print(d1 // (d2 - d1) * 2)
```

---
###まとめ
（就職の為に）今後もここで記録します。
terraformでさくっとiamユーザーとグループを作ってみる

こんにちは。[株式会社アダコテック](https://adacotech.co.jp/)のテックリードをしておりますkackyと申します。[terraform Advent Calendar 2019](https://qiita.com/advent-calendar/2019/terraform)の5日目の記事です。12月5日の22時から書き始めているのでかなりタイムアタックになっておりますｗ

# やりたいこと
terraformでiamユーザを作って、それをグループに所属させる。そんなことをさくっとしたいときのやり方tipsです。

@raki さんのご指摘により記述を直しました！有用なご指摘ありがとうございます☆

# ユーザー管理テーブルを変数定義する
こんな感じでユーザーとグループを対で登録します。

```
variable "users" {
  type = map(list(string))
  default = {
     "kacky" = ["developer"],
     "tech" = ["developer"],
     "adaco" = ["intern"]
  ]
}
```

# iam group作成
グループとして、developer、internに分けるとします。

```
resource "aws_iam_group" "developer" {
  name = "developer"
  path = "/"
}

resource "aws_iam_group" "intern" {
  name = "intern"
  path = "/"
}
```

# iamユーザーとmembershipの作成
ユーザー、グループはterraform 0.12.6で追加されたfor_each文を使うとあっさりできました。
これを使えばLocal Valuesでちまちまフィルタリングする必要がなくなりました。ナンテコッタイ／(^o^)＼

```
resource "aws_iam_user" "users" {
  for_each   = var.users
  user = each.key
  path = "/"
}

resource "aws_iam_user_group_membership" "example" {
  for_each   = var.users
  user       = each.key
  groups     = each.value
  depends_on = [aws_iam_user.users]
}

```

# まとめ
terraformの最新機能を使うとiamユーザーとグループといった一対の関係を直感的に変数定義してresourceに展開できるようになりました。他にもいろんな応用が利くと思いますのでお試しください。

※焦って書いているのでtypoしてたらすみません。今週中に直しますm(_ _)m
はじめて体系的にプログラムを学んで感じたことふたつ

#なぜプログラミング講座に通ったのか
ワタクシはこれまでユーザー部門という立ち位置で会社に業界としては最新のITツールやサービスを導入してきました。つまり情シス的な立場ではありません。それが面白いとおもってくれたのか、いわゆるGAFAや世界的なマーケティングツール会社のイベントに登壇してきました。そして、数年来大きく関心を持って会社を説得していたAWSの導入も業界でいち早く実現し、その関連で今年のAWSサミット大阪ではキーノートで登壇も経験しました。しかしながら、私はプログラマーではありません。よってプログラムの知識もありません。登壇している時ふと頭に浮かんだのです「この中でコード書けなくて喋ってるの俺だけだ」って。もし、内容を理解していたら登壇したときの話もより具体的になり、プログラマーの皆さんにも伝わるのではないかと。

もともと興味があり独学でやったりしていたのですが、「よしプログラミング勉強しよう。詰め込みの合宿でも行こうかな...」と検索していたら出てきたのがCODEBASE。えいや！ポチっと申し込みをしました。そこから二カ月半のプログラミングの旅がはじまりました。

#学んで感じたこと
ひとつめはプログラミングが好きになったこと。まだまだなのだが「好き」と感じている。体系的に学んだことがなかったこともあり、サイトがこのような仕組みで出来上がっているのか、そういう仕組みで動いているのかということを体感できたのは自分にとって大きい経験だった。また、アプリケーションはまだまだ全然勉強が足りないが、後ろでこういうプログラムを使って動かしていることを理解できたことは今後の仕事に大きく生きてくると確信している。

ふたつめは、これはプログラミングやプログラマーの世界では常識なのかもしれないがワタクシが最も驚いたこと。「なぜプログラマーは人のために世界のためにこんなに行動するのか！」ということである。今回のCODEBASEに参加して感じたのはみんな優しい。ほんとうに超初心者にもわかりやすく説明し自らも説明方法を改善しながら理解を促そうを努力をしている姿を何度も見てきた。また、サポーターのみなさま（卒業生も含めて）同様に親切丁寧に受講生をサポートしているのである（私も随分お世話になった）。さらには、シェアという文化がふつうにあり自分のコードなどを世界に広く公開しているではないか。それは多少の承認欲求と就職につながるといことであっても、そして、多少そのムード（シェア文化）は感じていたにせよオールドスクールの業界のサラリーマンのワタクシとしてはそういう文化を目の当たりにするやはり感動で心が震えた。なぜなら、オールドスクールの経済界では「シェアする文化」の真逆の「隠す文化（ノーシェアリングというのかな?）」だからだ。

営業ノウハウはシェアするどころか同僚にも伝えないのが普通だ。お客さんもシェアしない。本質的な情報もシェアしないのである。特に「情報は持っているほうが偉い」という文化もあり、偉い人こそ情報は隠したがる。まさにプログラマーの世界と真逆なのだ。ワタクシなりに数十年この状況と戦い続けているので随分サラリーマンの友だちも減ってきているのだが(笑)、本音で言うと世界をよくしたいなら良いものやチャレンジしたことは失敗というものも含めて（個人的には失敗というものはないと考えているが）シェアするべきだと思う。

大急ぎで書いたので乱文になったと言い訳してそろそろまとまりのない文章を終わりにするが、言いたいことは「プログラミングは美しいしプログラマーの文化も美しい」ということである。プログラムのコードが一切ない役に立つのかわからない雑感のような形になったことを読んでいただいた方に謝罪したいと思う。

言いたいのは、オールドスクールの経済界も世界をより良いものにしたいのであれば、よいものもチャレンジした結果もシェアしてシェアした人間や企業が認められるように進化しなければならないと思う。もしかしたら、プログラミング言語よりも一番学んだことは「愛のあるシェア」だったのかもしれない。
Rails 初学者のアソシエーションの解説

##has_manyとかいまいちわからない人向け！
これがわかる人は不要  [*Rails ガイド*](https://railsguides.jp/association_basics.html)

1.has_manyとbelongs_toはセットではない。一緒に使うことが多いが独立して使うことができる。
2.メソッドを理解することが重要！

例えば
Author（著者)テーブルとBook（本)テーブルがあったとし、その二つを関連づけたい時。

>class Author < ApplicationRecord 
>has_many :books, dependent: :destroy 
>end 

>class Book < ApplicationRecord 
>belongs_to :author 
>end 

上記の記述で下記のような連携ができるらしいのだが、いまいちどのような仕組みなのかわからなかった、、
>@book = @author.books.create(published_at: Time.now)


 **こう言う時は一つづつ分解して考えるといい**
authorは*オブジェクト*
booksは*メソッド*
createも*メソッド*

createがメソッドなのはなんとなくわかるのだが、booksは？？

もしhas_many: booksがなければメソッドにはならない。has_many: booksを追加したことによりbooksメソッドができた。ここでは表記されていないが実はhas_manyはbooks()だけでなく他のメソッドの使用も可能にしている。

***そもそもメソッドってなんだっけ？？***
Rubyでよく見かけたこんな感じのやつです。引数を入れるとreturnで値を返す。

```rb

def index
 @products = Product.all
end
```

booksはこのようなメソッドであり、returnで返ってきた値が反映される。

```
author.books.create
```
と書かれていた時、Rubyの処理系は以下のように順番に評価していきます。
#####authror を評価
  この場所で authorという単語がどんな意味に当たるのか調べに行く（ここではAuthorモデルの値だとわかる）
#####authorに対して booksを呼ばれていると認識する。
  booksというメソッドを authorに対して呼び出します。もしもauthorの実体であるAuthorモデルにbooksが定義されていれば呼び出すことができます。
  「authorオブジェクトが持っている情報でBook を検索する」モデル名なので大文字始まり。
もしくはテーブルから検索するイメージだとすると booksでも良いですがちょっと意図がずれそうです。
  この結果、戻り値としては ActiveRecord::Relationが返ってきます。
#####ActiveRecord::Relationに対してcreateが呼ばれていると認識する
戻り値で返ってきたActiveRecord::Relationにcreateを呼びます。この呼び出しは**ActiveRecord::Relation**がもともとbooksというメソッドの戻り値であったこととは無関係です。あくまで検索した内容の結果として値が利用されるだけです。
テキストに打ち込み説明するのは難しいですが、私自身も今理解しているところなので何かご指摘などございましたらよろしくお願いします。
Dockerについて

ドットインストールを参考にした記事です
# Dockerとは
- アプリケーションを開発、移動、実行するためのプラットフォーム
- 仮想化環境を実現するためのツール
- アプリの実行環境をラップしてくれる
- 環境の違いなんてなんのその
- 構築(Build)、移動(Ship)、実行(Run)

## Vargrant
Dockerをインストールするマシンを立ち上げるもの

## コンテナ
- Dockerの「イメージ」を元に作成される仮想環境の実行部分。
- オブジェクト指向でいうとインスタンス
- イメージから作られる実際の動作環境
- コンテナには、UbuntuなどのOSをはじめ、イメージで定義しているプログラム群を含み、それに加えてコンテナ起動後に個別プログラムを追加することができる
- 原則１コンテナ１アプリ
- (Dockerは、コンテナ同士をつなぐネットワーク環境の構築もできる）

##### Imageから勝手にコンテナを作ってスタートする
```
$ docker run
```
imageの構築、コンテナ構築、起動。引数でサービスを指定しないと失敗する

##### コンテナがある状態
```
$ docker start
```
コンテナが一つも存在しないと失敗する。

#### imageの 構築からコンテナの構築、起動まで。
```
$ docker up
```
imageがなくてもbuildから実行してくれる


[docker-compose `up` とか `build` とか `start` とかの違いを理解できていなかったのでまとめてみた。](https://qiita.com/tegnike/items/bcdcee0320e11a928d46)


## イメージ
- コンテナを起動させるためのベース
- オブジェクト指向でいうクラスのこと
- テキストファイル（Dockerfile）からビルドされる
- Resistory(DockerHub)を使ってImageそのものを共有可能

```command
$ docker build [DockerfileのPath]
```
でビルド

- 通常パソコンに、OSをインストールする時にしよう・
- OSを入れ替えたり、じぶんでパソコンを作ったりする時にPSをパソコンにインストールする
- インストールする時に必要になるのが、「イメージ（ファイル）」。


その他学習したことは随時更新していきます
開発宣言を理解してないくせにアジャイルを語るな

__煽りタイトル申し訳ありません。__

この記事は[福岡若手Sier_bc Advent Calendar 2019](https://qiita.com/advent-calendar/2019/fukuoka-sier_young_bc)の８日目の記事です。

[前回の４日目の記事](https://qiita.com/Gsann/items/15006bc8a364361c3f11)と同様、あまりテクニカルな話ではありませんのであしからず。

# はじめに
昔、自分の身の回りであまりにもアジャイル開発に無理解な人がいたために書きました。
したがって、この記事を読む人の対象は

- アジャイル開発に触れたことがない人
- アジャイルソフトウェア開発宣言を知らない人

です。さらに、注意として

- 筆者による主観
- 筆者の確証バイアス

が含まれているかもしれません。ご自分で情報に触れてみてください。

# そもそもアジャイル開発の話をする前に
まず、[アジャイルソフトウェア開発宣言を読みましょう。](https://agilemanifesto.org/iso/ja/manifesto.html)

この開発宣言で重要なことは、

>(前略)
この活動を通して、私たちは以下の価値に至った。
プロセスやツールよりも個人と対話を、
包括的なドキュメントよりも動くソフトウェアを、
契約交渉よりも顧客との協調を、
計画に従うことよりも変化への対応を、
価値とする。すなわち、左記のことがらに価値があることを
認めながらも、私たちは右記のことがらにより価値をおく。 

ということです。[IPAの解説](https://www.ipa.go.jp/files/000065601.pdf)にもあるように、
__左記のことがらに価値があることを認めているんですよ！__
だから、例えば「プロセスやツール」にも、「包括的なドキュメント」にも、価値があることを認めているから、__要らないなんてことはないんですよ。__
ただ、__左記のことがらよりも右記のことがらにより価値をおいているだけです。要は比較しているだけ。__

# アジャイル開発を誤解しないで!
昔、アジャイル開発を理解してない身の回りにいたとある偉い人が、
__アジャイル開発ってのは、設計書を作らないんですよ(迫真)__
と言ってたんですよ。そんなわけないだろうと。そもそも__「設計書を作らない」__の胴元はどこよって[Google先生に聞いてみました](https://www.google.com/search?q=アジャイル+設計書+作らない&client=safari&rls=en&biw=1280&bih=646&sxsrf=ACYBGNTypO2QtgsHuv-iSWK6O3spKaVsfQ:1575549966729&ei=DvzoXf-KLJyGr7wPiJ2vgAU&start=0&sa=N&ved=2ahUKEwj_yd6AxZ7mAhUcw4sBHYjOC1A4FBDy0wN6BAgNEDA)が、

- 設計書(ドキュメント)を作らないというのは誤解だ
- 無駄な設計書(ドキュメント)を作らない

といった説明ばかりでした。おそらく、__「無駄な」設計書を作らない__という説明が、__設計書を作らないんですよ(迫真)__に繋がったのではないか、と今では考えています。

# アジャイルソフトウェア開発宣言が伝えたいこと
とはいっても、正直アジャイルソフトウェア開発宣言も言葉足らずなところはあるかもしれません。これまた[IPAの解説](https://www.ipa.go.jp/files/000065601.pdf)にもありますが、

>アジャイルソフトウェア開発宣言で伝えようとしていることは、まずマインドセットがあって、そのうえで「プロセスやツール、ドキュメント、契約、計画」を考えるべきである、ということなのです。このマインドセットは「個人と対話、動くソフトウェア、顧客との協調、変化への対応」として簡潔に表現されていますが、後述の「原則」を踏まえてもう少し具体的に表すと次のようなことを示しています。

ということであり、具体的には

>• 「対面コミュニケーション」
　個人同士の対話を通じて相互理解を深めることで、よりよいチームが作られる。
• 「実働検証」
　動くソフトウェアを使って繰り返し素早く仮説検証をし、その結果から学ぶことがよりよい成果を生み出す。
• 「顧客とのWin-Win関係」
　お互いの立場を超えて協働することにより、よりよい成果と仕事のやり方を作ることができる。
• 「変化を味方に」
　顧客ニーズやビジネス市場の変化は事前計画を狂わす脅威ではなく、よりよい成果を生み出す機会と捉える。

ということです。なお、上記の__マインドセット__とは、__「暗黙の了解事項」__という意味で捉えるといいと思います。とにかく、上記のことを意識しつつ、「プロセスやツール、ドキュメント、契約、計画」を考えるべきなのです。

# まとめ
以上で、タイトルに関することを述べさせていただきました。近年はアジャイル開発手法である__「スクラム」__を採用されている企業が多いように見受けられますが、是非とも開発宣言を御一読いただき、認識の確認をしてみるのもいいかもしれません。
Xcode11のSpell Checkにつまずいた

# はじめに
Xcode11 でとうとう Spell Check が導入されました:clap:

# 使い方
とりあえずスペルチェックを常にONにします。

Edit -> Format -> Spelling and Grammar -> Check Spelling While Typing

<img width="900" alt="spelling" src="https://user-images.githubusercontent.com/34936885/70238347-7308ed00-17ac-11ea-8587-952c14dbd049.png">

これで下記のようにスペルミスの部分に赤い点線が表示されます。

<img width="500" alt="miss" src="https://user-images.githubusercontent.com/34936885/70238323-66849480-17ac-11ea-91dd-48a67cbe770b.png">

## ショートカット
* command + ;  
スペルミスの箇所にフォーカスしてくれます。
* command + :   
下記のように Spelling and Grammar のウィンドウを開いてくれます。  
<img width="400" alt="window" src="https://user-images.githubusercontent.com/34936885/70238284-52d92e00-17ac-11ea-8050-752df567638d.png">  
ここの下に候補が出てるので選択して Change をクリックすると書き換えてくれます:clap:

## メニュー
赤点線部分を選択し右クリックすると下記のように変換候補と Ignore Spelling, Learn Spelling が表示されます。

<img width="289" alt="ignore" src="https://user-images.githubusercontent.com/34936885/70238254-43f27b80-17ac-11ea-90fb-74fd0c5f88bf.png">

## その他
### Macのスペルチェック
関係ないですが Mac はシステム環境設定 -> キーボード -> ユーザ辞書 -> 英字入力中にスペルを自動変換にチェックを入れているとスペルミスしていても勝手に変換してくれたりします（たまに効かないですが:speak_no_evil:）

<img width="600" alt="keyboard" src="https://user-images.githubusercontent.com/34936885/70238230-3937e680-17ac-11ea-99df-1f8b5f522f9b.png">

### UITextChecker
こちらも関係ないですが UIKit には [`UITextChecker`](https://developer.apple.com/documentation/uikit/uitextchecker) というスペルチェックをしてくれるクラスがあります。（iOS3.2 からあるらしいけど初めて知った:see_no_evil:）

使い方は下記に詳しく書いてありました。

* [063 UITextCheckerでスペルチェック](https://sites.google.com/a/gclue.jp/swift-docs/ni-yinki100-ios/uikit/uitextcheckerdesuperuchekku)

これも試してみた結果、精度は Xcode のスペルチェックの方が高そうでした。

# Ignore&Learn
下記のように `csvText` の `csv` に赤線がある場合、無視するようにしたい。
※ 以下の確認環境は Xcode11.0です

<img width="177" alt="csv" src="https://user-images.githubusercontent.com/34936885/70238221-350bc900-17ac-11ea-8659-8a36410ba074.png">

こういう時に Ignore Spelling 使うんやな！と思いやってみる。消えた！が、別のファイルを確認すると赤い...もう一度同じファイルに戻ってみると再び赤くなっている:exclamation::question:

よくわからんけど Learn Spelling やってみる。消えた！別のファイルを確認しても赤線は消えている:tada:
試しに Xcode を再起動してみる赤線は表示されない:clap:他のプロジェクトを開いてみる赤線は表示されない:clap:

ん？これもう一度 `csv` に赤線を表示させたい場合どうするんだろ？

ちょっと調べてみましたが、わかりませんでした...

# さいごに
ついに Xcode でスペルチェックが導入されたのでスペルミスは撲滅されるのではないでしょうか:facepunch:

Ignore と Learn に関しては動作がよくわかりませんでしたがどっかのファイルに保存されてるはず？？

どなたか詳しい方教えてください:bow: (今回のはつまずいた記事ではないかも...)
WordPress 学習メモ 第1回

急遽WordPressを触らないといけない事になりキャッチアップのフローを、ノート代わりにまとめていきます。
主に自分の学習の流れを振り返りで残す形なので色々、省いてます。
Webエンジニアの諸先輩方からアドバイスやご指摘を頂けたらありがたいです！

#学習を始める前に
今回の目的は環境構築を行う事です。

既に存在する本番環境と同じ物をローカル環境に構築するのが、最初のスタートでした。
そもそもどうやって環境構築しようかなと思ってた際に、参考にさせて頂いたサイトです。
これがめちゃくちゃ簡単に環境を構築できたので驚きました。

[超簡単にローカル環境が構築できるLocalbyFlywheelの使い方](https://bazubu.com/local-by-flywheel-33920.html)

#本番サイトと同環境を構築する方法!

さて、環境構築が完了し、本番と状態にする際の手順を紹介します。
[たった３ステップでサイトの引っ越しが完了するプラグイン「All-in-One WP Migration」が簡単すぎ！](https://www.vektor-inc.co.jp/post/all-in-one-wp-migration/)

１：作成したローカル環境にプラグインである、All-in-One WP Migrationをダウンロードします。

![Screen Shot 2019-12-05 at 19.48.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394657/86ef7447-6031-8203-ae71-77da2cbcd31d.png)

２：本番のAll-in-One WP Migrationエクスポートしファイルをダウンロードする。
![Screen Shot 2019-12-05 at 20.01.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394657/b5366dfa-81c9-5d13-8c39-f0325c60ff2c.png)

３：ローカル環境でさっきと逆の手順でAll-in-One WP Migrationのインポートファイルを先ほどダウンロードしたファイルを選択します。

#環境構築完了！
これで開発をスタートできます。
次からは、実際に開発を行う際の手順を説明させて頂きます！