OmniAICreator/Qiita-1.07M huggingface dataset:
Node.jsでTwitterを自動化する

https://adventar.org/calendars/4650
OUCC(大阪大学コンピュータクラブ)のアドベントカレンダー12日目です。

Node.jsのtwitterモジュールでtwitterAPIを叩きました。
モジュールの更新が2017年で止まっており、一部機能が使えなくなっています。
先駆者の皆さんの記事のコードが動かないこともありました。

# ツイートする
twitter APIを取得して、API key, API secret key, Access token, Access token secretを取得しました。これに関しても参照ページからほかの方の記事をご覧ください。

送信できる環境が整ったので、ひとまずtwitterモジュールからツイートしてみました。

```
//モジュールの読み込み
const twitter = require('twitter');

//ツイート内容
const text = 'test'

//上からAPI key, API secret key, Access token, Access token secret
const client = new twitter({
    consumer_key        : "-----------",
    consumer_secret     : "-----------",
    access_token_key    : "-----------",
    access_token_secret : "-----------"
});

client.post('statuses/update', {status: text}, function(error, tweet, response) {
  if (!error) {
    console.log(tweet);
  }
});

```
これでちゃんとツイートできました。定期的に実行すればbotが作れますね。

# いいねを送信する
キーワードでツイートを検索して、いいねを送信していきます。
streamモジュールというものが以前は使えたらしいのですが、2019年春ごろから使えなくなっているようです。
モジュールの更新が2017年で止まっているので仕方ないですね。
そんなわけでstreamなしでやっていきます。

```
//モジュールの読み込み
const twitter = require('twitter');

//上からAPI key, API secret key, Access token, Access token secret
const client = new twitter({
    consumer_key        : "-----------",
    consumer_secret     : "-----------",
    access_token_key    : "-----------",
    access_token_secret : "-----------"
});

async function searchTweet(queryArg, nextResultsMaxIdArg = null) {
    client.get('search/tweets', { q: queryArg, count: 1, max_id: nextResultsMaxIdArg }, async (error, searchData, response) => {

      if (error) console.log(error);

      for (item in searchData.statuses) {
        const tweet = searchData.statuses[item];

      await client.post('https://api.twitter.com/1.1/friendships/create.json', {screen_name: tweet.user.screen_name}, () => {
        console.log(`\n${tweet.user.screen_name}さんをフォローしました。\n`);
      });

      //検索に失敗
      if (searchData.search_metadata == undefined) {
        console.log('no metadata');
      }

      else if (searchData.search_metadata.next_results) {
        let maxId = searchData.search_metadata.next_results.match(/\?max_id=(\d*)/);
        searchTweet(queryArg, maxId[1]);
      }
    }
  });
}

searchTweet('検索ワード');

```
postの内容を改変すればフォローもできます。


# バージョン
Node.js : 12.13.1

### モジュール
twitter : 6.13.1

# 参考ページ
twitterモジュール公式
https://www.npmjs.com/package/twitter

twitterAPIの解説
https://syncer.jp/Web/API/Twitter/REST_API/

bot作成の記事
https://yukimonkey.com/js-application/twitter-bot-2/

twitterモジュールの機能を一通り使った記事
https://tasoweb.hatenablog.com/entry/2018/06/01/002438
【初心者】メソッド一覧

###resources メソッド

```使用例.rb
Rails.application.routes.draw do
  resources :posts
end
```

###form_with メソッド
Rails 5.1というバージョンから推奨されている、
フォーム実装のためのヘルパーメソッド。

**■特徴**
1.form_withで自動でパスを選択してくれて、HTTPメソッドを指定する必要を無くす
2.コントローラーから渡された、ActiveRecordを継承するモデルのインスタンスが利用する事ができる
3.form_withではinputタグを使用しない

###redirect_to メソッド
```
redirect_to "リダイレクト先のパス"
```
コントローラー等での処理が終わった後に、アクションに対応するビューファイルを参照せずに、別ページへリダイレクトさせる為のメソッド。

##updateメソッド
```記入例.rb
  def update
    post = Post.find(params[:id])
    post.update(post_params)
  end
```
ActiveRecordのメソッドの一つ。
レコードに含まれている情報を更新する事ができる。
Rails Girls Nagoya 5thを開催します！

