OmniAICreator/Qiita-1.07M huggingface dataset:
Firebase プロジェクトのディレクトリ構成 ベストプラクティス

まだ１つしかプロジェクト作ったことないのでベストもクソもないのですが、よく見かけるサンプルのディレクトリ構成に違和感があるもので。。。

# 対象プロジェクト

Firebase プロジェクトで Hosting と Functions を使い、かつ Hosting にデプロイするファイルを Webpack 等を用いてビルドする場合です。

# ベストプラクティス

単純な話なのですが、Firebase プロジェクト直下に１つディレクトリを作成してこれを hosting プロジェクトのルートにするのがベストです。

```
<Filrebase Procject>/  # Firebase プロジェクトのルート
    firebase.json
    package.json
    hosting/           # Hosting プロジェクトのルート
        build/         # Hosting プロジェクトのビルド成果物 = Hosting のデプロイ対象
        src/           # Hosting プロジェクトのソース
        package.json
    functions/         # Functions プロジェクトのルート
        src/           # Functions プロジェクトのソース
        package.json
```

hosting と functions が横並びでディレクトリ構成が統一されます。
どう考えてもこれがキレイな構成ですよね。。。

`firebase.json`には Hosting プロジェクトのビルド成果物を公開ディレクトリとして設定します。

```json:firebase.json
  "hosting": {
    "public": "hosting/build"
```

ルート直下の `package.json` にはデプロイスクリプトなどを登録しておきます。

```json:package.json
 "scripts": {
    "deploy": "yarn --cwd hosting build && firebase deploy"
  }
```

# よく見かけるサンプル(良くない例)

よく見かけるサンプルでは、Firebase プロジェクトのルート = Hosting プロジェクトのルート となっているものが多いです。

```
<Filrebase Procject>/  # Firebase プロジェクトのルート、Hosting プロジェクトのルート
  　　firebase.json
  　　build/            # Hosting プロジェクトのビルド成果物 = Hosting のデプロイ対象
  　　src/              # Hosting プロジェクトのソース
  　　package.json
  　　functions/        # Functions プロジェクトのルート
    　　  src/          # Functions プロジェクトの
    　　  package.json
```

Hosting だけのプロジェクトであればこれでもいいのですが、Functions も使うプロジェクトだと hosting と functions が入れ子になってしまいます。

どう考えても歪な構成ですよね。。。

## 作成手順が良くない？

このような歪なディレクトリ構成がまかり通っているのは、入門書などで以下のような順番で説明しているからではないでしょうか。

1. 最初にローカルで動く SPA を作成
2. SPA を Firebase プロジェクトにしてデプロイする
3. Functions を使用するコードを追加

最初にSPAとして作成して後付けで Firebase プロジェクトにすると、どうしても`Firebase プロジェクトのルート = Hosting プロジェクトのルート` になってしまいます。。。
[React] モーダルの作り方

#概要
今回はモーダルの作り方についてみていきます。
モーダルは項目を削除する時とかに出てくる画面のことで、「本当に削除しますか？」に対して「はい」、「いいえ」みたいに選択できるものです。
#ポータル
モーダルは画面いっぱいを占領するので他の要素よりもトップに来なければいけません。
そこでポータルについて意識しないといけません。
簡単にいうと構造的に深くに作ってはダメで、浅いところに作るということです。
#実装していく
基本的に最初の方で

```javascript:src/index.js
ReactDOM.render(
  <App />,
  document.querySelector('#root')
);
```
のようにして開発していきますが、ここの配下にモーダルを作ると構造的に深くなってしまうので、モーダルを作るときにはroot以外にidを指定して場所を作ってあげてそこに対して作っていきます。

```html:public/index.html
<div id="modal"></div>
```
上記は例としてid="modal"として新たに要素を作っています。

```javascript:src/components/Modal.js
import React from 'react';
import ReactDOM from 'react-dom';

const Modal = props => {
  return ReactDOM.createPortal(
    <div className="">
      <div className="">
        This is a Modal!!
      </div>
    </div>,
    document.querySelector('#modal')
  );
};

export default Modal;
```
上記ではReactDOM.createPortalメソッドを使っており第一引数に表示したい画面の内容、第二引数に場所を指定しています。
適当にcssつけてみてください。
あとは表示したいコンポーネントで使ってあげるという感じです。
#まとめ
簡単にモーダルの作り方を説明しました。
参考になれば幸いです。
論文を日本語に翻訳するツール

