OmniAICreator/Qiita-1.07M huggingface dataset:
20代エンジニアのためのプログラマ勉強法まとめ

20代エンジニアのためのプログラマ勉強法まとめ

https://supporterzcolab.com/event/731/?utm_campaign=event_lottery_join&utm_source=notifications&utm_medium=email&utm_content=title_link

こちらに参加して聞いたお話まとめ
重要そうな部分を要約・抜粋

## 前提
- 20代のみなさんとMatzさんでは時代背景が違う
- 自分の過去の話だけしてもそこまで参考にならない
- プログラミングというよりも普遍的な学習法というか、実際に役立つ考え方や成功法則についての話にフォーカスする

## 論点
- 戦略を立てる
- インベントリをする
- アウトプットをする

## 戦略を立てる
物事を「把握」する事が必要

### 戦略を助ける視点
- 二分化
- メタファー・抽象化

### 二分化
- 「学生」と「社会人」
  - 満点と満点無の世界
- 「知識」と「インデックス」
  - 記憶と把握の世界
- 「苦手」と「得意」
  - 得意を伸ばす世界
- 「試験」と「常在戦場」
  - スコープ度外視の学習

### メタファー・抽象化
背景知識を活用しパターンを抽出・分かり易く認識する

- エンジニアリングは抽象化の極み
- メタファーは時としてミスリーディングを誘う
  - 抽象化して再構築してみる
- 一方で抽象化にはモレが生じることも理解しておく
  - 人間は分かり易いものを好む

### なぜ戦略を立てるのか
現代社会は罠が多いため

- 情報過多かつテクノロジーや文化の方向性に問題があるものもある。
  - エントリーシートの一括送信、営業の機械音声
  - いわゆるブラック企業(体を壊しても、誰も責任は取らない)
->色んな事に「No」と言ってもいい(言える必要がある)

### どう知識を得るか
結局人に言われた通りに知識を得て学習しても差別化にはならない

- 好きなことを学んで自分で追求した結果得られたものこそ、有用な知識でありユニーク
- インベントリで追求し続ける

## インベントリをする
棚卸しをする・振り返りをするということ

### 定期的なインベントリによって自分の戦略・目的をアップデートする
そもそも差別化したいなら聞いたままの話をやっても差別化にならない

- 得意、興味、趣味、嗜好、背景を知る(自分の)
- Matzさんの場合、こっそりやっていたことが以外と誰もやっていなかった。 
- 得意を生活に繋げる
- 他人は教えてくれないということを理解する

## アウトプットをする
アウトプット自体が成長であって、表現である

### 人間の可塑性にかける
繰り返すことで楽になり、楽になるとは最適化されるということ

### アウトプットだけは得意不得意は関係ない
アウトプットとは生存表明

### アウトプットは知名度の向上に繋がり、知名度は成功に変換可能
知名度は横展開ができる

## エンジニアとして必要な3要素
具体的アドバイス

### 基礎習得をすること
- 不変要素を押さえる
  - コンピュータサイエンス
  - アルゴリズム
  - コンピュータアーキテクチャ

### 英語を学ぶ
- 一次情報
- 圧倒的に情報量が違う

### コンフォートゾーンを抜ける
- 変化を恐れない
- 誰かを見下さない

## まとめ
考え続けること

## 雑感
「こっそりやっていたことが以外と誰もやっていなかった。 」がMatzさんを自分のフィルターを通して視た際に残った部分。
GoogleAppsScript Tips(slack通知)

```
/**
 * slackに通知を送信する
 * @param {string} message メッセージ本文
 */
function sendNotificationSlack(message) {
    // webhookから取得したURL
    var postUrl = 'https://hooks.slack.com/services/・・・';
    var username = 'ユーザー名';  
    var icon = 'アイコン';  
    var params = {
        "username"  : username,
        "icon_emoji": icon,
        "text"      : message
    };
    var payload = JSON.stringify(params);

    var options = {
        "method"      : "post",
        "contentType" : "application/json",
        "payload"     : payload
    };

    UrlFetchApp.fetch(postUrl, options);
}
```
イテレータはイテラブルではないので分割代入できない

## 要旨

- イテレータは分割代入できない。
- 分割代入できるのはイテラブル。
- イテレータはイテラブルとは限らない。
- 自前で実装したイテレータには、`[Symbol.iterator](){return this;}`を生やすこと。

## コード

```js
const fib = function fib(){
  let n_1 = 1, n_2 = 0;
  const iteratorResult ={
    value: n_1,
    done: false
  };
  return {
    next(){
      iteratorResult.value = n_1;
      [ n_1, n_2 ] = [ n_1 + n_2, n_1 ];
      return iteratorResult;
    }
  }
}

let f = fib();
let[a, b, c, d, e] = f;
/*
Exception: TypeError: f is not iterable
*/
```

## 問題

自前で実装した無限フィボナッチ数列イテレータですが、分割代入をしようとすると
`TypeError: f is not iterable`
と、イテラブルじゃないよ、と返ってきます。
もちろん、`for ... of`構文でも同様のエラーになります。
なぜか。

## 分割代入できるのはイテレータではなくてイテラブル

> iterable (反復可能)プロトコルによって、JavaScript オブジェクトは、for..of構造で値がループしているもの等の反復動作を定義、または、カスタマイズできます。
（略）
>iterable であるために、オブジェクトは@@iterator メソッドを実装する必要があります。
[反復処理プロトコル - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Iteration_protocols#The_iterable_protocol)

MDNを見れば明らかだったのですが、分割代入できるのはイテレータではなくてイテラブルであり、イテレータであっても `@@iterator` メソッドがなければイテラブルではない、ということです。

## ジェネレータはどうなっているのか

```js
const fib = function* fib( n_1 = 0, n_2 = 0 ){
  const n = n_1 + n_2 || 1;
  yield n;
  yield* fib( n, n_1 );
}

let f = fib();
f[Symbol.iterator]() === f;
/*
true
*/
```
なるほどね。

## 解決方法
```js
const fib = function fib(){
  let n_1 = 1, n_2 = 0;
  const iteratorResult ={
    value: n_1,
    done: false
  };
  return {
    [Symbol.iterator](){ return this; },
    next(){
      iteratorResult.value = n_1;
      [ n_1, n_2 ] = [ n_1 + n_2, n_1 ];
      return iteratorResult;
    }
  }
}

let f = fib();
let[a, b, c, d, e] = f;
e;
/*
5
*/
```
ということで、自前実装のイテレータには、`this`を返す`[Symbol.iterator]`メソッドを生やしておきましょう。
↓このMDNの説明は若干不親切かな、と思いました。
[イテレーターとジェネレーター - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Iterators_and_Generators#Iterators)

## これを教えてくれた人

@think49 さんです。感謝。
[JavaScript - イテレータを進めずに終了しているかどうかを取得する方法はありますか？｜teratail](https://teratail.com/questions/181789)
レポートフィルターを用いて集計内容を複数のシートに分離する。


今回の課題はレポートフィルターという機能を用いて、あるデータセットの集計を複数シートに分散して表示することである。

列ラベルや行ラベルだけを集計軸に追加すると同一シート内に集計結果を表示することができるが、追加した軸を複数のシートに分けることで表示したい場合にこのレポートフィルター機能を用いる。

1. 複数のファクターを持つデータセット(エンティティ)をピボットテーブルでデータを集計する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/274248/4c72c0f5-389a-d00e-e0f8-4cd09b38a738.png)

集計関数と集計軸は以下の通り。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/274248/ad2484ec-f598-575c-41be-3a8a57a7b1f6.png)


2. 集計時にシートを分離したい軸を「レポートフィルター」に追加する。
今回は年齢毎にシートを分けたいため、「Age」カラムを「レポートフィルター」に追加する。

※ファクター型ではなく、変数を持つ集計軸を指定すると作成されるシートが膨大になり、メモリが不足するため、注意が必要である。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/274248/5f666e4e-595b-1f56-8b9a-d76a6eabee57.png)

3. 集計が完了したピボットテーブルをクリックした状態の場合、「ピボットテーブルツール」というタブが表示されるようになる。

「ピボットテーブルツール」タブの「オプション」タブをクリックする。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/274248/c88cd91f-f12e-c7e2-5566-2aa8af506ab6.png)



4.「オプション」の隣にある「▼」をクリックし、「レポートフィルターページの表示」をクリックする。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/274248/666c40d8-2ed0-ebfd-8ac0-f8bbd7141117.png)


5. シート毎に分離したい集計軸を選択する。「OK」を選択すると集計が開始され、複数のシートに分けられる。
※今回はAgeのみが選択可能である。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/274248/028b5c24-ff08-e4f6-2c74-9846163ba0c4.png)

6.赤く囲った部分の新規シートが作成された。
※元データセットをシート毎に集計する前の元となったピボットテーブルのシートは残る。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/274248/d139ef26-8cf9-3e9b-47b1-425bdbcd8005.png)
プログラミング学習記録49〜オリジナルアプリ完成〜

##今日やったこと
- Railsで作ったオリジナルアプリ（The Magic of Memos)にユーザー退会機能を加える
- オリジナルアプリをHerokuにデプロイする


なんとか完成しました。

まだまだ自分でも「もっとこうしたいな」という部分はたくさんあるのですが、公の場に出せる最低限のレベルには達したと思うので、一旦完成ということにしました。

ユーザー退会機能を実装するにあたって、最初は条件分岐ゴリ押しでやっていたのですが、結局そのやり方ではできませんでした笑

その後、どうやらActive Recordの関連付け(アソシエーション)をすると、条件分岐を使わなくても退会機能を実装することができると知り、いろいろ頑張ってみたのですが、それでも難しかったです。

やはりRubyの基礎がまだまだなんだと思います。
チェリー本とかをしっかり読んだ本がいいのかもしれません。

結局、退会機能を自力で実装することはできなかったので、MENTAでRailsのエンジニアに助けを求めました。

Slackのグループに招待され、問題となっていた部分について聞いてみたら２回のやりとりで解決してしまいました。

