OmniAICreator/Qiita-1.07M huggingface dataset:
BigQueryやAthenaでの日付指定

## 解決したいこと
定期的に集計したいクエリを実行する際、集計対象日となる日付を下記などに渡して利用することが多い

そのときに下記のような問題がある

- クエリ内で一箇所で日付関連の定義を管理して、適切な名前をつけクエリを読みやすくしたい
  - クエリを呼び出す側の修正ではなく、クエリそのものの修正で完結させたい
- そのため集計対象日だけを渡して、他の日付はその日付を計算して算出したい
- 集計対象日として置換する前の文字列があちこちに書かれないようにしたい

## 集計対象日以外を考慮する集計
下記のように日付を考慮する集計が存在する

- 集計対象日を含む過去30日の集計
- 前月登録会員の30日以内行動の集計

## クエリ例
- udf (ユーザー定義関数) による設定の一元管理と関数名前付けによるわかりやすさを意識する
- udfを使いにくい環境では、with句での一元管理とカラム名前付けによるわかりやすさを意識する

### bigquery
udfを気軽に使えるため

```sql
create temporary function target_date()
returns date as (
  -- date(%(target_date)s)
  date('2021-10-18')
)
-- target_date() を用いて 30日計算した日付を返す関数を作成する
;
with t as (
  -- values を使えないので union allで代用
  select date('2021-10-18') as d, 1 as x union all
  select date('2021-10-19'), 2
)
select
  d
  , x
  , target_date() as target_date
from t
where d = target_date()
```

### athena
udfを使うためにJavaのコードを書くのはつらいので、with句でconfiguration用のテーブルを用意して使いたい日付をscalarとして利用する

```sql
with t as (
  select *
  from (
    values (date('2021-10-18'), 1), (date('2021-10-19'), 2)
  ) as t(d, x)
)
, config as (
  -- select date(%(target_date)s) as target date
  select date('2021-10-18') as target date
)
-- config tableを利用してさらにtableを作るか、config内で date_add等を使って算出する
select
  d
  , x
  , target_date() as target_date
from t
where d = (select target_date from config)
```
ABC216 C - Many Balls から学んだ

https://atcoder.jp/contests/abc216/tasks/abc216_c

![abc216c_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/68e13489-7a7c-4912-e08e-650a2b33f6ea.png)
![abc216c_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/40b3a374-771f-328d-ad5d-2ad8db9ede8e.png)
![abc216c_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/baa5f524-093e-3de8-e01d-81bb92d7c750.png)

分からないので解説確認。

https://www.youtube.com/watch?v=Tgd_zLfRZOQ

なるほど。以下で通った。

```abc216c.py
N = int(input())
ans = ""

while True:
    if N == 0:
        break
    elif N%2 == 0:
        ans += "B"
        N //= 2
    elif N%2 != 0:
        ans += "A"
        N -=1

print(ans[::-1])#23ms
```

2^120 は 10^36 らしいので、
N%2 を最優先に記述すれば
基本的には 120回以下に収まると判断していいはず 

参加者の解答を眺めていたが、
while 分の条件を設定できれば
if / elif / else の記述が少し減らせるのは面白いと思った。

```abc216c.py
def solv():
    N = int(input())
    ans = ""
    while N>1:
        if N%2 == 0:
            ans += "B"
            N //= 2
        else:
            ans += "A"
            N -= 1
    ans += "A"
    print(ans[::-1])
solv()#30ms
```
kubernetesのsecretファイルの書き方

##はじめに
kubernetesでsecretファイルを使うことがあったのだが、どこに何が書かれているのかさっぱり理解出来ていなかったので、
備忘録として以下に記す。

##根本原因
そもそもの根本としてsecretファイルの挙動を理解していなかったことが原因だった。

##そもそもSecretって？

##解決策
下記のように新規でトークンを発行した場合はsecretファイルに記述すると良い

```bash:secret.yaml
apiVersion: v1                ##apiのバージョン指定
kind: Secret                  ##ファイル種類をsecretと宣言
metadata:
  name: Github                ##Git Account名
type: Opaque                  ##secretの型を決める。今回はデフォルトの型を指定
stringData:                   ##base64にしない時の宣言フォーマット
  github_bot_password: hoge   ##git loginのパスワード
  github_new_token: XXXX      ##新規追加したトークンのパスワード
```

##感想
secretファイルは機密情報管理をする部分なので、詳しい書き方は覚えておいた方が良い(戒め)

