OmniAICreator/Qiita-1.07M huggingface dataset:
デザイン初心者のディレクターがデザインカンプの時に確認するところ

Webディレクターとして働いて、３年目になりますが今でも何が正解かわかりません・・

最初に言いますがこの記事はあくまでもボクが思うだけで参考になるかどうかわかりませんのでｗ

CMSのディレクターをやっていた時は、単純にお客様の好きなデザインを聞いて反映させていただけのお使いディレクターでした。

しかも、そのときはデザイナーの方が上げてくれたカンプには自分の好みで意見をいう始末・・

デザイナーの方からしたらとても迷惑なディレクターだなって思いますｗ

お客さんの意見じゃねーのかよってね？
![tumblr_inline_n0esjaVTAK1sy5s64.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540409/14b39802-027f-1aeb-bf0e-4f26120a255d.jpeg)


そして転職してからは完全に見方が変わりました。

そもそも、ディレクションでお客様の好きなデザインなどに「ちょっと待った」を言えるようになりました。

もちろんお客さんの意見をくんだ上での提案はしますが・・

ここからが今回の記事の主題ですが、ではお客さんのデザインなどにちょっと待ったを言えるようになった現在は、カンプのどこに目をつけて意見を言うようになったでしょうか？

まず最初に意識することは当たり前ですが、このサイトの存在意味をしっかりと抑えることです。

ボクもいまだにやってしまうんですが、例えばお客さんが「動きがあってかっこいいサイト」という要望があったとします。

ありがちなのは、最初にそこを意識してカンプを確認してしまうんです。

もちろん、それも正解ですが忘れていけないのはそのサイトに訪れるユーザーが使いやすいかということと、そのUXでコンバージョンがあがるのか？ということです。

javaをつかって動きがあって、見ていて面白いサイトというのはかっこいいかもしれないんですが、それでコンバージョンが上がりませんでしたじゃ話にならないと思います。

いや、まぁコンバーションあげなくていいからカッコよくしてくれって言ったら話は別ですがｗｗ

なので、お客さんの要望を抑えているかの確認をするのですが、まずは「コンバージョンを上げる」という基板をつくったうえで見ることです。

それを基板としてデザインに自信がないぼくが見るところが下記の２つです。

**1,文字の大きさ**
![tumblr_inline_n0esjp15Wc1sy5s64.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540409/0e24a1d8-eafd-babc-0c75-216ad12bc133.jpeg)

文字の大きさについてですが、サイトを見ることができるデバイスはかなりたくさんあります。

スマホ、タブレット、PC・・その中でもメーカーによってはディスプレイの大きさが違ったりします。

そのデバイスの数だけ文字の見え方が全然違います。

PCで見れても、スマホで見ると文字が潰れてしまうだとか・・・

けっこうありましたｗ

コーディングする前にある程度防げるかもしれませんが、カンプの際にはコンバージョンを上げるうえでの導線に妨げになるかどうかを確認します。
これはコンバージョンにつなげる意味でどこが目立っているかを確認します。


**２,どこが一番目立っているか**
![tumblr_inline_n0esk1EOFK1sy5s64.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540409/549d4c99-d72a-0529-195b-d4dde9917a4e.jpeg)

デザイナーの方は色の組み合わせや、使い方にちゃんと意味をもって使用しますよね？

例えば、安心感を与えるのであれば淡い緑やお問い合わせボタンは目立つようにオレンジとか、要所要所で意味があります。

ボクは、それらの意味はわかってるつもりではあるのですが、いつも確認するときは一度目を閉じてから見ます。

そのときにどこに目が行くかを調べます。

関係ないところが目立ってはいけないのです。

たまーにありますが、ブランディングエリアに社長が手を上げて我が社は！みたいなサイトありませんか？

だめではないのですが、制作者側としてはすべての導線がその社長にもってかれてしまい「おぉう・・」って感じになりますｗ

上の例えは完全にボクの上司のウケウリですがｗ

自分が真っ先にやることいつもこの２つです。

これならデザインに自信がない人でもできることです。

なかなかそれだけでは円滑にやりとりは進むとは思いませんが、この確認意識の内容はこの先Web業界が進展しても使える内容だと思います。

共感してもらえた方は是非意識してみてください。
Mailman で、特定ドメインから投稿された DKIM 署名済みメールは全て配送する

# 概要

Mailman でメーリングリストを運用している時、自組織内から発信されたメールは全て受理・配送したいということがあります。例えば、自組織向けの問い合わせ窓口として Mailman を使っている場合など。本稿では、Mailman の司会判定用モジュールを拡張して、特定ドメインから投稿された DKIM 署名済みのメールは全て受理・配送する方法を説明します[^restriction]。

[^restriction]: 最近は、Gmail などで捨てアカウントを作成し DKIM 署名済みの spam を送っている事例があるようです。そのため、DKIM 署名済みのメールを全て受理・配送するという方針はお勧めできません。

# 背景

Mailman でメーリングリストを運用している時、メーリングリスト非参加者からのメールを受信するには、(1) generic_nonmember_action オプションを「承認」に設定する、または、(2) accept_these_nonmembers オプションに適当な正規表現を設定する、などの選択肢があります。しかし、前者(1)はあらゆるメールを受け付けますし、後者(2)も詐称が容易なヘッダー From に依存していますから、spam に対して脆弱な設定になってしまいます。

この問題に対応するため、以下のような拡張を試みてきました。