post.rbとlike.rbの記述が足りていなかったのが、１番の原因でした。

詳しくは別の記事、ブログで述べますが、とにかく解決できてよかったです。

一区切りがついて若干、燃え尽きた感もありますが、明日からも引き続きプログラミング学習頑張ります。

おわり
PHP7.2以降のcountについて

PHP7.2から、countは、countableではない型に対してE_WARNING が発生するようになりました。
つまり、countのパラメータはarrayとcountable以外はだめです。
なのですがPHP7.2以前に書かれたソースコードは、NULLが入る可能性があったり...未定義が入る可能性があったり..結構自由に書かれていることがあります。

countを使うときは、「個数を数えたい場合」か「0か否かの判別で使っている場合」だと思うので、そのふたつの場合の対象方法について描きます。

### 個数を数えたい場合

個数を数えたい場合、countを使う前に変数が数えられるか判定します。

#### PHP7.3以降
PHP7.3以降での開発のときは、```is_countable()```を使います。
is_countableは、arrayかcountableかを判定してくれます。

```
if(is_countable($a)){
 count($a);
}
```

#### PHP7.2以前

PHP7.2以前の場合は、``` is_array() ```か```isset()```か```!empty()```で判定します。

arrayが入ることが確実の場合は``` is_array() ```で問題ないです。

```
if(is_array($a)){
 count($a);
}
```

ですが、countableオブジェクトが入る場合は配列じゃないのでfalseになってしまいますし、未定義が入る場合はNoticesになってしまうので、```isset()```か```!empty()```を使います。

ちなみに、未定義を入れてNoticesにならないのは、```isset()``` と ```empty()```だけです。

### 0か否かの判別で使っている場合
0か否かの判別で使っている場合は、isset, empty, is_nullを使うことをおすすめします。

|  | isset() | empty() | is_null() |
|:----------:|:-----------:|:------------:|:------------:|
|0|true|true|false|
|"0"|true|true|false|
|1|true|false|false|
|NULL|false|true|true|
|未定義|false|true|true|
|array()|true|true|false|
|array(1)|true|false|false|

単純に0か否かの場合は```isset()```でいいですが、
配列の中身を判別する際は``` !empty() ``` を使います。

## おまけ 

countを使っている箇所を修正してるときに見つけたものです。

```
<?php
$str = NULL;
$a = explode(" ",$str);
var_dump(count($a));
```
### 結果

> int(1)

explodeは、NULLを入れるのを受け入れ文字列の配列を返すので、countできる上に1になってしまうのです..！
Google App Scriptで絶対パスを使ってフォルダのIDを取得したい

# 1. はじめに
GASではフォルダやファイルへアクセスする際に，IDを使います．このIDはフォルダやファイルごとに一意に与えられているため，あるフォルダの中に同じフォルダやファイルを置くことが許されています．しかし，これが原因（？）で絶対パスを指定してフォルダやファイルにアクセスする関数がありません．この記事では，ある条件下でそれを実現するための関数を作成したのでご紹介します．

# 2. 前提条件
### 読者へ向けて
GASの実行方法や文法については知っているものと仮定します．

### Googleドライブのフォルダ階層について
同じフォルダ階層に同じ名前のフォルダ or ファイルが無いことを仮定します．
（この条件がこの記事のキモになります．）

# 3. コード
次のコードは指定したフォルダのIDを返す関数です．
・引数　：絶対パス（例："/path/to/your/folder"）
・戻り値：指定したフォルダが存在した場合はフォルダID，存在しなかった場合は"Not found."

```javascript:指定したフォルダのIDを取得する関数
function getFolderId(absolutePath){
  
  var folderId = "Not found.";

  // パスを"/"で分割
  // pathList[0]は""が入るので，以降では使用しない
  var pathList = absolutePath.split("/");
  
  // パスで指定したフォルダが見つからない場合
  if(!DriveApp.getRootFolder().getFoldersByName(pathList[1]).hasNext()){
    return folderId;
  }
  var folder = DriveApp.getRootFolder().getFoldersByName(pathList[1]).next(); 
  
  for(var i=2; i<pathList.length; i++){
    // パスで指定したフォルダが見つからない場合
    if(!folder.getFoldersByName(pathList[i]).hasNext()){
      return folderId;
    }
    folder = folder.getFoldersByName(pathList[i]).next();
  }
  
  folderId = folder.getId();
  
  return folderId;
  
}
```


# 4. 終わりに
この記事の前提条件として，「同じフォルダ階層に同じ名前のフォルダ or ファイルが無いことを仮定」がありました．この条件は，Googleドライブのフォルダ設計をうまく行なえれば，クリアできる条件だと思います．

GoogleAppScript歴がまだまだ浅いため，この記事に間違いや分かりにくい点があると思います．その際は，コメントにてお知らせいただけますと幸いです．

