OmniAICreator/Qiita-1.07M huggingface dataset:
エクセルでJAVAアプリを超簡単生成！「ワンダーロボ」画面定義、チャート、初期値の設定方法

###ステップ1.画面定義設定
###ステップ2.チャート設定
###ステップ3.初期値設定

---
###ステップ1.画面定義設定
最初に、画面定義設定の説明をします。画面定義設定は、「画面定義」、「メニュー設定」、「検索画面作成」とあります。以下が、項目ごとの役割と例図になります。

####[項目説明]

#####・「画面定義」
画面名：空白の場合、画面名をシート名「画面設計_〇〇〇」の「〇〇〇」と定義します。
管理ID：画面の管理IDを設定します。
画面高さ/画面横幅：空白の場合、画面項目のセルIDを自動調整します。
                 また、画面サイズを指定した場合、指定したサイズの範囲以外に画面項目のセルIDを設定 
                 し、画面サイズを自動的に再調整します。
画面表示：「前提条件」：権限を配置します。
　　　　　「表示」：メニューの候補値に、該当画面を表示します。
　　　　　「非表示」：権限を配置させて、メニューの候補値に該当画面を非表示にします。　　　　
説明（空白可）： SaaSForceで検索と編集が可能となります。
修正履歴（空白可）：データベースとSaaSForceには記録されず、Excel設計書の記録用のコメント欄です。

#####・「メニュー設定」
メニュー（空白可）：画面設定において、存在していないメニューを新規作成する場合、設計書をインポートする時の「インポートオプション」画面で、「自動メニューに追加する」をクリックするとメニューが新規作成されます。「追加しない」をクリックすれば、メニューは新規作成されません。

#####・「検索画面作成」
検索画面作成（空白可）：「作成」の時、検索画面を自動的に作成します。
検索項目（空白可）：検索画面の検索条件
（※ラベル可能※セルID可能※DB関連フィールド可能）
検索結果（空白可）：検索画面の表示結果
（※ラベル可能※セルID可能※DB関連フィールド可能）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184885/413bc435-9b21-7756-9723-dbdd5795bdc4.png)



---
###ステップ2.チャート設定
次に、チャート設定の説明をします。チャートの作成は検索条件の設定、チャート設定と参照テーブルで構成しています。

####2-1.画面設計書に記載
まずは画面設計書で作成していきます。図のようにshapeに記載していきます。
※「チャート」、「図形」、「チャートタイプ」、「スタイル」、「タイトル」、「テーブル」、「分析対象」、「分析項目」、「分析値」は記述必須になります。

<img width="1128" alt="30.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184885/a78926b7-9879-ce07-373f-9233faf93742.png">

<img width="1128" alt="33.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184885/30605bd4-3ab8-abb7-c42f-b84c644f078d.png">



####2-2.設計書ファイルをインポートして確認
SaaSForceの開発環境にログインし、設計書ファイルをインポートします。そして、利用画面で反映されているか確認して完了です。
<img width="791" alt="32.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184885/a69f4175-9d68-0ac0-34fe-8c0ac236326e.png">

---
###ステップ3.初期値設定
最後に、初期値設定の説明をします。これは、デフォルトで設定されている値のことを指します。
初期値は固定値以外の、以下の内容を設定することができます。
例：システム日付
　　ログインID
　　組織ID
　　システム年
　　システム月
　　システム日付
　　システム時間
　　システム年月
　　今日
　　月末日付
　　月初日付

「DropdownList」、「Checkbox」、「RadioButton」画面項目を例として説明します。
「DropdownList」、「Checkbox」、「RadioButton」画面項目の初期値設定はリストの表示値又はリストの保存値を設定します。

####3-1.「DropdownList」の設定方法
まずは、「DropdownList」の方法を説明します。例として、「注文管理詳細」画面の「出庫フラグ」の初期値を「未出庫」に設定します。

<img width="1128" alt="35.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184885/d1d0fafe-fa0d-ba22-3dfd-76d461a586e1.png">

「初期値設定」に、該当項目を指定します。そして、初期値に設定したい項目を記載します。
<img width="1128" alt="36.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184885/edf7ba9c-85bc-87fd-a6e6-8069a43b2b4f.png">

#####ユーザー利用画面表示例↓
<img width="789" alt="38.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184885/ac9afb51-dd2c-7795-7158-2c07187dfcf8.png">

####3-2.「Checkbox」「RadioButton」の設定方法
次は、「Checkbox」、「RadioButton」の設定方法を、「社員」画面を使って説明します。
「有効区分」と「性別」に、初期値を設定します。
「Checkbox」はチェック・非チェックを指定可能です。下図のように「有効区分」の初期値を「チェック」を設定することもできます。
<img width="1128" alt="42.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184885/1623dc35-04ef-6456-580e-4367c3afc016.png">

#####ユーザー利用画面表示例↓
<img width="794" alt="44.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184885/e0865582-bb64-2f80-776c-e942f7d22ad5.png">
自社で流通してた digdag on docker コマンド

# はじめに

社で digdag を触っていますが、Local にインストールされた Java Version の都合で動作しないことがあるそうです。

docker で動かせば解決するよということで自社で流通していたコマンドを紹介します。

# Command
```shell-session
$ docker run -it --rm \
-e AWS_ACCESS_KEY_ID=$(cat $HOME/.config/digdag/secrets/s3.access_key_id) \
-e AWS_SECRET_ACCESS_KEY=$(cat $HOME/.config/digdag/secrets/s3.secret_access_key) \
-u root \
-v $HOME/.config/digdag:/root/.config/digdag:ro \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-v $(pwd):$(pwd):ro \
-w=$(pwd) \
intimatemerger/digdag run --no-save hoge.dig
```

# メモ

`$HOME/.config/digdag` から `api key` や `access key` を読み込んでコンテナに引き渡しています。

ローカルの動作確認ではジョブの進捗管理機能とかいらないので、docker のオプションに `-v $(pwd):$(pwd):ro` を指定し、digdag の起動オプションに `--no-save` を指定しています。

便利ですね。
Terraform入門その一（インストール）

# 目次

