OmniAICreator/Qiita-1.07M huggingface dataset:
素因数分解を利用せよ！ ABC169 D問題「D - Div Game」

こんばんは Ruteです。
AtCoder Beginner Contest 169のD問題「D - Div Game」をACしましたので、
私がACをした解法の説明をしていきたいと思います。

## ABC169 - D問題「Div Game」
https://atcoder.jp/contests/abc169/tasks/abc169_d

### 問題概要:
正の整数$N$が与えられます。$N$に対して以下の操作を繰り返し行うことを考えます。
以下の条件を満たす正の整数$z$を選ぶ。
・ある素数$p$と正の整数$e$を用いて $z = p^e$と表せる
　　・$N$が$z$で割り切れる
　　・以前の操作で選んだどの整数とも異なる
・$N$を、$N/z$に置き換える
最大で何回操作を行うことが出来るかを出力せよ。

### 解法:
問題文を見ると、$N = p_1^{1} × p_1^{2} × p_1^{3}×...$
というように素因数分解できると考え、以下のアルゴリズムを考えました。
・$N$を素因数分解した結果をリストlsとおく。
・lsにおけるそれぞれの素数について、1連続・2連続... $k$　($k$は自然数)連続しているかを見る。<font color = "Grey">(ここで、1連続という言葉はないですが、分かりやすくするためにこのように表現しています)</font>
例えば、24の場合 $24 = 2×2×2×3$です。
2は、1連続　した後に　2連続　しています。よって$N$が$2,4$で割り切れるから<font color = "#FF0000">2回</font>操作ができることになります。

3は、要素が1つしか無いです。よって$N$が2,4で割った後に3で割り切れるから
<font color = "#FF0000">1回</font>操作ができることになります。

操作の回数を合計すると、<font color = "#FF0000">3回</font>となります。

これでは分かりにくいので、もう少し抽象的な言い方をすると、

lsにおけるある素数の要素$ls_i$について、その要素の個数を$A$とおくと、
<b>$\sum_{k =1}^{X}k ≦ A <\sum_{k =1}^{X+1}k$
を満たす$X$がその素数に対する操作回数となります。</b>
例えば、$ls_i$が3回連続していれば2回操作出来、$ls_i$が54回連続していれば9回操作できる　といった感じです。
あとは、これを実装すればよいです。

### ACしたコード
https://atcoder.jp/contests/abc169/submissions/14004504

```D.py
import math
def prime_diviation(n):
    factors = []
    i = 2
    while i <= math.floor(math.sqrt(n)):
        if n%i == 0:
            factors.append(int(i))
            n //= i
        else:
            i += 1
    if n > 1:
        factors.append(n)
    return factors
N = int(input())
#素因数分解
ls = prime_diviation(N)
now = 0 #現在参照する数字
ren = 0 #連続している数
target = 2 #連続している数の目標
ans = 0 #割り切れる回数
for i in range(len(ls)):
    if i == 0:
        #はじめの処理
        now = ls[i]
        ans += 1
    else:
        #もしnowと同じなら
        if ls[i] == now:
            ren += 1
            if ren == target:
                ans += 1
                ren = 0
                target += 1
        else:
            #1連続は確定している
            ans += 1
            ren = 0
            target = 2
            now = ls[i]
print(ans)
```

以上、ABC 169 D問題「D - Div Game」について私が考えた解法の説明を終わります。

