OmniAICreator/Qiita-1.07M huggingface dataset:
Angular Materialを使ってダッシュボードを実装する

Angular Materialの[Schematics](https://material.angular.io/guide/schematics)を使って、３分でダッシュボードを実装する。

コマンドをいくつか叩く。

```sh
$ ng new schematics-sample
? Would you like to add Angular routing? Yes
```

```sh
$ ng add @angular/material
$ ng g @angular/material:address-form form
$ ng g @angular/material:nav nav
$ ng g @angular/material:table table
$ ng g @angular/material:dashboard dashboard
$ ng g @angular/material:tree tree
```

ファイルを３つだけ修正する。

```typescript:app-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { DashboardComponent } from './dashboard/dashboard.component';
import { FormComponent } from './form/form.component';
import { TableComponent } from './table/table.component';
import { TreeComponent } from './tree/tree.component';

const routes: Routes = [
  { path: '', component: DashboardComponent },
  { path: 'form', component: FormComponent },
  { path: 'table', component: TableComponent },
  { path: 'tree', component: TreeComponent }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
```

```html:nav.component.html
<mat-sidenav-container class="sidenav-container">
  <mat-sidenav #drawer class="sidenav" fixedInViewport="true"
      [attr.role]="(isHandset$ | async) ? 'dialog' : 'navigation'"
      [mode]="(isHandset$ | async) ? 'over' : 'side'"
      [opened]="!(isHandset$ | async)">
    <mat-toolbar>Menu</mat-toolbar>
    <mat-nav-list>
      <a mat-list-item [routerLink]="['/']">Top</a>
      <a mat-list-item [routerLink]="['/form']">Form</a>
      <a mat-list-item [routerLink]="['/table']">Table</a>
      <a mat-list-item [routerLink]="['/tree']">Tree</a>
    </mat-nav-list>
  </mat-sidenav>
  <mat-sidenav-content>
    <mat-toolbar color="primary">
      <button
        type="button"
        aria-label="Toggle sidenav"
        mat-icon-button
        (click)="drawer.toggle()"
        *ngIf="isHandset$ | async">
        <mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
      </button>
      <span>schematics-sample</span>
    </mat-toolbar>
    <ng-content></ng-content>
  </mat-sidenav-content>
</mat-sidenav-container>
```

```html:app.component.html
<app-nav>
  <router-outlet></router-outlet>
</app-nav>
```

ダッシュボードの実装完了です。

<img width="1361" alt="スクリーンショット 2018-12-18 12.06.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/244226/6934c5c0-02f6-2b8a-51c5-3cf93d0b7a69.png">
<img width="1361" alt="スクリーンショット 2018-12-18 12.06.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/244226/85f21c35-850e-6205-186c-6eb389538a7f.png">
<img width="1361" alt="スクリーンショット 2018-12-18 12.06.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/244226/93d4acd1-f63d-78ca-4a3e-66588b6be462.png">
<img width="1361" alt="スクリーンショット 2018-12-18 12.06.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/244226/ad2934b4-2461-9be7-5c1c-af81acc5068b.png">
Vagrantで作った開発環境をホストOSのVSCodeで開発する

## 概要
Vagrantで作成された仮想環境で、`synced_folder`を利用してソースコードをホストOSと共有し、
ホストOSにインストールしたエディタを利用して開発を行います。
ついでに、速度を早くするためマウントにはNFSを利用します。
タイトルにはVSCodeと書きましたが、私がVSCodeを使っているだけでエディタは何でもOKです。

## ファイル共有方法
### NFSを利用できるようにする。
ターミナルを起動し、NFSを利用できるか確認します。

``` sh
$ nfsd status
nfsd service is enabled
nfsd is not running
```

nsfdの設定を何もしていなければ、`nfsd is not running` と出るかと思います。
nsfdを起動させましょう。

``` sh
$ sudo nfsd start
```

もう一度確認するとnsfdが起動した状態になっているかと思います。

``` sh
$ nfsd status
nfsd service is enabled
nfsd is running
```

次に、`/etc/exports`を作成します。
このファイルを作成することで、NFSが自動起動されます（たぶん）。

```
sudo touch /etc/exports
```

### Vagrantfileの修正
Vagrantfileに、ホストOSとゲストOSの共有フォルダ設定を追加します。

``` diff
Vagrant.configure(VERSION) do |config|
+ config.vm.synced_folder "ホストOSの共有フォルダパス", "ゲストOSの共有フォルダパス", type: "nfs"
end
```

### Vagrantのリロード
vagrantをリロードすると、共有フォルダ設定が反映されます。

```
vagrant reload
```

vagrantが起動していない場合は、`up` で起動させましょう。

```
vagrant up
```

## 確認
フォルダが共有されたので、Vagrantfileに設定した、ゲストOSの共有フォルダパスにソースを配置すれば、
ホストOSの共有フォルダパスにも同期されソースコードを見ることができます。
後はVSCodeなりお好きなエディタで開発しましょう。
DatastoreのEntityをKind単位で一括削除、コピー、リネーム

[PicApp アドベントカレンダー](https://adventar.org/calendars/3448)17日目です。

Datastore を使い始めて誰しも一度は思ったことがあると思いますが、MySQL や Oracle, PostgreSQL 等と違って、テーブル単位で管理されているわけではないので、一括削除、コピー、リネーム等はサポートされていません。すべては Entity です。Kind は Entity に付属するラベルのようなものなので、Kind 単位でなにかするという API はありません。

実際、一括削除したいんだけどなーと思ってググると公式ドキュメントに一蹴されます。

> ![2018-12-17 17_00_13-Deleting Entities in Bulk  _  Cloud Datastore Documentation  _  Google Cloud.png](https://qiita-image-store.s3.amazonaws.com/0/3284/aa03157c-13d1-8c94-73c6-a0dc8344723d.png)
バルクで削除したいなら Cloud Dataflow 使ってね。
いい感じのテンプレートも用意してあるよ！
https://cloud.google.com/datastore/docs/bulk-delete

そして、Cloud Dataflow を見に行くと、今後は Apache Beam で実装してね！
という、一見謎のたらい回しに遭遇してしまいます。


DROP TABLE, TRUNCATE TABLE のノリで簡単に Datastore を一括操作したいだけなのに、Dataflow を理解して、Apache Beam を理解して、実装して、というのはなかなかツライものがありますので、そんな人向けにコマンドラインツールを作りました。

dsflow です。[^name]
[^name]: リポジトリを作る前に "dsflow" でググって、同じような名前のものが無いことを確認したはずなのに、dataflow をラップしたようなフレームワークで dsflow というものがありました……
https://github.com/tomoemon/dsflow

Datastore の Namespace, Kind 単位で下記の操作をサポートしています

- copy
- delete
- rename
- json dump

# アーキテクチャ

細かい使い方は README.md に書いていますので、試してみたい方はそちらをご覧ください。ここでは簡単に Apache Beam と Dataflow の簡単な仕組みを紹介します。

![2018-12-18 11_36_59-astah - [no_title] (_).png](https://qiita-image-store.s3.amazonaws.com/0/3284/f367c2d6-be20-23e0-5d2d-dd3ebc9b3baf.png)

Apache Beam と Dataflow の関係は Hadoop を例にすると、MapReduce を実装するための SDK と Hadoop クラスタ環境と同じようなもので、SDK とプログラムを動かすランタイム環境と言えます。実際、Apache Beam で実装されたコードは Dataflow 以外の場所でも動かすことが可能です。
とはいえ、認証／認可のこと等を考えると、Datastore のように他の GCP サービスに含まれるデータを操作したい場合は、素直に Dataflow で動かすのが楽でしょう。

# Dataflow ジョブの実行とローカルからの実行

Apache Beam を使って実装されたコードは、Dataflow で実行するだけでなく、ローカル環境から実行することもできます。

Dataflow のジョブを作成すると、Dataflow はデータ操作を行うための GCE インスタンスを立ち上げます。ここで、必ず数分の時間を要するので、データ量が少ない場合は Dataflow を使わずに、直接ローカルから Datastore に対してデータ操作をしてしまった方が速いです。[^count]
[^count]: ローカルPCのスペックやネットワーク環境にもよりますが、おおよそ数万件程度が分岐点になると思います。

dsflow でもローカルからの実行と Dataflow を使った実行の両方をサポートしており、`dsflow` コマンドを叩いた場合は Dataflow を使い、`dsflowl` コマンドを叩いた場合はローカルから直接 Datastore を操作します。

# Apache Beam の注意点

Apache Beam は基本的に Java 先行で開発が進んでいる（ように見える）ので、Python や Go 向けのライブラリで使える機能が少なかったりちぐはぐだったりします。今回も Python で実装するにあたっては、Google の他のライブラリとの（proto 定義の）整合性を取るための作業が大半を占めました……。
Spring Boot/Herokuの始め方

Windows 10 64bitにて

# 必要ソフトインストール

1. 管理者権限でコマンドプロンプト起動
    1. Win+Xで表示されるメニューから選択
1. Chocolatelyインストール
    1. パッケージ管理システム
    1. https://chocolatey.org/install#installing-chocolatey の「Install with cmd.exe」のコマンドを実行
    1. `refreshenv`
        1. コマンドプロンプトの再起動をしなくても環境変数が最新の内容に更新される
1. Git・JDK・Maven・Spring Boot CLI・Heroku CLIインストール
    1. `cinst -y git jdk8 maven spring-boot-cli heroku-cli && refreshenv`
1. 管理者権限のコマンドプロンプトを閉じる

# アプリ作成・動作確認

1. コマンドプロンプト起動
1. 作業ディレクトリ作成・移動、例えば `mkdir \herokustudy && cd \herokustudy`
1. `spring init --dependencies=web myfirstapp && cd myfirstapp`
    1. `--dependencies`に指定できるもののリストは`spring init --list`で確認可能
1. `git init && git add . && git commit -m "spring init直後"`
    1. 後でHerokuにデプロイするのにgitは必須
1. `src\main\java\com\example\myfirstapp\DemoApplication.java`を編集(後掲)
    1. UTF-8で保存 (元ファイルがASCIIのみなので日本語を追加したときにうっかりWindows-31Jで保存しがち)
1. `mvnw spring-boot:run`
    1. Mavenのラッパコマンドがカレントディレクトリに用意してある
    1. 必要ソフトウェアダウンロード(初回のみ)・コンパイル・Tomcat起動が行われる
1. ブラウザで`http://localhost:8080/`にアクセス
1. `git add . && git commit -m "hello追加"`

```DemoApplication.java
package com.example.myfirstapp;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.*; // 追加
import org.springframework.stereotype.*;  // 追加

@Controller // 追加
@SpringBootApplication
public class DemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}

	// 追加
	@RequestMapping("/")
	@ResponseBody
	String hello() {
		return "こんにちは";
	}
}

```

# Herokuアカウント取得・デプロイ・動作確認

1. https://signup.heroku.com/
    1. ブラウザは閉じない (後のheroku loginで使う)
1. `heroku login`
    1. 先ほどのブラウザでログインが行われる
1. `heroku create`
    1. 引数でアプリケーション名(`https://○○○.herokuapp.com/`の○○○部分)を指定できるが指定なしなら適当に決めてくれる
    1. 自アプリの詳細なリストは`heroku apps:list --json`で確認可能
1. `git push heroku master`
    1. Herokuへのデプロイ(必要ソフトウェアダウンロード(初回のみ)・コンパイル・Tomcat起動)が行われる
1. `heroku open`
    1. ブラウザが起動してアプリケーションのURLにアクセスする
    1. ログは`heroku logs --tail`で確認可能

# おまけ：Gitのoriginをセット

1. 普段自分が使っているGitサーバ(GitBucket)に新リポジトリを空で作成
    1. 結果画面に新リポジトリのURLが表示される
1. `git remote add origin ＜新リポジトリのURL＞`
1. `git push -u origin master`

# おまけ：ChocolatelyでSourceTreeをインストール

1. 管理者コマンドプロンプトにてChocolatelyでSourceTreeをインストール → `cinst -y sourcetree`
1. `"C:\Program Files (x86)\Atlassian\Sourcetree\SourceTree.exe"` をタスクバーにピン留め

# 続き

[Spring Boot/HerokuアプリをVSCodeに取り込む](https://qiita.com/pilot/items/45aa98b0205d446f8f39)
[Spring Boot/HerokuアプリをEclipseに取り込む](https://qiita.com/pilot/items/8aaa5219037e7096a6dd)
[既存のSpring Bootアプリ(Git管理済)をHerokuにデプロイ](https://qiita.com/pilot/items/61d5d2cb2764c1f116fc)

以上
includeされたモジュールのメソッドから、includeしたクラスの定数を参照する

モジュールの中に定義されたメソッドから、そのモジュールをincludeした側の定数を参照する方法。

この方法だと、NameErrorが起こる。(M::QUUXという定数は存在しないから)

```ruby
module M
  def quux
    p QUUX # M::QUUXの参照を意味する
  end
end

class C
  QUUX = 'quux'
  include M
end

C.new.quux # => uninitialized constant M::QUUX (NameError) 
```

includeした側のクラスの定数を参照するには、次のようにすればできる。

```ruby
module M
  def quux
    p self.class::QUUX # includeしたクラスのQUUXを参照
  end
end

class C
  QUUX = 'quux'
  include M
end

C.new.quux # => "quux"
```

モジュールをincludeしても、includeされたメソッドの名前空間まで一緒になるわけじゃないみたい。
【深堀版】スマートスピーカーを遊びたおす会で話した「ヒロインとデート」のVUI設計思想

ごきげんよう
showです。

この記事は
**「するめごはんのVUI・スマートスピーカー Advent Calendar 2018」**
の18日目の記事です。

昨日、「スマートスピーカーを遊びたおす会」のVol.4を開催させて頂きました。

■イベントのconnpass
https://connpass.com/event/109561/

■デモ動画
https://www.youtube.com/watch?v=KY_9i-C6LwI

そして、そこで流したデモ動画についての記事を先ほど「スマートスピーカー 2 Advent Calendar 2018」に投稿しました。

■スマートスピーカー 2 Advent Calendar 2018
https://qiita.com/advent-calendar/2018/smart-speaker-2


僕が考えているVUIデザインについて記載しています。

■スマートスピーカーを遊びたおす会で話した「ヒロインとデート」のVUI設計思想
https://qiita.com/surumegohan/items/bb8a879c11c478863a8c

で、今この画面で開いているこの記事は僕のアドベントカレンダーなので、上記記事をもっと深堀します。

#VUIデザインについて再掲

上記記事でも触れましたが、VUIのデザインはユーザーの想定外の対話や、1ショット起動のため、フラット型をベースにする方がいいと僕は考えています。

![戻れる.png](https://qiita-image-store.s3.amazonaws.com/0/67398/6498a974-9b69-670e-a8d4-9a81b1994a2c.png)


##「ヒロインとデート」についてもう少し語ると

僕がヒロインシリーズを創っているのは、もっとも人間に近い対話設計にチャレンジできると考えているからです。

前作の「ヒロインの告白」は、告白なので基本的には「はい」「いいえ」で進むことがわかりやすくできます。

この次の対話設計としては、人間と想定する 結城琴葉ちゃん と、どれだけ自然に会話できるかを考えています。
そうなると「はい」「いいえ」だけで会話するのは無理です。
というか、それは会話や対話ではないです。

## 駅名と施設名を指定できる

デートをするシチュエーションを想定すると、現実には事前に行先を決めていると思われるのと、位置情報とリンクした際は、その位置情報に合わせた設計が必要になります。

とはいえ、僕がまだそこまで実装しきれていないので、デモ動画では駅名から聞かれます。

どこかで待ち合わせをしたとして、**「じゃあどこ行こう」**となった際に、例えばアメリカに行くとしたら **「グランドキャニオンに行こう」** などの観光スポットになると思います。
これは、グランドキャニオンの最寄り駅を指定するよりは、グランドキャニオンそのものを指定するはずです。

なので、声優さんに渡した脚本として、はじめから**「動物園」「水族館」などの場所・施設名を話しかけた場合の動き** も収録してもらっています。

##動物園に入ったら、水族館には突然ワープさせない

そして、例えば動物園に行った場合、そこからいきなり水族館にワープすることは現実的には（たぶん）ないので、そこへのワンショットはさせないようにデザインしています。

その変わり、動物園内で「パンダ」「フラミンゴ」「カバ」などの動物をめぐるようにしており、それぞれ
「●●（動物）を見に行こう」とユーザーが話しかける場合と、結城琴葉ちゃんが「パンダが観たい」と話しかけてくるような設計にしています。

動物園内ではワンショットで対象の動物を選択し、また、「他の動物」や「次の動物」だとランダムで他の動物を観に行くことを想定しています。

##LIFFで思い出をエモく

位置情報が使えるなら実世界とリンク、自宅にいながらでもClovaの操作によって、LINEさんのLIFFを使って、過去に廻った観光スポットとかをパーソナルに表示して、思い出としてエモく残すこともできると考えています。

##応用すると

例えば、アメリカ人でバットマンが好きな人が日本にきたとして、そこでモバイルでVUIを活用して日本観光をするとなると、英語でバットマンが日本観光案内をしてくれることもできなくはないと思っています。
しかも場合により課金もできる。

#というわけで

やりたいことが山ほどあります。
もうこうなると個人でやるのは限界なので**「オラに元気をわけてくれ」**状態です。

ともあれ、やりたいことがあるのにやらないという選択肢はとりたくないので、コツコツ頑張っていきます。

以上
rbenvに2.6.0-rc2がmergeされていないので、無理やり入れる

rbenvをhomebrewでインストールしています。

```bash
$ echo "install_package "openssl-1.1.0j" "https://www.openssl.org/source/openssl-1.1.0j.tar.gz#31bec6c203ce1a8e93d5994f4ed304c63ccf07676118b6634edded12ad1b3246" mac_openssl --if has_broken_mac_openssl\n
install_package "ruby-2.6.0-rc2" "https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0-rc2.tar.bz2#b3d03e471e3136f43bb948013d4f4974abb63d478e8ff7ec2741b22750a3ec50" ldflags_dirs standard verify_openssl" > /usr
/local/Cellar/ruby-build/20181207/share/ruby-build/2.6.0-rc2
$ rbenv install 2.6.0-rc2
```
リアルタイム翻訳機能の付いたWeb会議を作ってみた


# はじめに

この記事は[SkyWay Advent Calendar 2018](https://qiita.com/advent-calendar/2018/skyway)の19日目の記事です。

SkyWay(WebRTC)を使って作成した簡易Web会議システムに、リアルタイム会話翻訳機能（日本語と英語の翻訳と読み上げ機能）を実装できるか試してみました。

# できたもの

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">リアルタイム翻訳機能の付いたWeb会議を作ってみました。 <a href="https://t.co/o1W3jqmpyw">pic.twitter.com/o1W3jqmpyw</a></p>&mdash; 依藤充範 (@yorifuji) <a href="https://twitter.com/yorifuji/status/1074861173827297280?ref_src=twsrc%5Etfw">2018年12月18日</a></blockquote>

映像ではわかりづらいですが、右側の端末で喋った日本語の声が、左側の端末では英語の声で読み上げられています。
映像では試していませんが英語から日本語への変換もできます。

翻訳機能の付いたWeb会議として使うことができるかもしれません。

# デモサイト

Windows or macOS の Google Chrome でのみ動作します。

https://yorifuji.github.io/webrtc-realtime-translation/

右下の Room Name に任意の部屋の名前を入力して Connect してください。部屋の名前はユニークな名前の方が良いでしょう。
左下の `音声認識・翻訳` を押すと下記のダイアログが表示されます。

![スクリーンショット 2018-12-18 11.04.29.png](https://qiita-image-store.s3.amazonaws.com/0/104863/21e41f5d-a2f9-970c-9d21-9eba9525ad7b.png)

全てのチェックボックスにチェックを付けて、自分の話す言語を選択してください。なお、相手側も同じ言語を選択している場合は翻訳されません（例えば二人ともJapaneseを選択している場合は翻訳されません）。

なお、１台の端末で複数のタブで開くと音声認識が正常に動かないため、動作を確認する際は２台以上の端末で使ってください。

# 実現方法

翻訳は

ローカルで音声認識（文字起こし） --> WebRTC(SkyWay)でテキスト送信 --> 受信側で翻訳 --> 音声合成を使って読み上げ

という流れで実現しました。

## 音声認識（文字起こし）

[Web Speech API](https://w3c.github.io/speech-api/) の `SpeechRecognition` を使いました。現時点ではChromeのみ利用可能のようです。

こちらの記事に使い方がわかりやすく載っています。
https://qiita.com/kolife/items/a0af7702eef05994fbfb

今回、音声認識はローカルの端末で行い、文字起こししたテキストを SkyWay の機能を使って相手の端末に送信しています。

## 翻訳

翻訳APIを提供しているクラウドサービスを使うことも考えましたが、手軽に実現したかったのでこちらの記事を参考に、 `GoogleAppsScript` を使ったAPIを用意しました。
https://qiita.com/tanabee/items/c79c5c28ba0537112922

上記のAPIに相手から送られてきたテキストを投げて、翻訳されたテキストを取得しています。

## 音声合成

[Web Speech API](https://w3c.github.io/speech-api/) の `SpeechSynthesis` を使いました。

こちらの記事が参考になりました。
https://qiita.com/kyota/items/da530ad22733b644518a

今回は利用していませんが、出力する声の種類なども選べるそうです。

翻訳APIを使って翻訳したテキストを、上記のAPIを使って音声合成して読み上げています。

## その他

- Mute Remote Voice のチェックを外すと通常のWeb会議のように元の音声が再生されます
- ソースコードはこちらです https://github.com/yorifuji/webrtc-realtime-translation

# 実装して気づいたこと

- Chromeの音声認識 `webkitSpeechRecognition` は音声認識の際に利用するマイクデバイスが選べないようです、常に規定の（デフォルトの）マイクの音を認識するようです
- 1台の端末で複数のタブを開いて音声認識を同時に使うとうまく動きませんでした、私の使い方の問題かもしれません
- 音声合成した音を音声認識が拾ってしまうことがあるので、音声合成する直前に音声認識を停止するようにしました

# まとめ

Web会議システムにリアルタイム会話翻訳機能（日英翻訳）を追加してみました。意外と簡単に作ることができました。

Chromeの音声認識と音声合成は日英以外の言語にも対応しているので、翻訳する言語を増やすこともできそうです。

また、今回は日英翻訳に `GoogleAppsScript` を使いまいしたが、クラウドサービス（AWS,Azure,Watsonなど）が提供しているAPIを使うことでより自然な翻訳が実現できるかもしれません。
SAS ViyaのPython SDKのメソッドを確認する際にはhelpメソッドを使いましょう

[SAS Viya](https://www.sas.com/ja_jp/software/viya.html)はAIプラットフォームになります。Webブラウザ上で機械学習の設計、実行ができるStudioという環境も用意されていますが、開発者はプログラミングコードで開発することも可能です。プログラミング言語はJava/Python/R/SASが選べます。

機械学習を用いる際に専用のテーブル（casTable）を用いますが、今回はそのテーブルオブジェクト（Python版）のサマリーデータをグラフ化し、さらにHTMLとして保存します。

## 接続する

例えばSAS Viyaに接続する際には以下のようにコードを記述します。

```py
import swat as sw

cashost='localhost'
casport=5570
useremail='dev@sas.com'
userpassword='dev'
casauth='~/.authinfo'
conn = sw.CAS(cashost, casport, useremail, userpassword, caslib="casuser")
```

この conn オブジェクトがどんなメソッドを持っているかを確認する際には `conn.help()` を実行します。そうすると以下のような結果が得られます。

```
NOTE: Available Action Sets and Actions:
NOTE:    accessControl
NOTE:       accessPersonalCaslibs - Provides administrative access to all personal caslibs (CASUSER and CASUSERHDFS)
NOTE:       assumeRole - Assumes a role
NOTE:       dropRole - Relinquishes a role
  :
```

[SAS Viya The Python Perspective](https://www.amazon.co.jp/dp/B06X18R5WS/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1) によれば builtins メソッドも用意されているとのことなのですが、うまく結果が出ませんでした。

```py
conn.builtins
> <swat.cas.actions.Builtins at 0x7f04202a04e0>
```

キーで指定しても同じです。

```py
conn['builtins']
> TypeError: 'CAS' object is not subscriptable
```

同様にcasTableにもhelpメソッドが用意されています。

```
out.casTable.help()
> NOTE: Available Action Sets and Actions:
> NOTE:    accessControl
> NOTE:       accessPersonalCaslibs - Provides administrative access to all personal caslibs (CASUSER and CASUSERHDFS)
> NOTE:       assumeRole - Assumes a role
> NOTE:       dropRole - Relinquishes a role
```

----

listメソッドでオブジェクトの持つメソッドを出力させることもできますが、helpメソッドの方が説明文もあるので分かりやすいです。Python SDKの使い方に困ったらhelpメソッドを使ってみてください。

[SAS for Developers | SAS](https://developer.sas.com/home.html)

[SAS® Help Center: What's New in SAS Viya 3.4: System Programming Guide](https://documentation.sas.com/?docsetId=caspg&docsetTarget=n0wjwow8s4axl5n1vw0niv409sgr.htm&docsetVersion=3.4&locale=en)
giboをfzyで気持ちよく使うshell関数

新しい言語やらフレームワークで.gitignoreを考えるのが大変になってきて、
ようやくgiboを使う気になったので昨日からgiboデビューしました

でも、いざ書き出そうとして

```shell
=== Languages ===

Actionscript		Drupal			Jekyll			Perl			Stella
Ada			Eagle			Joomla			Perl6			SugarCRM
Agda			Elisp			Julia			Phalcon			Swift
Android			Elixir			KiCad			PlayFramework		Symfony
AppceleratorTitanium	Elm			Kohana			Plone			SymphonyCMS
AppEngine		EPiServer		Kotlin			Prestashop		Terraform
ArchLinuxPackages	Erlang			LabVIEW			Processing		TeX
Autotools		ExpressionEngine	Laravel			PureScript		Textpattern
C++			ExtJs			Leiningen		Python			TurboGears2
C			Fancy			LemonStand		Qooxdoo			
...
...
略
```

(ノД`)ﾊｧ…

これを目grepしてgibo dumpするのか〜〜ってなります

gibo dumpしたらfzyで選びたいですよね？(威圧)
giboとfzyがある環境下で.zshrcに追記しましょう

```shell
function gibo() {
	if [ -z "$2" ] &&  [ "dump" = "$1" ]; then
		command gibo list | sed -e 's/=== .\+ ===//g' | sed -e 's/\s\+/\n/g' | grep -v '^\s*$' | fzy | xargs -I@ gibo dump @
	else
		command gibo $*
	fi
}
```

うれしい

たぶん、fzyをfzfに書き換えればfzfでも動作すると思います

あ、あと、shell芸初心者なので、sed1回で済む方法とかあれば編集リクエストください
VBA：フォルダ内のファイルを順次処理

Excel VBAで個人的に使う短いコードを集めてみます。思いついたら適宜追加します。

## フォルダ内のファイルを順次処理
[Dir関数を使う方法](https://tonari-it.com/excel-vba-dir-folder-file-list/#Dir)と、FSO（ファイルシステムオブジェクト）を使う方法があります。現代人は後者です。下のようにCreateObjectを使う書き方であれば、VBEでの参照設定は不要です。

パスの区切りは、Windowsでは通常バックスラッシュ(半角の＼)あるいは円マーク(半角の¥)ですが、ここではふつうのスラッシュ(半角の/)でも大丈夫です。Macを併用する場合は、トラブルの原因になるのでスラッシュにしておくといいかも。

パス文字列の最後にも区切り文字が必要です。エクスプローラからパスをコピペしたときには、最後の区切り文字は付いてこないのでハマりどころです。

```vb:files.bas
Sub OpenFilesInFolder()

    Dim path, fso, file, files
    path = "C:/Users/xxxxxx/フォルダ名/"
    'path = ThisWorkbook.Path & "/フォルダ名/"  '相対パスの場合
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set files = fso.GetFolder(path).files

    'フォルダ内の全ファイルについて処理
    For Each file In files
    
        'ファイルを開いてブックとして取得
        Dim wb As Workbook
        Set wb = Workbooks.Open(file)
        
        'ブックに対する処理
        
        '保存せずに閉じる
        Call wb.Close(SaveChanges:=False)
    
    Next file

End Sub
```
以上はファイルを開いて、Excelのブックとして処理をする場合の書き方です。テキストファイルとして処理をする場合の書き方は「VBA FSO OpenTextFile」あたりで検索してください。

なお、複数のブックに対して処理をするもっとも簡単な方法は、処理対象ブックを全て開いておくことです。開かれているブックは Workbooks コレクションに入っているので、下のように書けば、現在開いている全てのブックに対して処理を行うことができます。

```vb:files_2.bas
    Dim wb As Workbook
    For Each wb In Workbooks
        'ブックに対する処理
    Next wb
```

追記：Word VBA でも同様の書き方が可能ですが、Documents.Openの引数を`file.path`とする必要があるようです。

```vb:files_word.bas
    For Each file In files
        Dim doc As Document
        Set doc = Documents.Open(file.path)
        'ドキュメントに対する処理
        Call doc.Close(SaveChanges:=False)
    Next file
```
VScodeでリモートのディレクトリを同期する。

vim はつらい。
VScodeでリモートのファイルを編集する場合、rmateを使う方法がよくみられるが、1ファイルごとにコマンドを打つのはつらい。
拡張機能のsftpを使用すれば、リモートのフォルダとローカルのワークスペースを同期できるので、かなり便利。

# sftpインストール
vscodeの拡張機能からインストール

#設定ファイル作成
command paletから、SFTP:CONFIGを使用。
ローカルのフォルダをワークスペースに選ぶと、sftp.jsonが作成される。

```
{
    "protocol": "sftp",
    "host": "リモートのIP or ホスト名",
    "port": 22,
    "username": "ユーザー名",
    //同期したいリモートのパス
    "remotePath": "/",
    //プライベートキーのパス(windowsでも /Users/...の書き方)
    "privateKeyPath": "/Users/auth.pem",
    //ローカルファイル保存時に、リモートに自動でアップロードするか
    "uploadOnSave": true,
    "downloadOnOpen": true
    "passphrase": "pass",
}

```
上記以外にも、設定値はある。
# リモートと紐づける
command paletから、SFTP:Sync Remote を使用し、同期する。

スーパー便利


# mac os mojave 10.14.1でrsa鍵がサポートされていない?
mac os mojave 10.14.1のssh-keygenで鍵を作成し、SFTP:Sync Remote　を行ったところ、
サポートしていない鍵のタイプなので、無理だった。
READMEをみる限り、rsaでも問題なさそうなのだが。。。

##issueが立っていた
### Unsupported key format for openssh format (Mac Mojave)
https://github.com/liximomo/vscode-sftp/issues/391

OSアップデートの影響みたいですね。

回避方法は、以下の通りの回答でした
 - ssh-keygen binaryのダウングレード(Dockerとかあるからいけるでしょ)
 - 鍵をPEM形式にしよう
私は、ubuntuで新しく鍵を作り直したら、問題なく同期できました。
対応されるのかな。対応されるといいな。
POST送信でアップロードした画像をサーバに保存したら0kBになった件(Laravel)

【症状】
フロント側のInputフォームからtype="file"で画像をPOST
Laravel側でstore()するも0kBのファイルが出来上がってしまう。

【結論】
php.iniでアップロードできるファイルの上限サイズが2MB等になってる。

【対策】

```php:/etc/php.ini
upload_max_filesize = 8M
```

変更できたら反映させるために再起動が必要。
自分の場合はApache再起動でOKでした。

```
$ service httpd restart
```
std::vectorとEigenで簡便なテンソル計算をしたい

データをテンソルとして保持する必要があるが、EigenのTensorは[Unsupported](http://eigen.tuxfamily.org/index.php?title=Tensor_support)とか書かれていて使うのが怖い。

テンソル自体は、中間変数として出てくるだけで、そこまで複雑な計算をするつもりはなく、vectorで格納した軸に対して、和が取れれば十分。

そんな時に使う小技です。


## 方針
1. std::vector<Eigen::MatrixXd>を使って、行列を格納
2. [accumulate関数](https://cpprefjp.github.io/reference/numeric/accumulate.html)を使い、vector方向に和を取る

accumulateの初期値として、`Eigen::MatrixXd::Zero(n,m).eval()`とすることで、accumulate関数を実行することができるようになるようです。
(eval()を使う理由はいまいちわかっていません)

- コード例

```
#include "Eigen/Core"
#include <iostream>
#include <vector>
#include <numeric> // accumulate関数に必要
#include <typeinfo>

int main(){
  // 初期化
  std::vector<Eigen::MatrixXd> tensor;
  for (int i = 0; i < 5; ++i) {
    Eigen::MatrixXd tmp = Eigen::MatrixXd::Constant(3, 4, static_cast<double>(i) + 0.5);
    tensor.push_back(tmp);
  }
  // 和の計算
  std::cout << "sum1 = " << std::accumulate(tensor.begin(), tensor.end(), Eigen::MatrixXd::Zero(3,4).eval()) << std::endl;
```

## 参考
http://kowaimononantenai.blogspot.com/2013/11/stdaccumulatevectorstdaccumulate3.html
https://forum.kde.org/viewtopic.php?f=74&t=118075
https://eigen.tuxfamily.org/dox/TopicPitfalls.html
https://qiita.com/sakisakira/items/7c6952e59e958cefe7fa
初心者が正規表現に軽く触れてみた。

 

プログラミングをし始めた人も時折目にする正規表現。

 

 正規表現について軽くまとめてみました。
　

簡単にいうと、


　
文字列に特定の文字が含まれているかを確認することや、特定の文字を取り除くなどの操作を行うための技術が正規表現です。
 

例えば複数のユーザーが電話番号を入力する時にハイフンをつける人とつけない人が混合してしまったとします。
 

そうすると異なるフォーマットでデータが保存されてしまい、ユーザーの情報が管理しづらくなります。


そんな時に正規表現を使うと全てのデータのハイフンを取り除いて保存することができるので非常に便利です。


そのほかにも正規表現の使われるシーンはいくつかあります。


 

・文字列の一部を置換する

・文字列が制約を満たしているか確認する

・文字列の一部を抽出する



などです。



ではJavaScriptでの正規表現における重要なメソッドをみてみましょう。

　

1. replaceメソッド

　

```js
var str = "リンゴを食べます。";

str.replace(/リンゴ/, 'みかん');
=> "みかんを食べます。"
```


replaceメソッドは、文字列の指定した部分を別の文字列に置き換えるためのメソッドです。

第一引数に置き換えたい文字列を指定し、第２引数に変換後の文字列を指定します。

また、操作したい文字列は/で囲みます。


2, matchメソッド

```js

var str = "Hello World";
str.match(/Hello/);
=> ["Hello"]

str.match(/good/);
=> null
```

matchメソッドは引数に指定した文字列がレシーバの文字列に含まれているか否かをチェックするためのメソッドです。

含まれている場合は、指定した文字列が要素となった配列が返り値として得られます。

また、含まれていない場合は、返り値としてnullが得られます。



電話番号からハイフンを取り除いてみる。

```js

var number = "090-1234-5678";
number.replace(/-/g, "");
=> "09012345678"
```

replaceメソッドの第一引数の後ろについているgはなんだ？という感じですが、これはグローバルマッチと呼び、文字列内で指定した文字が複数含まれている場合、その全てを置換するというオプションになります。

なのでもしこのgをつけなかった場合、初めのハイフンのみが置換されて、二つ目のハイフンはそのままになってしまいます。

　
＊パスワードに英数字8文字以上という制約を設定する。

```js
var pass = "Hello123";
if (pass.match(/[a-z\d]{8,}/i)) {
 //パスワード設定の処理
}else {
 alert('パスワードの形式が間違っています。');
}
```
条件分岐を設定してパスワードの形式が正しいかどうかを判定している。

　[]（角かっこ）を使用することでこれに囲まれた文字のいずれか1つがマッチするかどうかをチェックしています。

[a-z\d]：　a ~ zまでの英文字と数字にマッチ（\dは数字を表す。）

{n, m}: 直前の文字が少なくともn回、多くてもm回出現するものにマッチ。（ここでは少なくとも8回出現するものにマッチ。）

i: 大文字・小文字を区別しない検索。


＊メールアドレスの@以下を抽出する。

```js
var mail = 'aaa123@xmail.com';
mail.match(/@.+/);
=> "@xmail.com"
```

. : どの1文字にもマッチ。
+ : 直前の文字の一回以上の繰り返しにマッチ。

つまり、@以下にある任意の文字の一回以上の繰り返しにマッチするということ。


以上、初心者が触れてみた簡単な正規表現の書き方でした。
ドメイン駆動開発ってそもそも何？「実践ドメイン駆動設計」を読んだので...から学びたい vol.1

# 著者

@APPLE4869 さん

>株式会社クラウドワークス

[「実践ドメイン駆動設計」を読んだので、実際にDDDで設計して作ってみた！ - Qiita](https://qiita.com/APPLE4869/items/d210ddc2cb1bfeea9338)

# DDDってなんなの？

「物事の興味関心」をサービス、設計に実現する方法らしい。いや、それは分かってるんだけど？という話だよね。そうだよね。ごめん。

# ドメイン駆動設計の基礎知識 (引用より)


https://logmi.jp/tech/articles/310424

>まず、ものすごく単純な話、ドメイン駆動設計はソフトウェア設計の考え方とやり方の1つなんですね。

>1つは関心の分離。みなさんもよくご存じのように、ソフトウェアを作るときには、本当にいろいろ有象無象なことを解決しながらコードにしてソリューションとして作り上げていかなければいけない。

>ドメイン駆動設計では、関心の分離やドメインロジックが焦点で、どうやってモジュール化するかといったときに、オブジェクト指向でモジュール化するとことを非常に重視します。

https://logmi.jp/tech/articles/310424


# そもそもドメイン駆動設計(DDD)とは何か


ドメイン駆動設計入門
https://www.slideshare.net/TakuyaKitamura1/ddd-29003356

モデルの説明だけでこれだけある。

>● モデル
>○ 現実にある”もの”や”こと”を、関心毎に絞ってシンプルに図示したもの
>○ 選び抜かれてシンプルにされ、意図的に組み立てられた知識の表現形式
>○ 複数の人間の間で知識を共有するツール

https://www.slideshare.net/TakuyaKitamura1/ddd-29003356


# 引用役立ちすぎ

超複雑な物事に対して超簡素な俯瞰図を提供してくれる、今の時代に必要なのはこういう引用。

# 感想

とてもひとことでは言い切れない感があった。そもそもDDDというドメイ誰か天才が現れて1行で言い切ってくれるのを待とうか。











<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
ssh-keygenで生成される秘密鍵のヘッダ文字列が変わった話

ものすごく小さなトラブルでしたが、備忘録として書き残しておきます。

## 起きた問題
**AWS OpsWorksにデプロイ用のSSH秘密鍵が登録できない。**
OpsWorksに新しいAppを作成して、Application SourceとしてプライベートGitHubリポジトリに配置したコードを使おうとした。
リポジトリURLは `git@github.com:<ユーザ名>/<リポジトリ名>` な形式、もちろんプライベートリポジトリなのでssh鍵を使った認証が必須です。
そこで

```shell-session:問題の鍵生成コマンド
$ ssh-keygen -t rsa -f deploykey
```
などと鍵を生成し、
1. 生成された公開鍵（.pubの方）をGitHubリポジトリのデプロイ鍵として登録
2. 生成された秘密鍵（.pubじゃない方）をOpsWorksに登録
していくわけだが、手順2が通らなかった。曰く、赤文字で `Please provide a valid SSH key` と。

## 原因と対処法
最近のSSH秘密鍵の形式が変更されたのだが、OpsWorks側がまだこれに対応していないのが原因。

```:変更後
-----BEGIN OPENSSH PRIVATE KEY-----
XXXXXXXXXXXXXXX.....
```
```:変更前
-----BEGIN RSA PRIVATE KEY-----
YYYYYYYYYYYYYYY.....
```

~~鍵本体の仕様は変更されていないので、秘密鍵ファイルを開いて手作業でヘッダ部分の `OPENSSH` を `RSA` に置換してあげれば良い。~~ だめでした。~~旧形式で生成する方法は調査中ですが、一旦昔の `ssh-keygen` が入っているサーバで生成した鍵を使って対策しました。~~

### 2019/03/13 追記
@kazukifujii さんのコメントを参考に過去のコマンドを実行したところ、無事に旧形式で Private Key の生成ができました。 @kazukifujii さん、ありがとうございます！

```shell-session:旧形式で鍵生成コマンド
ssh-keygen -t rsa -f deploykey -m pem
```

これでOpsWorks側の鍵バリデーションが通るようになります。
![スクリーンショット 2018-12-18 11.20.41.png](https://qiita-image-store.s3.amazonaws.com/0/7459/c451fda9-da54-235e-09b3-a26b2ff241ca.png)

ちなみに、GitHubのリポジトリに設定したデプロイキーと、手持ちの秘密鍵のペアが正しく動作するか検証するときに下記のコマンドを使いました。[参考:git clone 時に秘密鍵を指定する](https://qiita.com/sonots/items/826b90b085f294f93acf)

```shell-session
$ GIT_SSH_COMMAND="ssh -i ~/.ssh/deploykey -F /dev/null" git ls-remote git@github.com:<アカウント>/<プロジェクト> HEAD
```
計算機・ソフトウェアが思うように動かなかった時にするとよい１０箇条。仮説（180）

計算機・ソフトウェアが思うように動かなかった時、
「動かなかった」
という報告をする技術者が時々いる。

なにをしたか、どうなったか、ネットで類似の現象を検索したか、何が原因だと考えるか。報告するとよいことは山のようにある。

技術者ではなく利用者ならいたしかたがない。順に、お聞きするしかない。

# 1 電源
電源ケーブルは挿さっていますか？
電池は充電していますか？

ノートPCだと、日付などを保持する小さい電池が切れていると動かないこともある。

# 2 ケーブル
本体とディスプレイのケーブルはつながっていますか？
キーボードマウスのケーブルはつながっていますか？

電池式のキーボード、マウスの場合は電池がきれていないか。

# 3 スイッチ
電源スイッチは押しましたか？
画面はひかっていますか？

画面が時間で切れているだけの時は、電源スイッチ以外のボタンを押さないといけない機器があるかもしれない。

# 4 操作は何をしたか。
電源ボタンを押したり、画面の何かをクリックしたり、コマンドを入れたり。
何をしたかを、順に記述する。

「何もしていないのに壊れた」インフラエンジニアの対応例
https://qiita.com/kaizen_nagoya/items/49c58fa6f4278717d061

# 5 画面はどうなっているか
操作の前に画面はどうなっていたか。
それから画面はどう変わっていったか。
最終的に現在、画面はどうなっているか。

画面に表示があり、操作可能であれば、画面をファイルに保存する。

操作可能でなければ、画面を写真撮影する。

画面が出ない時でも、遠隔ログインして、ソフトウェアの挙動を見ることができる場合がある。ただし、動作が止まる前に遠隔ログインしている必要があある場合もある。Macintosh, Linux, dockerなどでは、別の機器などから遠隔ログインするとよい。

関連コマンド

```
ssh
ps
ifconfig
```

Apple: 画面が真っ黒 iMAC 画面が真っ青 iMAC 画面が真っ白 iMAC 画面がまだらだ iMAC：再発：購入
https://qiita.com/kaizen_nagoya/items/be9cabac89d5a5e2668a
# 6  マニュアル、ネットで何を検索し、どう書いてあったか。

紙のマニュアルか、電子マニュアルか、ネットのマニュアルかの区分を教えてもらえるとありがたい。

マニュアルがなくてもネット検索でも出てくることがある。
https://qiita.com/kaizen_nagoya/items/8cb2891e120db8514f94
# 7 調べたことに対して、どう対応してみたか。

調べたことのURLを記録しておいてもらえるとありがたい。

# 8 原因は何だと思うか。
原因の仮説を３つ以上立ててみる。

仮説をうまくたてられなければHAZOPの魔法の言葉を使う。

# 9 原因だと思うことをどう調べればよいか。
原因の仮説をたてたら、その仮説に関連する事項をマニュアル、ネットで検索してみる。
調べるためのコマンドの例。
そのコマンドを実行した結果。

# 10 ここまでの内容を、物理現象、論理現象にかつ歴史的に区分して、書籍、ネットを再分類してみる。

うまく動かない時に、わらをもすがる思いでネットを検索している時は、まず書いてあることをやってみて確かめようとする。

それでもうまくいかないときは、記事を年代ごとに並べて、同じ機器なのか、同じソフトウェアの版なのかなどを確かめながら整理していると、試してみるとよいかもしれないことに出会うかもしれない。

# 参考文献(reference)
効率的なHAZOPの進め方
https://qiita.com/kaizen_nagoya/items/2b8eae196945b7976446

# 文書履歴(document history)
ver. 0.01 初稿 20181219 朝
ver. 0.02 追記　20181219 昼
ver. 0.03 参考資料追記　20220305
ver. 0.04 ありがとう追記 20230311
### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
####  Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
iOSのアクセスガイドがONなのに画面が消えてしまうときの対処

iPad などでアクセスガイドを使って特定のアプリを起動しっぱなしにすることでサイネージの代わりにしたりとかそういった使い方をしてる人も多いと思います。

パスコードも設定しておけば勝手に他のアプリに切り替えたりといったいたずらができなくなるし、この機能がONだと自動ロックがかからないので何かと便利なのですが、iOS 12 あたりからか、アクセスガイドがONなのに２０分ぐらいで画面が消えてしまうといった現象が起こるようになってしまい定期的に画面が消えてないかチェックしに行かなくてはならなく使い勝手が一気に下がってしまいました:disappointed_relieved:

いろいろ調べてみたのですが、やれ iOS のバグだの仕様だのといろんな意見がでてて、更にはなんかどこぞの設定をこれにしてから端末を強制再起動してなんたら…みたいな**めちゃめちゃ怪しげな対処法**まででていたようですが、ある日設定項目を見直してたらちゃんと画面が消えないようにするための設定をみつけました！

ということで忘れないようにここにメモっておきますね。

## アクセスガイドがONのときに画面が消えないようにする

設定アプリ > 一般 > アクセシビリティ > アクセスガイド と進み、
**ディスプレイの自動ロックをミラーリング**を**ON**にする

<img width="284" alt="IMG_3647.png" src="https://qiita-image-store.s3.amazonaws.com/0/25724/119bc15c-36c0-3d25-1bfd-419fa238b0c4.png">

はい。
これでだけでOKでした。


ちゃんと下にも説明が！

> オンにすると、アクセスガイドによって“画面表示と明るさ”の自動ロック設定がミラーリングされます。**オフの場合は何も操作しない状態が20分間続くと画面がオフになります**。


ということで、アクセスガイド使ってるのに画面が消えちゃって困っている人がいたら試してみて下さい:v:

（追記）
どうも更に調べてみると、この項目は[iOS 12.1.1 で追加されたっぽい](https://discussions.apple.com/thread/8577433?answerId=250028574022#250028574022)ので、そんな項目無いよ！という方はOSバージョンも確認してみて下さい
スマートスピーカーを遊びたおす会で話した「ヒロインとデート」のVUI設計思想

ごきげんよう
showです。

この記事は
**「スマートスピーカー 2 Advent Calendar 2018」**
の18日目の記事です。

昨日、「スマートスピーカーを遊びたおす会」のVol.4を開催させて頂きました。

■イベントのconnpass
https://connpass.com/event/109561/


僕も一応主催扱いになっていますが、90%が田中みそさん @miso_develop が仕切ってくれています。

なので僕は運営サポートの方が立ち位置としては近いかもしれないです。



#僕が何を話したか

今年のアドベントカレンダーにも記載させてもらっているEchoShowまわりとXperia Ear Duoについて主に話しました。

■AndroidユーザーならXperia Ear Duoすごいぞ
https://qiita.com/surumegohan/items/76ff4f589bfca45e2dbc

■EchoShowでAPLを使って告白される
https://qiita.com/surumegohan/items/be1a2d3f13eb3664a64f

そして、今作成している「ヒロインとデート（仮）」というClovaスキルについてデモ動画をやらせていただきました。
https://www.youtube.com/watch?v=KY_9i-C6LwI

#「ヒロインとデート（仮）」のVUIデザイン・設計思想

**ここからは僕個人の考えであり、必ずしもベストプラクティスとは限りません。** 

VUIのデザインにおいて重要なのは、Webページやスマホアプリのようなツリー型のドリルダウン構造は適していないことです。

例えば以下のような例は必ずしも適していないです。

![ツリー型のみ.png](https://qiita-image-store.s3.amazonaws.com/0/67398/b2363f84-5060-4aeb-8e5d-dcfba9d09752.png)

VUIのデザインは人間が意図しない状態で、**「そういえばアレは？」** となる場合があります。
上記デザインですとそれに適応できません。

なので、以下のようなフラットをイメージした方が良いと僕は考えています。

![フラット.png](https://qiita-image-store.s3.amazonaws.com/0/67398/45aa15a5-a127-797d-c73b-aa2909bab593.png)


これを念頭に、深堀していっても他の選択ができるような設計は以下になります。

![戻れる.png](https://qiita-image-store.s3.amazonaws.com/0/67398/adf82b7a-9bd0-91b9-6379-af3876a40af3.png)

##「ヒロインとデート」の場合の例

動画中にありますが、「上野駅」に行きたい旨をユーザーが話すと、上野動物園についての話題になります。

**ツリー構造のみですと、ここで「鶯谷駅」や「渋谷駅」等は選択できません。**
もしくはいちいちYes/Noを求められます。

「ヒロインのデート」のデモ動画の場合、デートの行先として、結城琴葉ちゃんから山手線の駅名を聞かれますが、「動物園」や「水族館」などの設備名でも対応するデザインになっています。

また、**想定外の場合は「他のところにしませんか？」** などのエラーメッセージを流すようにしています。
デモ動画では冗談として流しましたが、エラーハンドリングとしての発話も重要です。

かつ、僕が目指しているところは位置情報を用いることなので、そうなるとツリー型のみでは対応しきれません。

AlexaDevSummitの一部のセッションでもフラット型をイメージする旨がありましたが、VUIのデザインとしての品質をあげるには、このような設計も必要になると考えています。

#というわけで

人間の音声操作で、会話を表現しようとすると、VUIの設計思想はツリー型のみでは厳しいと考えています。

誰かの参考になれば幸いです。

以上
SAS Viyaのデータをグラフ化して保存する

[SAS Viya](https://www.sas.com/ja_jp/software/viya.html)はAIプラットフォームになります。Webブラウザ上で機械学習の設計、実行ができるStudioという環境も用意されていますが、開発者はプログラミングコードで開発することも可能です。プログラミング言語はJava/Python/R/SASが選べます。

機械学習を用いる際に専用のテーブル（casTable）を用いますが、今回はそのテーブルオブジェクト（Python版）のサマリーデータをグラフ化し、さらにHTMLとして保存します。

## テーブルの作り方

テーブルはCSV、HTML、他のデータベースなどから作れます。

```py
out = sess.upload('Jupyter_Saved_Work/Data/iris.csv')
```

ファイルをアップロードした後、casTableとして取得します。

```
tbl = out.casTable
```

## テーブルのサマリー

サマリーは summary メソッドで出力します。

```python
tbl.summary()
```

## 対象となるデータを絞る

今回は SepalLength と SepalWidth のデータだけをターゲットにします。

```python
df = tbl.summary(inputs=['SepalLength', 'SepalWidth'])
```

| Column | Min | Max | N | NMiss | Mean | Sum | Std | StdErr | Var | USS | CSS | CV | TValue | ProbT | Skewness | Kurtosis
|--------|--------|--------|--------|--------|--------|--------|--------|--------|--------|--------|--------|--------|--------|--------|--------|--------|
| 0 | SepalLength | 4.3 | 7.9 | 150.0 | 0.0 | 5.843333 | 876.5 | 0.828066 | 0.067611 | 0.685694 | 5223.85 | 102.168333 | 14.171126 | 86.425375 | 3.331256e-129 | 0.314911 | -0.552064
| 1 | SepalWidth | 2.0 | 4.4 | 150.0 | 0.0 | 3.054000 | 458.1 | 0.433594 | 0.035403 | 0.188004 | 1427.05 | 28.012600 | 14.197587 | 86.264297 | 4.374977e-129 | 0.334053 | 0.290781

## データを可視化する

データを可視化する場合にはbokehを使います。

```py
from bokeh.charts import Bar, show, output_file
```

対象データのカラムデータだけを取り出します。

```
df = tbl.summary(inputs=['SepalLength', 'SepalWidth'])['Summary']
df.columns
```

以下のような出力が確認できるでしょう。

```
Index(['Column', 'Min', 'Max', 'N', 'NMiss', 'Mean', 'Sum', 'Std', 'StdErr',
       'Var', 'USS', 'CSS', 'CV', 'TValue', 'ProbT', 'Skewness', 'Kurtosis'],
      dtype='object')
```

### HTML出力

HTML出力は output_file を使います。

```
output_file('visual2.html')
```

そしてさらにグラフの設定と出力を行います。

```py
show(Bar(df, 'Column', values='Max', color='#0000bb'))
```

これでHTMLファイルが出力されます。

<img width="500" alt="Screenshot_ 2018-12-18 11.22.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/274479/8720244b-2f4a-be50-8856-1682d006d0f6.png">

Jupyter Notebook上ではHTMLファイルはソースがそのまま見えてしまうのでダウンロードして確認します。

<img width="1105" alt="Screenshot_ 2018-12-18 11.14.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/274479/7e39ad46-844d-a781-2409-b61a8da02235.png">

----

レポートなどでグラフ化、再利用する機会は多いかと思います。output_fileやshowを使って手軽に可視化を行ってください。

[SAS for Developers | SAS](https://developer.sas.com/home.html)
clang: error: no such file or directory: 'xxx/Debug-appletvsimulator/libRCTVideo.a'

タイトルのエラーが出てビルドが出来なくなりました。

File -> Workspace Setting -> Build System を New Build System(Default) から Legacy Build System に変更するとビルドが通りました。


参考:[clang: error: no such file or directory: '..../Debug-appletvsimulator/libRCTAnimation.a'](https://github.com/facebook/react-native/issues/21400)
Terraform で VPC Peering をやる

業務で VPC Peering する機会があったので記録として残す。
https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/vpc-peering.html

# VPC Peering おさらい

２つのVPCをつないでお互いに保有するリソースをあたかも同じネットワークに存在しているかのようにする機能。

アカウント、リージョンを跨ぎのピアリングも可能。

# 制限事項(抜粋)

### CIDRブロックが重複してちゃダメ

CIDRブロックが一致・重複していると VPC Peering を作成できない。

### ピアリング先のVPCを経由した通信ができない

例えば、 `vpc-a` と `vpc-b` がピアリングしているのに加え、
`vpc-a` と `vpc−c` がピアリングしているとする。

この場合に、 `vpc-b` と `vpc-c` の相互通信をすることはできない。

# Terraform で VPC Peering をやる

```hcl
resource "aws_vpc" "vpc-a" {
  cidr_block = "10.0.0.0/16"

  tags {
    Name = "vpc-a"
  }
}

resource "aws_vpc" "vpc-b" {
  cidr_block = "10.1.0.0/16"

  tags {
    Name = "vpc-b"
  }
}

resource "aws_vpc_peering_connection" "op-connection" {
  peer_vpc_id = "${aws_vpc.vpc-a.id}"
  vpc_id      = "${aws_vpc.vpc-b.id}"
  auto_accept = true

  tags {
    Name = "op-connection"
  }
}
resource "aws_route_table" "vpc-a-route-table" {
  vpc_id = "${aws_vpc.vpc-a.id}"

  route {
    cidr_block                = "${aws_vpc.vpc-b.cidr_block}"
    vpc_peering_connection_id = "${aws_vpc_peering_connection.op-connection.id}"
  }

  tags {
    Name = "vpc-a-route-table"
  }
}


resource "aws_route_table" "vpc-b-route-table" {
  vpc_id = "${aws_vpc.vpc-b.id}"

  route {
    cidr_block                = "${aws_vpc.vpc-a.cidr_block}"
    vpc_peering_connection_id = "${aws_vpc_peering_connection.op-connection.id}"
  }

  tags {
    Name = "vpc-b-route-table"
  }
}


```
下記より詳細に見ていく。

### aws_vpc

これは単に VPC を２つ立ててるだけ。

```hcl
resource "aws_vpc" "vpc-a" {
  cidr_block = "10.0.0.0/16"

  tags {
    Name = "vpc-a"
  }
}

resource "aws_vpc" "vpc-b" {
  cidr_block = "10.1.0.0/16"

  tags {
    Name = "vpc-b"
  }
}
```

### aws_vpc_peering_connection

`peer_vpc_id` には accepter となる VPC の id を、
`vpc_id` には requester となる VPC の id を指定する。

マネジメントコンソールから VPC Peering しようとすると accepter が、
ピアリングを受け入れるかどうか許可する手順が必要だが、 `auto_accept` を `true` にしておくことでオート承認できるようにしている。

これは、VPCが同じAWSアカウントに所属している場合のみ有効。

```hcl
resource "aws_vpc_peering_connection" "op-connection" {
  peer_vpc_id = "${aws_vpc.vpc-a.id}"
  vpc_id      = "${aws_vpc.vpc-b.id}"
  auto_accept = true

  tags {
    Name = "op-connection"
  }
}
```

### aws_route_table

それぞれの VPC にルートテーブルを定義して相互通信できるようしている。
片方だけ定義すれば一方通行な通信になる。

```hcl
resource "aws_route_table" "vpc-a-route-table" {
  vpc_id = "${aws_vpc.vpc-a.id}"

  route {
    cidr_block                = "${aws_vpc.vpc-b.cidr_block}"
    vpc_peering_connection_id = "${aws_vpc_peering_connection.op-connection.id}"
  }

  tags {
    Name = "vpc-a-route-table"
  }
}


resource "aws_route_table" "vpc-b-route-table" {
  vpc_id = "${aws_vpc.vpc-b.id}"

  route {
    cidr_block                = "${aws_vpc.vpc-a.cidr_block}"
    vpc_peering_connection_id = "${aws_vpc_peering_connection.op-connection.id}"
  }

  tags {
    Name = "vpc-b-route-table"
  }
}
```

### セキュリティーグループ

必要に応じて適切な通信プロトコルを許可するために定義する。
今回は省略している。

# その他の制限事項

下記、ご参照いただきたい。

+ [Amazon VPC の制限 - VPCピアリング接続](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/amazon-vpc-limits.html)
+ [VPC ピア機能の基本 - VPC ピア機能の制限事項](https://docs.aws.amazon.com/ja_jp/vpc/latest/peering/vpc-peering-basics.html)

# おしまい。
【UiPath】改行コードで区切り、配列に入れた後に最終行だけ取り出す

【説明】
カンマ区切りで配列に入れる → [ 変数名.Split(","C) ]
上と同じ要領で[Get From Clipbord(クリップボードから取得)]したあとに最終行だけ取りたいとき、改行コードで区切ろうとして嵌ったのでメモ。
※※ Splitの引数は"Char型の配列(.ToCharArray)"が入る ※※


【補足&条件】
・改行コード = "vbCrlF"、"Environment.NewLine" ← どっちでもいい
・クリップボード内には下の文字列が入っている。"12345"のみ取り出したい。
![WS000020.JPG](https://qiita-image-store.s3.amazonaws.com/0/327749/ddd2b504-2e7e-3aa2-8db0-9542fa7435f5.jpeg)


【手順】

①クリップボードの【出力先】とString型の【配列】、最終行を入れるString型の【変数】を用意する
![WS000024.JPG](https://qiita-image-store.s3.amazonaws.com/0/327749/f830e91e-8443-227c-2aad-685b0259d807.jpeg)


②アクティビティ[Get From Clipbord(クリップボードから取得)]を追加
![WS000019.JPG](https://qiita-image-store.s3.amazonaws.com/0/327749/cb4ac958-63a8-707b-359a-43780530a922.jpeg)
　↓出力結果のみ指定する。
![WS000021.JPG](https://qiita-image-store.s3.amazonaws.com/0/327749/f651e993-1664-8e31-5993-61f5778603ff.jpeg)


④改行コードで区切って配列に入れる
・[Assign(代入)]を追加
　　左辺＝【配列】
　　右辺＝【出力先.Split(Environment.NewLine.ToCharArray) 】
![WS000022.JPG](https://qiita-image-store.s3.amazonaws.com/0/327749/d15c4cb9-3d4c-0e34-ca04-169c12614ab2.jpeg)
![WS000023.JPG](https://qiita-image-store.s3.amazonaws.com/0/327749/3bd40557-f4af-9561-f55b-99eb3b26ddcc.jpeg)


⑤配列内の一番最後の行を表示する
・[Assign(代入)]を追加
　　左辺＝【最終行を入れる変数】
　　右辺＝【配列(配列.Count - 1)】
![WS000025.JPG](https://qiita-image-store.s3.amazonaws.com/0/327749/15a26055-bea7-bc29-c3fb-1e948e9f3228.jpeg)


⑥実行
![WS000028.JPG](https://qiita-image-store.s3.amazonaws.com/0/327749/b1b91ff3-1485-14cb-421a-e286dae459fc.jpeg)
![WS000026.JPG](https://qiita-image-store.s3.amazonaws.com/0/327749/0aab9a72-1bc6-e579-9274-63b5445e71fc.jpeg)
Delphi TMessageManager

# TMessageManager使ってますか？

この記事は、Delphi Advent Calendar 2018 の18日向けの記事です。

DelphiのFMXというライブラリにはTMessageManagerという、メッセージを投げ合う便利な機能が有ります。
必要なメッセージの購読を登録すると、そのメッセージを誰かが発行した時に受け取れる機能です。

# 使い方

```delphi
uses
  System.Messaging; // 追加

type
  /// メッセージの準備
  // 送受信したいメッセージのクラスを作ります。
  // System.Messaging内のTMessage<T>から派生させます。
  // 今回は単純にStringを受け渡したいと思います。

  TMessageString = TMessage<String>;

  TOwnsMessage = class(TComponent)
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure RecvMessage(const Sender: TObject; const M: TMessage);
    procedure SendMessage(const S: String);
  end;

constructor TOwnsMessage.Create(AOwner: TComponent);
begin
  /// メッセージ購読の準備
  // 
  // マネージャを呼び出す
  var manager := TMessageManager.DefaultManager;

  // 購読したいクラスと、メッセージが飛んできた時に呼び出してもらいたい
  // 手続きを指定します.(今回はRecvMessage)
  // この時、IDがSubscribeToMessageから帰ってきますが、私は使いませんでした.
  manager.SubscribeToMessage( TMessageString, RecvMessage );
end;

destructor TOwnsMessage.Destroy;
begin
  /// メッセージ購読の解除
  // 
  // マネージャを呼び出す
  var manager := TMessageManager.DefaultManager;

  // 購読解除したいクラスと、購読時に指定した手続きを指定します.
  manager.UnsubscribeToMessage( TMessageString, RecvMessage );
end;

procedure TOwnsMessage.RecvMessage(const Sender: TObject; const M: TMessage);
begin
  // メッセージが流れてきた時に呼び出されるので M を所望のクラスにキャストして使用します。
  ShowMessage( TMessageString( M ).Value );
end;

procedure TOwnsMessage.SendMessage(const S: String);
begin
  // メッセージを送信します。
  // マネージャを呼び出す.
  var manager := TMessageManager.DefaultManager;

  // メッセージ送信
  manager.SendMessage( Self, TMessageString.Create( S ) );
end;

```

と、今回は同じクラスの中に押し込んだので便利さが伝わらないかもしれませんが、
同じメッセージクラスを違うクラス同士で投げ合えますので、何気に使い道が有るかと思います。

# 私が落ちた罠??????....(TT

TCPで通信するクラスがあって、その内容を上記TMessageManagerを使用してクラス間でやり取りしていました。
TCPの通信のクラスは、Threadで拵えていました。

TCPで受信した文字列をTMessageManager.SendMessageで他のクラスに投げていたのです。

(TTcpClientClass)TCPで受信 -> SendMessage -> (TMainForm)内容を解析して使用

不具合なく動いていたようなので、そのまま実稼働に移行しました。

しかし！！！！！！！！
現場で数時間動かすと、アプリが落ちたり応答無しになったり、、、（TT；

感の良い方はすでにお気づきだと思いますが、、、、

そうです。違うThread間でメッセージを何も考えずに投げ合っていたのです。
直接、GUIをいじったりしていたわけでは無いので、拵えていた時には気がつかなかったのです。。。

# で、どうした？

```delphi
  // 別スレッドからメインスレッドへ投げる時はSyncronizeを忘れずに..
  Synchronize( procedure
               begin
                 manager.SendMessage( Self, TMessageString.Create( s ) );
               end );

```

TMessageManagerはメッセージを投げるのには簡単ですが、
スレッド間の競合とかは、当然考えられていません。

#ps
  これは罠では無いだろうが！！と、お怒りの皆様。
　その通りでございます。m(_~_)m

###ps2
こんなおいらの仕事を見て不安になって、手伝ってやっても良いぞ！！
という方がいらっしゃいましたら、ご一報よろしくお願いいたします。

都市土木関連ですので、現場に行ける方大募集〜〜(^^;
EC-CUBE の開発環境の作り方

EC-CUBE の開発環境作成方法について、いろいろ方法があるのですが、きちんとまとまった記事が無いのでまとめてみます。

*それぞれのメリット・デメリットをもうちょっと詳しく加筆しますのでお待ちください🙏*

- レンサバを直接いじる → おすすめしない
- XAMPP, MAMP → おすすめしない
- ローカルの IIS → 素人にはおすすめしない
- ローカルの Apache や Nginx → 素人にはおすすめしない
- Vargrant → おすすめしない
- Docker → 素人にはおすすめしない
- ビルトインウェブサーバー → おすすめ

ビルトインウェブサーバーが何故おすすめかというと、 EC-CUBE3系と4系は、[1行のコマンドでインストール](https://qiita.com/nanasess/items/debc18697a89a7ccaddb) できるんです。(4系は[こちら](http://doc4.ec-cube.net/quickstart_install#コマンドラインでのインストール))

僕らコアなコミッターも、普段はビルトインウェブサーバーで開発していますので、ちょっと動かす分には全く問題ありませんよ！
アニメーションGIFから連続したコマの静止画を作りたい

アニメーションGIFから連続したコマの静止画（↓こういうやつ）を生成したかったので方法を調べました。
![output_2.png](https://qiita-image-store.s3.amazonaws.com/0/267555/89b4e30a-b907-a293-6390-cd07f2ca19f4.png)

## 実現方法

> ご指摘いただきましたが、`ffmpeg`のコマンドで出来るそうです。
> コメント欄参照。

OpenCVを使えばgifのフレー ム単位読み出しとかができるとのことなのでこれを使います。

```py
def read_gif(filename):
    gif = cv2.VideoCapture('sample.gif')
    _, img = gif.read()
    return img  
```

## 準備

とりあえず今回は、Python3とOpenCVで実装します。
必要なライブラリをインストールしておきます。

```
pip3 install opencv-python
pip3 install numpy
```

## 一枚の画像作成

あまりスマートじゃないですが、コードは以下のようになりました。
単純にgifのフレームを読み出していって、右の折り返し列が来たら次の行に進めて画像を出力していく感じです。
最終的にマトリクス状の一枚の静止画になります。フレームが足りない部分は黒塗りの画像で埋めます。

```combine.py
import cv2
import os
import numpy as np

def make_blank(h, w):
    return np.tile(np.uint8([0,0,0]), (h,w,1))

def combine_gif(filename):
    # gif読み込み
    gif_stream = cv2.VideoCapture(filename)

    # 折り返し列
    split = 10

    # フレーム読み込み処理
    vlist, hlist = [], []
    pre_w, i = 0, 1
    success = True
    while success:
        success, frame = gif_stream.read()
        
        # n行目を作成するリストに追加
        if frame is not None:
            hlist.append(frame)

        # 折り返し地点（or 読み込みがない）場合、
        if (i % split == 0 or not success) and len(hlist) > 0:

            # widthの差分を計算して黒埋め画像作成
            h, w = cv2.hconcat(hlist).shape[:2]
            diff = pre_w - w
            if diff > 0:
                hlist.append(make_blank(h, diff))

            # 横一列を結合して、行リストに追加
            vlist.append(cv2.hconcat(hlist))
            hlist = []
            pre_w = w

        i += 1

    # 行リストを結合して、画像出力
    vimg =  cv2.vconcat(vlist)
    cv2.imwrite('output.png', vimg)


if __name__ == '__main__':
    combine_gif("sample.gif")
```

## 連番画像作成

一枚の画像じゃなくて複数の連番画像を作成する場合は以下のような感じです。

```split.py
import cv2
import os

def split_gif(filename):
    # 保存先ディレクトリ作成
    output_dir = "output"
    if not os.path.exists(output_dir):
        os.mkdir(output_dir)

    # GIF読み込み
    gif_stream = cv2.VideoCapture(filename)

    # 連番画像出力
    i = 0
    while True:
        success, frame = gif_stream.read()

        if not success:
            break

        path = os.path.join(output_dir, str(i) + ".png")
        cv2.imwrite(path, frame)
        i += 1

if __name__ == '__main__':
    split_gif("sample.gif")
```

## 参考
- https://note.nkmk.me/python-opencv-hconcat-vconcat-np-tile/
- https://qiita.com/0x0c@github/items/a917c24509edfb48a828
Angular Materialのセットアップ

#内容
[Angular Material](https://material.angular.io/) を利用するためのセットアップ方法についてのメモ

## セットアップ方法

* ターミナル上で `npm install --save @angular/material @angular/cdk @angular/animations` と入力。
* `BrowserAnimationsModule`をimport
 
```tsx:app.module.ts
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';

@NgModule({
  ...
  imports: [BrowserAnimationsModule],
  ...
})
export class AppModule { }
```

* themeを設定

ここで言うthemeとは、アプリ内で利用するMaterialスタイルのこと。事前に準備されているもの(prebuild)がある。独自にテーマを作成する方法もあるが、そちらは後述。今回はprebuildのテーマを使用。`style.css` に以下を記述する。

```css:style.css
/* prebuildのテーマは４つ準備されているので好みで選択 */
 @import "~@angular/material/prebuilt-themes/deeppurple-amber.css";
/* @import "~@angular/material/prebuilt-themes/indigo-pink.css"; */
/* @import "~@angular/material/prebuilt-themes/pink-bluegrey"; */
/* @import "~@angular/material/prebuilt-themes/purple-green.css"; */
```

* 使用するコンポーネントを都度インポートする

```tsx:app.module.ts
import { MatButtonModule } from '@angular/material';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    MatButtonModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
```

* 適用されているかを確認

```html:app.component.html
<button mat-raised-button color="primary">ボタン</button>
```
![スクリーンショット 2018-12-18 10.26.42.png](https://qiita-image-store.s3.amazonaws.com/0/184967/3867a14e-0d9c-cd9e-3de4-3d19eca1af39.png)
casTableのサマリーでデータの傾向を見る

[SAS Viya](https://www.sas.com/ja_jp/software/viya.html)はAIプラットフォームになります。Webブラウザ上で機械学習の設計、実行ができるStudioという環境も用意されていますが、開発者はプログラミングコードで開発することも可能です。プログラミング言語はJava/Python/R/SASが選べます。

機械学習を用いる際に専用のテーブル（casTable）を用いますが、今回はそのテーブルオブジェクト（Python版）のサマリーにおける各カラムを説明します。

## テーブルの作り方

テーブルはCSV、HTML、他のデータベースなどから作れます。

```py
out = sess.upload('Jupyter_Saved_Work/Data/iris.csv')
```

ファイルをアップロードした後、casTableとして取得します。

```
tbl = out.casTable
```

## テーブルのサマリー

サマリーは summary メソッドで出力します。

```python
tbl.summary()
```

そうすると以下のようなテーブルが出力されます。

| | Column | Min | Max | N | NMiss | Mean | Sum | Std | StdErr | Var | USS | CSS | CV | TValue | ProbT | Skewness | Kurtosis
|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----|
| 0 | SepalLength | 4.3 | 7.9 | 150.0 | 0.0 | 5.843333 | 876.5 | 0.828066 | 0.067611 | 0.685694 | 5223.85 | 102.168333 | 14.171126 | 86.425375 | 3.331256e-129 | 0.314911 | -0.552064
| 1 | SepalWidth | 2.0 | 4.4 | 150.0 | 0.0 | 3.054000 | 458.1 | 0.433594 | 0.035403 | 0.188004 | 1427.05 | 28.012600 | 14.197587 | 86.264297 | 4.374977e-129 | 0.334053 | 0.290781
| 2 | PetalLength | 1.0 | 6.9 | 150.0 | 0.0 | 3.758667 | 563.8 | 1.764420 | 0.144064 | 3.113179 | 2583.00 | 463.863733 | 46.942721 | 26.090198 | 1.994305e-57 | -0.274464 | -1.401921
| 3 | PetalWidth | 0.1 | 2.5 | 150.0 | 0.0 | 1.198667 | 179.8 | 0.763161 | 0.062312 | 0.582414 | 302.30 | 86.779733 | 63.667470 | 19.236588 | 3.209704e-42 | -0.104997 | -1.339754

## 各カラムの説明

- **Column**  
テーブルのカラム名です。
- **Min**  
最小値です。
- **Max**  
最大値です。
- **N**  
値が入っている行数です。
- **NMiss**  
値が入っていない行数です。
- **Sum**  
合計値です。
- **Std**  
標準偏差です。
- **StdErr**  
標準誤差です。
- **Var**  
変数です。
- **USS**  
未補正平方和です。
- **CSS**  
補正平方和です。
- **CV**  
変動係数です。
- **TValue**  
仮説検証用のt検定値
- **ProbT**  
t検定のp値

----

サマリーだけでもデータの傾向は見えてくるかと思います。皆さんのデータ解析に役立ててください。

[SAS for Developers | SAS](https://developer.sas.com/home.html)