この記事は[Rails Girls Japan Advent Calendar](https://qiita.com/advent-calendar/2019/railsgirlsjapan) 6日目の記事です。
前回は3日目@rllllhoさんの[RailsGirlsでオーガナイザーをする時のやることリストとスケジュール](http://rlho.hatenablog.com/entry/railsgirls11th)でした。

初めまして！
RailsGirlsとの出会いからはや半年、この度 Nagoya5thのオーガナイザーを務めることになりました
chiroruと申します。

今日はこれから開催するNagoya5thの紹介と、せっかくなので、私がオーガナイザーになるまでの経緯も合わせて書いていきたいと思います。

#RailsGirlsとの出会い
私がRailsGirlsを知ったのは、RailsGirls Kitakyusyuで以前オーガナイザーをされたYukaさんのブログを読んだことがきっかけでした。

ちょうどその頃、私はRailsの勉強を始めたばかりで、まだコミュニティや勉強会の存在も知らなかったため、会って話せる仲間が欲しいという思いがありました。

そんな時にYukaさんのブログを読んで、初学者女性向けのこのイベントに興味を持ち、早速申し込みをすることにしました。しかし地元での開催予定が無かったため、２週間後の開催であったOsakaに、キャンセル待ちの5人目として申し込みをしました。(完全にダメ元でした)
そして開催4日前、なんとか参加できることに決まりました。(とっても嬉しかった！)

こうして私はRailsGirls Osakaで初めてイベントに参加し、RailsGirlsの仲間入りを果たすことができました。

#RailsGirlsに参加して変わったこと
【参加する前】
・Railsを学んでいる人やエンジニアを目指している人が身近にいませんでした。
　(私の場合は特に、同じ女性の方との出会いが欲しいなと思っていました)
・情報交換の場がオンライン上に限られていました。



【参加した後】
・Osakaでの出会いを通して、Nagoyaチームの方とも知り合うことができました。
（→一緒に定期勉強会に参加させてもらったり、RWCなどのイベントに参加してみたり）
・いろんな所で勉強会が開催されていることを知り、身近な場所に仲間を見つけました。

#そして現在…
前回Girlsとして参加をして、プログラミングを通じて多くの人と繋がる楽しさを知りました。
だから今度はこのような場を、提供する側としてRailsGirlsに携わりたい！多くの人と繋がって一緒に楽しみたい！という思いを持ちました。

そしてOsakaで繋がった方から、地元の愛知でまたRailsGirlsの企画をしていると聞き、その紹介で
Nagoyaのオーガナイザーになることができました！


#Rails Girls Nagoya5thを開催します!
告知です！
2020年1月31日・2月1日にRailsGirls Nagoya 5thを開催します。
本日より、Girls申し込みの受付も開始しておりますので、興味がある方は
以下のサイトよりお申し込みください。

情報公開中（http://railsgirls.com/nagoya ）
申し込みサイト（https://railsgirls-nagoya.doorkeeper.jp/events/101526）

それでは、またお会いしましょう！
Chiselトラブル集

## はじめに

めんたるしんでるのでまちがいがあったら優しく教えてください

## Javaのバージョン依存によるトラブル回避

ScalaはJavaの派生なのでJavaのバージョン次第では動かなくなることが多々あります
自分の場合はScalaバージョン2.11、Java-11の組み合わせで動かしたらめっさ怒られた...
Scala2.11はJava-8との組み合わせで元気になりました
余談ではありますが、Scala2.12とJava-11もとっても仲がよかったです
以下Javaのバージョン変更コマンド

```
$ sudo update-alternatives --config java
$ sudo update-alternatives --config javac
```

## おわり

何かあったらここに足していこうと思います
テーブルをjoinせずに値を取ってみた

Eccubeでdoctrineのselect()で遊んでみた記録です。

OrderにOrderStatusをjoinせずに受注ステータスを取ってみました。

#### まずは、OrderRepositoryの$qbの用意

```
$qb = $GLOBALS['kernel']->getContainer()
      ->get(\Eccube\Repository\OrderRepository::class)
      ->createQueryBuilder('o');
```


#### joinせずに受注ステータスを取ってみた
```
$qb
    ->select(
        '(SELECT os.name FROM \Eccube\Entity\Master\OrderStatus AS os WHERE os = o.OrderStatus)'
    );

$qb->getQuery()->getResult();
```

select()に入れればなんでもできそうでなかなか面白いです。

＊素晴らしいSQLを目指したものではなく、ただの遊びです。
Amazon Fraud Detector がAWS re:Invent 2019で発表されました！

この記事は株式会社ナレッジコミュニケーションが運営する[Amazon AI by ナレコム Advent Calendar 2019](https://qiita.com/advent-calendar/2019/knowcom-amazonai)の13日目にあたる記事になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229923/69986cd3-e48a-eee1-7ab5-dd160249a16d.png)

##はじめに
AWS re:Invent 2019にてオンライン詐欺を検出するサービスが発表されたのでまとめていきたいと思います。
Amazon Fraud Detectorは、Amazon Fraud Detectorはフルマネージドサービスで、オンライン支払い詐欺や偽のアカウントの作成など、潜在的に不正なオンラインアクティビティを簡単に特定できます。機械学習（ML）とAWSおよびAmazon.comの20年にわたる不正検出の専門知識を使用して、不正行為の可能性を自動的に特定し、より多くの不正行為を迅速に発見できるようにします。Amazon Fraud Detectorを使用すると、不正な検出のすべてを機械学習（ML）で処理するため、数回クリックするだけで、機械学習（ML）の経験がなくとも不正検出モデルを簡単に作成することができます。


2019/12/06 現在はプレビューの為、米国東部（バージニア北部）リージョンでのみ利用可能です。

###検出できるアクティビティ
![2019-12-06_20h30_18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229923/3d0a72d0-3599-0349-1bb1-9870433b2304.png)

- New account

正当な顧客アカウント登録とリスクの高い顧客アカウント登録を区別して、リスクに基づいて追加の手順またはチェックを選択的に導入できるようにします。たとえば、顧客アカウント登録ワークフローを設定して、リスクの高い特性を示すアカウント登録に対してのみ追加の電子メールと電話の確認手順を要求できます

- Guest checkout

取引履歴のない顧客間でも潜在的な不正行為を検出します。通常、定期的に取引を行うお客様は、登録済みアカウントを使用します。その結果、取引の履歴があるため、潜在的な不正行為を簡単に特定できます。一方、ゲストチェックアウトには、過去のアカウント使用状況やユーザーの行動データがないため、不正行為の検出がはるかに困難になります。Amazon Fraud Detectorを使用すると、潜在的な不正リスクを評価するために、ゲストのチェックアウト注文からEメールとIPアドレスを送信することができるため、それを受け入れるか、確認するか、顧客の詳細を収集するかを決定できます。 

- ‘Try Before You Buy’ service abuse

支払いを送信する前に調査のために衣類やアクセサリーを発送するファッションサービスなど、「購入する前に試してください」プログラムを悪用する可能性が高いアカウントを特定します。Amazon Fraud Detectorを使用すると、オンラインビジネスは顧客がサービス条件に違反するリスクを評価し、サービス条件に違反する状態で商品が盗まれたり返品されたりしないように、提供される商品またはサービスの価値に制限を設定できます。

- Online payment ※近日公開予定
- 
支払いを処理して注文を履行する前に、疑わしいオンライン支払いトランザクションにフラグを立てることにより、オンライン支払い詐欺を減らします。Amazon Fraud Detectorを使用すると、チェックアウトフローを設定して、新しい注文を評価し、疑わしい注文にフラグを付けて、支払いを処理する前に確認して、クレジットカードのチャージバックを減らすことができます。

###使い方
プレビューの為、申込みが必要となります。
以下、[Amazon Fraud Detector 機能](https://aws.amazon.com/jp/fraud-detector/features/)で公開されている使用方法になります。


- 5つのステップでAmazon Fraud Detectorの使用を開始する
 
```
ステップ1:過去の不正データセットをAmazon S3にアップロードします
```

```
ステップ2:事前に作成された不正検出モデルテンプレートから選択します
```

```
ステップ3:モデルテンプレートは履歴データを入力として使用して、カスタムモデルを構築します。モデルテンプレートは、データを検査および強化し、機能エンジニアリングを実行し、アルゴリズムを選択し、モデルをトレーニングおよび調整し、モデルをホストします
```

```
ステップ4:モデル予測に基づいて詳細情報を受け入れ、レビュー、または収集するルールを作成します
```

```
ステップ5:オンラインアプリケーションからAmazon Fraud Detector APIを呼び出して、リアルタイムの不正予測を受信し、設定された検出ルールに基づいてアクションを実行します。たとえば、eコマースアプリケーションは、電子メールとIPアドレスを送信し、不正スコアとルールからの出力（レビューなど）を受信できます
```

###価格
[Amazon Fraud Detector 価格](https://aws.amazon.com/jp/fraud-detector/pricing/)が公開されております。
※無料試用枠があります。
![2019-12-06_20h26_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229923/107c6fb2-4f9c-3a19-d25e-9714e694878d.png)



##おわりに
現在プレビュー中の為、参考ドキュメント等少ないですがアップデートがあればご紹介したいと思います。

###関連URL
- [Amazon Fraud Detector](https://aws.amazon.com/jp/fraud-detector/)
- [AWS re:Invent 2019](http://reinvent.awseventsjapan.com/)
Solaris 10にApacheをインストールする

Solaris 10にApacheをインストールする機会があったので、備忘録的に。

そもそも、Solarisを使ったことがほとんどなかったので。


# 環境

対象の環境はこちら。

```shell
$ cat /etc/release 
                    Oracle Solaris 10 1/13 s10x_u11wos_24a X86
  Copyright (c) 1983, 2013, Oracle and/or its affiliates. All rights reserved.
                            Assembled 17 January 2013
```

環境はVagrantで用意し、こちらの仮想マシンイメージを使用しました。

[tnarik/solaris10-minimal](https://app.vagrantup.com/tnarik/boxes/solaris10-minimal)


# OpenCSWからApacheのパッケージを探してインストール

`pkgutil`コマンドで探すのが良さそうです。

```shell
$ sudo pkgutil -a | grep apache
```

こちらのサイトから、探してくるようですね。

[OpenCSW Solaris package archive](http://mirror.opencsw.org/)

実行結果。

```shell
$ sudo pkgutil -a | grep apache   
apache2              CSWapache2           2.2.34,REV=2018.03.28      920.5 KB
apache24             CSWapache24          2.4.41,REV=2019.08.15        3.7 MB
apache24_dev         CSWapache24-dev      2.4.41,REV=2019.08.15      188.3 KB
apache24_manual      CSWapache24-manual   2.4.41,REV=2019.08.15        5.5 MB
apache2_dev          CSWapache2-dev       2.2.34,REV=2018.03.28      130.7 KB
apache2_devel_stub   CSWapache2-devel     2.2.32,REV=2017.02.10        9.3 KB
apache2_manual       CSWapache2-manual    2.2.34,REV=2018.03.28        2.9 MB
apache2_utils        CSWapache2-utils     2.2.34,REV=2018.03.28       73.8 KB
apache2c             CSWapache2c          2.2.34,REV=2018.03.28        9.1 KB
apache2rt            CSWapache2rt         2.2.34,REV=2018.03.28        9.4 KB
pm_apache_log_parser CSWpm-apache-log-parser 0.02,REV=2013.12.19         15.6 KB
```

Apache 2.4をインストールします。

```shell
$ sudo pkgutil -i apache24
```

インストール先は、こちら。

```shell
/opt/csw/sbin/amd64/httpd
/opt/csw/sbin/amd64/apachectl
/opt/csw/sbin/apachectl

/opt/csw/lib/apache2
/opt/csw/lib/amd64/apache2

# ログ
/var/opt/csw/log/apache2

# 設定ファイル
/etc/opt/csw/apache2
```

余談ですが、Apache 2.2だとだいぶディレクトリ構成（インストール先）が違いました。

サービス名を検索。

```shell
$ svcs | grep apache               
online         11:33:44 svc:/network/cswapache24:default
```

再起動。

```shell
$ sudo svcadm restart cswapache24
```

とりあえず。


# プロキシ環境下なら

環境変数を`export`して

```shell
$ export http_proxy=http://your-proxy-host:your-proxy-port
$ export https_proxy=http://your-proxy-host:your-proxy-port
```

`sudo`を`-E`オプション付きで実行するとよいでしょう。

```shell
$ sudo -E pkgutil -a | grep apache
$ sudo -E pkgutil -i apache24
```
MySQLでここ最近廃止・非推奨となった機能

MySQLは2015年に5.7、2018年4月に8.0のメジャーバージョンがGAとなり、その後も最新の8.0系についてはおよそ3ヶ月ごとのメンテナンスリリースでCHECK制約、CLONEプラグイン、INSTANT ADD COLUMNなど多くの新機能が追加されています。
一方で、新しいリリースで従来の機能が廃止または非推奨となることもあり、アップグレードの際には注意が必要となります。（大抵非推奨となった次のメジャーリリースで廃止されるため、突然問題となることは少ないです）

全てを紹介することはできませんが、目立つものや話題になったものについて幾つか挙げてみたいと思います。おおよそ5.6〜8.0の間を対象としています。


# システム・ユーザ関連
### mysql_upgrade
MySQLでは従来、パッケージのアップグレード後に `mysql_upgrade` コマンドを実行してテーブルの互換性チェックとアップグレードを行う必要がありました。
8.0.16からは、本機能を実行することなくアップグレードすることが可能となり、 `mysql_upgrade` は非推奨となりました。

### 環境変数 `MYSQL_PWD`
MySQLでは、CLIによるログイン実行時などに `-p` オプションを付与しなかった場合、OSに環境変数 `MYSQL_PWD` が定義されていればそれを用いてログインを試行する機能がありますが、8.0.18において本機能はセキュリティ上の観点から非推奨、かつ将来のリリースで削除予定となりました。

### SUPER権限
MySQLで管理者向け機能を利用する際、多くはSUPER権限が必要でした。
8.0からは非推奨となり、代替として[動的権限 (xxxx_ADMIN) の使用](https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html#dynamic-privileges-migration-from-super)が推奨されています。

### validate_password
（機能の廃止ではないですが、互換性のない変更のため取り上げます）
MySQL5.7で、パスワードの複雑さ（文字種、文字列長）を検証する `validate_password` というプラグインが追加されましたが、8.0からはプラグインでなくコンポーネントという扱いになりました。削除する場合は、 `uninstall component` コマンドを実行します。

```
uninstall component 'file://component_validate_password';
```


# パラメータ関連
### sql_mode='NO_AUTO_CREATE_USER'
システム変数 `sql_mode` に指定することで、存在しないユーザに対するGRANT文を実行した時にユーザが自動作成されることを禁止できました。
5.7ではデフォルト設定されており、削除することで従来のGRANT文によるユーザ作成を行うことができましたが、8.0からは本パラメータが廃止され、GRANT文でユーザを作成することは完全に不可能になりました。

### innodb_undo_tablespaces
InnoDBにおけるUNDO表領域の数を定義する `innodb_undo_tablespaces` というパラメータがあり、5.7以前ではデフォルトが0（システム表領域内にUNDO表領域を作成する）でしたが、8.0GA以降は「デフォルト2、かつ最小値2」となり、さらに8.0.14以降は「変更不可能、かつ将来のリリースで削除予定」となりました。

# データ型
### 旧形式の日付・時刻型
MySQL5.6.4より前に使用されていた、マイクロ秒非対応のTIME、DATETIME、および TIMESTAMPは8.0で廃止されました。
MySQL5.7にアップグレードした後、 `mysql_upgrade` を実行することで新形式の日付・時刻型に修正されるため、順当にバージョンアップしている場合は問題にならないと思われます。
参考：[MySQL 8.0: Removing support for old temporal datatypes](https://mysqlserverteam.com/mysql-8-0-removing-support-for-old-temporal-datatypes/)

# SQL関連
### GROUP BY 〜 DESCの廃止
以前のMySQLでは、GROUP BY句の末尾に `DESC` を付与することでORDER BY句なしに降順ソートすることができましたが、8.0.13でこの機能は廃止されました。
JavaScriptでCookieを使う

# JavaScriptでCookieを使う

## 保存
```javascript
document.cookie = "hoge=test";  // hoge=test
```

## 取得
全部取得しちゃう．「；」区切りになっているので，「；」を元に文字列操作する必要がある．

```javascript
document.cookie
```

## 削除
```javascript
document.cookie = "削除対象の名前=; max-age=0";
```
Processingのテキスト表示メモ

Processingでウィンドウにテキストを表示させるコードです。

よく忘れがちなので、メモがてら記事に残します。

#コード

```showText.pde
//フォント用の変数を準備
PFont myFont;
 
void setup() {
 size(200, 200);
 
 //フォントを読み込む
 myFont = createFont("Arial", 30); 
 
 //座標の基準
  //textAlign(CENTER, CENTER);
}
 
void draw() {
  background(255);
  fill(0);
 
 //フォントとサイズを適用
  textFont(myFont, 32); 
 //これでテキストのサイズを変えることも可能
  textSize(20);
 
 //テキスト表示
  text("hoge", 0, height);
}
```

上記のコードをそのまま実行すると、こうなります。
<img width="209" alt="showText.pde" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298379/fe470e53-3762-cd0a-61cb-f54c0445484a.png">

#注意すべき点
- `createFont()`の代わりに`loadFont()`ってやつもありますが、`createFont()`の方が脳死で使えます。

    - 説明は省きます。以下のサイトに分かりやすく載ってます。
        - [5.5　テキストの表示 - Yasushi Noguchi Class](http://r-dimension.xsrv.jp/classes_j/system_font/)

- テキストの色を指定するのは`fill()`です。

- テキストの座標基準は、実行例を見ると分かるように、左下が基準になっています。

    - この座標指定が面倒くさいので、`textAlign(CENTER, CENTER);`で座標の基準を真ん中した方が分かりやすいです。
    
        - textAlign(水平方向の基準, 垂直方向の基準);
        
            - 水平方向の基準→LEFT(左), CENTER(中央), RIGHT(右)
            
            - 垂直方向の基準→TOP(上), CENTER(中央), BASELINE(上のhogeだったらgの下が見切れる), BOTTOM(下)
コンテナ・オーケストレーションで使うストレージをAIで使うには？

毎度、ググっても出てこない小ネタを取り扱っております。
本記事は個人的な見解であり、筆者の所属するいかなる団体にも関係ございません。

# 0. 某所で以下の発表をしたのですが、資料をアップしていなかったので省略版をQiitaに書いておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/b5501378-005b-ca62-df27-f8e7bf07c421.png)

# 1. お題

AIでコンテナ＆コンテナでストレージ

## 1-1. コンテナとAIとGPUの関係
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/51da945f-2f85-9daf-a1f3-60cdd37cf71d.png)

## 1-2. コンテナとストレージの関係
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/c7e4c366-a304-c14f-d383-138133c15ca5.png)

# 2. よくある開発風景

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/e4d27841-40bb-b8a8-a5ef-8df4726179d0.png)

# 3. コンテナだと....。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/591d756d-a16e-a4cd-fe91-0a71864b6e97.png)

# 4. しかし、困ったことが

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/a655cc72-809f-1f6a-d97e-7f869040bf56.png)

# 5. ダメじゃん
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/3158f5c2-5963-1171-b8a0-0b0eee8465a4.png)

# 6. KubernetesにCSI(※)が追加された
Kubernetesから外部ストレージを管理するインターフェース(規格)としてCSI(※Container Storage Interface)が規定されました(2018/12)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/ff9355b8-f06c-eee3-9ed0-c0839bd1cc4f.png)

# 7. CSIは何か？

* コンテナ(正確にはPod)から外部ストレージを切り出してマウントできるようにするプラグインの規格
* この規格に沿ったプロビジョナーと言われるストレージを管理するプラグインを書けば、外部のストレージをPodにマウントすることができるようになる


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/4a6521df-69c7-3f0e-da0f-eb895946f889.png)

# 8.  これができるようになると何が出来るか？

* コンテナ内の領域にデータをダウンロードして演算が可能になりました
* コンテナ領域を外部のストレージに用意することをプロビジョニングといいます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/b31d37d6-c5ae-7a49-7cf2-b658a19cc7be.png)

# 9. CSIで実現されるストレージ接続機構

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/8f19657a-a637-9473-900d-75ddf57ce392.png)

# 10. Kubernetesに使われるプロビジョナー
## 10-1. NetAppさんのストレージのプロビジョナー
* NetAppさんのKubernetes接続ストレージは以下の2つ
  * SolidFire
  * FAS
* 上記に接続できるプロビジョナー
  * Trident

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/d350b77d-407a-fc91-05dc-57d760c58717.png)

## 10-2. DELL/EMCさんのプロビジョナー

* DELL/EMCさんのKubernetes接続ストレージは以下の2つ
  * VxFlex OS
* 上記に接続できるプロビジョナー
  * CSI Driver for Dell EMC VxFlexOShttps://github.com/dell/csi-vxflexos


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/818741d1-5b22-6871-71e1-aca364a0d574.png)

## 10-3. IBMさんのストレージのプロビジョナー

* IBMさんのKubernetes接続ストレージ
  * IBM block storage
  * IBM Spectrum Scale
* 上記に接続できるプロビジョナー
  * ubiquity-k8s-provisioner

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/98da4d6f-fa3d-42b2-a737-55f8b98aa353.png)
Rの標準plotで描くグラフ1.折れ線グラフ

