OmniAICreator/Qiita-1.07M huggingface dataset:
チャットワーク JavaScript を利用して一括削除方法

#事前説明
派遣社員です。今回新型コロナウイルスの影響で、1年3月続いている現場は今月解約予定です。
  ※ 該当一括削除方法はチャットワークから共有ではなく、自作削除方法です。
 作成原因：マイチャットのメッセージがたくさんあるから、一つ一つ削除はしんどいです。チャットワーク自体も(一括削除)実装されていないですが。
  ※チャットワーク営業さんに迷惑をかけないように、マイチャットのみ使ってください。（通信多い場合、サーバの負担が高くなる）
  ※使用不安、コードが理解できない、個人情報紛失心配人は、ご利用しないでください。

#手順説明
 ①.チャットワークを開いて
 ②.F12キーを押下する
 ③.console(コンソール)シート開く
 ④.下記のソースコードを貼り付け、ENTERキーを押下する(※の部分必ず記入してください)

```js

var parameter = Object();
parameter.pdata = '{"_t":"'+ ACCESS_TOKEN +'"}';
var self = this;
var st;
var door = true;

var chatId = "";                        // 記入しない場合、対象は最後のメッセージから検索する
var rid = "";                           // ※アドレスバーURLのrid後のIDを記入してください。
var strta = "1585887072";               // ※削除開始時間(日付⇒UNIX時間変換)該当値は例です。
var end = "1585887220";                 // ※削除終了時間(日付⇒UNIX時間変換)該当値は例です。

if (chatId) {
    st = true;
} else {
    st = false;
}
do {
    $.ajax({
        type : 'POST',
        data : parameter,
        async : false,
        url : 'https://www.chatwork.com/gateway/load_old_chat.php?myid='+MYID+'&_v=1.80a&_av=5&ln=zh-cn&room_id='+rid+'&first_chat_id='+chatId,
        dataType : 'JSON',
        scriptCharset: 'utf-8',
        success : function(res) {
            self.qlist = res;
            $.each(res.result.chat_list, function(index, value) {
                if (index == 0 && chatId == "" && st) {
                    chatId = value.id;
                    st = false;
                } else {
                    chatId = value.id;
                }
                if (value.aid == MYID && value.msg != "[deleted]" && strta <= value.tm && value.tm <= end) {
                    $.ajax({
                        type : 'POST',
                        data : parameter,
                        async : false,
                        url : 'https://www.chatwork.com/gateway/delete_chat.php?myid='+MYID+'&_v=1.80a&_av=5&ln=zh-cn&chat_id='+chatId+'&room_id='+rid,
                        dataType : 'JSON',
                        scriptCharset: 'utf-8',
                        success : function(res) {
                            if (res.status.success) {
                                console.log('メッセージID:'+ value.id + 'を削除しました。');
                            }
                        },
                    });
                }
                // 範囲以外時間になったら、処理を中止する
                if (value.tm < strta) {
                    door = false;
                }
            });
        },
    });
} while (self.qlist.result.chat_list.length > 0 && door);
```
累積した数値の集計と可視化

以下のデータを使うことにする。

```python
x = [i for i in range(1,11)]
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
```

この変数xに入った値の累積分布関数を作成したい。

# pandasの`cumsum`関数を使う場合

```python
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt


x = [i for i in range(1,11)]

df = pd.DataFrame(x, columns=['x'])
df["cumsum"] = df.x.cumsum() # 累積和を追加
df["cumsum_ratio"] = df.x.cumsum()/sum(df.x) # cumsumの値になるまでの確率
```

これにより、dfは以下のような構造になる。（indexは表示してない）

| x | cumsum | cumsum_ratio |
|--:|--:|--:|
|  1 | 1 | 0.018182 |
|  2 | 3 | 0.054545 |
|  3 | 6 | 0.109091 |
|  4 | 10 | 0.181818 |
|  5 | 15 | 0.272727 |
|  ... |... | ...|

これを描画すれば良い。

```python
fig, ax = plt.subplots(figsize=(4, 4))
ax.set_xlabel('Value')
ax.set_ylabel('Cumulative Frequency') 
ax.set_xlim(0,10)
ax.scatter(df.x, df.cumsum_ratio, color="blue",s=10) 
ax.plot(df.x, df.cumsum_ratio, color="blue", marker='o',markersize=1) 
```

![aaa](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88357/4c308483-b719-7af8-9edf-5349573b620e.png)


# scipyの`stats.cumfreq`関数を使う場合

https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.cumfreq.html

こちらは、累積分布関数ではないが、以下のように使える。


```python
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt

x = [i for i in range(1,11)]

res = stats.cumfreq(x, numbins=10)
x_ = res.lowerlimit + np.linspace(0, res.binsize*res.cumcount.size, res.cumcount.size)


x_1 = np.arange(counts.size) * binsize + start 

fig, ax = plt.subplots(figsize=(4, 4))
ax.plot(x_, res.cumcount, 'ro')
ax.set_title('Cumulative histogram')
ax.set_xlim([x_.min(), x_.max()])
```

![hogehoge](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88357/dc88fcf2-0dd1-4187-960e-3881f6c0e13d.png)
悲観的バージョン演算子（~>）とは何か？

# 悲観的バージョン演算子（~>）
Rubyでの開発を行っていると一度は出会う **悲観的バージョン演算子（~>）（Pessimistic Operator）**。Gemfileで例えば**~>0.7.7**などと記述されているのを見て、初めての方だと混乱される方も多いだろうし、少し慣れている方でもついググってしまう方もおられるかもしれない。そこでここでは初めての方には一先ず理解してもらうべく、初見ではない方にはもうググらなくて済むことを願って解説していければと思います。

## x.x.xの例
x.x.xの形式でバージョン指定が行われている場合、例えば下記の様にGemfileが記述されている場合を考えてみる。
```gem 'rails', '~>4.2.6'```
これは結論から言うと```4.2.6 <= 'rails' < 4.3```となる。

ではどの様に考えれば、この結論に至るのかを順を追って説明したい。

### まずは最小値である下限から考えてみる
上記の例を使用するとこの場合の下限は**4.2.6**となることが分かる。これでまずは下限が決まった。簡単。

### 次にどこまでが上限であるかを考えていく
同じく上記の例を使用すると、まずは**4.2.6**の１番右端にある**6**を削ってみる。そうすると**4.2**になる。
それから**4.2**に**0.1**を加算してあげる。つまり**4.3**。（深く考えずに機械的に１番小さい桁に**1**を足せば良い。）
この**4.3**より小さい値つまりは**4.3未満**であればOK。

### 結果
**4.2.6以上4.3未満**

## x.xの例
次にx.x.xの例だけではイマイチ理解出来なかった。若しくは別のパターンも見てみたい方々の為にもう一例。
Gemfileに下記の通り記述されていた場合を考えてみる。
```gem 'rails', '~>4.2'```
これも結論から言うと```4.2 <= 'rails' < '5'```となる。
では同じ要領で見ていこう。

### まずは下限を決める
これは~>で指定されている**4.2**で決まり。後は上限だけ。

### どこまでが上限になるか考える
**4.2**の１番右端の数字を削る。ここでは**2**。結果**4**となる。
次に１番小さい桁に**1**を足してあげると**5**が導かれる。つまり**5**未満であればOK。

### 結果
**4.2以上5未満**

## まとめ
悲観的バージョン演算子が登場したら下記の手順を思い出して頂ければ、今後慌てずググらず対応出来る。
1. 下限を決める
2. 上限を決める（**１番右端の数字**を削って**1**を加算した数値未満）
Python #JSON

学習メモ・備忘録

## JSON
様々なプログラミング言語間でのデータ交換フォーマットになる言語。PythonでもJSONは標準でサポートされている`json`パッケージを用いて扱うことができる。

## Pythonデータにエンコード
~~~python
import json

with open('test.json', 'r') as j:
    data = json.loads(j.read())
~~~

## JSONファイルに書き込む
~~~python
import json

data = ['I love', 
        {'language':  {'target': ['Python', 'Java', 'JavaScript']}},
        {'alcohol': {'target': ['Beer', 'Wine', 'Whisky']}}
       ]

with open('test.json', 'w') as j:
    j.write(json.dumps(data)) 
~~~
odoo で longpolling リクエストが失敗する件

docker で odoo + nginx な環境を立ち上げてみたら下記のエラーが出てきた。

```
nginx    | 2020/04/27 09:37:32 [error] 7#7: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.128.1, server: , request: "POST /longpolling/poll HTTP/1.1", upstream: "http://192.168.128.3:8072/longpolling/poll", host: "localhost", referrer: "http://localhost/web"
```

