OmniAICreator/Qiita-1.07M huggingface dataset:
EasyAutocompleteでAjax版autocompleteを実装しました

select2で大量のデータをセットしたら重くて使い物にならなかったので、EasyAutocompleteでautocompleteを実装しました。

[EasyAutocomplete - jQuery autocomplete plugin](http://easyautocomplete.com/)

# 1. HTMLを用意

```html
<link rel="stylesheet" href="easy-autocomplete.min.css">
<script src="jquery-3.3.1.min.js"></script>
<script src="jquery.easy-autocomplete.min.js"></script>
～省略～
<input type="text" id="js-autocomplete" class="form-control">
<ul class="list-group" id="js-input"></ul>

```
※テーマは使用しないので、テーマ用のCSSは読み込みません。

# 2. APIを用意

名前をLIKE検索するようなAPIを実装します。

```php
$model = new Model();

// パラメータ取得
$name = $_POST['phrase'];

// DBから取得
$users = $model->getByName($name);
/*
データ形式
$users = [
    ['name' => 'JAMES'],
    ['name' => 'JOHN'],
    ['name' => 'ROBERT'],
]
*/

$response = $users;

//jsonとして出力
header('Content-type: application/json');
echo json_encode($response);
```

# 3. フロント実装
```javascript
var options = {
    url: function(phrase) {
        return 'api.php';
    },
    getValue: function(element) {
        return element.name;
    },
    list: {
  		onClickEvent: function() {
            var selectedItemData = $("#js-autocomplete").getSelectedItemData();
            $("#js-input").append('<li class="list-group-item">' + selectedItemData.name + '</li>');// 候補をクリックすると、リストに追加されていきます。
            $('#js-autocomplete').val('');// リストに追加したら、入力フォームを空欄に戻します。
  		},
        maxNumberOfElements: 20,// 候補を表示する最大件数です。
  	},
    ajaxSettings: {
        dataType: "json",
        method: "POST",
        data: {
            dataType: "json"
        }
    },
    preparePostData: function(data) {
        data.phrase = $("#js-autocomplete").val();// phraseというキーでAPIにデータをPOSTします。
        return data;
    },
    requestDelay: 400,// 文字を入力中に何度もAPIにデータをPOSTしてしまうので、ミリ秒遅延させます。
    placeholder: "名前を入力してください"
};

$("#js-autocomplete").easyAutocomplete(options);
```

# 4. CSS調整

bootstrapを併用している影響か、入力フォームが広くならなかったので調整しました。

```css
.easy-autocomplete{
  width:100% !important
}

.easy-autocomplete input{
  width: 100%;
}
```
Macのvimは古いということなので最新のvimを入れることにした。

はじめに、
元の状態を覚えておく。
設定ファイルの退避。（インストールする際に上書きされそうだよねという通常(?)の感覚）

```:shell
which vim
/usr/bin/vim
cd
cp -b .vimrc .vimrc_backup
```

最新のvim確認しておく。↓8.1らしい。

```
brew search vim
　　　~略~
brew info vim
vim: stable 8.1.0500 (bottled), HEAD
```
(( git-cloneしてmakeするか、一手間簡単にbrew installするか
https://www.vim.org/git.php ))

インストールする。

```
brew install vim --with-lua --with-override-system-vi
```

`--with-override-system-vi`オプションをつければ、パス設定を省略できるようです。既存のvimはそのままに、いままでのviコマンドで今回インストールするvimを起動できるようにされます。
`--with-lua`オプション。蛇足なんですが、luaを有効にして何かのプラグインを試そうかと思い...。

（　vimのパス設定についてはどこで設定されてるのか探してみたけどよく分からなくて；；
`export PATH=/usr/local/bin:/usr/bin`を設定する方法でも可能なのでそうしてもいいですし。)
Ubuntu16.04でNvidiaのドライバーを絶対有効化する方法。

# 前提
下記のような状態の人のための記事です。
### やったこと
* UEFIセキュアブートのWindowsマシンにUbuntuをインストールした。
* UbuntuにNvidiaのドライバーをインストールした。
* nouveauをオフにした。
* セキュアブートをDisableにする警告に「はい」と答えてパスワードを入力して再起動もした。
* UEFI（旧BIOS）の「Boot」メニューの「Secure Boot」の欄がグレーアウトされていてDisableに変更できない。

### できないこと
* `cat /proc/driver/nvidia/version`を実行しても、そもそも`/proc/driver/nvidia/`ディレクトリが存在しない。
* `nvidia-smi`を実行しても`command not found`となる。

##### 注意
Ubuntu 16.04(Lubuntu)で実施しましたが、それ以外の環境でこの対処法が有効かどうかは検証していません。できるかもしれないしできないかもしれない。環境構成が違っても万策尽きた人は自己責任でやってみてください。

# 対処法
1. Secure Bootの設定変更メニューを表示させる設定をする

    ```
    sudo mokutil --disable-validation
    ```

1. 一時的なパスワードを設定する
<img width="500" alt="スクリーンショット 2018-11-02 17.22.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/205347/6af0ed2e-990b-774f-8c0b-a57d2710e9d7.png">

1. 再起動する

    ```
    sudo reboot
    ```

1. 下のような画面で任意のキーを押す
<img weight="500" src="https://qiita-image-store.s3.amazonaws.com/0/205347/93dd9598-8460-7520-987d-0c982d8e9b8e.jpeg">

1. 「Change Secure Boot State」を選択する
<img weight="500" src="https://qiita-image-store.s3.amazonaws.com/0/205347/e1bdfc4d-1a7d-bdbf-fb60-5e1eeb6d745f.jpeg">


1. **（注意！）**「2. 一時的なパスワードを設定する」で設定したパスワードの**「指定された番号の位置に該当する一文字」**を入力してEnterキーを押す。

    （例：一時的なパスワードを「Password1234」と設定していて、下の画像のように「8:」と指定された場合は、前から8番目の「d」と入力してEnterを押下）

    <img weight="500" src="https://qiita-image-store.s3.amazonaws.com/0/205347/fc7d7859-0ceb-b822-925b-ad0037cc5df5.jpeg">

    この入力は数回要求されるため繰り返し入力します。

1. Yes/Noを選択する。

    （この画像は既にDisableに設定したマシンで撮っているため、Enableの場合は「Disable Secure Boot」と表示されるかもしれません。画面のコメントをよく読みましょう。）
<img weight="500" src="https://qiita-image-store.s3.amazonaws.com/0/205347/3a3a6e35-2505-b9fc-1468-488c707c1021.jpeg">

1. 「Continue boot」を選択して起動する。

予めNvidiaのドライバーをインストール済みの場合は、これだけで`/proc/driver/nvidia/`ディレクトリが現れて`nvidia-smi`が通るはずです。
無理だったら再起動して、それでも無理だったらきっとあなたは疲れています。

以上。
VisualStudioCode + DockerコンテナでNode.jsのリモートデバッグ実行

#環境
### ローカル
OS: Windows 10 pro  1803
VisualStudioCode: 1.28.2
`node -v
v10.13.0`

`npm -v
6.4.1`

### Docker ホスト
OS：Windows 10 pro 1803
Docker：
Client:
` Version:           18.06.1-ce
 API version:       1.38
 Go version:        go1.10.3`

Server:
` Engine:
  Version:          18.06.1-ce
  API version:      1.38 (minimum version 1.12)
  Go version:       go1.10.3
 Kubernetes:
  Version:          v1.10.3`

デバッグ対象のコンテナ上で可動するnode.js
`# node -v
v10.12.0`
`# npm -v
6.4.1`


# 事前準備
### Node.jsサーバ
以下のコマンドで、node.jsを含んだイメージを使ってコンテナを作る。
`docker run --name nodejs.server -p 8080:3000 -it node /bin/bash`

--name オプションは付けてもつけなくても良い。付けなかったらデフォルトで名前が任意に振られる。
-pオプションはポートプロキシさせるので、適当に。
：より左側はDockerホストの受付ポート。右側は、node.jsサーバを実行したときの受付ポート。

適当なnode.jsのスクリプトともに、`node [任意のjsファイル]`で起動。
ローカル環境から、Webブラウザ経由で、以下のURLを参考に接続する。
`http://[Docker ホストのIPアドレス]:8080`

つながらない場合、以下のURLにDocker ホストの環境から接続を試す。
`http://localhost:8080`

これでもつながらない場合は、node.jsやコンテナの起動から見直す。
起動確認が完了すれば、一度コンテナを停止し削除しておく。

### Visual Studio Code
1. Visual Studio Codeで、.vscode ディレクトリにあるlaunch.jsonを開く。
2. 構成の追加ボタンをクリックし、Docker: Attach to Nodeを追加。
3. addressには、Docker ホストのIPアドレス、portには任意のポートを記載しておく。
localRoot,RemoteRootは、デバッグ対象のjsファイルがある場所にしておく。
![launch.json.png](https://qiita-image-store.s3.amazonaws.com/0/170075/0cc82f03-ce74-94cb-6c79-d7099545312b.png)

#デバッグ
1. コンテナの起動
`docker run --name nodejs.server -p 8080:3000 -p 2983:2983 -it node /bin/bash`

- 1つ目の-pオプション  
node.js用のDocker ホスト側のポートと、Node.jsサーバが受け付けるポート
- 2つ目の-pオプション  
launch.json で記載したポートと、node.jsのデバッグポート  


2. node.jsのデバッグ起動  
`node --inspect=0.0.0.0:[デバッグポート] [デバッグしたいjsファイル]`  
注）デバッガで接続する接続元を絞りたい場合は0.0.0.0を任意に変更してください。  

3. Visual Studio Code で、デバッグ対象のjsファイルを開いたまま、デバッガを起動
表示→デバッグ画面に遷移後、再生ボタンの直ぐ側のドロップダウンリストから、`Docker: Attach to Node`を選択。再生ボタンをクリック。

![debug.png](https://qiita-image-store.s3.amazonaws.com/0/170075/38da2fa1-d17c-e7ba-d28d-967271bcd536.png)
注）ソースコードを消してます。
4. 適当なところにブレークポイントを貼って、WebブラウザからNode.jsサーバへアクセスすると、
   ブレークポイントでストップする。

※自分用メモですが、何かあればコメントをお願いします。
Azure で割り当てられた IP アドレスを、2018年10月31日 までに更新してください

まあ、今頃な感じではありますが・・

幾度となくメールが来てたが、内容さっぱりわからずｗｗ
ギリギリまで放置してしまっていたが
なんとか対応できたので
あの意味不明なメール対応について解説します。

まず、windowsに「Azure Classic CLI」をインストールします。
https://docs.microsoft.com/ja-jp/cli/azure/install-classic-cli?view=azure-cli-latest

npmじゃなくてもmsiがありますんで、無駄に苦労しなくてもいいです。
linuxでやろうとするとpython2.7やらpyrunがないやらでこれも苦労するので
windowsでやっつけちゃいましょう。

https://github.com/Azure/azure-xplat-cli/releases
から
``azure-cli-0.10.20.msi``
をダウンロード・インストールします。

これでDOS窓からazureコマンドが使えます。

次は
``azure login``
とすると、URLとコードが表示されるので、適当なブラウザを開いてアクセスします。
（portal.azure.comにログインしているブラウザからやったほうがいいかもですね）

ここから、メールのとおりに・・
``azure network reserved-ipホニャララ``ってやると、
んなコマンドがないって言われるわけｗ
MSという会社はそんな簡単には問屋は卸さないｗわけですよ・・ｗ
もう意味不明ｗ

そうこうしてたらどうも「Azure CLIモードを切り替える」？！ことが必要っぽいです。（MSさんよ、メールに書いといてくれてもバチ当たらんでしょうに・・）

以下qiitaが参考になりました。ありがとうございます。
https://qiita.com/dz_/items/972c64849dd9b174edc2

ってことで、asmかarmのどちらかで動くだろうということで

``azure config mode asm``

と打てばazure network reserved-ipホニャララが使えるようになります。
（ワイ、まずarmでやったらreserved-ipありませんでしたｗ
たった1/2の確率であっさり負けましたわｗ）

ここで、まずcloud servicesのインスタンス・webワーカーを停止します。
普通にazure portalから該当Cloud Services（クラッシック）を選び、
「ステージング環境」を選んで「■停止」します。

停止したらこの環境のIPアドレスを予約化します。

``azure network reserved-ip create IPアドレス予約名 ロケーション(japaneastやjapanwestなど) -r サービス名 -d デプロイID``

「IPアドレス予約名」は適当な名前でよいです。

この作業で、CloudServicesに動的に振られたIPをとっ捕まえておくようですね。

このあと、サービスからIPを取り外します。

``azure network reserved-ip disassociate IPアドレス予約名 サービス名 デプロイID``

これを行うことでサービスには新しいipアドレスが割り振られました。
ここで、サービスを起動してもOKです。

とっ捕まえたipを削除・リリースします。

`` azure network reserved-ip delete IPアドレス予約名``

以上で完了です。
同じようにCloudServices本番環境も行いましょう。

新しく割り当てられたIPはサイトURLにわりとすぐに割り振られましたが
ルータ等にキャッシュされてしまっていると反映(俗に言う波及ってやつ)は時間がかかるかもです。

まあ、サイトURLを使ってることはないでしょうし、IPもしくはCNAMEで対応してるかと思うので
事前にネームサーバのZone設定でTTLを短くしておくのが吉かと思います。
（このあたりはネームサーバ設定のあるあるですね）

以上です。


PS.自分、MS系苦手なので・・
Object to primitive conversion

```javascript:file.js
obj[Symbol.toPrimitive] = function(hint) {
  // return a primitive value
  // hint = one of "string", "number", "default"
}

let user = {
    name: "John",
    money: 1000,
    
    [Symbol.toPrimitive](hint) { //원시로~
        alert(`hint:${hint}`);    //$ 는 역따옴표안에서 사용가능
        return hint == "string" ? `{name: "${this.name}"}`:this.money;
    }

};
alert(user); // hint: string -> {name: "John"}
alert(+user); // hint: number -> 1000
alert(user + 500); // hint: default -> 1500
```


자바스크립트는 기본타입과 참조타입(객체)으로 나눌 수 있습니다.
기본타입을 원시 데이터라고 하며 5, 'foo', true, false, null, undefined 와 같은 자바스크립트 값을 말합니다.

즉, 숫자, 문자열, 불리언, null, undefined 인 다섯가지 기본 타입을 말하며 이 자바스크립트값은 더 이상 단순화할 수 없기 때문에 원시적(primitive)이라 하며, 이러한 값을 가리켜 원시값이라 합니다. 

출처: http://webclub.tistory.com/240 [Web Club]

##ToPrimitive and ToString/ToNumber
```javascript:file.js
let obj = {
    toString() {
        return "2"
    }
}
alert(obj * 2); //4
//수학연산(바이너리 플러스 제외)는 ToNumber 변환을 수행한다

let obj = {
    toString() {
        return "2"
    }
}
alert(obj + 2) //22

let obj = {
    toString() {
        return true;
    }
}

alert(obj +2); //3
```
東京公共交通オープンデータチャレンジに、応募してみた。

#概要

東京公共交通オープンデータチャレンジに、応募してみた。
地下鉄モニター

#写真

![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/s/9/9/s99A.jpg?t=1541129468)
#APIの調べ方。

jsonなので、まず、jqueryのgetjsonを試す。
クロスドメインで、だめ。
PHPで、取ろうとしたが、httpsで、取れない。
aptitudeで、php5-curl入れて取れた。

jsonなので、jsdoにファイルアップロードして、
jqueryのgetjsonで読んで、見れた。

d3.jsonで読んで、tableで、表示できた。

/api/v4/odpt:Station.json　と　/api/v4/odpt:Station の違いは、json付くと、フィルターが利かない、全部取れる。でかい。

odpt:Stationは、odpt.Station:TokyoMetroでフィルターかける。
駅名、路線、geo（緯度経度）取れる。
odpt:TrainTimetableは、odpt:trainNumberでフィルターかける
列車時刻表が取れる。
odpt:StationTimetableは、odpt:stationでフィルターかける。
駅時刻表が取れる。

#バックエンドの構築。

jsdoのgetjsonで取れるように、phpでアローオリジンのヘッダーを入れる。
php5_curlで、読む。printで、吐く。

#フロントエンドのUI決定。

候補は、react,vue,angularとriotですが、ピンとこない。
結果、d3とleafletとbootstrapに決定。

#足りなかった技術。

d3で、テーブルをつくる。
leafletで、マーカーのアイコンと色。
jsdoで、クエリーストリングを受け取る。
leafletで、マーカークリックで、ページジャンプ。
以上、作った。
		
#応募の手順

説明、ヘルプを書く。
マップを書く。
テーブルを書く。
写真を撮る。
ビデオを撮る。

#開発者の皆様へ

今回、開発した、バックエンドのweb apiを提供致します。ご連絡、下さい。

#成果物

http://jsrun.it/ohisama1/s99A
http://jsrun.it/ohisama1/aies


#リンク

https://developer-tokyochallenge.odpt.org/?

以上。
WordPressでremove_actionが効かない時の対処メモ

今回　プラグインで wp_enqueue_scripts で実行した アクションフックが 子テーマの functions.php からなかなか外せなかったのでメモ。

## Priority

とりあえずadd_action側に priority の指定をしている場合は
remove_action でも priority を指定する

## After

テーマで指定されているフックはプラグインより後で実行されるので、 after_setup_theme のタイミングで remove_action する

```
add_action( 'after_setup_theme', 'my_remove_action' );
function my_remove_action() {
	remove_action( 'wp_enqueue_scripts', '外すアクション', 10, 2 );
}
```

## これで外れない場合の対処

本題はここからです。上記ではずれない場合の対処方法を考えます。

### remove_action() が動作する条件

外したい add_action() の後で読み込まれる必要がある。

### 実行順確認の準備

外したい add_action で実行される関数の中に 確認用で追記します。

```
function my_action_function() {
	echo '<pre>これが消えたら成功</pre>';
	// 実行する処理
}
add_action( 'wp_enqueue_scripts', 'my_action_function' );
echo '━━━━━━━━━━ この後で remove が読み込まれる必要がある ━━━━━━━━━━';
```

外す方の処置

```
function my_remove_function() {
	echo '<pre>今から消すよ！</pre>';
	$return = remove_action( 'wp_enqueue_scripts', 'my_action_function' );
	// 削除成功したら 1 が返る
	print '<pre style="text-align:left">';
	print_r( $return );
	print '</pre>';
}
// ここの add_action の実行タイミングが鍵になる
add_action( 'after_setup_theme', 'my_remove_function' );
```
みたいな形で書く。これで外す方の処理が

```
━━━━━━━━━━ この後で remove が読み込まれる必要がある ━━━━━━━━━━
```

より後で実行されてれば概ね remove に成功するので、後に実行されるように ここの add_action の実行タイミングを変更する。

アクションフックのタイミングは下記を見て検討する
https://wpdocs.osdn.jp/%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3_API/%E3%82%A2%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%95%E3%83%83%E3%82%AF%E4%B8%80%E8%A6%A7

ちなみに今回プラグインで wp_enqueue_scripts で実行した アクションフックが 子テーマの functions.php からなかなか外せな件ですが、 wp_loaded のタイミングで外せました。
プログラミング初心者が運転日報アプリをつくった話

<h2>アウトプット！</h2>
プログラミングの勉強にはアウトプットが大切だと聞きました。
ちょうど運転日報のアプリの記事があったので便乗ではありますが投稿します(markdown練習でちょくちょく更新するかもです)。
[GASを使って運転日報のWEBシステムを作ってみた話](https://qiita.com/rarara_x16/items/81659db9b4bbd374b929)

**追記（2018/12/3）**
社内表彰でTOP10に入りました！
但し、最終審査で社長・役員プレゼンでは、その中での上位にはなれず。
プレゼン能力のなさが露呈しましたｗ

<h2>なぜ取り組んだか？</h2>
業務効率化が趣味の私は、EXCELを使って楽しい時間を過ごしていました。
次は何をしようと思っていたところ、運転日報の作成が面倒だった記憶があったため、
<b>これでアプリとか作ったらよいんじゃないか</b>と思い、新たな可能性を求めて夏休みに勉強がてら作成をはじめました。

<h2>コンセプト</h2>
①運転日報の作成時間をひとりあたり30分/週削減！
②提出方式（紙で提出・レシート貼り付けなど）は守らないといけないので、うまい具合に融合させる。
運転日報には、日付、経路、メーター（出社/始業/終業/帰宅）、給油、駐車料金、高速料金など複数項目をもれなく記載する必要があり、なるだけ直感的に操作できるインターフェースを目指しました。

<h2>ヒアリング</h2>
現状分析としてヒアリングしました。むむ！
<img width="714" alt="スクリーンショット 2018-11-02 15.52.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/224314/992360fd-02c1-3a3a-d24c-bd097a3c9b68.png">
 
<h2>イメージフロー</h2>
運転される方の動きとしてはこんな感じなので、これをひたすら登録していく感じにしようと思いました。
<img width="487" alt="スクリーンショット 2018-11-02 15.53.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/224314/0c6d5cc0-eed3-1d2f-c8b9-c151edcef976.png">

また、フォーマットが手書きなどでメモしたものをExcelにぽちぽち打ち込んでいく仕様の為、以下の様な流れで行ければスムーズかなと思いました。印刷の手間、EXCELにわざわざ書き写す手間は除外されます。
<img width="659" alt="スクリーンショット 2018-11-02 15.55.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/224314/5f304468-e075-7b0d-8a2b-5b911f43819e.png">

<h2>WEBアプリ</h2>
iPhone用に、スタンドアローンモードを使ってアプリっぽくしました。
また、ブラウザで開いたときにホーム画面登録に誘導するための表示も付け加えました。
画面で注意したポイントとしては、
・誰でもわかるインターフェース
・入力忘れを防ぐために車の乗り降りのときに必ず入力する仕組み
を付けました。
紆余曲折あり、入力画面は以下のような形になりました。
<img width="525" alt="スクリーンショット 2018-11-02 16.16.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/224314/769b3780-e5b3-9f65-9d6d-63a3e13763d3.png">
ページ構成はこのような感じです。結構なページ数になりました…
<img width="851" alt="スクリーンショット 2018-11-02 21.34.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/224314/b539ef15-e3b0-ce2b-c1e0-38fa676b83f9.png">

<h2>EXCELシート</h2>
関数を組みまくり、シートにVBAで一括印刷の機能を付けて一人の人がその部署全員分の週次、月次の印刷ができるようにしました。劇的に作業が減るという意味では、アプリと同じくらいここが結構肝だったかもしれません。

<h2>結果</h2>
試験導入後、本格導入には至りませんでした。残念。
アンケート結果によると、約15分の削減効果がありました。単純計算で労働日数にすると年間1.5日分くらいです。

<h2>今後</h2> 
WEB系のものを作るのは初めてでしたが、HTML、PHP、MySQLの概要とコードが本やネットをみながらなんとなくかけるようになりました。
現在、Ruby on railsを勉強中なので、それも使ってより有用なものができればいいなと思います。
・シートを自動的に出力されるようにする
・レシートを写真にとってそのまま認識される
・位置情報登録で自動的に場所の名前として予測入力する
Nextcloud のファイル共有（URLリンク共有）

#はじめに
Nextcloudは、ownCloudから派生したオンラインストレージパッケージです。今回は、基本機能であるファイル共有の中でも、URLリンクによるファイル共有について紹介したいと思います。

#プラグイン
[別記事](https://qiita.com/mmisu/items/1a7f66c94ca4d8a66b49)で紹介した、File Sharingのプラグインです。デフォルトでは有効になっているプラグインですが、これを無効にしてしまうと、単純に個人のファイル置き場になってしまいます。
![画像43.png](https://qiita-image-store.s3.amazonaws.com/0/308127/a9b31f8b-68d5-6943-9bee-4523d609f6a1.png)


#管理者設定画面
こちらも[別記事](https://qiita.com/mmisu/items/1a7f66c94ca4d8a66b49)で紹介したものと同じです。プラグインが有効になっていると、管理者画面に全体の共有設定が表示されます。ここで、ユーザが共有設定できる範囲などを決めます。赤枠で囲っているのが、URLリンクの共有設定に関係する箇所です。注意点としては、パスワード設定は強制させた方が良いかと思います。
![画像45.png](https://qiita-image-store.s3.amazonaws.com/0/308127/3bcb119e-2afb-c3ab-a670-1e2e8b3794cf.png)

#ユーザによるURL共有設定
フォルダやファイルに表示されている共有アイコンをクリックすると、画面右側に共有設定画面が表示されますので、URLで共有にチェックを入れます。ここでは、全体の共有設定でパスワードは強制させるようにしてあるので、任意でパスワードを設定します。
![画像36.png](https://qiita-image-store.s3.amazonaws.com/0/308127/3d0ffb86-bc6e-e93d-2d58-1f1f8efbf5ef.png)
URLが発行されたので、権限などを付けていきます。以下の項目が設定できます。
・読み取り専用　ダウンロードのみとなります。
・アップロードと編集を許可する　フォルダ単位でURL共有した際に、アップロード権限を付与できます。
・ファイルドロップ（アップロードのみ）　アップロード専用の画面が表示されます。既に保管済みのファイルは表示されません。
・有効期限を設定　デフォルトは全体の共有設定で設定された日付が反映されています。ユーザがあとから変更する事も可能です。
![画像37.png](https://qiita-image-store.s3.amazonaws.com/0/308127/628d0599-4e0e-1b64-86ca-d9d358696961.png)

共有設定されたURLは、「Copy URL」でクリップボードにコピーできます。共有したい相手へメールなどに張り付けて伝えます。パスワードは別メールで送った方がよさそうですね。

URLを共有されたユーザは、そのURLにアクセスすると、パスワード入力画面が表示されますので、パスワードを入力します。
![画像39.png](https://qiita-image-store.s3.amazonaws.com/0/308127/a25812b7-09e3-822c-d0c8-1eb1df7ca4fa.png)
パスワードが通れば、共有されたフォルダ・ファイルが表示されるので、期限内にダウンロードしたり、アップロードしたりします。
![画像40.png](https://qiita-image-store.s3.amazonaws.com/0/308127/1b7e8cac-d59a-89de-c855-9b5a6c947b90.png)
もう一つ特徴的なものとして、ファイルドロップ機能があります。
これでURL共有をすると・・・。
![画像41.png](https://qiita-image-store.s3.amazonaws.com/0/308127/698583c4-19a3-83fa-82e8-9dbf3d07f320.png)
アップロード専用画面が表示されます。不特定多数の人からファイルを回収したいときに使える機能ですね。ちなみに、同じファイル名でアップロードされた場合は、ファイル名（1）のように、後ろが連番となっていきます。
![画像42.png](https://qiita-image-store.s3.amazonaws.com/0/308127/8b628304-6948-c028-61f0-847c4d91e44e.png)

#まとめ
ファイル共有は、NextcloudやownCloudの基本機能ですが、URLリンク共有の場合は、社外のアカウントを持っていないユーザとの共有がメインになるかと思います。メール添付の代わりや、大容量のファイル共有などで活躍する機能です。

この記事は、[スタイルズ社のNextcloudサイト](https://nextcloud.stylez.co.jp/nextcloudblog)にも公開しております。
Rails5 uninitialize constant Postscontrollerのエラー表示が出て悩んだ件

#uninitailize constantへの対応はどうすべきか

昨日からこのエラー表示が出てきて、自分もかなりの時間(それでも1日ほど)悩まされたので、一応備忘録として残しておく。


Postsコントローラーが何とかというのは、わかるが、何が問題なのか調べたところ、どうやらPosts_controller.rbつまり、Postsコントローラーのファイルが存在するかどうかを疑うべきらしい。
まずは、下記がroutes.rbで定義しているURLです。

```
new_user_session GET    /users/sign_in(.:format)       devise/sessions#new
            user_session POST   /users/sign_in(.:format)       devise/sessions#create
    destroy_user_session DELETE /users/sign_out(.:format)      devise/sessions#destroy
       new_user_password GET    /users/password/new(.:format)  devise/passwords#new
      edit_user_password GET    /users/password/edit(.:format) devise/passwords#edit
           user_password PATCH  /users/password(.:format)      devise/passwords#update
                         PUT    /users/password(.:format)      devise/passwords#update
                         POST   /users/password(.:format)      devise/passwords#create
cancel_user_registration GET    /users/cancel(.:format)        devise/registrations#cancel
   new_user_registration GET    /users/sign_up(.:format)       devise/registrations#new
  edit_user_registration GET    /users/edit(.:format)          devise/registrations#edit
       user_registration PATCH  /users(.:format)               devise/registrations#update
                         PUT    /users(.:format)               devise/registrations#update
                         DELETE /users(.:format)               devise/registrations#destroy
                         POST   /users(.:format)               devise/registrations#create
                   posts GET    /posts(.:format)               posts#index
                         POST   /posts(.:format)               posts#create
                new_post GET    /posts/new(.:format)           posts#new
               edit_post GET    /posts/:id/edit(.:format)      posts#edit
                    post GET    /posts/:id(.:format)           posts#show
                         PATCH  /posts/:id(.:format)           posts#update
                         PUT    /posts/:id(.:format)           posts#update
                         DELETE /posts/:id(.:format)           posts#destroy
              posts_find POST   /posts/find(.:format)          posts#find
```

#考えられる問題点
今回、root_path/postsを叩いた時にタイトルのようなエラーが表示された。これは、rails sした時に、この叩いたURLのcontrollerファイルをrails側で探してきて、存在しない場合、タイトルのようなエラーが表示されるような仕組みらしい。


ただ、探したところposts_controller.rbファイルは存在した。この時、もう一つ気をつけないといけない点が、controller名は複数形でないとならないというrailsの命名規則に基づいているかどうかも考えなければならない。
今回、自分はこの命名規則に基づいてcontrollerを生成していたので、ここが問題ではなかった。

次に、考えるべきところが、ファイルパスである。ここで、問題が生じていた。
app/controllers/posts/posts_controller.rb
このようにcontrollerディレクトリ以下から、さらにpostsディレクトリを生成して、そのpostsディレクトリ以下に、posts_controller.rbファイルを管理していた。



#対策
デフォルトでのrailsでは、controllersディレクトリ以下のみを読み取るようになっており、これを上記のようなファイルパスで読み取るようにする場合は、どうやらinitialize/config以下でさらに設定を行なわなければならないらしい。
とりあえず
app/controllers/posts_controller.rb
という感じでposts_controller.rbファイルをcontrollersディレクトリ以下にすると、エラーが解消された。

このエラーはcontrollerだけではなく、modelsディレクトリ以下でも上記と同じような事でエラーになるので、気をつけるべきかと・・

以下がtwitterになります。
https://twitter.com/FujisawaRyohei
フォローよろしくお願いします。
モジュールとミックスインについて簡単な備忘録

# モジュールとは

複数の処理を書く際に共通の処理をまとめておく時に使われるもの。
使い方としては、後に説明するミックスインの機能を使って、複数のクラスで定義する
共通の複数の処理をモジュールを定義しまとめることによって、いちいち処理を定義し、コードを
書かずとも呼び出すだけで良くなるというメリットや、コード量が少なくなり、見やすくなるなどの
メリットがある。

モジュールを定義するときは、下記のような書き方から始まる。

```rb

module SampleModule

end
```
このようにmodule モジュール名から始まり、classを定義する際や、メソッドを定義する際と同じよう
にendで終わる。

moduleの中には、上記のようにいつでも呼び出せたらいいような、処理をまとめておく。
これにより、コードも見やすくなり整理されていい感じである。

次に、処理を定義したmoduleの呼び出し方について見ていく。


##モジュール内で定義したメソッドを関数として呼び出す方法。
```rb

module SampleModule
 def sum(a,b)
   a + b
 end
 module_function:sum
end

puts SampleModule.sum(1,1) => 2
```
上記のようにfunction_moduleメソッドでモジュール内で定義したメソッドをシンボルで指定する事で
関数として呼び出す事ができる。

##module内で定義した定数を呼び出す方法
```rb
module SampleModule 
 CONST_NUM = 100
def sum(a,b)
 a + b
 end
end

puts SampleModule::CONST_NUM => 100
```
上記のようにモジュール名にコロンを二つで指定する事ができる。

## includeを使ったmodule定義したメソッドを呼び出す方法
```rb
module SampleModule 
 CONST_NUM = 100
 def const_num
  CONST_NUM
 end
end

include SampleModule

puts CONST_NUM
puts const_num
```
モジュールを定義後、includeメソッドを呼び出すことで、その下から、直接、
moduleで定義したメソッドや、定数を呼び出す事ができる。

##ミックスインについて
ミックスインとはクラスにモジュールを読み込ませることである。下記のsample codeで説明する。

```rb
module SampleModule
 def sum(a,b)
  a + b
 end
end

class Sample
 include SampleModule
 def call_sum(a,b)
  sum(a,b)
 end
end

sample = Sample.new
sample.sum(1,1) => 2
sample.call_sum(2,2) => 4
```
上記では、sumという複数のクラスで使うと仮定したメソッドを定義している。その定義した処理を
クラスにincludeメソッドで読み込むことによって、見やすく、手間を省く事ができている。
また、ModuleSampleで定義したメソッドもSampleクラスでincludeすることにより、
sampleクラスのオブジェクトをレシーバーに、関数として、sumメソッドを呼び出す事ができている。

他のクラスでまた、moduleで定義したメソッドを呼び出す場合は、同じようにincludeを使うと良い。

##まとめ
複数のクラスで使いそうなメソッドは、モジュールを定義し、まとめておき、いつでも呼び出せるようにしておく。
また、クラス定義ではなく、普通に何度も使いそうなメソッドも、module_function :メソッド名で定義する事でコードを書く手間が省けて良い。
RLoginでemacs使用時の文字列のコピー

RLoginでemacsを起動して、文字をマウスでコピーしてwindows上のエディタにコピーすると改行が右の端まで飛んでしまうことがある。そのようなときはemacsで
M-x text-mode
としてからコピーするとよいです。

長年の悩みが解決されました・・
Glue上のPySparkでS3上のファイルをリネーム

# リネーム処理

いろいろ調べた結果以下のように

- [Find latest file pyspark](https://stackoverflow.com/questions/50526076/find-latest-file-pyspark)
- [Pyspark: get list of files/directories on HDFS path](https://stackoverflow.com/questions/35750614/pyspark-get-list-of-files-directories-on-hdfs-path)
- [How rename S3 files not HDFS in spark scala](https://stackoverflow.com/questions/48200035/how-rename-s3-files-not-hdfs-in-spark-scala)

```python
# SparkContext
sc = SparkContext()

# Javaのクラス
URI           = sc._gateway.jvm.java.net.URI
Path          = sc._gateway.jvm.org.apache.hadoop.fs.Path
FileSystem    = sc._gateway.jvm.org.apache.hadoop.fs.s3.S3FileSystem

# HDFSのFileSystemを設定
fs = FileSystem.get(URI("s3://{}".format('your.bucket.name')), sc._jsc.hadoopConfiguration())
fs.rename(
    Path("s3://your.bucket.name/BEFORE_RENAME.csv"),
    Path("s3://your.bucket.name/RENAMED.csv")
)
```

## s3上で使うときにバグを踏む

- [HADOOP-13574 - Unnecessary file existence check causes problems with S3](https://issues.apache.org/jira/browse/HADOOP-13574)

s3に対してoverwriteを指定して書き込んだ時、ファイルが存在しないときにコードの条件文がおかしいのでExceptionになる？
リンク切れ検査

http://www.dead-link-checker.com/ja/

約5400リンクがあるサイトを確認し始めた。

丸２日たっても、1500しか済んでいない。

１時間あたり３１箇所。

最初の１時間は１５０箇所。なんでそんなに遅くなったのか？

ネット環境が悪いのか、一旦中断して、再度測定を開始したい。

p.s.

新しい機材、別のネットでためしても

最初の３０分で１５箇所。


平均は同じだが、当初の速度の、５分の１。
supported targets

supported targets: 
elf64-x86-64 
elf32-i386 
elf32-iamcu 
elf32-x86-64 
a.out-i386-linux 
pei-i386 
pei-x86-64 
elf64-l1om 
elf64-k1om 
elf64-little 
elf64-big 
elf32-little 
elf32-big 
pe-x86-64 
pe-bigobj-x86-64 
pe-i386 
plugin 
srec 
symbolsrec
 verilog 
tekhex 
binary 
ihex

全部入りbinutils
http://7shi.hateblo.jp/entry/2013/07/30/011348
Pythonで競プロに挑む日誌 vol.14 ~max, min 関数の便利な使い方~

目標を修正します。

# 現在の目標
* 今年の10月内に茶色を取得する
 * [ABC](
https://kenkoooo.com/atcoder/?user=&rivals=&kind=category) の A, B 問題を全部解く**←イマココ**
* 年内に緑色を取得する
 * [ABC](
https://kenkoooo.com/atcoder/?user=&rivals=&kind=category) の C, D 問題を全部解く
* [APG4b](https://beta.atcoder.jp/contests/apg4b) で C++ にも手を出す

# 修正後の目標
* 2018年内に茶色になる**←イマココ**
 * [ABC](
https://kenkoooo.com/atcoder/?user=&rivals=&kind=category) の A, B 問題を全部解く
* 2018年度内に緑色を取得する
* [APG4b](https://beta.atcoder.jp/contests/apg4b) で C++ にも手を出す

# 現状
![abc.png](https://qiita-image-store.s3.amazonaws.com/0/284026/af20cfbd-6860-840a-ee43-9975c846050d.png)
A 問題は全完. B 問題を消化中です. 
# 次やること
* B 問題を解く

#以下、雑感
問題を解く中で、「なるほどなぁ」と思ったことを書いておきます.「[双子とスイカ割り](https://beta.atcoder.jp/contests/abc025/tasks/abc025_b)」という問題に取り組んだ時、私は最初、下記のように解答しました.

```.py
# coding: utf-8
N, A, B = map(int, input().split())
 
p = 0
for _ in range(N):
    si, di = input().split()
    di = int(di)
    if di < A:
        val = A
    elif A<= di <= B:
        val = di
    else:
        val = B
    if si == "West":
        val *= -1
    p += val
 
if p < 0:
    print("West " + str(abs(p)))
elif p > 0:
    print("East " + str(p))
else:
    print(0)
```
ところが、

```.py
    if di < A:
        val = A
    elif A<= di <= B:
        val = di
    else:
        val = B
```
の部分は、

```.py
    val = min(max(A, int(di)), B)
```
で十分だという解答を見て, 「なるほどなー」と思いました.
【SQL】フラグが0以外の場合は条件を指定して、フラグが0の場合は全件表示する。

フラグが0以外の場合は条件を指定して。
フラグが0の場合は全件を表示する。

上記のような内容を1つのSQLで実現したかった。
IF文や動的SQLにしないでよいので、個人的に気に入っている。

```sql:SQL
DECLARE @w INT = 0
SELECT * FROM TEST_TABLE X
WHERE @w = 0 OR @w <> 0 AND X.TEST_FLG = @w
```
Webサイトの状況を確認するツール①　～Lighthouse～

Webサイトを開発・運用していくうえで、避けては通れないのがパフォーマンス。計測ツールも多々あるので、ニーズに合わせて最適なものを使っていきたい。

先日の「アプリケーション・パフォーマンス 2018」のイベントに参加をした際に、いくつか紹介をしてもらったので、備忘録を兼ねて。

# Lighthouse
**Chromeの拡張機能**
[Lighthouse によるウェブアプリの監査](https://developers.google.com/web/tools/lighthouse/?hl=ja)
↑よりインストール可能

今回は、私の大好きなサイト「amazon」で試してみました。
総合評価はこんな感じで表示されます。
![lh2.PNG](https://qiita-image-store.s3.amazonaws.com/0/269801/05736371-c8d6-a787-8e61-04457bc1f8b8.png)
*Performance、PWA、Accessibility、Best Practices、SEOの5つの観点で評価される。100点満点での採点。*

また、各項目ごとに細かな結果も出てきます。

## #Performance
![lh3.PNG](https://qiita-image-store.s3.amazonaws.com/0/269801/364c8d52-e674-5e74-a1ec-f7567a51016e.png)
細かな判定指標（First Contentful PaintやSpeed Indexなど）とともに、「Opportunities」として、改善提案も出てきます。

## #PWS（Progressive Web App）
>These checks validate the aspects of a Progressive Web App.

![lh4.PNG](https://qiita-image-store.s3.amazonaws.com/0/269801/2d2c2583-c636-1102-deac-1eee8dce97fb.png)
こちらは、PWAの観点でのチェックです。
・モバイル環境では、ちょっと遅いね。
・オフラインでは見れないね。
といった指摘をされています。
各項目がアコーディオンで開くので、その中を見ると対応策も書いてくれています。

## #Accessibility
>These checks highlight opportunities to improve the accessibility of your web app. Only a subset of accessibility issues can be automatically detected so manual testing is also encouraged.

![lh5.PNG](https://qiita-image-store.s3.amazonaws.com/0/269801/6fd42381-6fd9-d61a-88d0-3d34ddb77637.png)
ここでは、
・Elements Have Discernible Names（要素に識別可能な名前がついている？）
・Page Specifies Valid Language（ちゃんと言語設定されている？）
・Meta Tags Used Properly（メタタグ、適正に使ってる？）
といった観点での確認結果です。
もちろん、各項目がアコーディオンで開くので、その中で対策を確認できます。

## #Best Practices
![lh6.PNG](https://qiita-image-store.s3.amazonaws.com/0/269801/32fc5ff6-ae23-420c-41b9-9ac179a20227.png)
更なる改善項目、ということで、amazonnの場合はほとんど指摘がないです。
モバイルなどでのスクロールの詰まり(Scroll Jank) を解決するために、Passiveリスナーいれたら？といった提案のみです。
この項目では、
・Uses HTTPS（SSL使っているよね？）
・Avoids document.write()（document.writeは使っていないよね？）
・Page has the HTML doctype（doc宣言しているよね？）
といったチェック項目があります。

## #SEO
>These checks ensure that your page is optimized for search engine results ranking. There are additional factors Lighthouse does not check that may affect your search ranking. 

![lh7.PNG](https://qiita-image-store.s3.amazonaws.com/0/269801/6b38c0fa-0e7f-b6a8-17b8-8a2c187bbfa6.png)
SEO観点でのチェックですね。
・Page is mobile friendly（モバイルフレンドリーか？）
・Document has a <title> element（タイトル入れているよね？）
・Document has a meta description（メタタグ定義しているよね？）
・Links have descriptive text（リンクにテキスト入れているよね？）
といった基本的な要素の確認です。
amazonさんは100点、すばらしい。
といいつつ、この項目だけは私の関わっているWebサイトも100点でした。他は、散々たる・・・。

# まとめ
といった形で、Lighthouseでは手軽にサイトのチェックができるので、自己評価のつもりでやってみるのがおススメです。
もちろん、指摘事項は頑張って直していこうと思います。良いWebサイトを提供するために。
EdgeのDevToolsをF12で起動するとクラッシュする

# F12でEdgeのDevToolsを起動するとクラッシュする

気付いたらF12でEdgeのDevToolsを起動するとクラッシュするようになっていました。

どうやら、10月24日リリースの下記のWindows Updateが原因の模様

October 24, 2018—KB4462933 (OS Build 17134.376)
https://support.microsoft.com/ja-jp/help/4462933/windows-10-update-kb4462933

私の場合、とりあえずアンインストールで解決しましたが、上のページによると既知の問題のようで、次のファイルを削除すると正常に動作するようになるそうです。

- 64bitマシン：
C:\Windows\SystemApps\Microsoft.MicrosoftEdgeDevToolsClient_8wekyb3d8bbwe\microsoft.system.package.metadata\Autogen\JSByteCodeCache_64
- 32bitマシン： C:\Windows\SystemApps\Microsoft.MicrosoftEdgeDevToolsClient_8wekyb3d8bbwe\microsoft.system.package.metadata\Autogen\JSByteCodeCache_32
複数行テキストの末尾省略をCSSのみで実現する

# やりたいこと
複数行テキストの末尾を…（3点リーダー）で省略したい。
このとき、JavaScriptを使わずCSSだけで実現したい。

## なんでCSSだけで？
JavaScriptで末尾省略する方法だとある程度の行数のコードを書かないといけない。
また、ライブラリを使う方法もあるが、バージョンアップやjQuery依存など考慮するべき点がいくつかある。

CSSで実現できれば上記のような心配が少なく、保守性を維持しやすいかと思いCSSだけで実現する方法を探した。

# 実現方法
## CSS line-clamp を使う

```css
display: -webkit-box;
overflow: hidden;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
```

メリット
- 少ない行数で実現できる
- 幅が可変でも変な隙間ができたりせず綺麗に表示できる

デメリット
- ~~IE, Firefoxで未対応~~ → IEで未対応
- モバイル対応のみならば使える（Android版のFirefoxユーザーもいるが…）
- 使う場合はフォールバックも設定しておくのが望ましい。  
参考： https://codepen.io/martinwolf/pen/qlFdp

### 追記 2019.08.29
祝！ Firefox で対応されました。
![スクリーンショット 2019-08-29 12.00.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114828/b877ee92-709d-6706-a82c-a8248d4bc005.png)
https://caniuse.com/#search=webkit-line-clamp

※ちなみに Firefox for Android ではまだ未対応なのでモバイル対応が必要な場合は注意

### IE（に最低限の）対応版
IE は推奨していないけど、レイアウトが崩れるのは困るなーくらいの対応でいい場合に使えるサンプルを書いてみた。
IE の場合は…（３点リーダー）は表示されず、はみ出した文は非表示(hidden)になる。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="ezawa800" data-slug-hash="LYPjYZL" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="CSS line-clamp with IE compatible">
  <span>See the Pen <a href="https://codepen.io/ezawa800/pen/LYPjYZL/">
  CSS line-clamp with IE compatible</a> by Sho Ezawa (<a href="https://codepen.io/ezawa800">@ezawa800</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

#### IEで見た場合
![スクリーンショット 2019-08-30 17.48.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114828/bca8bea5-116c-6e7b-d4e9-94d0bf2c66df.png)

#### IE以外でみた場合
![スクリーンショット 2019-08-30 17.43.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114828/2f579b34-7788-2082-578a-57f732209063.png)


## before, after要素を使う

```css
.ellipsis {
    position: relative;
    height: 80px;
    overflow: hidden;
    line-height: 20px;
}
 
.ellipsis:before, .ellipsis:after {
    position: absolute;
    background: #fff;
}
 
.ellipsis:before {
    content: "･･･";
    bottom: 0;
    right: 0;
}
 
.ellipsis:after {
    content: "";
    width: 100%;
    height: 100%;
}
```

copied by http://blog.keisuke11.com/webdesign/word-trim/

メリット
- どのブラウザでも動作する

デメリット
- 行数は多めでハック感もややあり
- テキストの末尾と…（3点リーター）との間に隙間ができることがある（特に幅が可変のとき）

PC対応が必要でどうしてもFirefoxを外せない場合はこちら。
個人的には2つ目のデメリットが看過できないので使いたくない…。


# まとめ
~~Firefoxさん！CSS line-clamp対応してくれー！
（IEはいいです）~~

ありがとう Firefox さん！
これで安心して line-clamp が使えます！
エディタ上では完璧なのに、GearVR,OculusGoでUnity Video Playerが途中で止まったり、再生できない

# エディタ上では完璧
環境：
Unity 2018.2.14f1
Windows10
GearVR (Galaxy S7)

動画：4K未満のステレオmp4、ビットレートは10Mbps強

シーン：UnityVideoPlayerで、数秒後に360動画を再生するだけのシンプルなシーン。エディタ上では完璧に動作。

#実機でフリーズ
GearVRとGalaxy S7にて
別のシーンからLoadSceneにて読み込み。
全く再生できなかったり、数秒でフリーズしたり・・・。

これも似たような原因な気がする
https://answers.unity.com/questions/1358388/video-player-gearvr.html

#MultiThreaded Rendering
原因はMultiThreaded Renderingでした。EasyMovieTextureとUnity5.xの時は問題なかった気がしたのに…。半日潰してしまいました。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/174302/dc4d2f1e-7310-c0ab-f4e4-01a300676c2a.png)
チェックを外せばオッケーです。
コマ落ちしたりパフォーマンスが出ないときは、オブジェクトのStatic忘れがないか確認してみてください。
携帯通信（主にLTE）の無線アクセスネットワーク

以前、[携帯通信（主にLTE）のコアネットワーク](https://qiita.com/osaphex/items/c5025bcab5000acd5a1c)という記事を書きましたが、コアネットワークと並んでもう1つ重要な携帯通信網に「無線アクセスネットワーク (RAN: Radio Access Network)」があります。無線アクセスネットワークは無線関係の装置（変調装置など）がメインになるかもしれませんが、装置同士の繋がり方の部分でネットワークトポロジが興味深かったのでまとめてみました。

## コアネットワークと無線アクセスネットワーク

コアネットワークは外部へパケットを転送したり外部から来たパケットを端末へ届けるためのルーティングなどがメインの仕事でした。一方で無線アクセスネットワークは、最終的に無線技術を用いて端末とのインターフェイスを管理します。

<img src="https://qiita-image-store.s3.amazonaws.com/0/278104/fe9e7e6f-7441-3274-833f-51e3659696b1.png" width=600pt>


## LTE の無線アクセスネットワーク

LTE の無線アクセスネットワークは下図のような構造になります。
<img src="https://qiita-image-store.s3.amazonaws.com/0/278104/615ecf29-5690-2e92-c665-fc675af4fca9.png" width=600pt>

この図は User Plane と Control Plane を両方描いています（USer Plane と Control Plane の説明は[携帯通信（主にLTE）のコアネットワーク](https://qiita.com/osaphex/items/c5025bcab5000acd5a1c)を参照）。

新たに登場したものは

- S1 Interface
    - eNodeBとコアネットワークを結ぶインターフェイス
    - プロトコルは S1 Application Protocol (S1 AP)
    - S-GW とつながるインターフェイス（User Plane側）は特に S1-U と呼ばれ、 MME とつながるインターフェイス (Control Plane側）は S1-MME と呼ばれる
- X2 Interface
    - 近隣の eNodeB 同士を結ぶインターフェイス
    - プロトコルは X2 Application Protocol (X2 AP)

の2つになります。


### X2ハンドオーバとS1ハンドオーバ

eNodeB は近隣のものと相互接続がされています。この相互接続を使うことでハンドオーバ（端末が移動したときの通信経路の切り替え）を高速化することができます。これは __X2ハンドオーバ__ と呼ばれるハンドオーバ方法です。

X2ハンドオーバは前提として切り替え前と切り替え後の2つの eNodeB が同一の MME に接続している必要があります。この条件を満たせば、ハンドオーバで切り替える経路は S-GW と eNodeB の間だけになります。そこで X2 インターフェイスを介して情報をやり取りし、切り替えを行います。

<br />

2つの eNodeB が異なる MME に接続されている場合、X2 ハンドオーバはできません。この場合は仕方がないので S1 インターフェイスを介して情報のやり取りを行いハンドオーバをします。これを __S1ハンドオーバ__ と呼びます。


## eNodeB の構成

すこし細かいかもしれませんが、一緒に eNodeB の中のネットワークも見てみましょう。

<img src="https://qiita-image-store.s3.amazonaws.com/0/278104/ba14df1f-7bd1-f780-4d31-9a5194238157.png" width=600pt>

（画像は http://www.sharetechnote.com/html/RF_Handbook_RRH.html より）

大きく BBU (Base Band Unit) と RRH (Remote Radio Head) の2つから構成されます。

- BBU
    - ベースバンド装置
    - 無線の変調（物理層）、無線リソースへの端末の割当やスケジューリング（MAC層）などを担当
- RRH
    - 張り出し無線装置
    - 送信電力の増幅、受信信号の低雑音増幅、電波の生成・検出などを担当

LTE以前は BBU と RRH を1つのコンポーネントにして街中に配置していたようですが、最近はアンテナをそこら中に立てる「スモールセル」が主流になったため、RRH を切り離してよりアンテナを取り付けやすいようにしているそうです。

<img src="https://qiita-image-store.s3.amazonaws.com/0/278104/903365bb-e628-d260-765c-326d50e22489.jpeg" width=600pt>

（画像は http://japan.ni.com/usersolutions/fujitsu より）


## 最後に

[携帯通信（主にLTE）のコアネットワーク](https://qiita.com/osaphex/items/c5025bcab5000acd5a1c)と今回の記事を通して、日本中に張り巡らされている携帯通信網が具体的にどのように敷設されているのかが段々と分かってきました。あとはより具体的に

- BBU がどこに設置されているのか
- S-GW と MME はそれぞれいくつの eNodeB を管理しているのか
- P-GW は日本全国にいくつあるのか

といった情報がほしいのですが...なかなか見つからないものですね...



## 参考文献

『モバイルシステム技術テキスト エキスパート編 第7版』モバイルコンピューティング推進コンソーシアム

[LTEのネットワーク動作](http://www.atmarkit.co.jp/ait/articles/1012/24/news125.html) 

[LTE: X2 interface](https://www.slideshare.net/schwannden/lte-x2-interface)

[4G5G World](http://4g5gworld.com/)
railsチュートリアル

git commit -m'~~~~'と入力実行したところ、＞マークが出てそのまま動く気配がないです。入力はできます。
（ここでは平仮名で’プロジェクトの新規作成と入力’）
どのようなことが考えられますか[スクリーンショット 2018-11-02 14.59.33.png](https://qiita-image-store.s3.amazonaws.com/0/284608/abec1d1a-943c-3f9e-21fb-b552cff10993.png)
matplotlibのグラフをローカルに一時保存せずにslackへ送信するサンプルコード

# モチベ

## やりたいこと
定期的にDBのデータをグラフ化してslackに投げたい。
## なぜこの方法か
- redashの定額プランを払うほど使わない。
- lambdaやcloud functionsを使って費用を節約するつもりだが、ローカルに一時保存ができなさそう。

# 本題

## 概要
ざっくりいうと
- pyplotのグラフを`io.BytesIO()`を用いてメモリ上へ一時保存する。
- そのバイト列をslack api のリクエストに入れる。
- slackに投稿される。

## サンプルコード

```python:sample.py
import matplotlib.pyplot as plt
import numpy as np
import seaborn; seaborn.set() # for plot style
import io
import requests

# 適当なグラフを作成
rand = np.random.RandomState(42)

mean = [0, 0]
cov = [[1, 2], [2, 5]]
X = rand.multivariate_normal(mean, cov, 100)

fig = plt.figure()
plt.scatter(X[:, 0], X[:, -1])

# io を用いてメモリ上に保存
format = "png"
sio = io.BytesIO()
plt.savefig(sio, format=format)

# グラフの出力をしない
plt.close(fig)


# slackのアクセストークン
accessToken ='<YOUR_SLACK_ACCESS_TOKEN>'
channel_id = '<YOUR_SLACK_CHANNEL_ID>'

# ファイルに直接バイトを入れる
files = {'file': sio.getvalue()}
param = {'token': accessToken, 'channels': channel_id}
res = requests.post(url="https://slack.com/api/files.upload",params=param, files=files)

print(res.content)
```

## 参考サイト

- pyplot => io.BytesIO
    - [Dynamically serving a matplotlib image to the web using python - Stack Overflow](https://stackoverflow.com/questions/14824522/dynamically-serving-a-matplotlib-image-to-the-web-using-python)
- file => slack
    - [PythonでSlackに画像をアップロードする方法 - Qiita](https://qiita.com/tottu22/items/594e8c506ece0f8cc87c)
- io
    - [16.2. io — ストリームを扱うコアツール — Python 3.6.5 ドキュメント](https://docs.python.jp/3/library/io.html 16.2. io)
abc 112 d 最大公約数

C


悩んでる暇があったら全探索

```
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<list>
#include<cmath>
#include<map>
using namespace std;
using ll = long long;
const int INF = 1e9;
#define rep(i,n)for(int i=0;i<n;++i)
#define p pair<int,int>
int main() {
	int N;
	cin >> N;
	vector<ll>vx(N), vy(N), vh(N);
	int si = -1;
	for (int i = 0; i < N; ++i) {
		cin >> vx[i] >> vy[i] >> vh[i];
		if (vh[i] > 0)
			si = i;
	}
	ll resx = -1, resy = -1, resh = -1;
	for (ll x = 0; x <= 100; ++x) {
		for (ll y = 0; y <= 100; ++y) {
			ll h = vh[si] + abs(x - vx[si]) + abs(y - vy[si]);
			bool ok = true;
			for (int i = 0; i < N; ++i) {
				if (vh[i] > 0 && h - vh[i] != abs(x - vx[i]) + abs(y - vy[i]))
					ok = false;
				if (vh[i] == 0 && h > abs(x - vx[i]) + abs(y - vy[i]))
					ok = false;
			}
			if (ok)
				resx = x, resy = y, resh = h;
		}
	}
	cout << resx << " " << resy << " " << resh << endl;
	return 0;
}
```
D
整数N,Mが与えられる。
a1+a2+....aN=Mを満たす正の整数列a1,a2,,,aNをすべて考えた時のa1,a2,,,aNの最大公約数の最大値を求めよ

数学チックになってきた。
まずこれが必ずMの約数になることがわかる。
d=GCD(a1,a2,,,,,aN)とする。
このときa1,a2,,,aNはすべてdの倍数である。よってa1+a2+.....aNもdの倍数である。つまりdはMの約数である。
このうち最大を求めたい。
d=GCD(a1,a2,,,aN)とするとai>=dなのでNd<=Mである。これさえ満たしていれば必ずそういうa1,a2,,,aNは作れることがわかる。
具体的にはa1=d,a2=d,,,,aN-1=d,aN=M-(N-1)dとすればよい
まとめると答えはMの約数dのうちNd<=Mを満たす最大のものとなる。

```
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<map>
#include<math.h>
#include<queue>
#include<deque>
#include<stack>
#include<cstdio>
#include<utility>
#include<set>
#include<list>
#include<cmath>
#include<stdio.h>
#include<cstdio>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
const int INF = 1e9 + 7;
//約数列挙
vector<ll>calc_divisor(ll n) {
	vector<ll>res;
	for (ll i = 1LL; i*i <= n; ++i) {
		if (n%i == 0) {
			res.push_back(i);
			ll j = n / i;
			if (j != i)res.push_back(j);
		}
	}
	sort(res.begin(), res.end());
	return res;
}
int main() {
	ll N, M;
	cin >> N >> M;
	vector<ll>div = calc_divisor(M);

	//Mの約数dであって、d*N<=Mとなる最大のdを求める
	ll res = 1;
	for (ll i = 0; i < div.size(); ++i) {
		if (div[i]*N <= M) {
			res = max(res, div[i]);
		}
	}
	cout << res << endl;
	return 0;
}
```
【Rails】バリデーションをかける

#バリデーションとは
テーブルに格納するデータに制限を設けること。
具体的に使用する場面の例としては、

- 会員登録においてパスワードはn文字以上でなくてはならない
- 会員登録においてメールアドレスは既存のアカウントと重複してはならない
- 投稿においてタイトルは必須なので空は受け付けない

等の要望を実現するもの。

#よく使いすぎるバリデーションの種類
バリデーションの種類を少しだけ紹介。
自分が色々経験積んだらまた追加していくなり別記事にまとめるなりするつもり。

- **データが存在するかどうか**<br>
入力必須項目かどうか。

```ruby:
presence: true
```
- **データが一意かどうか**<br>
既存のデータと重複する内容ではないか。

```ruby:
uniqueness: true
```
- **文字数制限**<br>
「n文字以上」や「n文字以下」といった制限を加える。

```ruby:
# 8文字以上
length: {minimum: 8}
# 20文字以下
length: {maximum: 20}
```


#バリデーションをかけてみる
制限をかけたいデータが所属するテーブルに結びついたモデルファイルに処理を記述する。
ユーザーのパスワードに制限を加えたい場合、そのパスワードはUsersテーブルに格納されるので
app/models/user.rbに記述することになる。

```ruby:
validates :カラム名, {バリデーション名: [制限をかけるかどうかをtrue or falseで]} 

#例 nameカラムに空を受け付けないバリデーションをかける
validates :name, {presence: true}
#例 1つのカラムにバリデーションを複数かける
validates :email, {presence: true, uniqueness: true}
```
Docker for Mac のコンテナからMac上のWebアプリにアクセスする方法

# 手順

公式ドキュメントを見ると、以下のホスト名でアクセスできる。
https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds

```
host.docker.internal
```

例えば、Mac上でRailsサーバーを立てていて、Dockerのコンテナ上からアクセスしたい場合は以下のようになる。

```bash
# debianで出来たイメージなら動く。alpineにはbashやcurlが入っていないので注意。
docker exec -it <container_name> /bin/bash
# ホストのMacにアクセス。Railsは通常はポート3000を使っているので3000でアクセス
curl host.docker.internal:3000
```

# 注意点
公式ドキュメントを見ると、バージョン18.03からこのホスト名が使えるようになった。
https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds

それ以前だと以下のホスト名でアクセスできたようだ。

```
docker.for.mac.localhost
```
検索していると、上記のホスト名が多く出てくるので注意。
現在でも使えるが、いつ使えなくなるかわからない。
もしかしたら`host.docker.internal`も急に非推奨になるかもしれない。
lint-staged で部分ステージングのみを対象に git add されるようになった

## tl;dr

`lint-staged@8.x` から、ファイルの変更の一部だけをステージングしてコミット (pre-commit) した際に、変更部分だけを対象に `git add` が行えるようになりました。
というのが嬉しかったので周知したくて書きました。

参考: 
[🎉 Announcing lint\-staged with support for partially staged files](https://hackernoon.com/announcing-lint-staged-with-support-for-partially-staged-files-abc24a40d3ff)

## lint-staged？

`lint-staged` は `husky` などと組み合わせる事で、コミット時にファイルを linting できるツールです。
（詳細は [公式のドキュメント](https://github.com/okonet/lint-staged) または他の Qiita やブログの記事を参照してください）

使い方はこんな感じになります。

```json:package.json
{
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "linters": {
      "*.js": [
        "prettier --write",
        "eslint --fix",
        "git add"
      ]
    },
    "ignore": [
      "public/**/*"
    ]
  }
}
```

## lint-staged の git add

`lint-staged` はフォーマット処理等を加えたファイルに対し、 `pre-commit` が終了する前に `git add` で再度ステージに追加することが出来ます。
（`husky`, `lint-staged` のコードを追っていないのでこの理解は正確ではないかもしれません。）

ただ、この時にステージングされるのはステージングしていた差分ではなく **ファイル全体の変更差分** なので、
ステージングしていたのが変更の一部だけだった場合に余計な部分までステージに入り、そのまま処理されてしまうため、意図しないコミットになってしまいます。

`list-staged` のバージョン `8` からこの問題が修正されており、
部分ステージングに対して `lint-staged` で指定の処理を実行し、その一部のみを再ステージングするということが可能になりました。
うれしい！

## 破壊的変更

設定等に変更は無いのですが、 Node.js のバージョンが指定されています。

> Node >= 8.6 is required

ブログ記事と [リリース](https://github.com/okonet/lint-staged/releases/tag/v8.0.0) には上記のように書いてありますが、
README.md を見ると v6 以降と書いてあり、どっちが何なんでしょう… :thinking: 

> The latest versions of lint-staged require Node.js v6 or newer. 

どちらにせよ Node.js の v6 は来年４月でサポート切れるので、まだの人は早めにアップデートしておきましょう。
[nodejs/Release: Node\.js Foundation Release Working Group](https://github.com/nodejs/Release#release-schedule)
Xcodeのコマンドラインツールでエラーが出るので入れ直した

## 環境

- macOS High Sierra 10.13.6
- Xcode Version 10.1 (10B61)

## 事象
Macの環境設定でまずXcodeとコマンドラインツールを入れ、続いて `homebrew` を入れようと
コマンドを叩きましたが途中でこのようなポップアップが出てきてしまいました。

<img width="499" alt="スクリーンショット 2018-11-01 18.17.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/42028/f7fef6c6-2e19-4e36-6a2d-d23ffeb8344e.png">

インストールボタンを押すと下の画像の状態に。。

<img width="510" alt="スクリーンショット 2018-11-01 18.18.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/42028/2a569a73-c2ef-59a7-775c-99ef88b9ca76.png">


下記コマンドでインストールしても解決せず

```
$ xcode-select --install
```

## 解決方法

下記サイトにApple IDでログインし、
コマンドラインツールを落として入れ直したら解決しました。

[More Downloads for Apple Developers](https://developer.apple.com/download/more/)

### ダウンロードしたバージョン
- Command Line Tools (macOS 10.13) for Xcode 10
InterSystems IRIS NLPをVB.NETから使う方法のまとめ(2)

(1)で作業して作成したNLPのドメインを用いて、これを呼び出すコードをObjectScriptで記述する部分と、この関数（ストアドプロシージャと呼びます）をVB.NETで呼び出す方法について説明します。

ObjectScriptの基本的な呼び方例を次に示します。

```visualbasic:StoredProc()
Class User.MercForNLP Extends (%Persistent, %Library.Populate)
{

Property diseaseName As %String;

Property medicalDivision As %String;

Property dataType As %String;

Property contentFull As %String(MAXLEN = 100000);

ClassMethod StoredProcTest3() [ ReturnResultsets, SqlName = StoProcTest3, SqlProc ]
{

    Set rs=##class(%Library.ResultSet).%New("%iKnow.Queries.EntityQAPI:GetSimilar")

    Set domId = $system.iKnow.GetDomainId("AnalyzeMerc")

    Set sc=rs.Execute(domId,"糖尿病",1,50)

    Do %sqlcontext.AddResultSet(rs)
}
}
```

このテーブル（クラス）は[MercForNLP]です。そのフィールドとして、[diseaseName], [medicalDivision], [dataType], [contentFull]（と、デフォルトである[Id]）が作られています。
ここに、[ClassMethod]と宣言して関数（メソッド）[StoredProc3()]を作成しています。

この後ろにある[]の中身は、それぞれ、
ReturnResultSets : VB.NET側からIRISDataReaderで読み出せる形式でデータの戻り値を生成する
SqlName=StoProcTest3 : 呼び出し形式が"SQL形式"であるということ（Userドメイン空間で一意の名前になるように名前を決める必要がある）
SqlProc : SQL形式の戻り値を出すプロシージャであることの宣言
であることを意味しています。

NLPにアクセスする方法として、
%iKnow.Queries.EntityQAPI:GetSimilar
という関数を作ることがわかります。これはClass Referenceで次のように解説されています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/262065/2b70dd54-02a1-552d-a8e6-2910e196eb2d.png)

ResultSetである（として使う）rsに、GetSimilarの結果を戻すようなresultSetをNewで生成します。
rs=##class(%Library.ResultSet).%New("%iKnow.Queries.EntityQAPI:GetSimilar")

(1)で作成したドメイン[AnalyzeMerc]のID番号を得る方法として、
$system.iKnow.GetDomainId("AnalyzeMerc")
という関数で呼ぶことがわかります。

この中から、[糖尿病]というエンティティに類似したエンティティを50個まで取り出す作業として、
Set sc=rs.Execute(domId,"糖尿病",1,50)
という関数が割り当たっています。

ObjectScriptの最後に、戻すべきResultSetとして[rs]を渡していることがわかります。
Do %sqlcontext.AddResultSet(rs)


VB側での記述は次のようにします。以前記載しました、IRISサーバへの接続の後、IRISCommand、IRISDataReaderを使います。ポイントは、

Command = New IRISCommand("SQLUser.StoProcTest3", connection)
で指定している関数名が、[StoredProcTest3()]ではなく、[SQLUser.StoProcTest3]であることに注意が必要です。出力は、[reader.Read()]として出力リストを一つずつ読み出し、その項目名（フィールド名）をreader.Item("entUniId")のような形式で記述します。


```VB:ResultSetのフィールド名を知る方法
dim i as Integer
i = reader.FieldCount 'フィールド数の上限がわかる
dim s as String
s = Reader.GetName(1) '1からi-1までの数字を入れると、フィールド名が取得できる
```

VB.NET側の記述は次の通りです。

```VB:Button3_Click

 Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click

        Dim connection As IRISConnection

        connection = New IRISConnection

        connection.ConnectionString = "Server=localhost; Port=51773; " + "Namespace = TESTSAMPLES; " + "Password = trki1979; " + "User ID = torikai;"

        connection.Open()

        Dim Command As IRISCommand

        Dim reader As IRISDataReader

        Command = New IRISCommand("SQLUser.StoProcTest3", connection)

        Command.CommandType = CommandType.StoredProcedure

        reader = Command.ExecuteReader()

        While (reader.Read())

            MsgBox(reader.Item("entUniId") & "," & reader.Item("entity") & "," & reader.Item("frequency") & "," & reader.Item("spread"))

        End While

    End Sub
```
【Rails】入力されたデータをポストする

#内容
入力フォームによって入力された値をDBに格納するために必要なアクションでの処理を記録。
今回はusersテーブルに新しいユーザーを追加する処理(会員登録処理)を例にとっている。

#form_forを使用
特定のモデルを編集するのに適している、form_forを使用した際の例を紹介する。

###ビューでの処理
今回は会員登録ということにしたので下記のフォームを使用。
電話番号等入力するデータによって適したフォームがあるので、適当に選択する(フォームの種類についての詳細は<a href="https://qiita.com/Hal_mai/items/1e5afd0c99dd9059839f">こちら</a>)。

```html:new.html.erb
<%= form_for(@user, url: signup_path, method: :post) do |f| %>
    <p>
    <%= f.label :name, "アカウント名" %><br>
    <%= f.text_field :name %>
    </p>
    <br>
    <p>
    <%= f.label :email, "メールアドレス" %><br>
    <%= f.email_field :email %>
    </p>
    <br>
    <p>
    <%= f.label :password, "パスワード" %><br>
    <%= f.password_field :password %>
    </p>
    <br>
    <%= f.submit "登録する" %>
<% end %>
```

###コントローラでの処理
Userモデルから新しいモデルオブジェクトを生成。
中身はparamsから一度に取得。

```ruby:users_controller.rb
class UsersController < ApplicationController
    def new
    @user = User.new
    end

    def create
        @user = User.new(users_params)
        if @user.save
            # 会員登録の場合は同時にログインしたいので下の1行が必要
            # session[:user_id] = @user.id
            flash[:notice] = "会員登録完了"
            redirect_to("/")
        else
            reder("users/new")
        end
    end

    def users_params
        params.require(:user).permit(:name, :email, :password)
    end
end
```

###ルーティング
routes.rbではpostの指定も忘れずに。

```ruby:config/routes.rb
post "/signup" => "users#create"
```
#form_tagを使用
モデルと関係しない汎用的なフォームを生成するform_tagを使用した際の例を紹介する。

###ビューでの処理
こちらも会員登録ということにしたので下記のフォームを使用。
フォームは入力してほしいデータに合わせて適当に選択する(フォームの種類についての詳細は<a href="https://qiita.com/Hal_mai/items/1e5afd0c99dd9059839f">こちら</a>)。

```html:new.html.erb
<%= form_tag("/users/create") do %>
    <p>アカウント名</p>
    <input name="name" value="<%= @user.name %>">
    <p>メールアドレス</p>
    <input name="email" value="<%= @user.email %>">
    <p>パスワード</p>
    <input type="password" name="password" value="<%= @user.password %>">
    <input type="submit" value="新規登録">
<% end %>
```

###コントローラでの処理
Userモデルから新しいモデルオブジェクトを生成。
中身はparamsから1つずつ取得。

```ruby:qiita.rb
class UsersController < ApplicationController
    def new
        @user = User.new
    end
  
    def create
        @user = User.new(
            name: params[:name],
            email: params[:email],
            password: params[:password]
        )
        if @user.save
            session[:user_id] = @user.id
            flash[:notice] = "会員登録完了"
            redirect_to("/")
        else
            render("users/new")
        end
    end
end
```

##ルーティング
form_for使用の際と同様なので省略。