OmniAICreator/Qiita-1.07M huggingface dataset:
自動で購入する君

#自動で購入する君を作る
今回は自動で購入するbotを作成したので備忘録として。
コード全体は載せないけど、これを組み合わせれば自動購入botはほぼ作れます。

#使用するパッケージ
| パッケージ | バージョン |
|:-:|:-:|
| datetime  | 　標準モジュール  |
| requests  | 2.25.1  |
| selenium  | 3.141.0  |
| chromedriver_binary  | ブラウザに合わせる  |


chromedriver_binaryは下記参照。Chromeのドライバと合わせてインストールします。

[ChromeとPythonのchromedriver-binaryのバージョンを合わせたい。](https://qiita.com/akiko-pusu/items/86faca0cb9c877896c04)



#初期値設定

````autobuy.py
url = input("購入したいサイトのトップページURL:")
url2 = input("購入するURL:")

login = "ログインID"
password = "パスワード"

options = webdriver.ChromeOptions()
driver = webdriver.Chrome()
````
ここで初手詰まりポイント。driverのカッコ内を`(Options = Options)`としていたが、何故かログインできず。
ログイン時にロボットと勘違いされてしまいます。


#webdriverの設定
````
def init_condition():
    #If you want to run as headless, remove commentout
    #options.add_argument('--headless')
    options.add_argument('--disable-gpu')
    options.add_argument('--disable-desktop-notifications')
    options.add_argument("--disable-extensions")#
    options.add_argument('--lang=ja')
    return


def photo_leading_off():
    #Ignore photos
    options.add_argument('--blink-settings=imagesEnabled=false')
    options.add_argument("--proxy-server='direct://'")
    options.add_argument("--proxy-bypass-list=*")
    return
````
`webdriver`の動作設定。ここは脳死で書けばほぼ問題なし。
`--headless`はコメントアウトしてあるが、読み込み時にブラウザを起動せずにバックグラウンド動作的な感じにしたいときはコメントアウトを外す。

`photo_leading_off`は、起動すると画像をすべてすっ飛ばして起動。読み込みが早くなります。



#ログインをする
````
def login():
    driver.find_element_by_link_text("ログイン").click()
    driver.execute_script('document.getElementById("login_id").value="%s";' % login)
    #For Amazon
    #driver.find_element_by_id('continue').submit()
    driver.execute_script('document.getElementById("password").value="%s";' % password) 
    #For check box to remember
    #driver.find_element_by_name('rememberMe').click()
    driver.find_element_by_class_name('button').submit()
    print("\n\n Success login \n\n")
    return
````
ログインは、基本Webサイトを動作するイメージ。
一行目でHTML内から”ログイン”の文字を探しクリック。だいたいログインボタンには`ログイン`と書いてあるので結構汎用性あり。
そこから先はログインページの中身次第で”　”内を変更する必要があるが、だいたい似たような名づけをされているのでわかりやすい。


#時間設定
````
def time_control():

    i=0

    def job():
        print("Start job")
        nonlocal i
        i=1
        return
    
    start = input("開始時間(00:00:00) ")
    start1 = datetime.datetime.strptime(start, '%H:%M:%S').time()
    start2 = datetime.datetime.combine(datetime.date.today(), start1) + datetime.timedelta(seconds=5)
    start3 = start2.strftime("%H:%M:%S")
    print("Start at ", start1)
    schedule.every().day.at(start3).do(job)

    while i==0:
        schedule.run_pending()
        sleep(1)
    return
````
PC内の時間とリアルタイムの時差をとってプログラムを起動させる。start2内の数字が現実世界との差。
1秒ごとに更新しながら開始時間になったらjob起動するよ！jobが起動するとiが変わって無限ループキャンセルするよ！の意。

ちなみにPythonだと変数は特に指定がない限りすべてGlobalで認識されるらしい。
ただし、jobで変えた変数は返せないので一応nonlocalで定義している。
do()では関数しか入らず、式は入れられないのでiの返り値ではできなかった。

#購入！！！！
````
def purchace_ticket():
    driver.get(url2)
    driver.find_element_by_link_text("押したいボタンの名前とか").click()
    return
````
ログインのところとほぼ同じ。
find_elementは適当に使って問題なし。一番明瞭なのはxpathかも。


以上をmainの中に好きな順番で突っ込めば勝手に好きな時間にログイン、購入できる。
訂正やらなにやらあればコメントください！！！！！！！！


``*時間設定は実際成功していないので時間やらなにやらもうちょっと色々調整してみてください``
HTML~フォーム作成①~

ここではお問い合わせフォームの部品について見ていきます。

まずは、お問い合わせフォームを作るために必ず使う"type"属性について見ていきましょう！
フォーム部品の種類を指定する際に使用します！inputタグと一緒に使います。
それでは見ていきましょう。
#①１行テキスト

```index.html
<input type="text">
```
と入力するとブラウザ上で１行のみ表示されますね。
![スクリーンショット 2021-03-04 13.01.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/bbfcbcc4-d29d-77f8-dc57-f03cba1f993c.png)

これはtype属性の初期値です👍
他にも様々な値がありますので、参考にどうぞ！
▶http://www.htmq.com/html5/input_type_search.shtml

#②２行以上のテキスト
```index.html
<textarea></textarea>
```
![スクリーンショット 2021-03-04 13.20.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/bd5b5627-7d9f-c286-6c40-dcc06ae0bbf0.png)


#③password テキスト

```index.html
<input type="password">
```
![スクリーンショット 2021-03-04 13.23.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/43603c2d-a17a-f26f-5961-46939841098f.png)


いつも入力するpassword入力ホームになりましたね！！
ただこれだと、何を入力するのかがわかりにくいですね(^_^;)

そこで何を入力するのかがわかるようにしていきたいと思います👍
【備忘録】貸借対照表／損益計算書を処理したときに使ったカスタムロジック

貸借対照表／損益計算書の処理にこのロジックが100%必要というわけではないが、表の構造によって普通のマッピングではうまく取得できないときに、行全体をマッピングする方法＋このロジックを使うことで対応できたので備忘として残しておきます。

本当にただの備忘録のなので解説なしです。

```python:貸借対照表／損益計算書を処理したときに使ったカスタムロジック
# 値を保存する変数: table_values
import re
import pandas as pd
df = pd.DataFrame(table_values)

### カスタム箇所 ###

#このカラム名をIQ Botの列名に合わせて変える
kamoku = "資産"
kingaku = "資産金額"

#貸借対照表上で、マイナスじゃないんだけどマイナスとして扱うべき符号があればここに定義
minusSign = ("▲","△","A")

#科目名から除外したいノイズを定義
noise = (","," ")

### カスタム箇所おわり ###

def hasMinus(txt):
  for x in minusSign:
    if x in txt:
      return True
  return False

def getKamoku(txt):
  
  #数字を除外
  name = re.sub("\\d","",txt)
  #ノイズを除外
  for x in noise:
    name = name.replace(x,"")
  #マイナス符号を除外
  for x in minusSign:
    name = name.replace(x,"")
    
  return name

def getKingaku(txt):
  
  #数値のみを取り出した絶対値
  absVal = re.sub("\\D","",txt)
  
  #符号をつける
  if(hasMinus(txt)):
    return "-" + str(absVal)
  else:
    return absVal

#科目名からは数字とカンマを除外
df[kamoku] = df[kamoku].apply(getKamoku)
#金額は符号つきの数字を取得
df[kingaku] = df[kingaku].apply(getKingaku)

#科目名、金額とも空白の行を削除
cols = (kamoku, kingaku)
for i in range(len(df)):
  isAllSpace = True
  for col in cols:
    #ひとつでも値が入った行があれば、isAllSpaceはFalse
    if df.at[str(i),col] != "":
      isAllSpace = False
  if(isAllSpace):
    df.at[str(i),kingaku] = "この行は削除対象です"
  
df = df[df[kingaku] != "この行は削除対象です"]
  
#表の操作をするときに必ず入れるコード（最後）
table_values = df.to_dict()
```
Gitで間違えてmasterにcommitしてしまったときの対処法（SourceTree）

#はじめに
Gitでブランチを作成せずにmasterにcommitしてしまったため、記録として書きます。

今は記事作成に時間を割きたくないため、丁寧な書き方ではありませんが、画像を載せているのでご了承ください。

###本記事について
SourceTreeを使用したGit操作を行っているのでお役に立っていただけば嬉しいです。

###参考記事
https://off.tokyo/blog/git-master-commit/

#手順
###1
ブランチを作成せずmasterにcommitしてしまった

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/747599/e9f0f77c-1d5e-492f-2d02-638ba86c4ce5.png)

###2
まずは新しいブランチの作成
1. 「ブランチ」をクリック
2. 新規ブランチ名を記載
3. 「ブランチを作成」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/747599/3010844a-30ba-cc3e-9380-c0086f149b2f.png)

###3
次に、masterに移動　※私のではmainとなっています
1. 左側のmainをダブルクリックでmainに移動
2. 画像２のように「コミット適用前に戻す」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/747599/fc3b0bb3-234f-4cfb-b10a-4a1063390801.png)


###4
1.確認画面が現れるでの「OK」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/747599/d50fc1a3-0b9f-5e09-afcb-dab1d9a82de7.png)

###5
1.完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/747599/c23f058b-cc83-299d-27dc-4d81f013e718.png)

これで、新しいブランチにはcommitした物が保存されてt、masterには元の状態に戻っています。

