OmniAICreator/Qiita-1.07M huggingface dataset:
wordpress環境を CloudFront + ELB + EC2にて作成した時のメモ

wordpress環境を
CloudFront + ELB + EC2にて作成した時に
CloudFrontの設定でつまづいたところを残しておこうと思います。

## 各種設定
### Origin Domain Name
| オブジェクトの取得先 | DNSドメイン名の例 |
|:-:|:-:|
| Amazon S3 バケット | myawsbucket.s3.amazonaws.com |
| ウェブサイトとして構成されている Amazon S3 バケット | http://bucket-name.s3-website-us-west-2.amazonaws.com |
| MediaStore コンテナ  | mymediastore.data.mediastore.us-west-1.amazonaws.com |
| MediaPackage エンドポイント | mymediapackage.mediapackage.us-west-1.amazon.com |
| Amazon EC2 インスタンス | ec2-203-0-113-25.compute-1.amazonaws.com |
| Elastic Load Balancing ロードバランサー | my-load-balancer-1234567890.us-west-2.elb.amazonaws.com |
| 独自のウェブサーバー | https://example.com |

### SSL証明書
#### SSL証明書(CloudFront用)
us-eastでACMので作成する
#### SSL証明書(ELB用)
ELBを設置するリージョンで作成する

### ELBの設定
ELBのリスナーをHTTPS(443)にする
デフォルトのSSL証明書にSSl証明書(ELB用)を設定する

### CloudFront経由でもUserAgentを変更させない
アクセスログを確認するとアクセス元が「Amazon CloudFront」になってしまう
#### 対処法
該当のDestributionを選択
Behaviorsから対象のBehaviorを選択
Whitelist Headersから「User-agent」を追加する

### Forward Cookies
wordpressの場合、ログインセッションをcookieで管理している。
なので、Cookieを許可しなければ管理画面へはログインできません。
#### 対処法
Behaviorsから対象のBehaviorを選択
Forward CookiesのWhitelistを選択->Whitelist Cookiesに以下を追加

```
wordpress_*
wp-settings-*
```
*プラグイン等を色々使用している場合他にもcookieを使用している可能性もある。
都度確認するか、Forward CookiesをAllに設定することで対処する。