どうやら odoo.conf で workers を設定していないことが原因っぽい。
とりあえず `woerkers = 5` に設定してみたらこのエラーは消えてくれた。

デフォルトだと worker = cpu core x 2 + 1 みたいな設定になってくれないのね…
Basic 1. Spring Tools Suite インストール

# 1. こちらからEclipseをinstall

https://spring.io/tools

# 2. 動作確認
## 2.1. プロジェクトを作成する
New -> Projectの「Spring Boot」を開き、「Spring Starter Project」を選択する

<img width="932" alt="スクリーンショット 2020-04-27 18.41.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496885/47c0aa37-1f3d-ad46-fc57-fcd4e87466e0.png">

<img width="599" alt="スクリーンショット 2020-04-27 18.42.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496885/38006b89-9498-d4ad-4411-5c884134a842.png">


NameはHello
Gradle 3.X
Java 11

<img width="591" alt="スクリーンショット 2020-04-27 18.47.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496885/c6272f6b-25b1-63b9-e696-1f1655d37450.png">


Spring Webを検索
Spring Webを選択

<img width="591" alt="スクリーンショット 2020-04-27 18.49.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496885/3bf79b9b-3a87-45c3-f4d7-22b96dac6ce4.png">

Finish

## 2.2. hello worldのファイルに追記
src/main/java/com/example/hello/HelloApplication.java

```java:src/main/java/com/example/hello/HelloApplication.java
@SpringBootApplication
```

の下に

```java:src/main/java/com/example/hello/HelloApplication.java
@RestController
```

と

```java:src/main/java/com/example/hello/HelloApplication.java
public static void main(String[] args) {
	SpringApplication.run(Hello2Application.class, args);	
}
```

の下に

```java:src/main/java/com/example/hello/HelloApplication.java
@GetMapping("/hello")
public String hello(@RequestParam(value = "name", defaultValue = "World") String name) {
return String.format("Hello %s!", name);
}
```

を追加する。

- Command + Shift + O  import文の補完
- Command + Shift + F  コードの整形


## 2.3. ブラウザで表示

`src/main/java/com/example/hello/HelloApplication.java`を右クリックして
`Run As` -> `Spring Boot App`として起動する。

<img width="687" alt="スクリーンショット 2020-04-28 10.53.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496885/716d71f6-6a32-f8bf-1d96-8223d1196e68.png">


URLにブラウザでアクセス
http://localhost:8080/hello

<img width="832" alt="スクリーンショット 2020-04-27 18.52.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496885/c4cdb8a4-aa11-2fb1-25e4-0080aa5051ab.png">


`hello world!`と表示されればインストールは終了。
if railsリファクター

# ifにまつわるリファクター
もうちょっといい感じになるでしょ・・・！でも書き方がわからないなんてときのTips

### 条件と代入したいものが同じ！

```
rate = if point
  point
else
  20
end
```
↓

```
rate = point_usable_limit_rate || 20
```

### ifが二重ネストしているが、最初のifの結果と中のifが同じ場合

```
if CCCC
  if DDDD
    AAAA
  else
    BBBB
  end
    BBBB
end
```

↓

```
unless CCCC? # 最初にCCCC以外を弾く
    if DDDD
       AAAAA
    end
    BBBB
end
```

### 同じカラムを見に行くが値が違う時

```
if AAA.type == "MAYO" || AAA.type == "BUTTER"
  "MAYOBUTTER"
end
```

↓

```
if AAA.type.in?(["MAYO", "BUTTER"])
  "MAYOBUTTER"
end
```
[Rails6]サブドメインでルーティングしたいという話

https://hogehoge.com/:role/:controller/:action
みたいなURLが嫌になったので
https://role.hogehoge.com/:controller/:action
を目指す。