これまで僕が蓄積してきたグラフの描き方のサンプルをメモしておきます。
Rのデータセットairqualityを使って、横軸に観測日数、縦軸に気温をとって、ついでにエラーバーも乱数で生成してつけました。

```oresen.R
temp_txt <- expression(paste("Temperature (", degree, "F)"))  # 軸ラベル
tday <- 1:nrow(airquality)
attach(airquality) # こうしておくといちいちairquality$hogehoge と書かなくてよくなる。例えば、'airquality$Ozone'の代わりに'Ozone'と打つだけでいい。
error <- abs(rnorm(nrow(airquality), mean=0, sd=2)) # rnorm()で乱数を生成して誤差としている
plot(tday, Temp, type="o", xlim=c(0,20), ylim=c(50,80), cex=1.2, cex.axis=1.5, las=1, xlab="Day", ylab=temp_txt, cex.lab=1)
arrows(tday, Temp-error, tday, Temp+error, angle=90, length=0.1, code=3)
# code=3で両側に蓋を描ける。
```
これを実行すると下の図のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100982/d5044925-f5a6-b264-93ac-a560874b1a7b.png)

あるいは、次のように、最初にNULLのプロットでグラフの各種引数を埋めておいて、あとからpoints()あるいはlines()でデータをプロットするのもありです。とくにグラフを重ね描きするときはpar(new=T)をおかずにそのままpoints()を使えばいいだけなので、こちらのほうがすっきりすると思います。