#まとめ
masterに間違えてコミットしたら
新しいブランチを作成し、masterのcommitをリセットしたら終わり
です！
まとめたら簡単ですね。
LinuxとPythonでBDAを取得する

Linux と Python で Bluetooth Device Address を取得するときのメモ。

```
import dbus

BLUEZ_SERVICE_NAME = 'org.bluez'
DBUS_OM_IFACE = 'org.freedesktop.DBus.ObjectManager'
DBUS_PROP_IFACE = 'org.freedesktop.DBus.Properties'


bus = dbus.SystemBus()
adapter = dbus.Interface(bus.get_object(BLUEZ_SERVICE_NAME, '/org/bluez/hci0'),
					DBUS_PROP_IFACE)
addr = adapter.Get("org.bluez.Adapter1", "Address")
print(addr)
```
VS Codeで複数行に渡って正規表現を利用する

VS Codeでよく正規表現による検索や置換を行うが、通常、正規表現では1行ごとに適用されるため、複数行に渡って検索したい場合、明示的に`\n`を指定する必要がある。
しかし、検索したいパターンに何行分の改行があるかわからない場合もあるため、`\n`を任意回許容したいという需要がある。

具体例を見ていこう。

```text:テキスト
ドバト カワラバト rock dove
キジバト 神
カワセミ KF
ハクセキレイ セグロセキレイ
トビ トンビ 鳶
ドバト カワラバト rock dove
キジバト 神
カワセミ KF
ハクセキレイ セグロセキレイ
トビ トンビ 鳶
```
このテキストで`カワラバト`から`トンビ`まで検索したいとする。
結論からいうと次の正規表現で検索できる。

```text:正規表現
カワラバト[\s\S\n]*?トンビ
```

- `\s`: 空白文字を表す。`[ \t\n\r\f]`と同じ
- `\S`: 非空白文字を表す。`[ \t\n\r\f]`以外の一文字。
- `\n`: 改行文字を表す。`\s`で代用できそうだけど、1行ごとに検索するせいで明示的に入れないと駄目みたい。
- `*?`: 最小一致検索。この例だと2つみつかる。
    - ちなみに`?`を外すと最長一致検索。この例だと1つみつかる

![スクリーンショット 2021-03-04 12.36.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294661/87a7d592-8b06-6c09-a0e6-5e04e8ef1cd1.png)


**結論： `検索したい開始文字[\s\S\n]*?検索したい終了文字`で表現できる**

# おまけ: 検索された表現を使って置換したい場合
検索された表現を使って置換したい場合、取得したいパターンを`()`で囲んで、`$1`,`$2`と順に取得できる。
たとえば、`(カワラバト[\s\S\n]*?)神([\s\S\n]*?トンビ)`を`$1God$2`で置換すると、このパターンを満たす「神」だけが「God」に置換されます。
これは、`$1`で最初の括弧、`$2`で次の括弧にマッチしたパターンが取得されるためです。
Power Automate Desktopで社内のクソシステム操作を自動化

## 背景

ドキュメントの発番や承認など、社内システムを使わなくてもいけないことも多いのではないでしょうか。

私の勤め先では、国産のとあるシステムを使いドキュメントの発番や承認をしていますが、APIなし・CSVインポート不可のため、開発プロジェクトに必要なドキュメントを1時間かけて発番する作業が必要でした。
文字サイズも変更できず、発番処理だけで目と肩がバキバキになります。:rage: 

Power Automate Desktopが無償で提供されるようになり、この悩みから開放されるのでは！？と期待し、ドキュメントの発番作業を自動化してみました。

## Power Automate Desktopについて

元々、Microsoft 365の1つとしてPower Automate という自動化機能ががありましたが、クラウド上のアクティビティのみでした。
これをWindows上の操作も含めて自動化してくれるものです。今後Windows 10の標準機能として組み込まれるそうです。

古くはUWSCがありましたが、プログラミング記述が必須のため多くの人が使うにはハードルが高いものでした。Power Automate DesktopはGUIで自動操作を設定でき、プログラムができない人も導入しやすくなっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631668/a381d742-beec-5d64-e6ba-755f77d9cf08.png)


まだプレビュー版のためか、フローのエクスポートができないなど改善してほしいものはありますが、生産性向上には十分期待できるアプリではないかと思います。

https://flow.microsoft.com/ja-jp/desktop/

## システム操作を自動化

CSVファイルに記載したドキュメントを行ループしながらシステムで発番できることを目指します。
大きく、「システム操作の再現」と「入力する情報を外部に保持&ループ」させる処理が必要です。

### システム操作の再現

まずは、固定値を使いシステムに対しての操作を再現できるか確認してきます。
この操作はそれぞれの環境に依存するため一概に必ずできるとは言えないのですが、後述の「上位オブジェクトにフォーカス＋コピペ」を活用するのは多くのシステムで有効そうです。

当初、デスクトップレコーダーでやれると思いましたが、クソシステムの以下の仕様のためレコーダーの処理のみでは操作の再現が不能でした。オブジェクトが複雑な場合、再現できない場合がありそうです。
一方で、チェックボックス・ボタンなどのクリック処理はレコーダーで問題ありませんでした。

- 毎回、テキストボックスのIDがランダムで変更される。
- ドロップダウンの項目を動的に取得できない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631668/52e1f042-fa24-6959-a33b-a67137582f98.png)

「レコーダーでGUIオブジェクトを取得→クリップボードに所望の値を保存→Ctl+V」によりデータ入力が実現できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631668/e86b6b47-16e9-5e6f-b48a-16b88a199ceb.png)

### 入力する情報を外部に保持&ループ

これはシステムに依存せず普遍的に使えるテクニックではないでしょうか。
データテーブルとFor Each処理はやはり相性が良いです。

まずは、発番したいドキュメントの情報(ドキュメント名など)をデータテーブル型としてフロー内に読み込ませます。
データテーブルはCSV,Excel,SQLなどからインポートすることができますが。このあたりは、Microsoft 365のシステムを導入しているとより多くのものを自動化できる箇所ではないでしょうか。

その後、For Each処理でテータテーブルをループさせ、上述のクソシステムに対しての操作を実行していきます。

#### CSVからのデータのインポート

これは非常に簡単で「CSVを読み取ります」を追加するだけです。
これで、CSVTableという変数内にCSVファイルの情報が保存されるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631668/047a4307-50ba-99d9-9b3e-482dda48cb57.png)

https://docs.microsoft.com/ja-jp/power-automate/desktop-flows/variable-data-types


### ループ処理内でのデータの参照

1. For eachを追加します。反復処理の対象としてCSVTableを設定すると、全行ループしてくれます。つまり、CSVファイルが100行あれば100回ループします。
2.  CurrentItemという変数が追加されています。これは1回目のループならCSVファイルの1行目、2回目のループなら2行目のデータが格納されています。これを使いデータを動的に変更してきます。参照されているCurrentItemデータはメッセージを表示することで確認できます。
3. クリップボードに設定する値をCurrentItemに変更し、ダイナミックなデータ参照とシステム操作との組み合わせます。

**反復処理の対象としてCSVTableを設定**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631668/014b1bbf-0ed6-3683-478a-5cf2b411aa8e.png)

**CurrentItemの確認**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631668/0ed38c0a-d6c6-7d25-9205-94aa2e0f5758.png)

**システム操作との組み合わせ**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631668/dd7c8a8a-763e-0fdd-3281-38aa8d3953b6.png)


https://docs.microsoft.com/ja-jp/learn/modules/pad-loops/

## まとめ

以下の組み合わせでクソシステム業務の負荷をほぼ0にすることができました。

- 再現が不能な操作は上位オブジェクトにフォーカス＋コピペで対応できる場合がある。
- データテーブルとFor eachの組み合わせで一括処理

これを参考に生産性の低い業務から開放される方がいれば幸いです。:smile:
MetaTrader 5で金持ちになりたい！-始動編-

#楽して金持ちになりたいんじゃ！
そう思ってMetaTraderに手を出しました。EAという自動取引システムに心惹かれて。楽して稼ごうと思ったらそうなりますよね ←

