OmniAICreator/Qiita-1.07M huggingface dataset:
Flexboxを理解するためにコロンビア国旗を作ってみた

Flexboxを使ってコロンビア国旗を作る

![finish1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1311071/9693335f-fbc3-34eb-42bd-6e22b414f7e0.png)


目標：Flexboxの基礎を理解するため
テキストエディターはVSCode.
↓下記のFlexboxチートシートを参考
[Css Flexboxのチートシート] (https://www.webcreatorbox.com/tech/css-flexbox-cheat-sheet)

～codeを書き始める前の準備～
・構成を考える！　何をどんな風に、どうやって作るのか？
　最初にある程度決めておくと後が楽になります。
　例　コロンビアの国旗を調べる
　　　```<div>```は何個必要なのか？
　　　```class```属性名はどうしようか？
　　　

・紙とペンで実際に枠を書いてみる（添付画像参照）
ここまで出来たらcodeを書いていきます♪ ※head部分は省略

HTML

```html
<div class="colombia">
      <div class="col">
          <div class="col2">しかく１</div>
          <div class="col3">しかく２</div> 
          <div class="col4">しかく３</div>
      </div>
    </div>
```


```CSS
.colombia {
  width: 700px;
  height: 500px;
  border: 1px solid black;
  margin: 0 auto;
}

.col {
  width: 450px;　★
  height: 300px;　★
  border: 1px solid black;
}　※旗の枠部分

.col2 {
  background-color: yellow;
}

.col3 {
  background-color: blue;
}

.col4 {
  background-color: red;
}

```
上記の状態をブラウザで一旦確認

![1first.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1311071/adb42ca8-31e9-7a02-2cf2-ceea9b7fad3d.jpeg)

上記のCSSにFlexboxをつける。

```CSS
.colombia {
  width: 700px;
  height: 500px;
  border: 1px solid black;
  margin: 0 auto;

  display: flex; ※ .col｛｝を中央に寄せるためにFlexboxを指定
  justify-content: center;　※
  align-items: center;　※
}

.col {
  width: 450px;
  height: 300px;
  border: 1px solid black;
　
　display: flex;　※
  flex-direction: column;　※
}
```
上記の状態をブラウザで確認 ↓
```.colombia{}```に付けたFlexboxの影響で```.col{}```が中央揃えになりました。

```.col{}```に付けたFlexboxは前回と変化ありません。理由としては、```flex-direxction:``` が```column```となっているためです。

![second .png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1311071/d8f8bf04-8391-baee-14e0-07e72034aac7.png)


『子要素に』```flex-grow```を付けます。

```CSS
.col2 {
  background-color: yellow;
  flex-grow: 3; ※
}
.col3 {
  background-color: blue;
  flex-grow: 1.5;　※
}
.col4 {
  background-color: red;
  flex-grow: 1.5;　※
}
```
最後に、```<div>しかく１,しかく２,しかく３</div>```の文字を消して
完成です！！！


![finish1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1311071/9fff3fbe-6b16-303c-82c0-b693f0893702.png)


まとめ
Flexboxの理解を深めるため、今回は```padding , margin```を使用せず作成しました。
また、```Flexbox```は```margin```と一緒に使用しないよう意識することが大切です。
```flex-grow```の比率と色を変更すると、ロシア、オーストリア、オランダ、ドイツなどの国旗も出来ます。
是非、皆様も作ってみてください

今回は以上です。
ありがとうございます！
Salesforceへのデータ書き込み時にエラーとなったジョブの原因を調査する

XpelntyのSalesforce連携にはBulk APIが使用されています。Salesforceにデータをロードする際にBulk APIがエラーとなることがあります。今回はそうした場合にエラー原因を調査する方法について解説します。

#1. Salesforce側でBulk APIの結果を見るには？
1. Quick検索で「一括データ読み込みジョブ」と入力する。
2. 検索された結果から「**一括データ読み込みジョブ**」をクリックする。
3. エラーの詳細を知りたい場合、表示されたジョブのリストから状況が「中止」となっているレコードのジョブIDを選択します。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/2da719c2-3f21-5062-710a-381368332a48.png)


#2. エラーの内容の詳細確認
ジョブIDの詳細から「**結果を表示**」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/dc7d23b9-9224-5634-24b5-a91f781527f1.png)


JSON形式でBulk APIのジョブのエラーの詳細が表示されるので、なぜエラーが起こっているかを確認することが可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/1a5305c5-cae7-a629-522e-72ffbdbcdcb2.png)

また、どういうデータがリクエストされたのかは、手順２の画面で「**要求を表示**」をクリックすることで、リクエスト内容を確認することができます。
【初学者向け】SQLってなに？~「【オンラインハンズオン】はじめてのSQL」に向けて~