* [特定のメールサーバから投稿されたメールは全て配送する](https://qiita.com/tsuchm/items/44a76392ca94d28f1617)
* [メールを受理・配送する前に、投稿者自身による確認を行う](https://qiita.com/tsuchm/items/17af568a3b2f86d19800)

しかし、本学のメールサーバがオンプレミスから G Suite に移転したため、構成員が利用する送信用メールサーバが限定できなくなり、[特定のメールサーバから投稿されたメールは全て配送する](https://qiita.com/tsuchm/items/44a76392ca94d28f1617)手法は使えなくなりました。

代替手段として、[G Suite から送信されるメールには DKIM 署名が付与されている](https://support.google.com/a/answer/174124)ことを利用して、DKIM 署名が検証できたメールの From が、自組織のドメインに一致するメールは全て配送するという設定を紹介します。

# 設定

最初に、DKIM 署名を検証するための Python モジュールをインストールします。

```shell-session
sudo apt install python-dkim
```

次に、[DKIMModerate.py](https://gist.github.com/tsuchm/67cfd4bbe4cca299d407bc751bd88f41) を、`/usr/lib/mailman/Mailman/Handlers/` にコピーします。なお、`/usr/lib/mailman/` の部分は、各自の環境にしたがって適宜に読み替えてください。

その上で、`/etc/mailman/mm_cfg.py` に以下のような設定を記述します。

```py
DKIMDOMAINPATTERN = "[@.]example\.jp$"
GLOBAL_PIPELINE[GLOBAL_PIPELINE.index('Moderate')] = 'DKIMModerate'
```

最初の行は、自組織のドメインに一致する正規表現です。次の行は、Mailman 本体に付属している `Mailman/Handlers/Moderate.py` の代わりに、上記のモジュールを使うように指定しています。

設定は以上です。これで、`DKIMDOMAINPATTERN` に一致するドメインが From アドレスに設定されており、かつ、有効な DKIM 署名を持つメールは全て配送されるようになります。
ReactContext用のLoggerを作った

軽量なサービスの場合Reduxを使うのをやめてReactContextで管理するようになったんだけど、値の変更とかのタイミングでログ出してくれるredux-logger的なのあったらいいなと思ったので自作した話
（作ったの3ヶ月ぐらい前だから今だとすでにもっといいのがあるかも・・・

# 作ったもの
```javascript:hooks/useLogger.js
import { useCallback, useEffect, useRef } from "react"
import moment from "moment"

const colors = {
  prefix: "#4CAF50",
  log: "inherit",
  prev: "#9E9E9E",
  next: "#03A9F4",
  error: "#F20404",
}

function usePrevious(value) {
  const ref = useRef(null)
  useEffect(() => {
    ref.current = value
  })
  return ref.current
}

export function useContextLogger(prefix, inputs) {
  Object.keys(inputs).forEach(key => {
    const value = inputs[key]
    const prev = usePrevious(value)
    useEffect(() => {
      const timestamp = moment().format("HH:mm:ss.SSS")
      console.group(
        `%c[${prefix}] %c${key} %c@${timestamp}`,
        `color: ${colors.prefix}`,
        `color: ${colors.log}; font-weight: bold;`,
        "color: gray; font-weight: lighter;",
      )
      console.log(`%c prev`, `color: ${colors.prev}`, prev)
      console.log(`%c next`, `color: ${colors.next}`, value)
      console.groupEnd()
    }, [value])
  })
}
```

# 使い方
> 10分ぐらいでぱぱっと作った例なので微妙なところ満載ですがご容赦を

```javascript:contexts/todo.jsx
const TodosContext = createContext(null)
const TodosContextProvider = ({ children}) => {
  const [todos, setTodos] = useState([])
  
  const add = useCallback((todo) => {
    const id = todos.length + 1
    setTodos([
      ...todos,
      {
        id,
        text: todo,
        completed: false,
        createdAt: moment().format('YYYY/MM/DD HH:mm:ss'),
      }
    ])
  }, [todos])
  
  const toggle = useCallback((id) => {
    const todo = todos.find(t => t.id === id)
    if (!todo) return
    
    setTodos([
      ...todos.filter(t => t.id !== id),
      { ...todo, completed: !todo.completed },
    ].sort((a, b) => a.id - b.id))
  }, [todos])
  
  const remove = useCallback((id) => {
    setTodos(todos.filter(t => t.id !== id))
  })
  
  // ロガーで変更を監視したいパラメータをセット
  useContextLogger("TodosContext", { todos })
  
  return (
    <TodosContext.Provider value={{ todos, add, toggle, remove }}>
      {children}
    </TodosContext.Provider>
  )
}
```

こんな感じでログを仕込むと、↓のように変更前後の値がログとして吐き出される。

![logger.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16629/ad2422f8-de75-577f-2074-431cd06aa69c.gif)

本家redux-loggerには全然及ばないけど、まぁそれなりに実用的なものが出来て満足

# おまけ

単純なロガーもReactHooks使って作成したので置いとく。

```js:hooks/useLogger.js
function useLogger(prefix) {
  const log = useCallback(
    (log, src) => {
      const timestamp = moment().format("HH:mm:ss.SSS")
      console.log(
        `%c[${prefix}] %c${log} @ %c${timestamp}`,
        `color: ${colors.prefix}`,
        `color: ${colors.log}; font-weight: bold;`,
        "color: gray; font-weight: lighter;",
        src || "",
      )
    },
    [prefix],
  )
  return { log }
}
```

こっちは`console.log`の代わりに使えて、`useLogger`呼び出す際にprefixを設定できるから、どの部分で吐かれたログかを管理するのにいい感じ。

```js
const hogeLogger = useLogger('HogeComponent')

hogeLogger.log('test')
hogeLogger.log('obj ->', obj)
```
みたいに使える。
プログラミング　単語　

随時追加していきます

##A
available　利用可能
abstract　破壊する
ad　広告
add　加える
addition　足し算、添加、追加
average　平均値

##B
builder　作り手、造り手

##C
calucurator　電卓、計算機
cluster　同じ考え方を持つ人の集まり、集団
　　　　　ITでは、複数のコンピュータを連携させて1つのシステムに統合すること
console　慰める
constant 定数
construct 構築する　組み立てる


##D
decrement(読|デクリメント)　減少、減収
description　説明
define 定義する
distance 距離
division　割り算、分割

##E
exec　幹部
exist　存在する
expire 賞味期限
exception　例外

##F
format 形式、体裁

##G
glue　のり、接着剤

##H
handle　取り扱う、使う

##I
info　情報
interface　界面、合わせ目
implements　実装する
implode　破裂する

##J
join　連結

##L
length　長さ
limit　限定、限界

##M
mileage 走行距離

##N
node　点と線で構成図を書いたときの点の部分のこと
numelic 数値

##O
object 物体, もの, 実物, 対象

##P
parent　親、子持ち
Polymorphism　多様性
proc 処理

##R
reffer　参照する

##S
signature　署名、サイン
split　分割、分裂、裂ける、別れる
status 状態
square　広場、真四角
substraction　減算
substring　部分文字列

##T
tax　税金
tax rate　税率
throw　投げる、投入する

##Y
yum　Yellowdog Updater Modifiedの略
そこの君。vimを使ってみないかい？

本記事は、なんか布教したいエンジニア Advent Calendar 2019 の8日目の記事です。
##軽めの自己紹介
コツコツしない系小6のgoriraです。Twitter→https://twitter.com/GoriraTatsu
コツコツやらない30日間自作osシリーズ→https://qiita.com/gorira_tatsu/items/0b5aec93aa74a8c89107

##vimの好きなところ
###1.キーボードだけで解決する
キーボードだけで編集ができるので、わざわざマウス持って、手首を振る必要は無くなります。余談ですが、最近マウスが壊れたんですけど、キーボードだけで編集できるので、配送される間もそこまで不便ではなかったです。
###2.無駄な物が無い
画面がとってもスッキリしていて、文だけに集中できるので、作業効率が上がります。しかも無駄にpcのエネルギーを使わないので、軽いです。
###3.プラグインが豊富
vimのプラグインはとても豊富です。例えば、
- vimの見た目をかっこよくできる
- 補完機能が使える
- vim上からgitにアクセスできる
- 目的のファイルのアクセスを簡単に
- インデントの深さを視覚
などができます。詳しく調べたい方はhttps://vimawesome.com/ をどうぞ。

##vimの嫌なところ
###1.入力モードとコマンドモード
やっぱり他のエディタから乗り換えると、このモード分けは慣れないですよね。慣れが必要です。まあどんなこともそうだけどもやっぱり慣れない。（でもこの使い分けで高度な編集もできるよん。）
###2.操作が複雑
操作を覚えるのがとても大変でした。正直な話、今でもこの操作はなんだっけと思ってしまいます。

##インストール
今回は実行環境がmacなのでbrew:beer:でインストールします。コマンドは

```terminal
$ brew install vim
```
なのですが、すでにmacには8.0（旧バージョン）が入っているので、vimを起動しても旧バージョンの方が起動します。このことを避けるために、パスを変更します。まず、

```terminal
$ vim .bash_profile
```
ホームディレクトリにあるbash_profileを書き換えます。そうすると、こんな感じになってるはずです。（自分のpcの中身なのである程度関係ない）
![スクリーンショット 2019-12-06 18.18.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534096/cd0feade-0cd5-9afe-5f07-98ed9445c74f.png)

すでに入っていますが、/usr/local/Cellar/vim/8.1.2350を先頭に書き込みます。（パスの場所や、バージョンによって変わるので、多少違います）
そして、echo $PATHを打ち込み、/usr/local/Cellar/vim/8.1.2350があるか確認してください。それがあれば最新バージョンを起動することができます！

##操作方法
###基本コマンド
<table>
<tr><th>コマンド名</th><th>内容</th></tr>
<tr><td>vim [ファイル名]</td><td>起動する（ファイルを指定して、起動する）</td></tr>
</table>
###上書きとか保存とか
<table>
<tr><th>コマンド名</th><th>内容</th></tr>
<tr><td>:q</td><td>終了する</td></tr>
<tr><td>:w [ファイル名]</td><td>上書きする（名前をつけて保存する）</td></tr>
<tr><td>:q!</td><td>保存せずに終了する</td></tr>
</table>
###移動
<table>
<tr><th>コマンド名</th><th>内容</th></tr>
<tr><td>h</td><td>左に移動する</td></tr>
<tr><td>j</td><td>下に移動する</td></tr>
<tr><td>k</td><td>上に移動する</td></tr>
<tr><td>l</td><td>右に移動する</td></tr>
<tr><td>w</td><td>前方に単語１つ分移動する</td></tr>
<tr><td>b</td><td>後方に単語１つ分移動する</td></tr>
<tr><td>W</td><td>スペース区切りで前方に単語１つぶん移動する</td></tr>
<tr><td>B</td><td>スペース区切りで後方に単語１つぶん移動する</td></tr>
<tr><td>O</td><td>行頭に移動する</td></tr>
<tr><td>$</td><td>行末に移動する</td></tr>
<tr><td>gg</td><td>１行目に移動する</td></tr>
<tr><td>G</td><td>最後の行に移動する</td></tr>
</table>
###編集
<table>
<tr><th>コマンド名</th><th>内容</th></tr>
<tr><td>i</td><td>インサートモードに切り替える</td></tr>
<tr><td>Esc</td><td>ノーマルモードに切り替える</td></tr>
<tr><td>d &lt;カーソル移動コマンド&gt;</td><td>デリート（切り取りをする）</td></tr>
<tr><td>dd</td><td>行をデリート</td></tr>
<tr><td>y &lt;カーソル移動コマンド&gt;</td><td>ヤンク（コピーをする）</td></tr>
<tr><td>dd</td><td>行をヤンク</td></tr>
<tr><td>p</td><td>ペースト（貼り付ける）</td></tr>
<tr><td>u</td><td>アンドゥ（元に戻す）</td></tr>
<tr><td>Ctrl + r</td><td>リドゥ（やり直す）</td></tr>
</table>

##最後に
ここまでおつかれさまでーす。最後に教材を紹介します
・vimgorf https://www.vimgolf.com/
・日本語ドキュメント https://vim-jp.org/vimdoc-ja/
ではまた会いまっしょい
Qiita 記事にyoutube動画を貼る

普通にyoutubeの埋め込みコード貼り付けるだけじゃできなかったのでメモ．

普通の埋め込みの仕方がわからなかったけど，動画のサムネが表示されてyoutubeにとべるのでいいかと妥協．

下のコードがテンプレ．

``` markdown
[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/YOUTUBE_VIDEO_ID_HERE/0.jpg)](http://www.youtube.com/watch?v=YOUTUBE_VIDEO_ID_HERE)
```

`YOUTUBE_VIDEO_ID_HERE`の部分を埋め込みたい動画のIDに変える．
例えば，youtube.com/watch?v=AbcDecNef みたいに動画のURLがなってたら，AbcDecNefに変える．
最初の`YOUTUBE_VIDEO_ID_HERE`が多分動画のサムネイルで，後ろの方はそのまま動画のURLになってるっぽい．



普通の埋め込みみたいに，youtubeにとばずに，ここで再生できる方法が知りたい．



参考

[QiitaにYouTubeを埋め込む（MarkdownにYouTubeを埋め込む）](https://qiita.com/tnarihi/items/762b6ba4ac0a160eef5b)

[Markdown Cheatsheet](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#videos)
文字コードの5C問題とは

# 概要
Shift-JISでは「5C」のコードは¥を意味しており、エスケープ記号として解釈されることに起因する問題。

# 具体例
1. 「表示 (95 5c 8E A6)」という文字がある。
2. 「5c」がエスケープ文字と判断される（8Eをエスケープすると解釈）
3. 結果的に「侮ヲ(95 8E A6)」となってしまう。

# 対応策は？
- Shift-JISじゃなくて、UTF-8を使う。
- アプリ側でマルチバイト対応の関数を使う。

# 参考文献
https://www.wdic.org/w/WDIC/5C%E5%95%8F%E9%A1%8C
Dockerの溜まったゴミを消す

開発環境で`docker build`や`docker run`を繰り返していると、色々なゴミが溜まってPCのリソースを圧迫していきます。
それらの溜まったゴミを一発で消すコマンドです。(※自己責任で)

### いらないイメージ(`<none>`イメージ)を消す
```sh
docker image prune -f 
```

### 現在起動中のコンテナを全部止めて、全部消す
```sh
docker container stop `docker ps -a -q` && docker container prune -f
```
これは`docker-compose`使ってれば、`docker-compose down`で一発OKなんですが
個別にコンテナ起動してる場合もあると思うので一応

### 最強の呪文
```sh
docker system prune --all -f
```
このコマンドは

```
  - all stopped containers
  - all networks not used by at least one container
  - all images without at least one container associated to them
  - all build cache
```
ってことで徹底的にゴミを消し去ってくれます。
とてもスッキリするので、ぜひ一度お試しあれ
任意のバージョンのCocoaPodsをアンインストール/インストールする

開発チーム内でCocoaPodsのバージョンを合わせる時用のメモ

## 指定バージョンのアンインストール
ターミナルで以下のコマンドを実行
`sudo gem uninstall cocoapods`

以下のようにインストールされているバージョン一覧が表示されるので、
アンインストールしたいバージョンを選択する

> Select gem to uninstall:
1. cocoapods-1.5.3
2. cocoapods-1.7.5
3. All versions

## 指定バージョンのインストール
ターミナルで以下のコマンドを実行する。
例) 1.6.1をインストールする場合
`sudo gem install -v 1.6.1 cocoapods`

## 現在のバージョンを確認する
ターミナルで以下のコマンドを実行する。
`pod --version`

今入っている最新バージョンが表示される
なんかおしゃれっぽい背景アニメーション

# 最終成果物
これです。
なんかおしゃれ。
（個人差があります。）

![background.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177043/a0659ded-f5f1-ef76-7e02-2ab931970774.gif)


# 実装
## 土台になるhtmlの用意
さっくりと。

```index.html
<!DOCTYPE html>
<html lang ="ja">
<head>
    <link rel="stylesheet" href="../css/background.css">
</head>
<body>
    <div class='background'>
        <div class='wave -one'></div>
        <div class='wave -two'></div>
        <div class='wave -three'></div>
        <div class='wave -four'></div>
        <div class='wave -five'></div>
        <div class='title'>なんかおしゃれなやつ</div>
      </div>
    </body>
</html>
```

## CSS
こちらもさっくりと。
解説はあとあと。

```background.css
html {
  background: #eee;
}


.background {
  width: 100%;
  height: 100%;
  background: lighten(#f0f4c3, 10%);
  position: fixed;
  overflow: hidden;
}

.wave {
  opacity: .4;
  position: absolute;
  top: 0%;
  left: 75%;
  background: #0af;
  width: 100%;
  height: 100vh;
  margin-left: -25%;
  margin-top: -25%;
  transform-origin: 50% 48%;
  border-radius: 59%;
  animation: drift 4000ms infinite linear;
}

.wave.-two {
  animation: drift 5000ms infinite linear;
  opacity: .1;
  background: yellow;
}

.wave.-three {
  animation: drift 6000ms infinite linear;
  background: rgb(124, 214, 210);
}

.wave.-four {
  animation: drift 7000ms infinite linear;
  background: rgb(96, 212, 183);
}

.wave.-five {
  animation: drift 8000ms infinite linear;
}

.box:after {
  content: '';
  display: block;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  z-index: 11;
}

.title {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  z-index: 1;
  line-height: 300px;
  text-align: right;
  color: white;
  text-transform: uppercase;
  font-family: 'Playfair Display', serif;
  letter-spacing: .4em;
  font-size: 24px;
  text-shadow: 0 1px 0 rgba(black, .1);
  text-indent: .3em;
}
@keyframes drift {
  from { transform: rotate(0deg); }
  from { transform: rotate(360deg); }
}
```

## ちょっとだけ解説
cssもほとんど装飾ですね。
重要なのは以下3つ
- @keyframes drift
- border-radius
- animation
- position: fiexd;

keyframesでは要素を回転させるアニメーションを登録しています。
そして、全てを円にしてしまうと変化が起きないので縦横サイズとborder-radiusで楕円を用意します。
さらに、楕円全てを同じタイミング同じスピードでアニメーションさせても残念な感じになってしまうのでアニメーションの実行時間を1000msずつずらします。
あとは要素が増えた時にスクロールしても常に画面に表示されるようにfixedで固定。
これで背景アニメーションとして機能しますね。



## まとめ
うーん、おしゃれ。
実用的にはちょっと主張が強すぎますけど調整すればいろんな場面で使えるかもしれません。
Dockerを使うためにFreeBSDでbhyve(vm-bhyve)を使ってAlpine Linuxをインストール

dockerを使うためにはMacを使っているのでDocker for Macを使えばいいのですが、
デスクトップ環境にはできるだけ余計なものをインストールしたくないのでサーバ上でやることにします
しかし、社内のサーバはFreeBSDしかインストールされていない世界なので（フィクションです）
bhyve(vm-bhyve)を使って軽量なAlpine Linuxをインストールして、そこでdockerを実行することにします
FreeBSDのバージョンは12.1です

# vm-bhyveのインストール

```
# pkg install -y vm-bhyve grub2-bhyve
```

# vm-bhyveで使うbridgeを作成
今回はbridgeを手動で作成します

```
# sysrc cloned_interfaces="bridge0" ifconfig_bridge0="up addm em0"
# kldload if_bridge.ko
# ifconfig bridge0 create up
# ifconfig bridge0 addm em0
```

# vm-bhyveの初期設定

```
# sysrc vm_enable="YES" kld_list="vmm" vm_dir="/var/vm"
# kldload vmm
# mkdir /var/vm
# vm init
# vm switch create -t manual -b bridge0 public
# cp /usr/local/share/examples/vm-bhyve/* /var/vm/.templates/
```
vm initで/var/vm以下に色々ファイルが作成されます
/var/vm/.config/system.conf は以下のようになります

```/var/vm/.config/system.conf
switch_list="public"
bridge_public="bridge0"
type_public="manual"
```


# Alpine Linuxのインストール

https://alpinelinux.org/downloads/でVirtualのx86_64 のISOを使います

ISOのダウンロードと登録

```
# fetch http://dl-cdn.alpinelinux.org/alpine/v3.10/releases/x86_64/alpine-virt-3.10.3-x86_64.iso
# vm iso alpine-virt-3.10.3-x86_64.iso
# vm iso
DATASTORE           FILENAME
default             alpine-virt-3.10.3-x86_64.iso
```

テンプレートalpine、ディスク15Gで作成、メモリ1G、仮想CPU1、vm名はalpinevmで作成

```
# vm create -t alpine -s 15G -m 1G -c 1 alpinevm
```


設定を編集する場合はvm configureコマンドでで行います

```
# vm configure alpinevm
```

下記URLによるとAlpineのvirtualを使っている場合
https://github.com/churchers/vm-bhyve/wiki/Supported-Guest-Examples
vmlinuz-vanillaとinitramfs-vanillaをvmlinuz-virtとinitramfs-virtを
変更する必要があるようなので変更し、utctime="yes"も追加します

設定ファイルは今回の場合だと/var/vm/alpinevm/alpinevm.confに格納されます

```diff
loader="grub"
+utctime="yes"
cpu="1"
memory="1G"
network0_type="virtio-net"
network0_switch="public"
disk0_type="virtio-blk"
disk0_name="disk0.img"
-grub_install0="linux /boot/vmlinuz-vanilla initrd=/boot/initramfs-vanilla alpine_dev=cdrom:iso9660 modules=loop,squashfs,sd-mod,usb-storage,sr-mod"
-grub_install1="initrd /boot/initramfs-vanilla"
-grub_run0="linux /boot/vmlinuz-vanilla root=/dev/vda3 modules=ext4"
-grub_run1="initrd /boot/initramfs-vanilla"
+grub_install0="linux /boot/vmlinuz-virt initrd=/boot/initramfs-virt alpine_dev=cdrom:iso9660 modules=loop,squashfs,sd-mod,usb-storage,sr-mod"
+grub_install1="initrd /boot/initramfs-virt"
+grub_run0="linux /boot/vmlinuz-virt root=/dev/vda3 modules=ext4"
+grub_run1="initrd /boot/initramfs-virt"
uuid="自動で生成されているのでそのままで"
```

インストール開始

```
# vm install alpinevm alpine-virt-3.10.3-x86_64.iso
# vm console alpinevm
```

起動が終わると下記のような画面になるのでrootでログインして（パスワードは聞かれません）
setup-alpineコマンドを実行してインストールしていきます

```
Welcome to Alpine Linux 3.10
Kernel 4.19.80-0-virt on an x86_64 (/dev/ttyS0)

localhost login:
```

ここまで来れば何事もなくインストールできたのでdockerを使い始められそうです
Nutanix VMのvDiskのエクスポート(WinSCP編)

本記事はNutanix Advent Calendar 2019 3枚目 12/6の記事です。

#NutanixでvDiskを出す必要性 #とは

普通はないでしょう。

おうちで3ノード構成のうち先日1ノードだけCPUとメモリの使用率が表示されないなぁと思っていたら静かにお亡くなりになってました。それだけならいいのですが、別ノードのHot TierのSSDが壊れ若干クラスターも壊れかけてしまい、go watanaさんが書かれた[記事](https://blog.ntnx.jp/entry/2016/06/09/081212)の通りにエクスポートも実行しました。
ですが、ホワイトリストに追加コマンドも受け付けず、元々追加していたIPアドレスがあったものの、通信が途中でプツリと切れてしまい、他の手段をとる必要性がありました。

#ダウンロードする前に
仮想マシンがシャットダウンされていることを確認してください。

#vDiskの格納先
仮想マシンを作成する際やディスクイメージを作成する際に指定したコンテナの中にあります。
既にshadowhatさんが書かれた[記事](https://infraapp.blogspot.com/2019/12/nutanix.html)の通り、 /コンテナ名/.acropolis/vmdisk/
の中に格納されています。

#接続方法
WinCSPを立ち上げ、以下の通り入力します。
 ```
   転送プロトコル：SFTP
   ホスト名：Nutanixクラスターの任意のCVM or ClusterVIP (クラスターが壊れかけている際にはCVMにすることを強く推奨します)
   ポート番号：2222
   ユーザ名：prism elementのログインユーザー（admin等）
    パスワード： prism elementの上記ユーザのパスワード
```
#UUIDの特定

ディレクトリに入ったはいいものの、ファイルがあり過ぎてどれがどれだかわかりません。
ですので一度WinSCPはそのままにして、CVMにCLIで特定しましょう。

Powershellやteraterm等でCVMに以下の情報でログインします

```
ユーザー名 nutanmix
password nutanix/4u
port 22
```

ログイン後、仮想マシンがあるか確認します。

```
acli vm.list 
```

では、肝心のUUIDを特定しましょう

```
acli vm.get [vmname] | grep vmdisk_uuid
```

#ダウンロード
先ほど接続したWinSCPに戻り、フィルターでUUIDを入力してください。すると1つのファイルに絞れるはずです。
その後ダウンロードしますが、その前に転送モードの確認を行いましょう。WinSCPのデフォルトはバイナリモードですが、心配な方は設定でバイナリモードへ変更してください。

クラスターが壊れかけな時には、ここが鬼門です。

ダウンロードは常に行っているわけではなく途中で何回も切れます。
通信が切れ、再開、また切れるを繰り返します。
壊れかけなノードによっては中断されてしまいます。何度も行ってダメな場合には別のノードを試しましょう。

#ダウンロード後
diskイメージのファイルシステムを確認します。

```
qemu-img info [imagefile]
```

特に指定がなければrawファイルであると思います。
アップロードの予定がある場合は圧縮するとデータ転送量や時間の削減になりますので事前に行いましょう。コマンドは以下の通りです。

```
qemu-img convert -c -O qcow2 [imagefile]
```

#これって意味ある？
商用版Nutanixでここまで悲惨な状況になる前にサポートから色々と手助けがあるでしょう。

CEを使用されている方が悲惨な状況になった際に、手段の1つとしてこんなのもあったなぁぐらいに覚えて頂ければ幸いです。
Go methodについて

Goにはクラスの仕組みが無い代わりに、型にメソッドを定義できるとのこと。
今までやってきた言語にはなかった仕組みなので理解したい

そもそも、functionとmethodは別ものらしい...え?

まず、一般的な関数について
このように、**func <関数名> (引数) (返り値)**の順番で記述する

```go:main.go
func adder(x, y int) (z int) {
  z = x + y
  return z
}
```

Goは**<関数名>**の前にもう一つ**()**をつけることができる

```go:main.go
type Vertex struct { // 構造体
  x, y float64
}
func (v Vertex) abc() float64 {
...
}
func (レシーバ　型) 関数名（引数）戻り値の型 {
    // 処理
    return
```

struct(構造体)と関数を結びつけること、これがGoのオブジェクト指向らしい。
Goにはクラスがないのでstructに関数を結びつけることによって関係性とプログラム全体の構成がわかりやすくなる。


### 参考
[昔の自分に送るGolangの基礎的なこと(型確認・Slice・method)](https://medium.com/since-i-want-to-start-blog-that-looks-like-men-do/%E6%98%94%E3%81%AE%E8%87%AA%E5%88%86%E3%81%AB%E9%80%81%E3%82%8Bgolang%E3%81%AE%E5%9F%BA%E7%A4%8E%E7%9A%84%E3%81%AA%E3%81%93%E3%81%A8-%E5%9E%8B%E7%A2%BA%E8%AA%8D-slice-method-1bd2fae694d1)
Tempus Dominus Bootstrap 4 で日本語表記を変更

日本語環境で設置したらカレンダーのヘッダー表示が「一月 2019」のようになる。

設定値は以下のファイルで行っている模様。
`node_modules/moment/locale/ja.js`のmonthsプロパティが以下のようになっている。

```javascript
months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),
monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
```

直接直してもいいけど、
カレンダーのヘッダ表示を編集するには`dayViewHeaderFormat`を指定する。

```javascript
    $('#datetimepicker1').datetimepicker({
        format: 'L',
        locale: 'ja',
        dayViewHeaderFormat: 'YYYY年 MMM',
    });
});
```
フォーマットの形式YYYYで西暦4桁数値、MMMMでmonths、MMMでmonthsShortを使用する。
ReactのuseEffect内でsetIntervalを使いたい時はuseIntervalを使ったら楽

useEffect内のsetIntervalでstateを更新する記事があまりなかったので、 書き残しておきます。

useEffectの中で、 setIntervalを使い、 定期的にstateを更新しようとすると、ちょっとした工夫が必要になります。詳細は以下の記事を読んでいただけたら分かると思います。
[Making setInterval Declarative with React Hooks](https://overreacted.io/making-setinterval-declarative-with-react-hooks/)

上の記事が元ネタになるわけですが、 すぐに使えるようnpmに公開してくれている方がいました。
https://github.com/Hermanya/use-interval#readme

```sh
npm install use-interval
```

```react
import React, { useState } from 'react';
import useInterval from 'use-interval';

const App: React.FC = () => {
  const [state, setState] = useState<number>(0);

  useInterval(() => {
    setState(state + 1);
  }, 1000);

  return (
    <div>{state}</div>
  );
}
```
ObnizでLCD（ディスプレイ)直してみた。(OLED)

#[はじめに]
皆様　はじめまして。今年度(2019年)末から新しくIotをやりはじめましたjudgeeewaseです。はじめてのQiita投稿です！
(実は今年、Advent calendar参加しようかなって思って下書き書いてたら、Advent calendar埋まってしまったので、ついでなので載せます。)

私は今、誰でも簡単にIotができる、obnizというモジュールを触って、様々なものを作ろうと日々頑張っております。

obniz、楽しいですよね！？回路的な負担もなく、GUI(コードを書くことなく視覚的に)でプログラミングができるのはobnizしかなく、人を選ばない素晴らしいものだと思います。また、このスクラッチ(プログラム教材ソフト)さながらの簡単さは子供達へのよら実践的プログラミング教材として最適だと思います。

さて、前置きはこのぐらいにして、今回は私の失敗を2度と起こすことのないように備忘録を残させていただきます。もし同じように困っている方がいらっしゃれば、それの助けになれば幸いです。

#[本題]
皆さん、obnizのお値段を**ご存知**ですよね？
あんまり声を大きくして言えませんが

**約6000円もします(小声)**

ちょっと、ちょっとだけ高いですよね
(でも、**それだけの価値がある**ものです！)

もし！あなたが何かの拍子に落としてこわしてしまったら、また6000円払いますか？
イエスと言う人は多分少ないと思います。
そんなしょうもないことでユーザーが減り、obnizが広まらないのはもったいないですし非常に残念です。

そこで、今回僕がやってみた修理劇をお伝えしてみます。
今回僕がやってしまったのは

**「LCD(液晶のこと)の破損」**です。

obnizは基板に素子がついているのが丸見えな状態です。これを不格好と捉える人もいらっしゃるでしょうが、下手にカバーなどがついてない分修理しやすいと僕は思います。

今回以下のように破損してしまったLCDを直してみます。



**step1** 液晶を買いましょう笑

流石に割れた液晶を元に戻すのは不可能ですから新しく買うしかありません。液晶の型番は
です。
私はちょうど秋葉原に行く用事があったので秋月で以下のものを買いました。↓

http://akizukidenshi.com/catalog/g/gP-12031

同じ型番で検索するとAmazonでも出てくるので
秋葉原が遠いよーって方はそちらでお買い上げください。

↓買ったLCD
![AE61536C-D3A2-4F27-A521-96D6147227B7.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508403/b464c6bd-2811-4212-33d5-6508a07488d5.jpeg)



**step2** 買ったモジュールから液晶を剥がす

まぁ、液晶を引っ剥がします。ネットで検索しても、モジュールから液晶を引っ剥がすについてのブログが一個も無かったのでこのブログが初かもしれません(苦笑)

液晶は割れやすいので慎重に剥がします。
まず、**はじめに絶対**黄色い部分を半田であっためて基板から取っておきます。
剥がし方のコツとしては、
1.液晶の細くなっているところは絶対に触れてはいけません。
2.少しずつずらしたら、爪で引っ掛けて液晶を基板から浮かせます。
3.小さいマイナスドライバーを隙間にいれ、液晶裏の両面テープを剥がします。
4.慎重にやっていくと取れます。

取れるとこんな感じです。↓
![68D66132-8DC9-4D90-A15F-EE8A24B22EF9.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508403/6d350ec8-3633-7dab-ff7f-50373490b975.jpeg)


**step3**では！半田付けします！

これは簡単です。先ほどと同様にしてobnizの液晶を剥がします。今回、液晶は既に壊れていますから多少荒く引っ剥がしてもオッケーです。

剥がしたら黄色い部分を半田付けして終わりです！！

**↓結果**
![B5B5EC55-4D76-49E6-8174-FED318A4B1EB.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508403/b1a2b74f-77ea-6819-010a-46c366e07550.jpeg)


これでまた同じようにobnizが使えます。

以上です。
ここまでお読みくださってありがとうございました。
では、皆さんご機嫌よう。
【Scala】コード上で標準入力・出力のテストを実行したい

[Scala Advent Calendar 2019](https://qiita.com/advent-calendar/2019/scala)の17日目の記事

どうもアドベントカレンダーってものをつい最近知ったたけちゃです！
面白そうって理由で勢いよくエントリーし参加メンバーをみたら凄い人ばっかりでビビってます＾＾
Cats使ってみたって記事書いてどやろうとしたんですが、速攻挫折したので最近ハマってる競プロ関連で一つ記事書きます😤

## 背景
AtCoderの自動テストツールを作っていた時のこと

AtCoder(競技プログラミング)ではコードを提出して、間違っているとペナルティーが課せられる(ないものもある）。
そこで公式のサンプルの入力と出力を使い、ローカルでテストをしてから提出すればいいのではと思った。
もちろん公式サイト上でコードのテストはできるのだが、ローカルでテストできる環境が整えば、そのまま自動提出とかもできて色々捗る。。。


------------


まず
提出用コードの形式は`object Main extends App {}`
入力データは標準入力で渡される

以上のことを踏まえると。。。

1. Main関数をコード上で呼び出せる
2. 呼び出したMain関数に対して任意の標準入力を渡す
3. Main関数内の標準出力を取得して、正しいかを判断する

これらをやりたいため標準入出力について色々調べてみた。

## 目標
1. コード上でMain関数を呼び出す
2. 標準入力をオーバーライドする
3. 標準出力をオーバーライドする


## コード上でMain関数を呼び出す
これは結構すぐにできた
```scala
Main.main(Array.empty)
```
これでどこからでもMain関数が実行できる
※すでにMain関数があって、それを他のところで呼び出す


## 標準入力をオーバーライドする
`sample input`って文字を標準入力としてMain関数へ渡す。

```scala
import java.io.{ByteArrayInputStream, FileInputStream}
import java.nio.charset.StandardCharsets

val str = "sample input"
System.setIn(new ByteArrayInputStream(str.getBytes(StandardCharsets.UTF_8)))

// 外部ファイルを読み込んで、その内容を渡す場合
// System.setIn(new FileInputStream("test.txt"))
Main.main(Array.empty)
```

```scala
//Main.scala
object Main extends App {

  // 一行取得
  val line = scala.io.StdIn.readLine
  println(line) // sample input

}
```


## 標準出力をオーバーライドする
`System.setOut`を使うことでJVM全体に影響を及ぼせる
以下コードは、全ての標準出力を`debug.log`に書き込む

```scala
import java.io.PrintStream

val out: PrintStream = new PrintStream("debug.log")
System.setOut(out)
```

いやいやファイルに保存じゃなくて変数として取り出したいって時は

```scala
val outPutStream = new ByteArrayOutputStream()
val out: PrintStream = new PrintStream(outPutStream)
System.setOut(out)

//printlnは改行もあることを忘れずに
println("bamboo!")
print("tuna!")

val log = outPutStream.toString("utf8")
// log: String = "bamboo!\ntuna!"

//リセットしない限りprintの内容がoutPutStreamに追加される
outPutStream.reset()

val resetLog = outPutStream.toString("utf8")
// resetLog: String = ""
```

一つ不便なところがあって、標準出力をオーバーライドしちゃったせいで、
じゃぁ`outPutStream.toString("utf8")`で取り出した内容をみたいって時は、
まぁ当たり前だが普通にprintしても表示されない。

defaultをセットし直すか、外部ファイルに出力するしかない。

ちなみにdefaultに戻したいときは最初に保持して、それを後で代入すれば良さそう
```scala
val defaultSysOut = System.out
System.setOut(defaultSysOut)
```

## 余談
標準入出力をうまくテストできるライブラリとかないのかよ！
って探してたけど、そもそもScalaって言語で標準入力を使うって場面ってそうそうないじゃんって気づいた＾＾

もし便利なものがあったら教えてください！
適切な日本語を使うこと

#1.はじめに
はじめまして。
普段はゲームのQAとして管理業務や障害削減・効率化などに携わっています。
今回は私が日ごろ現場を見ている際に感じた、
~~書かないとすぐ忘れそうな~~ 
ちょっと細かい言葉の言い回しなどの部分の気づきについて紹介していこうと思います。

日頃、あまり意識せずに行っているかもしれない会話の際の言い回しなど、是非この機会に見直してみてください。
自身やチームのパフォーマンス向上にも繋がる部分だと思います。

※あくまでこの記事は私個人の見解です。



###ちゃんと意味を理解して使ってます？
弊社ではチャットをベースに業務のやり取りを行っているのですが、
業務中に、よく見かけるワードがいくつかあります。
例えば...<font color="red">「宜しくお願い致します」「畏まりました」</font>など、一見すると漢字も多く、丁寧に見えるかもしれません。
ですが、実は不適切であったり、あまり親切ではない使い方をしていることも。

#####品詞（補助動詞と動詞）
中学校の頃に習ったアレです。
たとえば先ほど例に挙げた「宜しくお願い致します」の<font color="red">「致します」</font>という言葉ですが、
「致す」と「いたす」の書き方ひとつでも、少し意味が変わってきます。

・「致す」は～動詞で、物事の動作・作用・存在をあらわす自立語となっており、
・「いたす」は補助動詞に分類されるため、他の語につき、補助的な役割で使われる動詞　となっています。
なので、普段使う「お願い致します」は<font color="red">「お願い」</font>をする<font color="red">動詞</font>についているので、
ひらがなの「いたします」のほうが適切だったりします。
※より堅苦しい雰囲気を出さなければならない場合などもあるため、絶対に漢字で書いてはいけないわけではないです！

#####常用漢字と表外漢字
日本語では「ひらがな」「カタカナ」「漢字」を組み合わせて文章を作っていきます。
その中でも漢字については「常用漢字」といった形で、
『一般の社会生活において、現代の国語を書き表す場合の漢字使用の目安』として定められている文字があります。
※公用文は原則、常用漢字を使うことが必須ですが、今回はあくまで使い方なので強制ではない前提でお話します。

例に挙げた「畏まりました」の畏まるという言葉は、
「わかりました」という言葉の敬語表現となっています。
「畏まりました」と、漢字で書くのも間違いではないのですが、
<font color="red">「畏」</font>には、<font color="red">「畏（おそ）れる」</font>といった意味のある、言葉となっており、
文字の印象があまりよくなく、実際に漢字で書くと読みづらい　なんてものでもあったりするため、やはり不親切な感じもしますよね。
なのでこれも「かしこまりました」の方が適切かと考えます。

###適切な言葉を使うことのメリット
例を少し挙げて説明をしてみましたが、正しく言葉を使うことでのメリットってなんだろう？と思い考えてみました。

####読みやすい文章になる
QAというポジションは、『各所とコミュニケーションを取って円滑に物事を進める』という部分が肝であるため、
ある程度、意識して読みやすい文章を書くことも必要であると私は考えます。

漢字ばかりの文章だと、変化が少なく目に留まる部分がなくなってしまうため、重要な箇所が流れやすくなる場合もあります。
~~あと何より読む気なくなっちゃいますよね~~
大事な部分を強調して伝える、そのためにもひらがな～漢字などの組み合わせでの緩急をつけることは重要です。

####雰囲気を変えられる
①「よろしくお願いいたします」「ありがとうございます」
②「宜しくお願い致します」「有難う御座います」
①の方がやわらかい印象で、コミュニケーション取りやすそうだな　と思う人の方が多いのではないでしょうか。
堅苦しい雰囲気でやり取りをしなければならない場面もあるかと思いますが、
普段はなるべくコミュニケーションを取りやすい雰囲気を作ることが大事だと考えています。
これも言葉の使い方を知るか否かで、できるかどうかが変わる部分です。

####検証時に指摘できる（もはや当然）
自分が把握して使えていれば、開発チームへの指摘もできます。
お知らせ掲載時の確認やヘルプページの文言など、
ユーザーがその掲載物を目にした際に、重要なポイントが気づきやすいように書かれているかどうか、
これだけでも少しユーザビリティの向上に繋がるはずです。

機能面のQAでいっぱいいっぱいだったりすると、やむを得ず優先度は下がりがちかもしれませんが、
適切な文章の掲載ができることで、CS問い合わせ件数などの削減にも繋がり、トータルコストの抑制にも結び付くと考えます。
そのため個人的には結構重要なのでは？と考えている部分です。

###結果的に、自分のためになる
伝わりやすく、適切な文章を使う・把握することにより、
自身の知識として指摘できる幅も広がり、コミュニケーション面も向上し、
結果的に『この人にはお任せしやすい』といった信頼にも繋がるはずです。

普段の業務でもうまく言葉を使うことで、チームの雰囲気作りへ大きく貢献できるのではないでしょうか。
私自身もやり取りをする際に、より気をつけて取り組んでいこうと感じました。

#さいごに
見返してみると、日本語のお勉強みたいな形になってしまいましたが、
正しい言葉の使い方で、読みやすい・伝わりやすい文章を書くことにより、コミュニケーションも行いやすくなり、
連携ミスや報告の見落とし削減などにも繋がり、自分自身の信頼も高まり、みんなハッピーになります。

検証に関する部分でも、ユーザにとって表示されているテキストなどはダイレクトに目に触れる部分でもあるため、
このような言葉に関する部分もしっかり気をつけていけると、より良い状態での製品提供にも繋がります。
きっと良いことづくめです。

この記事を読んで、明日から少し気をつけてみよう　と思っていただけると幸いです。
簡単でしたが、今回の記事は以上となります。
最後までご覧いただき、ありがとうございました。
Amazon SageMaker Processingを使って簡単な前処理をやってみた



先日のre:InventでSageMakerのアップデートが大量に公開されました。
その中の一つ、`Amazon SageMaker Processing`についてを紹介しようと思います。

## Amazon SageMaker Processing ってなんぞや
では、この`Amazon SageMaker Processing`ってそもそもなにものなのかを見ていきましょう。
公式ブログでは、
> Amazon SageMaker の新しい機能であり、データの前処理や後処理、モデルの評価といったワークロードをフルマネージドなインフラストラクチャの上で簡単に実行する機能

というように書かれています。
SageMaker上で利用できる簡易前処理機能、ということですね。

どのように使えるのか、公式のデモを一通り実行してみようと思います。

## 実際に利用してみる
まずはS3から利用するデータを読み込みます。
今回使うデータは、アヤメのデータにIDカラムと適当にデータに欠損をつけたものです。

``` python:jupyter
import pandas as pd

prefix = 's3://sagemaker-first-tests/data'
data_dir=f'{prefix}/iris.csv'

df=pd.read_csv(data_dir)
df.to_csv('dataset.csv', index=False)
```

読み込んだら、前処理を行うジョブを作成します。

``` python:jupyter
import sagemaker
from sagemaker.sklearn.processing import SKLearnProcessor

sklearn_processor = SKLearnProcessor(
    framework_version='0.20.0',
    role=sagemaker.get_execution_role(),
    instance_count=1,
    instance_type='ml.m5.xlarge'
    )
```

ジョブが作成できたので、前処理スクリプトを実行します。

``` python:jupyter
from sagemaker.processing import ProcessingInput, ProcessingOutput

sklearn_processor.run(
    code='preprocessing.py',
    inputs=[ProcessingInput(
        source='dataset.csv',
        destination='/opt/ml/processing/input'
    )],
    outputs=[ProcessingOutput(source='/opt/ml/processing/output/prepro_file')]
    )
```

`code`で、前処理スクリプトを指定します。今回はjupyterのHome直下に作成した`preprocessing.py`を指定しています。
`inputs`では、前処理を行うデータを指定します。
`outputs`では、前処理が終了したファイルの出力先を指定します。
また、出力されたデータはデフォルトのS3ファイルに出力されるようです。

今回の前処理スクリプトでは、欠損値のカラムが数値データの場合は`0`、文字データの場合は`NaN`で補完して、データを分割するようにします。
コードは以下になります。

``` python:preprocessing.py
import pandas as pd
import numpy as np
import os
from sklearn.model_selection import train_test_split

df = pd.read_csv('/opt/ml/processing/input/dataset.csv')

# 欠損値を0かNaNで埋める
for col_name in df:
    if df[col_name].dtypes == 'object':
        df[col_name] = df[col_name].fillna('NaN')
    else:
        df[col_name] = df[col_name].fillna(0)
 
# データ分割
train, test = train_test_split(df, test_size=0.2)
train, validation = train_test_split(train, test_size=0.2)
 
# outputファイルを作成
os.makedirs('/opt/ml/processing/output/prepro_file', exist_ok=True)
 
# データを保存
train.to_csv("/opt/ml/processing/output/prepro_file/train.csv", index=False)
validation.to_csv("/opt/ml/processing/output/prepro_file/validation.csv", index=False)
test.to_csv("/opt/ml/processing/output/prepro_file/test.csv", index=False)
```

以上が前処理の実行までの流れになります。
実際にデータを流してみたところ、以下のような結果になりました。

![sagemaker.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395106/4f5f20a6-f193-5b53-f4d4-c83f88c9fdcb.png)


欠損のある行が青色になっており、対応する箇所が任意の値に埋められてることがわかります。
(前処理後のデータはわかりやすいようにID順でソートしてありますが、実際はランダムにばらけていました。)

## まとめ
今回は `Amazon SageMaker Processing` を使って前処理をやってみました。
データの分割や欠損処理がとても簡単に行えるので、積極的に利用していきたいですね！

## 参考サイト
https://aws.amazon.com/jp/blogs/news/amazon-sagemaker-processin-fully-managed-data-processing-and-model-evaluation/
macOS CatalinaでVirtualBoxにBluetooth Dongleがアタッチできない

## 問題

表題の通りで、macOS Catalinaにおいて、VirtualBoxにBluetooth USB Dongleが認識されない問題があります。

Bluetooth USB Dongle自体はVirtualBoxのUSB一覧に表示されるのですが、選択してattachしようとすると、以下のエラーが発生します。

> Failed to attach the USB device XXX to the virtual machine YYY.
> Details:
> Failed to create a proxy device for the USB device. (Error:      VERR_READ_ERROR).
> Result Code:  NS_ERROR_FAILURE (0x80004005)
> Component: Console
> Interface: IConsole {8ab7c520-2442-4b66-8d74-4ff1e195d2b6}

各バージョンは以下の通り。

macOS: 10.15.1 (19B88)
VirtualBox: Version 6.0.14 r133895 (Qt5.6.3)

## 解決策

以下のコマンドを実行して、BT USBを抜き差しすると、認識されるようになります！

```bash
$ sudo nvram bluetoothHostControllerSwitchBehavior=never
```
Ref: https://forums.virtualbox.org/viewtopic.php?f=8&t=95479&start=15

Host/GuestともにOS再起動は不要です。

どうやら、Bluetooth Host Controllerに関連するデフォルト設定が変わったようですね。なので、その他のUSBデバイスには、アタッチの問題は発生しません。

なお、このままだとiPhoneなどをFinderでマウントすることができなくなるようです。(Xcodeの接続には問題ありません)
用がなくなったら、以下で元に戻しましょう。

```bash
$ sudo nvram bluetoothHostControllerSwitchBehavior=always
```

`bluetoothHostControllerSwitchBehavior`については、こちらに説明があります。
https://developer.apple.com/library/archive/technotes/tn2295/_index.html

## 最後に

この問題はVirtualBoxの問題のため、Guest OSには関係なく発生します。
この記事で、多くの方がこの厄介なトラブルから救われることを願っています。
パスパラメータとクエリパラメーターの違い

# パスパラメータとクエリパラメーターの違い
```
http://example.com/path/param1/param2?query=param3
```
■ パスパラメータ
param1、param2

■ クエリパラメーター
param3

で、何が違うの？

```
1. 一意なリソースを表すのに必要な情報かどうか 
2. 省略可能かどうか
```
一意なリソースを表す場合はパスパラメータに入れる。
一意なリソースとは例えばユーザーIDとか

省略可能ならクエリパラメーターに入れる。
例えばクエリパラメータの部分を省略した以下のURLでも正常にアクセスできます。

```
http://example.com/path/param1/param2
```
使われていないDigdagワーカーのEC2を自動でTerminateする

この記事は[ZOZOテクノロジーズ #5 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/zozo_tech5) 9日目の記事になります。

また、今年は全部で5つのAdvent Calendarが公開されています。

[ZOZOテクノロジーズ #1 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/zozo_tech)
[ZOZOテクノロジーズ #2 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/zozo_tech2)
[ZOZOテクノロジーズ #3 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/zozo_tech3)
[ZOZOテクノロジーズ #4 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/zozo_tech4)

# 概要
Digdagのクラスタを、EC2インスタンスで組む場合ワーカーをオートスケーリンググループに含めることでプログラムから任意の個数のDigdagワーカーを立ち上げることができます。その辺の構成については以下の記事に詳しく載っています。

https://techblog.zozo.com/entry/digdag_ha

ここで問題になるのが、Digdagワーカーのスケールインのタイミングです。ワークフローの最後にスケールインする方法が一番簡単ですが、他のワークフローが起動している場合にスケールインしてしまうと実行中のジョブが失敗してしまいます。また、ワークフローが途中で失敗してしまった場合にスケールインし忘れるということも起こりがちです。

そこで、自動でDigdagのジョブを掴んでいないか判断しスケールインをする仕組みを作ったので紹介します。

# queued_task_locks
Digdagで利用されるテーブルの中に`queued_task_locks`というテーブルが存在します。
このテーブルはジョブキューのロックの役割を担っており、以下のようなフィールドを持っています。

```
 id:               bigint
 site_id:          integer
 queue_id:         integer
 priority:         integer
 retry_count:      integer
 lock_expire_time: bigint
 lock_agent_id:    text
```

このフィールド中の `lock_agent_id` にはジョブを実行中のホスト名を含んだ文字列が入ります。
そのため各EC2ワーカーのホスト名をユニークにしておくことで、どのワーカーが現在Digdagのジョブを実行しているか判断することができます。

# 自動Terminate
`queued_task_locks`を見ることでDigdagワーカーがタスクを掴んでいるかどうかを取れることがわかったので、自動でワーカーがTerminateされる仕組みを作って見ましょう。

#### ソースコード
```sh
export PGPASSWORD='ポスグレのパスワード'
POSTGRESQL_HOST_NAME='ポスグレのホスト名'
POSTGRESQL_USER_NAME='ポスグレのユーザー名'

RETRY_COUNT='リトライ回数'
RETRY_INTERVAL='リトライ間隔'
MYHOST=`hostname`

for i in `seq 1 $RETRY_COUNT`
do
  HOST_LIST=`/usr/bin/psql -t -h POSTGRESQL_HOST_NAME -U POSTGRESQL_USER_NAME -c 'select lock_agent_id from queued_task_locks;'`
  for HOST in $HOST_LIST
  do
    if [ $(echo $HOST | grep -e $MYHOST) ]; then
      exit 0
    fi
  done
  sleep $RETRY_INTERVAL
done

MYINSTANCEID=`curl 169.254.169.254/latest/meta-data/instance-id/`
REGION='AWSのリージョン'
AUTOSCALING_GROUP='オートスケーリンググループのARN'

/usr/local/bin/aws autoscaling detach-instances --instance-ids $MYINSTANCEID --auto-scaling-group-name $AUTOSCALING_GROUP --should-decrement-desired-capacity --region $REGION
/usr/local/bin/aws ec2 terminate-instances --instance-ids $MYINSTANCEID --region $REGION
```

まず最初にリトライ回数とリトライ間隔を決めて定期的に`queued_task_locks`を見に行きます。そこで自分のホストが見つかった場合はスクリプトを終了します。

もしリトライ回数だけ`queued_task_locks`を見に行ってそれでも自分のホストが見つからない場合は自分をオートスケーリンググループから切り離し、Terminateを行います。
オートスケーリンググループから切り離すときに`--should-decrement-desired-capacity` をつけることで`desired-capacity` が勝手にデクリメントされます。

また、スケールインとTerminateの順番も重要です。先にTerminateをしてしまうとスケールインが実行される前にTerminateがスタートしてしまいます。

最後にこのスクリプトをcronで定期的に実行することで使われていないワーカーが勝手にTerminateされスケールインされます。

cronの間隔・リトライ回数・リトライ間隔を自分のワークフローにあった値にするのがきもとなります。

# まとめ
以上のように、`queued_task_locks`を利用することでワーカー自身がジョブを掴んでいるか判断し使われていない場合に自分でスケールイン・Terminateをする仕組みを紹介しました。


今日で3日続いたDigdagネタは終わりになります。明日は@gold-kouさんによる「NLB配下でgRPC通信するときに考えるALPN対応状況」です。
Chrome拡張機能の3つの世界

#はじめに
GoogleのChrome拡張機能の3つの世界について、簡単にまとめます。

ここでは、概念に触れるだけで実際の開発仕方などは書いてません。

Chrome拡張でやりたいことによって、3つのどの世界に処理を書けば良いのかが変わってきます。

それぞれの世界は、どこで動いていて、どういうことができるのか、を軽く紹介する記事になります。

#3つの世界
3つの世界とは、

- **Background**
- **Content Scripts**
- **Popup**

です。

ざっくり説明すると、Backgroundは裏でずっと動いてて、Content Scriptsは画面の操作をして、Popupは右上にあるChrome拡張のボタンを押すと出てくるやつです。
<img width="1440" alt="（画像）3つの世界の図" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298379/618c6779-c4a4-9435-567f-ff347e705669.png">
Chrome拡張と言ってまず思い付くのは、Content Scriptsで画面を動かすものが多いですね。
しかし、他の世界も同時に使うことでChrome拡張の幅が広がります。
順番に説明していきます。

##Background
名前の通り、裏で処理を行うものです。

Chrome拡張をインストールしたり、オンにしたりしてからずっと動いています。

Chrome拡張をオフにしたり、削除したりしない限り、ずっとです。

この世界のスクリプトに`window.onload`を書くと、最初のオンにしたときに実行されます。

つまり、ページ遷移しただけでは初期化されないということです。

世界同士の通信方法については今回触れませんが、例えば「Content Scriptsで取得した値を次のページでも利用したい！」っていう時は、一旦Backgroundに値を送って保持しておき、ページ遷移した後またContent Scriptsに持って来れば良いわけです。Popupも然りです。

ページ遷移だけでなく、他のタブを開いても変わりません。

##Content Scripts
ここでは、実際の見ているこのページの処理をします。

「背景の色を変えたい」だとか、「ページ内にあるリンクを取得したい」だとか、ページに対して何か操作したいって時に使います。DOM操作ってやつですね。

こんなこと
[Twitterから「いいね」を消し去るChrome拡張を作る - Qiita](https://qiita.com/hal1437/items/59d7a55124027d2ff492)
や、こんなこと
[課金なんて必要ない？YouTubeの広告自動スキップ＆バナー自動削除のChrome拡張作ってみた - Qiita](https://qiita.com/HirosuguTakeshita/items/fd1da5f6b727fbe611e4)
ができちゃいます。楽しいね。

この世界のスクリプトに`window.onload`を書くと、ページの更新ごとに実行されます。

Chrome拡張の大半がこの世界を利用しているので、調べてみると色々と記事が見つけられると思います。

##Popup
Chrome拡張を追加すると、Chromeの右上にアイコンが表示されるかと思います。

そのアイコン、またはアイコンを押した時に出てくるポップアップの処理をします。

ポップアップが出てくるのであれば、そのポップアップを閉じると処理が終わります。

この世界のスクリプトに`window.onload`を書くと、アイコンを押した時に実行されます。

拡張機能によっては、アイコンを押してオン/オフを切り替えたり、ポップアップのボタンで機能を変化させたり、といったものがありますが、その場合はここの世界を使っています。

ポップアップで機能を変化させている例としては、この方の記事なんかがあります。
[Chromeブラウザの拡張機能を作ってみたい初心者向けに開発方法を紹介！【サンプルあり】 - Qiita](https://qiita.com/guru_taka/items/37a90766f4f845e963e5#%E3%81%8A%E3%81%BE%E3%81%91%E5%88%9D%E3%82%81%E3%81%A6%E4%BD%9C%E3%81%A3%E3%81%9F%E8%A8%98%E5%BF%B5%E3%81%99%E3%81%B9%E3%81%8D%E6%8B%A1%E5%BC%B5%E6%A9%9F%E8%83%BD)

Content Scripts同様ここで値の保持はできないので、ポップアップ間で値を共有したいときは一旦Backgroundに送って保持してもらう必要があります。

#おわりに
3つの世界について触れましたが、何かミスってたり、それぞれの世界について他に知りたいことなどあればコメントお願いします。

画像を使ったりしたら分かりやすいのでしょうけど、如何せん画像が付けづらい概念の説明でどのように書くべきか難しいところです。

分かりづらかったらすみません。

##参考文献
それぞれの世界の通信方法（メッセージパッシングと言う）について、バチクソ分かりやすい記事があるので、開発する方は参考にした方が良いと思います。

[Chrome Extension の作り方 (最終話: メッセージパッシング) - Qiita](https://qiita.com/sakaimo/items/5e41d6b2ad8d7ee04b12)

[chrome開発者ツールを作る - Qiita](https://qiita.com/moajo/items/8241719479987697ca37)

[Message Passing - Chrome（公式）](https://developer.chrome.com/extensions/messaging#examples)
typescriptのclassで継承元のメソッドを呼ぼうとしたら怒られた時 (typescript error 2340)

# 概要
以下のコードは何が駄目か分かるでしょうか？

```ts
export class Hoge {
  public getA = () => 1;
}

export class Huga extends Hoge {
  public getA = () => {
    
    /*
    * error! 
    * 
    * 'super' キーワードを使用してアクセスできるのは、
    * 基底クラスのパブリック メソッドと保護されたメソッドのみです。ts(2340)
    */
    return super.getA();
  };
}
```

# 解決

エラー文だけ見ると「publicなのになんで？」という感じなのですが、ここで大事なのはそこではなく、「本来methodにするべき箇所でpropertyを使ってしまっている」という場所が問題です。

すなわち、以下にすると解決します。

```ts
export class Hoge {
  public getA() {
    return 1;
  }
}

export class Huga extends Hoge {
  public getA() {
    return super.getA();
  }
}
```

typescriptやjavascriptで書いていると、特にarrow functionのせいで変数でも関数でも差が無いように思い込みがちですが、classにおいてのpropertyとmethodは全く別物です。

細かい差異はいくつか他にもあるのですが、上記のように継承元の「method」を呼ぶことはできても「property」を呼ぶことはできないので注意しましょう。
【Laravel Excel】読み込んだファイルを編集して出力する方法

#はじめに
業務でExcelファイルを出力する必要が出たため使用しました。

42列×1万行ほど出力する予定で、bladeテンプレートを使った場合と比較した結果、Excel雛形を用意したほうが速かったので今回はそちらを使用しました。

###環境
Laravel　5.2
Laravel Excel　2.1
php　7.0

#インストール
インストールについては[document](https://docs.laravel-excel.com/3.1/getting-started/)にLaravelバージョンごとの案内があるのでそれにしたがってください。
config/app.phpのServiceProviderとaliassesに追加しておくと```use Excel```で呼び出せて便利です。

composer update後にphp artisan config:cacheをしないと反映されないみたいなので忘れずに！


#やり方
```php

//読み込み
Excel::load('file.xlsx', function($file) {
  //シートの選択
  $file->sheet('sheet1', function($sheet) {
    $sheet->row(1, ['apple', '100']);
    $sheet->row(2, ['banana', '30']);
    $sheet->row(3, ['orange', '200']);
  }
//出力形式の選択
})->export('xlsx')
```

まずExcel::loadで雛型ファイルを指定します。
**※ver3以降はExcel::import($yourImport)に置き換えられているそうです。**

雛形はstorageやresource配下に置くかと思いますが、Laravelのヘルパ関数で簡単にパスを取得できます。

シートの選択は、存在しないシート名を入れるとエラーになってしまうので、必要なシートは前もって作成しておく必要があります。

データの書き込みは、行ごとに\$sheet->row()に行番号と配列を渡すことで実行できます。
$sheet->cell()を使えばセルごとの書き込みも可能です。

出力はexport()で、引数に出力形式を入れるだけです。読み込みファイルと出力形式を変えることもできます。

#便利なメソッド
```php
$file->setFileName( Carbon::now()->format('Ym').'dataList');
```
取り込みと出力でファイル名を変えたい場合に便利です。
需要ありそうなのに何故かdocumentに載っていなかったので、、、


```php
$sheet->getStyle('A1:K3')->applyFromArray([
  'borders' => [ 'allborders' => [ 'style' => \PHPExcel_Style_Border::BORDER_THIN ] ]
]);
```
Excelに罫線を付けます。
documentだとsetAllBordersなどが紹介されていますが、使えなかったので、、、
こちらの[issue](https://github.com/Maatwebsite/Laravel-Excel/issues/1705)に助けられました

ほかにもセルごとに色を変えたりフォントやフォーマットの指定もできます。


雛形ファイルを使うとレイアウトの指定も楽なのでおすすめです。
参考にしていただければ幸いです。
Iパス試験　メモリ

#目次　メモリ
1. [メモリ(主記憶装置)とは](#1メモリとは)
2. [RAMとROM](#2ramとrom)
3. [RAMの種類](#3ramの種類)
 - [RAM = RandomAccessMemory(ランダム アクセス メモリ)通称ラム](#ram--randomaccessmemoryランダム-アクセス-メモリ通称ラム)
 - [ROM = ReadOnlyMemory(リードオンリーメモリ)通称ロム](#rom--readonlymemoryリードオンリーメモリ通称ロム)
4. [ROMの種類](#4romの種類)
 - [マスクROM](#マスクrom)
 - [PROM(プログラマブルROM)](#promプログラマブルrom)
     - EPROM(イレイサブルPROM)
     - EEPROM(エレクトリカリーEPROM)
     - フラッシュメモリ

#1.メモリとは
メインメモリ(主記憶装置)は、コンピュータの動作に必要なプログラムやデータを一時的に記憶する。
CPUの作業用の机のイメージ。


#2.RAMとROM
###RAM = RandomAccessMemory(ランダム アクセス メモリ)通称ラム
RAMは主にPCに使われ、**電源を切ると記憶が消去**される**揮発性**と言う特性を持つ。

###ROM = ReadOnlyMemory(リードオンリーメモリ)通称ロム
ROMは主に家電製品など「決められた動作を行うだけの特定向けコンピュータ」向けで、**電源を切っても記憶が保持**される**不揮発**性と言う特性を持つ**読み込み専用**メモリ。


#3.RAMの種類
###D-RAM(ダイナミックRAM)
D-RAMは安価で容量が大きく、PCのメインメモリ（主記憶装置）に使われている。読み書きはS-RAMに比べて低速。記憶内容を保つには、定期的に再書き込みを行うリフレッシュが欠かせない。

<details><summary>リフレッシュとは</summary>
DRAM半導体は自然に放電しており、放っておくと電荷がゼロになってデータが消失してしまうので、定期的に電荷を与えて書き込みし直すリフレッシュ動作が必要となる。
リフレッシュが単位時間（1秒）当りに行われる回数を示す値がリフレッシュレートと呼ばれ、リフレッシュが行われる周期（どれだけの時間間隔をおいて行われるのか）を示す値はリフレッシュサイクルと呼ばれる。
リフレッシュを必要とするDRAMが現在ではメインメモリとして使用されているので、コンピュータに電源が供給されていないとメモリの記憶が消えてしまう。
引用[BINARY IT用語辞典(リフレッシュとは)](https://www.weblio.jp/content/%E3%83%AA%E3%83%95%E3%83%AC%E3%83%83%E3%82%B7%E3%83%A5)</details>

###S-RAM(スタティックRAM)
D-RAMに比べて非常に高速だが高価なので小容量になる。D-RAMにとは違い、記憶内容を保持するのに**リフレッシュがいらない**。


#4.ROMの種類
###マスクROM
**読み込み専用のメモリ**で、主に家電製品に使われる。製造時にデータを書き込み、以降は**内容を書き換えることはできない**。

###PROM(プログラマブルROM)
プログラマ（ユーザー）の手によって**書き換えることが出来る**ROM。以下のような種類がある。

- **EPROM(イレイサブルPROM)**
**紫外線**でデータを消去して書き換えることができる。

- **EEPROM(エレクトリカリーEPROM)**
**電気的**にデータを消去して書き換えることができる。

- **フラッシュメモリ**
EEPROMの一種で、電気的にデータを消去するが、全消去ではなく一部の**ブロック単位**で消去して書き換えることができる。
主に**SDカード**があげられる。
Iパス試験　CPU

#目次: CPUについて
1. [CPUとは人間の頭脳](#1-cpuとは人間の頭脳)
2. [クロック周波数とその単位(Hz)](#2-クロック周波数とその単位hz)
3. [キャッシュメモリで高速処理](#3-キャッシュメモリで高速処理)

#1. CPUとは人間の頭脳
###CPU＝Central Processing Unit (中央処理装置)
CPUがメモリからのプログラムを読み込むと、そこに記された命令を解釈してCPU内の演算装置が処理し、制御装置がコンピュータを制御する。
人間の頭脳と同じ役割をしている。

#2. クロック周波数とその単位(Hz)

コンピュータに繋がれた各装置は、一定の周期信号『クロック』に合わせて動くことでタイミングを同調させている。
CPUの１秒間に繰り返される『クロック』数が多ければ多い程そのCPUの性能が良い（人間で言うところ頭の回転が早い）。

クロックが**１秒間**に繰り出される振動のことを**『クロック周波数』**といい、単位は**『Hz(ヘルツ)』**

**"クロック周波数１GHzのCPU"**の場合、**１秒で１０億回振動**していることになる！
さらに、１クロックで１つの命令を処理していると仮定すると、１秒間に１０億回命令を処理してることになる！

>Q.クロック周波数が1.6GHzのCPUは、４クロックで処理される命令を１秒で何回実行できるか？
>>A.クロック周波数が１.６GHzのCPUは、１秒間に[１.６＊１０億(G＝１０億だから)]回クロックを発生させる。
>>１つの命令が４クロックで１個処理されるので、[１６億回/４クロック＝４億回]
>>つまり、１.６GHzのCPUは４クロックで処理される命令を１秒間に４億回を実行することができる。

#3. キャッシュメモリで高速処理
CPUがメモリ（主記憶装置）とデータのやりとりをすると、メモリがデータの読み書きに時間がかかってしまい、CPUが待たされてしまう。
そこで、CPUに入っている**『キャッシュメモリ』**を使う。
**『キャッシュメモリ』**は**メモリよリ高速**にデータのやりとりができ、頻出するデータを置いておきいちいちメモリから読みこむ時間を短縮することでCPUとメモリの間での速度差を埋めることができる。

何層にも重ねることで、より高速にデータのやりとりができるCPUもある。
Iパス試験　コンピュータ５大装置

#目次: コンピュータの５大装置
  1. [演算装置(CPU)](#1演算装置cpu)
  2. [制御装置(CPU)](#2制御装置cpu)
  3. [記憶装置](#3記憶装置)
     - [主記憶装置(メモリ)](#主記憶装置メモリ)
     - [補助記憶装置](#補助記憶装置)
  4. [入力装置](#4入力装置)
  5. [出力装置](#5出力装置)

##1.演算装置(CPU)
CPUは演算と制御を行う装置で、演算装置は**四則演算**や、**データ処理**を行う。
人間の脳と同じ役割。
##2.制御装置(CPU)
CPUは演算と制御を行う装置で、制御装置では**プログラムの命令**を解釈して、**コンピューター全体に命令を出す**。
人間の脳と同じ役割。
##3.記憶装置
 - ###主記憶装置（メモリ）
 動作するために必要なプログラムやデータを、**一時的**に記憶する装置。コンピュータの電源を落とすと記憶されていた物が**消えてしまう**。

 - ###補助記憶装置
プログラムやデータを**長期保存**しておく装置。主記憶装置とは違い、電源がなくなっても記憶を**保持し続ける**。

##4.入力装置
コンピュータにデータを入力するための装置。代表的なのはキーボード、マウス、スキャナ。

 - キーボード : 文字や数字を入力できる。
 - マウス : マウス自身を動かすことで、位置情報を入力できる。
 - スキャナ : 図や写真をデジタルデータに変換して入力できる。

##5.出力装置
コンピュータのデータを出力するための装置。代表的なのは、ディスプレイ、プリンタ。

 - ディスプレイ : コンピュータ内部のデータを画面に映し出す装置。
 - プリンタ : コンピュータの処理したデータを紙に印刷する装置。
【ReactNative】Could not find iPhone X simulatorエラーの解決

#エラーについて

```
Found Xcode workspace sample.xcworkspace

Could not find iPhone X simulator

Error: Could not find iPhone X simulator
```
Xcode11でこの問題で少し詰まったので、メモ。
Simulatorアプリでいくらターゲットのsimulatorを追加しても
うまくいかなかったのですが、下記の方法で改善しました。

*ReactNative v0.59.8
#◆対策
/node_modules/react-native/local-cli/runIOS/findMatchinSimuilator.jsの62行目あたり

```
if(simulator.availability !== '(available)' &&
        simulator.isAvailable !== 'YES' ){

```
という部分の条件分岐を

```
if(simulator.availability !== '(available)' &&
        simulator.isAvailable !== 'YES' && 
        simulator.isAvailable !== true){  //    <- この行

```
へ変更。

#◆原因
xcode側の実装が変わっており、デバイス毎に以下のような
ステータスを持っているが、その中のisAvailableの変数が
String → Boolean に変わったようです。

```
{ state: 'Shutdown',
       isAvailable: false,
       name: 'iPhone X',
       udid: 'F15B13D6-4E4C-4047-84DA-0361220016D5',
       availabilityError: 'runtime profile not found' }
```

なのでbooleanでtrueの場合も真の処理を通してあげる修正を入れてあげると動作します。
Go クロージャを理解する

Goのクロージャ(他の言語でもありますよね)について、よく理解できていなかったので調べてみた

## クロージャとは
> クロージャ（クロージャー、英語: closure）、関数閉包はプログラミング言語における関数オブジェクトの一種。いくつかの言語ではラムダ式や無名関数にて利用可能な機能・概念である。引数以外の変数を実行時の環境ではなく、自身が定義された環境（静的スコープ）において解決することを特徴とする。

うーん...
簡単に言うと、「ローカル変数を参照している関数内の関数」ってこと...?

```go:main.go
package main

import "fmt"

func add() func() int {
  n := 0
  
  return func() int {
    n++
    return n
  }
}

func main() {
  a := add()
  fmt.Println(a())
}
```
クロージャを使わない場合、グローバル変数を用意したりする必要があるので、クロージャを使いなれておくと便利らしい

### 参考
[【学習GOLANGシリーズ】クロージャ](https://www.blog.umentu.work/%E3%80%90%E5%AD%A6%E7%BF%92golang%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA%E3%80%91%E3%82%AF%E3%83%AD%E3%83%BC%E3%82%B8%E3%83%A3/)