OmniAICreator/Qiita-1.07M huggingface dataset:
UnityでGithubを用いてデータ管理したい


#ご挨拶と本記事の目的
みなさんおはこんです。
昨今某ウイルスの影響でリモートワークが続く毎日であります。
そんな中、チーム開発をしている時、自分の開発と第三者の開発環境を統合したい時が来るかもしれません(いずれ来ます)
そんな中とても便利となるツールが`Github`というツールです。
これを用いるとどこでもチーム開発が可能になります。

本記事ではそのGithubを用いてUnityの進捗管理などをするための初期設定から、実際のコマンド操作に関して記述しています。
あと私の備忘録のためです。

注意：すでにGitやGithubアカウント、sshkeyの追加、Unityが自分の環境にインストールしている方を前提としています。
もしまだインストールされていない方や「Gitってそもそもなに？」と思われる方は、以下の記事を参照ください。

- [Windowsセットアップ](https://prog-8.com/docs/git-env-win)
- [Macセットアップ](https://prog-8.com/docs/git-env)
- [サルでも分かるGit入門](https://backlog.com/ja/git-tutorial/)



#### 頻出キーワード
リポジトリ：ファイルやディレクトリの状態を記録する場所
リモート：ネットワーク上の環境
ローカル：各自のパソコン上の環境
ブランチ：履歴の流れを分岐して記録していくためのもの


環境：macOS Big Sur バージョン11.6.1

##リモート編
### 1. リポジトリの作成

自分のGithubアカウントを開き、Repositoriesを開きましょう。
そして、Newのボタンを押して、リポジトリを作成。
![スクリーンショット 2022-02-21 23.10.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/756562/7a9e29e1-a24d-bc53-a14b-659c1dfb418c.png)

publicはリポジトリを一般に公開、privateは非公開になります。ひとまずprivateにしましょう。
またAdd.gitignoreでUnityを選ぶことを忘れずに
![スクリーンショット 2022-02-21 23.01.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/756562/3c41a679-fa8b-f8a1-33bf-6232490f7404.png)

そしたら...
![スクリーンショット 2022-02-21 23.13.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/756562/817a1e1d-bfd5-6372-c4ff-53cb97686a0b.png)

リポジトリが作成できました!! 
おめでとう！！

さて次はローカル環境の構築です。

## ローカル編

### 1. セットアップ

自身のコマンドプロンプトやiTermで、作成したいアプリケーションのディレクトリに移動し、以下のコマンドを打ちます。

```
git init
```

このコマンドで、アプリケーション内で初期化が完了しました。

### 2. リモートとの紐付け
以下のコマンドでローカルリポジトリとリモートリポジトリをリンクさせます

```
git remote add origin [リモートリポジトリのURL]
```

## 3. gitignoreをローカルに反映させる。

ここで先程リモートリポジトリで作成した、gitignoreをローカルに追加しましょう。
これがないと後述するpushする際に「ローカルとリモートの環境が違いすぎるからプルリクが出来ないよ」とGitに怒られてしまいます。

```
git pull origin main
```

## 4. branch変更
デフォルトではおそらくmainブランチにいると思いますが、本来mainブランチでの作業はお勧めしません。なのでここら辺でブランチを切り替えてしまいましょう

```
git checkout -b firstcommit
```

## 5. リモートリポジトリにpush
以下のコマンドでリモートリポジトリにアップロードすることができます

```
git add .
git commit -m "firstcommit"
git push origin firstcommit 
```

## 6.PullRequestをする
ここからはコマンドラインを一旦閉じてWebで自分が先程作成したリポジトリにいきましょう。以下のような画面が出ているはずです。


右のボタンを押して、自分が何をしたかのコメントを書くのも良いですね。
![スクリーンショット 2022-02-22 10.01.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/756562/fc4cf7fd-26e8-62f3-9a42-f0c21bd45b25.png)


## 7. Mergeする
つまり、今まで自分が作ってきた環境との統合です。
緑のボタンを押してマージしましょう。

![スクリーンショット 2022-02-22 10.16.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/756562/661db6ed-87ab-9830-c339-c041511da9b0.png)
![スクリーンショット 2022-02-22 10.01.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/756562/b5f2b115-364a-3665-4a4d-c143ebb2c312.png)


ここまでして1サイクルです。
お疲れ様です。



### コマンド編
ここからは私個人が、開発中に必要になってくるだろうと考えるコマンドです。余裕のある方はご覧ください。

既存のgitリポジトリを自分のローカル環境にコピーしたい時

```
git clone
```
新しくブランチを作成する際に、リモートリポジトリに他の変更がMergeされているかもしれないので、pullしよう

```
git pull
```


ログを見たい時

```
git log
```

現在の状態を確認

```
git status
```
リモートの特定ブランチをローカルに取り組む

```
git fetch origin BRANCHNAME
```

特定のpull requestをローカルに持ってくる

```
git fetch origin pull/ID/head:BRANCHNAME
```


## 最後に
今回はUnityでのGithubを用いたデータ管理の流れを説明したしました。
ほかにも「具体的なコマンドの意味を知りたい」や「もっとコマンドを自在に使いたい」と考える方は各自でお調べください(投げやり)

それでは今回もご高覧ありがとうございました。
Python マルチスレッドで同一サイトにHTTPリクエストするときのスクレイピングTip

# 結論

あ、リクエスト用のスレッドつくればいいのか（汗
記事書きながら思いついた。ありがとうQiita。

# はじめに

マルチスレッドでスクレイピング処理をしているときに、同一サイトで短時間多重リクエストしでかしそうになったので予防方法をメモする（別スレッドでリクエストするとスリープの意味をなさないので）



# 方法

リクエスト前後でスレッドをロックする

ロッククラスは以下の通りなので別スレッドから自由にロック、アンロックできる
>プリミティブロック (primitive lock) オブジェクトを実装しているクラスです。スレッドが一度ロックを獲得すると、それ以後のロック獲得の試みはロックが解放されるまでブロックします。どのスレッドでもロックを解放できます。

https://docs.python.org/ja/3/library/threading.html#threading.Lock

```python
import time
import threading
import requests


lock = threading.Lock()

def http_req(url):
    global lock
    lock.aquire()
    res = requests.get(url)
    time.sleep(5)
    lock.release()
    return res

def th1():
   res = http_req(url)
   # すっごいこと1
   ...
  
def th2():
   res = http_req(url)
　 # すっごいこと2
   ...

def main():
    # スレッドを立ち上げる処理
    ....
    # スレッドを待機する処理
    ....
 
```

# 感想

あ、リクエスト用のスレッドつくればいいのか（汗
記事書きながら思いついた。ありがとうQiita。
WordPressのContact Form 7 を使って、入力画面→確認画面→送信完了画面を作る

#Contact Form 7
プラグインをインストール

#Contact Form 7 add confirm
確認画面ようのプラグインをインストールする

[confirm "確認画面"][back "戻る"][submit "送信"]
↑こちらを追記

##確認画面にいかない！
https://info-con.co.jp/tips/wordpress-25-contact_form_7_add_confirm-v2/

#送信完了画面

[confirm "確認画面"][back "戻る"][submit "送信"]

```
<script>
document.addEventListener( 'wpcf7mailsent', function( event ) {
location = 'http://hoge.com/thank/';
}, false );
</script>
```

リダイレクト設定を行う

固定ページでthankページ作成

自分のページのURLを記述

```
location = 'http://hoge.com/thank/';
```


以上
DatabricksでTensorFlow Kerasを使ってみる

[Get started with TensorFlow Keras in Databricks \| Databricks on AWS](https://docs.databricks.com/applications/machine-learning/train-model/keras-tutorial.html) [2021/12/15時点]の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::


[TensorFlow Keras](https://keras.io/about/)は、機械学習プラットフォームであるTensorFlow上で動作するPythonで記述されたディープラーニングAPIです。TensorFlowとKerasはDatabricks機械学習ランタイムに含まれています。この10分チュートリアルノートブックでは、TensorFlow Kerasによる表形式データに対する機械学習トレーニングのサンプル、インラインでの[TensorBoard](https://docs.databricks.com/applications/machine-learning/train-model/tensorflow.html#tensorboard)の使用法を説明します。

# 要件

Databricks機械学習ランタイム7.0以降が必要です。

# シングルノードと分散トレーニング

シングルマシンのワークフローをテスト、移行する場合には[シングルノードクラスター](https://qiita.com/taka_yayoi/items/6e7c6cc14a5017ef6d15)を使ってください。

ディープラーニングにおける分散トレーニングを行う場合には、[分散トレーニング](https://docs.databricks.com/applications/machine-learning/train-model/distributed-training/index.html)を参照ください。

# サンプルノートブック

## TensorFlow Kerasクイックスタートノートブック

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

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
格安3Dプリンターでマイクラの世界を現実世界に持ってくる

![Image from iOS (65).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/42480b43-60cb-6019-c621-a01cc6044693.jpeg)


## はじめに


前回、格安3Dプリンターを自宅に導入したことを記事にしました。

https://qiita.com/oggata/items/8b5c2bc0aa8a4a02c516

3dslashのブロックを使ってマイクラっぽい建物をちまちまと作っていたのですが、であれば、普段遊んでいるマイクラの世界をそのままExportして印刷したほうが面白いかもしれないと思って調べてみると、既にマイクラのワールドデータを.objファイルで書き出す仕組みがあることがわかりました。ということで、今回はマイクラで遊んでいる世界をそのままリアルワールドにもってくる(3d印刷する)方法をメモとして残しておきます。


## 用意するもの

(ハードウェア)
 * PC(macでもwinでもok)
 * 3Dプリンター


(インストールが必要なもの)
 * マインクラフトJavaバージョン
 * マイクラのワールドをexportするソフト(jmc2objまたはMineways)
https://www.jmc2obj.net/
http://www.realtimerendering.com/erich/minecraft/public/mineways/
スライサーツール(3Dプリンターへ書き出すためのツール。3Dプリンターに付属している場合が多い)

(Webツール)
 * 3DモデリングWebツール
https://www.3dslash.net/
 * obj->stlのコンバーターWebツール
https://anyconv.com/ja/obj-to-stl-konbata/
 * chromeのobjビューアー(なくてもよいがあったら便利)
https://chrome.google.com/webstore/detail/obj-viewer/niolinkgjinohfdlpnnabmbjnlnlmmgi?hl=ja

## 手順

###1.マイクラの中で、ロケハンしてsaveする
マイクラのセーブデータをもとに3Dデータを作っておきます。
普通にゲームをして、保存すればok。

###2.マイクラのワールドデータが保管されている場所を開いてデータがあることを確認する
/Users/ユーザー名/Library/Application Support/minecraft/saves/

###3.jmc2objからマイクラのワールドデータを読み込む + 書き出し範囲を選択する
(赤の十字時点が自分のキャラが立っている地点になります。チャンクサイズ(描画範囲)はあまりおおきくなると印刷した時のブロックが潰れてしまうので、1~2くらいがおすすめです）
![スクリーンショット 2022-02-18 22.45.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/e08e6275-5b86-1440-707c-e57452552c5d.png)

### 4.exportする

### 4.5 objビューアーで書き出した部分をみる
(ここはやらなくても良いが、stlに変換した後で、思ったような場所ではなかった場合にやりなおすのが面倒なので、ここでどのようなデータがexportされたか確認しておくほうが良い)
![スクリーンショット 2022-02-19 11.43.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/b98f1f03-dd1f-2600-59c5-84afd0e02924.png)

### 5.obj->stlへ変換する
![スクリーンショット 2022-02-18 22.48.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/e9c7624a-5ead-b9ac-7c6f-7fbf1e9ffc9c.png)

### 6.3dslashでstlを読み込む + 不要なところを削る + stlで保存する
![スクリーンショット 2022-02-19 10.08.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/264bbb0c-342d-4436-09c9-81513c007fd0.png)

### 7.3D印刷用のソフトにstlを読み込みして印刷を行う

### 8.完成

いつも遊んでいる村周辺を書き出した
![Image from iOS (61).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/46c1b3a0-52de-6fc1-9e60-a2e0279e3f13.jpeg)

ピリジャーの前哨基地はこんな感じ
![Image from iOS (62).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/573ac15c-9385-65f4-3fab-938561c5deb2.jpeg)

いつも遊んでいる洞窟と祠
![Image from iOS (66).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/f9c34acc-0efc-2979-669b-efebc485cb5c.jpeg)


# Conclusion

格安3Dプリンターでは、3.5cm x 3.5cm x 2.0cmでだいたい4時間ほど。
export時にチャンクサイズが選べるのですが、あまりにも細かいものは、つぶれてしまうので、
チャンクサイズが1~2あたりが一番きれいにできるのではないかなと思いますが、この辺りは色々試行錯誤してみたいところ。
もう少し性能の良いプリンターを買いたくなるところですが、誰かに見せるための作品というわけでもなく、ただ普段のゲームの楽しみ方の一つなので、限られた資源(お金)での限界をみつけるくらいでちょうど良いのではないかなと思います。
なぜOpenShiftなのか

こんにちは！外資ベンダーでカスタマーサクセスをしている、Kazuyaです。

本日は、Red Hat・IBMが推進している、OpenShiftをなぜ使うのか(Why OpenShift)という点について、
取り上げたいと思います。

# そもそも OpenShiftって？
OpenShiftは、Red Hat社が提供しているEnterprise対応のKubernetes Container Platformです。
CaaS(Container as a Service)の基盤となるもので、CaaSとはPaaS(Platform as a Service)の中でも、
特にコンテナサービスに重点を置いたサービスを意味します。
OpenShiftを利用することで、短時間で簡単にアプリケーションを構築、開発、提供することができます。

# Kubernetesのメリットは？
Kubernetes(クーバネティス)は、CNCF(Cloud Native Computing Foundation）が開発を支援するオープンソース・ソフトウェア(OSS)。
Dockerコンテナを本番サービスで利用するためのPlatform。
ポイントはOSSであるというところ。

OSSは、たくさんの企業が開発に参画して急速に発展・改善を繰り返します。
アップデートが非常に多く、マイナーバージョンのリリースが早い。
リクエストに対するオーダーが早いことがOSSたるすばらしさ。

反して、
リリースから１年たたずに、そのバージョンのサポートが終了されることが多数。

企業が作るアプリケーションは、すぐにサポートから外れてしまう。
開発途中で、サポートが終了してしまうということも。

# そこでOpenShift
Kubernetesのスピード感に対して、企業が作るシステムは息の長いもの。
サポートが長く続いてほしい。
このようなニーズにこたえるべくして登場したといっても過言ではないのが、
「エンタープライズ向け」であることがメリットとなるOpenShift。
長期サポートがある。

# 長期サポートがあるだけなのか？
様々な局面にいて、Kubernetesにはなかったプラスアルファが用意されています。
## DevOpsの観点
* CI/CDツール環境が整備されている
    * マイクロサービス化のためのCI/CD機能が最初から備わっており、スムーズにCI/CD設定が構築できる
* 開発者がKubernetes環境へアクセスしやすい仕組みが採用されている（Kubernetesのインタフェースは複雑とされている）

## IT運用面の観点
* デプロイとスケーリングを高速化できる。(これはKubernetes自体の機能でもあるがそれを活かせるという意味）
* 信頼できるエンタープライズKubernetesという点
* 包括的なコンテナセキュリティ
* AnyPlace。ベアメタル・OpenStack・VMWare オンプレミス・パブリッククラウド。どこにでもインストール可能。

## エンタープライズ向けの観点
* 脆弱性対応など企業向けセキュリティが強化されている
    * OSSの課題として、脆弱性対応があげられる。企業でOSSを採用する際には、OSSに発生したセキュリティホールが見つかってから、できる限り早く解決することが望まれる。これに対して、Red Hatでは、政府機関・一般企業におけるLinux活用の推進を行うべく、脆弱性発見及び対応に注力し、セキュリティ国際的機関と連携して対応を進めているという安心感がある。事例として、Red Hat Enterprise Linux（RHEL)では、過去に重大な脆弱性が発見されたのち、24時間以内に対応する修正プログラムが提供できていた事例が多数ある。
    * Ret Hatが提供する、Red Hat 認定コンテナは、Kubernetesでコンテナ運用するうえで、最高水準の脆弱性対応が受けられるともいえる。
 
# つまり
Kubernetesを単体で企業のアプリケーションに採用するよりも、
より息の長い安心できるアプリケーションを、開発者がスムーズに作業を行うことができる環境で、作り出すことができる。
そんなところが、エンタープライズ対応のKubernetesベースのコンテナサービスといえる製品なのではないかと。

コストに対応する必要はありますが、
「OSSを基盤として使っています！」とクライアントのIT部門責任者に説明するより、
「OSS基盤のコンテナプラットフォームをエンタープライズサポートするOpenShiftを使ってより安全な環境にしています！」のほうが、
納得感が出るのではないかなと。

そんなところがメリットかなと感じた次第でした。

Kubernetes自体の技術は素晴らしい。
それを企業向けにアレンジして使いやすくしたのがOpenShift。
どちらを使うかはシチュエーションによるかもしれませんが、
大規模なソリューションを企業で構築するときには選択肢として大いにありですね👌

See you next time!
acts_as_listで rails db:migrate:reset すると undefined method `position' エラー

## 困っていたこと
gemの[act_as_lists](https://github.com/brendon/acts_as_list)をアイテムの並び替えに使っていたところ、下記のようなエラーが発生してrails db:migrate:resetが妨げられる現象がローカル開発環境で多発していた。（一方、本番デプロイは成功していた。）

```
$ rails db:migrate
== 20210406073220 CreateItems: migrating ===============================
-- create_table(:items)
   -> 0.0123s
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:

undefined method `position' for #<Item:0x00007ff2df744198>
Did you mean?  position=
```

実装はこんな感じ。

```ruby:Gemfile
gem 'acts_as_list'
```

```ruby:db/migrate/20220203113520_add_position_to_items.rb
class AddPositionToItems < ActiveRecord::Migration[6.1]
  def up
    add_column :items, :position, :integer

    # 既存のitemにデフォルトの順番番号を入れる
    Item.all.each { |i| i.update_column(:position, i.id) }
  end

  def down
    remove_column :items, :position
  end
end
```

`position`は後から追加したものなので、create_tableする段階で怒られるのは辛い...。

7年前ですが、Stack　overflowにも同じ問題が投稿されていました。が...

https://stackoverflow.com/questions/26079615/nomethoderror-undefined-method-position-for-faq0x00000108195e70

回答は１件しかなく、テーブルをcreateするmigrationファイルでpositionを追加したら？と書いてある。
ローカルならそれでもいいが、本番でそれは辛い。

## 解決！

modelに記述する`acts_as_list`に条件分岐を加えました。

```ruby:app/models/item.rb
class Item < ApplicationRecord
  acts_as_list if has_attribute?(:position)
end
```

参考

- [has_attribute?](https://railsdoc.com/page/has_attribute)メソッド

これでエラーが出なくなりました！

感謝 to @yukabeoka, @Y_uuu 。
開発環境フロントエンド(Flutter Web)からBFFへのCORS Cookie送出でハマった話

# これは何

Flutter Web の画面開発で、ローカルで動作しているフロント画面から 共有の開発環境で動作している BFF(Backend for frontend) サーバへのCookie送出が Cross Domain 制約に引っかかってしまう件の解決策です

Flutter Web での開発で発生した話ですが、本記事の状況は React 含め、Web系のFrontend開発全般で共通する話です。

元々はアクセストークンを localStorage に保管する方式で開発していたのですが、昨今のlocalStorageへのトークン保管是非の議論をうけ、多少ともリスクが減りそうなので Cookie 方式にしよう、というチーム議論の上で Cookie 利用に切り替えた所、見事にハマってしまいました。

## 結論

- CORSでのCookie送出に必要な設定をした上で、
- Cookieの属性を `SameSite=None`、`Secure` とする

（商用環境では `SameSite=Lax` 。開発環境のみこのように設定）

# 何が問題だったのか

ローカルで Frontend が動作し (Flutter Web のローカルサーバ）、BFF は 共有開発環境でドメイン付きで動作しています。

| Frontend(Flutter Web) | BFF Server |
|--|--|
| http://localhost:3000 | https://hoge-api.dev.example.com |

この構成では Frontend から BFF に Cookie が飛ばないことが問題でした。ブラウザは Chrome です

フロントエンドを共有開発環境に反映した場合は以下の構成で動作することになり、FrontendとBFFがCookie的には同一ドメインなので特に問題はありませんでした。

| Frontend(Flutter Web) | BFF Server |
|--|--|
|https://hoge.dev.example.com | https://hoge-api.dev.example.com |

また、BFFをローカルに立てた場合も CORS ではあるが Cookie としては同一ドメインなので問題なし。ただし Secure フラグは立てられないので、環境を判断してサーバで出し分ける必要があります。

| Frontend(Flutter Web) | BFF Server |
|--|--|
| http://localhost:3000 | http://localhost:8082 |

## CORSでのCookie送出に必要な設定

### サーバ側

- 適切なCORSヘッダを返す
  - `access-control-allow-credentials: true` を返す
  - `access-control-allow-origin` には `*` ではなく具体的なサーバのURLを記載
    - この場合は `http://localhost:3000`
  - `access-control-allow-headers` にも `*` ではなく具体的なヘッダを記載
    - ただし `cookie` は書かなくても良いようです
- サーバがセットするCookie には `SameSite=None` 、`Secure` を指定

### クライアント側

- fetch API の場合は `credentials: 'include'` をセット

```
fetch(url, {credentials: 'include'})
```

## ハマったポイント

いろいろと不勉強な点があり、解決に時間がかかってしまいました。
- CORSでいうクロスサイトとCookieのクロスサイトの定義が違う認識がなかった
- CORS元が http で CORS先が https の場合、cookie に Secure をセットすべきかどうか分からなかった
- `SameSite=None` 指定は避けたほうが良いかなというなんとなくの認識

※本件、セキュリティ方面に詳しい方からみると不適切な内容かもしれず、指摘があればぜひお聞きしたいです

## その他ちょっとした整理

| ２つのURLの違い | fetch API/XHR の CORS 対象かどうか | Cookie が共有されるかどうか |
|--|--|--|
| ポートが違う | CORS | 共有される |
| プロトコルが違う(http/https) | CORS | 共有される、ただし Secure属性があると https のみ |
| 同一ドメインでホスト名が違う・サブドメイン | CORS | Domain指定に合致していれば共有される |


# 調査した時参考になったサイト
- [MDN Web Docs CORS 資格情報を含むリクエスト] (https://developer.mozilla.org/ja/docs/Web/HTTP/CORS#%E8%B3%87%E6%A0%BC%E6%83%85%E5%A0%B1%E3%82%92%E5%90%AB%E3%82%80%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88)
- [Qiita @tomoyukilabs さんのCORSまとめ記事](https://qiita.com/tomoyukilabs/items/81698edd5812ff6acb34)
SQLiteのソースコードを読んでみる（０）～準備～

# はじめに（読み飛ばしていいです）

中学生のころ、数学 B の参考書を買った。私がプログラミングというものに興味を持ったのは、間違いなくこの本がきっかけである。その参考書には BASIC についての記載があった。最初見たときはまったく意味が分からなかった。紙面に書かれているソースコードを読んで、頭の中で追えるようになった頃には、プログラミングの虜になっていた。BASIC の構文を一通り学習し終わった私は、次に C 言語に手を染めた。当時読んだ本に「多くの言語は C 言語っぽい構文で書ける」と書いていたからだ。そんな単純な理由で、私は C 言語を吸い始めた。

C 言語を学び始めてから間もなく、疑問に思ったことがある。「ソースコードを実行したら期待通りの動きをするけれど、C 言語のコンパイラってどんな仕組みで動いているんだろう？」インターネットで調べてみると、どうやらコンパイラは「字句解析」や「構文解析」をいい感じに使ってできているらしい、ということが分かった。いろんな web サイトを見ながら、見よう見まねで「電卓プログラム」を作った。「この道のずっと向こう側には C 言語を作った人がいるんだ」という感覚があり、なんだかワクワクしたのを覚えている。

時が経ち、初めて MySQL を使った時のことである。再び私は疑問に思った。「MySQL ってどんな仕組みで動いてるんだろう？」インターネットで調べてみてもそれらしき情報は見つからなかった。より正確に言うと「三層スキーマ」や「レコード」といった概念の説明はわんさか出てくる。しかし、MySQL を作る方法（何を以て「作る」とするのかは議論の余地しかないが）については、ついに見つけることができなかった。

この記事は、言うなればリベンジである。私はあのとき SQL の謎に挑み、そして敗れたのだ。私はあの頃ほとんど何も変わっていない。変わっているとするなら、こんな本筋と全く意味のない文章をつらつらと書き連ねられるようになったことくらいである。

**冗談はこれから言っていくとして、私は今すぐにでも SQLite のソースコードを読みたいのだ！**

# とりあえずソースコードをダウンロード

[SQLite Source Repository](https://sqlite.org/src/doc/trunk/README.md)を見て、最新のソースコードを ZIP ファイル形式でダウンロードした。デスクトップに内容を展開してみると全体のファイルサイズが 100MB くらいあってビビる。
`/VERSION`というファイルに`3.37.2`と書いてある。おそらくこれがバージョンなのだろう。

# 目標とかやりたいこととか

- 当面の目標は「Qiita へ定期的に記事を投稿する」にします。
- そのための口実として SQLite のソースコードを吸っていく予定です。

# 私の能力

私の属性はおおむね以下のとおり。

- C 言語で書かれたソースコードはちょっとだけ読める（仕事では使ったことはない）
- OSS のソースコードを読んだことない
- 英語の知識は中学一年生で止まっている
- ニホンゴヨクワカラナイ

# 迷子

このままだとソースコードの森で迷子になってしまいそうだ。
とりあえず、[次回](https://qiita.com/Aburaiwashi/items/f724c6ff798266c609b2)はどのソースファイルから読めばいいかを考えてみる。

「はじめに」に力を入れすぎたので今回はここまで。
ransackで検索機能を追加する

## Ransackのインストール

```ruby
gem 'ransack'
```

‘bundle install’でインストール完了

## コントローラーに検索機能を追加する

コントローラー内のindexアクションなどに後に記述するviewの検索フォームからリクエストされたパラメータを使った検索機能を作っておく。

```ruby
# 例）ユーザーの名前で検索をかける
def index
  @q = User.ransack(params[:q]) # この部分で検索が行われる
  @users = @q.result
end
```

## view側に検索フォームを追加する

view側には、ransackが提供する```saerch_form_for```というヘルパーを使って検索フォームを追加する。

```ruby
= search_form_for @q, class: 'md-5' do |f|
  .form-group.row
    = f.label :name_cont, '名前', class: 'col-sm-2 col-form-label'
    .col-sm-10
      = f.search_field :name_cont, class: 'form-control'     
  .form-group 
     = f.submit class: 'btn btn-outline-primary'
```

この時、検索フィールドの名前を一定のルールで命名する必要がある。

今回は「名前に〇〇を含む」としたいので```name_cont```とする。```_cont```はransackが提供する検索マッチャー。

## 全検索マッチャー

[https://github.com/activerecord-hackery/ransack/blob/master/lib/ransack/locale/en.yml#L15](https://github.com/activerecord-hackery/ransack/blob/master/lib/ransack/locale/en.yml#L15)
C#でZipファイルの作成を行う

想定環境：Visual Studio 2019

ソリューションエクスプローラーを右クリックし，NuGetパッケージの管理から参照で検索欄に"C1.C1Zip"と検索
インストール

C1.C1Zipをインストールする
```C#
var zip = new C1.C1Zip.C1ZipFile();//C1ZipFileクラスのインスタンス化
string path="";//zipファイルを置きたい場所の指定　例：C:\Users\ユーザ名\Desktop\
zip.create(path+@"\main.zip")//@はエスケープシーケンス 
//main.zip ←好きな名前に変更
zip.password="";//パスワードの指定
zip.Entries.Add(filename)//filenameは圧縮したいファイル　例：テキストファイルやWordファイルなど
```
これで圧縮ファイルの作成が可能！！

# 追記
C#はオブジェクトの型推論？(var)が使えるから，インスタンス化するときにvarを使うとタイピングが短くてすむね
kintone カスタマイズ　レコード作成・編集時の添付数取得

#### 注意点
- DOM操作のためkintone側のアップデートで方法が変わる可能性あり

## 準備
#### 添付フィールドのClass名を取得（Chrome）
1 添付ファイルフィールドの上で右クリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1959394/8b5b93cf-8678-403e-3fd8-a1ff5ecf5a0a.png)
2 検証をクリック 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1959394/4e234ebf-b387-0bbe-7d25-c615964c1c73.png)
3 "control-gaia control-file-field-gaia field-???????"を探す。
 項目ごとの添付ファイル数取得にはこの<b>「field-???????」</b>のクラス名を利用する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1959394/5fd09897-f45d-2fe8-4360-ab8fbaa933b8.png)

## 取得方法
classnameの部分に<b>「.field-???????」</b>を代入してください。
※クラス名なので頭に「.」を付けるのを忘れずに。
#### PC
```javascript:PC
const className = ""//.field-???????
const field = document.querySelector(className);
const count = field.querySelectorAll(".plupload_file_name").length; //添付ファイル数
```
#### モバイル
```javascript:モバイル
const className = ""//.field-???????
const field = document.querySelector(className);
const count = field.querySelectorAll(".forms-file-preview-caption-name-gaia").length; //添付ファイル数
```
Oracle Analytics Cloud：条件付き書式を設定する

# やりたいこと
特定の条件を設定し、それに合致したときにグラフの色を変えたい。
例えば、ある一定の利益を超える商品だけ、ある一定の出荷量を超える月だけ、という条件でグラフの色を変えたい。
というときの設定方法です。

# ベースとなるビジュアライゼーションを作成
Oracle Analytics Cloud（**OAC**)でサンプルデータセット（Sample Order Lines）を使用して、適当に棒グラフを作成してみました。
ここで使用したサンプルデータセットの入手方法は、こちらを参考にしてください。
[Oracle Analytics Cloud：前年の値を計算](https://qiita.com/tyo38/items/71de5c655ce0b17fd5a0)
顧客の住所を元に、顧客数をグラフにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/00364201-8dfe-0ce9-c9fc-800786cfc692.png)

# 条件付き書式を設定
100名以上の顧客が在住する都市のみ、棒グラフの色を変更します。
棒グラフの右上のメニューバーにある「条件付き書式ルールの管理」アイコンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/8aa8dc1c-fa5b-900e-05eb-71efc2cf0d8a.png)
名前を「顧客数」として、メジャーにビジュアライゼーション列の「# of Customers」を選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/5477b1f0-3f1e-8588-a431-e949f5535246.png)
ターゲットに100と入力し、色を任意に指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/870e7147-484e-9d9d-6b42-fb64d83eb541.png)
Scopeを展開し、属性を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/9d7b4da3-5cef-7cbe-4c45-bcdad24ee417.png)
ビジュアライゼーション列の「City」を選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/63778b8d-c5fb-c6b7-1d2f-b5c74a7348ea.png)
設定できたら、「保存」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/0b780513-d344-cf72-28c2-3eed661c9183.png)
できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/79d250f3-a8e9-74ae-25f4-f70ceb27c1a7.png)
では、20名以下の顧客しかいない都市を別の色にしてみます。
もう一度、条件付き書式の画面を表示して、条件の追加「＋」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/7b922bda-9c64-b3c0-db03-c56c0013a495.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/c3fbddc6-de30-6738-8744-903106f8b2eb.png)
棒を値の大きい順にソートしたら完成です！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/22dc92f1-c0f4-238e-50ed-fb5dd6872f98.png)
転職ドラフトで100万円年収UPした話

2022年1月の転職ドラフトを通して正社員転職が決まったので、体験談を書きます。
新しく登録される方はぜひ私の紹介コード「LZWN」を使ってください。
3000～5000円程度のプレゼントをいただけます。

# 転職ドラフトとは
企業から求職者にオファーが届くサービスです。
ビズリーチやGreenなどと同じ仕組みですが、以下の特徴からテンプレオファーは届きにくくなっています。

* 年収が提示される（90%保証）
* 「指名理由」や「任せたいこと」などをしっかり記載する必要がある

オファーをいただいてからは、興味のある会社とコンタクトが取れ、
後は通常の流れとなります（カジュアル面談～面接など）。

# 経歴とスペック
大手SIERで金融業務システム開発から始まり、SESでWebをやったりインフラ現場に行くなどした後
主にモバイルアプリを扱った自社サービスの開発を行っています。
エンジニア経験は10年ほどです。

自社サービスの開発をするまでは、Java中心でSIERな技術しか持っていませんでした。
直近１年間は割とモダンな技術を幅広く扱っていました。
例として以下です。

* ReactNative
* Angular
* Spring boot
* GCP
* Firebase

リーダー／マネジメント経験はそれなりに豊富で、直近もプレイングリーダーとして働いています。
また、GitHubのアウトプットは一応ありますが、サービス公開などはしていない中途半端なものです。
その他のアウトプットは特にありませんでした。

# 転職ドラフト登録まで
転職ドラフトの存在は2年前（前回の転職時）から知っていましたが、その際はオファーをもらえる自信がなく登録していませんでした。
今回の転職でもオファーが全く来ないのではないかとビビっていましたが、
直近モダンな技術を経験したこともあり、自分の可能性を信じて登録することにしました。

# 転職ドラフトでの指名状況
まさかの13社から指名を頂きました。
指名が開始してから数日は何もなく、10日ほど経過した段階で指名が入り、
そこから指名締め切り直前で一気に増えました。

6割くらいが希望年収通り、3割くらいが希望年収＋50万でオファーいただきました。

# 指名理由
概ね以下のような理由でした。

* フルスタックに様々な技術を経験をしていること　← １番多かった
* マネジメント経験
* 厳しい状況で成果を出せていること
* 現場改善例が豊富なこと
* GitHubでのアウトプット

フルスタックエンジニアは器用貧乏の印象もあり、企業としては扱いづらいと思っていましたが、
意外と需要があることが分かりました。
また、GitHubも中途半端なものですが、それでも学習する人という印象は持たせられるので、
ある人は公開させることをお勧めします。

ただ、良くYouTubeなどでポートフォリオ必須などと言われますが、
実態はそうでもないなと思いました。
ポートフォリオを作るより、現場で実績を残す方を優先して
レジュメに実績としてネタを書けることにしておく方が大事と感じました。

# 指名された後
１社のみお会いして、そこにすんなりと決まりました。
年収交渉を考えれば複数企業から内定を取っておいた方が良いと思いますが、
転職活動に工数を使わずに完了させることができました。

１社に絞れたのも年収提示があり、オファー面談前に条件がほぼ分かっていたからで
実際オファーいただいた金額で内定するに至りました。

現年収から100万円プラスの年収となり、満足しています。

# 転職ドラフトを使ったことがない方へのメッセージ
使う前はオファーが来ないのではと不安になっていましが、使ってみて本当に良かったと思っています。
自分の市場価値や客観的な強みを知れますし、転職活動も非常にスムーズに有利に運べるので、
転職を検討されている方はとりあえず登録してみることをお勧めします。

新しく登録される方はぜひ私の紹介コード「LZWN」を使ってください。

＊こちらの記事は[転職ドラフト体験談投稿キャンペーン](https://job-draft.jp/articles/251)に参加しています
MySQLをstristモードへ設定する方法（ファイルの書き換え）

#前提
OSはWindows
サーバーはxampp
DBはMySQL

#結論
xampp -> mysql -> bin フォルダ内にある
「my.ini」ファイルを書き換えれば設定を変更することができる。

#strictモードとは
文字数がオーバーしていたり、カラム指定外のデータ型など、予期せぬデータが挿入されたときにエラーとして扱ってくれるもの。
詳しくはこちらを参照してください。他の設定の内容についても解説してあります。
https://www.wakuwakubank.com/posts/414-mysql-sqlmode/

#方法
こちらのテキストファイルを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2301963/fc3b40cd-7abd-7f00-cdd3-a68b657bc439.png)

その中の「mysql=MODE」の項目を編集する。
STRICT_TRANS_TABLESを追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2301963/3d6376fb-dbfa-3cd4-c810-0536cbdf7a8c.png)

MySQLを一旦stopして再起動させる。
すると設定が変更されている。
Rails CSVファイルのエクスポート

### Rubyの`CSVライブラリ`を使用できるようにする

```config/application.rb
require 'csv'
```

追記後サーバーを再起動

### Userの名前をCSV出力する

アプリを使っている全ユーザーの名前(name),メールアドレス(email),登録日時(created_at)をCSV出力できるようにしたい場合User.rbに次のように記述する。

```models/user.rb
class User << ApplicationRecord
  def self.csv_attributes
    # csvデータに、どの属性をどの順番で出力するのかを定義している。
    ['name', 'email', 'created_at']
  end

  def self.generate_csv
    # 最終的な戻り値がこの下の行のCSV.generateによって生成される文字列。
    CSV.generate(headers: true) do |csv|
      # csvデータのヘッダー情報を入れている
      csv << csv_attributes
      all.each do |user|
        csv << csv_attributes.map{|attr| user.send(attr)}
      end
    end
  end
end
```

### コントローラー内で`generate_csv`を呼び出す
CSV出力したいアクション内で下記を追記すれば全てのユーザー情報をCSVファイルに出力することができます。

```Users_controller.rb
users = User.all

respond_to do |format|
  format.csv { send_data @users.generate_csv, filename: "tasks-#{Time.zone.now.strftime('%Y%m%d%S')}.csv" }
end
```
DOBOT×AI 分類結果が一定確率以下の場合、無視する

以下のテキストでは、AIを用いた画像認識により対象物を分類し、ロボットアームにより仕分けを行っています。
・[DOBOT Magician AIｘ画像認識ｘロボットアーム制御](https://afrel.co.jp/dobot/education-product/)

分類した結果として、最も該当している（それらしい、確率が高い）ラベルが出力されるため、ぎりぎり該当したようなものも学習したいずれかのラベルに分類されてしまいます。そのような状態を回避したい場合、学習データをもっと集めて、より良いモデルを学習させる方法もありますが、今回の記事では、該当している確率が低いものは無視するようにプログラムを修正したいと思います。

# 修正前
```Python:classifer.py
            # 分類する（3-10）
            result = model.predict_classes(image)
            proba  = model.predict_proba(image)
            result_num = int(result[0])
```
修正前は、似ている対象物が異なるラベルとして出力されることがあります。
以下の画像では、左下のパーツは本来「beam_3」が正しいラベルとして学習していますが、「beam_2x4」という別のパーツとして認識しています。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145092/4ad8a368-f0a6-99e3-db55-19879ed7a03f.jpeg" width=70%>

# 修正後
```Python:classifer.py
            # 分類する（3-10）
            result = model.predict_classes(image)
            proba  = model.predict_proba(image)

            proba_check = False
            for p in proba[0]:
                if p >= 0.95: # 確率が95%以上の場合、フラグを立てる
                    proba_check = True

            if proba_check != True: # 95%以上のものがなければcontinueする
                continue

            result_num = int(result[0])
```

分類結果として出力されているそれぞれのラベルである確率を順番に確認し、95%以上のものがなければ以降の処理をスキップするように修正しています。
以下の画像のように95%に満たないものは判別結果として表示されません。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145092/9d6444fe-f295-05bc-c7bc-9be9b21dc0d9.jpeg" width=70%>
DOBOT×AI ネジやボルトを認識して仕分ける

以下のテキストのソースコードは、判別対象を吸引カップで移動させるようになっています。
・[DOBOT Magician AIｘ画像認識ｘロボットアーム制御](https://afrel.co.jp/dobot/education-product/)

対象物が小さい、あるいは細長く、吸引カップでは保持できないことがあります。
そのような場合、DOBOT magicianに付属する空気式グリッパーで掴む必要があります。

以下の記事でグリッパーで掴めるように修正方法を示しました。
・[DOBOT×AI 判別対象をグリッパーで掴む](https://qiita.com/shimamotosan/items/d15dde18889b8dba2204)

また以下の記事で、細長いLEGOパーツを対象物とし、パーツの向きを取得して、掴みやすいようにグリッパーを回転させるようにプログラムを修正しました。
・[DOBOT×AI LEGOパーツを認識して仕分ける](https://qiita.com/shimamotosan/items/98de5729ee260eb8a678)

今回の記事では上記にて修正したプログラムを使用し、対象物をより小さいネジやボルトに変えて、判別して仕分けることが可能かを試してみます。

![dobotxai_neji_01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145092/91b2554d-cdd5-8f04-d0f5-424062c2a5f3.jpeg)


<iframe width="560" height="315" src="https://www.youtube.com/embed/tKpNh4qU2cw" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


対象物が小さい場合、カメラの位置が高すぎると対象物が小さく映るため、判別が難しくなる可能性があります。そのような場合、カメラの位置を調整してください。
AWS SAMでDocker + Lambdaで環境変数が渡せない


なぜか公式ドキュメントでも情報が少ないのでこちらで共有しておきます。

## 困ったこと
Dockerイメージ環境変数を渡したいけどできない!?
ラムダレイヤーなどと同じ扱いで、ビルド済みのコンテナに環境変数は渡せなさそう
(いい方法あったら教えてください。)


## 結論
 **DockerBuildArgs**
を使ってdcoker build 引数に環境変数を追加する

https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-using-build.html#build-container-image

```template.yml
Resource:
  Function:
    Type: AWS::Serverless::Function 
    Properties:
      PackageType: Image
      MemorySize: 512
    Metadata:
      DockerTag: python3.9
      DockerContext: ./function
      Dockerfile: Dockerfile
      # ここ重要
      DockerBuildArgs:
        BUCKET_NAME: my-s3-backet-name
        TABLE_NAME: !Ref TableName
```
そして Dockerfile内で取得する

```Dockerfile
# ARG ブロックで取得
ARG BUCKET_NAME
ARG TABLE_NAME
# 環境変数にわたす
ENV S3_BUCKET_NAME=$BUCKET_NAME
ENV DYNAMO_DB_TABLE_NAME=$TABLE_NAME
```

これでSAMテンプレートで作成したリソース情報を取得できますね。

```app.py
TABLE_NAME = os.environ.get("DYNAMO_DB_TABLE_NAME")
BUCKET_NAME = os.environ.get("S3_BUCKET_NAME")
```

トークンやパスワードなど機密情報をわたす際は	Secrets Manager を使いましょう
Railsのルーティングパターン

自分の覚書として残します（随時更新予定）

#### 環境:
Rails: 6.0.4
Ruby: 3.1.0

## 一般的なルーティング



```ruby
Rails.application.routes.draw do
  resources :blogs
end
```

![スクリーンショット 2022-02-22 7.38.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159704/26f1c550-5f22-1df4-0112-5082e36c1476.png)

## 単数系

```ruby
Rails.application.routes.draw do
  resource :blog
end
```

![スクリーンショット 2022-02-22 7.39.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159704/42f9fdd9-542a-7bc9-654d-0997c64e3423.png)

## 確認画面をはさむ

```ruby
Rails.application.routes.draw do
  resources :blogs do
    collection do
      post 'confirm'
    end
  end
end
```

![スクリーンショット 2022-02-22 7.40.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159704/aa2379a6-b1de-e441-0927-e4784c0c36b5.png)

## 親子関係を表す

```ruby
Rails.application.routes.draw do
  resources :blogs do
    resources :comments
  end
end
```

![スクリーンショット 2022-02-22 7.41.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159704/8a11604c-463f-97fd-b96d-935fc204b8d0.png)

## idを持たないアクション（index/new/create）のみを親のスコープの下で生成する

```ruby
Rails.application.routes.draw do
  resources :blogs do
    resources :comments, shallow: true
  end
end
```

![スクリーンショット 2022-02-22 7.42.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159704/d2bd4ffd-1a98-1e5d-fbdd-d6b6dfd988ff.png)


### ログイン中のユーザーのプロフィールを `/profile` で表示したい場合

```ruby
Rails.application.routes.draw do
  resources :users
  get 'profile', to: 'users#show'
end
```

[参考記事: Railsのルーティング](https://ruby.studio-kingdom.com/rails/guides/routing#resource_routing_the_rails_default)

![スクリーンショット 2022-02-22 7.53.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159704/3bc85eb3-71ac-2dfd-6e74-d2baf7300a6a.png)

### ルーティングに名前をつけたい場合

```rb
get 'exit', to: 'sessions#destroy', as: :logout
```

![スクリーンショット 2022-02-22 8.13.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159704/d7366370-f10c-9c1b-768d-00001e6020e9.png)


### 名前空間を活用する

```rb
Rails.application.routes.draw do
  namespace :admin do
    resources :articles
  end
end
```

![スクリーンショット 2022-02-22 8.20.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159704/51613f1e-27b5-2d69-a4e9-9e6cdee4f423.png)



[参考記事: Railsガイド](https://railsguides.jp/routing.html)
Gitでリモートから特定のパスのみを取得する方法

Git本来の使い方にはそぐわないが、リモートリポジトリの一部のデータのみが必要で、かつ取得したデータを1度しか使わない場面（ビルドプロセスなど）において、このデータ取得を高速に行う方法について調査した。

#### 前提

* [Git Version 2.35.1](https://git-scm.com/docs/git/2.35.1)

#### 要約

shallow (`--depth 1`) + tree less (`--filter=tree:0`) cloneを行った後に、必要なディレクトリをsparse checkoutで取得すればよい。

```shell
URL=https://example.com/repository.git
BRANCH=main
CLONE_DIR=repository
TARGET_DIR="/abc /xyz"

git clone --depth 1 --filter=tree:0 --no-checkout -b ${BRANCH} ${URL} ${CLONE_DIR}
cd ${CLONE_DIR}
git sparse-checkout set --CONE ${TARGET_DIR}
git checkout
```

#### 補足1：shallow cloneとpartial clone

前提としてGitのオブジェクト構造について理解しておく必要がある。詳細は参考資料のドキュメントにわかりやすく解説されているが、今回は下記の図のcommit, tree, blobの関係性が掴めていれば問題ない。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186068/6af22445-72e1-59e5-0522-2c948a4728fd.png" width=350>

参考資料

* [Git - Gitオブジェクト](https://git-scm.com/book/ja/v2/Gitの内側-Gitオブジェクト)
* [コミットはスナップショットであり差分ではない - GitHubブログ](https://github.blog/jp/2021-01-06-commits-are-snapshots-not-diffs/)

[shallow clone](https://git-scm.com/docs/git-clone/2.35.1#Documentation/git-clone.txt---depthltdepthgt)と[partial clone](https://git-scm.com/docs/git-clone/2.35.1#Documentation/git-clone.txt---filterltfilter-specgt)は、Gitリポジトリから一部のオブジェクトのみをクローンする方法となる。shallow cloneは指定した深さまでのcommitに繋がるオブジェクトのみを取得するのに対し、partial cloneはblobのみもしくはtreeのみを取得するものとなる。これらの詳細は[パーシャルクローンとシャロークローンを活用しよう - GitHubブログ](https://github.blog/jp/2021-01-13-get-up-to-speed-with-partial-clone-and-shallow-clone/)にて詳しく説明されている。図で表現すると以下のようになる。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186068/96780f3c-708d-be9c-a164-e051ebbe601d.png" width=1000>

また、partial cloneを1つのブランチのみを対象とすることや、shallow cloneとpartial cloneを組み合わせること（これが要約で使われている一番薄くcloneする方法となる）もできる。なお、shallow cloneの場合はデフォルトで1つのブランチのみが対象（--single-branchが指定された状態）となる。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186068/aca19792-ca3b-cceb-577f-4471a911ec18.png" width=700 />

#### 補足2：sparse checkout

[sparse checkout](https://git-scm.com/docs/git-sparse-checkout/2.35.1#_sparse_checkout)は一部のファイルのみをworking directoryにチェックアウトする方法である。要約のコマンドでは、`--CONE`オプションを指定して、[CONE PATTERN SET](https://git-scm.com/docs/git-sparse-checkout/2.35.1#_cone_pattern_set)形式でチェックアウト対象を設定している。通常の[FULL PATTERN SET](https://git-scm.com/docs/git-sparse-checkout/2.35.1#_full_pattern_set)形式よりもマッチングの効率が良い。

参考

* [Bring your monorepo down to size with sparse-checkout | The GitHub Blog](https://github.blog/2020-01-17-bring-your-monorepo-down-to-size-with-sparse-checkout/)

#### 補足3：git archive

対応しているリモートリポジトリは少ないが、[git archive](https://git-scm.com/docs/git-archive/2.35.1) --remoteを使う方法もある。[path](https://git-scm.com/docs/git-archive/2.35.1#Documentation/git-archive.txt-ltpathgt)オプションを指定することで取得対象を限定できる。
CCNA勉強　Section16 QoS

#優先順位の付け方
1.CoS(Class of Service)
VLAN識別のためのIEEE802.1Qフレーム
タグ4byteの中にPCP(Priority Code Point)が3bit用意されている
0〜7

2.DSCP(Differentiated Services Code Point)
パケットヘッダ内のToS(Type of Service)フィールドを使用
8bit中3bitで優先度、3bitで破棄されやすさを設定
PHB(Per Hop Behavior)

AF(上3ビットで優先度1-4、下3ビットで破棄されやすさ1-3)
下は実質2ビットまでしか使わない
ビデオ会議は41

EF
最優先。音声はこれ。46

#輻輳制御
ポリシング
受信側に設定。CIRを超えたトラフィックを破棄したり優先度変えたり
シェービング
CIR超える場合にキューに格納

#キューイングの種類
分類・マーキング→キューイング→スケジューリング→ハードウェアキューの順。

FIFO(First In First Out) 
PQ(Priority Queing)
WFQ(Weighted Fair Queing)　カスタマイズ利かないのが難点
Class-Based WFQ 全キューを順番に確認して、指定された割合で取り出してハードウェアキューに。そこからは順番に送り出される。
LLQ(Low Latency Queing)　PQだけ最優先。あとは指定された割合で取り出す。

#輻輳回避
キューの中身がいっぱいになったときの話

テールドロップ:　いっぱいになったらそれ以降のパケットは破棄。TCPだと再送処理が行われるため不安定になる。できれば起こしたくない。
RED(Random Early Detection):キューがいっぱいになる前にランダムに破棄していく。
WRED(Weighted Random Early Detection):破棄するパケットに優先度をつける。
stop-processコマンドがプロセスが止まっていた原因だった話

Windows環境でクロームが重いのでPowerShellで時々

```
ps -Name *chrome* | stop-process
```
をよくやる。そしてPythonでも

```
os.system('powershell -Command "ps -Name *chrome* | stop-process"') 
```
や

```
subprocess.Popen('powershell -Command "ps -Name *chrome* | stop-process"') 
```

を使っていた。
ところがある日、自動処理が止まっていることを発見。
原因がこのコマンドであることにやっと気付いた。ハマった状況の蓋を開けてみると

```
次の項目に対して Stop-Process 操作を実行しますか
```
という確認が出て応答待ち、ペンディング状態だったのだ。

-Forceをつけたコマンドなら待たない。

```
powershell -Command "ps -Name *chrome* | stop-process -Force"
```
解決した。
ただ、本当に強制終了したくないプロセスがある場合は気をつけて。
STM32L010でナイトライダー (Keil)(STM32L010F4P6)


x Mbed2

目的
8LEDを順次点灯するプログラム

いろいろ
ほぼ3分クッキング


![o_con243.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/5dad7a95-39b9-2034-36ed-4c72ba0c7277.jpeg)


![o_con244.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/6418f80b-7d15-74a1-7855-bcb178f3516c.jpeg)


![o_con245.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/613f4481-0806-149a-298f-f4c3e3552f07.jpeg)


![o_con246.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/8c4f0600-fc01-6778-24a3-824cf4d1768c.jpeg)


![o_con247.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/b2d9e66e-39c1-50fe-674d-a09782a9c30d.jpeg)


-248


![o_con248.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/2fdbe7d0-8262-6d32-c5ab-1bfc47d29114.jpeg)




```c++


//IO_Knight_Rider_010_1

#include "mbed.h"

//GPIOの初期化
DigitalOut myled(PB_1); //D7

//GPIOポートの初期化
//                       76543210
PortOut ledport(PortA, 0b11111110); //D0 - D6

//シフトの軽量高速化の為
//              12345678   12345678   12345678   12345678
char b8[8] = {0b10000000,0b01000000,0b00100000,0b00010000,
              0b00001000,0b00000100,0b00000010,0b00000001
             };

//メイン関数
int main()
{

    char buf[10]; //バッファー

    //無限ループ
    while(1) {

        //0から7までループ
        for(int ii=0; ii<8; ii++) {

            buf[0] = b8[ii];//バッファーのクリア

            ledport = buf[0]<<1; //1シフト後に代入

            myled =( ((buf[0] & 0x80) == 0)  ? 0 : 1 ); //D7を代入

            wait_ms(1000); //1秒待つ

        }//for

    }//while

}//main



```
2022/2/22主にITとかセキュリティの記事

政府、「企業のプライバシーガバナンスガイドブック」を改訂
https://www.security-next.com/134288

金融庁、サイバーセキュリティ強化取組方針を改訂
https://www.security-next.com/134293

約8割がスマホアプリ開発時などにセキュ対策 - 「自信ない」との声も
https://www.security-next.com/134290

インスタアカウントが乗っ取り被害 - 新潟食料農業大
https://www.security-next.com/134257

件名「Yahoo! JAPAN IDを制限いたしました」のメール、Yahoo! Japanをかたるフィッシングに注意
偽サイトに誘導して個人情報などを詐取(2/18)
https://internet.watch.impress.co.jp/docs/news/1389599.html

広島県にサイバー攻撃
丸２日以上継続、目的不明(2/18)
https://www.hokkoku.co.jp/articles/-/664094

【コラム】すべての情報封鎖は、オリンピックのためにー中国(2/20)
https://news.nicovideo.jp/watch/nw10555671

企業の個人情報漏洩　いくらで許す？　消費者「5000円相当」　おわびの品の実態は…(2/20)
https://www.kobe-np.co.jp/rentoku/omoshiro/202202/sp/0015079658.shtml

Yahoo! JAPANがヨーロッパで使えなくなる？　モバプリの知っ得［166］(2/20)
https://ryukyushimpo.jp/style/article/entry-1472249.html

医療データ開国迫る巨大IT　健康管理や創薬に変革の波(2/20)
https://www.nikkei.com/article/DGXZQOUC082GN0Y2A200C2000000/

Amazonのほしい物リストから電話番号が漏洩か(2/19)
https://www.zaikei.co.jp/article/20220219/661084.html

広島県に16日からサイバー攻撃 県ホームページ閲覧に影響(2/18)
https://www3.nhk.or.jp/news/html/20220218/k10013491571000.html

実は家庭にも必要な「VPN」そのメリットを知ろう(2/18)
https://ascii.jp/elem/000/004/083/4083260/

スマホのオンライン契約に向いている人、向いていない人(2/20)
https://www.itmedia.co.jp/mobile/spv/2202/14/news031.html

シスコ製品のパスワードタイプ選択のベストプラクティス公開、米NSA(2/19)
https://news.mynavi.jp/techplus/article/20220219-2275592/

アプリのように動くスマホ向けWebサイトを制作できる、「PWA」とは(2/21)
https://xtech.nikkei.com/atcl/nxt/column/18/01679/011100034/
相互参照(双方向参照)なデータをきれいに設計する方法

**深夜テンションで書いてます。**
**記事はポエムのような内容です。**

プログラミングの上で、データの構造が複雑なことになることは多々あります。
その一つが相互参照が必要なデータ構造です。
きれいな設計にすることは難しいですが、少しの工夫で問題を簡単にできます。
#相互参照のデータ構造とは
ここでは相互参照のあるデータ構造とは以下のように定義します。

 + DictionaryまたはMapに格納されるデータがKey/Valueの2つの組であり、Key=>Value,Value=>Keyのどちらでも検索する可能性がある。
 + Key/Valueの双方がもう一方を引数として使うメソッドを持つ。

この状況では2つのクラスの結合は密です。
いかにして切り離すのが良いのでしょうか。
# トップダウン設計で書く

最上位の利用層から考えて、トップダウンでモックを作りながら書く方法です。
2つのデータを管理するクラスを作り、そのクラスに全てを任せます。
この状況では、Key/Valueのそれぞれのクラスは互いを知らずに済みます。
やり取りが必要な場合でも、プリミティブ型や双方に関係がある任意のクラスXと関連だけで書きます。

2つのクラスを管理するクラスは複雑になりますが、どこかで複雑度が発生するのは避けられません。
細かなオブジェクト同士の相互作用で記述するボトムアップ型の設計は、2つのクラスが包含の関係であるならうまくいきます。
(上記の例であれば、Value.Keyの形でデータが含まれるような状況)
#解決手段
## 任意のインターフェースにまとめる
上位クラスが必要な情報をまとめたインターフェースクラスを作っておくと、複雑度が抑えられます。
これはKey/Valueを管理する何らかのManager的クラスが参照するデータ範囲を限定するためです。
後で追加データが必要になれば、インターフェースを少し拡張しましょう。

ただし、インターフェース同士が相互参照するのは複雑な問題を起こします。
こういう設計をやると、あとでドメイン欠乏症が起こるリスクがあります。

## やり取りを関数オブジェクトの奥に押し込む
関数オブジェクトをやり取りする形にすれば、複雑な処理も引数と戻り値だけの問題に落ちます。
関数オブジェクトは1つのメソッドだけを持つインターフェースだと言えます。

関数オブジェクトを使う場合は副作用のない関数で引数・戻り値だけで処理することを徹底しましょう。
副作用を使うようになると、問題が起きた場所を探すのに大変苦労します。
この苦労のため、2回ほど試作品のプログラムを破棄しており、痛い目を見ています。

## Templateの力を使う

VScode+JavaScriptの環境では、JSdocのアノテーションでテンプレートを利用したジェネリックプログラミングが可能です。
今回、描画関連の処理はtemplateを多用することで、きれいに解決できました。
JSdocではクラスや関数の上に@templateでアノテーションを付けることで、テンプレート化できます。
詳細の説明は省きますが、使ってみると便利です。

#終わりに
今回のケースはRPGツクールMV用にモンスター図鑑プラグインを作る際に生じた問題の備忘録として記載しています。
関数オブジェクトのやり取りだけで解決できたのは、描画・検索関連の処理を別のプログラムに押し込んでライブラリ化したためです。
リレーショナルデータベースの再発明のようなものを作ったため、描画関連の処理を意識せずに書くことができました。
このプラグインは後日公開予定です。
C++ 標準入出力 メモ

競技プログラミングなどの問題解くときに必要になる基本的なコードのメモ。


# 標準入力読み取り　行毎

```c++
    using namespace std;

    string l;
    while (getline(cin,l)) {
        // ２行目以降の処理
    }
```

# スペース区切りstring 数値変換

```c++
#include <iostream>
#include <string>
#include <sstream> // istringstream

using namespace std;
int main(void){

string l("123 678");
int a1(0),a2(0);
istringstream iss = istringstream(l);
iss >> a1 >> a2;
cout << a1 << endl;
cout << a2 << endl;
}
```

#　文字列→数値 (stoi)

```c++
#include <iostream>
#include <string>
using namespace std;

auto i = std::stoi("123");
cout << i << endl;
```
Apache + Laravelで.htaccessを弄ってもAccess-Control-Allow-Originが変わらない問題を解決

初めましての方は初めまして。けこです。

この度ちょっとしたAPIサーバを立てる運びになりまして、その際にAccess-Control-Allow-Originの設定を"*"にすることはできません。という内容のエラーに苦しめられましたので、知見を共有させていただきます。（注意：Laravel初学者です）

### 構成等
フロントエンドVue.js、バックエンドLaravel+MySQLという構成です。
フロントエンドはexample.jp、バックエンドはxxx.example.jpというドメインを取っていました。よくあるSPAってやつです。

今回苦戦したのはフロントからバックエンドのAPIサーバ（Laravel）からデータを取るリクエストをする際のAccess-Control-Allow-Origin設定です。

### どんな問題が発生したか？

ドメイン名が完全一致ではない、つまりsame-originではないのでCORS通信の設定が必要です。
今回発生したのはいくら.htaccessを弄ってもAccess-Control-Allow-Originが反映されないという問題です。

もちろん、httpd.confの.htaccessの許可は出しています。

.htaccessはLaravelプロジェクトのpublicフォルダにあるので、

```
Access-Control-Allow-Origin: "*"
```
の記述があるか確認……ない。

```
Access-Control-Allow-Origin: "xxx.example.jp"
```

を追記。httpdを再スタート。……また"*"はダメというエラー、なんで？とドツボにハマりました。

### 解決法

今回の問題はCORSというLaravelパッケージにありました。
LaravelのCORS通信をサポートする便利なパッケージなのですが、どうもこのパッケージがAccess-Control-Allow-Origin設定を変更していたのが問題でした。

config/cors.phpを開くと以下のような文がありました。

```
'allowed_origins' => ['*']
```

このallowed_originsという項目がAccess-Control-Allow-Originの設定になります。この設定を以下のように変えてやると無事繋がるようになりました。

```
'allowed_origins' => ['https://xxx.example.jp']
```

ここかーーーー！ってなりました！

### 終わり
めっちゃありがちなミスだと思いますが4時間ぐらい悩んだので私と同じLaravel初学者の方は参考にしてみてください！
私もまだまだ精進が必要だと思いました……、CORSには他にも色々設定があるので興味があれば調べてみてくださいね！

ご拝読いただきありがとうございました！
テトリスを題材にpythonを学べるツールを作成してみた話

### 目次
- 自己紹介
- 取り組み背景
- 取り組み内容
- 動かしてみた様子
- 今後の課題

---

### 自己紹介
・ハンドルネーム: @seigot
・関西在住の社会人
・python歴：3年〜ほど
・Qiita: https://qiita.com/seigot

・今回: [Qiita記事 テトリスを題材にpythonを学べるツールを作成してみた話](https://qiita.com/seigot/items/0b42a807217dbe636226)

---
### 取り組み背景
・本業でpythonを使用する機会がない人からするとなかなか学ぶきっかけがない。
・文法を学ぶだけでは使用イメージが湧かず挫折しがちである
・しかし、アプリ開発や競プロ等をいきなり始めるのはハードルが高いと感じる

・このようなツイートに刺激を受けた
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">PyTorchの深層強化学習チュートリアルで、AIにマリオの動きを学習させてプレイしてみた。結構賢いな <a href="https://t.co/4EIGK4RnrX">pic.twitter.com/4EIGK4RnrX</a></p>&mdash; からあげ (@karaage0703) <a href="https://twitter.com/karaage0703/status/1341392530030669831?ref_src=twsrc%5Etfw">December 22, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

---

### テトリスを題材にpythonを学ぶ試み
・[How to write Tetris in Python](https://levelup.gitconnected.com/writing-tetris-in-python-2a16bddb5318)や[Tetris in PyQt5](https://zetcode.com/gui/pyqt5/tetris/)などを参考に、テトリスの本体やブロックを動かす部分を含めて実装

<img width="100" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344880/c4787dc9-2ba7-292e-d1e1-22bed3fe14b9.png">

・難易度を３段階ほど用意（次ブロックの出現順序、初期おじゃまブロック配置）
・180秒のスコアアタックができるようにルール化
・ブロックを動かす時の置き方をプログラミングできるようにしてみた
テトリスを動かすことでpythonが楽しく自然に身につく、、といいな（希望）

---

### 動かしてみた様子
・サンプルコードも実装
・とにかく列を揃える、できるだけ平らに置くなどの判断を簡易実装
・まだ初心者レベル

<blockquote class="twitter-tweet"><p lang="in" dir="ltr">Tetris <a href="https://t.co/mfCBQbkMO3">pic.twitter.com/mfCBQbkMO3</a></p>&mdash; st (@st17890027) <a href="https://twitter.com/st17890027/status/1544635088113397760?ref_src=twsrc%5Etfw">July 6, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

---
### まとめ
・テトリスを題材にpythonを学べるツールを作成してみた
・ものが動くと面白い
### 今後の課題
・より強いテトリス制御プログラムを作ってみたい
・機械学習要素を実装してみたい
・（可能な範囲で）対戦会ができればやってみたい。

---

以上

---


（追記）
ソースコードは以下です！
https://github.com/seigot/tetris
誕生日が2月22日なので2022年2月22日2時22分22秒にログ出力してみた

2月22日が誕生日の僕にとって**2022年2月22日 2時22分22秒**はなんとなく特別に思える。
せっかくなんでログ出力して記念にとっておく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643372/56ae7c5e-a091-5316-8f04-b79b2f876046.png)
エンジニアなのでコードも載せておく。
```.swift
import UIKit

let date = Date(timeIntervalSince1970: 1645464142)
let formatter = DateFormatter()

formatter.timeZone = TimeZone(identifier:  "Asia/Tokyo")
formatter.dateFormat = "yyyy年M月d日 H時m分s秒"
let stringDate = formatter.string(from: date)

print(stringDate)
```

2時22分22秒まで待とうかと思ったけど眠いのでEpochTimeで出力（笑）

次にこれだけ2が揃うのは100年後の2月22日か〜
200年後の2月22日はプレミアですね。

ちなみに僕の誕生日のEpochTimeはこれ。
```
824923342
```

なんとなくエモい感じになった誕生日でした。
26歳も頑張るぞ！
【スクラム】プロダクトバックログの書き方

# 概要
アジャイル開発におけるスクラムのプロダクトバックログの作成方法についてまとめてみた。

# プロダクトバックログとは？
- 機能や要求、要望、バグ修正など、プロダクトに必要なものを抽出し、順番に並び替えたリスト
- 一つのプロダクトにつき、１つと決められている
- 順番はその項目が実現された時に得られる価値やリスク、必要性に応じて決められる
- それぞれの項目は一意の順番を持ち上位のものから作っていく


# プロダクトバックログの形式
## テンプレート

|ユーザストーリ|デモ手順|見積もり|
|----|----|----|
|[Who(ユーザー・顧客)] として、[What(達成したいゴール)] をしたい。なぜなら[Why(理由) ] だから。| クライアント視点でどうのように手順で利用されるのかを書く | 相対的なタスク量(フィナボッチ数) |

- ユーザストーリ
    - この機能はなにか背景と意図が伝わるように書くこと
    - 1番大事なのは、Whyの部分
        - クライアント側の意図がわかれば、よりよくものを実現してあげる時に役立つ
        - 例えば、「移動中に素早く見れるようにするためだ」とあれば、モバイルで見ることが多そうなので、モバイルベースで文字を大きくしようや、素早くなので、複雑はパス構成は避けようなどの議論が生まれる
    - ここで気をつけるべきポイントは、How(方法)を書かないこと
        - Howについては、ユーザーストーリーを実現するためのタスクを開発者がスクラムチームに対して検討・整理する際に議論すべきことだから
- デモ手順
    - クライアント目線での手順を記載する
    - スプリントレビューにおいてもこの操作を見せればよくなる
    - 正解の定義にもなる
- 見積もり
    - 具体的な時間ではなくて、作業量を相対的に出す
    - フィナボッチ数で大まかに素早く見積もりを決めることができる
    - 開発者が決めるので、後々で大丈夫

- **誰でも理解できる言葉を用いて記載する(＝専門用語を利用しない)ことを意識することもここでは重要なポイント**
## 例

|ストーリー|デモ手順|見積もり|
|---|---|---|
|動画の再生速度を変更したい。視聴者が自由に再生速度を早めることで、時間がないユーザにも動画を素早くみてもらうことができる。また、再生速度を遅くすることで、母国語ではない映像をゆっくり視聴できる。|	プレイヤー内の再生速度変更のボタンを押すと再生速度一覧が表示されて、選択すると値に応じて再生速度が変更される。|3|

# プロダクトバックログを書くにあたって
- 今は必要ないこと、リリースに間に合わないかもしれないといった先入観を捨てて、なんでも追加する
    - とりあえず多くの量を書く
    - アイデアを書き出す
- ユーザストーリ、デモ手順だけでは機能は作れないため、実際は話し合って要件を細かく落とし込む必要がある
    - 話し合う機会を生む
    - スプリントプランニングの時に落とし込んだりして、詳細を明確にしていく

# プロダクトバックログの項目の順番を決める
- スクラムチームで決める
    - 自分達が大丈夫だと思える順番にすることで開発に自信をつける
- 超重要、重要、普通、あれば嬉しい、の４ジャンルに分類し、並び替える
    - 超重要は、なければ業務が止まってしまうタスクやサービスの目玉
    - 優先順位を決めることから始めてもOK
- 一列に並べる
- 並べ終えたら、開発初めにすぐ着手するであろう項目はもう一度順番の確認

# 見積もりの算出
- 見積もりは実際に作業する人(開発者)が決める
- 1,2,3,5,8,13,21...のフィナボッチ数で決定する
    - フィナボッチ数を利用することで正確に見積もりを求める必要がなくなるため素早く見積もれる
    - 基準のタスクがは3だとして仮に21などがあれば、不確実なことが多く実装が見えていないため、21になるってことになるため、見直す必要があるねって言う話になる
- 基準となる作業を決めて基準を3か5とする
    - 簡単すぎても大変すぎてもダメ
    - 少し大変そうで、作業の手順ややり方が想像つくものを選ぶ
- プロダクトバックログの他項目は、基準をもとにどれくらいかで決める
    - 各人理由も簡単に述べるとよい
- あくまで推測なのでこれを決めるのに時間をかけすぎない！
  


# 補足
- プロダクトバックログは作って終わりではなくて、常に更新するようにし、チーム全体が把握していることが大事
- あくまでも予測なのであまり時間を書けないようにする
塊を生成するVueコンポーネント

[Blobsアプリ](https://blobs.app/)で生成される塊をVue3コンポーネントとして使えるようにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515818/a872b520-866c-a50b-c520-45dcb07f81e8.png)

---
# Vueバージョン
+ Vue3

# インストール
npmで[塊生成パッケージ](https://github.com/lokesh-coder/blobshape)をインストールします。
`npm i blobshape`

# コード
```html
<div>
    <i-blobs :size="6"></i-blobs>
</div>
```
+ 色を付ける場合はcssのcolorプロパティで指定してください。
+ 幅と高さはi-blobsの親要素に従います。
+ sizeは指定しなくても良いです(任意プロパティ)

---

```html
<template>
    <svg :viewBox="`0 0 ${size} ${size}`">
        <path :d="makePath()" />
    </svg>
</template>
<script>
import { defineComponent,toRefs } from 'vue'
import blobshape from "blobshape";
export default defineComponent({
    name:"i-blobs",
    props:{
        size:{
            type:Number,
            default:100
        },
        growth:{
            type:Number,
            default:6
        },
        edges:{
            type:Number,
            default:6
        }
    },
    setup(props) {
        const {size,growth,edges} = toRefs(props);
        return{
            makePath(){
                const {path} = blobshape({size:size.value,growth:growth.value,edges:edges.value});
                return path
            }
        }
    },
})
</script>
<style scoped>
svg{
    fill:currentColor;
    height: inherit;
    width: inherit;
    max-height: inherit;
    max-width: inherit;
}
</style>
```

### コード説明
 コンポーネントで指定したsizeをblobshape生成関数とviewBoxに渡します。blobshapeリポジトリのサンプルコードではviewBoxを特に指定していませんが、指定しないと描画外に塊が生成されることがあります。
svgのスタイルはscopedを指定することでi-blobsコンポーネント内だけに限定し、fillプロパティをcurrentColorにすることでcolorプロパティの色で塗られるようにしています。