4月10日（土）、[どいこさん](https://qiita.com/doiko)が主催で行った[株式会社X-HACK](https://x-hack.jp/)さんの勉強会「【オンラインハンズオン】はじめてのSQL」に参加しました。

<br>
ある程度の前提知識が必要な上での参加だったので、その前提知識+αでまとめてみました。
<br>
実はこの勉強会に参加する前、ひたすら「SQLとは」で検索してみました！
<br>
Wikipedia見てぞっとしたり（笑）、正直まだまだわからないものばかりでしたが、ざっと100記事くらいは触れたと思います。
<br>
<br>
それからわかったのは、概要や種類について書かれた記事は多くあったものの、**具体的な活用場面まで書いてある記事は少なかった**ということです！
<br>
勉強を始めて５ヶ月目なのですが、
こういった普段の生活であまり意識してこなかったような新しいこと、
特に抽象的なことを学ぶときは、体感として
何ができるのか、どんないいことがあるのかなど、
具体的なところまで知ったほうが理解が早いです。
<br>
（この世界は習うより慣れろな部分が強いと思っているので、ちょっとこの性格は大変かも！笑）
<br>
そんなわたしのような初学者の方向けにSQLとはどういったもので、具体的に何ができるのかというのを簡単に記していきます。
<br>
# 1.SQLとは
読み方は「シークェルorシーケル」
データベース言語（Notプログラミング言語）

**データベース**とは、データを保存して、管理するもの
データを取り出すときに使用
代表的なものとしてPostgreSQL,MySQL（構造の違いがある）

![スクリーンショット 2021-04-14 20.10.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1313937/51e170e2-40e6-e91a-a062-73e93d9472a5.png)

【データベースを扱う際に使われる用語】
・**テーブル**・・・データを保存しておくための表
・**カラム**・・・テーブルの列
・**レコード（orロー）**・・・テーブルの行
・**フィールド**・・・テーブルの入力項目
※構造はエクセルに似ている

#２．SQLでできること
・データの保管、更新、取得、削除
・テーブルの作成、更新、削除
・データベース操作（アプリ開発時）
・データを分析してさまざまなビジネス活動の改善
→ **これらほとんどデータ保管そのもの、保管しておかないとできないことだらけ**


#3．具体的な活用例
**Twitter,InstagramといったSNS関係**
・□年×月▲日の投稿を検索／削除するとき　など

**WordPress**
・途中まで書いたブログを更新するとき
・おすすめの記事一覧を実装したいとき　など

**ゲーム**
・1日にログインしているユーザーの数を知りたいとき（ユーザー数億単位のものもある！）
・特定のユーザーの情報を調べたいとき　など

<br>
<br>
エクセルだと扱える量に限界が、、、(データ重すぎて処理できなくなる)
そのためSQLは膨大な量のデータを扱うときに必須！

<br>
<br>
次回、勉強会の内容をあげます！
ここまで読んでいただきありがとうございました！
（有識者の方、つよつよエンジニアの皆様のご意見ご指摘などお待ちしております！！！）
<br>
【参考】
▽[SQL入門勉強会「はじめてのSQL」 第1回資料]
(https://qiita.com/doiko/items/0b4c5353dccd8497b0a8)
▽[「キタミ式イラストIT塾 基本情報技術者 令和03年」]
(https://www.amazon.co.jp/%E3%82%AD%E3%82%BF%E3%83%9F%E5%BC%8F%E3%82%A4%E3%83%A9%E3%82%B9%E3%83%88IT%E5%A1%BE-%E5%9F%BA%E6%9C%AC%E6%83%85%E5%A0%B1%E6%8A%80%E8%A1%93%E8%80%85-%E4%BB%A4%E5%92%8C03%E5%B9%B4-%E3%81%8D%E3%81%9F%E3%81%BF%E3%82%8A%E3%82%85%E3%81%86%E3%81%98/dp/4297117819/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=1E76JXDW5WLZJ&dchild=1&keywords=%E3%82%AD%E3%82%BF%E3%83%9F%E5%BC%8F%E3%82%A4%E3%83%A9%E3%82%B9%E3%83%88it%E5%A1%BE+%E5%9F%BA%E6%9C%AC%E6%83%85%E5%A0%B1%E6%8A%80%E8%A1%93%E8%80%85+%E4%BB%A4%E5%92%8C02%E5%B9%B4+%E6%83%85%E5%A0%B1%E5%87%A6%E7%90%86%E6%8A%80%E8%A1%93%E8%80%85%E8%A9%A6%E9%A8%93&qid=1618357637&sprefix=%E3%81%8D%E3%81%9F%E3%81%BF%2Caps%2C303&sr=8-1)
▽[【データベース用語まとめ】テーブル、カラム、フィールド、レコードとは？]
(https://26gram.com/database-terms)
herokuエラー　H12：Request timeout

## 開発途中でHerokuでデプロイしたwebアプリを確認中に出てきたエラーに関してです。

画像つきで投稿機能があるアプリで、画像一覧が表記されずにこのエラーが発生しました。WiFiの調子が悪かったりなどもあり、はっきりとした原因はわかりませんでしたが、解決しました。

## 結果

### AWSのS3を利用して画像を管理することで解決しました。
画像1つは1MB程度ですが、一覧で十数枚が一度に出てくる画面だったので、WiFiの環境も影響してリクエストタイムアウトが出たものと思います。
S3の設定方法に関しては公式ページ（下記参照）をご確認ください。※後日まとめてアップ予定です


## 何が起きたのか

デプロイ済の対象ページへ遷移しようとした際になかなか繋がらず、

**Application error**
An error occurred in the application and your page could not be served. If you are the application owner, check your logs for details. You can do this from the Heroku CLI with the command


と表記が出てきました。
確かに長いこと読み込んでいたので、おかしいとは思いましたが、、

ここで指示にある[check your logs for details]通りに、herokuのエラーログを確認しました。

エラーログの確認はアプリのターミナルで

```
heroku logs --tail 
```

を実行し確認したところ、長いエラー文の中より

```
heroku[router]: at=error code=H12 desc="Request timeout" 
```

という文を見つけました。

パっと見た感じでも、どうやら時間がオーバーの様子。
**Herokuのエラーコード**（下記参照）にて確認してみると
３０秒を超えると強制終了されるそう。

>Heroku によって処理される Web リクエストは、いくつかの Heroku ルーター を経由して dyno に転送されます。これらのリクエストは、アプリケーションですぐに処理されることになっています。ベストプラクティスは、Web アプリケーションの応答時間を 500 ミリ秒未満にすることで、これによりアプリケーションが解放されてさらに多くのリクエストを受けられるようになり、訪問者に対して高品質のユーザーエクスペリエンスを提供できます。たまに Web リクエストが異常停止したり、アプリケーションによる処理に非常に時間がかかったりすることがあります。このような場合、完了までにかかる時間が 30 秒を超えると、ルーターはリクエストを強制終了します。


また、サイズの大きいファイルはアップロードが原因である可能性が書かれていましたので、下記の通りS3を利用しました。


>多くの Web アプリケーションではユーザーがファイルをアップロードできます。これらのファイルのサイズが大きかったり、ユーザーのインターネット接続が遅い場合、アップロードにかかる時間が 30 秒を超えることがあります。リクエストをブロックする一部の種類の Web アプリケーションでは、これにより H12 リクエストタイムアウトが発生することがあります。これについては、 S3 に直接アップロードする ことをお勧めします。


サイズの大きいファイルとは4MBを超える可能性のあるアップロードだそうです。今回はそこまで大きくないはずですが、トータルの大きさでしょうか（知識不足すみません。。）


>直接アップロードでは、ファイルは最初にアプリを経由せずに、ユーザーのブラウザーからS3バケットにアップロードされます。この方法は、サイズが4MBを超える可能性のあるユーザーのアップロードに推奨されます。


上記により問題なく表示はされるようになりました。
が、時々遅いことがあるので少し不安はありますが。。
何かわかれば追記させていただきます。



## 参照リンク


AWS公式リンク
https://aws.amazon.com/jp/

エラーコード一覧
https://devcenter.heroku.com/ja/articles/error-codes

リクエストタイムアウト詳細
https://devcenter.heroku.com/ja/articles/request-timeout

AWSS3を使用して静的アセットとファイルアップロードを保存する
https://devcenter.heroku.com/articles/s3#direct-upload
滋賀県の新型コロナウイルス感染症患者の発生状況をCSVに変換

最新の情報を抽出できるように更新日を追加

```
apt install python3-tk ghostscript
pip install camelot-py[cv]
```

```python
import requests
from bs4 import BeautifulSoup

import pathlib
import re

from urllib.parse import urljoin

import pandas as pd

import camelot

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"
}


def fetch_soup(url, parser="html.parser"):

    r = requests.get(url, headers=headers)
    r.raise_for_status()

    soup = BeautifulSoup(r.content, parser)

    return soup


def fetch_file(url, dir="."):

    p = pathlib.Path(dir, pathlib.PurePath(url).name)
    p.parent.mkdir(parents=True, exist_ok=True)

    if not p.exists():

        r = requests.get(url)
        r.raise_for_status()

        with p.open(mode="wb") as fw:
            fw.write(r.content)

    return p


def fetch_pdf(url):

    soup = fetch_soup(url)

    tag = soup.find("span", text=re.compile("^患者の発生について")).find_parent("a")

    link = urljoin(url, tag.get("href"))

    p = fetch_file(link)

    dfs = []

    tables = camelot.read_pdf(
        str(p), pages="all", split_text=True, strip_text="\n", line_scale=40
    )

    for table in tables:

        if table.data[0][0] == "例目":

            df_tmp = pd.DataFrame(table.data[1:], columns=table.data[0])

            row, col = df_tmp.shape

            if 10 < col < 13:
                dfs.append(df_tmp)

    df = pd.concat(dfs)

    df["更新日"] = update

    return df


url = "https://www.pref.shiga.lg.jp/ippan/kenkouiryouhukushi/yakuzi/310735.html"

soup = fetch_soup(url)

dfs = []

for i in soup.find_all("a", text="患者の発生について"):

    update = (
        i.find_parent("span")
        .find_previous_sibling("span", class_="first")
        .get_text(strip=True)
    )

    print(update)

    link = urljoin(url, i.get("href"))

    d = fetch_pdf(link)

    dfs.append(d)

df = pd.concat(dfs)

df.info()

df

df.to_csv("data.csv", encoding="utf_8_sig")
```
合計金額を割引/小数点四捨五入round

# 合計金額を割引
下記の例は、1個325円のりんごを何個購入するかを入力することで、合計金額が表示されるようにします。
また、3個以上購入すると1割引されるようにしました。

```py:script.py
from utils import FruitMenu

fruit_menu1 = FruitMenu('りんご', 325) 

print(fruit_menu1.fruit_info())

count = int(input('購入するりんごの個数を入力してください(3個で1割引):'))

result = fruit_menu1.get_total_price(count)

print('合計金額は'+ str(result) +'円です')
```
```py:utils.py
class FruitMenu:

    def __init__(self, name, price):
        self.name = name
        self.price = price

    def fruit_info(self):
        return self.name + ':' + str(self.price) + '円です'

    def get_total_price(self, count):
        total_price = self.price * count
      
        if count >= 3:
            total_price *= 0.9
        
        return round(total_price)   # 四捨五入するためにroundを用います
```
```text:出力結果
りんご:300円です
購入するりんごの個数を入力してください(3個で1割引):2    と入力した場合、
合計金額は650円です

りんご:300円です
購入するりんごの個数を入力してください(3個で1割引):3    と入力した場合、
合計金額は878円です
```
上記では、関数`get_total_price()`を呼び出し、りんごの購入する個数に対する金額を戻り値として返すように処理になっています。
まず、1個325円のりんごを購入する個数でかけて、変数`total_price`に入れます。
そして、3個以上だと1割引なので、`if`文を用いて条件式`count >= 3`とし処理を`total_price *= 0.9`と記述することで、購入する個数が3個以上であれば合計金額から1割引である0.9をかけ、再び変数`total_price`に入れます。2個以下の場合は処理させる必要が無いので、elseを用いて処理を記述する必要はありません。
そして呼び出し元に返す時、料金では小数点は必要ないので整数で出力するために**`round`**を用います。
これにより、整数で求めていた合計金額を出力することができます。
### round
roundを用いることで、小数を四捨五入した結果の整数を取得することができます。

```py:例
number = 7 * 0.6
print(round(number))
```
```text:出力結果
4
```
Windows版MAMPでPerlをとりあえず動かしてみる

# 目的  

ローカルでPerl/CGIを動かしたい。
XAMPPもあるけど、MacOSで慣れ親しできたMAMPをWindowsでも使いたい。

そんな自分への忘備録。

# 事前準備

- MAMPのインストール・httpd-vhosts.confの設定など
- hostsファイルの設定
- .cgiの有効化

上記は
https://pc-karuma.net/mamp-settings-mac/
https://qiita.com/tsukishimaao/items/cab4caa065d901608856
https://www.be-webdesigner.com/technotes/server/httpd_conf/cgi.htm (CGIの実行許可を与える、まで設定)
この辺見てペペッと設定しちゃってください。

  
  
  
ちなみに、

```httpd-vhosts.conf
<VirtualHost XX.XXX.XXX.XXX:80>
    DocumentRoot "C:\任意のサイトまでのディレクトリパス"
    ServerName test-tarochan.local # てきとう
    ErrorLog "C:\任意のディレクトリパス\log\error.log"
    <Directory "C:\任意のサイトまでのディレクトリパス">
        Options Indexes FollowSymLinks ExecCGI
    </Directory>
</VirtualHost>
```

IP(XX.XXX.XXX.XXX)は自分のローカルを指しておくと
同じネットワークに入っているひとに見せたり、スマホで確認できたりします。
細かいところは割愛します。

# トラブル
そのまま、下記ファイルを作ってtest-tarochan.local/test.cgiにアクセスすると
500 internal server errorになります。`#!/usr/local/bin/perl`パスがあっていないっぽい。（コピペだし）

```test.cgi
#!/usr/local/bin/perl

print "Content-type:text/plain\n\n";
print "Hello World";
```


MacOSの場合は`usr/bin/perl`にしてくださいね～と
リソース豊富ですが、Windows*MAMP*Perlはなかなか見つからない。
MAMPの中で`perl`を検索すると実体は置いてあるっぽい...

やっと惜しいラインみつけたと思ったのが
https://documentation.mamp.info/en/MAMP-PRO-Windows/Languages/Perl/
MAMP Proの説明下部分。このパスに変えてみる。動かない。


# 解決
結局のところ下記のパスでいけました。

```test.cgi
#!C:\MAMP\bin\perl\bin\perl.exe

print "Content-type:text/plain\n\n";
print "Hello World";
```

これが正しい書き方なのかは微妙ですが、
https://stackoverflow.com/questions/7860380/how-do-i-run-perl-files-over-xampp-on-windows/7860435
上記XAMPPへの質問からエキスもらって、試したらいけました。


## おまけ

Active PerlなるものがWindowsにインストールできるって資料はあったので、そうしたらいいんじゃないかと思いつつ
Perl/がMAMPの中にあるのに使えないなんてことあるの！？ と、あきらめない気持ち...... (　･ิω･ิ)

さて、バックエンドの勉強をしますか。
Fixture利用のTips

# 1. Fixtureのロードは、各テストケースごとに行う
## 冒頭で `public $autoFixtures = false;` を記述しておく
```
    /**
     * Fixtures
     *
     * @var array
     */
    public $fixtures = [
        'app.Hoge',
        'app.Fuga',
    ];
    public $autoFixtures = false;
```

## 各テストケース内でFixtureをロードする
```
    /**
     * Test something method
     *
     * @return void
     */
    public function test_something()
    {
        $this->loadFixtures(
            'Hoge',
            'Fuga'
        );
```
## 参照
https://qiita.com/SRAUFactory/items/a3f367ea415fc13b3dd1

# 2. テストごとにFixtureを分ける
同じテーブルに対して、複数のテストから利用していると、
AテストのためにFixtureを編集すると
Bテストがコケる、ということに遭遇します。
あっちをいじると、こっちがおかしくなる・・・・で、めんどくさいので
テストケースごとに Fixtureを用意する。

## テストケースごとのFixture置き場
Fixtureディレクトリに任意のディレクトリ（`something`）を作ってその中に配置。
> tests/Fixture/something/somethingTableFixture.php 

## テスト側での呼び出し
```
    /**
     * Fixtures
     *
     * @var array
     */
    public $fixtures = [
        'app.something/somethingTable',
    ];
    public $autoFixtures = false;

    /**
     * Test something method
     *
     * @return void
     */
    public function test_something()
    {
        $this->loadFixtures(
            'somethingTable'
        );
```
`loadFixtures`するときは Fixtureクラスの名前だけでおｋ。

# Fixture作成に便利なコマンドオプション
```
$ bin/cake bake fixture -s -c [default以外のDB] [Table名] -r -n 5
$ bin/cake bake fixture -s -c [default以外のDB] [Table名] -r -n 5 --conditions "city='Tokyo'"

```

- -s：スキーマの定義はDBから取得して利用する。Fixtureファイルに直接定義が書かれない。
- -c：default以外のDBのコネクション名を指定。
- -r：実際のDBデータからレコードをとってくる。
- -n：何件とってくるか。
- --conditions：とってくる条件。SQLのwhere。 


# 3. 謎のトランザクションエラー回避のためのおまじない
## たまに起きる 謎のトランザクションエラー
> phpunit <ファイル名>

↑で、単体実行するとエラーが出ないのに、
全体実行すると ↓下記のようなエラーが出ることがある。

> ERROR:  current transaction is aborted, commands ignored until end of transaction block

MySQLだと出たことがないけど、PostgreSQLだと高い確率で遭遇する。
phpunit実行時、裏っかわでは、テスト用のTableをcreateしたり、dropしたりしてるんだが
どうやらこの時、2に記述したような、同Tableを複数のFixtureが利用していると起きるらしい？

ので、`tearDown()` におまじないを書いておく

```
    /**
     * tearDown method
     *
     * @return void
     */
    public function tearDown()
    {
        $this->fixtureManager->shutdown(); //ポスグレトランザクションエラー回避
        parent::tearDown();
    }
```

## 参照
https://api.cakephp.org/4.2/class-Cake.TestSuite.Fixture.FixtureManager.html#shutDown()

https://book.cakephp.org/4/ja/development/testing.html#id11
Mysql2::Error: Specified key was too long; max key length is 767 bytesに遭遇した

#　私がやった対処等

①config/database.ymlのencoding:utf8mb4部分の修正
utf8mb4⇨utf8に変更

②（私はこの段階で既にrails db:createしていたためでまだ組み始めたばかりだったため）一旦、rails db:dropでデータベース消去

③
$ rails db:create
$ rails db:migrate
の順で復旧
【Kotlin 初心者】Preferencesの使い方

## Preferences
API通信したアプリのtokenなどのデータをローカルに保存させます

参考URL
https://developer.android.com/guide/topics/ui/settings/use-saved-values?hl=ja

## Preferencesに書き込む
```
val shardPreferences = this.getPreferences(Context.MODE_PRIVATE)
val shardPrefEditor = shardPreferences.edit()

shardPrefEditor.putString("token", token)
shardPrefEditor.apply()
```

## Preferencesで読み取る
```
val shardPreferences = this.getPreferences(Context.MODE_PRIVATE)
var data = shardPreferences.getString("token", "[]")
```
データセットの暗号化

#Tableau CRM Encryption ソリューション

暗号化機能が Salesforce ファイルシステムに保存されている保存時のデータに拡張されるため、Salesforce のお客様のセキュリティが向上となる

暗号鍵を作成するには、権限セットにて、暗号化鍵を管理をOnにする必要がある
これはプロファイルに直接チェックはできず、権限セットで付与する方法をとる。

![スクリーンショット 2021-04-18 15.46.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385774/801330ee-eddc-fa64-aeaf-fc35e0af3872.png)

#鍵の作り方

かなり簡単で、設定のプラットフォームの暗号化で鍵の管理でデータ種別を選択して、作成

#項目の暗号化

設定、_暗号化ポリシーにて、項目を暗号化を選択し、どのオブジェクトのどの項目を暗号化するのかを決定する
![スクリーンショット 2021-04-18 16.07.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385774/38efc61a-521b-6299-2a44-3059c720ef8c.png)

#注意事項
- 既存のデータは暗号化されない。
- 暗号化が有効になる前に Tableau CRM にあったデータは暗号化されません。
- データフローを介して Salesforce オブジェクトからインポートされる既存のデータは、次のデータフローの実行時に暗号化されます。
- 他の既存のデータ (CSV データなど) は、再インポートしないと暗号化されません。
- 暗号化が有効になっても、既存のデータは暗号化されませんが、暗号化されていない状態で引き続きアクセスできて完全に機能します。


#参考文献
 
 [Tableau CRM Encryption](https://help.salesforce.com/articleView?id=sf.bi_analytics_encryption.htm&type=5)

[Shield Platform Encryption の使用開始](https://trailhead.salesforce.com/ja/content/learn/modules/spe_admins/spe_admins_get_started)
【Rails】formオブジェクトを用いてフロントエンドにjson形式でレスポンスを返す

React × Rails SPAの作成にあたりformオブジェクトを用いた実装をする必要があった。その際のレスポンスの返し方についてまとめておきます。

## HTMLを返すだけなら苦労しない。

普通formオブジェクトでは以下の流れでデータを扱う

1. コントローラーでストロングパラメータを用いてformから送信された値を受け取る
2. formオブジェクトに定義したattr_accesorでストロングパラメータで許可したキーを受け取る
3. saveメソッドなり保存処理を自前で実装。ActiveRecordのメソッドでDBに値を保存
4. コントローラーでredirectなどを用いてページをレンダリング

3で保存処理をした後はformオブジェクトの役目は終わる。

## json形式のレスポンスをどう返すか？

ところがSPAでフロントエンドから非同期でAPIを動かす場合はjson形式でレスポンスを返さないといけない。
そこで以下のように**ハッシュ形式で保存した複数のモデルをsaveメソッドの戻り値とする。**

```ruby
def save
  hoge = Hoge.new(some_column: some_value)
  fuga = Fuga.new(some_column: some_value)

  # 別々にレスポンスとして扱うためにハッシュ形式を採用(配列でもいけるが、なんのデータなのかわかりやすくしたい)
  hash = {}
  hash[:hoge] = hoge
  hash[:fuga] = fuga
  return hash #生成したハッシュをコントローラーに返し、レスポンスにする
end
```

こうするとコントローラーでhashから値を取り出す形でjson形式のレスポンスを定義できる。

```ruby
def create
	@test = Test.new(test_params)
  if @output.valid?
    test_save_result =  @test.save  
    # ステータスは手動で設定する。リソース保存時のステータスは201
    render status: 201, json: { hoge: test_save_result[:hoge], fuga: test_save_result[:fuga] } 
  else
    render status: 422, json: { errors: @test.errors.full_messages } 
  end
end
```
2進数から10進数へ変換するフローチャートを考える

# はじめに
本記事は基本情報技術者試験の勉強のアウトプットの一環で作りました。
間違っている所やもっと上手なやり方などあればコメントで教えていただければ幸いです。

# 2進数から10進数へ変換するフローチャートを考える
## 前提条件
・10111011(2進数表示)を10進数へ変換する
・自由に変数を設定できる。
## 結論
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/914577/f70d9849-4ad6-b3bd-7c7c-ca160b216815.png)


## 解説
①から⑤を順に追って説明します。
### ①
Binary：10進数へ変換したい2進数表示の1011011を入れる。
N：これから条件分岐によって、同じ処理を繰り返すためその回数を表現するために定める。
Decimal：条件分岐の処理1回につき、下1桁ずつ10進数に変換していくので、それを足し合わせるための箱の役割。最後まで足し合わせたらこれが答えになるので出力します。
### ②
もしもBinaryが0ではない場合、Trueにすすむので下1桁ずつの基数変換が始まります。終わるの(Falseに進む)はBinaryが0になった時です。
その処理が何回目なのか数えるためにNに1を足す。
N回目という考え方はこれから2進数の数字に各桁の重みを掛けるときに重要になるのです。
### ③
ここが肝です。
A：Binaryに10で割った物の余りを出すことによって下1桁を抽出します。
C：Aにその桁の重み、すなわちN＝1のときは、2の0乗を掛けることによって10進数表記に変えます。
最後にDecimalという箱にCを足し合わせます。
### ④
Binaryを10で割ることによって、計算が終わっている下一桁を消す。
条件分岐でTrueになる場合毎回、下一桁が削られつづけるので最終的には0になり繰り返しが終了(Falseとなる)してDecimalの出力へと進む。
### ⑤
条件分岐でTrueに進んだ時に毎回更新していたCの足し合わせであるDecimalを出力。
10111011を入力したので187が出力されます！
# 終わりに
ググっても条件分岐を利用した2進数から10進数へ変換するフローチャートが無かったので誰かの参考になれば幸いです。
もっとアルゴリズムの構築能力を増強してこれからも基本情報技術者試験に向けた勉強のアウトプットをこまめにしていきたいと思います。
undefined method `devise' for 〜のエラーに遭遇した

# 対処

参考：https://note.com/oreno/n/n1e32cefe430b

### 解決手段
先に解決方法ですが
一旦、railsを止めて再度、rails sで再起動すれば起動しました。

###  原因
原因は、railsを起動したまま
$ rails g devise:install
$ rails g devise user
$ rails db:migrate

の操作をしていたためだと思います。
import追加内容/実践例

# import
importは「`import モジュール名（ファイル名）`」と記述することで、Pythonではコードの一部を別ファイルに移して、モジュールとして読み込むことができます。
importやモジュールについての参考記事url : https://qiita.com/ITdiary/items/daff5591e9b420a5055a
今回は前回の記事に追加でimportの説明をしたいと思います。
「`from モジュール名 import クラス名`」と記述することで、そのモジュール内の指定したクラスを直接読み込むことができます。
これを用いることで、下記の例ではscript.py内でもこれまでと同じ様にNumberクラスを用いることができます

```py:script.py
from utils import Number   # 「from モジュール名 import クラス名」

valid = validate(1)   # 前回import モジュール名の時は「モジュール名.関数名()」なので、utils.validate()と書く必要があった
print(valid)
```
```py:utils.py
class Number

def validate(hand):
    if hand < 0 or hand > 2:
        return False
    else:
        return True
```
# 実践例
```py:script.py
from utils import FruitMenu

fruit_menu1 = FruitMenu('りんご', 300) 
fruit_menu2 = FruitMenu('みかん', 250)
fruit_menu3 = FruitMenu('バナナ', 200)
fruit_menus = [fruit_menu1, fruit_menu2, fruit_menu3]

for menu in fruit_menus:
    print(menu.fruit_info())
```
```py:utils.py
class FruitMenu:

    def __init__(self, name, price):
        self.name = name
        self.price = price

    def fruit_info(self):
        return self.name + ':' + str(self.price) + '円です'
```
```text:出力結果
りんご:300円です
みかん:250円です
バナナ:200円です
```
上記の流れとしては、まずインスタンス生成後にインスタンス変数`name`と`price`に値を自動で代入させるために\_\_init\_\_メソッドを用いました。
それらを変数`fruit_menu1~3`にそれぞれ代入し、リスト`fruit_menus`にまとめました。
そして、for文を用いてリストの要素を１つずつ取り出し、変数`menu`に入れて処理を行います。
`from utils import FruitMenu`と記述しているのでfor文の処理で関数`fruit_info()`を呼び出すことができ、utils.pyファイル内の関数`fruit_info()`内の処理を実行させます。処理には先程自動で値を代入した変数`name`と`price`を用いて、出力させたい内容を記述し、returnを用いて戻り値として呼び出し元に返します。ここで注意なのは、`price`は数値なので文字列に変える必要があります。
そして、呼び出し元である`print(menu.fruit_info())`に返され、print()で出力されることで上記のように出力結果を得ることが出きます。
VSCodeで、Shift_JISをWindows 1252に誤認識させないための呪文

# まず答え
VSCodeで、Shift_JISをWindows 1252に誤認識させないための呪文。冒頭近く、XMLなら、doctypeの後くらいに入れておくとよさげ。（）内も記載しておかないと、ふざけているのかと思われて、メンテナンスした人が消しちゃうかもしれないので注意。

```
<!--うえからしたにすべりこむ（VSCodeでShift_JISを誤判定させない呪文）-->
```

# 思い出話～今回の経緯

Shift_JISが誤認識されるのを避けるための呪文には古くからの歴史があります。その昔、ブラウザの文字コード認識が微妙にしょぼかった時代、そして、まだ今ほどUTF-8が普及していなかった時代、

```
<!--あいうえお-->
```

というコメントを挿入するダーティハックがありました。

時は流れて令和になりました。VSCodeでSalesForce用のprocess-conf.xmlを編集していたのですが、VBAで生成してprocess.batをキックする構造でちょちょいと作ろうとして、だからVBAで読み書きしやすいようにShift_JISにして、VSCodeでひな形を編集しようとしたら、日本語が化けるじゃないですか。判定はWindows 1252。なんじゃそりゃ。ansinewとも呼ばれる、ヨーロッパ版ANKみたいな文字セットの模様です。半角カナ的な部分にいろいろ入っているので、誤認識されやすいみたいっすね。このへん、あんまり適当なことを書くと、マサカリを携えた怖い人が寄ってくるので、大概にしておきましょう。

対策をググってみると、ソースコードを弄るとか、7-zipで構成ファイルを弄るとか、なんだかやりたくないハックが出てきます。これは良くない。問題のXMLファイルと、正しく判定できた（類似の）XMLファイルを比較して、共通部分を削っては、誤判定・適正判定の関係が維持されるように絞り込んでゆきます。するとどうでしょう。「からしたにす」という文字列をコメントに入れると、Shift_JISと正しく判定されるではないですか。残念ながら、これ以上縮めることはできませんでした。

# 仕上げとご意見拝聴の旨

後は覚えやすさですね。記憶コストが小さくないと、気軽に挿入できません。そこで、「うえからしたにすべりこむ」という文字列を編み出しました。これでOK。将来は、自動判定の候補を指定できるようになるとよいなあ、と思いますが、目先ではしょうがないので、同じ悩みを持つ方は使ってみてください。もっとエレガントな呪文も、あったら教えてくださいね。
hyn/multi-tenant使用中にDBのタイムゾーンを変更したらLaravelからテナントのDBに接続出来なくなった時のメモ

# 環境
Laravel
MySQL(AURORA)
hyn/multi-tenant

# 結論
テナントDBアカウントのパスワード生成にcreated_atを使用しているため、
値が変更されるとテナントDBアカウントでテナントDBに接続出来なくなる。

# 経緯
AURORAのパラメータグループで time_zone を変更したらテナントDBアカウントでテナントDBに接続出来なくなった。

```
Access denied
```

調べたらテナントDBのパスワード生成には websites.created_atを使用しているようだ。

```vendor\hyn\multi-tenant\src\Generators\Database\DefaultPasswordGenerator.php
    public function generate(Website $website) : string
    {
        $key = $this->app['config']->get('tenancy.key');

        // Backward compatibility
        if ($key === null) {
            return md5(sprintf(
                '%s.%d',
                $this->app['config']->get('app.key'),
                $website->id
            ));
        }

        return md5(sprintf(
            '%d.%s.%s.%s',
            $website->id,
            $website->uuid,
            $website->created_at,
            $key
        ));
    }
```

うちのwebsites.created_atはtimestamp型なのでDBのタイムゾーンによってよしなに変換される日時は変わってしまう。
今回の場合は9時間遅い時間を返すようになってしまった。
なのでcreated_atに9時間早い日時を設定したところ、DBに接続出来るようになった。

```
update websites set created_at = '2021-04-14 11:24:12';
```

以上
[記事紹介] 正規表現クロスワードを遺伝的アルゴリズムで解こうとしてあきらめた話

@qualitia_cdevの中の一人、@hirachanさんが書いた記事がおもしろいのでみなさまにご紹介します。


### 正規表現クロスワードを遺伝的アルゴリズムで解こうとしてあきらめた話

https://qiita.com/hirachan/items/340c2f4322f93da1f070
python 変数とオブジェクトについて

##初めに
初学者です。
前回の記事では貴重なご指摘ありがとうございます。
学習不足だったので私なりにまとめていきます。

###pythonで管理されるオブジェクトについて
`pyton`ではあらゆる情報がオブジェクトで管理されます。具体的には整数や文字列などの情報になります。
以下が簡単な例になります。

```python
1       #整数
'ハロー' #文字列
[1,2,3] #リスト
```

上記のような情報(他にもあらゆる情報)は`オブジェクト`という枠組みによって管理されます。

###オブジェクトID
先ほど、あらゆる情報はオブジェクトとして管理されると説明しました。そしてそのオブジェクトを識別する仕組みが`オブジェクトID`になります。
`オブジェクトに対してオブジェクトIDが１つ付与されるイメージです。`
では具体的にみていきましょう。
ターミナルでprint関数を使いidを表示させてみましょう。

```python
>>> print(id(1))
140423150496048
```
ものすごい量の数字が出力されました。この数字がオブジェクトIDになります。

### pythonの変数について
pythonの変数はオブジェクトを参照します。ではどうやってオブジェクトを参照するかというと変数はオブジェクトIDを管理することでオブジェクトを参照することができるのです。
参照とは普段あまり使いませんが、`オブジェクトがどこにあるかを指し示す`となります。
では具体例として変数にオブジェクトを紐付け、オブジェクトIDがあるか見てみます。

```python
num = 1
id(num)
140423150496048
```
先ほどと同じ数値が出てきました。以上の点からnum変数に`1`というオブジェクトの参照をしているということになります。
unityを用いずにwindowsアプリケーション(C#)とros(ubuntu)で通信を行う

# 初めに
[siemens社](https://github.com/siemens/ros-sharp)のros-sharpによりrosbridgeを用いてros melodicと通信を行います。
ros-sharpを動かすpcとrosを動かすpcの二台が同じlan環境内にあることを前提とします。
ros-sharpは、visual studio 2019 community を用いて開発を行います。
rosは、ubuntu 18.04 & melodicです。

# 環境構築
## ROS
[ros bridge](https://github.com/siemens/ros-sharp/wiki/User_Inst_ROSOnUbuntu)を参考に行います。

```
sudo apt-get install ros-melodic-rosbridge-server
```
rosのバージョンは環境に合わせて読み替えてください。

また、私の環境ではポート9090を開放しないと上手く動きませんでした。
## Windows
[リポジトリ](https://github.com/siemens/ros-sharp)を適当なところにzipでダウンロードしてください。

# ビルド
## windows
ros-sharp-master→Libraries内のRosSharp.slnをvisualstudioで開きます。
main関数はRosSocketConsoleExample.csにあり、

```c#:RosSocketConsoleExample.cs
static readonly string uri = "ws://192.168.***.***:9090";
```
には、rosを動かしているpcのipアドレスを入力します

RosBridgeClientTestをスタートアッププロジェクトにしてビルドを行います。

# 実行
ros側を先に実行します。
３つターミナルを立ち上げて実行します。
## ROS
```shell:1
export ROS_IP=192.168.***.***
export ROS_MASTER_URI=http://192.168.***.***:11311
roslaunch rosbridge_server rosbridge_websocket.launch address:=192.168.***.***
```
```shell:2
rostopic echo /publication_test
```
```shell:3
rostopic pub /subscription_test std_msgs/String "subscription test message data"
```
## windows
ros-sharp-master\Libraries\RosBridgeClientTest\binにある、実行ファイルを実行します。
【初心者向け】404ページは絶対に作っておこう

#どうも7noteです。404ページは作っておきたい話。

web制作はwebサイトの構成があり、デザインがあってそれをコーディングして公開。基本的にこの流れですが、実際にwebサイトを構成するものには他にも必要なファイルがあります。

・ .htaccess
・ 404ページ
・ robots.txt
・ sitemap.xml
...etc

そしてこの中で解説していきたいのが404ページ。
まずは404についての説明から。

## 404ページって何？なにかのエラー？

> 404エラー（Not Found）は、すでに削除されたページや、間違ったURLにアクセスした際に表示されるエラーです。
引用元：https://digitalidentity.co.jp/blog/seo/about-404-not-found.html

このようにユーザーがアクセスしたページが存在していなかった際に404エラーが出ます。
そして、**404エラーになった場合に表示させるページが404ページになります。**
さらに詳しい話は通信用語満載なので、その辺をもっと詳しく知りたい方は[こちら](https://ferret-plus.com/2536)


存在しないページ、404エラーがでた場合に404ページがあるwebサイトなら自動的に404のファイルを読み込み表示してくれます。
404ページを用意していなければ無機質な404が表示されます。

![スクリーンショット 2021-04-15 9.39.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/7ee752d3-0b00-b377-3e88-311662075b7f.png)



## 404ページを作ると何がいいのか？メリットは？

**404ページを作るメリット**

- 404ページがないと無機質な表示だけで「???」となるユーザーもいる
- 404ページにリンクを設置することで、他のページへ誘導できる
- 予期せぬURLやコンテンツへのリンクも404ページが表示されるので安心

こんなところでしょうか。404ページがなくてもwebサイトとしては運用に問題ありませんが、間違ったURLやもう削除してしまった古いページにアクセスされたとしても、404ページから他のページを見てくれる可能性があるのでそれだけでも十分価値があるでしょう。

また近年**どんどん凝った404ページを作成するwebサイトが増えてきました。背景としてはSNSの普及**があるのかなと思います。ちょっとしたゲームのようなものができる404ページや、クスっと笑ってしまうような404ページを見たユーザーがSNSでシェアすることによって、多くの人の目に止まりサイトにアクセスされることがあります。
SNSで話題になるとテレビなどでも紹介される可能性があるので、膨大な広告費などをかけずとも宣伝になる可能性を秘めている、これが404ページを作るメリットだと考えています。

## 404ページの作り方

### ①404.html（404.php） のファイルを作成してコーディングする

**※作成時の注意点**
cssなどの外部ファイルの読み込みはルートパスの表記で。

```404.html
<!-- 外部ファイルの読み込みはルートパスで -->
<link rel="stylesheet" href="/css/style.css">
```

### ② .htaccessに以下を追加
```.htaccess
ErrorDocument 404 /404.html
```


## いろんな企業の404ページ

### 「google」
![スクリーンショット 2021-04-15 9.56.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/57edeb62-62fa-79d1-0b0c-df8d733dc2c4.png)

### 「Qiita」

![スクリーンショット 2021-04-15 9.57.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/b645bbf9-cf05-138e-d7e1-b4522e348aac.png)

### 「クロネコヤマト」

https://www.kuronekoyamato.co.jp/ytc/404error.html
![スクリーンショット 2021-04-15 9.58.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/880151f1-ce98-6172-9ef5-0f2651c5e859.png)


### 「LIG」

![スクリーンショット 2021-04-15 9.59.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/b57072ba-9c65-6aeb-1d4f-a602036099fd.png)


## まとめ

404ページを作成するデメリットは**作成に少しだけ時間がかかってしまう点**だけです。
とはいえ凝った404にしなければ20分〜30分くらいでぱぱっと作ることもできるのでデメリットは少ないですね。

それよりも404ページがあることで**サイトの統一感**や**他ページへの誘導**ができるのであれば作っておくべきというのが私の見解です。
面白いなと思った404があればまた追加していきますね。コメントでも面白かった404ページがあればぜひ教えてください。

#### おそまつ！
~ Qiitaで毎日投稿中!! ~
[【初心者向け】WEB制作のちょいテク詰め合わせ](https://qiita.com/7note)
ここ一年のフローの変化を追う

約1年の間にLightningフロー（現在はSalesforceフロー）に様々な要素が追加され、使い勝手が随分と上がりました。
~~むしろ、便利になりすぎて怖いぐらい~~

ということで、ここ最近でフローに起こった大きな変化をさらいます。

#Spring '20
<dl>
  <dt>保存前更新トリガ</dt>
  <dd>レコード作成・更新をトリガーとして、データベースに保存を行う前に実行するフローが作れるようになりました。</dd>
  <dd>プロセスビルダーによるレコード更新よりも<strong>10倍</strong>速いという売り文句をひっさげています。</dd>
  <dd>ApexのBeforeトリガと似たようなもので、トリガを引いたレコードとは別にレコードを作成できません。</dd>
</dl>

#Summer '20
<dl>
  <dt>保存後更新トリガ</dt>
  <dd>レコード作成・更新をトリガーとして、データベースに保存を行った後に実行するフローが作れるようになりました。</dd>
  <dd>これにより、トリガーを引いたレコードと別のレコードに更新を加えるなど、フローでできることが広がりました。</dd>
  <dd>リリースノートを引用すると、</dd>
  <dd>『これらのフローはプロセスビルダーで作成したワークフロールールやレコード変更プロセスの大部分を置き換えることができます。』</dd>
  <dd>とのこと。</dd>
  <br>
  <dt>プラットフォームイベントトリガ</dt>
  <dd>まだあまり使ったことが無いので、分からないことが多いです。</dd>
  <dd></dd>
  <dd></dd>
</dl>

#Winter '20
<dl>
  <dt>削除前更新トリガ</dt>
  <dd>今まではApexコードを書いて、Before Deleteトリガを書く必要がありました。</dd>
  <dd>それがフローでも可能になりました。</dd>
  <dd>コードを書くのとフローを作るのとどっちが速いかと言われると…　　人によるのではないでしょうか。</dd>
</dl>

#Spring '21
<dl>
  <dt>フローをトリガしたレコードの前の値が参照可能に</dt>
  <dd>何よりもこれが一番大きいですね。</dd>
  <dd>これにより、ISNEW()・ISCHANGE()・PRIORVALUE()などのフローでは使用できない関数の代替手段ができてしまいました。</dd>
  <dd>プロセスビルダーを選択する理由が一つ、つぶれることに…。</dd>
  <br>
  <dt>スケジュール済みパスを追加可能に</dt>
  <dd>プロセスビルダーで言うスケジュール済みタスクのようなものが、追加できるようになりました。</dd>
  <dd>プロセスビルダーを選択する理由がさらにつぶれることに…。</dd>
</dl>
Android Gradle plugin requires Java 11と言われてSyncできないときの対処法

AGP 7.0.0-alpha02からJava 11が必須になったようです。
https://developers-jp.googleblog.com/2020/12/announcing-android-gradle-plugin.html
あの設定どこだっけってときどきなって、かなり高確率で最初に当たるので、メモしておきます。

```
An exception occurred applying plugin request [id: 'com.android.application']
> Failed to apply plugin 'com.android.internal.application'.
   > Android Gradle plugin requires Java 11 to run. You are currently using Java 1.8.
     You can try some of the following options:
       - changing the IDE settings.
       - changing the JAVA_HOME environment variable.
       - changing `org.gradle.java.home` in `gradle.properties`.
```


最近は以下のようなエラーメッセージでも同様のことが起こるようなので、対処方法を試してみてください。

* Java 11にしかないパラメーターを使っているパターン

> Unrecognized VM option 'MaxPermSize=2048m'

* Toolchainで11を使っているパターン

> A problem occurred configuring project ':app'.
> Could not determine the dependencies of task ':build-logic:compileKotlin'.
   > No matching toolchains found for requested specification: {languageVersion=11, vendor=any, implementation=vendor-specific}.
      > No locally installed toolchains match (see https://docs.gradle.org/8.1.1/userguide/toolchains.html#sec:auto_detection) and toolchain download repositories have not been configured (see https://docs.gradle.org/8.1.1/userguide/toolchains.html#sub:download_repositories).

## 対処法


Gradleの設定を開いて、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27388/955ded92-c5ab-512d-1210-57aa99ea83b8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27388/c98b3ebf-e59e-a0e1-46f2-a2923a7889ba.png)

Android Studioに入っているJDKを選ぶだけです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27388/40a9d753-8259-0d1c-bcf8-e6d29bbf466e.png)
[Swift] ドキュメントに新規追加されたデータのみとってくる

ファイアベースストアからデータを取得する時に、データベース側で新しいドキュメントが追加されたことを監視
して、更に新規追加されたドキュメントのみ取得すると言うことができる。

それが

**addSnapshotListener関数**

まずは、普通のドキュメントの取得方法

```swift
Firestore.firestore().collection("user").getdocuments{(res, err) in
            if let err = err {
                //エラー時の処理
                return
            }
            //データの取得に成功したとき      
                }
            })
```

これでuserドキュメントのデータを全件配列としてコールバック関数の引数であるresとして受け取れる。

では、更新されたデータのみを取得する場合の書き方を見てみる。

```swift
private func fetchChatroomsInfoFromFirestore() {
  Firestore.firestore().collection("user").①addSnapshotListener{(snapshots, err) in
            //            .getDocuments { (snapshots, err) in
            if let err = err {
   
                return
            }
            
            ②snapshots?.documentChanges.forEach({(documentChange) in
                switch documentChange.type{
                case .added:
                     self.handleAddedDocumentChange(documentChange: documentChange)
                case .modified,.removed:
                    print("nothing to do")
                }
            })
}
```

**まずは、①のaddSnapshotListener**
この関数は、初回のデータ取得時にコレクションに対してリスナーを設置する&&通常のデータ取得と考えると分かりやすい。かなり特殊な動きをする。
例えば、fetchChatroomsInfoFromFirestore関数が、画面生成時に呼ばれるViewDidlosd関数のなかで呼ばれると、userドキュメントののデータを全件取得して更にドキュメントに対してリスナーを設置する。
このリスナーはドキュメントの更新を監視するもので新規ドキュメント追加時にオートでaddSnapshotLisner以下の処理が実行されるようになる。

②は取得したuserコレクションのドキュメント情報全件（配列）のsnapshotに対して**前回の取得時のデータに対して何らかの変化があったドキュメント**に対して　foreachをかける。（documentChanges）
ドキュメントのタイプが新しく更新されたものと言う条件式をつけて処理を書くことで
新しいデータのみ取得される。

<h2>初回取得時と二回目の取得時の処理の流れ<h2>

上の説明を聞くと、初回のデータ取得時はもともと入っていたデータだから取得されないんじゃないのと思うかもしれないが、ここが特殊な動きで
最初にデータを取得する時は、全件のデータを取得して、その後の更新時は前回取得したデータに対して最新のデータを照合してその差分を抽出するような動きになる。

また、データのタイプ型にはremovedや、modifiedなどがあり、

**removed: 差分データで消されたドキュメント**
**removed: 差分データで更新されたドキュメント**

とデータがどのように変化したかで対象ドキュメントを絞る事ができる
curl の無い container (alpine) 内から POST リクエストを送る方法 / Fire POST request without curl

https://www.reddit.com/r/bash/comments/2vt3p1/make_a_post_request_without_curl/coksadc/ ここにあった。

netcat (nc) を使えば良い？

（他のやり方もありそうとはいえ）

以下は GET の場合だが。

```
% docker run -it alpine:3.9.4 sh -c 'echo -e "GET / HTTP/1.0\nHost: example.com\n\n" | nc example.com 80'

HTTP/1.0 200 OK
Accept-Ranges: bytes
Age: 556620
Cache-Control: max-age=604800
Content-Type: text/html; charset=UTF-8
Date: Thu, 15 Apr 2021 00:23:33 GMT
Etag: "3147526947"
Expires: Thu, 22 Apr 2021 00:23:33 GMT
Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
Server: ECS (sjc/4E76)
Vary: Accept-Encoding
X-Cache: HIT
Content-Length: 1256
Connection: close

<!doctype html>
<html>
<head>
```
MicrosoftのRPA - Power Automate Desktop 2021年4月アップデートについて

皆さんこんにちは、マイクロソフトの川端です。
2021年4月のPower Automate Desktopのアップデート情報を紹介していきます。

#1. はじめに
元の情報（英語）はこちらになります。
https://flow.microsoft.com/ja-jp/blog/power-automate-desktop-april-2021-update/

本内容はPower Automate Desktopのバージョン2.7.49.21099での動作内容となります。

以前のバージョンをお使いの場合も、こちらから最新のインストーラーをダウンロードし起動、インストール完了して頂ければ最新版へと更新されます。
https://flow.microsoft.com/ja-jp/desktop/

#2. Power Automate Desktopの2021年4月アップデート情報
###コンソール画面（初期起動画面）から[最新の状態に更新]ボタンが使えるように
コンソール画面内では、[自分のフロー]と[共有アイテム]のデスクトップフローのリストで見られようになっていますが、共有されたフロー内での新しいフローの追加、変更、名前の変更などがあった場合に、その更新を[最新の状態に更新]ボタンから随時手動でPower Automateクラウドサービス側に保存されているフローの同期ができるようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/c305ca39-fad7-942c-65d6-c03b1c6b67c7.png)

###フローデザイナー画面で[名前を付けて保存]が利用できるように
追加編集しているようなときに以前保存していたバージョンを保持したまま、新しい名称、新しいフローとしてデスクトップフローを保存することができるようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/e06e0993-ec63-224a-0c33-4fc329b63f2c.png)

###デスクトップレコーダーで[画像記録]のオプションをオンにしてレコーディングができるように
[画像記録]をオンにすることで、画面上のGUIのコンポーネントベースの記録から、画像認識ベースの記録にデスクトップレコーダーを使えるようになりました。画面オブジェクトが取れない場合に画像認識を利用する場合でも、デスクトップレコーダーの直感的な操作感で記録を行うことができるようになります。また、あわせてOCR(光学文字認識）を利用し、デスクトップレコーダー内で画像からテキストを抽出することができるようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/1d90fdf2-00c7-b72d-6c4b-d47d8cf65a7d.png)

###Javaアプリケーション、Javaアプレットでの読み取り精度向上、性能向上
既に用意されていたJavaアプリケーションに対する自動化ですが、読み取り精度の向上がなされ、高度化されています。UI要素をより詳細に指定することができるようになりました。

#3. 最後に
今月も様々なアップデートがありました！引き続き最新版のPower Automate Desktopのご利用をお楽しみください！
[無料トライアルはこちら]

[無料トライアルはこちら]:https://flow.microsoft.com/ja-jp/robotic-process-automation/
[一人暮らしの男性に向けて]非同期処理とは？

##はじめに
非同期処理について再確認するために記事をまとめました。
結構馴れ馴れしい感じの説明になっておりますが、ご愛嬌ということで、お許しください。

##非同期処理とは？

###一般的な説明
通常のプログラムって実行すると、コードを上から順に1行ずつ実行していきますよね。重いfunctionだったり、sleep(5000);とかだったら待たないと処理が終わることができません。非同期で処理をした方が効率が良い時があっても同期で処理がされていきます。それを解決してくれる処理が非同期処理です。
非同期処理は、文字通り非同期に処理ができます。例えば、１０秒かかるfunctionがあったとしてそのレスポンスを待っている間に違うfunction処理を実行することができます。

###レンチンが基本の一人暮らしの男性の自炊に例えると
「セブンイレブンのレンチンでできるホルモン焼き丼・豚汁」という献立だとします。
まず一番時間がかかるのは炊飯する白米ですよね。40分ぐらいかかるので、一番最初に処理を開始いたします。その間、豚汁を作ります。人参きったり、豚肉きったり...味付けしたり。
で、豚汁作業中に白米が終わりセブンのレンチンホルモンをレンジに入れます。豚汁終了とタイミングにホルモンを白米の上にのせ丼が完成、豚汁をよそい食卓に並べれば完成。

わざわざ炊飯中になにもやらないでじっと待つことはないですよね...

##コードに例えると

###律儀に炊飯中はじっと待つタイプの方のコード
```
console.log("start");

function chouri(name ,milliSeconds) {
  var startTime = new Date().getTime();
  while (new Date().getTime() < startTime + milliSeconds);

  console.log(name + "終了");
}

chouri('炊飯', 2400); // 白米を炊飯するのに40分かかる
chouri('豚汁', 1200); // 豚汁を作るのに20分かかる
chouri('レンチンホルモン', 120); // レンチンホルモンに2分かかる

console.log("end");
```
これは通常通り、上から下に実行されます。
ログは以下の通りです。

```
start
// 40分後
炊飯終了
// 20分後
豚汁終了
// 2分後
レンチンホルモン終了
end
```

全ての調理が終わるのに、1時間2分かかります。

### 今度は効率の良い調理コード

```
console.log("start");

function suihan() {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log('炊飯終了');
    }, 2400);
  });
}