基本的な参考記事: [Railsでサブドメインに対応させる方法](https://qiita.com/TAKESHI_ONAGA/items/c5fbba776982835f5216)
でもこのルーティングはまだちょっと不満だったので（コントローラの階層化もしたいしそれぞれのindexも作りたい）以下ちょっとそのあたりを拡充した話になります。

```config/environments/development.rb
# ※めんどくさかったのでやっていませんが環境変数使うなりなんなりもうちょっといいやり方があると思います
# (略)
  config.hosts << "example.com"
  config.hosts << "worker.example.com"
  config.hosts << "admin.example.com"
# (略)
```

```routes.rb
  constraints subdomain: '' do
    get '/', to: "pages#index"
  end
  constraints subdomain: 'worker' do
    scope module: :worker do # moduleにすることでドメイン後にworkerとか入らずに済む
      get '/', to: "pages#index"
    end
  end
  constraints subdomain: 'admin' do
    scope module: :admin do
      get '/', to: "pages#index"
    end
  end
```


```app/controllers/admin/pages_controller.rb
class Admin::PagesController < ApplicationController
  layout 'admin' # おまけでレイアウトファイル振り分け
  def index
  end
end 
```

これで http://admin.example.com/:controller/:action ができました！やったね！
【python】 python2でbasicConfigにTimedRotatingFileHandlerを設定しても動かなかったときの注意メモ

# はじめに

pythonでloggingを使ってログローテートを使用としたときの話です。

python2で（仕方がなくです）、logging.basicConfigでhandersを指定して、TimedRotatingFileHandlerを使っていたのですが、なぜか指定ログファイルに書き込みすらも行われず、もちろんログローテートも行われなかった。
しかし、python3で実行するとうまくいく。

よくわからないと思って、違う方法で解決したのでメモします。

どなたか、python2の一部のバージョンでそれ動かないよとか、
そもそもこれ指定してる？とかの情報をいただければ幸いです。

**追記で記述したのですが、社内の方に情報をいただき、動かない理由が明らかになりました！ありがたい。。**

# 内容

## 結論

結論から言うと、TimedRotatingFileHandlerをaddHandler()にかませることでうまくいきました。

```python
import logging
from logging.handlers import TimedRotatingFileHandler 


logger = logging.getLogger(__name__)
formatter = "%(asctime)s:%(name)s:%(levelname)s:%(message)s"
handler = TimedRotatingFileHandler(
	"/hogehoge/logger.log",
	when="M",
	backupCount=1
)

logger.setLevel(logging.INFO)
handler.setFormatter(logging.Formatter(formatter))
logger.addHandler(handler)

logger.info("===== START HOGEHOGE =====")
```

## 詳細

うまくいかなかったソースは以下になります。

```python
import logging
import logging.handlers

logger = logging.getLogger(__name__)
formatter = '%(asctime)s:%(name)s:%(levelname)s:%(message)s'
logging.basicConfig(
    level=logging.DEBUG,
    format=formatter,
    handlers=[logging.handlers.TimedRotatingFileHandler(
        filename ='/hogehoge/logger.log',
        when="M",
        backupCount=1
    )]
)

logger.setLevel(logging.INFO)
logger.info("=== START HOGEHOGE ===")

```

原因は不明でしたが、ひとまず上記の方法でうまくいかなかったら、
addHandlerに食わせることを考えようと思います。

## 追記
環境により仕方なく、python2でTimedRotatingFileHandlerをしようと考えて、
basicConfigにhandlersを設定していて、動かなかったのですが、
その理由がどうやらシンプルにサポートされていないからでした。。。

確かに以下の内容に、handlersがなく、basicConfigで使用できないことがわかりますね。
こんなことで時間取られた、、もっとドキュメントを読めよということですね。
勉強になりました。

```
## 内容
以下のキーワード引数がサポートされます。

・filename
StreamHandler ではなく指定された名前で FileHandler が作られます。

・filemode
If filename is specified, open the file in this mode. Defaults to 'a'.

・format
指定された書式化文字列をハンドラで使います。

・datefmt
指定された日時の書式で time.strftime() が受け付けるものを使います。

・level
ルートロガーのレベルを指定された レベル に設定します。

・stream
Use the specified stream to initialize the StreamHandler. Note that this argument is incompatible with filename - if both are present, stream is ignored.

## 参照
https://docs.python.org/ja/2.7/library/logging.html
```
AsciiDocの良いところ

## はじめに

軽量マークアップ言語で最もメジャーなMarkdownと比較しつつ、AsciiDocの良いところをここでは書いています。

既にAsciiDocに関する良記事は以前からありますので、こちらを参照することをお勧めします。

- [AsciiDoc入門](https://qiita.com/xmeta/items/de667a8b8a0f982e123a)

※余談ですが、4年前くらいにこちらの記事で基本的なことを知ることが出来ました。
私は当時Markdownを知らなくて、AsciiDocを先に覚えました。

## AsciiDocは軽量マークアップ言語の１つ

AsciiDocとは、軽量マークアップ言語のひとつです。
簡単な文法を覚えるだけで書くことが出来、そのままでも単なるテキストとしても読めます（可読性が高い）が、HTMLやPDFに変換することで表現力豊かな文章を作成することが出来ます。
※変換には、`Asciidoctor`や`pandoc`などを使用します。

- 記述／出力イメージ（Wikipediaより）

![](https://i.imgur.com/vBze2WO.png)

## テーブル（表）を書くのが簡単

まず、Markdownで表を書くのはすこし難しいです。
列を追加するときなど、繊細な作業になりメンテがしづらいです。

- Markdownの表の書き方

```markdown
| Column 1 | Column 2 | Column 3 |
| -------- | -------- | -------- |
| Text     | Text     | Text     |
```

- 出力

| Column 1 | Column 2 | Column 3 |
| -------- | -------- | -------- |
| Text     | Text     | Text     |

一方でAsciiDocも似たような書き方が出来るのですが、さらにcsv形式で書くということが出来ます。

- AsciiDoc、csv形式での表の書き方

```AsciiDoc
[options="header"]
,=====
Column 1,Column 2, Column 3
Text,Text,Text
,=====
```

先頭末尾の`|`が無いだけでもすっきりしていて書きやすいです。
それに、この表部分だけを抜き出して他所に提出するシーンがあったとしてもcsv形式なので恥ずかしくありません。

また、外部のcsvファイルをそのまま取り込んで出力することもできます（後述）

## 定数を使うことが出来る(attribute)

Markdownではできない（と思いますが）定数定義ができます。
これをattribute(属性)というようですが、以下のように書きます。

- 記述例

```AsciiDoc
// attributeを定義
:burebureName: ブレブレサービス

// attributeを使うとき
{burebureName}は、こんなサービスです。
```

- 出力結果

![](https://i.imgur.com/5prIE9D.png)

これは、ドキュメント量が増えてくると効いてきます。
上記のように、言葉がブレやすかったり今後変わる可能性のあるような文言に使えます。

## 外部ファイルの取り込みが出来る

これもMarkdownではできない（と思いますが）外部ファイルの取り込みができます。

例えば、APIリファレンスによくあるレスポンス出力例を別ファイルにするというような使い方が出来ます。
レスポンスの出力内容を変えたときに、テストで出力したjsonファイルをそのまま使おうと思えば使えます。

- 記述例

```AsciiDoc
* レスポンス

[source,json]
----
include::./sample.json.[]
----
```
- sample.json

```json
[
    {
      "created_at": "2000-01-01T00:00:00+00:00",
      "id": "c686397e4a0f4f11683d",
      "updated_at": "2000-01-01T00:00:00+00:00",
      "page_views_count": 100
    }
]
```

- 出力結果  
![](https://i.imgur.com/NxI2Qm4.png)

ちなみに末尾の`.[]`は、`.[lines=1..3]`とすると1~3行だけ出力します。

前述のcsvテーブルもこんな感じに外部ファイル化できます。

```AsciiDoc
[options="header"]
,=====
include::./sample.csv.[]
,=====
```

## おわりに

Markdownに比べると覚えることは若干多いと経験上感じていますので、

- 軽いメモを取る場合には、Markdown
- ドキュメント総量が多い、メンテナンスの頻度が高い場合には、AsciiDoc

と使い分けをすることを個人的にはお勧めします。

## 参考

- [AsciiDoc-homepage](http://asciidoc.org/)
- [AsciiDoc cheatsheet](https://powerman.name/doc/asciidoc)
- [AsciiDoc-Wikipedia](https://ja.wikipedia.org/wiki/AsciiDoc)
kerasで画像認識

[前回](https://qiita.com/yohiro/items/404fa6c0925077958989)作成した訓練用データを使ってサル・イノシシ・カラスを見分ける画像認識プログラムを作成する

#kerasとは

https://keras.io/ja/

>Kerasは，Pythonで書かれた，TensorFlowまたはCNTK，Theano上で実行可能な高水準のニューラルネットワークライブラリです．

#ソースコード

##インポート

```python
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras.utils import np_utils
import keras
import numpy as np
```

##メイン関数
おおまかな流れは以下の通り：
1. 前回保存した`animal.npy`を読み込む
2. 訓練用データを訓練関数に渡してモデルを作成
3. 作成したモデルを評価関数に渡して分類精度を検証

```python
classes = ["monkey", "boar", "crow"]
num_classes = len(classes)
image_size = 50

def main():
    X_train, X_test, y_train, y_test = np.load("./animal.npy", allow_pickle=True)
    X_train = X_train.astype("float") / 256
    X_test = X_test.astype("float") / 256
    y_train = np_utils.to_categorical(y_train, num_classes)
    y_test = np_utils.to_categorical(y_test, num_classes)

    model = model_train(X_train, y_train)
    model_eval(model, X_test, y_test)
```

・`X_train`, `X_test`を256で割っているのは、正規化(データを0～1の範囲にしている)。

・`to_categorical`は、`[0, 1, 2]`という配列を

```
[[1, 0, 0]
 [0, 1, 0]
 [0, 0, 1]]
```

というように、正解のindexにのみ1が入っており、その他の場所には0が入っている配列に変換する。

##訓練

以下のコードの34行目以降を参考にする
参考：https://github.com/keras-team/keras/blob/master/examples/cifar10_cnn.py

```python
def model_train(X, y):
    model = Sequential()
    model.add(Conv2D(32, (3,3), padding='same', input_shape=X.shape[1:]))
    model.add(Activation('relu'))
    model.add(Conv2D(32, (3,3)))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(Dropout(0.25))

    model.add(Conv2D(64, (3,3), padding='same'))
    model.add(Activation('relu'))
    model.add(Conv2D(64, (3,3)))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(Dropout(0.25))

    model.add(Flatten())
    model.add(Dense(512))
    model.add(Activation('relu'))
    model.add(Dropout(0.5))
    model.add(Dense(3))
    model.add(Activation('softmax'))

    opt = keras.optimizers.rmsprop(lr=0.0001, decay=1e-6)

    model.compile(loss='categorical_crossentropy',
                    optimizer=opt, metrics=['accuracy'])

    model.fit(X, y, batch_size=32, epochs=100)

    # モデルの保存
    model.save("./animal_cnn.h5")

    return model
```

###`model = Sequential()`
モデルオブジェクトを作成する

###`model.add(Conv2D(...))`
層を追加する

###`model.add(Activation('relu'))`
活性化関数として「ReLU（Rectified Linear Unit）」を用いる層を追加する

###`model.add(MaxPooling2D(pool_size=(2,2)))`
マックスプーリング（インプットを所定の領域で区切って、各領域の最大値を出力する）する層を追加する

###`model.add(Dropout(0.25))`
25%（何の？）を捨ててデータの偏りを無くす

###`opt = keras.optimizers.rmsprop(lr=0.0001, decay=1e-6)`
最適化の宣言。`optimizers.rmsprop`という手法で、ラーニングレートは0.0001、学習率を下げていくレートは1回あたり0.000001。

###`model.compile()`
モデルのコンパイル。

###`model.fit(X, y, batch_size=32, epochs=100)`
`X`と`y`でトレーニングを行う。
`batch_size`は1回のトレーニングで用いるデータの数。
`epochsは`トレーニングを何セットやるか。

##訓練結果の評価
`evaluate`メソッドで作成したモデルの検証を行う。

```python
def model_eval(model, X, y):
    scores = model.evaluate(X, y, verbose=1)
    print('test Loss: ', scores[0])
    print('test Accuracy: ', scores[1])
```
ハッシュの便利メソッド

# ハッシュとは
キーと値の組み合わせでデータを管理するオブジェクト

# よく使用されるハッシュのメソッド
* keys
* value
* has_key?
* dig
* values_at


## keys
ハッシュのキーを配列として返す

```ruby
currencies = { japan: 'yen', us: 'dollar', india: 'rupee' }
currencies.keys
=> [:japan, :us, :india]
```

## values
ハッシュの値を配列として返す　

```ruby
currencies = { japan: 'yen', us: 'dollar', india: 'rupee' }
currencies.values
=> ["yen", "dollar", "rupee"]
```

## has_key?
ハッシュの中に指定されたキーが存在するか確認できる

```ruby
currencies = { japan: 'yen', us: 'dollar', india: 'rupee' }
currencies.has_key?(:us)
=> true
currencies.has_key?(:germany)
=> false
```

## values_at
ハッシュのキーに対応する値を配列として返す
対応するキーが無かったら、nilを返す

```ruby
currencies = { japan: 'yen', us: 'dollar', india: 'rupee' }
currencies.values_at(:japan, :india, :canada)
=> ["yen", "rupee", nil]
```

## dig
ネストしたハッシュから安全に値を取り出すことが出来る

```ruby
order = {
  payments: {
    payment_method: {
      name: 'credit card'
    }
  }
}
```

nameの値を取り出した場合は、以下のように取り出せる

```ruby
order[:payments][:payment_method][:name]
=> "credit card"
```

何らかの理由でpayment_methodの情報が入ってなかったとして、先程と同じようにnameの値を取得しようとするとエラーが発生する

```ruby
other_order = {
  payments: {
    #payment_methodが存在しない
  }
}

other_order[:payments][:payment_method][:name]
NoMethodError (undefined method `[]' for nil:NilClass)
```

このような場合にdigメソッドを使用すると、キーが見つからなくても```nil```が返るようになる


```ruby
order.dig(:payments, :payment_method, :name)
=> "credit card"
other_order.dig(:payments, :payment_method, :name)
=> nil
```

digメソッドは配列やハッシュが混在していても使用できる

```ruby
all_order = [
  {
    payments: {
        payment_method: {
            name: 'credit card'
        }
    }
  },
  {
    payments: {
        payment_method: {
          # payment_method情報が存在しない
        }
    }
  },
  {
    payments: {
        payment_method: {
            name: 'cash'
        }
    }
  }
]

all_order.dig(0, :payments, :payment_method, :name)
=> "credit card"
all_order.dig(1, :payments, :payment_method, :name)
=> nil
all_order.dig(2, :payments, :payment_method, :name)
=> "cash"
```

# 参考
[プログラミング言語 Ruby リファレンスマニュアル](https://docs.ruby-lang.org/ja/)
[プロを目指す人のためのRuby入門](https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%92%E7%9B%AE%E6%8C%87%E3%81%99%E4%BA%BA%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AERuby%E5%85%A5%E9%96%80-%E8%A8%80%E8%AA%9E%E4%BB%95%E6%A7%98%E3%81%8B%E3%82%89%E3%83%86%E3%82%B9%E3%83%88%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA%E3%83%BB%E3%83%87%E3%83%90%E3%83%83%E3%82%B0%E6%8A%80%E6%B3%95%E3%81%BE%E3%81%A7-Software-Design-plus%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA/dp/4774193976)
AWS/EC2にてMySQLを設定してみます

AWS EC2 のMySQLにてユーザの許可を設定していきます。

1 . EC2/Linuxでmariabdbがあるかどうか

```
yum list installed | grep mariadb
```

2 . MySQLが存在するか

```
yum list installed | grep mysql
```

3 . yumにRepository mysql8.0(version 5.7含む)

```
yum localinstall https://dev.mysql.com/get/mysql80-com... -y
```

4 . mysql 5.7インストールするので、 mysql 5.8を無効にする

```
yum-config-manager --disable mysql80-community
```

5 . mysql 5.7有効

```
yum-config-manager --enable mysql57-community
```

6 . 情報確認

```
yum info mysql-community-server
```

7 . 設定

```
yum install mysql-community-server -y
```

8 . version確認

```
mysqld --version 
```

9 . 起動

```
systemctl start mysqld.service
```

10 . 自動起動

```
systemctl enable mysqld.service
```

11 . 状態確認

```
systemctl status mysqld.service
```

12 . rootのパスワード確認

```
cat /var/log/mysqld.log | grep password
```

13 . 初期設定

```
mysql_secure_installation
```

14 . charset確認

```
mysql -uroot -p
show global variables like 'character%';
```

15 . default charset設定

```
vi /etc/my.cnf
[mysqld]
character_set_server=utf8

[client]
default-character-set=utf8

```

16 . database作成

```
create database db_test character set UTF8 collate utf8_bin;
```

17 . local user作成

```
CREATE USER 'test'@'localhost' IDENTIFIED BY 'Adsasdf123@!';
```

許可設定

```
mysql> GRANT ALL PRIVILEGES ON db_test.* TO 'test'@'localhost';
```

18 . remote user作成

```
CREATE USER 'remote_user'@'%' IDENTIFIED BY 'Adsasdf123@!';
mysql> GRANT ALL PRIVILEGES ON db_test.* TO 'remote_user'@'%';

```

19 . firewall port 3306　開き

接続確認します。

以上！
COVID-19に対するエレメントAIの対応 - 危機の克服のための社会構成員としての役割

![heart.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566223/95bdd814-9544-52e0-489c-08196d4e655a.jpeg)

> 注）この記事はエレメントAIのCEOであるJean-Francois Gagneが2020年3月27日に投稿した’COVID-19：what we’re doing’ を翻訳したものです。[原文](https://www.elementai.com/news/2020/covid-19-what-were-doing)はこちらでご確認いただけます。
 
全世界のコミュニティの皆さん、私たちはCOVID-19によって先行きの見えない時期を過ごしています。これは前例のないことです。毎日全世界の一人一人、そして各自が属する社会や組織が速いスピードで変化しています。状況がだんだんと深刻になる中で、Element AIは私たちのできる限りを尽くしグローバルコミュニティに責任感を持って対応することで、私たちの役割を果たそうと努めています。

過去数週間にわたって、Element AIは危機に対処するために最前線にいる人々たちを支援するための取り組みを始めています。
 
#### 学界のための開放型研究プラットフォーム

COVID-19に関連する新しい情報が次々と明らかになる中で、最新の情報を常に把握していることがCOVID-19を解決するための大きな進歩につながります。重要な発展のためには学界の研究が必須であるため、学界が最新の科学的な発見を熟知することができるようにすることを私たちは最も重要視しています。
私たちは、学界が最新の情報をより速く入手し、伝染病を緩和するのに必要な研究に邁進することができるよう、無料のプラットフォームを開発しました。現在の[COVID-19開放型研究データセット(COVID-19)](https://pages.semanticscholar.org/coronavirus-research)を基盤として構築されたプラットフォームは、他の開放型データセットが公開されるにあたって段々と定型、あるいは非定型の形式すべてが持続的に拡張していくでしょう。
 
#### マシーンラーニングの専門知識とリソースの共有

Element AIはMILA, InVivo AI, またMILAが主導的に構築したMILA AI Taskforceのチームの他のメンバーたちと協力し、COVID19の問題の解決策を模索している研究者たちへのマシーンラーニングの専門知識と資源の支援をしています。

先週、MILAのサイエンスディレクターであり、Element AIの共同創業者であるヨシュア・ベンジオ教授はこのように言いました。

“今のCOVID-19の事態は、できるだけ多くの命を救うというとても単純な目標をともに目指しながら、私たちが自ら自分自身を犠牲にして共同の利益のために共に行動することのできる機会と動機を与えてくれます。私たちが普段の生活に戻っても、私たちのこの精神を忘れないようにしましょう。この精神は問題をともに解決し、解決策を共有し、理解する過程で得る喜びを重視するという点で、科学の精神であるともいえます。”（出典）

Element AIはコンピューティングリソース（GPU, CPU, ストレージ）を共有することで、COVID19に関連する研究や調査がより速く進行することを願います。
 
#### 社会的距離（ソーシャル・ディスタンシング）の効果に対する認識の再考

Element AIの現在および過去の社員たちが主導的に週末ごとにハッカソンを開催し、COVID19の感染曲線をより平らにするために個人がどのような役割を担うのかを表すツールを開発しました。

コロナ計算機と呼ばれるこのツールは、感染者が接触した人の数によって感染病がどのように進行して行くのかを理解することを助けます。すなわち、このツールは少しの間だけでも私たちが互いの相互作用を制限することがコロナウイルスの拡散を阻止し、医療システムの崩壊を阻止するということを明らかにすることを目指しています。
 
#### 今後の展望

状況が急激に変化する中で、私たちは日々新しい質問に向き合います。私たちのオフィスが閉まっているとしても、私たちは可能な限り私たちの顧客社とコミュニティを助けるために最善の努力を尽くします。

状況が完全に終息したといえるまでの道のりはまだまだ長いものですが、Element AIは私たちにできることを探し続けていきます。

私たちがともに働き、互いの責任を果たすことで、誰も経験したことのないこの時期を克服することができると考えます。ともに乗り越えていきましょう。
Pythonで毎日AtCoder #49

### はじめに
[前回](https://qiita.com/taxfree_python/items/bffa918d31be47609915)
昨日のABCの結果
<img width="529" alt="スクリーンショット 2020-04-27 17.43.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273421/ac3d227c-72c5-47a2-6264-30d90e79e6c3.png">
今日は、Boot camp for Beginners Mediumを解きます。

### #49
[キーエンスコンテスト2020-C](https://atcoder.jp/contests/keyence2020/tasks/keyence2020_c)

**考えたこと**
**問題文はちゃんと読みましょう**。$A_i$の要素は$10^9$以下でないといけません。
サンプルのように複数個の要素の和を計算するのは面倒です。そこで、$K$個の$S$を用意すれば楽になります。もし、$S$が$10^9$でないなら他の要素は$S$以上であればACです。もし$S$が$10^9$なら問題文より、$10^9$以下の整数にしなければなりません。ここで1以外の整数だと和が$10^9$になる可能性があるので、他の要素は1になります

```python
n, k, s = map(int,input().split())

if s < 10**9:
    ans = [s] * k + [10**9] * (n-k)
    print(*ans)
else:
    ans = [s] * k + [1] * (n-k)
    print(*ans)
```
キーエンスコンテストだけページの色が違うのは仕様?

[ABC137-C](https://atcoder.jp/contests/abc137/tasks/abc137_c)

**考えたこと**
greenなのに茶diff。アナグラムである文字列は要素の数が同じであればいいので、文字列ごとにsortしてCounterに入れてます。←もっと簡単に書けると思います。
あとは、CounterのValueが2以上である要素に対してコンビネーションを計算します。math.factorialだとREになったので、scipyを使います。

```python
from collections import Counter
from scipy import misc #scipyのバージョンに注意
n = int(input())
s = [list(input()) for _ in range(n)]

ss = []
for i in range(n):
    a = sorted(s[i])
    a = ''.join(a)
    ss.append(a)

ss = Counter(ss)
ans = 0
n = len(ss)
k = ss.keys()
for i in k:
    if ss[i] == 1:
        continue
    if ss[i] >= 2:
        ans += round(float(misc.comb(ss[i],2)))
print(int(ans))
```

[ABC072-D](https://atcoder.jp/contests/abc072/tasks/arc082_b)

**考えたこと**
[False]*Nのlistをmとします。$P_i = i$のとき$m[i]$をTrueとし、これから$m[i]=True$をT、$m[i]=False$をFと書きます。mの要素の並びを分割すると(TT,TF)の二つになります。(TFT)も(TF),(FT)に分解できます。(TT,TF)のどちらも1回のswapで(FF)にできます。なぜなら、$P$に同じ要素はないので、(TF)をswapして(TT)となるようなことはありません。(TF)にも同じことがいえます。そして、swapは連続して行うことはありません。
以上のことから、$m[i]$がTならば必ず一回のswapでFにできます。

```python
n = int(input())
p = list(map(int,input().split()))

m = [False] * n
for i in range(n):
    if p[i] == i+1:
        m[i] = True

ans = 0
flag = False #一個前のswapの有無の確認
for i in range(n):
    if flag:
        flag = False
        continue
    if m[i]:
        flag = True
        ans += 1
print(ans)
```

### まとめ
日本語難しい。実装もきれいになりたい。ではまた。
公共の安全 と 個人情報の保護 の均衡 - 人工知能技術、データトラストなどを基盤とするソーシャル・ディスタンシング　2.0

![sd2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566223/128361f2-ea42-b60a-6251-28f6ff8165f9.jpeg)


> 注）この文章はエレメントAI(Element AI) の共同創業者でありAdvisorであるYoshua Bengio教授のブログに2020年3月23日に投稿された“Peer-to-peer AI-tracing of COVID-19”を翻訳したものです。[原文](https://yoshuabengio.org/2020/03/23/peer-to-peer-ai-tracing-of-covid-19/)はこちらでご確認いただけます。


“社会的距離“をとることにはもちろん効果があるが、当然ながら、とても残忍な方法であり経済的に大きな被害を与えるという限界を示していることがわかる。私たちは、感染している人々の動線を追跡し、該当する場所に訪れた人々に社会的距離をとらせることが、どんなに良い効果を生んでいるかを知っている。ここに技術を加えるのなら、それはより大きな助けとなるだろう。ワクチンの臨床実験期間や大規模の人々にワクチン接種をすることを考えると、経済が再開するのにはこれから18－24ヵ月かかると思われる。私たちの経済を復興させていくためにも、私たちは現在の方法とは違う、新しい自粛方式を考慮しなければならない。また同時に、私たちはこのような技術が、のちに政府機関などが自身を追跡することに悪用されないように監視することにも注意を払わなければならない。

想像してみよう。スマートフォンのアプリケーションが、あなたがどこを訪れたのか、また誰にあったのかをもとにあなたが感染している可能性を割り出し、その情報をあなたに会う人々と共有するということだ。これをもとにアプリケーションは各々の感染の危険度を自らアップデートすることができる。あなたが誰かと会う際に、その人々があなたを感染させる感染源となりうるのか判別することができるだろう。相手との距離を維持し、彼らがあなたの店、家、または車に入ってくることを阻止するだろう。同時に、常に自分の感染の危険水準を知ることができるため、自らが周りの人々に与えうる危険をより意識することができ、このような危険を避けるためにも外出の自粛や意識的な手洗いをすることを促すことができる。万が一、ウイルス検査をすることになれば、医療従事者は暗号化技術が適用されたアプリバージョンを使用し、検査結果に対する重要な情報をスマートフォンで回覧することができるようにし、匿名化した情報(GPS経路ではなく、だれに会ったのかなど、関連するリスク)のデータ管理をする非政府機構のデータトラスト（Data Trust）にアップロードする。データトラストにアップロードされた情報は感染症リスクの予測変数を学習するのに使用され、利用者はデータをアップロードする対価として、アップデートされたバージョンのリスク予測変数を使用し、より正確な感染予測が可能になる。すなわち、データトラストを使用しているため、P2P追跡は中央集権的データベースからすべての使用者の移動情報を保存しなければならないということではない。中央データベースには予測変数を学習するのに必要な地域的な情報が除外された情報、匿名化された情報のみを収集、また保存する。実際に、いつ、どこで会ったのかなど、重要な地理的情報はスマートフォンに保存され、相互間（P2P）でのみ伝達されるということだ。また、このアプリでは疾患に対する利用者の質問に答えることができ、検査が必要な場合、地域保健当局につなぐこともできる。それだけでなく、新しい症状が出ていないか確認する一日点検機能を提供し、リアルタイムで体内の危険度を評価、また追跡することができる。

あなたが出会う人々、店の店主はあなたがスマートフォンにアプリをインストールしているのかを確認することができる。（アプリは10m以内でBluetooth技術によって通信が可能である）つまり、あなたが自由に野外活動をし、人々に会うためにはアプリをダウンロードして、情報をアップロードしなければならないということである。（社会的圧力を感じることになるだろう。）または、政府が特定の人員、食料品店、学校、または大学などが位置する一部の地域に接近するためには、無条件にアプリをインストールするように義務化することもありうる。ある人々は、スマートフォンがないため（多くの高齢者など）、政府が安いスマートフォンを彼らに提供することを考慮しなければならないだろう。

地域別にアプリの収集情報や程度を運用することもできる。地域別にウイルスの増加率をコントロールするため（例えば、ウイルスの再生産数＝Reproduction numberを1以下に維持するため）収集される変数の量を調節することができる。これを通して、社会経済的な被害（所得が減ったり経済全般の生産が低下したりする場合）と保健に関連する被害との間の均衡を保つことができるはずである。最も良いのは再生産数が１またはそれよりも少し低い水準で形成されることであり、そうすることで感染によって起こるランダムな変動にも耐えられるようにするためである。

まだ多くの細部的な事項が考慮されなければならず、そのためには感染学、モバイルコンピューティング、 UI、マシーンラーニング、データベースの暗号化、データの信頼に対する専門的な法的知識に至るまで、多様な専門家たちの共同の努力が必ず要求される。しかし、これはオープンソース協業ツールを使用し、公開的に開発することができ、近いうちに全世界的に無料で配布されるだろう。
 
文：Vargha Moayed & Yoshua Bengio
(初心者向け)【UiPath】エラー解決へ向けたポイント・コツその④_エラーメッセージウィンドウ後編


前章までのご説明で、エラーメッセージの確認方法や、エラーの要因場所の特定方法については、
ご理解いただけましたでしょうか。

前回の記事はこちら→[エラー解決へ向けたポイント・コツその③_エラーメッセージウィンドウ前編](https://qiita.com/chi_inamori/items/3ce005a936d3fa04cad6)

ここまで来た方は、あとは実際にエラー解決の方法を見つけるのみとなります！

**使用した環境**
下記の説明(画像)で使用している
 UiPath Studioは、コミュニティライセンスのバージョン2020.2.0-beta.108のものです。

# とりあえずエラー文はググってみよう

私はこれまで2年近くUiPathを触ってきましたが、実際今でも初めて見るような
エラーメッセージに出会うことがあります。

その場合は基本的に今でも、エラーメッセージを理解する、そしてエラーを解決するために、

表示されたエラーメッセージそのまま、Google先生などの検索ブラウザーの検索バーに入力、
あとは半角スペースに「UiPath」というキーワードでよく検索して、調べます。

ただ、まだまだUiPathそのものが最近定着してきたツールになるため、
解決に直結する記事を見つけるのは、容易でないことがしばしばです。。

エラー要因で調べたけど、UiPathに関連するものがないって場合は、
「マクロ(VBA)」や「.NET Framework」に関連する記事も参照してみましょう。

UiPathは、「**VB.NET**」というMicrosoftが出している開発言語を使っており、
上記のキーワードは関連性が高いワードになります。

記事内すべての意味が分からなくても、解決の糸口を少し見つけられるかもしれませんので、
ぜひチェックしてみてください！

##よくあるエラーメッセージ

###「このセレクターに対応するUI要素が見つかりません」
結局のところ、これが一番よく見るエラーではないでしょうか。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614942/2d26377d-9be4-c4cb-bda8-01222686ffbb.png)

この場合は、取得したセレクター情報が可変的に設定できていない場合が多いです。
ここでは、セレクターを可変的にする方法として、
一番簡単である[修復]ボタンを使った方法をご紹介します。

### そもそも[修復]ボタンってどこにあるの？

修復ボタンは、セレクターエディターを表示させたとき、かつ、
検証が×となっているときにのみ有効になっているボタンです。
<details><summary>セレクターエディターの表示方法</summary>
1. メニュー>[セレクターを編集]を選択して表示させる
![セレクターエディター表示方法_例1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614942/7da64f0e-8e3e-f8fa-21e7-195c4296f316.png)
2. プロパティパネルから表示させる
![セレクターエディター表示方法_例2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614942/aa7c9b2b-45d0-3470-a360-b362c37916ef.png)
　※アクティビティによっては、上記のセレクターの欄が、
　プロパティ>入力>ターゲット(左端の[+]ボタン押下)>セレクターとなっている場合があります。
</details>
![セレクターエディター_修復ボタン](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614942/62d70982-5944-6bab-4157-ecb21969a187.png)

上記の例は、メモ帳アプリにて新規メモを立ち上げた状態のものを指定した際のセレクター情報になります。
名前を付ける前の状態を指定しているので、
例えば下記のような「TESTメモ」という名前を付けて一度保存したウィンドウは、
上記のセレクター情報では認識できません。
![比較](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614942/cbbc5350-adb2-7ba0-9a3a-f8868ec92801.png)

「TESTメモ」というウィンドウも認識させたい場合は、先ほどの[修復]ボタンを押下し、
UI認識モードになったことを確認したうえで、「TESTメモ」というメモ帳ウィンドウの方を選択します。

選択後、上手くいっていれば、
「現在のUI要素と一致するようにセレクターが更新されました」というメッセージが表示され、
セレクターエディター画面も以下のように検証のエラーがなくなっている状態になると思います。

![MSG-セレクター一致](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614942/f6551e64-e005-8fd7-4880-9f98a360a6ef.png)


![セレクター修復後](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614942/a3fa27ee-0d4e-ca57-1555-bf47650eada1.png)
修復を行うことで、titleのところにあった、「無題」という部分がワイルドカードである
「*(半角アスタリスク)」に自動的に置き換えられました。 
<details><summary>ワイルドカードとは</summary>
どんな文字にも置き換えられる文字のことで、セレクター情報をあいまいな形で定義することが出来きます。
UiPathで使用できるワイルドカードは2種類あり、それぞれ以下のような役割を持っています。
「 \* 」：何かしらの複数文字が入ることを示します。
「 ? 」：何かしらの1文字が入ることを示します。
</details>

上記の状態になっていれば、再度実行してみてもエラーなく実行できると思います。

セレクター情報の調整方法については、下記サイトもお薦めです。併せてご参照ください。
[【できるUiPath】セレクターの変数を編集して操作対象を動的に指定しよう](https://dekiru.net/article/17803/)


#　最後に
今回は、始めたばかりの人にでもエラー解決できるよう、
よくある例も一つに絞り、解決方法も簡単なセレクター調整方法しかご紹介できませんでしたが、

* どういったセレクター情報のときに可変的にするべきか
* もっと詳しくセレクター情報を確認する方法

等のセレクター調整についてのポイントは、また次回別の記事としてまとめてみたいと思います。
(その際は、またこちらにリンクを付けておきます。)

それまでには、私ももっとスキルを磨かねばデス。

最後までお読みいただきありがとうございました！
CakePHP viewの共通化

#やること
* エレメントを使って、addとeditのctpファイルを共通化してシンプルにコードを書く。
* ~~コントローラのアクションのコンポーネント化~~ 共通する処理を関数化する



#結局！コンポーネント化はやめました。
なぜなら、
コンポーネントは**コントローラ間で共有**されるロジックのパッケージで、
アクションの共通化をするなら、関数化で十分。

##コントローラのコンポーネント化


###Error: Call to a member function saveAll() on null
####解釈
モデルオブジェクトは、saveall()って関数を呼び出される。
nullからsaveall()を呼び出そうとしたら、nullのメンバ関数ではないって怒られている。

####原因
Postモデルがから状態だった。
やっかいなのは、controllerでモデルを使う方法と、componentでモデルを使う方法が違うこと。
componentでモデル利用
``` $userModel = ClassRegistry::init('Post');```
controllerでモデル利用

```php

public $uses = array(
    'Post',
    'Comment',
    'Tag',
    'Post_tagging'
   );
```


エラーを出しているのソース

```php5


         if ($this->Post->saveAll($format_save_data,array('deep' => true))) {
             $this->Flash->success(__('The post has been saved.'));
             return $this->redirect(array('action' => "index"));
         } 
  

?>
```

解決したソース

```php

$userModel = ClassRegistry::init('Post'); //Postモデルを読み込む

$userModel->saveAll($format_save_data,array('deep' => true))
```
SpringBoot と Let's Encriptの構成

# 参照
[ほぼここのパクリ](https://dentrassi.de/2018/09/25/securing-a-spring-boot-application-with-pkcs-1-pem-files/)

# アプリ側の対応
## gradle へ依存追加

```gradle
implementation("de.dentrassi.crypto:pem-keystore:2.2.0")
```

## Application（エントリポイント）で読み込み追加

```kotlin

import de.dentrassi.crypto.pem.PemKeyStoreProvider
import java.security.Security

@SpringBootApplication
class Application {
}

fun main(args: Array<String>) {
    Security.addProvider(PemKeyStoreProvider());
    runApplication<Application>(*args) {
        setBannerMode(Banner.Mode.OFF)
    }
}
```

# application.propeties

```properties
server.ssl.enabled=true
server.ssl.key-store=/path/to/keystore.properties
server.ssl.key-store-type=PEMCFG.MOD
server.ssl.key-store-password=dummy
server.ssl.key-alias=keycert
```
server.ssl.key-store-passwordは、まんま`dummy`で良い。
server.ssl.key-storeは、サーバ上のパスになり、keystore.propertiesはサーバに配置すること。

# keystore.properties
```keystore.properties
alias=keycert
source.cert=/etc/…/fullchain.pem
source.key=/etc/…/privkey.pem
```

source.certとsource.keyは、let's encryptで作ったものを指す。
【備忘録】Azure Databricks(Spark)に対して、JDBC接続を実施する場合におけるサブクエリ利用時のエラーへの対応方法

## 概要

　Azure Databricks(Spark)に対して、JDBC接続によりサブクエリを含むクエリを実行する場合には、”UseNativeQuery=1”を指定する必要があるようです。Exists句を含むクエリを実行する場合にも同様の方法で解決できます。

　Azure DatabricksではSimba社のjdbcドライバーを利用することが想定されており、Simba社のSpark jdbcドライバーを利用する他のソフトウェアにおいても同様の解決ができるかと。



## エラーメッセージと解決策について

### エラーメッセージについて

>   Response message:java.sql.SQLException: [Simba][SparkJDBCDriver](500051) ERROR processing query/statement. Error Code: 42000, SQL state: Syntax error or access violation, Query: AEValueSubQuery is not supported.



### 問題点

JDBCドライバーのデフォルト設定にて、クエリを、HiveQLに変換することが原因なようです。下記が、Simba社のドキュメント記載内容となります。

>   UseNativeQuery
>
>   | Default Value | Data Type | Required |
>   | ------------- | --------- | -------- |
>   | `0`           | Integer   | No       |
>
>   This property specifies whether the driver transforms the queries emitted by applications.
>
>   -   `1`: The driver does not transform the queries emitted by applications, so the native query is used.
>   -   `0`: The driver transforms the queries emitted by applications and converts them into an equivalent form in HiveQL.

引用元: [Simba Spark JDBC Driver with SQL Connector 2.6.3 Installation and Configuration Guide](https://www.simba.com/products/Spark/doc/JDBC_InstallGuide/content/jdbc/hi/options/usenativequery.htm)



### 解決策

Database URLにて、”UseNativeQuery=1”を追記してください。

**標準のDatabase URL**

```java
jdbc:spark://japaneast.azuredatabricks.net:443/default;transportMode=http;ssl=1;httpPath=sql/protocolv1/o/6164547948198512/0418-005719-reins180;AuthMech=3;UID=token;PWD=<personal-access-token>
```

↓

**変更後のDatabase URL**

```java
jdbc:spark://japaneast.azuredatabricks.net:443/default;transportMode=http;ssl=1;httpPath=sql/protocolv1/o/6164547948198512/0418-005719-reins180;AuthMech=3;UID=token;PWD=<personal-access-token>;UseNativeQuery=1;
```



## 関連リンク

-    [BI ツールを 接続する ](https://docs.microsoft.com/ja-jp/azure/databricks/integrations/bi/jdbc-odbc-bi#step-2-configure-jdbcodbc-connection) (Microsoft社 Azure Databricks docs)
-   [UseNativeQuery](https://www.simba.com/products/Spark/doc/JDBC_InstallGuide/content/jdbc/hi/options/usenativequery.htm) (Simba社 Simba Spark JDBC Driver docs)
素人Python日記⑥ ～ネット上にある講座をなぞってみる

# この投稿の目的
日記みたいなものです。

前回読んでいたテキストは飽きてきたのでいったんポイーで。
今日は、Qiitaで見つけた初心者用講座？を進めてみました。


## やったこと
 -  [@kaki_k](https://qiita.com/kaki_k)さんの[Python Django入門 (3)](https://qiita.com/kaki_k/items/7b178ad39394a031b50d)から「[入門（4）](https://qiita.com/kaki_k/items/6e17597804437ef170ae)」まで
 -  書籍管理アプリを作っていくチュートリアル的なもの
 -  初めてformに触れた
 -  初めてbootstrapを使った
 -  初めてJQueryを使った

 
## ちょっと理解がすすんだこと
 -  モデルのいじり方
 -  makemigrations モデル　でマイグレーションファイルができる
 -  migrate モデル　ではマイググレーションファイルをデータベースファイルに反映している
 -  マイグレーションファイルとは、SQLをわざわざ書かずにデータベース内にテーブルを作るためのもので、DBの設計図的なもの。これを読んでテーブル作成をdjangoが勝手にやってくれるので、DBの種類（MySQLとかSQLiteとか）を考慮しなくてよい
 -  urls.pyの中のurlpatternでincludeを使う意味：子urlsで書いたものをまとめられる
 -  staticもtemplatesも、ディレクトリはアプリ名で挟む（アプリ名\static\アプリ名）と、独立化するとき便利：全static・templatesが一旦同時展開されるため
 -  get_object_or_404について
 -  render関数のこと：引数はrequest、template_name、context
 -  request：GETとPOSTに注意

 
## わかってないこと
 -  html側での呼び出し方
 -  引数の渡し方
 -  templateとstaticのパス ※解決

特にstaticの方はどハマりしました。
最初、記載通りにサイトが反映しなかったので、もしかしたら自分が入れたBootstrapとJQueryのどちらかが機能していないのかと思いました。ともに触ったのは初めてだったので、何がいけないのか、どうやって問題の箇所を特定するのかから混乱。

ページ記載のコードをコピペしてみたのですが、これでもうまくいかず。そのあたり一部コメントでも指摘がされていて、どうやら呼び出すときのパスを記載しなおさないといけなそう。
パスの問題なら簡単だ！とナメてかかったところ、これがハマったのでした。

ただ、いろいろ探る過程で、これまで何となくすっ飛ばしていたsettings.pyの内容も少しだけかみ砕いて理解することができました。
やっぱり自分で問題に直面して解決していくことで初めて理解できる部分も多いです。
こうしたことは、テキストを読んでいるだけではわからないので、貴重な経験でした。

次回も継続してこのチュートリアルを進めていきます。


---
＜次の一歩＞
[素人Python日記⑦ ～ネット上にある講座をなぞってみる（その2）](https://qiita.com/wahahahagi/items/7ed2e55bb3a134653975)

＜牛歩的経緯：自宅環境構築＞
[自宅待機を有効活用する① ～思い立ちからゴール設定まで](https://qiita.com/wahahahagi/items/9bdb192d8a55a5087dfe)
[自宅待機を有効活用する② ～LET'S NOTE CF-W8のHDDをSSD換装する話](https://qiita.com/wahahahagi/items/bf216504dbb79d0f9863)
[自宅待機を有効活用する③ ～2020年、ようやくXPをWin10に](https://qiita.com/wahahahagi/items/411b6c0f06d816bac4cc)

＜牛歩的経緯：Djangoと仲良くなる＞
[素人python日記① ～Django導入までの思考回路](https://qiita.com/wahahahagi/items/304229a520f2b0650f03)
[素人Python日記② ～Djangoガールズのチュートリアルをやる（初日）](https://qiita.com/wahahahagi/items/28162eae687c4c793d14)
[素人Python日記③ ～Djangoガールズのチュートリアルをやる（2日目）](https://qiita.com/wahahahagi/items/cfca309d344b616ddeb2)
[素人Python日記④ ～Djangoガールズのチュートリアルをもっかいやる（6日ぶり3日目）](https://qiita.com/wahahahagi/items/373acaa269e35f2e2713)
[素人Python日記⑤ ～参考書を手に取ってみる](https://qiita.com/wahahahagi/items/dbbda23a151303b9395a)
【備忘録】Azure Databricks(Spark)に対して、JDBC接続を実施する場合におけるExists句利用時のエラーへの対応方法

## 概要

　Azure Databricks(Spark)に対して、JDBC接続によりExists句を含むクエリを実行する場合には、”UseNativeQuery=1”を指定する必要があるようです。サブクエリを含むクエリを実行する場合にも同様の方法で解決できます。

　Azure DatabricksではSimba社のjdbcドライバーを利用することが想定されており、Simba社のSpark jdbcドライバーを利用する他のソフトウェアにおいても同様の解決ができるかと。



## エラーメッセージと解決策について

### エラーメッセージについて

>   Response message:java.sql.SQLException: [Simba][SparkJDBCDriver](500051) ERROR processing query/statement. Error Code: 42000, SQL state: Syntax error or access violation, Query: AEExistsPredicate is not supported.



### 問題点

JDBCドライバーのデフォルト設定にて、クエリを、HiveQLに変換することが原因なようです。下記が、Simba社のドキュメント記載内容となります。

>   UseNativeQuery
>
>   | Default Value | Data Type | Required |
>   | ------------- | --------- | -------- |
>   | `0`           | Integer   | No       |
>
>   This property specifies whether the driver transforms the queries emitted by applications.
>
>   -   `1`: The driver does not transform the queries emitted by applications, so the native query is used.
>   -   `0`: The driver transforms the queries emitted by applications and converts them into an equivalent form in HiveQL.

   引用元: [Simba Spark JDBC Driver with SQL Connector 2.6.3 Installation and Configuration Guide](https://www.simba.com/products/Spark/doc/JDBC_InstallGuide/content/jdbc/hi/options/usenativequery.htm)


### 解決策

Database URLにて、”UseNativeQuery=1”を追記してください。

**標準のDatabase URL**

```java
jdbc:spark://japaneast.azuredatabricks.net:443/default;transportMode=http;ssl=1;httpPath=sql/protocolv1/o/6164547948198512/0418-005719-reins180;AuthMech=3;UID=token;PWD=<personal-access-token>
```

↓

**変更後のDatabase URL**

```java
jdbc:spark://japaneast.azuredatabricks.net:443/default;transportMode=http;ssl=1;httpPath=sql/protocolv1/o/6164547948198512/0418-005719-reins180;AuthMech=3;UID=token;PWD=<personal-access-token>;UseNativeQuery=1;
```



## 関連リンク

-    [BI ツールを 接続する ](https://docs.microsoft.com/ja-jp/azure/databricks/integrations/bi/jdbc-odbc-bi#step-2-configure-jdbcodbc-connection) (Microsoft社 Azure Databricks docs)
-   [UseNativeQuery](https://www.simba.com/products/Spark/doc/JDBC_InstallGuide/content/jdbc/hi/options/usenativequery.htm) (Simba社 Simba Spark JDBC Driver docs)
Ruby on RailsのDBをMySQLに変えてみた

こんにちは！モリタケンタロウです！
今回はRuby on RailsのDBをデフォルトのSQLiteからMySQLに変更する方法について紹介します。

最初からMySQLのDBを使うと決めてアプリを作る場合は、↓の記事を参考にしてみてください。

* [AWS Cloud9でRuby on Railsを動かしてみた（MySQL編）](https://qiita.com/MORITAKENTARO/items/ab6f1b9a7c356409f1da)

# とにかくやってみよう！
やることは二つです。

* データベースの定義ファイル(`config/database.yml`)を書き換える
* MySQLをインストールする

ということで、早速`config/database.yml`を編集します。

```Yaml
# 編集前
default: &default
  adapter: sqlite3
  pool: 5
  timeout: 5000

development:
  <<: *default
  database: db/development.sqlite3

# 編集後
default: &default
  adapter: mysql2
  encoding: utf8
  pool: 5
  username: root
  password:
  host: localhost

development:
  <<: *default
  database: development
```
そして、MySQLをインストールするために、GemFileを編集します。

```yml
# 編集前
# Use sqlite3 as the database for Active Record
gem 'sqlite3'

# 編集後
# Use mysql2 as the database for Active Record
gem 'mysql2'
```
そしたら、`bundle install`でMySQLをインストールします。
何かエラーが出てきたら[コチラの記事](https://qiita.com/MORITAKENTARO/items/ab6f1b9a7c356409f1da)を参考にしてみてください。

```bash
$ bundle install
The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java`.
Fetching gem metadata from https://rubygems.org/............

# 省略

Bundle complete! 15 Gemfile dependencies, 62 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
```

うまくインストールできました。
それではアプリを起動して…ってのはもう少し我慢で、その前にMySQLのサービスを起動しないといけないみたいです。
じゃないと、「**Mysql2::Error** Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)」って怒られて一瞬ショックな気持ちになります。
ということで、`sudo service mysqld start`コマンドでMySQLのサービスを起動します。
**※ これもsudo付けないと「Permission denied」って怒られた…**

```bash
$ sudo service mysqld start                                         
Initializing MySQL database:  Installing MySQL system tables...

# 省略

Please report any problems at http://bugs.mysql.com/

                                                           [  OK  ]
Starting mysqld:                                           [  OK  ]
```
サービスを起動したら、今度はDBを作ります。
DB作らないでアプリを起動しても「**ActiveRecord::NoDatabaseError** Unknown database 'development'」って怒られるだけです。
`rails db:create`コマンドで`config/database.yml`に書いてある内容でDBが作られます。

```bash
$ rails db:create
Created database 'development'
```
そしていよいよアプリを起動します。

```bash
$ rails server                                                                                                                                                         
=> Booting Puma
=> Rails 5.0.7.2 application starting in development on http://localhost:8080
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.12.4 (ruby 2.6.3-p62), codename: Llamas in Pajamas
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://localhost:8080
Use Ctrl-C to stop
```
![yayrailsmysql.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612211/b1dbbc96-5db7-ac3f-5f3f-81803c3a6237.png)
できたっぽいですね！
それでは～
iTunesストアのトップソングのRSSを自動で取得してみた

#はじめに
この記事はなんとなくJSとかをやっている学生がメモ変わりに使っているものです。内容は期待しないでください。

#1.取得したデータをファイルに保存するプログラム

```
#!/bin/bash
dname="/home/vagrant/workspace/itunes-rank-rss"
mkdir -p $dname
filename="${dname}/hourly-topsong-`date +'%Y%m%d%H%M'`.xml"
curl -s -H "User-Agent: CrawlBot;" -o $filename https://itunes.apple.com/jp/rss/topsongs/limit=10/xml
```

{#!/bin/bash}はシェルスクリプトを/bin/bashにあるbashシェルで実行するための記述。
二行目はdnameという変数が保存するディレクトリを示しています。
三行目は-pオプションを使ってディレクトリがなければ新しく作り,ある場合も動作するようになる。
四行目はfilenameという変数に指定した名前のXMLファイルを代入しています。${dname}はdnameを文字列ではなく変数として扱うためのものです。
```date +'%Y%m%d%H%M'```
これは日付と文字列を出力するコマンドでファイル名を作っています。
五行目はcurlコマンドを使用しています。

#2.curlコマンドとは
サーバもしくはクライアント側からデータ転送するコマンド。基本は以下のような形です。
```cual オプション　URL
```curlには様々なオプションがあります。今回は-s,-o,-Hの3つのコマンドを使用しています。

|オプション|意味|使い方|
|:---:|:---:|:---:|
|-o|実行結果をファイルへ出力|curl -o 出力先PATH URL|
|-s|ファイル出力時の進捗状況を非表示|curl -s -o 出力先PATH URL|
|-H|ファイルヘッダーに追加|curl -H 文字列|

#3.仮想環境で実行する
今回はUbuntuで行うのでiTerm2で仮想環境を起動する。

起動したところで
1.Virtual Box(バーチャルボックス)
2.Vagrant（ベイグラント）
という2つのソフトウェアを使った仮想環境でUbuntuを使用します。
cd ~/vagrant/ubuntu
vagrant up
vagrant ssh

Ubuntuがインストールされたディレクトリに移動。vagrant upは仮想的なPCにインストールされたUbuntuを起動するコマンドで,vagrant sshはVagrantの仮想マシンがセットされている状態でSSHに接続します。
シェルスクリプトのプログラムを動かすためには、その実行を許可するような権限がファイルに付与されている必要があり,今回は全てのユーザが実行可能なようにコンソールに記述しました。
```chmod a+x niconico-ranking.sh
```


#4.ファイルの保存を自動化する
今回記述したプログラムを自動的に行うため,cronを使って実行します。
```crontab -e
```
以上の内容でcronを設定します。
cron最後尾に以下を記述し,毎時40分おきに指定してプログラムを実行します。
```40 * * * * /home/vagrant/workspace/itunes-rank.sh
```
lsコマンドでディレクトリの内容を確認してファイルがあれば成功です。お疲れ様でした！！




###XMLとは
XMLは日本語では「拡張可能なマークアップ言語」と訳されます。XMLでは、囲んだ文字列をデータとしてわかりやすく管理する目的でタグを使います。
XMLは、データ記述用の言語です。文書中のデータをわかりやすくしたり、データを交換したりできます。マシンに情報をわかりやすく、効率よく伝えるための言語です。

###cronとは
多くのUNIX系OSで標準的に利用される常駐プログラム（デーモン）ので、利用者の設定したスケジュールに従って指定されたプログラムを定期的に起動してくれる。
[Android]ライブラリ導入方法


# ライブラリ導入方法
以下の手順となります。
・Module 追加
・dependencies追加
・プロジェクトビルド


## Module 追加
<img width="907" alt="2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618722/a91112db-16a0-723d-33f4-d26b3ab18b7d.png">
<img width="573" alt="1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618722/88a00ed0-0bb8-6ef1-ec95-a7020d625d46.png">
<img width="906" alt="3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618722/315973a7-8488-a442-96bc-c89a5e35b0bb.png">

## dependencies追加

build.gradle[app]でdependencies追加する。
上の Subproject name と一緒の名前を使う。

```
implementation project(":samplelibrary")
```

## プロジェクトビルド
<img width="284" alt="4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618722/6856da4c-a65c-f4f8-185b-2a62316508c9.png">