OmniAICreator/Qiita-1.07M huggingface dataset:
MacでWifiにつながらない(ドメイン名前解決できない)

突然、wifiが不安定になり接続できなくなりました。

# 問題
wifiに接続してDNSサーバーのIPも取得できていますが、名前解決できません...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249038/270afd2d-4fc2-e844-a15d-3f47a5cd025d.png)

Macの
環境設定-> ネットワーク -> wifi -> 詳細 -> DNS

DNSのIPは取得できています...

何故かdigれません...

```
$ dig google.com 
無反応
```

# 解決
名前解決出来ないのでgoogleの提供しているDNSサーバー(8.8.8.8, 8.8.4.4)を先程のDNSのところに追加しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249038/55b39b81-b09e-4648-bd53-99bf201eb922.png)

すると名前解決できます！

```
$ dig google.com

; <<>> DiG 9.8.3-P1 <<>> google.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 28542
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;google.com.			IN	A

;; ANSWER SECTION:
google.com.		299	IN	A	216.58.197.238

;; Query time: 51 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Thu Jul 16 01:14:30 2020
;; MSG SIZE  rcvd: 44

```


コアの原因はわかりませんでしたが、DNSサーバーの問題だったようです。
Swiftを1行でセグフォらせる

旬を逃した話題ですが、面白そうだったのでSwift版をやってみます。


```swift:demo.swift
print(UnsafePointer(bitPattern: 8)!.pointee)
```

```sh:
$ swiftc -O demo.swift
$ ./demo
Segmentation fault: 11
```