function tonjiru() {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log('豚汁終了');
    }, 1200);
  });
}

function horumon() {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log("レンチンホルモン終了")
    }, 120);
  });
}

async function chouri() {
  await Promise.all([suihan(), tonjiru(), horumon()]);
}

console.log("start");
chouri()
console.log("end");
```
こちらのコードは同タイミングで処理がされていきます
ログは以下の通りです。

```
start
end
// 2分後
レンチンホルモン終了
// 20分後
豚汁終了
// 40分後
炊飯終了
```
これを処理すると、40分で調理が終わります。
ただ、注意としてはレンチンホルモンは冷めてます。

## まとめ
手際の良い主婦の調理フローをコードに落とし込むのは至難の技ということにしましょう。
これが非同期処理です。
【小ネタ】Streamlitのシークレットマネージャー機能を使ってみる

# はじめに
Streamlitからのお知らせの中にこんなのを見つけて、試しに使ってみたのでメモがてら投稿します。

> Try out Secrets
> Secrets Management is now available in sharing [just make sure to upgrade to the > 0.80.0 release]. Read more [here](https://blog.streamlit.io/secrets-in-sharing-apps/?utm_source=Streamlit&utm_campaign=a2e1bccf19-EMAIL_CAMPAIGN_2020_11_11_08_14_COPY_01&utm_medium=email&utm_term=0_e7877ed028-a2e1bccf19-395960071) and check out the [docs](https://www.notion.so/Secrets-Management-730c82af2fc048d383d668c4049fb9bf?utm_source=Streamlit&utm_campaign=a2e1bccf19-EMAIL_CAMPAIGN_2020_11_11_08_14_COPY_01&utm_medium=email&utm_term=0_e7877ed028-a2e1bccf19-395960071) to get started.

意訳）
シークレットを試してみる
シークレットマネージメントが0.80.0リリース版で使えるようになったよ。
詳細はドキュメントみてね！

# Secrets Management（シークレットマネージャー）機能について
パスワード情報を直接ソースに書かずに外部から渡すことができる機能。

## サンプルプログラム
```python:streamlit_app.py
import streamlit as st