とりあえず[MQL5プログラムマーケット](https://www.mql5.com/ja/market)やYouTubeやブログで配っているものを眺めてみましたが__「そんなに儲かるなら他人に教えずこっそり稼げばえぇやん」__というものばかりで、アフィリエイト目的やサロンという名の情弱を相手にした毎月金を巻き上げるシステムの宣伝ばかりでした ←言い方

さて、どうしよう。
そうだ、自分で作ろう。

こうなりますよね？

#とりあえずやること
プログラムの知識も当然必要ですが、まずはMetaTrader 5をインストールして動かさないと話が始まりません。
インストーラは公式サイトからダウンロードしても良いのですが、テストに使用したいデモ口座が追加できなかったので、[Titan FX](https://titanfx.com/ja)のものを使用しました。

ちなみに
実際の取引に使用する口座を開設する場合は[TariTali（タリタリ）](https://taritali.com)を通してキャッシュバックを狙うのも良さそうですね。でも口座開設はある程度目処がついてからやりましょうね。リアルマネーでテストするなんて無謀デスヨ？

インストール出来たら、ツール→MetaQuotes 言語エディタ（またはF4キー押下）でエディタを開きましょう。
![MetaTrader-001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255409/2bc80176-4768-cb41-c48e-5ce4a8c31ef6.png)
あとは煮るなり焼くなり、と言いたいところですが、ファイル→新規作成でMQLウイザードを開いてエキスパートアドバイザを作ってみましょう。
![MetaTrader-002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255409/ed94a412-a5a6-e735-1233-2c173f3e59c6.png)
上から2番目の（自動生成）を選び、次の画面でファイル名を入力、さらに次の画面で使ってみたいシグナルプロパティ（注文を出すきっかけ）を追加していきます（今回は試しにRSI(Relative Strength Index)を使ってみます）。
![MetaTrader-004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255409/c84f919a-7955-e4ff-ebce-248c02391b24.png)
さらに次の画面で、トレーリングプロパティ（決済するきっかけ）を追加していきます（今回はParabolic SAR）。
![MetaTrader-005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255409/69afc220-91ba-ea25-e6e9-e4d123e446e1.png)
資金管理プロパティはいじらずそのまま完了ボタンを押せばEAの完成です。早速テストしてみましょう。画面上部の水色の丸に緑色の矢印が乗っかっているボタンをポチっと押します。ストラテジーテストの画面になったら適当に設定して(←)結果を楽しみに待ちます。今回のテスト内容はこちら。銘柄はポンド・ドル、期間はM5(5分足)、1年数ヶ月分の取引データで試します。
![MetaTrader-006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255409/38c7f5d8-b1e2-4676-4386-c97e44adce99.png)
__50万円__あったデモ口座の残高がこちらになります。
![MetaTrader-00７.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255409/d5285ae2-153d-6596-616e-c99077b6a6aa.png)
╭( ･ㅂ･)و わーい、8割減...
#ここからが本題（ようやく）
何が起きていたのかを履歴で振り返りましょう。画面の上側がチャート、下側が取引結果です。
![MetaTrader-009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255409/a2f95efd-50e2-15be-f22f-d54c6af15f08.png)
9:12に売り注文を出しています（画面上側の赤い下向きの矢印、画面下側の青く反転している行）。10:17に決済しています（画面上側の青い上向きの矢印、注文と赤い点線で結ばれている）。

どうして注文・決済に至ったか。
シグナルプロパティで「RSI」を選びました。RSIの値が70を超えました。自動取引プログラムは「売り」と判断しました。
トレーリングプロパティで「Parabolic SAR」を選びました。潮目が変わったと判断して決済しました。

ものすごく大雑把に書きましたが、ようは「条件に当てはまる場合に何かをする」ということです。そのきっかけをどんどん追加・修正していくのです。たとえばパラメータを調整する、たとえば別のシグナルと組み合わせる、たとえば条件文を修正する...泥沼...溺れないように気をつけましょう。

#ただし
簡単に儲かると思わないことです。相手は世界中に居ます。年収数千万のトレーダーだったり、しかも工学博士だったり、めちゃくちゃデータ解析と予想が正確で「え？なんでそこで売り注文出した？」っていう方法で攻めてくる天才だったりしちゃいます。もう一度言います、簡単に儲かると思わないで先に進んでください。

この段階でMetaTraderを動かすためのVPSを契約してしまった人、リアル口座を開設＆入金してワクワクしてしまっている人、悪いことは言いません。解約できるものはさっさとして、金が残っているならとっとと引き出しておきましょう。

次回はMQL5について書き残す予定です。いつになるかはわかりませんが。
SQL ~データベースの操作4~

初学者です。SQLの知識が浅いためまとめたいと思い、記述している記事です。

- MySQL
- Ruby on Rails 6.0.0

# はじめに
ここではSQLというDBを操作する言語について書いています。

*この記事は、続きの記事になります。
第一回目はこちらになりますので、よろしかったらどうぞ！

https://qiita.com/yumi1003/items/8dc8083884ebd6b9775e

今回は**多様な条件の中で、特定のデータを検索できるようになる**ことが目標です！

### 前提に
データベースの作成、テーブルやカラムはすでに作成してある、データは存在している、という前提で進めます。
また、Sequel Proを使用したデータ検索です。
**→ ここから先のコードは全てSequel Proのクエリに記述しますのでご注意ください！**



# 条件にあったデータを取得する
まずはじめに、条件にあったデータの取得をしていきます。
Rubyでも使用した検索機能の**whereメソッド**と似たものが、SQL文にも存在します！

## WHERE
**WHERE**は、取得するデータを「条件」によって制御できる句です。
**WHERE**句では取得するレコードの条件を指定し、その条件が正のレコードを持ってきてくれます。

```
WHERE 条件
```

「条件」と言われてもいまいち想像がつかない、、ということで詳細に見ていきます！
*↓条件の例* **(例として記述しましたが、実際はWHERE句のみでは使用できません。SELECT句、FROM句などが必要！)**

```
WHERE id = 1

WHERE last_name = "キイタ"

WHERE id <= 5
```

**WHERE**句の条件には、比較演算子("="や"<="など)を使用します。
ルールとして、内容が文字列や日付の場合にダブルクォーテーション" "で囲わなければいけません。

これだけではわかりにくいので実際に使った時の記述を見てみましょう。
以下のテーブルやカラムに多数の情報が入っているとします。

**usersテーブル**

|カラム名|内容|
|------|----|
|last_name|苗字|
|first_name|名前|
|age|年齢|
|prefecture|出身の都道府県|

ここでは、**ユーザー情報(usersテーブル)から、名字がキイタ(last_nameカラムの中のキイタ)**という人のデータを取得したいとします。
すると以下のような記述になります！

```
SELECT *
FROM テーブル名
WHERE last_name "キイタ"
```

エンターで実行すると結果が出てくるはずです。

次に一部の文字列を検索する方法について学びましょう！

## LIKE
**LIKE**とは、**WHERE**句と併用して使うことで、「文字列検索」を実行できます。
下記のように記述します。

```
WHERE 列名　LIKE '検索文字'
```

正確に合致するかわからないという場合は、曖昧検索として「%」というワイルドカードも使用できます。

```
SELECT *
FROM users
WHERE prefecture
LIKE '%都'

続いては、複数の条件に合致するデータを取得してみましょう！

## AND演算子
**AND演算子**は、複数の条件を指定して式を作り、その条件が**全て正である時、式が正**となります。

```
WHERE 《a》 AND 《b》
```

実際の使用例を見てみましょう！

```
SELECT *
FROM users
WHERE age <= 24 AND prefecture = "神奈川県"
```
この記述で、**age(年齢)が24以下 かつ prefectureが神奈川県**のレコードを全て取得できることになります。
これで複数の条件にのみ当てはまるものを検索できました！

次は、「どちらかの条件」に当てはまったデータを取得する方法についてです！

## OR演算子
**OR**演算子は、**複数の条件を指定し、その条件のうちどれかひとつ以上が正となれば、式が正**と判断します。
例えば、以下のような式があった時、条件aと条件bのどちらかが正であれば、式自体が正となります。

```
WHERE 《a》 OR 《b》
```

ここも具体的にデータを当てはめて確認してみましょう。

```
SELECT *
FROM users
WHERE age <= 20 OR prefecture = "東京都"
```

上記の文は、**ageが20以下 もしくは prefectureが東京都**であるレコードを取得しています。
1つ以上の条件が満たせていれば取得するという点がミソですね。

次に、逆に「条件とは異なる」データを取得する方法を学びます！

## NOT演算子
**NOT**演算子は、1つの条件を指定して式を作り、その**条件に当てはまらないもの**を取得します。

```
WHERE NOT 《a》
```
上記の記述で、**aの条件が誤**となります。つまり、aという条件のみ省いて検索できるんです！
使い方をみていきましょう。

```
SELECT *
FROM users
WHERE NOT prefecture = "東京都"
```

この記述で、**prefectureが東京都じゃない**レコードを取得できます。

続いては、「条件の範囲内にあるデータ」を取得する方法についてです！

## BETWEEN演算子
**BETWEEN**演算子は、**1つのカラムに対し上限と下限を指定して式を作り、カラムの値がその範囲に含まれるとき、その式は正になる**という演算子です。
ここでは**AND**演算子とともに使います。

```
WHERE カラム名 BETWEEN 《上限》 AND 《下限》
```

では実際に例を使って見て行きます。

```
SELECT *
FROM users
WHERE age BETWEEN 21 AND 24
```

これで、**ageの21以上24以下のuser**という条件を指定できます！

最後に「複数条件のどれかに当てはまる」データを取得します！

## IN演算子
**IN演算子**は**1つのカラムに対しリストを指定して、カラムの値がそのリストに含まれる時、その式は正になる**という演算子です。

```
WHERE カラム名 IN (値１,値2,...)
```

ちょっと分かり辛いですね。例を見て行きましょう。

```
SELECT *
FROM users
WHERE prefecture IN ("東京都","神奈川県")
```

この式だと、**prefectureが"東京都" もしくは "神奈川県"であるuser**という意味になります！
イメージとしては「特定の条件のどれかが含まれているかどうか」といった感じでしょうか。

# まとめ
お疲れ様でした！
ここまでで「条件にあったデータを取得したい場合」の検索方法について学びました！
実際に開発現場で使うこともあるそうなので、この程度であればパパッと入力できるようになりたいですね('ω' )

次回は「複雑な条件にあったデータの所得方法」についてまとめたいと思います。
CodeIgniter4 のクエリビルダ `$builder->selectXXX()` は第2引数にAS句を指定できる

マニュアルにこっそり記載があるがわかりにくいのでメモ。
クエリビルダのグルーピング系 `$builder->selectXXX()` メソッドには第2引数を設定することでAS句として使える。

```php
// 例
$builder->selectMax('age', 'member_age');
$query = $builder->get();
// Produces: SELECT MAX(age) as member_age FROM mytable
``` 

対象となるメソッドは以下

- $builder->selectMax()
- $builder->selectMin()
- $builder->selectAvg()
- $builder->selectSum()
- $builder->selectCount()

実は `$builder->selectMax()` にだけ例示（というか引用だが）のように第2引数を設定している例があるのだが、他のメソッドは省略されてしまっている模様。
実際は他のメソッドでも利用可能（予測はつくと思うが）

恐らく使用頻度が高いであろう `$builder->selectCount()` だけを見ていると一瞬あれ？となるので備忘録として残す。
（というか、自分が引っかかっただけの失敗談）
Gitコマンドの簡単なまとめ

今回は、よくあるgitのコマンドなどについて簡単にまとめました。

##Git##
Gitとは分散バージョン管理システムで、複数人での開発を行う際に用いられる。
自分の書いたコードを他人に共有できる。

##リモートリポジトリ##
**リモートリポジトリとは**
複数人で共有するためにネット上(主にGithub、Bitbucketなど)にアップロードされたリポジトリのこと

またローカルリポジトリとは、自分のPCに配置されているリポジトリのこと

　
**リモートリポジトリの紐付け(追加)**

```
git remote add origin url
```
・urlのところに、リモートリポジトリのurlを設定する
・originは、デフォルトの名前

##git add##

```
git add .
```
・ファイルをコミットの対象（Gitの管理対象）に入れる。
　

```
git add ファイル名
```
・ファイル名を指定することで個別に追加もできる。

##git commit ##

```
git commit -m "コミットメッセージ"
```

・コミットするときに、メッセージをつけることができる。このメッセージは、コミットメッセージという

・メッセージの内容は、簡潔に変更した内容がわかるメッセージにする。

##git push##

```
git push origin master
```
・リモートリポジトリにアップロードする
・masterは、デフォルトのブランチ名
##git pull##
```
git pull origin master
```
・リモートリポジトリの最新の内容を取り込める。

##git status##

```
git status
```
・変更したファイルを確認できる。

##ブランチ##
**ブランチとは**
プロジェクトから分岐させプロジェクト本体別の環境に枝分かれさせることができる。機能ごとにブランチを分けることで、作業内容を明確に決め作業を進行させるなど様々な使い方ができる。

 複数人で作業する際、作業内容が混在すると大変なことになりかねないので、そういった時にブランチを分岐することで安定した作業ができて効率よく機能の実装もしも不具合が発生してもプロジェクトに戻して復元も行えたり、問題を切り離して対応することが可能になり問題解決に集中できる。

**コマンド**

```
git checkout
```
ブランチの切り替えを行うときに使用するコマンド。
・オプション
「-b」

```
git checkout -b ブランチ名
```

チェックアウトとブランチ作成を同時に行える。

「-f」

```
git checkout -f master
```
・ブランチの強制切り替えを行う

##参考元##
こちらのサイトを参考にさせていただきました。
・[サル先生のgit入門](https://backlog.com/ja/git-tutorial/)
DOBOT Magicianの可動域(2D)

DobotMagicianを横から見たときの可動域を描画します.

```bash:install
sudo apt install python3-pip -y
pip3 install matplotlib
```

```python:ki_2_link.py

import matplotlib.pyplot as plt
import math

L1 = 135
L2 = 147
end_effector_params = [61.0,0.0,0.0]

def ki(j1,j2):
  if(check_joint_limit(j1,j2) == False):
    raise Exception('out of range')

  j1_rad = math.pi * j1 / 180
  j2_rad = math.pi * j2 / 180

  x = L1 * math.sin(j1_rad) + L2 * math.cos(j2_rad) + end_effector_params[0]
  y = L1 * math.cos(j1_rad) - L2 * math.sin(j2_rad) + end_effector_params[2]

  return (x,y)

def check_joint_limit(j1,j2):

  d_j = j2 - j1

  if (j1 >= 0 and j1 <= 85):
    if (j2 >= -10 and j2 <= 95):
      return True

  return False

fig = plt.figure()
ax1 = fig.add_subplot(111)

plt.xlim(-100,400)
plt.ylim(-200,200)

plt.xlabel('x')
plt.ylabel('y')

plt.axes().set_aspect('equal')

plt.grid()

for j1 in range(-180,180,1):
  for j2 in range(-180,180,1):
    try:
      x,y = ki(j1,j2)
      plt.plot(x,y,marker='.',color='blue')
    except:
      pass

plt.show()

```
以下のような領域が得られました.![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/fc066973-0aae-6593-d6a9-a50ee5740cb5.png)





###参考
http://izawa-web.com/dobotrange/dobotarmangle.html

###実際の領域

![dobot.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/b0ed63db-bd23-4d99-c752-9af455d4b1e3.png)
Rubyのincludeを理解したい②

#書くこと
先日書いた、こちらの記事の続きとなります。

https://qiita.com/yuki-b4/items/942ab9fd4b0bba66978a

前回の記事の概要をまとめると
>Rubyのクラスとインスタンスの関係から、メソッドはどのように扱われているのか？

ということをまとめました。

今回の記事は、前回の内容を元に、Rubyのモジュールから本題のincludeについて、説明していきます。

## includeとは？
早速ですが、Rubyのincludeについて少し触れていきましょう。
実際に見てもらったほうが早いので、まずはこちらをご覧ください。

```example.rb
class QuestionAnswer
  include ActiveModel::Model   #ActiveModel::Modelというモジュールをincludeしています。
end
```

このように、`QuestionAnswer`というクラスに、`ActiveModel::Model`というモジュールをincludeしています。こうすることで、

>クラスにinclude モジュール名と記述することで、そのモジュールのインスタンスメソッドをクラスで使用出来るようになります。

これが、includeの大枠の役割となります。

## includeとメソッドの旅

以上のincludeの役割と踏まえると、**このクラスから生成されたインスタンスは、includeされたmoduleのところまでメソッドを探しに行けるという**ということが言えそうです。

この話は、前回の記事の最大のテーマ

>インスタンスはメソッドを持つのではなく、生成されたクラスに参照しに行く性質を持つ

ということにつながってきます。このことを、もう少し端的な例で見てみましょう。

```example.rb
Module Alpha
  def module_a_method
    @a_method
  end
end

class Beta
  include Alpha  #モジュールをincludeしました。
  def class_b_method
    @class_b_method
  end
end

Ceta = B.new
Ceta.module_a_method
```
ここで、`Betaクラス`から生成されたインスタンスが`Ceta`に代入されています。
そして、`Ceta`は`Module Alpha`で定義されたインスタンスメソッド`module_a_method`を利用しています。

通常、**スコープ**の性質上、あるクラスから生成されたインスタンスはそのクラス内に記述されたインスタンスメソッドのみを用いることができます。しかし、今回はモジュールをincludeしているので、そこで定義されている`module_a_method`を利用することができます。

これは、以下の図で理解してもらうと良いかもしれません。

![アウトプットメモ-338.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/948673/063bc3e4-4df7-c504-179c-535fe58b312c.jpeg)

このように、**生成されたインスタンスは、メソッドを参照しに行く性質があるからこそ、includeの役割が果たされるのだ**と理解することができました。

##まとめ
1. includeは、記述したクラスにそのモジュールのインスタンスメソッドを利用させることを許可（？）している
2. Rubyのメソッドは、インスタンスには属さず、クラスに属している。その代わり、インスタンスはメソッドを探しに行くという性質を持つ。
3. 2より、includeが成り立つのはrubyのメソッドの性質が寄与していることがわかる

## おまけ

[Github](https://github.com/rails/rails/blob/5aaaa1630ae9a71b3c3ecc4dc46074d678c08d67/activemodel/lib/active_model/model.rb)を確認したところ、

```model.rb
module Model
    extend ActiveSupport::Concern
    include ActiveModel::AttributeAssignment
    include ActiveModel::Validations  #ActiveModelから、Validationsをincludeしている
    include ActiveModel::Conversion
(中略)
end
```

このことから、バリデーションを設定することも可能になります。

```example.rb
class QuestionAnswer
  include ActiveModel::Model   

  validates :answer, presence: true
```
`ActiveModel::Model`も、上位のモジュールをincludeしているのですねぇ。

## 感想
このincludeが理解できたことで、今まで形式的に覚えていたことが芯から理解できるようになる気がします。こういう根本を知っていくって、楽しいですよね。

##最後に
最後まで読んでいただき、ありがとうございます。
ソースコード、記事の書き方について「もっとこうしたほうがいいよ！」というご意見、「そこどうなっているの？」というご質問など、お待ちしております。

## 参考文献
- [【ruby】 メソッド探索から見る、モジュール・特異メソッド・特異クラス](https://at-grandpa.hatenablog.jp/entry/2016/02/14/090544)
- [Ruby on Rails 6.1.3
Module
ActiveModel::Model](https://api.rubyonrails.org/classes/ActiveModel/Model.html)
- [(Github)rails/activemodel/lib/active_model/model.rb ](https://github.com/rails/rails/blob/5aaaa1630ae9a71b3c3ecc4dc46074d678c08d67/activemodel/lib/active_model/model.rb)
- [【Ruby】クラスにModuleをincludeする方法を図解形式で１から理解する！](https://pikawaka.com/ruby/include)
- [Railsのデザインパターン: Formオブジェクト](https://product-development.io/posts/rails-design-pattern-form-objects)
【Vue + Rails】422 (Unprocessable Entity) 新規ユーザーの作成ができない原因と解決方法について

#原因
* **CSRF保護がオフになっていたため**

>CSRF(Cross-Site Request Forgery）
 
>悪意のあるユーザーがサーバーへのリクエストを捏造して正当なものに見せかけ、認証済みユーザーを装うという攻撃手法

このエラーが怒った原因として、Vue側（フロント）から送られてきたPOSTリクエストの中に含まれるCSRFトークン。そして、Railsはページのトークンとcookie内のトークンが同一のものではないと判断されたがために起こってしまったエラーと考えられます。

Vue + Railsを使用して作成したがため外部からのPOSTによってエラーが出たのではないかと思います。

#解決（結論）
結論から申しますと、僕の場合は```cotrollers/user_controller.rb```へ
**CSRF(Cross-Site Request Forgery）の対策用のコード**を１行足すだけでした。

```cotrollers/user_controller.rb
class UsersController < ApplicationController
  protect_from_forgery # 追記

  ・
  ・（略）
  ・
end
```

#解決方法
解決に至った手順についてです。

##①ディベロッパーツールにて、422 (Unprocessable Entity)を確認

![スクリーンショット 2021-03-04 11.44.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536974/56c2fbe0-3b64-4c31-87cb-7fe7b9fe05ce.png)

##②ディベロッパーツールのNetworkタブ→JSでフロント側の確認
![スクリーンショット 2021-03-04 11.47.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536974/eac494ed-c84f-817f-ac78-f15d2d8a20ed.png)

![スクリーンショット 2021-03-04 11.48.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536974/0f8d3210-848f-0f59-ba8f-9b6107bc63e0.png)

フロント側は大丈夫そう

##③続いて、XHRタブ
![スクリーンショット 2021-03-04 11.48.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536974/cbece8df-0152-9a4f-6511-fc866dc5f379.png)

XHRタブは、非同期通信でリクエストを送っているリソースを確認できるみたいです。
![スクリーンショット 2021-03-04 11.50.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536974/23ae51ca-d17c-c2ed-c959-91826717559b.png)

ここに422エラーがありました。

##④色々、触ってみる。（ここでは）usersをタップ
![スクリーンショット 2021-03-04 11.52.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536974/aa142856-1445-0a71-09d6-55e930aaacda.png)

するとこんな画面が。

Previewタブをみてみると・・・

##⑤ActionController::InvalidAuthenticityToken
![スクリーンショット 2021-03-04 11.53.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536974/11e1fad4-c5f7-8c9c-523b-a60808e6c242.png)

おお！見慣れたRailsのエラーが！！！！

ここで、「なるほど、CSRF保護がオフになっているのか」と解決まで辿り着きました。

#最後に。今回学んだこと
ログや、ディベロッパーツールを舐めてはいけないこと思い知らされました。

恥ずかしながら、エラー発生時、ネットワークタブなどこれまで見向きもしていませんでした。
しかし今回、色々ディベロッパーツールをあさりながら解決に至ることが出来たのも事実です。

Networkタブ。活用していきます。

#参考
[【Rails API】ActionController::InvalidAuthenticityTokenの解決方法](https://qiita.com/_ayk_study/items/88269643c675fd4ca975)

[RailsのCSRF保護を詳しく調べてみた（翻訳）](https://techracho.bpsinc.jp/hachi8833/2017_10_23/46891)
DockerでDjangoのための環境構築をしてみた

## 理由

Techpitさんの講座の「[【Django】Amazon風簡易ECサイトを作ってみよう！](https://www.techpit.jp/courses/66)」の受講の際に、Djangoを使用することとなったが、その時の環境構築をDockerで行いたいと思ったためです。

## 実装

``` Dockerfile:Dockerfile
FROM ubuntu:latest
ADD requirements.txt .
RUN apt-get update && apt-get install -y \
    && apt-get install -y python3 python3-pip\
    && apt-get install -y  curl  \
    && curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py \
    && python3 get-pip.py \
    && pip install -r requirements.txt \
    && rm requirements.txt \
    && rm get-pip.py

WORKDIR /django-ec

CMD ["bash"]
```

<dl>
<dt>FROM</dt>
<dd>ubuntu環境を持ってきています
<dt>ADD</dt>
<dd>`Dockerfile`と同じ階層にある`requirements.txt`をコンテナに持っていきます</dd>
<dt>RUN</dt>
<dd>ADDでRUNで主な環境構築を行なっています。</dd>
<dd>ubuntuの場合、apt-getを用いて様々なものをインストールできます。</dd>
<dt>WORKDIR</dt>
<dd>django-ecというフォルダを作り、そこに移動します</dd>
<dt>CMD</dt>
<dd>デフォルトではbashを起動します</dd>
</dl>


```yml:docker-compose.yml
version: '3'

services:
  django:
    build: .
    ports: 
      - '8002:8002'
    volumes:
      - '.:/django-ec'
    tty: true
    stdin_open: true
```

毎回、`docker run`の時にオプションをつけるのがめんどくさいので、`docker-compose.yml`を作成しました。


```txt:requirements.txt
django
Pillow
```

今回の講座で`django`意外にも画像を扱う`Pillow`も使っていました。

## まとめ

Dockerを用いて環境構築をするのは、思っているより簡単なので、今後もたくさんDockerを使って環境構築をしていきたいと思います。
【Rails】flashとflash.nowの使い分けと理屈について【Ruby】


Railsチュートリアルで使われている2種類のメッセージ表示メソッドflash[]とflash.now[]。

どちらもメッセージを表示するという結果は変わらないですが、処理によってうまく動作しなかったりするので、それぞれの使い分けついて書いていきます。

<h2>flash[]とflash.now[]</h2>

結論から言うと、下記になります。
<b>
flash[]:
　redirect_to 使用時(データの追加、更新、削除を行いたいとき)
</b><b>
flash.now[]:
　render 使用時(データの取得を行いたいとき)
</b>
なぜこのような使い分けをするかというと、次の画面を表示するためのrenderとredirect_toによって処理の仕方が異なり、その処理の違いに関連してflash[]が表示され続けてしまったり、表示されなかったりします。

なぜrenderとredirect_toをそもそもなぜ使い分けるかを、ざっくり書いていきます。

<h2>renderとredirect_to</h2>
<b>render:</b>
・そのままviewを出力するメソッド。再度リクエストを投げない。
・route→controller(render)→view

<b>redirect_to:</b>
・再度リクエストを投げなおし、ルーティングからもう一回処理をし直す。
・route→controller(redirect_to)→route→controller→view

どちらも結果としては画面遷移のためのメソッドですが、redirect_toは再度リクエストを投げる処理をしています。

これは<b>別の画面を呼び出したいときに、再度リクエストを投げてその画面のアクションを呼び出しなおすことで、処理の無駄をなくさせるため</b>です。

renderは別画面を描画するだけで、別画面のアクション内の処理を実行しません。
そのため、renderで別画面の処理を正常に表示させたい場合、別画面のアクションの処理をrender前で処理したうえで、renderを実行する必要があります。

そういった、別の画面を呼び出す際に、わざわざrednderの前にその画面用の処理を書くより、その別画面用のアクションをredirect_toで呼び出してしまえば、処理を2重に書かずに済み、ラクチンです。

しかし、redirect_toでルーティングをしなおした際に、保持していたインスタンス変数がリセットされてしまいます。

そのため、
・フォームで送信失敗時に情報を残しておきたい時はrenderでフォームに値を入れる
・データ更新をして、別画面に遷移させる際はredirect_toを使う
といった使い分けになります。

この<b>redirect_toとrenderによって、再度リクエストされてアクションが呼びだされるか</b>が、ここでは重要です。

<h2>flashとflash.now[]の使い分け</h2>
renderとredirect_toの説明が長くなりましたが、flash[]とflash.now[]に立ち戻ります。

各メソッドのflashメッセージの消失トリガーは、
<b>flash[]
　次次アクション終了時に削除
</b>
<b>flash.now[]
　次アクション終了時に削除
</b>

よって、renderやredirect_toと組み合わせた場合、<a href="https://qiita.com/kashiwamochi_ruby_rails/items/b4a43486aec3790ef0dd">(redirect_toとrender, flashとflash.nowの違い</a>から引用)

>flash[]とredirect_to => 次のページにリダイレクトした時点でflashは消える
>flash[]とrender => renderはリクエストを送信しないため、次のページに移動してもflashは残る
>flash.now[]とredirect_to => redirect_toの時点でflashが消えるため、flash自体表示されない
>flash.now[]とrender => 次のページへリダイレクトした時点でflashは消える

となります。

したがって、遷移した一回のみ表示させたい際の適切な使い分けは、
<b>
flash[]:
　redirect_to 使用時(データの追加、更新、削除を行いたいとき)
</b><b>
flash.now[]:
　render 使用時(データの取得を行いたいとき)
</b>
<br>
nowがついているほうは<b>「今リクエスト」だけ表示する</b>と認識すると覚えやすいですね。

間違っていたらコメントいただけると幸いです。

参考：
<a href="https://railsdoc.com/page/flash">Railsドキュメント 簡単なメッセージを画面に表示</a>
<a href="https://note.com/kentarotawara/n/nd8010d4d0649">renderとredirect_toの違いを整理　【Day 1/30 2nd】</a>
<a href="https://qiita.com/kashiwamochi_ruby_rails/items/b4a43486aec3790ef0dd">redirect_toとrender, flashとflash.nowの違い</a>
<a href="https://railsguides.jp/layouts_and_rendering.html#redirect-to%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B">Railsガイド 2.3 redirect_toを使用する</a>
プログラミングの歴史を知りたかっただけなんだ！


#家系プログラミング
C、C++、Python、Fortran、Go、etc...
プログラミング言語っていっぱいある。けど、プログラミングはあくまで人が作ったもの。
元にする言語があるはずなので、家系ラーメン的な流派があるはず。
そんなものどこを探してもなかったので、独自に作ってみました。
これからプログラミングを学びたいって人はこれを参考にしてみてもいいかも。


#家系プログラミング系譜
カッコ内は出てきた年代。おおよそでしかないので参考まで。

````
FORTRAN(1950)
COBOL(1950)


ALGO(1958)
  ∟ Pascal(1960)
  ∟ Simula(1960)              C(1972)
         ∟   Objective-C(1984)  」∟ Java Script(1995)
         ∟      C++(1960)       」
                    ∟ Java(1995)
                          ∟ Kotlin(1995)
                    ∟ Scala(2000)
                    ∟ C#(2000)



Perl(1980)
  ∟Python(1990)
      ∟Ruby(1993)
      ∟PHP(1995)  //C言語要素も含まれる


めっちゃ色々参考にされた
Swift(2010)
Go(2009)


````

だいたいこんな感じ。実際にその言語を使って書かれたというよりは「その言語の影響を受けた」という表現が正しいと思います。
訂正があればコメントください。ずいずい訂正します。

こう見ると、ALGO派とPerl派に分かれる感じになるんでしょうか。まぁOSによっての違いとかもあるので厳密ではないですが。
特に2000年以降の新しい言語は色々な言語を参考にしている気がする。いい意味で精査されているんだろう。

#【結果】初心者は新しい言語を覚えたほうがよさげ
新しい言語は色々無駄が省かれていて、覚えやすくなってそう。もちろんやりたいことと一致するものを選ぶべきだが、新しい方で
できるのであれば、その方が楽にやりたいことを実現できそう。

そのあとから派生元の勉強をしても遅くないのでは？
プログラミング初心者や未経験の人は、Qiitaに記事を投稿出来るレベルなのかについて

はじめまして、しゅんやと申します。

なんか、緊張しますね、初めての記事は、、、。

ということで、今回はタイトルにもある通り、


<b>「プログラミング初心者や未経験の人はQiitaに記事を投稿出来るレベルなのかについて」</b>


を書いていきたいと思います。

まあそもそも、この記事に需要があるかどうかは全くわからないのですが、少なくとも未経験である僕は普通に知りたいと思ったので、同じように考えてる人がもしかしてどこかにいるのではないかという可能性を信じて、ダメ元で書いてみる事にしました(笑)


ではいきましょう！


<h1>結論</h1>

まず結論から申し上げると、「投稿しても問題ない」です。

例えば、僕みたいな未経験の人が書く記事というのは「基礎的なもの」が多く、ベテランエンジニアやプログラマーの人達が書く記事はレベルが高すぎて、逆に基礎的な部分が抜けていたりするので、そういう面で初心者や未経験者が書く基礎的な内容の記事は投稿しても問題無いし、むしろ需要があったりすることもあるということです。

他にも、短い期間しか勉強していない状態で、どこまでのアウトプットが出来るのかという事が他の人の参考になったりとか、普通に自分用のアウトプットにも使えて後で見返せるメモになったりといったように、さまざまなメリットがあるのは確かなようです。

まあただ、未だ技術が少ない状態で、最初から体裁整えようとして記事ばかり書くと「プログラマー」では無く「ブロガー」になりかねないので、あくまでメモ程度として書くぐらいがちょうど良いという旨の意見をいただいた時は、一番同感しました。(ブロガーの方を悪く言っているわけではありません)

なので、ぼくも本当はこのような記事を書いてる暇があるならコードを書いた方が良いと思うのですが、まあ初投稿ということで、試しに書いてみました（笑）

<h2>最後に</h2>
いかがだったでしょうか。

最後に「いかがだったでしょうか」と言うあたり、なんだかブロガーっぽいですね。(ブロガーの方を悪く言ってるのではありません笑←2回目)

ぼくがなるべきなのは「プログラマー」であって、ブロガーではないので、今回のようなブログっぽい記事はこれ1つだけにして、今後はちゃんと技術面に重点を置いて実践的な記事を書いていきたいと思います。(そのレベルに達すればの話ですが笑)


ということで、最後まで見ていただきありがとうございました！


では！！！
獣医師が必死にバイオインフォマティクスPythonによる実践レシピをwin10で動かす（その1）

## 必要な環境の構築
環境
Win10 pro 64bit
RAM 16 GB
jupyter notebook
python3  

## 仮想環境を作成  
Windows: 「スタート」 > 「すべてのプログラム」 > 「Anaconda3 (64-bit)」 > 「Anaconda Prompt」から実行
`conda create -n bioinformatics biopython biopython=1.70`  

バイオインフォマティクス環境のアクティブ化
`conda activate bioinformatics`  

リポジトリをソースコードに追加

```
conda config --add channels bioconda
conda config --add channels conda-forge
```  

コアになるソフトウェアパッケージを追加  

```
conda install scipy matplotlib jupyter-notebooks pip pandas cython numba scikit-learn seaborn pysam pyvcf simuPOP dendropy rpy2
```

早々にjupyter-notebooks pysamが入らないでこける
→しょうがないので後で別に入れることにする
そもそも名前が違うらしいjupyter-notebooks→jupyter
修正したら動いた

```
conda install scipy matplotlib jupyter pip pandas cython numba scikit-learn seaborn pysam pyvcf simuPOP dendropy rpy2
```

pysamはpipでもこける
pysamのインストールにはLinuxもしくはmacOSが必要みたい、ガーン
PySAMバージョン2.2.0はWindowsの64ビットPythonバージョン3.5以降のPyPiで利用できるらしいので、これを入れてみる  

```
pip install nrel-pysam
```

無事に突破

次はR環境を入れるのだが、本の記述が間違えているので、Dockerを覗きながら力業で解決してみる  

```
conda install r r-ggplot2 r-irkernel r-essentials r-gridextra rstudio
```

後でggplot2のバージョンを直す羽目に

```
conda install r-ggplot2==2.2.1
```

ここでカーネルを切り替えようとしても切り替えられず
切り替えるためのソフトを追加

```
pip install environment_kernels
```

仮想環境の確認

```
conda info -e
```

とりあえず環境は大丈夫そう

~~なのでjupyter notebookの設定ファイルを作る
`jupyter notebook --generate-config`
anaconda3があるところに/.jupyter/jupyter_notebook_config.pyができているので下記を追記
`c.EnvironmentKernelSpecManager.conda_env_dirs = ['/Users/username/anaconda/envs/' ]`~~
上の工程はいらないことが発覚

作成したカーネルを追加する

```
ipython kernel install --user --name=bioinformatics --display-name=bioinformatics
```

追加されたのか確認

```
jupyter kernelspec list
```

これで無事に切り替え完了
この後、**一度Jupyter notebookをログアウトして、今作った環境からJupyter notebookを起動して再度スタート**
↑ここで死ぬほどハマった(;'∀')
WSLでCentOS7をインストールする

# WSLでCentOS7をインストールする

## CentOS7のファイルのダウンロード
CentOS7のファイルを下記のGitHubリポジトリからダウンロードします。
[mishamosher/CentOS-WSL](https://github.com/mishamosher/CentOS-WSL)

この方のリポジトリには、CentOS 7.9-2009、CentOS 7.8-2003 が配布されています。

## 古いCentOS7のファイルが必要な場合

最新ではなく古いCentOS7をインストールしたい場合、アーカイブされた下記のGitHubリポジトリからダウンロードします。

[wsldl-pg/CentWSL](https://github.com/wsldl-pg/CentWSL)

この方のリポジトリには、CentOS 7.6-1901、CentOS 7.6-1905、CentOS 7.6-1907が配布されています。

## 展開と実行
ダウンロードしたファイルは、Zip圧縮されていますので展開してください。
展開したフォルダを、%USERPROFILE%\AppData\Local\Packages にコピーし、実行します。

``` Batchfile::
C:\Users\(ユーザ名)\AppData\Local\Packages\CentOS7>CentOS7.exe
Using: C:\Users\(ユーザ名)\AppData\Local\Packages\CentOS7\rootfs.tar.gz
Installing...
Installation Complete!
Press any key to continue...
```
## 確認
インストールが完了したかどうか確認するため、以下のコマンドを投入します。

``` Batchfile::
C:\Users\(ユーザ名)\AppData\Local\Packages\CentOS7>wsl -l -v
  NAME                   STATE           VERSION
* docker-desktop-data    Stopped         2
  docker-desktop         Stopped         2
  CentOS7                Stopped         2
  Ubuntu-20.04           Stopped         2
```

## 起動
起動するには以下のコマンドを投入します。

``` Batchfile::
C:\Users\(ユーザ名)\AppData\Local\Packages\CentOS7>wsl -d CentOS7
[root@DESKTOP-MT7U9JC CentOS7]#
```

## インストール後の設定

### ルートパスワードの設定

インストール直後はrootのパスワードが設定されていません。
以下のようにコマンドを投入してパスワードを設定します。

``` Shell::
[root@DESKTOP-MT7U9JC CentOS7]# passwd root
Changing password for user root.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
[root@DESKTOP-MT7U9JC CentOS7]#
```

### 一般ユーザーの生成
一般的に使用するユーザーを生成します。

#### ユーザーの作成、パスワード設定

``` Shell::
# useradd sampleuser
# passwd sampleuser
```

#### ユーザーを wheelグループに追加

``` Shell::
# usermod -aG wheel sampleuser
```

### wslでログインするデフォルトのユーザーを変更する。

``` Batchfile::
.\CentOS7.exe config --default-user  ユーザー名
```

上記のコマンドは、シェルではなくコマンドプロンプトで実行します。
CentOS7.exe の実行は、コマンドプロンプトから cd で移動してから実行します。

以降は、通常のCentOS7の操作と同じになります。

### アンインストール
アンインストールするには、他のディストリビューションと同様に cleanコマンドを投入します。

``` Batchfile::
.\CentOS7.exe clean
```
RDKitやPsi4をインストールするDockerfileを作った

勉強会向けに環境構築しようと思ったら、WindowではいくつかRDKitの機能が使えなかった。
それなら「DockerならLinuxっぽいしいけるやろ」と思って色々突っ込んでみました(重い……)

こちらを参考にして、必要なもの、いらないものを調整しました。
https://punhundon-lifeshift.com/dockerfile

```
FROM ubuntu:latest
#https://punhundon-lifeshift.com/dockerfile

# proxy
#ENV http_proxy http://doraemon:1a2b3c@111.111.111.111:8080
#ENV https_proxy https://doraemon:1a2b3c@111.111.111.111:8080

# install linux commands
RUN apt-get -y update && apt-get install -y \
sudo \
wget \
vim \
curl \
unzip

# add Japanese packages to ubuntu
RUN apt-get install -y language-pack-ja-base language-pack-ja \
fontconfig fonts-takao && locale-gen ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:ja
ENV LC_ALL ja_JP.UTF-8

# install miniconda3-py3.6
WORKDIR /opt
RUN wget https://repo.anaconda.com/miniconda/Miniconda3-4.5.4-Linux-x86_64.sh && \
sh /opt/Miniconda3-4.5.4-Linux-x86_64.sh -b -p /opt/miniconda3 && \
rm -f Miniconda3-4.5.4-Linux-x86_64.sh

# set path
ENV PATH /opt/miniconda3/bin:$PATH

# install libraries
RUN pip install --upgrade pip && \
conda update -n base conda && \
apt-get -y install openbabel && \
conda install psi4 psi4-rt python=3.7 -c psi4 && \
conda install -c conda-forge rdkit && \
pip install openfermion && \
pip install py3Dmol && \
pip install pubchempy && \
conda install -c conda-forge nodejs jupyterlab

# make 'work' directory
WORKDIR /
RUN mkdir /work

CMD ["bash","-c","jupyter notebook --notebook-dir=/data --ip=0.0.0.0 --port=8889 --no-browser --allow-root"]
```

ビルド
`docker build -t test-phi4 .\phi4-docker`

Dockerの実行
`docker run -v ${pwd}/Anaconda:/data --rm -p 8888:8888 -p 8889:8889 --name test-phi4 -it test-phi4`
コンフリクトしてるファイルをAndroid Studioで一気に開く方法

*ちょっとしたチップスみたいなものです*

### Android Studioでファイルを開くコマンドを生成する
1. Tools->Create Command-Line Launcher...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476234/cf12a48a-c02b-4cbb-2644-15b33b3c67af.png)

2. 適当な場所に保存
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476234/4953ff06-ac07-8a78-8313-ce25b7a709cf.png)

3. studioでファイルを展開できるようになる

### コンフリクトしてるファイルの一覧を取得してstudioの引数に渡す
このコマンドを叩けばOK

```
git ls-files -u | cut -f 2 | sort -u | xargs studio
```

### あとは、、、
お好みに合わせてaliasつけたりすれば完璧
オートエンコーダーのSSIMの実装方法解説

#はじめに
オートエンコーダーのSSIMの実装方法を整理します。

#SSIMとは
SSIM（Structural Similarity Index Measure)とは、2004年に発表された画像の類似度を測定する指標です。
オートエンコーダーの課題の中で、オリジナル画像から作られる**生成画像が鮮明ではない**特徴があります。英語ではBlurred Generated Imageといいます。この場合、**小さい異常の検知が難しい**問題があります。
既存のオートエンコーダーには**mse(mean squared error)**を損失関数として使い、どうしても鮮明ではない画像しか作られませんでした。ところで、SSIMを損失関数として使ったら、**より鮮明な生成画像が得られ、**結果的に異常検知のOK/NGの判別性能が向上する結果となりました。めでたしめでたし。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/05eb66d0-aa5a-3dbc-a372-95d69b933e1d.png)


#2.実装の手順
学習フェーズと推論フェーズに分けて説明します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/a8fa9390-7ba1-8f82-11c7-4099e4553520.png)
##2.1.学習フェーズ
### SSIMのカスタマイズ損失関数の定義
Tensorflowの```tf.image.ssim```関数を利用し、```ssim_loss()```のカスタム損失関数を定義します。
パラメータ設定には、```float32```と```uint8```によって異なりますので、それに関してはTensorflowのドキュメントを参照してください。

```Python
import tensorflow as tf

def ssim_loss(y_true, y_pred):
    return 1-tf.reduce_mean(tf.image.ssim(y_true, y_pred, 
                                          max_val = 1.0,filter_size=11,
                                        filter_sigma=1.5, k1=0.01, k2=0.03 ))
```
###Compileにlossとして指定

autoencoderというmodelを用意します。
```mse```と使うcompile文と、```ssim_loss```を使うcompile文を併記しますので、参考にしてください。
SSIMは、このコードを使えば、問題なく学習ができます。

```Python
#損失関数　mse
autoencoder.compile(optimizer = 'adam', loss = 'mse')

#損失関数　SSIM
autoencoder.compile(optimizer = 'adam', loss = ssim_loss)
```
##2.2.推論フェーズ
学習したモデル（h5ファイル）を読み込む時、「このモデルはSSIMというカスタム損失関数を使ってるよ」とプログラムに教える必要があります。
例えば、```autoencoder-ssim.h5```とうモデルを読み込む場合は、下記のようにコードを書きます。
###load_modelの追記
```Python
from tensorflow.keras.models import load_model

loaded_model = load_model('autoencoder-ssim.h5', custom_objects={'ssim_loss':ssim_loss}

```
```custom_objects ```部分を見てみましょう。

```Python
custom_objects={'ssim_loss':ssim_loss}

```
最初の'ssim_loss'は、```autoencoder.compile(optimizer = 'adam', loss = ssim_loss)のloss='ssim_loss'```のことです。
2番目のssim_lossは```カスタム損失関数名```になります。


###SSIM関数の記述
上記の理由で、推論のコードにも```カスタム損失関数```を記述します。学習用のコードに書いた同じカスタム損失関数を書けばOKです。

```Python
def ssim_loss(y_true, y_pred):
    return 1-tf.reduce_mean(tf.image.ssim(y_true, y_pred, 
                                          max_val = 1.0,filter_size=11,
                                        filter_sigma=1.5, k1=0.01, k2=0.03 ))
```
これで問題なく、SSIMの学習モデルを読み込み、新しいデータでの推論が可能です。

#まとめ

SSIMのカスタム関数を用いた、オートエンコーダーの学習・推論のコードの実装方法について解説しました。

#参考資料
１．Improving Unsupervised Defect Segmentation by Applying Structural Similarity to Autoencoders
https://arxiv.org/abs/1807.02011

２．【論文読み】新・オートエンコーダで異常検知
https://qiita.com/shinmura0/items/ee074172ec3c818b614e
amplifyの作法 その18

#概要

amplifyの作法、調べてみた。
練習問題やってみた。

#練習問題

aさんとbさんは、気が合うので、同じ事をすると、気分が良い。
bさんとcさんは、軋轢があり、違うことがしたい。
みんなが、気持ち良くなる組み合わせを求めよ。

#評価関数を組み立てる。

求める組み合わせを考える。

|aさん|	bさん|	cさん|	評価|
|:--|:--|:--|:--|
|歩く|	歩く|	歩く|	NG|
|歩く|	走る|	歩く|	NG|
|走る|	歩く|	歩く|	NG|
|走る|	走る|	歩く|	ok|
|歩く|	歩く|	走る|	ok|
|歩く|	走る|	走る|	NG|
|走る|	歩く|	走る|	NG|
|走る|	走る|	走る|	NG|

評価関数

H = (a - b)**2 + (b + c - 1)**2

a,b,cは、[1,0]をとる。
a=1,b=1,c=0の場合は、0
a=1,b=1,c=1の場合は、1

#式を展開して、イジングモデルをつくる。

sympyを使う。

```
from sympy import *

a, b, c = symbols("a,b,c")
f = (a - b)**2 + (b + c - 1)**2
print(f)
f4 = str(expand(f))
print(f4)
f5 = f4.replace('**2', '')
print(f5)
f6 = str(simplify(f5))
print(f6)
f7 = f6.replace('a', 'q[0]').replace('b', 'q[1]').replace('c', 'q[2]')
print(f7)
```


求めた、イジングモデル。

f = -2*q[0]*q[1] + q[0] + 2*q[1]*q[2] - q[2] + 1

#amplifyに投入。

```
from amplify import (BinaryPoly, BinaryQuadraticModel, gen_symbols, Solver, decode_solution, )

q = gen_symbols(BinaryPoly, 3)
f = -2*q[0]*q[1] + q[0] + 2*q[1]*q[2] - q[2] + 1
print(f.asdict())
model = BinaryQuadraticModel(f)
solver = Solver(client)
result = solver.solve(model)
values = result[0].values
print(values)
print(f"q = {decode_solution(q, values)}") 

```


以上。
音量調整をキーボードだけでしたい！(Windows)

##1. はじめに　(結論だけ知りたい方は2へ)
　YouTubeでまこなり社長の[知らないとヤバい！生産性の高いパソコンの使い方 13選](https://youtu.be/3B1LCJACKro)という動画を視聴しました。その動画の「生産性の高いPCの使い方　その６」でカーソル移動はCtrlを使うという話をされていました。MacだとCtrl + p, n, b, fでそれぞれ上下左右に移動できるそうです。しかし自分はwindowsユーザーなのでこれが使えません。windowsではカーソル移動のショートカットキーはないそうです。自分もmacと同じようにカーソル移動をキーボードだけで操作したいと思い、色々調べていたら既にQiitaで記事になっていました(さすがQiita!)。詳しいことは以下の記事を参照してください。

>[[Windows 10] 矢印キーに指を伸ばすエンジニアはザコ！とバカにされた（Change KeyとAutoHotkeyの導入）](https://qiita.com/riekure/items/49b941fa5159f9948313#:~:text=F13%E3%82%AD%E3%83%BC%20%2B%20HJKL%E3%82%AD%E3%83%BC%E3%81%AE%E7%B5%84%E3%81%BF%E5%90%88%E3%82%8F%E3%81%9B%E3%81%A7%E7%9F%A2%E5%8D%B0%E3%82%AD%E3%83%BC%E3%82%92%E5%AE%9F%E7%8F%BE,-AutoHotKey%E3%82%92%E3%83%80%E3%82%A6%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%89)

　この記事を読んでカーソル移動をキーボードだけで操作できるようになって感動した自分は音量調整もキーボードだけで操作したくなりました。今回はキーボードにショートカットキーを割り当てて音量調整をキーボードだけで操作する方法を解説します。

##2. キーボードだけで音量調整をする方法(概説)
　パソコンによっては音量調整のショートカットキーがすでに割り当てられている方もいます。今回はショートカットキーが割り当てられていないキーボードを持っているひと向けの記事です。
1. 「Change key」を用いてCaps LockキーをF13に指定する。
2. ahkファイルにショートカットキーとその動作を記述する。
3. 起動時に自動実行するようにする。

このうち1と3に関しては先ほど紹介したりえくれさんの[[Windows 10] 矢印キーに指を伸ばすエンジニアはザコ！とバカにされた（Change KeyとAutoHotkeyの導入）](https://qiita.com/riekure/items/49b941fa5159f9948313#:~:text=F13%E3%82%AD%E3%83%BC%20%2B%20HJKL%E3%82%AD%E3%83%BC%E3%81%AE%E7%B5%84%E3%81%BF%E5%90%88%E3%82%8F%E3%81%9B%E3%81%A7%E7%9F%A2%E5%8D%B0%E3%82%AD%E3%83%BC%E3%82%92%E5%AE%9F%E7%8F%BE,-AutoHotKey%E3%82%92%E3%83%80%E3%82%A6%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%89)がとても分かりやすく書かれているのでこちらを参照してください。


##3.  ahkファイルにショートカットキーとその動作を記述する
　[ahkファイルを作成](https://qiita.com/riekure/items/49b941fa5159f9948313#ahk%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E4%BD%9C%E6%88%90)に記載されているahkファイルの中身を次のようにしてください。

```
F13 & u::Send,{Volume_Up 2}		;Caps Lock(F13) + uを1回押すごとに音量が2あがる
F13 & d::Send,{Volume_Down 2}		;Caps Lock(F13) + dを1回押すごとに音量が2あがる
F13 & m::Send,{Volume_Mute}		;Caps Lock(F13) + mでミュートのON/OFF切り替え
```

##4. まとめ
　以上のようにショートカットキーを割り当てるとキーボードだけで音量調整ができるようになりました。音量調整のショートカットキーを割り当てたことで自分はとても楽になりました。特にZoomを使う時に役に立っています。Zoomだと音量が大きい人と小さい人が混じっているからです。今まではマウスを使って音量調整をしていたのですが、キーボードだけで音量調整ができるようになりホームポジションを崩さずに操作できるようになりました。もしこの記事を読んで悩みが解決されたら幸いです。(もちろん既に音量調整のキーが割り当てられているパソコン、キーボードを買うというのも１つの手です。)
Google OAuth同意画面のユーザーサポートメールの変更方法

## 実現したいこと
Google OAuth同意画面のユーザーサポートメールを自分自身のメールアドレスから別のメールアドレスに変更したい。

## 手順
1. [Google Developers Console](https://console.developers.google.com/project)のプロジェクトの[IAM](https://console.cloud.google.com/iam-admin/iam)にアクセス。上部の追加ボタンをクリック、新しいメンバーにメールアドレスを入力、ロールをオーナーに選択し保存。
2. 1.で追加されたメールアドレスのアカウントから[Google Developers Console](https://console.developers.google.com/project)にアクセスし、利用規約に同意。
3. 1.で追加されたメールアドレスのアカウントから[OAuth同意画面](https://console.cloud.google.com/apis/credentials/consent/edit)にアクセスし、ユーザーサポートメールのプルダウンに新たに加わったメールアドレスを選択し保存。

![スクリーンショット 2021-03-04 9.47.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264073/1244a9dc-c03d-d054-ee81-6f5f8df8898a.png)

![スクリーンショット 2021-03-04 9.52.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264073/55bd0d9f-b276-d37f-8f33-26009abcf65c.png)

## 参考

https://stackoverflow.com/questions/23105894/how-to-change-google-consent-screen-email
amplifyの作法 その17

#概要

amplifyの作法、調べてみた。
練習問題やってみた。

#練習問題

看護師、aさん、bさん、cさん、から２人を選べ。

#評価関数を組み立てる。

求める組み合わせを考える。

|aさん |bさん |cさん |評価 |
|:--|:--|:--|:--|
|出ない |出ない |出ない |NG |
|出ない |出る |出ない |NG |
|出る |出ない |出ない |NG |
|出る |出る |出ない |ok |
|出ない |出ない |出る |NG |
|出ない |出る |出る |ok |
|出る |出ない |出る |ok |
|出る |出る |出る |NG |

評価関数

H = (a + b + c - 2) ** 2

a,b,cは、[1,0]をとる。
a=1,b=1,c=0の場合は、0
a=1,b=1,c=1の場合は、1

#式を展開して、イジングモデルをつくる。

sympyを使う。

```
from sympy import *

a, b, c = symbols("a,b,c")
f = (a + b + c - 2) ** 2
print(f)
f4 = str(expand(f))
print(f4)
f5 = f4.replace('**2', '')
print(f5)
f6 = str(simplify(f5))
print(f6)
f7 = f6.replace('a', 'q[0]').replace('b', 'q[1]').replace('c', 'q[2]')
print(f7)

```

求めた、イジングモデル。

2*q[0]*q[1] + 2*q[0]*q[2] - 3*q[0] + 2*q[1]*q[2] - 3*q[1] - 3*q[2] + 4

#amplifyに投入。

```
from amplify import (BinaryPoly, BinaryQuadraticModel, gen_symbols, Solver, decode_solution, )

q = gen_symbols(BinaryPoly, 3)
f = 2*q[0]*q[1] + 2*q[0]*q[2] - 3*q[0] + 2*q[1]*q[2] - 3*q[1] - 3*q[2] + 4
print(f.asdict())
model = BinaryQuadraticModel(f)
solver = Solver(client)
result = solver.solve(model)
values = result[0].values
print(values)
print(f"q = {decode_solution(q, values)}") 


```

以上。
go mod の使い方

こちらの記事と同様のことを行ってみました。
[GOPATH モードからモジュール対応モードへ移行せよ](https://qiita.com/spiegel-im-spiegel/items/5cb1587cb55d6f6a34d7)
>go mod tidy を実行するのが異なります。

使用したバージョン

```text
$ go version
go version go1.18.1 linux/amd64
```

テスト用のプログラム

```go:hello.go
package main

import (
    "fmt"

    "rsc.io/quote"
)

func main() {
    fmt.Println(quote.Hello())
}
```

この時点で実行すると次のようになります。

```text
$ go run hello.go 
hello.go:6:5: no required module provides package rsc.io/quote: working directory is not part of a module
```

hello モジュールの作成

```bash
go mod init hello
go mod tidy
```

実行時の様子

```text
$ go mod init hello
go: creating new go.mod: module hello
go: to add module requirements and sums:
	go mod tidy
$ go mod tidy
go: finding module for package rsc.io/quote
go: found rsc.io/quote in rsc.io/quote v1.5.2
```

次のファイルが作成されます。

```text
go.mod
go.sum
```

フォルダーの構造

```text
$ tree
.
├── go.mod
├── go.sum
└── hello.go
```

プログラムの実行

```text
$ go run hello.go 
こんにちは世界。
```

次のバージョンで確認しました。

```text
$ go version
go version go1.19.2 linux/amd64
```