Terraform入門その一（インストール）**[本記事]**
[Terraform入門その二（AWSのEC2作成）](https://qiita.com/kenkono/items/a3a67585b1737a11c5c4)
[Terraform入門その三（hello worldの表示）](https://qiita.com/kenkono/items/2fb65e7326f957315362)
[Terraform入門その四（AWSのELB&ASGの導入）](https://qiita.com/kenkono/items/1dc35586f908a6bd177c)

# 環境
MacOS Mojave
Terraform v0.12.2
# インストール
Terraformホームページより該当OSのパッケージをダウンロードしてきます。
https://www.terraform.io/downloads.html

作業用のディレクトリを作成し、ダウンロードしたパッケージを格納します。

```
# パッケージのダウンロード
mbp:~ mac$ wget https://releases.hashicorp.com/terraform/0.12.2/terraform_0.12.2_darwin_amd64.zip
# 解凍
mbp:~ mac$ unzip terraform_0.12.2_darwin_amd64.zip
# 作業ディレクトリの作成
mbp:~ mac$ mkdir working
# パッケージを作業ディレクトリに移す
mbp:~ mac$ mv terraform working/
```

パスを通します。以下はbashの際の設定です。
`vi .bash_profile`で設定を記述します。

```python:.bash_profile
export PATH="$PATH:~/working"
```

設定を反映させるため、以下コマンドを入力します。

```
mbp:~ mac$ source .bash_profile
```

反映がされたか、バージョンの確認

```
mbp:~ mac$ cd terraform
mbp:terraform mac$ terraform --version
Terraform v0.12.2
```

続きまして、下記記事でAWSのEC2インスタンスの作成を行います。
[Terrafrom入門その二（AWSのEC2作成）](https://qiita.com/kenkono/items/a3a67585b1737a11c5c4)

# 参照
[Installing Terraform](https://learn.hashicorp.com/terraform/getting-started/install)
React-modalで簡易モーダル作成

##React-modalでお手軽モーダル作成
いざ作るとなると案外めんどくさいモーダルウインドウ
ReactだとReact-modalで簡単に実装できるが、ちょっと悩んだので書き残し

```
$ npm install react-modal
```
で導入

Modal.setAppElementを設定してないとエラーが発生するので忘れないように！

```ModalWindow.js
import React from 'react';
import Modal from 'react-modal';
const customStyles = {
  content : {
    top                   : '50%',
    left                  : '50%',
    right                 : 'auto',
    bottom                : 'auto',
    marginRight           : '-50%',
    transform             : 'translate(-50%, -50%)'
 }
};

Modal.setAppElement('#your-app') //任意のアプリを設定する　create-react-appなら#root
class ModalWindow extends React.Component {
  constructor() {
    super();
    this.state = {
      modalIsOpen: false
    };
    this.openModal = this.openModal.bind(this);
    this.afterOpenModal = this.afterOpenModal.bind(this);
    this.closeModal = this.closeModal.bind(this);
  }
  openModal() {
    this.setState({modalIsOpen: true});
  }
  afterOpenModal() {
    this.subtitle.style.color = '#f00';
  }
  closeModal() {
    this.setState({modalIsOpen: false});
  }
  render() {
    return (
      <div>
        <button onClick={this.openModal}>Open Modal!!</button>
        <Modal
          isOpen={this.state.modalIsOpen}
          onAfterOpen={this.afterOpenModal}
          onRequestClose={this.closeModal}
          style={customStyles}
          contentLabel="Example Modal"
        >
          <h2 ref={subtitle => this.subtitle = subtitle}>ModalWindow</h2>
          <div>Opend</div>
            <button onClick={this.closeModal}>close</button>
        </Modal>
      </div>
    );
  }
}
export default ModalWindow;
```
モーダルウインドウとモダールを開くトリガーになるボタンを実装している

```jsx
<Modal></Modal>
```
の中身がモーダルになる

あとはこれをボタンを配置したいとこに置けばOK
30代エンジニアがG検定取得した奮闘記(JDLA Deep Learning for GENERAL 2019#2)

#はじめに
今後10～20年後を考えた際に、
AIの知識は無駄にならないと確信しているため、
受験することにしました。

本音を言えば、E検定を受けたかったが、前提の講義費用が高い。。(最低20万～)
そのため、まずはG検定取得することにしました。
(G検定合格後、E検定費用だしてもらえないか交渉中)

#前提知識
・理系大学出身(微積分などの数理部分は理解しているつもり)
・ITエンジニア10年(ptyhonは最近だが、java等の応用でいけるだろうと楽観)

#勉強期間
1か月

#勉強方法
書物について、フリマアプリで探しましたが、
ほとんどSOLD OUTだったため、
同様に目指している方は定期的に見ることをお勧めします。
(個人的に失敗したなと反省。。)

１．教科書(1週間)
[人工知能は人間を超えるか](https://www.amazon.co.jp/%E4%BA%BA%E5%B7%A5%E7%9F%A5%E8%83%BD%E3%81%AF%E4%BA%BA%E9%96%93%E3%82%92%E8%B6%85%E3%81%88%E3%82%8B%E3%81%8B-%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0%E3%81%AE%E5%85%88%E3%81%AB%E3%81%82%E3%82%8B%E3%82%82%E3%81%AE-%E8%A7%92%E5%B7%9DEPUB%E9%81%B8%E6%9B%B8-%E6%9D%BE%E5%B0%BE-%E8%B1%8A/dp/4040800206/ref=asc_df_4040800206/?tag=jpgo-22&linkCode=df0&hvadid=295639570041&hvpos=1o1&hvnetw=g&hvrand=17058243945950601488&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1028850&hvtargid=pla-527065028061&psc=1&th=1&psc=1)を流し読み

２．問題集(2週間)
[徹底攻略 ディープラーニングG検定 ジェネラリスト問題集](https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5-%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0G%E6%A4%9C%E5%AE%9A-%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%A9%E3%83%AA%E3%82%B9%E3%83%88%E5%95%8F%E9%A1%8C%E9%9B%86-%E3%82%B9%E3%82%AD%E3%83%AB%E3%82%A2%E3%83%83%E3%83%97AI%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE-%E6%98%8E%E6%9D%BE/dp/4295005665/ref=pd_sbs_14_2/356-4207434-7911830?_encoding=UTF8&pd_rd_i=4295005665&pd_rd_r=6ecfdee2-924b-11e9-ade0-e9d6b5a53cc0&pd_rd_w=B3i2S&pd_rd_wg=qH4j1&pf_rd_p=ad2ea29d-ea11-483c-9db2-6b5875bb9b73&pf_rd_r=7CQRDQBPGS7SFYJ1H7JX&psc=1&refRID=7CQRDQBPGS7SFYJ1H7JX)
を解きながら調べ理解を深める。

３．模擬テスト(1週間)
[Study-AI](http://study-ai.com/generalist/)
仕上げ。

#まとめ
~~勉強中。(受験日：2019/07/06)~~

試験終わりましたが、難しかった。。。
5割はできたと思いますが、勉強不足が否めない。。
人物問題でないやんけ。。計算問題もちょっとだけやん。。。
20問ぐらい法律・倫理問題なので、
AI白書に載ってたのかもと思われました。

(2019/07/13追記)
合格してました！(7/12 16時頃)
受験者数と合格者数は以下の通りでした。

|項目  |人数  |
|---|---|
|総受験者数|5,143名|
|合格者数|3,672名|
|合格率| 約71%(合格率高いですが、内容は難しかったです。。)|

合格証は8月末までと思ったより遅い。。

## 試験勉強考察
今回の経験から今後、受験する方へ少しでも参考になればと思います。

試験内容は概ね以下の割合の印象でした。
① 問題集, Study AI(6割)
② 深層学習(2割)
③ 法律・時事(2割)

###① 問題集, Study AI
以下を9割正解できる状態で挑めたため、
大きな割合で得点及び時間稼ぎできたと思います。
・徹底攻略 ディープラーニングG検定 ジェネラリスト問題集
・Study-AI
全く同じ問題が多々でることがありましたが、
虫食い箇所が違う箇所もあったため、問題文全て理解するようにしたほうが良いです。

人物の答えは覚えずに、エクセル等カンイングペーパー用意だけでよいです。(4問ぐらい？)
また、計算問題も少なかったです。(2問ぐらい？)

私が試験中に使用した資料は以下にアップしているため、活用ください！
[カンニングペーパー資料](https://github.com/bossjerom/g_test)

###② 深層学習
言葉から初耳のものがあったため、
理想は深層学習の青本を学習する必要があったようです。
検索である一部は回答できたと思います。

###③ 法律・時事
ここが、一番の鬼門です。
2か月前の時事問題がでるぐらい、
学習範囲を抑えるのは厳しいため、
一番後回しで検索すべきと思います。
AI白書が抑えているポイントもあるようなので、
余力ある方は上記手元にあって損はないと思います。

###検索の工夫
試験中は、問題文、回答内容をコピーできない制御になってます。(右クリックも使用できない)
そのため、都度入力して検索が必要なため非効率的です。
そこで、以下のChromeアドオンを追加することをお勧めします。
これにより、入力不要でコピー検索可能になり時間を稼げるようになります！
[RightToCopy](https://chrome.google.com/webstore/detail/righttocopy/plmcimdddlobkphnofejmeidjblideca)

###総括
・学習して即答できるものを増やし、時間を稼げるようにする
・カンニングできるものは資料化し、覚えない
・法律・時事問題は稼いだ時間で検索しながら時間をかけて回答する

AIの試験範囲は広がり続けると思いますので、
迷っているのならば早いうちに受けるべきだと思いました。
条件分岐におけるand,orの動き

#and, orとは

・and

|| 0 | 1 |
|:---:|:---:|:---:|
|0|false|false|
|1|false|true|

・or

|| 0 | 1 |
|:---:|:---:|:---:|
|0|false|true|
|1|true|true|

andは対象全てが1であればtrueを返す。
逆に言えば**1つでも**0があればfalseを返す。

orは対象に0があっても1が1つでもあればtureを返せる。
簡単に言うと**1つでも**1があればtrueを返す。

#ifで扱う&&と||

上記の例をプログラムで扱うとこうなる。
分かると思いますが&&, ||いずれも左から見ます。

```swift
func hoge() {
    let a = false
    let b = false
    let c = true
    
    // andは両方trueで初めてtrueを返せる
    // しかしaがfalseなため、どう頑張ってもtrueは返せない。
    if a && b {
        print("ここは入らない")
    } else {
        print("つまりbは見ないでここに到着!")
    }
    
    // 次はcがtrueなため、trueを返す希望がある。
    if c && a {
        print("ここは入らない")
    } else {
        print("今度は右辺のaを見てここに到着!(結局falseで終わってしまったが。。)")
    }
    
    // orは1でもtrueがあればtrueを返す。
    // cがtrueなため、どう頑張ってもtrueしか返せない
    if c || a {
        print("つまりaは見ないでここに到着!")
    }
    
    // 次aがfalseなため、cを見に行く必要がある。
    if a || c {
        print("cをみてtrueだったからここに到着!")
    }
}
```

# これをみんな大好きnilと合わせると

```swift
func fuga() {
    let a = false
    let b = true
    let c: Bool? = nil
    
    // ①
    if a && c! {
    } else {
        print("printされる")
    }

    // ②    
    if b || c! {
        print("printされる")
    }

    // ③    
    if b && c! {
        print("クラッシュ")
    }
    
    // ④
    if a || c! {
        print("クラッシュ")
    }
}
```


<details>
<summary>解説 (clickでopen)</summary>
上から順に
①aがfalseなのでcを見に行かずfalseを返す
②bがtrueなのでcを見に行かずtrueを返す
③bがtrueなため、希望を持って右辺を参照、しかしnilなためクラッシュ
④aがfalseなため、trueを求めて右辺を参照、しかしnilなためクラッシュ
</details>

# 結局何が言いたいか
**条件分岐におけるandとかorって条件に書いてある全てのものを見ている訳ではないよ!!**
これだけ

# まとめ
and: falseが見つかったら仕事放棄
or : trueが見つかったら仕事放棄

# 補足
厳密に言うと「and, orとは」で書いているように0,1で見ています。
Boolで返しますが、Boolで見ていません。

if文はわかりやすいように!(a&&b)のような書き方はしていません。
if,elseの形のみで表現しています。
WordPress REST API oauth2 Authorization code を Postman で取得する方法

GUIで簡単に取得できるのですが、しょうもないことでドハマリしました。

#正しい手順
oauth プラグインをダウンロード
https://ja.wordpress.org/plugins/oauth2-provider/
有効化する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163299/1b15aaf4-6244-1e31-b4b2-82d991aaf857.png)
##settings 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163299/42222490-df37-64b8-0d9c-94091274699f.png)

OAuth Server Enabled　にチェック


##サーバーステータス
サーバーステータスが全部正常かチェック
黄色の noticeで動かない場合があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163299/c4615e61-33ef-72c3-b86e-b7f0149edb51.png)

##Add New Client
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163299/1b961f2f-c757-9bf3-ea3a-bf568ef29543.png)

以下のように設定したとしても、無理だった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163299/e7b1da45-5602-f6d7-9d5c-81c664ae578d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163299/2b41ad3e-404d-d5dd-66c3-859a52f578ab.png)



#ハマりポイント

##Client 名wordpress側と postman 側を同じにする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163299/adae3bf7-cf14-877a-1a1a-bb4acd530203.png)
Postman の　Token name と　WordPress の　client id は同じにしてください。
同じにしなくても動くはずですが、エラーを起こす場合があります。

##wordpressをRESTにする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163299/e2ada133-f750-cc6f-9297-158ac3aaf229.png)
正しくログインできるとこの画面が表示されますが、できませんでした。

原因は、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163299/c4d1fba1-d960-547f-dbd7-806c624e856a.png)

初期設定だとパーマリンク設定が基本でGETクエリで投稿を判定するので、RESTじゃないからRESTAPIが動かないという罠です。 投稿名で設定しましょう。

英語のyoutubeビデオを見つけるまでは、デフォルトでRESTAPIはWordPress core に統合されているから有効と聞いていたので、有効になってないとは露程にも思いませんでした。
SECRET_KEYを誤ってGitHubにプッシュしたときの対処法（Django編）

# 概要
DjangoアプリをGitHubで管理していて、公開リポジトリにしたかったのですが、一番最初のコミットからSECRET_KEYをコミットしていました。（この時点では非公開）

また、複数のコミット歴があるので、どのように処理すればいいかわからず、`①最初からやり直す`、`②履歴の書き換え`を考えていました。

今回はそれ以外の方法で解決できたので、その方法を書いてみます。

なお、環境は`python 3.7.3`、`django 2.2`になります。

# 1. local_settings.py設定

###### 1-1. local_settings.py作成

まずは下記のコマンドを実行し`local_settings.py`を作成してください。

___※settings.pyと同じディレクトリに作成___

```terminal:terminal
$ touch local_settings.py
```

###### 1-2. SECRET_KEY削除

`settings.py`にある`SECRET_KEY`を削除します。

```python:settings.py
SECRET_KEY = 'こちらにご自身のSECRET_KEYが記載されている' #行ごと削除
```

###### 1-3. settings.py設定

`local_settings.py`を読み込むため、下記を追加してください。

```python:settings.py
try:
    from .local_settings import *
except ImportError:
    pass
```

# 2. SECRET_KEYの再生成

###### 2-1. get_random_secret_key.py作成

`settings.py`と同じディレクトリに`get_random_secret_key.py`を作成し、下記を追加してください。

```python:get_random_secret_key.py
from django.core.management.utils import get_random_secret_key

secret_key = get_random_secret_key()
text = 'SECRET_KEY = \'{0}\''.format(secret_key)
print(text)
```

###### 2-2. 再生成する

`プロジェクトフォルダー`にディレクトリを移動し、下記を実行します。

___※プロジェクトフォルダーはsettings.pyやwsgi.pyがあるフォルダー___

実行後に新しい`SECRET_KEY`が生成されます。

```terminal:terminal
$ python get_random_secret_key.py
SECRET_KEY = 'こちらにSECRET_KEYが生成されます'
```

###### 2-3. SECRET_KEY変更

`local_settings.py`に新しい`SECRET_KEY`を追加します。

```python:local_settings.py
SECRET_KEY = 'こちらに新しく生成されたSECRET_KEYを記入' #追加
```

# 3. GitHubにプッシュ

###### 3-1. .gitignore作成

プッシュする前に`.gitignore`を作成して、`local_settings.py`を記載します。

下記のコマンドを実行してください。

___※.gitignoreを作成済みであれば、追加でファイルを記載してください___

```terminal:terminal
$ echo local_settings.py > .gitignore
```

###### 3-2. プッシュする

下記コマンドでGitHubにプッシュします。

```python:terminal
$ git add -A #全部コミットしたい場合
$ git add local_settings.py settings.py .gitignore #ファイルを指定したい場合は、こちらでもok
$ git commit -m "SECRET_KEY変更" #"コメントはご自由に変更してok"
$ git push origin master #origin, masterは各々の設定にしてください
```

###### 3-3. 完成

これで、`①SECRET_KEYを新しくし`、`②GitHubから見えないようにする`ことができました。

# 4. まとめ

処理を図にまとめてみました。

![secret_key_github_fix.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403981/8cc0df90-2765-f9b5-6fd4-3d77505595c2.png)

# 5. 参照
- [Djanjo公式ドキュメント | SECRET_KEY](https://docs.djangoproject.com/ja/2.2/ref/settings/#secret-key)
- [GitHub | Django utils.py](https://github.com/django/django/blob/2.1/django/core/management/utils.py#L76)
- [DjangoのSECRET_KEYをバージョン管理対象外にする](https://qiita.com/haessal/items/abaef7ee4fdbd3b218f5)
- [DjangoアプリをHerokuにデプロイする方法](https://qiita.com/frosty/items/66f5dff8fc723387108c)

以上
[AWS] Lambda function で X-Ray を使ってみる。





# はじめに
やることは、とりあえず AWS lambda で X-Ray を使ってみるところまで。
「こういうときはこうするんだよ」みたいなお役立ち情報はほぼありません。
言語は Python3.6 を使用。

# 最低限の動作
## 設定
Lambdaの画面で「アクティブトレースを有効にします」というチェックボックスをON（チェック）にして保存するだけ。
![2019-06-19 11_04_42-Window.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193715/4c9c555a-3037-5817-0321-c45791878691.jpeg)


## 実行
Lambdaソースは `Python 3.6` のデフォルト。statusCodeとメッセージを返すだけの処理です。
テストを実行し、`X-Ray のトレースを表示` ボタンから、X-Ray の画面に遷移。
以下のようなトレース情報が表示されます。
![2019-06-19 11_06_00-Window.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193715/c124dda3-614f-7684-4096-dad938da5a2b.jpeg)
![2019-06-19 11_06_14-Window.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193715/e528cc43-ddfb-e9db-77c2-c8281ce03a5d.jpeg)
![2019-06-19 11_09_58-Window.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193715/b380b3b2-d3f6-25b5-6c87-f547d53f566d.jpeg)



# Lambdaから呼び出すサービスもトレースしたい
これだけだと、ただ開始～終了を計測しているだけですね。
X-Rayの強みはAWSのサービスも計測できること。
というわけでそれもやってみます。

## X-Ray SDK をダウンロード。
lambda環境のデフォルトのままでは実現できないようです。
X-Ray SDK をソースと一緒に置く必要があります。
とりあえずローカルにダウンロード。下記コマンドで今いるフォルダにダウンロードされます。

```bash
$ pip install aws-xray-sdk -t .
```

## Lambda function ソース
LambdaからSNSをpublishするようにします。
あと sdk の patch を適用する必要があるようです。そのためのSDK同梱。

```python:lambda_function.py
import json
import boto3

# パッチ適用
from aws_xray_sdk.core import patch
patch(['boto3'])

def lambda_handler(event, context):
    # SNS を Publish
    client = boto3.client("sns", region_name="ap-northeast-1")
    request = {
        'TopicArn': "<SNS Topic の ARN>",
        'Message': "test message",
        'Subject': "test subject"
    }
    response = client.publish(**request)


    # TODO implement
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }
```

## まとめてzip
functionのソースとSDKをまとめてzip化。
![2019-06-19 11_51_45-タスク ビュー.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193715/f621458d-7d8b-056c-5092-80813afd9d6d.jpeg)

ダウンロードしたSDKは中を見ると色々入ってますが、以下の３種だけでいいようです。
使い方次第では他のライブラリも必要になるかもしれません。

* awsxray_sdk
* jsonpickle
* wrapt

## ソースをアップロード
Lambdaの編集画面で、コードエントリタイプを「.zipファイルをアップロード」に変えて、SDK（ライブラリ）と lambda_functionソースファイルをまとめた先ほどのzipを選択。
保存して、こうなっていればOK。
![2019-06-19 13_16_23-タスク ビュー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193715/3cf71727-60f9-b791-9bd1-ed46f16987af.png)

## 実行
SNSのトレース情報も計測されるようになりました。
![2019-06-19 11_16_35-Window.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193715/27e674f2-1038-260b-c214-47c86a747c92.jpeg)
![2019-06-19 11_16_56-Window.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193715/da82073f-dde4-a394-e57a-9fe8a8e7feed.jpeg)
HerokuのPostgreSQLの使い方【LineBot辺】

# HerokuのPostgreSQLの使い方
Heroku上でPostgreSQLを使う場合、Pythonの場合は[psycopg2](http://initd.org/psycopg/docs/)を使えば良いようだ。
なお、HerokuにPostgreSQLを追加した時点で、環境変数に```DATABASE_URL```という名称でアクセス用のアドレスが追加される。
アドレスは長い周期で変わるからのようだ。

なので、前回わざわざユーザーを作っていたが使用する必要がないようだ。
今回自分が作ろうとしているラインボットなど、SQLの返答の行数がたかが知れている場合、次のように同期やメモリなどを考えずに取ってこさせれば良い。

``` python

DATABASE_URL = os.environ['DATABASE_URL']
conn = psycopg2.connect(DATABASE_URL, sslmode='require')
cur = conn.cursor()
cur.execute("なにか適当なSQL文")
data_list = cer.fetchall()

```

自分の場合は、「3人以上の軽いゲームを教えて」というような日本語とテーブルゲームのテーブルからSQL文を作成し、メッセージを送り返すようなプログラムを作った。
linebotについても初めてだったので、とりあえず[一番手軽そうな資料](https://uepon.hatenadiary.com/entry/2018/06/19/222537)を参考にGitHubからサンプルを回収し、クラスを新しく作って返信用のクラスから回答を取ってくるようにさせた。
具体的には、下記のように「GamebarResponce」という名前のクラスを作って、メッセージを投げ込んだらゲームを探して返信するようにした。


```python:main.py(抜粋)
@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    gm = GamebarResponce()
    gm.connect_database()

    retstr = gm.check_text(event.message.text) + "ゲームを探しました。\n"
    retstr += gm.get_game_from_message()

    line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text=retstr))
```

## ソフト作成時の注意点
ソフトの作成・アップロード時には注意点がいくつかある。
1. メモリサイズは限られる。1GBを超えたりすると、強制的にアプリが落とされる。日本語解析のライブラリなど、大規模なものは入れることができないため注意だ。
2. GitHubから落としたサンプルは、ライブラリの記述やheroku乗で動かす際のファイルが欠落している。自分の場合、次のようにrequirements.txtを書き換え、Procfileファイルを作成した

```text:requirements.txt
requests >= 2.0
future
psycopg2-binary
Flask
gunicorn
mojimoji
kanjize
```

なお、本プログラムの作成には[漢数字・ローマ数字変更ライブラリ「kanjize」](https://qiita.com/nagataaaas/items/154751c4f23b468e1c15)と、[全角・半角変換用ライブラリ「mojimoji」](https://qiita.com/ikuyamada/items/fea6c8f81e7cac7cf318)を利用させていただきました。
正規表現で文章をチェックする前の下準備に利用させて頂いています。


```text:Procfile
web: gunicorn main:app --log-file -
```

# 動作チェック

そして作られたアカウントにメッセージを送ってみた結果が下記の画像。
![画面例.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395414/8a53cb6f-ec86-2247-5655-8b91bbbbc5a0.jpeg)
一部間抜けなミスがあるが、現在は修正済。レスポンスも気になるような遅さではないのでこれで一旦完成とした。
あとはデータを追加し次第公開予定。

# おわりに

適当な日曜大工レベルのアプリの場合、ツボを押さえれば簡単に公開までこぎつけることができるようだ。
自分の場合は正規表現で間に合うような日本語の解析に、わざわざ文章解析用のライブラリを使ってしまい、リソースを無駄にした上に遠回りしてしまった。
当たり前だけどリソースは予め確認する必要がある。

次は何を作ろうかな。
リスト最後尾への追加は、実際どのくらい遅くなるのか

[elixir school](https://elixirschool.com/ja/lessons/basics/collections/#%E3%83%AA%E3%82%B9%E3%83%88) のドキュメントに以下の記載がある。

```
Elixirはリストコレクションを連結リストとして実装しています。
すなわちリストの長さを得るのは線形時間(O(n))の処理となります。
このことから、リスト先頭への追加はほとんどの場合にリスト末尾への追加より高速です
```

そうなんだ。
で、実際どのくらい？が気になったので試してみた。

バージョン情報は以下。

```
[twintaro@phoenix ~]$ elixir --version
Erlang/OTP 22 [erts-10.4.2] [source] [64-bit] [smp:1:1] [ds:1:1:10] [async-threads:1] [hipe]

Elixir 1.9.0-rc.0 (e5888e7) (compiled with Erlang/OTP 22)
```

以下のコードで試す。


```
defmodule My do
  def insert_check(len) do
    ary = for x <- 1..len do
      x
    end
    starttime = Time.utc_now
    for y <- 1..100 do
#1      List.insert_at(ary, -1, y)
#2      [y|ary]
    end
    endtime = Time.utc_now
    IO.inspect Time.diff(endtime, starttime, :microsecond) / 100
  end
end

length_patterns = [1,1,10,100,1000,10000,100000]
for lp <- length_patterns do
  IO.inspect My.insert_check(lp)
  IO.inspect "-----"
end
```

コメントアウトしてある部分は、
1が最後尾への追加、
2が先頭への追加
です。

1~100000までの長さの配列を作って、そこに対して要素の追加を行います。
(実際に追加されるんじゃなくて、追加された配列が返る)

回数少ないとブレそうなので１００回やって平均を出します。
で、結果。

1.最後尾への追加

```
0.21 # 1
"-----"
0.29 # 10
"-----"
0.57 # 100
"-----"
6.79 # 1000
"-----"
63.48 # 10000
"-----"
981.81 # 100000
"-----"
```

確かに、配列の要素が増えるほど、処理時間が増えてる。。。
では、先頭への追加は？

2.先頭への追加

```
0.14 # 1
"-----"
0.06 # 10
"-----"
0.05 # 100
"-----"
0.07 # 1000
"-----"
0.1 # 10000
"-----"
0.29 # 100000
"-----"
```

うん、要素が増えても、処理速度は変わらない。
要素数が少なければそんなに問題にならないかもですが、
理由がなければ先頭に追加をしておけば安心ですね。

実際数値で出してみて、腹落ちしたというお話でした。m(_ _)m
iOSを12.3にアップデートすると、ASP.NET coreのAzure AD認証ができなくなった

# 無限ログインループ発生
## どういうアプリで起きたか
ASP.NET core MVC(2.2)のWEBアプリケーション（の社内ツール）です
（自分はその開発・保守をしています）。
利用者の認証にはAzure Active directory v2のOpen ID Connectを組み込んでいます。
社内ツールですが、社員の皆さんの手持ちのデバイスからもアクセスできるようになっています。
## どういう環境で起きたのか
iOSを12.3にアップデート後、iPhoneユーザーの皆さんがSafariでアクセスするときにそれは起きました。
## どういう事象が起きたか
ログイン画面でログインしても、またログイン画面に戻ってしまう「無限ログインループ」が発生していました。
直属の上司×２にその事象が起きて困っていた＆若干イラついていたので、急いで調べました。

# 原因：Safariがトークンをくれなかった
## まずそもそも認証の仕組みはどうなっているのか
サインインの処理が走ったタイミングで、
1. クライアントからリダイレクトしてAzure ADにトークンを取得し
2. そのトークンをアプリに再びリダイレクトし、
3. アプリがしかるべきビューを返却しています
今年やっと公開された分かりやすい図です（この図がずっとほしかった、、、！）
![aspnetcorewebapp-intro.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269736/0e031a10-b87e-9c4b-98cd-ac177795c080.png)

（参照：https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-v2-aspnet-core-webapp）
## 事象が発生していた原因
ログイン画面から認証処理が走り、初期画面が表示されるのが正なのですが、
アプリに再度リダイレクトされるタイミングで、Azure ADから取得したトークンが削除されていました。
Safariのアップデート時に、*同じサイトのものでないクッキーをリクエスト時に送信できない*仕様に変更されたようです。
![Safari12_releasenote.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269736/c358073f-fd9c-fe1b-3e8c-e6dce555be95.png)

（参照：https://developer.apple.com/documentation/safari_release_notes/safari_12_release_notes)
クロスサイトスクリプティング対策のようです。
これに関連してか、cookieのsamesite属性がsafariでは未対応のようです。
# 対策：startup.csの設定を変えた
ASP.NET coreのstartup.csに設定することでSameSiteModeをオフにすることができます。
ひとまずこれによって無限ログインループは解消されました
```C#
 services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
                .AddAzureAD(options => {
                    Configuration.Bind("AzureAd", options);
                })
                .AddCookie(options=>
                        options.Cookie.SameSite = SameSiteMode.None
                    );
```
https://github.com/aspnet/AADIntegration/issues/52
# これから
safari13もプレビューになっているようですが、これからはcookieの設定もアプリでちゃんと管理しないといけないな、と思いました（小並感）。
# 参照
- webkitフォーラムでの議論
   - https://bugs.webkit.org/show_bug.cgi?id=188165
   - release 77でやってるから、てゆってるけど、、、
- djangoでのソリューション
   - https://github.com/vintasoftware/safari-samesite-cookie-issue
   - cookieの変化を説明してて分かりやすい
- asp.net 公式
   - https://github.com/aspnet/AspNetCore/issues/4647
   - プチ炎上
   - MS的には「APPLEのせい！」
- stack overflowのissue
   - https://stackoverflow.com/questions/52544576/azure-active-directory-safari-redirection-issue
   - Azure　Portalでも出てた事象
- CORSとは
   - https://qiita.com/tomoyukilabs/items/81698edd5812ff6acb34
- CookieのSamesite属性について
  - https://laboradian.com/same-site-cookies/![uploading-0]()
マークダウンとは？を数行で説明

# 概要

**マークダウン**とは、乱暴に言うと**次のルールでテキストを書くこと**(記法)。

- 章タイトル／見出しは「`# `」で始める
- 箇条書きは「`- `」もしくは「`* `」で始める
- 引用は「`> `」で行う

以上！

## 本記事の目的

「マークダウンってなんですか？」って聞かれることがそこそこの機会あり、その時に如何に簡単に説明するか？を言語化したかった。

文章構造を表現するためのフォーマットだとか、マークダウンはHTMLへの変換を目的としたものだとか、籠めたい想いや内容の不足はいろいろあるが、**「細けぇことはイインダヨ」**という方針で、表現してみたくなった。

### 余白

> Markdown（マークダウン）は、文章の書き方です。
> 
> http://www.markdown.jp/what-is-markdown/

> Markdown is a text-to-HTML conversion tool for web writers.
> 
> https://daringfireball.net/projects/markdown/



# もうすこし詳しく

数行で説明しようとするなら、上記の述べ方、が私が聞く立場ならばしっくりくるかな（異論は認める）。

んで、「記法はそれだけ？何が嬉しいの？」って興味をもって聞き返されたら、次のように答えるかな。

## どういう記法か？

次のルール（フォーマット）に則ってテキストを書くことを「マークダウン（記法）で書く」と呼ぶ。

- 章タイトル／見出しは「`# `」で始める
    - 半角記号の後ろに半角スペースを1つ入れる
    - 節タイトルや**小**見出し等の階層構造を「`## `」、「`### `」で表現する
- 箇条書きは「`- `」もしくは「`* `」で始める
    - 半角記号の後ろに半角スペースを1つ入れる
    - 実は「`+ `」も使える。
- 入れ子構造にするときは、半角スペース4つインデントする。
    - 例：「`　　- `」、「`　　 * `」※表現の都合で全角スペース利用。
    - 番号を振りたい時は「`1. `」とする。
        - 全部「`1. `」「`1. `」でもよいし、「`2. `」「`3. `」とカウントアップしても良い。
- 引用は「`> `」で行う
    - 半角記号の後ろに半角スペースを1つ入れる
- **強調**は「`次の**ABC**の部分を`」のようにアスタリスク２つで囲う。

より詳しい記法は、「Markdown記法 チートシート」などで検索のこと。


## 何が嬉しいの？

まず、次のことが嬉しい。

- テキストを書いた人と読んだ人との間で、見出しや箇条書きの部分での認識齟齬が生まれない。
- 箇条書きの記号として何が良いか？を悩む手間が省ける。
- 互いに「この記号は、、、何を意図したのだろう？」などと、文章の外側の部分で迷わずに済む。

そして、環境がそろえば容易に「**見出し、箇条書き、引用などをいわゆるHtml相当で装飾**した状態」で見る／見せることが出来る、ことが嬉しい。
なお、以下ではテキストファイルを「`*.md`」の拡張子で保存することを前提とする。

- [Visual Studio Code](https://code.visualstudio.com/) でファイル（左）を開くと、装飾状態をプレビューでリアルタイム表示できる（右）。
![VSCodeでのMarkdownプレビュー表示](https://gyazo.com/af1563891d2cfaf551847cf04a717c8d.jpeg)
- VSCodeにプラグイン「`vscode-pandoc`」をインストールすることで、プレビュー表示に沿ってHTMLファイル、**Wordファイルへ簡単に変換**できる。
- GitHubに入れた時には、ブラウザ上でプレビュー表示のように表示しててくれる。
    - いわゆる「README.md」などのファイルがコレ。

### 余白

> VSCodeでMarkdownを Word や PDF に変換してみる
> 
> https://www.doraxdora.com/blog/2018/11/09/post-6681/


# まとめ

Markdownとは、テキストで見出しや箇条書きを悩まずに表現して齟齬なく伝えることが出来る記法。

ついでに、実際に装飾したWordやHtmlへ変換できるのが嬉しい記法。


改めて以上ー。
Docker上にapacheサーバを立てて，それをherokuにデプロイしたかった記録

# TL;DR

とあるプロダクトを出すためにApacheサーバをDocker上に立てて，それをherokuにデプロイして，外から簡単にアクセスできるようにしたかった．

#やったこと

普通にhttpdをpullしてやってみた

```
$ docker pull httpd
```
して，以下のようなDockerfileを書いてみた．

```
FROM httpd as httpd-server

EXPOSE 80

CMD ["httpd"]
```

しかしながら`It Work!`は出ず....

ログを確認

```
2019-06-19T00:46:47.377085+00:00 heroku[eb1651c4697b.1]: Starting process with command `bin/httpd -D FOREGROUND`
2019-06-19T00:46:48.048067+00:00 heroku[eb1651c4697b.1]: State changed from starting to up
2019-06-19T00:46:49.247891+00:00 heroku[eb1651c4697b.1]: State changed from up to crashed
2019-06-19T00:46:49.160414+00:00 app[eb1651c4697b.1]: (13)Permission denied: AH00072: make_sock: could not bind to address [::]:80
2019-06-19T00:46:49.160441+00:00 app[eb1651c4697b.1]: (13)Permission denied: AH00072: make_sock: could not bind to address 0.0.0.0:80
```

どうやら権限が足りなくてポートをバインドできていない...

# 解決法

わからないので調べている
go moduleについてメモ

##　前提
バージョンがgo1.11以上じゃないとmodのsubcommandが無いっぽい

go1.10

```
$ go version
go version go1.10 darwin/amd64

$ go help
The commands are:

        build       compile packages and dependencies
        clean       remove object files and cached files
        doc         show documentation for package or symbol
        env         print Go environment information
        bug         start a bug report
        fix         update packages to use new APIs
        fmt         gofmt (reformat) package sources
        generate    generate Go files by processing source
        get         download and install packages and dependencies
        install     compile and install packages and dependencies
        list        list packages
        run         compile and run Go program
        test        test packages
        tool        run specified go tool
        version     print Go version
        vet         report likely mistakes in packages

```

go1.11

```
$ go version
go version go1.11.4 linux/amd64

$ go help
The commands are:

        bug         start a bug report
        build       compile packages and dependencies
        clean       remove object files and cached files
        doc         show documentation for package or symbol
        env         print Go environment information
        fix         update packages to use new APIs
        fmt         gofmt (reformat) package sources
        generate    generate Go files by processing source
        get         download and install packages and dependencies
        install     compile and install packages and dependencies
        list        list packages or modules
        mod         module maintenance　←これ
        run         compile and run Go program
        test        test packages
        tool        run specified go tool
        version     print Go version
        vet         report likely mistakes in packages
```

#### 補足作業メモ
下記コマンドで確認してみた所、1.10までのバージョンしかインストール出来なかった。

```
$ goenv install -l
```

私はbrewでgoenvをインストールしたのでアップグレードが必要。

```
$ brew upgrade goenv
$ goenv install 1.11.4
$ goenv global 1.11.4
$ goenv version
1.11.4 
```

あとはIDEのGOROOTを .goenv ディレクトリ内に新しくインストールされたフォルダを指定する。

## go moduleの使い方

### コマンドで実行する場合
```
$ export GO111MODULE=on
$ go mod init
```

実行するとgo.modというファイルが出来る。
buildするとgo.sumが出来る

### Dockerにする場合

Dockerファイルに下記のような感じで書いてあげれば依存パッケージがダウンロードされる

```
COPY go.mod .
COPY go.sum .
RUN go mod download
```

## 参考
- [depからgo modulesへの移行と、移行時にTravis CI & GoReleaserでハマる（かもしれない）ポイント](https://horizoon.jp/post/2019/02/25/dep_to_go_mod/)
カクヨム風記法でルビと圏点（傍点）が振れるpandocフィルタを作った

- [pandoc-kakuyomu-ruby](https://github.com/Gamou-T/pandoc-kakuyomu-ruby)（GitHub）

## 動機

皆さんはいつもドキュメントを書く時に何を使ってますか？

自分はmarkdown使ってます。いいですよね、markdown。pandoc使えばepubやpdfに変換できますし、VSCodeでそのプレビューもできる。

しかし、markdownだけではどうしようもない事がありました。それがルビです。

ルビを振るにはtexに変換した後に手動でコマンドを入れるか、htmlタグを手動で入れるぐらいしか方法がありません。これではwordに負けてしまいます。

先人（[mod_poppo](https://qiita.com/mod_poppo)氏）の記事[^1]によると、公式でpandocフィルタがあるらしいのですが、やはり自分もその記法が気に食わなかったので自分で作る運びとなりました。

## 要件

- pythonで書く
  - 今度Windows10にも標準で付くらしいので環境構築が楽（多分）
  - 既にそれ用のライブラリがあったから
- 先人のフィルタと同等以上の機能を付ける
  - でなきゃただの劣化コピーなのでわざわざ作る意味がない

## 記法

[カクヨム記法](https://kakuyomu.jp/help/entry/notation)をベースに使います。カクヨムは標準で圏点に対応しているため、これをそのまま流用するのが楽だと考えました。

なお、カクヨムでは区切り文字に半角縦棒`|`も使えますが、このフィルタでは使えません。ぶっちゃけ日本語入力中にわざわざ半角に切り替える事なんてそうそうないし大丈夫でしょう。（慢心）

また、markdownのマークアップ（強調、上付き、下付き等）と併用する事はできません。

また、このフィルタは~~長音記号と和文（ひらがな、カタカナ、漢字）にのみ対応しております。アルファベット及び記号には対応しておりませんので悪しからず。~~（追記: 長音記号以外の記号（unicodeで定義された約物）にも対応しましたが、LaTeXの特殊文字との競合は一切考慮しておりません。この辺は運用でカバーしてください。ここがアマチュアプログラマの限界です。

```markdown
## 範囲を明示的に指定してルビを振る

あれは｜雀《すずめ》です。

あれは｜雲雀《ひばり》です。

### ひらがな・カタカナにも振れる

このコードは｜読みにくい《くそったれ》です。

これは｜スパゲティー《くそったれ》コードです。

## 漢字だけを対象にルビを振る

あれは雀《すずめ》です。

あれは雲雀《ひばり》です。

### これはそのまま出力される

このコードは読みにくい《くそったれ》です。

皆さんも｜Linux《リナックス》を使いましょう。

## 一行中にいくつでも使える。

“事故”る奴は…“不運《ハードラック》”と”踊《ダンス》”っちまったんだよ…

## 圏点も振れる

《《アレ》》には気をつけてください。

### もちろんルビと併用可

《《アレ》》を処理《こわ》してください。

### アルファベットには対応していない

ワタシ 《《Linux》》 チョットデキル。

### 記号が入ってても使えない

《《彼は「あれが欲しい」と言った。》》
```

ついでに`pxrubrica`というLaTeXで使えるルビのパッケージがあるため、そちらのグループルビ・熟語ルビなど一部の機能も使えるようにしました。（markdownのfront-matterで指定する必要あり）

ちなみにこちらも区切り文字は全角縦棒`｜`で統一しています。半角だと動きません。

ルビ内に区切り文字を入れなければ`luatexja-ruby`など他のパッケージでも使用可能です。（区切り文字があるとエラーを吐く）

要するに`\ruby{親文字}{ルビ}`と`\kenten{親文字}`にさえ対応していれば何でも使えます。（多分）

```markdown
---
header-includes: # pxrubricaを読み込み、自動切替熟語モード（進入大）に指定
  - \usepackage{pxrubrica}
  - \rubysetup{<J>}
---

## グループルビ

あれは雲雀《ひばり》です。

あれは啄木鳥《きつつき》です。

## 熟語ルビ

それには苦労《く｜ろう》しました。
```

## ダウンロード・インストール

[Github](https://github.com/Gamou-T/pandoc-kakuyomu-ruby)の方からどうぞ。（投げやり）

## （6/19 18:30追記）ルビ記法のエスケープに対応

なんか足りないなと思ったらルビ記法のエスケープ機能がありませんでした。以下の記法でエスケープできます。

```markdown
単語｜《よみがな》
```
実際の表示はこうなります。

> 単語《よみがな》

## 参考記事

- [Pandoc Markdownで青空文庫風のルビ記法を使う](https://qiita.com/mod_poppo/items/218500f4e22eaecfe4b5)（[mod_poppo](https://qiita.com/mod_poppo)氏）

[^1]: [Pandoc Markdownで青空文庫風のルビ記法を使う](https://qiita.com/mod_poppo/items/218500f4e22eaecfe4b5)
ニートの自然言語処理100本ノック:37

日本語の設定で無駄に時間を取ってしまった。
後,plt.legend()を使おうと思ったが出力結果が一つだけだったので次の予習に回すとしよう。

```python
import MeCab
from pprint import pprint
import collections
from n30_execise import maping_morphology
from n31_execise import load_mecab_file
from n36_execise import extract_type_all,extract_frequent_words
import matplotlib.pyplot as plt
import pandas as pd

# グラフの種類、出現単語、出現回数

def create_words_frequency_graph(x,y,graph='bar',title="",xlabel="",ylabel="",y_lim=[0,10000],_grid=None,log_log=False):
    '''
    とりあえず、bar　plot で出力する
    日本語フォント
    FIXME:histogramの時だけbins=bins_が必要?分岐する必要あり(default bins_=False)

    '''
    igfont = {'family':'IPAexGothic'}
    plt.rc('font',**igfont)

    data = pd.Series(y,index=x)
    data.plot(kind=graph,label=y,grid=_grid,loglog=log_log)
    plt.title(title,**igfont)
    plt.xlabel(xlabel,**igfont)
    plt.ylabel(ylabel,**igfont)
    plt.ylim(y_lim)

    plt.show()


if __name__ == "__main__":
    
    # ファイルパス
    mecab_file = "neko.txt.mecab"

    # neko.txt.mecabを読み込む
    mecab_text = load_mecab_file(mecab_file)

    # 形態解析後のマッピングリスト
    analyzed_list = maping_morphology(mecab_text)
    # 表層形だけを取り出したリストを作成する
    surface_list = extract_type_all(analyzed_list)
    # 出現頻度の高い値とその回数を取り出す
    freq_value,freq_count = extract_frequent_words(surface_list,N=10)
    print(freq_value,freq_count)
    # グラフ作成
    create_words_frequency_graph(freq_value,freq_count,title="出現頻度の高い単語グラフ",xlabel="出現単語",ylabel="出現頻度",y_lim=[0,9000])


```
#　出力結果
![スクリーンショット 2019-06-19 12.16.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263492/b8db868e-1334-43bc-26a3-ff2f124e5ecc.png)
Salesforce Commerce Cloudへ接続するためのEclipseの設定

# はじめに
Salesforce Commerce Cloud へカートリッジ（プラグインみたいなもの）を
アップロードする際にEclipseでの設定がいりますので、
設定手順を共有いたします。

# Eclipse・Javaのインストール
Commerce Cloudと接続するためにUX StudioというものをEclipse内でインストールしなければいけないのですが、サポートバージョンが決まっております。
Eclipseを利用するのにJavaが必要なのでインストールしておきます。

* Java8
  - https://www.oracle.com/technetwork/jp/java/javase/downloads/jre8-downloads-2133155.html

* Eclipse Neon(Eclipse IDE for Java EE Developers)
  - https://www.eclipse.org/downloads/packages/release/neon/3

# UX Studioのインストール

* 「Help」 > 「Install New Software…」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377903/58420a98-1103-35cf-9457-776c55aab013.png)

* 「Add…」ボタンを押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377903/00f55755-d6f6-b77e-7fce-276e9f68aba0.png)

* Eclipseのバージョンに対応するUX Studioのインストール
  - 以下内容を入力
    - Name: UX Studio
    - Location: https://developer.salesforce.com/media/commercecloud/uxstudio/4.6
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377903/deef5516-93fa-45ce-7396-d5a3ea5c8bf1.png)

* 途中で以下のようにWarningが出ますが迷わず「OK」を押してください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377903/cd056f74-95ed-f9c1-5824-19a14a237854.png)

* Eclipse再起動

# Salesforce Commerce Cloudへの接続設定
* 「File」 > 「New」 > 「Other...」を押下

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377903/7e127854-cde1-162c-f5b6-e0343ab8aeda.png)

* 「UX Studio」 > 「Digital Server Connection」を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377903/b0ca1496-3752-34d1-9847-44df8885e0b0.png)

* 必要事項を入力する
  - 以下入力する
    - Host name：XXXXXX.demandware.net
    - User name：Business Managerのアカウントユーザー名
    - Password：Business Managerのパスワード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377903/bdc21c2d-c36a-c744-2131-bce223497eb2.png)

* バージョンを指定する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377903/8908ba0e-4533-b60d-494b-f1163f113c16.png)

* 以下赤枠の部分のように緑色の文字が表示されれば接続完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377903/473bde26-24b9-7457-8ae3-ae70aca05ba6.png)

# おわりに
Eclipseは重いのですごく嫌な気持ちになりますが、最近はVS codeでアップロードするプラグインも提供されています。ただしVS codeの方はオフィシャルのものではなさそうなので、注意が必要かもしれません。
またVS codeの設定方法も記載したいと思います。
Ruby　ハッシュ　値を上書き

<img width="668" alt="デスクトップ_—_-bash_—_80×24_と_sample_rb.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378273/449f6c28-93c9-dcfb-5bca-84a33aa1e2a5.png">
スクレイピングで無限スクロールするときのTips

#機械学習するときのデータ収集
機械学習をやっていて、欲しい画像をえるためにスクレイピングで、googleエンジンなどを使うとぶち当たるのは無限スクロールの壁。
ページネーションされていればいいけど・・・
マウスでのスクロールを機械的にする方法はいろいろとあるようですが、
その中で自分の環境でうまくいった方法をお教えします。
多分これが一番早いと思います・・・

##実行させるJavescript
まずはスクロール
多くのサイトで挙げられているのが
`driver. window.scrollTo(0, window.innerHeight)`
ですが、自分は
`document.getElementById('b_footer').scrollIntoView(true)`
を採用して、フッターのところまでスクロールさせてます。
サイトによってはフッターがなかったり、代わりにToastsがあったりしますが、基本的に一番下のタグを選択できればＯＫかと

##読み込み終了まで待機する
下までスクロールしたら画像が表示するまで待機する必要がありますが、
Seleniumには暗黙的に待つ`implicitly_wait()`メソッドが用意されていますが、これではうまくいきませんでした。
な、の、で、
`time.sleep()`でプログラム自体を待機させてます。とあるサイトでは御法度とされてますが・・・

##プログラミングコード例
Bing画像検索で画像サムネイルを得るためのコードです。

```python
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC 
from selenium.webdriver.common.keys import Keys
from time import sleep

keyword="牛丼"

driver = webdriver.Firefox()

url="https://www.bing.com/?scope=images&FORM=Z9LH1"
driver.get(url)

form = driver.find_element_by_name("q")
form.send_keys(Keys.ENTER,keyword,Keys.ENTER)
WebDriverWait(driver,10).until(
EC.presence_of_element_located((By.CLASS_NAME,"mimg"))
)
imgset=set()
for i in range(20):
    print(i)
    #driver.execute_script("window.scrollTo(0,100 );")
    driver.execute_script("document.getElementById('b_footer').scrollIntoView(true)")
    driver.implicitly_wait
    sleep(2)
    img = [ele.get_attribute("src") for ele in driver.find_elements_by_class_name("mimg")]
    imgset |= set(img)
```
重複を防ぐために画像のurlをセットに格納しています。

###最後に
もしいい案があれば教えて下さい。
ruby 　ハッシュオブジェクトと、シンボルオブジェクト

<img width="649" alt="デスクトップ_—_-bash_—_80×24_と_sample_rb.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378273/dba41a67-6dcb-093c-92ba-b70911b479e3.png">

hashは複数の変数を持つことができる。
入力の仕方としては以下の通り。
「macOS」タグについて (タグシノニム: 「mac」「macosx 」「osx 」)

### 対象
(件数は2019-06-19現在)

- https://qiita.com/tags/macos : 844件

### 説明

Apple社が提供するMac Pro, MacBook Air, Macbook Proなどに搭載されるOSのこと。

https://ja.wikipedia.org/wiki/MacOS

OS名の変遷に伴い、Qiita記事執筆者はどのOS名を使うか混乱し、結果としてQiita記事は分散していくという典型例。

### タグシノニム
(件数は2019-06-19現在)

- https://qiita.com/tags/mac : 7616件
- https://qiita.com/tags/macosx : 2661件
- https://qiita.com/tags/osx : 1372件
- [https://qiita.com/tags/MacOS,](https://qiita.com/tags/MacOS,) : 2件 (タグ入力間違い?)

備考: macタグについてはハードウェアの記事の可能性もなくはないが、ソフトウェアの記事も多そうなため、タグシノニムとした。

### バージョン違い
(件数は2019-06-19現在)

- https://qiita.com/tags/sierra : 175件
- https://qiita.com/tags/elcapitan : 157件
- https://qiita.com/tags/mojave : 137件
- https://qiita.com/tags/highsierra : 111件
- https://qiita.com/tags/macOSSierra : 108件
- https://qiita.com/tags/macOSMojave : 90件
- https://qiita.com/tags/macOSHighSierra : 54件
- https://qiita.com/tags/macOSMojave10.14.3 : 5件
- https://qiita.com/tags/macOSCatalina : 2件
- https://qiita.com/tags/mohave : 1件

Tigerは? 

### その他

- https://qiita.com/tags/macOSServer : 5件
- https://qiita.com/tags/macbook : 129件
- https://qiita.com/tags/macbookpro : 98件

### Acknowledgement

Thanks to @mafumafuultu (macとmojaveタグ)
rubocopでソースの複雑さ (AbcSize) を計測した結果を一覧にする

今入ってるプロジェクトでAbcSizeが大きくなっているのが問題になっていて、全体的に俯瞰する目的で作ってみました。
ほぼ下記の参考記事のを改変したものになります。先達の皆様に感謝です。

参考記事
https://tech.grooves.com/entry/2017/07/14/094352
https://gist.github.com/sinsoku/2c37b2efed514c7ac212203dc867e045

プロジェクト直下のディレクトリに置いて実行してみてください。


```ruby
#!/usr/bin/env ruby

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# 参考記事
# https://tech.grooves.com/entry/2017/07/14/094352
# https://gist.github.com/sinsoku/2c37b2efed514c7ac212203dc867e045

# How to Use
#   $ ruby calc_abcsize.rb

# Result Sample
# ./tmp/abcsize.txt
#    path/to/file/foo : 10
#    path/to/file/bar : 20
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=

require 'csv'
require 'json'
require 'rubocop'
require 'tempfile'

# 結果がこの値以下の時は出力されません
ABC_SIZE_MAX = 15

CONFIG = <<~EOF
AllCops:
  DisabledByDefault: true
  Exclude:
    - 'tmp/**/*'
    - 'db/schema.rb'
    - 'node_modules/**/*'
Metrics/AbcSize:
  Max: #{ABC_SIZE_MAX}
EOF

MESSAGE_REGEXP = %r{\[(.+)/#{ABC_SIZE_MAX}\]$}
FILE_PATH = 'tmp/abcsize.txt'

def config
  @config ||= Tempfile.new.tap do |f|
    f.write(CONFIG)
    f.close
  end
end

def out
  @out ||= Tempfile.new.tap { |f| f.close }
end

def run_rubocop
  args = ['--parallel', '--config', config.path, '--format', 'json', '--out', out.path]
  RuboCop::CLI.new.run(args)
  JSON.parse(File.read(out.path))
end

def calc_result(json)
  result = []
  json['files'].each do |file|
    file['offenses'].each do |offense|
    #   res = offense['message'].match(MESSAGE_REGEXP)
    #   result << [res[1].to_f, file["path"]] if res
      res = offense['message'].match(MESSAGE_REGEXP)
      result << [res[1].split('>')[1].to_f, file["path"]] if res
    end
  end
  result.sort{|a, b| b[0] <=> a[0]}
end

json = run_rubocop
result = calc_result(json)

File.open(FILE_PATH, 'w+') do |file|
  result.each{|item| file.puts item.join(" : ")}
end

```
連想配列（オブジェクト）について勉強してみた

# 連想配列を勉強してみた

勉強するきっかけはVue.jsを勉強していく中で、ひょっとしてお前は連想配列からできているのではないかと感じたので調べて見る事にした。

## 配列の初期化と要素の追加

### 連想配列の静的初期化
静的な初期化では、初期化と同時に要素も設定できます。

```javascript:javascript
let vhash = {
  data : 'hashData',
  methods: 'hashmethod'
}
```

配列と違い、インデックスのかわりに文字列(data:,methods)が要素を特定する**キー**となり、それに対応する値としてdata:はhashData、methods:はhashmethodという値が設定される。

```javascript
console.log(vhash.data) // hashData
console.log(vhash.methods) // hashmethod
```

### 連想配列の動的な初期化と要素の追加
個人的に凄く衝撃的な記述をしていて、なるほどと思うことも多々ありました。

```javascript:javascript
//配列の初期化
let vhash = {}
//配列にkeyを設定し、keyに対し値を設定する
vhash.data = 'hashData'
vhash.methods = 'hashmethod'
```

```javascript:結果の出力
console.log(vhash.data) // hashData
console.log(vhash.methods) // hashmethod
```

連想配列の静的初期化の説明の時にネタばれがありましたが、連想配列は「.(ドット)」を使って参照でき、存在しない場合は新たにkeyを追加するらしいです。
「　[]　(大カッコ)」を極力使用したくない僕として驚きでした。

## 自分なりに色々試してみた。
【追記】
連想配列と言っていますがJavaScript では「オブジェクト」と言うらしいです。
でもオブジェクトと調べたらJavaScriptのあらゆるものはオブジェクトという感じの記事をみたりしたので今回は連想配列を勉強していく過程でオブジェクトに行き着いたという感じにしておきます！
コメントに感謝です！

**[JavaScript オブジェクトの基本](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object)**

連想配列を勉強中(本当はVue.jsを勉強中)既視感を感じました。
もしかしてVue.jsは連想配列なのでは？
早速試してみる。

### 連想配列の中にメソッドをぶちこむ。

```javascript:javascript
let vhash = {
  data(){
    return{
      message: 'good morning',
      message2: 'hello js'
    }
  }
}
```

もう既に意味分からない事をしていますね。
Vue.jsでは良く見る光景なので試してみる。
dataメソッドのreturnに連想配列を更に渡してるって感じになります。

```javascript:結果の出力
console.log(console.log(vhash.data().message)) //good morning
console.log(console.log(vhash.data().message2)) //hello js
```

はい…表示されました。
本当に何者なんだ連想配列

#### 連想配列の中に連想配列を入れそのなかにメソッドを入れる

```javascript:javascript
let vhash = {
  methods: {
    getMassage(){
      return 'おはようございます'
    },
    getMassage2(){
      return 'こんにちわ'
    },
    getMassage3(){
      return 'こんばんわ'
    },
  }
}
```

これもVue.jsでよくみる光景ですね。
key名がmethodsのなかに複数のメソッドを連想配列として格納してます。

```javascript:結果出力
console.log(vhash.methods.getMassage()) //おはようございます
console.log(vhash.methods.getMassage2()) //こんにちわ
console.log(vhash.methods.getMassage3()) //こんばんわ
```

これもちゃんと表示されますね。
連想配列の中にメソッドが書ける事を知っていれば後は普通の配列のように配列の中に配列が書けるとのと同じだと考えれば大丈夫だと思います。

## 余談
ここまでVue.jsを臭わせる事を書いてきたので最後にVue.jsを軽く見ていきたいと思います。

```javascript:Vue.jsをインスタンス化
let vm = new Vue()
```

まず第一段階としてVue.jsをインスタンス化
ここから第一引数に直接連想配列をいれればよく見た形になりますが、今回は分けて書きましょう。

```javascript:javascript
let vueValue = {
  el: '#app',
  data: {
    message: 'Hello Vue'
  }
}
```

この連想配列をVue.jsの第一引数に渡します。

```javascript:javascript部分
let vueValue = {
  el: '#app',
  data: {
    message: 'Hello Vue'
  }
}

let vm = new Vue(vueValue)
```

```html:html部分
<div>
  <p>{{ message }}</p>
</div>
```

```:ブラウザの表示
Hello Vue
```

分解して考えて見るとVue.jsが特殊な記述を行ってない事がわかります。
当然な事かもしれませんが、連想配列の仕組みを理解していないとVue.jsのコードが難解なコードに見えてくると思います。
最後に上記で書いたコードを良く見る形にしておきます。

```javascript:javascript部分
let vm = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue'
  }
})
```
UbuntuのトップバーでSlackの未読表示をオフにする

目について邪魔なのでオフにする
公式に機能は提供されていないが、以下の記事のようにアセットを無理やり上書きする。

>Hide Slack unread and highlight Tray Icon on Ubuntu/Linux — beberlei.de
>https://beberlei.de/2017/07/29/hide_slack_unread_and_highlight_tray_icon_on_ubuntu_linux.html

現在の自分の環境だと上記で足りないファイル(*-linux.png)があったので追加して以下コピペ用
highlightの方はメンションの表示（赤丸のやつ）なのでそっちは表示したい場合はunreadだけ上書きする。

```bash
sudo -i
cd /usr/lib/slack/resources/app.asar.unpacked/src/static
mv slack-taskbar-highlight.png slack-taskbar-highlight-backup.png
mv slack-taskbar-highlight-linux.png slack-taskbar-highlight-linux-backup.png
mv slack-taskbar-unread.png slack-taskbar-unread-backup.png
mv slack-taskbar-unread-linux.png slack-taskbar-unread-linux-backup.png

cp slack-taskbar-rest.png slack-taskbar-highlight.png
cp slack-taskbar-rest-linux.png slack-taskbar-highlight-linux.png
cp slack-taskbar-rest.png slack-taskbar-unread.png
cp slack-taskbar-rest-linux.png slack-taskbar-highlight-linux.png
```
Ruby chomp

<img width="581" alt="デスクトップ_—_-bash_—_80×24_と_sample_rb_と_https___master_tech-camp_in_curriculums_34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378273/daf7415b-5558-ac18-316f-b62f3c8f6a9c.png">

chompをgets.の前に置けば、文末が改行されないようになる。
Ruby gets 

<img width="580" alt="sample_rb.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378273/d7c2bb4b-a06b-6a9b-f9ca-a31552893f52.png">

getsの上にputsを置くだけで
どのように入力すればいいのか分かりやすくなる。
スプレッドシートに書かれた日付が「表示形式」によってGASの中で型が変わる調査

(2020/03/21 追記)
2020年2月に GASで **V8ランタイム** が使えるようになりました。これによりECMAScriptに対応をしたようです。それまでは **Rhinoランタイム** だったそうです。この記事を投稿したときは **Rhinoランタイム** でしたが、下記の記事は **V8ランタイム** でも同じ結果になりました。

----

下記のようなスプレッドシートがあって、列によって「表示形式」が異なります。

![ss.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/ebf04674-d83f-0c67-190b-0805b9c83c24.png)



```js
function main(){
  const sheet   = SpreadsheetApp.getActiveSheet();
  
  const jidou   = sheet.getRange('A2').getValue();
  const hiduke  = sheet.getRange('B2').getValue();
  const nichiji = sheet.getRange('C2').getValue();
  const nashi   = sheet.getRange('D2').getValue();
  
  // typeofで判定
  Logger.log(typeof jidou); // -> object
  Logger.log(typeof hiduke); // -> object
  Logger.log(typeof nichiji); // -> object
  Logger.log(typeof nashi); // -> string
  
  // Object.prototype.toString.call()で判定
  Logger.log(Object.prototype.toString.call(jidou)); // -> [object Date]
  Logger.log(Object.prototype.toString.call(hiduke)); // -> [object Date]
  Logger.log(Object.prototype.toString.call(nichiji)); // -> [object Date]
  Logger.log(Object.prototype.toString.call(nashi)); // -> [object String]
}
```

表示形式が「書式なしテキスト」だと、GASの中ではStringになりました。
GAS側でDateオブジェクトとして扱ってる場合、スプレッドシート側の表示形式をいじられると困ることになるかも？

**2023/10/30追記**
コメントにて getDisplayValue(s)を使う技を教えていただきましたのでそちらも参照してください！