st.write("DB username:", st.secrets["db_username"])
st.write("DB password:", st.secrets["db_password"])
st.write("My cool secrets:", st.secrets["my_cool_secrets"]["things_i_like"])
```

ローカル環境では、こんな感じでファイルを用意しておくことで利用可能です。

設定ファイル例）

```toml:.streamlit/secrets.toml
db_username = "Jane"
db_password = "12345qwerty"

[my_cool_secrets]
things_i_like = ["Streamlit", "Python"]
```

■実行結果
![スクリーンショット 2021-04-15 8.42.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6280/b5465860-f40f-f457-89b0-caf2d994fd2e.png)


※ また以下のように環境変数としてもアクセス可能です。

```python
import os
st.write("DB username:", os.environ["db_username"])
st.write("DB password:", os.environ["db_password"])
```

# Appendix
## 参考サイト
- [Add secrets to your Streamlit apps](https://blog.streamlit.io/secrets-in-sharing-apps/?utm_source=Streamlit&utm_campaign=a2e1bccf19-EMAIL_CAMPAIGN_2020_11_11_08_14_COPY_01&utm_medium=email&utm_term=0_e7877ed028-a2e1bccf19-395960071)
- [Secrets Management](https://www.notion.so/Secrets-Management-730c82af2fc048d383d668c4049fb9bf)

# ご意見・ご感想をお待ちしております
今回の記事はいかがでしたか？
・こういう記事が読みたい
・こういうところが良かった
・こうした方が良いのではないか
などなど、率直なご意見を募集しております。
頂いたお声は、今後の記事の質向上に役立たせて頂きますので、お気軽に
コメント欄にてご投稿ください。[Twitter](https://twitter.com/narinarita1980)でもご意見を受け付けております。
皆様のメッセージをお待ちしております。
AWS Inspector とは

## 勉強前イメージ

Inspector : 監査人
監査のチェック？

## 調査

### AWS Inspector とは

EC2インスタンスの脆弱性の診断を自動的に行なってくれるサービスになります。
脆弱性の診断とはサイバー攻撃でよく使われるような手法のパケットなど送信し、セキュリティレベルを判定することです。
こちらを使うことで、実際に現状使用しているEC2インスタンスのセキュリティレベルを確認することが出来ます。

### 使用できるリージョン・OS

※2021/04現在になります。
詳細は [Amazon Inspector でサポートされているオペレーティングシステムとリージョン](https://docs.aws.amazon.com/ja_jp/inspector/latest/userguide/inspector_supported_os_regions.html) をごらんください

使用できるリージョンは以下で、

- 米国東部 (オハイオ) us-east-2
- 米国東部（バージニア北部） us-east-1
- 米国西部 (北カリフォルニア) us-west-1
- 米国西部 (オレゴン) us-west-2
- アジアパシフィック (ムンバイ) ap-south-1
- アジアパシフィック (ソウル) ap-northeast-2
- アジアパシフィック (シドニー) ap-southeast-2
- アジアパシフィック (東京) ap-northeast-1
- 欧州 (フランクフルト) eu-central-1
- 欧州 (アイルランド) eu-west-1
- 欧州 (ロンドン) eu-west-2
- 欧州 (ストックホルム) eu-north-1
- AWS GovCloud (米国東部) gov-us-east-1
- AWS GovCloud (US-West) gov-us-east-2

使用できる主要OSは以下になります

- Amazon Linux 2
- Ubuntu (20.4 LTS、18.04 LTS、16.04 LTS、14.04 LTS)
- Debian (10.x、9.0～9.5、8.0～8.7)
- Red Hat Enterprise Linux (8.0x、7.2～7.x、6.2～6.9)
- CentOS (7.2 ～ 7.x、6.2 ～ 6.9)

基本的なリージョンやOSは使用できるので、対応していなくて困るといったことはあまりないのではないかと思います。

### メリット

- アプリケーションのセキュリティの問題点を識別

アプリケーションのデプロイ前とデプロイ後のセキュリティチェックを行い、対処することで
アプリケーションに対するセキュリティを強化出来ます

- セキュリティを DEVOPS に統合

既存のDevOpsプロセスに評価を組み込むことで脆弱性の評価を自動化出来ます

- AWS のセキュリティについての専門知識を活用する

評価とルールのナレッジ更新を継続的に行っており
それに関してサービスの形で活用でき、また適応するまでのプロセスを簡略化出来ます

## 勉強後イメージ

EC2インスタンス単体の脆弱性が見れるって感じかな。
雰囲気わかるけど一回試してみたい、どうやって出るのか。

## 参考

- [Amazon Inspector](https://aws.amazon.com/jp/inspector/)
- [【Amazon Inspector とは？】初心者にもわかりやすく解説](https://www.wafcharm.com/blog/amazon-inspector-for-beginners/)
- [AWS再入門ブログリレー Amazon Inspector編](https://dev.classmethod.jp/articles/re-introduction-2020-inspector/)
【新人エンジニア応援】猿でも分かるオブジェクト・クラス・インスタンス

#0.はじめに

おはようございます。早起きして、Qiitaを覗いていたら、４月ということで、新人エンジニア向けのイベントが開催されていたので、便乗して１つ簡単なアウトプットをしようと思います。

https://qiita.com/official-events/63aa63fd921659fb3b5d

簡単に自分の紹介をさせていただきます。

今は都内の不動産Techのベンチャーで勤務しており、個人開発も含めると、エンジニア歴は13年、web開発4年のSaaS保守・運用エンジニアです。

今日は猿でも、猿でも新卒エンジニアでも理解できるオブジェクト指向を薄っぺらく解説します。

※猿にも分かるようにする過程で、やや意味が曲がってしまっている可能性がありますので、ご愛嬌ということでよろしくお願いいたします。

#1.オブジェクトって

そもそも、オブジェクト指向のオブジェクトって何？ってまず思いますよね。

オブジェとは違いますよ？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661133/7a3302a3-a68b-3f3a-2696-4f7f7fceac0f.png)

新宿アイランドの前に佇むLOVEとは、全く別のものです。

オブジェクトとは、オブジェクト指向で操作対象になるデータのことです。

例えば、会計ソフトを作る上で、必要となるオブジェクトは、

入出金の金額のデータ
商品のデータ
顧客のデータ

などなど、定義づけでは、属性を持っていることも要件として入ってくることが多いです。

例えば入出金で言うと、１２０円の入金があったとき、その入金がどんな属性なのか
・パンを売った代金
・２０２１年４月１５日午前８時０５分１２秒に登録された
・田中さんがレジを操作して、入金された

などがありますね。

オブジェクト指向プログラミングでは、こう言った属性を持つオブジェクトにメソッド（関数）を適用することで、プログラムを記述していきます。

#2.オブジェクト指向って何がいいの？

オブジェクト指向ってよく言うけど、何がメリットなんだろうってところですが、

まず１つ考えられるのは、人間的視点での分かりやすさです。

非オブジェクト指向言語よりも、人間の言語で解説しやすいような設計だと思われます。

と言うのも、先にも挙げたようにオブジェクト（モノ）を、メソッドで操作していくという仕組みは、

例えば、「パン（オブジェクト）」を「売る（メソッド）」、「お金（オブジェクト）」を「入金する（メソッド）」と言ったように、

基本的に名詞と動詞で説明可能な設計になっているからです。

だからこそ、基本が理解できれば未経験のエンジニアでも理解しやすい設計になっています。


２つ目に、切り分けのしやすさです。

例えばチームで開発を行う際に、一人が商品オブジェクト周りを開発、一人が入金オブジェクトを開発とクラスで切り分けて開発を行い、
開発後に2つのクラスを繋ぐことによって、商品を売る→入金するという流れを後から構築することが可能です。

#3.クラス・インスタンスって何？

１年１組！とかじゃなく、オブジェクト指向におけるクラスとは、設計図と言われることが多いです。

例えば、商品（オブジェクト）は、「商品の名前」「金額」「画像」を持つとします。
という概念を記述したものが、「クラス」にあたります。

そして、インスタンスとは、クラスを元に実際に生成されたオブジェクトのことで、
先にあげたクラス（設計書）に実際に、「商品の名前＝パン」「金額＝120円」「画像＝（省略...)」のように、必要な値を入れて、

オブジェクトとして利用するための雛形が「クラス」、「クラス」を元に生成されたオブジェクトが「インスタンス」と呼ばれています。

またクラスの特徴に、継承が可能という特徴があり、例えば商品全体を定義する商品クラスがあったとします。
しかし、商品が飲料であった場合は、その商品が何mlなのかも属性に入れたい！という場合、

食べ物には何mlという概念は無いので、その属性は商品が飲料であった場合にのみ必要になりますよね。

そう言った場合に、商品クラスを継承した飲料クラスを作成します。

そして飲料クラスの中に、何mlという属性を追加することで、飲料の場合は内容量という属性を付加することができます。

また、商品クラスを継承した弁当クラス、雑誌クラスなど、商品の中でも設計書が多少異なるような場合に、
このように継承をしていくことで、図解的にも処理的にも分かりやすくオブジェクトを管理することができます。

#4.終わりに

そろそろ出社の時間なので、この辺りにしておきます。

Twitterと別記事の宣伝だけさせてください。是非フォローお願いします。
https://twitter.com/pichu_vi

https://qiita.com/ryoya1122/items/502c07410197746e79e4

https://qiita.com/ryoya1122/items/f72486e8db0508a7ee08
SharpDevelop で、VB.Net を C# に変換してみた( その1 )

#背景

残念な事に、[こちら](https://forest.watch.impress.co.jp/docs/news/1240998.html)などでも発表されているように、VB が、Microsoft での言語としての発展が終わってしまうようです。

まだ使えるようですが、いい加減 C# に乗り換えようと思って調べたメモです。

まだまだやりかけですが💦


#情報収集

英語でも検索しましたのが、この需要自体が日本に多いのか、日本語サイトの情報がほとんどでした。
どこも似た様な内容でしたが、とりあえずこちらを参考。

https://qiita.com/yaju/items/3afb486bfbbddc1e6aa8


オンラインのツールは、ソースを外部に送ることになってイマイチだし、複数のファイルを一括でできないこともありとりあえず今回は見送り。

Visual Studio の変換プラグインは、どうにも評判が悪そうだし、どのサイトでも SharpDevelop がよさそうなんで、SharpDevelop でやってみることにしました。


#ダウンロード

SharpDeveop は、Ver.5 から VB 対応がなくなってしまったので、その前の Ver.4.4 を[こちら](https://web.archive.org/web/20190927212213/http://www.icsharpcode.net/OpenSource/SD/Download/Default.aspx)から Download。

Archive サイトですが、[公式](https://github.com/icsharpcode/SharpDevelop/releases)からも上記のリンク先に飛びます。

#やってみる

とりあえず開くと、速攻でエラーになります。古いバージョンなので、Visual Studio 2015 までしか対応していないようです。

ただ、バージョンチェックしているだけっぽいので書き換えてみます。

まず Solution ファイルを編集。

```text:編集前
VisualStudioVersion = 16.0.29409.12
```

```text:編集後
VisualStudioVersion = 12.0.29409.12
```

次に Project ファイルを編集

```text:編集前
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
```

```text:編集後
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
```

これをやると、無事ソリューションが開けました。

開けたら、実行は簡単でプロジェクトを右クリックして、[Convet]→[From VB.NET to C#] を選択。


#問題点

とりあえず、まだまだ実用になってないですが、現在時点で下記の問題点がでました。

１. 当たり前ですが、Visual Studio 2017 から使用可能になっていた補完文字列がエラーになります。

```vb:NG
Dim str = $"{変数}"
```

２. こちらは、Visual Studio 2010 からの機能ですが、自動実装 Property もエラーになります。

```VB:NG
Public Property Hoge As String
```

３. これは、やむなしという気もしますが、変数名に「〇」という文字を使っているとエラーになります。( 伏字じゃなくて本当に「〇」です。そもそも使うなよって話もある気がしますが )

```VB:NG
Dim 〇 As Integer
```

４. 複数行テキストがエラーになります。

```VB:NG
Dim str = "
1行目
2行目
"
```

５．括弧を全角で書いていたところがエラーになる。というかこれがエラーになってなかったのがびっくり。これは直そうよって感じですね💦

```VB:NG
Dim value =　（1+2）*3
```

６．Nullable もエラーですね。こちらも Visual Studio 2015 ではできてた気がします。

```VB:NG
Dim value As Integer?
```

まだ、コンパイルすら通るようになっていないので、画面デザイン系はチェックすらできてません。
（ただ、一応、変換はできてました）

他にもまだまだ問題点がありそうです。
とりあえず上記を手修正で変換して、[その2](https://qiita.com/wacha/items/d17ee9b2f3451963881d)に続きます💦
【Python】Youtubeの新着動画を自動的にダウンロードしておくコード（違法性なし）

# はじめに
特定のキーワードに合致する新着動画をYoutubeから検索して自動的にダウンロードしておくプログラムを書きました。
コピペで動かせるので新人プログラマさんにもおすすめです。

本記事で紹介するライブラリは違法性はないとのことですが、youtubeのダウンロードは自己責任でお願いいたします。
※当然「複製して配布」はNGです！

https://japan.zdnet.com/article/35162547/

# 準備
必要なPythonモジュールをインストールします。

```
pip install google-api-python-client
pip install apiclient
pip install youtube_dl
```
# コード
```python
from __future__ import unicode_literals
import youtube_dl
import apiclient

