OmniAICreator/Qiita-1.07M huggingface dataset:
micro:bitでエスパードミノを作る

アドベントカレンダーのために何か作ろうかなーと考えていて，複数台での無線通信使いたいなーと思っていたころ，数年前にSONYのMESHを使った作品を思い出した．

[エスパードミノ](https://vimeo.com/17150420)
これは2010年に制作された作品で，[情報処理学会エンターテイメントコンピューティング2010](http://ec2010.entcomp.org/)でのデモンストレーションや[文化庁メディア芸術際2014](http://archive.j-mediaarts.jp/festival/2010/entertainment/works/14ej_Esper_Domino/)などで数多くの賞を受賞した作品です．

簡単に説明すると，MESHのドミノを倒すと離れているもう1つのドミノが連鎖して倒れるといった作品です．
今回はこれをmicro:bitで作りたいと思います．

## 内容
## 準備するもの  
- [micro:bit](http://akizukidenshi.com/catalog/g/gM-12513/) × 2
- [サーボモーター](http://akizukidenshi.com/catalog/g/gM-08761/)  
- [コネクターブレイクアウトボード](http://akizukidenshi.com/catalog/g/gP-12836/)

## ハードウェア
![スクリーンショット 2019-11-28 18.48.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191122/97bae9ba-d916-2a66-4774-466799894eb1.png)
配線はこんな感じですね．ブレイクアウトボードを使うとジャンプワイヤーを使って簡単に配線できます．

もう一個のmicro:bitは特に配線はしないです．強いてゆうなら電源も無線化したいので，[パワーボード](http://akizukidenshi.com/catalog/g/gM-12832/)などがあるといいでしょう．
### 倒す仕組み
サーボを使って倒すのですが，まずはmicro:bitを立たせる必要があります．
ここはみなさん試行錯誤してもらっていいと思います．自分は3Dプリンターで適当な外装とサーボの腕を伸ばす部品を作りました．
<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191122/095f6df6-1d4f-5b36-8ae8-d7ac679d495f.jpeg" width="200"> <img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191122/df1facd7-6557-efcd-b3dd-b99c0f856e73.jpeg" width="200"> <img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191122/9703956b-1d6e-b881-4aee-82093470a4df.jpeg" width="200">


## ソフトウェア
### 送信側(倒す側)
![スクリーンショット 2019-11-28 19.14.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191122/0df99835-772b-76dd-d299-1d191b3ad8ae.png)


### 受信側(倒される側)
![スクリーンショット 2019-11-28 19.14.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191122/40a0db28-e073-3fb2-ed97-515ecbbb73f6.png)

## 完成
こんな感じになりました．
<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191122/71be010f-ac1b-b8f4-1e33-f77c96d00888.gif" width="500">

見た目はあれですが，やりたかったことは出来ました．次回は複数台でやってみたいですね．
kubectlのインストール及びセットアップ(翻訳)

出典：https://kubernetes.io/docs/tasks/tools/install-kubectl/

# kubectlの概要
Kubernetes のコマンドラインツールで、Kubernetes 上のアプリケーションの管理、デプロイなどを行うものです。
kubectlを使用すると、クラスタリソースの検査に始まり、コンポーネントの作成、削除、更新を行うことができます。あなたの新しいクラスタで、サンプルアプリケーションを立ち上げてください。

## 始める前に
クラスタのバージョンと前後1バージョンのkubectlバージョンを使用する必要があります。たとえば、v1.2クライアントは、v1.1、v1.2、v1.3のマスターで動かす必要があります。 kubectlの最新バージョンを使用すると、予期しない問題を回避できます。

## kubectlのインストール
kubectlをインストールする方法はいくつかあります。
※検証したCentOSの手順を掲載します。
  他の手順は、本体を参照ください。

### バイナリ版kubectlのインストール



#### 1. 最新バージョンをダウンロードする場合のコマンド

```
curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
```

#### 2. 特定のバージョンをダウンロードする場合のコマンド

以下のコマンドが、最新版のバージョンの文字列を取得するコマンドのため、

```
$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt) 
```

特定のバージョンをダウンロードする場合は、以下のように欲しいバージョンに置き換えてコマンドを実行します。
※以下の例は、Linux の v1.11.0 をダウンロードする場合の例です。

```
curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.11.0/bin/linux/amd64/kubectl
```

#### 3. `kubectl` に実行権限を付与する

```
chmod +x ./kubectl
Move the binary in to your PATH.
sudo mv ./kubectl /usr/local/bin/kubectl
```

## kubectlの設定
kubectlがKubernetesクラスタを検索してアクセスするには、kubeconfigファイルが必要です。このファイルは、kube-up.shを使用してクラスタを作成するか、Minikubeクラスタを正常に展開すると自動的に作成されます。クラスタの作成の詳細については、「スタートガイド」を参照してください。作成していないクラスタにアクセスする必要がある場合は、「クラスタアクセスの共有」を参照してください。デフォルトでは、kubectlの設定は〜/ .kube / configにあります
gmaps4railsのマップタイプを設定する

## はじめに
Google Map APIを利用したアプリ開発をしています。
その時に、マップの表示のデフォルトを航空写真にしたかったので実装してみました。
マップの表示の種類のことをマップタイプと呼ぶそうです。

## コード
このようになりました。

```html

<script>
  handler = Gmaps.build('Google');
  handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
    markers = handler.addMarkers(<%= raw @hash.to_json %>);
    handler.bounds.extendWith(markers);
    handler.fitMapToBounds();

    // マップタイプの追記
    handler.getMap().setMapTypeId("satellite");

  });
</script>
```

## 参考
参考にしたのはこちら

gmap4railsの設定の変更に役立った
・[gmaps4railsの地図の拡大率を設定する](https://qiita.com/tackey/items/2dd3cc3131fedff879ac)

mapTypeIdというものがあることを知った
・[Google Maps API の使い方・利用方法](http://www.webdesignleaves.com/pr/plugins/googlemap_01.html)

・[Mapクラスのメソッド一覧](https://developers.google.com/maps/documentation/javascript/reference/map)
【Laravel5.8】PHP7.4でTrying to access array offset on valueが山盛り出るようになった

Laravel5.8で試したからLaravel5.8としているだけで、他のバージョンや、あるいは他のフレームワークでも発生すると思います。

[PHP7.4.0がリリースされました](https://www.php.net/)。

で、PHP7.4からスカラー型変数に[配列アクセスするとE_NOTICEが出る](https://qiita.com/rana_kualu/items/2d71a88aab59b35cdcb8#trying-to-access-array-offset-on-value-of-type-s)ようになりました。

```php
$a = null;
echo $a[1];
```

これはPHP7.3までは何も言いませんでしたが、7.4では[E_NOTICE](https://3v4l.org/cO0n3)が発生します。
さらにPHP8ではE_WARNINGになる予定です。

これの何が問題って、値が入ってるかどうかわからないテーブルにリレーション張ってる場合ですよ。

```php:テーブルAのモデル
class TableA extends Model{
    /**
     * テーブルBへのリレーション
     */
    public function TableB()
    {
        return $this->belongsTo(\path\to\TableB::class, 'b_id', 'id');
    }
}
```

コントローラはwithで引っ張ってきてbladeに投げるだけ。

```php:コントローラ
    $tableAs = TableA::with(['TableB'])->get();
    return view('hoge.blade.php', [$tableAs]);
```

ビューではなんか適当に表示。

```php:hoge.blade.php
@foreach ($tableAs as $tableA)
	ID: {{ $tableA->id }}
	Bの値: {{ $tableA->TableB['name'] }}
@endforeach
```


テンプレートはだいたいこんな書き方をしてると思うのですが、というか私がしてるのですが、テーブルBに値が無かった場合、これまで"Bの値"は単に空白になっていました。
PHP7.4に上げた瞬間、至る所でLaravelがErrorExceptionを吐くようになってえらいことになりましたよ。


根本的に正しく解決するにはどうすればいいのかはよくわかりませんが、とりあえず

```php
	Bの値: {{ $tableA->TableB['name'] ?? '' }}
```

ってすることで事なきを得た。

事なきを得たと思ったんですが、実はこれLaravel本体側でも発生するんですよね。
確認したところではemailバリデータを使うと出てきます。
そのうち修正されるとは思いますが、先にLaravelのアップデートを終わらせるまでPHP本体のアプデは待った方がよいでしょう。
ReactでHTMLの文字列をレンダリングする（変数に格納されているHTMLの文字列をレンダリングする）

## 概要

Reactでhtmlの文字列をレンダリングする（変数に格納されているHTMLの文字列をレンダリングする）。

## 実装

`dangerouslySetInnerHTML`を使うと可能。

dangerouslyの名の通り、注意して使うように。。

```react
render(){
    let hoge = "<div style='color: red;'>auauauaua</div>";
    return <div dangerouslySetInnerHTML={{ __html: hoge }}></div>;
} 
```
エンジニアが読むべき○○シリーズに書かれない本当に読むべき情報リソースを書いておく

二行で：
公式ドキュメントとソースコード読め。
自分の身の回りのドキュメントとソースコードも読め。

## はじめに

「エンジニアが読むべき○○」とか「新人プログラマに読んでほしい記事」などという記事が多々あるが、おおよその場合、一部の条件に特化しているか（特定の言語、フレームワークなど)、本当に大事なことを書かれていないか、くだらないか、なので、本当に読むべき情報リソースを書いておく。
足りないところを補完する目的なので、私の一記事ですべてを網羅しているわけではない。
この記事は自戒の意味が大きいが、たぶん万人に当てはまるのでQiitaで公開しておく。

## 公式ドキュメント

エンジニアが読むべき○○シリーズでは、書いてはいけない決まりでもあるのか？ってレベルで決して書かれない。
まずは公式サイトを読むのが基本中の基本。
QiitaとかStack Over Flowとか個人ブログとかその他は、まず公式サイト当たってからそのサポートとして読むべき。
ほとんどの場合公式は英語だが読め。

公式チュートリアルや、公式本など、公式○○シリーズは基本的に読む（やる）。

ものによっては、国際機関で公式な定義がされている場合があるのでその場合はそれを読む。

## 自分が使う言語やプロジェクトのソースコード(OSSの場合)

初心者にはハードルが高い面もあるが、ちょっとずつ読み進める。ソースコード読んどくだけで解決する課題は多い。
自分の使うすべてプロジェクトを読み解くことは時間的に不可能だから、何を読むべきか勘が必要になる。

自分が使う言語で書かれた大規模プロジェクトのソースコードなどもここに入る。
古くからある大規模プロジェクトは負の遺産が多いこともあるので、新しいものも混ぜる。

## 自分がかかわっているプロジェクトのドキュメント、ソースコード.etc

有象無象な記事を読むより自分のかかわるプロジェクトの情報をちゃんと読もう。
質が高くない場合もあるが、自分のためにはなる。

## まとめ

公式ドキュメント、ソースコードと自分の身の回りにあるものをないがしろにして、Qiitaとかニュースサイトとか、動画とか紹介したところで対した意味はない。
そういったものは興味をもつきっかけにはなるが、公式を読まねば正しく重要な情報を身に着けることはできない。
甘い言葉に騙されずまずは公式を読め。

もちろん面白い記事がためにならないわけではない。
ただ、公式をすっ飛ばして学んだ気になるならそれはまやかしである。
PHP関連パッケージのアップデート後にセッション処理でエラーになったときの回避策

<h2>はじめに</h2>
PHP関連のパッケージアップデートしたら、セッション処理エラーを吐かれた。
そんなときの回避策。

<h2>エラー出力の内容</h2>
Apacheのエラーログに以下メッセージが出力されている。

```
Failed to write session data (files). Please verify that the current setting of session.save_path is correct (/var/lib/php/session)
```

<h2>回避策</h2>
とりあえず、なんでもいいから復旧させたい！という場合は、/var/lib/php/session の権限を777にする。

```
$ chmod 777 /usr/lib/php/session
```

PHP関連パッケージがバージョンアップされたときに、
 "/var/lib/php/session" の権限が変わってしまったことが原因なので、
権限を777にすることで回避します。
削除後同名のフォルダを作成するとエラーになる

[富士通システムズウェブテクノロジー Advent Calendar 2019](https://qiita.com/advent-calendar/2019/fsweb) 2日目の投稿です
記事の内容は全て個人の見解であり、執筆内容は執筆者自身の責任です。所属する組織は関係ありません。

Windows機内の一時ファイル置き場に沢山の不要ファイルが溜まってきたので
単純に削除するのではなく、せっかくだから今まで使ってこなかったPowerShellを使ってみようとしました。
その際、はまってしまったことを整理した記事です。


## 発生したトラブル :dizzy_face:
フォルダの作成に失敗します。

## やりたいこと :sunny:
不要なファイルが入っているフォルダを削除し、新しい同名のフォルダを作成します。

## 実行環境 :computer:
Windows10 Enterprise バージョン1809

## 実行したスクリプト :cd:
```Trash.ps1
$target = "C:\temp\Trash"

# 不要フォルダを削除する
if (Test-Path $target) {
    Remove-Item $target -Recurse
}
# 新規にフォルダを作成する
New-Item $target -itemType Directory | Out-Null
```

## エラーの詳細 :worried:
以下の2つのエラーのどちらかが発生します。
後者はおそらく削除のためにロックをかけているのでしょう。
そのタイミングで作成しようとすると発生すると思われます。


```
C:\Scripts\  > .\Trash.ps1
New-Item : 指定された名前 C:\temp\Trash の項目は既に存在します。
発生場所 C:\Scripts\Trash.ps1:8 文字:1
+ New-Item $target -itemType Directory | Out-Null
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : PermissionDenied: (C:\temp\Trash:String) [New-Item], IOException
    + FullyQualifiedErrorId : DirectoryExist,Microsoft.PowerShell.Commands.NewItemCommand

C:\Scripts\  >
```
```
C:\Scripts\  > .\Trash.ps1
New-Item : アクセスが拒否されました。
発生場所 C:\Scripts\Trash.ps1:8 文字:1
+ New-Item $target -itemType Directory | Out-Null
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : PermissionDenied: (C:\temp\Trash:String) [New-Item], UnauthorizedAccessException
    + FullyQualifiedErrorId : ItemExistsUnauthorizedAccessError,Microsoft.PowerShell.Commands.NewItemCommand

C:\Scripts\  >
```


## 原因 :scream_cat:
PowerShellの`Remove-Item`コマンドは、別プロセスで実行されるらしく、
削除完了を待たずに、次の処理に移行してしまいます。
すると、`C:\temp\Trash`の削除が完了する前に`C:\temp\Trash`を作成しようとするため
今回のトラブルが発生しました。

## 対応方法 :bulb:
対応方法は大きく３つ思いつきました。
1. 削除完了を待ってから作成を行う
2. 削除対象を別名で退避し、作成を行う
3. 外部アプリを使う。
別途削除アプリを作り、PowerShellから待ち受けで実行すればできますが、
それは今回の目的から外れるので1と2を試しました。

## 「削除完了を待ってから作成を行う」場合 :point_up:
`Remove-Item`コマンドを実行後、`Start-Sleep`コマンドを使い何秒か経過してから
`New-Item`コマンドを実行しても良いのですが、適切なスリープ時間を決めることは難しいです。
そこで、`C:\temp\Trash`が存在しているかどうかをチェックし、
存在しなくなったら作成するようにしたのが、次のスクリプトです。

```Trash.ps1
$target = "C:\temp\Trash"

# 不要フォルダを削除する
if (Test-Path $target) {
    Remove-Item $targetBk -Recurse
}

# 対象の存在チェックを繰り返す
while (Test-Path $target) {
    # まだ存在しているので1秒待ってから再度チェックを行う
    Start-Sleep -Seconds 1
}

# 新規にフォルダを作成する
New-Item $target -itemType Directory | Out-Null
```
削除される対象の量の大小によって、Sleep時間は増減させればいいでしょう。
ただし、このスクリプトにはトラブルが発生しました。

whileの`Test-Path`の際に、アクセスエラーが発生することがあるのです。
原因はわかりません。


## 「削除対象を別名で退避し、作成を行う」場合 :v:
`Rename-Item`もしくは`Move-Item`コマンドで対象をリネームすることで
削除処理の影響をなくしたのが、次のスクリプトです。

```Trash.ps1
$target = "C:\temp\Trash"

# 不要フォルダを削除する
if (Test-Path $target) {
    $targetBk = $target + "Bk"
    # 一度退避してから削除する
    Rename-Item $target $targetBk
    Remove-Item $targetBk -Recurse
}

# 新規にフォルダを作成する
New-Item $target -itemType Directory | Out-Null
```
フォルダを作成と削除を分けることでトラブルを回避します。
先の「削除完了を待ってから作成を行う」と異なり、こちらは安定して動作しました。

## まとめ :smiley:
もともと削除処理は結果を待ち受けません。
それを無理に待ち受ける処理にするよりも
その動作をそのまま受け入れた方式の方が自然に動作するようです。
Jira Webhook と Template を使ってSlack通知を快適にする

## はじめに
こんにちは。
ナビタイムジャパンで社内JiraやSlackの運用をしている TAKE です.
弊社では500人を超えるユーザーが利用していますが,たくさんの依頼が日々届きます.
今回は『Issue Templates for Jira』を用いて,テンプレートごとのSlack通知を行いたいというニーズにより改善を行ったことについてお伝えいたします.

### Issue Templates for Jira
課題作成時にテンプレートを選択することによって下記のことができるようになります
* 入力するべきフィールドを指定できる
* デフォルト値を設定できる

### 社内でのチケットをSlackに通知したい例
* 「課題タイプ **構築依頼** かつ **AWS** の構築依頼テンプレート」のみ,Slackの **#bot_aws** に通知したい
* 「課題タイプ **タスク** かつ **問い合わせ** のテンプレート」のみ,Slackの **#bot_問い合わせ** に通知したい

## どのように快適になるか
Jiraを利用するユーザーは各テンプレートに通知先を記入することによってテンプレート毎に異なるチャンネルにSlack通知できます.
また,管理者に設定の変更をお願いする必要もありません！
![webフック](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315364/5bfd2ec6-10ff-30e3-15d0-a54094ddb263.png)



## 利用するサービスの種類とバージョン
* Jira Server 7.11.1
* Issue Templates for Jira 7.10.1-J7
* AWS Lambda

## 全体図
![全体図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315364/d61c8535-48ee-3809-6bbe-aaaedf320435.png)


## AWS Lambda の設定

1. リソースの作成
1. 処理の作成
 1. Jiraの送信するオブジェクトから通知先フィールドを取得
 1. slackに送信するjsonに加工する
 1. slackに送信
1. デプロイ

※Slack通知までは[こちら](https://qiita.com/yokoc1322/items/553ad147b82277b2beca)を参考になります

## Jiraの設定
Webhookで通知できるように設定します
1. Webhookの新規作成
2. 先程作成したLambdaのエンドポイントを入力
![Webhookの設定例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315364/502ffd71-9770-a329-e399-6e1a60f1750e.png)

3. 既存のワークフローの設定を開く
4. ワークフローのトランジションの設定を開く
5. 事後操作にwebhookの設定をする
![ワークフローの設定例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315364/8472377a-2c71-f913-44da-5516970b2564.png)




## Template の設定
弊社ではデフォルト通知先というフィールドを新規作成しています.
(ユーザーのテンプレート作成時には,ここに通知先を記入することになります）
![全体図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315364/5a26110e-03e0-ed73-6b14-a3f5e94bc2b8.png)


## まとめ
Templateを作成する時にチャンネルを指定すると,今後テンプレートを使ってチケットが作成されたときに指定されたSlackチャンネルに通知できます!
【RTX】再起動したかな？と思った時の確認コマンド【show environment】

##はじめに
yamahaのrtxで起動時間を確認したいと思った時のコマンド。

##発行コマンド

```
# show environment
  RTX1000 Rev.7.01.08 (Tue Mar 18 18:56:49 2003)    ※機種名とファームウェア番号
    main:  RTX1000 ver=00 serial=xxxxxxxx MAC-Address=00:a0:de:xx:xx:xx MAC-Address=00:a0:de:xx:xx:xx MAC-Address=00:a0:de:xx:xx:xx
  メモリ: 18% used    ※メモリの使用率、機種によってはCPU負荷も確認できます 
  ファームウェア: internal  設定ファイル: 0
  起動時刻: 2019/11/01 00:00:00
+09:00
  現在の時刻: 2019/11/28 19:00:00 +09:00
  起動からの経過時間: 28日 19:00:00
  セキュリティクラス レベル: 1, タイプ: ON, TELNET: OFF

```

「起動からの経過時間」が、直近になっていれば再起動がかかっています。

ログから確認する場合は、

```
# show log reverse
```

直近のログから出力されるので、再起動ログが出ているか確認することも可能です。
OpenChain認証取得、日立製作所の取り組み

株式会社 日立製作所 野村祐治

# はじめに
日立製作所では、「オープンソース ライセンス ガバナンス プロセス認証」を取得しました。
この認証はOpenChainプロジェクトが求める仕様に適合しており、OpenChainプロジェクトが認める最初の第三者認証の取得事例になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320984/29c0a2b0-5e78-f090-9d14-782cdaf951e0.png)
</dev>

今回は認証の取得にいたる、日立の取り組みを紹介します。
 

# 日立製作所のOSSコンプライアンスへの取り組み
日立製作所では、OSSコンプライアンスを遵守するため以下の取り組みを実施しています。

- OSS専門組織
- OSS取扱いに関する会社規則
- OSS取扱いに関するガイドライン
- OSS取扱いに関する社内教育
- OSS取扱いに関する社内インフラ

# OSS専門組織
OSS専門組織 として、OSSソリューションセンタを2015年10月に設立しました。
OSSソリューションセンタは、OSS活用の日立グループ内の取りまとめとして以下をミッションに活動しています。

- ミッション: OSSによる日立グループへのビジネス貢献

	- OSS活用ノウハウおよび、サポート・ソリューションの提供
	- OSSを安心して利用するためのインフラ・ガイドの提供
	- OSSコミュニティ貢献・標準化活動を通じたプレゼンス向上

#OSS取扱いに関する会社規則
OSSの特性に合わせたOSS取得に特化した会社規則を制定しました。OSS取得の規則においては、以下を規定しています。

- OSS取得に関する審議体の規定
- OSS取得に関する審議項目と、審議担当部署の規定
- OSS取得の決裁者
 

# OSS取扱いに関するガイドラン
OSSの取扱いにおいて、利用者の行うべき作業・検討すべき項目をガイドラインとして規定しました。
日立製作所の標準開発方法論で定義する開発フェーズ、開発プロセス毎にワークシート形式で必要な作業をガイドしています。

### ガイドラインの例(抜粋)

|フェーズ|プロセス|検討・作業項目      |
|:---|:---|:---|
|企画|要件定義|・OSSの提供状況の確認<br>・脆弱性事故への対応方法の確認|
|基本設計|システム方式設計|OSSの入手手続き|
|受入テスト|導入・受入|ライセンス遵守状況の確認|


#OSS取扱いに関する社内教育
OSSに携わる人全員が受講するe-learningと、より深い知識習得のための集合教育に分けて教育を実施しています。

- OSSの基礎(e-learning)
	- OSSを利用するために必要な基礎知識を習得する教育(コンプライアンスのポイント､活用するための検討事項)
- OSSコンプライアンス教育(集合教育)
	- OSSのコンプライアンス(ライセンス、知財、他)、ガイドラインに関する教育
 

# OSS取扱いに関する社内インフラ
会社規則、ガイドラインで規定した作業を効率よく行うため、社内インフラを開発・整備しています。

### 社内インフラの構成
 
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320984/beb5a0ce-b3e2-4380-92b4-483f1dd0d062.png)


#OpenChain認証の取得
OpenChainプロジェクトでは、OSS取扱いのプロセスに関する仕様を定めています。
日立製作所では従来より独自の社内プロセスによりOSSの取扱いを行っていましたが、今後広くビジネスを行って行くには業界標準のプロセスを取り込んでいくのが良いと判断し、OpenChainの仕様に準拠する活動を行いました。
具体的な作業として、OpenChainで定められた仕様に準拠するように、社内の取り組みを改善しました。

|OpenChain仕様カテゴリ|対応する社内の取り組み|
|:---|:---|
|G1. FOSSに関わる責任の理解<br>・OSS取扱いに関する社内教育|・OSS取扱いに関するガイドライン|
|G2. コンプライアンスを履行するための責任者のアサイン|・OSS専門組織|
|G3. FOSSコンテンツのレビューと承認|・OSS取扱いに関する社内インフラ<br>・OSS取扱いに関する会社規則|
|G4. FOSSコンテンツ ドキュメントとコンプライアンス関連資料の頒布|・OSS取扱いに関する社内インフラ|
|G5. FOSSコミュニティへの（積極的な）関わり方の理解|・OSS取扱いに関する社内教育<br>・OSS取扱いに関するガイドライン|
|G6. OpenChain 要件適合の認定|・OSS取扱いに関する会社規則<dl>・OSS取扱いに関するガイドライン<br>・OSS取扱いに関する社内教育|
※FOSS：Free/Open Source Software 

従来の日立製作所のプロセスは、OpenChainの仕様で定めるプロセスと大きな差異は無く、軽微な改善でOpenChain仕様に準拠可能でした。

社内のプロセスを改善している時期に、OpenChain仕様準拠の認証サービスを行う企業が登場し、その企業に依頼して仕様準拠の認証をしてもらうことにしました。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320984/d9ecd67c-5e66-e901-1443-78f95d5d31b1.png)

2018年11月に、認証取得を得ました。
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320984/6800fdc1-ea7a-6925-78e9-81e569d875bd.png)

# おわりに
OpenChainの認証を取得する企業は、どんどん増えています。OpenChainプロジェクトで情報交換も出来ると思いますので、皆さん、OpenChainプロジェクトに参加しましょう！

さて、明日の記事は、2019年12月19日に行われたJapanWG全体会合のレポートが投稿される予定になっています。
ますます活発な活動になっているJapanWGですが、最新のトピックスもレポートされると思いますのでお楽しみに！

# 他社商品名、商標等の引用に関する表示
Black Duck は、Synopsys, Inc. の米国およびその他の国における登録商標です。
文系初心者が半年で AWS を触れるようになるまでの記録

[NAVITIME JAPAN Advent Calendar 2019](https://qiita.com/advent-calendar/2019/navitime_japan) 6日目の記事です。
### はじめに
今年4月に新卒でナビタイムジャパンに入社したふみぽんです。
サーバーって何？という状態からどうやって AWS を扱えるようになったのかをよく聞かれるので、記事にしてみました。
ちなみに、AWS で好きなサービスは CloudFront です。
### 今のレベル感
#### 【今できること】
* AWS のサービス名を聞いて何のサービスか分かる
* コンソールからの構築
* CloudFormation を用いた構築
* AWS CLI を用いたツールの開発

####【まだできないこと】
* 障害調査
* データベース自体の理解
* 社内で利用していないAWSサービスの理解

### 勉強方法
1. AWS の公式動画、[AWS Black Belt](https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-service-cut/)を見る
    * 無料
    * サービス毎にそれぞれ1時間で説明してくれるから短時間で学習できる
2. [Developers IO](https://dev.classmethod.jp/)
    * 実際に使ってみた経験を記事にしてくれている
    * 最新のアップデート情報もすぐに記事に
3. シェルの勉強
    * クラウド業務の自動化をするならシェルの知識は必須
    * オススメの本：[新しいLinuxの教科書](https://www.amazon.co.jp/dp/4797380942)
        * スラスラ読めて、基礎から勉強できるので初心者におすすめです。
        
AWS に関して、本で勉強は一切していません。ひたすら動画を見ました。
機能や UI がすぐに変わるので、本が出た頃には情報が古くなっているなんてこともあります。（動画も更新頻度が2年に1度くらいなので情報が古い場合がありますが）
クラウドの中でシェア No.1なだけあって、ネットにも情報がたくさん落ちていますので、お金を出さなくても業務レベルの知識が身につくと思います！
### 記録
#### 配属1ヶ月目
ありがたいことに配属されて1ヶ月くらいは業務の9割を AWS の学習にあてさせていただきました。 この1ヶ月は初めましてのことだらけで、分からない単語が出てくる度に動画を止めて調べていたところ、1つの動画を見終わるのに1日以上かかってました。辛い。

* 動画視聴の順番 ：
IAM [Part1](https://www.youtube.com/watch?v=K7F5yTThynw&feature=youtu.be)/[Part2](https://youtu.be/qrZKKF6V6Dc)、[VPC](https://youtu.be/aHEVvsk6pkI)、EC2（[EC2](https://youtu.be/P5zX4DdlYOE)、[AWS のコスト最適化/リザーブドインスタンス](https://d1.awsstatic.com/webinars/jp/pdf/services/20171110_AWS-BlackBelt_RI_update.pdf))、 [Amazon EC2 スポットインスタンス](https://youtu.be/e-L-1z08j8Q)、[ELB](https://youtu.be/4laAoK-zXko)、[CloudWatch](https://youtu.be/gOaZeJpb0Y4)、SNS、[Auto Scaling](https://d1.awsstatic.com/webinars/jp/pdf/services/20170315_AWS-BlackBelt-AutoScaling.pdf)、[CloudFront](https://youtu.be/mmRKzzOvJJY)、[S3](https://youtu.be/oFG5kMZjKtc)
※リンクがあるものは私が特に重要だと思った動画です

#### 配属2ヶ月目 
この頃から動画で学習が終わったサービスの構築を割り振っていただいたり、MTG に同行させてもらうようになりました。 勉強は業務の３割くらい。 この頃になると、なんとなく MTG 中の話が理解できるようになり、動画もサラッと頭に入ってくるようになります。壁を乗り越えた感。

* 動画視聴の順番 ：
[Route53](https://d1.awsstatic.com/webinars/jp/pdf/services/20160113_aws-blackbelt-route53-public.pdf)、[DynamoDB](https://d1.awsstatic.com/webinars/jp/pdf/services/20170809_AWS-BlackBelt-DynamoDB.pdf)、ACM、Lambda [Part1](https://youtu.be/QvPgjEwgiew)/[Part2](https://youtu.be/96ku2x1NCaE)/[Part3](https://youtu.be/rMG18Fr896U)/[Part4](https://youtu.be/AOx5iNmxOC8)、[APIGW](https://youtu.be/EpEETIox03s)、SES、[CloudFormation](https://youtu.be/HU47ZAM3mtw)、ECS

#### 配属3ヶ月目以降 
できることが増え、業務 100％になりました。 これだけ AWS に触れていると単純接触効果で AWS が大好きになります。その勢いのまま、勉強します。 業務中に疑問に思ったところを実際に試してみたり、ドキュメントを読みながら実際に構築するのがオススメです。

* 動画視聴の順番 ：
CloudTrail & AWS Config、[Amazon Athena](https://youtu.be/VH1FV9J92CU)、AWS Glue、[RDS](https://youtu.be/nDme-ET-_EY)、Amazon Aurora with MySQL Compatibility、Amazon Aurora with PostgreSQL Compatibility、GuardDuty、 Amazon CloudSearch and Amazon Elasticsearch Service、Cognito、ElastiCache、Code Services、EMR

### これから 
動画はあくまで基礎学習です。動画を全て見終わったからといってどんな業務でもできるようになるかというと、そうでもなかったです。さらに知識を深めるにしても範囲が広すぎてどこから手をつけたらいいのか分からないので、これからは業務で知らないことが出てきたら調べる方法で知識を増やしていきます。
また、今月中にソリューションアーキテクトの資格取得にも挑戦しようと思います！ 

私と AWS の戦いはまだまだ続く。
DOMについて調べたことの備忘録

#　DOMについて
- Document Object Model
- HTML や XML 文書を操作するための、たくさんの機能や規則のこと
- DOMは階層構造をとる
- 各要素はノードという単語を用いて表現される

# ノードについて
- ノード
- 子ノード(children)
- 親ノード(parent)
- 兄弟姉妹ノード
- ノードは、webページとプログラミング言語をつなぐ役割を持つ
- ID名からノードを取得、操作する


[JavaScript初心者でもすぐわかる！DOMとは何か？]
(https://eng-entrance.com/what-is-dom)

[DOMとは何か？【JavaScript初心者向けにわかりやすく説明します！】](https://watablogtravel.com/document-object-model/)




 DOMの話に戻ります

## HTML要素の取得：getElementById()
- Documentオブジェクトのメソッドである「getElementById()」が一般的らしい
- 文字列のHTMLタグを認識できる

###使用例

```HTML
<body>
<p id="text">これはサンプルテキストです</p>
 
<script>
    var p = document.getElementById('text');
 
    console.log( p );
</script>
</body>
```
実行結果

```HTML
<p id="text">これはサンプルテキストです</p>
```
## HTML要素をJavaScriptから書き換える：innerHTMLプロパティ

- 「innerHTML」プロパティを代入するだけ！

#### 使用例
```HTML
<div id="wrap">
    <p>これはサンプルテキストです</p>
</div>
```

これをinnerHTMLプロパティでp要素をh1要素に書き換える

```JavaScript
var div = document.getElementById('wrap');
 
div.innerHTML = "<h1>サンプルタイトル</h1>";
 
console.log( div );
```
実行結果


```HTML
<div id="wrap">
    <h1>サンプルタイトル</h1>
</div>
```

## JavaScriptからHTML要素を作成する：createElement( )

- もっとも簡単な方法はcreateElement()
- 例えば「createElement('p')」と記述することで「p要素」を新規に生成

```JavaScript
var pElement = document.createElement('p');
```

- この方法で作成しても、画面に表示されないので、***HTML要素をDOMに追加***しなくてはならない


## HTML要素を追加：appnedChild()
- JavaScript側で生成したHTML要素をDOMに追加

```JavaScript
var p = document.createElement('p');
 
//テキストを追加する
p.textContent = 'これはサンプルです';
 
//body要素内にp要素を配置する
document.body.appendChild( p );
```
実行結果

```HTML
<p>これはサンプルです</p>
```

※ textContent()メソッドでテキストを追加


## DOMが読み込まれるタイミング：onloadイベント
- DOMによるオブジェクト化がされていないと、JavaScript側からHTMLを操作できない
- DOMが読み込まれた後にJavaScriptが実行できるようにしなければならない
- その中で、もっとも簡単なのが***onloadイベント***

```JavaScript
dow.onload = function() {
 
    //ここに処理を書く
 
}
```
- しかし複数記述すると、その都度上書きされてしまうので、上に書いたものは実行されない・・・

```JavaScript
window.onload = function() {
//処理１
}
 
window.onload = function() {
//処理２
}
 
window.onload = function() {
//処理３
}
```
- こちらの処理は一番下しか実行されない



## onloadでなくaddEventListenerを使ってみる

#### 使用例
```JavaScript
window.addEventListener('load', function() {
//処理１
})
 
window.addEventListener('load', function() {
//処理２
})
 
window.addEventListener('load', function() {
//処理３
})
```

- 第一引数にloanを書き、第二引数に実行する関数処理をかく
- addEventListenerを使用することで、３回記述したとしても全て実行することができる

[【JavaScript入門】はじめてのDOM操作・取得まとめ！](https://www.sejuku.net/blog/25221)
コメントを弾幕表示するChrome拡張を作ってみた

## 作ったもの

- コメントを投稿するとリアルタイムで弾幕表示されるChrome拡張を作りました

![demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175213/8d5a49ed-36c2-0df4-93ad-b479347a3b70.gif)

- 利用シーンとしてはGoogleスライドなどでプレゼンしている際にリアルタイムにフィードバックや感想を投稿するような場面です

## 使ってる技術

- フロントエンド: Chrome拡張
- バックエンド: Firestore

<img width="930" alt="構成図.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175213/17042eda-3cb9-c73a-68e4-19709a630d06.png">

- Chrome拡張はストアに公開するのに費用がかかるためローカルに配置したものを取り込みました
- Firestoreの使い方は[別の記事](https://qiita.com/ozaki25/items/9ce5021c545c4f44f3af)に書いたのでそちらもご参考で

## 処理の流れ

- 弾幕を表示する画面はChrome拡張をセットしておきます
    - Chrome拡張の処理でFirestoreを購読し最新のメッセージを待ち構えます
- 投稿者は専用のWebアプリからコメントを投稿します
    - 送信されたコメントは[Firestore](https://firebase.google.com/docs/firestore?hl=ja)に格納されます
- コメントがFirestoreに格納されるとリアルタイムでChrome拡張に通知が飛んできます
    - Chrome拡張はコメントを受け取ったら画面上にそれを表示します

## 工夫したところ

### 全画面表示に対応したい

#### 何が起きたか

- この機能を作ったきっかけは、Googleスライドでのプレゼンを想定していました
- なので、まずは適当なWebページに弾幕を表示するところから作りました
    - コメントを`body`の最後尾にappendするだけで簡単！！
- しかし、いざGoogleスライドで全画面表示すると弾幕が表示されず、、、全画面表示だとDOM構造やCSSの影響で単純には表示できませんでした

#### どう対応したか

- 全画面表示といっても所詮Webページである、ということで開発者ツールを開きDOM構造を調査
- どこにappendすればコメントがでるかを特定して対応しました
    - ※なのでGoogleスライド以外の全画面表示では表示されない場合があります

### ページごとに表示/非表示を切り替えたい

#### 何が起きたか

- ある程度実装が完了して落ち着いてきましたが、このChrome拡張を入れてるだけで弾幕がでるのがとてもうっとうしくなってきました
    - ページによっては弾幕が邪魔でボタンが押せず、、、など

#### どう対応したか

- 弾幕のon/offスイッチを作りました
- 毎回on/offを切り替えるのも面倒なので、ドメイン単位でon/off情報を保持できるようにしてみました
    - Googleスライドのページで一度onに設定すれば毎回切り替る必要がなく便利！
    - それ以外のページはoffのままなので影響なし！

<img width="238" alt="swtch.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175213/9f044367-f621-eb43-114c-251806cf4971.png">

### 最新の投稿がないときは過去分を表示したい

#### 何が起きたか

- 使用感を試している中で、投稿されない時間が続いたときに最後のコメントが表示されっぱなしだとつまんないよねという話になりました
- なので、最新の投稿が来なかった場合は過去分を引っ張り出してきてそれを表示するようにしてみましたが、、、
    - 過去分をどういうロジックで出そうか、というのが悩みどころになりました
- 直前のものを出すと、ついさっき出たばかりのコメントなのでつまらない
- あまりに古すぎるとプレゼン内容とコメントが乖離しすぎてしまう

#### どう対応したか

- 参加者の人数などその時々で状況が異なるため、何件遡って表示するか設定できるようにしました
- ついでに1つのコメントの表示時間もカスタマイズできるようにしています
    - 網掛けしているところはFirestoreの設定情報です

<img width="562" alt="settings.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175213/5370743d-604f-43ff-9023-37420e81939d.png">

- この画面はChrome拡張のオプション画面として作りました
    - 以下の手順で表示される画面です

<img width="947" alt="option.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175213/0bd26f4a-21ef-eb77-fdeb-b14007b19eb3.png">


### 感想

- 簡単な構成ですが求めていた機能を実現することができました
- Firestore簡単で便利！
- Chrome拡張はじめて作って勉強になりました！
Homebrew で明示的にインストールしたパッケージ名だけを一覧にするコマンド

## コマンド

```bash
brew info --installed --json=v1 \
    | jq -r '.[] | select(.installed | any(.installed_on_request)) | .name'
```

## 出力例

```
autoconf
awscli
berkeley-db
carthage
clang-format
```

## 解説

`brew info --installed --json=v1` はインストール済みのパッケージ情報を出力する。 `--json=v1` オプションで出力を JSON 形式にする。

JSON 形式のパッケージ情報の例を以下に示す。 `installed_on_request` プロパティはそのパッケージが `brew install` コマンドによって明示的にインストールされたら true になる。 false ならそのパッケージが他のパッケージの依存関係として暗黙的にインストールされたことを表す。 このプロパティに対応していなかった昔の Homebrew でインストールした場合は `null` になるかもしれない（確かめていない）。

```js
[
  {
    "name": "zsh",
    ...
    "installed": [
      {
        "version": "5.7.1",
        ...
        "installed_as_dependency": false,
        "installed_on_request": true
      }
    ],
    ...
  }
]
```

このパッケージ情報を `jq` でフィルタリングしてパッケージ名を取り出す。[jq 1.6 のマニュアル](https://stedolan.github.io/jq/manual/v1.6/)

`jq -r '.[] | select(.installed | any(.installed_on_request)) | .name'`

`-r` オプションで出力を生の文字列にする。そうしなければ JSON の文字列リテラル（ダブルクォートされた文字列）が出力されてしまう。

`'.[] | select(.installed | any(.installed_on_request)) | .name'` で条件を満たすパッケージの名前を出力する。

- 入力はパッケージ情報オブジェクトの配列
- `.[]`： 各パッケージ情報オブジェクトについて
- `| select(...)`： 条件に一致したオブジェクトを選ぶ
    - 条件 `.installed | any(.installed_on_requst)` ： `installed` 配列の要素に `installed_on_request` が真のものがひとつでもあれば真
- `| .name`： 各オブジェクトの `name` を出力

## 執筆時点の環境

```
$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.14.6
BuildVersion:   18G1012

$ brew --version
Homebrew 2.2.0-14-gb89ec55
Homebrew/homebrew-core (git revision 808d3; last commit 2019-11-28)
Homebrew/homebrew-cask (git revision 5266f2; last commit 2019-11-28)

$ jq --version
jq-1.6
```
マスターデータに左右されるサービス品質に向き合う話

## 概要
マスターデータの変更によってシステムの挙動は変わるため, 自動テストが難しくなります.
本記事はそれをどう克服しているかお話しします.

## 地点検索システムの品質保証
地点検索技術の開発を担当している [ymoch](https://github.com/ymoch) です.
本稿では地点検索のシステムと品質保証について取り上げます.
(地点検索それ自身については [アドベントカレンダー 1 日目](https://qiita.com/navitime_tech/items/1b392167a7454d4b15a0) で論じていますので割愛します)

ナビタイムの地点検索システムは, 全文検索システム (主に Solr) + API サーバで構成されています.
地点検索の品質を保証するために, これらを結合した状態で自動テストを実施しています.
具体的には, 以下のようなシナリオを実現できるか確認するため,
API サーバにリクエストを実行し, その結果が期待通りかどうか確認します.

- キーワード「東京」で検索すると, 東京駅がヒットする.
- ナビタイムジャパン周辺のコンビニを検索すると, ファミリーマート北青山三丁目店がヒットする.

## マスターデータは自動テストを難しくする
地点検索システムは, 地点データが投入されて始めて動作します.
実際にテストを運用してみると, 投入されるデータによってシステムの挙動が日々変わることに気づきます.
このため, 自動テストを行うためのテスト項目の選定や期待値の記述が難しくなります.

- 地点の開設・閉鎖によって, ヒットする地点が変わる
- 地点の人気度が変動し, 上位にヒットする地点が変わる
- データ提供者の都合で, 地点の ID や名称が変わる

たとえば, キーワード「東京」で検索した結果が, 東京ディズニーランドに変わるかもしれません.
また, 2017 年 10 月にナビタイムジャパンのすぐ近くにセブンイレブンがオープンし,
周辺のコンビニ最上位が入れ替わってもおかしくない状況にあります.
こういったデータの変更に由来する挙動のゆらぎに対処しないまま自動テストを運用すると,
日々失敗するテストの調査をすることになります. これでは自動化の恩恵を受けることができません.

実装の確認だけが目的であれば mock や sandbox を用いることでコスト削減を狙うことができますが,
本物のデータやバックエンドを用いたときに初めて問題が起きることもあります.
ある程度は受け入れて, システムレベルでテストすることが求められます.

## 曖昧さを受け入れる
マスターデータを利用してテストするケースでは,
曖昧さを受け入れつつ, 自動テストを運用する仕組みを構築することが重要です.
例えば, 以下のようなテストを記述して運用できれば,
品質を保証しつつも簡単にはマスターデータに左右されなくなります.

- 「東京」で検索すると, 名称に「東京」が含まれる地点がヒットする.
- ナビタイムジャパン周辺のコンビニを検索すると, 上位 3 件にファミリーマート北青山三丁目店が含まれる.

単にテストプログラムを書くこと自体は難しくありませんが,
テストケースが増えるとスケールしなくなりますので, フレームワークを決めておくことにしました.
[Postman](https://www.getpostman.com/) なども候補にあがりますが, 最近は [Preacher](https://preacher.readthedocs.io/en/latest/) を使い始めています.
少々複雑なテストでも, プログラムを書かずに jq と YAML だけで完結できる点が魅力のツールです.

```yaml
label: 地点検索システムのテスト

default:
  request:
    path: /spot
  response:
    status_code: 200

cases:
- label: キーワードに合う地点が検索できる
  request:
    params:
      word: 東京
  response:
    body:
    - describe: .items[0].name.ja
      should:
      - contain_string: 東京

- label: ある場所の周囲にある地点を検索できる
  request:
    params:
      word: コンビニ
      center: '[139.714896,35.667395]'  # (株)ナビタイムジャパン
      considers-distance: true
      limit: 3
  response:
    body:
    - describe:
        jq: .items[].name.ja
        multiple: true
      should:
      - have_item:
          all_of:
          - contain_string: ファミリーマート
          - contain_string: 北青山三丁目
```

## 展望
ナビタイムジャパンでは, データ作成にも専門性が求められることから, アプリケーションの開発チームとマスターデータの開発チームが異なることがよくあります. サービスの品質を向上するための組織構成ですが, 結合して品質を保証することも一つの挑戦になります.
今後も本物のデータやバックエンドを用いた検証について研究し, 安心してサービスをリリースできる環境を作っていきたいと考えています.
【メール調査（postfix）】メールログの見方

<h2>はじめに</h2>
メール調査でメールログを調べるときの見方について記載します。

<h2>手順</h2>
①メールログから抽出したい文字列を出力。

```
$ cat /var/log/maillog |grep "from=<XXXXXX@testfrom.co.jp>"
```

②例えば以下のような出力があったとします。

```
# May 12 21:50:55 server postfix/qmgr[1513]: 222F78322B9: from=<XXXXXX@testfrom.co.jp>, size=132527, nrcpt=1 (queue active)
# May 12 21:53:04 server postfix/qmgr[1513]: 66B928322E9: from=<XXXXXX@testfrom.co.jp>, size=74720, nrcpt=1 (queue active)
# May 12 21:53:17 server postfix/qmgr[1513]: A72198372F3: from=<XXXXXX@testfrom.co.jp>, size=25568, nrcpt=1 (queue active)
# May 12 22:00:11 server postfix/qmgr[1513]: EBD85837B18: from=<XXXXXX@testfrom.co.jp>, size=14550452, nrcpt=3 (queue active)
```

③キューIDより確認したい該当のメールを特定。
前述の出力結果だとキューIDは、
「222F78322B9」、「66B928322E9」、「A72198372F3」、「EBD85837B18」になります。

④例えば、「222F78322B9」についてメールの流れを追う場合は、
以下コマンドを発行します。

```
# cat /var/log/maillog | grep "222F78322B9"
```

⑤キューID「222F78322B9」についての結果が以下のように出力されます。

```
May 12 21:50:55 server postfix/smtpd[8163]: 222F78322B9: client=mail.testfrom.co.jp[XXX.XXX.XX.XX]
May 12 21:51:20 server postfix/cleanup[8166]: 222F78322B9: message-id=<XXXXXXXXXXXXXXXXXXXX@testfrom.co.jp>
May 12 21:51:50 server postfix/qmgr[1513]: 222F78322B9: from=<XXXXXX@testfrom.co.jp>, size=14550452, nrcpt=3 (queue active)
May 12 21:52:10 server postfix/smtp[7987]: 222F78322B9: to=<XXXXXX@testto.co.jp>, relay=XXX.XXX.XX.XX[XXX.XXX.XX.XX]:25, delay=44, delays=44/0/0.15/0, dsn=5.3.4, status=bounced (message size 14550452 exceeds size limit 10485760 of server XXX.XXX.XX.XX[XXX.XXX.XX.XX])
May 12 21:53:30 server postfix/bounce[9232]: 222F78322B9: sender non-delivery notification: ABC55832B09
May 12 21:54:00 server postfix/qmgr[1513]: 222F78322B9: removed
```

⑥「status=」の部分が何になっているか確認します。
status=sent の場合、送信成功を表します。
status=bounced の場合、拒否されたことを表します。
status=deferred の場合、送信できず延期されたことを表します。

status=sent 以外の場合、status=XXX の後にあるエラー内容から原因を探ります。
前述の出力結果だと

```
status=bounced (message size 14550452 exceeds size limit 10485760 of server XXX.XXX.XX.XX[XXX.XXX.XX.XX])
```
となっていました。
この場合は、メールサイズ上限の制限に引っかかり、メールが拒否されています。

このように、status=XXX の後に続くエラーコードから原因を探りましょう。
Oracle Code One 2019に行ってきました

この記事は[SRA Advent Calendar 2019](https://qiita.com/advent-calendar/2019/sra)の1日目の記事です。

こんにちは！　関西事業部の佐々木です。

#今年のOracle Code Oneの印象
1996年から20年以上続いてきたJavaOneは2018年からOracle Code Oneになりました。
今年はOracle Code Oneになってから2回目で、2019年の9/16から9/19にサンフランシスコで開催されました。
私は2015年のJavaOneから5年連続の参加です。

さて、カンファレンス名から「Java」の文字が消えてしまったOracle Code Oneですが、私の印象としては去年よりさらにJava以外の言語、GoやPythonなどのセッションが増えたように思えます。
JavaOne時代からJava言語以外のセッションもありましたが、ScalaやKotlinなどのJVM言語やJavaScriptが多かった印象です。
もちろん、コンテナ技術やDevOpsなどプログラミング言語に特化しないセッションもJavaOne時代から多くあるのですが、Oracle Code OneになってJava色が薄まったように感じます。

それから今年は日本人登壇のセッションが多かったようにも思います。
Oracle Code Oneの[Facebookグループ](https://www.facebook.com/groups/478276439599729/permalink/516710042423035/)にもまとめたのですが、毎日日本人が参加しているセッションがありました。
皆さんカッコよかったです。

#今年のミッション
去年のOracle Code Oneでは「Amazon.comで買い物をする」というミッションを自分に課しました。([去年の記事](https://qiita.com/kazsharp/items/9fa23710a97fd395eb53))
この内容は[Oracle Code One 2018 報告会 in 大阪](https://kanjava.connpass.com/event/107341/)の登壇時にも話をしたのですが、その時に初代Java Championのさくらばさんから

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">来年はAmazon Goで買い物ですねww <a href="https://twitter.com/hashtag/kanjava?src=hash&amp;ref_src=twsrc%5Etfw">#kanjava</a></p>&mdash; Yuichi Sakuraba (@skrb) <a href="https://twitter.com/skrb/status/1066202432978354176?ref_src=twsrc%5Etfw">2018年11月24日</a></blockquote>

との言葉をいただき~~逆らうと怖いので~~Amazon Goに興味があったので今年のミッションは「Amazon Goで買い物する」にしました。
（さくらばさんは去年のOracle Code Oneの時に行ったとのことです）

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">今年のミッションAmazon Goに来た <a href="https://t.co/4gKDgePF9t">pic.twitter.com/4gKDgePF9t</a></p>&mdash; 佐々木和繁@3391 (@kazsharp) <a href="https://twitter.com/kazsharp/status/1174831017498005504?ref_src=twsrc%5Etfw">September 19, 2019</a></blockquote>

事前にAmazon Goのアプリをインストールしておき、表示されたQRコードをゲートにかざして入店します。

![20190919_232953993_iOS - コピー.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100799/ffe55cbc-c131-4cf6-6433-efa33542e024.jpeg)

棚に商品がずらっと並んでいるので、勝手に商品を取って再びゲートをくぐって店を出ます。

<img width="375" alt="IMG_3392.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100799/56096cce-5d21-cdd8-4708-711fb11e0067.jpeg">

アプリを確認すると決済されていることがわかります。
一度取った商品を戻したり、取るフリをしたりしてみましたが間違って購入とかにはならなかったです。

#ボビーフィッシャーを探して
最後に、個人的には今年一番の収穫だと思っているストリートチェスについてです。
（屋外でプレイするチェスのことを何と言うのかわからないけど、ストリートファイターⅡが好きなのでストリートチェスと呼びます）
今年のOracle Code Oneのセッションは大体Moscone Southってところでやってたのですが、そのすぐ近くにYerba Buena Gardensという公園があります。
その公園の東の端でチェスをやっている人たちがいました。
**これは映画「ボビーフィッシャーを探して」でみた場面じゃないか！**
パッと見、定職を持ってなさそうなおっちゃんたちですが、一人のおっちゃんに声をかけて一局お手合わせ願いました。

![20190918_224140045_iOS - コピー.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100799/992bb841-025d-99a3-27f4-d553315d10ae.jpeg)

あっさり負けたのですが「一日中、毎日おるからまた来いよ」と言われました。
（やっぱり定職持ってないんや）
そして次の日はセッション最終日で夕方には蟹Oneがあるのですが、最後に予約していたセッションがキャンセルになってしまいました。
**「時間空いたやん！　チェスできるやん！！」**
ということで再びおっちゃんのもとへ
今度は先手後手を交代して一局ずつの二局プレイしましたが、やはり勝てませんでした。
終わってからおっちゃんに「カンファレンスは今日で終わりなんでもう来れない」と言ったら「来年またおいで」と言われました。

どうやら来年のミッションは決まったようです。
【1分解説】サーバが再起動した？と思ったときの確認方法【LinuxOSのサーバ起動時間確認コマンド】 

<h2>はじめに</h2>
Linuxサーバが再起動した？と思った時にサーバの起動時間を確認するコマンド「uptime」。
使い方は簡単。

<h2>使い方</h2>
サーバで「uptime」コマンドを発行すると起動から何分経過しているかが表示されます。
以下の発行例では、257日以上起動していることが分かります。

```
# uptime
 18:34:28 up 257 days, 14:08, 30 users,  load average: 0.04, 0.08, 0.07
```

■18:34:28 の部分
起動された時刻。

■257 days, 14:08 の部分
起動してからの経過時間。

■30 users の部分
ログインしているユーザ数。

■load average: 0.04, 0.08, 0.07　の部分
負荷状況を表すロードアベレージ(1分平均、5分平均、15分平均)。

![24ECD642-9CBB-4108-8455-DED38E8286BF.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536706/4d3052cf-5b7c-c9f2-3fbf-6c5deab5860c.png)
【Rails】CSVファイルからデータをインポート

簡単なTODOアプリに、CSVファイルからタスクを追加する機能を実装します。
手順は以下の記事で説明されているものとほとんど同じです。めちゃくちゃ参考になりました。
[【Ruby on Rails】CSVインポート](https://qiita.com/seitarooodayo/items/c9d6955a12ca0b1fd1d4)
##実装
タスク追加、編集、削除機能、ログイン機能などを持つTODOアプリにCSVアップロード機能を実装して行きます。
[Ruby on Railsで簡単なアプリを作成](https://qiita.com/d0ne1s/items/5e63dde992f20f25b8bb)
[【Rails】ログイン機能を実装する](https://qiita.com/d0ne1s/items/7c4d2be3f53e34a9dec7)
###rubyの標準ライブラリ`csv`を追加
```ruby:/config/application.rb
require 'csv'
```
###`roo`というgemを追加
csvファイルを読み込むためのgem`roo`を追加します。

```ruby:Gemfile
gem 'roo'
```

```terminal:terminal
$ bundle install
```

###タスク一覧画面にcsvアップロード用のフィールドを追加
```erb:/app/views/tasks/_logged_in.html.erb
<%= form_tag import_tasks_path, multipart: true do %>
  <%= file_field_tag :file %>
  <%= submit_tag "インポート" %>
<% end %>
```

###コントローラーにアクションを追加
`Task.import(params[:file])`で使われている`import`メソッドは後ほど定義します。

```ruby:/app/controllers/tasks.controller.rb
def import
  Task.import(params[:file])
  redirect_to root_url
end
```

###ルーティングを設定
`collection {post :import}`と書き込むことで、`resources :tasks`で作成されるルーティング以外の、tasksコントローラーのアクションへのルーティングを追加することができます。

```ruby:/config/route.rb
resources :tasks do
  collection {post :import}
end
```
```terminal:terminal
$ rails routes
.
.
import_tasks POST   /tasks/import(.:format)   tasks#import
.
.
```
`import_tasks`という名前付きルートが追加されました。

###モデルにCSV読み込み、登録処理を実装
```ruby:/app/models/task.rb
#importメソッド
def self.import(file)
  CSV.foreach(file.path, headers: true) do |row|
    # IDが見つかれば、レコードを呼び出し、見つかれなければ、新しく作成
    task = find_by(id: row["id"]) || new
    # CSVからデータを取得し、設定する
    task.attributes = row.to_hash.slice(*updatable_attributes)
    task.save
  end
end

# 更新を許可するカラムを定義
def self.updatable_attributes
  ["title", "user_id"]
end
```

###動作確認
以下のようなファイルを用意します。

```taskForTodoApp.csv
title,user_id
パンを買う,2
筋トレ,2
メルカリの発送,8
ティッシュを交換する,2
```

**実行結果**
<img width="503" alt=" 2019-11-28 18.43.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244893/30701ae2-32cf-7b37-62da-7b6aa6ba6257.png">

##ハマったポイント
・CSVファイル内にuser_idを記載しておらず、データベースへの登録時にエラーが発生していたところで少しハマりました。

##TODO
・TSVファイルも取り込めるようにする

##参考
[【Ruby on Rails】CSVインポート](https://qiita.com/seitarooodayo/items/c9d6955a12ca0b1fd1d4)
【bind】TXTレコード追加したいと思ったときの手順

<h2>はじめに</h2>
bindでTXTレコードを追加したいと思ったときはどうすれば良いか記載します。

<h2>設定変更</h2>
設定ファイル(例)：/etc/bind/bind.com.zone

◆設定変更前

```
$TTL	3600
@	IN	SOA	test.bind.com. test.bind.com.  (
				2019112801      ; Serial
				3600		; Refresh
				900		; Retry
				3600000		; Expire
				3600 )		; Minimum
	IN	NS	ns.test.bind.com.
	IN	MX	0 test.bind.com
test	IN	MX	0 test.bind.com
*	IN	MX	0 test.bind.com
test	IN	A	X.X.X.X
ns	IN	CNAME	test
www	IN	CNAME	test
```

◆設定変更後

```
$TTL	3600
@	IN	SOA	test.bind.com. test.bind.com.  (
				2019112802      ; Serial ＃serialをあげる
				3600		; Refresh
				900		; Retry
				3600000		; Expire
				3600 )		; Minimum
	IN	NS	ns.test.bind.com.
	IN	MX	0 test.bind.com
test	IN	MX	0 test.bind.com
*	IN	MX	0 test.bind.com
test	IN	A	X.X.X.X
ns	IN	CNAME	test
www	IN	CNAME	test
test    IN TXT "TXTレコードとして追加したい文字列" ＃追記
```

【留意点】
設定変更時、「200019112802      ; Serial」のように、
Serialの数字をあげておく必要があります。

管理しやすいように、出力例では「変更日のYYYYMMDD + 連番2桁」としています。

<h2>設定変更を反映する</h2>

```
systemctl reload named.service
```
【1分解説】FFFTPの使い方

<h2>はじめに</h2>
FFFTPでサーバに繋ぎたい！と思ったときの方法について記載します。

<h2>使い方</h2>
①FFFTPを開く。
②起動すると「ホスト一覧」のウィンドウが表示されるので「新規ホスト」を選択。
![host.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536706/c9b26c6c-30c6-2255-8eed-a3d6a54584fe.png)

③必要情報を記入する。
![hostsettei.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536706/bc69e11d-2451-f4cb-2b06-88b7b13b5de5.jpeg)

◆ホストの設定名
任意の名前を付けます。（画像では「test」と指定。）

◆ホスト名(アドレス)
FTP接続したい相手サーバ名(FTPホスト名)を記入します。

◆ユーザー名
FTPユーザー名(FTPアカウント名)を記入します。

◆パスワード
FTPパスワードを記入します。

④必要事項の記入ができたら、「OK」をクリック。
⑤設定した項目を選択し、「接続」をクリック。
⑥接続完了。
[Unity]冬のアドカレ2019　破壊系アセットGO Shatter Toolkitについて

この記事は[Unityアセット冬のアドベントカレンダー 2019 Winter！](http://assetstore.info/asset-advent-calendar-2019-winter/)の12月21日の記事になります。
#GO Shatter Toolkitとは？
オブジェクトの破壊表現を簡単にしてくれ[アセット](https://assetstore.unity.com/detail/tools/particles-effects/shatter-toolkit-1017#releases?utm_source=jppt&utm_medium=20191221)です。
最終リリースは2015年ですがUnity2019.2.3でも問題なく動作しました。
#できること
![qiita1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344267/be0898a4-212d-7c52-efbd-f4ddb438eba8.gif)
オブジェクトをぶつけてオブジェクトを破壊。
破壊された破片オブジェクト同士がぶつかり、破壊されることもあります。

![qiita2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344267/6b89a240-211f-6886-40e9-64b21c00f935.gif)
切断面のテクスチャをしているすことも可能。

#基本的な使い方
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344267/54d209b8-eb7d-fbfb-c367-83c7eddd7ffe.png)


破壊したいオブジェクトにRigidbody、MeshCollider(Convexにチェック)、ShatterTool、WorldUvMapper、ShatterOnCollisionをアタッチする。

それぞれの機能は以下の通り(書いてないのは分からなかったやつです)

##ShatterTool
破壊を制御するメインのスクリプト。
###GenerationLimit
破壊された破片がさらに破壊される回数を指定できます。
###Cuts
破壊された破片数を指定できます。
###FillCut
切断面にメッシュを張るか指定できます。基本オンにしておいていいと思います。

##WorldUvMapper
切断面にテクスチャを張るスクリプト。
###Scale
テクスチャの大きさを指定します。

##ShatterOnCollision
何かがぶつかったときに破壊するためのスクリプト。
###RequiredVelocity
どれくらいの勢いでぶつかったら破壊するか。
###CooldownTime
破壊した後何秒間、破壊を待機するか。

#切断面のテクスチャを変える
![11.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344267/131493d7-14bb-c4e2-d183-4e82e52f5d08.png)
先ほどのWorldUvMapperをTargetUvMapperに変更し、スタート位置と大きさを設定します。
【PHP超初心者】おみくじプログラムを作ってみた

<h2>はじめに</h2>
PHPの超初心者向け書籍を購入し、初めて作ったプログラムを公開します。
rand関数を使って、おみくじプログラムを作ってみました。

<h2>おみくじプログラムの中身</h2>
Omikuji.php

```
<?php
$fortunes = array('大吉','中吉','小吉','末吉','凶');
$result = $fortunes[rand(0, count($fortunes)-1)];
echo "あなたの今日の運命は". $result . "です。". PHP_EOL;
```


発行するとランダムで、今日の運勢が出力されます。
試しに発行してみると、

```
$ php Omikuji.php 
あなたの今日の運命は凶です。
```
凶でした。

<h2>以下使用している関数など</h2>
・array
配列

・rond
乱数を生成する

・PHP_EOL
改行コードを出力する
FIX APIを利用する上で使えそうな動画

中身は英語ですが、参考になりそうです。まぁ大学出てたら英語くらいできますよね（論文書くのに必要だし。。。）
Pythonでの書き方の資料があまりにも少なかったので、これを見て勉強しようと思います。Thanks a lot, Darwinex!!!

[動画1：Introduction](https://www.youtube.com/watch?v=RhPew0ge-kw&list=PLv-cA-4O3y95np0YK9NrKqNKLsORaSjBc&index=6&t=0s)

[動画2：Variable Definitions](https://www.youtube.com/watch?v=RhPew0ge-kw&list=PLv-cA-4O3y95np0YK9NrKqNKLsORaSjBc&index=6&t=0s
)

[動画3：App Configurration](https://www.youtube.com/watch?v=ZM2IEooF72M&list=PLv-cA-4O3y95np0YK9NrKqNKLsORaSjBc&index=7)

[動画4：Logic, Code & Structure](https://www.youtube.com/watch?v=UA_HIDeABNc&list=PLv-cA-4O3y95np0YK9NrKqNKLsORaSjBc&index=8
)

[動画5：Examples in C++ & Python](https://www.youtube.com/watch?v=vhwT8UKwKnU&list=PLv-cA-4O3y95np0YK9NrKqNKLsORaSjBc&index=9)

[動画6：Installing QuickFIX for Python](https://www.youtube.com/watch?v=ecs5NMNdEoA&list=PLv-cA-4O3y95np0YK9NrKqNKLsORaSjBc&index=11)

[動画7：FIX Pricing Class - I](https://www.youtube.com/watch?v=ecs5NMNdEoA&list=PLv-cA-4O3y95np0YK9NrKqNKLsORaSjBc&index=11)

[動画8：FIX Pricing Class - II](https://www.youtube.com/watch?v=YdUS2BqcclQ&list=PLv-cA-4O3y95np0YK9NrKqNKLsORaSjBc&index=12)

[動画9：FIX Pricing Class - III](https://www.youtube.com/watch?v=RjTpi7djKsI&list=PLv-cA-4O3y95np0YK9NrKqNKLsORaSjBc&index=13)
WebAssembly 日本での利用事例 2019年まとめ

他にもあるよ、という方ご連絡ください。追加します。

## パーツとしてWASMを使う事例

アプリを全部WebAssemblyにするというよりは、一部にWebAssembly化したライブラリを使いました、という使い方が出てきているように思います。

* [こえのブログ](https://developers.cyberagent.co.jp/blog/archives/20506/)
* [株式会社ノックノートによるWebゲームでの利用例](https://speakerdeck.com/goccy/pwagemuwokai-fa-sineiteibuapurihua-madesitazhong-defalseke-ti-todui-ce)

この2つは典型的です。

前者はmp3エンコーダーをWASM化して利用しています。ライブラリを再利用するということで、生産性を高めた例かなと思っています。

後者はライブラリを再利用するというよりも、バックエンド / エッジとフロントエンドとでコードを共通化したいという目的から、WASMを利用しています。ハッシュ値生成アルゴリズムを共通化しています。これをバックエンドでC実装を、フロントエンドでJS実装を、それぞれ利用していたとすると、開発、テスト、メンテナンスとコストがかさんで仕方がないでしょう。WASMにすることで、これらのコストが下がっている点も注目すべきだと思います。

## 他言語の資産をWebに持ち込んだ事例 

アプリケーション全体を移植している例としては、[vim.wasm](https://github.com/rhysd/vim.wasm
)があります。vimをWASM化しています。vimの移植性の高さを利用しているのが特徴です。Webを1つのグラフィックスフレームワークとして捉えることで、大きくコードを変更することなく移植を行っています。

また独自のイベントループを持つGUIアプリを、既にイベントループのあるWebに移植するために、WebWorkerとSharedArrayBuffer, Atomics APIを利用している点も興味深いです。[詳細はREADMEに記述されています](https://github.com/rhysd/vim.wasm/blob/wasm/README.md)。

スクラッチから書かれたものとしては、[GopherBoy](https://bokuweb.github.io/gopher-boy/)があります。Goで書かれたGameboyエミュレータです。[Gocon2019で講演がありました](https://speakerdeck.com/bokuweb/gocon2019)。詳細はそちらをどうぞ。

vim.wasmも、GopherBoyも、どちらもWASM化されたあと、第3者によってWebアプリに組み込まれている点も興味深いです。WASM化することで非Webの資産が、Webのエコシステムへの組み込みが可能になっています。

## まとめ

以前は、スマホアプリを全てWebに持ってくることで高いUXを提供し、Royalityユーザとのエンゲージメントを高めるといった使い方をされている事例が目立っていましたが、今年はWebのエコシステムに他言語の資産を組み入れるという使い方が増えているように思います。

とくにバッグエンドとフロントとでコードを共通化するという使用例は、メンテナンスコストが議論されていることを踏まえると興味深いと思っています。[Fastly](https://www.fastly.com/blog/announcing-lucet-fastly-native-webassembly-compiler-runtime)や[Cloudflare](https://developers.cloudflare.com/workers/archive/webassembly/)の取り組みを踏まえると、エッジとフロントでコードを共有するための仕組みとして利用する例も増えてくるかもしれません。

またブラウザ外での利用も増えてゆくと期待しています。[wamerはPythonなどの言語に安全でポータブルなネイティブプラグインを実現しています](https://pypi.org/project/wasmer/)。[WASMのES Module integrationの標準化](https://github.com/WebAssembly/esm-integration)と実装が進めば、NodeJSでの利用もしやすくなり、デュプロイや配布に関するトラブルがへる、といったことも期待されます。

安全なネイティブコードの実行環境という点では、[WebAssembly System Interface](https://wasi.dev/)も興味深く、また期待も高まっています。組み込みから、コンテナまで、多様な期待がありますが、どうなるかはまだまだ未知数で、楽しみです。
デバッグメモ：SageMakerでNo space left on device問題

# 障害概要
SageMakerのノートブックインスタンス上でimport文を実行すると、失敗する。

# 発生原因
エラーメッセージを見ると、`No space left on device`という文字がある。
`df -f`を実行したところ確かに使用しているファイルシステムの利用率が100%だった。

# 対応内容
削除しても問題なさそうなファイルを消しても、400kbしか容量を確保できなかった。
なので、notbookインスタンスのボリュームサイズを5GBから15GBに変更する。

# メモ
- [Inodeの枯渇が原因で容量が十分にあっても`No space left on device`が出ることがある。](http://3.1415.jp/sa5pox9m/)
- /tmp/ディレクトリで10GBまでファイルを保存できるが、一時ディレクトリなのでファイルの永続性はない。
- /home/ec2-user/SageMaker/では、ノートブックインスタンスを停止してもファイルは残る。

# 参考リンク
`No space left on device`について
https://tackeyy.com/blog/posts/process-of-solving-disc-full-on-ubuntu-server
RailsのDM一覧に最後のメッセージを表示させる方法

#はじめに
[記事①](https://qiita.com/nojinoji/items/2b3f8309a31cc6d88d03)と[記事②](https://novice-programmer.com/dm_index/)を参考にDM機能を作らせていただきました。投稿してくださった方々に深く感謝いたします。
以下は[記事①](https://qiita.com/nojinoji/items/2b3f8309a31cc6d88d03)の通りにDM機能を作成した前提で進めます。

#やりたいこと
TwitterやLINEのようにメッセージの一覧に最後のメッセージを表記させる。

#実装
[記事①](https://qiita.com/nojinoji/items/2b3f8309a31cc6d88d03)通りに進めるとメッセージ一覧はrooms#indexに表示させることになると思うので、以下のようにすればユーザ間の最後のメッセージを引っ張ってくることができます。

まず、[記事②](https://novice-programmer.com/dm_index/)を参考にroomsコントローラ側に`@anotherEntries`を定義します。

```ruby:roomsコントローラー
def index
  @currentEntries = current_user.entries
  myRoomIds = []

  @currentEntries.each do | entry |
    myRoomIds << entry.room.id
  end

  @anotherEntries = Entry.where(room_id: myRoomIds).where('user_id != ?', @user.id)
end
```

そして、`@anotherEntries`にはuser_idが自分のidではない相手の情報が配列として入っているので、以下のようにすればやりとりした最後のメッセージを引っ張ってこられます。


```erb:rooms#index
<% @anotherEntries.each do |e| %>
  <%= Message.find_by(id: e.room.message_ids.last).content %>
<% end %>
```
上はただ表記させただけなので、あとは自分好みにリンクにしたり字数に制限をかけたりしてみてください。
また、ここでは最後のメッセージを表示させましたが、上記の`content`の部分を`user.name`にすれば最後にメッセージを送ったユーザ(自分か相手)の名前を引っ張ってくることもできます。
就職がめんどくさかった新卒就活サービスエンジニアの話

:calendar_spiral: [i-plug Advent Calendar 2019](https://qiita.com/advent-calendar/2019/i-plug) の【1日目】の記事です:santa::tada:
## こんにちは！

新卒ダイレクトリクルーティングサービス OfferBox を運営している株式会社[i-plug(アイプラグ)](http://i-plug.co.jp/)の宮崎:santa_tone2:と村治:santa:です！

弊社のAdventCalender:calendar_spiral:をご欄いただき
**:raised_hands_tone1: ありがとうございます :raised_hands_tone1:** ＼\ｱﾘｶﾞﾀﾔｰ/／

第一弾として、新卒エンジニア[大野木](https://qiita.com/nogissh)についてご紹介します。
![ohnogi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535485/f2665b5b-07d3-27dd-9d24-2c99adb3766a.png)
彼は2019年4月に、大阪のベンチャー「[i-plug(アイプラグ)](http://i-plug.co.jp/)」で初めての新卒エンジニアとして入社しました。
学生時代は、なんとなく自分が「おもしろい」と思ったプロダクトの開発をしてきた彼。入社から8ヶ月が経った現在では、「社会人になると “おもしろい” だけじゃいけないんだ。」ということに気づきました。

新卒エンジニアが、“入社から取り組んできたこと”。さらに、“そこから得た学び”までインタビュー形式で答えてもらいました。

- 学生エンジニア
- 新卒エンジニア

といった、近い立場にあるエンジニアの方に、少しでも共感できる部分があれば幸いです。

## 1.学生時代はどんなことをしていましたか？

- - DJing x 機械学習 : おもしろさを追求した研究
    - 　以前からDJが好きだったので、『公開状態のプレイリストをデータに用いて、新しいプレイリストを作る』というテーマで研究していました。世にあるプレイリスト作成サービスや機能が作るプレイリストを「より良い曲順にできるんじゃないか」とも思っていて、単純におもしろそうかな、と。
- 具体的にはどんなことでしょう？
    - 　最適解探索アルゴリズムのひとつである、遺伝的アルゴリズムを用いたプレイリスト生成手法を検討していました。最適解が何か？という評価関数は自分で作る必要がありました。評価関数で使う指標は、公開されているDJのセットリストから学習したモデルを用いて、最適解を導き出していました。
- いま学生時代を振り返ると、どうですか？
    - 　学生時代からアプリやシステムを作ったりしていて、そこそこ自信はありました。ただ、作るときのモチベーションは「こんなものがあったら、おもしろそうだな。」といったもの。自分のおもしろいと思ったことを追求していて、今思えばユーザーのことはあまり意識していなかったですね。

## 2.どうやって就職しましたか？
- 就職活動やi-plugとの出会いについて教えてください。
    - 　たくさんのエントリーシートを書き、同じ基準でふるいに掛けられる就職活動。正直「めんどくさいな」と思っていました。そんな時、たまたまNHKの「クローズアップ現代」で i-plug が取り上げられていたんです。そこで、従来のエントリー型ではなく、直接ダイレクトリクルーティング型というものを初めて知りました。
    - 　企業からアプローチしてもらえる。これはおもしろそうだ、と。そこで[OfferBox](https://offerbox.jp/)を登録して使い始めました。そんな中で、“i-plug も新卒募集をしている”ことを知り、話を聞きに。これがi-plugとの出会いでした。
    - 　自分は社で初めての新卒エンジニアでした。人事の方とお話したところ「エンジニアの新卒募集はしてないよ」って。結局は内定をいただきましたが。
       その後、CTOとも面談し、『機械学習を用いた学生や企業にとって最適なマッチング』をしていると聞いて、さらに興味を深めていきました。

## 3.入社後はどんなことをしてきましたか？
- 入社後の取り組みは？
    - 　【1.現状把握】まずは“自社プロダクトの中身”の把握と理解から始まりました。
    - 　【2.共有】日々のタスクをこなす中で、自分が思っている認識と他のメンバーの認識があっているのかすり合わせをしたいと思い、その都度、勉強会のようなことを実施してみました。
    - 　【3.起案】少しずつ仕事に慣れてくると、やりたいことが増えてきました。「もっと学生の行動や特性を拾えるような仕組みがあったほうが良い」と感じ、週に1度、数人のメンバーで討論会のようなことをしました。いろいろアイデアは考えたものの、実現には至っていません。
- 学生時代と入社後でどんな違いがありましたか？
    - 　これまでは「これを作ったほうがおもしろいんじゃないか」とか、個人的な視点やモチベーションでアプリ開発をしていましたが、i-plugに入社後は**「作ったもので、どうお金を回収するのか？」「作ったもので、どういう価値を提供するのか？」**といった視点が必要だ、と気づくことができました。

## 4.今はどんなことをしていますか？

私は学生時代とは違った気づきを得て、現在はマーケティングの勉強や、価値をどうやってお金に変えるかということ考えています。また、メイン業務の開発をしながら、社内の経営者やマーケッターが、普段どういった活動をしているのかヒアリングをして、エンジニアリングとは違った学びを深めようとしています。

## 編集後記

卒業から8ヶ月:hourglass:新たな生活は始まったばかりですが、学生時代と違う気づきを得ながら社会人生活を送る彼の、意欲に溢れる声が聞けました:star2:


:santa_tone2:弊社 **i-plug** のAdventCalender:calendar_spiral: を引き続きご覧ください!!!:santa:
【Python】機械学習用にIcrawlerで画像を収集【1000枚】

#結論

```python
# coding: utf-8
import os
from icrawler.builtin import GoogleImageCrawler

"""----------------   Settings   ------------------"""
search_word = u"猫"#日本語の場合は、頭に"u"をつける
dir_ = "./images/"+search_word+"/"
download_num = 1000 #ダウンロードする枚数
"""--------------------------------------------------"""


if not os.path.exists(dir_):#フォルダが無ければ作る
    os.makedirs(dir_)

crawler = GoogleImageCrawler(storage={"root_dir": dir_})
crawler.crawl(keyword=search_word, max_num=download_num)
```