OmniAICreator/Qiita-1.07M huggingface dataset:
librosaを使って音楽で遊んでみる

私は音楽大好き人間なんですが、`librosa`というPythonライブラリを使うと音楽を簡単に分析できるらしい！ってことで遊んでみました。（ちなみに音響工学的な話は無知です）

# 準備物
* Jupyter notebook
* python3.7
* [librosaライブラリ](https://pypi.org/project/librosa/)
* numpy
* matplotlib
* 適当な音楽ファイル（mp3）

# まずは音楽ファイルを読み込んで再生
```python
import librosa
import IPython
import librosa.display
import matplotlib.pyplot as plt
import numpy as np
import matplotlib as mpl

y_full, sr_full = librosa.load("/path/to/sample.mp3")
IPython.display.Audio(data=y_full, rate=sr_full)
```

全部再生されますね。jupyter notebookは音楽の再生もできてすごい。

# 音楽ファイルのうち、一部を取り出してみる
```python
y, sr = librosa.load("/path/to/sample.mp3", offset=115, duration=15)
IPython.display.Audio(data=y, rate=sr)
```
音楽ファイルのうち、115秒〜130秒の区間のみ再生されました。
これ以降のフェーズはファイルがでかいと時間がかかったりグラフが潰れたりするので、小さくしておきます。

# BPMを取り出してみる
```python
tempo, beat_frames = librosa.beat.beat_track(y=y, sr=sr)
print(tempo)
# 129.19921875
```

# 音源を調波音と打楽器音に分解（HPSS）
```python
y_harmonic, y_percussive = librosa.effects.hpss(y)
IPython.display.Audio(data=y_harmonic, rate=sr)
IPython.display.Audio(data=y_percussive, rate=sr)
```

これ、面白い。
旋律や和声を表現する調波音（`y_harmonic`）とリズムを表現する打楽器音（`y_percussive`）が分離された音源が生成されます。「HPSS（Harmonic Percussive Sound Separation）」という手法らしく、検索すると論文などがいくつかでてきます。

ただし、やってみるとわかりますが、例えばベース・ピアノ・ドラムというオーソドックスなJazzトリオの演奏であっても、ドラムとピアノが綺麗に分離することはなく、打楽器音のほうにピアノが入ってきたり、調波音のほうにシンバルが入ってきたりはするようです。まぁリズムをとっている音はドラムだけではなく、ピアノやベースもリズム作っている部分があるので当然ですね。

### margin調整で分離を顕著に
marginを調整すると、もっと分離が顕著になります。

```
y_harmonic_m3, y_percussive_m3 = librosa.effects.hpss(y, margin=3.0)
```

marginを設定することで、調波音とも打楽器音とも言えない微妙な音を取り除くようです。大きくするほど分離が強くなり、音も少なくなっていきます。
librosaではこの辺の[論文](http://www.terasoft.com.tw/conf/ismir2014/proceedings/T110_127_Paper.pdf)をもとに実装されている様子。

### グラフで理論を理解する
この分離は、「調波音のスペクトログラムは時間方向に滑らか」、「打楽器音のスペクトログラムは周波数方向に滑らか」という特徴を利用しているようです。何をいっているのかよくわからないですが、グラフにしてみるとちょっと理解できた気がします。

スペクトログラムは[wikipedia](https://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%9A%E3%82%AF%E3%83%88%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0)によると「横軸が時間を表し、縦軸が周波数を表す。そして、各点の明るさや色である時点のある周波数での強さ（振幅）を表す。」グラフだそうです。

[librosaのドキュメント](https://librosa.github.io/librosa/generated/librosa.decompose.hpss.html#librosa.decompose.hpss)にexampleがあったので拝借しました。

```python
D = librosa.stft(y)
H, P = librosa.decompose.hpss(D, margin=3.0)

plt.figure()
plt.subplot(3, 1, 1)
librosa.display.specshow(librosa.amplitude_to_db(np.abs(D), ref=np.max), y_axis='log')
plt.colorbar(format='%+2.0f dB')
plt.title('Full power spectrogram')

plt.subplot(3, 1, 2)
librosa.display.specshow(librosa.amplitude_to_db(np.abs(H), ref=np.max), y_axis='log')
plt.colorbar(format='%+2.0f dB')
plt.title('Harmonic power spectrogram')

plt.subplot(3, 1, 3)
librosa.display.specshow(librosa.amplitude_to_db(np.abs(P), ref=np.max), y_axis='log')
plt.colorbar(format='%+2.0f dB')
plt.title('Percussive power spectrogram')

plt.tight_layout()
plt.show()
```

こんな感じででてきました。確かに調波音は横に滑らかな一方、打楽器音は縦方向に滑らかに伸びています。

![spectrogram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24894/4134f59a-fcb2-29bc-5ebf-f597b376826a.png)

とりあえずここまで。音響の基礎的なことを理解していないのでもうちょい知らないとな。
AWSーAlibaba Cloud間をVPNでつないでみた

AWSとAlibaba Cloudの間をIPSec VPNでつないでみました。



# 構成

AWS側にVirtual Private Gateways、Alibaba Cloud側にVPN Gatewayを用意して、両者をIPsec VPNで接続します。

![vpn.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192584/febc5cd0-6ffa-0ab0-23b4-6e1a5836d572.png)


# 接続結果

AWS側

<img width="657" alt="aws_tunnel.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192584/9afa76af-22bd-7ee9-c91e-e63110f9e151.png">


Alibaba Cloud側

<img width="1446" alt="ali-conn.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192584/dd7a8530-59d3-b791-23ca-c9391d240c1e.png">


Pingの結果 (AWS->Alibaba Cloud)

<img width="401" alt="aws-ping.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192584/0691957c-c8d4-3fef-8d44-e0628600500c.png">


Pingの結果 (Alibaba Cloud->AWS)

<img width="422" alt="ali-ping.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192584/c40132b1-7ce9-4f15-9903-b1dfe37818ee.png">


# 必要なもの

- Alibaba Cloudのアカウント
- AWSのアカウント

# 構築手順
お互いのGlobal IPと事前共有鍵の設定が必要になるため、交互に作成すると無駄なく作成できると思います。

1. Alibaba CloudでVPN Gatewayを作成する
2. AWSでVirtual Private Gatewayを作成する
3. Alibaba CloudでCustomer Gatewayを作成する
4. AWSでCustomer Gatewayを作成する
5. Alibaba CloudでIPsec Connectionを作成する
6. AWSでVPN Connectionを作成する
7. Alibaba Cloudでルーティングを設定する
8. AWSでルーティングを設定する


- AWSのVPN設定手順
    - https://docs.aws.amazon.com/ja_jp/vpn/latest/s2svpn/SetUpVPNConnections.html
- Alibaba CloudのVPN設定手順
    - https://jp.alibabacloud.com/help/doc-detail/65072.htm?spm=a21mg.p38356.b99.7.646a2e9bLKzpEk


### 3. Alibaba CloudでCustomer Gatewayを作成する

- AWS側はトンネルが2個できるので、それに合わせてCustomer Gatewayも2個作成する
- Alibaba CloudのCustomer GatewayのIPは、AWSのトンネルのOutside IP Addressをそれぞれ設定する

### 4. AWSでCustomer Gatewayを作成する

- AWSのCustomer GatewayのIPは、Alibaba CloudのVPN GatewayのIPを設定する

### 5. Alibaba CloudでIPsec Connectionを作成する

以下が手元で接続確認できた設定値となります。

|名前|値|
|---|---|---|
|VPN Gateway|作成したVPN Gatewayを選択|
|カスタマーゲートウェイ|作成したカスタマーゲートウェイを選択|
|ローカルネットワーク|Alibaba Cloud側VPCのCIDR|
|リモートネットワーク|AWS側VPCのCIDR|
|**高度な設定**|
|**IKE 構成**|
|事前共有鍵|自動で設定|
|バージョン|ikev2|
|ネゴシエーションモード|main|
|暗号化アルゴリズム|aes256|
|認証アルゴリズム|sha256|
|DHグループ|group2|
|SA ライフサイクル (秒)|86400|
|LocalId|自動で設定|
|RemoteId|自動で設定|
|**IPsec 構成**|
|暗号化アルゴリズム|aes256|
|認証アルゴリズム|sha256|
|DH グループ|group2|
|SA ライフサイクル (秒)|86400|

### 6. AWSでVPN Connectionを作成する

- Alibaba Cloudで設定した事前共有鍵を、Pre-Shared Keyに設定する
- 他はデフォルト値のまま

# 雑感

AWS側、Alibaba Cloud側ともマネージドのVPNサービスでVPN接続ができるとは思ってませんでした。
kaggleでOpenCVのカスケード分類器を使う(備忘)

# 要約
カスケードファイルはデフォルトでカーネル内に落ちてます。
パスは "/opt/conda/lib/python3.6/site-packages/cv2/data"
そのまま読み込んで使いましょう。

# はじめに
最近Kaggleで画像系コンペが増えてきましたね。
画像コンペはKaggleのカーネルではパワー不足な時がありますが、
もしかしたら需要あるかもしれないので、KaggleのNotebook内でOpenCVのカスケード分類器を使用する方法を書きます。

# コード

ちなみにGANコンペで使用したコードです。

```python
import cv2
path = cv2.data.haarcascades + 'haarcascade_{}.xml'
cascade_files = [
    cv2.CascadeClassifier(path.format('upperbody')),
    cv2.CascadeClassifier(path.format('lowerbody')),
    cv2.CascadeClassifier(path.format('frontalface_default')),
    cv2.CascadeClassifier(path.format('frontalface_alt')), 
    cv2.CascadeClassifier(path.format('frontalface_alt2')), 
]
def check_human(img):
    img = np.asarray(img)
    for clf in cascade_files:
        gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
        pos = clf.detectMultiScale(gray)
        if len(pos) != 0:
            return False
    return True
```

## 分類器一覧

```bash
!ls /opt/conda/lib/python3.6/site-packages/cv2/data | grep xml

haarcascade_eye.xml
haarcascade_eye_tree_eyeglasses.xml
haarcascade_frontalcatface.xml
haarcascade_frontalcatface_extended.xml
haarcascade_frontalface_alt.xml
haarcascade_frontalface_alt2.xml
haarcascade_frontalface_alt_tree.xml
haarcascade_frontalface_default.xml
haarcascade_fullbody.xml
haarcascade_lefteye_2splits.xml
haarcascade_licence_plate_rus_16stages.xml
haarcascade_lowerbody.xml
haarcascade_profileface.xml
haarcascade_righteye_2splits.xml
haarcascade_russian_plate_number.xml
haarcascade_smile.xml
haarcascade_upperbody.xml
```
plantumlの図の要素とソース行を紐付けるために、行番号とを追加する

テキストファイルからUML図を生成できるplantumlはとても便利です。
しかし、図を見て更新したい箇所がある場合に、ソースの位置を特定するのにワンクッションあります。

そこで、UML図にソースファイルの行番号を付加することを考えました。
以下のようなソースファイルがあるとします。

```plantuml:act.pu
 1: @startuml
 2: 
 3: start
 4: 
 5: if (Graphviz installed?) then (yes)
 6:   :process all\ndiagrams;
 7: else (no)
 8:   :process only
 9:   __sequence__ and __activity__ diagrams;
10: endif
11:
12: stop
13: @enduml
```

このソースファイルからは、以下の図が生成されます。

![LOwn3i8m34HtVuN7zXTWW8sVG8ginAMMKYV4QQNmzHWcsExUdKvtjKwjxri6-2e0MN2wDQhh8IyKTPepfykCVMN5QR3DW7YghKGsGq_lceGUZJOx0sTZdBJyTOhcuJu4u-VE6Za494qEA7Ovf0y7Fnk-jtp-bFe6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164821/8d8ceac0-c894-6551-a2e5-8309f5ba13e7.png)

awkで、ソースファイルの”:”に行番号をつけることにします。

```
$ cat act.pu | gawk '{print gensub(/(^ *:)/, "\\1**"NR"**:", $0)}'
```
以下のように図に行番号が追加されるので、図を変更したい場合は、その行番号付近を修正すれば良いことがわかります。

![JOun2iCm40JxUyMLjXuGWbF4NJuH448wnmBvvEXaW_pwN48ATxl3iEmerPMwBGdWbm3YXDsZk7NUuu6HbQP4uTvZdOcnQoGz80x6N8mPrf8zYQ0wJmxHlOfRv0QKXB3Z_3Ul9pDpQagj5Nfln9wiHST1WVCrxh4s1QSbNPs-t_8AenPz-W40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164821/87ab2755-35f3-7634-3454-8b02c6f7618c.png)

このくらいの図ではあまりメリットは感じられませんが、もう少し大きくなると瞬時にわかって便利です。
副次効果としてユニークなIDがつくメリットもあります。
Next focusなどcssの擬似クラス

# Next.jsでfocusなどの擬似クラスを書くとき

ReactではCSSを書くときにinline stylesで書けます。
しかし、Next.jsで擬似クラスを書こうとしたら、うまく反応してくれなかったので、
Styled JSXを使った時のメモをを残します。

## 問題点
inline stylesでCSSを記載していたのですが、何故か:focusなどの擬似クラスが反応してくれませんでした。

```jsx
import React from 'react'

// ex
const Password = () => {
  return (
    <input type='password' style={style} />
  );
}

// :focusの部分が擬似クラスとして読み込まれていない？
const style = {
  border: '1px solid #1b2538',
  ':focus': {
    border: '1px solid #1976d2',
  }
}
```

## 改善
Nextでは「Styled JSX」モジュールがデフォルトで含まれているので、こちらの書き方に直したら擬似クラスも反応してくれました。

```jsx
// ex
import React from 'react'

const Password = () => {
  return (
    <div>
      <input type='password'/>
      // 変更箇所
      <style jsx>{`
      input {
        border: 1px solid #1b2538;
      }
      input:focus {
        border: 1px solid #1976d2;
      }
      `}</style>
    </div>
  );
}
```

こちらのモジュールのいいところは、CSSをフルサポートしているので、box-shadowなど要素をそのまま書けること。
わざわざキャメルケースに直したりする必要をないので、使いやすくて楽です。

## まとめ
Next.jsでCSSを書くときは「Styled JSX」モジュールがデフォルトで組み込まれているので、このモジュールを積極的に使っていく。

## 補足
ReactとかJSが得意な者の記事ではありません。
問題点の原因がわかる方がいたら教えていただけると助かります。
Vue.tsをDockerに構築

#Vue.tsをDockerに構築したい
Vue.jsをDockerに構築をする方法はあったんですが、Vue3.0からTypeScriptが対応されたとの事だったのでせっかくならTSでやりたいと思ったので自分なりにやってみました。
OSはMacです。Dockerが入ってる前提で進めます。
##Dockerfileを用意
```dockerfile

FROM node:8.11.3-alpine

WORKDIR /app

RUN apk update && \
    npm install -g @vue/cli

EXPOSE 9000

CMD ["/bin/sh"]
```
##コンテナのイメージをビルド
```console
$ docker build -t vue_app_image .
```
##ビルドしたイメージからコンテナを起動
```console
$ docker run -v `pwd`:/app -p 9000:9000 --name vue_app -it -d vue_app_image
```
##コンテナに入ってvueプロジェクトの準備
```console
$ docker exec -it vue_app sh
```
##コンテナ内でのコマンド
ここからが情報をかき集めて自分なりに行った方法です。
###webpackが無いとエラーが出るのでインストールします。
```console
/app # npm install --save-dev webpack webpack-cli webpack-dev-server
```
###カレントディレクトリにVue Projectを作成
```console
/app # vue create .
```
Manually select features を選択した後に使用言語を選ぶのでTypeScriptを選択します。
###vue.config.jsをプロジェクトルートに作成
プロジェクトルートにvue.config.jsを作成すると自動で読み込まれるようです。すげえ

```js

module.exports = {
    devServer: {
        host: '0.0.0.0',
        port: 9000,
        disableHostCheck: true,
    },
};
```
###実行
```
/app # npm run serve
```
`http://0.0.0.0:9000/`にアクセスするとVueの画面が出てくるかと思います。
もっといい方法があれば教えてください。VueもDockerもまだまだなので...

#参考サイト
https://qiita.com/nrslib/items/be90cc19fa3122266fd7
https://qiita.com/rh_taro/items/ca08b930f704275286a4
https://log.pocka.io/posts/vue-webpack-tutorial/
https://dev.classmethod.jp/client-side/spa/change-vue-project-devserver-port/
vuejs-datepicker使ってみた

# vuejs-datepickerとは
https://npmjs.com/package/vuejs-datepicker
vue.jsと組み合わせて、こんな感じでカレンダーから日付を選択出来る、npmモジュールです。
![スクリーンショット 2019-09-08 14.20.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286594/66d74dff-0060-b2fa-dcef-74fb8e5ecf77.png)

# 使い方
基本的に公式に書いてある通りですが

### 1 インストール
```terminal
npm install vuejs-datepicker --save
```
### 2 使いたいcomponentsにimport
```js
import Datepicker from 'vuejs-datepicker';
```
### 3 コンポーネントに登録
```js
components : {
  Datepicker
}
```
### 4 コンポーネントとして使う
```js
<Datepicker></Datepicker>
```


# 日本語化したい
### 1 使いたいcomponentにimport
```js
import {ja} from 'vuejs-datepicker/dist/locale'
```

### 2 dataに登録
```js
data () {
  return {
    ja:ja
  }
},
```

### 3 componentにlanguageをバインドする
```js
<Datepicker :language="ja"></Datepicker>
```
# 枠線を付けたり、中央寄せしたりしたい
そのまま使うと枠線すら無いため、多少はスタイルを当てて見栄えを整えたい。

###(結論)
div配下のinputタグに対してcssを当てたら上手くいった。

```html
<Datepicker :language="ja" class="test" placeholder="日付"></Datepicker>
```
```sass
  .test {
    div > input {
      border: 1px ridge #333333;
      display: block;
      margin-left: auto;
      margin-right: auto;
      text-align: center;
    }
  }
```
理由は、`vuejs-datepicker`タグの中に、さらに`div`タグがあり、その中にさらに`input`タグが入っているため。
![スクリーンショット 2019-09-08 15.00.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286594/049cff6a-4eac-e593-7068-990248b29578.png)

###(失敗)
**上から`div`要素を被せて、枠線を上書き**
→`div`タグの中の`input`タグは`inline`要素のため、上書きが出来ない。
Squidでproxy protocolを用いた送信元の制御

# 背景

AWS上のプロキシをNLBで冗長化したいが、NLBはNATしてしまうため送信元IPが全て同じになってしまうため、Proxy protocolを使用した制御を行う。

# 要件
プロキシの冗長化
ホワイトリストのURLフィルタリング
送信元IPをベースに認証

# squid
squidに下記設定を入れる。

```configuration:squid.conf
#ポートの指定とproxy接続時にproxy protocolを必須にする
http_port 8080 require-proxy-header 
#NLBのIPをACLに追加
acl nlb_ip src 10.0.0.1
acl nlb_ip src 10.0.1.1
#クライアントIPをACLに追加
acl client_ip src 10.0.0.10
acl client_ip src 10.0.1.10
#URLフィルタリング
acl whitelist dstdomain "/etc/squid/whitelist"
#Proxy Protocolの利用許可
proxy_protocol_access permit nlb_ip
proxy_protocol_access permit client_ip
#httpアクセスの許可
http_access permit nlb_ip
#クライアントの許可とホワイトリストの適用
http_access permit client_ip whitelist
```

```configuration:whitelist
google.com
```

# AWS 
1. EC2ダッシュボードから、ターゲットグループにアクセス
2. 対象のターゲットグループを選択し、アクション->属性の編集を選択する
3. Proxy Protocol v2の有効化にチェックを入れ、保存を選択する。

![nlb_proxy_protocol.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393044/d49828cd-5427-fa01-490b-826317b036ff.png)

![nlb_proxy_protocol_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393044/f736b3c5-7fa9-2581-65f9-46d19b395484.png)


# その他注意事項など
- NLBのIPも```proxy_protocol_access```で許可しないとだめ
- CLBを使う場合はサブネットを指定して許可する
- NLB側でProxy Protocolを有効にしたときはSquid側もproxy protocolを有効にしないとうまくアクセスができなくなる逆にNLB側を無効にしてもアクセスできない。つまり、両側で有効・無効がマッチしていないとダメ

- ```http_access permit```は一致するルールがあると以降のルールを評価しないためAND条件を適用したい場合は同一行に記載する

# 参考
http://blog.serverworks.co.jp/tech/2018/04/13/clb-proxyprotocol/
もしもHerokuへのpushに失敗したら

heroku push　が失敗した場合は以下のコードを実行する。

```ruby:qiita.rb
git config --global url.ssh://git@heroku.com/.insteadOf https://git.heroku.com/
```


その後、

```ruby:qiita.rb
heroku push
```

を実行するとうまくいった。
GAS（googleappsscript）初心者入門

# logの出し方

https://tonari-it.com/gas-logger-log/

* Logger.log();を記述
* 実行
* ログ

# GASのコードをgithubで管理

２つ方法があって

* localにGASのコードを持っていき、githubにpushする
* chrome拡張でgasのeditorを使いながらgithubにpushする

editorを普段自分が使っているものでやりたいかgasのでやりたいかによって分けると良さそう。

chrome拡張でgithub管理するなら下記の記事が詳しい
https://tadaken3.hatenablog.jp/entry/gas-github

# ライブラリの追加

https://tks-kan.com/2018/12/14/4536/

この記事がいい感じにまとまってる
GAS（googleappsscript）でのスクレイピング方法まとめ

# この記事の目的

* GASでのスクレイピングのやり方
* GASのスクレイピングでできること、いいこと

# GASでのスクレイピングのやり方

## IMPORTXMLを使う方法

Xpathとは
https://qiita.com/rllllho/items/cb1187cec0fb17fc650a

この記事がわかりやすい
https://msr036.com/2018/05/17/importxml/

## tableの取得はIMPORTHTMLが便利

https://strategy-conference.com/analysis/spreadsheet/1045/

GASとは少し違うがtableやlistの場合、IMPORTHTML関数でとってくるのが楽。

```
=ImportHTML(URL,"table",1)
```

でURLの1番目に来るtableタグ内の情報を抜いてくれる

## Parser（ライブラリ）をつかう

https://www.kotanin0.work/entry/2019/01/06/200000

parserライブラリを使うとfromとtoでスクレイピングしたい箇所を指定して.iterate()で配列を作れるからめっちゃ楽。

例えば下記のサイトで案件名のリストを取りたいなら

```javascript
function myFunction() {
  var html = UrlFetchApp.fetch('対象サイトURL').getContentText();
  var entries = Parser.data(html).from('開始タグ').to('終了タグ').iterate()
}
```

* UrlFetchAppでコンテンツをとってくる
* fromとtoにタグを設定
* iterateで対象のコンテンツを配列で渡す

## UrlFetchApp.fetchを使う

* activeなsheetを取得
* UrlFetchApp.fetchで他サイトにアクセス
* .getContentText()でコンテンツ取得
* find関数を定義して開始タグと終了タグの間のコンテンツを抜いてくる
* setValueで値を入れる

https://qiita.com/standard-software/items/16214dc4e64d28952c2d

```javascript
function webScraping(){
  var sheet = SpreadsheetApp.getActiveSheet();
  var response = UrlFetchApp.fetch("https://qiita.com").getContentText();
  var header = find(response, '<title>','</title>')
  sheet.getRange(1, 1).setValue(header)
}
function find(text, from, to) {
  var fromIndex = text.indexOf(from);
  if (fromIndex === -1) return '';
  text = text.substring(fromIndex + from.length);
  var toIndex = text.indexOf(to);
  if (toIndex === -1) return '';
  return text.substring(0, toIndex);
}
```

# GASのスクレイピングでできること、いいこと

* 定期実行が楽
* とってきたデータの編集も楽
* 共有もしやすい
Webサーバ調査でよく使用したLinuxコマンド

<h1>Apache周り</h1>
```
# Apacheの起動
sudo systemctrl start httpd.service

# Apacheの再起動
sudo systemctrl restart httpd.service

# Apacheの状態を確認
sudo systemctl status httpd.service

# Apacheの停止
sudo systemctl stop httpd.service
```

<h1>プロセスの確認</h1>
```
# すべてのプロセスの一覧を確認
ps aux
```
<h3>オプション</h3>
`a`:端末操作の他ユーザのプロセスを表示
`u`CPUやメモリの使用率を表示
`x`端末操作以外のプロセスを表示

<h1>ネームサーバー確認</h1>
```
dig <ドメイン名> NS +short
```
<h3>オプション</h3>
`NS`:ドメイン名に対応するNSレコードを取得
`+short`:IPアドレスだけ表示
RailsでRestした時のメモ

##はじめに
いつもはJavaなのですがスキルアップのため、RailsでRestを作ってみました。

##前提条件
Rails 6.0.0

##プロジェクトの作成
Restを利用する時のRailsプロジェクトの作成は、下記のコマンドで行います。
```
rails new プロジェクト名 —api
```

##コントローラーの作成
Railsにはscaffoldというのがあり、それを使うとDBのレコードに対応した一覧・詳細のテンプレートが自動生成されるようですが、今回は使わずに下記コマンドで、コントローラーを作ります。
```
rails g controller rest_controller
```
コントローラーでは下記のようにするとクライアントへの戻り値がJSONとなるようです。
```
render json: res
```
また、リクエストパラメータの参照は下記のようにします。
```
params[:seq]
```

##ルーティングの設定
ルーティングとはリクエスト時のパスとコントローラとのマッピングですが、下記のようにします。矢印の右側はコントローラーのクラス名とメソッド名ですが、コントローラーを略して指定します。
```config/routes.rb
Rails.application.routes.draw do
　get '/DemoSample/GetImg' => 'rest#get'
end
```

##rack-corsを導入、設定
Gemfileにコメントアウトされたrack-corsへの参照があるので有効にした後、下記のコマンドを実行します。
``` 
bundle install
```
rack-corsを導入するとconfig/initializers/cors.rbが生成されるので、下記の設定を追加します。今回はget以外のメソッドは対応しないので、設定なしにします。
```config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins 'localhost:3000'
    resource '*',
             headers: :any,
             methods: %i[get options head]
  end
end
```
##静的ファイルの対応
Railsでは静的ファイルは、public配下に配置します。

##サーバーの起動
下記のコマンドでサーバを起動します。今回はJavaからの移行なのでポートは8080を指定します。
```
bundle exec rails server -p 8080
```

##動作確認する
Reactとの連携が確認できたので、rack-corsの設定も有効なようです。
HSVからRGBへの変換をGLSLで実装する

## 前提
[HSVからRGBへの変換 - Wikipedia](https://ja.wikipedia.org/wiki/HSV%E8%89%B2%E7%A9%BA%E9%96%93#HSV%E3%81%8B%E3%82%89RGB%E3%81%B8%E3%81%AE%E5%A4%89%E6%8F%9B)に基づいて、HSV色空間からRGB色空間への変換を実装する。変換の対象となるH, S, Vの定義は以下の通りとし、変換後のR, G, Bは0.0 - 1.0の範囲とする。

- H (Hue) : 色相
    - 0.0 - 360.0のfloat
- S (Saturation) : 彩度
    - 0.0 - 1.0のfloat
- V (Value) : 明度
    - 0.0 - 1.0のfloat

## 実装
円柱モデルと円錐モデルでわずかに異なる。
下記のコードでは円錐モデルを採用しているため`float c = s`となっているが、円柱モデルにする場合はこれを`float c = v * s`とすれば良い。

```glsl
vec3 hsvToRgb(float h, float s, float v) {
    // h: 0.0 - 360.0, s: 0.0 - 1.0, v: 0.0 - 1.0
    float c = s; // float c = v * s;
    float h2 = h / 60.0;
    float x = c * (1.0 - abs(mod(h2, 2.0) - 1.0));
    vec3 rgb = (v - c) * vec3(1.0, 1.0, 1.0);

    if (0.0 <= h2 && h2 < 1.0) {
        rgb += vec3(c, x, 0.0);
    } else if (1.0 <= h2 && h2 < 2.0) {
        rgb += vec3(x, c, 0.0);
    } else if (2.0 <= h2 && h2 < 3.0) {
        rgb += vec3(0.0, c, x);
    } else if (3.0 <= h2 && h2 < 4.0) {
        rgb += vec3(0.0, x, c);
    } else if (4.0 <= h2 && h2 < 5.0) {
        rgb += vec3(x, 0.0, c);
    } else if (5.0 <= h2 && h2 < 6.0) {
        rgb += vec3(c, 0.0, x);
    }

    return rgb;
}
```

以上
cssで背景画像のみを透過させる方法

#opacityを使うと...
要素を透過させるといえば、`opacity`を思い浮かべると思いますが、それだと背景画像だけでなく子要素の文字など全体が透過されてしまいます。

#背景画像のみを透過させる方法
そこでこのようにしました。

```css
 background-color:rgba(255,255,255,0.3);
 background-blend-mode:lighten;
```
うまくいきました。
<img width="1437" alt="スクリーンショット 2019-09-08 14.49.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491850/1a01a92c-e337-2e17-8612-84d40824bf7a.png">
各言語のコメントアウトを一覧にまとめる

# はじめに
コーディング中は良いですが、しばらく触れないと忘れるため、まとめます。

# コメントアウト一覧

| 言語               |     コメントアウト  |  補足 |  
|:-------------------|------------------|-------|  
| HTML               | <!-- comment --> |  |
| CSS                | /* comment */    |   |
| Javascript         | // comment       | 1行コメント  |
|                    | /* comment */    |   |
| Python             | # comment        | 1行コメント  |
|                    | ''' comment '''  |   |
|                    | """ comment """  |   |
| Java               | // comment       | 1行コメント  |
|                    | /* comment */    |    |
| PHP                | // comment       | 1行コメント  |
|                    | # comment        | 1行コメント  |
|                    | /* comment */    |    |
| SQL                | -- comment       | 1行コメント (※1)|
|                    | # comment        | 1行コメント (※2)|  
|                    | /* comment */    |   |  
| Unix Shell         | # comment        |  1行コメント |
| vim                | " comment        |  1行コメント |
| MS-DOS             | REM comment      |  1行コメント |
|                    | :: comment       |  1行コメント |
| PowerShell         | # comment        |  1行コメント |
|                    | <# comment #>    |   |
| VBA                | ' comment        |  1行コメント |
| JCL                | //" comment      |  1行コメント |
| Markdown           | \[](comment)     |  1行コメント |
|                    | <!-- comment --> |  (※3)     |

(※1) --の後ろに半角スペース要注意
(※2) MySQLが対応
(※3) HTMLと同じ記法が扱いやすい
（1行コメント内でバックスラッシュを区切っても複数行コメントは可能）

# 参考
[docs.python.org : 字句解析 - コメント]
(https://docs.python.org/ja/3/reference/lexical_analysis.html?highlight=%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88#comments)
[Codecampus : Pythonでのコメントアウトの方法とは？]
(https://blog.codecamp.jp/python-comment)
[JavaScriptのコメントはこう書くべし! 活用法まで徹底解説]
(https://www.sejuku.net/blog/28449)
[【Java】コメントの種類と書き方]
(https://qiita.com/mtanabe/items/2e52e6e162d28df8437f#java%E3%81%AE%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88%E3%81%AE%E7%A8%AE%E9%A1%9E)
[IBM support : DB2 SQLステートメント]
(https://www.ibm.com/support/knowledgecenter/ja/SSEPGG_11.5.0/com.ibm.db2.luw.sql.ref.doc/doc/c0056402.html)
[IBM support : JCLステートメント]
(https://www.ibm.com/support/knowledgecenter/ja/SSLTBW_2.2.0/com.ibm.zos.v2r2.ieab600/iea3b6_JCL_statements.htm)
[MySQLのコメント構文]
(https://qiita.com/ques0942/items/d89de1ff7c92b4810d10)
[kin29.info : MySQLとPostgreSQLのコメントの書き方のちがい]
(https://kin29.info/mysql%E3%81%A8postgresql%E3%81%AE%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88%E3%81%AE%E6%9B%B8%E3%81%8D%E6%96%B9%E3%81%AE%E3%81%A1%E3%81%8C%E3%81%84/)
[あおきのTechメモ : バッチファイルの「::」コメント]
(http://aoki1210.hatenablog.jp/entry/20080622/p1)
[バヤシタ : PowerShellコメントアウトの書き方]
(https://bayashita.com/p/entry/show/36)
[Markdown記法でコメントアウトする]
(https://qiita.com/yu0819ki/items/e1e1d20cedc68706ba23)

# おわりに
シェルスクリプトでは、このような技で複数行コメントアウトできるそうです。勉強になります。
[bashで複数行コメントアウトする方法]
(https://qiita.com/imura81gt/items/a2998147bd7ae8056b26)
令和元年度むろらんICTクラブ（終了しました）

いよいよ２０２０年からプログラミング教育が小学校で必修化されることから、室蘭地域の大人と子どもが楽しくプログラミング等を学びあう課外活動「むろらんＩＣＴクラブ」を開塾します。 デザインやアプリ制作、世代間の知識・経験の共有などを通じて楽しく学びあうことで、ＩＣＴに対して高い興味や関心を示す子どもたちを増やしていきます。

北海道工業都市ならではの取り組みを行い、将来的には、室蘭地域にて有能なＩＴ技術者が育つような土壌づくりの一端を担いたいと思います。

2019年度は年4回の事業を開催しました 
第1回　5月１8日　第2回　７月２０日　第３回　９月２８日　第４回　１１月１６日
【Rails】devise使っているのに@user多用してた話

# はじめに
Railsのdevisと言うgem非常に便利ですよね。
中でもcurrent_userと言うメソッドは非常に使い勝手が良くて重宝しています。

ですが、current_userと言うメソッド。
使いどころをちゃんと理解しておらず非効率に使っていました。

と言うことで、どう非効率だったか、振り返ります。

# 前提
ユーザ登録ではなく、ユーザ編集の時の話です。
また、current_user以外に対して操作したい場合は、この限りではありません。

# before
こんな感じで書いていました。
current_userを使って、わざわざインスタンスオブジェクトを作り出していた訳です。

```registration_controller.rb

def edit_profile
 @user = User.find(current_user.id)
end

def update_profile
 @user = User.find(current_user.id)
 @user.update(user_params)
 redirect_to :next_action
end

```

```edit.html.haml
  = form_with model:@user, url:users_edit_profile_path, method: :post,local: true do |f|
    = f.text_field :lastname, placeholder:'例) XX', value:"#{@user.lastname}"
    = f.text_field :firstname, placeholder:'例)XX', value:"#{@user.firstname}"
    = f.submit '変更する'

```

# After
わざわざ@userを噛ませる必要なんてなかったと言う事実。
@userもcurrent_userもUserモデルに対するインスタンス変数ですよね。。

```registration_controller.rb
def edit_profile
end

def update_profile
 current_user.update(user_params)
 redirect_to :next_action
end
```

```edit.html.haml
  = form_with model:current_user, url:users_edit_profile_path, method: :post,local: true do |f|
    = f.text_field :lastname, placeholder:'例) XX'
    = f.text_field :firstname, placeholder:'例)XX'
    = f.submit '変更する'

```

そもそも、プレーンなコントローラアクションを使っていればmodel指定さえすっ飛ばせるような？

# まとめ
こうやって書いていると理解していないことが多過ぎて、これをアップすることも憚られますが・・・
ただ、アウトプットしていかないと知らない、と言うことさえ知らずに過ごしてしまいそうなので頑張ります。
fullpageを使うときのメモ

fullpageプラグインを使うときの自分用メモです。
cssフォルダにfullpage.css、
jsフォルダにfullpage.jsを置いておくことを前提にします。

<h2>index.html</h2>

```html
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
```
をhtmlにカキカキ。

mainタグの中には

```html
<main id="fullpage">
 <div class="section"></div>
 <div class="section"></div>
 <div class="section"></div>
 <div class="section"></div>
 <div class="section"></div>
</main>
```

.sectionの部分がfullscreenで表示される。

<h2>custom.js</h2>

```html
<script type="text/javascript">
 $(function() {
  $('#fullpage').fullpage();
 });
</script>
```

横にスライドさせるslickみたいなのもあったけれど、使わなかったので今回は省略。
Node.jsでQRコードを読み込む


QRコードのデコードをNode.jsで行います。

[ハッカソン仙台](https://www.nict.go.jp/info/event/2019/09/07-1.html)で発生してた質問から記事化してみました。

> [Creating and Reading QR Codes with Node.js](http://thecodebarbarian.com/creating-qr-codes-with-node-js.html)

```
QRコード(画像) -> URLなどのテキスト
```

ってイメージです。

## 準備



## モジュールインストール

[qrcode-reader](https://www.npmjs.com/package/qrcode-reader)と[jimp](https://www.npmjs.com/package/jimp)を使います。

```bash
$ npm i qrcode-reader
$ npm i jimp
```

## コード

```app.js
'use strcit';

const QRReader = require('qrcode-reader');
const fs = require('fs');
const jimp = require('jimp');

async function run(IMAGE_PATH) {
  const img = await jimp.read(fs.readFileSync(IMAGE_PATH));
  const qr = new QRReader();

  const value = await new Promise((resolve, reject) => {
    qr.callback = (err, v) => err != null ? reject(err) : resolve(v);
    qr.decode(img.bitmap);
  });

  return value.result;
}

//呼び出し
run('./qr.png').then(res => {
    console.log(res);
})
```

## 実行

`app.js`と同じ階層に`qr.png`を設置して実行します。

```bash
$ node app.js
```
Rails datetimepickerがうまく動かなかったときの最終手段

当たり前に知っている人も多いと思いますが、私にとっては盲点だったので書いておきます。
#datepikerがうまく動かない
clearボタンを押すと画面が遷移してしまう。テーブルのセルに指定すると全く別の所に表示され、table-hoverにするとうまく表示されないなどトラブルが続出しました。それぞれ解決策はあるのですが、他の実装を変えるたびに違うトラブルが発生して面倒でした。
#意外な盲点　そもそも使う必要無くない?
恐らく大多数の方にとっては当たり前だと思いますが、`input type="date"`使えば良いじゃんとなりました。
見た目はこんな感じです。
<img width="263" alt="スクリーンショット 2019-09-08 14.10.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491850/e563fcad-1b5c-610c-b55f-90606b7cf047.png">
ブラウザ標準なので非常に安定していますし、複雑なコードを書かなくて良いので楽ですね。
もちろんViewヘルパーもあります。

~~~
=date_field_tag
=f.date_field
~~~

type属性は他にもmonth,color,rangeなど色々な値をとるので今度遊んでみたいと思います。
DAG(有向非循環グラフ)に対する最長経路問題（AtCoder Beginner Contest 139より）

最近はKaggleを優先していてなかなか競プロの時間を取れないのですが、AtCoderのABCには参加しています。

で、1週間遅れになってしまいましたが、先日のABC139でDAGの問題が出ました。
DAGは今後も重要そうな気がして、YouTube公式解説のC++のコードを読み解き、Python化しました。

#### 問題内容・解法

##### E - League

[https://atcoder.jp/contests/abc139/tasks/abc139_e:embed:cite]

解法の考え方については以下の公式解説が非常に分かりやすいです。

[https://www.youtube.com/watch?v=UWbGRhF3Ozw&t=8183s:embed:cite]

簡単に紹介しておくと、問題で与えられたデータは、リーグ戦をイメージして、各選手について対戦したい選手の順番が決まっているというものですが、これを試合idに読み替えます。
![190908_図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122973/3fc70869-e354-4767-c16d-050fc05b222c.png)
すると、これは<b>DAG(有向非循環グラフ)に対する最長経路問題</b>であると読み替えることができます。
![190908_図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122973/e6a011ee-8333-c1c0-5841-0110f1c88411.png)
上の例では、頂点Aから頂点Eへの移動が最長経路となり、値は4、つまり試合日程を全てこなすのに必要な最小の日数は4日である、ということになります。

DAGということはループが存在しないわけですが、この問題でなぜそう読み替えられるかというと、
「選手1はまず選手2と対戦したくて、選手2はまず選手3と対戦したくて、選手3はまず選手1と対戦したい」などというデータがあった場合、これを満たす試合日程を組むことはできないわけですが、これはグラフ上ではループとして検出できます。
問題文では条件を満たすように試合日程を組めなければ'-1'を返せと言っているので、ループが検出されたら'-1'を返すように実装することになります。

さて、以下がPythonによる実装になります。

```python
import sys
sys.setrecursionlimit(10**6)
readline = sys.stdin.readline

MAXN = 1005
MAXV = MAXN*(MAXN-1)//2
to = [[] for _ in range(MAXV)] # 頂点間の辺の情報
id = [[[] for _ in range(MAXN)] for _ in range(MAXN)] # 試合のid=DAGの頂点番号
def toId(i,j): # 選手idから試合idを返す関数
    if i > j: # i,jが逆になっても試合idは同じ
        i,j = j,i
    return id[i][j]

visited = [False]*MAXV
calculated = [False]*MAXV
dp = [1]*MAXV # Vからスタートしたときの最長経路。頂点の個数ベースで経路の長さを数えるので、初期値は1

def dfs(v):
    if visited[v]:
        if not calculated[v]:
            return -1 # 計算が終わっていない頂点を2度訪れるのはループがあるということ
        return dp[v]
    visited[v] = True
    for u in to[v]: # 全ての辺をなめる
        res = dfs(u)
        if res == -1: return -1 # ループがあれば-1を返す
        dp[v] = max(dp[v], res+1)
    calculated[v] = True
    return dp[v]

def main():
    n = int(input())
    a = [[int(i) for i in readline().split()] for _ in range(n)]
    for i in range(n):
        for j in range(n-1):
            a[i][j] -= 1 # 選手idを0始まりに変換
    V = 0
    for i in range(n):
        for j in range(n):
            if i < j:
                id[i][j] = V
                V += 1 # 0から順に各試合にidを割り振る
    for i in range(n):
        for j in range(n-1):
            a[i][j] = toId(i,a[i][j]) # 選手idを試合id(頂点番号)に置き換える
        for j in range(n-2): # 頂点間の依存関係はn-2個
            to[a[i][j+1]].append(a[i][j])
    ans = 0
    for i in range(V):
        res = dfs(i)
        if res == -1:
            print('-1') # ループがあれば-1を返す（問題文の指示）
            return
        ans = max(ans, res)
    print(ans)
    return

if __name__ == '__main__':
    main()
```

ここで（大）問題は、Pythonでsubmitすると一部のテストケースでTLEになってしまいます（泣）。
リスト内包表記を入れるとかしてチマチマ高速化しようか悩んでいたところ、Pypyでsubmitしてみるという手があることを知りました。

[https://juppy.hatenablog.com/entry/2019/06/14/Python_%E7%AB%B6%E6%8A%80%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E9%AB%98%E9%80%9F%E5%8C%96tips_%28Python%E3%81%A7Atcoder%E3%82%92%E3%82%84%E3%82%8B%E9%9A%9B%E3%81%AB%E5%80%8B:embed:cite]

Pypyで提出すると、無事ACとなりました。
低級言語への乗り換え圧力を強く感じましたが、なんとか乗り切ったことにします。
【Struts2】情報収集

#参考サイト
######随時ピックアップしているので記事内容が重複している部分があります。
[実践サンプルで学ぶStruts 2 - 生まれ変わった定番フレームワークを徹底解説](https://news.mynavi.jp/article/20071003-s_struts2/11)
※内容は古いので注意。考え方だけ参考にすること。

[Struts2(BeanとActionの分離) ](http://atmarkplant-dj.blogspot.com/2012/01/struts2bean.html)
※Beanと言う用語とは。

[Unit Testing（Struts2/Getting Start/）](https://struts.apache.org/getting-started/unit-testing.html)
※Actionクラスの単体テスト（struts2-junit-plugin）。

[Hibernateで理解するO/Rマッピング]
(https://www.atmarkit.co.jp/ait/series/2296/)
※15年前の記事なので注意。

[Struts2のValueStackのイメージを図解でざっくり理解【初心者向け】]
(https://yuki.world/struts2-valuestack/)
※Struts2超初心者向けです。

[Actionクラスに付与するインタフェースと機能](https://qiita.com/alpha_pz/items/10bfcf2661c713fca38e)
[Struts2 Sessionを使う](http://java-lang-programming.com/ja/articles/5)
※リクエストスコープ／セッションスコープで言うところのセッションか？
[Javaの道>Servlet・JSP>Servlet>4.セッション](http://www.javaroad.jp/servletjsp/sj_servlet4.htm)
※基本はこうだが。

[「作りながら学ぶJavaアプリケーションフレームワーク」連載一覧]
(https://codezine.jp/article/corner/47)
- [Struts 2入門（1）～基本形で理解する仕組みと構造～](https://codezine.jp/article/detail/2296)
- [Struts 2入門（2）～バリデーションの仕組みを理解する（前編）～](https://codezine.jp/article/detail/2391)
- [Struts 2入門（3）～バリデーションの仕組みを理解する（後編）～](https://codezine.jp/article/detail/2572)
- [Struts 2入門（4）～インターセプターという仕組み～](https://codezine.jp/article/detail/3264)
- [Struts 2入門（5）～Viewレイヤーの仕組み～](https://codezine.jp/article/detail/3565)
- [Struts 2入門（6）～XML不要のZero Configuration～](https://codezine.jp/article/detail/3837)
- [Struts 2入門（7）～データ連携の仕組み～](https://codezine.jp/article/detail/4060)
- [Struts 2入門（8）～Struts2で構築するToDoアプリケーション～](https://codezine.jp/article/detail/4214)
多分これが一番簡単だと思います。 WindowsでPython仮想環境構築 2019年

# この記事を読んで出来る事

Python2.7とPython3.7の仮想環境を構築してVS Codeで実行環境を切り替える。(※Pythonのバージョンは任意)

# 必要な環境

- Windows 10
- Visual Studio Code
- Python Extension Pack (VS Code拡張機能)
- Powershell 

# 新規にインストールされるパッケージ

- Python2.7
- Python3.7
- pipenv (pythonモジュール)

# 手順

## Python3.7をインストール
Python3.7
https://www.python.org/downloads/release/python-374/
※ PC環境に応じてどちらかを選択
32bit: Windows x86 executable installer
64bit: Windows x86-64 executable installer

※ 注意:「Add Path」はデフォルトで使いたいPythonのバージョンのみ設定。(ここではPython 3.7)

## Python2.7をインストール
Python2.7
https://www.python.org/downloads/release/python-2716/
※ PC環境に応じてどちらかを選択
32bit: Windows x86 MSI installer
64bit: Windows x86-64 MSI installer

※「Install just for me」を選択してPython3系のインストール先にあわせるのがオススメ
![py2-install-screenshot.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494172/1a9386cd-5f38-3a47-3c31-9f564e1b568a.jpeg)


## pipenvをインストール

Powershellを開いて、pythonがインストールされているか確認

```
PS> python --version
Python 3.7.3
```

pipenvをインストールする

```
PS> pip install pipenv
```

## pipenv用環境変数を設定
上の手順までで仮想環境は利用できますが、プロジェクト毎(フォルダ毎)に仮想環境を切り替えられたほうが取り回しがシンプルになるのでpipenv用の環境変数を設定します。(`Win` + `s` → `環境変数を編集`)

| 名前 | 設定値 |
|:---|:---|
|変数名|PIPENV_VENV_IN_PROJECT|
|変数値|True|

## 仮想環境を作成
```
PS> mkdir sample
PS> cd sample
PS> pipenv install --python 3.7
```
※ここでは仮想環境にpython 3.7を利用

## VS Codeで仮想環境の切り替え
1. VS Codeを起動して、上で作成したsampleフォルダーを開く。
2. 左下ステータスバーのPythonの文字をクリックして仮想環境を選択する
![vscode-switch-python-screenshot.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494172/55cf32bb-c02a-aa58-d666-64cae8854cf2.jpeg)

# 補足
仮想環境で使えるPythonはPCにインストールされている必要があります。
例えば、仮想環境でPython3.6.8を使いたい場合　

```
pipenv install --python 3.6.8
```
としてもPython3.6.8は使えません。Python3.6.8をインストール後`pipenv install`する必要があります。
github関連

githubで新しいブランチを作成する方法

現在のブランチ一覧を確認

　$ git branch

ブランチを作成

$ git branch hoge

作成したブランチに移動
$ git branch hoge

ブランチを作成＆作成したブランチに移動
$git checkout -b hoge2

ブランチをマージさせる
$ git merge hoge2
RailsでJavascript(jQuery)が画面遷移の時に動かないときは

#現象
リロードするときはカレンダーが表示されるが、link_toから画面遷移すると遷移するとJavaScriptがうまく動作しない。

#原因
Railsのturbolinksという昨日が原因でした。



#自分の環境

Linux Debian 10.0(Docker上)
ruby 2.6.3p62
Rails 5.2.3

#対処法
```application.js
$(document).ready(function(){
```
⬇︎

```application.js
document.addEventListener("turbolinks:load", function() {
```

これによりturbolinksを無効にできました。

##別の対処法
```erb
<%= link_to "リンク名", 〇〇_path, data: {"turbolinks" => false} %>
```

これでもturbolinksを無効にできます。

#参考にさせていただいたサイト
https://qiita.com/hodosan/items/ee84482d18d6dccd9488
https://qiita.com/ryichiki/items/157b0f4288ce605de2a2
https://gist.github.com/saboyutaka/8727377
新人君に伝えたいバグったときの正しい質問の仕方

```
晩飯がまずかったんです。
```
よりも

```
チャーハンに隠し味で醤油いれたら、しょっぱかったんです。
```
のほうが何かしらアドバイスのしようがあるよね。って話です。

---


最近、それなりに経験を積み、ありがたいことに開発のリーダー的な立ち回りをさせてもらうことも増え、いわゆる新人プログラマな皆さんと関わる機会が増えました。
新人プログラマな方は経験が浅いこともあり、(特にバグ発生などに)質問を受けることがよくありますが、たいていの場合はイマイチ要領を得ない質問であることが多いです。
そういった時に「もっとこういう風に質問してくれ〜」と伝えている内容をまとめてみようと思い立ちました。

# 簡単な自己紹介
新卒からエンジニアをしていて、今年で5年目です。
セキュリティ中心にインフラ系エンジニアを2年半→web系エンジニアを2年ほどやっています。
web系に転向してからは、python / java / nodejs などバックエンドを中心に、フロント系も少しだけやっています。最近はpythonにはまっています。


# 先輩エンジニアが思っていること
質問するにあたって、質問相手がどう思っているのかを把握するのはとても大事なことです。
>他人のことに関心を持たない人間は苦難の道を歩まねばならず、他人に対しても大きな迷惑をかけることになる。人間のあらゆる失敗はそういう人たちの間から生まれるのです。
>アルフレッド・アドラー

苦難の道を歩む確率を少しでも減らすために、先輩が考えていることを先に知っておきましょう。

#### 効率的に進めてくれ
多くのエンジニアは基本的に物事を効率的に進めたいと考えるタイプの人間です。
そう考えると、「わからないまま悩む」という非効率よりも、「先輩に聞いて理解する」という効率を求める人の方が多いのは明白です。

初心者が1時間悩んでもわからないことでも、慣れてる人なら5分で終わる場合があります。
「みんな忙しそうだし…」で1時間無駄にされるくらいなら、自分の時間を5分使った方がマシだと、たいていの諸先輩は思っています。


まれに、「わからないこと」を説教するタイプの人もいますが、そんな人は最低なので、別の人に聞いてください。~~そういう人は大体すでに嫌われています。~~
他の先輩と仲良くなる話のきっかけができたなぁくらいの気持ちで、別の先輩に教えてもらいましょう。

#### わからないことをわからないと言って
人は忘れる生き物です。（ほぼ）どの先輩エンジニアも人です。
つまり先輩エンジニアは、自分が新人エンジニアだったときのことを忘れています。
なので、新人エンジニアが躓いていたとしても、このくらいなら一人で大丈夫だろうとほったらかしてしまうことが多々あります。
あれは意地悪をしているんじゃありません。あなたが転んでいることに気づいていないのです。
大声をあげて、転んでいることをアピールしてください。
話の途中でもわからなければ止めてください。わからないまま説明する時間は紛れもなく無駄な時間です。


#### わかった時はわかったリアクションをして
先ほどの逆です。
多くの先輩方は、質問を受けた以上は後輩くんに理解してもらえるように説明しよう。という責任感に襲われています。
なので、説明している最中も、これで伝わってるかなぁと結構不安です。
そんな時にわかった時にリアクションがあると安心して話をすすめられます。
それに、わかっている時にリアクションがあると、逆にリアクションがない時は「いまいちわかってないのかな？」と説明を出すこともできます。

先輩に「あなたの理解度検知機能」を実装するためにも積極的にリアクションを取ります。



# 正しい質問の仕方
「**ゴール**」「**やったこと**」「**現状**」  を明確に含んで質問をしてください。
文章化するのが辛ければ、「**ゴールは～～です**」「**～～をしました**」「**～～と表示されました**」と箇条書きでもいいので、そのまま伝えてください。



## なぜそうするのか
エンジニア(というより人間)は知識と過去の経験から最適な行動を導き出す生き物です。

どんなに凄腕なエンジニアでも、なにかを判断する時には脳内のGoogle先生で検索していると思っていいです。

Googleで検索するときは検索ワードが必要ですよね？

バグを引いたあなたは、バグが発生する過程を事細かに見ていたことだろうと思いますが、

```javascript
senpai != you
```
ですので、「なんか動かなくなりました！！」と言われてもこちらとしては、知らんがな。です。

突然「昨日の晩御飯がマズかったです。どうしたらいいですか」って言われても、「それは辛かったね」くらいしか言えませんよね？

それよりも「昨日チャーハンつくったんですけど、隠し味に醤油を入れたら、しょっぱくなりすぎました」と言われた方が、アドバイスしやすいです。

(ゴール)→チャーハン
(やったこと)→醤油を入れた
(現状)→しょっぱい
です。


こう言われると「なにを当たり前な事を…」と思うかもしれませんが、実際多くの新人君たちはこれが出来ていないと感じます

でなければ、僕が仕事中に「あぁ！そういうことね！」と後輩に言う回数はもっと少ないはずです。

## どう実践すればいいのか
簡単です。
箇条書きの形式で紙に書き起こせばいいんです。
ここでいくつかポイントがあります
### 「やったこと」は出来る限り漏らさず書く
特に操作の前後関係や、回数に関する部分は明確にしてください。
X回以上やったらバグる。みたいなことがわかっていれば「ループまわりの処理が良くなさそうだな…」とあたりをつける最高の材料になります

### 書くのがめんどくさいと思うほどの文章量にしないこと
これはひとつ前と相反しているようにも見えますが、そんなことはありません。
大事なのはめんどうな量の「文章」を書かないことです。
箇条書きでたくさん書く限りは問題ありません。

今まさにバグって困っているあなたが「めんどくさい」と思ってるほどの文章量は、特に困っていない先輩としては「苦痛」以外の何物でもありません。

### 原因がわかった後にそのメモを見直す
これが一番大事です。これさえちゃんとやれば、1,2は勝手に出来るようになると思います。
ちゃんと原因がわかった後に見直すと、自分がした「やったこと」のどこが間違っていたのかハッキリと見えると思います
これ意図的にすることで、「次はもっとこうしてみよう。」という気づきが生まれます。

---
わりと単純な内容ですが、上手に質問できることはれっきとしたスキルだと思うので、ぜひ試してみてください。
ご意見などあればコメントでお知らせください。
Laravel6で新規追加されたJob Middlewareを使ってみる

# 概要
つい最近Laravel6がリリースされました。
その中でも、Laravel6で新規追加されたJob Middlewareについて、かなり単純ですがサンプルコードを書きました。
1から作成している記事がまだ見当たらなかったので、もしさっと1から試してみたい！という方はぜひ読んでみてください。

# ソースコード
試してみたい方はGitHubにあげているのでこちらからどうぞ。
[solt9029/LaravelJobMiddlewareTutorial](https://github.com/solt9029/LaravelJobMiddlewareTutorial)

# そもそもJob/Queueとは？
知っている方は読み飛ばしてください。
例えばユーザがアカウント登録を行ったときに、そのアカウント登録内容をメール送信したいような場合があります。
そういったときに、メール送信処理の間ユーザを待たせるのはよろしくありません。
Job/Queueを使えば、そういった処理を非同期に行うことができ、ユーザを待たせずにメール送信を行ったりすることができます。

# 実際にやってみる

## プロジェクト作成
Laravel6はPHP7.2以上を求めるので注意してください。
まずはLaravelの新規プロジェクトを作ります。

```sh
composer global require laravel/installer # laravelコマンドが入ってない場合
laravel new LaravelJobMiddlewareTutorial
```

## 環境変数設定
次に、環境変数を編集していきます。
今回は簡単にするためにSQLiteを使用しようと思うので、MySQLまわりの設定を削除し、以下の設定を加えます。
また、Queueで今回はデータベースを使用するために、syncではなくdatabaseに変更します。

```text:.env
DB_CONNECTION=sqlite
QUEUE_CONNECTION=database
```

## データベース設定
```sh
touch database/database.sqlite
php artisan queue:table # Queue用のテーブルを作るマイグレーションファイル作成
php artisan migrate
```

## Job作成
```sh
php artisan make:job LogJob
```

作成したJobを編集していきます。
今回は単純に、ログが表示されるだけのJobを用意してみました。

```php:app/Jobs/LogJob.php
use Illuminate\Support\Facades\Log;

class LogJob implements ShouldQueue
{
    //

    public function handle()
    {
        Log::info('LogJob handled');
    }
```

さて、ここからLaravel6での新機能です。
先ほどのJobに以下の関数を加えます。

```php:app/Jobs/LogJob.php
    public function middleware() {
        return [new LogJobMiddleware];
    }
```

まだ作成していませんが、これによって、LogJobMiddlewareというミドルウェアを通過するようになります。

## Middleware作成
さて、先ほど指定したLogJobMiddlewareというものを実際に作っていきましょう。
`app/Http/Middleware/LogJobMiddleware.php`を作成し、以下のようにします。

```php:app/Http/Middleware/LogJobMiddleware.php
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Log;

class LogJobMiddleware
{
    /**
     * Process the queued job.
     *
     * @param  mixed  $job
     * @param  callable  $next
     * @return mixed
     */
    public function handle($job, Closure $next)
    {
        Log::info('LogJobMiddleware handled');
        return $next($job);
    }
}
```

## LogJobが動くRouteを設定
ここでは、`/log`にアクセスが来たときに、LogJobが動くようにしてみましょう。
`routes/web.php`に以下を追加します。

```php:routes/web.php
Route::get('/log', function() {
    dispatch(new LogJob);
    return 'LogJob dispatched';
});
```

## 動作確認
さて、これで実装は完了です！
実際に試してみましょう。

以下のコマンドでサーバを立ち上げます。

```sh
php artisan serve & php artisan queue:work
```

確認する流れとしては、

- ブラウザで`http://localhost:8000/log`にアクセスする
- （LogJobがQueueに追加される→）ブラウザに「LogJob dispatched」と表示される
- LogJobMiddlewareを通過し、`LogJobMiddleware handled`というログが残る
- LogJobが実行され、`LogJob handled`というログが残る

といった感じになります。
ログは`storage/logs/laravel-XXXX-XX-XX.log`で確認できるかと思います。

# 最後に
今回はかなりシンプルな例とするためにログを残すだけでしたが、Job Middlewareにカスタムロジックなどを記述することにより、Jobの記述を綺麗にできるかと思います。
最後まで読んでいただきありがとうございました。

# 関連記事
- https://laravel-news.com/laravel-6
- https://qiita.com/hirakumorishima02/items/5cde65ffc6ae40965974
Linux ubuntu の ターミナル に 時間 を 表示 する

# 目的

- Linuxのターミナル画面に下記画像のような時間を表示する方法を知る  
※本記事はUbuntu18.04を対象とした内容です。


# 実施概要

1. 設定ファイルを開く
1. とあるコマンドのパスを通す
1. 確認

# 実施詳細

1. 設定ファイルを開く
    1. 下記コマンドを実行してユーザディレクトリ直下に移動する。
    
        ``` shell
        cd ~
        ```
1. あるコマンドのパスを通す
    1. 下記コマンドを実行して設定ファイルを開く。
    
        ```shell
        nano .bashrc
        ```
    
    1. 開いたファイルの最後に下記の一行を追記する。
    
        ```.bashrc
        export PS1='[\t]\u@\h\w\$ '
        ```
        
        ![コマンドラインに時間_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/0d563bc7-5aa0-d6d4-f206-d6092fdaf6c2.png)


    1. 次の順に実施し変更を保存する  
        - 「Ctrl」+ 「x」を押下 → 「y」を押下 →  「Enter」を押下

    1. ターミナルを再起動する

1. 確認

    1. ターミナル画面を選択し「Enter」を押下し下記のように時間が表示されていることを確認する

        ![コマンドラインに時間_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/81e2aa5c-fd1e-1c75-b3da-2446d00b352b.png)

1. exportコマンドを用いてコマンドの意味を調べる

    - ターミナルで先ほど追記したコマンドを実行すればそのターミナルを開いている間のみその設定を保持できる

```
$ export PS1='[\t]'
```
↓
プレビュー
![コマンドラインに時間_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/df8645d0-2c04-59eb-1589-8da6ca044e63.png)

```
$ export PS1='[\t]\u '
```
↓
プレビュー
![コマンドラインに時間_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/035312f1-e3c1-cbb2-286e-1eecd5687121.png)

```
$ export PS1='[\t]\u@\h '
```
↓
プレビュー
![コマンドラインに時間_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/5c2eab3d-7109-9987-02e5-c2a242f29a75.png)

```
$ export PS1='[\t]\u@\h\w '
```
↓
プレビュー
![コマンドラインに時間_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/1695c390-a915-95f7-85f4-4e4373535c83.png)

```
$ export PS1='[\t]\u@\h\w\$ '
```
↓
プレビュー
![コマンドラインに時間_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/47631b74-89d3-f273-eb9f-56cb2827507d.png)
rails before_actionを行なったあとにアクションを中止する仕組みについて

#はじめに
筆者はrailsチュートリアルを学んでいる時にbeforeアクションの後に他のアクションが実行されない理由について疑問を持ちました。それを自分なりに調べた事を以下にまとめます。
残念ながらbefore_actionの内容は、railsのソースコードを自力で探し出せ読み解けるスキルレベルではないと説明できないため筆者では完璧に理解することはできませんでした。しかしある程度の仕組みを理解できましたので記事にします。

#結論
before_ationでredirect_toを行うと、
response_body(コントローラーによって送信されたHTTP応答を返すための変数)が空で無くなるため、before_ationで呼んでいたcallback chainが止まり、以降のbefore_actionやactionが実行されなくなります

#使用例


```ruby
class UsersController < ApplicationController
  before_action :logged_in_user, only: [:index, :edit, :update, :destroy]

  def index
    @users = User.paginate(page: params[:page])
  end

  # beforeアクション
  # ログイン済みユーザーかどうか
  def logged_in_user
    unless logged_in?
      store_location
      flash[:danger] = "Plaease lon in "
      redirect_to login_url
    end
  end
end
```
`index`を実行する前に`logged_in?`の`redirect_to`を実行すると`index`は実行されません。

#解説
`redirect_to`などで`response_body`に値が入っている場合は、次のアクションを行わないようです。

詳しい解説は以下の記事を参考にしてください（筆者では完全に説明できるほどのスキルはありません)
[Railsでbefore_filter/before_actionがアクションを中止する仕組みを読んでみる](https://techracho.bpsinc.jp/baba/2013_08_06/12650)
MySQL8.0.17の認証プラグインを変更する


#Laravelで下記のエラーが発生した場合
```
PDOException::("PDO::__construct(): The server requested authentication method unknown to the client [caching_sha2_password]")
```

#システム変数 default_authentication_plugin の値を表示します
```
mysql> SHOW VARIABLES LIKE 'default_authentication_plugin';
+-------------------------------+-----------------------+
| Variable_name                 | Value                 |
+-------------------------------+-----------------------+
| default_authentication_plugin | caching_sha2_password |
+-------------------------------+-----------------------+
1 row in set (0.02 sec)
```

#rootユーザーの認証プラグインをmysql_native_passwordに変更する
```
mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'pass';
Query OK, 0 rows affected (0.01 sec)
```

#接続を終了する
```
mysql> exit;
Bye
```
#再起動する
```
<コンピューター名>-no-MBP:~ <ユーザー名>$ mysql.server restart;
Shutting down MySQL
.. SUCCESS! 
Starting MySQL
. SUCCESS! 
```

#再度起動して接続する
```
<コンピューター名>-no-MBP:~ <ユーザー名>$ mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.17 Homebrew
```

#mysql.user テーブルからuser, host, pluginのカラムの値を表示する

rootユーザーのpluginの値がmysql_native_passwordになっている

```
mysql>  SELECT user, host, plugin FROM mysql.user;
+------------------+-----------+-----------------------+
| user             | host      | plugin                |
+------------------+-----------+-----------------------+
| mysql.infoschema | localhost | caching_sha2_password |
| mysql.session    | localhost | caching_sha2_password |
| mysql.sys        | localhost | caching_sha2_password |
| root             | localhost | mysql_native_password |
+------------------+-----------+-----------------------+
4 rows in set (0.00 sec)
```

#参考

https://qiita.com/ucan-lab/items/3ae911b7e13287a5b917
https://dev.mysql.com/doc/refman/5.6/ja/show-variables.html
https://www.dbonline.jp/mysql/user/index9.html
[Unity] Assets フォルダから全ての meta ファイルを消すワンライナー


**ルートディレクトリ・ホームディレクトリ等で実行すると、いろんな Unity プロジェクトの構成が悲惨なことになる可能性があるので注意してください！**

必ず cd で meta ファイルを消したいディレクトリに入ってから実行してください。
子ディレクトリの meta ファイルも全て削除されます。

## Mac

```bash
find . -name "*.meta" -type f -delete
```

Mac OS 10.14.6 でテストしました。

## Windows

### cmd.exe の場合

```shell
del /s /a /f *.meta
```

### PowerShell の場合

```powershell
get-childitem *.meta -recurse -force | remove-item -force
```

Windows 10 でテストしました。

## 必要になる場面

- プロジェクト全体をコピーしたいけど meta は消したい
- 他のプロジェクトから部分的にフォルダをコピーしたいけど meta は消したい

というような時に使用してください。
初学者のためのPython 環境構築@2019/9 版

#誰のため?
　pythonの環境設定で苦労している pythonの初学者

#はじめに
　Python が様々なシーンで使われることが多くなってきた。特に昨今盛んになっているのがAI、機械学習、金融や初学者向けのプログラミングの学習などである。pythonはインタプリタ言語として比較的歴史があるので、python2.x, python3.xの２つのバージョンが並列している。特にpython2.xで開発され、未だに運用されているケースも数多ある。そこで本稿では、python2.x系と3.x系を併存させる方法について論じる。

#使用目的と実行環境
##WindowsとMacOS
###2.x系列が不必要な場合=>Anaconda
 Windows/Mac 単体で使う場合は、Anacondaでそのままインストールするのが手間がかからない。以下は読まずに最後のIDEの項のみ設定すれば良い。


##Linux
 LinuxではROSを利用したり、先に述べたAIの勉強を行うので、環境を切り替えて使う。

#目的
　python2.x とpython3.xの環境を共存させる。

#背景
　筆者自身がROS(Robot Operating System)や機械学習, 金融関連の処理をpythonで構築する必要がある。ROSはデフォルトで呼び出されるpythonは(=コマンドプロンプトで、いきなりpythonと入力時に)2.7が動作する環境が必須で、その他の場合は3.7以上が望ましい。

#環境
##python2.7環境
　現在のDistributionの環境をそのまま使う

`$ python -V
python2.7.12`

##python3.7のインストール
###Linux(ubuntu)
　1. $ sudo apt update
　2. $ sudo apt install python3.7
　3. .bashrcの編集
　　.bashrc (最後に下記を追加)
　　`alias python3='/usr/bin/python3.7'`

　4. $ source .bashrc
　5. $ sudo apt-get install python3-distuitls
###Mac
 T.B.D

#共存方法(virtualenvを採用)
 1. pip install
  - Linux<br>
   $ sudo apt install python-pip
  - Mac<br>
   T.B.D
 2. python2側でvirtualenvをインストール(Linux/Mac共通)
  - $sudo pip install virtualenv virtualenvwrapper --ignore-installed six
 3. virtualenv, virtualenvwrapperのセットアップ
  1. 仮想環境のディレクトリ作成<br>
   $ cd ~ <br>
   $ mkdir ~/.virtualenvs

  2. .bashrc ファイルの作成<br>
   .bashrc<br>
   export WORKON_HOME=$HOME/.virtualenvs<br>
   source /usr/local/bin/virtualenvwrapper.sh

  3. .bash_profileに以下の行を追加<br>
   .bash_profile<br>
　　　:<br>
　　　:<br>
 if[-f ~/.bashrc];then<br>
 　.~/.bashrc<br>
 if

  4. .bash_profileの再読み込み<br>
   $ source .bash_profile

#仮想環境
##構築
- Linux
　$ mkvirtualenv --no-site-package --python /usr/bin/python3.7 env0

- Macintosh
　$ mkvirtualenv --no-site-package --python /usr/local/bin/python3.7 env0

##取り扱い
- 仮想環境への移行
　$ workon env0

- 仮想環境一覧
　$ workon

- 仮想環境の終了
　$ deactivate

#実行環境の整備
- 必要な環境はpipを用いて個別に設定していく<br>
 1. 仮想環境への切り替え<br>
　$ workon env0
 2. 必要な拡張をインストール<br>
 プロンプトが`(env0)$ `となっているのを確認して、pipにてインストール<br>
 (env0)$ pip install pandas-datareader<br>
 同様に下記もインストール<br>
 seaborn, pyserial, jupyter

#IDE
　python用には様々なIDEがあるが、VisualStuido Code (VSCode)を利用する。
　下記のextensionを導入している。
　1. 導入extension
　　- python
　　- RainbowCSV
　　- EditCSV
　　- filesize
　2. インタプリタの設定
　　pythonの環境が複数入っている場合は、以下の通りにインタプリタ(python version)を設定する
　　1. `Ctrl + Shift + P` => コマンドパレット
　　2. python select interpreter で検索
　　3. 上記で設定した環境を選ぶ(今回はenv0)
　3. WordWrap(行末の折返し)の設定
　　File->Preferences->Settings
　　Editor.WordWrap
　　　Off=>On
　4. その他
　　max_user_watches数が少ないと警告が出たら、
　　$ cat /proc/sys/inotify/max_user_watches で確認
　　8192
　　$ sudo nano /etc/sysctl.conf
　　行末に以下を追加
　　fs.inotify.max_user_watches=524288
　　nanoを終了し、
　　$ sudo sysctl -p
Visualforceページから標準画面を開くブックマークレット

# Visualforceページから標準画面を開くブックマークレット


オブジェクトの標準ページが見たいけど、VFで上書きされてて見れない場合、

`<ID>?nooverride=1`で標準表示画面

`<ID>/e?nooverride=1`で標準編集画面

に飛べますが、ブックマークレット２個作成しましたので共有しておきます。



## Chromeのお気に入りを新規登録する際に以下を入力して登録してください。

※１行目は名前なので適当に変えてOK。２行目をURL部にそのまま張り付けてください。



該当画面を開いてブックマークレットを選ぶと、標準画面が別ウィンドウで表示されます。




### 1. 【カスタムオブジェクト専用】Visualforceページで表示したレコードの標準表示画面を開く
 

VFからの標準表示画面
```javascript:(function(){window.open('../'+window.location.search.match(/id=([^&]*)/)[1]+'?nooverride=1','');})();
```


### 2.【カスタムオブジェクト専用】Visualforceページで表示したレコードの標準編集画面を開く

VFからの標準編集画面
```javascript:(function(){window.open('../'+window.location.search.match(/id=([^&]*)/)[1]+'/e?nooverride=1','');})();
```