## 参考にしたサイト
[Google Apps Scriptでファイル名、フォルダ名からファイルへアクセスしたい](https://qiita.com/tanaike/items/94c263d3906ee23ad522#a1%E7%89%B9%E5%AE%9A%E3%81%AE%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E3%81%B8%E7%89%B9%E5%AE%9A%E3%81%AE%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E4%BD%9C%E6%88%90%E3%81%97%E3%81%A6%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9)

[Google更新レファレンス【Class DriveApp】](https://developers.google.com/apps-script/reference/drive/drive-app)
Vue CLI のサンプル　（整数の加算、減算）

Vue CLI　のサンプルです。次のようなページを作成します。
整数の加算、減算をします。
![calc01.png](https://qiita-image-store.s3.amazonaws.com/0/179446/56e39891-0272-a7b4-52e6-4b12f108a7a4.png)

```vue:src/App.vue
<template>
  <div>
      {{value_aa}}
<input type="text" v-model="value_aa">
<p />
      {{value_bb}}
<input type="text" v-model="value_bb">
<p />
和 {{wa}}<p />
差 {{sa}}</p>
<button @click="calculation()">計算</button>
<button @click="clear()">クリア</button>
  </div>
</template>

<script>
export default {
  data () {
    return {
      value_aa: 0,
      value_bb: 0,
	wa: 0,
	sa: 0,
    }
  },
  methods: {
    calculation () {
      this.wa = parseInt(this.value_aa) + parseInt(this.value_bb)
      this.sa = parseInt(this.value_aa) - parseInt(this.value_bb)
    },
    clear () {
      this.value_aa = 0
      this.value_bb = 0
      this.wa = 0
      this.sa = 0
    }
  }
}
</script>
```

src/App.vue の使い方はこちら
[Vue CLI の簡単な使い方](https://qiita.com/ekzemplaro/items/73f5bf76ef4912b7a0ea)
質問者＆回答者の目線からみるteratailとの上手な付き合い方

# teratailとは

![imgAboutLogo.png](https://qiita-image-store.s3.amazonaws.com/0/166345/0ec99ad4-4f28-029e-a5c7-06919820b116.png)


[teratail【テラテイル】｜ITエンジニア特化型Q&Aサイト](https://teratail.com/)

[StackOverflow](https://ja.stackoverflow.com/)のようなエンジニア向けのQ&Aサイト
プログラミングに関する問題解決をサポートしてくれるらしい

# 記事を書くきっかけ
普段から利用しており、自分なりに思うところがあったので残しておきたかったから。
稚拙な文章で申し訳ありませんが読んであげてください。

- 質問者
- 回答者

に分けて書いています。

# 質問者目線

## Markdownを利用しよう
アカウントを作って間もない人に多い。
問題が解決出来ずに困っているのは分かりますが、決められたルールは守りましょう。
teratailを利用していて散見されるのは以下の画像のような感じ。

### Markdownなし
<img width="790" alt="スクリーンショット 2019-04-06 16.57.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/166345/b2a01793-8c86-ea27-6465-992c4fcf71c2.png">

**・・・インデントの霊圧が・・・消えた・・・・？**

### Markdownあり

<img width="783" alt="スクリーンショット 2019-04-06 17.40.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/166345/b988b27e-487c-d8b8-20b5-094c99a54d33.png">


　
こういう投稿は回答者からしても読む気にならないので、素早い回答が得られるためにも改善すべきです。


## 自分が何を分かっていないのかを理解する


```
例)
プログラミング初心者です。Pythonで物体検知したいのですがやり方が分かりません。どのように実装すれば良いでしょうか？
出来ればコード付きで教えて欲しいです。
```

これは典型的な**「自分が何を分かっていないのかが分からない」**人の質問です。
もしくは分かろうとすることを放棄した人の質問です。

この例で言えば、質問者が分からないのは物体検知の実装ではなくプログラミングそのものです。
[質問するときのヒント](https://teratail.com/help/question-tips)の２番にも記載があります。質問力を上げていきましょう。


## 載せれるコードは全て載せる

よく、コードの一部を切り取って質問をする人がいます。意図は分かります。

**ここでエラー出ているんだからここだけでいいじゃん？**

ということでしょう。
確かにエラーが出ているところはそこかもしれません。
でも、エラーの原因となっているのは別のところにある可能性の方が高いです。
それによって、以下の事例のように質問者も回答者も不利益な時間を産むことになります。

[teratail | pタグの要素内の上下にmarginでもなくpaddingでもない余白](https://teratail.com/questions/183030)

質問者が載せていない情報によりお互いに不利益な時間を費やすことになってしまいます。

## 個人情報は載せない

時々ですが「会社」「上司」「お客さん」等の単語が質問文に出現していることがあります。最悪の場合、会社に迷惑がかかりますし何より自分自身の首を絞めかねません。投稿する際は気をつけてください。

## エラー文に対する自分なりの解釈を示す

```
例）
エラーが出ました、どうすればいいのか分かりません。
```

これも「何が分かっていないのか分からない」質問に含まれます。
エラー文は、ただエラーが発生したから出しているのではなく、エラーを解決するヒントになる情報を提示しています。
エラー文を読んで何が分からないのかを毎回考えるようにすることで、自力で解決する力もつくでしょう。
その上で分からないのであればエラー文の何が分からないのかを質問文に追加して上げてください。

[Qiita | エラーメッセージの読み方と対処, 検索や質問の原則](https://qiita.com/cannorin/items/eb062aae88bfe2ad6fe5)


# 回答者目線
なんで自分の時間を割いてまで質問に回答しているのだろう？そう疑問に思っている人はいるでしょうか？

ただの暇人？それとも自己顕示？

~~いや、そういう人もいると思いますよ。~~
でも、回答者としてteratailを利用するメリットって大きいです。

## 手軽にアウトプットできる場
自分の頭の中の知識を文字として示すことってそうそう簡単じゃないんですよね。
どのように書いたら相手に伝えられるかを考えながら回答することで、実は自分が分かっていなかった部分があるを発見することもあります。
アウトプットに関して言えばここQiitaであったり、自分でブログを作成して投稿したり色々手段はあると思いますが、teratailはより気軽にアウトプットできるのでオススメです。

## 他者の回答と比較できる
自分がした回答した質問に別の回答者が回答することが多々あります。
「そんな方法もあるのか」とか「その技術は知らなかった」等、驚きと発見が出てくることでしょう。
そういう回答は自分の知識の幅を広げるのを助けてくれます。

## 自分の知らない色々情報で溢れている
色んな人が色んな技術に関して質問しています。その質問が目に入ることで普段だと知ることもなかっただろう技術について知ることができます。
そういう技術があるということを知っているだけでも大きくて、今後自分がやれることの幅がぐーんと広がるでしょう。

## 自分のために回答する
まあ、人のために回答している人もいるかもしれませんし、それはそれでいいのかもしれません。
でもまずは自分のために回答してください。ここでいう「自分のため」というのは「相手のことを考えてない回答をする」ということではなく、自分にとって意味のある回答をするということを指しています。
その結果として他者のためになっているのであればGoodです。

# 終わりに
こういうのは本当に使い方次第で有益なものになり得ると思いました。
参考になれば幸いです。
mod n を利用して負荷分散

# 概要

> APIキー複数作って負荷を均等に分散させ、利用制限を緩和したい

**ここはJKらしくmodを使おう:innocent:**

# modてなに

高校数学で出てくる。数Aだったかな？

modて言うと難しそう:frowning2:

→ **ある数をnで割った余り**と考えれば簡単:relaxed:

```
$ 10 ≡ 1(mod3) $
→ 10÷3の余りは1
```

# ソースコード
jQueryで書いたよ

```javascript:script.js
var clientId;
$.ajax({
  url: './count.php' // Simple count up,
  type: 'GET',
  dataType: 'text',
  cache: false,
  async: false
})
.done((response) => {
  var count = response;
  var calc = count % 2;
  if (calc === 0){
    clientId = 'API-key 111111111111111'
  }else if(calc === 1){
    clientId = 'API-key 000000000000000'
  }
})
```

phpは[ONZE](https://on-ze.com/archives/1422)さんを参考にしてます。

```php:count.php
<?php
$counter_file = 'count.txt';
$counter_lenght = 8;
$fp = fopen($counter_file, 'r+');
if ($fp) {
    if (flock($fp, LOCK_EX)) {
        $counter = fgets($fp, $counter_lenght);
        $counter++;
        rewind($fp);
        if (fwrite($fp,  $counter) === FALSE) {
            echo ('<p>'.'ファイル書き込みに失敗しました'.'</p>');
        }
        flock ($fp, LOCK_UN);
    }
}
fclose ($fp);

echo $counter;
?>
```

# まとめ

一応mod使えば負荷分散出来んじゃね？？

って思ったから書いたけどOKかはしらね (・ω<)

その辺詳しい人よろしくお願いします
VPCピアリングをやってみた

##1.できることとできないこと##

- できること
 - 異なるVPCを接続する。
 - 異なるリージョンのVPCを接続。(インターリージョンVPCペアリング)
 - 複数のVPCとピアリング。
 
- できないこと
 - CIDRが重複するVPC間のピアリング
 - ピアリング先のVPCがピアリングしているVPCに直接通信することはできません｡
 - ピアリング先のVPCが接続しているVPN/DXを経由してオンプレミスと直接通信することはできません｡
 - ピアリング先のVPCのインターネットゲートウェイ/NATデバイスを経由してインターネットに直接通信することはできません｡
 - ピアリング先のVPCエンドポイントを経由してAWSリソースに直接通信することはできません｡
 - リージョン間の VPC ピアリング接続では、IPv6 経由の通信はサポートされません。（リージョン内はサポートされている）

VPCピアリングは、**１vs１のVPC間を接続する** ので、1vsNで接続したい場合は、AWS PrivateLinkやAWS Transit Gatewayを検討する必要があります。

##2.やってみる##

- 条件
 - 同一アカウント
 - 異なるリージョン
 - EC2(VPC A) →SSH→ EC2(VPC B)
 - EC2(VPC B)にパブリックIPやキーは割り当てない。
 

**ピアリング接続の作成**
VPC Aで条件のとおり、ピアリングを作成する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/36d38dd9-88f6-a782-5cb7-18ed230d45a6.png)
作成すると、VPC Aが「承諾の保留中」になるので、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/e118d27a-067c-4f97-0fb0-933f2f4e6c05.png)
VPC Bで、「リクエストの承諾」をしてあげる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/35b55ba8-6b2a-a96c-027f-7677649b09e4.png)

**ルートテーブル**
VPC AにVPC Bへのルートテーブルを追加してあげる。TargetはVPC Bのpeering connectionを指定してあげる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/1c68754f-c568-7dd1-7c35-479e83bd5294.png)

同じようにVPC BにVPC Aへのルートテーブルを追加してあげる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/2bfc6f93-e53a-0b03-04d0-a5fd72f33e0a.png)

**セキュリティグループ**
VPC BのセキュリティグループはVPC Aからのみアクセスするようにします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/262b9c3a-595c-4d4f-80da-e14e8b0d37ca.png)

**接続**

EC2 A にsshで接続する。

```
ssh -i ***.pem ec2-user@[EC2 A Public IPAddr]
```

ssh/configの作成。

```
vi ~/.ssh/config

Host EC2A
Hostname [EC2 A Public IPAddr]
User ec2-user
IdentityFile ~/.ssh/id_rsa
 
Host EC2B
Hostname [EC2 B Private IPAddr]
User ec2-user
IdentityFile ~/.ssh/id_rsa
ProxyCommand ssh -W %h:%p EC2A
```

権限変更。

```
chmod 600 ~/.ssh/config
```

EC2 B に接続する。

```
ssh EC2B
```
【言語不問(?)】substring の考え方（文字列の範囲）

## 要約

`substring` 関数などで部分文字列の範囲を指定するときは、
文字と文字の間に連番（文字列先頭からの距離）を振り、
その値で指定すると考えるとよい。
（この考え方だと文字列の長さも分かりやすい。）

---

## おことわり

この記事では例を Java と JavaScript で書いていますが、ほとんどの言語・ライブラリーで概ね同じと思われます。
ただし、配列などのインデックスを1始まりで指定する言語の場合は異なるかもしれません。

## `substring` の引数をどう指定すればよいか、初心者には分かりにくい

ほとんどの言語の標準ライブラリーには、文字列からその一部（部分文字列）を切り出す関数が用意されているでしょう。
これは例えば文字列 `"ABCD"` から 部分文字列 `"BC"` を切り出すようなときに使います。

[Java](https://docs.oracle.com/javase/jp/8/docs/api/java/lang/String.html#substring-int-int-) や [JavaScript](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/substring) では `substring` 関数です。
次のようにして使います。

```Java
"ABCD".substring(1, 3); // -> "BC"
```

この関数は引数として切り出したい範囲の開始位置と終了位置を受け取ります。
しかし初心者にはこれをどう指定すればよいかが分かりにくいのではないでしょうか。

API ドキュメントには次のように書かれています。

<dl>
  <dt>Java</dt>
  <dd>
    <dl>
      <dt>beginIndex</dt>
      <dd>開始インデックス(この値を含む)。</dd>
      <dt>endIndex</dt>
      <dd>終了インデックス(この値を含まない)。</dd>
    </dl>
  </dd>
  <dt>JavaScript（MDN）</dt>
    <dd>
    <dl>
      <dt>indexStart</dt>
      <dd>返される部分文字列の、最初の文字を含んだ位置です。</dd>
      <dt>indexEnd</dt>
      <dd>返される部分文字列から外される最初の文字の位置です。</dd>
    </dl>
  </dd>
</dl>

はい、分かりませんね。

## こう考えよう

次のように、文字と文字の間に番号を振ります。

```
|A|B|C|D|
0 1 2 3 4
```

いや、「番号」と考えると0始まりか1始まりかという余計なことを考えてしまいますね。
単に**原点からの距離**と考えましょう。
原点（先頭）は当然0です。

`substring` 関数の引数は、この値で指定します。
`"ABCD"` から `"BC"` を切り出すのであれば、

- `"B"` の直前の `1` から
- `"C"` の直後の `3` まで

となります。
したがって次のように指定すればよいです。

```Java
"ABCD".substring(1, 3); // -> "BC"
```

### 文字列の長さ

ちなみに、「距離」と考えると、文字列の長さも分かりやすいです。

```
|A|B|C|D|
0 1 2 3 4
```

文字列 `"ABCD"` の長さは4です。
`"ABCD".substring(1, 3)` で切り出した文字列の長さは `3 - 1` で2です。

## さいごに

もしテキストエディターのようなものを作ることになった場合、文字の範囲選択の始点・終点やキャレット位置は同じように考えるとよいです。

なお、この記事では話の焦点を絞るために文字列にのみ触れましたが、
配列などについても同様に考えましょう。

## 関連記事

https://qiita.com/kazurego7/items/aeaec6c0b8449569e58c

／以上
Virtual Box のホストオンリーネットワークが設定できない...

初めての投稿です。
ハッキング・ラボの作り方を購入して勉強しようとしているのですが、virtualboxのネットワーク設定でいきなりつまずきました...
####環境
・virtualbox 5.2.26
・kali-linux 2019.1
・windows10

#どこでハマったか
__ホストオンリーネットワークの設定__
ゲストOSの設定からホストオンリーネットワークの設定を行おうとしたのですが、
![2019-04-06 (1).png](https://qiita-image-store.s3.amazonaws.com/0/307611/c34a9f63-0045-9090-6942-e39c82e271d0.png)
こんな感じで[無効な設定]となって名前のところに通常ならあるはずの[VirtualBox Host-Only Ethernet Adapter]がなく選択できません。

__ホストネットワークマネージャーを見てみる__
ネットで調べたところネットワークを追加しないといけないらしいので、
[グローバルツール]->[ホストネットワークマネージャー]->[作成]でネットワークの追加を試してみる。![2019-04-06 (2).png](https://qiita-image-store.s3.amazonaws.com/0/307611/11b087e6-bc8c-cda0-ef27-c7810bcbf439.png)
こんなエラーがでてネットワークが作成できない。

__ホストOSの問題？__
ホストOSの問題かと思いwindowsで[ネットワーク接続]->[アダプターのオプションを変更する]からネットワーク接続を見てみたところVirtualBox Host-Only Ethernet Adapterがない。これどうやったら作れるんだろうか。![2019-04-06 (4)_LI.jpg](https://qiita-image-store.s3.amazonaws.com/0/307611/f5eee40a-3d3e-3e0d-5378-fb31d13def75.jpeg)

__いろいろ調べたけど解決できない...
同じ問題で悩んでいる人いるのだろうか__

##追記
ネットでさらに調べたところ、こちらのサイトに解決方法が載っていました。
[消えた"VirtualBox Host-Only Network"を復元する](https://www.remix.asia/blog/remix/2017/10/virtualbox_hostonly_network.html)
プロンプトでvirtualboxのファイルが置いてあるフォルダに行って

>\>VBoxManage.exe hostonlyif create

と入力するとホストオンリーアダプターを作成することができました。その際にウィルスバスターを一時的に無効にする必要がありました。
__結局インストールするときにウィルスバスターが邪魔してアダプターの作成がうまく行われなかったのかな？__
【基本情報技術者試験対策】ラウンドロビン方式に関する問題で躓いたところ

#はじめに
あくまで自分が躓いたところであるため、他の人からしたら「え、当たり前じゃん？」って感じだとは思います。
だから、読んだところであんまり得られるものはないよ。
後、基本情報技術者試験の午後の部の問題文ってとんでもなく長いから、<font color="blue">一部抜粋</font>という形をとらせてもらうよ。
完全版については下記をご参照ください。
>https://www.jitec.ipa.go.jp/1_04hanni_sukiru/mondai_kaitou_2018h30_2/2018h30a_fe_pm_qs.pdf
問2 設問1

#躓いた問題と、躓く要因となった箇所(<font color="Red">赤文字</font>で示す)
プロセスのスケジューリングに関する次の記述を読んで，設問1，2に答えよ。

　OSの機能の一つに，プロセスのCPUへの割当てがある。プロセスをCPUに割り当てる順序(以下，実行順序という)を決定する方式として，本問で示すラウンドロビン方式と優先度順方式を考える。プロセスが実行されるコンピュータのCPUは一つであり，<font color="Red">CPUは一度に一つのプロセスしか実行できないものとする</font>。
![figure1.png](https://qiita-image-store.s3.amazonaws.com/0/368574/5391b80f-4e9e-548b-f667-d879bc26643d.png)

　図2に示す処理順序をもつプロセスXを，図1に示すラウンドロビン方式で実行する場合を考える。プロセスXの処理時間及び待ち時間を表1に示す。
　表1において，処理時間とは，処理1，処理2及び処理3のそれぞれが実行を開始してから終了するまでに必要なCPUの使用時間である。<font color="red">待ち時間とは，入出力待ち1及び入出力待ち2のそれぞれが入出力を開始してから完了するまでに要する時間であり，その間CPUを使用しない</font>。
　タイムクウォンタムが20ミリ秒のとき，プロセスXが生成されてから消滅するまでに，図3に示す①～④の遷移が起こる回数の組合せとして正しい答えを，解答群の中から選べ。
![figure3.png](https://qiita-image-store.s3.amazonaws.com/0/368574/5cb01a0a-08d0-4daa-ecaa-c05d5a472ecb.png)![select.png](https://qiita-image-store.s3.amazonaws.com/0/368574/c365f2af-2005-9f53-35ff-6c9ecc17f43f.png)

#勘違い：プロセスはそもそも１つ
当たり前じゃん。
問題文で出てきてるの<font color="red">プロセスXだけ</font>じゃん。
と、思われるかもしれない。
いやホントにその通りなんです……。
それなのに僕は、あろうことかプロセスXの<font color="blue">処理</font>と<font color="blue">入出力</font>を一つのプロセスと考えてしまっていたのです。
だから「入出力待ち１を待っている間に、処理２を実行できるな！」なんて馬鹿なことを考えていました。
解いている時のノートのカオスっぷりといったらヤバイです。
超簡単な問題なのに、書いているうちに頭がこんがらがるくらいごちゃごちゃなものになっていました。

#まとめ
基本情報技術者試験の午後は、よく言われるように、ちゃんと基礎が備わっているかどうを問う問題よりも、<font color="red">国語力</font>が問われる問題が多いです。
ラウンドロビン方式ってなんだ？って状態で試験に臨んでも、その概要については問題文に書かれているってケースがほとんどです。
で、僕が今回躓いたのも、知識不足というよりも、<font color="red">問題の内容を理解できていない</font>ことに原因があります。
試験本番まで時間ないけど、数こなせばきっと慣れてくるはず……。
ぼちぼち頑張ります。
VS Code 1.33 の気になった変更点

[Visual Studio Code](https://code.visualstudio.com) の バージョン 1.33（2019年3月分アップデート）がリリースされたので、[リリースノート](https://code.visualstudio.com/updates/v1_33)を眺めてみて気になった変更点をチェックしてみた。(以前のバージョンを眺めてみた時のやつはこちら。[1.32](https://qiita.com/12345/items/80ebfc7a4fb2430430e1) / [1.31](https://qiita.com/12345/items/4ba59be50c6ee9407131) / [1.30](https://qiita.com/12345/items/853b30a4769d76e64d56) / [1.29](https://qiita.com/12345/items/6993dc21f310e1b5dd99) / [1.28](https://qiita.com/12345/items/b53d93fcb225abfc702d) / [1.27](https://qiita.com/12345/items/6a3967dd424b2be57104) / [1.26](https://qiita.com/12345/items/8ce4b6e045d50a6049ce) / [1.25](https://qiita.com/12345/items/e7b5b9954f5d721be2c8) / [1.24](https://qiita.com/12345/items/935770c6a3515ca80472) / [1.23](https://qiita.com/12345/items/627298550aab19f1d8a6) / [1.22](https://qiita.com/12345/items/8253a1eee38b6741905e) / [1.21](https://qiita.com/12345/items/71ce73c52cf2232fc10c) / [1.20](https://qiita.com/12345/items/1390c7cab11d968e7691) / [1.19](https://qiita.com/12345/items/a331c014a9d3fa9dac0e) / [1.18](https://qiita.com/12345/items/9b827138b5044ca82482) / [1.17](http://qiita.com/12345/items/28d83361341ce3ff3c9c) / [1.16](http://qiita.com/12345/items/5215293977dde2149c0f) / [1.15](http://qiita.com/12345/items/cebf4b4e9bfb2d2ef771))

# 「表示言語を構成する」コマンドの改善
https://code.visualstudio.com/updates/v1_33#_easier-display-language-configuration

コマンド`表示言語を構成する`は、以前は単に設定ファイル（locale.json）を開くことしかやってくれなかったが、今回からインストール済みの言語の一覧が表示されるようになり、そこから言語を選んで変更できるようになった。
また、一覧の一番下にある`追加言語のインストール`を選ぶと機能拡張のランゲージパックの一覧が表示される。
![configure_lang.png](https://qiita-image-store.s3.amazonaws.com/0/181011/62472436-735c-bc20-1a91-30a849999f64.png)
ただし、言語変更後にVS Codeの再起動が必要なのは変わらず。

# ソース管理ビューの改善
https://code.visualstudio.com/updates/v1_33#_improved-source-control-view

ソース管理ビューを右クリックして表示されるコンテキストメニューで、リポジトリやソース管理プロバイダーの表示/非表示が切り替えられるようになった。
![source_control_view.png](https://qiita-image-store.s3.amazonaws.com/0/181011/6a118964-d098-d7b3-5c4d-a92fa5658940.png)
また、ソース管理プロバイダー欄に表示するリポジトリの数を指定できるようになった。設定`Scm > Providers: Visible`で数を指定する。0を指定すると高さを手動で調節できるようになる。
![scm_view.gif](https://qiita-image-store.s3.amazonaws.com/0/181011/59d79ef2-0ea3-714a-ba1b-f2ed272f56e7.gif)

# インテリセンスの設定項目の追加
https://code.visualstudio.com/updates/v1_33#_intellisense-customization

インテリセンス（入力補完）に関する設定項目がいくつか追加された。

### フィルタ設定
設定`Editor > Suggest: Filtered Types`で入力補完のタイプごとにON/OFFを切り替えられるようになった。`false`を設定すると入力補完が無効になる。なおこの設定項目は設定画面では設定はできず、`settings.json`を編集する必要がある。
![intellisense_filter.gif](https://qiita-image-store.s3.amazonaws.com/0/181011/dac5833e-e8fa-cd1e-ff30-65341cac400d.gif)

### リストボックスの高さの設定
設定`Editor > Suggest: Max Visible Suggestions`で入力補完候補のリストボックスの高さを指定できる。1～15の値を指定可能。
![intellisense_visible.gif](https://qiita-image-store.s3.amazonaws.com/0/181011/cf211c29-28d7-d36d-7164-bdd8b7491c58.gif)

### アイコンの表示/非表示
設定`Editor > Suggest: Show Icons`で入力補完のタイプを表すアイコンの表示/非表示を切り替えられる。
![intellisense_icon.gif](https://qiita-image-store.s3.amazonaws.com/0/181011/fd2cfe0c-9a89-1e2a-51e2-fc72aa6e7365.gif)
日本語wordnet の連想辞書のjson化

demo https://codepen.io/gnjo/pen/MReGoB

1: .jsonならば一度読めばキャッシュから読み込める事を利用して連想辞書の高速検索を行う。
2: json化する。大本のデータは以下、タブ区切りで十五万要素ある。4MB程度。
original http://compling.hss.ntu.edu.sg/wnja/jpn/downloads.html

データ形式

```
連想番号-品詞\t単語\t人か物かのグループ
```
例では読み込み専用ファイルと読み出し専用ファイルの連想番号は同じである為、結果、類義語。

```
06510836-n	読み込み専用ファイル	hand
06510836-n	読み出し専用ファイル	hand
```
3: タブ形式は扱いにくい。jsonに変換する。連想番号末尾の品詞も分ける事で高速化する。6MB程度。
https://raw.githubusercontent.com/gnjo/gnjo.github.io/master/wnjpn-ok.tab.json

データ形式

```
[[連想番号,-品詞,単語,人かモノ]]
```

```
[
[06510836,-n,読み込み専用ファイル,hand]
,[06510836,-n,読み出し専用ファイル,hand]
... arrray over the 150,000
]
```

```js
//get json
 (async ()=>{
  const url='https://raw.githubusercontent.com/gnjo/gnjo.github.io/master/wnjpn-ok.tab.json'
  ,ary=await fetch(url).then(d=>d.json() )
  ...
 })();

```

4: 検索は```.filter```等で検索単語で取得できた配列の連想番号を取得して、今度は連想番号でフィルターをかければよい。

```js
//core
function calc(ary,word='',max=5){
 if(word.length===0) return [] 
 return ary.filter(d=> ~d[2].indexOf(word) ).slice(0,max) //search the containts words
  .map(d=>d[0]).map(num=> ary.filter(d=>d[0]===num) ) //search syno...m
  .reduce((a,b)=> a.concat(b) ) //flattan
 ;
}
```


###ライセンス
日本語ワードネット （1.1版）© 2009-2011 NICT, 2012-2015 Francis Bond and 2016-2017 Francis Bond, Takayuki Kuribayashi　 
linked to http://compling.hss.ntu.edu.sg/wnja/index.ja.html

##追記　ウェブワーカー版。選択した用語の連想語をリアルタイムで検索。
https://codepen.io/gnjo/pen/pBbOya?editors=1010
djangoでhtmlに画像を埋め込む


#問題点
現在、Djangoで自己紹介ページを作っています。
そこで躓いた点があります。

```python:index.html
<img src="images/○○○○.jpg" width="100" height="100" >
```
webページ上で、上記のhtmlによって画像を表示しようとしても表示されませんでした。
#解消策
Djangoで画像を表示しようとする際には、以下のように記述する必要がありました。

```python:index.html
{% load static%}  #staticフォルダを読み込む
<img src="{% static "images/○○○○.jpg"%}" width="100" height="100">
```
#まとめ
{% static ""%}で囲むことによって問題が解消しました。
Djangoを使うにあたって、{% static ""%}だけでなく{% url "" %}などのタグがあるようです。
まだDjangoを学び始めて1週間くらいなのでこれから実力をつけていきたいです。
オブジェクト指向で設計する難しさ。

オブジェクト指向にはSOLIDという原則があります。

https://en.wikipedia.org/wiki/SOLID

これを厳密に守れる人は、守ってください。で話は終わります。

僕の場合、守れないことが多いです。情けない。。

守れない主な理由としては
- 時間制約：設計するのに時間がかり、実装スピードが落ちる。
- シンプルにむずい：最初に設計しても、結局後から1, 2回自分でコードを直すことが多い。

です。


つまり、一発でいい設計まで速くたどり着けば解決しますね！！
精進します。


なんでむずいかをちょっと言語化しました。

## むずさの分解
### Single responsibility principle
この原則は「クラスを変更する理由は一つでなければならない。」と訳されるものです。

これが本当にむずいです。
なんでかというと、僕らがコードを追加する理由が複雑だからです。
それはライブラリのせいで複雑な時もあれば、ドメインが複雑な時もあれば
既存コードが~~ゴミ~~複雑な場合もあります。

そのコードを書かなければいけない複雑な理由を
MECEに実装可能レベルまで分解して
クラスに落とし込む必要があります。

難しいでしょう？

ユーザーの入力を受け付けるため。
永続化するため。
ビジネスロジックを計算をするため。
プレビューを表示するため。

といったレベルの分解は容易ですが、
もっと細かく分解する必要があると感じます。

ある計算に必要な情報がバラバラな箇所に存在するから、集めて入力オブジェクトを生成するため。
複数回ユーザー入力を受け付け、その度に変更部分のみを再計算しプレビューに反映させるため。

とかの粒度で理由を理解している時に書くコードは綺麗にかけるような記憶があります。

MECEに分解できない。はまだましです。
僕らはたまに、書く必要のないコードを書いてしまうこともあります。。
僕の場合、このゴミに依存して
綺麗な設計ができていないケースが
1年くらい前までありました。。

### Open–closed principle
この原則は要するに「拡張可能、変更不可能にするべし。」です。
これは慣れれば簡単です。
多くのケースでデザインパターンが役に立つので、
学びましょう。

### その他の原則
その他の原則に関してはまた別で。
個人的にそこまで難しさを感じていないためです。

## 一発でいい設計まで速くたどり着くために

即効薬はないという結論です。。。

- ドメインを深く理解する。
- パターン化をして都度、経験を蓄積する。

### memo

イベントが発生するたびに、ドメイン（もしくはアプリ）の状態がどう変わるかを、
しっかり考えればなんかいける気がするぞ未来の自分へ。
Windows10 上のファイルを WSL を介して SSH サーバに転送する

### Windows → Linux

c は小文字にする。U は大文字。

```text
cp /mnt/c/Users/xxx/file.py file.py

cp -r /mnt/c/Users/xxx/aaa aaa
```

Windows 上の

```text
C:\
```

は、Linux 側で

```text
/mnt/c/
```

となる。

### SSH クライアント → SSH サーバ

```text
scp file.py pi@192.168.x.x:/home/pi/xxx/file.py 
```

パスワードを入力する。
Watendly経由の面接で得た未経験が知っておくべきこと

## はじめに
どうも、ねこきち（@nekokichi_yos2）です。

3月からWatendlyを中心に就職活動をしています。

といっても、ど素人がいきなりベンチャーに入れるわけないので、話を聞きにいってるだけですが..。

僕のような臆病で根性なしの未経験者でも気軽に面接までこぎつけるので、”応募はしないけど現役やプロの話を聞きたい”方にはWatendlyは就活におすすめです。

**今回は、3月の中旬から色々なベンチャーと話を聞いた中で、数々のベンチャーから色々な話を聞けたので共有しようかなと。**
（まだ4社だけど）

ネットやスクールの情報だけじゃ得られない情報ばかりだったので、これから働く未経験の方に役立てていただけたら幸いです。

※注意

ただし、関西で聞いた話なので、東京でも同じ事情かは保証しません。

あくまで一般的な意見としてお読みください。

## 業界編
### ベンチャーは中途組が多い
即戦力が好まれますので、ベテランやプロが多く在籍してます。

特に、
- 人を教育するリソースが足りてない
- そもそもそんなことをする暇がない
という事情が多いです。

もちろん大卒で入社する人も確実にいますが、**大多数は転職/中途組が多い印象です。**

### BtoBはセキュリティに厳しい
受託開発、特にITリテラシーがない顧客とのB to B形態の場合、セキュリティには敏感です。

トラブルや万が一のケースが起きないように、参画メンバーらが事前に知っておくこともあるんだとか。

### １つの技術だけでは生きていけない
”エンジニアは移り変わりが激しい”とよく言われますが、ベンチャーや異なる現場では使う言語や技術が様々なので、１つだけで食っていくのは難しいです。

例えば、HTML/CSSやJavaScriptの言語に加え、
- ライブラリ、フレームワーク
- プログラミング全般の教養
- データベース
- セキュリティ
などが求められます。

**振られる仕事によってはその都度学ばなければならず、ずっと同じ技術"だけ"でやっていくのは無理です。**

### 使える領域が広ければいい
逆に、使える技術が多ければ多いほど、対応できる仕事も多くなります。

ですから、何か１つ突出したスキルを身につけて、他に移るを繰り返した方がいいかと。

## 採用編
### 何か１つでも得意分野を持て

### GitHubはパッと見で判断される
まず、GitHubのどこを見られるかというと、
- star
- fork
- commit
- issue
- pull request
- prefix
などです。

**いきなり、リポジトリに上がっているコードを見ることはありません。**

コードの細かいところまで見られるのは、パッと見の後です。

しかし、starやforkがなくても、
- **継続的に取り組んでいるか**
- **コミットやプルリクの内容**
でアピールポイントを稼ぐのもアリです。

### １つのアプリ/サービスの運用経験は+
**ただ作るよりもリリース、リリースよりも運用。**

実際の現場では1度作った製品やプログラムを長期的に管理するので、
- 改善点
- 反応率
を得て、修正やら追加を行うそうです。

ですから、1年ぐらいの運用歴があるとGood。

## 技術編
### RDB
Webアプリを開発する企業の場合、ほとんどがPHPでサーバーサイドを実装してると言ってました。

また、FirebaseのRealtime Database, Cloud FirestoreやAWSのAmazon DynamoDB等のNoSQLデータベースはベンチャーでも使われてますが、基本はRDBを中心に扱う企業が多いかなと。
### API
サーバーとの連携に必要。

### ターミナル
コマンドラインでの操作は、
- **ファイル移動**
- **ライブラリ/フレームワークの導入**
に必要みたいです。

データベースやLinuxではよく使われてますし、業界の必須スキルじゃないかと。

### Git/GitHub
**エンジニアに就くなら"当たり前"のスキルです。**

どの企業に行っても、必要だと言われました。

### Rx系ライブラリ
**業務では必ず使われるんだそうです。**

RxSwiftやRxJavaとか、Rx系は様々。

理由は、通信処理を全て非同期で実装できる便利なものだから、と言ってました。

### アーキテクチャ
MVC、MVVM。

プログラム設計の際、効率的で合理的なコードを書くための設計思想？

### コード周り
コードに関して求められるのは、
- **コードを読む力**
- **１つ１つのコードに意味があるか**
- **テキトーで意味ないコードは書くな**
です。

納期がある分、全体がスムーズに共有できるようなコードを書くことが求められます。

下記がエンジニア必読と言われるのも、あらゆる開発において役に立つからだと思います。
↓
- [リーダブルコード](https://www.amazon.co.jp/%E3%83%AA%E3%83%BC%E3%83%80%E3%83%96%E3%83%AB%E3%82%B3%E3%83%BC%E3%83%89-%E2%80%95%E3%82%88%E3%82%8A%E8%89%AF%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E6%9B%B8%E3%81%8F%E3%81%9F%E3%82%81%E3%81%AE%E3%82%B7%E3%83%B3%E3%83%97%E3%83%AB%E3%81%A7%E5%AE%9F%E8%B7%B5%E7%9A%84%E3%81%AA%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF-Theory-practice-Boswell/dp/4873115655)
- [リファクタリング](https://www.google.com/aclk?sa=L&ai=DChcSEwig_9efkLvhAhWXdmAKHQVlBFkYABADGgJ0bQ&sig=AOD64_0SGQ6FpAWuIszGJloX0klLDZ2dHA&ctype=5&q=&ved=0ahUKEwiV6NOfkLvhAhXJIqYKHc23A3wQwzwICA&adurl=)

冗長で意味不なコードを書かぬためにも、入社前に上記のような技術書を読んでおくといいでしょう。

## おわりに
Watendlyで就活する前は、
- ポートフォリオさえあればいい
- 基礎レベルの知識さえあればいい
- どうせ入社後に教えてくれるでしょ
みたいな感覚でした。

ですが、最初に言ったようにベンチャーにはベテランが多い上、優しく教えてくれるような生易しいところではないようです。

このように、生の声とネットの情報とでは全く違うので、とにかく会いに行って話を聞きにいきましょう。

そうすれば、
- 何を学んでおくといいか
- どういうポートフォリオがいいのか
など、今後のエンジニア人生を形成しやすくなりますので。
Ubuntuでtmux 2.8に文字幅修正のパッチあててビルドして、ホームディレクトリ配下にインストールする

## 概要

Unicodeにおいて、文字幅が『曖昧』と定められている文字が結構あります。あるらしいです。文脈や環境によって半角として扱われたり全角として扱われたりするためにそう定められているらしいんですけど。

それはそうだとしても半角なのか全角なのかどっちかにしないと表示上困るわけですが、ターミナルエミュレータによってはこれをオプションで切り替えられるものがあります。

わたくし普段macOS上でiTerm2を使用していまして、以前はとある理由からこれを半角に設定していたのですが、最近全角に切り替えました。（Preferences -> Profiles -> Text -> Unicode -> "Ambiguous characters are double-width"のチェックボックスで切り替えが可能）

そうしたところ、tmuxで複数のペインを表示させた場合のボーダーを描画している文字がちょうど曖昧幅だったらしく、表示が崩れるようになってしまいました。これは困る。

iTerm2側の設定は現状のまま全角とみなすようにしておきたかったので、tmux側をどうにかして回避できないかとググったところ、ありがたいことに[曖昧幅の文字に関連する修正を統合したパッチが公開されている](https://github.com/z80oolong/tmux-eaw-fix)のを発見。導入してみたところまさに求めていたものが得られました、どうもありがとうございます。

というわけで備忘として導入手順を記載しておきます。

## 前提

[以前書いたtmuxソースコンパイルについての別の記事](https://qiita.com/ha4gu/items/aebe9207904f52ee4fb6)ではインストール先を`/usr/local`にしていたのですが、今回は影響範囲を自ユーザだけに留めるという目的でインストール先を`$HOME/.local`に変えてます。作業ディレクトリも`$HOME/.local/src`です。そんな変なところに入れる必要ないんだけど、という人は`--prefix=/usr/local`とかしておけば良いのではないでしょうか。

本手順はUbuntu 18.04上で確認しています。

## 手順

必須パッケージのインストール

```shell
sudo apt update
sudo apt install git automake bison build-essential pkg-config libevent-dev libncurses5-dev
```

PATH環境変数の追加（`.bashrc`などに追記して読み込んで有効化しておく）

```shell
export PATH="$HOME/.local/bin:$PATH"
export MANPATH="$HOME/.local/share/man:$MANPATH"
```

ソースコードのダウンロード
※ここでは例として`tmux 2.9a`をインストールします

```shell
mkdir -p ~/.local/src/ # 作業用ディレクトリが存在していない場合には実行
cd ~/.local/src/
git clone https://github.com/z80oolong/tmux-eaw-fix.git
git clone -b 2.9a --depth 1 https://github.com/tmux/tmux
```

パッチの適用とビルド

```shell
cd tmux/
patch -p1 < ../tmux-eaw-fix/tmux-2.9a-fix.diff
./autogen.sh
./configure --prefix=$HOME/.local
make
```

インストールと確認

```shell
make install
which tmux  # $HOME/.local/bin/tmux なのを確認する
tmux -V     # tmux 2.9a なのを確認する
man -w tmux # $HOME/.local/share/man/man1/tmux.1 なのを確認する
```
Laravelインストールの流れ(Mac)

Laravelを導入して開発を行うことになったので、せっかくのこの機会にLaravel導入の流れを簡単に紹介しておきます。

# Laravelインストールまでの簡単な流れ
1. composerをインストール。
(https://qiita.com/Naoki206/items/8a93c6788eb10d53e7dd)
2. composerを使ってLaravelをインストール。

# composerとは？
wikiさんによると、
PHPプログラミング言語向けのソフトウェアおよび必要なライブラリの依存関係を管理する標準形式を提供するアプリケーションレベルのパッケージ管理システム

らしいですが、まあ難しいのでわかりやすく説明すると。

例えば、あなたが開発しているプロジェクトがあるとします。

そのプロジェクトにはAというパッケージが必要で、そのAには、Bというライブラリ、またBにはCというライブラリが必要になるとします、

このような状態はライブラリ(パッケージ)が、他のライブラリに依存しているといえ、その際に、このライブラリ(パッケージ)達のひとつひとつの依存関係を自力で埋めていくのは大変です。

composerはこんな時、プロジェクトAをインストールするだけでAが必要とするライブラリ(パッケージ)を自動的に全てインストールしてくれるという優れものです。

今回はこのcomposerを使ってLaravelをインストールしていきたいと思います。

#composerをインストール
まずコマンドで、下記のコードを実行し、composerをインストールします。

```ruby:コマンド
curl -sS https://getcomposer.org/installer | php
```
次に、composerがどの位置からも呼び出せるように、composerの位置を下記のコードを実行し、移動させます。

```ruby:コマンド
mv composer.phar /usr/local/bin/composer
```

```
composer -v
```

上記のコマンドを実行し、以下のようなアスキーアートが表示されると無事インストールが完了していることを確認できます。

```
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 1.0-dev
```


#Laravelをインストール
プロジェクトを生成したいディレクトリ下に移動し、
先程インストールしたcomposerを使って、以下のコードを実行することでLaravelをインストールします。(プロジェクト名の部分に任意の名前を入力)

```ruby:プロジェクトを生成したいディレクトリ下
composer create-project laravel/laravel プロジェクト名
```
尚、バージョンを指定したい場合は、下記のようにコードを実行。
("バージョンナンバー"の部分に指定したいバージョンの番号を入力)

```ruby:プロジェクトを生成したいディレクトリ下
composer create-project "laravel/laravel=5.5.*" プロジェクト名
```

*このインストールには5分ほど時間がかかります。


##ローカル環境のブラウザで表示
ローカル環境のブラウザに表示する場合、まず以下のコードを実行し、サーバーを起動させる必要があります。

```ruby:laravelプロジェクト直下
php -S localhost:8000 -t public
```
そして、ブラウザを起動し、[localhost:8000](http://localhost:8000)にアクセスします。

ブラウザ上に大きく『Laravel』の文字が表示されると無事インストールが完了できているのを確認できます。

##VPSサーバーから表示(パーミションの変更)
VPSなどの本番環境から表示させる場合は、パーミッションの設定をしないといけません。

以下のコードを実行し、２つファイルをSSHやFTPソフトなどでそれぞれ”読み込み・書き込み”ができるように設定しましょう。

```ruby:作成したlaravelディレクトリの直下
# storageのパーミッションを変更
chmod -R 777 storage

# bootstrap/cacheのパーミッションを変更
chmod -R 777 bootstrap/cache
```

そして、以下のURLをブラウザに貼り付ける

```
http:// ホスト名/プロジェクト名/public
```

こちらもブラウザ上に大きく『Laravel』の文字が表示されると無事インストールが完了しているのを確認できます。
Tkinterメッセージボックス利用時の空ウィンドウ削除方法

Pythonでメッセージボックスを出力する方法として、「tkinter」の「messagebox」を利用する方法がある。

例えば、

``` python
from tkinter import messagebox

messagebox.showerror("error", "can not execute process")

```
と書くと、

![image.png](https://qiita-image-store.s3.amazonaws.com/0/389843/329d2d32-bafa-8568-d78f-29524deae0ca.png)

と出力される。
ただ、実はこれとは別に下図のような謎のウィンドウがもう1つ出力される。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/389843/7c6646e9-cc99-8122-0c93-6ed14b8af3cd.png)

これでは見栄えが良くない。

# 対策

下記のように、Tkinterのルートウィンドウを作成して非表示にしてしまう。

``` python
import tkinter as tk
root = tk.Tk()
root.withdraw()

```
どうやら、Tkinterはルートウィンドウを持たなければならず、ルートウィンドウがない場合、勝手に作成するらしい。
（他にいい方法があれば教えてください。）

# 参照
> https://codeday.me/jp/qa/20190225/299233.html
APIGateway + Lambdaでbase64変換された画像ファイルをS３に保存する


## やろうとしていること。

1. API Gateway を使って POST リクエストを受け付けるエンドポイントを作成する。
1. POST リクエストのボディには PNG 画像が base64 エンコードされた文字列が含まれる。
1. 投げられたリクエストは lambda で処理される。
   - PNG 画像の base64 文字列は binary に変換
   - `{自動作成したUUID}.png`という名前で s3 に保存

## 作業

### s3 バケットを作成する。

- aws のコンソール上からサービス-> s3 を選択
- 適当な名前でバケットを作成する。
- 今回は権限変更の必要なし。（バケットの内容を外部公開したいなら必要）
- 作成した`バケットの名前`は覚えておく。

### lambda でリクエストボディに入力された関数を作成する。

- aws のコンソールの上からサービス-> Lambda を選択 -`関数の作成`ボタンから関数を作成する。
- 下記内容を入力する。
  - 関数名 -> 適当
  - ランタイム -> python3.7
  - 実行ロール -> 基本的な Lambda アクセス権限で新しいロールを作成（あとで s3 にファイルをアップロードできるように権限の変更必要）
- 関数の作成をクリック
- ダッシュボードから自分が作成した関数名の関数を選択する。
- 実行ロール項目に現在設定されているロール名が表示されているので`IAM コンソールで {自分が作成したロール名} ロールを表示します。`をクリック
- IAM のコンソールに移動するので`ポリシーをアタッチします`をクリック
- `AmazonS3FullAccess`を選択してポリシーのアタッチをクリック
- 関数コードのに下記のようなコードを書く

```python

import boto3
import base64
import uuid

def convert_b64_string_to_bynary(s):
    """base64をデコードする"""
    return base64.b64decode(s.encode("UTF-8"))

def lambda_handler(event, context):
    # requestbodeyの中のjsonはeventに辞書型に変化されて保存されている
    # なので、eventの中には {"mypng": "base64でエンコードされた文字列"}が入力される想定。
    base_64ed_image = event['mypng']
    # バケット作成を作成してbynary変換して保存する。
    s3 = boto3.resource('s3')
    bucket = s3.Bucket('<s3でバケットを作成したときにつけたファイル名>')
    bucket.put_object(
                    Key=f'{uuid.uuid4()}.png',
                    Body=convert_b64_string_to_bynary(base_64ed_image),
                    ContentType='image/png')
    # とりあえずOKを返す。
    return {'statusCode': 200}

```

- 右上の保存ボタンを押す。

### API エンドポイントを作成する。

- aws のコンソールの上からサービス-> API gateway を選択
- `APIの作成`ボタンからAPIを作成する。
- 適当な API 名をつけて、あとはそのままで API の作成ボタンを押す。
- 自分が作成した API を選択し、`アクション`ボタンからメソッドの作成を選択し、POST メソッドを追加
  - 統合タイプ -> Lambda 関数
  - Lambda 関数 -> 先ほど作成した関数の関数名を入力
- 保存する。

### API のテスト

- 先の手順で作成したメソッドを選択するとテストボタンがあるのでリクエストボディに値を入力してテストしてみる

```json
{
  "mypng": "<base64エンコードされた文字列>"
}
```

- png ファイルを base64 に変換する python スクリプトは下記の通り

```python
# これでファイルを文字列で読み取れるのでテキストに書き込むなり標準入力に出力するなりする。
def convert_file_to_b64_string(file_path):
    """ファイルをbase64にエンコードする"""
    with open(file_path, "rb") as f:
        return base64.b64encode(f.read()).decode("UTF-8")
```

### API のデプロイ（外部公開）

- aws のコンソールの上からサービス-> API gateway を選択
- 作成したAPIを選択
- `アクション`ボタンからAPIのデプロイを選択
   - デプロイされるステージ -> 新しいステージ
   - ステージ名 -> 任意のアルファベットとハイフンの組み合わせ
- デプロイボランを押す。
- コンソールに表示されたURLにデプロイ（外部公開）されている。
[mac]brew install python3 実行時に brewがコケて死んだ時の対処法

`$ brew install python3` でpython3をインストールしようとしただけなのに、
brewがコケて死んだ時の対処法。

調べればすぐに出てきますが、一応こういうこともあるんだなー程度にめも。

以下のようなエラーで死にます。

```
Error: An unexpected error occurred during the `brew link` step
The formula built, but is not symlinked into /usr/local
Permission denied @ dir_s_mkdir - /usr/local/Frameworks
Error: Permission denied @ dir_s_mkdir - /usr/local/Frameworks
```

brew link ステップでコケたのも権限が足りないのもわかる。で、どうするんだと…
下記リンクを参考にして対処しました！

https://qiita.com/yshishido/items/0cd7ce9346e67a8908ed

やることとしては以下の通り



##1. $ brew doctor

`$ brew doctor`と打つだけで解決策を表示してくれるらしい！簡単！

```
$ brew doctor
...
You should create these directories and change their ownership to your account.
  sudo mkdir -p /usr/local/sbin
  sudo chown -R $(whoami) /usr/local/sbin
...
```

ん？エラーで出てたディレクトリと違う…？けどまあ実行。

## 2. シンボリックリンクを再作成!

```
$ brew link python
Linking /usr/local/Cellar/python/3.7.3... Error: Permission denied @ dir_s_mkdir - /usr/local/Frameworks
```

エラー！
もしかしてさっきの関係なかった？

こっちも作成する

```
$ sudo mkdir -p /usr/local/Frameworks
$ sudo chown -R $(whoami) /usr/local/Frameworks
```

再度チャレンジ

```
$ brew link python
Linking /usr/local/Cellar/python/3.7.3... 1 symlinks created
```

できた！
Vueを利用してポートフォリオを作成してみる(2/3)

Vueを利用してポートフォリオを作成してみる(１/3)の続きです。
https://qiita.com/mf37459/items/fcf1e9167c62e39843d1

Vue.cliを利用して開発環境を設定するまでは、問題なく行うことができました。
次に作成されたフォルダ構成を使ってどのようにサイトを作成していくかで悩んだので備忘録。
(今回作成するポートフォリオはページ遷移のないものとします)

#$Vue create [ディレクトリ名]で作成されるもの

以下のようなディレクトリが作成されました。

```bash
 - test
 　├ babel.config.js
 　├ node_modules
 　　∟ (...)
 　├ package.json
 　├ public
 　　∟ (...)
 　├ README.md
 　├ src
 　∟ yarn.lock
 ```
[各生成物のイメージは以下の通りです]
[babel.config.js]は新しいjavascript記法を古いjavascriptに変換するためのルールを記載したもの。
[node_modules]は使用するライブラリが色々入っている。
[package.json]はアプリ名やどのライブラリのどのバージョンをインストールしたかが記載されている。
[public]は、静的ファイルが置かれます。meta要素やfaviconの設定などはここで行なっているようです。
[README.md]は使い方とかの説明、元から各コマンドが記載されているし、自分で追記しても良い。
[yarn.lock]は各ライブラリのバージョンを固定する
[src]は、開発用ディレクトリでbuild前のソース群です。ページの内容をいじる際はこの中身をいじります。

というわけで内容をいじる際に必要なのは src となっています。今回のポートフォリオでは、srcの中身以外は触りませんでした。

#srcディレクトリの中身
前記事の設定通りに作成した場合のディレクトリ構造は以下の通りです。

```bash

 - src
 　├ App.vue
 　├ assets
   　∟ logo.png
 　├ components
   　∟ HelloWorld.vue
 　∟ main.js
 ```
[各生成物のイメージは以下の通りです]
[App.vue]はVue単一コンポーネントファイル。どのコンポーネントをどの順番で表示するかが書かれている。Vue.Routerを使用するとページごとでどのコンポーネントを表示するか切り替えることができると思われますが、今回は１ページのみなので、ここを見ればどのコンポーネントをどの順番で使用しているのかがわかります。
[assets]はコンポーネントで呼び出す画像などを配置します。元から入っているlogo.pngはvueのロゴ画像です。
[components]は各コンポーネントが配置されています。コンポーネントは各UIを分割したものというイメージです。WEBサイトはこのコンポーネントの集合で作成されています。HelloWorld.vueはサンプルの文字部分が記載されており、App.vueでimport、表示されています。
[main.js]はアプリケーションの最初に読み込まれ実行されるjavascriptです。new VueによってApp.vueを起動しているようです。

#中身をいじってみる
conponentsフォルダの中に新しく、TheBodyとTheHeaderというファイルを作成します。

```bash
 - src
 　├ App.vue
 　├ assets
   　∟ logo.png
 　├ components
    ├ TheBody.vue (*new)
    ├ TheHeader.vue (*new)
   　∟ HelloWorld.vue
 　∟ main.js

```

新たに配置した各ファイルは、パッと見てわかりやすいように以下の内容とします。

```vuejs:TheHeader.vue
<template>
  <div>
    <h1>this is HEADER</h1>
  </div>
</template>

<style scoped lang="scss">
div {
  border: 5px solid #42b983;
  border-radius: 5px;
  height: 10vh;
  margin-bottom: 10px;
  width: 80%;
}
</style>
```

```vuejs:TheBody.vue
<template>
  <div>
    <h1>this is Body</h1>
  </div>
</template>

<style scoped lang="scss">
div {
  border: 5px solid #42b983;
  border-radius: 5px;
  height: 80vh;
  width: 80%;
}
</style>

```

*cssでdivがかぶっていますが、styleの部分でscopedを設定しているので問題ないです。
*templateの直下には１要素しか置くことができません。下のように２要素置くとエラーとなります。
>
＜template＞
　　＜div＞...＜/div＞
　　＜div＞...＜/div＞
＜/template＞

次にこのコンポーネントをApp.vueに配置します。

```vuejs:App.vue
<template>
  <div id="app">
    <TheHeader/> // (*new)
    <TheBody/> // (*new)
  </div>
</template>

<script>
import TheBody from './components/TheBody.vue' // (*new)
import TheHeader from './components/TheHeader.vue'// (*new)

export default {
  name: 'app',
  components: {
    TheBody,// (*new)
    TheHeader// (*new)
  }
}
</script>

<style lang="scss">
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}
</style>

```

以上を行うと、下のような表示になります。

<img width="1454" alt="スクリーンショット 2019-04-06 17.52.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/205283/329cd49d-bcbb-3e79-e324-3537d358055d.png">
Office365のゲストユーザー（外部ユーザー）の一覧を取得する

外部ユーザーをテナントに招待するといろいろ便利なんだけど、ゲストユーザーも数十を超えると管理がつらくなってくる。定期的に一覧取得して、不要なアカウントを削除する方法を考えておく。

とりあえず、今回は一覧を取得する。


#　ゲストユーザー一覧を取得する

こんな記事があったので、倣ってみた。
[Powershell – Useful Azure AD queries using the AzureAD Module](https://blogs.technet.microsoft.com/chadcox/2017/06/30/powershell-useful-azure-ad-queries-using-the-azuread-module/)

    Conect-AzureAD
    $_default_log = $env:userprofile + '\Documents\azuread_guest_accounts.csv'
    
    Get-AzureADUser -Filter "userType eq 'Guest'" -All $true | select DisplayName,UserPrincipalName,Mail,RefreshTokensValidFromDateTime,AccountEnabled | export-csv $_default_log -NoTypeInformation


ドキュメントフォルダの直下に、csvファイルでエクスポート。
ゲストユーザーの表示名、UPN(ゲストユーザーお約束、#EXT#@<tenant名>.onmicrosoft.com）、メールアドレス（こっちは一般的なメールアドレス）、有効になった日時、テナントにアクセス可能か、を一覧にしてくれている。

#　属性取得する


    Connect-AzureAD
    Get-AzureADUser -UserPrincipalName <UPN> | Select-Object *

ゲストユーザーを取得するときは、さっきの#EXT#@を含むほうで実施する。


    Connect-msolService
    Get-MsolUser -UserPrincipalName <UPN> | Select-Object *

上記でも同じように取得できる。（一部内容が違う）

# ゲストユーザーを削除する。

    Connect-AzureAD
    Remove-AzureADUser -ObjectID <Account>
アカウントには、ゲストユーザーのUPN（さっきの#EXT#@のやつ）で行う。


# 課題いくつか

### 課題1.最終ログインを取得したい

LastLogonを取得したい。社内のアカウント以上に、能動的に消さないと残ってしまいがち。
GUIならできるんだけどね・・・。

### 課題2.外部のAzureADユーザーか、MSアカウントユーザーか取得する

GUIならできるんだけどね・・・。

### 課題3.自動削除

最終的には、週次バッチとかで、最終ログインが30日以上前のゲストユーザーは自動削除、とかできたら管理ラクになりそう。
AsyncStorageをdebugする一番簡単な方法

![alt](https://user-images.githubusercontent.com/26253721/39765058-e8d0eae4-531b-11e8-9305-4c852f269517.png)
react nativeで、AsyncStorageをデバッグする時、どうやってますか？
私は、まず以下のようなファイルを作成してから、


```js
// AsyncStorageDebug.js
import { AsyncStorage } from 'react-native'

export const AsyncStorageDebug = () =>
  AsyncStorage.getAllKeys((err, keys) =>
    AsyncStorage.multiGet(keys, (error, stores) => {
      window.asdebug = stores
      window.astable = () => console.table(stores)
      window.asclear = () => AsyncStorage.clear()
    })
  )
```

App.jsで、

```js
// App.js
import { AsyncStorageDebug } from './AsyncStorageDebug'
if (__DEV__) AsyncStorageDebug()
```
と記述しています。

後は、start remote debug
してから、
f12を押し、chromeのconsoleを開いた後、
asdebug
または、
astable()
と打つと、AsyncStorageの中身を表示出来ます。
asclear()
と打つと、AsyncStorageの中身を全て削除します。

asdebugは、通常のconsole.logの形で表示し、
astable()は、表の形で表示します。

## 注意
現在chrome のコンソールで、environmentが正しく選択されないバグが発生しているので、
topではなく、debuggerWorker.jsを選択するとasyncStorageがデバッグ出来るようになります。
<img width="1054" alt="スクリーンショット 2019-04-08 13.53.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/183835/33c91d4c-ec45-02b5-8467-49676abe1297.png">
Node.js Expressフレームワークの「ポート指定部分」に注力してみた

Node.jsでExpressフレームワークを使用した時に出てくる、ポート設定部分の説明です。
記述を上から説明すると、**ポートを指定**してあげて、**そこをlisten**してくれるように指定しているだけです。

```js
const port = process.env.PORT || 3000;
app.listen(port, () => {
  console.log(`listening on ${port}`);
});
```

Expressアプリの設定は環境変数で行うことが多いようなので
webサーバーに対してどのポートがlistenしているか教えるために環境変数にPORT設定してあげるのがお作法らしいです。なので、**なんでも良いから環境変数(process.env.PORT)でイケるところか、PORT3000で設定させてよ**ってニュアンスだと理解。


```js
const port = process.env.PORT || 3000;
```
**app.listen**か**app.set('port', ...)**で任意のサーバーが環境から特定のパラメーターを指定したPORTから受け取れるようにしてあげる。
[What is process.env.PORT in Node.js?](https://stackoverflow.com/questions/18864677/what-is-process-env-port-in-node-js)

```js
app.listen(port, () => {
  console.log(`listening on ${port}`);
});
```



# process.envとは?
Node.jsにおける環境変数は、process.envというオブジェクトに格納されます。
このオブジェクトは最初から存在しており、いくつかの環境変数が入っています。
コマンドラインで確認できるよ。

```console
$ node
> process.env
```
 **app.set('port', process.env.PORT || 3000)**と**app.listen(3000);**の違いは
多くの環境（例えばHeroku）では、規約として、環境変数PORTを設定して、Webサーバーにどのポートをlistenするかを指示できます。

だからprocess.env.port || 3000は、環境変数PORTにあるものは何でも、存在しない場合は3000を意味します。

つまり、app.listen、またはapp.set（ ‘port’、…）に渡します。これにより、サーバーは環境から、どのポートをリッスンするかをパラメータとして受け入れることができます。

app.listen（）にハードコードされた3000を渡すと、あなたの要件や、あなたが実行している環境の要件に応じて、ポート3000でリッスンします。
mui Developer EditionでSORACOMを使ってみる

#この記事について
muiを入手したので、その開発情報を自分用にまとめたものです。

[mui Developer Editionで遊んでみる（準備編）](https://qiita.com/kobayuta/items/9a78b923648a2478604d)
[mui Developer Editionで遊んでみる（HOME画面のカスタマイズ）](https://qiita.com/kobayuta/items/76cd0d2483e42ae6e34d)
[mui Developer EditionでSORACOMを使ってみる](https://qiita.com/kobayuta/items/b8b15639be6c866641e1)


# muiでSORACOMを使う
muiはネットワークに接続されてなんぼのデバイスです。家の中ではWiFiでOKなのですが、デモなどで外に出た時に無線LAN環境があるとは限りません。そこで、SORACOMさんで購入できるエイビット社製USB通信モデムAK-020とSORACOM SIMで通信できるか試してみました。

## 準備するもの
・USB通信モデム
・SORACOM SIM

## 使えるようにする手順
https://dev.soracom.io/jp/start/device_setting/ にある「Raspberry Pi+USBモデム」の手順に従い、設定する。

以上。

これでWiFiがない環境でも使えるようになりました。
しかし、SORACOMさん親切すぎる。。。
Carthageをビルドして利用する

[Carthage](https://github.com/Carthage/Carthage) は主に [Homebrew](https://brew.sh/index_ja) でインストールすることが多いと思いますが、Homebrew で最新バージョンを使用できるまでにタイムラグあったり、特定のバージョンの Carthage を使用しなければならない場合に困ってしまいます。そんな時のために、Carthage を自分でビルドして利用する方法を紹介します。

### Carthage のインストール方法

インストール方法は、Carthage の GitHub リポジトリの README に [Installing Carthage](https://github.com/Carthage/Carthage#installing-carthage) という項目に下記４通りの方法が書かれています。

- Installer
- Homebrew
- MacPorts
- From source

この最後の **From source** が自分でビルドしてインストールする方法で、下記の通りです。

1. Carthage リポジトリをクローンする
2. `make install` を実行する
3. `/usr/local/bin` にインストールされる

簡単ですね。Carthage は Swift で実装されているため、Xcode がインストールされていればビルドすることができます。ただし現時点 (ver. 0.33.0) では Xcode 9.4 以降が必要です。

### 単純に Carthage バイナリをビルドする

上記のインストール方法にあるとおり、Carthage には Makefile が含まれており、その中に単純にバイナリをビルドするだけのターゲットも見つかります。ちょうど４月初にリリースされた ver. 0.33.0 からターゲットが変わっていますが、下記のとおりビルドすることができます。

- Carthage 0.33.0 以降は `make installables` を実行する
- Carthage 0.33.0 未満は `make swiftpm` を実行する (少なくとも 0.30.0 以降はこれでビルドできるはず)
- `.build` ディレクトリにビルドされた carthage バイナリができる

Carthage リポジトリから特定のバージョンのタグをチェックアウトすることで、特定のバージョンのバイナリをビルドして利用することができます。