Qiita初心者なので、表現が若干変だったらすみません((
もし、この解法が役に立った！等と思った方は<font color = "lightGreen">LGTM</font>のボタンを押して頂けると嬉しいです！
RailsのCSRF対策と、public配下のhtmlファイルについて

#環境とエラーメッセージ#

RailsのERbを使わず、public配下のhtmlファイル（静的ファイル）から、データをPOST通信しようとしている。

``` ターミナル.
Can't verify CSRF token authenticity.
```
要は、「想定していたセキュリティートークンと違うので、リクエストを弾いた」ということになります。


#CSRFとは#

クロス・サイト・リクエスト・フォージェリーの略で、不正行為の一つ。

攻撃者が被害者にリンクをクリックさせる、またはページを訪問させることで、対象のサイトにリクエストを送らせる行為。
つまり、攻撃者は自分を有効なリクエストだと認証させ、被害者のアカウント情報をいじったりできてしまうという被害が生まれる。

そこで、Railsでは悪質なものを通常のリクエストだと誤認させないように対策を自動でしている。


#Railsの対策#

Railsでは既に、application_controllerにCSRF対策のコードが自動で埋め込まれている。

```application.controller.rb
protect_from_forgery with: :exception
```

これは必須セキュリティトークンを導入していて、Railsが生成する全てのフォームや、Ajaxリクエストで自動にこのトークンを含めるというもの。

もし、セキュリティトークンが想定している値と一致しなければ、エラーとさせることができる。


####CSRF対策自体を無効にさせる####

```application_controller.rb
protect_from_forgery with: :null_session
```

全てのアクションに対して、CSRF対策を無効化している。
しかし、これだと極端に攻撃性に弱くなってしまうという問題がある。



#部分的にセキュリティトークンを除外させる#
外部からのAPIを受ける特定のアクションのみ除外させることで、安全性を担保しつつ、クライアントからのデータを受け取ることができる。


```feeds_controller.rb
protect_from_forgery :except => [:create, :index]

def create
end

def index
end
```

コントローラのアクション名を指定することで、public配下のhtmlファイルからのデータを受け取ることができるようになった。

##参考にさせていただきました##

https://qiita.com/chobi9999/items/2b59fdaf3dd8f2ed9268

https://www.transnet.ne.jp/2016/10/26/%E3%80%8Cruby-on-rails%E3%81%AEcsrf%E5%AF%BE%E7%AD%96colnd/

https://railsguides.jp/security.html#%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%83%95%E3%82%A9%E3%83%BC%E3%82%B8%E3%82%A7%E3%83%AA-csrf
Excel関数備忘録

項番の自動採番①
-
```
=MAX(OFFSET(INDIRECT(ADDRESS(1,COLUMN())),0,0,ROW()-1,1))+1
```
- 列内の通番で採番する
- 空白のセルを挟んでも通番で採番できる
- 1行目に使うとエラーになるためIFERRORなりを付けると良い

```Excel:IFERRORあり
=IFERROR(MAX(OFFSET(INDIRECT(ADDRESS(1,COLUMN())),0,0,ROW()-1,1))+1,1)
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404204/f4ad7f0f-d97e-be91-0795-cdb26cc37ee1.gif" width=30%>

項番の自動採番②
-
```
=IFERROR(INDIRECT("R[-1]C",FALSE)+1,1)
```
- 上のセルが空白の場合は1から採番する


複数の検索要素がある表からのデータ抽出
-

```
=VLOOKUP(子コード,OFFSET(INDIRECT(ADDRESS(MATCH(親コード1,※1,0)+ROW(※2),COLUMN(※2))),0,1,COUNTIF(※1,親コード),※3),※3,FALSE)
```
- 下の画像を例に説明
    - 子コード：検索する県コード（セル：C2）
    - 親コード：検索する地方コード（セル：B2）
    - ※1：親コードの検索対象列（セル：B5:B26）
    - ※2：親コードのヘッダーセル（セル：B4）
    - ※3：子コード（VLOOKUP）の検索対象幅（例の場合、VLOOKUPはC列D列が検索範囲のため2となる）

``` Excel:実際に使用した関数
=VLOOKUP(C2,OFFSET(INDIRECT(ADDRESS(MATCH(B2,B5:B26,0)+ROW(B4),COLUMN(B4))),0,1,COUNTIF(B5:B26,B2),2),2,FALSE)
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404204/b8f59c53-6ba0-9e63-fefc-883cba1c325d.gif" width=30%>
Apache 2.4 で使える If 文

Apache 2.4 では If 文 が使え、 特定のドメインの時に処理をするようなことができます。

```
<If "%{HTTP_HOST} == 'www.dev.sample.com'">
  AuthUserFile /dir/file
  AuthGroupFile /dev/nul/.htpasswd
  AuthName "input your id and passwd"
  AuthType Basic
  require valid-user
</If>
```

条件には `==` を使っていますが、そのほかにもシェルスクリプトと同じような比較も可能です。

* 文字列の比較
    * `!=`: 不一致
    * `>`, `<`, `<=`, `>=`: 大小比較
    * `=~`: 正規表現の一致
* 整数の比較
    * `-eq`: 等しい
    * `-ne`: 等しくない
    * `-lt`: 小さい
    * `-le`: 小さいまたは等しい
    * `-gt`: 大きい
    * `-ge`: 大きいまたは等しい
* その他
    * `-z`: 文字列長がゼロ
    * `-n`: 文字列長が1以上
    * `-f`: ファイルが存在する
    * `-d`: ディレクトリが存在する
    * `in`: 含まれる

特に便利なのは `=~` による正規表現との比較です。

```
<If "%{HTTP_HOST} =~ /user.test.sample.com$/" >
```

`If` のほかに `ElseIf`, `Else` も使えます。

## さらに詳しいことは

次のページをご覧ください。

* http://httpd.apache.org/docs/2.4/mod/core.html#if
* http://httpd.apache.org/docs/2.4/expr.html
PHPでsudoコマンドを実行する方法

#OSコマンドを実行する関数

##shell_exec
>shell_exec ( string $cmd ) : string
###返り値
実行されたコマンドからの出力を返します。 エラーが発生した場合やコマンドが何も出力しなかった場合は NULL を返します。

###例
```php
<?php
$output = shell_exec('ls -lart');
echo "<pre>$output</pre>";
?>
```

##exec
>exec ( string \$command [, array &$output [, int &\$return_var ]] ) : string
###返り値
コマンド結果の最後の行を返します。コマンドを実行し、 一切干渉を受けずに直接コマンドから全てのデータを受けとる必要が あるならば、PassThru() 関数を使ってください。
実行されたコマンドの出力を取得するには、必ず output パラメータを設定・使用してください。

###例
```php
<?php
// ("whoami" コマンドをパスに有するシステム上で)
// 実行中のphp/httpdプロセスを所有するユーザーの名前を出力
echo exec('whoami');
?>
```
##passthru
>passthru ( string \$command [, int \$return_var ] ) : void

引数 return_var を指定した場合、 Unix コマンドのステータスで置換されます。返り値は有りません。

##\「`」演算子
shell_exec()と同じ。

#それぞれの違い
##shell_execとexecの違い
###返り値について
|コマンド名|返り値|
|---|---|
|shell_exec|すべて文字列|
|exec|文字列、配列|
###実行結果について
|コマンド名|実行結果|
|---|---|
|shell_exec|すべての実行結果を返す|
|exec|最後の行しか返さない(output引数を入れればすべて取得できる。)|
##passthruについて
返り値がないので、実行結果を確かめることができないので汎用性に書けていると思われます。

#sudoコマンドの実行方法
本題です。
##任意のユーザにsudo権限を付与

```
$ sudo visudo
```
上記コマンドを入力すると/etc/sudoersの設定ファイルが開くので、最後の行に以下の文を追記

```
任意のユーザ名 ALL=(ALL) NOPASSWD:実行したいコマンド
```
「実行したいコマンド」の部分では「ALL」も指定できますが危険なので避けます。
Lalavelのseeding

#laravelのFakerクラスのseedeing

#seedingの流れ
１）DB接続
２）seedの日本語化
３）modelファイル作成
４）migrateファイル作成
５）DBテーブル作成
６）seedファイル作成
７）factoryファイル作成
８）seeding実行


#DBの設定(postgres)

```php:config/database.php
    'default' => env('DB_CONNECTION', 'pgsql'),
```


```php:.env
DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=laravel
DB_USERNAME=postgres
DB_PASSWORD=
```
#seedデータの日本語化
```php:app/config/app.php
    'faker_locale' => 'ja_JP',
```

#modelファイルを作成する
```
$ php artisan make:model hoge

Model created successfully.
```


#migrateファイルの作成

```
$ php artisan make:migration create_hoge_table

Created Migration: 2020_06_04_211755_create_hoge_table
```

```php:app/database/migrations
    public function up()
    {
        Schema::create('hoge', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('last_name');
            $table->string('first_name');
            $table->integer('age')->nullable();
            $table->string('postal')->nullable();
            $table->string('address')->nullable();
            $table->string('tel')->nullable();
            $table->timestamps();
            $table->softDeletes();
        });
    }
```
#DBテーブルの作成

```
$php artisan migrate

Migrating: 2020_06_04_122729_create_hoge_table
Migrated:  2020_06_04_122729_create_hoge_table (0.01 seconds)
```

#seederファイルの作成

```
$ php artisan make:seeder HogeTableSeeder

Seeder created successfully.
```

```php:app/database/seeds
class HogeTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        factory(App/HogeTableSeeder::class, 50)->create();
    }
}
```

#factoryファイルを作成する

```
$ php artisan make:factory HogeFactory

actory created successfully.
```

```php:app/database/factories

use App\Hoge;

$factory->define(Hoge::class, function (Faker $faker) {
    return [
        'last_name' => $faker->lastName,
        'first_name' => $faker->firstName,
        'age' => $faker->numberBetween(8, 80),
        'postal' => $faker->postcode,
        'address' =>  $faker->address,
        'tel' =>  $faker->phoneNumber,
    ];
});
```

#seedingでダミーデータを、DBに挿入する。
```
$ php artisan db:seed

Seeding: HogeTableSeeder
Seeded:  HogeTableSeeder (0.15 seconds)
```
【AWS】ECSで使用するECRのURLをマルチステージ対応にする


ECRのImage URLにアカウントIDを直接ハードコーディングしてしまうと
本番環境とステージング環境でアカウントIDが別れている場合などにdocker-compose.ymlが共通にできません。
この問題を環境変数で解決します。

# docker-composeファイル
```docker-compose.yml
image: ${AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/xxx:latest
```
アカウントIDを環境変数から参照するようにします。

参考URL
Compose における環境変数 | Docker Documentation
https://matsuand.github.io/docs.docker.jp.onthefly/compose/environment-variables/


# シェル上からの実行

## プロファイル、アカウントID指定版(面倒）

```bash
AWS_PROFILE=xxx AWS_ACCOUNT_ID=xxx ecs-cli compose up --create-log-groups --cluster-config xxx
```
プロファイル名以外にアカウントIDも指定が必要になるため書き換えミスが発生しそうです。

## プロファイルのみ版（簡単）

```bash
AWS_PROFILE=xxx AWS_ACCOUNT_ID=`aws sts get-caller-identity | jq -r .Account` ecs-cli compose up --create-log-groups --cluster-config xxx
```

プロファイル名をもとにアカウントIDを補完するようにしました。
一時環境変数としてAWS_PROFILE, AWS_ACCOUNT_IDを渡す時にAWS_ACCOUNT_IDの評価時にAWS_PROFILEを参照しているところがミソです。

標準でアカウントID解決するやりかたあるのではと探したんですが見つけらなかったのでシェル芸に逃げました。

参考URL
【小ネタ】AWS CLIでAWS Account IDが取れるようになりました！ | Developers.IO
https://dev.classmethod.jp/articles/get-aws-account-id-with-get-caller-identity/
jq コマンドを使う日常のご紹介 - Qiita
https://qiita.com/takeshinoda@github/items/2dec7a72930ec1f658af
AtCoder 生活　74日目

[前回](https://qiita.com/flandrescarlet237/items/af94b29a9c15e6bee428)

#74日目
今回は茶色diffの問題を2問解きました。

|問題|難易度|自力で解けた|かかった時間|
|:-:|:-:|:-:|---|---|
|ABC065|C|✕|113分12秒|
|ARC013|B|✕|47分23秒|



##[ABC065_C](https://atcoder.jp/contests/abc065/tasks/arc076_a)

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const int INF = 2e9;

int main(){
    int n,m;
    cin >> n >> m;
    int a = abs(n-m);
    bool ok = false;
    if(a < 2) ok = true;
    ll mod = 1e9 + 7;
    ll ans;
    if(ok){
        if(n == m) ans = 2;
        else ans = 1;
        rep(i,n){
            ans *= (i+1);
            ans %= mod;
        }
        rep(i,m){
            ans *= (i+1);
            ans %= mod;
        }
        cout << ans << endl;
    }
    else cout << 0 << endl;
}

```

解くのにかかった時間：113分12秒
感想:これは自力で解きたい問題だった…


##[ARC013_B](https://atcoder.jp/contests/arc013/tasks/arc013_2)

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const int INF = 2e9;

int main(){
    int c;
    cin >> c;
    ll p = 0,q = 0,r = 0;
    rep(i,c){
        vector<ll> a(3);
        rep(j,3) cin >> a[j];
        sort(a.begin(),a.end());
        p = max(p,a[0]);
        q = max(q,a[1]);
        r = max(r,a[2]);
    }
    cout << p*q*r << endl;
}

```

解くのにかかった時間：47分23秒
感想：考え方まではたどり着けたが、あと一歩足りなかった


###最後に
もう少し深く考えれるようにしていきたい。
Reactでaxiousを使って詳細ページを作る

今回はaxiousを使ってタスク詳細ページを作る

###APIを記述
```src/service/v1ApRequest.js
import axios from 'axios'

// Taskの詳細ページのAPI
export const getTaskSubscriptionDetail = (id = ":id") => axios.get(`${API_ROOT}/task_subscriptions/${id}`)
```
:point_up_tone1:APIのリクエストがたくさんあるときは一つのファイルにまとめておくとわかりやすい


###タスク詳細ページ作成

```src/containers/TaskDetailPage.js
import { getTaskSubscriptionDetail } from '../services/v1ApiRequest'
import { SET_TASKSUBSCRIPTION } from '../constants/actionTypes'
import TaskSubscription from '../models/taskSubscription'

class TaskDetail extends Component {
  componentDidMount() {
    // this.props.match.params.idは
    // ..../path/to/:id　の :idの部分をとってくれる
    // ..../path/to/:hoge_id　だったら
    // this.props.match.params.hoge_id　で取得できる
    // mapDispatchToPropsで定義したAPIを呼び出してStoreに保存するための関数を実行
    this.props.fetchTaskDetail(this.props.match.params.id);
  }

  render() {
    return (
          <div className={styles.taskName}>{this.props.taskSubscription.task.name}</div>
    )
  }
}
const mapStateToProps = ({ app, taskSubscription }) => ({
  isLoading: app.isLoading,
  taskSubscription: taskSubscription.selected // 4. APIのレスポンスがここに入る
})

//APIの結果をactionとしてdispatchする→コンポーネント側でやるならmapDispatchPropsを使う
const mapDispatchToProps = dispatch => ({
  fetchTaskDetail: (id) => {
    // 1. API呼び出して
    getTaskSubscriptionDetail(id)
      .then((res) => {
        // 2. レスポンスを受け取って
        console.log(res.data);
        // 3. dispatchにレスポンスを変換したもの（API）をpayloadにセットしたアクションをReducerへ運ばせる
        dispatch({
          type: SET_TASKSUBSCRIPTION,
　　　　　　//payload: res.data　だとスネークケースになるので、以下でキャメルケースにする
          payload: TaskSubscription.newFromApiResponse(res.data)
        })
      })
      .catch((error) => {
        // API読んでる最中にエラーが発生したらこっちが実行される
        console.log(error);
      });
  }
})
export default connect(
  mapStateToProps,
  mapDispatchToProps
)(withRouter(TaskDetail))


```

###ルーティング
```src/routes/index.js
 tasks: (id) => `/tasks${id ? `/${id}` : "" }`, 
// idがないときは一覧(/tasks)、idがあるときは詳細(/tasks/:is)のページへ
```
VisualBasic配列に関する備忘録

# 配列の初期化について

プログラムを作る上で、配列の初期化について調べたので、その備忘録を記す

配列宣言時
参照先がないためNothing

初期化（初期値がある場合）
例
Dim a() as integer = {1,2,3,4}

この場合
最大添字は3
最小添字は0
要素数は4

初期化（初期値がない場合)
Nothingもしくは空配列がおすすめ
Nothingの場合は参照先がないので、そのまま配列を参照するとエラー
空配列に関しては、要素がないだけで、実態もあり参照されている

例（Nothingの場合）
Dim a() as integer

a = Nothing

例（空配列の場合）
Dim a() as integer

Redim a(-1)

空配列の最大、最小の添字と要素について
最大の添字は-1
最小の添字は0
要素数は0

ここからは個人的な意見
ループなどで配列を利用すると思うと、Nothingを考慮しなければならいので、空配列がおすすめ
しかし、パフォーマンス的にはよくないのかな？
また、Nothingの時の添字と要素数を調べたい
【自動化】PythonでOutlookメールを送信する

最近のコミュニケーションツールはLINEなどチャットベースのものが主流になってきていますね。

ですが、日本ビジネスメール協会の『ビジネスメール実態調査2020』によると、仕事で使っている主なコミュニケーション手段の第1位は**「メール」（99.1%）**なのだそうです。

## メールって面倒…

私の会社は『メール文化』なので、あらゆる情報をメールでやり取りしています。

中でも面倒なのが、
【ソフトウェアのバグのステイタスを毎日夕方にチームメンバーにメールする】
というものです。

**定期的に同じような情報を同じようなメンバーにメールする**という事務作業はどこの会社でも少なからずあるのではないでしょうか？

このような機械的な業務こそ、最も自動化の効果が大きいのです。

早速、具体的な方法を見ていきます。

##PythonでOutlookメールを送信

先ほどの『ビジネスメール実態調査2020』によると、仕事で使用しているメールソフトは「Outlook」（50.52%）と「Gmail」（38.40%）が二強だそうです。

そこで、本記事ではOutlookでのメール作成の方法をご紹介します。

outlookを操作するためにはwin32com.clientをimportする必要があります。
私はAnacondaを使っていますが、特に追加でインストールしなくてもimportできました。

```python:python
import win32com.client
```

次にOutlookのオブジェクトを作成します。

```python:python
outlook = win32com.client.Dispatch("Outlook.Application")
```

そして次にメールオブジェクトを作ります。

```python:python
mail = outlook.CreateItem(0)
```

`CreateItem(n)`のnの部分を変えることにより、Outlookのメールや予定表など様々なアイテムを作ることができます。0にするとメールのオブジェクトを作成できます。

このmailオブジェクトに属性をセットしていくことで、メールを作成していきます。

|  属性  |  意味  |
| ---- | ---- |
|  mail.to  |  宛先  |
|  mail.cc  |  CC  |
|  mail.bcc  |  BCC  |
|  mail.subject|  件名|
|  mail.bodyFormat|  メール書式<br>1：テキスト<br>2：HTML<br>3：リッチテキスト |
|  mail.body  |  本文  |


```python:python

mail.to = 'hazuki@mahodo.com; aiko@mahodo.com'
mail.cc = 'onpu@mahodo.com'
mail.bcc = 'momoko@mahodo.com'
mail.subject = '1級試験の件'
mail.bodyFormat = 1
mail.body = '''お疲れ様です。どれみです。

なんか今年の試験はコロナの影響でリモート面接になったらしいです。
さっきマジョリカから聞きました。

びっくりしたので取り急ぎご連絡です。

よろしくお願いいたします。
'''
```

ここまでで作成したメールをいきなり送信する前に確認することをオススメします。
確認するには、`mail.display(True)`とします。

```python:python

mail.display(True)
```

このようにメールが開きますので、確認してOKなら送信してください。

<img width="534" alt="1級試験の件.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634673/7d7451ac-6ff0-e21c-6d15-d9cae472ed4d.png">




皆様が面倒なメール送信業務から解放されることを願っています。
最後にコードをまとめて載せておきます。

```python:python
import win32com.client

outlook = win32com.client.Dispatch("Outlook.Application")

mail = outlook.CreateItem(0)

mail.to = 'hazuki@mahodo.com; aiko@mahodo.com'
mail.cc = 'onpu@mahodo.com'
mail.bcc = 'momoko@mahodo.com'
mail.subject = '1級試験の件'
mail.bodyFormat = 1
mail.body = '''お疲れ様です。どれみです。

なんか今年の試験はコロナの影響でリモート面接になったらしいです。
さっきマジョリカから聞きました。

びっくりしたので取り急ぎご連絡です。

よろしくお願いいたします。
'''

mail.display(True)
```

##Outlookのメールを読み込むには？

今回はOutlookのメール送信の自動化をご紹介しましたが、OutlookのメールをPythonで読み込む方法についてはこちらの記事をご覧ください。
https://qiita.com/konitech913/items/fa0cf66aad27d16258c0
シェルスクリプト　数値計算　bc コマンド


# bc コマンド
ー任意の精度（小数点以下の桁数を指定）の数値を扱い、四則演算・平方根・三角関数など様々な数学関数を計算できる

【前提】
bcコマンドはインストールしないと利用できないので以下のコマンドでインストールしておいてください

```Linux:$bc
$ sudo yum install bc
```

#単純な計算
計算内容を文字列として | を使って、bcコマンドに渡すと計算する。

```Linux:足し算（例
[hkoen@localhost ~]$ echo "20.5+5" | bc
25.5
```

```Linux:割り算（例
[hkoen@localhost ~]$ echo "20.5/5" | bc
4
```

#複雑な計算
-l を利用すると標準数学ライブラリを読み込んでより複雑な数学関数を実行します

```Linux:平方根（例
[hkoen@localhost ~]$ echo "scale=20;sqrt(20.5/5)" | bc -l
2.02484567313165869332
```

上記は√(20.5/5)の計算結果を小数点第20位まで表示するという意味です。

#シェルスクリプトで書いてみる

base10.sh （任意）というシェルスクリプトファイルに記述します。

```Linux:base10.shファイル内容
#!/bin/bash

echo "20.5+5" | bc
echo "20.5*5" | bc
echo "scale=10;sqrt(2)" | bc -l
echo "$1 + $2" | bc　　　　 #引数1,引数2 を設定
```

```Linux:base10.shファイル実行結果
[hkoen@localhost ~]$ chmod 755 base10.sh
[hkoen@localhost ~]$ ./base10.sh 7 9
25.5
102.5
1.4142135623
16
```
まず、chmod 755 base10.sh でユーザーにファイルの実行権限を付与します。

そして ./bas10.sh を呼んだ後に引数1、引数2：７、９を指定して実行します。


正常に計算してくれています。
最速 rails  mail devise ウェルカムメール送信機能実装 action mailer不要 一番簡単


##【ゴール】
deviseユーザ登録時にmailerを使用してmailの送信（ウェルカムメール）
参考：https://web-camp.io/magazine/archives/19143
参考：https://freesworder.net/rails-mail/

##【メリット】
■UXの向上
■アプリケーション完成度向上


##【開発環境】
■ Mac OS catalina
■ Ruby on Rails (5.2.4.2)
■ Virtual Box:6.1
■ Vagrant: 2.2.7


##【実装】

###アプリケーションを作成

```mac.terminal
$ rails new mail

$ cd mail

```

###gemfile追加

```app内.gemfile
gem 'devise' #deviseの会員登録時にメールを飛ばします
gem 'dotenv-rails' #環境変数に使用します。詳細は後述
```

###ターミナルへ戻り諸々作成

```mac.terminal
$ bundle install #gemfileをインストール

$ rials g devise:install #deviseを初期化

$ rails g devise User 

$ rails g devise:views

$ rails g devise:controllers users

```

###DB,migrationfileを編集、下記のコメントアウ外す。
※メールの情報を追いかける為。

```db/migrate/xxxxxxxxxx_devise_create_users.rb
# Confirmable
      t.string   :confirmation_token
      t.datetime :confirmed_at
      t.datetime :confirmation_sent_at
      t.string   :unconfirmed_email # Only if using reconfirmable
```

###modelを編集
※「:confirmable」のアクセスも追加

```user.rb
class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable, :confirmable　←追加

end

```

###.envファイルをルートディレクトリに追加し、下記を追記
※一応パスワードがあるので「.env」を導入、先のgemfile導入はこの為
※環境変数に埋め込passwordは事前に申請してください

```/.env
mail = 'あなたのgamilアドレス'
password = 'パスワード申請が必要'
```

###config/initializers/mail_config.rb作成、編集
※メールの形式を指定
※「user_name」「password」は上記の.envファイルから引っ張ってきています

```config/initializers/mail_config.rb
ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
  address: 'smtp.gmail.com',
  domain: 'gmail.com',
  port: 587,
  user_name: ENV['mail'],
  password: ENV['password'],
  authentication: 'plain',
  enable_starttls_auto: true
}
```

###view/users/mailer/confirmation_instructions.html編集

```confirmation_instructions.html

##任意に変更、メールの内容になります。

<p>Welcome <%= @email %>!</p>

<p>You can confirm your account email through the link below:</p>

##ここまで


<!-- <p><%#= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %></p> -->
#コメントアウト,今回不要の為

```


###再度ターミナルへ

```mac.terminal
$ rails db:migrate

$ rails s -b 0.0.0.0
```

以上でユーザー登録時にメール送信されているはずです。

action mailer等経由して3時間くらい時間取られましたが
思ったより簡単に実装できました。
Pythonで定刻にBeep音を鳴らす(Ubuntu)

#pythonで定刻にBeep音を鳴らす(Ubuntu16.04)
pythonプログラムを起動してから何秒後かに
Beep音が欲しかったけど、なかなか鳴らせなかったのでメモします。
#環境
ubuntu 16.04
python 3.6

#プログラム
```python
import os
import time
duration = 1  # seconds
freq = 440  # Hz

bool1 = True
elapsed_time = 0
while bool1:
    start = time.time()
    elapsed_time += time.time() - start
    if elapsed_time >= 2.5:#各自調整
        os.system('play -nq -t alsa synth {} sine {}'.format(duration, freq))
        bool1 = False
```
***
メモ程度です。。。もっと最適な方法があったら教えてください。
Corne lightをBT化させるときにつまづいた話

# BT化でめっちゃつまづきました
![EZqoLd-U4AEpNiK.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70350/4f7c4b4a-7ed1-6a39-a2d4-8c13bfe506b8.jpeg)

自作キーボードキットのCorne lightを無線で動くようにしたくてがんばりましたが、たくさんのつまづいたので箇条書きで記しておきます。

## 物理的な苦労話
- 電池基板、はんだ付けに手が二本だと足りない  
  おとなしくスタンド？を買うがヨシ！
- 電源スイッチ折れる。ジャンパでOK!おそらく多分  
スレーブ側は無事だったのでよかった
- BLEと電池基板をつなぐ動線が折れる心も折れる  
なんども吸い取り線でとるはめに
- 電池基板破壊。泣きながらカッターで銅箔を露出させる  
ぺらい基板なのでスルーホールがバキっと。
- 電池基板が暴れる。俺も暴れたい。おおよしよし。  
俺たちは雰囲気でBLEの上に陣取っているんだ！

## ブートローダーやファームウェアでつらかった話
- 自分のWIN環境では初回のシリアル通信ができなかった  
CPUがRyzenなのが理由だったりすんのかな。
- 古いMacを引っ張り出してBLE Micro Pro Web Configuratorでシリアル通信をするも複数種類出てきてどれにしたらいいのかわからなかったので何度もやった。つらい。
    - cu.~~とtty.~~~があり、tty.~~の方でやったらうまく行った
    - Windowsだとシリアル通信とかしか出ない
- BLE関連のキーコードがいまいちわからなくてまだ搭載していないでいる
- 初回以外では自分のWIN環境で動くのでほんと……！こいつ……！！となる
- 再起動時になんもしなくても打てるようになると思ったらスレーブ側の電源のONOFFが必要だった。

とまあ物理的にも精神的にも大変でしたがなんとか動くようになったのでよかったなあと。
みんなこの配線どうやってるのか……。
Chrome バージョン83から入力ボックスが太く表示されて見にくくなった場合の回避方法


GoogleChromeを利用していて突然いつも使っているサイトの入力欄の枠が太くなって、サイトによっては入力しにくくなってしまいました。

今まで
![画像2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364758/c964319c-60ee-2c43-6ca2-8592a8398372.png)

Chromeのバージョンアップ後
![画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364758/993dbdc9-d9de-ca83-5384-e78bd8c5c53b.png)

カーソルが見えなくなってしまいました。

どこの入力欄を選択しているかの視認性はよくなっているようなのですが、
上記のような例の入力に支障がありそうなので、改善方法を調べました。
以下のようなやり方があるようですので、参考に記載いたします。

Chrome にて以下のページにアクセスする
[chrome://flags/#form-controls-refresh](chrome://flags/#form-controls-refresh)
「Web Platform Controls updated UI」 を[Disabled]にして[Relunch]をクリックして読み直
すと、設定が解除され元の画面表示に戻りました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364758/cc57e7dc-99ea-cabb-56bd-edf44e9a85d3.png)
Pi Imagerで、SDカードが消える魔法

#はじめに
　ラズパイのイメージャーを使ってOSを入れようとした所、エラーが出て止まったと思ったらエクスプローラーにSDカードが表示されなくなってしまいました。その事についてまとめました。

##原因
　イメージを焼く時に途中でエラー等で止まった時に起こります。
　私のPCでしか試していないので、どの程度の頻度で起きているか等は不明です。

##解決方法
　①まず、画面右下のWindowボタンを右クリックして「ディスクの管理」を開きます。
　　もしくは、「ディスクの管理」と検索して、「ハードディスク　パーティションの作成とフォーマット」を開いても同じです。

　②画面下部からSDカードだと思われるボリュームを探します。
　　恐らく、未割り当てになっていると思いますが、容量を参考に探してみてください。（写真は、説明用に一部のみの割り当てを外しています。）
![DiscSetting.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372828/cd5e8ccb-5f49-0d28-7252-42fbdc815e1d.png)

　③見つけたら、未割り当て部分を右クリックして新しいボリュームを選択します。![NewValue.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372828/a69f2bd7-e7ac-c110-48f0-875c1e32b942.png)

　④次へをクリックして、ボリュームのサイズを設定します。よく分からない場合は、そのまま次へを押して大丈夫です。
![ValueSize.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372828/592408fe-9e3d-e09e-bddb-4ab8bc9ffd87.png)

　⑤ドライブの文字を設定します。お好きな数字にしてください。
![DeviceChange.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372828/cab40bca-b66e-417c-8763-bae0c4e1e504.png)

　⑥フォーマット画面になります。今回の場合は、中途半端にゴミが残ってたりなどありそうなので、そのまま次に行きます。
![DeviceFormat.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372828/b7272b09-6e06-b6b2-57df-8a6e97f4a71c.png)

　⑦完了を押します。
![kanryou.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372828/d2d2452b-556f-3b65-16d3-fd5c0af0d2be.png)

これで、エクスプローラーにも表示されると思います。

##あとがき
　とにかく、途中で止めなければ何も問題ないので止めない様に気を付けましょう。
　イメージの焼き込みがわからなければ、素直にNOOBSを入れるのが手っ取り早いかもしれません（笑）
AWS: アプリケーションサービス

#アプリケーションサービス
##AWSのアプリケーションサービス
###アプリケーションサービスに共通する基本的な考え方
AWSのアプリケーションサービスはAWSのサーバーリソース上に構築されており、サーバーとアプリケーションのメンテナンスはAWSにまかせている。
そのため、コスト面でも安定性の面でも、自身で構築するより優れていることが多い。

##SQS(Simple Queue Service)
AWSが提供するフルマネージドなメッセージキューイングサービス。


- キュー
    - メッセージを管理するための入れ物
    - 利用開始時に作成すれば管理する必要なく、エンドポイントと呼ばれるURLを介して利用する
- キューの管理機能
    - キューの作成・削除・動作属性などの詳細な設定もあり
- メッセージ機能
    - キューに対するメッセージの送信・取得と処理済みのメッセージの削除がある
    - 複数のキューをまとめて処理するバッチ用のAPI
    - 処理中に他のプロセスから取得できなくするための可視性制御のAPI

### StandardキューとFIFOキュー
- Standardキュー
    - メッセージの配信順序を保証せず、同一のメッセージが2回配信される可能性がある
- FIFOキュー
    - メッセージの配信順序を保証する。秒あたりの処理件数はStandardキューに劣る

###ロングポーリングとショートポーリング
- ロングポーリング
    - メッセージがある場合に、即レスポンスを返すが、メッセージがない場合、設定されたタイムアウトギリギリまでレスポンスを返さない
- ショートポーリング
    - リクエストを受けるとメッセージの有無に関わらず即レスポンスを返す

###遅延キューとメッセージタイマー
- 遅延キュー
    - キューに送られたメッセージを一定の時間見えなくする機能
- メッセージタイマー
    - 個別のメッセージに対して一定時間見えなくする機能

##SNS(Simple Notification Service) & SES(Simple Email Service)
- SNS
    - プッシュ型の通知サービスで、システムのイベント通知の中核を担う
- SES
    - Eメール送信サービスで、SMTPプロトコルを利用する

###SNSの利用について
- トピック
    - 情報を管理する単位
- Publisher
    - 通知する人。
- Subscriber
    - 通知される人。利用するトピック及び受け取るプロトコルを指定

###SNSを使ったイベント通知
- リソースの設定・状態を評価するAWS Configでルールに違反している使われ方が発見された
- CloudWatchでEC2のCPU・ネットワークなどのメトリクスを監視しているときにしきい値を超えた

などといったケースで利用される


###SES
Eメール送信サービス。SMTPプロトコルやAPIを通じたメール送信の他に、Eメールを受信し、S3に保存することも可能

- 送信時にウイルスやマルウェアを検出理sてブロックする機能
- 送信の成功工数や拒否された数を統計的に処理し、配信不能や苦情を管理する機能
- Sender Policy Framework(SPF)やDomainKeys Identified Mail(DKIM)といった認証機能
3Dの取り扱いは難しかった

温度センサーから収集した温度情報を基にフロント画面表示を変えるアウトプットに挑戦しました。

温度収集はobnizセンサーから収集します。

![BEC112C4-EFD0-45DB-B84A-6ACCF9AB4659.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599091/a81307a3-d153-476c-0fb2-f42333bdefc9.jpeg)


画面には3Dを扱えるA-frameを活用してみました。

https://aframe.io/

温度情報拾ってif文を流してブラウザのコンソール画面では温度を出力できているのですが、getElementIdからcolorプロパティをredには変えられません・・・。

![2020-06-04_21h11_26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599091/65839169-5f67-ffd1-a7db-771a0f04d98d.png)


```html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Hello, WebVR! • A-Frame</title>
    <meta name="description" content="Hello, WebVR! • A-Frame" />
    <script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
    <script
      src="https://unpkg.com/obniz@2.3.0/obniz.js"
      crossorigin="anonymous"
    ></script>
  </head>

  <body>
    <a-scene>
      <a-box
        id="sensor"
        position="-1 0.5 -3"
        rotation="0 45 0"
        color="#4CC3D9"
        shadow
      ></a-box>
    </a-scene>

    <script>
      var sceneEl = document.querySelector("a-scene");
      var cylinder = sceneEl.querySelector("#cylinder");

      var obniz = new Obniz("xxxx-xxxx"); // 自分のObniz_IDをいれましょう。
      obniz.onconnect = async function () {
        obniz.display.clear();
        obniz.display.print("Hello obniz!");

        // Javascript Example
        var tempsens = obniz.wired("LM60", { gnd: 0, output: 1, vcc: 2 });

        // setIntervalで間隔を作る
        setInterval(async function () {
          // 非同期で取得
          var temp = await tempsens.getWait();
          // 温度をコンソールに表示
          console.log(temp);
          // displayに反映
          if (temp > 25) {
            console.log("hot"); //ここまでは実行できてる
            target = document.getElementById("sensor");
            target.style.color = "red";
          }
          obniz.display.clear();
          obniz.display.print(temp + "C"); // 英語が出力できる
        }, 1000); // 1000ミリ秒 = 1秒
      };
    </script>
  </body>
</html>
```


よく考えたら「style.color」で変えられるのはstyle属性のcolorプロパティのような。
一方で上記のbox要素の色を決めているのはcolor属性？のようなので、style.colorでは変えられないのではという仮説を感じたところで時間切れでした。

色を変える＝Style属性と決めつけずに、扱う技術に応じた作法を学ぶ必要があると今回学びました。
ゼロから始めるLeetCode Day46「406. Queue Reconstruction by Height」

#概要
海外ではエンジニアの面接においてコーディングテストというものが行われるらしく、多くの場合、特定の関数やクラスをお題に沿って実装するという物がメインである。

その対策としてLeetCodeなるサイトで対策を行うようだ。

早い話が本場でも行われているようなコーディングテストに耐えうるようなアルゴリズム力を鍛えるサイト。

せっかくだし人並みのアルゴリズム力くらいは持っておいた方がいいだろうということで不定期に問題を解いてその時に考えたやり方をメモ的に書いていこうかと思います。

[Leetcode](https://leetcode.com/)

[ゼロから始めるLeetCode 目次](https://qiita.com/KueharX/items/6ee2502c3b620c795b70)

前回
[ゼロから始めるLeetCode Day45 「1379. Find a Corresponding Node of a Binary Tree in a Clone of That Tree」](https://qiita.com/KueharX/items/013008af197ae14fcc09)

今はTop 100 Liked QuestionsのMediumを解いています。
Easyは全て解いたので気になる方は目次の方へどうぞ。

[Twitter](https://twitter.com/kueharx)やってます。

# 問題
[406. Queue Reconstruction by Height](https://leetcode.com/problems/queue-reconstruction-by-height/)

難易度はMedium。
Top 100 Liked Questionsからの抜粋です。

待ち行列に立っている人のランダムなリストがあるとします。
それぞれの人は整数のペア、`(h,k)`で構成されており、`h`は人の高さ、`k`はその人の前にいて`h`以上の高さを持つ人の人数を指します。

この問題では与えられた待ち行列を再構成するようなアルゴリズムを設計します。

>Input:
[[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]

>Output:
[[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]

# 解法

二つの整数についてしっかりと整理し、的確にアルゴリズムを組むことが求められる良い問題です。

こういった問題の場合はやはり問題を細かく分割し、それぞれの処理を独立させて考えた方が分かりやすくなると思います。

```Python
class Solution:
    def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:
        if not people: return []
        dic, height, res = {}, [], []
        for i in range(len(people)):
            p = people[i]
            if p[0] in dic:
                dic[p[0]] += (p[1], i),
            else:
                dic[p[0]] = [(p[1], i)]
                height += p[0],
        height.sort()
        for h in height[::-1]:
            dic[h].sort()
            for p in dic[h]:
                res.insert(p[0], people[p[1]])
        return res
# Runtime: 88 ms, faster than 99.14% of Python3 online submissions for Queue Reconstruction by Height.
# Memory Usage: 14.3 MB, less than 5.88% of Python3 online submissions for Queue Reconstruction by Height.
```

めちゃ速い！
よくよくdiscuss調べてみたら[これ]
(https://leetcode.com/problems/queue-reconstruction-by-height/discuss/89345/Easy-concept-with-PythonC%2B%2BJava-Solution)とほとんど一緒でびっくりしました。

今回はここまでです。お疲れ様でした。
【Python】エネルギーデータをなんちゃってCalenderHeatmap【Plotly】メモ

# 概要
* エネルギーデータのカレンダー状のヒートマップを作りたかった。
* [calmap](https://github.com/MarvinT/calmap)があるけど、pandas1.0以上に対応していないっぽい。(ixつかってる？)
* せっかくだからplotlyで作ってみた。(hovertextとかおしゃれだし・・・）

# 実装
* 使用データ  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148213/6c3aca19-4f25-e273-4a0f-7b0837775289.png)

* ソースコード  

```python:gen_calmap
def gen_calmap(df,column_name_lst,aggr='sum',height= 260,width = 900):
    try:
        for column_name in column_name_lst:

            # heatmap_df_lst生成
            heatmap_df_lst = _calender_heatmap_df(df,column_name,aggr)
            
            for heatmap_df in heatmap_df_lst:
                fig = px.imshow(heatmap_df[0],
                                x=heatmap_df[0].columns.unique(),
                                y=heatmap_df[0].index.unique(),
                                labels={'y':'Weekday','x':'Week','color':column_name},
                                width=width,
                                height=height,
                                aspect='auto',
                                )
                
                # セル間に隙間を入れる
                fig.data[0]['ygap']=1
                fig.data[0]['xgap']=1
                
                fig.update_traces(
                    text = heatmap_df[1],
                    hovertemplate="Date: %{text} <br>Week: %{x} <br>Weekday: %{y} <br> "+ column_name +": %{z}"
                )
                fig.show()
    except:
        print('calmapの生成に失敗しました。')

def _calender_heatmap_df(df,column_name,aggr='sum'):
    heatmap_df_lst =[]
    
    # DataFrame再生成
    data = pd.DataFrame(eval("df[column_name].resample('D').{}()".format(aggr)))
    data.index = pd.to_datetime(data.index)
    
    ## add data
    data['week'] = pd.to_datetime(data.index).strftime('Week:%W')
    data['weekday'] = pd.to_datetime(data.index).weekday
    data['date'] = pd.to_datetime(data.index).strftime('%Y/%m/%d')

    weekday_dic = {0:'Mon',1:'Tue',2:'Wed',3:'Thr',4:'Fri',5:'Sat',6:'Sun'}
    
    # データの展開
    for year in data.index.year.unique():
        # heatmap生成
        heatmap_df = data.loc[data.index.year == year,:].pivot_table(index='weekday',columns='week',values=column_name)
        
        # 曜日を月曜日→日曜日の順番に並べ替える
        heatmap_df = heatmap_df.rename(index=weekday_dic)
        
        # 日付dfを生成
        date_df = data.loc[data.index.year == year,:].pivot(index='weekday',columns='week',values='date')
        date_df = date_df.rename(index=weekday_dic)
        
        # dfをリストに加える
        heatmap_df_lst.append([heatmap_df,np.array(date_df)])
        
    return heatmap_df_lst

```

```python:実行
gen_calmap(df=data,column_name_lst=['電力量[kWh]','ガス量[m3]'],aggr='sum')
```

## 結果
* 割といい感じにできた。

![plotly_calmap.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148213/9684d18d-c77d-3fcd-dd65-90fc169997bb.gif)


# まとめ
* 特にエラーのことは考えていない。
* Githubっぽくできた。
Qiitaニュースの過去記事が見えない

そもそも今日初めてQiitaニュースの存在を知ったよ。

Qiitaのヘルプページを見てたら[Qiitaニュース](https://help.qiita.com/ja/articles/qiita-news)というメールマガジンについて書かれていました。
で、そこから[https://zine.qiita.com/qiita-news/](https://zine.qiita.com/qiita-news/)のアーカイブにリンクが張ってあります。
ここ、1ページ目こそ表示されているものの、最下部のリンクから2ページ目以降に飛ぼうとすると『お探しのページは見つかりませんでした。』になります。

![20200604.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26088/7ce0ad80-aed6-e771-f90a-b8121c3dbdbb.png)


なお、[https://zine.qiita.com/category/qiita-news/](https://zine.qiita.com/category/qiita-news/)というURLだと2ページ目以降が見れます。

ここまで書いた後で気付いたのですが、[Qiita Zineのトップ](https://zine.qiita.com/)の右側からQiitaニュースを選ぶと正しいURLになりますね。
すなわち、最初のヘルプページに書かれているURLが間違っていた(しかも半端に動くせいで気付かなかった)というだけの話だった。
[06.10編集]fleamarket_sample_72a DB設計

# チーム共有用

# 機能洗い出し
- ユーザー新規登録/ログイン・ログアウト
- 商品出品・購入
- コメント
- カテゴリー検索
- マイページ/商品編集機能
- クレジットカード登録・変更

# ER図
https://gyazo.com/916e8b82e9fc662ac1f7ae576b813c7e

# DB設計
# usersテーブル
|Column|Type|Options|
|------|----|-------|
|nickname|string|null: false|
|email|string|null: false, unique: true|
|password|string|null: false|
|family_name|string|null: false|
|first_name|string|null: false|
|family_name_kana|string|null: false|
|first_name_kana|string|null: false|
|birthday_year|string|null: false|
|birthday_month|string|null: false|
|birthday_day|string|null: false|
## Association
- belongs_to :delivery_date　dependent: :destroy
- has_many :creditcards　dependent: :destroy
- has_many :comennts　dependent: :destroy
- has_many :products　dependent: :destroy


# delivery_datasテーブル
|Column|Type|Options|
|------|----|-------|
|family_name|string|null: false|
|first_name|string|null: false|
|family_name_kana|string|null: false|
|first_name_kana|string|null: false|
|zipcode|integer|null: false|
|prefecture|string|null: false|
|city|string|null: false|
|address|string|null: false|
|building|integer||
|phone|integer|
|user|reference|null: false, foreign_key: true|
## Association
- belongs_to :user

# productsテーブル
|Column|Type|Options|
|------|----|-------|
|name|string|null: false|
|comment|text|null: false|
|price|integer|null: false|
|brand|string||
|size|string||
|shippingcharge|string|null: false|
|area|string|null: false|
|days|string|null: false|
|user|reference|null: false, foreign_key: true|
|category|reference|null: false, foreign_key: true|
## Association
- belongs_to :user　dependent: :destroy
- belongs_to :category　dependent: :destroy
- has_many :comments　dependent: :destroy
- has_many :images　dependent: :destroy

# categorysテーブル
|Column|Type|Options|
|------|----|-------|
|name|string|null: false|
## Association
- has_many :products

# commentsテーブル
|Column|Type|Options|
|------|----|-------|
|content|text||
|user|reference|null: false, foreign_key: true|
|product|reference|null: false, foreign_key: true|
## Association
- belongs_to :user
- belongs_to :product

# creditcardsテーブル
|Column|Type|Options|
|------|----|-------|
|user|reference|null: false, foreign_key: true|
|customer|string|null: false|
|card|string|null: false|
## Association
- belongs_to :user

# imagesテーブル
|Column|Type|Options|
|------|----|-------|
|image|image|null: false|
|product|reference|null: false, foreign_key: true|
## Association
- belongs_to :product

# 補足
- payjp公式リファレンス
https://pay.jp/docs/api/#charge%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88
creditcardテーブル
user_id:userテーブルのid
customer_id:顧客ID/一度の登録で複数回使用できるようにする。
card_id:customerを使用している場合、card_idを指定する事でデフォルトカード以外のカードも使用できる

- アソシエーションのdependentオプション
https://pikawaka.com/rails/association#dependent%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3
親レコードが削除された時に子レコードデータとの整合性を保つ事ができる。
Vue.jsで動的な複数のclassを指定する時の書き方

それぞれstringを返すなら以下のようにclassを付与できます
なお`:class`は`v-bind:class`の省略記法です

```html
<div :class="[activeClass, errorClass]"></div>
```

```js
data: {
  activeClass: 'active',
  errorClass: 'text-danger'
}
```

また、Vueはbooleanな値を使って以下のようにclassを付け替えすることもできます

```html
<div :class="{ 'active': isActive }"></div>
```

```js
data: {
  isActive: true
}
```

以上2つの指定方法が混在しているDOMについては以下のように纏められます。

```html
<div :class="[activeClass, errorClass, { active: isActive }]"></div>
```

```js
data: {
  activeClass: 'active',
  errorClass: 'text-danger',
  isActive: true
}
```

配列の形でそれぞれの指定方法に則って記述するだけですね。

また、この指定方法ではDOMにロジックが寄って見通しが悪くなることが考えられます。
その場合、算出プロパティを用いて付与するクラスをまとめると良いでしょう。
同様なロジックが存在している場合にも、算出プロパティは変更がある場合のみ再計算してそれ以外はキャッシュして返してくれるのでパフォーマンスの面でも優れます。

```html
<div :class="classObject"></div>
```

```js
data: {
  isActive: true,
  error: null
},
computed: {
  classObject: function () {
    return {
      active: this.isActive && !this.error,
      'text-danger': this.error && this.error.type === 'fatal'
    }
  }
}
```
[AWS] Amazon Redshift　クラスターがわからないから調べた

#Amazon Redshiftとは
クラウド内のフルマネージド、ペタバイト規模の**データウェアハウスサービス**。
Amazon Redshiftクラスターと呼ばれる一連のノードを起動することで作成できる。

#クラスターって？
リーダーノードと、1つ以上のコンピューティングノードから構成される一連のノードのこと(AWS公式サイトより)。

コンピューティングノードって言葉は要はコンピュータのことで、そのコンピュータ同士が連携してつながっている時にノードって言葉がつきます。
リーダーノードは読んで字の如く、そのコンピューターたちの親玉です。図で見るとこんなかんじ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605944/6cbfef47-d987-42da-ddee-14d211c8bb22.png)
図で見るとわかりやすいですね。

まとめるとクラスターは、ノード(コンピュータ)が集まった集合体のことです。

#最後に
学習始めたばかりなので間違っていたり、意見があればコメントお願いします！

参考
https://docs.aws.amazon.com/redshift/index.html
[AWK] 巨大な行列の転置を行う

# 問題設定

下記のように文字列を転置することを考えます。

```sh
cat input.txt
AAA
BBB
CCC
```

```sh
cat output.txt
ABC
ABC
ABC
```

# 小さい行列の場合

まず手始めに小さい行列を転置します。
A-Cの3行で、それぞれ3文字を格納した行列を作製します。

```sh
seq_len=3
awk -v seq_len="${seq_len}" \
'BEGIN {A=65; C=A+3; for (i=A; i<C; i++){
    alphabet=sprintf("%c", i)
    s=sprintf("%"seq_len"s","")
    gsub(/ /,alphabet,s)
    print s}
    }' \
> input1.txt
```

```sh
cat input1.txt
AAA
BBB
CCC
```

それでは転置を行います。
[Stack Overflow](https://stackoverflow.com/questions/1729824/an-efficient-way-to-transpose-a-file-in-bash)にAWKのコードがありました。
連想配列を巧みに扱ったエレガントなコードです。
拝借します。

```sh
awk -F "" '
{for (i=1; i<=NF; i++)  { a[NR,i] = $i }}
NF>p { p = NF }
END { for(j=1; j<=p; j++) {
        str=a[1,j]
        for(i=2; i<=NR; i++){ str=str""a[i,j] }
        print str}}' input1.txt \
> output1.txt
```

```sh
cat output1.txt
ABC
ABC
ABC
```

なにも問題ありませんね:smiley:

# 大きい行列の場合：メモリ消費量が尋常ではない

それでは大きいサイズの行列を転置します。
A-Zの26行で、それぞれ1,000,000文字を格納した行列を作製します。

```sh
seq_len=1000000
awk -v seq_len="${seq_len}" \
'BEGIN {A=65; Z=A+26; for (i=A; i<Z; i++){
    alphabet=sprintf("%c", i)
    s=sprintf("%"seq_len"s","")
    gsub(/ /,alphabet,s)
    print s}
    }' \
> input2.txt
```

ファイルサイズは25Mです。

```sh
ls -lh input2.txt | cut -d " " -f 5
25M
```

それでは、これを上記のコードで計算します。

その前に、計算時間とメモリ消費量を記録するコマンドを作ります。

```sh
alias time_='/usr/bin/time -f "========\nreal %es\nuser %Us \nsys  %Ss \nmemory:%MKB \n========"'
```

では、実行します。

```sh
time_ awk -F "" '
{for (i=1; i<=NF; i++)  { a[NR,i] = $i }}
NF>p { p = NF }
END { for(j=1; j<=p; j++) {
        str=a[1,j]
        for(i=2; i<=NR; i++){ str=str""a[i,j] }
        print str}}' input2.txt \
> output2.txt
```

```sh
========
real 25.33s
user 23.87s 
sys  1.44s 
memory:7554988KB 
========
```

**メモリをなんと<font color="blue">7.6GB</font>も消費しています！！** :scream:

# 解決法

メモリ消費量が大きい理由は、連想配列に全データを格納しているからです。
なので、目的の計算が終わったら直ちにファイルに書き出すようにします。

```sh
nr=$(cat input2.txt | wc -l)

time_ awk -v nr="${nr}" -F "" \
'{for(i=1; i<=NF; i++){
        row[i]=row[i] $i
        if(NR==nr) print row[i]
    }
}' input2.txt \
> output3.txt
```

```sh
========
real 6.46s
user 6.36s 
sys  0.09s 
memory:240704KB 
========
```
**メモリ消費量<font color="Red">240MB</font>！！**

**計算時間はおよそ1/4、メモリ消費量にいたっては約<font color="Red">3/100</font>になりました！**:tada:

最後に、Stack Overflowのコードと今回のコードで出力結果が同じか確認します。

```sh
[ -z $(diff output2.txt output3.txt) ] &&
printf "同じ結果です\n"
同じ結果です
```
同じ結果が得られました。

# 学んだこと

大きなファイルを扱う場合、連想配列に格納したデータは`END`まで保持せず、すぐに出力しましょう:fist:
LINUX コマンド【wc 編】使用例

# wc コマンド
ーファイルの「行数」「単語数」「バイト数」を表示してくれる

```Linux:$wc
$ $wc /etc/passwd
```
```Linux:実行結果
[hkoen@localhost ~]$ wc /etc/passwd
  44  101 2433 /etc/passwd
```
44:行数
101:単語数
2433:バイト数

#オプションコマンド
・-l：行数のみ
・-w：単語数のみ
・-c：バイト数のみ

```Linux:実行結果（-l）
[hkoen@localhost ~]$ wc -l /etc/passwd
 44 /etc/passwd
```



#実際にどう使うの？！
wc -lで行数をカウントする手順は、
内容のわからないファイルに対してcatやgrepを行う前によく使われます。
知らないファイルをいきなりcatやgrepをしてしまうと、
端末上に膨大な行の結果が出力されてしまう恐れがあるからです。

また、特定の文言を指定したgrepと組み合わせたログ解析の目的でも使われます。
WEBサーバ上の特定のアプリケーションに対するアクセス件数を調査したり、バッチ処理の結果を調査する際にも有用です。
クラウドのVMインスタンスを定期的に停止させる方法（AWS＆GCP）

業務で夜間に開発系のサーバを停止させて翌朝起動させたかったり、GPUインスタンスの停止漏れを防ぐために毎日夜間に停止させたりと、ニーズが高まったので方法を調べた結果を残しておきます。

この記事に画面キャプチャを載せて一から手順を書くよりも公式のヘルプページの方が確実ですので、概要は以下を御覧ください。そこまで難しい手順は無く、特にGCPについてはgcloudコマンドをコピペで実行していくだけで、ほぼほぼできあがります。

[AWSはこちら](https://aws.amazon.com/jp/premiumsupport/knowledge-center/start-stop-lambda-cloudwatch/)
[GCPはこちら](https://cloud.google.com/scheduler/docs/start-and-stop-compute-engine-instances-on-a-schedule?hl=ja)

ただし、AWSについてはインスタンスIDを直接指定ではなく、GCPのようにタグを使った方式にしたかったのと、PythonではなくRubyで実装したかったので、上記手順とはやや違うことをやりました。

こちらについては後日アップデート予定です。

## 追記（2020年6月10日）

> AWSについてはインスタンスIDを直接指定ではなく、GCPのようにタグを使った方式にしたかったのと、PythonではなくRubyで実装したかった

Lambdaのソースコードはこちらになります。タグで制御できると運用が楽になるのでおすすめです！

```ruby

require 'aws-sdk'

def lambda_handler(event:, context:)
    msg = start_instance
    { statusCode: 200, body: JSON.generate(msg) }
end

def start_instance
    ec2 = Aws::EC2::Resource.new(region: [リージョン])
    msg = ""
    ec2.instances({filters: [{name: 'tag:タグkey', values: [[タグvalue]]}]}).each do |i|
        name = i.tags.find { |v| v[:key] == "Name" }[:value]
        msg += "Instance:#{name}(#{i.id}) is "
        case i.state.code
        when 0  # pending
            msg = msg + "pending, so it will be running in a bit."
        when 16  # started
            msg = msg + "already started."
        when 48  # terminated
            msg = msg + "terminated, so you cannot stop it."
        else
            msg = msg + "stopped."
            i.start
        end
    end
    puts msg
    msg
end
```
Visual Studioを起動したら、ライセンス確認の画面が表示され、先に進まなくなったときの対処法

# はじめに
久しぶりにVisual Studioを起動したら、ライセンス認証の画面が表示されました
何度、ライセンスの有無を確認しても、エラーとなり対処に困ったので備忘録をまとめました

# TL;DR
一度Visual Studioをアンインストールして、再度インストールし直すことで解決できました

# 発生した事象
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103774/664f5c45-748e-bb4f-c1a0-55889311eb01.png)

上記のような画面が表示されました
サインアウト→サインインしても、解消されず、「更新されたライセンスの有無を確認」をクリックしても、変わらず。。。

ググると、以下のサイトを見つけました

[Visual Studio 2015 のアクティベーションが外れる](https://operationslab.wordpress.com/2016/07/31/visual-studio-2015-%E3%81%AE%E3%82%A2%E3%82%AF%E3%83%86%E3%82%A3%E3%83%99%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%8C%E5%A4%96%E3%82%8C%E3%82%8B/)

上記のサイトによると、30日に1回以上、Visual Studioを起動しないとライセンス認証が無効になるとのことです

無効になった場合は、Visual Studioを再インストールすることで解決できるそうです

実際に再インストールしたら、無事にVisual Studioが起動しました
DOTweenでカーブさせる

#DOTween便利
　1週間ほど前にDOTween使い始めました。便利ですねこれ。
　ただ、ちょっと探した感じ、オブジェクトを円周上でカーブさせる方法が見つかりませんでした。パスをうまいことやるとそれっぽいことができるようですが、勉強がてら拡張メソッドを書いてみました。

#できたやつ


DOCurveAroundAndRotateの実行の様子。Cylinderを中心にCubeが回転している。
![docurve.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439286/5ee5a557-7d04-3ba6-5ab4-9b809821d759.gif)



```C#
public static class DoTweenExt
{
    //centerを中心、axisを軸として、degree(度)回転する
    public static TweenerCore<float, float, FloatOptions> DOCurveAround(this Transform transform, Vector3 axis, Vector3 center, float degree, float duration)
    {
        var from = Vector3.negativeInfinity;
        return DOTween.To(() => 0, (x) =>
            {
                if (float.IsNegativeInfinity(from.x)) from = transform.position;
                transform.position = Quaternion.AngleAxis(x, axis) * (from - center) + center;
            },
            degree,
            duration
        );
    }

    //オブジェクトそのものも回転させる
    public static TweenerCore<float, float, FloatOptions> DOCurveAroundAndRotate(this Transform transform, Vector3 axis, Vector3 center, float degree, float duration)
    {
        var from  = Vector3.negativeInfinity;
        var fromRot = Vector3.zero;
        return DOTween.To(() => 0, (x) =>
            {
                if (float.IsNegativeInfinity(from.x))
                {
                    from = transform.position;
                    fromRot = transform.localEulerAngles;
                }
                var q = Quaternion.AngleAxis(x, axis);
                transform.position = q * (from - center) + center;
                transform.localEulerAngles = fromRot + q.eulerAngles;
            },
            degree,
            duration
        );
    }

    //使い方
    //(x,y,z)=(2,0,0)を中心に3秒かけて90度回転させる。
    //transform.DOCurveAround(Vector3.up, new Vector3(2, 0, 0), 90, 3);
}
```

#解説
　みんな大好き、Toメソッドを使います。Toの使い方ですが、

```C#
DOTween.To(() => Vector3.zero, (x) => transform.position = x, new Vector3(3, 0, 0), 1);
```
　(0,0,0)から(3,0,0)に1秒かけて移動します。

```C#
DOTween.To(() => 0, (x) => transform.position = new Vector3(x,0,0), 3, 1);
```
　上と意味は同じですが、変化する値があくまでもプリミティブなfloatになってます。このfloatを角度にして、角度からposition、localEulerAnglesを割り出します。

　それがCurveAroundAndRotateの

```C#
var q = Quaternion.AngleAxis(x, axis);
transform.position = q * (from - center) + center;
transform.localEulerAngles = fromRot + q.eulerAngles;
```
　この部分です。まずはQuaternionを出します。そのQuaternionと回転させたいVector3を掛ければ、(0,0,0)を中心に回転します。fromは開始位置ですが、あくまでもこの関数が走り始める時点での位置です。変数初期化時にtransform.positionを入れてしまうと、Sequenceで動かすときにおかしくなってしまいます。
　角度も同様で、関数が走り出す時点でのeulerAnglesをfromRotにとっておきます。で、fromRotとさっきのQuaternionのeulerAnglesとを足したものを放り込みます。

#所感
　Quaternionってすげー

　※ CurveAroundAndRotateでオブジェクトの向きがうまく変わらないバグがありましたので、修正しました。(2020/6/5)
【C#】 ファイルの内容を削除

##自己紹介
こんにちは。tetraです。
最近C#の学習を始めました。C#歴3ヶ月目の新卒エンジニアです。
ファイルを削除ではなく、ファイルの内容を削除するのはどうすればいいのかわからず時間を無駄にしたので作成します。

##ファイルの削除
最初はデリートを押すなんて考えていましたが、ファイルサイズを０にすれば内容のみを削除できると考えました。
早速書いていきます。

```sample.cs

using System.IO;
class sample
{
    static void Main()
    {
        using (var fileStream = new FileStream("./sample.txt", FileMode.Open))
        {
            fileStream.SetLength(0);
        }
    }
}
```


##いかがでしょうか？
いかがでしょうか。経験が浅いため至らぬところがまだまだあります。
もし間違い等に気がつきましたら、コメント又は[tetra](https://twitter.com/_T_E_T_R_A_)までお知らせください。
Logstash mutate filterのドットの扱い

# Logstash filter mutate pluginとは
Logstashでログを加工する時に、必ず使うのが「filter plugin」
その中でも、「mutate」は、fieldを消したり、リネームしたり、追加したりなど利用することが多いが、ドットが付いているfieldはnestedデータとして扱われるので、そのままでは「mutate」を使うことができない。

# やりたいこと
- data1.data2 を data1 にしたい 
- data1.data2.data3 を data1.data2 にしたい
- data1data2 を data1 にしたい

### 環境
- logstash-7.7.0

#### OK

``` 
       mutate {
           rename  => { "[data1][data2]"  => "data1" }
           rename  => { "[data1][data2][data3]"  => "[data1][data2]" }
        }
```
#### NG

``` 
       mutate {
           rename  => { "data1.data2"  => "data1" }
           rename  => { "data1.data2.data3"  => "data1.data2" }
        }
```
#### OK

``` 
       mutate {
           rename  => { "data1data2"  => "data1" }
        }
```

#### Elastic document.
- https://www.elastic.co/guide/en/logstash/current/event-dependent-configuration.html#logstash-config-field-references
TechAcademyが無料公開している「HTML・CSS入門講座」を受講する～導入～

# はじめに
この記事は、TechAcademyが無料公開している「HTML・CSS入門講座」を、HTML・CSS初心者が受講していくに当たり心構えを示した記事です。
この記事を書いている時点では、まだ受講していません。

# 目的と目標
###受講する目的
* Webプログラミングの知識を身につけるための導入。
* HTMLは中途半端な知識しかないので、基礎をもう一度学び直す。

### 受講する目標
* Webページを見たときに、どの箇所がHTMLでどの箇所がCSSかを判別できるようになる。
* 掲示板のような見た目のWebページを作る(なんでもいいからWebページを作成する)。

### Qiitaに記事を書く目的
* Markdownに慣れる。
* 学んだことを自分の言葉で発信するため。
* 読みやすい文章を書く練習。

過去に学んだことを見返した時、すぐに理解できるような記事を書く。

# おわりに
一言で言えば、HTML・CSSを学んで、その成果を記事として残すということです。
とりあえずやってみよう！の精神で頑張ります。

## リンク
HTML講座受講記事 : [こちら](https://qiita.com/MakoMakoMakotsu/items/996d65c0fe69da0c1f61)
CSS講座受講記事 : [こちら](https://qiita.com/MakoMakoMakotsu/items/8dcce71b7fb748e7998c)


## 参考
* [はじめてのHTML入門講座(TechAcademy)](https://www.youtube.com/playlist?list=PLjw-30bsJNVU87F5iCPAW9kB4QDUGQxUG&app=desktop)

* [はじめてのCSS入門講座(TechAcademy)](https://www.youtube.com/playlist?list=PLjw-30bsJNVVa4PuUseJ5YPN1K2dJr041&app=desktop)