##参考資料
[公式Secret](https://kubernetes.io/ja/docs/concepts/configuration/secret/)
[Secretの設計文書](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/auth/secrets.md)
googlecolabでkaggleのデータをダウンロードする。

# 概要
[この記事](https://ichi.pro/kaggle-de-tasetto-o-googlecolab-ni-chokusetsu-daunro-dosuru-220937211860794)をやります。
上の記事で動かなかったらこのqiitaの記事を見てください。

主にやることは以下です。
1. kaggleのAPI keyを取得する(kaggle.jsonの取得)
2. googledriveをgooglecolabにマウントする。
3. driveにkaggle.jsonをアップロードし、pathを指定してcolabからアクセスする。
4. kaggle.jsonとpythonのkaggleを用いてデータのダウンロード


## 1. kaggleのAPIkeyを取得
* kaggleのホームで右上の自分のアイコンをクリック
* 出てきたタブのyour profileをクリック
* 自分のプロファイルの下の列でaccountをクリック
![スクリーンショット 2021-10-19 16.33.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548975/b9682f8f-888e-b75d-71b1-7ff26406a544.png)

* 下にスクロールし、APIの場所でcreate new api tokenをクリック

![スクリーンショット 2021-10-19 16.35.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548975/1dbbab51-2ee0-2143-c3cb-98534b676d4a.png)

これでkaggle.jsonがダウンロードできる。

## 2. googledriveをgooglecolabにマウントする。
適当なnotebook作って、以下を打ち込み、指示に従ってkeyを入力

```python
# Mount google drive
from google.colab import drive
drive.mount('/gdrive')
```

## 3. driveにkaggle.jsonをアップロードし、pathを指定してcolabからアクセスする。

今回はMy Driveのルートにkaggleというフォルダを作りそこに先ほどダウンロードしたkaggle.jsonをアップロードする。
`/My drive/kaggle/kaggle.json`のようになれば良い。
2でマウントした際に`/gdrive`の上にMy driveをマウントしたことになるので、kaggle.jsonにアクセスする際には`/gdrive/My Drive/kaggle/kaggle.json`からアクセスできる。

## 4. kaggle.jsonとpythonのkaggleを用いてデータのダウンロード
```python
!pip install kaggle
```
これを行ってkaggleコマンドのインストール


あとは以下のコマンドで、kaggleフォルダに移動し、kaggleコマンドを使ってデータをダウンロード

```python
# Import OS for navigation and environment set up
import os
# Enable the Kaggle environment, use the path to the directory your Kaggle API JSON is stored in
os.environ['KAGGLE_CONFIG_DIR'] = '/gdrive/MyDrive/kaggle'

# Navigate into Drive where you want to store your Kaggle data
os.chdir('/gdrive/MyDrive/kaggle')
# # Paste and run the copied API command, the data will download to the current directory
!kaggle datasets download -d prasunroy/natural-images
# # Check contents of directory, you should see the .zip file for the competition in your Drive
os.listdir()

```
VsCodeで@も含めて選択できるようにしたい。

#今回の目標
VsCodeで@も含めて選択できるようにしたい

#手順
vscode画面にて
①左上のファイル
②ユーザー設定
③赤丸をクリック
![b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539538/4288b640-a505-cdc3-8674-717614a835b3.png)

④設定setting.jsonに追記

    "[ruby]": {
        "editor.wordSeparators": "`~!$#%^&*()-=+[{]}\\|;:'\",.<>/?"
    },

おわり
wheneverにおいてのcron設定

##環境
Ruby 3.0.2
Rails 6.1.4.1
Docker version 20.10.7
docker-compose version 1.29.2

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

https://e-words.jp/w/cron.html

##cronの設定

- wheneverをインストールしてあることを確認して下記の設定
- cronはコマンド```'分　時　日　月　曜日'```で設定
- 「月曜〜金曜の19時」に実行したい

```config/schedule.rb
...
every '0 19 * * mon-fri' do
  rake 'namespace名:task名'
end
```

設定内容を確認

```
% docker-compose exec app bundle exec whenever
```


cronにデータを反映

```
% docker-compose exec app bundle exec whenever --update-crontab
```

実際のcrontabファイルを確認

```
 % docker-compose exec app bundle exec crontab -l          
```

##参考

https://qiita.com/Esfahan/items/e7a924f7078faf3294f2
nuroルータでwslのインターネット接続が安定しない（HG8045Q）

# 経緯
nuroに変えてからwslのインターネット接続が安定しません。
```apt get install``` などでソフトウェアをインストールするときに「ネットワーク接続がありません」とエラーが出ていました。
何度か同コマンドを試すと通ることもあり、インターネット接続が安定していない状況でした。
なお、windows 11、mac、linuxからでは問題ありませんでした。

# 考えられる原因
調べるとデフォルトで設定されているSonetのDNSサーバーが遅いとあって、これが悪さをしているのではないかと考えました。
googleが無料で公開しているgoogle DNSに変更することにしました。

https://officeforest.org/wp/info/nuro%E5%85%89%E3%82%92%E5%85%A5%E3%82%8C%E3%81%9F%E3%82%89%E3%83%AB%E3%83%BC%E3%82%BF%E3%83%BC%E3%82%92%E8%AA%BF%E6%95%B4%E3%81%99%E3%81%B9%E3%81%97/

# やったこと
1. [192.168.1.1](192.168.1.1)からルーターの管理画面に行く
1. 上タブから「LAN」を選び、横メニューから「DHCPサーバ設定」。プライマリDNSサーバに「8.8.8.8」とセカンダリDNSサーバに「8.8.4.4」をそれぞれ設定する。
![スクリーンショット 2021-10-19 161756.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2192701/a7e382bf-5ac5-1d50-232d-6ed353f839c4.png)

1. 上タブから「IPv6」を選び、横メニューから「DHCPスタティックIP設定」を選択。「LAN側のDNSソース」をプルダウンから「スタティック設定」を選択して、優先DNSに「2001:4860:4860::8888」、予備DNSに「2001:4860:4860::8844」を設定。
![スクリーンショット 2021-10-19 162121.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2192701/e9f35325-bf0d-9177-a4bc-b630ecc92e89.png)
1. 上タブ「システムツール」からルータを再起動する。

# 結果
今のところwslのインターネット接続は安定しています。
wsl以外でも少々早くなった気がします。
バージョン管理の各方法の特徴と違いに関する備忘録（初心者の所感）

※２０２１年１０月１９日時点での最新バージョンを使用した際の体感です。
　主な使用言語がJavaなので、開発環境はそれに寄ったものになってます。
　OS:Windows10

はじめに

　プロジェクトでバージョン管理を行おうと思った際にどれがどのようなサービスを提供しているのか、がわかりにくかったため、備忘録的に記しておこうと思いました。まだまだ初心者のため、足りない部分はあると思いますがご了承ください。
　また、本投稿はバージョン管理の使い方や環境設定の解説ではないため、省かせていただきます。

・Git

　コマンドラインを利用したバージョン管理機能。主にローカルリポジトリでの管理を行う。
　グループでのバージョン管理も可能だがオンラインで共同編集するための機能はない（はず）。

・GitHub

　Gitを用いてオンライン上にリモートリポジトリを作成し、共同編集を可能にしたもの。
　とあるサイトには、GitとGitHubの違いに関して、メールとGmailのような違いとあったが、個人的にはメールサーバとGmailの違いという印象を受けた。要するに、Gitを元にしたサービスがGitHubであり、Gitをインストールしていることが前提となる。

・GitHub Desktop

　GitHubが提供するGUIで管理ができるアプリケーション。
　これをインストールすると内部にGitが組み込まれているようで、Gitを別でインストールしなくてもバージョン管理が可能。GitHubにログインし、ローカルリポジトリの作成、クローンを行い、そのファイルを各種エディタで編集して、アプリ内でコミットやプルプッシュが行える。
　IDEによってはそのIDEの機能の一つとしてバージョン管理が行えるものもあるが、そういったIDEと併用するのは難しそう（二重構造になりそう？）なので上手く使い分けたい。ちなみに、私は見事にこの状態に陥りました。

・AndroidStudio

　GitやGitHubと直接的に連携できるIDEの例として、AndroidStudioを取り上げる。おそらく、というか必ずこのほかにも連携するIDEが多くあると思うが、私が利用したのはこれなので、これについて述べる。
　AndroidStudioの場合、必要となったのは、GitHubへのログイン（これがちょっと曲者）とGitのインストールだった。Gitはすでにパソコン上にインストールされていたとしても、AndroidStudio直下にないとエラーを吐くので恐れずシステムが吐く指示に従ってインストールしていいと思う。また、GitHubへのログインはトークンを生成したりしなきゃいけず、めんどくさかったので別途記事にする（はず）。
　話を戻すと、一度連携できればおそらくすべてAndroidStudio上で完結するので、いちいちアプリの移動は必要ない。

以下は紹介はしますが、記憶が怪しいので余談程度に読んでください。

・SourceTree
　Atlassianが提供するGitHubと連携し、GUIで管理できるアプリケーション。
　会員登録であったり、SSHしか使えなかったりと利用できるまでがめんどくさいが、UIに関してはGitHub　Desktopよりも直感的で使いやすいと感じた。ただし、めんどくさいの方が大きい。

・Eclipse
　私はSourcetreeとこれを連携させてバージョン管理を行なっていました。
　Eclipseでも直接GitHubとつなげそうな感じがしたが、当時の私には方法がわかりませんでした。

最後に

　バージョン管理をしようと思った時に、ローカルでの管理なのかリモートでの管理なのかわかりづらいと感じたので、自分が忘れないためのメモとしても残しておこうと思いました。知識も不十分ですし、文章もわかりにくい点が多いかと思いますが、もし少しでも参考になれば幸いです。
関数定義と再帰関数

# 関数宣言
**関数**とは、JavaScriptおいてオブジェクトの一種であり、同じ処理を1つにまとめて定義したもの。関数を定義することで、同じ処理を繰り返し記述する必要がなくなる。
さらに、オブジェクトのプロパティである関数を**メソッド**と呼ぶ。JavaScriptにおいて、機能的な違いはないが分かりやすくするため呼び方を区別することがある。

```javascript:関数宣言
function <関数名> ( 引数 ){
    // 処理内容
    return <返り値>
}
```

#関数式
**関数式**とは、関数を変数値として変数へ代入できる式のこと。
関数宣言と違い、変数名で参照可能なため、function()の後の関数名は省略することができる。
この関数名を持たない関数を**無名関数**（匿名関数）という。


```javascript:関数式
const <変数名> = function() {
    // 処理内容
    return <返り値>
}
```

# 再帰関数
**再帰関数**とは、関数の処理の中で自分自身を呼び出す関数のこと。
再帰関数を作成する場合は、無限ループにならないように以下の2点に注意する必要がある。
■ **終了条件を設定すること**
■ **繰り返すごとに必ず状態が変化すること**

```javascript:再帰関数の例
function func (n) {
    // 終了条件
    if(n === 0){
        return 1;
    }
    // funcを再帰的呼び出し
    return n * func(n - 1);
}
```

###参考
[https://jsprimer.net/basic/function-declaration/#function-expression](https://jsprimer.net/basic/function-declaration/#function-expression)
WSL2 (Ubuntu 20.04LTS) のターミナルで ls したときのディレクトリの表示色を変える

基本、dircolors で変えればいいのだけど、DIR の色を変えても Windows のファイルシステムの色は変わってくれない。OTHER_WRITEBLE を変えるのがポイントっぽい。

# 手順

WSL2 + Ubuntu 20.04LTS の場合、`~/.bashrc` で `~/.dircolors` が存在していれば自動的に読み込むようになっているので、`~/.colorrc` じゃなくて `~/.dircolors` にします。

```
$ dircolors -p > ~/.dircolors
$ vi ~/.dircolors
```

これで、下記の DIR じゃなくて OTHER_WRITABLE を編集する。01;36 として水色にしてみた。

```.dircolors
RESET 0 # reset to "normal" color
DIR 01;34 # directory
LINK 01;36 # symbolic link. (If you set this to 'target' instead of a
 # numerical value, the color is as for the file pointed to.)
MULTIHARDLINK 00 # regular file with more than one link
FIFO 40;33 # pipe
SOCK 01;35 # socket
DOOR 01;35 # door
BLK 40;33;01 # block device driver
CHR 40;33;01 # character device driver
ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ...
MISSING 00 # ... and the files they point to
SETUID 37;41 # file that is setuid (u+s)
SETGID 30;43 # file that is setgid (g+s)
CAPABILITY 30;41 # file with capability
STICKY_OTHER_WRITABLE 30;42 # dir that is sticky and other-writable (+t,o+w)
OTHER_WRITABLE 01;36 # dir that is other-writable (o+w) and not sticky
STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable
```

vi で編集すると色の指定を変えると、文字の色がその場で変化するのでわかりやすい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/9d34faf1-58ad-1533-6fc9-ce01c62397b2.png)

こんな感じになる。

これで、

```
$ source ~/.bashrc
```

とすれば色が反映される。はず。

色については下記の記事が参考になります。

- [lsコマンドの色を変更する](https://qiita.com/PinkPhayate/items/a670e7e7935baea988f2)
ターゲット・ランタイム Apache Tomcat v8.0 が定義されていません。が出た時の対処法。

たまにeclipseでJUnitテストをやろうとすると、以下のエラーがでるときがある。

ターゲット・ランタイム Apache Tomcat v8.0 が定義されていません。 「プロジェクト名」 不明 ファセット・プロジェクトの問題
#解決法
Eclipseでプロジェクトエクスプローラーの中の、対象プロジェクトを右クリック。
プロパティ>ターゲットランタイム>Tomcat8(Java8)を選択。
kintone REST API Client で全アプリの情報を取得する

以前、レコード前取得を kintone REST API Client で楽にやってみたことがありましたが、
今回はボタンをクリックしたらConsoleに全アプリの情報を取得してくるようなアプリを作ります。

# kintone REST API Client の getApps メソッド

https://github.com/kintone/js-sdk/blob/master/packages/rest-api-client/docs/app.md#getApps

limitというプロパティがあって、一度にとって来れるアプリ情報の件数は 100 までとのこと。

|Name | Type | Description |
|:-:|:-:|:-:|
|limit   |  Number or String | The number of apps to retrieve.<br>Must be between 1 and 100.<br>If nothing is specified, it will default to 100.  |
|offset|Number or String|The number of retrievals that will be skipped.<br>Must be between 0 and <br>2147483647. If nothing is specified, it will default to 0.|

offsetを使って100件ずつ再帰的に取ってくるのがよさそうです👀

# JavaScript

以下2つを準備しておきましょう。

👀**kintone UI Component**

https://kintone-ui-component.netlify.app/ja/

👀**kintone REST API Client**

https://github.com/kintone/js-sdk/tree/master/packages/rest-api-client





```js
// 一覧画面表示後
kintone.events.on(["app.record.index.show"], (event) => {
  // kintone REST API Client の準備
  const client = new KintoneRestAPIClient();

  // メニュー下の余白にボタンを設置する
  const sp = kintone.app.getHeaderSpaceElement();
  const btn = new Kuc.Button({
    text: "ボタン",
    type: "submit",
  });
  sp?.appendChild(btn);

  // ボタンをクリックしたらアプリ情報を再帰的に取得
  btn.addEventListener("click", async () => {
    const resp = await getAppsInfo();
    console.log(resp);
  });

  /**
   * 再帰的にアプリ情報を取ってくる
   * @param ofs オフセット 初期値 0
   * @param appsAry アプリ情報配列 初期値 []
   */
  const getAppsInfo = async (ofs = 0, appsAry = []) => {
    // アプリ情報を取りに行く。res.appsにアプリ情報の配列が格納される。
    const res = await client.app.getApps({
      offset: ofs,
    });
    // 前回までの配列に今とってきたアプリ情報の配列をくっつける
    appsAry.push(...res.apps);

    // 100件ぴったりだったら次もあるかも？ということで再帰的にアプリ情報を取りに行く
    if (res.apps.length === 100) {
      return getAppsInfo(ofs + 100, appsAry);
    }
    // 100件ぴったりじゃなかったらもう取り終わってるのでアプリ情報を返す
    return appsAry;
  };

  return event;
});
```

# 結果

ボタンクリックで全件取ってこれました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/be40af01-19a4-052f-24bb-952dcf2da63b.png)

あとは取ってきたアプリ情報をゴニョゴニョとやってみると、なにかおもしろいアプリ管理用のアプリができるかも？
postgresqlのメモ[追記式]

# 完全に個人用のPostgreSQLのメモ
※ 完全に個人用メモのため，随時追記していきます．
## PostgreSQLをアップデートしたとき
```
To migrate existing data from a previous major version of PostgreSQL run:
  brew postgresql-upgrade-database

This formula has created a default database cluster with:
  initdb --locale=C -E UTF-8 /usr/local/var/postgres
For more details, read:
  https://www.postgresql.org/docs/14/app-initdb.html

To start postgresql:
  brew services start postgresql
Or, if you don't want/need a background service you can just run:
  /usr/local/opt/postgresql/bin/postgres -D /usr/local/var/postgres
```
```
$ cat /usr/local/var/log/postgresql.log

FATAL:  database files are incompatible with server
DETAIL:  The data directory was initialized by PostgreSQL version 13, which is not compatible with this version 14.0.
```
## DBのオーナー変更
```
ALTER DATABESE [DB_NAME] OWNER [OWNER_NAME] TO [NEW_OWNER_NAME];
```
## Role系
### Role一覧
```
\du
```
### Role作成
```
CREATE ROLE [ROLE_NAME];
```
### 権限を持たせてRoleを作成
※ デフォルトのユーザーが持っている権限を例に

```
CREATE ROLE [ROLE_NAME] WITH SUPERUSER CREATEROLE CREATEDB REPLICATION BYPASSRLS;
```
### Roleに権限を与える
※ デフォルトのユーザーが持っている権限を例に

```
ALTER ROLE [ROLE_NAME] SUPERUSER CREATEROLE CREATEDB REPLICATION BYPASSRLS;
```
### Role削除
```
DROP ROLE [ROLE_NAME];
```
ABC214 C - Distribution から学んだ

https://atcoder.jp/contests/abc214/tasks/abc214_c

![abc214c_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/2e8c32c2-7ee9-5571-1837-6536306bd9d1.png)
![abc214c_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/ef167aee-b69d-4869-dd8a-426bb6159335.png)
![abc214c_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/60bcf107-1200-7004-b7db-1b3a28c6dca5.png)
![abc214c_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/9559c423-2f0f-6e37-af7d-5343b7629ab4.png)
![abc214c_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/4acc8854-f301-66e0-bf05-f19803a503fc.png)

だいぶ悩んだ。
####アプローチ1
No1 すぬけさんからスタートする場合、
No2 ,T[2] から宝石を受け取って、 3, 4, ,5 ,6 ... N,1 と No1 すぬけさんに戻るまでの時間
No3 ,T[3] から宝石を受け取って、    4, ,5 ,6 ... N,1 と No1 すぬけさんに戻るまでの時間
                                 ・
                                 ・
の中から最小の時間を求める。

####アプローチ2
No1 が終わったら No2 を基準に start し、アプローチ1 と同じことをやる。
。。多分、for 分は N だけだと足りない。2*N は必要だと気付く。

よし、行ける!!っと思い、思惑通りに書いたつもりだったが、
WA となって、全くそうなってないことに気付く。

```abc214c_ng.py
N = int(input())
S = list(map(int,input().split()))
T = list(map(int,input().split()))
lis = [[T[i]] for i in range(N)]
 
for i in range(1,2*N):
    if i>1:
        lis[i%N].append(lis[(i-1)%N][0] + S[(i-1)%N])#アプローチ
    lis[i%N].append(lis[(i-1)%N][-1] + S[(i-1)%N])   #アプローチ
 
for i in range(N):
    print(min(lis[i]))
```

リスト内のデータが増えていき、どれとどれを使って
演算しなければならないかゴチャゴチャになったために
サンプルが通っただけで、出来たと思い込んでしまった。それが敗因。

####アプローチ3
例えば、すぬけさんを通過する度に最小となる時間を選択することができれば、
シンプルで分かり易いのではないだろうか？
っと考えて以下を書いたら通った。

```abc214c_ok.py
N = int(input())
S = list(map(int,input().split()))
T = list(map(int,input().split()))

lis = [0]*N
lis[0] = T[0]
for i in range(1,2*N):
    lis[i%N] = min(T[i%N],lis[(i-1)%N]+S[(i-1)%N])

for i in range(N):
    print(lis[i])

```

なかなか勉強させてもらった。
記事のタグをselect multipleで 

↓新規投稿画面

```php
<select multiple class="form-control border-success" id="exampleFormControlSelect2" name="tags[]">
    @foreach($tags as $tag)
        <option value="{{$tag->id}}"
                @if(in_array($tag->id, (array)old('tags'))) selected @endif>{{$tag->name}}</option>
    @endforeach
</select>
@if ($errors->has('tags'))
    <span class="text-danger">{{$errors->first('tags')}}</span>
@endif
```

```php
                {{Form::select('tags[]', $tags->pluck('name','id'), null, ['multiple' => true, 'class' => 'form-control border-success', 'id' => 'tag'])}}
                @if ($errors->has('tags'))
                    <span class="text-danger">{{$errors->first('tags')}}</span>
                @endif
```

↓記事編集画面

```php
<select multiple class="form-control border-success" id="exampleFormControlSelect2" name="tags[]">
                        @foreach($tags as $tag)
                            <option value="{{$tag->id}}"
                                    @if(in_array($tag->id , ($articles->tags->pluck('id')->all())) || in_array($tag->id, (array)old('tags')))  selected @endif>{{$tag->name}}</option>
                        @endforeach
                    </select>
                    @if ($errors->has('tags'))
                        <span class="text-danger">{{$errors->first('tags')}}</span>
                    @endif
```


```php
                {{Form::select('tags[]', $tags->pluck('name','id'), $articles->tags, ['multiple' => true, 'class' => 'form-control border-success', 'id' => 'tag']) }}
                @if ($errors->has('tags'))
                    <span class="text-danger">{{$errors->first('tags')}}</span>
                @endif
```
【個人開発】おしゃれ画像とデジタル時計を表示するだけのWebアプリ

# はじめに
[Unsplash](https://unsplash.com)と呼ばれるフォトサイトから取得した画像とデジタル時計を表示するだけのアプリになります。

# 作ったサービス
見た目はこんな感じでシンプルなものにしました。
![Demo_img_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123678/c1600604-9653-ec23-0c3d-60101d08c4a7.png)
アプリはこちら↓

https://photoclock.netlify.app/

GitHub : https://github.com/ur-oot/PhotoClock

# 作ったきっかけは？
前回[こちら](https://qiita.com/ur_oot/items/75af7c38ca93b3ef4fbd)の投稿の通り、初めてWebアプリを作成してまた何かを作りたくなったのと、Macとかを起動してるけど使ってない時間に表示しておくだけのものが欲しくなったからです。
表示するならクオリティーの高い画像と時計くらいがあればいいなと思い、今回作成したWebアプリを作ろうと決めました。

# 使い方
アクセスすると上記の画像のように、画像と時計が表示されます。画像はデフォルトで5分ごとにランダムで更新されます。
画像に関しては冒頭に述べたとおり、知っている方も多いと思いますが、Unsplashと呼ばれるストックフォトサイトのAPIから取得しています。

左上のメニューを選択すると、画像の更新時間とUnsplashのコレクションが選択できるようになっています。
コレクションの画像を選択すると、Unsplashのコレクションサイトに遷移します。"Select this collection"を選択すると、選択したコレクションの画像からランダムに表示するようになります。
![Demo_img_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123678/ce06e6c7-4c89-a9ff-8b82-c1b6e1ee8695.png)

また、表示する際にできるだけスッキリさせたかったので、PWA:Progressive web apps対応をしました。
iPadとかで見ても以下のように表示されます。
![IMG_0032.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123678/3e5a1326-32db-ce30-9ce7-a5a9c2af200a.png)

# 使用技術
## インフラ
- GitHub
- Netlify

## フロントエンド
- HTML
- CSS(SCSS)
- JavaScript
- Vue.js
- Vuex

前回はCSSにフレームワークを利用しましたが、今回はシンプルな作りであるのと、CSSを勉強したいというのがあり、フレームワークは利用しませんでした。

# おわりに
最後まで目を通していただきありがとうございます。
またアプリを作りたいと思っているので、なにかアイデアが浮かべば作りたいと思います。（受け身のアプリではなく、できればユーザーが参加できるアプリにしたい）
自己署名証明書の開発環境においてブラウザの警告表示を消す

# 概要と経緯

- 自己署名した証明書を信頼することになる点をご理解してご利用ください
- Chrome などで 開発環境のHTTPSサーバーに対して REST API でアクセスするときに、 `NET::ERR_CERT_AUTHORITY_INVALID` や `NET::ERR_CERT_COMMON_NAME_INVALID` が発生するのを防ぎたい
- (自己署名証明書の利用時の警告マークを消したい)


![white.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083912/1051afa1-2baa-e333-2a8e-e15581583afc.png)

# 環境

## Server

- AWS
- Ubuntu 20.04.2 LTS
- nginx version: nginx/1.18.0 (Ubuntu)
- OpenSSL 1.1.1f  31 Mar 2020

## Client

- Windows 10 
- Chrome Version 94.0.4606.81 (Official Build) (64-bit)


# Ubuntuでの作業

## 準備

- 対話形式で設定するのが手間がかかるので、ファイルから読み込む形式を採用
- `crt.cnf` と `csr.cnf` を任意のディレクトリに保存する
  - ２つのファイルの内容を適宜書き換える
  - commonName と DNSは統一する（nginxの設定、hostsの設定も含めて）

```
cd /home/ubuntu/
mkdir self_signed_cert
cd self_signed_cert
cp /path/to/crt.cnf .
cp /path/to/csr.cnf .
```


```text:csr.cnf
[ req ]
default_bits       = 2048
distinguished_name = distinguished_name
req_extensions = req_extensions
prompt = no

[ distinguished_name ]
countryName                = JP
stateOrProvinceName        = MyState
localityName               = localityName
organizationName           = MyOrganization
commonName                 = hogehoge.com

[ req_extensions ]
subjectAltName = @alt_names

[ alt_names ]
DNS.1   = hogehoge.com
```

```text:crt.cnf
subjectAltName = DNS:hogehoge.com
```



## 鍵の作成

```
openssl genrsa 2048 > server.key
```

## 証明書署名要求の作成と確認

```
openssl req -new -key server.key -config csr.cnf -out server.csr
openssl req -text < server.csr
```

## 証明書の作成と確認

```
openssl x509 -days 365 -req -sha256 -signkey server.key -extfile crt.cnf < server.csr > server.crt
openssl x509 -text -in server.crt -noout
```

## PKCS #12 の作成

```
openssl pkcs12 -export -in server.crt -inkey server.key -out server.p12
```

## nginx の設定（一部抜粋）

```nginx
ssl_certificate /home/ubuntu/self_signed_cert/server.crt;
ssl_certificate_key /home/ubuntu/self_signed_cert/server.key;

server_name hogehoge.com;
```

# Windows での作業

## hostsの設定

- IPはAWSのグローバルIPを設定

```
100.100.100.100 hogehoge.com
```

## Windowsに証明書をインポート

- 先ほど作成した PKCS #12 `server.p12` を用意
- Chromeから [プライバシーとセキュリティー] - [セキュリティ] - [証明書の管理] を選択
- [信頼されたルート証明機関] - [インポート]
- `server.p12` を選択してインポート

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083912/27a4822b-fcee-914c-e2ea-c02a311db886.png)

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083912/f4650b76-933c-f821-1a0a-5c71c7fbf820.png)


## ブラウザで確認

- 念のためブラウザを再起動
- https://hogehoge.com/
- にアクセスして鍵のマークになることを確認


![success.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083912/f12e01d8-fa26-d59e-b9a6-1fed0cbb2972.png)

# 参考にしたサイト

https://github.com/openssl/openssl/issues/3536

https://qiita.com/nis_nagaid_1984/items/b8f87d41ea108d47af61

https://www.karakaram.com/creating-self-signed-certificate/

https://geekflare.com/san-ssl-certificate/

https://www.globalsign.com/en/blog/what-is-common-name-mismatch-error

https://qiita.com/sanyamarseille/items/46fc6ff5a0aca12e1946

https://stackoverflow.com/questions/49862701/nginx-neterr-cert-common-name-invalid
【Unity】デザインパターン トラブルシューティング

# オブザーバーパターンの購読設定を起動時非アクティブなオブジェクトのAwake内で実行すると購読登録できていない
初回のアクティブ時にAwakeが実行されるので、アクティブになるまではSubscriveが実行されない。
〇〇Manager的な管理用オブジェクトのAwakeから登録するのが無難。（他に良い方法があればコメントお願いします。）
Databricksにおけるモデル推論

[Model inference \| Databricks on AWS](https://docs.databricks.com/applications/machine-learning/model-inference/index.html) [2021/10/4時点]の翻訳です。

モデルレジストリに登録されたモデルに対して、バッチ推論のために[自動でノートブックを生成](https://docs.databricks.com/applications/machine-learning/manage-model-lifecycle/index.html#generate-inference-nb)したり、オンラインサービングのためのモデルの設定を行うことができます。

MLlibとXGBoost4Jモデルを用いたスケーラブルなモデル推論においては、Saprkデータフレームに対して推論を直接実行するために、ネイティブな`transform`メソッドを使用してください。推論ステップを含む[MLlibサンプルノートブック](https://docs.databricks.com/applications/machine-learning/train-model/mllib/index.html#example-notebooks)をご覧ください。

他のライブラリ、モデルタイプに対しては、大規模データセットにスケールアウトするように、Spark UDF(ユーザー定義関数)を作成してください。小規模データセットに対しては、ライブラリが提供するネイティブなモデル推論ルーチンを使用してください。

モデルがMLflowに登録されている場合には、[Spark UDFを作成](https://www.mlflow.org/docs/latest/python_api/mlflow.pyfunc.html#mlflow.pyfunc.spark_udf)することができます。そうでない場合には、機械学習モデルをラップするために[pandasのイテレーターUDF](https://docs.databricks.com/spark/latest/spark-sql/udf-python-pandas.html)を使用してください。

ストリーミングアプリケーションにおいては、Apache Sparkの[構造化ストリーミングAPI](https://docs.databricks.com/spark/latest/structured-streaming/index.html)を使用してください。[MLlib pipelines and Structured Streaming example](https://docs.databricks.com/applications/machine-learning/train-model/mllib/index.html#mllib-pipelines-and-structured-streaming-example)を参照ください。

以下の文章では、Databricksにおけるディープラーニングモデルの推論の紹介をしています。

- [Deep learning model inference workflow](https://docs.databricks.com/applications/machine-learning/model-inference/dl-model-inference.html)
- [Deep learning model inference examples](https://docs.databricks.com/applications/machine-learning/model-inference/dl-model-inference-examples.html)
- [Deep learning model inference performance tuning guide](https://docs.databricks.com/applications/machine-learning/model-inference/model-inference-performance.html)
- [Databricksにおける機械学習リファレンスソリューション](https://qiita.com/taka_yayoi/items/4ca350a3cf1ddc3fd782)

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
Databricksにおけるモデル開発のトラッキング

[Track model development \| Databricks on AWS](https://docs.databricks.com/applications/machine-learning/track-model-development/index.html) [2021/10/14時点]の翻訳です。

モデル開発のプロセスはイテレーティブなものであり、モデルを開発、最適化していく際の作業を追跡し続けるのは困難なものです。Databricksにおいては、トライしたパラメーターの設定や組み合わせや、それがどの程度のパフォーマンスを示したのかを含むモデル開発プロセスの追跡を支援するために[MLflowトラッキング](https://mlflow.org/docs/latest/tracking.html)を活用することができます。

MLflowトラッキングは、モデル開発を記録し追跡するために、*エクスペリメント*と*ラン*を用います。ランはモデルコードの単一の実行処理です。MLflowのランにおいては、モデルのパラメーターと結果を記録することができます。エクスペリメントは関係するランのコレクションです。エクスペリメントでは、モデルのパフォーマンスがどの程度か、パフォーマンスがパラメーターの設定、入力データなどにどのように依存するのかを理解するために、ランを比較、フィルタリングすることができます。

本書のノートブックでは、モデル開発を追跡するためにMLflowを用いてすぐに使い始められるようにするためのシンプルなサンプルを説明します。DatabricksにおけるMLflowトラッキングの使い方の詳細に関しては、[Databricksにおける機械学習トレーニングのトラッキング](https://qiita.com/taka_yayoi/items/ba0c7f46ff7c3dbf87bb)をご覧ください。

> **注意**
MLflowは、Jobs APIの[spark\_submit\_task](https://docs.databricks.com/dev-tools/api/latest/jobs.html)でサブミットされたジョブをサポートしていません。代わりに、Sparkコードを実行するためには[MLflow Projects](https://docs.databricks.com/applications/mlflow/projects.html)を利用してください。

# モデル開発トラッキングにオートロギングを使う

MLflowは、数多くのMLフレームワークで記述されたトレーニングコードを自動で記録することができます。これは、MLflowトラッキングを使い始めるには一番が簡単な方法です。

このノートブックでは、[scikit\-learn](https://scikit-learn.org/stable/index.html)によるオートロギングをどのように使うのかを説明しています。他のPythonライブラリのオートロギングに関しては、[MLflowにおけるトレーニングランのオートロギング](https://qiita.com/taka_yayoi/items/dd81ac0da656bf883a34#%E3%83%A9%E3%83%B3%E3%81%AE%E8%87%AA%E5%8B%95%E3%83%AD%E3%82%AE%E3%83%B3%E3%82%B0)を参照ください。

## MLflowオートロギングクイックスタートPythonノートブック

https://docs.databricks.com/_static/notebooks/mlflow/mlflow-quick-start-python.html

# モデル開発トラッキングにlogging APIを使う

このノートブックでは、MLflowのlogging APIの使い方を説明します。logging APiを用いることで、記録すべきメトリクスに対するコントロールを強化することができ、テーブルやプロットなどの追加のアーティファクトを記録することができます。

このサンプルノートブックでは、[Python logging API](https://mlflow.org/docs/latest/python_api/index.html)の使い方を説明します。MLflowでは[REST、R、Java API](https://mlflow.org/docs/latest/tracking.html)を使用することもできます。

## MLflow logging APIクイックスタートPythonノートブック

https://docs.databricks.com/_static/notebooks/mlflow/mlflow-logging-api-quick-start-python.html

# エンドツーエンドのサンプル

このチュートリアルノートブックでは、データのロード、データの可視化、ハイパーパラメーター最適化の並列処理、MLflowを用いた結果のレビュー、モデルの登録、そして、Spark UDF(ユーザー定義関数)として登録したモデルを用いて、新規データに対する推論までを含む、Databricksにおけるモデルトレーニングのエンドツーエンドのサンプルを説明します。

## 要件

Databricksランタイム6.5ML以降

## サンプルノートブック

https://github.com/taka-yayoi/public_repo/tree/main/mlflow_end_to_end


### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
MiniKubeで永続ストレージ

Minikubeのインストールまでは終わったとして、永続ストレージのyamlファイルメモ
0, Minikubeインストール
1, PersistentVolume (PV)
2, PersistentVolumeClaim(PVC)

#0, Minikubeインストール
　https://qiita.com/Taroi_Japanista/items/798d67db3c4c50b53d59


#1,PersistentVolume (PV)


PVは永続的ストレージつまり実際のストレージリソースの設定ですね。
pv0001.yamlという名前でファイルを作成して、それをkubectlでapllyします。
  
```
$sudo vi pv0001.yaml
ファイルの中身

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv0001
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  capacity:
    storage: 5Gi
  hostPath:
    path: /data/pv0001/
```
実効コマンド

```
$ kubectl apply -f pvc0001.yaml
persistentvolume/pv0001 created
```
ちゃんとできているか確認
ここで見えているボリュームが実際に使えるストレージ容量になります。

```
$ kubectl get pv

NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM STORAGECLASS   REASON   AGE
pv0001   5Gi        RWO            Retain           Available           manual                  38s
```

-------------------------------------------------
#2,PersistentVolumeClaim(PVC)

PVCは、ユーザーからの使用したいストレージ要求ですね。
pvc0001.yamlという名前でファイルを作成して、それをkubectlでapplyします。


```
$sudo vi pvc0001.yaml
5GBを要求する場合のファイルの中身
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: task-pv-claim
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
```
実効コマンド

```
$ kubectl apply -f pvc0001.yaml
```
確認

```
$ kubectl get pv,pvc
NAME                      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                   STORAGECLASS   REASON   AGE
persistentvolume/pv0001   5Gi        RWO            Retain           Bound    default/task-pv-claim   manual                  2m49s

NAME                                  STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/task-pv-claim   Bound    pv0001   5Gi        RWO            manual         19s
```

ダッシュボードでも確認でしました。
![minikube_persistent Volume03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478729/92cde925-138b-0b51-e054-6a7fc0b69939.png)


--------
お次はCSIドライバーかな。。
w2ui(grid)のデータソースとしてSeaside(Pharo)を使う

## はじめに
w2uiのgridはスクロールに伴いオンデマンドでサーバーからデータを取得することで無限スクロールを可能とするグリッドライブラリです。
ここでは、w2ui(grid)のデータソースとしてSeaside(Pharo)を使うサンプルを紹介します。

## 動作した環境
|項目|内容|
|---|---|
|サーバー|Pharo8.0.0＋seaside3||
|クライアント|Google Chrome|
|javascriptライブラリ|w2ui 1.5|

## ソースコード
※稼働中のプログラムの一部をコピペしただけで、このサンプルが動作するかの検証は行っていません。
# javascript
```javascript:javascriptサンプル
$(function() {
    $("#grid").w2grid({
        name: "grid",
        limit:  50,
        url: "dummy",
        recid: "id",
        columns: [
            { field: "id", text: "id", size: "40px", hidden: true },
            { field: "お名前", text: "お名前", size: "100px", sortable: true }
        ],
        onRequest: function(event) {
            const data = eval('(' + document.getElementById("data").innerHTML + ')');
            event.url = document.getElementById("url").innerHTML + '?' + data.replace(/&amp;/g, "&");
        }
    });
});
```
* limitプロパティで１回あたりにサーバーから取得するレコード数を指定しています
* w2gridがサーバーにデータをリクエストする直前にonRequestイベントが発火するので、そこでリクエスト先のURLを上書きしています。
* リクエスト先URLはPharo側でspan要素にセットされた情報を元に生成します

# Pharo
#### htmlレンダリング
```smalltalk:renderContentOnメソッド
renderContentOn: html
	| req |
	html div style:'display:none;'; with:[
		req := html jQuery ajax callback:[
			| param |
			param := NeoJSONReader fromString: (self requestContext request fields at: 'request').
			self createResponse: (
				self getList: param
			) contentType: 'application/xml'.
		].
		html span id:'url'; with: (req options at:'url').
		html span id:'data'; with: (req options at:'data').
	].
	html div id:'grid'; style:'width: 1200px; height: 500px; margin-top: -1px;'.
```
* jQuery ajax callback:[]でリクエスト先のコールバックを定義しています
* コールバックオブジェクトからリクエスト先URLの情報を取得して、idがdataとurlというspan要素にその情報をセットしています
* requestContextからリクエストパラメータを抽出して変数parmにセットしています
* createResponseがクライアントに検索結果を返します（getListメソッドが検索を実行）

#### 検索実行
```smalltalk
getList: param
	| total records |
	"ここにSQLサーバーからレコードを取得するコードを書きます"
	"変数paramにはw2gridから送られてきた検索条件が入っています"
	"（SQL文の例）'SELECT id,お名前 FROM hoge LIMIT ', (param at: 'limit') asString , ' OFFSET ',(param at: 'offset') asString"
	^ NeoJSONWriter toString: 
		(Dictionary new
			at: 'status' put: 'success';
			at: 'total' put: total;
			at: 'records' put: records;
			yourself
		)
```
* 変数totalには検索にヒットしたレコード数をセットします
* 変数recordsには今回クライアントに返すレコードの配列をセットします
* レコード取得部分は省略します

#### ライブラリの読み込み
```smalltalk
updateRoot: anHtmlRoot
	super updateRoot: anHtmlRoot.	
	anHtmlRoot beHtml5.
	anHtmlRoot stylesheet url: 'path/to/css/w2ui-1.5.min.css'.
	anHtmlRoot javascript url: 'path/to/libs/jquery3.5.1.min.js'.
	anHtmlRoot javascript url: 'path/to/libs/w2ui-1.5.min.js'.
```

## まとめ
w2uiを使えば、たったこれだけの少ないコード記述でグリッドを使ったWEBアプリの作成が可能であることがわかっていただけると思います。
（お知らせ）シアトルで実践する「プログラミング的思考」というマガジン（無料）を note に書きました

https://note.com/ywatanabe/m/m9b7fa90063d1

クロス投稿になりますが、note の方に、14本の記事をマガジンにしてまとめました。無料です。（そもそも、在米で日本に銀行口座がない自分には無料のオプションしかないんです・・）

「プログラミング的思考」という造語（？）はつかみどころがないし、誤解を招きやすい言葉だと感じます。そう思われる方もたくさんいらっしゃるのではないかと思います。

- 「プログラミングはソフトウェア開発のほんの一部の作業だ」
- 「プログラミングというよりコンピュータサイエンスじゃない？」
- 「具体的にどんな思考（考え方）を指して言っているの？」

そういった意見や疑問もあると思います。

私はただの開発者ですが、自分がMicrosoft本社で仕事をする上で自ら実践していたり、同僚が実践している「ソフトウェア開発に必要な考え方」という視点から「プログラミング的思考」（＝コンピュータ資源を活用して問題解決をするために使う考え方）を解説してみました。
認証メールを飛ばさない

現在作っているアプリの認証にdeviseを用いているのですが、それにgoogle認証を付け加えたいと思っています。
google認証に関しては以下の記事を参考にして追加してください

https://qiita.com/d0ne1s/items/e1ee23ea23343d6aaa34

user認証時に確認メールを飛ばす設定をしているので、確認ができないとuserの登録ができないようになっています。
ですが、googleアカウントを登録する際はその確認メールがいらないと思うのでどうしようか悩みました。


deviseのconfirmable
これは送られてきた確認メールに記載されているリンクをクリックするとトークンを取得できconfirmed_atに値が入ります
これがnilのままだと登録できないのでgoogleアカウントを用いたuser情報を作成した時にconfirmed_atを入れるようにします。

```ruby:user.rb
  def self.from_omniauth(auth)
    where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
      user.email = auth.info.email
      user.nickname = auth.info.name
      user.password = Devise.friendly_token[0,20]
    end
  end
```

現在こんな感じでgoogleの情報をとっています。
・gmailアドレス
・googleアカウント名
・ランダムのパスワード
ここに付け加えてconfirmed_atを作成します。

まずはconfirmed_atにどんな値があるか確認したいので、テストとして適当なアカウントをアプリに登録します
その後コンソールでuserの中身を見てみましょう！

```
rails c
#コンソール立ち上げ

User.all
#全userを取得

@user = User.find(1)
#1番のuserの情報を@userに入れる
```

これを実行するとuserの情報が取得できるのでそこで

```
@user.confirmed_at #を実行すると

=> Fri, 15 Oct 2021 15:10:13 JST +09:00
```

確認メールをクリックした瞬間の時間が入っていると思いますので、同じようなことをuser.rbに書きます。

```
  def self.from_omniauth(auth)
    where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
      user.email = auth.info.email
      user.nickname = auth.info.name
      user.password = Devise.friendly_token[0,20]
      user.confirmed_at = Time.current
    end
  end
```

付け加えたのは`Time.current`つまり現在の時間です
googleで認証した瞬間のtimeを入れるのでconfirmed_atがnilにならず確認メールと同じ型のデータが入ることがわかりました。
時間の設定はconfig/applicationでtimezoneをtokyoとしているので、設定していない人とは時間が違うかもしれませんのでご確認ください

これでgoogleで認証後、googleアカウントに紐づけてnickname,email,passwordカラムを取得できるようになりました！

ですかこれではまだメールが送られてしまうので、送られないようにします。

```
skip_confirmation!
```

というヘルパーメソッドを使用することで確認メールの送信をスキップすることができます！
これを先ほどのコードに入れると

```
  def self.from_omniauth(auth)
    where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
      user.email = auth.info.email
      user.skip_confirmation!
      user.nickname = auth.info.name
      user.password = Devise.friendly_token[0,20]
      user.confirmed_at = Time.current
    end
  end
```

最後にちゃんとconfirmed_atが追加されているかの確認と、google認証を使わず、そのままメールアドレスを使った新規登録した場合にちゃんとメールが送られてくるのを確認できたら実装完了です！
Databricksにおけるモデルのトレーニング

[Train models \| Databricks on AWS](https://docs.databricks.com/applications/machine-learning/train-model/index.html) [2021/6/11時点]の翻訳です。

このセクションでは、Databricksにおける機械学習、ディープラーニングモデルのトレーニングの方法を、著名なライブラリを用いたサンプルを用いて説明します。また、、モデルトレーニングに用いるデータセットの準備、scikit-learn、XGBoostなどのオープンソースライブラリを用いた一連のトライアルの実行を自動で行い、ソースコードを参照、レビュー、修正できるようにするためのそれぞれのランに対応するソースを含むPythonノートブックを生成する[Databricks AutoML](https://qiita.com/taka_yayoi/items/0ed860131a02aeade14f)を活用することもできます。

- [機械学習](https://docs.databricks.com/applications/machine-learning/train-model/machine-learning.html)
    - [scikit\-learn](https://docs.databricks.com/applications/machine-learning/train-model/machine-learning.html#scikit-learn)
    - [MLlib](https://docs.databricks.com/applications/machine-learning/train-model/machine-learning.html#mllib)
    - [XGBoost](https://docs.databricks.com/applications/machine-learning/train-model/machine-learning.html#xgboost)
- [ディープラーニング](https://docs.databricks.com/applications/machine-learning/train-model/deep-learning.html)
    - [Get started with TensorFlow Keras in Databricks](https://docs.databricks.com/applications/machine-learning/train-model/keras-tutorial.html)
    - [TensorFlow](https://docs.databricks.com/applications/machine-learning/train-model/tensorflow.html)
    - [PyTorch](https://docs.databricks.com/applications/machine-learning/train-model/pytorch.html)
    - [Distributed training](https://docs.databricks.com/applications/machine-learning/train-model/distributed-training/index.html)
    - [Deep Learning Pipelines](https://docs.databricks.com/applications/machine-learning/train-model/deep-learning-pipelines.html)
- [ハイパーパラメーターチューニング](https://docs.databricks.com/applications/machine-learning/automl-hyperparam-tuning/index.html)
    - [Automated MLflow tracking](https://docs.databricks.com/applications/machine-learning/automl-hyperparam-tuning/index.html#automated-mlflow-tracking)
    - [Hyperparameter tuning with Hyperopt](https://docs.databricks.com/applications/machine-learning/automl-hyperparam-tuning/index.html#hyperparameter-tuning-with-hyperopt)

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
Pythonプログラミング：urllib.requestを使ったtimeoutを指定したHTTPリクエスト発行


# はじめに

Tipsです。
Webサイトを対象に（Sleepを入れて負荷をかけないように）スクレイピングをしていました。
が、時折ハングアップしてしまう場面にも直面していました。

・・・はい、timeoutの設定が漏れてました。
そのため、応答があるまで待ち続けてしまっていました（≒ハングアップの状況）。

というわけで、HTTPリクエストを発行する処理を見直したいと思います。

## 本稿で紹介すること

- urllib.requestを使ったHTTPリクエストの発行

尚、筆者は以下のVersionで動作確認をしています。
  - Python: 3.6.10

# サンプルコード

結論だけ、BeforeとAfterのCodeを紹介。

## Codeを紹介

端的に言えば、urlopen関数で、timeoutパラメータを指定するだけです。
以下、Code例です。
元のCode全体は、**[こちら](https://qiita.com/Blaster36/items/680000a7479e3a90857f)**を参照されたし。

```python:Before
def get_links_paging(query=None, page=None):
    print(URL.format(urllib.parse.quote_plus(query, encoding='euc-jp'), page))
    try:
        # HTTPリクエストヘッダーにUser Agentを設定
        req = Request(URL.format(urllib.parse.quote_plus(query, encoding='euc-jp'), page), data=None, headers={'User-Agent': USER_AGENT})
        with urlopen(req) as res:
            # HTMLドキュメントからBeautifulSoupを初期化
            soup = BeautifulSoup(res.read().decode('euc_jp', 'ignore'), 'html.parser')
```

```python:After
def get_links_paging(query=None, page=None):
    print(URL.format(urllib.parse.quote_plus(query, encoding='euc-jp'), page))
    try:
        # HTTPリクエストヘッダーにUser Agentを設定
        req = Request(URL.format(urllib.parse.quote_plus(query, encoding='euc-jp'), page), data=None, headers={'User-Agent': USER_AGENT})
        # Timeout（10秒）を設定してHTTPリクエストを発行
        with urlopen(req, timeout=10) as res:
            # HTMLドキュメントからBeautifulSoupを初期化
            soup = BeautifulSoup(res.read().decode('euc_jp', 'ignore'), 'html.parser')
```

これで、待ち惚けは解消されます。
timeoutを迎えると、以下のようなメッセージを出して、処理を継続するようになりました。

```python:
Exception:  The read operation timed out
```

ちなみに、requestsモジュールでもtimeoutの設定はできます。
こちらもデフォルトだと、HTTPリクエストはtimeoutしません。

# まとめ
urllib.requestを使ったtimeoutを指定したHTTPリクエスト発行する方法を紹介。
HTTPリクエストを発行して、数秒待って応答がなければエラーとして処理しましょう。
大量にデータを集めたいときは、いちいち立ち止まっていられません！timeout設定ありきで前進あるのみ！！
GitHub Flowについて

Gitを学習する中で、GitHub社の開発ワークフローがあることを知ったので、
今後開発業務を行う中で、参考にできればと思い備忘

# GitHub Flowの流れ

- ローカルリポジトリ
    1. masterブランチからブランチを作成
    2. ファイルを変更しコミット
    3. 同名のブランチをGitHubへプッシュ
- リモートリポジトリ
    1. プルリクエストを送る
    2. コードレビューをし、masterブランチにマージ
    3. masterブランチをデプロイ

# ポイント

- masterブランチは常にデプロイできる状態を保つ
- 新開発はmasterブランチから新しいブランチを作成してスタート
- 作成した新しいブランチ上で作業してコミットする
- 定期的にPushする
- masterにマージするためにプルリクエストを使う
- 必ずレビューを受ける
- masterブランチにマージしたらすぐにデプロイする
    - テストとデプロイ作業は自動化
<br>
<br>

初めてGitを導入したりする場合は、まずこのやり方でやってみるとやりやすそう。
tqdmのプログレスバーを非表示にしたい

# なに
tqdmのプログレスバーを非表示にする方法。
# 方法
`disable=True`にすればよい。

```python
from tqdm import tqdm

hide_progress_bar = True
hoge = list(range(100))

for num in tqdm(hoge, disable=hide_progress_bar):
   num = num ** 100000
```

# Background
`nohup`使って学習プログラムを回しているとき、うっかり`tqdm`のプログレスバーを表示させていると、出力ログがえらいことになる。もはや人災。

そこで、こういうシチュエーションではプログレスバーを非表示にしてログをスッキリさせたい。

# 参考
https://github.com/tqdm/tqdm/issues/1
Git基礎まとめ

今更感あるが、改めてGitを学習したのでその備忘
基本的なことのまとめの為、細かいコマンドなどは省略

#Gitのデータ構造
- gitはスナップショットで記録する
    - データを圧縮してスナップショットで保持している
    - 差分保存だとブランチを切るときに時間がかかる
- コミットが直前のコミットを記録している
    - 変更履歴をたどることができる
- リポジトリは履歴データのデータベース
- gitとは3つのエリアがある
    - ワークツリー→ステージ→リポジトリ
- ステージはコミットの準備
    - 変更分だけ記録する
- リポジトリはスナップショットを記録

# バージョン管理してたくないファイル

- .gitignoreファイルを作成する
    - 自動生成ファイルやパスワード記載ファイルなどの載せたくないファイル

#addとcommitとpush

- 作業して変更したファイルの反映
- git add
    - ワークツリー→ステージ
- git commit
    - ステージ→ローカルリポジトリ
- git push
    - ローカルリポジトリ→リモートリポジトリ
  

# fetchとpull

- fetchを基本的に使う方が良い
    - fetchでリモートリポジトリからローカルリポジトリへ変更を反映
    - mergeでワークツリーに反映
- pullはfetchとmergeを同時に行う
- pullは別のブランチで使うと統合するつもりがなくともmergeされてしまう

# ブランチ

- 複数の機能を同時並行で開発するための仕組み
- ブランチを分岐させれば他の人の変更の影響を受けない
- ブランチはコミットIDを記録したポインタ
- HEADは作業ブランチへのポインタ
- Gitはブランチの作成や切り替え、マージが他のバージョン管理ツールより高速

# コンフリクト関連の事故が起きにくい運用ルール

- 複数人で同じファイルを変更しない
- pullやmergeをする前に変更中の状態をなくしておく
- pullするときは、pullするブランチに移動してかたpullする
- コンフリクトしても慌てない

# ブランチを利用した、開発の流れ

- masterブランチをリリース用、トピックブランチを開発用に作成して進めるのが基本
    - バグが起きた時に前のバージョンに簡単に戻せる

# プルリクエスト

- 手順
    1. masterブランチを最新に更新
    2. ブランチを作成
    3. ファイルを変更
    4. 変更をコミット
    5. GitHubへプッシュ
    6. プルリクエストを送る
    7. コードレビュー
    8. プルリクエストをマージ
    9. ブランチを削除

# リベース

- 変更を統合する際に、履歴をきれいに整えるために使うのがリベース
- マージとの違い
    - リベースは履歴が一直線
    - マージは枝分かれ
- GitHubにプッシュしたコミットをリベースするのはNG

# マージかリベースか

- マージ
    - メリット
        - コンフリクトの解決が比較的簡単
    - デメリット
        - マージコミットがたくさんあると履歴が複雑化する
- リベース
    - メリット
        - 履歴をきれいに保つことができる
    - デメリット
        - コンフリクトの解決が若干面倒（コミットそれぞれに解消が必要）
- 作業の履歴を残したい場合・・・マージ
- 履歴をきれいにしたい場合・・・リベース
- 基本的な方針
    - プッシュしてないローカルの変更にはリベースを使い、プッシュした後はマージを使う
    - コンフリクトしそうならマージを使う
- プルのマージ型
    - 通常の形
    - マージした記録を残したい場合
- プルのリベース型
    - —rebaseをつける
    - 記録が残らないので、GitHubの内容を取得したいだけの時
nuxt/vuetifyでクリックしたら数秒表示されるツールチップが使いたい

「コピーする」ボタンをクリックしたときに、対象をクリップボードにコピーし、わかりやすいようにツールチップで `コピーしました！` 的なのを表示したかった。
あと一定時間経過したら消えて欲しかった。
今回は1秒。

補足ですが、クリップボードへのコピーはこちらを利用しました。

https://github.com/webcore-it/nuxt-clipboard2

# ツールチップ とは

引用: [ウィキペディア > ツールチップ](https://ja.wikipedia.org/wiki/%E3%83%84%E3%83%BC%E3%83%AB%E3%83%81%E3%83%83%E3%83%97)

この言葉がわかんなくて情報探すの苦労した

vuetifyの該当ページは以下

https://vuetifyjs.com/ja/components/tooltips/

既存の設定値だけでどうにかなるかと思ったけど、ならなかったりバギーだったりで諦めた

# 実装

```vue
<template>

  （略）

  <v-tooltip right nudge-bottom="30" v-model="showCopied">
    <template v-slot:activator="{}">
      <v-btn color="primary" class="mx-auto" @click="clickCopy()">
        コピーする
      </v-btn>
    </template>
    <span>コピーしました</span>
  </v-tooltip>

  （略）

</template>

<script lang="ts">
import { Component, Vue } from "nuxt-property-decorator";

declare module "@nuxt/types" {
  interface Context {
    $copyText: any;
  }
  interface NuxtAppOptions {
    $copyText: any;
  }
}

declare module "vue/types/vue" {
  interface Vue {
    $copyText: any;
  }
}

@Component
export default class HogeComponent extends Vue {
  showCopied = false;
  targetText = "";

  // なにかをトリガーに targetText に値入れたりする処理など（省略）

  async clickCopy() {
    try {
      await this.$copyText(this.targetText);
      this.showCopied = true;
    } catch (e) {
      console.log(e);
    } finally {
      await this.sleep(1000);
      this.showCopied = false;
    }
  }

  sleep(msec: number): Promise<void> {
    return new Promise(resolve => setTimeout(resolve, msec));
  }
}
</script>

```

こんな感じ。
ボタンをクリックすると右下にツールチップが表示され、1000ms（=1秒）で消える。

|![スクリーンショット 2021-10-19 13.04.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213486/e558b821-36ca-9610-99e6-a27de13276d3.png)|
|:--|

めっちゃ雑な動くサンプル

https://codepen.io/ssugo/pen/PoKzodV
【Swift】パスワード入力の際にUITextFieldを黒丸で隠す方法

パスワード入力の際にUITextFieldを黒丸で隠す方法のメモ

```swift
let tf = UITextField()
tf.isSecureTextEntry = true
```
OFFにしたい時はtrueをfalseにする。

## Swiftのお役立ち情報

https://wagtechblog.com/programing/swift-iphone-application-school

https://wagtechblog.com/programing/swift-textbook.html
インスタ自動いいねBOTを作る

今回はGASを使ってサーバーレスでインスタいいねBOTを定期実行させます
GASは超初心者です

# GASの使い方
こちらを参考にGASのプロジェクト作成してください

https://www.astina.co/media/system/post-1137

# 流れ
タグを選択
↓
タグ検索
↓
最新から10件の投稿IDを取得
↓
いいね(10回ループ)

# 必要データ
①sessionid
②csrftoken

この2つが必要です
自分もよく分かっていませんが「ログイン時に割り当てられる個人ID」と「アカウントを操作するのに必要なトークン」だと勝手に思っています

これらはデベロッパーツールから確認することができます

# 必要データの取得方法
①自分のインスタアカウントにログインする
②デベロッパーツールを開く(開き方が分からない場合ググってください)
![スクリーンショット 2021-10-19 13.04.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/418010ba-b6d3-0359-c678-d0e847a811ea.png)

# 使用API
検索
https://www.instagram.com/explore/tags/検索ワード/?__a=1

いいね
https://www.instagram.com/web/likes/投稿ID/like/

# ソースコード
```javascript
var headers = {
　　　　　　　　"cookie":"sessionid=ここに自身のsessionid;",
    "x-csrftoken":"ここに自身のx-csrftoken"
};

function SELECT_TAG() {
  try {
    var tags = [
      "like4like",
      "l4l",
      "follow4follow",
      "f4f",
      "tflers",
      "%EC%A2%8B%EC%95%84%EC%9A%94%EB%B0%98%EC%82%AC",
      "%E3%81%84%E3%81%84%E3%81%AD%E8%BF%94%E3%81%97"
    ];
    var tag = tags[Math.floor(Math.random()*tags.length)];
    return tag;
  } catch(error) {
    console.log("SELECT_TAGでエラー発生")
  };
};

function GET_ID_LIST() {
  try {
    var tag = SELECT_TAG();
    var url = "https://www.instagram.com/explore/tags/" + tag + "/?__a=1";
    var options = {
      "method" : "get",
      "headers" : headers
    };
    var reply = UrlFetchApp.fetch(url, options);
    var json = JSON.parse(reply);
    var data = json["data"]["recent"]["sections"];
    var ID_LIST = [];
    for(var i=0; i<data.length; i++) {
      var id_num = data[i]["layout_content"]["medias"][0]["media"]["id"]
      var id = id_num.slice(0,id_num.indexOf("_"))
      ID_LIST.push(id);
    };
    return ID_LIST;
  } catch(error) {
    console.log("GET_ID_LISTでエラー発生")
  };
};

function Create_Favorite() {
  try {
    var ID_LIST = GET_ID_LIST();
    for (var i in ID_LIST) {
      var url = "https://www.instagram.com/web/likes/" + ID_LIST[i] + "/like/";
      var options = {
        "method" : "post",
        "headers" : headers
      };
      var ResponseCode = UrlFetchApp.fetch(url, options).getResponseCode();
      console.log(ResponseCode);
    };
  } catch(error) {
    console.log("Create_Favoriteでエラー発生");
  };
};
```

あとはトリガーを設定するだけで定期実行してくれます

え、、GASって神...？？
【Swift】入力された郵便番号と都道府県が正しい情報か確認する

iOSアプリなどで住所を入力してもらう際に、郵便番号と都道府県が一致しているか確認する際のコード。

コードはあまり美しくありませんがご了承ください。

CLGeocoderを使って郵便番号から都道府県を出力させ、入力値との相違を確かめるのですが、CLGeocoderから出力される都道府県名はローマ字。

そこでCLGeocoderで出力されるローマ字とユーザーが入力する日本語の都道府県名を一致させるための辞書を作る。

```swift
let RomeKanjiPrefecture = ["北海道": "Hokkaido","青森県": "Aomori","岩手県": "Iwate","宮城県": "Miyagi",
"秋田県": "Akita","山形県": "Yamagata","福島県": "Fukushima","茨城県": "Ibaraki",
"栃木県": "Tochigi","群馬県": "Gunma","埼玉県": "Saitama","千葉県": "Chiba",
"東京都": "Tokyo","神奈川県": "Kanagawa","新潟県": "Niigata","富山県": "Toyama",
"石川県": "Ishikawa","福井県": "Fukui","山梨県": "Yamanashi","長野県": "Nagano",
"岐阜県": "Gifu","静岡県": "Shizuoka","愛知県": "Aichi","三重県": "Mie",
"滋賀県": "Shiga","京都府": "Kyoto","大阪府": "Osaka","兵庫県": "Hyogo",
"奈良県": "Nara","和歌山県": "Wakayama","鳥取県": "Tottori","島根県": "Shimane",
"岡山県": "Okayama","広島県": "Hiroshima","山口県": "Yamaguchi","徳島県": "Tokushima",
"香川県": "Kagawa","愛媛県": "Ehime","高知県": "Kochi","福岡県": "Fukuoka",
"佐賀県": "Saga","長崎県": "Nagasaki","熊本県": "Kumamoto","大分県": "Oita",
"宮崎県": "Miyazaki","鹿児島県": "Kagoshima","沖縄県": "Okinawa"]
```

あとはユーザーの入力した都道府県名と郵便番号をもってくるだけ。

```swift

//都道府県を格納しておく変数
var prefecture : String = "東京都"


//郵便番号のバリデーション
CLGeocoder().geocodeAddressString("0000000", completionHandler: {(placemarks, error) -> Void in
    //存在しない郵便番号
    if((error) != nil){
        print("郵便番号が存在しない")
    }
    if let placemark = placemarks?.first {
        //郵便番号と県名が異なる(日本語とローマ字)
        if placemark.administrativeArea != self.prefecture && 
placemark.administrativeArea != self.RomeKanjiPrefecture[self.prefecture] {
            print("郵便番号と都道府県が違います")
        }
        else{
            print("成功")
        }
    }
})

```

## Swiftのお役立ち情報

https://wagtechblog.com/programing/swift-iphone-application-school

https://wagtechblog.com/programing/swift-textbook.html