OmniAICreator/Qiita-1.07M huggingface dataset:
Netlifyで他のPrivateリポジトリをsubmoduleで使う方法

## はじめに
Netlifyでホスティングしているリポジトリにsubmoduleで他のプライベートリポジトリを使おうと思ったら一手間必要だったので、その時のメモ

## 問題発生
Netlifyでホスティングしているリポジトリにsubmoduleで他のプライベートリポジトリを使おうと思い、ふつうにpush & buildしようとしたらbuildでこけた

Deploy logでは下記のようなError messageが

```
Preparing Git Reference refs/heads/master
Error fetching branch: https://github.com/owner/project refs/heads/master
Failing build: Failed to prepare repo
Failed during stage 'preparing repo': exit status 1
Finished processing build request in 6.873688521s
```
念のため、`Clear cache and deploy site`を試みたが、

```
Preparing Git Reference refs/heads/master
Error checking out submodules: Submodule 'path/to/submodule' (https://github.com/owner/project) registered for path 'path/to/submodule'
```
などと言われて、通らず

## どうして？
冷静に考えたら、自分以外の人（今回はNetlify）が特に認証なども行わずにプライベートリポジトリをクローンできたら問題だなぁと思った

## 対処法
Netilfy公式のdocsにある[Repository permissions and linking](https://docs.netlify.com/configure-builds/repo-permissions-linking/#access-other-repositories-at-build)をみるとしっかりと対処法が明記されていました。
>If a submodule repository is public, you can use https format (for example, https://github.com/owner/project) to link it in your submodule configuration. If the repository is private, or if you prefer to use ssh format (for example, git@github.com:owner/project.git), you will need to follow the instructions below to generate a deploy key in Netlify and add it to the submodule repository settings.

ざっくり翻訳すると、
「submoduleがpublicであれば、submoduleのconfigにhttpsのurlを書けばOK
submoduleがprivate（またはsshを使いたい）であれば、Netlify内で`deploy key`を生成してsubmodule repositoryに設定しましょう」
ってな感じなので

つまり、deploy keyで設定してsshでアクセスを試みればよさそう

### Deploy Keyの生成とGitHubへの追加
これも上記の公式のdocsをみれば書いてあるが、
Netlifyのサイト内で`Settings` -> `Build & deploy` -> `Continuous deployment` -> `Deploy key`までいき`Generate public key`を押す
すると

```
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDOG2pzIItUQ1IWKqQSN8pAB4VeHwHDFSw0M3ASVMj6sv+09zpBgA+bM0yf6x733q0hOPZASWf8IhmB8NINxz8d+DPndY6ORipQr3ROEhFS5gOfQZEEF6W9VO2ics3XwPczNT9E........
```

ってな感じの公開鍵が生成されるので、これをGitHubのsubmoduleリポジトリの`Settings` -> `Deploy keys`までいき、`Add depoloy key`を押して、適当な名前を入力し、その下に生成された公開鍵をコピペし、`Add key`を押します

### .gutmodulesの修正
ホスティングしてるリポジトリの`.gitmodules`をエディタでひらき、submoduleで使おうとしてるprivateリポジトリのurlを

```
https://github.com/owner/project
```
というhttps形式のものから

```
git@github.com:owner/project.git
```
というsshの形式のものに修正し、保存

### submoduleをsyncして再push
その後、

```
$ git submodule sync
```
を実行し、`.git/config`のsubmoduleセクションを更新

最後に、`.gitmodules`の差分をpushしたらbuildが通るようになった


## 参考
- [Repository permissions and linking](https://docs.netlify.com/configure-builds/repo-permissions-linking/#access-other-repositories-at-build)
- [サブモジュールを自分のフォークしたリポジトリで置き換える方法](https://www.atlassian.com/ja/blog/git-submodules-workflows-tips#tip1)
nuxt.jsのstoreの初期化方法

## 概要

以下のような初期化ではなく、あらかじめ初期値を宣言することで初期化する方法の紹介です

```javascript=
export const state = {
    text: '',
    arr: [],
    obj: {}
}

export mutations = {
    resetState(state) {
        state.text = ''
        state.arr = []
        state.obj = {}
    }
}
```

## コード(例)
```javascript=
// 今回 deep copy するために使用
import { cloneDeep } from 'lodash'

// state の初期値を宣言
const initialState = {
    text: '',
    arr: [],
    obj: {}
}

// 初期値を deep copy 
export const state = () => cloneDeep(initialState)

export const mutations = {
    resetState(state) {
        Object.keys(state).forEach(key => {
            // state のキー毎に initialState で定義した初期値を deep copy して代入
            state[key] = cloneDeep(initialState[key])
        })
    }
}
```

## 注意点
- 最初のstateの宣言、`resetState`での代入は`deep copy`で行わなければならない
- `shallow copy`で行うとinitialStateの値自体が書き換わってしまい正常に初期化できない場合がある
9行でわかるhead&tailの使い方（サンプルコマンドあり）

# 動画
動画は[こちら](http://www.youtube.com/watch?v=VELZASzb3SU)から（画像クリックでyoutubeへ）
[![head&tailの使い方](https://i.ytimg.com/vi/VELZASzb3SU/hqdefault.jpg?sqp=-oaymwEZCNACELwBSFXyq4qpAwsIARUAAIhCGAFwAQ==&rs=AOn4CLCudn-o8QcPsxIOP4mQLICSgcEqbw)](http://www.youtube.com/watch?v=VELZASzb3SU)

# head & tail
ファイルの先頭・末尾を抜き出すコマンド

# オプション：
* -n :表示行数指定　-n 20, -n20, -20
* -v :ファイルごとにヘッダ出力(verbose)
* -q :ファイルごとにヘッダ出力しない(quiet)

# 使い方サンプル：
* cat sample.txt | head -5
* cat sample.txt | tail -20
コードを読む時の俺々モデリング方法論

# ターゲット

- 入社してすぐで、大規模なコードを読むのに慣れてない方
- クラス図を知っている方（クラス、継承がわかってればOKです）
- 厳密な方法よりも、コードを読む時のちょっとした図の書き方を知りたい方

# はじめに
僕は入社2年目で、古くから伝わるJavaコードのメンテナンスをしているのですが
複雑なコード読むには、以下のような問題に直面して苦戦していました。
-　似た様な名前のクラスが大量にあって混乱する
-　どのクラスにどんなメソッドがあったか覚えておけない（さっき見てたメソッドどこにあるの？）
-　過去に似た修正をしたはずだが、過去のコードを見ても思い出すまでに時間がかかる

そんな中で、いろいろな試行錯誤をして気づいた有用なモデリング方法（クラス図の書き方)を紹介します。
注:自分はastahが好きなのでastahを使いますが、大抵のモデリングツール、作図ツールでも同じようなことが出来ると思います。

# 図にタイトルをつける

まずは図にタイトルをつけます。
この時、自分が知りたい事や修正したい事といった目的をタイトルとします。
こうすることで、この図が何を明らかになり以下のような事態が防げます。

 - 要らない要素まで図に書こうとして、時間を無駄にしてしまう
 - 要らない要素が増える事で、見にくい図になってしまう
 - 脇道にそれて全然違う事を調べている
 
さらに、作成した図をissueタイトルのついたパッケージに入れておくと
あとから「このIssueのココを修正した時、どうやって解決したんだっけ？」という時に掘り出しやすくて便利です。
![Screenshot from 2020-07-20 23-49-40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187123/3f014181-9ef9-b3af-5df4-df2a18cb3030.png)

# クラスを書く
図を作成したら、クラスを書いていきます。
ここで注意する点は、

- タイトルに書いた事以外の要素を表現しようとしない
- ノート機能（メモ）で関数の振る舞いや覚書を書いておく
- 疑問等もノートに残しておく

クラス図はクラス間の関係や継承関係などの構造を表現することは出来ますが、振る舞いを表現する事は出来ません。
なので関数の振る舞いなど、クラス図で表現出来ない要素や表現のやり方が分からない要素はノートに書いておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187123/80fef44d-d212-f0ab-a926-219892c6d904.png)

# まとめ

- 目的を明確にして図のタイトルや図要素を描く
- とにかくメモを残す

自分は上記2つを意識するだけで、かなりコードの理解力があがりました。
まだまだ2年目の駆け出しで、モデリングもコーディングも未熟ですが、一度試していただいて少しでも
コードを読むのがツライという人の助けになれば幸いです。
また、間違いや方法の改善点等発見され際はコメント等で教えていただければ泣いて喜びます。
viewWithTagで簡単に対象オブジェクトを呼び出して処理できる。

Swift初心者です。
こういうケースを想定してみてください

- ボタン（UIButton）がmain.storyboardにボタンA〜ボタンHまで8個配置されている
- ボタンAを押されたらボタンC,E,Gに対する動作を指定する
- ボタンBを押されたらボタンD,F,Hに対する動作を指定する

Swift初心者の私はこう書きました。
どうも、UIButton型の配列を作るのがうまくできなかったので、まずはボタンC〜Hを操作できるよう、ViewController.swift上で変数を宣言しました。
```
    @IBOutlet weak var btnC: UIButton!
    @IBOutlet weak var btnD: UIButton!
    @IBOutlet weak var btnE: UIButton!
    @IBOutlet weak var btnF: UIButton!
    @IBOutlet weak var btnG: UIButton!
    @IBOutlet weak var btnH: UIButton!
```

そのうえで、

```

@IBAction func play(sender :UIButton){ 
  switch sender.tag {
    case 1:
　　   btnC.imageView?.startAnimating()
　　   btnE.imageView?.startAnimating()
　　   btnG.imageView?.startAnimating()
    default:
　　   btnD.imageView?.startAnimating()
　　   btnF.imageView?.startAnimating()
　　   btnH.imageView?.startAnimating()
```
といったコードを書いていきました・・・

もっといい方法があるんだろうな、と思いながら書いていましたが、もちろんありました。
viewクラスの中にあるviewWithTagというメソッド。

```
let button = self.view.viewWithTag(tag) as! UIButton
```
main.storyboard上に、Viewというエリアがあり、ここにタグを入れられることは知ってました。
![スクリーンショット 2020-07-20 23.42.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32299/6f33d42d-3ad8-a5f0-8e83-63b97a78fa0c.png)

このタグの番号を持つボタンを取得してくれるというメソッドが、viewWithTagメソッド。
これを使えば、掲題の課題は下記のようにして記述ができる

```
    @IBAction func play(sender :UIButton){
        play(tag: sender.tag)
    }
    
    @IBAction func playThreeOdd(sender: UIButton) {
        play(tag: 1)
        play(tag: 3)
        play(tag: 5)
    }
    
    @IBAction func playThreeEven(sender: UIButton) {
        play(tag: 2)
        play(tag: 4)
        play(tag: 6)
    }
```
としてあげれば、あとはplayメソッドの引数をtag番号にして、viewWithTagメソッドでそのボタンを取得し、操作を書いてあげるだけ。

```
    func play(tag: Int){
        let button = self.view.viewWithTag(tag) as! UIButton
        button.imageView?.startAnimating()
    }
```
Unity：自分から見たターゲットの少し左（もしくは右）を狙いたい場合

３Dアクションゲームを作成していてタイトルの問題にぶち当たった。
解決策が見つかったのでここに記載。※某質問サイトで質問したら超スピードで回答を頂いた。

【実現したかったこと】
キャラクターA（自分）から見たターゲットBの座標があり、その少し左方向に狙いをつけたい、という事態に遭遇。
（作成した攻撃モーションが少し右にずれてたので狙いをつける位置自体を逆方向にずらして当たるようにしちゃえ、というぶッ飛んだ発想）
つまり以下のような状態
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677963/19f02af8-7476-00de-1084-05c0f6c7ccc3.png)



【解決策】
ターゲットのポジション　－　自分のtransform.Right * 少し(float)　　でターゲットの少し左の座標を導き出せる。

  var newPos = target.transform.position - (self.transform.right * 0.5f)//ずらしたい距離
　左右逆にずらしたい場合はずらしたい距離の正負を逆にしてやれば良い。
macで「英数」キーを「半角/全角」、「かな」キーを「command」キーに変更する方法

#はじめに
Windows/Linuxでは親指で押せるようにスペース左の「無変換」キーを「全角/半角」、スペース右の「変換」キーを「alt」にして使っていたのですが、初めてmacを買って同じようなキーマップにするのに意外と時間がかかったのでメモ。

#やりたいこと
このキー配置だと親指がうまく使えるので愛用しています。（デフォルトだと自分の場合commandキーが地味に押しにくい。。。）
![スクリーンショット 2020-07-21 0.07.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547016/48fa6750-c311-4a00-3de0-209ec2aee2a8.png)


#やり方
Karabinerというソフトを使うと簡単に解決します。

まずKarabinerを公式サイトよりインストール
[Karabiner-Elements](https://karabiner-elements.pqrs.org/)

インストール後下記のように設定します。
<img width="995" alt="スクリーンショット 2020-07-21 0.01.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547016/b2918468-a1c5-12a6-dfd6-e5f054d72f13.png">



・「英数」キーを「F13」という存在しないキーに割当て
・「かな」キーを「command」キーに割当て（これにより「かな」キー自体がなくなります）

このままだと英数/かな切替ができないので、
システム環境設定>キーボード>ショートカット>入力ソース>前の入力ソースを選択
にF13を設定します。これにより「英数」キーでWindowsの全角/半角と同じように切替ができます。

<img width="660" alt="スクリーンショット 2020-07-21 0.01.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547016/65bc0064-495c-36af-95b1-4bcd8b75caf4.png">


以上です。
CUTコマンドの使い方（サンプルあり）

# 動画
動画は[こちら](https://www.youtube.com/watch?v=_FZWHh4nNPI&t=69s)から（画像クリックでyoutubeへ）
[![head&tailの使い方](https://i.ytimg.com/vi/_FZWHh4nNPI/hqdefault.jpg?sqp=-oaymwEZCNACELwBSFXyq4qpAwsIARUAAIhCGAFwAQ==&rs=AOn4CLDL3zkH6dXhOo_ltfDc94Ctu3shjw)](https://www.youtube.com/watch?v=_FZWHh4nNPI&t=69s)

# CUTコマンド
CSVやTSVなどデリミタで区切られたデータの特定の列を取り出したり出来るコマンド。

# ユースケース
* DBから取り出したテーブルデータのカラムを取り出したい。
* DBに取り込むときに失敗したファイルの中身を見て確認したい。
→ぱっと思いつかず、基本DBになってますが、ほかのユースケースも結構ありそう。

# 構文
cut オプション ファイル名

# 覚えておきたいオプション
* -f:取り出すカラムの番号を指定。ex ：-f1,5（filedで覚える）
* -d: フィールドのデリミタを指定する（delimiterで覚える）
* --complement:-fで指定する番号以外のカラムのデータを取り出す。
（ほかにもありますが、覚えるのはこれだけで十分）

# サンプルコマンド

* cat sample.txt | cut -d' ' -f1,5　→　sample.txtからスペースを区切り文字として1,5カラム目のデータを取り出す。
* cut -d',' sample.txt -f1 → CSVファイルの１カラム目のデータを取り出す
* cat sample.txt | grep 'a' | cut -d' ' -f1 → grepした結果から特定の列を絞り込む。
Angularのテンプレート内にテンプレートを作る

`ng-template`, `ng-container`, `*ngTemplateOutlet` を使う

```html
<div *ngFor="let item of list">
  <ng-container *ngTemplateOutlet="group; context: { item: item }"></ng-container>
</div>

<ng-template #group let-item="item">
  <span>{{item.a}}</span>
  <span>{{item.b}}</span>
  <span>{{item.c}}</span>
</ng-template>
```
マイグレーション作成

# 今回やること
マイグレーション機能（データベースのバージョン管理）を使用して、phpMyAdminに作ったデータベース(mommy_book)にテーブルを作成する！

##ポイント
- migrationファイルの内容の中には、テーブルを作成する処理が含まれている　
  - up(): テーブル作成（バージョンアップ処理）
  -  down(): テーブル削除（ロールバック処理）
  
- Laravelにはプロジェクト作成段階で**ユーザ認証**が組み込まれてるようになっている
    - **ユーザ用のテーブル**と**パスワード再確認用テーブル**を作成するmigrationファイルがデフォルトで**database/migration**の直下に保存されている
　


今回のMommy_bookアプリでは、デフォルトのユーザ用migrationファイル（**Usersテーブル**用）に加えて、**Babiesテーブル、Vaccinesテーブル、Baby_checkupsテーブル、Baby_teethテーブル、Matanity_checkupsテーブル、Albumsテーブル**を作るため６つのmigrationファイルを作成する。

##流れ
1. migrationファイルを作成
2. テーブル定義書をもとにmigrationファイルを編集
3. migrationを実行
4. phpMyAdminのデータベースにテーブルが作成されているかを確認

ここでは、**①デフォルトでテーブルを作る場合（Usersテーブル）**と**②自分でmigrationファイルを作る場合（ex. Babiesテーブル）**の作成を説明します


##①デフォルトでテーブルを作る場合（Usersテーブル）

1.migrationファイルは既にあるので、**database/migration**の直下の**create_users_table.php**を開く
[デフォルトではup()は以下の通り、down()はデフォルトのままなので省略]

```
 public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }

  ```     

2.テーブル定義書をもとにmigrationファイルを編集
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656419/c81ae258-75e0-3f26-c6fe-f73caff9b178.png)

3.migrationを実行 (コマンドで）

 ```
php artisan migrate
```
4.phpMyAdminで確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656419/d147654b-5daa-0423-f8f4-aed9b1d8f3bc.png)

☆データベースにテーブルが作成できているので成功☆


##②自分でmigrationファイルを作る場合（ex. Babiesテーブル）

1. migrationファイルを作成

コマンドで、以下の通り(-createオプション：テーブル名は複数形で)

```
php artisan make:migration create_babies_table --create=babies
```

**database/migration**で作成した**create_babies_table.php**を開く
[デフォルトではup()は以下の通り、down()はデフォルトのままなので省略]

```
  public function up()
    {
        Schema::create('tweets', function (Blueprint $table) {
            $table->id();
            $table->timestamps();
        });
    }
```

2. テーブル定義書をもとにmigrationファイルを編集
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656419/32df9b4b-ba49-0d3c-ac07-aabdc6f54048.png)

3. migrationを実行

```
php artisan migrate
```

4. phpMyAdminのデータベースにテーブルが作成されているかを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656419/f14490ef-a99b-ae25-95c6-7c492265907b.png)


☆データベースにテーブルが作成できているので成功☆


##カラム設定で出てきたもの
ベースとなる書き方
**型がintegerのときは、引数を取ることできないので注意!!!!**

```
 Schema::create('テーブル名', function (Blueprint $table) {
$table->カラムの型（'カラム名', 引数）
}
```
nullのとき⇩

```
$table->カラムの型（'カラム名', 引数）->nullable();
```

メールアドレスなど値の重複を防ぎたいとき⇩

```
$table->カラムの型（'カラム名', 引数）->unique();
```


外部キー⇩

```
$table->foreign('外部キー名')->references('外部キーに対応する主キー名')->on('選択した主キーのテーブル名');
}   
```

timestamps()
有効（全体）桁数指定で、NULL値可能なcreated_atとupdated_atカラムを追加する
NULLが指定された場合は、デフォルト値が入る



## まとめ
以下の手順を繰り返す！！
1. migrationファイルを作成
2. テーブル定義書をもとにmigrationファイルを編集
3. migrationを実行
4. phpMyAdminのデータベースにテーブルが作成されているかを確認
PHP-数値を3桁ごとにカンマを付与する関数

##number_format関数
#### 数字を千位毎にグループ化してフォーマットする

```php5
<?php
  echo number_fornmat(1234567); //1,234,567
```

**laravelで使うときは下記のような感じで使う**

```php5
$price = [1000, 2000, 3000,];
foreach ($price as $value){
<td>¥{{ number_format($value->price) }}</td>
}

結果
¥1,000
¥2,000
¥3,000
```

余談ですが、勝手に小数点を含む数値」を四捨五入するので、第二引数に桁数を指定すれば小数点以下も表示できます。

```php5
<?php
  echo number_format(1234.567,2); // 1,234.57
```
Haskellにはそもそも+++という演算子が存在する

# Haskellにはそもそも+++という演算子が存在する

[JavaScriptで+++は許されない+ ++は許される](https://qiita.com/matyapiro31/items/19d62605632dd90d0647) を読んで書きましたシリーズです。

## +++演算子の説明

　Haskellには、`+++`は許される/許されない以前に、まさにそのような演算子が存在します。
　これは`Control.Arrow`モジュールで定義されている`ArrowChoice`型クラスのメソッドであり、次のような型を持つ演算子です。

```Haskell
(+++) :: ArrowChoice a => a b c -> a b' c' -> a (Either b b') (Either c c')
```

　慣れていなければ読みづらいので、少しこれに説明をつけます。
　最も一般的な`ArrowChoice`型クラスのインスタンスは単純な関数なので、簡単にするために`a`をこれに置き換えます。

```Haskell
(+++) :: (b -> c) -> (b' -> c') -> (Either b b') -> (Either c c')
```

　`Either a b`は、`a`か`b`のどちらかを表す型です。
　すなわち、この関数の型は「`b`を受け取って`c`を返す関数」と「`b'`を受け取って`c'`を返す関数」を結合(`+++`)させて、「`Either b b'`を受け取って`Either c c'`を返す関数」にすると読めます。
　`Either b b'`は`b`か`b'`のどちらが入っているか分からないけど、`b`を`c`にする関数と`b'`を`c'`にする関数の両方があれば適切な方の関数を適用することができるという理屈ですね。

## &&&演算子もある

　こちらも`+++`同様`Control.Arrow`モジュールで定義されています。ポインタや論理積とは全く関係ありません。

```Haskell
(&&&) :: Arrow a => a b c -> a b c' -> a b (c, c')
```

## Haskellでは好きな演算子を定義できる！！

　ところで、Haskellでは、かなり高い自由度で自分の好きな二項演算子を定義することができます。
　普通の足し算に物足りなくなったら、`++++++++++`演算子を定義してパーティー気分を味わいましょう。

```Haskell
(++++++++++) :: Int -> Int -> Int
a ++++++++++ b = a + b
```

　C++のあの演算子を真似すれば、謎のプロっぽさが出るかもしれません。

```Haskell
a .* mp = undefined
p ->* mp = undefined
```

　他にも、カッコいい矢印を使ってFizzBuzzを書いてみたりできます。

```Haskell
(~>) :: Int -> String -> Int -> Maybe String
a ~> s = \b -> s <$ guard (b `mod` a == 0)

fizzbuzz :: Int -> String
fizzbuzz = fromMaybe . show <*> (3 ~> "fizz" <> 5 ~> "buzz" )
```

　矢印`->`が予約されていることへの反抗として、クソ長矢印を定義してもいいでしょう。なんかコメントっぽくハイライトされていますが、これは合法なHaskellコードです。

```Haskell
a ----------> b = undefind
```

## まとめ

　Haskellには、`+++`という演算子が存在する。
　Haskellでは演算子をある程度自由に定義できる。そのため、演算子の解釈に困ることはない。(演算子が何を意味しているのかで悩むことは滅茶苦茶ある)
IQ Bot テーブルの抽出応用編まとめ

IQ Botのテーブル抽出は、カスタムロジックを組み合わせるとかなりフレキシブルに行うことができます。

ここでは、以下のような帳票に対して、カスタムロジックを使ってフレキシブルにテーブルの抽出結果を成形するやりかたを解説します。

##サンプル帳票
![どこでも商事（明朝、グレー、紺文字）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/33ed9cb1-44eb-040f-6644-ae50dcdf26c5.jpeg)

## 通常の抽出結果
上記のような帳票をIQ Botで抽出すると、以下のような結果が得られます。
![抽出結果.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/8deb95c9-b44c-3a8f-9612-21013de87eb4.jpeg)

## カスタムロジックを使ってできること

カスタムロジックを使うと、以下のようなことができます。
各項目をクリックすると、やりかたのリンクに飛べます。

###[(1)空欄行の中身を埋める](https://qiita.com/IQ_Bocchi/items/198815e9607f76678718)
![01_空欄埋めイメージ2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/90b9d3f3-49bf-7606-681e-459aa8699c65.jpeg)

###[(2)下X桁を小数として扱う](https://qiita.com/IQ_Bocchi/items/412e1062d8bb2bd98d70) 
![小数点.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/8ecff98e-6fb1-bc78-a4b8-b5791d33600d.jpeg)

###[(3)テーブルの列から必要な部分だけを取り出す](https://qiita.com/IQ_Bocchi/items/2215c907d7fcf7cc7382) 
![金額だけ取り出し.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/88872640-c276-02e5-59c8-0d52ea808dfa.jpeg)

###[(4)テーブルの列を自由に分割する](https://qiita.com/IQ_Bocchi/items/2628b5d2306b388db489) 
![金額、税区分、税率を分割.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/f6f7052e-c04d-87fd-5666-79e611a3e159.jpeg)

###[(5)明細の不要な行を除外する](https://qiita.com/IQ_Bocchi/items/e714b15225f425a582c5)
![不要な行の削除.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/73fb3612-762f-dec4-5309-2c3fa7371b25.jpeg)

##最後に

以上、カスタムロジックを使ってできる代表的な明細の処理を紹介しましたが、他にも「こんなケースはどうですか？」などの質問があれば、ぜひこの記事にコメントを残していってください。

時間はかかるかもしれませんが、なるべくお答えいたします。
プレースホルダーとは？

#そもそもプレースホルダーの意味は？

- 正式な値が入るまで一時的に場所を確保しておく措置のこと

- 後から入力される実際の値の代わりに仮に使用される文字列や値、ラベル、目印、確保された位置やスペースのこと

#プログラミングにおけるプレースホルダーとは？

- 式や命令文などの一部に利用者の入力値など実行時に外部から与えられる要素を反映させるような場合に、それが入る予定の場所のこと

#プレースホルダーの例

- HTMLの場合、入力フォームのテキストボックスやテキストエリアの中であらかじめ表示される初期表示文言のこと

- PowerPointの場合、タイトルや本文、図表などのレイアウトを保持する点線で囲まれたボックスのこと



参考サイト:https://wa3.i-3-i.info/word118.html
参考サイト:http://e-words.jp/w/%E3%83%97%E3%83%AC%E3%83%BC%E3%82%B9%E3%83%9B%E3%83%AB%E3%83%80.html
参考サイト:https://makitani.net/shimauma/placeholder
【GAS】検索したメール本文の特定部分をスプレッドシートに書き込む

# はじめに
特定の条件のメールを検索して、本文の特定部分を取得するコードです。
処理イメージは以下です。
1. 以下のようなメールがあった場合に、申請番号の値「1234567890」と件名「けんめい」を取得し、
2. 以下のようにスプレッドシートに値をセットする
処理をします。

##### メール
<img width="362" alt="スクリーンショット 2020-07-20 23.17.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14760/d943d0e2-b314-bffb-b3f2-dfdfce13377f.png">

##### スプレッドシート
<img width="353" alt="スクリーンショット 2020-07-20 23.21.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14760/2ba60572-4438-88cd-8ae0-16c40ff794df.png">


# コード
``` javascript
function myFunction() {
  // メール検索条件。処理済みのメールは除外。
  let query = 'subject:(検索したい件名 -label:済み';
  // メール検索
  let threads = GmailApp.search(query);

  // 取得した申請番号と件名を格納する配列  
  let items = [];

  // 1スレッドずつ処理 
  threads.forEach(function (thread) {
    // １メッセージずつ処理
    thread.getMessages().forEach(function (message) {
      let subject = message.getSubject();
      let body = message.getBody();

      // 正規表現で処理するためHTML形式ではないプレーンな型の本文を取得
      var plainBody = message.getPlainBody();

      // 正規表現で取得したい箇所を取得
      let ringiAppNo = plainBody.match(/申請番号： (.*)/);
      let ringiSubject = plainBody.match(/件名：(.*)/);
      
      // 結果を入れる配列に格納
      items.push([
        ringiAppNo[1],
        ringiSubject[1]
      ]);

      /* 戻り値の説明
      戻り値
      0 : マッチした文字列全体が入る
      1~ : それぞれのキャプチャ
      index : マッチした場所 (bite値 じゃなくて 0から数えて何番目の文字か？)
      input : 検索される側の文字列
      */
    });

    // スレッドに処理済みラベルを付ける
    // ※要注意※ あらかじめラベルが無いとうまくいかない。
    let label = GmailApp.getUserLabelByName('済み');
    thread.addLabel(label);
  });

  // 処理結果が０件だったとき用にエラーハンドリング
  if (items.length == 0) {
    // ０件の時は、メッセージボックスを表示
    Browser.msgBox("処理対象なし", Browser.Buttons.OK);
  } else {
    let sheet = SpreadsheetApp.getActive().getSheetByName('書き込みしたいシート名');
    let row = 2;
    let column = 1;
    let numRows = items.length; // 配列数 = 行数
    let numColumns = items[0].length; // 配列の要素数 = カラム数
    sheet.getRange(row, column, numRows, numColumns).setValues(items);  
  }
  
}

```

# 参考
* [【GAS】Gmailのメール本文をスプレッドシートに転記する方法](https://valmore.work/how-to-copy-gmail-message-to-spreadsheet/#i-5)
* [[JavaScript] String.match(regexp) の返り値は何か？ / 正規表現の変わりに文字列を使うとどうなるのか](https://fernweh.jp/b/string-match/)
* [javascriptのmatchメソッドで戻り値より任意の数字、英文字を切り出す](https://qiita.com/bitarx/items/d0699b23fcf07d703738)
Swift日記(8日目)

#今日やったこと
 - 用語の勉強

#FizzBuzzやった

``` FizzBuzz.swift
import UIKit
func printfizzbuzz(fizz_value:Int){
    for i in 1...fizz_value{
        if i % 15 == 0 {
            print("FizzBuzz")
        }else if i % 3 == 0  {
            print("Fizz")
        }else if i % 5 == 0 {
            print("Buzz")
        }else{
            print(i)
        }
    }
}

printfizzbuzz(fizz_value: 100)

```

#クラス・関数・変数

 - 関数
  - 実行する命令のかたまり、のようなもの。中でいろんな処理をしてくれる
 - 変数
  - 様々なものを入れておく入れ物。中身を一定のルールで変えることができる。中身を変えることができない入れ物を定数という。
 - クラス
  - 関数と変数をまとめた集まり。
  - クラスの中にある変数をプロパティ、関数をメソッドと呼ぶ。なぜぇ。。。
  - クラスの中でプロパティやメソッドが働いてできあがった変数をインスタンスという。

変数一個に2種類も呼び方あるの納得いかねぇ。。。
C++ 二次元array,vectorの最小値,最大値とそのインデックスの取得


```cpp
vector<vector<int>> ary(n, vector<int>(n));
int MIN = INT_MAX;
int MAX = INT_MIN;

for (i = 0; i < n; i++) { 
          minx = min(minx, (int)*min_element(ary[i].begin(), ary[i].end()));
        　maxx = man(maxx, (int)*max_element(ary[i].begin(), ary[i].end()));
     
            if (*MIN > minx) {
                *MIN = minx;
                min_index= distance(ary[i].begin(), min_element(ary[i].begin(), ary[i].end()));
            }
            if (*MAX < maxx) {
                *MAX = maxx;
                max_index= distance(ary[i].begin(), max_element(ary[i].begin(), ary[i].end()));
            }
}
```
EXE,DLLのビット数を確認する

日課のメモの放出。月曜日は時間がないので。。。
今回は以下のリンク先の情報を参考にさせていただきました。ありがとうございます。

- [EXE、DLLが32bitなのか64ビットなのか確認する方法 - Qiita](https://qiita.com/towtow/items/a5c92482cca797456b86)

# EXE,DLLのビット数を確認したい

とある案件でシステム構成を調べている際に、とあるDLLのビット数を確認する必要が出てきました。
しかしながら、タスクマネージャにはビット数出てこないし、バイナリエディタないし、(バイナリエディタを)インストールできないし(禁止のルールだったので･･･)。
その際に調査したメモを放出します。

# まずは、タスクマネージャーで確認

起動できるEXEなら、タスクマネージャーで確認。
プロセスタブの各アプリ名の後ろに(32ビット),もしくは(64ビット)と表示される。

# 起動しないタイプのEXE,DLLはdumpbinで確認

起動しないタイプのEXE,DLLはこちらの方法で確認する。
cmdじゃなくて、VSのコマンドプロンプトを実行して下記のコマンドを実行。
( "Visual Studio Tools" から "Visual Studio コマンドプロンプト" を起動)

```text:32ビット
dumpbin /headers "確認するファイルパス" | findstr machine
             14C machine (x86)
                   32 bit word machine
```

```text:64ビット
dumpbin /headers "確認するファイルパス" | findstr machine
             14C machine (x86)
                   32 bit word machine
```

# バイナリエディタで確認

今回の状況とは違いますが、逆にVSがなくてバイナリエディタが用意できるのであればPEヘッダ見てみませう。

```text:32ビット
50 45 00 00 4C 01
```

```text:64ビット
50 45 00 00 64 86
```

# そもそも、Windowsにこだわらなくていいじゃん。fileコマンドという文明の利器があります

普通にfileコマンドで確認できます。
Windowsなら、Cygwin使えば確認可能です。
まぁこれ確認した当時はWindowsOS限定だったし、Cygwinなんて便利なものなかったんですよね････
IQ Bot：明細の下X桁を小数として扱う

実務で扱う帳票の中には、以下のように、罫線の位置が小数点を表しているケースがあります。

![小数点.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/d91471e8-5e0c-1e22-6d35-635a5c052db4.jpeg)

このようなケースも、IQ Botのカスタムロジックを使えば処理できます。

#サンプルコード

```python:カスタムロジック（小数点付加）の実装例

# 値を保存する変数: table_values
#表の操作をするときに必ず入れるコード（最初）
import pandas as pd
df = pd.DataFrame(table_values)

#############################################
# ↓↓↓ ここからが今回の処理 ↓↓↓ 
#############################################

import re

def decimalAdd(num, digit):  
  num = re.sub("\\D","",num)
  seisu = str(num)[:-digit]
  shosu = str(num)[-digit:]
  result = str(seisu) + "." + str(shosu)
  return result

df["単価"] = df["単価"].apply(decimalAdd,digit=2)

#############################################
# ↑↑↑ ここまでが今回の処理 ↑↑↑
#############################################    

#表の操作をするときに必ず入れるコード（最後）
table_values = df.to_dict()

```

#応用例

上記のサンプルコードの細かい説明は省きますが、応用する場合に変える必要があるのは以下の部分だけです。

```python:カスタムロジック（小数点付加）の実装例
df["単価"] = df["単価"].apply(decimalAdd,digit=2)
```

変更箇所は２か所。

1. `"単価"`の部分を処理したい列名に変えます。（２つあるので２つとも）
2. `digit=2`は、下2桁を小数とみなすという意味です。下3桁を小数にしたい場合は、`digit=3`というふうに変えます。

#コードの意味がどうしても気になる人は……

以下の記事を読みながら上記のコードを眺めてみると、意味がわかると思います。

- [pythonのスライスについて](https://qiita.com/okkn/items/54e81346d8f35733ab5e)
- [pythonの関数定義　↓と同じことを解説してますが、どちらもGoodでした](https://qiita.com/hiroyuki_mrp/items/f4f1a173c7d454029466)
- [pythonの関数定義　↑と同じことを解説してますが、どちらもGoodでした](https://qiita.com/Fendo181/items/a934e4f94021115efb2e#%E9%96%A2%E6%95%B0)
- [数値だけを取り出す](https://qiita.com/IQ_Bocchi/items/b380ab96e5bf8b0b1e57)
- [pandasのapplyに複数の引数を渡す方法](https://qiita.com/yubiquita/items/6d5966e8e10904076230)
【初心者でもわかる】font-familyの正しいつけ方・ツールも紹介

# どうも7noteです。デザインを通ってないと種類が多くて指定が厄介なフォントのお話。
どうも7noteです。
この記事は以下へ引っ越しました。

https://naruweb.com/tool/font-family/
npmにパッケージを公開しようとすると404エラーが出るときの対処法

タイトル通り、npmにパッケージを公開(`npm publish`)しようとするときに404エラーが出た。日本語の情報が無く、原因を探すのに右往左往したのでメモしておく。

##筆者の環境
Windows 10 Home 1909
Node v12.18.2
npm 6.14.5

##状況

以下パッケージ名などは伏せてある。

```bash
$ npm publish ./
npm notice 
npm notice package: <name>@<version>
npm notice === Tarball Contents === 
npm notice <filesize>kB LICENSE
省略(ファイル色々)
npm notice <filesize>kB README.md
npm notice === Tarball Details ===
npm notice name:          <name>
npm notice version:       <version>
npm notice package size:  <package-size>
npm notice unpacked size: <unpacked-size>
npm notice shasum:        <shasum>
npm notice integrity:     <integrity>
npm notice total files:   <total-files>
npm notice
npm ERR! code E404
npm ERR! 404 Not Found - PUT https://registry.npmjs.org/<name> - Not found        
npm ERR! 404 
npm ERR! 404  '<name>@<version>' is not in the npm registry.
npm ERR! 404 You should bug the author to publish it (or use the name yourself!)
npm ERR! 404
npm ERR! 404 Note that you can also install from a
npm ERR! 404 tarball, folder, http url, or git url.

npm ERR! A complete log of this run can be found in:
npm ERR!     <directory of logfile>

```

##解決法
`npm adduser`でログインするだけ

```bash
$ npm adduser
Username: <username>
Password: <password>
Email: (this IS public) <email-adress>
Enter one-time password from your authenticator app: <2FA Code>
Logged in as <usename> on https://registry.npmjs.org/.
```

##まとめ
チュートリアル記事は飛ばさずに読みましょう。
文系卒だけどいきなりRuby on Railsの勉強をはじめてみた #11 アカウントの有効化

この章では、アカウントを有効化するプロセスを実装するらしい。
アカウントを有効化するというと小難しいが、なにかのサービスに新規登録する際に届く認証メールも有効化の1つなので、イメージしやすい。

# 11.1 AccountActivationsリソース
まずは、Usersのテーブルにカラムを追加する。
有効化したかどうか、有効化するときに利用するダイジェスト、有効化した日時の情報を格納するためだと思われる。

そして、次に「コールバック」と呼ばれるシステムを実装する。
これにより、オブジェクトを生成するたびにトークンやダイジェストが生成されるようだ。
そういえば、トークンとダイジェストはなにが違うのだろう...。

#11.2 アカウント有効化のメール送信
この章では認証メールを送る機能を実装した。

難しく、かつ、長いのであまり理解はできなかった...。
ただ、Railsのメソッドを利用することでメールを送信することができることや、ユーザーごとに発行URLを変えられることを知った。

#11.3 アカウントを有効化する
この章は難しすぎて、脳死状態でコードをコピペするはめになった。
基本的にテストとかリファクタリングなるものをまだ理解できていない気がする。

#11.4 本番環境でのメール送信
メール送信はHerokuアドオンの「SendGrid」というものを利用するっぽい。
というくらいしか、よくわからなかった。
Empty path name is not legal.(Unity,C#) の 意味と エラー対処

Unity(C#)でファイル書き込みをしようとした際にエラーが出ました．
あまりUnityやC#について日本語で書かれているものが見つからなかったので，残しておきます．

## Empty path name is not legal. とは
これで検索をかけたところファイル名に使用できない文字が含まれていないか？
という原因がありましたが，
自分の場合は呼び出し位置の変更によってエラーが出たため、
ファイルパスには問題がないことが分かっていました。

⇒Empty path name is not legal.
　は単純に和訳しても「空のパス名は違法です」なので，
　上記で言っていることは全く違いますね……
　全然日本語の記事が見つからなかったので，
　素直に英文の意味を考えればこんなに悩むエラーでもなかったです．反省．　

## エラー箇所

エラーが出たのは下記の記述部分でした．
最初はa,b,cを同じ関数の中で定義していたことから，
関数に引数を渡す時点（もしくは渡す前）に文字コード周りで
エラーが起きているのかな？と思いましたがそういうわけでもなく……


```hoge.cs

public void WriteHeader(string a,string b,string c){
 using (StreamWriter sw = new StreamWriter(filepath, false, Encoding.GetEncoding("Shift_JIS")))
 {
      string[] s1 = { a,b,c };
      string s2 = string.Join(",", s1);
      sw.WriteLine(s2);
 }
}
```

## 結局，原因は？

Unityでありがちな問題ですがStart()の実行順序関連でした．
自分の場合はfilepathを同じクラスのStart()で定義しており，
それより前に別のクラスからWriteHeader()関数を呼び出しているため，
「FilePath」が見つからない，というようなエラーだったようです．
（それならもっと他のエラーが出てもよさそうな気はしますが……）

しかし，Start()の実行順は確か決まりがなかった気がするけど，
どうやって確実に元ファイルのStart()を実行後にこの関数を呼び出せるだろうか？
ということで調べなおしてみたところこんな記事がありました．
https://ekulabo.com/execution-order
どうやらスクリプトの実行順をEdit>Project Settingsから設定できるようです．

よくここまでこれ無しでやってきたもんだな……という便利さなので，
使ったことのない人，同じようなエラーで実行順に悩んでいる人がいたら(いるのか？)
ぜひ一度お試しいただければと思います．
【#2 Python】Pythonで一番注意すべきポイントはインデント！！

<br>Pythonは分かりやすい言語だと言われていますが、
JavaやC言語から入った私は「インデント(字下げ)」に少し苦しめられました･･･。

JavaやC言語だと、波括弧{}で囲まれているのでインデントにそこまで気を配る必要はありません。~~CTRL + A、CTRL + Iで一発だしね。~~<br>
しかし波括弧を使わないPythonではインデントは超大切!!
コードの見た目がそのままプログラムの動作に影響するので、気を付けなければなりません。

```python
score = 50
if score == 100:
    print("よくできました!")
    print("次も頑張りましょう!")
# 条件式が成り立たないため実行されない
```
```python
score = 50
if score == 100:
    print("よくできました!")
print("次も頑張りましょう!")    #インデントがないため、if文の外と見なされる
# 次も頑張りましょう!
```

私はここで少し引っかかりました。
言語が違うとやっぱりちょっとあれ？ってなりますね。気を付けよう。<br>
【MATLAB】Waterfall図の作成

# 概要
2つの数字の差異を可視化するときによく使われるWaterfall図。
Excelでも2016からデフォルト機能で描けるようになりました（下図）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634607/077a2990-939d-f095-470f-381185d47075.png)

MATLABでもデフォルトで描ければ業務自動化が捗るのになと思っていたら，
関数を公開してくださっている方を発見しまして（[参考文献[1]](#参考文献)），参考にさせていただきつつ自分好みの見栄えにしました。




# 本文
## 関数の呼び出し

こんな感じで数字とラベルを投げると，

```matlab
y=[10, 2, -3, -3, 5]; % 基点の値，要因A/B/C/Dによる変動，終点の値は省略
xlabel={'基点','要因A','要因B','要因C','要因D','終点'};
wfall(y,xlabel);
```

こんな感じでグラフを表示してくれる関数 `wfall`を作成しました。
![bar.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634607/d4340e6b-6c77-a562-6321-c36559172169.png)


## 関数 `wfall`
ポイントは3点です。

1. 要因バーの底辺の位置は，bar関数のプロパティ `BaseValue` で設定する。
2. バー1つ1つに直行座標軸 `ax(i)` を設定する。そのままだと最後に描いたバーしか見えないので，背景色 `Color` を `none` に設定する。
3. バーの色は `Colormap` & `CLim` で設定する。`CLim` の0=基点と終点=藍色，1=増加=緑，-1=減少=赤色とする。

```matlab
function [] = wfall(y,xlabel)

%% 準備

n = length(y);
cumy = cumsum(y); % 累積和
c = sign(y); % 符号判定（バーの色に使う）

% 座標軸をn+1個作成
ax = gca;
for i = 2:n+1
    ax(i) = copyobj(ax(1), ax(1).Parent);
end

%% グラフ描画

h = bar(ax(1), 1, cumy(1), 'CData', 0, 'BaseValue', 0);
hold on
for i = 2:n
    h(i) = bar(ax(i), i, cumy(i), 'CData', c(i), 'BaseValue', cumy(i-1), 'ShowBaseLine', 'off'); % 要因バーの底辺をBaseValueで設定（ポイント①）
end
h(n+1) = bar(ax(n+1), n+1, cumy(n), 'CData', 0, 'BaseValue', 0);
hold off

%% グラフの見栄え設定

% 縦横サイズ
set(ax, 'XLim', [0, n+1]+0.5, 'YLim', [min(min(cumy), 0), max(max(cumy), 0)]);

% すべてのバーが見えるようにする（ポイント②）
set(ax(2:end), 'Color', 'none');

% 横軸縦軸の設定
for i = 1:n+1
    set(ax(i),'XTickLabels',xlabel(i));
end
set(ax(2:end), 'YColor', 'none');

% バーの色設定（ポイント③）
clmap = [...
    255,0,0;... % 赤 - colorcodeは-1
    0,51,153;... % 紺
    0,128,0]; % 緑
set(ax, 'CLim', [-1, 1], 'ColorMap', clmap/255);

% CDataプロパティの適用
set(h, 'FaceColor', 'flat') 

% グリッド設定
set(ax,'XGrid','off');
set(ax,'GridLineStyle',':');
set(ax,'GridAlpha',0.1);
set(ax,'Layer','top');

end
```

# 参考文献

以下のサイトを参考にさせていただきました。

[1] stack overflow > Consulting waterfall chart matlab > Answer Method 1
https://stackoverflow.com/questions/60685448/consulting-waterfall-chart-matlab

[2] MathWorks > ヘルプセンター > bar
https://jp.mathworks.com/help/matlab/ref/bar.html
オンライン授業でいろいろヘッドセットを試してみたのでログを残してみた

# この記事で書かれていること

- いろんなヘッドセットをオンライン授業で授業提供する側として使用して、その結果どうだったか

## 背景

- オンライン授業にともない、経費でヘッドセットを買うときに、すでにAmazonで購入するには出遅れていた。
- そのため、まずは当時、すぐに入手できる安価なものから購入して、その結果により次の購入で品質を上げるというサイクルにした。

## どんなヘッドセットを使ったか

### 量販店で購入したもの編

#### ドンキで購入したヘッドセット
- 両耳イヤーマフタイプのヘッドセット。
- 3000円台。
- 迷彩柄が魅力的な、スタッフみんなのテンションが上がった一品。
- しかし、近くで大量に買えたものの、マイクと口が遠く、また環境音を拾いまくりだったので、「雑多な環境の中でオンライン授業を提供するのには向いていない」。
- オンラインミーティングでも、隣同士でそのヘッドセットを使っていると、お互いの声を拾うので、業務で使用する品質ではない。
- ただし、自宅など、ある程度の閉鎖空間で使用する分には問題がない。(リモートワーク向け)
- 近く、ヘッドセットをリプレースするので、残念ながらその対象の筆頭である。

#### ビックカメラのヘッドセット
- 両耳イヤーマフタイプのヘッドセット。
- 3000円〜4000円。
- コロナでヨドバシが営業自粛で休館している間も営業してくれていた会社にとっての救世主。
- マイク部分が稼働するので、オンライン授業を提供する製品としては及第点。

### Amazonで購入したもの編

#### Razer Kraken RZ04-02830100-R3M1
- [Razer Kraken Black ゲーミングヘッドセット アナログ接続 PS4 PC Switch スマートフォン 冷却ジェルパッド【日本正規代理店保証品】 RZ04-02830100-R3M1](https://www.amazon.co.jp/gp/product/B07NJQ1YBY/ref=ppx_yo_dt_b_asin_title_o04_s00?ie=UTF8&psc=1)
- 安定のRAZER。
- セール価格で8980円で購入。現在は9769円。
- 両耳イヤーマフ指向性マイクタイプのヘッドセット。指向性マイク。
- 安定のRAZER。
- 環境音の吸収は無いので静かに授業提供できる。

#### 両耳イヤーマフ無線USBレシーバー接続型
- [ 2.4GHzゲーミングヘッドセット ワイヤレス ヘッドホン 回転式 ヘッドフォンusb サラウンドヘッドホン 重低音強化ノイズキャンセリング マイク付き PC/PS4/PS4 Slim Nintendo Switch対応 ブラック2年間メーカー保証](https://www.amazon.co.jp/gp/product/B086378N39/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1)
- 6499円で購入。
- マイク部分が固く、当初はまっすぐのまま使用していたが、思い切って曲げてみたら曲がったので、指向性の音を拾うようになった。
- 環境音の吸収はほとんどない。
- 無線のゲーミングヘッドセットの中ではかなりコスパ良しとなる。
- 無線なので、オンライン授業を提供しつつ、対面で授業提供もできるスグレモノ。

#### エレコム HS-HP28BK
- [エレコム ヘッドセット マイク 両耳 オーバーヘッド 片出しケーブル 1.8m HS-HP28BK](https://www.amazon.co.jp/gp/product/B01HGGWZCG/ref=ppx_yo_dt_b_asin_title_o07_s00?ie=UTF8&psc=1)
- 当時は2149円で購入。現在1305円。
- さらにこれも必要。[サンワサプライ ヘッドホン+マイク用変換アダプタケーブル(3極メス×2→4極オス) KM-A25-005](https://www.amazon.co.jp/gp/product/B01BV916AQ/ref=ppx_yo_dt_b_asin_title_o08_s00?ie=UTF8&psc=1)　約600円。
- マイクのまわりにスポンジがあるのと、マイク性能の低さのため、マスクをつけながらの授業提供はほぼ不可能なのと環境音拾いまくり。
- ヘッドセット入れ替えリプレース対象。

#### 片耳インナーイヤーBluetooth接続タイプ
- [ [令和２年進化型]Bluetoothヘッドセット　Bluetoothイヤホン　ワイヤレスイヤホン V5.0 10時間連続使用　マイク内蔵　ビジネス　耳掛け型　ハンズフリー通話　片耳型 CVC8.0ノイズキャンセリング　 ミュート機能　左右耳兼用 高音質　ブルートゥースヘッドセット　マイクブーム180°回転　快適装着　iPhone＆android対応　オンライン英会話/ビジネスチャット/仕事/通学/ウォーキングなどに適用　収納ボックス付 在宅勤務](https://www.amazon.co.jp/gp/product/B08728RQNX/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1)
- メーカー名が先頭に来ていない品名。(一応メーカーサイトはあった)
- クーポンで2533円で購入したが、現在は3000円台。
- ２機との接続ができるが、両方から音が聞けるわけではない。
- zoomのマイクテストでは、イヤホンの構成上、音質は両耳イヤーマフほどの品質は良くないが、聞こえる。
- 環境音の吸収については、まだ実戦していないのでノーコメント。(ただ部屋の扉の開閉音を拾ったので、かなり不安が残る)
- 部屋の中で、曲を流しながらzoomでのマイクテストを行ってみたところ、けっこう音は拾った。(拾ったが、自分の声も通っている)
【確率雨量】100年に1度の大雨ってどうやって計算しているの？　―第1回　対数正規法―

# 移転のお知らせ

こちらの記事は下記のサイトに移転しました。

> [NNテックブログ](https://nnhiroba.xsrv.jp/nnTechBlog/Article/Article?ID=24)
【#1 Python】分かりやすいと噂のPythonを触ってみた

<br>
最近ProgateにてPythonの勉強を始めました。
Pythonは最近よく使われるようになってきたプログラミング言語で、とにかく人間が使いやすいように考えられたものだそう。
例えば、Javaだと出力する際に「System.out.println();」とつらつら書かなくてはなりませんが、Pythonでは一言(後述)！
また、初心者にありがちなセミコロンの付け忘れも、Pythonならそもそもつける必要がないので考慮する必要がありません。<br>
プログラミングを始めたいけど何からしたらいいか分からない･･･という方は、とりあえずPythonから始めてみてもいいかも。<br>

### 文字列の出力
Pythonでは、文字列はシングルクォーテーション(')かダブルクォーテーション(")どちらで囲んでも構いません。
ただ、囲まないとエラーになるので気を付けましょう。
また、実行されないコメント(コードに関するメモ)は、行頭に「#」をつけることで書くことが出来ます。

```python
print('Hello Python')    # Hello Python
print("Hello Python")    # Hello Python

print(Hello Python)    # SyntaxError: invalid syntax
```
<br>
### 数値の出力
数値はクォーテーションで囲む必要はありません。
計算もその場で出来ます。分かりやすい、、。
ちなみに計算式をクォーテーションで囲むと、文字列となります。

```python
print(5)    #5
print(3 + 5)    #8
print("3 + 5")    #3 + 5
```
<br>
### 変数
「変数名＝値」で変数を定義できます。変数名はクォーテーションで囲む必要はありません。
プログラミングの「＝」は、「等しい」という意味ではなく「右辺を左辺に代入する」という意味になるので注意！

```python
name = "John"
number = 10

print(name)    #John
print("name")    #name
print(number)    #10
```
<br>変数を使うメリット

- データに名前をつけることで、扱っているデータの中身が何を表しているかが明確になる
- 同じデータを繰り返し利用できる
- 変数の値を変更する際直すところが少なくて済む

#### 変数のデータ型
通常、文字列型と数値型は一緒に扱えません。
しかし型変更を行えば大丈夫です。

```python
price = 100
price("りんごの価格は" + price + "円です")    #TypeError: Can't convert 'int' object to str implicitly
price("りんごの価格は" + str(price) + "円です")    #りんごの価格は100円です
※数値型を文字列に変更したため連結できる！！
```

```python
count = "3"
price = 100
total_price = price + int(count)    #数値型に変更
print(total_price)    #300
```

基本的なことは他のプログラミング言語と一緒です。
文字列型と数値型を連結する際は少し手を加えなければなりませんが、それ以外はとても簡潔で分かりやすいなという印象を受けました。
<br>
テンプレートテンプレート仮引数が読めなく困った。

普段はJavaを書いているのですが、ちょっとした用事でC++を読むことになり
その途中でテンプレートテンプレート仮引数が読めなくて躓いたので自分用のメモを作成します。

下のようなコードがあった時クラスAがテンプレートテンプレート仮引数を持つ。

```cpp
template<template<class U> class T>
class A{
  public:
    A(){
    }   
};
```
このクラスが表現したい事は単純で、ただ単にAを生成する時のTは
テンプレート引数を1つ持つクラスしか渡せませんということらしい。
(これに辿り着くまで、かなり悩んだ)

なので使い方としては以下のようになる。

```cpp
#include <string>

template<template<class U> class T>
class A{
  public:
    A(){
    }   
};

template<class T>
class B{
  public:
    B(){
    }   
};

int main(){
  A<B> a0; //この行はコンパイル出来る
  
  //A<std::string> a1;　//この行はコンパイル出来ない
}

```

この時、クラスAにたいして`std::vector`をパラメタとして渡せなくて躓いた。
もし`std::vector`を渡せるクラスAを書きたい場合下記のように書く必要がある。

```cpp
template<template<class U,class V> class T>
class A{
  public:
    A(){
    }   
};
```

## 追記
コメント頂いて知ったのですが、g++だと`-std=c++17`をつけると
冒頭のAクラスのままでも`std::vector`を実パラメタとして渡せるようです。
IQ Bot：OCRの誤読にどう対応する？

IQ Botの研修は基本的に、OCR側がラベルや値をきれいにとれたケースを前提に進みます。

ですが、現場で実際に帳票を扱ってみると、OCRが期待したとおりに文字を読み取ってくれるとは限りません。

IQ Botは座標指定型と違い、マッピング設定の画面からOCRをかけ直すことはできません。
（自動検出型なので、OCRをかけ直す意味がない）

※座標指定型／自動検出型の違いについては、以下の動画を参照してください。

https://youtu.be/wFghPwZL18o?t=2455

ただ、OCRが誤読したらIQ Bot側では手の打ちようがないのかというと、打ちようはあります。

この記事では、OCRの誤読に対する対処方法を見ていきます。

#誤読のパターン別　対応方法

誤読に対する対応方法は、誤読が発生する箇所がラベルなのか、値なのかによって変わります。
ラベルと値については、以下の記事を参照してください。

https://qiita.com/IQ_Bocchi/items/d569254f986cfeb1155c#%E3%83%A9%E3%83%99%E3%83%AB%E3%81%A8%E3%81%AF%E5%80%A4%E3%81%A8%E3%81%AF

ラべルも値も関係なく、帳票全体が誤読だらけという場合は、そもそも帳票がOCRの想定する品質／ユースケースに適合していない可能性があります。

以下は、「全体的にはだいたい上手に読めているけれども、一部誤読してしまう項目がある」という前提で、ラベル／値ごとに対処方法を見ていきます。

## ラベルの誤読が発生する場合

ラベルの誤読が発生する場合には以下の３種類の対処があります。
結論から言うと、一番万能な対処となるのは③ですが、一応①と②も紹介しておきます。

### ① 誤読のパターンをパイプ区切りで登録する
ラベルの誤読のパターンがある程度予測できるとは、たとえば「数量」というラベルを一定の割合で「類量」と読んでしまうケースがあるが、それ以外の誤読のしかたはしない、というようなパターンです。

そのような場合は、以下の要領でラベルの別名を登録していく方法がとれます。
![別名の登録.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/2265472d-c588-5eec-1723-6f50f79b7732.jpeg)

パイプラインで区切られたラベル名に、正規表現を使うことはできません。
なので、このやりかたが使えるケースは非常に限定的です。

### ② ラベル後方の文字数を減らす

IQ Botが帳票からラベルを検知する方法は、前方一致です。
この仕組みを使って、以下のようにラベル後方の文字数を減らすことで、検出確率を上げることができます。

| 登録したラベルの文字列 | 帳票上の文字列（OCRの結果） | 検出結果 |
|:-----------|:------------|:------------|
| 数量 | 数量 | ○　一致しているので検出可能 |
| 数量 | 数●<br>（「量」を誤読）   | ✖ ラベルの検索要素には「数量」と登録されている<br>　→　IQ Botは帳票から「数量」を前方一致で探しに行く<br>　→　「数●」は「数量」とは一致しないのでヒットせず<br>　→　ラベルは検出できない|
| 数 |  数●<br>（「量」を誤読）   | ○　ラベルの検索要素には「数」と登録されている<br>　→　IQ Botは帳票から「数」を前方一致で探しに行く<br>　→　「数●」は「数」と前方一致するのでヒットする<br>　→　ラベルが検出できる |

上記の仕組みを使って、例えば「電話番号：」というラベルから「：」を除外しておくなど、ラベル後方にある認識が不安定な要素をあらかじめ除外しておくと、ラベルが検出しやすくなります。

ただし、お気づきのように、このやりかたはラベル後方の文字列を誤読する場合にしか使えません。
ラベル前方の文字列を誤読してしまう場合（「数量」における「数」を誤読してしまう場合）には使えません。

### ③　仮のラベルを指定する

ラベルの誤読のパターンが予測できない場合は、仮のラベルを指定するか、項目を固定座標的に取得する方法が考えられます。
いずれの方法も、以下の記事にやりかたが載っていますので参考にしてみてください。

https://qiita.com/IQ_Bocchi/items/9082c2b262004694bada

## 値の誤読が発生する場合

### 値の誤読のパターンが決まっている場合

以下のように、誤読のパターンが決まっている場合はシンプルなカスタムロジックで対応できます。
カスタムロジックのやりかたは、それぞれのリンク先に載っています。

▼決まった文字が決まった形に文字化けする場合（都道府県欄の「東京」を必ず「棘」と読んでしまうなど）▼

https://qiita.com/IQ_Bocchi/items/b1e7a75439fede2171e6

▼数値項目しか入らない項目に、数値以外のノイズが入る（紙の汚れを記号として読み込んでしまう等）▼

https://qiita.com/IQ_Bocchi/items/b380ab96e5bf8b0b1e57

▼印影の重なった社名など、文字列の一部が正しく読める場合▼

https://qiita.com/IQ_Bocchi/items/107f0ec20110d618838d

### 値の誤読のパターンが決まっていない場合

値の誤読のパターンが決まっていない場合は、無理に置き換えて正しい値を自動算出しようとせず、誤りを検知して人間の検証に回す方法を考えます。
IQ Botにおける誤りの検知については、以下の記事を参照してください。

https://qiita.com/IQ_Bocchi/items/4e220a9bd6e337de4508
IQ Bot：印影の重なった社名にカスタムロジックで対応する

印影の重なった社名をOCRにかけると、印影と重なった部分が文字化けしたり、文字として認識できずに欠けてしまったりすることがあります。

例えば以下のサンプル帳票の右上の部分などです。

![印影の重なった社名.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/8298d919-53c6-236c-3f21-f65778538f26.jpeg)

こうした部分を正しく読む方法として、ひとつは前処理で印影除去などをする方法があります。
ですが、前処理で印影除去を行った場合でも、もともと印影が重なっていなかった部分に比べると精度が下がる場合が多いです。

この記事では、もっと手軽にできてパワフルな、カスタムロジックを使って対応する方法を説明します。

##前提

この方法を使うためには、以下の条件が揃っている必要があります。

1. 社名のうち、印影が重なっていない部分は正しく読めている
2. その正しく読めた部分を根拠に、社名の全体が判断できる

たとえば以下のような場合です。

![ふるえに.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/e2a69eb7-f3a1-eb06-09c6-20a04a8e9b26.jpeg)

##やりかた

[カスタムロジック](https://qiita.com/IQ_Bocchi/items/67694b1b0d1376ede7e7)に、以下の処理を入れます。

```python:カスタムロジック実装例
# 値を保存する変数: field_value
if "ふるさとエニ" in field_value:
  field_value = "ふるさとエニウエア商事株式会社"
```

上記は取得結果に「ふるさとエニ」という文字列が含まれていたら、取得結果を「ふるさとエニウエア商事株式会社」に置き換えるという処理です。

"ふるさとエニ"と"ふるさとエニウエア商事株式会社"を置き換えるだけで、簡単に様々なケースに応用できます。

社名が特殊フォントで書かれている場合など、請求元の名称からはまともに情報がとれない場合もあります。
（特殊フォントは誤読したり、文字として認識できない場合が多い）
そのような場合は、振込先の口座名義などを根拠に検出する方法もとれます。
アプリ作成　コメント機能非同期化

# 非同期化記述解説
<img width="745" alt="スクリーンショット 2020-07-20 21.51.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663122/ff96bb17-f0c8-6039-6186-4838601d0bd0.png">

## FormData
フォームのデータの送信に使用することができます。その他にも、キーのついたデータを伝送するためにフォームとは独立して使用することもできます。今回はコメントフォームがあるので、そのフォームの情報を取得するのに使います。

## attrメソッド
要素が持つ指定属性の値を返します。
要素が指定属性を持っていない場合、関数はundefinedを返します。

## processDataオプション
デフォルトではtrueになっており、dataに指定したオブジェクトをクエリ文字列(例: msg.txt?b1=%E3%81%8B&b2=%E3%81%8D )に変換する役割があります。
クエリ文字列とは、WebブラウザなどがWebサーバに送信するデータをURLの末尾に特定の形式で表記したものの事です。

## contentTypeオプション
サーバにデータのファイル形式を伝えるヘッダです。こちらはデフォルトでは「text/xml」でコンテンツタイプをXMLとして返してきます。

ajaxのリクエストがFormDataのときはどちらの値も適切な状態で送ることが可能なため、falseにすることで設定が上書きされることを防ぎます。


<img width="736" alt="スクリーンショット 2020-07-20 21.59.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663122/e8310483-922a-cce6-69f6-efcfb97e78bd.png">

この後、インクリメンタルサーチ機能をつけたいと思う。
ログイン画面作成（備忘録）　section73（序）

ファイルをアップロードするためのコードを記述していく。

```
<input type="file" name="image" size="35" value="test"  />
```
typeのファイル属性をfileにするとファイルを選択できるリンクが出来上がる。

但し、typeの属性をfileにした場合、formの属性にenctypeという特別な属性を記述する。

```
<form action="" method="post" enctype="multipart/form-data">

</form>
```

' enctype="multipart/form-data" 'は決まり文句なのでファイルをアップロードするときは
必ず記述する。

ここから、fileでアップロードしたデータをPHPで処理していく。
エラーが無い確認するコードの中のcheck.phpに移動する直前にファイル処理のコードを
記述していく。

```
	if(empty($error)) {
		$image = date('YmdHis') . $_FILES['image']['name'];
		move_uploaded_file($_FILES['image']['tmp_name'],'../member_picture/' .$image);
		$_SESSION['join'] =$_POST;
		$_SESSION['join']['image'] = $image;
		header('Location: check.php');
		exit();
	}
```

まず、`tyle="file"`でアップロードされたデータは配列のデータになっている

`date('YmdHis')`　はアップロードした時点の日付,時間,分,秒を取得している。
`$_FILES['image']['name']`　はアップロードした写真の名称を取得している。
ex) 20200720205513icon.png　というデータになる。
→２０２０年7月20日２０時５５分１３秒にicon.pngというデータをアップロードした状態。
時間をファイルに付与する理由はアップロードしたデータが同じものだった場合、
重複することを防ぐため。

次に `$_FILES['image']['tmp_name']` の`tmp_name`は一時的にデータが保管されている場所を示している。
一時的なので後に消えてしまう可能性があるので `move_uploaded_file`ファンクションを使って保存したい場所を
指定して移動する。
１つ目のパラメータに’今ある場所’、２つ目のパラメータに’保存したい場所のパス情報’を記述する。
以上のデータを` $image`（画像ファイル名）の変数に格納する。
作った画像ファイル名は今後データベースに保存しないといけないので`$_SESSION`に保存しておく。

```
$_SESSION['join']['image'] = $image;
```
`$_SESSION['join']['image']`という配列 join に image というキーを作っておいて、
値として`$image`のファイルを保存する。

→以下、　join配列のイメージ。今後はキーである image を使うと$imageが呼び出される。

```
$join ={
     image => $image
}
```

以上の処理を行うとやっと　check.php に移動することができる
Kubernetes上のコンテナ間でUDPブロードキャストを諦めた

# 結論

素直に諦めて別のやり方に切り替えました．なので，難しいと思います．

# やろうとしたこと

KubernetesにデプロイしたDockerコンテナ同士でUDPブロードキャストパケットをやり取りして研究の検証をしようとしていました．

# 上手くいかないところ

コンテナからホストOSへはUDPブロードキャストパケットは到達していました．コンテナからコンテナが到達できない状況でした．

# 調べたこと

以下の記事にKubernetesの設計的に難しいとの記述がありました．

[UDP broadcast fails between pods · Issue #1063 · kubernetes-sigs/kind](https://github.com/kubernetes-sigs/kind/issues/1063)

> the pods in fact schedule on different nodes. I don't think it's expected in Kubernetes's network model that you can broadcast between pods like this.

# ソースコード/マニフェスト

以下を使って試していました．

```go:agent.go
package main

import (
	"bytes"
	"log"
	"math/rand"
	"net"
	"os"
	"strconv"
	"time"
)

func reciever() {
	pc, err := net.ListenPacket("udp4", ":7531")
	if err != nil {
		log.Fatal(err)
	}

	buf := make([]byte, 1024)
	old_buf := make([]byte, 1024)

	for {
		n, addr, err := pc.ReadFrom(buf)
		if err != nil {
			log.Fatal(err)
			break
		}

		if bytes.Equal(buf, old_buf) {
			continue
		} else {
			log.Printf("recv:   %20s\t%s\n", addr, buf[:n])
			old_buf = buf[:n]
		}

	}
	defer pc.Close()
}

func sender() {
	// Listening
	pc, err := net.ListenPacket("udp4", ":7532")
	if err != nil {
		log.Fatal(err)
	}
	defer pc.Close()

	// Setup for sending
	addr, err := net.ResolveUDPAddr("udp4", "192.168.0.255:7531")
	if err != nil {
		log.Fatal(err)
	}

	for {
		// wait for listening
		time.Sleep(time.Second * 2)

		// create payload
		random_num := strconv.Itoa(rand.Intn(1000))
		hostname, err := os.Hostname()
		if err != nil {
			hostname = "unknown"
		}

		// send
		my_payload := "hoge " + random_num
		_, err = pc.WriteTo([]byte(my_payload), addr)
		if err != nil {
			log.Fatal(err)
		}
		log.Printf("sent:   %20s\t%s\n", hostname, my_payload)
	}
}

func main() {
	hostname, err := os.Hostname()
	if err != nil {
		hostname = "unknown"
	}
	log.Println(hostname, "starting agent")
	go sender()
	log.Println(hostname, "sending finish")
	reciever()
}
```

```dockerfile
FROM golang:rc
EXPOSE 7531
ADD agent.go /work/
WORKDIR /work/
CMD go run agent.go
```

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
    name: agent-dep
    labels:
        ser: agent
spec:
    replicas: 3
    selector:
        matchLabels:
            app: agent
    template:
        metadata:
            labels:
                app: agent
        spec:
            containers:
                - name: my-agent
                  image: tomoyk/agent:v0.18
                  ports:
                      - containerPort: 7531 
---
apiVersion: v1
kind: Service
metadata:
    name: agent-ser
spec:
    type: ClusterIP
    externalIPs:
        - 192.168.0.6
    ports:
        - name: "agent-port"
          protocol: "UDP"
          port: 7531
          targetPort: 7531
    selector:
        ser: agent
```

# 対処方法

- UDPブロードキャストをやめる
- hostネットワークにコンテナを直接差す
- Kubernetesに変更を加える

# 検証環境

- Docker for Windows 2.3.0.3
- K3s v1.18.3+k3s1
AtCoder 生活　91日目

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

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

|問題|難易度|自力で解けた|かかった時間|
|:-:|:-:|:-:|---|---|
|ABC065|C|◯|45分33秒|
|AGC034|A|✕|47分18秒|
|ARC059|C|◯|14分51秒|
|ARC068|C|◯|3分59秒|



##[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;
const ll mod = 1e9 + 7;

ll f(ll x){
    ll k = 1;
    while(x != 1){
        k = k*x%mod;
        x--;
    }
    return k;
}

int main(){
    ll n,m;
    cin >> n >> m;
    ll t = abs(n-m);
    if(t > 1) cout << 0 << endl;
    else {
        ll a = f(n);
        ll b = f(m);
        ll ans = a*b%mod;
        if(t == 0)cout << ans*2%mod << endl;
        else cout << ans << endl;
    }
}

```

解くのにかかった時間：45分33秒


##[AGC034_A](https://atcoder.jp/contests/agc034/tasks/agc034_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,a,b,c,d;
    cin >> n >> a >> b >> c >> d;
    string s;
    cin >> s;
    int p = 0;
    for(int i = a;i < max(c,d);i++){
        if(s[i] == '#' && s[i-1] == '#'){
            p++;
            break;
        }
    }
    if(d < c){
        p++;
        for(int i = b;i <= d;i++){
            if(s[i] == '.' && s[i-1] == '.' && s[i-2] == '.'){
                p--;
                break;
            }
        }
    }
    if(p == 0) cout << "Yes" << endl;
    else cout << "No" << endl;
}

```

解くのにかかった時間：47分18秒
感想：そろそろさっと解ける様になりたい


##[ARC059_C](https://atcoder.jp/contests/arc059/tasks/arc059_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;
    cin >> n;
    vector<int> a(n);
    rep(i,n) cin >> a[i];
    ll ans = INF;
    for(int i = -100;i <= 100;i++){
        ll sum = 0;
        rep(j,n){
            sum += (a[j] - i) * (a[j] - i);
        }
        ans = min(ans,sum);
    }
    cout << ans << endl;
}

```

解くのにかかった時間：14分51秒


##[ARC068_C](https://atcoder.jp/contests/arc068/tasks/arc068_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(){
    ll x;
    cin >> x;
    ll ans = x/11*2;
    ll res = x%11;
    if(res == 0)cout << ans << endl;
    else if(0 < res && res < 7) cout << ans + 1 << endl;
    else cout << ans + 2 << endl;
}

```

解くのにかかった時間：3分59秒


###最後に
苦手な問題も素早く解けるようになりたい

種類|難易度|かかった平均時間|解けた問題数|
|---|:-:|---|---|
|ABC|C|45分33秒|1問中1問|
|ARC|C|9分25秒|2問中2問|
Rubyでちょっとずつポーカーを実装する その4

#前回の記事
[その1](https://qiita.com/paraizo2424/items/23f5ab031dbda184ce9d)→[その2](https://qiita.com/paraizo2424/items/10c4a2576a53e655aef9)→[その3](https://qiita.com/paraizo2424/items/6187b5b6cd7c7ebc6eca)

#プレイヤーをn人が参加する
ゲームに何人参加するのかを管理するのは誰だろうか??ディーラーだろうか？？
とりあえず、ゲームマスターというクラスを作成して任せてみることにする。

#勝敗を判定するのは誰か？
ディーラーが判定するのだろうか。さっき作ったゲームマスターだろうか？？
とりあえず、ゲームの進行役的な存在のゲームマスターが勝敗は判定することにしよう。

#同じ役のときの勝敗は？
ワンペアvsワンペアのとき、カードの数値が大きい方が勝ち、同じ数値ならスートの強さを比較する。
いろいろと考えたけど難しいので次回にしよう。
とりあえず、最も強い役が複数いるときは引き分けとし、最も強い役が一人だけの場合は、その人を勝者としよう。

#流れ
<ゲーム開始>
プレイヤーがゲームの参加者が何人か入力する gamemaster.initialize(プレイヤー人数)
プレイヤー同士の勝敗を判定する gamemaster.judge
<ゲーム終了>

#コード
https://github.com/paraizo2424/poker_game/commit/b1becfe81a7b827302d0116562c8e57240e7b403

#次回
[その5](https://qiita.com/paraizo2424/items/519e14a7cc878e17bb42)