OmniAICreator/Qiita-1.07M huggingface dataset:
VScodeでReact開発環境構築

#はじめに
Macを買い換えたときに、いろいろ忘れていたので備忘録も兼ねて書いていきます。
以下の良記事を参考にしていますので詰まった場合はこちらも読んでみてください。

[nvm + Node.js + npmのインストール]
(https://qiita.com/sansaisoba/items/242a8ba95bf70ba179d3)
[create-react-appでyarn startできない(できた)](https://qiita.com/hppRC/items/4c09c1f33135a40870bd)

動作環境
- macOS Catalina 10.15.5
- node.js 12.18.0
- Visual Studio Code 1.45.1
#nvmのインストール

はじめにnvmのインストールをします。
nvmとはNode.js のバージョンを切り替えて使うことを可能にするツールのことです。
[nvmのGithubはこちら](https://github.com/nvm-sh/nvm)
VScodeのターミナルで以下のコマンドを実行します。

```
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
```

```
touch ~/.bash_profile
```

```
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
```

#Node.js + npmのインストール
次にNode.jsのバージョンを最新のLTSにしておきましょう。
LTSとはLong Term Supportの略で、長期的にメンテナンスするみたいな感じです。

```
nvm install --lts
```

```
nvm use --lts
```
以下のコマンドを実行して、Node.jsとnpmのバージョンが表示されれば大丈夫です。

```
node -v
v12.18.0
```
```
npm -v
6.14.4
```

このままだとsshでログアウトして再接続後は有効にならないので、
defaultのバージョンを指定しておきましょう。これでログイン後にすぐ使えます。

```
nvm alias default lts/*
```

#yarnのインストール
npmでもReactを起動することはできますが、
npmよりもyarnの方がより高速で信頼度の高いものになっているのでyarnを使います。
[yarnの詳細はこちら](https://classic.yarnpkg.com/ja/)

```
npm install -g yarn
```
yarnのバージョンを確認して表示されればOKです。

```
yarn -v
1.22.4
```

#構築した環境でReactを起動
React開発環境に必要なcreat-react-appをインストールします。

```
yarn global add create-react-app
```
次にアプリケーションを作成します。作成する場所はどこでも大丈夫です。

```
yarn create react-app sample-app
```
作成したプロジェクト配下に移動し、以下のstartコマンドを実行します。

```
cd sample-app
```
```
yarn start
```
実行後、ブラウザが起動し、Reactの画面が表示されていればOKです。

#yarn startできない
yarn startを実行したが以下のエラーが発生した場合

```
error Command failed with exit code 1.
```
以下のコマンドで解決することができました。

```
npm install npm
```
```
yarn add yarn
```
次に以下のコマンドを実行して何も表示されなければ大丈夫です。

```
echo $HOST
```
何か結果が返ってくる場合は以下のコマンドを実行しましょう。

```
unset HOST
```

もう一度echo $HOSTを実行してなにも表示されなければ大丈夫です。
これでReactを起動できると思います。

```
yarn start
```
a タグがtarget="_blank"のときnoopenerなしのrel="noreferrer"だけで良いという話

# 概要
https://html.spec.whatwg.org/multipage/links.html#link-type-noreferrer

> `<a href="..." rel="noreferrer" target="_blank"> has the same behavior as <a href="..." rel="noreferrer noopener" target="_blank">.`

自分も知らなかった
案外知らない人が多そう

# 気づいた経緯
最近いきなりeslint-plugin-reactのnoopenerなしが怒らなくなったので、調べたら以下が入っており、noreferrerだけで同一の挙動をすることを知った
https://github.com/yannickcr/eslint-plugin-react/pull/2043

https://github.com/yannickcr/eslint-plugin-react/issues/2022#issuecomment-623677544
によるとnoopenerついてないとwindow.openerが削除されないブラウザはないと確認をとっており、レガシーブラウザも大丈夫そうなのもあってこのような変更になったみたい
【初心者向け】プログラミング学習に必須なインターネットの用語・仕組み解説（フロントエンド編）

#はじめに
　プログラミング学習を初めて半年立ちますが、アウトプットする力がないと気づき、これから自分の備忘録として学習したことを記事にしていきます。
もしアドバイスなどがあればコメントお願いします。

#前置き

　半年間プログラミング学習を行なってきて、技術を身につけていくために**「専門用語」**と**「仕組み」**を理解することが重要だと思いました。**「専門用語」**を知らないと解説などを見ても、何を書いてるのかわからないし、インターネットがどうやって、ユーザーが欲しい記事を取ってきているかなどの**「仕組み」**を知らないと、今どの部分を学習しているかわからずチンプンカンプンになることがよくありました。
　逆に、この2つを理解して学習を進めて行けば、わからないところが出てきてもググりやすくなり、言語の学習をする時も学習を効率的に進めやすくなると思います。今回は、初心者向けにフロントエンドを中心にインターネットで必要な**「用語」**や**「仕組み」**を解説していきたいと思います。

#インターネットが動く仕組み
　図書館を例にして、インターネットがどのようにして動いているのか解説していきます。
![toshokan_benkyou.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651278/5dd12936-dddc-8c1c-ffab-22993f74c805.png)

##HTTPプロトコル（HTTP通信）
　まず探したい本がある時、

　自分「この本はどこですか？」
　受付「この本はここですよ。」
　などのやりとりをすると思います。このやりとりのことを**「HTTPプロトコル（HTTP通信）」**と言います。

　ユーザーが見たいWebページをリクエストする
　　　　　　　　　↓
　サーバー側がリクエストしたページを取ってきユーザーに渡す
　　　　　　　　　↓
　ユーザーが受け取る

　この一連の流れのことを**「HTTPプロトコル（HTTP通信）」**と言います。

##URL(ドメイン）
　受付の人に本の場所が書いてある紙を渡されると思います。その紙に書かれている場所がURL（ドメイン）です。URLは人が理解しやすいように表示されています。

　例えば、facebookのURLだと
　https://www.facebook.com
　のように一目見ただけで、どのページにいるのかわかるようになっています。

##IPアドレス
　先ほど解説したURL(ドメイン）は人がわかりやすように機械によって変換されていましたが、逆に機械が判別しやすいようなものとして**IPアドレス**というものがあります。

　**IPアドレス**は、00.00.00.0のような数字の羅列です。

　住所を例にして言うと、郵便番号にあたるものが**IPアドレス**、住所にあたるものが**URL**です。
このように機械が判別しやすいように**URL**を数字に変換したものが**IPアドレス**です。

##DNSサーバー
　**URL（ドメイン）**と**IPアドレス**を紐づけて管理している場所のことを**DNSサーバー**と言います。
![dnsserver.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651278/412ff4d3-115d-ef74-1ed1-91c0baa74b3a.png)

　図のようにDNSサーバーは、ユーザーに表示する時は、人にわかりやすいようにURL（ドメイン）で表示し、機械で判別するときは、数字の羅列のIPアドレスに変換する役割を担っています。

##HTML
　先ほどの図書館の例に戻りますが、探したい本の部分がHTMLです。
![html-source.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651278/b0a00124-6500-4cf4-db45-f9e346b0ef36.png)

　上記のようにh1やpなどのことをタグと言います。私たちがみているWebページは、このHTMLを人がわかりやすいようにブラウザが変換して表示しています。


##CSS
　探している本の部分がHTMLでしたが、HTMLだけでは文字だけの味気ないものになってしまいます。文字や背景に色がついていたり、画像や絵が挿入されている本の方が見やすいですよね？その装飾の部分を担当しているのがCSSです。

##JavaScript
　また、その本をもっと豪華に装飾するものをJavaScriptと言います。
Webページで言うと、クリックすると上から解説が出てきたり、動きのあるページにするときにJavaScriptというものが使われます。

##ホスティング
　最後に図書館の場所のことを**ホスティング（位置付け）**と言います。図書館の住所のようなものです。
インターネットで言うと、サーバーのこの場所にプログラムがありますよと**ホスティング**をしないと、そのプログラムは動きません。
　**ホスティング**するための便利なサービスとして、Heroku、AWS、Firebaseなどのサービスがあります。これらの場所を提供するサービスを利用することで初めて自分の作ったプログラムを世の中に出すことができます。

##まとめ
　今回は、インターネットが動く仕組みを簡単に解説してきました。概要のような形で解説してきたので説明が不十分なところもあると思いますが、プログラミング学習の最初の入りの部分で活用していただければと思っています。
　もしこの記事で少しでも興味が湧けば、ググったり、参考書で調べたりして知識を深めっていってください。
CesiumでWMSレイヤを読み込んだときにポップアップを出なくする方法


`WebMapServiceImageryProvider`関数を呼び出すときに`enablePickFeatures: false`としてやればよい。

```
    new Cesium.WebMapServiceImageryProvider({
      url:
        "http://***",
      layers: "***",
      enablePickFeatures: false,
      parameters: {
        transparent: "true",
        format: "image/png",
      },
    }),
```
VS CodeでJavaの未使用インポートを保存時に消す設定

Visual Studio Codeで
Javaのソースファイルにて、
保存時に
未使用インポートを消す。

という設定を見つけましたので、メモしておきます。

Java > Save Actions: Organize Imports
<img width="366" alt="JavaSaveActionsOrganizeImports.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150699/8611538f-df7d-dfa4-edb6-66b54818038e.png">


です。

Macをご使用の方は
「Command + ,」で設定ファイルを開き、「Java import」って検索ワードを打ち込むと見つかると思います。


ちなみに、

Organize　は　整理する　って意味で、　オーガナイズ　と発音するそうです。[こちら](https://www.google.com/search?q=Organize+%E6%84%8F%E5%91%B3&oq=Organize%E3%80%80%E6%84%8F%E5%91%B3&aqs=chrome..69i57j0l7.1857j1j1&sourceid=chrome&ie=UTF-8)で調べました。

整理するってことなので、
未使用インポートを消すだけじゃなく、
グループ分けや並び替えも行われるようです。



以上です。
leet code easy Longest Common Prefix


Write a function to find the longest common prefix string amongst an array of strings.

If there is no common prefix, return an empty string "".

```python
class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
#sizeにstrsの要素数を入れる。０、１の時は固定で返す。
        size = len(strs)
        if len(strs) == 0:
            return ""
        if len(strs) == 1:
            return strs[0]
#sort()でアルファベット順に並べ替える。
        strs.sort()
#minで一番短い単語をendに入れる。
        end = min(len(strs[0]),len(strs[size - 1]))
        i = 0
#最短の単語の文字数までの中で、strs[0][i]==strs[size-1][i](最初と最後の単語＝最もアルファベット順で異なっている２つの、[i]番目の数字が同じか探索していく。)）
        while (i < end and strs[0][i]==strs[size-1][i]):
            i += 1
#最初の単語の、１文字目からi文字目（共通文字の最後）までをreturnする
        pre = strs[0][0:i]
        return pre
```
Golangをインストールしてみた。

```
# get golang.org/dl/go1.10.7
$ go1.10.7 download

# The newly downloaded version can be used like go:
$ go1.10.7 version
=> go version go1.10.7 linux/amd64

# インストール先の確認
$ go1.10.7 env GOROOT
```
Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.

#spring bootを起動しようと思ったらつまったところ

既存のdockerを削除し新しく起動しなおそうとしたところすでにポート8080が使われていると言われた。

```
Action:
Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
```



そのためもう一度確認してみるとない・・・

```
% docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
```


前にいじったときのものが消えていないようだ、こういうのをゾンビプロセスというようだ

###ゾンビプロセス
実行終了中のプロセスをゾンビ・プロセスといいます。プロセスの処理は既に終了し，メモリーなどの資源（リソース）はすべて解放されています。ただし，プロセスが使用したメモリー領域やファイル，ソケット，シグナルなどの情報を管理するtask_struct構造体だけが存在しています。


8080を使っているものをみてみる

###コマンドメモ
lsof - プロセス・ポートがオープンしているファイルを表示する

####lsofコマンドとは
「lsof」コマンドは、「プロトコル」「ホスト名」「IPアドレス」「サービス名」「ポート」などを指定して、プロセスが開いている「ファイル」「ディレクトリ」「ブロックファイル」「キャラクタファイル」「ライブラリ」などを表示する。
「ストリーム」「ソケット」の情報も表示可能。

```
% lsof -i:8080
COMMAND   PID  USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
java    49604 mohumohu   45u  IPv6 0xfe0dd73d15734193      0t0  TCP *:http-alt (LISTEN)
```

前に触ったjavaが動いていたようだ

```
 % ps -ef | grep java
  501 49604     1   0 Wed02PM ??         2:50.46 /Users/mohumohu/Library/Java/JavaVirtualMachines/openjdk-14.0.1-1/Contents/Home/bin/java
```

idが一致したのでこれを消す

```
 % kill -9 49604
```

もう一度、ps -ef | grep javaを打ってみると消えたようだ

これで起動できるようになりました
【エラー備忘録・単純ミス】railsアプリ作成時のpostgresql接続失敗【PG::ConnectionBad: FATAL:】

##結論
①データベースを作成していなかったことが直接の原因。
②エラー調査のためpostgresqlにログインするときに失敗したのは、ナンバーロックがオフになった状態で数字をテンキーで入力したことが原因と思われる。これがエラー理由を誤信させ、エラーが長引いた原因。

##環境
Windows10home
rails5.2.4
postgresql 12.3

##状況
RailsアプリのCRUD処理まで実装した後、GitHubに上げるため、`database.yml`のユーザーネームとパスワードを平文から環境変数に変更。
環境変数変更に使用したgemは`dotenv-rails`。
その後もビューの確認のため、シード投入やデータベースリセットを繰り返していたが、その中で急にpostgresqlに繋がらなくなった。

```ruby:Gemfile
gem "dotenv-rails"
```
上記の`bundle install`をした後に以下のファイルをRailsアプリ直下に作成。

```:（railsアプリ名）/.env
DB_USERNAME = psqlのユーザー名を入力
DB_PASSWORD = psqlのパスワードを入力
```

```yml:database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: <%= ENV["DB_USERNAME"] %>
  password: <%= ENV["DB_PASSWORD"] %>

development:
  <<: *default
  database: CRUD_app_development

test:
  <<: *default
  database: CRUD_app_test

production:
  <<: *default
  database: CRUD_app_production
  username: CRUD_app
  password: <%= ENV['CRUD_APP_DATABASE_PASSWORD'] %>

```

```:エラー内容
$ rails db:seed
rails aborted!
PG::ConnectionBad: FATAL:  �f�[�^�x�[�X"CRUD_app_development"�͑��݂��܂���    
bin/rails:4:in `require'
bin/rails:4:in `<main>'
Tasks: TOP => db:abort_if_pending_migrations
(See full trace by running task with --trace)
```
文字化けは原文のまま。
このエラー表示の前に、`database.yml`の設定ミスによる異なるエラー表示もあったが、ターミナルを閉じたので正確には分からない。
確かパスワードを入力していなかったのが原因だったと思う。

##試したこと
環境変数の内容は正しいのか？nilになっていないか → ○　`rails c`で環境変数を入力して確認
`database.yml`のユーザー名とパスワードを平文にして実行 →　× 同じエラー
postgresqlにログインしてテーブルを確認する → パスワードを入力しても認証失敗でログインできず。ということは、postgresqlのユーザーネームかパスワードが正しくないことが原因か？

##原因

```
$ rails db:create
Created database 'CRUD_app_development'
Database 'CRUD_app_test' already exists
```
開発環境だけデータベースが作成されていなかった。
というのも、シードデータ投入とリセットを繰り返す中でデータが完全に消去されなかったため、`rails db:drop`を実行していた。
そのときは`database.yml`の設定でテスト環境にユーザーネームとパスワードをしていなかったので、エラーが発生。
そのエラー内容をよく見ておらず、このときに開発環境のデータベースがドロップされたことに気づかずに作業を進めていた。
登録したパスワードでpostgresqlにログインできなかったため、今回のエラー原因がpostgresqlのユーザー・パスワード設定にあると勘違いしたことがエラーが長引いた原因。

##教訓
エラー内容はよく見ましょう。

なお、`rails db:create`後は、postgresqlにログインできた。
なぜ？データベース作成後でないとpostgresqlにログインできないのはおかしいのではないか。
試しに再度`rails db:drop`してログインを試したら普通にログインできた。
予想される原因としては、テンキーで数字を入力しているため、ナンバーロックがオフになった状態で入力したことが考えられる。なんともお粗末な原因。
vSphereHAだけでvCenterは引っ越すのか

# vSphereHAだけでvCenterは別のESXiホストにvMotionしてくれるのか確認した話
はい皆さんこんにちは

結論から言うとこの記事は

vCenterHA機能は使わず、vSphereHAだけの状態でESXiホストが接続不可になった場合に、
他のESXiホストにvCenterがvMotionしてくれるのを確認した内容を記載します。

検索用：vSphereHA vCenter vMotion

# 詳細

環境：
ESXi6.7　×3台
vCenter6.7

用語が一杯でややこしいので一つずつ解説します。

vCenter：
vSphereの管理環境です。WEBコンソールが提供されています。

ESXiホスト：
vSphereの仮想ホストで、仮想マシンを動かすためのリソースを提供します。
vCenterもこの上で動いています。

vCenterHA：
vSphereの6.5から追加された機能で、vCenterが操作不能となった際に別のESXiホストで、
予め設定していたサブのIPアドレスとして起動する機能です。
なお、アプライアンス版のみ対応。

vSphereHA：
これはクラスターを組んでいるESXiホストが操作不能となった場合に、
稼働中の仮想マシンを正常なESXiホストにvMotionする機能です。
他にも色々できますが、vMotionに必要なリソースを予め予約する事もできます。

vMotion：
仮想マシンをオンライン状態で異なるESXiに移行する機能。
（実際には止まるタイミングがあります）


##さっそく試してみた
ESXiホストの1台目にvCenterと他の仮想マシン
ESXiホストの2台目には仮想マシン無し
ESXiホストの3台目には仮想マシン無し

この状態で1台目のLANを抜くと
2台目と3台目のESXiホストに1台づつvMotionされ、
最後にvCenterが移動されました。
vCenterが使えるようになるまでは、大体10分ぐらいでした。

##おまけ
ESXiホストの1台目にvCenterと他の仮想マシン
ESXiホストの2台目のリソースの空きは無し
ESXiホストの3台目には仮想マシン無し

vSphereHAのアドミッションコントロールのリソース予約をOFFの状態で
1台目のLANを抜くと
自動的にリソースの空いている3台目にvMotionされました。

##感想
今までvCenterは物理の筐体にインストールする事が良くあったので、
仮想アプライアンスになった時にvSphereHAがどう動くのか、調べる機会があったので記事にしました。

**ありがとうございました。**
（追記）軽率に gcc のバージョン上げたら Ansible が全く動かなくなって泣きそうになった話

# 初めにまとめ（TL；DR）

~~特に長くはないです~~

- 必要が生じたのでサーバ側の gcc バージョンを上げた
- 新しいバージョンの gcc で make したいソフトウェアがあったが、Ansible 経由でうまく動いてくれなかった
- 雑に「常に新しいバージョン使う」よう設定したところ、Ansible の命令を一切受け付けなくなった
- ~~古いほうに戻したら Ansible 動いたので、対策検討中~~
- [結局 `scl` が sudo を妨害するバグだった](https://bugzilla.redhat.com/show_bug.cgi?id=1319936)


# 追記

devtoolset-9 であれば発生しない問題でした。

# やったこと

とあるソフトウェアを make install したかったのだが、gcc バージョンが古いと駄目だったので gcc バージョンを上げた。
参考：https://thr3a.hatenablog.com/entry/20180308/1520506543

`scl enable devtoolset-7 bash` して、新しいほうの gcc バージョンを使えば make できることは検証用のサーバで手動実施したのでわかっていた。
手作業の 99.99% は悪なので、Ansible タスク化しようと、以下のようなタスクを書いた。

```yml
shell: 'scl enable devtoolset-7 bash; ./install
```

が、これを実行しても、一向に何も帰ってこない。
`-vvv` してみてもコマンドが実行された気配すら無く、無理矢理 `/proc/[pid]/fd/` 配下を cat してみても何も出力されてない。

原因がよくわからないので、上記参考サイトにあるように、以下の profile を配置した。

```bash
$ cat /etc/profile.d/enabledevtoolset-7.sh
#!/bin/bash
source scl_source enable devtoolset-7
```


# 起こったこと

急に ansible が動かなくなった。

```
TASK [Gathering Facts] *************************************************************************************************************************************************************************************
fatal: [devstorm-app]: FAILED! => {"ansible_facts": {}, "changed": false, "failed_modules": {"setup": {"failed": true, "module_stderr": "Shared connection to hoge.example.com closed.\r\n", "module_stdout": "/var/tmp/sclJc174F: line 8: -H: コマンドが見つかりません\r\n", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 127}}, "msg": "The following modules failed to execute: setup\n"}
```

上記は何度か見かけており、Python バージョンの違いによって発生することは知っていたが、Python バージョンなんか変えてないし、当然 interpriter を指定しても動くようにはならない。
そして、ググっても Python バージョンのことしか出てこない。
加えて厄介だったのが、このとき「もう gcc バージョン指定の shell はいらないから」とタスクも書き換えており、それが原因なのかと思いこんでタスクを戻したり色々試行錯誤してしまって原因特定に時間がかかってしまった。
さらに面倒なことにしてしまったのが、ちょうど業務も終了時間だったため「今日のところはシャットダウンして、明日起動したらワンチャン直ってるだろ」と楽観視して帰ってしまったことである。
なんでも再起動で直る思想はよくない。


# 原因特定に至った背景

いくらググっても Python バージョンの話しか出てこないので、ローカルとサーバの Python バージョン合わせるかーとか思ってバージョンを出したところ

```bash
$ python
Python 3.6.7 (default, Nov 16 2018, 12:28:24)
[GCC 4.2.1 Compatible Apple LLVM 10.0.0 (clang-1000.10.44.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
```

・・・おや？ `GCC 4.2.1` とな？
そういえば gcc っていじったよな・・・と思い、上記の profile を削除したところ、無事 Ansible タスクが実行された。
やはり、何か起こった際には冷静に一つずつ状態をロールバックさせなければならないし、そのためにもロールバック可能な作業手順というのが必要。


# 今後必要なこと

とはいえ、gcc バージョン上げないと必要なソフトウェアがインストールできないので gcc バージョン上げて Ansible 動かせるようにする必要がある。
ローカルもサーバも gcc 上げた Python でやってみたら動きそうな気がするけど、そうすると今度は他のサーバで動かなくなりそうだから色々調べつつやってみる必要がある。
解決したら編集・追記します。
いかなる理由があろうとリンクは絶対に <a href> にしてほしい


こちらの記事を拝見しました。

- [ただリンクにしたいときにhref="url"の代わりにonClick="location.href = 'url'"的なことをすると体験を損ねます](https://qiita.com/fruitriin/items/f795613cce153aecc8d6)

著者の主張を要約するとこんな感じでしょうか。

- ハイパーリンク（ハイパーテキストアンカー）を `<a href>` でなく JavaScript で遷移させると、別タブで開けないというデメリットがある
- 意図して別タブで開かせたくない場合を除いて、 JavaScript での遷移は避けるべき
- できるだけ `<a href>` が望ましい
- 強い意思を持って JavaScript 遷移を使うならいいんじゃないか

これに対して、実際に onClick によるリンクで（正確な表現に置き換えると「JavaScript に依存したページ遷移で」）困った思いをしている者としての補足をさせていただきます。

先に結論を言うと、私は表題のように**「いかなる理由があろうとリンクは絶対に `<a href>` にしてほしい」**と考えています。

まず事実として、別タブで開けないという問題以前に、スクリプト無効環境では「遷移すらできない」という重大な問題が発生します。スクリプト無効環境というのは、古のテキストブラウザだったり、ブラウザのスクリプト設定を意図的に無効にしてたりする場合だけではありません。ブラウザ設定やアドオンによりスクリプトの一部が実行されない、あるいはネットワークの設定で一部のスクリプトファイルがロードされないことにより、意図した処理が行われないことはままあります。

例えばブラウザの設定から Cookie を受け入れない設定にして以下の HTML ファイルにアクセスしてみてください。 Link の文字列をクリックしても何も起こりません。

```
<p><span class="js-anchor">Link</span></p>

<script>
sessionStorage.setItem('foo', '1');

document.querySelector('.js-anchor').addEventListener('click', () => {
  location.assign('page1');
});
</script>
```

開発者ツールで Console を見ると、 `sessionStorage.setItem()` の部分でエラーが起こっているのが分かります。そして**後続の処理は実行されない**ので、 Link をクリックしても何も起こらないわけです。

あるいは、 Firefox で [Third-party Request Blocker](https://addons.mozilla.org/ja/firefox/addon/tprb/) をインストールして、以下の HTML ファイルにアクセスしてみてください。やはり Link をクリックしても何も起こらないはずです。

```
<p><span class="js-anchor">Link</span></p>

<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
$('.js-anchor').on('click', () => {
  location.assign('page1');
});
</script>
```

これは「Third-party Request Blocker」のデフォルト設定ではドメインをまたいだ通信をすべてブロックするため、 code.jquery.com から jquery-3.5.1.min.js のロードが行われないことによるものです[^1]。別にこのアドオンを入れていなくても、読み込み先のサーバーが落ちていたり、極端に速度が低下していれば同じようなこと（結果的にスクリプトが正常に動作しないこと）は起こりえます。

---

その昔、ブラウザの JavaScript 実装が酷かった頃は、安全のためにスクリプトを無効にした方が良いという論調がありました。ガラケーの世界では、端末によっては比較的最近までそういうことがあり、サービス提供者が公式にスクリプトを無効にせよと案内したことすらあります[^2]。

昨今ではさすがにそういうこともなくなり、未だスクリプトを無効にしているユーザーなど無視しても構わないという風潮になってきていますが、上記のように意図的にスクリプトを無効にしていなくとも、別の事情でスクリプトが正常に動かないということはままあります。

個人的な話になりますが、私も昔はブラウザのスクリプト設定を無効にしていたため、2006年に Firebug が登場する前は、リンクをクリックして何も起こらないページに出くわした際は右クリックでHTMLソースを開き、目視で処理を追って本来の遷移先URLを見つけ、それをブラウザのアドレスバーにコピペして遷移するという、地獄のようなことを繰り返していたことを思い出します。今はスクリプトは有効にしているものの、 Cookie はデフォルトで拒否しており（もちろんログインが必要なドメインは個別に許可しています）、またいくつかアドオンを入れている関係から、依然同じような事態には遭遇します。

お願いです、いかなる理由があろうとリンクは常に `<a href>` を使ってください。

[^1]: 実際にこのようなアドオンを導入しているユーザーは、問題ないと判断したドメイン間の通信を個別に許可しているでしょう。実例は[高木浩光＠自宅（テレワークを除く）の日記 - 「NoScript」をやめて「RequestPolicy」にした](http://takagi-hiromitsu.jp/diary/20090531.html)をご覧ください（※「Third-party Request Blocker」ではなく類似の機能を持っていた「RequestPolicy」について、導入意義を含めて解説された記事です）。
[^2]: 例えば2010年にソフトバンクが[ブラウザのセキュリティ設定に関する重要なお知らせ](https://www.softbank.jp/mobile/info/personal/news/support/100527/)をリリースしたのは記憶に新しいところです。
Chrome Extensionのバージョンアップしたらリジェクトされたため対応した話

# リジェクト内容
久しぶりにChrome Extensionをバージョンアップして申請したらリジェクトされてしまいました。
メールに書いてあった理由は以下の通り。
>「ストアでのスパム行為と掲載順位」
アイテムの一部の説明フィールド、アイコン、スクリーンショットが提供されていないため、不審なアイテムと判断されています。

あるときから審査が厳しくなったためコード直してそのままでは審査に通らなくなることがあるそうです。

# 対応内容
- アイテムの一部の説明フィールド
- アイコン
- スクリーンショット

の中でどれか1つでもが審査基準に満たしていないと上記のリジェクト内容になるみたいです。
これでは、何がどう満たせていないのか分かりにくい……。

同リジェクト内容の記事 [Chrome拡張の審査がリジェクトされてから通るまで - Qiita](https://qiita.com/munieru_jp/items/3faef67782d0319e3577) を見たのですが、
私の場合は、スクリーンショットも貼ってあり、説明も記載していました。

ということで、アイコンがどうやら怪しそうです。

リジェクトを受ける前は、128 x 128のアイコンしか用意していませんでした。
そこで、アイコンサイズの種類、16 x 16と48 x 48を増やしました。

```manifest.json
    "icons": {
        "16": "img/icon16.png",
        "48": "img/icon48.png",
        "128": "img/icon128.png"
    }
```
上記の変更のみで再度申請したら無事、審査に通過してバージョンアップに成功していました！

# まとめ
__アイコンは、128 x 128と48 x 48と16 x 16の3種類用意しておこう。__
因みに128 x 128はインストール時とChromeウェブストアで使用されて、48 x 48は拡張機能管理ページで、16 x 16はその管理ページのファビコンとして使われます。

128 x 128は提供するのは必須だったのでそれだけしか作っていなかったのですが、16 x 16と48 x 48も必須になっていたとは。
[Manifest - Icons - Google Chrome](https://developer.chrome.com/extensions/manifest/icons)  に書いておいてほしい……。
<br/>
因みに作成したChrome Extensionは、[Markdown Links Creater](https://chrome.google.com/webstore/detail/markdown-links-creater/mehjjeabilngkppolejabfpjckgikifm?hl=ja&gl=JP)というものです。
タブにあるブラウザをまとめてMarkDownのリンクしたりできます。
単純な機能しかないですが興味のある方はどうぞ（宣伝）
time_selectのセレクト欄を30分毎に表示する方法

### 状態
Railsでアプリ作成していて、time_selectを使い時間を入力させたいが、デフォルトだと1分単位で使いにくかったので、30分単位にしました。

### 方法
まず現状

```ruby
= f.time_select :end, {}, class: 'content__main__box__field__select'
```

これだと1分ごとの表示に加え、現在時刻が自動でセレクト欄に入ってしまう。

```ruby
= f.time_select :end, {:include_blank => true, :minute_step => 30}, class:'content__main__box__field__select'
```

これで00分と30分のみ選択できるようになり、現在時刻が自動でセレクト欄に入らず、しっかり空欄になりました。


改めて**ググる力**の大切さを学びました！笑
検索してもうまくヒットさせられず、時間がかかりました、、、。

日々勉強ですね。
iOSショートカットレシピ　西武バスで特定区間の経路検索を１クリックで行う

　西武バスの[経路検索サイト](https://transfer.navitime.biz/seibubus-dia/pc/map/Top)は、乗車駅、降車駅を毎回設定してから検索ボタンを押します。通勤経路のように毎回同じ駅で乗り降りする場合に、自宅で検索する時は自宅近くの駅から会社近くの駅まで、会社で検索した場合はその逆、で検索するショートカットを作りました。このショートカットのボタンをホーム画面に作っておけば、毎回１クリックで会社までや自宅までのバス時間が検索できます。
　西武バスの経路検索サイトは入力ページのフォームに入力した乗車駅、降車駅、乗車日時をURLの形で検索サイトに投げることでバスの検索を実現しています。このURLのフォーマットをハックして知りたい区間や時間を設定したURLを作れば、それに従って検索結果を表示してくれます。
　処理の流れは、
1. バス停名とバス停コードの設定
2. 現在地の取得
3. 現在時刻の取得
3. 現在地に従った乗車駅降車駅駅までの所用時間の設定
4. バス停名からバス停コードの取得
5. 現在時刻を年月日時分に分割
6. バス停と時刻の情報をURLのフォーマットに設定
7. SafariにURLを渡して検索表示
となります。
　以下の説明では、自宅の近くのバス停は自宅のすぐ前（徒歩０分）で「自宅近くのバス停」と言う名前、会社近くのバス停は会社から徒歩13分で「会社近くのバス停」と言う名前とし、自宅住所は「中野区」とします。

＊サイトの仕様が変更になったらしく、iPhoneでエラーになっていた部分を修正しました（2020.7.24）

#　アクションと解説

## バス停名とバス停コードの設定

　バス停の名前を変数に設定して、対応するバス停コードを辞書のフォーマットで設定します。バス停のコードは西武バスの[経路検索サイト](https://transfer.navitime.biz/seibubus-dia/pc/map/Top)で検索すると出力されるページのURLから読み取ります。バス停の名前も（カッコやスペース等も含めて）この出力で使われている文字列を使ってください。
<img width="60%" alt="次のバスは10.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535482/2fbd1724-34b7-6344-aaef-1ca82a73865a.jpeg">

## 現在地と時刻を取得して、乗車、降車駅とバス停到着時刻を設定

　現在位置を取得します。「天気」アクションを用いているのは反応を速くするためで、詳しくは [“iosのショートカットTips”](https://qiita.com/osadataku/items/0578fb8c67b635dad598) を見てください。現在位置の情報からは郵便番号や住所などさまざまな要素が選べるので、自宅と会社を区別できる要素を使って、乗車駅、降車駅、乗車駅の自分の到着時刻設定します。ここでは自宅は中野区にあり、会社は別の住所だとして、「市区町村」文字列に「中野区」が含まれるかどうかで判断しています。
　「カレンダー」アクションは現在時刻の取得とその時刻に対する計算もしてくれるので、会社でこの検索を行ないバス停まで徒歩で１３分かかるという場合のバス停の到着時刻を１アクションで設定できます。
<img width="60%" alt="次のバスは20.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535482/476e5831-ff2f-fcbb-cdeb-3d11316a6d99.jpeg">

## 駅名から駅コードの取得と現在時刻を年月日時分に分割

　辞書に登録しているバス停コードを駅名から取りだします。
　「調整済みの日付」（乗車バス停への到着時刻のマジック変数名）から年月日、時、分、を後のURLに使えるフォーマットで取り出します。取り出し方の詳細は [“iosのショートカットTips”](https://qiita.com/osadataku/items/0578fb8c67b635dad598) を見てください。
カスタムフォーマットは次の表のとおりです

|  | フォーマット |例|
|:-:|:-:|:-:|
|年月日   | yyyyMMdd  |20200709 |
|時|  HH | 08 |
| 分  |  mm | 03 |

<img width="60%" alt="次のバスは20a.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535482/ca8fa868-d910-c016-8b4b-91b39ae13775.jpeg">

## バス停と時刻の情報をURLのフォーマットに設定しSafariに渡して検索結果を表示

　ここまでで設定したバス停名と乗車時刻の情報を西武バスの検索サイトのフォーマットに合わせてURLの文字列を作り、２バイト文字列の処理のためURLエンコードを行ない、エンコードした文字列を使ってSafariで表示します。図ではURL切れていますが、全文は以下の文字列です
```URL
https://transfer.navitime.biz/seibubus-dia/smart/transfer/TransferSearch?targetstart=&roughEstimate=co2&startName=乗車駅&start=&start=&orvCode=0.0.乗車駅コード.乗車駅&orvAdd=...&startPosType=&orvPosType=4&goalName=降車駅&goal=&goal=&dnvCode=0.0.降車駅コード.降車駅&dnvAdd=...&goalPosType=&dnvPosType=4&day=年月日&hour=時&minute=分&year=&month=&basis=1&sort=2&wspeed=standard&method=2&useRouteMethodDefault=2&type=
```
<img width="60%" alt="次のバスは40a.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535482/a880bad2-4d6a-e27d-8278-3d24a0529ef3.jpeg">

---

　思った通りに動作しましたでしょうか？　結果が思い通りでない場合やエラー表示になる場合は、アクションが出力するURL文字列と、通常通りにマニュアル入力で検索した場合の結果表示のURLとの違いからデバッグしてみてください。
　Good luck !
プロセス、スレッド、タスク、ジョブ

プロセス、スレッド、タスク、ジョブ周りをかなりざっくりまとめました。
かなり単純化している+深いところまでは理解できていないので、突っ込みどころは色々あるかと思いますが、大枠をつかみたい方のお役に立てるかと思います。

誤りがあれば、どんどんコメントでご指摘いただければと。

## プログラムの実行手順
1. メモリが、実行するプログラムを読み込む
2. CPUが、メモリ情報を読み込んで処理する
3. 処理が終わったら、メモリを開放する

メモリは机、CPUは脳に例えられたりします。
必要な処理を一旦メモリに展開して、CPUが処理していくイメージです。
CPUはメモリだけをみていれば良いので作業に集中できます。

## プロセスとは
上記の「プログラム実行手順」の1~3のまとまりをプロセスと呼びます。
プログラムがメモリにアップされてから開放されるまでの一連の処理のことです。

## スレッドとは
プロセスが「メモリ→CPU」で処理される中で、新しいプロセスが作られることがあリます。
この「プロセスの処理の中で作られたプロセス」=「子プロセス」=「スレッド」です。
スレッドもプロセスの一種です。

## タスクとジョブ
ざっくり言うと、「プロセスやスレッドのこと」です。
厳密な定義はシステムやアプリ、チームによって変わるので、深く考えない方が良いみたいです。

**タスク、ジョブの定義の例**

- 1プロセス
- プロセスの集合体
- 1スレッド
- スレッドの集合体
- プロセスやスレッド内の特定の処理

## その他
### マルチプロセスとは
同じ資源(ファイル、アプリなど)を使って複数のプロセスをメモリに展開して処理すること。
例えばテキストエディタはマルチプロセスです。
複数のタブを同時に開くことができ、それぞれのタブ内での操作は互いに干渉しません。

### 共有メモリとは
各プロセスやスレッドは独立していますが、共有メモリと言うメモリ領域を活用することで、プロセス間でデータの共有、受け渡しが可能です。

### ゾンビプロセスとは
親プロセスの後片付けを待っている状態の子プロセスのことです。
親プロセスが子プロセスの終了ステータスをチェックしない(waitしない)プログラムを書いてしまった時に発生します。
ゾンビプロセスはメモリ領域を占領し続けます。
メモリ領域には上限があるので、ゾンビプロセスが溜まっていくとパフォーマンスが悪化していきます。

親プロセスをkillすることで、ゾンビプロセスを退治することができます。

## 参考
- [プロセスとスレッドの違い - ついでにタスクとジョブ - | ただ屋ぁのブログ](https://tadtadya.com/process-thread-task-job/)
- [イケてるエンジニアになろうシリーズ 〜メモリとプロセスとスレッド編〜 - もろず blog](https://moro-archive.hatenablog.com/entry/2014/09/11/013520)
Rubyでzipファイル作るならrubyzipだよね

#概要
とあるタスクで大量のzipファイルを作る必要があったのですが、このgemと出会ったことで救われました。
本記事ではrubyを使ってzipファイルを操作する4つの方法を紹介しています。
##Rubyのバージョン
Ruby 2.4 またはそれ以上
##gemをインストール
Gemfileに追加する

```ruby:Gemfile
gem 'rubyzip'
```
ターミナルで次のコマンドを実行する

```terminal:terminal
bundle install
```
#4つの用途で使い分ける

## 1. zipファイルを作る
```ruby
Zip::OutputStream.open('example.zip') do |zos|
  zos.put_next_entry('first_file.txt')
  zos.puts 'hoge hoge'

  zos.put_next_entry('second_file.txt')
  zos.puts 'hoge again'
end
```
`puts`メソッドの引数には文字列またはファイルの読み込んだデータを使用してください。
生成されたzipファイルの中身は次の構造になります。

```
example.zip
- first_file.txt
- second_file.txt
```

またそれぞれのファイルの中身は以下のようになります。

```:first_file.txt
hoge hoge
```

```:second_file.txt
hoge again
```

## 2. zipファイルを読み取る
`get_next_entry`メソッドでzipファイル内のファイルが次々とセットされます。

```ruby
Zip::InputStream.open('example.zip') do |zis|
  entry = zis.get_next_entry
  print "First line of '#{entry.name} (#{entry.size} bytes):  "
  puts "'#{zis.gets.chomp}'"
  entry = zis.get_next_entry
  print "First line of '#{entry.name} (#{entry.size} bytes):  "
  puts "'#{zis.gets.chomp}'"
end
```
**1**で生成された`example.zip`を読み取ると次のように表示されます。

```terminal:terminal
First line of 'first_file.txt (10 bytes):  hoge hoge
First line of 'second_file.txt (11 bytes):  hoge again
```

## 3. zipファイルのディレクトリを読み取る

`get_input_stream(entry)`メソッドを使用して各エントリーの`InputStream`を取得します。

```ruby
zf = Zip::File.new('example.zip')
zf.each_with_index do |entry, index|
  puts "entry #{index} is #{entry.name}, size = #{entry.size}, compressed size = #{entry.compressed_size}"
end
```
このソースコードではzipファイル内に圧縮されたファイルの`index`, `name`, `size`, `conpressed_size`を表示させます。

**1**で生成された`example.zip`を読み取ると次のように表示されます。

```terminal:terminal
entry 0 is first_file.txt, size = 10, compressed size = 10
entry 1 is second_file.txt, size = 11, compressed size = 13
```

## 4. zipファイルを変更する
zipファイルを直接変更します


`add(entry, path)`でpathで示したファイルを追加
`rename(entry, new_name)`で名前を変更

**1**で生成したファイルを変更

```ruby
Zip::File.open('example.zip') do |zip_file|
  zip_file.add('third_file.txt', 'third_file.txt')
  zip_file.rename('first_file.txt', 'first_file_rename.txt')
  zip_file.add('fourth_file.txt', 'fourth_file.txt')
end
```
以下のファイルを追加で用意しました。

```:third_file
hoge third
```

```:fourth_file
hogehoge fourth
```

実行してみます。
**3**を用いて情報を取得

```:terminal
entry 0 is second_file.txt, size = 11, compressed size = 13
entry 1 is third_file.txt, size = 10, compressed size = 12
entry 2 is first_file_rename.txt, size = 10, compressed size = 10
entry 3 is fourth_file.txt, size = 14, compressed size = 14
```
生成されたzipファイルは次の構造に変更されました。

```
example.zip
- second_file_txt
- third_file.txt
- first_file_rename.txt
- fourth_file.txt
```

#まとめ
zipファイルを操作するための4つの方法を本記事で紹介しました。
`rubyzip`には他にも便利なメソッドが用意されているので一度見てみることをおすすめします。

#参考
https://github.com/rubyzip/rubyzip
Ubuntu 20.04にRubyをインストールする

# Ubuntu 20.04にRubyをインストールする
## 流れ
- 関連アプリケーションのインストール
- rbenv(バージョンマネージャー)をインストール
- rbenvで指定のバージョンをインストール
- irbで動作確認

## 関連アプリケーションのインストール
- 以下のコマンドを実行

```shell
$ sudo apt-get install -y libreadline-dev
```

## rbenv(バージョンマネージャー)をインストール
- 以下のコマンドを実行

```shell
$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
```

- bashrcまたはzshrcに以下を追加し、PATHを通す。

```
export PATH=$PATH:$HOME/.rbenv/bin 
```

- rbenvがインストールできたことを確認する

```shell
# 再読込 for bash
$ source ~/.bashrc
# 再読込 for zsh
$ source ~/.zshrc

# 初期化
$ rbenv init
# バージョン確認
$ rbenv --version
```

## rbenvで指定のバージョンをインストール
- 以下のコマンドを実行

```shell
$ rbenv install 2.7.1
$ rbenv global 2.7.1
$ ruby --version
```

## irbで動作確認
- 最後に対話環境でrubyが動作するかを確認します。

```shell
$ irb
irb(main)> 5 + 10
=> 15
```

## トラブルシューティング
### rbenvで指定のバージョンをインストールしようとすると`rbenv: no such command install`
#### 原因
rubyのビルド用プラグインがインストールされていない

#### 対応
以下のコマンドを実行してください。

```shell
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
```
なぜ私はNeovimを使うのか

#なぜVimなのか？
EclipseのようなIDEやVSCodeのような多機能エディタが世に渡る中、なぜVimのような難しくてなれないエディタを使うのをすすめるのか。
その理由は主に以下の3つである。
1. **ほぼホームポジションにいるだけであらゆる操作ができる**
2. **カスタマイズ性が豊富で、突き詰めればどこまでも自分好みのエディタにすることができる**
3. **多くの環境にはじめから導入されており、設定ファイルも基本的にテキストだけなのでどこでも使える**

####1.ほぼホームポジションにいるだけであらゆる操作ができる
Vimには無数のキーバインドやコマンドが用意されており、極めればマウスや矢印キーに手を伸ばすことなく思考のスピードでテキストを編集することができる。Vimの操作に慣れてしまえば他のエディタを使うのが嫌になるくらいになるだろう。
しかし大量のVimキーバインドをすべて習得するのは非常に難しく、慣れるまでが大変である。実は私も完璧にVimのデフォルトキーバインドを使いこなせているわけではない。だからVimの操作難易度を下げるために様々な設定でたくさん楽をするのである。

####2.カスタマイズ性が豊富で、突き詰めればどこまでも自分好みのエディタにすることができる
これが私がVimを好む一番の理由である。Vimには無数の設定項目があり、やりたいことはたいていできるようになっている。つまりVimは自分好みのオリジナルエディタへと変わることができるのだ。
さらに、Vimの世界にはたくさんの超すごい開発者たちが超有能なプラグインを公開しているため、完全に1から環境を構築する必要はなくて安心である。

####3.多くの環境にはじめから導入されており、設定ファイルも基本的にテキストだけなのでどこでも使える
VimはLinuxやMacに標準搭載されていることが多く、他の環境(クラウドサービスを含む)で自由に使うことができるので、Vimに使い慣れていると多くの開発環境に適応することができる。さらにVimの設定ファイル(`.vimrc`)は完全にテキストの形式なので、簡単に持ち歩いたり、ファイルの移動ができなくてもコピーアンドペーストだけで簡単に自分の設定を反映させることができる。
**しかし魔改造を行ったVimは持ち歩くことが困難であり、この利点を活かすことができない。**

#なぜ"Neo"vimなのか？
Vimは多くの環境にはじめから導入されているが、Neovimは決してそんなことはない。なぜ新たにインストールしてまでNeovimを使うのか。
そもそもNeovimは、すごいVimmerたちが新たに立ち上げたVimであり、開発速度も早く本家Vimとの下位互換をほとんど維持している夢のようなVimである。魔改造VimにはうってつけのVimなので使わない手はない。
さらにNeovimは**暗黒美夢王**のShougo氏が作ったとてつもないプラグインを簡単に導入できる。プラグインについては別の記事で紹介するが、暗黒美夢王のプラグインは絶対にモノにするべきだ。

#Vimを使わないほうがいい場合
私はできればすべてNeovimに統一したいくらいだが、.NETやAndroidの開発はIDEを使っている。ビルドが複雑なプロジェクトやたくさんのファイルを同時に編集する必要があるプロジェクトでは、どうしてもIDEに勝てない。しかしVimは素晴らしいエディタなので、できる限り自分にあった設定を追求してみてはどうだろうか。

#Neovimのインストール
パッケージ管理ツールを使えば簡単である。例えばaptなら以下のコマンドでインストールする。

```shell
sudo apt install neovim
```
あとはターミナル上で`nvim`と打つだけで起動する。ファイルを開くときは`nvim [ファイル名]`だ。
[Rails]joinsについて

仕様をすごく勘違いしてたのでメモに残しておく。

```
テーブルBがテーブルAに所属している(Bがa_idというカラムを持つ)ならば、
A.joins(:bs).select("as.*, bs.*")
=>a_idで紐付いた一つの大きなテーブルができる
```

と思っていたが、違う・・・

```
モデルの定義で、
A has_many: bs
B belongs_to: a

という関係ならば、

A.joins(:bs).select("as.*, bs.*")
または
B.joins(:a).select("as.*, bs.*")
=>A.id = B.a_idで紐付いた一つの大きなテーブルができる
※joinsの引数の複数形、単数形に注意。モデルの定義を参照。

```
って感じなんすね。
逆でもいけるんだね。
MySQLの起動、停止、ログイン、ログアウト

環境：Cloud9(Linux)

## MySQLを起動する
`sudo service mysqld start`

## MySQLを停止する
`sudo service mysqld stop`

## MySQLの起動状態を確認する
`service mysqld status`

<img width="358" alt="スクリーンショット 2020-06-08 12.06.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538652/5b029912-9065-0f11-510e-b766373acb33.png">
↑起動している場合は「running」

<img width="337" alt="スクリーンショット 2020-06-08 12.06.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538652/8bdba40a-0c8d-800d-a487-0145d020961a.png">
↑停止している場合は「stopped」
## MySQLにログインする
MySQLの管理者ユーザーであるルートユーザーでMySQLにログインする例。
`mysql -u root`
Cloud9はデフォルトでパスワードなしでログインできる状態。

![8A25C30A-C4E3-4621-9648-C13EB4EA4366.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538652/156f0c74-f274-34d1-44a5-e24ef4fe63ba.png)
「mysql >」が出ていたらOK。MySQLのコマンドが打てる状態。

## MySQLからログアウトする
`exit`
![0293559F-A9E1-4F8B-8347-6EA1680CFD24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538652/40266238-00a2-9a54-5e04-a957f01748c0.png)
↑Linuxのコマンドが打てる状態に戻る。
Spring+SpringSecurity+Mysqlで「Table 'xxx.authorities' doesn't exist」

メールアドレスとパスワードでログインしようとすると、
`Table '(データベース名）.authorities' doesn't exist`
というエラーが出た。


この時のテーブル名はuserだったが、
`mysql > alter table user rename to authorities;`
でauthoritiesに変更。

次に
`Unknown column username`や`Unknown column authority`といったエラーが出た。


SecurityConfig.java

```
package com.example.demo;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;


@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter  {
	@Autowired
	private DataSource dataSource;	

	@Bean
	public PasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();
	}
	
	private static final String USER_SQL = "SELECT"
	+ " email,"
	+ " password,"
	+" true"
	+" FROM"
	+" authorities"
	+" WHERE"
	+" email = ?";
	
	@Override
	public void configure(WebSecurity web) throws Exception {
		web.ignoring().antMatchers("/webjars/**", "/css/**");
	}
	
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.authorizeRequests()
		.antMatchers("/webjars/**").permitAll()
		.antMatchers("/css/**").permitAll()
		.antMatchers("/login").permitAll()
		.antMatchers("/signup").permitAll()
		.anyRequest().authenticated();
		
		http.formLogin()
		.loginProcessingUrl("/login")
		.loginPage("/login")
		.failureUrl("/login")
		.usernameParameter("email")
		.passwordParameter("password")
		.defaultSuccessUrl("/home", true);
	}
	
	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.jdbcAuthentication()
		.dataSource(dataSource)
		.usersByUsernameQuery(USER_SQL)
		.passwordEncoder(passwordEncoder());
	}

	
}
```

上記の、`.usernameParameter("email")`　`.passwordParameter("password")`
のところで、column名がusernameとauthorityに固定されてしまうらしい。

カラム名をemail→username、password→authorityに変更
`mysql > alter table authorities change email username varchar(50);`
`mysql > alter table authorities change password authority varchar(100);`


SecurityConfig.javaの該当部分も変更。

その後ログイン成功。
Chromeリモートデスクトップでホスト側操作できない

エンタメ系企業の社内もろもろを担当しているakibinです。

暑くなってきたので若い頃のユーミン（荒井由実）聴いてます。シティ・ポップがこの暑さに映える。

#困ったこと

[Chromeリモートデスクトップ](https://support.google.com/chrome/answer/1649523?co=GENIE.Platform%3DDesktop&hl=ja)でホストであるMacOSにアクセスして画面共有までできたが、マウスやキーボード操作ができない！

#対応方法

[こちら](https://support.google.com/chrome/thread/2648353?hl=ja)にあるように、環境設定→セキュリティとプライバシー→アクセシビリティでChromeリモートデスクトップのアプリにチェックを入れる！以上！！

あービール飲みたい！！

こちらもよろしくです。
＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊
◆ Twitterアカウント
@AkibinMusic

◆ Youtubeチャンネル
https://www.youtube.com/channel/UC-JOpwEnJn3gCrUA4NdCYgg
Cloud9(Linux)でMySQLをアップデートする

## インストールされているMySQLのバージョンを確認
Cloud9ではデフォルトでMySQLがインストールされています。まず現在のバージョンを確認。
`mysql --version`
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538652/e9d692c3-e211-7bad-60d5-92ffc3fd7809.png)
5.5系のMySQLがインストールされています。
これを5.7系にアップデートします。

## MySQLを停止する
`sudo service mysqld stop`

## MySQLをアンインストールする
5.5系のMySQLをアンインストールする場合は以下のよう「55」になります。
`sudo yum -y remove mysql-config mysql55-server mysql55-libs mysql55`

## MySQLをインストールする
5.7系をインストールする場合、「57」を指定します。
`sudo yum -y install mysql57-server mysql57`

## 再度バージョンを確認する
ちゃんとインストールされたかバージョンを確認します。
`mysql --version`
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538652/fe4958ea-a423-9b31-35ba-c619606d26f8.png)
5.7系がインストールされました。


## 参考
どのバージョンをインストールするかの選定について。。
[MySQLバージョン サポート終了期間に注意して、GA版から選ぶ | 「ポテパンスタイル」](https://style.potepan.com/articles/18377.html)
GAはGeneral Availability(一般向けの提供)の頭文字で、Stable(安定版)と同じと捉えていいようです。
独自ルール:gitignoreの利用

* [自分とこの環境下におけるGit & GitLabレクチャー](https://qiita.com/NeK/private/dee76f411cf2488b6873)

# gitignoreとは
git addによってgitが管理するファイルを選択することができる．しかし，「絶対に管理対象にならないもの」をgit add毎に考えるのは面倒くさい．

.gitignoreの中に「絶対に管理対象にならないファイルの名前」を書いておくことで，gitの管理から必ず外れるようにできる．具体的な名前だけでなく正規表現(*や$を使った表現)を使うことができる．

使い方としては，一行にひとつの候補を書く．ちなみに，unixで書いたものをwindowsのメモ帳でみると改行されていないように見える(が実際には改行されている)

## .gitignoreファイルの置き場
プロジェクトのトップディレクトリに置く．

## 管理対象外にしたいファイル
Gitでファイルのバージョンを管理する時，意識しなくとも管理対象から外したいファイルがある．例えば以下のようなもの．

* エディタの一時ファイル
    * hoge.txt~や#hoge.txt# など最後に~が付いたり#で囲われていたりする．
* logファイル
* TeXで作ったpdf
    * originalのtexファイルがあればよい
* 実行ファイル
* 大きなデータファイル
    * hoge.datなど．データファイルはプログラムを動かして取得すればいいのでGitで管理しない
* プログラム関係
    * C,C++
        * *.oなどオブジェクトファイル
    * python
        * \_\_pycache\_\_/
            * キャッシュディレクトリ
        * *.py[cod]
            * pycなど実行効率化のためのファイル
        * *$py.class

基本的にはファイル名(特に拡張子)で判別できる．

## gitignoreを使った管理
プロジェクトディレクトリに以下のファイルを作成する．

* .gitignore
    * 頭にピリオド"."を付け忘れないように注意

その中に<font color="Red">管理対象外</font>にしたいファイル名を書くと自動的に管理対象から外してくれる．
具体的なファイル名でもいいが，正規表現を使うことができる．

# TeX，ROS，ROS2を使用する場合の推奨
研究室での推奨.gitignoreは以下の通り．
最新版は研究室内GitLabのスニペットを参照のこと．

```text:.gitignore
# General
*~
\#*#
*.o
\.nfs0000*
\..*

# tex
*.aux
*.dvi
*.log
*.synctex.gz
*.pdf
*.fdb_latexmk
*.fls


# for ROS,ROS2
build/*
install/*
log/*

# for Python
__pycache__/
*.py[cod]
*$py.class
venv/*

# OpenAI Gym
videos/*
```

# 慣れてきたら．．．
慣れてくれば来るほど手動で行うのは面倒になる(最初はgitignoreの動作を理解するために自分で書いたほうがいいが)．
以下に`.gitignore`を自動生成してくれるものをリスとしておく．

* [gitignore.io](https://www.toptal.com/developers/gitignore)
    * [gitignore.ioのススメ](https://qiita.com/dhun/items/adcae139b5ba1da56c81)
* [gibo](https://github.com/simonwhitaker/gibo)
    * [giboでgitignoreを自動生成する](https://qiita.com/taquaki-satwo/items/358d2d473fff9a25d5eb)
    * [気付いたら.gitignoreはgiboで自動生成する時代になっていた](https://qiita.com/tmknom/items/c4bcebe17d25381fa45d)
Git commitの超基礎的な備忘録

#Git commit はファイル名をちゃんと指定しよう

JavaとGitの勉強をしていて、めちゃくちゃアホみたいな話ですが

ググった内容そのままやっていて、なんでコミットされないんやろうと、

ずっと繰り返していて「ファイル名」を指定していなかっただけなのに

気づくのに15分くらいかかっていました。

そして「-m」も抜けているとviが立ち上がって１０文字くらいのコメントするだけで、

10分くらいかかってしまった。。。

前職でもGitをちゃんと使った管理をしていなかったので、

日々の学習で必ず使っていこうと思います。

```Java
// これでcommit! -mを忘れるとviが立ち上がってそこでメッセージを残さないといけなくなる！
git commit ファイル名 -m "メッセージ内容"

// commit後にpush!これでGitに反映される
git push origin master
```

「千里の道も一歩から」の精神で続けていきます（汗）
【Unity/C#】コルーチンのサンプル

#概要
本記事では[【Unity/C#】コルーチンについて](https://qiita.com/tilyakuda/items/353cc268bbd43c6e8898)でコルーチンについての基本的なことを学んだのでコルーチンを用いた実用例をいくつかご紹介したいと思います。

#目次
* [x秒後に処理](https://qiita.com/drafts/45adca059187cfc3b7cd/edit#x%E7%A7%92%E5%BE%8C%E3%81%AB%E5%87%A6%E7%90%86)
* [x秒ごとにfor文を動かす](https://qiita.com/drafts/45adca059187cfc3b7cd/edit#x%E7%A7%92%E3%81%94%E3%81%A8%E3%81%ABfor%E6%96%87%E3%82%92%E5%8B%95%E3%81%8B%E3%81%99)
* [1フレーム後に処理](https://qiita.com/drafts/45adca059187cfc3b7cd/edit#1%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E5%BE%8C%E3%81%AB%E5%87%A6%E7%90%86)
* [1フレームごとにfor文を動かす](https://qiita.com/drafts/45adca059187cfc3b7cd/edit#1%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%81%94%E3%81%A8%E3%81%ABfor%E6%96%87%E3%82%92%E5%8B%95%E3%81%8B%E3%81%99)
* [Fade](https://qiita.com/drafts/45adca059187cfc3b7cd/edit#fade)
 * [FadeIn](https://qiita.com/drafts/45adca059187cfc3b7cd/edit#fadein)
 * [FadeOut](https://qiita.com/drafts/45adca059187cfc3b7cd/edit#fadeout)

#x秒後に処理
サンプルコード

```C#
	IEnumerator Delay(float _delayTime)
	{
		//ここで指定した秒数止める
		yield return new WaitForSeconds(_delayTime);

		//ここから処理
	}
```
#x秒ごとにfor文を動かす
```C#
	IEnumerator Delay(float _delayTime)
	{
		for (int i = 0; i < 10; i++)
		{
			//この間に処理


			//この間に処理

			//ここで指定した秒数止める
			yield return new WaitForSeconds(_delayTime);
		}
	}
```
#1フレーム後に処理
	IEnumerator Delay()
	{
		//1フレーム遅らせる
		yield return null;
		//このコルーチンが呼び出されて1フレーム後にここまで到達

		//1フレーム遅らせる
		yield return null;
		//このコルーチンが呼び出されて2フレーム後にここまで到達
	}

#1フレームごとにfor文を動かす
サンプルコード

```C#
	IEnumerator Delay()
	{
		for (int i = 0; i < 10; i++)
		{
			//この間に処理


			//この間に処理

			//ここで指定した秒数止める
			yield return null;
		}
	}
```
#Fade
##FadeIn
サンプルコード

```C#
	IEnumerator FadeIn(SpriteRenderer _sr,float _decrease)
	{
		//この処理が動いていたら２重に呼び出されてもここで止める
		if (startUp==true)
		{
			yield break;
		}
		//↑で処理を止めるフラグをtureに
		startUp = true;

		//カラー情報を取得
		Color color = _sr.color;

		//α値を0になるまで減らす
		while (_sr.color.a>=0)
		{
			//α値を減らす
			color.a -= _decrease*Time.deltaTime;
			//カラーを適応
			_sr.color = color;
			//処理を1フレーム遅らせ続ける
			yield return null;
		}

		//処理を終了
		startUp = false;
		yield break;
	}
```
![FadeIn.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211130/f0550ddb-d29c-5f2e-8199-34ae21575964.gif)


##FadeOut
サンプルコード

```C#
	IEnumerator FadeOut(SpriteRenderer _sr,float _add)
	{
		//この処理が動いていたら２重に呼び出されてもここで止める
		if (startUp==true)
		{
			yield break;
		}
		//↑で処理を止めるフラグをtureに
		startUp = true;

		//カラー情報を取得
		Color color = _sr.color;

		//α値を0になるまで減らす
		while (_sr.color.a<=1)
		{
			//α値を増やす
			color.a += _add*Time.deltaTime;
			//カラーを適応
			_sr.color = color;
			//処理を1フレーム遅らせ続ける
			yield return null;
		}

		//処理を終了
		startUp = false;
		yield break;
	}
```
![FadeOut.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211130/b73d5c7e-f81e-983b-495b-2ea17074edf2.gif)
Windows 10 + Python3 + selenium + geckodriver で headless Firefox を試してみる

#目的
Windows 10 + Python3 + selenium + geckodriver で headless Firefox を試してみる
##WebDriverのインストール
[WebDriver](https://developer.mozilla.org/ja/docs/Web/WebDriver)より geckodriver-v0.26.0-win64.zip をダウンロード後
適藤なフォルダに解凍する -> C:\Dev\Tools\geckodriver-win64
上記のフォルダを環境変数に登録する
##python用のパッケージをインストールする

<pre>
> pip3 install selenium
</pre>

#サンプルコード

```python
from selenium import webdriver
from selenium.webdriver.firefox.options import Options

# ブラウザーを起動
options = Options()
options.binary_location = 'C:\\Program Files\\Mozilla Firefox\\firefox.exe'
options.add_argument('-headless')
driver = webdriver.Firefox(options=options)

# Google検索画面にアクセス
driver.get('https://www.google.co.jp/')

# htmlを取得・表示
html = driver.page_source
print(html)

# ブラウザーを終了
driver.quit()
```
#参考にしたサイトはこちら
[WebDriver](https://developer.mozilla.org/ja/docs/Web/WebDriver)
[Seleniumブラウザー自動化プロジェクト > WebDriver > ドライバー要件](https://www.selenium.dev/documentation/ja/webdriver/driver_requirements/)
[【Python】SeleniumでHeadless Firefoxを使おう](https://qiita.com/derodero24/items/9b38bc4ca99bfd8d5ea3)
[Selenium Python(ABC順)](https://www.seleniumqref.com/api/webdriver_abc_python.html)
読書要点「プリンシプルオブプログラミング」第1章, 第2章

# 第1章 前提

プログラミングの性質とも言える前提知識である。
これを受け入れてプログラミングに取り組む必要がある。

###プログラミングに銀の弾丸はない

プログラミングには、「とりあえずこれをすればいい」という特効薬はない。
プログラミングの成果物はソフトウェアだが、ソフトウェアの性質はそもそも困難性を持っている。
ソフトウェアの困難性を示す性質は以下のとおりである。

- 複雑性
- 同調性
- 可変性
- 不可視性

困難性を示すソフトウェアを構築するためのプログラミングという工程も当然困難なものになる。
プログラミングの歴史の中で、複雑さに対抗する手段がいくつも提案されてきている。
歴史に学ぶことはプログラミングの困難性に対抗するヒントとなりうる。

###コードは設計書である

プログラマーが行うソフトウェアの設計からデバッグに至るまで、全ては設計行為である。
プログラミングの成果物であるコードは設計書である。

製品の改良は基本的に設計時に行うが、プログラミング全体が設計行為である以上、「基本設計」「詳細設計」「プログラミング」「テスト」「デバッグ」はどれも不可分な作業であることを認識しなければならない。
これらの不可分な一連の作業は、一種の創造行為であり、人と分担して行うことはそれなりに難しいことである。

コードは設計であるため、コードはできるだけ早く書き始めたほうがいい。
不明確な部分だらけで、いつまでも設計が終わらないからである。

###コードは必ず変更される

ソフトウェアの持つ可変性を考えれば、コードは使い捨てではなく何度も使いまわされるという性質を持っていることになる。
アップデートを繰り返し常に変更されうるという前提のもとコードを書く必要がある。
そのため前提として、コードは変更に強いものを書く必要がある。
書く時間が増えたとしても、それ以降の変更に強いコードになれば十分に元を取れる。

# 第2章 原則

多くの場合に共通して適用されるべき、プログラミングにおける決まりごとである。
ただし絶対ということはなく、状況に応じて調整していくことができれば良いコードを書くことに繋がっていく。

###KISS

コードはシンプルに保ち、単純かつ簡潔であるべきだということである。
コードは意識しなければ複雑になっていく。
複雑になるほど修正されにくく、腐ったコードになっていく。
コードは変更されるものであるため、修正容易性を度外視した複雑なプログラムを組んではいけない。

単純性、簡潔性の維持のためにはコードに余計なことをしないことが重要である。
単純であるほど結果的に応用が効きやすく、様々な状況に対応しやすいことも念頭に置いておきたい。


###DRY

同じコードを重複して書いてはいけないということである。
重複を許してしまうと、コードを読む側は同じ記述を複数回読むことになり無駄が生まれる。
コードの修正時も、似たような記述を何度も正確に修正しなければならず、大きな労力が必要になる。

コードから重複を排除するためには、コードを抽象化するのがよい。
つまり、処理のまとまりを関数化、モジュール化する。
抽象化自体が労力や時間を要する作業だが、重複による将来的なリスクの発生よりはよほど良い。
多くのプログラミングに関わる技術は重複を避けるための機能を備えているため、上手に活用してDRYを実現したい。

###YAGNI

コードは必要最低限のものだけを書くべきだということである。
これから使うかもしれないといって追加したコードは結局利用されないことがほとんどである。
また、そのことによって余計な複雑性を盛り込み、KISSの原則に逆らうことにもつながる。

汎用性よりも単純性を求め、コードに余計なことをしないという意識が重要である。
一見単純に見えるコードのほうが汎用的に使えるケースも多い。


###PIE

コードを人が読む表現として書くべきだということである。
ソフトウェアの動作を真に記述しているのはコードだけであり、人に意図を伝えるためには最終的にコードを読んでもらうことになる。

コードは書かれることよりも読まれることのほうが多い。
書く時間が長くなってしまっても、読みやすいコードを書いたほうが価値として高くなる。
コードで表現できない場合は積極的にコメントも利用するべきである。

###SLAP

コードを書くときは抽象レベルを統一するべきだということである。
つまり階層構造を作り、同じ抽象レベルの概念をまとめていくべきだということである。
SLAPの実施により、コードに要約性と閲覧性が生まれる。
読む側も目的に応じてどの階層に着目すればいいのかがわかりやすくなる。

上手に階層化されたコードは、スッキリとした1冊の書籍のようにとても読みやすいものとなる。

###OCP

拡張に対して開いている、修正に対して閉じているコードを書くべきだということである。
性質として変更され続けるソフトウェアは、変更に対して柔軟であるべきだ。
柔軟であることに必要な要素が「閣僚に対して開いている」「修正に対して閉じている」ことだ。

クライアントとサーバの間にクライアントインターフェースを用意して設計するのが良い。
それによってクライアントは、サーバーの変更に際して最小限の変更で済むようになる。
ただし、過剰なOCPの適用は無駄で冗長なコードを生み出すことにつながる。
変更が起きそうな場所を予測する、あるいは運用の中で変更が必要な場所を掴んでいく必要がある。

###名前重要

プログラミングにおいて、命名を最重要な問題として取り組むべきだということ。
わかりやすい名前は、そのメンバの責務を伝えつつ、内部処理の詳細を隠蔽してくれる。
結果としてそのメンバを読むのが楽になり、それを使用してコードを書く行為も楽になりそのコードを読むことも楽になる。
一方で悪い命名は逆の効果を生み、負債のようにマイナスの影響を与え続ける。

名前重要を達成するためには、使う側、読む側を意識しつつはじめに命名することを意識するのが良い。
Cognos Analytics カスタムビジュアライゼーション 開発環境セットアップ

#カスタムビジュアライゼーション 開発環境セットアップ
カスタムビジュアライゼーションの開発環境をセットアップする手順を記載します。
前提として、端末がCognos Analyticsサーバーに接続可能な環境である必要があります。

**NodeJS/NPMのダウンロード**
以下のリンクから、Nodes.jsのバージョン10をダウンロードします。
※ここでは「node-v10.19.0-x64.msi」をダウンロードしています。
<img width="608" alt="001.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/04dd77e5-5fa8-0fce-d2f1-ab04ad0a5e1b.png">

**NodeJS/NPMのインストール**
ダウンロードしたモジュールをクリックしてインストーラーを起動します。
※全てDefaultのままでインストールを行います
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/02ad7441-d663-aecf-6282-99d8afb1d049.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/0f1c7ae6-522b-1113-7103-f481dd8db48b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/5a94d8be-f57f-696f-dd87-77484d0da1f9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/ab610b51-958a-5003-5d19-3d78cd0876fc.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/c69bfe30-457e-07b3-440f-d51c39ba86eb.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/5d31b82d-aa13-5d8d-eac8-e003acc212f0.png)

**CognosAnalyticsの視覚化CLIツールのダウンロード**
Chromeブラウザから、以下のURLにアクセスしてツールをダウンロードします。
http://CognosHost:9300/bi/js/vida/customvis.tgz

**CognosAnalyticsの視覚化CLIツールのインストール**
Windowsのコマンドプロンプトを起動し、任意のパスで下記コマンドを実行しインストールを開始します。

```html
npm install -g customvis.tgz
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/629e353f-19d6-b819-1e9a-c73211c28119.png)

以上で開発環境のセットアップは完了です。

#参考情報
**IBM Cognos Analytics 11.1 R4 のカスタム視覚化のためのステップバイステップ・ガイド - 開発環境のセットアップ**
https://www.ibm.com/support/knowledgecenter/ja/SSEP7J_11.1.0/com.ibm.swg.ba.cognos.dg_custom_vis.doc/ca_customviz_tutstepbystep1.html

#目次
**Cognos Analytics カスタムビジュアライゼーション機能の紹介**
https://qiita.com/shinyama/items/0adde0d1665a4e385faa
Cognos Analytics カスタムビジュアライゼーション機能の紹介

#カスタムビジュアライゼーション概要
Cognos Analyticsの「カスタムビジュアライゼーション」機能を、何回かに分けて紹介します。カスタムビジュアライゼーションは、一言でいうと「d3.jsでCognosのグラフを自作する」機能です。
Cognos製品のデフォルトに無いグラフを使用する要件が出てきた時に、必要になってくる技術ですね。
技術的には、Cognosの技術というよりd3.jsの技術が重要なので、Cognosはやって来たけどd3.jsはやって来んかった～、という人(私も・・・)は是非この機会にd3.jsを学ぶとCognosスキルの幅が広がると思います。

d3.jsの技術さえあれば、こんなグラフが自在に作れてしまいます。
お客様の無茶ぶりに「Cognosではできませんよ～」ではなく、「ああ、まあ、自分で作りますから良いですよ」と、さらっと言えるとかっこいいですね。
<img width="576" alt="004.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/5054e929-5de0-bfd9-4ea1-3d31bdc4b3bb.png">

#構成
カスタムビジュアライゼーション(以降CuVis)の開発は、以下のような構成で行います。
Cognosサーバーにつながる端末に、nodes.jsを導入し、CuVis環境を立ち上げ、エディタ上でd3.jsでコーディングをして、ブラウザからCognosにアクセスして、開発イメージの確認やパッケージとしてアップロードを行います。
<img width="499" alt="001.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/359b05f4-fe79-35ad-6f17-20413350034e.png">


#目次
**Cognos Analytics カスタムビジュアライゼーション 開発環境セットアップ**
https://qiita.com/shinyama/items/613ffd5ede5924406348

**Cognos Analytics カスタムビジュアライゼーション 基本の操作**
https://qiita.com/shinyama/items/e1a235a03d8f9978af35

**Cognos Analytics カスタムビジュアライゼーション チュートリアル - visdef.xmlの説明**
https://qiita.com/shinyama/items/2f3cdf902c8de39d29ca
leet code easy Roman to Integer Approach 1: Left-to-Right Pass

Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M.

Symbol       Value
I             1
V             5
X             10
L             50
C             100
D             500
M             1000
For example, two is written as II in Roman numeral, just two one's added together. Twelve is written as, XII, which is simply X + II. The number twenty seven is written as XXVII, which is XX + V + II.

Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used:

I can be placed before V (5) and X (10) to make 4 and 9. 
X can be placed before L (50) and C (100) to make 40 and 90. 
C can be placed before D (500) and M (1000) to make 400 and 900.
Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from 1 to 3999.

```python
class Solution:
    def romanToInt(self, s: str) -> int:
#ローマ数字と数字の辞書を作りwhileループで検索していく
        v ={"I":1, "V":5, "X":10, "L":50, "C":100, "D":500, "M":1000}
        total = 0
        i = 0
        while i < len(s):
#この問題はの難しい点は、4,9の二つ。それ以外の時は、左から右に数字が小さくなっていく。そのため、下記では、左から右に数字が「大きくなる例外」だけifで条件分岐した。
            if i + 1 < len(s) and v[s[i]] < v[s[i + 1]]:
#例外の時 (IXなど)は、右側の数字（X）から左側の数字(I)を引いた値を、totalに加える。
                total += v[s[i+1]] - v[s[i]]
                i += 2
            else:
                total += v[s[i]]
                i += 1
        return total

```