```oresen2.R
plot(x=NULL, xlim=c(0,20), ylim=c(50,80), cex=1.2, cex.axis=1.5, las=1, xlab="Day", ylab=temp_txt, cex.lab=1)
points(tday, Temp, type = "o", cex=1.3)
arrows(tday, Temp-error, tday, Temp+error, angle=90, length=0.1, code=3)

```
Azure Video Indexer デモまとめ

## 目的

前回の投稿でAWS Rekognitionについて軽く触れました。
[AWS Rekognition デモまとめ](https://qiita.com/ykajiro/items/02502b8395030862de57)
今回は実際にAzure Video Indexerのデモを体験したので、Rekognition同様に使用感等をみていけたらと思います。

---

## Rekognitionとの違い

Video Indexerは基本的にはRekognitionとできることが同じです。そのため違いを説明していきます。
- UIの違い
- 会話内容トピック
- ブランド認識
- シーン分割
- カスタマイズ性
- 顔の分析/比較(機能がないだけで説明は省略します)

---

## UIの違い 1

Video IndexerはタイムラインというUIがあり、より時間軸を意識した作りとなっています。タイムラインでは下図のようにどんどん情報を追加できます。
<img width="592" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191585/d80ca6f7-7ab7-d94b-5c11-150e8ca922e8.png">

---

## UIの違い 2

プレイヤー部の機能がリッチです。Rekognitionは再生と音声しか制御できませんが、Video Indexerでは再生速度、音声解析した言葉の字幕(背景色なども変更可)、画質設定、全画面、シークサムネイルと機能が揃っています。さらにそれを埋め込みボタンでhtml化してくれました。
<img width="1000" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191585/230377f3-bfc3-b89b-cb34-f953c2e7c008.png">

---

## 会話内容トピック

会話内容からトピックを抽出してくれるようです。逆に会話がない画像ではトピックがなかったです。日本語の解析はまだまだ精度が悪く、そこからできたトピックも精度が悪そうです。
<img width="582" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191585/8082ee14-6902-b9bd-0196-c85dd52c1721.png">

---

## ブランド認識

ブランドを登録しておき、関連リンク等を設定しておけるようです。動画内広告(例えば車のブランドなど)のコンバージョンに影響しそうです。
<img width="1000" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191585/c42fb79c-ca39-25ea-8183-bc28bc92ca88.png">

---

## シーン分割

シーン分割はチャプターのように機能します。キーフレームは画面の構成が変更点を切り取ってくれているような動きに見え、シークサムネイルでも利用してる画像のようでした。
<img width="504" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191585/be0cc7ff-2e91-bad7-84d6-b5fffc8a6416.png">

---

## カスタマイズ性 1

ブランド認識も同様ですが、モデルを拡張することが可能なようです。Rekognitionでは拡張性は見当たらなかったので、ML視点で見るとここは大きな違いかもしれません。
<img width="1000" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191585/089925cb-187a-ceb6-b1f0-f59024773783.png">

---

## カスタマイズ性 2

おそらく動画のクリッピングができる機能のようです。抽出方法は解析したメタを利用できるようでした。動画編集する場合は必要と思いますが、完パケを配信するサービスでは特段必要性は感じませんでした。
<img width="1000" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191585/3d482288-84b1-d5ac-8727-39df923b2be8.png">

---

## 補足情報

解析時間については640x480の1分程の尺の動画を解析するのに6分ほどかかりました。
Rekognitionと異なり、Suggestiveなものはレビュー対象という形で表現されています。怪しい動画はMicrosoft側にレビュー依頼する必要があります。ただし日本語の精度が低いのにつられ、こちらの判定精度も悪いように感じました。
<img width="712" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191585/f6f5190c-f8aa-a002-d390-821670e5cd31.png">

---

## まとめ

Video Indexerの機能を見るとRekognitionは画像解析から端を発する感が強い印象でした。顔の分析/比較機能の有無はそこら辺にありそうです。動画にスコープを絞る場合はVideo Indexerの方が高機能に感じました。
Panasonic の電力計　kw2g から rs485 でデータを読む

ＲＴコマンド を送って、リスポンスを受け取るサンプルです。
プロトコルは MEWTOCOL です。

```py:kw2g.py
#! /usr/bin/python3
#
#       kw2g.py
#
#                                               Dec/07/2019
#
#
# ------------------------------------------------------------------
import  serial
import  time
import  sys

# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
#
ser = serial.Serial(port='/dev/ttyUSB0', baudrate=19200,bytesize=8,parity='O',stopbits=1,timeout = 1)
#
data = ['%','0','1','#','R','T','*','*','\r','\n']
data_int = []
for it in range(len(data)):
        uu = ord(data[it])
        data_int.append(uu)
#
ser.write(bytearray(data_int))
#
time.sleep(0.5)
#
response = []
while True:
        try:
                sys.stderr.write("*** reading ***\n")
                bytesAvailable = ser.inWaiting()
                sys.stderr.write("%d bytes available to read\n" % bytesAvailable)
                response = ser.readline()
                break
        except KeyboardInterrupt:
                break
#
str_hex = "hex: "
str_out = "chr: "
for it in range(len(response)):
        str_hex += " %02x" % response[it]
        str_out += "  %c" % response[it]
print(str_hex)
print(str_out)
ser.close()
#
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

実行結果

```text
$ ./kw2g.py 
*** 開始 ***
*** reading ***
25 bytes available to read
chr:  25 30 31 24 52 54 39 39 34 30 30 31 30 33 30 31 30 30 30 30 30 30 30 31 0d
hex:   %  0  1  $  R  T  9  9  4  0  0  1  0  3  0  1  0  0  0  0  0  0  0  1  
*** 終了 ***
```
Amazon Transcribe Medicalについて調べてみた

この記事は株式会社ナレッジコミュニケーションが運営する [Amazon AI by ナレコム Advent Calendar 2019](https://qiita.com/advent-calendar/2019/knowcom-amazonai) の6日目にあたる記事になります。

# はじめに
今回のメインテーマについて触れる前にAmazon Transcriveについておさらいします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323405/9e57d290-173a-70c1-859c-ab34347bf733.png)

Amazon Transcribeは自動音声認識 (ASR) サービスです。
Amazon Transcribe APIを使用すればS3に保存されたオーディオファイルから音声を文字起こしし、テキストファイルを返したりといったことも実装できます。 
またAmazon Transcribeを使用すれば文字起こしのストリーミングをリアルタイムで受け取ることも可能です。
そして2019年11月には日本語も対応しました！待ち望んでいた方も多いのではないでしょうか。

料金体系も非常にシンプルで秒単位の課金になります。
例えば東京リージョンの価格は1 秒あたり 0.0004USD のレートで月ごとに課金されます。
30分のビデオを文字起こししたとしても100円かからない程度です。お得ですね。
※15 秒未満のリクエストについては 15 秒分の料金が発生します。


# Amazon Transcrive Medical リリース！
Amazon Transcrive MedicalはAmazon Transcribeの新しい認識機能で医療分野で活躍するサービスです。
電子医療記録 (EHR) システム(※1)の標準化が進んできたこともあり、医者と患者の会話などを記録することが重要になってきました。
Amazon Transcrive Medicalはそういったニーズに応えた臨床メモなどを記録することに特化したサービスです。

※1　
異なる医療機関・健康関連組織で別々に管理されている個々人の健康・医療情報を地域／国レベルで集約・統合して共同利用する仕組みのこと。

# 特長
医療業界ではあまり一般的ではない専門用語が数多くありますが、Amazon Transcrive Medicalはそういった単語もカバーします。
また従来の文字起こしサービスの課題であった「点」「丸」「カンマ」「ピリオド」などを言う必要もないのも特徴です。

さらにAmazon Transcrive MedicalはHIPPA(※2)適格の対象です。
[MT Samples](https://www.mtsamples.com/) から匿名化された実際の医療記録をサンプルとして使用できるのでぜひ試してみてください。

※2　
1996 年に制定された米国における医療保険の相互運用性と説明責任に関する法令

# 提供リージョン
2019年12月現在Amazon Transcribe Medical は米国東部 (バージニア北部) と米国西部 (オレゴン)リージョンで利用できます。

# 最後に
AWSが提供するAIサービスはAmazon Transcrive Medicalのように業界に特化したサービスもちらほら提供され始めましたね。
cloudは使えないといった業界は今後どんどん縮小していくのでは、と感じさせる興味深いアップデートでした。
App Launch Mistakes: Know How It Affects the Success of Your App

![isock_uzenzen_rocket.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/279134/bd2f1f6d-23aa-f96f-ace5-682266b52213.jpeg)

By developing a robust app for your business you can assure success as well as more download for your app. Most of the users these days only love to use those apps which provide a better experience and satisfy all their needs. Hence you have to develop your business app keeping in mind various factors and must see that your app development plan revolves around the targeted audience. 

To prevent the abundance of the app users have to focus on developing the best user experience (UX) and user interface (UI). You also have to find different ways to improve your app's first immersion so that users do not just abound it just after the first use. And if you want to provide all over best experience to your app users then it becomes essential for you to pay attention to app launch. 

## Few Mistakes to Avoid While Your App Launch 
Some of the businesses make silly mistakes while launching their app, as a result, their app fails to gain the user's attention. Hence to attract new customers and want to improve their app retention then they have to try to avoid common mistakes which they are making while launching the app. Avoiding all these mistakes during the launching phase can ensure your app success and also get popular in lesser time.  

## App Store Optimization
Mobile developers can improve visibility with the help of app store optimization as both the app stores (that is Google and Apple) allows them to do so in lesser time. Hence businesses who want to improve the visibility of their app on the leading app stores ave to [hire angularjs developers](https://www.appemporio.com/hire-developers/angular-js/) who have hands-on experience and are performing app development and optimization work from years. Without taking the advantages of app store optimization you cannot expect that your app appears on the topmost list on the app store. 

## Allow Users to Share Referrals
Businesses can boost their app success by sharing referrals and allowing other users to share the same with their friends and family. Social media sharing can also be used as a successful weapon when it comes to launching the app and improving its popularity in a short time span. If you don't allow users to refer and share the app with other users without any hassle and deal then you can never grab the needed success for your app on the app store. 

## Summing It Up
Without implementing the right and robust app launch strategy you cannot expect that your app will get the massive success and top position on the app store. Your app must mainly focus on various opportunities that you can grab when you pre-launch your existing app or newly developed app for your users. This step made by you can persuade numerous users to download and use your app on a regular basis. At the same time, the developed strategy will help you to avoid many of the mistakes which you made previous and met the failure.
FrameDebuggerの情報を外に書き出してみる試み

#FrameDebuggerの情報を外に書き出してみる試み

FrameDebuggerの中身を書き出す君(作業中)の記事です。

ソースはコチラ
https://github.com/wotakuro/FrameDebuggerSave

# 何してるの？
![frameDebuggerToLog.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35544/8237c887-925f-d4a3-f417-ed7e08d6e4ce.gif)

上記GIFの様にFrameDebuggerの情報を1ステップずつ舐めていって、ログに書き出すツールを作成してみている記事になります。
動作は今の所2018.4でのEditor起動でしか確認しておりません…。

# 何でこんなことしてるの？

UnityのFrameDebugger最大の不満点は描画を１ステップずつずらしていかないと、描画に関する詳細の情報を取得できない事です。
ShaderやShaderKeyword、描画しているPass名等々が一覧で確認できません。
これは凄い不満だったので、今回作成しました。

特にShaderKeyword抜き出しは、ShaderVariantを抑えるためにも、この取得をさっくり出来るのは非常に重要なのですが、、、
現状では、相当設計して作成していない限り、一覧で持ってくるのは非常に困難です。

# ハマった事

FrameDebuggerは、どのステップにいるかを指定してあげないと、その時の詳細情報が取れない仕様になっています。

最初は [FrameDebuggerUtility](https://github.com/Unity-Technologies/UnityCsReference/blob/2018.4/artifacts/generated/bindings_old/common/Editor/FrameDebuggerBindings.gen.cs) という便利なクラスを見つけて、こちら経由で操作していました。
※InternalクラスなのでReflectionの嵐です。

## 失敗した実装
1.FrameDebuggerUtility.SetEnable で有効に
2.FrameDebuggerUtility.countでフレーム数取得
3.FrameDebuggerUtility.limitの値を書き換える
4.FrameDebuggerUtility.GetFrameEventDataでそのフレームのデータを取得して書き出して、またFrameDebuggerUtility.limitを書き換えて次のフレームへ行く

と言った形の実装です。
こちらでは Editorアプリ上で再生していないときは上手くいっていたかのように見えました…。
ただEditor上で再生したときに走らせると「FrameDebuggerUtility.SetEnable(true)」で有効にした直後に、FrameDebuggerUtility.SetEnable(false)が呼び出されて即座に失敗しました…。
原因は表示していなくてもFrameDebuggerのWindow自体が処理を持ってしまっていたからでした…

## 現在の実装
仕方ないので、[FrameDebuggerWindow](https://github.com/Unity-Technologies/UnityCsReference/blob/2018.4/Editor/Mono/PerformanceTools/FrameDebugger.cs#L227)を呼び出して何とかする方向にしました。
※これもまたReflectionの嵐…

1.FrameDebuggerWindow.ShowFrameDebuggerWindow()でウィンドウを呼び出す。
2.FrameDebuggerWindow.EnableIfNeededでFrameDebugger起動
3.FrameDebuggerWindow.ChangeFrameEventLimitでフレームずらす
4.FrameDebuggerUtility.GetFrameEventDataでそのフレームのデータを取得して書き出して、またFrameDebuggerWindow.ChangeFrameEventLimitを書き換えて次のフレームへ行く


という感じで、操作は[FrameDebuggerWindow](https://github.com/Unity-Technologies/UnityCsReference/blob/2018.4/Editor/Mono/PerformanceTools/FrameDebugger.cs#L227)から行い、データは[FrameDebuggerUtility](https://github.com/Unity-Technologies/UnityCsReference/blob/2018.4/artifacts/generated/bindings_old/common/Editor/FrameDebuggerBindings.gen.cs) から取得するという形です

そんなこんなで、FrameDebuggerの中身を文字列に書き出すことに成功しました！！

## 追記
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">わりとやりたい事出来た感じあるー。<br>というか、RenderTargetの情報も抜き出せて便利だなぁー <a href="https://t.co/6gmRcPoqQk">pic.twitter.com/6gmRcPoqQk</a></p>&mdash; 黒河優介(YusukeKurokawa) (@wotakuro) <a href="https://twitter.com/wotakuro/status/1209374131600281600?ref_src=twsrc%5Etfw">December 24, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
こんな感じでCSV書き出しをするようにしました。
new_record?で場合分け ❏Rails❏

newとeditで同一の部分テンプレートを利用しているが、それぞれちょっとだけ変えたい時

Railsの`new_record?`メソッドを使って場合分けすることができます。

・インスタンスが新規作成されて、情報がないものは`true`
・インスタンスに既に情報が保存されている場合は`false`

```ruby:_form.html.haml
- if tweet.new_record?
  %p 新規作成
- else
  %p 編集

= form_with model: tweet, local: true do |form|
...
```

```ruby:new.html.haml
= render "form", tweet: @tweet
```

```ruby:edit.html.haml
= render "form", tweet: @tweet
```

newページでは`新規作成`が、
editページでは`編集`が表示されるようになりました。

直感的で非常にわかりやすいです。

<br>
前回 `current_page?`による場合分けを解説しました。
>https://qiita.com/ITmanbow/items/dc9b2e2b48f4901049f4

しかしこのやり方だとURL設計の変更に弱いという弱点を指摘されました。（ありがとうございます。）
ですので、登録フォームの場合分けは`new_record?`を使う方が良いと思います。

<br>
参考
>https://programming-beginner-zeroichi.jp/articles/35

<br>
ではまた！
D - Coloring Edges on Tree

2日かけてできませんでした〜〜〜〜！！！！泣

#問題
https://atcoder.jp/contests/abc146/tasks/abc146_d
<img width="998" alt="スクリーンショット 2019-12-06 19.45.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307024/806d58e0-11e4-fea6-208f-72a8fc9e3512.png">

#回答
```ruby
N = gets.to_i
A,B = (N-1).times.map{gets.split.map(&:to_i)}.transpose
C=Array.new(N-1,0)
list=Array.new(N).map{Array.new}
for i in 0..N-2
  for j in 1..N
    if list[A[i]-1].include?(j)
      next
    end
    if list[B[i]-1].include?(j)
      next
    end
    list[A[i]-1].push(j)
    list[B[i]-1].push(j)
    C[i] = j
    break
  end
end
puts C.max,C
```

#結果
<img width="731" alt="スクリーンショット 2019-12-06 19.51.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307024/a3d25bb5-a837-b04c-a2d6-34a6e6e46d67.png">


#感想
マジで悔しすぎて**12時間以上**考えたのに解けなくて泣いてる。

上のやり方だと、色を１から順に入れていくので、
1 2　→　1の色
4 5　→　1の色
3 4　→　頂点４で１の色を使っているので２の色
2 3　→　頂点２で１の色、頂点３で２の色を使っているので３の色
で３色必要になってしまうのだが、
実際は
1 2　→　1の色
4 5　→　2の色
3 4　→　1の色
2 3　→　2の色
で２色で良いので、ダメみたい、

なので、幅優先探索ってやつをやる必要があるみたいなのだが、
辺の場所などの保持が分からなくなって頭がパンクしました。おわり
EC-CUBE4のContainerの探検記録

EC-CUBE4のcontainerの中を探検したときの記録です。

*本記事は、正式な使用法ではありませんので、参考程度にご覧ください。


##containerをゲット
まずはゲットしてみました。

```
$container = $GLOBALS['kernel']->getContainer();
```


##containerの中で見つけたもの
こんなのが入っていました。

##### ログイン中のCustomer
```
$Customer = $container->get('security.token_storage')->getToken()->getUser();
```
##### eccubeConfig
```
$eccubeConfig = $container->get(\Eccube\Common\EccubeConfig::class);
```

##### request
```
$request = $container->get('request_stack')->getCurrentRequest();
```

##### entityManger
```
$entityManger = $container->get('doctrine.orm.entity_manager');
```

##### OrderRepository
```
$OrderRepository = $container->get(\Eccube\Repository\OrderRepository::class);
```

なんでも入ってるようです。


## その他 いろいろ
##### ログイン中のCustomerの操作権限の確認
```
$isGranted = $container->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_FULLY');
```

##### formFactory
```
$formFactory = $container->get('form.factory');
```
##### twig
```
$twig = $container->get('twig');
```
##### paginator
```
$paginator = $container->get('knp_paginator');
```

以上です。
業務システム営業フックとしてのkintoneとハンディターミナル連携デモ

[kintone Advent Calendar 2019](https://qiita.com/advent-calendar/2019/kintone) の 15日目の記事です。

#内容
kintoneとハンディターミナルを連携させます。
連係自体はkintone APIを使ってごりごり書くしかないので、当記事では、どんな目的でそれをするのか、目的を達成するためにどの様な構成にするのか、という視点で記事を書きました。

#背景
弊社は中国上海市でkintoneを使って、お客様にあわせた業務システムをオーダーメイドで作っている会社です。営業はいません。なので、基本戦略は（こんな事言っていいのかわかりませんが）"通常ならサイボウズ社がkintone案件で取りこぼす特殊案件のおこぼれを拾って食べていく"です。
イメージ図
<img width="414" alt="図解" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79724/8892e8eb-51d4-ba73-e8be-55dedcccc0c8.png">

そのため、kintoneをベースとして、サイボウズ社や他代理店に引合いが来るが、対応できない場合にうちを思いだしてもらうための、デモシステムを今回作ります。

#ストーリー
kintone案件だと思って営業行ったら、バーコード使った簡単なシステムみたいなの探してるんだよね、なんかkintoneでいいのない？と言われたときに、うちを思いだしてもらう。そのためのkintone＋ハンディターミナルの連携デモプログラム。

#環境
- ハンディターミナル
　[KEYENCE制ハンディターミナル BT-W80 シリーズ](https://www.keyence.co.jp/products/autoid/handheld-terminals/bt-w80/models/bt-w85/)
　開発は Visual Studio 2008（古いのですが、うちのスタッフが使い慣れてるからこれがいいって言ってたので）

- kintone
中国ドメイン

- WebService
とりあえず社内のIISにたてました。ハンディから直接でも行けそうな気がするのですが、うちのスタッフがJSON扱うのにこの方が慣れてるから、これがいいって）

#ターゲット業務
ERP等の基幹システム関係はターゲット外にします。そもそもそのレベルの案件はkintoneとしての引き合いに引っかかってこないので。したがって、下記の様なサブシステム的な業務について、kintone+ハンディターミナルで実現できますよ。という感じで行きます。

- 出庫ミスの防止（品番チェック、数量チェック、先入先出チェック）
- 工具や補助品等の材料費に直接ならない系の入出庫管理

#設計
当日の出荷指示に対してきちんと全ての出荷ができているか。のチェックをハンディターミナルで行うデモを作ります。僕はハンディターミナルのプログラムを書けないので、kintoneでざっくりアプリだけ作って、あとは適当な設計書を書いて、会社の子に丸投げしました。

アプリは２個、出荷指示と出荷実績です。
出荷指示アプリには何を、いつ、いくつ出荷しなければいけないかの指示情報を格納。
![出荷指示APP.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79724/540574ae-face-59bc-8315-64aafeb95fac.png)

思いっきり中国語ですが、订单数量が出荷指示数量、已扫描数量がスキャン済の数量、剩余数量が残数です。この画面ではまだ何も出荷されていない状態ですが、ハンディターミナルで出荷をしたときに、この「已扫描数量」を更新することで、残数の把握ができる感じですね。

出荷実績アプリには、スキャン実績を格納します。
<img width="577" alt="出荷実績.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79724/02ab1cb4-5a21-5220-0f3f-fcffebef29d6.png">
項目が色々粗いですが、思い付きで設計したので、こんなものでしょう。

設計書を書きます。Wordです。内容が薄いうえに中国語のふりをした、単に漢字が多いだけの日本語ですが、うちの社員様は優秀なのでこれでもちゃんと作ってくれるはずです。うちの会社いつもこんな感じです。本当に社員様には頭があがりません。

<img width="310" alt="設計書.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79724/2436ba5e-d45a-56a1-1b76-10004a86acb8.png">

#出来て来たもの
あの設計書でこれができてくるんですよ。すごくないですかうちの社員。長年適当な設計書で丸投げしてきた僕のやり方は間違ってなかった（本当にありがとうございます）。

<img width="442" alt="ハンディ.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79724/f4c7a4ef-dfc1-7ca4-054c-fd59829f3eb1.png">

kintoneにもきちんと反映されています。
![完成版kintone.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79724/b6d1c926-d7a2-2b87-d347-4a1ea06ff978.png)

実際のスキャンの様子がこちら（ツイッター埋め込み動画）
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">qitta投稿用：kintoneとkeyenceハンディターミナル連携デモ <a href="https://t.co/fygcIZKUeK">pic.twitter.com/fygcIZKUeK</a></p>&mdash; 松村稔@プロ牛乳石鹸 (@kai0707) <a href="https://twitter.com/kai0707/status/1202902191263993857?ref_src=twsrc%5Etfw">December 6, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

#最後に
技術的な内容が皆無で恐縮ですが、中国でkintoneを扱ってる会社の一つが、どんな感じで生存のための作戦考えて、営業やってるのかみたいなところが少しでも参考になれば幸いです。

もう少し先になりますが、メリークリスマス！
テストから考えるプログラムの役割と構造

## はじめに

Railsを始め、**フレームワーク**を利用すると良くも悪くも「プログラムの構造」に対して縛りが発生してきます。
しかしながら、Railsが好まれ・利用されている背景などを考えてみると、この`構造が縛られる`ということがむしろ好意的に受け取られているのではないかと考えてます。

つまり、何を言いたいかと言うと。。。

　**プログラムの構造を１から考えることは難しい**

プログラムの構造を考えるにあたり、`役割`を意識することが多いと考えてます。
その際に大きな問題になるのが**抽象化**と**共通化**の問題。

よく言われるのは、**共通化するな抽象化しろ**ということかなと思います。
では、どこまでが**共通化**で、どこからが**抽象化**なのか。

今回は`テスト`に焦点を当てることで、該当箇所が**抽象化**できているのか？を考えていくアプローチについて書いていければと思っています。

## なぜテストに焦点を当てたのか

答えは単純明快

　**テスト時に自分考えた構造がおかしいことに気づいたから**

これだけでは説明不十分なので、少し掘り下げて考えていきます。

　**よくできたプログラムは、テストしやすい**

自動テストを書くようになり、神話のような感覚で聞いていたこの言葉の意味が最近良くわかるようになってきました。
**スパゲッティコード**というような表現をされるようなコードは、とにかくテストが書きづらい。
これはもう、紛れもない事実であると言い切れます。

例えば、下記のメソッドのプログラムのテストを書くことを考えてみてください

```ruby
class SampleClass
  def add(x, y)
    x + y
  end
end
```

1 と 2 を渡して、3 が返ってきているか？のテストをしようかな… :thinking: 
と大半の方が考えたのではないかと思います。

では、次はどうでしょう？

```ruby
class SampleClass
  include SampleModule
  def add(x, y)
    round(x + y)
  end
end

Module SampleModule
  def round(x)
    x > 100 ? 100 : x
  end
end
```

SampleClassの`add`をテストしたいはずなのに…
`計算結果が100を超える場合と超えない場合`を意識したテストが必要になりそうじゃないでしょうか？

`round`という役割をあえて分けたにもかかわらず、結果的に`add`が`round`の動作に依存していることになっている。
すごい極端な例を上げましたが、個人的な**テストしやすさ**はこういうことなのかと考えています。

## 結論

**抽象化**したつもりが、**分離したコードの結果を意識したテストを書かないといけない**という状態に陥ったとすると、それはおそらく適切に構造化ができていないサインだと思います。

今回、自分自身が恥ずかしながらこういうケースに遭遇し、改めてテストコードを書くことの大切さと、コードを構造化することの難しさを感じたので戒めもこめて記事に残しました。

構造化に悩むプログラマーの方々、自動テストの導入になかなか踏み切れないプログラマーの方々の一助になればと思います。
AWS re:Invent 2019 - Keynote with Andy Jassy Amazon SageMaker サービスまとめ

##はじめに
AWS re:Invent 2019 - Keynote with Andy Jassy 動画にて紹介されました Amazon SageMaker に関する新サービスの情報をまとめました。

■本動画のリンクはこちらから
[AWS re:Invent 2019 - Keynote with Andy Jassy](https://www.youtube.com/watch?v=7-31KgImGgU&t=6304s)


##Amazon SageMaker 関連のサービス紹介
本動画内で紹介された Amazon SageMaker 関連のサービスです。

- Amazon SageMaker Studio
- Amazon SageMaker Notebooks
- Amazon SageMaker Experiments
- Amazon SageMaker Debugger
- Amazon SageMaker Model Monitor
- Amazon SageMaker Autopilot

###Amazon SageMaker Studio
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321349/03520142-d1ad-e4ec-97da-54ccbfdf20e6.png)

- ウェブベースの IDE で完全に統合された ML サービス 
- notebook、コード、データセットの管理・アクセス・サーチは全てこれ1つで完了
- 機械学習プロジェクト管理のフォルダも作成可能
- フォルダやうロジェクト、コンテンツの共有も可能

###Amazon SageMaker Notebooks
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321349/44f0d667-ed3f-4976-f8f1-0d8d4c147549.png)

- １クリックで notebook を立てることが可能
- インスタンスのプロビジョニングも不要
- CPUの増減も簡単に実行可能
- 新しいインスタンスに自動でnotebook のコンテンツのコピーや移動が可能

###Amazon SageMaker Experiments
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321349/897c814a-e36e-0621-dcbf-7c4e5c0b30cc.png)

- 入力されたパラメータや構成、結果を自動的にキャプチャ
- リアルタイムの実験をブラウザリングやモニタリング可能
- 直近の実験を名前やパラメータで検索をかけることが可能

###Amazon SageMaker Debugger
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321349/eac29c7f-9a9b-d320-ffd6-8da528838a8d.png)

- 機械学習モデルのデバッグサービス
- 監視したいメトリクスを自動的に設定
- モデルのトレーニングパフォーマンスをリアルタイムで提供

###Amazon SageMaker Model Monitor
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321349/5f3ccfe6-6a29-6e56-9ade-32fc9837be9c.png)

- データを予測実行前後で違いが出てないかのチェックが可能
- 1クリックでモデルのモニタリングを実行
- SageMaker Studio でデータのビジュアル化が可能

###Amazon SageMaker Autopilot
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321349/a9b2619f-7a1d-639a-d91f-029d31860d52.png)

- 自動的にデータの変換が可能
- ベストなアルゴリズムを選択
- 50種類の異なるモデルでトレーニングを自動的に実行
- 50種類のモデルの結果を順位付けをして結果を出す

##おわりに
AWS re:Invent 2019 - Keynote with Andy Jassy 動画にて紹介されました Amazon SageMaker に関する新サービスの情報は以上となります。本記事では紹介しませんでしたが、Amazon SageMaker 以外の新サービスや既存サービスのアップデート情報なども、本動画で紹介されております。そちらもぜひ、確認下さい。
DNSレコードの最後のドット「.」は大事

# 概要

DNSのCNAMEレコードにおいて、最後のドットを省略して設定したことで少しハマった。
最後のドットはドメインの終端を示す記号として重要だということがわかったので、不要に省略するのはやめたほうが良さそう。

# 環境

- バリュードメインでドメインを取得した
- Office365を独自ドメインで利用している
- Office365のNSにてドメインを管理している

# 経緯

独自ドメインを使ってGCPでWEBページを公開したいと考え、サブドメイン（www）の管理をGCPのCloudDNSに移管しようと考えた。
しかしながら、Office365のドメイン管理ではサブドメインの管理を他NSにできるNSレコードは追加できないことがわかった。
よって、Office365のNSからバリュードメインのNSに切り替えることとし、バリュードメインのNSに必要なDNSレコードを追加しようとした。

# 実施した手順

Office365のExchangeサービスを利用するにあたり、必要なDNSレコードは以下の通りだとOffice365のページには書いてある。

|種類	|優先度|	ホスト名|	ポイント先のアドレスまたは値|	TTL|	アクション|
|:-----------------|:------------------|:------------------|:--|:--|:--|
|MX|	0|	@|	example-com.mail.protection.outlook.com|	1時間| |
|TXT|	-|	@|	v=spf1 include:spf.protection.outlook.com -all|	1時間| |
|CNAME|	-|	autodiscover|	autodiscover.outlook.com| 1時間| |

この通りに設定しようとして、バリュードメインのNSのDNSレコード設定にて以下の様に記述した。

```
mx example-com.mail.protection.outlook.com. 0
txt @ v=spf1 include:spf.protection.outlook.com -all
cname autodiscover autodiscover.outlook.com
```
# 課題

しかしながら、Office365側でDNSレコードの設定が正しいか確認するとCNAMEでエラーが出てしまう。
どうやらCNAMEが期待されたとおりに設定されていないようだ。

``` sh:期待値
CNAME autodiscover autodiscover.outlook.com
```
``` sh:現実の設定
CNAME autodiscover autodiscover.outlook.com.example.com
```

「CNAMEはサブドメインのエイリアスを貼るようなものだが、他のドメインへのエイリアスは貼れないのか？」と一瞬思ったが、どうやら違いそう。


# 原因

一言で言えば、上記の記述だとCNAMEのポイント先が以下のどちらなのか曖昧なので、下の設定をされてしまったからだということがわかった。

- autodiscover.outlook.com
- autodiscover.outlook.com.example.com

CNAMEは`CNAME AAA BBB`のように記述するが、これは「AAAというサブドメインの問い合わせが来たら、BBBと同じ処理をするよ」という意味だ。
ここがポイントなのだが、BBBは同じドメインのサブドメインを指定することもできるし、他のドメインを指定することもできる。
（例：example.comにアクセスするとexample.netと同じサーバーから応答をさせる場合など）

ここで、BBBにドット「.」が含まれる場合を考える。
CNAMEは`CNAME aaa bbb.com`という設定をすることになるが、これはDNSサーバーからすると
「aaa.example.comはbbb.comを示す」のか「aaa.example.comはbbb.com.example.comを示す」のか判断がつかないようだ。
（こうしたケースでDNSサーバーがどっちの挙動を示すのが正しいのかは詳しく調べてはいない。）


# 解決方法

CNAMEのレコードの終端にドット「.」を記述すれば良い。レコードの終端のドットはドメインの終端を示すようだ。
つまり、`CNAME aaa bbb.com.`と記述することで、「aaa.example.comはbbb.comを示す」ことが確定する。

参考文献[^1]からの引用＋改変だが、以下のように整理できる。

```
    CNAME("foo", "bar)        // 良い (bar.example.comと解釈される)
    CNAME("foo", "bar.com.")  // 良い (bar.comで確定する)
    CNAME("foo", "bar.com")   // ダメ (曖昧、今回ハマったパターン)
    CNAME("foo", "meta.xyz")  // ダメ (同じく曖昧、meta.xyz.example.comかも？)
```


# 結論

必要な場合は、DNSレコードの終端にはドットをつけよう。
今まで「なんでDNSのレコードの終端にドットが付いてることあるんだろ」と気にはなっていたが、放置していたのが良くなかった。
Office365の設定例のページにもドットを入れておいてほしい。

# 参考文献

[^1]: [Why CNAME/MX/NS targets require a “dot”](https://stackexchange.github.io/dnscontrol/why-the-dot)
スクレイピングで怒られが発生した件についての顛末書


15卒業生です。
関係者でもいいよ、とのことでしたのでSFC時代にスクレイピングで怒らたやらかしの顛末をご紹介します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214098/b6203de7-320c-54b9-b13b-f9937dbaebe3.png)

# 顛末書
会社口コミサイトのスクレイピングを行った結果を、学内サーバーに置いてデータの授受をした件についてご報告します。

## 怒られ発生時期
ことが起きたのは、就活の頃でした。
私はSFCに入ってプログラミングを始めたたちでして、就活期といいますと情基礎・オブプロ・ゲープロなどをちょうど取りきって「プログラミング完全に理解した」と調子に乗っている時期でございます。
特に、データ分析を得意としておりまして、スクレイピングという技術でWeb上のデータを収集し、それを分析・ビジュアライズする、ということを研究でも趣味でも行っていた時期でした。

## 怒られの背景
慶應義塾、とくにSFCというのは「実学の府」を自称しています。
スクレイピングやデータ分析の技術を実際に活用するということが常に頭の片隅にありました。
その当時、前述の通り就活期でしたので「そうだ、就活をサイエンスしよう」と思いつきました。

当時、よく使っていた会社のクチコミサイトがありまして、そのサイトは定量・定性のデータがたくさん溜まっており、いわば「会社の食べログ」でした。
就活生は、有料機能を一定期間無料で使えたということもあり、非常に参考にさせていただいておりました。
これをデータベース化して、レコメンドエンジンを構築しようと決め、そして実装に移しました。

スクレイピングというのは、かなり全能感のある技術です。
Web上のデータを、一般ピープルがぽちぽちコピペしている中、そのデータをすべてぶっこ抜くわけです。とても楽しい。

## 怒られの原因
そこまでは、悪くなかった。(もしかしたら利用規約的にはダメだったのかも)
しかしながら、調子に乗った私は、それを誰でもアクセスできる権限で学内サーバーにあげました。
もっというと、それをTwitterの公開垢で友人宛にmentionで送ってしまいました。

これをエゴサしていたのが転職サイトの運営者。
その日にDMが来て「消せ、あと私が悪かったですという覚書を書け」と。

## 覚書の内容
- 私が行ったのは利用規約を超えた行為です。
- このデータを共有したことによる、運営会社の損害は全額支払います。

という、なかなか学生には不安になる内容でした。
認印か実印か、とにかく法的拘束力の高そうな書類を提出させられました。

もちろん、現在まで損害の請求はされていませんが、当時は就活生だったということもあり、随分長い間不安な気持ちにさせられました。

この覚書の効力は、いまだによく理解できていません。
正直言って、いまだに学生に対してかなりパワープレイしてきたなという、嫌な感覚を持っています。
(もちろん、今企業の立場としては、株主や従業員などステークホルダー保護の観点で必要とも考えます)

事実、スクレイピング周りの法律は、他にも先方のサーバー負荷の問題など、非常に微妙なとこがあります。
スクレイピングを日常的に行っているみなさんは、あらためてせめて下記のようなサイトで法的整理を確認し、保守的にスクレイピングをするのが良いでしょう。
[スクレイピングは違法？3つの法律問題と対応策を弁護士が5分で解説 | トップコート国際法律事務所](https://topcourt-law.com/internet_security/scraping-illegal#i-11)

なお、ログイン後でないとアクセスできないページについては、多少配慮してスクレイピングはしておりませんでした。

# 後日談
今だからごめんなさいな話ですが、個人的にそのスクレイピングデータは使い続け、レコメンドエンジンは大活躍しました(大変、みすぼらしく原始的な実装でしたが)。
軸の無い学生だったので、就活時はレコメンド順に上からESを出し、最終的には3位あたりにレコメンドされた会社に内定・就職しました。
(余談ですが、これはジョハリの窓の[盲点の窓](https://lightworks-blog.com/johari-window#3-3)にアプローチできたという解釈です)

そういえば、なぜかアカウントもBANされなかったです。

# 最後に
最終的にはハッピーエンドなのですが、やはり覚書を書かされたときは怖かったです。
皆さんはぜひ、安全にデータやスクリプトを扱った上で、おもしろい分析をしてほしいなと切に願います。
railsで本番とか開発環境とかの分岐

##Controllerでの分岐

```.rb:ruby

if Rails.env.development?
  logger.debug("開発")
elsif Rails.env.test?
  logger.debug("テスト")
else
  logger.debug("本番")
end

#↓　本番と開発環境を分岐

if Rails.env.development? || Rails.env.test? 
  logger.debug("テスト")
else
  logger.debug("本番")
end
```
scalaで新しいライブラリを追加する話@AndroidStudio, Mac

scalaにreactiveandroidを入れたかったのです。
慣れてないと辛かったので記録
環境は
https://qiita.com/Ohtak/items/0a13f449b8d735bb37da
と同じです

#手順
build.sbtに

```
libraryDependencies += "com.reactiveandroid" % "reactiveandroid" % "1.4.3"
```
を追記。sbtコマンドするとインストールされる
文法ミスがあったり見つからなかったりするとエラー吐かれる
ちなみに上記ライブラリの場合mavenのものなので、

```
resolvers += "reactiveandroid" at "https://jcenter.bintray.com/"
```
の記述も必要。
間に空行を入れないとエラーになるので注意

OKパターン

```
resolvers += "reactiveandroid" at "https://jcenter.bintray.com/"

libraryDependencies += "com.reactiveandroid" % "reactiveandroid" % "1.4.3"
```

エラーパターン

```
resolvers += "reactiveandroid" at "https://jcenter.bintray.com/"
libraryDependencies += "com.reactiveandroid" % "reactiveandroid" % "1.4.3"
```

ただsbtに入っている状態でbuild.sbtを変更しても反映されない。
（sbtコマンドを叩いたタイミングで読み込まれるため。）
変更を反映させる場合、`exit`して`sbt`し直すか、`reload`コマンドすればOK
https://qiita.com/suin/items/06b2181163007945f901
mrubyc-esp32を試す

# 概要

前記事(関連のリンク)でESP32(M5Stack)でmrubyを動かせる様になったので、今度はmrubyc-esp32を試してみます。

開発環境の構築は関連のリンクからみてください。
ちなみに仮想マシンでおこなってますが、Macの方は重たく画面の更新が怪しい時があるので、Linuxの方で試しています。


# 手順

Githubのmrubyc-esp32にあるREADMEの通り進めていきます。

[GitHub - mruby-esp32/mrubyc-esp32: mruby/c application template for ESP32](https://github.com/mruby-esp32/mrubyc-esp32)

## ソースコードのClone

mrubycディレクトリ下で試しています。
git cloneで取ってきます。

```
$ mkdir ~/mrubyc
$ cd ~/mrubyc
$ git clone --recursive https://github.com/mruby-esp32/mrubyc-esp32.git
$ cd mrubyc-esp32
```

## mrubyのインストール

mruby/cはmrubyでコンパイルしたバイナリーを用いるためmrubyをインストールします。
MRUBY_PATHにmrubyのパスを指定する必要があるので ```which``` で調べます。

```
$ sudo apt install mruby
$ which mruby
/usr/bin/mruby
```

MRUBY_PATHにはbinの前まで指定する様です。

```
$ export MRUBY_PATH=/usr
```

M5StackをUSBケーブルで接続してから下のコマンドで、ビルド、アップロード、動作確認してみます。

```
$ make MRUBY_SCRIPT=hello.rb flash monitor
.
.
I (313) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (30) mrubyc_task: Loading binary...
Hello, mruby/c is running on ESP32!
I (30) mrubyc_task: Success
```

"Hello, mruby/c is running on ESP32!" が表示されて正常に動作している事が確認できます。

# 関連

- [MacにESP32向けのmruby開発環境を構築する - Qiita](https://qiita.com/katsuyoshi/items/dc0aed3aeb35d8a0ebcb)
- [ESP32向けのmruby開発環境を構築する(Linux編) - Qiita](https://qiita.com/katsuyoshi/items/ed96b0e5044cfe590d04)

# 参照

- [GitHub - mruby-esp32/mrubyc-esp32: mruby/c application template for ESP32](https://github.com/mruby-esp32/mrubyc-esp32)