#もの
https://sites.google.com/view/translatepaper/home/%E7%BF%BB%E8%A8%B3
※なお、テストは十分に行われておりません。
#モチベーション
論文を読むときに媒体がPDFだと文末の-(ハイフン)とか改行があってそのままだとGoogle翻訳にかからない。
めんどいからそこらへん自動で除去りたい。
[先人](http://dream-exp.hatenablog.com/entry/2017/07/22/shaper"論文をGoogle翻訳にかける時に便利なWebApp「Shaper」を公開しました")がやってるけどこのツールとGoogle翻訳で二回コピペするのがめんどいね。
じゃあ翻訳までやってくれるものつっくろ。
以上

あとGoogleAppScriptの勉強
#残念な点

- Form投稿+ユーザID入力ボタン押下って2ステップ必要なこと(回避方法がわからなかった)
- Google Form使ってやるのは勝手ハイフンとか改行とか整形してくれて楽だったんだけど、そのせいでスプレッドシートに情報が蓄積されちゃう(有料の論文とか問題かも)

何か良い回避方法があったら教えてください

#仕組み(殴り書き)

GoogleFormで回答
GoogleFormからの情報をスプレッドシートに登録
自作Formのボタンを押すことで、スプレッドシートからのデータに対してLanguageApp.translate()が動いて翻訳される
```var japanese = LanguageApp.translate(data, 'en', 'ja');```
翻訳されたデータをあらかじめ作っておいたテンプレートに当てはめてHTMLファイルとして出力する

```
  var template = HtmlService.createTemplateFromFile('temp_result');
  template.before = data;
  template.after = japanese;
  return template.evaluate()
```

#コード全体
``` translatepaper.gs
function doGet(e) {
  var sheet = SpreadsheetApp.getActiveSheet();
  Logger.log(SpreadsheetApp.getActiveSheet().getName());
  var row = sheet.getLastRow();
  var userID = e.parameter.name
  if (userID != null){
    Logger.log(userID);
    while (row > 1){
      if( userID == sheet.getRange(row,3).getValue() ){
        break;  
      }
      else {
        row = row - 1;
      }
    }
  }
  if(row == 1){
    var data = 'The specified user ID does not exist.';
  }
  else {
    var data = sheet.getRange(row,2).getValue();
  }
  Logger.log(data);
  var japanese = LanguageApp.translate(data, 'en', 'ja');
  Logger.log(japanese);
  sheet.getRange(row,4).setValue(japanese);
  
  var template = HtmlService.createTemplateFromFile('temp_result');
  template.before = data;
  template.after = japanese;
  return template.evaluate()
}
```
``` temp_result.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <div>
    <div>
    <p>翻訳前</p>
    <p>
    <?= before ?>
    </p>
    </div>
    <div>
    <p>翻訳後</p>
    <p>
    <?= after ?>
    </p>
    </div>
    </div>
  </body>
</html>
```

#最後に

- 今回省略できたハイフンとか改行の処理を自分でやることになるかもしれないけど、GoogleFormを使わないって選択肢をとれば、残念な点二つとも回避できそう
- ちなみにハイフンとか改行の処理はなんとGoogleFormにコピペした時点でしてくれてます！(多分)
herokuで"We're sorry, but something went wrong."が出てアプリが開けなくなった

Herokuでアプリを公開したら`We're sorry, but something went wrong.`というメッセージが出てアプリが開けなくなったので対処法を書きます。

# 試した方法1
`We're sorry, but something went wrong.`で検索すると

```
$ heroku run rails db:migrate
```

を実行すれば解決すると出てきたので試したが解決できなかった。

# 試した方法2

```
$ heroku logs -t
```

上記のherokuコマンドでログを確認したところ以下のエラーが出力されていました。

```
ActionView::Template::Error (The asset "<画像名>.png" is not present in the asset pipeline.)
```

このエラーを調べたところ、本番環境でアセットパイプラインが正しく設定されていないため、`app/assets/images/`以下にある画像が正しく読み込まれていないことが原因でした。
そこで、以下を実行して本番環境上でアセットパイプラインが自動で通るように設定を変更しました。

```
$ rails assets:precompile
```

```config/environments/production.rb
config.assets.compile = true   #falseをtrueに変更
```

もう一度デプロイし、`$ heroku run rails db:migrate`を実行すると問題なくアプリを開くことができました。

# 参考にした記事
[Heroku コマンド・設定 メモメモ](https://qiita.com/pugiemonn/items/0e69b7a29a384b356e65)
[[デプロイ]アセットパイプラインとはなんぞや？？？[本番環境]](https://qiita.com/hayabusa3703/items/430bf371c94057195392)
スニペットで最速補完していく [VSCode]

# スニペットとは
wikiを参照すると
> 情報処理の分野ではよく使う短いプログラムコードを統合開発環境から呼び出す機能のことである.
>また, 呼び出される短いコードのことをスニペットと呼ぶ場合もある.

とのこと.

この機能はVSCodeでも標準で搭載されています.
以下でスニペットの定義と呼び出しの仕方について書いていきます.

# VSCodeで自作スニペットを作成する
## ユーザー自身でスニペットを定義するためにjsonファイルを開く
言語ごとにjsonファイルが用意されているため, そこにスニペットの定義を書いていくことになります.
jsonファイルの開き方は以下のどちらかです.

### jsonファイルの開き方 : パターン1
1. `Ctrl + Shift + P`でコマンドパレットを開き, [configure user snippets]と入力します.
2. そうすると言語の一覧がズラッと出てくるので, 設定したい言語を選択してください.

### jsonファイルの開き方 : パターン2
1. 上部のタブの[ファイル]->[基本設定]->[ユーザースニペット]を選択します.
2. そうすると言語の一覧がズラッと出てくるので, 設定したい言語を選択してください.
![open_json.gif](https://qiita-image-store.s3.amazonaws.com/0/264254/f2f31999-847b-3871-eb7a-0670cde3d552.gif)


## jsonファイルへ定義を書いていく
下記のようなフォーマットでjsonへ書き足していきます.

```json
"スニペットの名前": {
  "prefix": "呼び出す際のキーワード",
  "body": [
    "展開したい内容",
    "",
    "",
  ],
},
```
正直スニペットの名前は利用しないのでどうでもいいですが, 他のスニペット名と被らないようにしましょう.
`"prefix"`をコード内で記述し, `tab`を押すと`"body"`の内容へと補完されます. (補完候補がいくつかある場合はその一覧がでるため, 適するものを選択することになります)

### `tab`を押してスムーズに入力位置を切り替えるには
`$1, $2, …, ${10}, ${11}, …`を利用すると補完時に`tab`で移動する位置を決めることができます.
また`$0`で終わりの位置を決定できます.
例としては以下のような感じです.


```json
"Add memo box": {
	"prefix": ">@memo_box",
	"body": [
		"<div class=\"memo\">",
		"<div class=\"box-title\">$1</div>",
		"",
		"$2",
		"</div>$0"
	],
	"description": "add div-tag has class'memo'"
},
```
実際の挙動はこんな感じです.
![snippets_move.gif](https://qiita-image-store.s3.amazonaws.com/0/264254/bc63d9c1-e8a5-b713-8a12-b236d81231ec.gif)



## タブ補完を有効にする
`Ctrl + ,`でユーザー設定を開き, `Tab Completion`の部分を選択し, `on`か`onlySnippets`を選択します.
![tab_completion.png](https://qiita-image-store.s3.amazonaws.com/0/264254/a3259c5f-e808-d209-23b2-f2467c20a881.png)

# VSCodeでスニペットを利用する
`"prefix"`で登録したキーワードを打ち, `tab`キーを入力すると`"body"`の内容へと補完されます. (補完候補がいくつかある場合はその一覧がでるため, 適するものを選択することになります)

先ほどにも載せましたが以下のように動作します.
![snippets_move.gif](https://qiita-image-store.s3.amazonaws.com/0/264254/bc63d9c1-e8a5-b713-8a12-b236d81231ec.gif)
ロリポップ!でSSHに接続するための設定 

# はじめに
SSH接続する手順や、その後にaliasや公開鍵を登録して、簡単に接続する方法をシェアハピしたいと思います。
意外と簡単だから大丈夫だべ✋
ちなみに、ロリポップ!で設定した時のやり方なので、詳しいSSHの説明はしていないです。
もうちょっと詳しく知りたければ、他の記事見ると良いと思います🌊

## 接続編
SSHの主な接続方式としては２種類あって
**パスワード認証方式**
**公開鍵認証方式**
があります。

ロリポップ!でSSH接続するとき、下記の手順になりました。

```console
~$ ssh ユーザー名@ホスト名 -pポート番号
```

で、パスワードを求められる
この場合、予め用意されているパスワードを入力するので、パスワード認証方式です。

```console
~$ ユーザー名@ホスト名's password: 
```

パスワードを入力しまして、
これでサーバーに入れるようになると思うんですけど、これを毎回入力するのは面倒臭いです🤚
なので、ailiasと公開鍵を登録して簡単に接続します。

## aliasを登録する

aliasと呼ばれる環境変数を設定していきます。

```console
~$ vim ~/.bashrc
```

なんでも、いいのですがエディタで開いて・・。


```sh
 alias ssh888="ssh ユーザー名@ホスト名 -pポート番号"
```


変数名は分かりやすい名前にします。ここでは仮に「ssh888」
という名前にしました。
この変数名がそのまま、接続先やポート番号の情報になります。
保存したあとは


```console
~$ source ~/.bashrc
```

このコマンドも実行して、読み込み直します。
そして、aliasを呼び出してやるだけで・・。

```console
~$ ssh888
```

サーバー接続情報が予め設定されてあるので、パスワード入力画面に移りました！

```console
~$ ユーザー名@ホスト名's password: 
```
次は公開鍵をサーバーに登録します。


## 公開鍵を作成・登録する

まだ公開鍵がない場合、新しく鍵を作成します。

```console
~$ ssh-keygen
```

鍵を生成後、aliasで登録したホストに公開鍵を渡します。

```console
~$ ssh-copy-id -i ~/.ssh/id_rsa.pub ユーザー名@ホスト名 -pポート番号
```

-iオプションで公開鍵を指定します。
これでaliasで呼び出してあげるとログイン出来ます！
お疲れ様でした🍺


## 参考URL
[インフラエンジニアじゃなくても押さえておきたいSSHの基礎知識](https://qiita.com/tag1216/items/5d06bad7468f731f590e)
[ロリポップのレンタルサーバにSSHキー認証でログインする](https://akamist.com/blog/archives/3190)
MonacoindのLua拡張プラグインを使ってみた

#概要
monacoindに導入されたLua VMについての備忘録兼解説的な記事です。
プラグインの使い方をサンプルコードをチラ見しながら説明します。

#何ができるようになって、何が嬉しいのか

**monacoindをインストールするだけでluaで書いたプログラムが実行できるし、monacoindへの操作もできる**
ブロックチェーンに直に触ることのできるアプリをmonacoindだけで作れるようになります。jsonRPCに苦しめられる必要はありません。書いて、実行するだけです。
![MonacoindLuaVM.jpg](https://qiita-image-store.s3.amazonaws.com/0/199495/e276a634-3128-fa41-2787-59340f824e36.jpeg)



##もう少し具体的に
**luaからmonacoindを操作できる**
[提供されているサンプル](https://github.com/monacoinproject/monacoin/tree/plugin_dev/sample/plugin)を見るとわかりますが、`getblock()`や`send_from()`といった情報取得や送金命令などのcoindへの操作を記述出来ます。
jsonRPCやbitcoinjs-libを使わなくてもコインが送れる！

**monacoindのイベントに合わせてluaプログラムを実行**
monacoindにはイベントが発生します。例えば新しいブロックの更新です。そういったタイミングにおいて、luaプログラムを実行することができます。
自動販売機的なことがmonacoindだけで出来るようになる！

#利用手順
・この拡張はmasterブランチではなくplugin_devブランチに組み込まれているのでそれをビルド。
ブランチの指定さえすればビルドの方法やその後の設定などは通常と同様ですが、getrawtransaction()を使いたいのでmonacoin.confにtxindex=1は入れておくことを推奨
・wallet.datが存在するディレクトリ（`~/.monacoin/`だと思います）にpluginディレクトリを作成
・作成した`~/.monacoin/plugin/`配下にluaで書いたプログラムを置いて準備完了
・端末から`monacoin-cli loadplugin ファイル名（.luaまで含める）`を実行するとプラグインが読み込まれて実行有効化され
・プラグインが有効な状態でイベントが起きると関数が実行される
・端末から`monacoin-cli unloadplugin ファイル名（.luaまで含める）`を実行するとプラグインを無効化

※testnetを使う場合`~/.monacoin/testnet4/plugin/`です

#サンプルコードを見てみる
以下を見るのが全体像をつかむのに適しています。
https://github.com/monacoinproject/monacoin/blob/plugin_dev/sample/plugin/empty.lua
これらの関数を実装しておけば、プラグインが有効化されている限りそれぞれのタイミングで実行してくれます。
`OnInit()`と`OnTerm()`はそれぞれのタイミングで実行されるだけなので単純です。
`OnBlockNotify()`はinitialsync=true状態だと通知が山ほど来てしまうので、スルーしましょう。[コード参考](https://github.com/monacoinproject/monacoin/blob/plugin_dev/sample/plugin/http_post.lua#L7L10)
`OnWalletNotify()`はmonacoindのウォレット内の自分のアドレスに関係あるトランザクションだけを通知してくれます。

#簡単なプログラムを書いてみた
[私のコード](https://github.com/apollo-maple/LuaTest-mona/blob/master/search_payment_to_address.lua)です。ブロックチェーンを監視して特定のアドレスに対しての入金を検知したらmonacoindを実行している端末の標準出力に表示します。だからなんだよって言っちゃいけない。

#デメリットというかちょっと手間なこと
**Luaってなんですか**
今回初めて私はLuaという言語の名前を聞きました、Lua自体を勉強する必要があります。
ですが、簡単なプログラムを書く分にはこの言語は簡単に感じています。関数型？知らんな!と思っていても手続き型でCのようにとりあえずは書けます。真面目に書こうとしたら大変なのかもしれませんがとりあえず動く分には動きます。

**本格的なWebアプリを作るにはどうしたらいい？**
ユーザーのリクエストに応じてmonacoindを操作するためには、その内容を蓄えておいた外部データベースにmonacoindから持ってくるなどの工夫をする必要がありそうです。簡便さを保持したまま作成できるアプリにはいくらか制限がありそうですね。

#まとめ
monacoindだけでブロックチェーンを使った学習、アプリが出来る！

#注意
とりあえずtestnetを使いましょう。ありがたいことにMonapartyもelectrum-monaもblock explorerもtestnet版が有志によって存在します。これを使わない手はありません。それとtestnetならブロックチェーンの同期も早いのですぐに開発に取り掛かれます。


#参考外部記事
[MonacoinにLua VMを組み込んでみました· GitHub](https://gist.github.com/monacoinproject/734f65c15e0a375c68d62ffe3254dc33)
[Monacoind の lua 拡張 – Blockchain Engineer Blog – Medium](
https://medium.com/blockchain-engineer-blog/monacoind-%E3%81%AE-lua-%E6%8B%A1%E5%BC%B5-862f6c888495)
Jenkins導入(CentOS7)

CIについての勉強の一環としてJenkinsの勉強。
構築時のメモ。

#環境
・VirtualBox
・CentOS7.6(1810) minimal

#前提条件
・firewallが無効になっていること
・rootでログインしていること

#構築
OpenJDKのインストール

```console
# yum -y install java-1.7.0-openjdk.x86_64
```

公開鍵のインポート

```console
# wget -O /etc/yum.repos.d/junkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
# rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key
```

Jenkinsのインストール

```console
# yum -y install jenkins
```

Jenkinsの起動・自動起動設定

```console
# systemctl start jenkins
# systemctl enable jenkins
```

#動作確認
``` http://[サーバIPアドレス]:8080/ ```にアクセスしてページが表示されることを確認する。

![スクリーンショット 2019-02-11 17.33.15.png](https://qiita-image-store.s3.amazonaws.com/0/357364/c8026e57-7018-e130-6096-dd59a4cc5dba.png)

ログインユーザは ``` admin ```で初期パスワードは以下で確認する。

```console
# cat /var/lib/jenkins/secrets/initialAdminPassword
05545b6ab9b14f9aadbe879f4f572e6b
```

以上
webエンジニアがViroReactでAR/VRアプリ入門！

# ViroReactとは？

ViroReact is a developer platform for rapidly building AR/VR applications using React Native. Use a single code base for your AR and VR apps.

https://viromedia.com/viroreact/

# 環境構築

まぁnpmとかyarnはみんな入ってるとして...

brewでwatchman, yarnでreact-native-cliとreact-viro-cliを入れる

```
$brew install watchman
$yarn global add react-native-cli
$yarn global add react-viro-cli
```

実機テストできるアプリをダウンロードしておきましょう

https://itunes.apple.com/us/app/viro-media/id1163100576?mt=8

ViroReactでAPI_KEYをゲッチュしておきましょう

https://viromedia.com/signup

# 新規プロジェクト作成

とりあえずinit

```
$react-viro init ViroSample --verbose
```

```
$cd ViroSample
$yarn install
```

App.jsの25行目らへんに先程げっとしたAPI_KEYを書く

```App.js
/*
 TODO: Insert your API key below
 */
var sharedProps = {
  apiKey:"API_KEY_HERE",
}
```

# アプリ起動

```
$yarn start
```

アプリが動くURLが出てくるので、それをViroMediaのアプリにコピペします

```
http://xxxxxx.ngrok.io
```

さっきのURLをアプリ上に貼ると

<img width="375" alt="Image from iOS (1).png" src="https://qiita-image-store.s3.amazonaws.com/0/77198/37f868a9-2f46-61f4-af9c-bab4bd74d5b4.png">

無事にハローワールドできました！

<img width="375" alt="Image from iOS (2).png" src="https://qiita-image-store.s3.amazonaws.com/0/77198/3581afa6-38f2-dcbc-56e8-0d3d76aaa79b.png">
理科大生のためのSlackつくった

### はじめに
* [究極のIT系最新技術情報収集用Slackチーム公開](https://qiita.com/kotakanbe@github/items/32cf4eb3de1741af26fb)
* [Slack-list-ja](https://bokuweb.github.io/slack-list-ja/)


などエンジニアのSlackコミュニティで結構、あるんですけど、大学にもあったらいいなと思って、東京理科大学のSlackつくりました！入ってください:bow:
登録は理科大のメールアドレスがあれば入れます。OBのアドレスでもOKです！

**参考**

* [slackin](https://github.com/rauchg/slackin)
* [slack-invite-automation](https://github.com/outsideris/slack-invite-automation)

### 作ったもの
[Tokyo University of Science Slack Team](https://rikadai-slack.now.sh/)
https://github.com/funabashi800/slack-auto-invitation

<img width="560" alt="スクリーンショット 2019-02-11 16.28.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/266140/0bf5bce1-59c5-c0ee-7ecd-497220ccf3a6.png">

### 開発環境
* node: v10.15.0
* nuxt: v2.4.3
* semantic-ui: v2.4.2

### Slack API
今回は新規ユーザーへのメールアドレスによる招待と、ワークスペースへの登録者人数と現在のステータスがオンラインのユーザーの数をカウントするため、以下を使用

* [users.list](https://api.slack.com/methods/users.list)
* [users.admin.invite](https://github.com/ErikKalkoken/slackApiDoc/blob/master/users.admin.invite.md)

#### users.list (登録者数とオンラインユーザーのカウント)
```javascript
async asyncData(){
    let {data} = await axios.get('https://slack.com/api/users.list', {
      params: {
        token: process.env.SLACK_TOKEN,
        presence: true
      }
    })
    let total = data.members.length;
    let active = data.members.filter(user => {
      return user.presence === 'active'
    }).length
    return {
        info: {
          total: total,
          active: active
        }
    }
```

#### users.admin.invite (ユーザーへの招待メール送信)
```javascript
async sendEmail() {
    try{
        let params = new URLSearchParams();
        params.append('token', process.env.SLACK_TOKEN);
        params.append('email', this.email);
        let {data} = await axios.post('https://slack.com/api/users.admin.invite', params);
     }
     catch(err){
         ......
     }
```

### Deploy
デプロイは[Now](https://zeit.co/now)を使いました。:sunglasses:

```json:now.json
{
    "name": "dist",
    "version": 1,
    "alias": "rikadai-slack"
}
```

```bash
# 環境変数(SlackのToken)の登録
$ now -e SLACK_TOKEN="your_slack_workspace_token"

# サブドメイン名の変更（早いもの勝ち）
$ now alias
```

**参考**

* [nowで構築するSlack自動招待(slackin)]
(https://qiita.com/hiro93n/items
/fd42484e696a223935ae)
* [Environment Variables and Secrets](https://zeit.co/blog/environment-variables-secrets)

### さいごに
もし**理科大**の方でこの記事見てる人いたらシェアお願いします！
**チャンネルは自由につくってもらっていいので、たくさんつくってください！**
**開発仲間**を見つけたり、**勉強会**とかができればいいなと思ってます！

一応、アプリのインテグレーションだけは管理者権限にしてます！それ以外はたぶん自由！
<img width="722" alt="スクリーンショット 2019-02-11 17.23.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/266140/a7fcd0c5-2a9c-4000-4036-5df7c068c110.png">

勝手に坊っちゃん使ってごめんなさい:bow_tone1:
USBの電力管理

特に節電に関して。
レジュームに関してはLinux kernelの動作に関して記述。

#サスペンドとレジューム
##サスペンド
- ホストはデータのやり取りがある間、1ms間隔でSOFパケットを送出している
- ホストは一定期間データのやり取りがないと判断すると、自身がサスペンド状態に入り、バス上にＳＯＦパケットを送出するのをやめる
- Full/High Speedのデバイスの場合、SOFが3ms以上の間来ないことを検出すると、自身をサスペンド状態にする
    - 3ms以上来なかったことは割り込みとして通知されてくることが多い
- Low Speedデバイスの場合は、3msの間キープアライブ信号を受け取らないと自身をサスペンド状態にする
- ホストはハブの個々のポートごとにサスペンドのリクエストを出すことが可能


##レジューム
- ホスト起点でのレジューム状態への移行とデバイス起点でのレジューム状態への移行の2種類ある

####ホスト起点でのレジューム
- ホストは少なくとも20ms(TDRSMDN)の間、バスをレジューム状態にする
    - 実際のLinuxのHubのコントローラの実装では40msの遅延を入れているようだ
        - これは多少の規格外なデバイスにも対応するためのものでもある
    - drivers/usb/core/hub.c のusb_port_resume()関数内で遅延を入れている
- デバイスはバスがK状態になったことを検知して自信をレジュームさせる
- また、ホストコントローラとしてはデバイスのレジューム復帰に少なくとも10msは許容しなければならない(下記コード内TRSMRCYという時間のこと)

```
int usb_port_resume(struct usb_device *udev, pm_message_t msg)
{
・・・中略・・・
		/* drive resume for USB_RESUME_TIMEOUT msec */
		dev_dbg(&udev->dev, "usb %sresume\n",
				(PMSG_IS_AUTO(msg) ? "auto-" : ""));
		msleep(USB_RESUME_TIMEOUT);

		/* Virtual root hubs can trigger on GET_PORT_STATUS to
		 * stop resume signaling.  Then finish the resume
		 * sequence.
		 */
		status = hub_port_status(hub, port1, &portstatus, &portchange);

		/* TRSMRCY = 10 msec */
		msleep(10);
・・・中略・・・
}
```
- USB_RESUME_TIMEOUTの定義はinclude/linux/usb.hにある

```
/*
 * USB Resume Timer: Every Host controller driver should drive the resume
 * signalling on the bus for the amount of time defined by this macro.
 *
 * That way we will have a 'stable' behavior among all HCDs supported by Linux.
 *
 * Note that the USB Specification states we should drive resume for *at least*
 * 20 ms, but it doesn't give an upper bound. This creates two possible
 * situations which we want to avoid:
 *
 * (a) sometimes an msleep(20) might expire slightly before 20 ms, which causes
 * us to fail USB Electrical Tests, thus failing Certification
 *
 * (b) Some (many) devices actually need more than 20 ms of resume signalling,
 * and while we can argue that's against the USB Specification, we don't have
 * control over which devices a certification laboratory will be using for
 * certification. If CertLab uses a device which was tested against Windows and
 * that happens to have relaxed resume signalling rules, we might fall into
 * situations where we fail interoperability and electrical tests.
 *
 * In order to avoid both conditions, we're using a 40 ms resume timeout, which
 * should cope with both LPJ calibration errors and devices not following every
 * detail of the USB Specification.
 */
#define USB_RESUME_TIMEOUT	40 /* ms */
```
- デバイスはバスが1-15ms(TDRSMUP)の間レジューム状態になったときに自身もレジューム状態になる


####デバイス起点でのレジューム(リモートウェークアップ)
- デバイスからResume信号をバス上に出力する
- 上位のハブのダウンストリームポートがそのResume信号を検知し、バス上をK状態にする
    - この時、ハブがルートハブでない場合は、ハブのアップストリームポートポートに対してResume信号を出力する
- デバイスは一定時間(TDRSMUP)後にResume信号を停止する
    - TDRSMUPは1-15ms
- その後、上位ハブが20ms(TDRSMDN)後にResume信号を停止する

自分の理解は上記ですが間違っていたらもろもろとご指摘ください・・・
どこまでシステムの尻拭いをコードに埋め込むか

# どこまで正確性を担保したプログラムを書くのか
システムだって人が作ったものだからミスを犯す。
それは自身が手がけているシステムかもしれないし、連携先のシステムかもしれない。
システムにどこまでミスをカバーしてもらえばいいのか。。。
## 業務中に思った疑問
要件に無いところにおいて、どこまでプログラムでエラーを補えばいいの?
エラーって何？？どこまでがエラーなの？？

と混乱したことから、学んだことを初心者なりにまとめておこうと思い書きました。

## 状況
実装していて、システム間のやりとりが必要になりました。
その時下記のような状態であり、どこまでシステムでカバーするのか問題になりました。

登場人物
・システム[A|B]
・API_[b1|b2|b3]　（システムBのAPI）

システムA はシステムB に値を格納するため、API_b1, API_b2にデータを送る。
このとき片方でもエラーが返ってくると、システムAは次の動作ができない。

- 前提１（システムB について）
 - 送られたデータを整形して格納する
 - バリデーションがあり、基本的には正しいデータのみ受け付ける
 - システムA が送った値が不正な値でも登録できてしまうことがある
 - 返すエラーからは登録されているか、いないかわからない

- 前提2（エラーの対処）
 - API_b3 に問い合わせれば登録状況がわかる
 - 登録されていなければシステムA はデータを再送信する
 - 間違って登録されていた場合はアラートをあげる

- 前提3（エラーについて）
 - エラー時、簡単なデータメンテで解消することが可能
 - エラーの頻度は1か月に1回程度発生しそうである

## システムとしてあるべき姿
- 基本的には正常系のみを担保
 - 工数の削減
 - 余分なコードを書かないことから、バグを生む原因の減少
- 気づける仕組みの用意
 - エラー発生時にデータメンテができるようにする

コードを書いて網羅的なテストをする時間、エラー対応のコードを入れたことによる新たなバグ修正の時間（完璧なコードを毎回かければいいのですが...）とデータメンテにかかる時間を比べたら、（このケースの場合）簡単なデータメンテをしたほうが楽であるかと思います。
どっちにしろ、間違って登録されていた場合はデータメンテが必要なることを踏まえるとより明確です。
逆に、すべてうまくいって、失敗も起きなければ工数をかなり削減できたことになります。

## まとめ
自分への戒めのためにも書きました。
自身だけでなく納品先にも上記のやり方でいいか聞く必要はもちろんありますが、丸投げされている場合には考えるべき事象だなと思いました。
完璧主義者的考えをついしてしまい、自分の手は汚したくないから、全部システムに入れてしまえ！とつい考えてしまいそうなところです。
天秤にかけることは難しいですがこれからも経験積んでいきたいと思います。
Resources.LoadのBestPracticesの検証(3,複数回読んでみる

[Resources.LoadのBestPracticesの検証(2,使用している状態で消してみる](https://qiita.com/tessa256/items/9b1e08548038a484c98c)
の続き

---

UnityのAddComponentのつくり上、
いろんなところで複数回よばれ、いろんなところで解放
が呼ばれるはずなので軽く
2個生成して2個削除したときどうなるかを見てみる。

今回は前回のソースに

```
protected override void OnLoadComplete(Object _object)
{
	~
	Debug.Log("OnLoadComplete:" + _object.GetInstanceID() + ":" + _object.GetHashCode());
}
```

を出力してロードしたものは`違うものなのか？同じものなのか？`を見る

GameObject2個生成コンソール出力
![loadone.png](https://qiita-image-store.s3.amazonaws.com/0/354152/2c7d36b7-627a-6e6e-2d66-5ec7595a46a4.png)
GameObject2個生成プロファイラー
![loadtwo.png](https://qiita-image-store.s3.amazonaws.com/0/354152/41fa696d-720c-d5d8-5266-bbf0543dc94c.png)

GameObject1個目解放
![unloadone.png](https://qiita-image-store.s3.amazonaws.com/0/354152/2e4ba38c-5e2e-0da8-f082-e8682225483e.png)
GameObject2個目解放
![unloadtwo.png](https://qiita-image-store.s3.amazonaws.com/0/354152/74289ae4-0f4f-1d76-0de8-78d50517955e.png)

画像においては複数Resources.Loadを呼んでも読み込まれた実態は1つのように見える
解放については1個目の開放ではTextureSprite両方とも使われているので解放に失敗
2個目でSpriteは解放できたがTextureは解放できずと前回と同じ結果になった。

途中結果
`最善の方法は使わないこと`
について取得したら解放するとソースに書いても意図とした取得、解放にはならず
`メモリ管理が困難になる`
になる
まともに使うためにはかなり無駄な労力を費やしそうなのが見えてきた。
単純なだけにソースレビューするだけでなく実機確認及びProfiler確認までしないと
この部分の問題を発見することは非常に困難と見える。

Loadした分Unloadすればよいという挙動ではないのでちゃんと解放するには難儀しそうな印象。
実はResources.UnloadはResources.Loadで得たUnityEngine.Objectを引数指定すれば
解放されるものではないでは？ということも含め検証を進めていくとしよう。

解放についての検証はまた次回
firebase serve --only functions で Cannot find module 'firebase-admin' エラー

#試したこと

https://github.com/firebase/firebase-functions/issues/84

ここのやり取りに書いてあることを試しました。でもここの登場人物たちと同じようにエラーは解決しなかったです。

## nvm use v6.11.5

エラーメッセージの内容は変わらず。ただCloud Functionsと同じバージョンをつかうように促すためのWarningが一つ消えただけ。

## functions/ 内でnpm install

エラーメッセージの内容は変わらず。

## functions/ 内でnpm run build 

https://firebase.google.com/docs/functions/typescript?hl=ja

Error: Cannot find module '../lib/tsc.js'

どうすりゃええねん。

#うまくいった解決策

##functions/ 内でrm -rf node_modules/ → npm install

http://clc.gonna.jp/2017/05/npm-start-%E3%81%97%E3%81%9F%E3%82%89-error-cannot-find-module-libtsc-js-%E3%81%8C%E5%87%BA%E3%81%A6%E3%81%8D%E3%81%9F/

とりあえず動きました。

なんか、node_modulesの中身って時々壊れるみたいですね。

コンピューターがトラブったらとりあえず再起動するみたいな、そういう解決策。しばしば重要で忘れがちですね。
【メモ】データを配列に格納、シートをコピーして、配列の内容を転記。

個人用のメモ。会社で30人以上のエクセルのPC関係事務手続き用のシートを作る必要があった。

* 「設定」シートにいろいろユーザー名等が記入されている。
* これを配列に格納。
* テンプレートのシートをコピーして、必要事項を配列から転記。
* シート名は配列内に格納した「使用者名」にする。
シート名が重複していたら↓みたいに（２）といった番号をふる。
/武田/武田(2)/鈴木/本田/本田(2)/本田(3)/・・・・

範囲を配列にする自作関数（Range2Array）、重複するシートの数を返す関数（Count_Duplicate）は他の場面でも使えるかなと思いました。

```vb

'★メインプロシージャ
Sub 設定シート作成()
'●設定シートのデータを配列に格納
Sheets("設定").Select
array_user = Range2Array(4, 9) '①自作Range2Array関数
'●配列の列
'1：ID
'2：使用者
'4：ユーザー名これがEmptyだったら転記しない
'5：所属
'7：モデル
'8：●●ソフト使用1 or 0
'9：▲▲ソフト使用1 or 0


For array_i = 1 To UBound(array_user)
    If array_user(array_i, 4) <> Empty Then '配列の「4:ユーザー名」が空でなければ以下実行。
    '●テンプレシートをコピーし、シート名を「2:使用者」に変更。
        Copy_Sheet (array_user(array_i, 2)) '②プロシージャ
    '●配列を新シートに転記
        Cells(4, 3) = Date
        Cells(5, 3) = "シート作成者"
        Cells(8, 9) = "新規"
        Cells(9, 9) = array_user(array_i, 7) '7：モデル
        Cells(10, 9) = array_user(array_i, 5) '5：所属
        Cells(11, 9) = array_user(array_i, 2) '2：使用者
        Cells(12, 9) = array_user(array_i, 4) '4：ユーザー名
        Cells(13, 9) = "Win10" 'OS
        Cells(14, 9) = array_user(array_i, 1) & ".id" '1：ID
        Cells(17, 9) = "Printer-3" '以下、プリンター名。
        Cells(18, 9) = "Printer-4"
        Cells(19, 9) = "Printer-5"
        Cells(20, 9) = "Printer-6"
        Cells(21, 9) = "Printer-7"
        '●●ソフト使用と▲▲ソフト使用にレ点(機種依存文字・文字コード)
        If array_user(array_i, 8) = 1 Then Cells(15, 9) = ChrW(&H2713)
        If array_user(array_i, 9) = 1 Then Cells(16, 9) = ChrW(&H2713)
    End If
Next
End Sub
```

```vb


'①範囲を配列にする関数（開始行、開始列）→2次元配列
Public Function Range2Array(begin_row As Long, begin_column As Long) As Variant
    last_row = Cells(begin_row, begin_column).End(xlDown).Row '終端行
    last_column = Cells(begin_row, begin_column).End(xlToRight).Column '終端列
    
    Range2Array = Range(Cells(begin_row, begin_column), Cells(last_row, last_column))
End Function


```
```vb
'②templateをコピーして、新規シート作成し、シート名変更（ユーザー名）
Public Sub Copy_Sheet(user_name As String)
Worksheets("テンプレート").Copy After:=Worksheets(Worksheets.Count)
N_Duplicate = Count_Duplicate(user_name) '③関数使用。重複してるシート名に(重複数)つける。
If N_Duplicate > 1 Then
    ActiveSheet.Name = user_name & "(" & N_Duplicate & ")"
Else
    ActiveSheet.Name = user_name
End If
End Sub
```


```vb
'③これから作成するシート、既にあるシート含めて何個同じ名前のシートあるかを返す。
Public Function Count_Duplicate(user_name As String)
Dim N_Duplicate As Integer
N_Duplicate = 1 '初期値はNは1
For i = 1 To Worksheets.Count
    If Sheets(i).Name = user_name Then
        N_Duplicate = N_Duplicate + 1 '重複あればNを1増やす。
    End If
Next i
Count_Duplicate = N_Duplicate
End Function
```

```vb
'★やり直してシート消すプロシージャ
Sub テンプレと設定以外のシート削除()
Application.DisplayAlerts = False
    For sheet_i = Worksheets.Count To 1 Step -1
        If Worksheets(sheet_i).Name = "テンプレート" Then 'テンプレートシートは消さない
            GoTo Continue
        End If
        
        If Worksheets(sheet_i).Name = "設定" Then '設定シートは消さない
            GoTo Continue
        End If
    Worksheets(sheet_i).Delete
Continue:
    Next sheet_i
Application.DisplayAlerts = True
End Sub
```
メモ:flutter_local_notificationsを使用した時に出た「android:attr/fontVariationSettings not found.」の解決

# 事の起こり
- flutterを開発中に[flutter_local_notifications](https://github.com/MaikuB/flutter_local_notifications)を使うためにパッケージロードするようにしたら、build errorが出るようになった。

```
error: resource android:attr/fontVariationSettings not found
```

# 結論
- androidの`build.gradle`に記載されている`compileSdkVersion`の設定を28以上（build errorが出た時は27だった）にする事で解決できた。

```:android/app/src/build.gradle
android {
    compileSdkVersion 28
```

- 結果としてはflutter_local_notificationsは別に関係なかった。

# 説明
- [fontVariationSettings](https://developer.android.com/reference/android/R.attr.html#fontVariationSettings)という変数は`API 28`から追加されたもので、それ以前のAPIでは使えない。（android APIのドキュメントにも`added in API level 28`と記載されている）
- `compileSdkVersion`というのは、コンパイル時に使うandroid APIのversion設定。これが古すぎると使えないpackageなどがある。
- `compileSdkVersion`は最新版にしておくことが公式で強く推奨されている。パフォーマンスチューニングなども考えると正しいことだが、非推奨APIなどをどうしても使う必要がある場合は注意が必要だろう。
- API28はandroid9（pile）なので2019/01時点での最新版。

# 参考
- [Out of Dimension: Android アプリの後方互換性と前方互換性](http://extra-vision.blogspot.com/2016/09/android-compilesdkversion-minsdkversion.html)
- [error: resource android:attr/fontVariationSettings not found - Stack Overflow](https://stackoverflow.com/questions/49208772/error-resource-androidattr-fontvariationsettings-not-found)
- [compileSdkVersionはどのバージョンを選択すべきなのか調べた話 | AdSheep](https://adsheep.net/compilesdkversion/)
- [Android 9 の機能と API  |  Android Developers](https://developer.android.com/about/versions/pie/android-9.0)
Resources.LoadのBestPracticesの検証(2,使用している状態で消してみる

[Resources.LoadのBestPracticesの検証(1,ロードとアンロード](https://qiita.com/tessa256/items/05bec7892657b2afa9d0)
の続き

---

前回のResourcesLoader.csを継承して実際に呼んだものを
描画した状態で消したらどうかを見てみる
今回使用するソースは

```cs:ResourcesLoadSprite.cs
using UnityEngine;

public class ResourcesLoadSprite : ResourcesLoader
{
	[SerializeField, Header("表示するSpriteRendererを指定")]
	private SpriteRenderer TargetRenderer;

	protected override void SetLoadObjectType()
	{
		LoadObjectType = typeof(Sprite);
	}

	protected override void OnLoadComplete(Object _object)
	{
		base.OnLoadComplete(_object);

		TargetRenderer.sprite = _object as Sprite;
	}
}
```

ざっくり挙動は
０．SetLoadObjectTypeはResource.Loadが型を指定しないと一部情報が飛ぶので引数で与えているデータ型
１．ロードが完了したら指定した描画コンポーネントにSpriteを渡す。

前回と比べて`実際に描画している状態`でよりアプリ内で使われているのに
近い状態にしてみた。

GameObject生成
![load.png](https://qiita-image-store.s3.amazonaws.com/0/354152/b396c368-a40f-f9f0-59ec-fa8b87b66a00.png)
GameObject削除
![unload.png](https://qiita-image-store.s3.amazonaws.com/0/354152/883dcf37-5caa-2c4d-e93d-9929525ae7aa.png)

Texture2Dは使用されているため解放できなかったのはわかるが
Sprite情報は解放されてしまった。

[続く](https://qiita.com/tessa256/items/ae5cc80aa0a5d6306858)
Rubocop Airbnbの導入

#はじめに
Rubocop Airbnbを導入したので、手順をメモします。

#Rubocopとは
Rubocopは書かれたコードがRubyのコーディング規約に沿った書かれ方をしているかを自動的に確認してくれるgemです。

#Rubocopではなく、Rubocop Airbnbを導入する理由
Rubocopはデフォルト設定だと自分で設定を変更する必要があるとのことなので、airbnbの開発で使用されているrubocopの設定をインストールできるRubocop Airbnbを導入することにしました。

#Rubocop Airbnbの導入手順
基本的に[Rubocop Airbnb](https://github.com/airbnb/ruby/tree/master/rubocop-airbnb)の手順に従いました。

###Gemfileにgemを追加
gemを追加したら、bundle installします。

```ruby:Gemfile
group :development do
  gem 'rubocop-airbnb'
end
```
###Rubocop-airbnbを適用させるアプリファイルに、rubocop.ymlとrubocop-airbnb.ymlを作成し、それぞれ内容を記載
rubocop.ymlの内容は必要に応じて適宜変更してください。

```ruby:rubocop.yml
 inherit_from:
  - .rubocop_airbnb.yml

 # Rails用に最適化
 Rails:
   Enabled: true

# 文字数の上限を８０文字から変更
LineLength:
  Max: 130

 #rubocopで検証したくないフォルダを指定
 AllCops:
   Exclude:
     - 以下省略
```
```ruby:rubocop-airbnb.yml
 require:
   - rubocop-airbnb
```

###実行
設定が完了したら、`bundle exec rubocop --require rubocop-airbnb`で実行します。

以上で終了です。
ゼロから始めるPowerShell生活

#はじめに
Microsoft PowerShellのご紹介です。

#PowerShellとは
"Microsoft"が提供するWindows標準搭載のCLI(Command Line Interface)シェルおよびスクリプト言語です。
つまりプログラム言語のひとつですが、Microsoftが提供していることもあり、強力かつ簡潔なツールです。

#なぜPowerShellか
私もいろいろな恩恵をPowerShellから受けていますが、以下のようなシチュエーションで「PowerShell」を選択します。
・***Powershellのほうが簡潔にプログラムを書ける場合***
  --> (e.g: パイプライン[Pipeline]を利用してファイル単位で簡単にエンコードができる。）
・***Powershellでのみ操作できる内容である場合***
  --> (e.g: システム管理者権限でWindowsのほぼ全機能が利用できるようです。「Get-WMIObject」コマンドレットを利用して、Windowsのアプリケーション情報の取得もできるなど。）
・***他のプログラムですぐに解決できない問題があり、時間がない場合***
  -->(e.g: C++言語で記載すると大げさになる処理、例えばcurlコマンドでデータをPOSTやGETする場合）


#環境準備
PowerShellが標準で搭載されているOSは下記の通りです。
・Windows Server 2008 R2以降 (以下を含む：2012, 2012 R2, 2016, 2019)
・Windows7以降 (以下を含む：8 , 8.1, 10)


■キーボードの[Windows]ボタンを押下して「Powershell」と入力します。
その上で「Windows PowerShell ISE」にカーソルを合わせて、右クリックで「管理者権限で実行」を選択します。

***このアプリがデバイスに変更を加えますが許可しますか？と聞かれたら「はい」を選択します。***

![image.png](https://qiita-image-store.s3.amazonaws.com/0/356673/a34c755b-e11f-7d93-d94b-aa44e2aaa202.png)


■Windows PowerShell ISEを起動します。
①：プログラムファイル編集部分（ファイルとして保存）　②：コマンド実行部分
![image.png](https://qiita-image-store.s3.amazonaws.com/0/356673/dbd7ca04-3586-33a9-db7b-c4f64f8ab1da.png)

■セキュリティエラーを回避するため、PowerShellの実行ポリシーを変更します。

***②コマンド実行部分***

STEP1：***「Get-ExecutionPolicy」***と入力し、初期設定を確認します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/356673/fd54eea1-31f4-b2dc-6a5e-bd5182b5c703.png)
STEP2：***「Set-ExecutionPolicy RemoteSigned」***と入力し、設定を変更します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/356673/10295c35-5173-a32f-d259-2ca0b902d737.png)
STEP3：***「Get-ExecutionPolicy」***と入力し、設定変更を再確認します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/356673/4fcbf9ac-3821-5835-95ec-b748fd5dfe05.png)


#サンプルコード
①：プログラムファイル編集部分にコードを記載して実行する。

```
Write-Host "Hello, World"
```
これで正しい実行結果が出力されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/356673/2a286479-c068-8fd3-f2cc-09968ce66d0a.png)
侍エンジニアの広告を自作Chrome拡張機能で消す

## 作成経緯
侍エンジニアの記事にはうんざりしてしまっていることだろう。
そして、検索から侍エンジニアを消す...
##### 本当にそれでいいのか？
個人的に初級者にはわかりやすい内容になっていると感じる。
##### 「広告なしで必要な部分だけ見たい...」
というのが率直な気持ちだ。
@thr3aさんの以下の記事を見つけた
[爆速でChrome拡張機能を作成する](https://qiita.com/thr3a/items/702e58f5d793332a1001)
これを使えばCSSを書き換えて、いい感じの情報閲覧サイトへ変えられそう！

## 概要
[Sarumrai Blocker](https://github.com/SunSki/samurai_blocker)
github上に置いてあるコードをChromeに読み込ませれば終わりだが、簡単に何をやっているのか説明していきたい。
contentscript.jsをちょっと書き換えているだけで、jQueryの基本さえわかればすぐできる。
chrome拡張機能については[爆速でChrome拡張機能を作成する](https://qiita.com/thr3a/items/702e58f5d793332a1001)を見るべし。

```javascript
$(function () {
    //jQueryでCSSを変更する
    $('.main-header').remove();
    $('header').html('<h1>さむらいえんじにあ!</h1>');
    $('aside').remove();
    $('div.header-sticky').remove();
    $('footer').remove();
    $('.fade-in').remove();
    $('.eye-catch-content-wrapper').remove();
    $('.mbt-border-top').remove();
    $('.vce-related-box').remove();
    $('.p-entry_push').remove();
    $('.wp_social_bookmarking_light').remove();
    $('blockquote').remove();

    var id = Number.MAX_SAFE_INTEGER;
    $('#text,span,p,h5,div,ul,a').html(function (index, element) {
        if (element == 'まとめ') {
            id = index;
        }
        if (index >= id) {
            return '';
        }
    });
});
```
まず、.remove()して不要な要素を削る。
侍エンジニアのサイトがwordpress使ってコーディングサボっていて、要素がついていない部分があるので、そこが指定しにくい。
共通して"まとめ"というワードの下に不要な情報が突っ込まれているので、"まとめ"以下の記述を表示させなくする。しかし、何も囲まれていないテキストがちょっとあるので完全に消せはしない...

## あとがき
もっとやり方があると思うし、アップしたコードも全然改善の余地があると思う。
これから、うざいサイトを見つけたらどんどんいい感じに加工していきたい。
<img width="1363" alt="スクリーンショット 2019-02-11 16.43.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/214664/f7bb5193-aea9-14e6-5ffa-327750fa3fb2.png">
初めてのプログラミング

#初めてのプログラミング
[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしているaluku0807です。
今日はパソコン全般苦手な私がプログラミングを始めてすぐ知識などをアウトプットする内容はたいしたことないですが、今回は初めてhtmlとcssに触れて学んだことを発信していきます。ただ素人なので間違いがあればどんどん指摘して下さい。

## HTMLについて

**HTMLとはウェブサイトの文章構造を書いたもの**
私がHTMLで一番苦戦したことは終了タブがどこに行ったか分からなくなることです。コードを書くときdivタブをよく使うのでどこのdiv終了タブかわからなくなることが多々ありました。
またimgタブには終了タブがいらないことは覚えておきましょう。

##CSSについて
**CSSとはHTMLで書いたもののレイアウトを整えるもの**

そうです。いくらHTMLでいい文字を起こしたからと言っても、レイアウトが整ってなかったらダサいです。そのためにCSSでレイアウトを整えていきます。きれいなホームページを作る際にはCSSの技術が欠かせません。
CSSでは文字の大きさを変えたり、高さ、幅、背景の色などいろいろなところを変化させることができます。しかしそれをするには、そのためのfont-size,
height,width,background-colorなど様々なプロパティを覚えなければなりません。


##最後に
今回はHTMLとCSSについて私なりにアウトプットしてみました。まだまだ基礎が固まっていない段階なので復習を繰り返していきます。
HTMLとCSSの段階でで苦戦中なので、同情してくれる方はぜひご連絡下さい。
これからも続けいていきます。
データ分析関連（データサイエンス、データ分析、機械学習）書籍マップ Ver.1.00

[データサイエンス、データ分析、機械学習関連の本](https://qiita.com/aokikenichi/items/ae4df263f591e47528a6)に書籍を付け足してますが、読んでいく順番がわからないので、マインドマップを用いて前後（上下）関係を図にしてみました。
ツッコミどころ満載と思いますので優しく教えてくださいな。

+ おことわり
    + ごめんなさい。一部読んでいない本もあります。
    + 数学と機械学習系のつながりがふわふわ。
    + 私が、基礎から順に読み進めるよりも、同時並行で乱読多読（精読していない）しているのでもっと王道なラインがあるかも。
        + でもWebに見当たらないので書きました。
+ 使い方
    + 端から中央に読み進めるというよりも、書きな感じです。
        + ある本が分からなかったらその前提知識が怪しいので、
            + 図の端の方の本にトライしてみる。
            + （別の説明がある）横並びの本にトライしてみる。
        + ある本をマスターしたら中央に向かってみる。
+ 1冊ずつの紹介は別記事に書いてます。
    + [データサイエンス、データ分析、機械学習関連の本](https://qiita.com/aokikenichi/items/ae4df263f591e47528a6)
        + [SE, PG系の方がデータ分析、機械学習をやる必要が出た時にまず手にとるべき一冊](https://qiita.com/aokikenichi/items/fb1bb3d8e872af9139ec)
        + [データサイエンス、データ分析、機械学習に必要な数学](https://qiita.com/aokikenichi/items/4d683dc5774f844f8113)
    + [データサイエンス系気になる近刊書籍](https://qiita.com/aokikenichi/items/ff22e792c3da0f1781d6)

![データ分析.png](https://qiita-image-store.s3.amazonaws.com/0/116049/20dc0c2d-6e57-afbf-8dc8-9bd32fb1bc26.png)
Resources.LoadのBestPracticesの検証(1,ロードとアンロード

今回のUnityバージョン
*Unity 2018.3.5f1*

---

https://unity3d.com/jp/learn/tutorials/topics/best-practices/resources-folder
Unity公式のチュートリアルより要約
・最善の方法は使わないこと
・メモリ管理が困難になる
・アセットの管理が非常に難しくなる
・配信機能の低下
・プロトタイプを迅速に制作するには優れているが、製品版では排除する必要がある
・リソースフォルダ以下のAssetはシリアライズされる

次の場合は便利に使える
・プロジェクトの存続期間を通して一般的に必要
・メモリ集約型ではない
・パッチを適用する傾向がない、またはプラットフォームやデバイス間で差がない
・最小限のブートストラップに使用

とあるがなにより
・最善の方法は使わないこと
とはどういうことなのか？

簡単に下記ソースコードを書いて検証してみた

```cs:ResourcesLoader.cs
using System.Collections;
using UnityEngine;

public class ResourcesLoader : MonoBehaviour
{
	protected System.Type LoadObjectType;

	[SerializeField, Header("ResourcesLoadのPathを指定")]
	private string ResourcesLoadPath;

	private UnityEngine.Object Asset;

	private void Awake()
	{
		SetLoadObjectType();
	}

	private IEnumerator Start()
	{
		var request = Resources.LoadAsync(ResourcesLoadPath, LoadObjectType);

		yield return request;

		Asset = request.asset;
		OnLoadComplete(Asset);
	}

	private void OnDestroy()
	{
		if (Asset != null)
		{
			Resources.UnloadAsset(Asset);
			Asset = null;
		}
	}

	protected virtual void SetLoadObjectType()
	{
		LoadObjectType = typeof(Object);
	}

	protected virtual void OnLoadComplete(Object _object)
	{
		;
	}
}
```

ざっくりどんな挙動をするかというと
１．GameObjectが生成されたらResourcesLoadPathに設定されているPathでリソースの非同期読み込みを行う
２．ロードが完了したらOnLoadCompleteが呼ばれる
３．GameObjectが削除されたらResources.UnloadAssetを呼ぶ

で検証の前にカメラだけがあるSceneにおいてAssetがどうなってるか
ProfilerでMemoryの項目をDetailed表示でAssetのSampleを取っておく
![before.png](https://qiita-image-store.s3.amazonaws.com/0/354152/1b36ccb3-4a20-59bd-f67d-9a7cf0dd791f.png)
適当にGameObjectを作ってAddComponentし、test.pngを読み込んだのが
![load.png](https://qiita-image-store.s3.amazonaws.com/0/354152/94e6936a-3722-a620-3fdb-fe7d3ac3522d.png)
PrefabやらTransformやらMonoBehaviourなど増えているがLoadに関係するもののみ開いておく
そしてGameObjectを削除したら
![unload.png](https://qiita-image-store.s3.amazonaws.com/0/354152/63f8673d-487d-ac3a-3af6-72b8ed1f803a.png)

画像データのロードにおいてはSprite情報は解放されず
Texture本体のみ解放されてしまったように見える。

ソースコードではリソースのAssetを読んで消したから関連するものは
消したつもりだったが完全に消し去ることはできなかったようだ。

[続く](https://qiita.com/tessa256/items/9b1e08548038a484c98c)
[PHP]MacにComposerをインストールしよう。

![composer.png](https://qiita-image-store.s3.amazonaws.com/0/278346/04865d88-2c9a-7698-b193-0f83ac942301.png)
PHPを扱うものとしてはComposerは必須ですよね。
インストール方法を簡単ですがまとめました。
#+Composerって？
PHPのパッケージ管理ツールのことです。
CakePHPやLaravelなどのフレームワークであったり、Githubなどで公開されている便利なパッケージ（メール操作・ファイル操作など）を一元管理してくれます。
違う環境で作業を行うときなど、コマンドを叩くだけですべてのパッケージを一括でインストールできます。
#+事前準備
- パソコン：MacでもWindowsどちらでもOK。
- PHP：バージョン5.3.2以上 ※MAMPでサクッとインストールした方が簡単。

※ PHPのインストール確認
1.Macのターミナル or Windowsのコマンドプロンプトを立上げる。
2.以下のコマンドを入力する。

```
$ php -v
```

3.こんな感じでバージョンが表示されるとOK。

```
PHP 7.1.12 (cli) (built: Nov 27 2017 15:53:40) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies
```

#+インストール
1.インストールしたいディレクトリに移動する。

```
$ cd インストールディレクトリ
```
2.インストール用コマンドを入力

```
$ curl -sS https://getcomposer.org/installer | php
```
これで、ディレクトリ内に 「composer.phar」 が作成されればインストール完了です。
このファイルを実行することでcomposerを利用できます。

また、パスを通すことでグローバルに実行できます。
パスを通すには以下の様にパスが通ったディレクトリ(/usr/local/bin/)に移動してください。

```
$ mv composer.phar /usr/local/bin/composer
```

※ homebrewでのインストールは以下にサクッとまとめています。
[[PHP]MacにhomebrewでComposerをインストールしよう。](https://qiita.com/kumapeta/items/bded1c57ee36613e9cb4)

#+確認
1.composerコマンドを入力

```
$ composer
```
2.こんな感じでバージョンが表示されるとOK。

```
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 1.6.5 2018-05-04 11:44:59
Usage:
  command [options] [arguments]
```
[PHP]MacにhomebrewでComposerをインストールしよう。

![composer.png](https://qiita-image-store.s3.amazonaws.com/0/278346/04865d88-2c9a-7698-b193-0f83ac942301.png)
PHPを扱うものとしてはComposerは必須ですよね。
homebrewでのインストール方法を簡単ですがまとめました。
#+Composerって？
PHPのパッケージ管理ツールのことです。
CakePHPやLaravelなどのフレームワークであったり、Githubなどで公開されている便利なパッケージ（メール操作・ファイル操作など）を一元管理してくれます。
違う環境で作業を行うときなど、コマンドを叩くだけですべてのパッケージを一括でインストールできます。
#+事前準備
- パソコン
- PHP：バージョン5.3.2以上 ※MAMPでサクッとインストールした方が簡単。

※ PHPのインストール確認
1.Macのターミナル or Windowsのコマンドプロンプトを立上げる。
2.以下のコマンドを入力する。

```
$ php -v
```

3.こんな感じでバージョンが表示されるとOK。

```
PHP 7.1.12 (cli) (built: Nov 27 2017 15:53:40) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies
```

#+インストール
1.homebrewでComposerを検索する。

```
$ brew search composer
```
こんな感じで表示されればOKです。

```
==> Formulae
composer
```

2.インストール用コマンドを入力

```
$ brew install composer
```
以上でインストールは完了です。

#+確認
1.composerコマンドを入力

```
$ composer
```
2.こんな感じでバージョンが表示されるとOK。

```
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 1.6.5 2018-05-04 11:44:59
Usage:
  command [options] [arguments]
```
Windows 10 Pro x64 + Python3 で Jsonファイルの読み書きを試してみる

#目的
参考サイトでjsonデータを取得後、ファイルに書きこんだ後、読み込んでみる
※まずは基本的な読み書きを確認
※自分用の確認メモ
## サンプルコード
PS > python -V
Python 3.7.2
組み込み関数：openで指定可能なモード
'r':読み込み用に開く (デフォルト)
'w':書き込み用に開き、まずファイルを切り詰める(上書？)
'x':排他的な生成に開き、ファイルが存在する場合は失敗する
'a':書き込み用に開き、ファイルが存在する場合は末尾に追記する
'b':バイナリモード
't':テキストモード (デフォルト)
'+':ディスクファイルを更新用に開く (読み込み／書き込み)

```python
# Windows Add env PYTHONIOENCODING = UTF-8 & restart vscode

import http.client
import json

# 表示するユーザ名
USER_ID = "tabizou"
# ユーザの投稿数
ITEM_NUM = 10
# ページ番号 (1から100まで)
PAGE = "1"
# 1ページあたりに含まれる要素数 (1から100まで)
PAR_PAGE = "100"

conn = http.client.HTTPSConnection("qiita.com", 443)
conn.request("GET", "/api/v2/users/" + USER_ID + "/items?page=" + PAGE + "&per_page=" + PAR_PAGE)
res = conn.getresponse()
print(res.status, res.reason)

data = res.read().decode("utf-8")
#----------追加---------------------------------------
print(type(data))

# json ファイルの書き込み
with open('qiita.json', 'w', encoding='UTF-8') as f:
    for chunk in data:
        f.write(chunk)
    print("書き込み終了")

conn.close()

# json ファイルの読み込み
with open('qiita.json', 'r', encoding='UTF-8') as f:
    jsonstr = json.load(f)

print(type(jsonstr))
#----------追加---------------------------------------
print("==========================================================")
# ヘッダ出力
print("\"no\",\"created_at\",\"tile\",\"url\"")

# 投稿数を指定
for num in range(ITEM_NUM):
    created_at = jsonstr[num]['created_at']
    tile = jsonstr[num]['title']
    url = jsonstr[num]['url']

    # ダブルクォートありCSV形式で出力
    print("\"" + str(num) + "\",\"" + created_at + "\",\"" + tile + "\",\"" + url + "\"")

print("==========================================================")
```
##参考にしたのは以下のサイト
[Qiita API v2 を使って投稿一覧を取得する](https://qiita.com/fkooo/items/250f42a0b641fb96b5ff)
[json --- JSON エンコーダおよびデコーダ](https://docs.python.org/ja/3/library/json.html)
[7. 入力と出力](https://docs.python.org/ja/3/tutorial/inputoutput.html)
[組込関数：open](https://docs.python.org/ja/3/library/functions.html#open)
Nutanix CEでクラスターを組む時に引っかかったこと

#初めに
シングルノードクラスターの状態でインストールした後に、マルチノードクラスターを組んだ時にはまったので、そのメモ書きな感じです。

#CEのセットアップ終了後
SSHでCVMに入る

#クラスター作成
```
cluster -s ipaddress1,ipaddress2,ipaddress3,ipaddress4 create
```
ipaddress1,2,3,4は各ノードのCVMのIPアドレス

#クラスターの起動(？)
```
cluster start
```

#そのあとにやっておいたほうがいい設定
クラスター名編集

```
ncli cluster edit-params new-name=付けたいクラスター名
```
DNSサーバー編集

```
ncli cluster add-to-name-servers servers=DNSサーバーのIP(8.8.8.8など)
```
クラスターのIP

```
ncli cluster set-external-ip-address \
 external-ip-address=クラスターにアクセスしたいIPアドレス
```

#電源を落とすとき
クラスター停止

```
cluster stop
```
CVMを落とす

```
cvm_shutdown -P
```
AHVを落とす

```
shutdown -h now
```
本当はどこかでメンテナンスモードにしないといけないんですが...

#再度電源を入れる時
電源を入れて、クラスターを組んだどこかのCVMにSSHで入り

```
cluster start
```
起動したらクラスターのIPでログイン
(自動でやってくれないんですよ...)

#シングルノードクラスター→マルチノードクラスターにしたときはまったポイント
シングルの時はCVMにすぐアクセスすればPrismが見れたけれども、クラスターは基本クラスのIP
なので、クラスターを組まないと入れないし、セットアップが終わっただけじゃPrismは見れない

#参考サイト
[鼻からミルク氏のスライド](https://www.slideshare.net/detteiu/nutanix-ce-multi-node)

[Nutanix公式portal](https://portal.nutanix.com/#/page/docs/details?targetId=Nutanix-Community-Edition-Getting-Started:com-cluster-config-multinode-manual-ce-t.html#ntask_dbk_n3h_fr)

#使用している機材
X8DTT-HF+ 4ノード
Xeon E5520 2.26GHz *2
48GB (4GB×12)

SSD1(起動用)中古の120GBのSSD
SSD2(Hot tier)cssd-s6o480cg3vp
HDD(Cold tier)ST9250610NS
それぞれ4ノード分
ケースは2028TP-HTRと同じもの

メモリ増やしたいっすねぇ
あとノードごと入れ替えしたいです。SASのHDD使えないので。(ケース目的で買いました)

調べて知ったのですが、2U4nodeのタイプでLSIのチップが乗っているものはケースとの接続する基板に搭載されているんですね。
私のものは載っていないタイプなので、なんでSASのドライブが使えないのかが最初わからなかったです。

余談ですが、SuperMicroで統一して使うならばIPMI ViewというSuperMicro純正ツール使うと管理は楽です。
XPぐらいから多分アップデートされてないツールなので色々古いですが10でも動きます。
素材リンク

何か毎回探してるなとなったので、自分用にまとめ。
随時追記しますが、なんとなく使いづらい、使いづらそうみたいなのは除外していきます。
まとまってきたらカテゴリ別に分ける予定。

# サービス
## [Toreru](https://search.toreru.jp/)
商標検索

# アイコン
## [Font Awesome](https://fontawesome.com/)
そのうち使ってみた感想を書く。

## [Material Design](https://material.io/tools/icons/?style=baseline)
アイコン専用ではなく、マテリアルデザインのガイドラインの中で提供される[ツール](https://material.io/tools/)の一つ。
他にもマテリアルデザインの見本を見ながらカラー選んだりもできる。

# 色選び
## [HUE/360](http://hue360.herokuapp.com/)
一色選ぶと、近似色、補色などの色を適当に絞ってくれる。

## [Adobe Color CC](https://color.adobe.com/ja/create/color-wheel/)
同じく色の選択をサポート。

## [COLOR SUPPLY](https://colorsupplyyy.com/)
同じく色の選択をサポート。
アイコンなどの使用例で選択した色の使用感を確認できる。

## [Accessible Brand Colors](https://abc.useallfive.com/)
選んだ色の視認性を確認

## [Khroma](http://khroma.co)
AIによるパレット作成。考えずにいくつかのパターンから選べるのはいいかも。

## [Colors](http://clrs.cc/)

# Photo

## [Pexel](https://www.pexels.com/)

## [Unsplash](https://unsplash.com/)

# Font
## [google fonts](https://fonts.google.com/)
Googleフォント

# ダミーテキスト
## [Lorem ipsum](https://www.lipsum.com/)
英語

## [‎すぐ使えるダミーテキスト](https://lipsum.sugutsukaeru.jp/)
日本語

## [組見本用創作文『問わずがたりの洋酒外史』](http://www.type-labo.jp/Kumimihon.html)
日本語

# Font選び
## [Google Fonts + 日本語](https://googlefonts.github.io/japanese/)
日本語サンプル。
何気に見せ方も好きです。

## [ためしがき](https://tameshigaki.jp/)
フリーフォント選び。

# 方針、チェックリスト
## [Check List Design](https://www.checklist.design/)
よく利用されるコンポーネント毎のチェックリスト

# Link
## [Awesome Design Tools](https://flawlessapp.io/designtools)
もうちょっとちゃんとしたToolのリンク集？

### (https://www.evernote.design/)
LookingGlassの技術的複数運用について

#公式SDK(1.0.0)に実装されました！！公式を使いましょう！！

#先まとめ
現SDKでは一台目のパラメータしか読まないので
2台目以降はレンチキュラーが正常に作動しないので
コードに若干手を入れました。

---

#前提環境（デメリット）
・LookingGlassを複数台所有していること
・SDKのアップデートを待っていられない人向け（そのうち実装される）
・複数台映せるグラボパワーがあるPC環境

---

#メリット
・縦に並べるとキャラクターの半身以上を大きく映せる
・LookingGlassは縦方向は一視点だが2台並べると”なんか”気にならない
・横に並べるとキャラの移動がなんか新鮮

---

#技術的お話
##現状の仕様
・LookingGlassのEEPROMからそれぞれ固有のレンチキュラーのパラメータを読んで
　立体視用に変換している。それぞれパラメータはバラバラ。
・現在のコードでは”一台目”のパラメータしか読んでいない。

---

```EEPROMCalibration.cs(改造版)
（中略）
private static int rw(中略)
       {
（中略）
           hid_device_info enumerate = (hid_device_info)Marshal.PtrToStructure(ptr, typeof(hid_device_info));
           string epath = enumerate.path;

           //ここから追加
           for (int k = 0;k < TargetDisplay; k++)
           {
               hid_device_info enumerate_Multi = (hid_device_info)Marshal.PtrToStructure(enumerate.next, typeof(hid_device_info));
               epath = enumerate_Multi.path;
           }
           //ここまで追加
           IntPtr handle = HIDapi.hid_open_path(epath/*enumerate.path*/);//epathを読むように変更
```

---

・hid_device_info enumerateがEEPROMのアドレスを持っているので2台目以降の時は
　enumerate.nextで次のアドレスを引っ張って来て情報を取得するように変更。（next==0で最後フラグ）
　2台目以降フラグはunityのTargetDisply番号を渡すようにしました。（ここは設計次第）
※unityでマルチディスプレイを行うときは『Display.display[X].Activate();』が必要です。

---

#最後に
・公式SDKで複数台対応されるのが待ちきれない人用です。
・LookingGlassを複数台持っていて、かつ複数台に描画できるPCを持っている人用です。
・複数台で縦に並べて好きなキャラクターをドアップで見たい人用です。

---

#おまけ
LookingGlassのパラメータはコードをイジらずともインスペクターから
いじれます。[こちら](https://qiita.com/koukiwf/items/3d2db86846944af857b9)
IntelliJ IDEA＆GradleでServlet/JSP

#はじめに

IntelliJ IDEA/Gradle で Servlet/JSP を「とりあえず」動かすにはどう環境を整えたらいいのか分からず。
先人の知恵をコピペしてできましたのでご報告。先人の皆さま、ありがとうございます。

今回作った環境は以下のとおりです。

- Gradle 5.1
- Apache Tomcat 8（Servlet 3.1）
- JDK 1.8

#Tomcat8 を動かす

まず、普通に Java/Gradle でプロジェクトを作ります。
出来上がったプロジェクトの build.gradle を以下のサイトの出来上がり品でまるっとコピペしました（見出し「実行方法」の手前です）。
Tomcat 8 の場合のスクリプトとなります（一番下に Tomcat 9 への対応についても書かれています）。

Qiita : [@Kakkyさま](https://qiita.com/Kakky)
[IntelliJ Community で Tomcat の実行環境を整備する](https://qiita.com/Kakky/items/27fa8940016428ee71f6)

これでタスクから appRun すると数分でもろもろ取り込んでくれてサーバーが起動します。
ルートの URL は localhost:8080/<プロジェクト名>/ です。

#ファイルの配置

IntelliJ IDEA では Ultimate Edition じゃないと諸々やってもらえませんので、自分でフォルダを作りファイルを置きます。
と言っても（結果的には）そんなに難しいことはないです。 src/main 下に webapp フォルダを作ります。

- src/main/java下に .java（Servlet）
- src/main/webapp下にその他ファイル（HTML や JSP ファイルなど。 WEB-INF もここに作ります）

なお、 web.xml は Servlet3.1 用に DTD/XSD 宣言を用意します。以下のサイトの下の方にあった記述をコピペさせていただきました。

Qiita : [@shinyayさま](https://qiita.com/shinyay)
[IntelliJ IDEA を使って Web アプリケーションを Tomcat へデプロイしてみた](https://qiita.com/shinyay/items/a3561bae8f0b1804bbb4)

この辺りを作成・修正していると、自動的に Tomcat が再起動します。書きかけだと Exception が出ますが、構わず書き続けます。
これで、 HelloServlet や hello.jsp を作って叩いて喜びます（この辺りは他の入門サイトにもソースがあるので・・・）。

JSP の場合は上記サーバールートで、Servlet ではサーバールート＋マッピングでURLとなります。
マッピングで /greet としたら、URLは、localhost:8080/<プロジェクト名>/greet です。

以上です！リンク先の方、ありがとうございました！！