### Query String Forwarding and Caching
例えば検索(https://example.com/?test) などでも
CloudFrontを経由することでhttps://example.com/ にアクセスしたことになってしまう。
#### 対処法
Behaviorsから対象のBehaviorを選択
Query String Forwarding and Cachingを「Forward all, cache based on all」にする

## 参考
[コンテンツがエッジキャッシュに保持される期間の管理 (有効期限)](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/Expiration.html)
Windows Server 2019 on KVM on Ubuntu 18.04 on AMD Athlon 200GE でエラーが出てインストールできない

# Windows Server 2019 on KVM on Ubuntu 18.04 on AMD Athlon 200GE でエラーが出てインストールできない

→[この記事で解決](https://symfoware.blog.fc2.com/blog-entry-2330.html)

---
デフォルトで選択されているCPUタイプがEPYC-IBPBとなっているのが問題っぽい。
上の記事のようにNehalemにするとインストールすることができた。
capistrano-env_configで対象サーバの/etc/environmentを編集する

#概要
RailsとCapistranoを採用した自社開発サーバにて、ちょっとした問題があり、
/etc/environmentを編集して問題を解決しなければならない場面がありました。
capistrano-env_configを使えば解決できそうということになり、
いざ使ってみたのですが、ちょいと試行錯誤したお話。

#使ったもの
- Capistrano
- https://github.com/itay-grudev/capistrano-env_config

#実践
##とりあえずREADME通りに対象ファイルに必要なものを追加・編集
#####Gemfile
特にグループとかは意識せずにそのまま追記。

```
gem 'capistrano-env_config' , '0.0.5' 
```

#####Capfile
READMEのUsageでは「require 'capistrano/env_config/environment'」を使えと書かれてあるのに対し、Installationには「require 'capistrano/env_config'」を使えとありましたが、どっちでもいいかな？と思い、とりあえずInstallationにある方を採用。

```
require 'capistrano/env_config' 
```

#####deploy.rb
とりあえずこの三行を加えればデプロイジョブを流した際に、
/etc/environment内に「VARIABLE_hoge=VALUE_hoge」という文字列が追記されるという理解。

```config/deploy.rb
environment = Capistrano::EnvConfig::Environment.new
environment.set( 'VARIABLE_hoge', 'VALUE_hoge' )
environment.sync
```

#####権限の変更
```chown hoge:hoge /etc/environment```
```chmod g+w /etc/environment```

#####実行コマンド
後は以下のコマンドを実行すれば、environment.setで宣言したものが同期されるという理解。
```bundle exec cap staging deploy env:sync```


#途中結果
失敗しました。
内容としてはenv:setが空っぽです！みたいな怒られ方をされる。

#修正
色々考えた結果、以下の内容でいけました。
#####Gemfile
そのまま。
#####Capfile
そのまま。
#####deploy.rb
新たにNamespaceとTaskを作成し、その中でやりたいことを記載。

```config/deploy.rb
namespace :hoge_env_config do
  task :sync do
    set :env_config_roles, [ :web, :app ] #指定しない場合、「All」が適用される。
    environment = Capistrano::EnvConfig::Environment.new
    environment.set( 'VARIABLE_hoge', 'VALUE_hoge' )
    environment.set( 'VARIABLE_hoge_2', 'VALUE_hoge_2' )
    environment.sync
  end
end
```

#####権限の変更
そのまま。
#####実行コマンド
deploy.rb内で作成したhoge_env_config:syncをコマンドに追記。
```bundle exec cap staging deploy hoge_env_config:sync```

#最終結果
修正後、目的通りの動作をさせることができました。
まんま上記の内容で行った場合の/etc/environment内の内容は以下の通りです。
#####/etc/environment
```
VARIABLE_hoge=VALUE_hoge
VARIABLE_hoge_2=VALUE_hoge_2
```

#所感
ハマった原因としましては、capistrano-env_configへの理解よりもRubyやCapistranoに対する理解の問題だったと思っています。
自分が最初に記載した内容だと、ただ関数を呼び出しているだけでありCapiのタスクとして処理がされないのだと。
ならどうすべきか。ここでようやっとTaskとして処理させなければいけないという理解に至りました。
というわけでNamespaceで囲ってあげたわけです。
本記事に直結はしませんが、誤認識していた点として、実行コマンドにあるdeployもてっきりただdeploy.rbをキックしているものとばかり思っていましたが、実際は「deployというNamespaceをキックしている」のだと再認識しました。
公式のREADMEの書きっぷりでも熟練したRuby使いはさくっと理解できちゃうのだろうか・・・
以上です。ご拝読いただきありがとうございました。
typescriptからrails ujsを使う

railsでrails-ujs使うなら、requireすれば簡単にできる

```application.js
//= require rails-ujs
```

ただ、typescript + webpack + yarnでフロント管理してる時に、簡単に使えないので、入れ方を調査した

## 1. add rails-ujs
```
yarn add rails-ujs
```

## 2. moduleの解決方法をnodeに設定

typescriptのmodule解決方法は二つある

* [Classic](https://www.typescriptlang.org/docs/handbook/module-resolution.html#classic)
* [Node](https://www.typescriptlang.org/docs/handbook/module-resolution.html#node)


デフォルトはClassicになってる、rails-ujsはnodeにしないといけないので、tsconfigに設定追加

```tsconfig.json
"moduleResolution": "node",
```

## 3. importする
```application.ts
import Rails from "rails-ujs";

window.onload = () => {
  Rails.start();
};
```

## nodeにする場合、importはどう動いてるか

ここに詳しく説明してる https://www.typescriptlang.org/docs/handbook/module-resolution.html#node

今回のケースでは

```application.ts
import Rails from "rails-ujs";
```

1. node_modules/rails-ujsのを探す
2. node_modules/rails-ujs/package.json探す
3. package.json中のmain探す
   
    ```node_modules/rails-ujs/package.json
    { "main": "lib/assets/compiled/rails-ujs.js" }
    ```
4. main中で設定したパス node_modules/rails-ujs/lib/assets/compiled/rails-ujs.jsを探す
Unreal Engine 4メモ：structの接頭辞が「F」の理由

# 接頭辞「F」の意味
UE4の構造体は「F」の接頭辞が付いています。しかしそれは何の略なのでしょうか？
Actorが「A」、UObjectが「U」ならば恐らく「Float」ではないかという予測は立ちます。
しかしstructならば「S」が妥当なような気がします。

そこで調べてみました。すると答えはフォーラムにありました。
みんな疑問に思ってたんですね。

# structの接頭辞「F」はfloatの意味。
やはり、floatの意味だったようです。そして始まりはfloat型のベクトルを表す「FVector」でした。その「F」はいつしかすべての構造体に付くようになり広まっていったようです。
その結果リフレクションのシステムにまで及んだのが現在の形みたいですね。

[参照：std math function ?](https://forums.unrealengine.com/showthread.php?1588-std-math-function&p=10304&viewfull=1#post10304)
VSCode

## 環境

```
$ code -v
1.46.1
```

## settings.json

```settings.json
{
    "workbench.startupEditor": "newUntitledFile",
    "editor.wordWrap": "on",
    "editor.mouseWheelZoom": true,
    "workbench.enableExperiments": false,
    "explorer.openEditors.visible": 0,
    "extensions.autoUpdate": false,
    "update.mode": "none",
    "telemetry.enableTelemetry": false,
    "telemetry.enableCrashReporter": false,
    "workbench.editor.enablePreview": false
}
```
非エンジニアによるS3画像サーバの運用を検討する

# はじめに

Webサービスにおいて負荷分散等の理由からHTMLを格納するサーバと、画像のみを格納するサーバ（以下画像サーバ）にサーバリソースを分けるシーンがあります。
画像サーバへのファイルの追加や更新をサービス運用メンバ（非エンジニア）にて行ってもらうにあたり、AWSマネージメントコンソールから作業するのは色々不都合があると考え、運用メンバが慣れ親しんでいるFTPクライアントソフトを使った方法を検討しました。

# 準備

S3上のファイルを公開する際、Route53やCloudFrontを併用する方法がありますが、今回はあまり話を広げずS3とIAM、FTPクライアントのファイル管理についてのみとします。

## S3

既存のBucketは稼働しているシステムで利用しているため、専用のBucketを作成します。
作成後は「アクセス権限」→「バケットポリシー」にて以下を入力しBucketを外部からアクセスできる状態にします。

```json:バケットポリシー
{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::[バケット名]/*"
        }
    ]
}
```

## IAM

画像ファイルを操作する専用のポリシーとユーザーを作成します。

### ポリシー

Bucketの一覧は表示させつつ、特定Bucketのみ更新できる設定を追加します。

```json:IAMポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "s3:ListAllMyBuckets",
                "s3:GetBucketLocation"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:s3:::*"
        },
        {
            "Action": "*",
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::[バケット名]",
                "arn:aws:s3:::[バケット名]/*"
            ]
        }
    ]
}
```

### ユーザー

以下の通り作成します。

- AWSアクセスの種類
    - プログラムによるアクセス：有効
    - AWSマネジメントコンソールへのアクセス：無効
- アクセス許可
    - 既存のポリシーを直接アタッチから先に作成したポリシーを選択
- ユーザー作成後、認証情報よりアクセスキーを作成する
    - アクセスキーIDとシークレットアクセスキーをメモしておきます（以降のFTPクライアントで使います）

## FTPクライアント

今回の例としてWinSCPをあげます。
WinSCPはversion5.13からS3の操作が可能になりました。
https://forest.watch.impress.co.jp/docs/news/1107401.html

メモしたアクセスキーIDとシークレットアクセスキーで、S3へのアクセスおよび対象Bucketの更新が可能となります。

# おわりに

本件を導入することにより、サービス運用メンバはAWSを意識することなく画像ファイルの更新ができるようになりました。専用の管理画面をエンジニアにて開発して運用メンバに提供する案も考えましたが、今回あげた案の方が運用メンバが慣れ親しんでいるFTPクライアントで利用できるのと、導入コストが低い点で採用となりました。
メディアクエリだけでモバイルデバイスを判定する

デバイスを判定する方法として、UAから判断したり[UAparser.js](https://github.com/faisalman/ua-parser-js) などのライブラリを使う方法がありますが、とにかくモバイルかどうかだけを判定したい時に、ライブラリを読み込んだりするのもどうなのか。と思っていた時に、発見した方法がメディアクエリを利用する方法


参考：
https://medium.com/@ferie/detect-a-touch-device-with-only-css-9f8e30fa1134

# CSSの2つのフィーチャーを使う

それは **[Hover](https://developer.mozilla.org/ja/docs/Web/CSS/@media/hover)** と **[Pointer](https://developer.mozilla.org/ja/docs/Web/CSS/@media/pointer)**

**hover**
> ポインティングデバイスが要素のhoverをサポートしているかをチェックすることができる

**pointer**
> ポインティングデバイスを持っているか、もしそうならば、主要なポインティングデバイスにどれだけの正確性があるかを調べる

この二つを組み合わせることで、モバイルデバイスを判定することができる

```css
/** mobile 判定 **/
@media screen and (max-width: 640px) and (hover: none) and (pointer: coarse) {
  .some-classname {
    display: none;
  }
}
```

とてもシンプル。
Javascript側で使いたいときは、window.matchMediaを使う

```javascript
/** mobile判定 */
function isMobile() {
  return (window.matchMedia("(hover: none) and (pointer: coarse)").matches)
}
```

## Androidが判別できない

上記だけでは、Androidが判別できない。
Androidでサポートされていないqueryのようで、判定できない様子

結局のところ UAで判定するしかないのだろうか...

```javascript
function isMobile() {
  return (window.matchMedia("(hover: none) and (pointer: coarse)").matches) ||
         (navigator.userAgent.indexOf('Android') > 0)
}
```
redashでソースコードをハイライトする方法

# redashでソースコードをハイライトする方法

redashのtextboxはマークダウンを使用できる場合もあればhtmlで記述できる表記もあり様々です。
![textboxウィンドウ.PNG](https://qiita-image-store.s3.amazonaws.com/0/386370/10a83f61-a3a2-90ea-6471-59ca40b6c971.png)

今回はテーブル作成方法を探していた途中で見つけたソースコードの記述方法を紹介します。
（テーブル作成方法は未解決です。。）

### 一般的にマークダウンでソースコードを貼る方法

最初に試した記述は一般的に検索すると出てくるソースコードの貼り付け方です。これですよね。↓

    ```
    ソースコード
    ```

redashの場合は意図した表記になりません。
（先頭に改行を入れても変わらず）
![textboxソースコード試し.PNG](https://qiita-image-store.s3.amazonaws.com/0/386370/991e0591-870f-f0d6-26d9-0e4082ddbabc.png)
確かにこの表記もありますが今回使いたいのはこれじゃない。

### redashでソースコードを貼る方法
redashの場合はタイトルを表記し、改行×2。
そのあと半角スペース×4の後に表記すると、意図した表示になりました。
![textboxソースコード成功.PNG](https://qiita-image-store.s3.amazonaws.com/0/386370/68f7407d-f26d-8c71-2c11-904c4e2695c6.png)
![textboxダッシュボード.PNG](https://qiita-image-store.s3.amazonaws.com/0/386370/086286e3-fb28-58a6-350a-aba20ac98e14.png)

※半角スペース×4→tabではだめでした。
Ruby、seleniumでスクリーンショットを撮ろうとして困った話

# 困ったこと
以下のようなコードを書いてヘッダレスでWEBサイトを撮ろうと思ったら、エラーが出てうまく動かなかった。

```
require "selenium-webdriver"

...

options = Selenium::WebDriver::Chrome::Options.new
options.add_argument('--headless')
driver = Selenium::WebDriver.for :chrome, options: options
driver.manage.window.resize_to(width, height)
driver.get(url)
driver.save_screenshot(image_path)
driver.quit
```

出るエラーは、

```
unable to connect to chromedriver 127.0.0.1:9515
```

なにやらchromedriverとの連携がうまくいっていないらしい。chromedriverはhomebrewで入れたものをそのまま使っている。コマンドラインからそのまま叩いたらchromedriver自体は起動している（ように見える）ので、rubyとの連携がうまくいっていないのだろう、と思った。

ちょっと調べてみると、`chromedriver-helper`というgemを入れたら動くようになったという情報を見つけたのでgemfileに加えて`bundle install`すると・・・

```
  +--------------------------------------------------------------------+
  |                                                                    |
  |  NOTICE: chromedriver-helper is deprecated after 2019-03-31.       |
  |                                                                    |
  |  Please update to use the 'webdrivers' gem instead.                |
  |  See https://github.com/flavorjones/chromedriver-helper/issues/83  |
  |                                                                    |
  +--------------------------------------------------------------------+
```

なにやら最近非推奨のgemになったらしい。代わりにwebdriversというのを入れろと言われたので入れてみた。→うまくいった！

# 感想
色々なブラウザをサポートしているのかな、という感じ。（単にchromedriver-helperの更新が終わるから変わっただけかもしれない)
何はともあれ、動いてよかった
AMTでリモート接続

AMTを使ってリモート接続するうえで、なんやかんや躓いた記録。

## 環境

|AMTバージョン|11.6.0.1042|
|:--|:--|

## Intel AMTとは
Intel vPro対応のPCやサーバでマシン情報を取得したり、電源ON/OFFなどのリモートコントロールができる機能。
ハードウェアでサポートされているので、追加でVNCサーバ等を設定しなくてもよく、電源ON/OFFやBIOS設定等ができるのが利点。

## AMTの初期設定
設定方法はいくつも説明してくれているサイトがあるので割愛
>[Intel AMT （１）PC ：リモートで情報取得、遠隔操作するための初期設定（Intel AMT 10編）](http://itwork100.com/intelamt-10-pc-set/)
>[AMTとはクライアントPCの管理・制御をリモートからでも簡単に行えるようになりSEさんの労力やコストを削減できる機能です。](https://zigsow.jp/review/226/245865)

設定している中で躓いたところを列挙します。

- NICは一つだが電源OFF時も独立したモジュールがNICにIPを振るようでOSが起動するとOS側とモジュール側で二つのIPに応答するようになるので、OSとモジュールは別のIPを設定した方が良い。(試しに同じIPを設定してpingを打つと見事にDUP!が返ってきた）
- Networkをactivateしてもpingが通らない場合、一度Unconfigureでリセットして再設定すると私はうまくいった。

### AMT使用ポート
外部からリモート接続する際はポートフォワードする必要がある。
私が接続に成功した設定は下記となる。

|ポート番号|用途|
|:--|:--|
|16992|SOAP/HTTP ポート|
|16993|SOAP/HTTPS ポート|
|16994|リダイレクション /TCP ポート|
|16995|リダイレクション /TLS ポート|

[参考:インテル® アクティブ・マネジメント・テクノロジー: プライバシー・ステートメント](https://www.intel.co.jp/content/www/jp/ja/privacy/intel-active-technology-vpro.html)
「工場向け「地域版」5G」日本経済新聞20190409 可能性と危険性

「工場向け「地域版」5Gの」
https://www.nikkei.com/article/DGXMZO43469470Y9A400C1MM8000/

>総務省が今秋にもエリアを限った無線通信を通信大手以外の業種に広く開放する

>同省は12日に割り当て条件を決め、今秋までに省令を変える。携帯大手には、この電波は当面割り当てない。

>地域版5Gは既存の衛星通信と電波を共用するため、総務省は通信が乱れないように地域を限る。まずは建物内や敷地内で通信サービスをする企業に割り当てる。来年にも実施する追加の割り当てでは、より広い地域で使えるようにする。

>総務省によると、携帯大手と別枠で地域限定の電波を割り当てる具体的な計画があるのは現時点で日本とドイツだけだ。独でも工場内などの利用を想定する。今月初旬に世界に先がけて携帯大手が商用サービスを始めた米国と韓国は大手以外への割り当てには動いていない。

確定情報ではない

#5G
5G（第5世代移動通信システム）
https://www.nttdocomo.co.jp/corporate/technology/rd/tech/5g/

au 5G
https://www.au.com/mobile/area/5g/

ソフトバンク 第5世代移動通信システム「5G」
https://www.softbank.jp/biz/5g/

楽天、4G/5Gの試験施設「楽天クラウドイノベーションラボ」
https://news.mynavi.jp/article/20190221-774910/

# 可能性
工場向け5Gが成功する可能性は、5G向け端末と、5G向け基地局の低価格化が鍵である。
5Gに対して、対抗するのは、Wi-Fi6, IEEE 802.11axの可能性がある。

Wi-Fi6は、端末も基地局も大量生産で低価格化が予想できる。
5G端末も基地局も大量生産は予測できるが、流通費用が低くなるかどうかが鍵となる。

## 市場性
低価格化の鍵は、市場競争。
工場に、特定の製造業者の端末、基地局を導入するのであれば、市場性による低価格化は難しい。

|  | ５G | Wi-Fi6 | LPWA |
|:--|:--|:--|:--|
| 普及 | これから | 立ち上がり始め | 立ち上がり中 |
| 通信速度 | 最大10Gbps | 最大4.8Gbps | 250 kbps(LoLa) |
| 距離 | 周波数による | 規格未決定 | 最大10 km(LoLa) |
| 特徴 | 音声・デジタル | Wi-Fi互換 | 消費電力 |

#危険性
市場性があっても、すべての通信機器が成功した訳ではない。競合する規約・仕組みが、より安価であれば、費用対効果に遜色がなくても、終わっていったサービスはたくさんある。

ポケベル, ISDN, PHS, ADSL, ZigBeeなど次々に置き換わっている。
LPWA (Low Power, Wide Area)も競合である。

## 5G端末
## 5G基地局


### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
####  Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life
Python2とPython3で外部のシェルスクリプトやコマンドを実行する方法まとめ

[前回](https://qiita.com/qualitia_cdev/items/f6cfe189c299821e3b1c)の記事でPython3からシェルスクリプトを実行するテストを紹介しました。
今回はPythonでシェルスクリプトを実行する方法についてPython2.xとPython3.xの違いを中心にまとめます。

## Python 2.x

#### os.system('ls -al')
コマンドが成功すれば0が返ってきます。


```
import os

status = os.system('ls -al')
print status
```


#### commands.getoutput('ls -al')
実際に実行した結果が返ってきます。

```
import commands

res = commands.getoutput('ls -al')
print res
```


## Python 3.x

#### subprocess.run
os.systemより発展されたもの。コマンドの戻り値を色々設定出来ます。一番良く使うパターンはこんな感じ。

```
import subprocess

res = subprocess.run(
        ['ls', '-al’], stderr=subprocess.PIPE)

print(res.stderr)
```

subprocessの使い方は色々あります。
以下の記事などご参考ください。
ref. [subprocessの使い方(Python3.6)](https://qiita.com//caprest/items/0245a16825789b0263ad)

#### commands.getoutput
3.xではなくなりました。簡単に使えて楽だったので少し残念です。
firestoreとできるだけ通信したくない！～firestoreオフラインデータの使い方～

firestoreのオフラインデータをキャッシュとして使い、なるべくサーバと通信しない方法をやっていきます。
firestoreの基本的な操作はわかってる人向け。

#まずはオフラインデータを有効にしようね

[オフライン データを有効にする | Firebase](https://firebase.google.com/docs/firestore/manage-data/enable-offline?hl=ja)
>ウェブの場合、オフラインの永続性はデフォルトで無効になっています。永続性を有効にするには、enablePersistence メソッドを呼び出します。

オーケー！

>ユーザーが同じ Cloud Firestore データベースを参照する複数のブラウザタブを開き、オフラインの永続性が有効になっている場合、Cloud Firestore は最初のタブでのみ正しく動作します。

それは困る。具体的な状況はわからんが俺の直感が困ると告げている。
でも大丈夫！

https://firebase.googleblog.com/2018/09/multi-tab-offline-support-in-cloud.html
>Multi-Tab Offline Support in Cloud Firestore!

マルチタブもイけるようにしたよ（意訳）
さすがgoogle！そこにシビがれる！blogじゃなくてdocumentに書いとけよそういうこと！
というわけで。

```js
const db = firebase.firestore();
db.enablePersistence({ experimentalTabSynchronization: true }).then(() => {
  console.log("マルチタブでオフラインデータが使えるよ！");
});
```

はい！オフラインデータが有効になりました。
これでfirestoreに追加したデータは、同時にlocalのindexedDBにキャッシュされます。

#キャッシュからデータを取得しよう
[オフライン データを有効にする | Firebase](https://firebase.google.com/docs/firestore/manage-data/enable-offline?hl=ja)
>端末がオフラインのときにドキュメントを取得すると、Cloud Firestore はキャッシュからデータを返します。そのドキュメントのデータがキャッシュに存在しない場合やドキュメントが存在しない場合、get 呼び出しはエラーを返します。

違うの！オフラインのときだけじゃなくて、いつでも最初はキャッシュからデータがほしいの！
というわけでコレ！

```js
// friendsコレクションからservalのデータを取得するよ！
const serval = await db
  .collection("friends")
  .doc("serval")
  .get({ source: "cache" }); // コレ！
```
docRefのgetメソッドにはオプションが設定できるよ！
`source:"cache"`で明示的にキャッシュからデータを取得できちまうんだ！
通信も発生しないんだ！

#遊び方は無限大
`get()`にオプションをつけていだけなので、collectionを丸ごと取得したり、whereも使えます。
キャッシュにデータがないときはerrorを返すので、catchして`get({ source: "server" })`すれば良いと思います。
キャッシュ生活始めよう！
OpenGLでEquirectangular形式の画像を扱う場合の作法

# はじめに

こんにちは！

メロンパン大好きリコーの@meronpanです。 :melon: 

主にTHETAプラグインに関連する記事を書いてます。

THETAプラグインをご存じない方は[こちら](https://api.ricoh/products/theta-plugin/)をご覧ください。

もし、興味を持たれた方は[Twitter](https://twitter.com/theta_plugin)のフォローと
[THETAプラグイン開発コミュニティ(Slack)]
(https://join.slack.com/t/thetadeveloper/shared_invite/enQtNzcxODI2MTk2ODg0LWY5YmU2ZTIxNGYwNzlmNWZjMWMyMWFlMzY3ZmQ3NGU3ZjZiZjI0Njk4MGIxMDU5NDJiMzQ4Y2FkNDEzYmFlNGU)への参加もよろしくおねがいします｡

[前回記事](https://qiita.com/meronpan/items/d95d69d31386e8b2878f)ではTHETA内でインスタ映え画像を表示するTHETAプラグインについて書きました。

今回はその続きと思いきや、気まぐれのメロンパン

THETAの画像(Equirectangular形式の画像)を扱う場合の作法についてやんわりと説明して行きたいと思います。

いやー、メロンパンのやること想像つかない。 :melon: 

というわけで早速内容に入ります。


# 目次

* THETAで撮影した画像形式（Equirectangular）
* Equirectangularの扱い方を学ぼう
* 球体モデルを作成しよう
* メロンパンの戯れ
* メロンパンの呟き

# THETAで撮影した画像形式（Equirectangular）

「Equirectangular」は日本語で[正距円筒図法](https://ja.wikipedia.org/wiki/正距円筒図法)といいます。

「正距円筒図法(Equirectangular)」は地図投影法の一種であり、緯線・経線が直角でなおかつ等間隔に交差するように描かれている図法です。

この図法で描かれた世界地図を見たことがある人も多いと思います。

メロンパンがたった１人でみなとみらいに行った時の画像を使って説明します。 :melon: 

THETAでとった360°画像は以下のようになってます。

![equirectangular.png](https://qiita-image-store.s3.amazonaws.com/0/265189/ef7eaeb7-584f-8cec-35e0-e1a75942db15.png)


こちらが「正距円筒図法(Equirectangular)」です。


# Equirectangularの扱い方を学ぼう

世界地図が地球儀に置き換えられるように、Equirectangularは球体モデルに変換することが出来ます。

全天球画像で画像処理を行うときは、Equirectangularから球体に形式を変換してから処理することが非常に多いです。

下図にあるように、Equirectangular上の点Peを単位球上の点Psに変換する場合を考えたいと思います。

λは経度、φは緯度を表します。

![equi2sphere.png](https://qiita-image-store.s3.amazonaws.com/0/265189/4268a2af-5634-f20e-60fa-8700e75e0e87.png)


Equirectangular ↔ 単位球の相互変換式は以下の図のように、点と軸と平行な線で構成された立方体から考えます。

（分かりやすくするために、単位球上の点周りを拡大して補助線を引きました。）

変換式は、下図の右側のようになります。

![equi2sphere2.png](https://qiita-image-store.s3.amazonaws.com/0/265189/5fb15556-cedd-7233-db97-490f84920256.png)




# 球体モデルを作成しよう

やり方としてはグラフィック処理で、球体の型を作成し、そこにEquirectangularの画像を貼り付けることを行います。

実際には、「Equirectangularの扱い方を学ぼう」で説明した計算式を使ってEquirectangular形式の画像を球面に置き換える処理を行っています。

作成した球体の型は以下の写真です。

![sphere_model.png](https://qiita-image-store.s3.amazonaws.com/0/265189/7877c7fc-041a-3d66-2bd9-ec72131efdf0.png)


型は頂点の集合体となっており、わかりやすいように頂点間を繋いで格子状に表示してみました。

同様にEquirectangularも格子状に分割し、球体の型に貼り付けていくイメージです。

型に貼り付けるとー

![sphere.png](https://qiita-image-store.s3.amazonaws.com/0/265189/77013151-2837-0afd-f8a6-9eeba45a56b8.png)


じゃじゃーん！！

球体のモデルができましたー



# メロンパンの戯れ

ここでは数式を変えるだけで球体以外にも画像を貼り付けられることを紹介したいと思います。

以下を参考にボンヌ図法で表示させてみました。

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

リンク先よりボンヌ図法の数式を参考に「球体モデルをみてみよう」で説明したようにボンヌ図法の型を作成するとー

![bonne_model.png](https://qiita-image-store.s3.amazonaws.com/0/265189/2a2a22b2-2b4c-15bd-6883-6e5a1ddaeec7.png)


さらに、撮影した画像をボンヌ図法で作成した型に貼り付けていくとー

![bonne.png](https://qiita-image-store.s3.amazonaws.com/0/265189/96c5a8e7-b7f8-f96b-0fe1-f8e7faf62ea6.png)


できましたー


# メロンパンの呟き

openGLを使ったTHETAで撮影した画像の扱い方を紹介しました。

数式を使ってモデルを表すことができればもっと色々なことができると思います。

メロンパンはあまり数学得意ではないので、脳みそフル回転させました。

みなさんもメロンパンフル回転させて、ぜひ色々な表現方法を試してみてください。

これであなたもTHETAプラグインにメロメロン :melon:
ORACLE データベースのエクスポート

#概要
オラクルの論理バックアップの取得は、expdpコマンドを使って行います。
このコマンドを実行すると任意のディレクトリに.dmpという拡張子のバックアップファイルが作成されます。
※.dmpファイルは通常中身を確認できません。

筆者は過去に大規模開発案件にてexpdpコマンドを使い、
データベースのバックアップを行うバッチを作成したので備忘録として残したいと思います。

#準備
expdpコマンドの実行にはオラクルでディレクトリオブジェクトの登録・ユーザーへの権限付与が必要です。
ディレクトリオブジェクトとはオラクルでの階層の別名のようなもので
下記の場合、"/home/test"配下にダンプファイルが作成されます。

```sql:SQL
    create or replace directory TEST_DIR as '/home/test';
    grant read, write on directory TEST_DIR to SCOTT;
```
※TEST_DIR =設定するディレクトリオブジェクト名
　/home/test=設定するパス
　SCOTT=ユーザ名

####■コマンド例
ディレクトリオブジェクトBにログを出力する場合

```sql:SQL
expdp ユーザ/パスワード directory=ディレクトリオブジェクト名A dumpfile=ディレクトリオブジェクト名B:dmpファイル tables=スキーマ.テーブル reuse_dumpfiles=y    
```
###パラメータ
####■動作モード
|パラメータ|内容|引数|
|---|---|---|	
FULL|全体エクスポートで処理を行う。|full=y or n
|SCHEMAS	|指定のスキーマ名に対して処理を行なう。カンマで複数指定可能|schemas=スキーマ名
|TABLES|指定のテーブルに対して処理を行なう。同スキーマならカンマで複数指定可能|tables=テーブル名
※他にも表領域を指定してエクスポートを実行できますがここでは割愛します。

####■ダンプファイル
dumpファイルとlogファイルを別ディレクトリに出力したい場合は、それぞれディレクトリオブジェクトを用意し、コマンド内で指定する。

|パラメータ|内容|引数|
|---|---|---|
|DIRECTORY|ディレクトリオブジェクト名。デフォルトでのダンプファイル、ログファイルが出力されるディレクトリとなる。| directory=ディレクトリオブジェクト名|
|DUMPFILE|ディレクトリオブジェクト名：出力ファイル名となる。|dumpfile=ディレクトリオブジェクト名:ファイル名|
|REUSE_DUMPFILES|エクスポート時に既にダンプファイルがある場合、上書き保存を許可する。(パーミッションは変更されない)　※Oracle11g以降|reuse_dumpfiles=y or n|
####■ログファイル
|パラメータ|内容|引数|
|---|---|---|			
|LOGFILE|出力ディレクトリオブジェクト名：出力ログファイ名となる|logfile=ディレクトリオブジェクト名:ログファイル名|
|NOLOGFILE|ログファイルを出力しない|nologfile=y or n|

####■注意点　パーミッション
expdpコマンドで作成したダンプファイルの所有者はORACLEとなりパーミッションの関係上、一般ユーザでは読み取れないので注意が必要です。
筆者は動作確認でディレクトリオブジェクト配下に空のファイル(test.dmp)を作成しパーミッションも任意に設定しました。
expdpコマンドのダンプファイル名をtest.dmpにして
__上書きオプション : reuse_dumpfiles=y__
でコマンドを実行することでファイルの移動や読み取りを行いました。
[TypeScript]IE11でも手軽に動くawait/async

#ES2017と非同期と取り残されたIE11

　SPA(SinglePageApplication)のような仕組みを用いたJavaScriptでフロントエンド開発では、Ajaxによる非同期通信を頻繁に行うことになります。この際、非同期で生じる多数のコールバックによって、プログラムの可読性が下がる結果となります。しかしES2017ではasync/awaitが導入され、ほとんどのブラウザでは標準的に動くようになっています。しかしそこに取り残されたものがいます。IE11です。

#IE11対応の必要性とGoogleBot

　開発元のMicrosoft自身がEdgeに移行することを推奨しており、新規案件では対応の必要性は皆無と言って良いでしょう。しかしIE11での必要性は無くてもIE11で動くようにしておいた方が良い決定的な理由があります。それはIE11で動くものはGoogleBotが理解できる、つまりSEO対策が行えるということです。ES2017をフロントエンド開発に用いた時点で、そこはGoogleBotが理解できないサイトと化すのです。GoogleBotの動作確認を最も簡単に行うには、仕様の古いIE11を用いるのが一番簡単なのです。

#そもそもIE11でPromiseが使えない

　async/await以前の問題として、IE11ではPromiseが使えません。正確には標準対応していません。ただし使う方法はあります。HTMLの中に以下のコードを入れるだけです。

```
<script type="text/javascript" src="https://www.promisejs.org/polyfills/promise-7.0.4.min.js"></script>
```

　無いものを無理矢理実装してくれるものなので、ネイティブで対応している環境に比べれば当然のごとくオーバーヘッドがあります。しかし元々非同期が必要なケースは遅延実行が核となるので、大した問題にはなりません。

#async/awaitはどうするの？

　さきほどの内容でIE11でPromiseは使えるようになりました。次はasync/awaitです。この部分にはいくつかの選択肢があるのですが、一番簡単なのはTypeScriptを使うついでにトランスコンパイルしてもらうことです。

```tsconfig.json
{
	"compilerOptions": {
		"sourceMap": true,
		"target": "es5",
		"module": "commonjs",
		"lib": [
			"es2015",
			"dom"
		]
	}
}
```
　targetをes5にしておけば、await/asyncがトランスコンパイルでIE11でも使用可能となります。対応作業はこれだけです。当然ですがTypeScriptのコンパイル環境が必要となるので、Node.jsとTypeScriptのモジュールはインストールが必要です。

#サンプルソース

##　サンプルコード置き場
　　　[GitHub](https://github.com/mofon001/TypeScript_await_IE11)

##　サンプル解説
　このサンプルでは非同期の同期が分かりやすいようにSleep()による待機機能を作りました。1秒ごとに出力という文字列がブラウザに追加されていきます。

```index.html
<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8" />
	<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1" />
	<script type="text/javascript" src="https://www.promisejs.org/polyfills/promise-7.0.4.min.js"></script>
	<script type="text/javascript" src="index.js"></script>
	<title>TypeScript_await_ie11_test</title>
</head>
<body>
</body>
</html>
```

```index.ts
/**
 * 待機用関数
 * timeout 待機時間(ms)
 * @returns Promise<void>
 */
function Sleep(timeout:number) : Promise<void>{
	return new Promise((resolv)=>{
		setTimeout(()=>{
			resolv()
		}, timeout)
	})
}
/**
 *メイン関数(非同期)
 *@returns Promise<void>
 */
async function Main() : Promise<void>{
	const div = document.createElement('div')
	document.body.appendChild(div)
	while(true){
		div.innerHTML += '出力<br>'
		await Sleep(1000)
	}
}
//ページ読み込み時に実行する処理を設定
addEventListener("DOMContentLoaded", Main)
```

　非同期系の機能をPromise化してしまえば、後は昔ながらの線形的な書き方でプログラムを記述することが出来ます。

#まとめ
　現在、Webシステム用のオリジナルフレームワークを作っています。[フロントエンド側のライブラリ](https://croud.jp/?p=484)がある程度が仕上がり、こっちはまだ未公開ですがNode.jsで開発しているバックエンド側の実装もある程度すすみました。

　その中で、フロントエンドからバックエンドへの通信機能を、ローカル関数を呼ぶかのごとく簡単に使える機能の実装しました。そこで今回のawait/asyncを使っています。結果としてとんでもなく記述が簡単になりました。

　そのあたりの内容は、サンプルアプリケーションを一本作ってから記事にしたいと思います。
dockerでbundle installしてMySQL2をインストールしようとしたらハマった話


## 環境

OS：macOSMojave
バージョン管理：rbenv
ruby version: 2.6.0

##症状
自分はDocker環境でこの事象が発生しましたがDocker環境以外でも同じ問題でつまづいたことがあります。その時とはややエラーの内容が異なりましたので別の解決方法で解決しました。
その際に参考にしたのは[こちらの記事](https://qiita.com/HrsUed/items/ca2e0aee6a2402571cf6)で解決させていただきました。

エラーの内容が`ld: library not found for -lssl`で止まってしまっている場合などは上記の記事で解決できると思います。

今回の事例は

```
$ docker-compose run --rm app ./bin/bundle install --path vendor/bundle
```
Dockerで`bundle install`をしようとしたら

```
Errno::EACCES: Permission denied @ rb_sysopen -
/app_name/vendor/bundle/ruby/2.6.0/gems/mysql2-0.5.2/CHANGELOG.md
An error occurred while installing mysql2 (0.5.2), and Bundler cannot continue.
Make sure that `gem install mysql2 -v '0.5.2' --source 'https://rubygems.org/'` succeeds before
bundling.
```

というエラーで弾かれてしまいました。

## 原因

`Permission denied`と出てるのでどうやら権限周りの問題が原因になってそうです。

まず最初に疑ったのはrbenvではなくsystemのrubyやgemを使っているのではないかと思い確認してみました。

```
$ which ruby
/Users/username/.rbenv/shims/ruby

$ which gem
/Users/username/.rbenv/shims/gem
```

どうやらrbenvで管理されているのでこれは問題なさそう。

そしてめげずに調べたら[こんな記事](http://infinity108.com/114/)がありました。

確かに前にsudoつけて色々インストールした記憶があるなと思い色々な箇所の権限を確認してみましたが問題になってるのは上記のエラー内容に記載されてる`/app_name/vendor/bundle/ruby/2.6.0/gems/mysql2-0.5.2/`以下っぽい。

コマンドで権限を確認してみる

```
$ ls -ltr vendor/bundle/ruby/2.6.0/gems/mysql2-0.5.2
total 64
-rw-r--r--   1 root  staff     87  4  5 22:17 CHANGELOG.md
-rw-r--r--   1 root  staff   1078  4  5 22:17 LICENSE
-rw-r--r--   1 root  staff  24534  4  5 22:17 README.md
drwxr-xr-x   4 root  staff    128  4  5 22:17 examples
drwxr-xr-x   3 root  staff     96  4  5 22:17 ext
drwxr-xr-x   4 root  staff    128  4  5 22:17 lib
drwxr-xr-x  10 root  staff    320  4  5 22:17 spec
drwxr-xr-x   6 root  staff    192  4  5 22:17 support
```

やはりinstall時にsudoをつけてしまっていたみたいですね。。。。

## 解決策

先ほどの記事内の手順に沿って

```
$ sudo chown -R (ユーザー名):staff vendor/bundle/ruby/2.6.0/gems/mysql2-0.5.2
```
を実行し、ディレクトリの権限をユーザーに戻す。

そして再度

```
$ docker-compose run --rm app ./bin/bundle install --path vendor/bundle
```

すると


```
Fetching mysql2 0.5.2
Installing mysql2 0.5.2 with native extensions
```

無事にインストールができました。

自分は普段はiOS,Androidが専門なので中々つまづきましたが今後サーバーサイドも結構やることがありそうなので忘備録として書きました。
ブックマークレットで簡易リンク集をひらくよ

# まえがき
環境が複数あると、つい各環境のサイトをブックマークするんですが、
パッと見がよく似てるブックマークが並んでしまい、
たまーにリンクを間違えてイラッとしたりすることもあり…(´・ω・｀)

そういうのを少しでも防ぎたかったので、ブックマークレットで対応したって話です。


# ソースはこんなの

```js
javascript: (function() {
    list = [
        {
            "name": "ローカル",
            "url": "https://local.example.com/"
        },
        {
            "name": "開発",
            "url": "https://dev.example.com/"
        },
        {
            "name": "ステージング",
            "url": "https://staging.example.com/"
        },
        {
            "name": "本番",
            "url": "https://example.com/"
        }
    ];
    newwin = window.open("", "_blank");
    newwin.document.open();
    newwin.document.write("<html><head></head><body>");
    for (i in list) {
        row = list[i];
        newwin.document.write("<h3><a href='" + row.url + "admin/'>" + row.name + "</a></h3>");
    }
    newwin.document.write("</body></html>");
})();
```

これを[bookmarklet maker](http://userjs.up.seesaa.net/js/bookmarklet.html)などブックマークレットの生成ツールを使って圧縮、ブックマークに登録します。

このブックマークレットをクリックすると、新規ページ（タブ）で↑のリンク集が表示されます。
H3タグで囲ってるのでちょっと文字が大きく表示されるから、押し間違いが減ってイラッとしなくなりました（個人差あり）。


# あとがき
しょーもない・・・けど自分には必要だったので記録でした。
たぶんまた作りそうだったし、そのときコピペ出来た方が楽なので。

・・・まぁ、実はこれに飽き足らず自分用にChromeアプリを作ったりもしたんですが、、、
「正直、そこまでいらないな・・・(´・ω・｀)」と思ったのでこっちだけ記録です。
jQueryのブラウザバック問題について

#jQueryのブラウザバック対処法
jQueryをお使いの方であれば、一度は悩まれたことがあるはずの「ブラウザバック問題」を取り上げます。

jQueryはWebサイトに簡単に動きをつけられる便利なツールですが、ページの「戻る」ボタンで実装ページに戻るとjQueryは効きません。

おそらくjQueryが一方通行的なロードの仕方をしているからでしょうが、これは非常にまずいです。
ユーザーの方が、ページを戻った時にレイアウトの崩れた画面を見ることになってしまいます。

そこで、以下の方法で解決しましょう。



#document&ready
よくこの問題が起こるのはanimateのscroll移動などですね。

```javascript:application.html.erb
<script>

$(document).on("click", ".angle-icon", function(){
          $("html,body").animate({
              "scrollTop": 0 
          },"slow");
        });

</script>
```

これは、私が実際に実装した際の　jQueryコードです。
angle-iconクラスをクリックすると、ページ最上部へスクロールします。

しかし、やはり「ブラウザバック問題」が発生しました。
そこで、

```javascript:
<script>

$(document).ready(function(){
 $(document).on("click", ".angle-icon", function(){
  $("html,body").animate({
         "scrollTop": 0 
    },"slow");
  });
});

</script>
```

これで、ブラウザバックしてもきちんとjQueryが効きます。
Pythonでforやwithで使う変数の型宣言

# はじめに

最近、動的型付けの言語に型を宣言して書くスタイルが流行っているように思います。(説明が雑ですが）
Pythonも例に漏れず、その流れを汲んでいます。allennlpとか、fastapiとか綺麗にtypeを書いてくれてるので参考になります。

個人的には、APIの型をちゃんと書いてくれてると、OSSのソースコードとかも読みやすいし、チームで開発する際にも良いことがたくさんあると思っています。「動的な言語は、型がないからいいんじゃん！」っていう方もいると思いますが...

導入自体は難しくないので、Pythonの公式やmypyなどを確認してみると良いです！
TypeHint: https://docs.python.org/ja/3/library/typing.html
Mypy: http://mypy-lang.org/

# for

さて、静的型付けの言語、特にCとかだとforで新しい変数を宣言するときに、以下のように書くことがあると思います。

```C:
for (int i = 0; i < 10; i++) {
    hoge
};
```

これをPythonで書くと、

```python
i: int 
for i in range(10):
    hoge 
```

これだけ。

## with

```python
from typing import IO
from pathlib import Path

fp = Path('file_path')

f: IO
with fp.open('r') as f:
    pass
```

らしいです。
ちなみに、for, with以外では許されていない記法らしいです。


# 参考
- https://www.python.org/dev/peps/pep-0526/#where-annotations-aren-t-allowed
- https://stackoverflow.com/questions/41641449/how-do-i-annotate-types-in-a-for-loop
proxy配下のnpm設定

いつも忘れるので覚え書き。

社内環境によってnpmの実行がはじかれる場合。
まずは現在の設定を確認

```パス
$ npm config list
```

## proxy設定 ##

デフォルトでは環境変数のHTTP-PROXY(http-proxy)を参照。（設定がなければnull）
環境変数にproxy設定を入れるのが手っ取り早いが、今回はnpmだけproxy経由したいので、
npm configにproxy設定を追加。
※環境変数とnpm configに設定がある場合は、npm configが優先される

```
$ npm config set proxy http://PROXY.com:PORT
```

`https-proxy`も同様の設定

```
$ npm config set https-proxy http://PROXY.com:PORT
```

`npm config` に追加されていることを確認。


## レジストリ設定 ##

`npm install` 時に以下のようなエラーが発生したらregistry URLを変更

```
npm ERR! network tunneling socket could not be established, cause=7252:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:openssl\ssl\s23_clnt.c:766:
npm ERR! network
npm ERR! network This is most likely not a problem with npm itself
npm ERR! network and is related to network connectivity.
npm ERR! network In most cases you are behind a proxy or have bad network settings.
npm ERR! network
npm ERR! network If you are behind a proxy, please make sure that the
npm ERR! network 'proxy' config is set properly.  See: 'npm help config'
```

registryの`https`を`http`に変更

```
$ npm config set http://registry.npmjs.org/
```

以上で`npm install`が利用可能になる。

## proxyを削除する ##
proxy設定を削除する場合。以下をターミナルから実行。

```
$ npm config delete proxy
$ npm config delete https-proxy
$ npm config set https://registry.npmjs.org/  ←初期設定に戻す
```

proxy設定をON/OFFを繰り返すならBATにした方が良い。
【ASP.NET】コードビハインドで同期／非同期ポストバックによる分岐を実装する

マスターページの利用を前提としています。


非同期ポストバックを利用するためには、```ScriptManager```、```ToolkitScriptManager```のどちらかをマスターページに記載しておく必要があります。

```html:hogehoge.master
<!-- ここで指定した ID を後ほど利用します -->
<cc1:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server">
</cc1:ToolkitScriptManager>
```

```vb:hugahuga.aspx.vb
' ページロードなどのイベント
Private Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load

    ' ポストバックそうでないかを判定できる
    If IsPostBack Then
        ' 同期／非同期に関わらずポストバック時に実行される
        ' 画面の再表示などで使われる

    Else
        ' ポストバックではない場合に実行される
        ' 画面の初期表示などで使われる

    End If

    ' こちらは同期ポストバックか非同期ポストバックかを判定できる
    ' hogehoge.masterで指定した ID を使う
    If DirectCast(Master.FindControl("ToolkitScriptManager1"), ScriptManager).IsInAsyncPostBack Then
        ' なんらかの非同期処理

    Else
        ' なんらかの同期処理

    End If

End Sub
```

また、JavaScript側で非同期通信の開始／終了時に実行したい処理を記述することもできます。

```javascript:hugahuga.aspx
    addEventListener('load', function () {
        const mng = Sys.WebForms.PageRequestManager.getInstance();

        mng.add_initializeRequest(function (sender, args) {
            // 非同期処理の開始時に実行したいなんらかの処理
            // テキストボックスを一時的に入力不可にしたいときなどに使えます。
        });

        mng.add_endRequest(function (sender, args) {
            // 非同期処理の終了時に実行したいなんらかの処理
        });
    }, false);
```
PHPでGuzzleを使って非同期でHTTPリクエストを投げるメモ

非同期でHTTPリクエストができるGuzzleを試してみたメモ。
内部的にはcurl_multiを使っているそうです。

## インストール
composerを使ってインストールします。

```
$ composer require guzzlehttp/guzzle
```

## 使い方

非同期でHTTPリクエストを投げるコードがこちら。

```php
<?php
require 'vendor/autoload.php';

use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Promise;
use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\Exception\RequestException;

$client = new Client();

$promises = [];
for($i = 0; $i < 10; ++$i){
    $promise = $client->requestAsync('GET', 'http://httpbin.org');
    $promise->then(
        // Fullfilled
        function(ResponseInterface $res){
            echo $res->getStatusCode() . "\n";
        },
        //Rejected 
        function(RequestException $e) {
            echo $e->getMessage() . "\n";
            echo $e->getRequest()->getMethod();
        }
    );
    $promises[] = $promise;
}
Promise\all($promises)->wait();
```

- Guzzleには、非同期でリクエストするためのメソッドが複数用意されています。
上記のコードでは、`requestAsync()`を使ってます。
http://docs.guzzlephp.org/en/stable/quickstart.html#async-requests


- 非同期リクエスト用のメソッドは、Promise/A+の仕様で実装されているので、仕様に沿って`then()`で成功時と失敗時に呼び出す関数を設定します。
https://promisesaplus.com/

が、この方法だとPromiseオブジェクトがメモリを食うため、foreach()でメモリオーバーで落ちる可能性があるらしい。

この問題を回避するために使えるものが、Poolオブジェクト。
先ほどのコードをPoolオブジェクトを使う方法で書き換えたものが下記のコード。ジェネレータを使ってます。

```php
<?php
require 'vendor/autoload.php';

use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Promise;
use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Pool;

$client = new Client();
$requests = function() use ($client) {
    for($i = 0; $i < 10; ++$i){
        yield function() use ($client) {
            $promise = $client->requestAsync('GET', 'http://httpbin.org');
            $promise->then(
                // Fullfilled
                function(ResponseInterface $res){
                    echo $res->getStatusCode() . "\n";
                },
                //Rejected 
                function(RequestException $e) {
                    echo $e->getMessage() . "\n";
                    echo $e->getRequest()->getMethod();
                }
            );
            return $promise;
        };
    }
};
$pool = new Pool($client, $requests());
$promise = $pool->promise();
$promise->wait();
```
PostgreSQLでMySQLのAUTO_INCREMENTを使う

# AUTO_INCREMENT属性とSERIAL型

AUTO_INCREMENT属性はMySQL用なので、PostgreSQLでは使用できません。

PostgreSQLでは、SERIAL型を使います。

```sql:MySQLの場合
CREATE TABLE tasks (
    id INT(10) NOT NULL AUTO_INCREMENT,
    name VARCHAR(255) NOT NULL,
    created_at TIMESTAMP,
    updated_at TIMESTAMP,
    PRIMARY KEY (id)
);
```

```sql:PostgreSQLの場合
CREATE TABLE tasks (
    id SERIAL NOT NULL,
    name VARCHAR(255) NOT NULL,
    created_at TIMESTAMP,
    updated_at TIMESTAMP,
    PRIMARY KEY (id)
);
```

# メモ

- MySQLではAUTO_INCREMENT属性を、PostgreSQLではSERIAL型を使う
- SERIAL型は`1`から`2,147,483,647`の値を取り扱う
- なお、PostgreSQLでは`int(10)`のように、INT型に桁数の指定はできない
- PostgreSQLのINT型は`-2,147,483,648`から`2,147,483,647`の整数を取り扱う

# 参考

- [MySQL 8.0 Reference Manual - Using AUTO_INCREMENT](https://dev.mysql.com/doc/refman/8.0/en/example-auto-increment.html)

- [PostgreSQL 10.5文書 8.1. 数値データ型](https://www.postgresql.jp/document/10/html/datatype-numeric.html)
lambdaでエラー


# AWSのリソースからlambdaで引っかかったところ

```python:test.py
support_client = boto3.client('support')
```

```sh
An error occurred (AccessDeniedException) when calling the DescribeTrustedAdvisorChecks operation
```

AccessDeniedExceptionだから普通に権限ないって怒られているみたいですね…

![FireShot Capture 162 - IAM Management Console_ - https___console.aws.amazon.com_iam.jpg](https://qiita-image-store.s3.amazonaws.com/0/251226/db95a9b2-6de4-e0e7-9a00-d5f2d9232d70.jpeg)

なのでIAM Roleから実行対象のlambdaのロールにPolicyをアタッチすればよい
Knowledge-Embedded Routing Network for Scene Graph Generation

https://arxiv.org/abs/1903.03326

## abstruct

・シーン理解
・Knowledge-Embedded Routing Network(KERN)を開発->オブジェクトラベルとオブジェクト対のラベルを別々のGNNで予測
・the large-scale Visual Genome datasetでSOTA
・CVPR2019

## 背景
##### ・シーングラフ生成の既存アプローチ 
・ターゲットオブジェクトの領域に頼る
・認識を助けるために加えて文脈的な手掛かりを導入する

#####・既存の問題点
・大量のサンプルが必要
###
##・なぜ大量のサンプルが必要か
・実社会でのオブジェクト同士の関係が不均一→大量サンプル数が必要

・KERNは、オブジェクト同士の関係の統計的相関が意味空間を効果的に正則化し、予測の曖昧さを少なくすることで、データの不均衡問題にうまく対処した

## ネットワークの大きな流れ
object detection(Faster RCNN)
↓
グラフ作成
↓
GNNを繰り返すことによってノードを予測
↓
予測されたノードラベルを使用
2つのノードをラベル数分のグラフを作成
GNNを繰り返すことでノードの関係を予測
すべての接続しているペアを入力
↓
シーングラフ作成
Gitコマンド

## ローカルリポジトリ作成

```
$ git init
```

## リモートブランチをクローン

```
$ git clone https://~
```

## プル

```
$ git pull
```

## フェッチ

```
$ git fetch
```

## ログ確認

```
$ git log
```

## ローカルの変更を確認

```
$ git status
```

## ステージングに追加

```
$ git add .
```

## ステージングからワークツリーに戻す

```
$ git reset .
```

## ワークツリーの変更を破棄する

```
$ git checkout .
```

## コミット

```
$ git commit -m "Initial commit"
```

## コミット番号を指定して戻す

```
$ git reset --soft コミット番号
```

--soft：ファイルの変更を保持する
--hard：ファイルの変更を破棄する

## 直前のコミットを取り消す

```
$ git reset --soft HEAD^
```

## n個前のコミットまで取り消す

```
$ git reset --soft HEAD~2
```

## プッシュ

```
$ git push
```

## 上流ブランチにプッシュ

```
$ git push origin
```

## リモートの同名ブランチにプッシュ

```
$ git push origin develop
```

## リモートのブランチ名を指定してプッシュ

```
$ git push origin develop:develop
```

## リモートのブランチにプッシュして上流ブランチに設定

```
$ git push -u origin develop
```

## リモートのブランチを強制的に上書き

```
$ git push -f
```

## ローカルブランチを表示

```
$ git branch
```

## リモートブランチを表示

```
$ git branch -r
```

## リモート・ローカルブランチを表示

```
$ git branch -a
```

## ブランチ作成

```
$ git branch develop
```

HEADからブランチが作成される

## ブランチの切り替え

```
$ git checkout develop
```

ローカルにブランチがある場合：ローカルブランチに切り替えられる
ローカルにブランチがなくリモートにブランチがある場合：リモートブランチからチェックアウトされる
ローカル・リモートにブランチがない場合：エラーで失敗する

## ブランチ削除

```
$ git branch -d develop
```

-D：ローカルブランチのコミットがリモートにない場合エラーとなるため、Dオプションで強制的に削除する

## リモートブランチ削除

```
$ git branch --delete origin develop
```
MacでUSBに焼いたWindows10がインストールできなかったので対処した話

## 概要
自作PCを作った際になるべく安く済まそうと、Windows10のプロダクトコードだけ買ってisoはMacを使って自分で焼けばいいやと考えていたのですが、簡単にはいきませんでした。
Qiitaで書くべき内容かは怪しいところですが、ブログを持っていないのでメモとして書き残しておきます。
先に結論から言うと、落としていたwin10のisoが良くなかったぽいです。

## hdutil & dd コマンドで焼いてみた
なるべくCUIで済ませたいと思っていたので、まずはコマンドでやってみました。
[MacでWindows 10の起動ディスク（USBメモリ）を作成する方法](https://ottan.xyz/mac-windows-10-usb-1879/)
を参考に全く同じ手順で行ったので、本記事では手順を割愛します。
使用したisoは、**2018/10のパッチ適用後**のwin10のものです。

さて、書き込みが終わったUSBをMacから取り外し、組みたてほやほやのマシンに挿して起動してみます。
BIOSでUSBの優先度を上げておいたので、Windows10のインストーラーが無事に立ち上がります。
なんや簡単やんけと思っていたのですが、セットアップ中に「有効なドライバがありません」と吐いてしまい、インストールに失敗してしまいます。調べてみると、こんな記事が見つかりました。
[Macしかない環境でWindows10のISOをブータブルUSBに作成[M.2 SSDが認識されない]](https://hdwe.biz/2018/07/macwindows10isousbm2-ssd.html)
確かに自分のマシンでもM.2 SSDを使用していたので、これで勝つると思いました。その時は。

## unetbootinで焼いてみた
CUIでは無くなってしまいましたが、専用のソフトウェアがあるならそっちを使ったほうがいいよね。ということで前述の記事を参考にして再度焼き直しました。こちらも手順は割愛します。

さて、2度目の挑戦です。無事にインストーラーが立ち上がり、ドライバが無いと文句を言われることもなくなりました。しかし、今度は`install.wim`が読み込めないと怒られてしまいます。
`install.wim`はその名の通り、winのインストーラーの中核を成すファイルです。コイツが読み込めないとどうしようもありません。

## 原因調査
USBに焼いている途中でファイルが破損してしまったんか...？と思い、一度USBをフォーマットし、再度unetbootinで焼いてみましたが、これも失敗。
ソフトやUSBが原因では無さそうなので、`install.wim`ファイルがちゃんといるのか確認してみましたが、問題なく**4.3GB**のファイルがおりました。  

...あれ...？ FAT32って4GBまでのファイルしか書き込めないはずでは...？  

ここが怪しそうだったので、試しに**2018/10のパッチ適用前**のisoを落としてきて、それをunetbootinで焼いてみました。
焼き終わった`install.wim`のファイルサイズを見てみると**3.7GB**。これなら行けそうです。

## 結果
いけました。途中でBIOSがUSB認識しなくなったりとトラブルはありましたが、結果としては無事にインストールを終えることができました。
恐らく、Windows公式のイメージ作成ツールではこんな事態は起こらないと思うのですが、どうやって4GB超えのファイルを焼いているのでしょうか。ご存知の方は教えてくださると幸いです。
メモ：複数のコマンドを並列実行する簡易コマンド

GNU parallelをインストールせずに並列実行を実現したかったので、そのとき作ったShellのメモ

### ちなみにGNU parallelを使った場合はこんなかんじ

```bash
% time parallel -j 2 {} << EOF
  echo 1;sleep 5;
  echo 2;sleep 5;
EOF
1
2
parallel -j 2 {} <<<'  echo 1;sleep 5;     echo 2;sleep 5;'  0.22s user 0.23s system 8% cpu 5.500 total
```

### 処理部分

```shell
CPU_CORE=2
parallel_exec () {
  for i in "$@"; do echo $i; done | xargs -I{} -P ${CPU_CORE} sh -c {}
}
```

### 使用方法

```shell
parallel_exec "コマンド１" "コマンド２"
```

### 使用例

```shell
$ parallel_exec "echo hoge" "echo foo"
hoge
foo
```

### 実行時間計測結果

```shell
$ time parallel_exec "sleep 3; echo hoge" "sleep 1; echo foo"
foo
hoge

real	0m3.021s
user	0m0.011s
sys	0m0.014s
```
sleep 1の foo が先に出力され、全体の実行時間も約３秒なので期待通り。

### エラー時の挙動

ちなみにスクリプト中のコマンドでエラーが発生すると parallel_exec 自体もエラーコードを返してくれる

```shell
$ parallel_exec "sleep 3; exit 0" "sleep 1; exit 1"
$ echo $?
1
```
XOOPS で AdelieDebug利用中はリダイレクト停止させる

XOOPS Cubeのモジュール開発時に[AdelieDebug](https://github.com/suin-xoops/xoops-adelie-debug/tree/master/source/AdelieDebug)を利用すると画面上にデバッグのために欲しい情報が出てきて便利です。

でも、リダイレクト画面だと数秒のうちに次の画面に遷移してしまうため表時内容を確認することが出来ません。

そこでAdelieDebug利用中はリダイレクトさせないようにしてみました。

いじったのはhtml/modules/legacy/templates/legacy_redirect.html

下記の様に変更してみました。

```legacy_redirect.html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=<{$xoops_charset}>" />
  <{if !class_exists('AdelieDebug_Preload')}>
  <meta http-equiv="Refresh" content="<{$time}>; url=<{$url}>" />
  <{/if}>

<title><{$xoops_sitename}></title>
</head>
<body>
<div style="text-align:center; background-color: #EBEBEB; border-top: 1px solid #FFFFFF; border-left: 1px solid #FFFFFF; border-right: 1px solid #AAAAAA; border-bottom: 1px solid #AAAAAA; font-weight : bold;">
  <h4><{$message}></h4>
  <p><{$lang_ifnotreload}></p>
</div>
<{if class_exists('AdelieDebug_Preload')}>
<p style="color:red;text-align: center">AdelieDebug実行中のだめ自動でリダイレクトしません.</p>
<{/if}>
</body>
</html>
```

実際にはファイルを直接いじるよりもAltSys等つかってDBテンプレートをいじるとか、テーマ下テンプレートにいれておくのがいいでしょうね。

これでリダイレクトせずに停止してるんで、じっくり表時内容を確認出来ます。
HIVEのクエリでデリミタで区切られた文字列の前後を入れ替える

某データを見ていたら、政令指定都市の場合に市区町村名が

```
千種区, 名古屋市
```

などと区, 市の順に並べて格納されており、正規化に難儀したので備忘録メモ。

## 解決したい課題・制約など
- 市区町村データの中に`区名, 市名`という具合にデリミタで区切られて逆順になっているレコードがある
- それらをHIVEのクエリの中でデリミタを取り除き通常の順に並び替えたい
- それ以外は普通に`市町村名`となっているのでそれらに影響を与えないこと
- HIVEのバージョンは1.1.0


## 解決例
HIVEの`regexp_replace`が普通に後方参照を扱えるので、デリミタ前後をグループ化してキャプチャし`$2$1`として入れ替える。
デリミタは今回の場合カンマ`,`で、直後にスペースが入る可能性があったので`,? *`とした。

### 名古屋市千種区でテスト

```sql
hive> select regexp_replace('千種区, 名古屋市', '^([^,]+),? *([^,]*)$', '$2$1');
OK
名古屋市千種区
```

| 正規表現の該当部分      | 該当した文字列 | 意味 |
|-----------|----------|------------|
| `^`         |          | 先頭 |
| `([^,]+)`   | 千種区    | カンマ（`,`）以外の文字1文字以上。$1で参照される|
| `,? *`      | ,        | デリミタの指定。カンマ（`,`）と、その後に空白が続くかもしれない|
| `([^,]*)`   | 名古屋市  | カンマ（`,`）以外の文字0文字以上、存在しないかもしれない。$2で参照される|
| `$`         |          | 末尾|

`$1`が`千種区`、`$2`が`名古屋市`になるので、`$2$1`は`名古屋市千種区`になる。



### 通常の市町村名の場合はそのままの値が戻ることを確認。

```sql
hive> select regexp_replace('春日井市', '^([^,]+),? *([^,]*)$', '$2$1');
OK
春日井市
```
| 正規表現の該当部分      | 該当した文字列 | 意味 |
|-----------|----------|------------|
| `^`         |          | 先頭 |
| `([^,]+)`   | 春日井市    | カンマ（`,`）以外の文字1文字以上。$1で参照される|
| `,? *`      |        | デリミタの指定。カンマ（`,`）と、その後に空白が続くかもしれない|
| `([^,]*)`   |   | カンマ（`,`）以外の文字0文字以上、存在しないかもしれない。$2で参照される|
| `$`         |          | 末尾|

`$2`が空になるので、`$2$1`は`春日井市`になる。



## 参考
- [Hadoop利用者ならきっと知ってる、Hive/Prestoクエリ関数の挙動の違い](https://qiita.com/y-ken/items/400b7c70c324ac67af02)
- [[整形] URL文字列を整形する（★★★）](https://support.treasuredata.com/hc/ja/articles/215479727)
さくっとVagrantでCentOS7の環境を用意

# 概要

ただ仮想環境でCentOS7の環境を用意するだけ

# インストールしとくもの

* Vagrant
* VirtualBox
* （GitBash）これはお好みで

私はWindowsでやっていますが、Macでも同様と思います。
作業はGitBashで行っていきますが、お好みで他のものでも良いと思います。

# 手順

```bash
# initする
vagrant init centos/7

# Vagrantfileが作成されているはず
ls -al
drwxr-xr-x 1 aaamm 197609    0 4月   9 07:41 ./
drwxr-xr-x 1 aaamm 197609    0 4月   9 07:40 ../
-rw-r--r-- 1 aaamm 197609 3085 4月   9 07:41 Vagrantfile

# 起動
vagrant up
```

以上

# おわり

ただ試しに少し使用するように、何も設定しないやつをすぐ構築したかったやつです。
Ajaxで動的に変わるセレクトボックスを作ったが動かないのでメモ（前は動いたのに）

#1. 前提
セレクトボックスで都道府県を選択すると、次のセレクトボックスで市町村などのより詳細なエリアが選択できるやつ

[![Image from Gyazo](https://i.gyazo.com/31f2102dac5d5737f196d2a642dcced6.png)](https://gyazo.com/31f2102dac5d5737f196d2a642dcced6)

#2. 現象

都道府県を選択しても次のセレクトボックスが動かない。
（開発環境（AWS Cloud9）でのみ。Herokuでデプロイしたものは動く。）

#3. 原因を調査

[![alt](https://i.ytimg.com/vi/Nf0QjFx5O5k/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIpCGAFwAYABAQ==&rs=AOn4CLCsSkc0-iSQjAw-I257VwN0oHXx1A)](https://youtu.be/Nf0QjFx5O5k)
【デバッグ解説動画】RailsアプリでAjaxがうまく動かないときに確認するポイントあれこれ

**Ajaxが動く流れ**
1. ブラウザでセレクトボックス変更
2. jQueryからJSへreplaceChildrenOption
3. JSからRailsにリクエスト
4. Rails内でデータ取得
5. JSにレスポンス
6. ブラウザのサブカテゴリ書き換え

**手順１**

- ChromeのデベロッパーツールのSourceでブレークポイントを付ける
    - 止まる→１〜２あたりは動いている
    - 止まらない→イベントが正しく設定されていない→そこにブレークポイントをつけてみる

　↑問題ない

**手順２**

- NetworkのXHR：JS側でリクエストを投げたのがわかる。返ってきたデータなども見れれば３〜４はできてるとわかる

　↑返ってこない。Why？

#4.Railsのログを見てみる

```
Can't verify CSRF token authenticity.
Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms)
```

「422って数字、デベロッパーツールのエラーで見たことあるな…」
↓
調べてみる

Ruby on Rails のサーバーにPOSTが送れない！？（Can't verify CSRF token authenticity）
http://nonbiri-tereka.hatenablog.com/entry/2014/09/03/104824

>
CSRFとはなんでしょうか？Cross-Site Request Forgeriesの略で、POSTするところに誘導するような攻撃のようです。これを防ぐ為に実装されたとかなんとか。
>
解決方法
ApplicationControllerのprotect_from_forgery, :exceptionの箇所を、null_sessionとする。

ここで紹介されているとおりexceptionを、null_sessionにしたところきちんと動いてくれた。

ひとまずここまで。
[外部からPOSTできない？RailsのCSRF対策をまとめてみた
](https://qiita.com/KumatoraTiger/items/cc6a1107374cce500e6d)↑こういうの見ればいい？

また調べよう。
ABC - 097- A&B&C

#AtCoder ABC 097 A&B&C
[AtCoder - 097](https://atcoder.jp/contests/abc097)

#A問題

 - A,B,C間の距離がD以下であれば通話可能

```java
	private void solveA() {
		Scanner scanner = null;
		int numA = 0;
		int numB = 0;
		int numC = 0;
		int numD = 0;

		try {
			scanner = new Scanner(System.in);
			numA = scanner.nextInt();
			numB = scanner.nextInt();
			numC = scanner.nextInt();
			numD = scanner.nextInt();

			boolean canTalk = false;

			canTalk = ((Math.abs(numA - numB) <= numD && Math.abs(numB - numC) <= numD)
					|| Math.abs(numA - numC) <= numD);

			System.out.println(canTalk ? "Yes" : "No");

		} finally {
			if (scanner != null) {
				scanner.close();
			}
		}
	}
```

#B問題

 - X以下の最大のべき乗数を求める
 - 簡略化しようとすると変な回答をしてしまうので、おとなしく全探索をする
 - $i^j \leqq X$をループで回し、X以下の最大を求める
    - $i \leqq X$ となる。 $X$ 超えたら終了という条件

```java
	private void solveB() {
		Scanner scanner = null;
		int numX = 0;

		try {
			scanner = new Scanner(System.in);
			numX = scanner.nextInt();

			int max = 0;
			for (int i = 1; i <= numX; i++) {
				for (int j = 2; j < 10; j++) {
					if (Math.pow(i, j) <= numX) {
						max = Math.max(max, (int) Math.pow(i, j));
					} else {
						break;
					}
				}
			}

			System.out.println(max);
		} finally {
			if (scanner != null) {
				scanner.close();
			}
		}
	}

```

#C問題

文字列を切り出す作業を実際にやってみると、文字列長はKまででいいことがわかる。
**文字列長がKより長い文字列はK番目以内に来ることができない**

 - 文字列は連続した値なので以下の操作でよい
    - 文字列のindex=0から1-K文字切り出して
    - index=1から1-K文字切り出して
    - index=2から1-K文字切り出して
    - ・
    - ・

```
文字列：abcoder
長さK：6

a
ab
abc
abco
abcod
--abcode
--abcoder
b
bc
bco
bcod
bcode
--bcoder
co
cod
code
coder
```

```java
	/**
	 * 文字列を切り出す作業を実際にやってみると、文字列長はnumKまででいいことがわかる。
	 *abcoder
	*
	*a
	*ab
	*abc
	*abco
	*abcod
	*--abcode
	*--abcoder
	*b
	*bc
	*bco
	*bcod
	*bcode
	*--bcoder
	*co
	*cod
	*code
	*coder

	*/

	private void solveC() {
		Scanner scanner = null;
		String s = "";
		int numK = 0;

		try {
			scanner = new Scanner(System.in);
			s = scanner.next();
			numK = scanner.nextInt();
			/*
			 * 切り出し時の重複除外のためsetを利用
			 */
			Set<String> wk = new HashSet<String>();

			String wkS = "";
			for (int i = 0; i < s.length(); i++) {
				int max = i + numK < s.length() ? i + numK : s.length();
				for (int j = i; j <= max; j++) {
					wkS = s.substring(i, j);
					if (wkS != null && !wkS.equals("")) {
						//重複の除外
						wk.add(wkS);
					}
				}
			}

			/*
			 * 入れなおし
			 */
			List<String> wkList = new ArrayList<String>();
			for (String string : wk) {
				wkList.add(string);
			}

			/*
			 * 文字順にソート
			 */
			Collections.sort(wkList);

			System.out.println(wkList.get(numK - 1));

		} finally {
			if (scanner != null) {
				scanner.close();
			}
		}
	}


```