Unsafeコードであることが明確でありつつ、簡潔なコードで[セグメンテーション違反](https://ja.wikipedia.org/wiki/%E3%82%BB%E3%82%B0%E3%83%A1%E3%83%B3%E3%83%86%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E9%81%95%E5%8F%8D)を発生させることができました。

環境: macOS 10.15.5 / x86-64

## 少しだけ解説

このコードは、不正アドレスである8番地の領域から`Any`オブジェクトのデータを読み込もうとするコードになっています。`UnsafePointer`の`Pointee`型を明示していませんが、`print()`の引数に由来して`Any`に型推論されています。

macOSの仮想メモリ空間において先頭の１ページ(4KB)は、読込＆書込の権限がない領域となっています。そのため、そのような領域からデータを読み込もうとした場合は、セグメンテーション違反が発生します。

> [Memory Usage Performance Guidelines / Viewing Virtual Memory Usage](https://developer.apple.com/library/archive/documentation/Performance/Conceptual/ManagingMemory/Articles/VMPages.html)
> The first page (__PAGEZERO, starting at address 0x00000000) has no permissions set. This ensures that any reference to a NULL pointer immediately causes an error. 


不正アドレスの代表格である0番地を使用した場合、最適化によって [`ud2`](https://mudongliang.github.io/x86/html/file_module_x86_id_318.html)命令による自発的かつ`Illegal instruction: 4` でエラー終了するようなコードが生成されてしまうようです[^b1]。この最適化を避けるため、今回のコード例では非0の番地を使用しました。

[^b1]: Rustのセグフォ記事でも同様となる[コメント](https://qiita.com/YoshiTheChinchilla/items/b9f4a6e92266e8ec9d3d#comment-2762f65196b563b35d92)がありました。

### 0番地による実行例

```swift:demo2.swift
print(UnsafePointer(bitPattern: 0)!.pointee)
```

```sh:
$ swiftc -O demo2.swift
$ ./demo2
Illegal instruction: 4
```

```
$ swiftc -O -S demo2.swift 
        (略)
_main:
        (略)
        ud2
```
【Android:Kotlin】DataBindingのandroid:layout_marginTopとかで苦しんでるあなたへ【JetPack】

この記事にたどり着いたということは

```kotlin
<TextView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_weight="1"
    binding:layout_marginTop="@{viewModel.isMarginTop ? @dimen/ten_dp : @dimen/zero_dp }"
    android:text="List"
    />
```

こんなものを書いてエラーが出て困っていますね。

そんな時は


```kotlin
@BindingAdapter("binding:layoutMarginTop")
fun setLayoutMarginTop(view: View, dimen: Float) {
    val layoutParams = view.layoutParams as ViewGroup.MarginLayoutParams
    layoutParams.TopMargin = dimen.toInt()
    view.layoutParams = layoutParams
}
```
とBindingAdapter用のメソッドを作りましょう。
layout_〇〇のようなものはDataBindingはまだ対応していないようです。
GrubをUSBメモリにインストール(UEFI)　〜grubインストール〜 

[前記事](https://qiita.com/kitarow0309/items/f27e5514b293ae073e1a)ではUSBメモリの下準備を行いました。
いよいよgrubをインストールしていきます。
以下のコマンドを入力していきます。

```ruby:mount&install
$sudo mkdir /mnt/boot                       #(1)
$sudo mount /dev/sdc1 /mnt                  #(2)
$sudo grub-install --target x86_64-efi --debug --efi-directory /mnt --boot-directory=/mnt/boot --removable      #(3)
```

最後のコマンドを入力するとgrubのインストールが始まる(ものすごい速さで文字が流れるが焦らないこと)。最後に終わると、No eroor reported的なメッセージが表示される。ちなみに上記のコマンドを簡単に解説する(読み飛ばし可)

 #1・・・自分の領域(/user名/home)に新たに「mnt」という部屋を作り、更にその部屋の中に「boot」を作る
 #2・・・前記事で作った「/dev/sdc1」を#1で作った「mnt」という部屋と紐付ける(「mnt」内の部屋「boot」もついでに紐付けられる)。つまり、「mnt」にインストールしたファイルは自動的にUSBの中にあるパーティション「/dev/sdc1」に送られる。
 #3・・・/mnt/bootにgrubをインストールする。#2で「/mnt」と「/dev/sdc1」は紐付けられているからgrubはUSB内にインストールされる。

これで、grubのUSBインストールは終了である。[次記事](https://qiita.com/kitarow0309/items/2ecf6d9b2e30bb711710)にてgrubからLinuxを起動する方法を示す。
Vuex mutationのペイロード（引数）に複数の値を指定する

Vuexのmutationをつかってデータ（state）を更新する際、
ペイロード（引数）の渡し方を勘違いしており、**複数の値**がうまく渡せませんでした。

##結論
こんなふうに書きます。
※ store.jsというファイル名でvuex用のJSファイルを作り、main.jsに読み込ませています。
　 stateおよびmutationはstore.jsに書いています。

####mutation側
```javascript:store.js
//hogeとfugaを引数にするhogehogeミューテーション
  mutations:{
    hogehoge( state, {hoge, fuga}){
      //hogeとfugaを使って色々やる処理を書く
      }
  }
```

####コンポーネント(mutationを呼び出す)側

```javascript
  methods:{
    fugafuga(){
      this.$store.commit(
        //第1引数 ミューテーション名
        "hogehoge" ,
        //第2引数 ペイロード
        { hoge : "01" ,
          fuga : "1"  }) 
    }
  }
```

ポイントはペイロードを`{}`で囲ってオブジェクトにしていることです


##間違ってたこと
ペイロードを`{ }`で囲わず、そのまま複数並べていました。

####mutation側　ダメな例
```javascript:store.js
  mutations:{
    hogehoge( state, hoge, fuga){ 
//以下略
```

####コンポーネント(mutationを呼び出す)側　ダメな例

```javascript
 this.$store.commit(
  "hogehoge" ,
  "01" ,
  "1" ) 
```
ちなみに、これも駄目です

```javascript
this.$store.commit(
  "hogehoge" ,
   {hoge : "01" },
   {fuga : "1"  })
```
  
 　
##まとめ
ペイロードはあくまで"第2引数"であるので、複数の値を渡す際にはオブジェクトにまとめ、「一つの引数」として渡す必要があります。
なお、[公式リファレンス](https://vuex.vuejs.org/ja/guide/mutations.html)でも（引数の単複問わず）オブジェクト形式を推奨しています。


##参考
- [Vuex公式](https://vuex.vuejs.org/ja/guide/mutations.html)
- [Vuexのミューテーションの使い方。状態を更新しよう｜Vuex](https://dev83.com/vue-vuex04/)
いちどブランチにmergeしたmasterの内容を無かったことにできないか

## ●ブランチの更新状況をタイムスリップする

### 1. **git reflog** で 今までやったことを一覧する
```
ユーザー名 アプリ名 % git reflog
ff07e4a HEAD@{29}: checkout: moving from master to edit_page
ca7518c (origin/master, master) HEAD@{30}: checkout: moving from edit_page to master
ff07e4a HEAD@{31}: checkout: moving from edit_page to edit_page
ff07e4a HEAD@{32}: checkout: moving from function-category to edit_page
ea29d73 HEAD@{33}: checkout: moving from edit_page to function-category
```
どこまで戻りたいかが見れる。
今回の場合は HEAD@{29} masterをmergeする前まで戻りたい。
Commit id でいうと　ff07e4a まで。

### 2. **git reset** で戻ろうじゃないか
```
ユーザー名 アプリ名 % git reset --hard HEAD@{29}
HEAD is now at ff07e4a Update show.html.haml
```
戻ったよ！

問題はここから。

### 3. この状態でmargeしてないことにしたいのよ！

![スクリーンショット 2020-07-16 0.48.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591023/fbd0c5b4-00c4-dcec-030b-2c27a2859419.png)

Pull originのところに、しっかり残っている。
コイツを消し去りたい。
でもできない。


# ●Comming soon?!

何か手がかりがあったら更新します。
GrubをUSBメモリにインストール(UEFI)　〜USB準備〜

つづいて、USBを準備をしていきましょう
grubをUEFIで起動させるにはMBRかつUSBの第1パーティションにgrubをインストール必要があります。USBのMBRは[前記事](https://qiita.com/kitarow0309/items/2d562c796c36e3a50e83)で示しています。本記事ではUSB内に第1パーティションを作成する方法を示し、その後にフォーマットしてLinuxに作成したパーティションを認識させるまでを示します。
下記の#で補足した部分に気をつけながら対話的にコマンドを入力していきます。
(...は省略事項)

```ruby:fdisk
$sudo fdisk /dev/sdc
 コマンド(mでヘルプ):n                #「ｎ」で新しいパーティションを作成
 Partiton type:
 p primary....
 e extended
 Select (default p):p              #「p」でパーティション作成---
 パーティション番号(1-4 default1):1   #「1」で1番目のパーティションを作成
 最初 sector ...:                   #Enter(2048使用)
 初期値2048を使います
 Last sector....:+3G            #作成するパーティションの容量を指定(3GB)

 コマンド(mでヘルプ):p         #パーティション作成後のUSBメモリの内容を表示
 Disk /dev/sdc: 7.7 GB ...
 ...
 
 デバイスブート 始点 ... ...
 /dev/sdc1 ...       #「sdc1」が表示されている＝第1パーティションが作成された

 コマンド(mでヘルプ):w                 #「w」で変更を保存
　パーティションテーブルは変更されました！

```

上記の#で補足した部分に気をつけながら対話的にコマンドを入力していきます。
すると、sdc1という名前でパーティションが作られます。

次に作ったパーティションを「アンマウント」した後に「フォーマット」しましょう。

今の段階を学校とかのプールで例えると
学校の敷地内(/dev/sdc)に大工さんたちがプールを指定の敷地(/dev/sdc1)に作った段階で、大工さんはプールの中でウロウロしている状況です。とりあえず大工さんは邪魔なので出ていってもらいましょう。これが「アンマウント」です。そして、人がいなくなったプールに水を張る作業が「フォーマット」です。こうすることでプール(/dev/sdc1)は実際に使える状態になるのです。

```ruby:mkfs
$sudo umount /dev/sdc1                    (1) 
$sudo mkdosfs -F32 -nGRUB /dev/sdc1       (2)
```

(1)でアンマウントしています。(2)でフォーマット(FAT32)しています。ちなみに -nGRUBのGRUB部分を変えると作成したパーティション領域に名前をつけれます。好きに付けてください。

ここまででUSBの下準備は完了です。いよいよ[次の記事](https://qiita.com/kitarow0309/items/26ccb5f35e4044f38e5a)でGrubのインストールに移ります。
Prisma CloudでAWSリソースの脆弱性管理（導入＋EC2編）

Palo Alto社のセキュリティ製品、Prisma CloudをでAWSリソースの脆弱性管理を行ってみます。
今回は、EC2インスタンスに対して、脆弱性診断をかけてみます。

# 準備

## アカウント発行
Prisma Cloudは１ヶ月の試用期間があります。
ライセンスをお持ちでない方は、Trialアカウントを発行してみてください。

## AWSアカウントの登録
とくにここでの手順の記載はしません。
CloudFormationで驚くほどに簡単に設定が完了します。

# 脆弱性診断
Computeメニューに存在します。
今回は、AWS EC2インスタンスに対して、実施してみます。

### 準備
対象インスタンスに対し、TwistlockのDefenderをインストールします。
インストールコマンドは、「Compute-Manage-Defenders」から入手可能です。
Deployタブから、対象のサーバーに合わせたコマンドを取得して、対象サーバーで実行します。
Amazon Linux2のようなSSMデフォルト対応済みのようなインスタンスでは、RunCommandでサクッとシェルスクリプトを流せばOK :)

以降、Prisma Cloudのコンソールにも、対象のホストが登場します。

<img width="1166" alt="Prisma Cloud | Compute 2020-07-15 21-39-00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51320/e35790e2-b661-f591-1ce4-dce00fd75ff3.png">

<img width="884" alt="Prisma Cloud | Compute 2020-07-15 21-29-56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51320/985fcaf1-53c7-bdb3-260f-5c8766db777e.png">


### スキャン

初回に自動的にスキャンが走っています。

rsyslogに注目。今のインスタンスのrsyslogには脆弱性があるようです。
<img width="1166" alt="Prisma Cloud | Compute 2020-07-15 21-39-00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51320/dce9c7f2-ca98-1854-57f7-f83f56565c27.png">

<img width="1079" alt="Prisma Cloud | Compute 2020-07-15 21-43-53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51320/6735aea4-546f-1e36-3fb0-c7fd377d7770.png">

<img width="898" alt="Prisma Cloud | Compute 2020-07-15 23-59-25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51320/6f1b2714-34f0-6475-316a-9b00c9e3de3d.png">

また、サクッとSSM経由でアップデート。
真面目に運用に乗せるには、Patch Managerとかでやるべきでしょうが、今回はとりあえず、
「yum -y update rsyslog」を流します。

アップデートが終われば再スキャン！
<img width="1160" alt="Prisma Cloud | Compute 2020-07-16 00-25-04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51320/58441dfe-fb6e-a5d0-23a4-f3924cf68535.png">

無事、脆弱性が解消しました :)
<img width="896" alt="Prisma Cloud | Compute 2020-07-16 00-25-41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51320/e8c71a79-958b-a7d2-2495-314f1234040f.png">

# まとめ

Prisma Cloudをとりあえず、今回はAWS EC2について、導入してみました。
イメージを掴んでもらうためにも画面キャプチャ多めにしましたが、直感的に操作できると思います。

Inspectorなどの謹製サービスを組み合わせても同様のインベントリ管理はできそうですが、レポートも簡単に出力できたり、様々な通知インテグレーションを備えたアラート機能もあり、Prisma Cloudは強力なツールと思います。

また、別のサービスなどでも試してみたいと思います。
投稿の制限(Ruby on Rails)

#プログラミングの勉強日記
2020年7月16日　Progate Lv.205
Ruby on RailsⅤ, Ⅵ

#バリデーション
　不正なデータがデータベースに保存されないようにデータをチェックするシステムを<font color=orange>バリデーション</font>という。バリデーションに引っかかった場合(不正なデータの場合)にはデータベースに保存されない。
　バリデーションはモデルで設定する。`validates`を用いてカルム名と内容を指定する。`{presence: true}`を用いることでそのカラムの値が存在するかどうかをチェックできる。

```ruby:models/posts.rb
class Post < ApplicationRecord
  validates :content, {presence: true}
end
```
　`length`を用いて`{maximum:数値}`を指定することで最大文字数を設定できる。

```ruby:models/posts.rb
class Post < ApplicationRecord
  validates :content, {length : {maximum:140} }
end
```
　値の重複がないかをチェックするための`{uniqueness: true}`というバリデーションもある。

```ruby:models/posts.rb
class Post < ApplicationRecord
  validates :content, {uniqueness: true}
end
```


　バリデーションの内容はハッシュになっているので、コンマで区切ることで複数指定できる。

```ruby:models/posts.rb
class Post < ApplicationRecord
  validates :content, {presence: true, length : {maximum:140}}
end
```

#投稿失敗画面の表示
　投稿をデータベースに保存するために使っている`saveメソッド`は保存に成功した場合は`true`をバリデーションに引っかかって保存に失敗した場合は`false`を戻り値として返すようになっている。
　投稿を保存できなかった場合は投稿一覧ページの代わりに投稿編集ページに転送する。

```ruby:posts_controller.rb
def update
  #保存できた場合
  if @post.save
    redirect_to("/posts/index")
  #保存できなかった場合
  else
    redirect_to("/posts/#{@post.id}/edit")
  end
end
```

#直前の投稿内容を表示
　投稿失敗時に直前の投稿内容が消えてしまう理由

　1. `update`アクションでは投稿失敗時に`edit`アクションに転送している。

```ruby:posts_controller.rb
def update
  redirect_to("/posts/#{@post.id}/edit")
end
```
　2.`edit`アクションではデータベースから編集前のデータを取得している

```ruby:posts_controller.rb
def edit
  @post=Post.find_by(...)
end
```
　3. フォームの初期値は2で取得した`@post.content`の内容である

```erb:edit.html.erb
<textarea> <%= @post.content %> </textarea>
```

なので、投稿失敗時には直前の内容ではなく、編集前のデータが表示されてしまう。`update`アクションの`@post`には直前の編集内容が入っているので、この`@post`を`edit.html.erb`で利用できれば、直前の編集内容を表示できる！（`edit`アクションを経由せず、`update`アクションから`edit.html.erb`を直接表示する）
　`render`メソッドを用いることで、別のアクションを経由せずに直接ビューを指定する。`render`メソッドを使った場合とそのアクションで定義した`@変数`をビューでそのまま使える。

```ruby:posts_controller.rb
def update
  render("posts/edit")
end
```

```erb:posts/edit.html.erb
<textarea> <%= @post.content %> </textarea>
```

　これで`edit`アクションを経由せずに`edit.html.erb`を直接表示できる。

#エラーメッセージの取得
　`save`メソッドを呼び出したときにバリデーションに失敗すると、Railsでは自動的にエラーメッセージが生成される。`@post.errors.full_messages`の中にエラー内容が配列で入る。

```terminal:ターミナル
$ rails console
> post=Post.new(content:"")
> post.errors.full_message
=> []
> post.save
=> false
> post.errors.full_message
=> ["contentを入力してください"]
```

```erb:posts/edit.html.erb
<% @post.errors.full_message.each do |message| %>
  <%= message %>
<% end %>
```
　`@post.errors.full_message`にエラーメッセージの配列が入っているので、each文を用いることですべてが表示される。

#サクセスメッセージの表示
　ページ上に一度だけ表示されるメッセージをフラッシュという。フラッシュが表示された後、ページを更新したり別のページに移動したりすると、フラッシュは表示されなくなる。Railsではフラッシュを表示するために、特殊な変数`flash`が用意されている。アクションで変数`flash[:notice]`に文字列を入力すると`flash[:notice]`でビューを使える。変数`flash`は一度表示されたあとに自動で削除される。

```ruby:posts_controller.rb
def update
  if @post.save
    flash[:notice]="表示したい文字列"
  ...
```

```erb:layouts/application.html.erb
<% if flash[:notice] %>
  <div class="flash">
    <%= flash[:notice] %>
  </div>
<% end %>
```
free コマンドの空きメモリ容量はここを見て

オプション：-m （MB 表記）

## 表示パターン１

<img width="848" alt="スクリーンショット 2020-07-16 0.13.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26033/47366b20-786a-3302-d218-e1e0210036a5.png">
<img width="842" alt="スクリーンショット 2020-07-16 0.33.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26033/a6743a09-6766-3aef-dfdf-10e2128c390a.png">

---

## 表示パターン２

<img width="842" alt="スクリーンショット 2020-07-16 0.40.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26033/282b0032-6028-84c6-3f2e-f443f71ccb1a.png">


## 参考

[free コマンドでメモリ空き容量を確認するときの注意点 | SUSE](https://www.suse.com/ja-jp/support/jp/kb/tids/00100006/)
[Linux のメモリー管理(メモリ－が足りない？,メモリーリークの検出/防止)(Kodama's tips page)](http://www.math.kobe-u.ac.jp/HOME/kodama/tips-free-memory.html)
[サーバーの負荷状態を調査する（vmstat,free,top,proc,ps） | 100%レンタルサーバーを使いこなすサイト](https://go-journey.club/archives/2912#I/O%E8%B2%A0%E8%8D%B7%E3%81%8C%E9%AB%98%E3%81%8F%E3%81%AA%E3%82%8B%E5%8E%9F%E5%9B%A0)
Pythonで一定時間（秒）以上処理をsleepさせる

Pythonで一定時間以上処理を止めたい時の実装。

外部APIをfor文の中で何度も呼ぶときなどに、一定間隔を空けたいことがある。
でも必ず一定時間のsleepを入れてたらちょっと非効率。処理時間が一定間隔に満たなければsleepを入れたい。

例）Twitter APIへのリクエストの間隔を2秒以上空けたい。

```
import time
from datetime import datetime


def hoge():
    start = datetime.now()

    # ここでAPIリクエストやそれに付随する処理
    hoge()

    exec_time = (datetime.now() - start).microseconds

    # 処理に2秒以上かかってなければ最短2秒になるようにsleepする
    sleep_sec = float(2000 - exec_time) / 1000
    if sleep_sec > 0:
        time.sleep(sleep_sec)
```

もっといい書き方もありそう。
freeeAPIで勤怠打刻を自動化したい！　その１

## 動機

人は、ルーチンワークを意識すると言うのが、苦手な生き物である！！（主語でかい）
みなさん、よく月末に勤怠を入力してくださいって、言われません？
言われない？自動化してる？

**僕は割と言われます**
毎回、「すみません（汗」と、言って勤怠を入れるのである。
もう、３回言われたら、自動化して対策するのが、エンジニアってものですよ。
（財布も月３回、家に忘れたから、忘れるものと割り切って対策組んだし）
ちょうど、人事労務freeeにはAPIが公開されているので、こいつで勤怠打刻を自動化しましょう！

## 出勤と退勤の定義

自動化するに当たって、どのような動作を出勤・退勤として、処理させるか。
会社のWi-Fiがスマートフォンが掴んだら？
私用のスマートフォンでの接続は許可されていない。
そして、僕は業務用ケータイは持ってない。（そもそも、客先常駐なので、ここでいう会社のWi-Fiは客先のWi-Fiになるわけで）

GPSは、使うときだけONにしてるから、うっかり物の僕は絶対入れ忘れる。

さて、どうするか。
答えはシンプル。
業務マシンのログインを出勤・ログアウトを退勤と定義する。
電源のオンオフだと、リモートワークの時ですね・・・オフィスのマシンが使えなくなるんです。
なので、ログイン・ログオフです。

ちなみに、想定環境は Windows です。
ログイン時にbatファイル経由でPythonスクリプトを起動して、freeeに打刻するという仕組みです。

```bash:batファイルのイメージ
REM record.bat
python worktimerecorder.py [batファイルの起動時間] [出勤 or 退勤]
```
~~pythonを直接叩いても良さそう~~

## freee APIを叩く準備

freeeの[チュートリアル](https://developer.freee.co.jp/tutorials/starting-api)を勧めて、APIを叩ける状態にする。

アプリの作成からClient ID/Client Secretの生成・作成したClient IDを使って認可トークンの生成・認可トークンを使用してアクセストークンとリフレッシュトークンの生成を行います。
**いろいろ試したいなら、テスト事業所とテストアカウント作ったほうがいいです。**
僕はそれがボトルネックになっていたので自分のアカウントでやりましたが、実際の勤怠をいじるのでお勧めしない

補足として、アプリの権限設定は、[人事労務] 打刻 と[人事労務] 勤怠 を選びました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83578/233d81ec-6a3e-63d4-e962-ec4fa0d16a42.png)



## freee APIを叩く

叩く準備が整ったので、実際に叩いてみます。
freeeの以下のチュートリアルを参考にしていきます。
[最初のGET/POSTリクエストを行う](https://developer.freee.co.jp/tutorials/first-call)
freeeのAPIリファレンスはSwaggerで作られているので、このページからAPIを叩くことが可能です。

APIのリファレンスページのAuthorizeのボタンをクリックして、AccessTokenを入力するとログイン状態になり、勤怠やタイムレコーダーAPIが使えるようになります。＼プログライズ！ライジングホッパー！！／
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83578/70f52d9c-ca58-934e-67f3-2f7b12d2207a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83578/ecedb157-68db-6cd5-81a5-8947f3b75bcf.png)

次にログインユーザー情報を取得して、company_idとemployee_idを控えておきます（他のAPIでよく求められるので）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83578/b8a0497b-ba8b-e5de-466c-90be3bdee58e.png)

控えたIDで、打刻情報の一覧を取得してみます。
Parametersの横のTry itからパラメータを入力して、Executeで実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83578/afdc4006-9655-9d95-a29f-57ca8630ebe3.png)

以下のようにJSONで返ってきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83578/cbc909fb-79a0-d714-2434-c0435ef04d55.png)

これを元に、Pythonで勤怠打刻スクリプトを作っていきます。
・・・が、今回はここまでです。（というかここまでしかやってない）

[つづく](https://www.google.com/search?q=%E3%81%A4%E3%81%A5%E3%81%8F+%E3%83%92%E3%82%A4%E3%83%AD+aa&client=firefox-b-d&hl=ja&sxsrf=ALeKk00Izp90zEgJAR2_JVUrN-LFA4AiVA:1594825378095&source=lnms&tbm=isch&sa=X&ved=2ahUKEwiVl4_Bw8_qAhULfXAKHdtKD3oQ_AUoAXoECAwQAw&biw=1741&bih=1004)(・ω⊂)<任務完了...
自分用メモ-Qiitaで(なるべく)毎日記事を投稿する

# すみません

- 本記事は技術的な内容は皆無です。Qiita始めたばかりなので、意気込み的な感じです。
- せっかくQiitaを始めたので、なるべく毎日、どんな内容でも良いから記事にしてアウトプットしよう！と思い至った次第です。
- インプットばっかりで、アウトプットしてないやんけ！！！
- [Qiitaを1年間ほぼ毎日投稿した話と転職の話](https://qiita.com/miriwo/items/681ff186f4d6f9057135) ←こちらの記事に影響を受けました。頑張ります。

# 目的とか目標とか
[Qiitaを1年間ほぼ毎日投稿した話と転職の話](https://qiita.com/miriwo/items/681ff186f4d6f9057135)にならって、以下がんばっていきます。

- なるべく毎日、最低1記事は投稿する。
- CTFのWriteUpや、日々調査した技術情報、話題のネタや、過去にインプットしたもの等など････をアウトプットしていく
- 毎日投稿することを重視。コマンド一行、情報の概要だけでもいいからとにかく記事を書く。
- 最初は自分用のメモとして書く。
    - 「内容が雑すぎて恥ずかしくなる時は記事タイトルに「自分用メモ」などと記載するとハードルが下がる。」との事。積極的に活用しよう。
- 記事タイトルに動作環境はできるだけ記載する。
DNSについて

## DNS(Domain Name System) 
ドメイン名のシステム。
ドメイン名をIPアドレスに変換する。
ネームサーバとフルリゾルバから構成される。
フルリゾルバという秘書を通してネームサーバーの情報を受け取るようなイメージ。

 - ネームサーバ
  - ドメイン名とそれに紐づくIPアドレスが登録されているサーバー
  - ドメインの階層ごとにネームサーバーがあり、そのネームサーバーが配置された階層のドメインに関する情報を管理する。

 - フルリゾルバ
   - どのドメインに紐づくIPアドレスについて教えて、と問い合わせると色々なネームサーバーに聞いてIPアドレスを調べて教えくれるサーバー

### アクセスまでの流れ（この一連の流れを「名前解決」と言う）
webブラウザで「`http://www.example.com`」というサイトにアクセス
↓
フルルゾルバにアクセス
↓
フルリゾルバがwww.example.com/についてルートネームサーバに問い合わせて、ルートネームサーバが「comのネームサーバに問い合わせて」と返す
↓
その情報をもとにフルリゾルバがwww.example.com/についてcomネームサーバに問い合わせて、comのネームサーバが「example.comのネームサーバに問い合わせて」と返す
↓
その情報をもとにフルリゾルバがwww.example.com/についてexample.comのネームサーバに問い合わせると、example.comのネームサーバが「IPアドレスは93.184.216.34だよ」と返す。
↓
フルリゾルバがブラウザに「IPアドレスは93.184.216.34だよ」と返す。
↓
webブラウザがIPアドレス93.184.216.34のwebサーバにアクセスできる

１回アクセスしたらしばらくはフルリゾルバがIP情報をキャッシュするので、ネームサーバにはアクセスしなくてもよくなる。

#### リソースレコード
ドメイン名とIPアドレスを紐づけた一つ一つの情報をリソースレコードと言う。リソースレコードは種類があり、「ドメイン名とIPアドレスを紐づけた情報は」Aレコードという。
リソースレコードはこのドメイン名とIPアドレス以外にも情報を管理している。
メールアドレスと、それに紐づくメールサーバの情報も管理していて、それはMXレコードという。
ホスト名には、「canonical name（正式名）」以外に、「aliases（別名）」を付けることができ、それを管理しているレコードをCNAMEと言う。
Flutterの学習まとめ

qiitaも含めいろいろと情報が出てきているが、自分なりに試行錯誤しながらわかりやすい情報をまとめてみました。（環境構築はできていて、これから始める方に向けた内容かも。）

ブログ等も記事も良いが、最近は動画で説明してくれる方がより開発しやすい気がしているので動画のまとめが多いです。

## まずはじめに。
結局はステートレス、ステーフルのどちらかであること。
概念とか、大枠の部分を説明してくれています。

Flutter Widgets 101
https://www.youtube.com/playlist?list=PLOU2XLYxmsIJyiwUPCou_OVTpRIn_8UMd

- 1~5まで、約30分くらい。
- 字幕 > 自動翻訳 > pcは日本語が選択できます。


## 状態管理

## DB(SQLite3)

おすすめはこちら図説もあり、雰囲気がより掴める。
NoteKeeper（todoアプリ）というサンプルアプリを例に、DBを作り、そこにinsert,update,deleteなどの操作をして、状態をDBに格納するまで。動画の本数も多いが、じっくり進めていくとより理解度が増す気がしました。
todoアプリを作ったら、次はtodoの情報をDBに入れる練習に最適なんじゃないかなと。

4-1: https://www.youtube.com/watch?v=1BwjNEKD8g8
4-2: https://www.youtube.com/watch?v=wVSBUnNUr00
4-3: https://www.youtube.com/watch?v=iY2RYQKPm84
4-4: https://www.youtube.com/watch?v=g9Uk1Xou0m4
4-5: https://www.youtube.com/watch?v=LJH8UI8E1Lw
4-6: https://www.youtube.com/watch?v=t39VV2XyqR0
4-7: https://www.youtube.com/watch?v=zkxBSCig3zs
4-8: https://www.youtube.com/watch?v=xke5_yGL0uk


## 書籍

随時更新していきます。
GrubをUSBメモリにインストール(UEFI)　〜USB準備と確認〜

ブートローダーGrubをUSBメモリに入れて起動するまでをまとめます。
多くのサイトではBIOS/MBRの場合で説明が書かれていますが、今回はUEFI/GPTの場合のインストール方法を示します。(中級者向け)

#USBメモリの下準備
USBメモリは4GBもあれば十分です。(今回は8GB)
まずはUSBがLinuxにどんな風に認識されているか確認します。(...は省略事項）

```ruby:mbr初期化
$install apt update 
$install apt mbr
```
まずはUSBをMBRにします。
GPTなのにMBR??
僕もそう思いましたが、このほうがうまくいくようですので....
次に行きます


```ruby:fdisk
$sudo fdisk -l                 (1)
 Disk /dev/sdc:7.9282732GB ... (2)
 .... 
 Device
 /dev/sdc1 .... (3)
 ....
```

(1)でUSB以外の記憶領域も含めた全てのデバイス(HDD,SSD,USB等)が表示させるコマンドです。WindowsではCドライブ〜、Dドライブ〜とか表示されてるものに近いです。

(2)には容量が表示されてます。自分のUSB容量に近いものを探してください

次に/dev/sdc1という表記についてを述べます。LinuxではUSBメモリが接続されると「/dev」内にある設定ファイルによりLinuxに認識され、更にLinuxはそのUSBに「sdc」という名前をつけていると考えてください。(この名前の付け方はPCそれぞれですので、sdb、sdc....となってもOKです。この後の文では「sdc」を自分のPC環境に合わせて読みすすめてください。)

自分のUSBを見つけたらその下を見ていただくと、
/dev/sdc1
が出てきます。先程、USBメモリに「sdc」という名前をつけたのになぜかここでは「sdc1」になっています。これは「sdc」のUSBメモリ内の1番目のパーティションにつけられた名前です。もし「sdc1」が出てこない場合はそのUSBにはパーティションがありません。

パーティションがない場合にも備えて[次の記事](https://qiita.com/kitarow0309/items/f27e5514b293ae073e1a)でパーティション作成を示します。
次の記事はGrubをUSBメモリインストールする前提でパーティションを作成していますので、続けて読んでいただければと思います。パーティションがある場合は読み飛ばしてください
【Wordpress】フォームから送信されたメール本文が文字化けする

ドツボにはまったのでメモ。

######環境
サーバ：Google Cloud Platform
使用プラグイン：ContactForm7, WP Mail SMTP, WP Multibyte Patch
メールサービス：SendGrid


######事象
コンタクトフォームからメールを送ると、本文だけが文字化けした状態で送られてきました。下のような感じ。

*[件名] こんにちは
[本文] $B%F%9%H$G$9 (B*

SendGridを怪しんで設定を調べてみたのですが、怪しいところは見つからず、ContactFormの設定上も修正できそうなところが無かったので、思い切ってプラグインのWP Multibyte PatchをOFFにしてみたところ、事象が解消。

しかしながらWP Multibyte Patchは日本語でWordPress運用している場合必須とも言えるプラグインであるため、むやみにOFFはしたくありません。できれば当該事象（メール）に関する設定をピンポイントで弄って事象解消したいところです。で、以下の通り対応したところ事象解消しました。


WP Multibyte Patchは、「WordPress 日本語版用 WP Multibyte Patch 設定ファイル」なるものが用意されており、こちらのファイルを既定の場所に配置し、ファイル記述を行うと、デフォルトの設定値を任意に上書きすることができるそうです。



####1.ディレクトリ移動
wordpressがインストールされているフォルダ配下の、以下に移動。
/wp-content/plugins/wp-multibyte-patch

####2.wpmp-config-sample-ja.phpをコピー
`wpmp-config-sample-ja.php`をコピー。
※バックアップ目的なので、実施しなくても問題なし。
　なおGCPのコンソールにSSHでログインすると、権限足らず、sudoでコピーしました。
　以降の作業はほぼすべてsudoで作業してます

####3.コピーしたファイルをリネーム
`wpmp-config-sample-ja.php`を`wpmp-config.php`にリネームします。

####4.wpmp-config.phpファイルを編集
```php:wpmp-config.php（変更前）
$wpmp_conf['mail_mode'] = 'JIS';
```

```php:wpmp-config.php（変更後）
$wpmp_conf['mail_mode'] = 'UTF-8';
```

####5.ファイルを移動
編集したファイルを/wp-contentに設置。
ゼロから始めるLeetCode Day87 「 1512. Number of Good Pairs」

# 概要

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

どうやら多くのエンジニアはその対策としてLeetCodeなるサイトで対策を行うようだ。

早い話が本場でも行われているようなコーディングテストに耐えうるようなアルゴリズム力を鍛えるサイトであり、海外のテックカンパニーでのキャリアを積みたい方にとっては避けては通れない道である。

と、仰々しく書いてみましたが、私は今のところそういった面接を受ける予定はありません。

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

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

Python3で解いています。

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

前回
[ゼロから始めるLeetCode Day86 「33. Search in Rotated Sorted Array」](https://qiita.com/KueharX/items/6a43823893682500fbf7)

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

**[技術ブログ](https://kueharx.blogspot.com/)始めました！！**
技術はLeetCode、Django、Nuxt、あたりについて書くと思います。**こちらの方が更新は早いので**、よければブクマよろしくお願いいたします！

# 問題
[1512.  Number of Good Pairs](https://leetcode.com/problems/number-of-good-pairs/)
難易度はEasy。

問題としては、整数の配列`nums`が与えられます。

`nums[i] == nums[j]` で `i < j` の場合，ペア`(i,j)`を有効とし、有効であるペアの数を返すアルゴリズムを設計してください。

>Example 1:

>Input: nums = [1,2,3,1,1,3]
Output: 4
Explanation: There are 4 good pairs (0,3), (0,4), (3,4), (2,5) 0-indexed.

>Example 2:

>Input: nums = [1,1,1,1]
Output: 6
Explanation: Each pair in the array are good.

>Example 3:

>Input: nums = [1,2,3]
Output: 0

# 解法


```python
class Solution:
    def numIdenticalPairs(self, nums: List[int]) -> int:
        ans,dic = 0,{}
        for i,j in enumerate(nums):
            if j in dic:
                ans += dic[j]
                dic[j] += 1
            else:
                dic[j] = 1
        return ans
# Runtime: 32 ms, faster than 100.00% of Python3 online submissions for Number of Good Pairs.
# Memory Usage: 13.6 MB, less than 100.00% of Python3 online submissions for Number of Good Pairs.
```


`dic`で要素を管理して、はい終わり！
速度や容量的にもかなりいいものがかけたのではないでしょうか（自画自賛）。
急いで書いたので深い解説、とまではいきませんが他にも`Counter`を使ったり、`pointer`を二つ使って書いたりもできるとは思います。
その解答をかけるようであれば、ぜひdisucussに投稿してみてください。


では今回はここまで。
お疲れ様でした。
PRML 演習問題 5.39 解答

##問題
>ラプラス近似の結果(4.135)を用いて, ベイズニューラルネットワークモデルにおける超パラメータ$\mathbf{\alpha, \beta}$のエビデンス関数が(5.175)で近似できることを示せ.

```math
\begin{align*}
\mathrm{Z}&=\mathrm{\int{f(z)dz}}\\
&\simeq\mathrm{f(z_0)\int{exp}\Bigl\{-\frac{1}{2}(z-z_0)^TA(z-z_0)\Bigr\}dz}\\
&=\mathrm{f(z_0)\frac{(2\pi)^{M/2}}{|A|^{1/2}}}
\tag{4.135}
\end{align*}
```

```math
\begin{align*}
\mathrm{lnp(D|{\alpha},\beta)\simeq-E(w_{MAP})-\frac{1}{2}|A|+\frac{W}{2}ln\alpha+\frac{N}{2}ln\beta-\frac{N}{2}ln(2\pi)}
\tag{5.175}
\end{align*}
```

##方針

>超パラメータのエビデンスはネットワーク重みを

```math
\begin{align*}
\mathrm{p(D|\alpha,{\beta})=\int{p}(D|w,\beta)p(w|\alpha)dw}
\tag{5.174}
\end{align*}
```

>のように積分することで得られる.これはラプラス近似の結果(4.135)を用いると容易に評価される. これの対数を取ると(5.175)が与えられる.

つまり題意を示すには(5.174)をラプラス近似の結果(4.135)を用いて変形し, (5.175)に帰着させればよい.

##解答
```math
\begin{align*}
\mathrm{p(D|\alpha,{\beta})=\int{p}(D|w,\beta)p(w|\alpha)dw}
\tag{5.174}
\end{align*}
```

において$\mathrm{f(w)=p(D|w,\beta)p(w|\alpha),Z=p(D|{\alpha},\beta)}$として(4.135)を適用すると($\mathbf{W}$は$\mathbf{w}$の次元)
式変形に以下を利用

```math
\begin{align*}
\mathrm{p(w|\alpha)=N(w|0,\alpha^{-1}I)}
\tag{5.162}\\
\mathrm{p(D|w,\beta)=\prod^N_{n=1}N\bigl(t_n|y(x_n,w),\beta^{-1}\bigr)}
\tag{5.163}
\end{align*}
```

```math
\begin{align*}
\mathrm{Z{\simeq}f(w_{MAP})}&=\mathrm{p(D|w_{MAP},\beta)p(w_{MAP}|\alpha)}\\
&=\mathrm{\prod_{n=1}^NN(t_n|y(x_n,w_{MAP}),\beta^{-1})N(w_{MAP}|0,\alpha^{-1}I)}\\
&=\mathrm{\prod_{n=1}^N\frac{1}{(2\pi)^{1/2}}\frac{1}{(\beta^{-1})^{1/2}}exp\Bigl[-\frac{1}{2\beta^{-1}}\bigl\{t_n-y(x_n,w_{MAP})\bigr\}^2\Bigr]\frac{1}{(2\pi)^{w/2}}\frac{1}{|\alpha^{-1}I|^{1/2}}exp\Bigl\{-\frac{1}{2}w^T_{MAP}(\alpha^{-1}I)^{-1}w_{MAP}\Bigr\}}\\
&=\mathrm{\prod^N_{n=1}\Bigl(\frac{\beta}{2\pi}\Bigr)^{1/2}exp\Bigl[-\frac{\beta}{2}\bigl\{t_n-y(x_n,w_{MAP})\bigr\}^2\Bigr]\Bigl(\frac{\alpha}{2\pi}\Bigr)exp\bigl(-\frac{\alpha}{2}w^T_{MAP}w_{MAP}\bigr)}
\end{align*}
```

よって

```math
\begin{align*}
\mathrm{lnp(D|{\alpha},\beta)}&\simeq\mathrm{{ln}f(w_{MAP})+\frac{W}{2}ln(2\pi)-\frac{1}{2}ln|A|}\\
&=\mathrm{\sum^N_{n=1}\Bigl[\frac{1}{2}\bigl\{ln\beta-ln(2\pi)\bigr\}-\frac{\beta}{2}\bigl\{t_n-y(x_n,w_{MAP})\bigr\}^2\Bigr]}\mathrm{+\frac{W}{2}\bigl\{ln\alpha-ln(2\pi)\bigr\}-\frac{\alpha}{2}w^T_{MAP}w_{MAP}+\frac{W}{2}ln(2\pi)-\frac{1}{2}ln|A|}\\
&=\mathrm{-\Bigl[\frac{\beta}{2}\sum^N_{n=1}\bigl\{t_n-y(x_n,w_{MAP})\bigr\}^2+\frac{\alpha}{2}w^T_{MAP}w_{MAP}\Bigr]}\mathrm{-\frac{1}{2}ln|A|+\frac{N}{2}ln\beta-\frac{N}{2}ln(2\pi)+\frac{W}{2}ln\alpha}\\
&=\mathrm{-E(w_{MAP})-\frac{1}{2}ln|A|+\frac{N}{2}ln\beta-\frac{N}{2}ln(2\pi)+\frac{W}{2}ln\alpha}
\tag{5.175}
\end{align*}
```

したがって題意は示された.
クラウドの学習ができるサイトまとめ

久しぶりにQwikLABSでAWSのハンズオンでもしようかなと思ったらいろいろ揃ってたのでまとめました。

# はじめに
現在は、おおよその主要なクラウドについては、無料のハンズオンテキストが公開されているようです。

# QwikLABS
AWSをハンズオンするのに一番最初に思いつくのはQwikLABSです。ただ後述のGCPのほうが今はアピールされているようでした。というのも、2016年に[Googleに買収](https://japan.zdnet.com/article/35092609/)されてしまっていました。「ラボを開始」をクリックすると、AWSとGCPの一時的なアカウントが一時的に使えるのが嬉しいです。

## 参考

+ QwikLABS
 - https://www.qwiklabs.com/

# Microsoft Learn
Azureをちょっとハンズオンするにはマイクロソフト純正のハンズオンサイトがありました。
無料でサンドボックス的なAPIなどが利用できるようです。

## 参考

+ Microsoft Learn
 - https://docs.microsoft.com/ja-jp/learn/
+ 無料でAzureの練習ができる！Microsoft Learnを試してみた
 - https://vitalify.jp/app-lab/microsoftlearn-20190102/#1_Microsoft_Learn

# Trailhead
もともとSalesforceの学習用のサイトですが、AWSについてのテキストも少しありました。

## 参考

+ Trailhead
 - https://trailhead.salesforce.com/

# Udemy
動画が豊富なサイトです。ただし有料なのがたまにきずです。資格取得に向けたコンテンツが多いと感じました。

## 参考

+ udemy
 - https://www.udemy.com/

# おわりに
おおよその主要なクラウドについては、それなりのハンズオンができることがわかりました。やっぱりQwikLABSが良くて、AWSのコンソールが一時的に使えるので、なかなか趣味では使わない壮大なサービスや、一旦使うととてつもない金額を請求されるようなBigData系のサービスも無料でお試しできるのは良いと思いますので、おすすめです。

以上
【Rails】createメソッドで保存ができない時に使える「pry-rails」

##経緯
ポートフォリオ作成中にモデルの保存がなかなかできずにハマってしまった。
「pry-rails」というgemを使うことで解決できたのでメモします。

##コントローラ

以下のようなコード、メソッドを組んでました。

```records_controller.rb
class User::RecordsController < User::Base

##中略...

  def create
    @record = current_app_user.records.build(record_params)
    if @record.save
      flash[:success] = '正常に入力されました'
      redirect_to user_root_url
    else
      flash.now[:danger] = '正常に入力されませんでした'
      render :new
    end
  end

##中略...

  private def record_params
    params.require(:record).permit(
      :material,
      :study_date,
      :study_hour,
      :study_minute,
      :memo,
    )
  end
end
```
##モデル
モデル名：record
カラムは以下の通りです。

```
["id", :integer]
["material", :string] #教材を入れたい
["study_date", :date] #日付を入れたい
["study_hour", :integer] #勉強時間（hour）を入れたい
["study_minute", :integer] #勉強時間（minute）を入れたい
["memo", :string] #メモがきを入れたい
["app_user_id", :integer]
["created_at", :datetime]
["updated_at", :datetime]
```
##解決手順
Gemfileに以下追記

```Gemfile.
group :development, :test do
  gem 'pry-rails'
end
```

ターミナルにてbundle install

```terminal
$bundle install
```
クリエイトメソッドに追記

```records_controller.rb
class User::RecordsController < User::Base

##中略...

  def create
    binding.pry #こいつを追記すること！！
    @record = current_app_user.records.build(record_params)
    if @record.save

##中略...
  
```

その上で、保存を試して見よう。そうするとGUIは待機状態になり
ターミナル上でコマンドライン操作が可能になる。
以下画面になる。

```
From: /apps/study-meter/app/controllers/user/records_controller.rb:20 User::RecordsController#create:

    19: def create
 => 20:   binding.pry
    21:   @record = Record.new(record_params)
    22:   if @record.save
    23:     flash[:success] = '正常に入力されました'
    24:     redirect_to user_root
    25:   else
    26:     flash.now[:danger] = '正常に入力されませんでした'
    27:     render :new
    28:   end
    29: end
[1] pry(#<User::RecordsController>)>
```
ここで、paramsと入力。すると

```
[1] pry(#<User::RecordsController>)> params
=> <ActionController::Parameters {"authenticity_token"=>"y5Y+hutJRPbyX9VM0lpiIax4hfeF5TXoykVL35fLQV727TmH/+/f/qncyRtDaANL1h5kqIOErcrGRhfCYuYCKg==", "record"=>{"study_date"=>"2020-07-14", "memo"=>"日本史", "study_hour"=>"0", "study_minute"=>"3"}, "commit"=>"投稿", "host"=>"study-meter.com", "controller"=>"user/records", "action"=>"create"} permitted: false>
```

こうみてみると、どのカラムになんの値を入れようとしていたのかがわかる。
「memo」のカラムには、メモがきを入れようとしており、materialのカラムに、「日本史」を入れようとしていた。

それなのにmemoのカラムに日本史が入っているたり、materialのカラムにはそもそも入力がされてない。
そこで、「おかしい」と気づく。

materialはnot null制約をしていたから
「materialはnilじゃ駄目なのにnilのまま保存しようとするってどういうことやねん。」という流れで
保存がうまくいかなかったのでしょう。

・メソッドは問題ないはず
・意図しないカラム意図しないカラムを入力しようとしてる

この点からviewのformの書き方がおかしいとあたりをつけることができた。
案の定そこのコードがおかしかったのでそこを直して解決した。

##結論
pry-railsは、エラー原因特定にすごく便利なライブラリでした。
TDD勉強#3(July 15th, 2020)

#新しい知識
###static
staticが含まれるクラスをインスタンス化せずにその変数にアクセスすることができる．
この変数をstatic変数，または，クラス変数と呼ばれる．
クラス変数はグローバル変数のような使い分けをすることができる．

```java

アクセス修飾子 static 型名 変数名    //宣言
クラス名.変数名    //呼び出し
```

###抽象クラス
どういう処理を行うかが決まっていないときに使う．
抽象メソッドは処理内容を書かない．
抽象クラスはインスタンス化できない．

```java
abstract class Sample {    //抽象クラスの宣言
    abstract void test();    //抽象メソッドの宣言．{}がない．
}
```
抽象クラスは親クラスとなることが前提のクラス．
抽象メソッドはサブクラスでオーバーライドされることで処理内容が確定する．

###super
親クラスの変数やメソッドに子クラスからアクセスする．

```java
super.メソッド名    //親クラスメソッドを呼び出す．
```
【Rails】link_toメソッドで指定する引数の順番について

###Q. link_toメソッドで指定する引数の順番は決まっているのか？

⬇️

###A. ink_toは `表示したい文字→パス→クラスとメソッド` と構文の様に順番が決まっている。

#####🆗 <%= link_to 'ツイート一覧へ', '/tweets', class: 'sample' %>

#####🆖 <%= link_to 'ツイート一覧へ', class:, 'sample’, ‘/tweets’ %>
線形検索

# 概要
社内のcrowiに貼っていた記事をこちらに移動しました。

1年半前くらいにアルゴリズムの勉強をしていたときの名残りです。番兵(番人)という考え方を知らなかったので興味深いなーと思った記憶があります。
久しぶりにAtCoderとかやりたくなってきたな・・・。

# 線形検索
線形検索とは、検索のアルゴリズムのひとつ。
n個の要素で構成された配列やリストから特定のデータを探すにあたって、先頭から順に比較し、一致すればそこで終了する。

# 例題
1行目に検索したい値、2行目に検索対象の配列が空白区切りで入力される。
検索したい値が配列中に存在する場合は何番目に存在するかを、存在しない場合は `Not Found` と出力せよ。

標準入力

```
29
4 8 1 15 29 6 97 3 10 
```

```php
<?php
$n = trim(fgets(STDIN));
$values = explode(' ', trim(fgets(STDIN)));

$count = count($values);
for ($i = 0; $i < $count; $i++) {
    if ($values[$i] === $n) {
    	echo $i + 1;
        exit;
    }
}

echo 'Not Found';
```

標準出力

```
5
```

## 番兵を使うと比較演算の実行回数が減る
番兵(番人ともよぶ)とは、配列などの要素として配置される特別な値のことで、ループの制御を簡略化する目的などで使われる。

線形探索では、検索対象の配列の末尾に目的とするデータを番兵として設置する。

番兵を使えば、メインループにおける比較演算の回数を減らすことができる。
上の例では、①for文の終了条件、②キーと探したい値の比較の2回の比較演算が行われる。
番兵を使った場合、比較演算は1回で済む。番兵によってwhileループは必ず終了することが保障されているため、終了条件を省くことができる。 

```php
<?php
$n = trim(fgets(STDIN));
$values = explode(' ', trim(fgets(STDIN)));

$count = count($values);
$i = 0;
$values[$count] = $n;
while ($values[$i] !== $n) {
    $i++;
}

if ($i === $count) {
    echo 'Not Found';
}

echo $i + 1;
```
　
線形探索はO(n)のアルゴリズムだが(最小1回、最大n回の演算が行われる)、番兵を使った実装は高速化が見込まれ、大きなデータに対して効果が期待できる。
DenoでpreactのコンポーネントをSSRする

## はじめに

@isihigameKoudaiさんの [DenoでReact Server Side Renderingした話](https://qiita.com/isihigameKoudai/items/40b5263b7296c79873a6) の記事に触発されて、DenoでpreactコンポーネントのSSRをやってみました。

## 必要なもの

- Deno (v1.2.0で動作確認しています)
- [htm](https://github.com/developit/htm)
- [preact-render-to-string](https://github.com/preactjs/preact-render-to-string)

## preactのコンポーネントをSSRする

まず、`mod.ts`という名前で以下のようなファイルを用意します。

```typescript:mod.ts
import { html } from "https://cdn.skypack.dev/htm@v3.0.4/preact/standalone.module.js";
import renderToString from "https://cdn.skypack.dev/preact-render-to-string@v5.1.10";
import { serve } from "https://deno.land/std@v0.61.0/http/server.ts";

// コンポーネント
const App = () => html`
  <div>
    Hello world!
  </div>
`;

// HTTPサーバを起動
const server = serve({ port: 3000 });
for await (const req of server) {
  req.respond({
    body: renderToString(html`
      <html>
        <head>
          <title>Hello world</title>
          <meta charset="utf-8" />
        </head>
        <body>
          <${App} />
        </body>
      </html>
    `)
  });
}
```

次に、以下のコマンドで`mod.ts`を実行し、HTTPサーバを起動します。

```shell
$ deno run --allow-net mod.ts
```

サーバが起動したら、`curl`でリクエストを送信します。

```shell
$ curl http://localhost:3000
<html><head><title>Hello world</title><meta charset="utf-8" /></head><body><div>Hello world!</div></body></html>
```

HTMLが表示されれば成功です!

## おわりに

この記事は以下のサイトを参考にしました :bow:

- [DenoでReact Server Side Renderingした話](https://qiita.com/isihigameKoudai/items/40b5263b7296c79873a6)
- [htm](https://github.com/developit/htm)
- [preact-render-to-string](https://github.com/preactjs/preact-render-to-string)
VCIよわよわ初心者開発者に贈る「最初の一歩の前」

#対象
VCIを作ってみたいバーチャルキャストよわよわ初心者
※よわよわ初心者の定義は下記を参照してね！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494837/d5e90c9c-87ba-70aa-6596-dc60efc28178.png)

#言っておきたいことお品書き
- unityは最新版を***入れてはいけない***
- unityはモデリングソフトではない
- マテリアルってなんぞ？
- 画像の取り扱いは注意
- discord入っておいたほうが良い
- luaのスクリプトのお手本が欲しいと思ったらembeddedscriptworkspaceフォルダを漁るべし

#unityは最新版を***入れてはいけない***
Unityには、バージョンによって***必ずしも互換性がありません！***かなり内部は複雑なようで、細かなバージョン違いでもエラーが出たりするので、導入するバージョンは注意しましょう。もちろん最新版なら良いというものではありません。***必ず推奨バージョンを調べて導入すること！***

というか公式の情報も修正が追いついてないようで、いろいろなことが書いてありますが、現在（2020/07/15）ではUnity2019.3（筆者はvci0.27発表当時の最新版の2019.3.14fを使用）が推奨環境のようです。（参照元：https://github.com/virtual-cast/VCI/releases ）2018系でも動くみたいですが、今後どうなるかわからないので開発側のバージョンに合わせておいたほうが良いでしょう。ちなみに私の環境ではeffekseer（エフェクトを入れる際に使われるもの）がバージョンをまたぐと表示が変になりました。

#unityはモデリングソフトではない
私も最初勘違いしていたのですが、unityで何でもやるのかな、と思ってたら**そうではないです。**モデリングはblenderなどの別のソフトを使って行います。unityだけでも大変なのにblenderやeffekseerや他にも色んなものを覚えないといけません、、、大変だね！

とはいえ、球や板などのよくあるモデルは最初から用意されているので、それらを使えば試作研究には用は足ります。私はだいたい球だけとかを使って大まかなイメージを決めてからモデリングを始めます。

#マテリアルってなんぞ？
私自身があんまり詳しい人でないので言うのがはばかられるのですが、事バーチャルキャストだけで言うなら、「見た目を規定するもの」と思って良いと思います。一色だけだったり、テクスチャと言われる画像をモデルに貼り付けたり、します。基本的に画像はマテリアルとして読み込まれるらしく、文字（バーチャルキャストではtextmeshproという文字を入れるオブジェクト）もマテリアルです。文字がマテリアル（物質）ってよくわかりませんが、見栄えに関係するものにはマテリアル（かパーティクル）が関係するようです。気持ち悪いですが慣れましょう。

似たものでシェーダーというのもありますがこれは影などの付き方を決めるものです(が、いろんな事ができて私は理解しきれてない、、、)。

#画像の取り扱いは注意
画像は読み込むと**基本いじられてしまいます**
まず形状が正方形にされます（これは処理を早くするためみたいです）。更にサイズも、大きいものを入れても2048*2048くらいに小さくされてしまいます。大きくしようとしても8kまでしか無理です。更に、圧縮されたりもします。あと、色も照明をきちんと設定してあげないとうまく合いません。そこら辺こだわりがある方は特に注意してください！

#discordは入っておいたほうが良い
公式wikiには大体のことが書いてあるのですが、常識扱いされて書いてない仕様が結構あったり、古いまま残ってたりすることがあるので、人に聞かないとわからないことが結構あります。そういう人のためにdiscord（チャットのようなものです）チャンネルがあります。VCI開発者チャンネルというのが公式wikiにリンクがあるので、ぜひ入りましょう。

# luaのスクリプトのお手本が欲しいと思ったらembeddedscriptworkspaceフォルダを漁るべし
準備もできてチュートリアルもこなして、早速luaでスクリプトを組もう！と思ったときにお手本が欲しくなると思います。インターネット上を漁っても今のところあまりないので、ここは正直に公式のサンプルを見ましょう。The seed onlineで公式１のアイテム(https://seed.online/users/2 )は単機能ごとに用意されているので参考にしやすいです。
この子達を取り込んで、バーチャルキャストの中で呼び出すと、C:/Users/\__USER_NAME\__/AppData/LocalLow/infiniteloop Co,Ltd/VirtualCast/EmbeddedScriptWorkspace
のフォルダの中に対応されるスクリプトが保存されます。


ちなみに、チュートリアルはこっち（https://virtualcast.jp/wiki/doku.php?id=vci:script:tutorial ）の方をおすすめします。youtube動画のやつ（スイカ）もありますが、こちらはよわよわ初心者にはちょっとレベルが高いので、自信のある方以外は、wikiの方にしましょう。cubeだけでも結構難儀するのでまずは小さく始めることをおすすめします。
git の差分をいい感じに表示できる delta の紹介

git の差分をいい感じに表示できる delta を紹介します。rust 製です。

https://github.com/dandavison/delta

まず先に before / after を載せておきます。

### before 


<img width="876" alt="スクリーンショット 2020-07-15 23.28.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29088/62315e4b-e968-5097-74c5-afee4f8beadd.png">


### after

<img width="1120" alt="スクリーンショット 2020-07-15 23.27.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29088/5f595ce4-37e5-7c8b-59e9-7bdfb3cd34d7.png">

### 導入方法

brew でインストールできます。

```sh
brew install git-delta
```

### 設定方法

.gitconfigに書きを追加します。

```
[core]
  pager = delta --theme='Monokai Extended'
[interactive]
  diffFilter = delta --color-only
```

完了です。

### 確認

おもむろに`git log -p` をしてください。シンタックスハイライトした差分が表示されるかと思います。


git の cli ツールである tig が対応していればさらに良いのですが、ISSUEが作られているもののなかなか機能追加は大変そうな印象です。

https://github.com/jonas/tig/issues/542
選択ソート

# 概要
社内のcrowiに貼っていた記事をせっかくなのでこちらに移動しました。

1年半前くらいにアルゴリズムの勉強をしていたときの名残りです。
「プログラミングコンテスト攻略のためのアルゴリズムとデータ構造」を参考に図を作成してプログラムを書きましたが、正直、「参考」に貼ったアプリケーションのほうが分かりやすいです。

# 選択ソート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253650/87db9181-c068-975c-be39-f680b1d35960.png)


| A[N] | N個の整数でできた配列 |
| ------------ | ------------- |
| i| 未ソートの部分の先頭を示すループ変数で、配列の先頭から末尾に向かって移動する |
| minj| 各ループの処理でi番目からN-1番目までの要素のうち、最小値の位置 |
|j | 未ソートの部分から最小値の位置(minj)を探すためのループ変数 |

未ソート部分から最小値の位置を探し、その位置の要素と未ソート部分の先頭の要素を交換する。
交換されて先頭にきたものはソート済みとする。
これを繰り返し、配列の先頭から小さい順に決定される。

選択ソートは離れた要素を交換するため安定なソートではない？(ここがちょっとわからない)

## 計算量
未ソート部分の最小値を見つけるため、各ループでN-1回、N-2回、N-3、…、1回の比較が行われる。
よって、常に(N^2 - N) / 2 回の比較が行われる。
N^2に比べてNは十分小さいので無視することができ、定数である1/2も無視することができるので、選択ソートはN^2に比例するといえる。

## 問題
入力は、1行目に数列の長さを表す整数N、2行目にN個の整数が空白区切りで与えられる。
出力は、1行目に整列された数列の要素を空白区切り、2行目に交換回数を出力する。

入力値

```
6
5 6 4 2 1 3
```

プログラム

```php
<?php
$arrayCount = trim(fgets(STDIN));
$array = explode(' ', trim(fgets(STDIN)));

list($sortedArray, $sortedCount) = selectSort($arrayCount, $array);

foreach ($sortedArray as $value) {
    echo $value.' ';
}
echo PHP_EOL, $sortedCount, PHP_EOL;

function selectSort($arrayCount, $array)
{
    $sortedCount = 0;
    for ($i = 0; $i < $arrayCount; $i++) {
        $minj = $i;
        for ($j = $i; $j < $arrayCount; $j++) {
            if ($array[$j] < $array[$minj]) {
                $minj = $j;
            }
        }

        $temporary = $array[$i];
        $array[$i] = $array[$minj];
        $array[$minj] = $temporary;
        if ($minj !== $i) {
            $sortedCount++;
        }
    }

    return [$array, $sortedCount];
}
```

出力結果

```
1 2 3 4 5 6 
4
```

# 参考
- 書籍 プログラミングコンテスト攻略のためのアルゴリズムとデータ構造  
 - 私には難しすぎる・・・。
- [iOSアプリ アルゴリズム図鑑](  https://itunes.apple.com/jp/app/%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E5%9B%B3%E9%91%91/id1047532631?mt=8)
   - 動くイメージで解説してくれるので分かりやすい。
form_withとfields_forで複数modelを一括保存

# この記事でやること

- rails6
- form_withを使う
- fields_for
- 複数modelを一括登録

をやっていく

# fields_forとは

form内で異なるmodelを編集できるようにするもの

https://railsdoc.com/page/fields_for

```ruby
<%= form_with model: @post, url: posts_path do |form| %>
  <label for="name" class="block text-gray-700 text-sm font-bold mb-4">スケジュール登録</label>
  <%= form.text_area :name, id: "name", class: "form_style border_or w-full mb-4 focus:outline-none focus:shadow-outline" %>
  <%= form.text_area :user_id, class: "hidden", value: @current_user.id %>
  <%= fields_for :event do |event_form| %>
    <%=  event_form.text_area :event_name, id: "event_name", class: "form_style border_or w-full mb-4 focus:outline-none focus:shadow-outline" %>
  <% end %>
  <div class="flex items-center justify-between">
    <%= form.submit "登録する", class: "bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline" %>
  </div>
<% end %>
```

上記のようにform_withタグ内に下記で入れていく

```
fields_for モデル名 do ||
```

# 親子関係の場合

form_withのmodelとfields_forの指定先のmodelが親子関係の場合は下記が必要

```model/oya.rb
belongs_to :post
```

```model/kodomo.rb
has_many :events
```

```controller.rb
def create
 @event = @post.events.new(id: params[:id])
end
```

# 参考にした記事

「【Rails 5】モデルを一括登録する手順」
https://qiita.com/Ryoga_aoym/items/91a3940cfa4de268fca4

「1つのフォームで複数のモデルを扱う [Ruby on Rails]」
https://www.petitmonte.com/ruby/multiple_models.html
Google フォームって知名度低くない？Google スプレッドシートと連携させるとこんなに幸せに！

本記事は [Google スプレッドシートのデータを JS で fetch したい！](https://qiita.com/otchy/items/9acf845314e06c9971bc)の続編です。そこそこ反響が良かったので気を良くして約束通り続編を書くことにしました。前記事が未読の方はそちらを先に読んでいただいた方がわかりやすいと思います。

さて、すでに存在している Google スプレッドシート上のデータを JS あるいは任意の HTTP をサポートする言語から `fetch` 出来るようにはなりましたが、そもそもどうやってデータを集めたら良いのでしょう。

むろん CSV などの元データがあれば読み込ませればいいですし、ゼロから手作業で入力・編集することも出来ます。それらが容易なのはスプレッドシートの大きな利点です。しかし、例えば多くの人からのアンケート結果を集計する場合など、アンケート回答と同時にスプレッドシートが埋まっていればそれほど楽なことは無いと思いませんか？

そこでまず出てくるのが Google フォームです。これは日本ではあまり知名度がない気がするのですが、ちょっとしたアンケート程度で凝った UI やバリデーションが不要の場合は選択肢の筆頭になりえます。

[Google ドライブ](https://drive.google.com/)を開き、「新規」メニューから Google フォームを選ぶと編集画面が開くので、そこで必要な項目をポチポチ足していくと、ユーザに公開出来るフォームが完成します。

![google-form-menu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24898/bf4f16ba-3ebd-266b-e543-ff205b28cc22.png)
![new-edit-form.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24898/2aa616f8-3d98-3295-8480-8f50171396a2.png)

例えば、前回使用したダミーデータのような情報を集めようと思ったらこのような感じになるでしょか。

![user-form-edit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24898/9401a1ff-6068-0352-bfcf-ddb38470ea15.png)

フォームが完成したら「送信」ボタンから直接メールで送るか、リンクを取得するなどしてフォームを配れば、多くの人から回答を集めることが出来ます。

![get-shareable-link.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24898/abaa38b9-9dbd-b35f-d03a-63eb7910fe0d.png)

回答が集まり始めたら、フォームの編集画面にある「回答」タブで回答の内容を確認してみましょう。

![results-view.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24898/b86e1a61-eda7-1272-882b-b60b8c7236d6.png)

見ると分かるように、簡単な集計結果はグラフで表示されるので、目的が単なるアンケートならこれで終わりで良いかもしれません。さらなる分析が必要だったり一覧表で回答を確認したい場合は、結果をスプレッドシートで見てみましょう。「回答」タブの上部にあるスプレッドシートのアイコンをクリックすると、このフォームとリンクしたスプレッドシートを作る、あるいは既存のスプレッドシートに追加することが出来ます。

![new-spreadsheet.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24898/e9b4bcbb-7bb4-9703-dbe2-6dba0747a9fa.png)
![linked-spreadsheet.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24898/df25f17a-a63c-abfb-7746-3c1d67c3e78e.png)

このスプレッドシートはフォームとリンクしているので新しい回答があると自動的に更新されます。

![auto-input.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24898/12ce9cab-c73a-7315-7b0c-b42fd3028b10.gif)

また、データ自体は通常のスプレッドシートと変わらないので、何らかの式を書き足して集計できるのみならず、条件付き書式で見やすく色を付けたり、ピボットテーブルでクロス集計を行ったり、表現力の高いグラフを描いたりすることだって出来ます。

![conditional-format.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24898/fec1c192-e5a2-0250-6c6b-8e09a8350c5b.png)
![pivot-table.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24898/0cc03650-e1ff-6b8b-9573-e8cfd95f570a.png)
![donut-chart.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24898/225886b9-7cce-fad9-cd91-daa20e3a1193.png)

実際のところ Google フォームと Google スプレッドシートの組合せはかなり強力で、プログラミング無しでも相当多くの事が済んでしまうでしょう。さらに[前記事](https://qiita.com/otchy/items/9acf845314e06c9971bc)で紹介した方法で GET API を実装すれば、外部システムとの連携すらできて可能性は相当に広がります。

ところが、これでもまだかゆいところには手が届ききっておらず、例えば次のようなことを実現しようと思うと、自前で POST API や入力用の UI を実装する必要が生じます。

- ID を自動的に採番する
- 郵便番号をバリデーションする
- 生年月日に基づいて年齢を自動的に計算する

…といったところで、紙幅が (筆者の気力が) 尽きてしまいましたので続きはまた次回！
この記事をストックしていただければ、次の記事を公開した際に通知を飛ばすので、ご贔屓のほどよろしくお願いします。
【Vue.js】複数のインスタンスを作成する方法【初心者】

現在Vue.jsを勉強しています。
Appというインスタンスの他にpage2というインスタンスを作成しようと思います。

vueファイル内で```new Vue```と書くことはできないので、```main.js```に```new Vue```を書くことによって複数のインスタンスを作成します。

コンポーネントを他のコンポーネントでも使えるようにするには、script内を```export default```で囲むことによってvueインスタンスを生成します。したがって、基本的にscriptの部分は export default で囲むことが前提となります。（なんか足りてない、または間違っている気がするので見直してみます。）

参考：[export defaultについて](https://qiita.com/notch0314/items/e9f2b704a340824393b8)

##main.js
・main.jsに```new Vue```を書くことによって複数のインスタンスを作成します。
・作成するpage2をインポートする必要があります。


```main.js
import Vue from 'vue'
import App from './App.vue'
import page2 from './components/page2.vue'
import router from './router'

Vue.config.productionTip = false

new Vue({
  router,
  render: h => h(App),
}).$mount('#app')

new Vue({
  router,
  render: h => h(page2),
}).$mount('#page2')
```


##page2.vue
・id はpage2とする必要があります。
・script内のexport defaultで下記を記述する必要があります。

```
name: 'page2',
  components: {
  }
}
```

```page2.vue

<template>
  <div id="page2">
<router-view></router-view>


ああああ
  </div>

</template>


<script>
export default {
  name: 'page2',
  components: {
  }
}
</script>
```

これで、元々あったAppに加え、page2という2つのインスタンスをアプリ内に作成することができました。
[守ろう36協定]Freee人事労務APIとGASでslackに残業時間アラート

2019年４月より、３６（サブロク）協定で定める時間外労働に、罰則付きの上限が設けられており、人事部の人たちは月45時間の上限を超えない様にメールやスラックで残業時間が規定を超えそうな人に対してアラートを飛ばしてくれています。

ただ、そんなことのために時間を割いているのも、また36協定に引っかかってしまう原因になりかねないのでAPIとGASで都度アラートを飛ばして作業効率できればいいのにな。と思いPHPerがGASを書いてみました。
(トリガーの設定→毎日処理させる設定については別記事参照)
(slackの通知設定→「Incoming Webhook」で検索すれば詳しい記事が出てくるのでそちらを参照)

## コード

```gas.js
var now   = new Date();
var year  = now.getFullYear();
var month = now.getMonth() + 1;
var day   = now.getDate();
var company_id = 'カンパニーID設定';
var token = 'Freeeのトークン設定';

//メソッドにPOSTを指定しログイン情報を設定
var options = {
    'method' : 'GET',
    'headers' : {
        'Authorization':'Bearer ' + token,
        'accept': 'application/json'
    }
};

function myFunction() {
    //アクセス先URLにGETクエストを送信し、従業員一覧を抽出
    var response = UrlFetchApp.fetch('https://api.freee.co.jp/hr/api/v1/companies/' + company_id + '/employees', options).getContentText();

    //JSON形式に直す
    var res = JSON.parse(response);

    var cnt = res.length;
    //従業員一人一人残業時間計算メソッドを使う
    for(i = 0; i < cnt ; i++ ){
        var emp_id = res[i].id;
        totalTime(emp_id)
    }

}
//従業員ごとの残業時間を算出
function totalTime(emp_id){

    //GET先の設定
    var url = 'https://api.freee.co.jp/hr/api/v1/employees/' + emp_id + '/work_record_summaries/' + year + '/' + month + '?company_id=' + company_id + '&work_records=true';

    var response = UrlFetchApp.fetch(url, options).getContentText();
    //JSON形式に直す
    var res = JSON.parse(response);
    var overtime_work_minute = 0;

    //配列の数を取得
    var cnt = res['work_records'].length;
    for(i = 0; i < cnt ; i++ ){
        var workDate = res['work_records'][i].date;
        var workYear = workDate.substr( 0, 4 );
        var workMonth = workDate.substr( 5, 2 );
        var workDay = workDate.substr( 8, 2 );
        var getDate = new Date(workYear, workMonth,workDay);

        //今月か確認するif文
        if(workMonth == month){
            //月内のデータであれば残業時間を追加していく
            overtime_work_minute += parseFloat(res['work_records'][i].total_overtime_work_mins);
        }
    }
    overtime_work_hour = overtime_work_minute / 60;

    //合計値が20時間を超えていればのif文
    if(overtime_work_hour >= 40){
        sentence =  overtime_work_hour+ "残業時間あなたの残業時間のライフは0よ。";
        postSlack(sentence)
    } else if(overtime_work_hour >= 30){
        sentence = "合計残業" + overtime_work_hour+ "時間。残業せず帰りましょう。";
        postSlack(sentence)
    } else if(overtime_work_hour >= 20){
        sentence = "合計残業" + overtime_work_hour+ "時間です。36協定を忘れずに";
        postSlack(sentence)
    }
}

function postSlack(sentence) {


    var slackPayload  = {
        'text'      : sentence
    };
    var slackOptions = {
        'method'      : 'post',
        'contentType' : 'application/json',
        'payload'     : JSON.stringify(slackPayload),
    };
    var slackUrl = 'slackのURLを貼る';
    UrlFetchApp.fetch(slackUrl, slackOptions);

}
```

## あとがき

今勤めてる会社では「Freee人事労務」ではなく「ジョブカン」を使ってますし、チャットツールは「チャットワーク」なので今回書いた記事を会社内で使うことはないんだろうな。
herokuでプリコネの文字を解読するtwitterアプリ作った(失敗)


#リンク

本アプリ
https://twitter.com/priconeAI

リポジトリ
https://github.com/misogihagi/priconne-AI

# 感想

herokuでtesseract使おうとするとlibpngでエラーでて環境整えるまでめんどくさかった。
ゲームとかアニメとかに使われている文字は丸く配置されていたり、手書きだったりして本当にちゃんとしたやつを作るとなると時間がかかりそう。
そもそも自分で読めないものを読ませようとするのが間違っていたのかも