KEY_WORD = "YOASOBI"          # ダウンロード対象のキーワードを入力
DOWN_DIR = "\\Videos\\"       # ダウンロードフォルダ
API_KEY  = "<APIキーを入力>"   # APIキー

youtube = apiclient.discovery.build("youtube", "v3", developerKey=API_KEY)

def youtube_search():
    search_response = youtube.search().list(
      q=KEY_WORD,
      part="id,snippet",
      maxResults=50,
      order="date"
    ).execute()

    ydl_opts = {"outtmpl": DOWN_DIR + "%(title)s-%(id)s.%(ext)s"}
    for search_result in search_response.get("items", []):
        if search_result["id"]["kind"] == "youtube#video":
                with youtube_dl.YoutubeDL(ydl_opts) as ydl:
                    ydl.download(["https://www.youtube.com/watch?v=%s" % (search_result["id"]["videoId"])])

if __name__ == "__main__":
    youtube_search()
```

# 実行結果
無事新着動画がダウンロード出来ています。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1203022/c5a7bfa4-2035-f371-6bda-f9f82bf89d94.png)

※実行中に撮ったキャプチャです。

このPythonプログラムをタスクスケジューラーやcronで（5分間隔等で）定期実行すれば新着動画を自動的にダウンロードするツールの完成です。

YouTube Data API の使用にはAPIキーが必要です。
下記の記事で取得の説明をしています。

https://qiita.com/shinkai_/items/10a400c25de270cb02e4

再生回数が1000件以上のものといった絞り込みをしたい場合は以下の記事を参考にしてください。

https://qiita.com/shinkai_/items/4ba36edf8aae98d45bf5

以上です。