OmniAICreator/Qiita-1.07M huggingface dataset:
Chakra UIで複数フォントのスタイルを設定する

# 概要
Chakra UIで、複数フォントを扱う方法を整理します。

Chakraの[公式のフォント解説](https://chakra-ui.com/guides/recipes/using-fonts)に、複数のフォントスタイルを指定する方法が見当たらなかったため、記事を書こうと思いました(見逃していたらすみません)。

参考にしたページは[こちら](https://stackoverflow.com/questions/65886321/cant-change-default-fonts-in-chakra-ui)になります。
※基本的にはCSSと同じ考え方という認識。

# 環境

```shell
$ node -v
v16.0.0

$ npm -v 
7.10.0
```
package.json

```json
"@chakra-ui/react": "^1.7.3",
```
# 結果
見た目で反映されていることのわかりやすさ重視で、筆記体フォント、ヒラギノ角ゴ ProNの優先度で表示する。
※注 フォント以外のCSSは、create-react-appデフォルトのスタイルが適用されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1424230/3f5948ae-109d-6e2c-5d68-b50f7e66656a.png)

# 実装

テーマファイル(theme.ts)

```typescript
import { extendTheme } from "@chakra-ui/react";

const theme = extendTheme({
    fonts: {
        heading: `cursive,"Hiragino Kaku Gothic ProN"`,
        body: `cursive,"Hiragino Kaku Gothic ProN"`,
    },
})

export default theme
```

## 呼び出し元

index.tsx

```typescript
ReactDOM.render(
  <React.StrictMode>
    <ChakraProvider theme={theme}>
      <App />
    </ChakraProvider>
  </React.StrictMode>,
  document.getElementById('root')
);
```

App.tsx

```typescript
function App() {
  return (
    <div className="App">
      <header className="App-header">
        <Text>ナルト(NARUTO)とサスケ(SASUKE)</Text>
      </header>
    </div>
  );
}
```

# 感想

まだ歴史が浅いせいか、Chakraのドキュメントはバリエーションに乏しい気がします。
フォントはデザインの印象に大きく左右するので、なるべくデザイナさんの意図通り、今後も引き出しを増やしていきたい所存です。
Type of the default value for '〇〇' prop must be a function

## 問題
Nuxt.js 2.15.8
以下のエラーが出た

```:.vue
  props: {
    note: {
      type: Object,
      default: "",
    },
  },
```

```:.vue
Type of the default value for '〇〇' prop must be a function
```

## 解決方法
defaultの部分を修正する

```:.vue
  props: {
    note: {
      type: Object,
      default: () => {},
    },
  },
```
アプリ設定の「ストレージを消去」の代わりに、アプリの「容量の管理」画面を起動させる方法

Androidのアプリ設定では、アプリのストレージを消去し、ほぼインストール直後の状態に戻すことができますが、このボタンを「容量の管理」に変更し、アプリを起動させることができます。

|ストレージを消去|容量を管理|
|:-:|:-:|
|![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155171/0276fcf9-1760-7728-c2e1-e8fc376e035f.png)|![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155171/36d828cb-f1cb-1dda-8400-e6725c28b016.png)|

これを実現するのは非常に簡単で、AndroidManifest.xmlの`application`タグに`android:manageSpaceActivity`というattributeでActivity名を記述するだけです。
これだけで「ストレージを消去」が「容量の管理」になり、ここに記述したActivityが起動されるようになります。

```xml:AndroidManifest.xml
    <application
        ...
        android:manageSpaceActivity=".ManageSpaceActivity"
        ...
        >
```

アプリ内で、システム設定アプリから「ストレージを消去」した場合と同じ動作をさせるには
`ActivityManager.clearApplicationUserData()`をコールします。これでアプリは終了し、ストレージが消去されます。

```kotlin
findViewById<View>(R.id.button_clear).setOnClickListener {
    getSystemService<ActivityManager>()?.clearApplicationUserData()
}
```

この容量の管理画面では、全消去ではなく、部分的にデータをクリアする機能を提供し、同時に「ストレージを消去」と同様に全消去の機能も提供するのがお行儀が良いでしょう。
様々なデータを扱うアプリの場合、ストレージが逼迫してきたので消去しなければならないが、アカウント情報など重要度の高い情報は残しつつ、再ダウンロードなどすればよいデータだけ削除したいという要望をかなえることができますね。

以上です。
findコマンドのエラーメッセージをgrep -vで除外したいのに出来なかった時の話

#結論、標準出力(stdout)と標準エラー出力(stderr)は違うからね！
あるファイルを探したくて、次のようなコマンドラインを打ったところ、`Operation not permitted`がたくさん！

```zsh:/bin/zsh
$ find . -iname filename     <- -inameは大文字小文字区別しないオプション
find: ./Library/Application Support/MobileSync: Operation not permitted
find: ./Library/Application Support/CallHistoryTransactions: Operation not permitted
find: ./Library/Application Support/CloudDocs/session/db: Operation not permitted
find: ./Library/Application Support/com.apple.sharedfilelist: Operation not permitted
find: ./Library/Application Support/Knowledge: Operation not permitted
find: ./Library/Application Support/com.apple.TCC: Operation not permitted
...
./Downloads/filename.    <- 目的のファイル！
```
Operation not permittedがダダーっと！見づらい。。。
そうだ、grep -v で除外すればいいんだ！（-v は後に続く文字列を除外するオプション）
(いや、待て、もっとシンプルな方法があるだろ。。。（後で気づく））

```zsh:/bin/zsh
$ find . -iname filename | grep -v "not permitted"
find: ./Library/Application Support/MobileSync: Operation not permitted
find: ./Library/Application Support/CallHistoryTransactions: Operation not permitted
find: ./Library/Application Support/CloudDocs/session/db: Operation not permitted
find: ./Library/Application Support/com.apple.sharedfilelist: Operation not permitted
find: ./Library/Application Support/Knowledge: Operation not permitted
find: ./Library/Application Support/com.apple.TCC: Operation not permitted
...
./Downloads/filename.    <- 目的のファイル！
```

あれ？ `Operation not permitted`を含む行が除外されない！なんで？？？

ググるとやっぱり同じような思いの人が見つかります。
[How can I exclude all "permission denied" messages from "find"?](https://stackoverflow.com/questions/762348/how-can-i-exclude-all-permission-denied-messages-from-find)

上記stack overflowのスレッド参考にすると、以下のようにすれば良いとのこと。
`find . -iname filename 2>&1 | grep -v "not permitted"`

2は標準エラー出力(stderr)。
1は標準出力(stdout)。※ &はリダイレクトの文脈（>のあと）においてファイル名ではなくファイルディスクリプタであること意味する。
つまり標準エラー出力を標準出力にリダイレクトしてるんですね。
パイプが渡すのは標準出力の方だけということが分かりました。

あーこれで解決！

...

**ってもっとシンプルな方法あるやんけ。**
`find . -iname filename 2>/dev/null`

でもエラーメッセージ全部除外するんじゃなくて一部のみ除外って時はstderrをstdoutへリダイレクトするのが役立つね！ってことで勉強になりました。
dnsmasqでサクッとDNSサーバ構築

CentOSに構築していきます。

```bash
$ cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)
```

まずはdnsmasqのインストール


```bash
$ yum -y install dnsmasq
...

```

次にdnsmasqの設定ファイル。主要な項目だけ書き出してみました。


```conf:/etc/dnsmasq.conf
# DNSのポートを指定。何もしなければ53が使われる。
# port=5353

# デフォルトの/etc/hostsを参照したくないのであれば記述
no-hosts

# DHCP機能を使わない場合
no-dhcp-interface=eth0

# hostsとして参照させたいファイルを指定
addn-hosts=/etc/hosts-dnsmasq

# ドメイン名を自動的にhostsに付与するか
expand-hosts

# DNSSECバリデーションを有効化
dnssec

# ログの出力先
log-facility=/var/log/dnsmasq/dnsmasq.log

# DNSクエリのログを取る
log-queries

# ローカルドメイン名
domain=thekelleys.org.uk

# このようにサブネット指定で複数のローカルドメインを指定することも可能
domain=wireless.thekelleys.org.uk,192.168.2.0/24

# 上位サーバへ問い合わせる際は、ドメイン名が必須
domain-needed

# 上位サーバに対して、プライベートIPアドレスの逆引き要求をしない
bogus-priv

# 上位DNSの設定ファイル。
resolv-file=/etc/dnsmasq_resolv.conf
```

hostsファイルを作成。IPは名前解決したいものを指定。今回は適当に。

```txt:/etc/hosts-dnsmasq
192.168.1.200 test-dns
```

次に、上位DNSの指定を書いたファイルを作成する。

```/etc/dnsmasq_resolv.conf
nameserver 8.8.8.8
```

## dnsmasqの開始

```bash
$ systemctl start dnsmasq
$ systemctl enable dnsmasq
Created symlink from /etc/systemd/system/multi-user.target.wants/dnsmasq.service to /usr/lib/systemd/system/dnsmasq
.service.
```

`firewalld` でdnsmasqのデフォルトポート(53)をオープンする。

```bash
firewall-cmd --add-service=dns --zone=public --permanent
firewall-cmd --reload
```

## 名前解決を確認

digを使うためbind-utilsをインストール

```bash
$ sudo yum -y install bind-utils
```

名前解決を行うDNSサーバを自分自身(localhost)に指定しつつ、先程設定したドメインに対して名前解決リクエストを行う。

```bash
$ dig @localhost test-dns
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.8 <<>> @localhost dns
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12024
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;dns.                           IN      A
;; ANSWER SECTION:
dns.                    0       IN      A       192.168.1.200
;; Query time: 1 msec
;; SERVER: ::1#53(::1)
;; WHEN: Fri Dec 17 15:13:36 UTC 2021
;; MSG SIZE  rcvd: 48
```

すると、Aレコードにhosts(etc/hosts-dnsmasq)ファイルで指定した192.168.1.200が表示されているのが確認できました。

これで、dnsmasqを設定したサーバのIPを他のネットワークからDNSサーバとして参照すれば、hostsに指定したIPに対して名前解決してくれるはずです。
APIもScrapyでアクセスできるんですよ

# Scrapyを使う
WebスクレイピングのフレームワークであるPythonのScrapyはAPIのアクセスにも使用できます。

やってみましょう。

# やってみる！
とりあえずアクセストークンを取得しないと話が始まらないので取得します。
それから、Scrapyをインストールして、雛形を作成します。

```bash
python3 -m venv .venv
source .venv/bin/activate
pip install scrapy
scrapy startproject freee_scrapy
cd freee_scrapy/
scrapy genspider scrapy_freee_api_spider api.freee.co.jp
```

そしたら、あとはSpiderのコードを書くだけです。
今回は、お触りだけなので「事業所一覧の取得」をやってみます。

```python:scrapy_freee_api_spider.py
import scrapy
from scrapy.http import JsonRequest
import json

class ScrapyFreeeApiSpiderSpider(scrapy.Spider):
    name = 'scrapy_freee_api_spider'
    allowed_domains = ['api.freee.co.jp']

    def start_requests(self):
        base_url = "https://api.freee.co.jp/api/1/companies"
        request_headers  = {
            "Authorization" : "Bearer アクセストークン",
            "X-Api-Version" : "2020-06-15"
            }

        yield JsonRequest(url=base_url, headers=request_headers, callback=self.parse)

    def parse(self, response):
        jsonresponse = json.loads(response.text)
        self.logger.info(jsonresponse)
```
※settings.pyでROBOTSTXT_OBEYをコメントアウトしてください。

```python:settings.py
# ROBOTSTXT_OBEY = True
```

実行します。

`scrapy crawl scrapy_freee_api_spider`

事業所一覧が取れました。

```
2021-12-17 23:55:50 [scrapy_freee_api_spider] INFO: {'companies': [{'id': ******, 'name': '', 'name_kana': '', 'display_name': 'ブライトシステム', 'role': 'admin'}, {'id': ******, 'name': None, 'name_kana': None, 'display_name': '開発用テスト事業所', 'role': 'admin'}]}
```

# 解説
今回はScrapyで`JsonRequest`を使用しました。
これを使用すると、ヘッダーに`Accept: application/json, text/javascript, */*; q=0.01`を送信するようになります。
`start_requests`から`JsonRequest`を呼び出すようにしています。
あとは、`json.loads`で辞書形式に変換してしまえば、使いやすいでしょう。

Scrapyを使うとシンプルにAPIのアクセスもできるようになります。
【AWS】Transfer Familyでユーザ別にルートディレクトリを変更する

## きっかけ
- とある案件で使用しているTransferFamily For FTPを使用しているが、FTPユーザ別にルートディレクトリ(Bucket+Key)を分けたいという要望があったため。

## 前提
- AWS: 社用アカウント利用
- TransferFamily for SFTP: 以下リンク内にある"AWS Secrets Managerスタックテンプレート"を使用して構築済み

https://docs.aws.amazon.com/ja_jp/transfer/latest/userguide/custom-identity-provider-users.html

### 動作検証(構築)
- Transfer Familyの画面からエンドポイントを確認
![SnapCrab_NoName_2021-12-16_10-39-3_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/d9312332-211d-bafc-1b8f-db374a4e21a5.png)

- SecretsManagerでシークレット情報を登録
  -  シークレット名はSFTP/(FTPユーザ名)
  -  シークレット値
    - "Password": FTPのパスワード値
    - "Role": IAMポリシー:S3FullAccessを付与したロールを作成、ロールのARNを記載(実際の運用では適切な権限を設定)
![SnapCrab_NoName_2021-12-16_10-32-17_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/926d49e2-4284-d101-6aa0-637a88ebb428.png)

- FTPクライアントからの接続確認
  - ホスト名: TransferFamilyのエンドポイント
  - ポート番号: 22
  - ユーザ名: SecretsManagerのシークレット名SFTP/XXXとしたXXX部分
  - パスワード: シークレット値のPasswordで設定した値
     - 接続モードはPassiveのみ
   ![SnapCrab_NoName_2021-12-16_13-31-22_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/570d31ce-244f-ede8-8bd1-7e175d1ef6f8.png)

### 設定変更と動作検証(ルートディレクトリ変更)
- SecretsManagerのシークレット値を追加
    - キー: HomeDirectoryDetails
    - 値: [{"Entry": "/", "Target": "/(設定したいバケット)/(設定したいディレクトリ)"}]
![SnapCrab_NoName_2021-12-16_16-9-35_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/9a1e06ed-309f-f680-18b6-b804ebdd850d.png)
- FTPクライアントからの接続確認
  - 上記記載の接続情報で再接続を実施
![SnapCrab_NoName_2021-12-16_16-6-34_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/741f0b82-8882-748b-37ba-55c9c1d10220.png)

## 参考サイト
https://docs.aws.amazon.com/ja_jp/transfer/latest/userguide/custom-identity-provider-users.html

https://dev.classmethod.jp/articles/aws-transfer-family-with-apigateway-custom-id-provider-aws-secrets-manager/
【Django REST Framework】Vue.jsを適用するまでの流れを箇条書きでメモする

#はじめに
最近どハマりしているVue.js。これをフロントエンドに適用してみたのですが、通常のDjangoアプリ開発とは大分手順が異なりました。
今回はほぼ自分用ですが、どういう工程でVue.jsを適用させたのかをメモ書きしていきます。

※具体的な実装内容はYoutubeの講座動画そのままなので、コード等は記述致しません。
※必要なライブラリの導入方法も省略致します。

#参考にしたもの
貴重な日本語の講座動画です。大変有難うございました！
[Youtube（フルスタックチャンネル様）](https://www.youtube.com/playlist?list=PLoSZs76tLtJja77B6z6FfBxw4X6ka_yBx)
※参考動画リストに飛びます！


#手順
【バックエンド側】
1. 普通にプロジェクト、アプリを作成
2. models.pyを作成
3. プロジェクト直下のurls.pyを修正（apiフォルダ内へのurls.pyに飛ぶよう設定）
4. アプリ直下にapiフォルダ作成（urls.py、serializer.py、views.pyをそれぞれ作成）
5. settings.pyにページネーション機能を追加
6. api確認

【フロントエンド側】
1. Vueプロジェクト作成（事前にnode、VueCLIをインストール）
2. プロジェクト直下に移動後、「webpack-bundle-tracker（ver=0.4.3）」をインストール
3. Django側で「django-webpack-loader」をインストール（settings.pyの「INSTALLED_APPS」にも忘れず追加）
4. プロジェクト直下にvue.config.jsを作成
5. 「vue add vuetify」でVuetifyをインストール（事前にvue.config.jsの内容はコピーして退避）
6. App.vueの内容をすべて削除し、最小限のコードを記述。
7. routerフォルダ➡index.jsを開き、Aboutページのルーティング設定、baseを削除
8. Vueプロジェクト➡srcフォルダ直下にcommonフォルダを作成し、csrf_token.jsを作成
9. 同じくcommonフォルダ直下にapi.service.jsを作成
10. Home.vue(一覧)を記述
未経験エンジニアがやったこと・やるべきこと

#この記事の目当て

- これから未経験としてITに踏み込む人に伝えたい
- テックキャンプに入りたい・迷ってる人に伝えたい
- IT業界へ転職活動中の人に伝えたい
- 自分の今までの活動をまとめたい

少し長いですがよろしくお願いいたします。

#自己紹介
- 男
- 19歳
- 工業高校卒
- 前職は居酒屋でバイトから正社員　(バイト3年、社員歴1年3ヶ月)

#テックキャンプに入ってどう思ったか
色々と嫌な噂はありますが、僕個人としてはすごく価値がある期間だったと感じています。
中でも一番の価値はチームです。チームメンバーがいなければ挫折していたと思いますし、お互い問題を解決しあったり楽しい毎日でした。
ただ楽しいだけでなく、皆さんの進捗に負けないために緊張感をもち、成長しあえる環境がテックキャンプの価値だと思っています。

まだ改善できるところはありますし、噂は本当だなと思う部分もありましたが、皆さんが思っているほどネガティブな印象はありませんでした。

「お前がクソガキだからわからない」、
「お前と俺は違うんだよ」

とかどうでもいいです。
僕がいいと思ったからいいんです。（クソガキっぽさ全開）

#テックキャンプ卒業後どう思ったか・何をしたか

まず、チームの皆さんがいると思えたらすごく心が楽でした。
CAさん(キャリアアドバイザー)以外に頼れるというか、仲間がいてよかったと思っています。
まずは自己分析でしたが、なかなかできず・・・
テックキャンプ卒業後にやったことを面接で話したいなって気持ちで色々と始めました。時系列順に書いていきます。

1.PF（ポートフォリオ）の制作を進める
2.チームメンバーのひださんという方とpaizaのBランクを目指す(僕なんてCランクでミスったりしてましたが笑）
3.11月後半からpaizaやUdemyでPHPを学ぶ
4.モチベーションを高めるためにconnpassというサイトからオフライン勉強会に参加しました。
5.業界の動向とか見ようとbridgeやテッカブルの記事を見てnoteに書く
6.業界を知ることが大事と(ひださんに)言われ、エージェントに応募しまくる
7.pikawakaさんのzoom相談(後で詳細を言います)
8.エンジニアのオンライン勉強会に参加
9.今朝、「メモの魔術」という本を買って一日使って自己分析

他にも朝活やらゼロ秒思考やらしながら(ほとんど中途半端に終わってますが)、この一ヶ月半やってきました。

社会経験も就活の経験も全部ない僕は途方に暮れて不安しかありませんでしたが、なんとかようやくスタートラインに立てたと思っています。
ここまで来れたのって本当にいろんな方のおかげです。
特にひださん、ありがとうございます。

#この記事を読んでいる皆さんのアクションプラン
実際に僕がやって、価値があると思ったことです。
業界を知れば幅が広がります。
よければ実践してみてください。

##エージェントを使おう

先ほど紹介させていただいたpikawakaさんのサイトです！！
ぜひこちらからエージェントに登録をしてzoom面談してみてください！
特にハタラクティブさんとUZUZさんはおすすめです！！

https://pikawaka.com/it-industry/inexperienced-engineer-job-site

##[最重要]現役エンジニアのpikawakaさんとお話する

pikawakaさんと2時間くらい面談して、とても参考になるお話ばかりでした！！
現役のエンジニアの方で、とても真摯にこれからのキャリアを考えてくれました。
全くIT業界についてわからなかったので、ぜひ未経験の方はzoom面談をしてください！！

https://line.me/R/ti/p/%40665wmzdn


##connpassを使ってオフライン勉強会に参加する

現役のエンジニアがたくさんいます。
コミュニケーションを重ねて、いろんなエンジニアの方から業界研究をしてみてはいかがでしょうか？

https://connpass.com/dashboard/

#終わりに

今回は未経験エンジニアが転職でやるべきことを書かせていただきました。
これが一人でも多くの人に参考になればいいと思います。
【Hotwire】HTMLだけで分かる Turbo 🚜


# はじめに

https://hotwired.dev/

Rails7のリリースで、Hotwireに注目が集まっています。どうしてもRailsとペアで語られがちなHotwireですが「HTMLさえあれば動く」のが重要なポイントです。（つまり LaravelやExpressなどあらゆるWebフレームワークと共存できます！）

そこで今回は、HTMLのみでHotwireの世界観を体験できるような内容で以下にまとめたいと思います。

## 触れること

- Hotwireの構成モジュールの一つである「Turbo」その中でも「Turbo-Frame」 
- ごく基礎的なことのみ

こんな感じのが**HTMLの記述だけで**作成できます

[![Image from Gyazo](https://i.gyazo.com/895f5659cd303dd47bb8a5686ca9bdf6.gif)](https://gyazo.com/895f5659cd303dd47bb8a5686ca9bdf6)

## 触れないこと
- Stimulus
- Strada
- その他あらゆる発展的内容




# HTMLファイルの準備

以下の２ページを用意します。
- index.html
- foo.html

まずは、HTMLファイルを準備します。

## `index.html`

ポイントは２つのみです。

- Turboは`head`でCDNから読み込んでいます。
- `<turbo-frame id="bar">` というカスタムタグがあります。

```html:index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <!-- Hotwire のインストール -->
    <script type="module">
      import hotwiredTurbo from "https://cdn.skypack.dev/@hotwired/turbo";
    </script>
  </head>

  <body>
    <main class="container">
      <h2>Turbo-Frame</h2>

      <turbo-frame id="bar">
        <h3>フレーム内は置換される</h3>
        <a href="./foo.html">リクエスト: foo.html</a>
      </turbo-frame>
    </main>
  </body>
</html>
```

![スクリーンショット 2021-12-17 23.29.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452235/22125301-7072-93b7-632c-18b0c647da8e.png)




## `foo.html`

この後説明を入れますが、`index.html`の一部を置き換えるためのファイルです。

- 以下の例のように必要なタグしか持たない状態でも可。
- もちろん完全なHTMLでもOK。

```html:foo.html
<body>
  <h1>あってもなくてもいいH1</h1>

  <turbo-frame id="bar">
    <form action="./index.html">
      <input placeholder="送信すると戻る" />
      <input type="submit" />
    </form>
  </turbo-frame>
</body>
```

# `foo.html`をリクエストする

1. `<a>`タグをクリックすることで、サーバーは`foo.html`（`<body>`しかない不完全なHTML）を返します。
2. Turboは、idが一致する`<turbo-frame>`を見つけるとそれらを置換します。

[![Image from Gyazo](https://i.gyazo.com/12648c82e7fa39254a2751514442e267.gif)](https://gyazo.com/12648c82e7fa39254a2751514442e267)


ちなみに、`<turbo-frame>`内に含まれない`<h1>あってもなくてもいいH1</h1>`は無視されます。完全なHTMLでも、不完全なHTMLでもどっちでもいいのはこのためです。いづれにせよこの場合`<turbo-frame>`だけしか認識されません。

なお、ブラウザの開発者ツールを見てみると、ちゃんとSPA的な動きをしています。アドレスバーも変わりません。（もちろん変える設定もできます）

[![Image from Gyazo](https://i.gyazo.com/895f5659cd303dd47bb8a5686ca9bdf6.gif)](https://gyazo.com/895f5659cd303dd47bb8a5686ca9bdf6)


# まとめ

HTTPリクエストによってHTMLが返却されるだけで、対応する id のフレームのみを入れ替える（置換する）動きが実現できました。

- `src`属性を使えば、初期表示からリクエストを行うことができます。`<turbo-frame src="./foo">`
- 実装したのはHTMLのみで、JavaScriptは一切記述していません。

## 何がそんなにいいのか

- あらゆるフレームワークでSPAできる
- HTMLだけでコンポーネント化できる
    - デザイナーのHTMLがそのまま使えるかもしれない
    - ReactやVue文法に縛られないピュアなHTML
- 手軽に遅延ロードできる
【初心者必見】C言語うまくいかないの大体これ

こんにちは。watnowのゆいぴです。
[アドベントカレンダー][link-1] やろうよと言われたので何書くか悩んで血迷った挙句の記事です。
[link-1]:https://qiita.com/advent-calendar/2021/watnow-calendar

一年くらい大学でC言語やってて、長期休暇挟むたびにどうやって書くか忘れるポンコツです。
この前大体あってそうなプログラム書いてるのになんかうまくいかないな、と思って先生に聞いたら初歩的なミスすぎて「勉強足りないんじゃないの？w」と煽られて確かにその通りだったんだけど普通に悔しくて泣きました。~~（あと普段ならそんなことやらんわと家に帰ってブチギレました。）~~

その自戒の意味も込めて、
・C言語でうまくいかないときによくあること
・初心者の時によく間違えたこと
・私が今でも時々間違えていること（これは自戒）
みたいなのをまとめた記事を書くことにしました。
ポンコツなので初歩的なミスばっかりしているので『C言語大学でやり始めたけどなんかうまくいかんしわからんわ』みたいな人にも多少参考になると思います。読んでみて『そんな簡単なことで間違えてるのはお前だけやぞ』と思ったらすみません。

ちなみに開発環境はVisual Studio Codeです。VSCodeしかほとんど触ってないので途中他の環境だとこれはできないよみたいなのもあるかもしれません。井の中の蛙ちゃんなので許してください。


#目次
[1.コンパイラの確認（特にMacの人）](#1-コンパイラの確認（特にMacの人）)
[2.括弧の数とセミコロンを確認](#2-括弧の数とセミコロンを確認)
[3.includeしてない問題](#3-includeしてない問題)
[4.dやらsやらどれ使うんだ問題](#4-dやらsやらどれ使うんだ問題)
[5.おわりに](#5-おわりに)

#1. コンパイラの確認（特にMacの人）

コンパイラの確認をしてください。

同じコードを書いていてもたまにコンパイラが違うと動かないことがあります。
私のおすすめはgccです。大学でも大体gccなら動作確認してますって言われることが多い気がする。gccで動かなかったことあんまりないです、やはり井の中の蛙、、、。

特にMacと書いたのは、**C言語の実行を楽に行いたい**と思ってコンパイラをlldbに変えたらうまくいかなかった経験があるからです。（Windowsを使用していたときはgccで普通にショートカットで実行できてたのにMacだと毎回コマンド打たなきゃいけなくてそれが嫌でlldbに変えたら動かなくなっちゃった。つらい。）

ちなみにじゃあC言語の実行を楽にするのはどうやるねんって興味持った人はこの記事参考にしてみると良いかも。同じアドベントカレンダーに参加してる後輩の記事です（宣伝）。普通にlldbで動くプログラムならこれ設定しとくとかなり快適になるのでおすすめです。
https://qiita.com/F-lapin/items/cb59f0406295009227dc
#2. 括弧の数とセミコロンを確認

これは多分あるあるなんですけど()や{}がちゃんと数揃っているか確認してください。割と揃ってないことある気がする。私はコピペしてちぎって貼ってを繰り返してると時々ぐちゃぐちゃになって無駄に赤線黄色線を大量に引かれて怒られます。

あと文末にセミコロンがついてるかどうかも確認してください。
余談ですが他の言語（特にPythonとか）も書いてる友達とかは久しぶりにC書くとセミコロン書き忘れる〜とぼやいてました。。。

括弧が足りているか手っ取り早く確認する方法としては　`右クリック＞ドキュメントのフォーマット　`とするとなんかいい感じにプログラムの体裁を整えてくれるのであとはちゃんと目視で確認してください。でも多分このフォーマットするやつはVSCodeでしかできないやつかもしれない。知らんけど

#3. includeしてない問題

ライブラリ関数って便利ですよね。
でも最近私がよくやらかすのがこのincludeしてない問題です。

色々やりたい処理をmainの中につらつらと書いて、いざコンパイルするとめっちゃ怒られる。
なんでだろうと思ってみてみると

`implicit declaration of function '〇〇' is invalid in C99`
これが出てる。（〇〇の中は怒られている該当箇所とかが入ります。）
ヘッダファイルとかいうのがあって、それを書いてないと関数を使わせてもらえないらしいです。
（ヘッダファイルっていうのは`stdio.h`みたいなやつのことらしい。）

何をincludeすればいいかはまあ関数名ググれば大体出るんですけど、
「いちいちブラウザを開きたくないんだが？」という~~横着な~~人は
`関数を選択＞右クリック＞定義へ移動`（これもVSCode限定かも？わからん）
とすると大体ヘッダファイルが開かれるのでそれみてこれが欲しいのね〜と書いてあげることもできます。

#4. dやらsやらどれ使うんだ問題

これは変数の宣言が何型の時にどれを使うんだよ〜と詳しくここに書くと長くなるので私が雑に覚えていることを書いておきます。
（本当はもっとちゃんとしたルールがあるけれど、大学の課題くらいだとあんまり使わなかったり、初心者がざっとみてわかりやすいことを優先したかったり、という事情で書いてないです。詳しいことが知りたければ他の優しい人が丁寧にまとめてくれてるからそっちみてね。）

雑な覚え方
`数字→%d`
`小数点→%f`
`文字→％s`

あと`scanf`でうまくいってない人は引数のところに`&`があるかを確認するといいと思います。
#5. おわりに

こんな雑な覚書のような記事を見てくださりありがとうございました。
少しでもC言語うまくいかへんわみたいなのが解消されたら嬉しいです。

また、大学の課題でC言語やっている程度の素人ですので、きちんと勉強されている方からすると解釈や表記等が間違っていたりする場合もあると思いますが、その場合は優しく教えていただけると私の糧となりますのでよろしくお願いします。
enebularで デスクを監視する

※この記事の内容は2021年12月2日の[enebular developer meetup](https://enebular.connpass.com/event/228869/) で発表した内容をベースにしています。


# ごあいさつ
アドベントカレンダーも後半戦。年の瀬です。
2021年もリモートワークが多い年でした。
コロナ禍も2020年から2年目ということで、慣れてきた方も多いと思いますが、
一方で不満点も浮き彫りになってきたかと思います。


# リモートワークの悩み
そんな中で、リモートワークの悩みの一つが、それぞれの社員の様子がわからないことです。


![ScreenShot 2021-12-17 22.47.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242072/065df9f3-f514-b160-3c93-f11d0d21e386.png)


とある調査では実に80%以上の上司が「以前と比べて難しさを感じる部下とのコミュニケーションシーン」ｊに
「日常の行動観察」を挙げています。


![ScreenShot 2021-12-17 22.48.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242072/42973257-091d-1d43-bc9c-d5b6f88b6623.png)

※[コクヨ：テレワーク下の上司と部下のコミュニケーション課題](https://www.kokuyo-marketing.co.jp/blog/hatarakikata/post-28/)　より


そんな課題を解決するソリューションをenebularで実現したいと思います。

# 構成

前回のenebular developer meetingでは、
店内の座席使用状況をリアルタイムで表示するソリューションを提案しましたが、
今回はそれを拡張して、Google Spreadsheet上に仕様記録を追記していくようにしたいと思います。

ざっくりというと座布団にEテキスタイルを使用した、着座センサーを設置し、
その様子を1分おきにチェックす、というものです。

![ScreenShot 2021-12-17 22.55.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242072/f8b00086-d1e8-2b2a-bf42-4faddd1e0137.png)

# 実装手順

とりあえずGoogle Developers Consoleにて登録を行います。
このへんは[enebularブログ](https://blog.enebular.com/nodes/letsuse-google-spreadsheet-node/)にて
詳しく説明されているのでそちらをご参照ください。

→https://blog.enebular.com/nodes/letsuse-google-spreadsheet-node/



Google Developers Consoleの登録を行い、
[node-red-contrib-google-sheets](https://flows.nodered.org/node/node-red-contrib-google-sheets) をパレットに登録できたあとに、早速ノードを作成します。

実際のノードはこちら↓
![ScreenShot 2021-12-17 23.01.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242072/e45abdb9-ea90-a9fd-9485-c75a4c0edce2.png)


左の`http in`ノードでnünoから送信された値を受け取り、
中央の`function` ノードで値に日時を追加しています。
右の`GSheet`ノードで連携したSpread Sheetに値を送信しています。

`function`ノードの中身はこちら

```
const time = new Date(Date.now() + ((new Date().getTimezoneOffset() + (9 * 60)) * 60 * 1000))
msg.payload = [
    time.getHours()+":"+time.getMinutes(),
    msg.payload.val]


return msg;
```

Spreadsheetで扱いやすい形式にするため、日時を生成しています。

ちなみに今回、日時＋値　をセットにしてSpread Sheetに送信したかった為どうするか悩んでいたところ、
なんとなく配列にして送信してみたら1列目と2列目に登録されてくれました。

ドキュメントにも記載を見つけられなかったので地味に嬉しかったです。
その後無事動作していることを確認しました。


![ScreenShot 2021-12-17 23.17.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242072/2493d082-dd4f-365e-4617-1f6a22001782.png)


あとはこの値をSpread Sheet上でグラフ化しグラフを公開設定すれば、
無事完成です！

![ScreenShot 2021-12-17 23.18.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242072/059f4dc5-db74-f91b-14f0-e1b8014d2bf7.png)


いかがでしたでしょうか。
職種によってはリモートワークは今後も続いていくことになりそうですが、
enebularを通じてより快適なリモートワークライフをしていきたいですね！

では皆様よいお年を〜！
気象庁：お天気APIを使ってみた

こんにちは、いつも傘を忘れてしまう私なので
今回は気象庁のAPIを使ってお天気情報を取得するアプリを作成しました。
#使用した技術
・Windows10(PC)
・Vue3
・TypeScript
・HTML/CSS
・FireBase
・<a href="https://getbootstrap.jp/">Bootstrap5</a>
・<a herf="https://www.jma.go.jp/bosai/forecast/">気象庁API</a>
・<a herf="https://date-fns.org/">date-fns</a>
・イラスト：<a herf="https://hiyokoyarou.com/">ぴよたそ</a>

#画面
かわいい寅さんが今日の天気を教えてくれます。
寅さんは基本あなたの事を呼び捨てにしてくるのでとても距離感が近いです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2365717/f345239c-2a49-22fb-a712-e89bdf5345b1.png)

上のメニューバーを押すと、メニューが開く仕様です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2365717/2183467c-1fa8-b4f8-edd8-4172fc826e2e.png)
<a href="https://qiita.com/koda-momo/items/a0cb477c9bf901214a51">kakeibo</a>
<a href="https://qiita.com/koda-momo/items/169395b0446c9b7d2646">todo</a>

#出来る事
・FireBaseの登録データから名前を取得して寅さんが呼んでくれる
・FireBaseの登録データから住所を取得して今日の天気を表示
・下の部分で住所を変えると他の天気も見れる

#コードで説明
今回は気象庁のAPIを使って天気を取得しています。
<a href="https://qiita.com/koda-momo/items/8c59cc07ab5df4486478">前回</a>も述べましたが私はAPIを呼ぶのが好きです。世の中には呼びたいAPIがたくさんありますね。

という事でまずは
(1)FireBaseからログイン中ユーザの住所(今回は東京都)を取得
(2)全国データを取得して、都道府県IDを取得
(3)登録している都道府県と同じ場所のコードを取得してweatherPlaceCodeという変数に代入

(2)から…↓

```typescript
      const response1 = await axios.get(
        "http://www.jma.go.jp/bosai/common/const/area.json"
      );
      const allInfo = response1.data.offices;
      const keyNumber = Object.keys(allInfo);

      for (const key of keyNumber) {
        if (allInfo[key].name === userAddress.value) {
          weatherPlaceCode = String(key);
        }
      }
```

(3)続いてそのコードをURLに入れてお天気情報を取得します。

```typescript
      const response2 = await axios.get(
  `https://www.jma.go.jp/bosai/forecast/data/forecast/${weatherPlaceCode}.json`
);
```

無事に東京のデータが返ってきたので必要な情報(お天気)を掘り出します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2365717/cbd8c8ed-7ede-eb6e-58ab-bb7179bced26.png)


```typescript
  weather.value = response2.data[0].timeSeries[0].areas[0].weathers[1];
```
これで寅さんもお天気をユーザに伝える事が出来ました。
良かったね！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2365717/2d2f835b-76f0-9d1d-02d1-6c1fe7df2cd7.png)

#ちなみに
寅さんの挨拶も時間によって変わります。

```typescript
   /**
     * 時間によって、寅さんの挨拶を変える.
     */
    const whatNowTime = () => {
      //現在時刻を取得
      const now = new Date();
      //時間と分を取得
      const nowHours = now.getHours();
      const nowMinutes = now.getMinutes();
      //時間を繋げて3-4桁の数字に
      let nowTime = 0;
      if (String(nowMinutes).length === 1) {
        nowTime = Number(String(nowHours) + "0" + String(nowMinutes));
      } else {
        nowTime = Number(String(nowHours) + String(nowMinutes));
      }
      //4:00-10:59 おはよう、11:00-17:59 こんにちは、それ以外こんばんは
      if (Number(nowTime) >= 400 && Number(nowTime) < 1100) {
        sayHallo.value = "おはよう";
      } else if (Number(nowTime) >= 1100 && Number(nowTime) < 1800) {
        sayHallo.value = "こんにちは";
      } else {
        sayHallo.value = "こんばんは";
      }
    };
```

時間のところはいちいち文字列だの数字だのにしてしまったのでそれは必要なかったかな…と反省です。

#まとめ
今回は気象庁APIを使ってお天気情報を取得しました。
APIを使うだけで色々な情報が取得できるので非常にありがたいですね…
これでもう雨に濡れずに済みそうです。

ここまでご覧頂きありがとうございました。
Deno製のReact風フロントエンドフレームワークAleph.jsをインストールしたが，alephコマンドが実行できなかった

# 概要
公式ドキュメント通りに，DenoでAleph.jsをインストールした．
しかし，alephコマンドが実行できず，`command not found`と言われた.

```zsh
$ deno run -A https://deno.land/x/aleph/install.ts
Check https://deno.land/x/aleph/install.ts
Looking up latest version...
Aleph.js was installed successfully
Run 'aleph -h' to get started

$ aleph -h
zsh: command not found: aleph
```

# 解決方法
原因としては，Denoでインストールしたバイナリファイルに対するpathが通っていないことだった.
Denoのバイナリファイルは`~/.deno/bin`に入っているのでそこに対するパスを通してあげれば実行できるようになる．

自分の場合は以下のコードを`.zshenv`に追加してpathを通した．

```sh:.zshenv
# denoのパスを通す
export DENO_INSTALL=~/.deno
export PATH=$DENO_INSTALL/bin:$PATH
```

追加後,`source .zshenv`を実行することで，無事alephコマンドが実行できた.

```zsh
$ source .zshenv

$ aleph -h
Aleph.js v0.3.0-beta.19
The Full-stack Framework in Deno.

Docs: https://alephjs.org/docs
Bugs: https://github.com/alephjs/aleph.js/issues

Usage:
    aleph <command> [...options]

Commands:
    init           Create a new app
    dev            Start the app in development mode
    start          Start the app in production mode
    build          Build the app to a static site (SSG)
    upgrade        Upgrade Aleph.js command

Options:
    -v, --version  Prints version number
    -h, --help     Prints help message
```

# バージョン
deno 1.17.0
Aleph.js v0.3.0-beta.19
転職ドラフトを利用して、ドラフト時の提示年収よりUPして転職成功した話

# 転職ドラフトとは
[転職ドラフト](https://job-draft.jp/)とはざっくり言うと、**「求職者がレジュメを登録しておくと、月に一度のドラフト会議が開かれたタイミングで参加企業がレジュメを読み、気になった人を指名してくれる」**といったサービスです。

もちろん指名が来たら即内定が貰えるわけではなく、指名承諾後は通常通り面接やコーディング試験等を行います。
イメージとしては書類選考が通過している段階で、企業に応募できるといった感じかと思います。

ただ指名を受ける際に、企業から**「年収」「指名理由」「企業が抱えている課題」「何を任せたいのか」**等の、ホームページやブログなどには掲載されていないような情報が入手できるので、その点は面接の際に**有利**になるのかなと思います。

# 転職ドラフトに登録したきっかけ
某Youtuberの動画を見て、転職ドラフトの存在を知りました。
SESでずっと働いていて、漠然と「2年後くらいには事業会社に転職したいな〜」と思っていました。

登録しているだけで指名が来て、自分の市場価値がわかるのなら、すぐに転職するつもりはなくても登録しておいて損はないかなと思ったのがきっかけです。

# 転職ドラフトの結果
ドラフト会議にはこれまで２回参加しました。
１回目：指名数14
２回目：指名数6

業務でAWSやフロントエンドのフレームワークを使ったことがない、バックエンド開発（Java/Kotlin）オンリーのへっぽこエンジニアでしたが、たくさんの指名をいただけて、自分としてはかなり驚きました。

指名をいただけたポイントとしては下記の3つが大きかったのかなと思います。
**・業務で上流工程の経験をたくさん積ませてもらっていた。
・チームリーダーとしてメンバーマネジメント・進捗管理などを行なっていた。
・ポートフォリオだったり、Qiitaの記事だったりアウトプットをそこそこしていた。**

最終的には、１回目に参加したドラフト会議の時にご指名いただいた企業とご縁があり、**転職が決まりました〜！**
ドラフト時の提示年収よりUPしてオファーを出していただけて、やる気満々で次の企業で使用する技術スタックのお勉強をしています。
**転職ドラフト様ありがとうございます。。**

# 選考を通して感じたこと
指名承諾後、選考に入った後の面接等に関しては、他の転職エージェント経由で面接した場合と、そこまで大きな違いはなかったです。
（転職ドラフトでは、転職エージェントを通してではなく、企業の採用担当の方と直接やりとりをする必要があり、日程を調整するのが少し大変でした。）

ただ「転職ドラフトとは」でも書きましたが、事前にホームページやブログなどには掲載されていないような情報が入手できていた分、事前に準備がしやすく話しやすかった気はします。

転職ドラフトに登録する際にレジュメを提出するのですが、そのレジュメの審査が厳しく、その審査を通過するために、嫌でも自身の経歴とかを言語化しないといけないので、その過程で面接で話すネタが整理されたという部分もあるのかなと思います。

転職ドラフトのレジュメは、過去に転職活動していた時の職務経歴書と比べると情報量が段違いで、採用する側の企業としても転職ドラフトのレジュメくらいの情報は欲しいのかなと、過去の転職活動の時を振り返って思いました。
（Word1枚、2枚程度の職務経歴書で何がわかるんだっていう感じですよね。。）

# 転職ドラフトへの改善要望
特にサービスの仕組みの部分に対しては、要望等はありませんが、UI/UXの部分で下記が気になりました。

・指名いただいた企業のソートができない。
　（指名年収順、指名日時順、企業の指名数順、企業の指名承諾率順など）
・メッセージの通知にラグがある。
・自身がメッセージを送信した後、画面がリフレッシュされない。
・日程調整機能の使用方法がわかりづらい。

# 転職ドラフトを使ったことがない方へのメッセージ
転職する気はない人も、いつか転職しようかなと思っている人も、今すぐ転職したいと思っている人も、登録しておいて損はないサービスかと思います。

ぜひ、一度はドラフト会議に参加してみてはいかがでしょうか？

「指名がなかなか来ないなぁ」とそわそわしたり、想像より高い年収で指名が来てガッツポーズしたり、仕事が手につかない２週間が過ごせるかと思います。笑

**オススメです！**

＊こちらの記事は[転職ドラフト体験談投稿キャンペーン](https://job-draft.jp/articles/251)に参加しています。
C#でカノジョをつくる（17日目）

おつかれさまです。たなしょです。
きょうから本格的にカノジョの作成を始めていきます。
あともう一息でカノジョをつくれます。
## フォームを作成
こんな感じフォームを作成しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268048/38b463cc-1083-98a9-2b05-8b1bd6ac82f2.png)

画像は[ACillust](https://www.ac-illust.com/main/detail.php?id=22251059&word=%E6%82%A9%E3%82%80%E5%A5%B3%E3%81%AE%E5%AD%90%2F%E7%B4%AB)さんから拝借しました。
今回は喜怒哀楽の表情もつけるので4枚ほど画像を使いました。
ちなみに今回使う画像はResources.resxに保存しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268048/24b4af51-f642-a4a7-e2cd-606dd9b40ba7.png)

## 今回のコミュニケーション方法
何日か前のカノジョプロトコルと同じようにチャットボット形式でメッセージのやり取りをします。
今回は一方的なコミュニケーションではなくこちらの言葉をある程度返せるようにします。

今回は豊富な語彙を持たせるために`random.txt`に大量のランダムに発言するワードを記載します。
```
いい天気だね
今日は暑いね
おなかすいた
10円おちてた
```

また挨拶や特定のワードに反応してそれっぽく返すように正規表現でパターンマッチングさせるためのpattern.txtも用意します。
```
こん(ちは|にちは)$  こんにちは|やほー|ハーイ|どうもー|まああなた？
おはよう|おはよー|オハヨウ  おはよ！|まだ眠い…|さっき寝たばかりなんだー
こんばん(は|わ) こんばんわ|わんばんこ|今何時？
```

##最後に
少し短いですが今回はここまでで終わりです。
明日はrandom.txtとpattern.txtを処理するためプログラムを実装していきます
OpenAPI (Swagger) 関連の便利なツールや tips を紹介

LIGHTz ではシステム間連携仕様共有やSPA開発での仕様共有に OpenAPI (Swagger) を使っています。
OpenAPI (Swagger)を使う上で便利なツールや tips を紹します!

# swagger editor を docker で利用する

- `docker run -d -p <任意のポート>:8080 swaggerapi/swagger-editor` で起動できます
- 以下のエイリアスを登録すると便利です
    - `alias swagger='command="docker run -d -p <任意のポート>::8080 swaggerapi/swagger-editor" && echo $command && eval $command && open http://localhost:<任意のポート>:'`
- syntax 確認も swagger editor で行うことができます

# openapi-generator-cli を docker で利用する


- 以下のようなコマンドでコード生成ができます
    - https://github.com/OpenAPITools/openapi-generator#openapi-generator-cli-docker-image

```
docker run --rm -v "${PWD}:/local" openapitools/openapi-generator-cli generate \
    -i https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/3_0/petstore.yaml \
    -g go \
    -o /local/out/go
```

- 対応言語の一覧 (　-g の引数) は以下のコマンドで確認できます。
    - `docker run --rm openapitools/openapi-generator-cli list`
- i の部分は `/local/openapi.yml` でファイルシステムを指定することができる

# openapi を Visual Studio Code で見たい書きたい
- 拡張を openapi or swagger で検索するとたくさん出てきます
- 個人的には swagger editor で一通りのことができるので使っていないです

# openapi ドキュメントを html 化する
docker や vs code を立ち上げるのが億劫な人がいたり、どこかにホスティングする場合は html 化して配布するのが良いでしょう。

- 以下のコマンドで html 化できます  
    - `docker run --rm -i yousan/swagger-yaml-to-html < petstore.yaml or .json> petstore.html`
    - 利用しているコンテナ
        - https://github.com/yousan/swagger-yaml-to-html
大学図書館アプリを引き継いでくれる方を募集しています

# はじめに
私は4年生でまもなく卒業なので、岩手県立大学図書館アプリの開発・保守を引き継いでくれる方を募集しています。
アプリの開発や運用などに興味がある方であれば大歓迎です！
興味ある方は、以下の連絡先までご連絡お願いいたします。
g031q024@s.iwate-pu.ac.jp

## 開発した経緯
大学の図書館から本を借りるには、大学の図書館ページにアクセスして蔵書検索をする訳ですが、この過程が割と面倒だと感じました。
ライブラリーアテンダントに所属していた私は、大学の職員さんと相談し、大学の図書館アプリを開発する許可を得て、開発を始めました。

## 学んだこと
アプリを開発しても、色々な人に使ってもらえることが確約されているわけではありません。
アプリを開発するのも大変ですが、そのアプリを多くの人に使ってもらえるようにするのもかなり大変だなと感じました。
PR活動は大学職員さんにも協力していただき、学内メールや学内ポスターなどの掲示も行いました。
開発した当初はあまりアクティブユーザーも多くはありませんでしたが、職員さんに学内メールで周知して頂いたりとPR活動に力を入れた結果、アクティブユーザーは2倍以上にまで増えました。

## 開発言語
iPhone版はSwift
Android版はJava
(Flutterで作り直したいなと思い始めてる)

## 機能
・蔵書検索、予約
・図書館案内機能
・図書館ブログ閲覧機能
・生協カード残高確認機能(Felicaに対応している端末で生協カードの残高をスキャンできちゃう)
・プッシュ通知でのお知らせ

## 完成版(現在)はこんな感じ
![IMG_4063.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145857/c0b5876e-1487-b95c-1e45-1e5d83f2a880.png)

## 生協カードの残高も確認できます
![IMG_4064.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145857/0b1ce99a-75a2-6850-f6de-cbfa6a1a93ca.png)

## AppStore,GooglePlayからインストールできるので、県大生は是非インストールしてみてください！
[iPhone版はこちらから](https://apps.apple.com/jp/app/%E7%9C%8C%E5%A4%A7%E5%9B%B3%E6%9B%B8%E9%A4%A8%E3%82%A2%E3%83%97%E3%83%AA/id1395946863?mt=8)
[Android版はこちらから](https://play.google.com/store/apps/details?id=la.xmilkyway.com.la&hl=ja&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1)
Azure Functions Core Tools を切り替える

# 急いでいる人へ
以下で切り替えられます
https://github.com/anthonychu/funcvm

# なぜ Azure Functions Core Tools の切り替えが必要なのか
Azure Functions を deploy しようとしたら、以下のエラーがでました。

`Referenced bundle Microsoft.Azure.Functions.ExtensionBundle of version 2.4.0 does not meet the required minimum version of 2.6.1. Update your extension bundle reference in host.json to reference 2.6.1 or later.`

メッセージを追って issue を見にいったところ、その時点では以下の事が書かれていました。

- Azure Functions Core Tools を 4 -> 3 にダウングレードしろ
- ダウングレードには Azure Functions Core Tools の切り替えを実行しろ  
https://github.com/Azure/Azure-Functions/issues/1987

# 切り替え
```
$ func --version
4.0.3971

$ npm install -g @anthonychu/funcvm

$ funcvm use 3 
Downloading https://functionscdn.azureedge.net/public/3.0.3904/Azure.Functions.Cli.osx-x64.3.0.3904.zip to /Users/niten.nashiki/.funcvm/download/3.0.3904...
2 minutes remaining
less than a minute remaining
half a minute remaining
less than a minute remaining
half a minute remaining
less than 20 seconds remaining
less than 10 seconds remaining
less than 5 seconds remaining
Using 3.0.3904

$ func --version
3.0.3904
```

## (おまけ) Azure Functions Core Tools を 4 -> 3 になったらどうなった?
Azure Functions Core Tools を 4 -> 3 に変更したら動いてくれるようになりました。
[Go]ローカル環境でのテスト自動実行スクリプトにより開発体験を向上する

この記事は [DENSO アドベントカレンダー 2021](https://qiita.com/advent-calendar/2021/denso) の 18 日目の記事です。

Go で実装する際に使用している便利スクリプトを紹介します。
ファイルの編集保存の度にテストを自動実行し、色付けしたテスト結果を出力します。テストコマンド入力の煩わしさがなく、表示色で結果を判断できログを読む認知負荷が軽減します。コード編集に集中できるため、リファクタリング作業で重宝しています。

# 動作デモ

デモではアサーションの期待する結果を編集して保存しています。ターミナルでスクリプトを一度実行した後は、エディタ内に留まったまま随時テスト結果を確認できます。
![Untitled.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/928808/fa808451-bded-f49a-63eb-8480c5f3a948.gif)

# 準備

[reflex](https://github.com/cespare/reflex) (ファイル差分が生じたことを検知)と、[gotest](https://github.com/rakyll/gotest) (テスト結果に色付け)をインストールします。

```shell:
$ go install github.com/cespare/reflex@latest
$ go install github.com/rakyll/gotest@latest
```

<br>

# スクリプト

シェルスクリプトと Makefile の２種類を紹介します。お好みで選んでください。

### シェルスクリプト

プロジェクトのルートディレクトリにスクリプトを用意します。

```bash:test.sh
#!/bin/bash

cd "$(dirname "$0")" || exit 1

if [ -z "$1" ]; then
  reflex -r '\.go$' -- gotest ./... -v
else
  reflex -r '\.go$' -- gotest -run "$1" ./... -v
fi
```

`chmod +x test.sh`で実行権限をつけておきます。

処理の内容は、拡張子`.go`ファイルに差分が生じたら、その都度`gotest ./... -v`を実行します。特定のテスト関数のみテストするときは、引数にテスト関数名を渡すと`-run`つきで実行します。

```shell:
$ ./test.sh
```

特定のテスト関数のみテストします。

```shell:
$ ./test.sh TestDoSomething
```

<br>

### Makefile

複数のスクリプトを１つのファイルで管理できるのでおすすめです。インデントがタブであることに注意。

```makefile:makefile
.PHONY: test

FUNC=

test:
ifndef FUNC
	reflex -r '\.go$$' -- gotest ./... -v
else
	reflex -r '\.go$$' -- gotest -run $(FUNC) ./... -v
endif
```

全件テストします。

```shell:
$ make test
```

特定のテスト関数のみテストします。

```shell:
$ make test FUNC=TestDoSomething
```

<br>

# 終わりに

このツールのおかげでリファクタリングが楽しくて、ついつい時間が経つのを忘れそうになります。
Big Sur で brew 使おうとしたら Your Command Line Tools are too outdated. と言われた

# 私のマシンに関して
MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)
![スクリーンショット 2021-12-17 16.19.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110482/d9606e40-d393-3661-e40d-3c02ea6ab3a0.png)

# エラー内容 と 解決方法

brew install xx しようとしたら以下のエラーが出た。

```
Error: Your Command Line Tools are too outdated.
Update them from Software Update in System Preferences or run:
  softwareupdate --all --install --force

If that doesn't show you any updates, run:
  sudo rm -rf /Library/Developer/CommandLineTools
  sudo xcode-select --install

Alternatively, manually download them from:
  https://developer.apple.com/download/all/.
You should download the Command Line Tools for Xcode 13.1.
```

指示通り sudo xcode-select --install すると以下のエラーが出た。

```
xcode-select: error: no developer tools were found, and no install could be requested (perhaps no UI is present), please install manually from 'developer.apple.com'.
```

結局 以下から Command Line Tools for Xcode 13.2 をとってきて install したら、brew が復活した
https://developer.apple.com/download/all/
Reactのメリット・デメリット

私はReactを学習している駆け出しのエンジニア。今日はReactのメリット・デメリットをしっかり理解すべく、備忘録として残していく。やっぱり、メリット・デメリットを理解して使わないといつまで経ってもエンジニアとしてひよっこのままだと思うので、、、。

早速、書いていくぅ！

## Reactのメリット

#### ①レンダリングが高速  
レンダリングとはWebページの描画を意味しており、Reactでは仮想DOMという技術が使用されています。Reactのレンダリングが行われるのは、変更前と変更後の仮想DOMを構築し変更差分を検出することで、DOMの構築が必要か判断します。変更に差分がない場合は、**DOMの更新は行われません。**  
更新が必要最低限となっているためReactのレンダリングのパフォーマンスは最適化され、高速になっています。
####  ②パーツを管理しやすいコンポーネントベース  
コンポーネントとは、構成要素や部品と言った意味を持っており、Reactでは全ての要素を部分ごとにコンポーネントに分けて管理します。それぞれを個別で管理することで、複雑なUIの管理を簡単にし、自由に開発することが可能です。小さいパーツで分けておくと管理がしやすく拡張性を上がります。また、再利用もできるので便利に開発できます。
#### ③JavaScriptで書ける  
JavaScriptのライブラリなので当たり前だがこれは非常に大きいなメリットです。Reactで採用されているJSX記法はJavaScriptの拡張構文であり、関数の戻り値にコンポーネントが指定できたり、内部のロジックの記述にJavascriptの記法ができるため、Javascriptの特性を最大限に活かした記述ができます。

## Reactのデメリット  
#### ①ページアクセス時の読み込みが長くなってしまう。  
　ReactはWeb動作を快適にするために、仮想DOMという技術が用いられています。仮想DOMはメリットがある反面、最初のアクセス時にデータの読み込みが長くなってしまいます。例えば、ニュース記事のページのように読むだけでほとんど操作をしないページはReactを使ってもあまり意味がなく、むしろ最初の表示に時間がかかるため、UX（ユーザー体験）は低下をしてしまう場合があります。一方、地図検索のように頻繁に操作をするようなウェブではReactを使うことでUXを大きく向上させることができます。
【Flutter】timezoneパッケージで日本時間取得

# 概要

「flutter_local_notification」パッケージ使用時に「timezone」パッケージを使用する必要があり、その際に日本時間の取得に躓いた為、取得方法をまとめた。

**flutter_local_notification**

https://pub.dev/packages/flutter_local_notifications

**timezone**

https://pub.dev/packages/timezone

# 現在時刻の取得方法

パッケージのインポート

```dart
import 'package:timezone/data/latest_all.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
```

初期化

```dart
// タイムゾーンデータベースの初期化
tz.initializeTimeZones();
// ローカルロケーションのタイムゾーンを東京に設定
tz.setLocalLocation(tz.getLocation("Asia/Tokyo")); 
```

現在時刻の取得

```dart
var now = tz.TZDateTime.now(tz.local)
```
tripwire とは

## 勉強前イメージ

見たときは全然わからんかった

## 調査

### tripwire とは

トリップワイヤと読み
サーバの状態や保存されたデータを監視して、変更を検知して通知する [IDS(不正侵入検知システム)](https://qiita.com/miyuki_samitani/items/b4676484119a89c00467) の一つです。
トリップワイヤ社の製品で、商用版が販売されていて
無償版はオープンソースで公開されています。

### 機能

クライアントサーバ型IDSで、
コンピュータ内のストレージに保存されたファイル等の変更を監視、
どのように変更されたかなど確認することができます。
不正に改ざんされた際はいぜんの状態に戻すことができる。

また、製品版はサーバが監視対象を一元管理・監視することができます。

### メリット

- セキュリティの強化

いつどこで何が変更されたかを確認することができます。
不正侵入検知だけではなく、オペミスの検知も確認することができます。

- 運用管理の向上

もしオペミスや不正侵入された際の被害箇所をすぐ確認することができます。
また、検知した変更が正しいのか、不正なのかを確認することもできます。

- コンプライアンスの証明

ポリシーに対する状況を自動的にレポートを出力することができます。

### 特徴

- エージェント型の検知

webのコンテンツの監視、OS・ミドルウェアのリアルタイム監視を行うことができます。

- 豊富なテンプレート

あらかじめ定義したデフォルトのテンプレートがあるので簡単に導入ができます。
また、固有の設定も行うことができます。

## 勉強後イメージ

tripwireを導入したら、変更されたかどうか見えるってことか。
リリース以外に変更されたらすぐ見つけることができるのね。

## 参考

- [tripwire](https://atmarkit.itmedia.co.jp/aig/06network/tripwire.html)
- [Tripwire](https://e-words.jp/w/Tripwire.html)
（非情報系・非電気系でも）エンベデッドシステムスペシャリスト試験に合格した

# 1. 自己紹介
SE職として新卒採用で入社して以来、組込みシステムの開発に携わってきました。
と言ってもハードウェアに近い部分はほとんど触ったことがありませんので、組込みエンジニアと呼べるのか怪しいものです。

# 2. 概要
令和3年度秋期のエンベデッドシステムスペシャリスト試験に合格しました。
![result.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501246/90474f16-8f9e-164a-6ee2-95c390f2bcef.png)

# 3. 受験時のレベル
|項目|情報|
|:-:|:-:|
|経歴|社会人5年目|
|学生時代の専攻|理系（非情報系・非電気系）|
|所有資格|FE・AP合格|

学生時代は情報処理と無縁の分野を専攻していましたので、入社してからシステム開発について勉強しました。
FEは3年目秋、APは5年目春に合格しました。

# 4. 受験した理由
同年春にAPを受験した後、次は高度区分のスペシャリスト試験を目指そうと考えていました。
最初は1年半の間を空けようと思っていたのですが、AP合格による午前Ⅰ免除のチャンスをその分逃してしまうこと、AP合格から半年で高度区分に受かればドヤ顔できることから、同年に受験することを決めました。
エンベデッドシステムスペシャリストを受けようと思ったのは、スペシャリスト試験の中で問題が一番面白そうだったからです。

# 5. 勉強方法
勉強を開始したのは5月上旬頃で、使用したのは以下の参考書と、公式サイトからダウンロードした過去問です。
[情報処理教科書 エンベデッドシステムスペシャリスト 2021~2022年版](https://www.amazon.co.jp/%E6%83%85%E5%A0%B1%E5%87%A6%E7%90%86%E6%95%99%E7%A7%91%E6%9B%B8-%E3%82%A8%E3%83%B3%E3%83%99%E3%83%87%E3%83%83%E3%83%89%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%B9%E3%83%9A%E3%82%B7%E3%83%A3%E3%83%AA%E3%82%B9%E3%83%88-2021-2022%E5%B9%B4%E7%89%88-%E7%89%A7-%E9%9A%86%E5%8F%B2/dp/4798167789/)

参考書を読んで分からない用語が出てきたらネットで調べて、理解が進めば次を読む、というのを繰り返していました。
最初は分からないことばかりで、1日に3ページ、休日を使っても1日10ページぐらいしか進められませんでした（仕事が忙しくてあまり時間を確保できなかったという事情もありますが）。

また、試験1か月前ぐらいから過去問を解き始めました。

# 6. 午前・午後対策

# 午前
午前Ⅰは免除により受験していませんので、午前Ⅱの対策のみ書きます。
受験勉強の項で記載したように、参考書を読み進めて知識を習得しましたが、試験までに全然理解できなかった部分は問題を暗記しました。

特にハードウェア関連は他の分野と比べてさっぱり理解できなかったので、問題文を暗記して挑みました（知識定着の観点から良くありませんが・・・）。

# 午後
午後問題は大きくソフトウェアとハードウェアに分けられるのですが、仕事でソフトウェアの開発をしていますので、ソフトウェアに絞って対策しました。
とはいえ扱うテーマが幅広すぎてどうしていいか分かりませんでしたので、とりあえず過去問を解きまくりました。

後は当日、適度な緊張によりアドレナリンが分泌され、集中力・思考力・発想力が突発的に向上するのを祈るのみです。

# 7. 感想
まさか初回で受かるとは思っていませんでした。人間やればできる。
PolarでRegtest Bitcoin/Lightningノードを大量生産する

ライトニングノードの設定をいろいろ試してみたり、作ったライトニングアプリの挙動をテストしたいとき、手元にRegtestのネットワークを立ち上げるのが非常に手間に感じていました。
大量のターミナルを立ち上げてるとどれがどれだかわからなくなってきますよね。

そこで、Polarというソフトを使うとGUIで手軽にRegtestモードのライトニングネットワークを立ち上げられると聞いて、早速使ってみました。

### Polarの導入方法
[GitHubからソースまたはバイナリをダウンロードします。](https://github.com/jamaljsr/polar/releases)

私はUbuntu環境だったので、バイナリはアーキテクチャによって`polar-linux-amd64-v1.3.0.deb`か`polar-linux-x86_64-v1.3.0.AppImage`のどちらかになりますね。

私はノートPCで実行したかったので、.AppImageの方をダウンロードしました。GUIで実行するので、ダウンロードフォルダ内のファイルをダブルクリックで起動…する前に、右クリックして「プロパティ」からファイルを実行できるように権限を設定しましょう。 コマンドラインから`chmod`コマンドを使ってもいいです。

### Polarの使い方

Polarが立ち上がると、早速ネットワークを作ろうと言われるので必要なノード数を選んで作成します。c-lightning、Lnd、Eclair、Bitcoin Coreから選びますが、後から追加することもできるので、あまり深く考える必要はありません。

選択すると画面が遷移し、ネットワーク図が表示されます。

![Screenshot from 2021-12-17 22-20-49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359045/025f362f-0883-c464-d7e6-9d3460501a28.png)

例えばこのネットワークにはBitcoin Coreのノードが1つと、それに接続したc-lightningノードが4つあります。

右上の「Start」を押すとそれぞれのノードがDockerイメージから起動します。初回はDockerイメージのダウンロードがあるので少し時間がかかります。

Bitcoinノードをクリックすると右側にメニューが出てきます。”Actions”タブから任意の数のブロックをマイニングしたり、コマンドラインを開いて直接操作したり、ログを確認できます。

Lightningノードもクリックすると右側にメニューが表示され、”Actions”タブから資金を追加したり、チャネルを開けたり、インボイスの発行や支払いができます。もちろんコマンドライン操作やログの確認も。

”Connect"タブにある情報を使ってローカル環境のLappsをつなぎ、動作確認することもできます！

また、チャネルの開閉はノードについている点をドラッグすることで視覚的に行なえ、バランスも視覚的に表示されます。下図はいくつかチャネルを開き、ペイメントを行った後のネットワークの様子です：

![Screenshot from 2021-12-17 22-27-26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359045/d96edf3c-d9cf-7674-3716-68d9df122bdc.png)

Polarを使うとRegtest上のLightning Networkを自由自在に構築できます。ぜひテストに活用してください。

ちなみに追記ですが、自分は自作のc-lightningプラグインのテストに使用したかったのですが、各ノードはそれぞれコンテナが独立しているため、それには別途特製のDockerイメージを作る必要がありそうです。特製のDockerイメージの追加や管理はメニューバー右上の”Manage Images"から行うことができるようなので、私もこれからチャレンジしてみます！
M1 Pro搭載MacBook ProでGeekbench5のベンチマークを出してみた

#はじめに
HCB Advent Clendar 2021の17日目を担当するKimです。
今回は，2019モデルMacBook ProとM1Pro搭載Mac MacBook Proのベンチマークを出してみました
#マシンスペック
２つのマシンスペックは以下の記事に書いてます！
https://qiita.com/QT21-004-5_HCB/items/da8efc1fa2ff7f55a49a
#使用したベンチマークソフト
- Geekbench5
    - CPU Benchmark
        - Single-Core
        - Multi-Core
    - Conpute Benchmark
        - Metal
        - OpenCL

https://www.geekbench.com

#スコア比較

|モデル|Single-Core|Multi-Core|Metal|OpenCL|
|:---:|:---:|:---:|:---:|:---:|
|2019|887|3308|6879|6973|
|M1 Pro|1340|10314|37257|33090|

###比較表
https://www.cpu-monkey.com/ja/cpu_benchmark-geekbench_5_single_core-13
https://www.cpu-monkey.com/ja/cpu_benchmark-geekbench_5_multi_core-14
#おわりに
今回は他にアプリを動かしながらのスコアなので，
理想値より実践値よりの認識ですが，5倍はとてつもないですね...
みんなもM1 Macを買おう！
Shopify 史上最大のアップデート Online Store 2.0 とは

Shopify Unite 2021 で発表された過去最大のアップデートの１つ Online Store2.0 の調査記事です。

https://unite.shopify.com/

# Online Store 2.0

> Online Store 2.0では、ストアのレイアウトとデザインのコントロールがこれまで以上に簡単になり、皆さまがより多くのデータにアクセスする自由性が拡大するので、お客様に卓越した体験を提供することができます。

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


### セクションとブロック

2.0 ではこれまで以上にストア内のページのカスタマイズがしやすくなりました。コンテンツの追加や編集、削除がコーディングなしでできるようになっています。

これは Liquid ファイルを JSON テンプレートファイルで管理し、セクションとブロックでカスタマイズ出来るようになったからです。
詳細は Shopify Japan の Junichi Okamura san が解説してくれています。

https://www.shopify.jp/blog/partner-theme-blocks

2.0 のテーマでは、テーマエディターから直接テンプレートが追加出来るため、マーチャント自身が技術的な専門知識（Liquidの知識）がなくともオリジナルのページを作れるようになりました。


### 新テーマ "Dawn"
[Dawn は Online Store 2.0 に対応した公式テーマ](https://themes.shopify.com/themes/dawn/styles/default?locale=ja)でオープンソースです。Shopify テーマ構築の[ベストプラクティスの設計](https://shopify.dev/themes/best-practices)となっており、2.0 の特徴であるセクション・ブロックや、メタフィールドの機能が備わっており、高速です。こちらも詳細は [Shopify Japan の Junichi Okamura san が解説](https://www.shopify.jp/blog/dawn-shopify-theme)してくれています。

https://github.com/Shopify/dawn

### メタフィールド
個人的に一番嬉しいアップデートが[メタフィールド](https://help.shopify.com/ja/manual/metafields)です。これまで API やコーディングが必要だったメタフィールドを、ノーコードで管理画面から直接編集・追加することが出来るようになりました。

百聞は一見に如かずなので 10:55-12:30 を見て下さい。

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

これまで、Shopify はデータ構造としては[「商品・注文・顧客」の３つを管理](https://qiita.com/t-kurasawa/items/8f8ac73014d73af8ac10#shopify-%E3%81%AE%E6%8A%80%E8%A1%93%E7%9A%84%E7%89%B9%E5%BE%B4)していました。このメタフィールドのアップデートによって「あらゆるデータ」を Shopify 上で管理出来るようになります。これは革新的ですね。

メタフィールドで利用したくなる項目をあげていけば、「型番」「関連商品」「公開日」「賞味期限」・・・などいくらでも考えつきますね。

https://help.shopify.com/ja/manual/metafields

https://shopify.dev/apps/metafields


### テーマエディタ・開発者ツール
- テーマエディタのサイドバーにページ内のすべてのコンテンツがツリー状に表示されるようになり、使いやすくなった
- Shopify CLI がアップデートされ GitHub と統合。プレビュー、テーマチェックの実行が出来るようになりよりモダンな開発が可能に


## さいごに
いかがでしたでしょうか。私も年の瀬にしっかりと 2.0 にアップデート出来ました。
以上で [Shopify Advent Calendar 2021](https://qiita.com/advent-calendar/2021/shopify) 18日目の記事を終わります。

Make Commerce Better for Everyone !!

### 参考記事

https://www.shopify.jp/blog/unite-2021

https://www.shopify.jp/blog/partner-shopify-online-store
スキャンしたPDFのテキスト起こし(OCR)を大量に一気にやってみた

## 目的
本プログラムは複数ディレクトリに保存された各PDFファイルをOCRし、.txt形式で保存することを目的としています。
テキストを取り込んでNLPにかけたいときなど、Rで一気にやれると楽なので作ってみました。
## こんな感じのディレクトリ構造を想定しています
こんな感じで整理してください

```
  カレントディレクトリ
  |--ディレクトリA
  |    |--PDFファイルa1
  |    |--PDFファイルa2
  |    |--PDFファイルa3
  |
  |--ディレクトリB
  |    |--PDFファイルb1
  |    |--PDFファイルb2
  |    |--PDFファイルb3
  |
  |--ディレクトリC
       |--...
```
### まずはパッケージのインストールなどをします
OCRのパッケージは精度が高めなtesseractを使います。なお、そのままだと日本語を認識しないため、日本語パックを使えるようにします。

```{R}
install.packages("tesseract")#OCRのパッケージ
install.packages("Rcpp")#tesseractを利用するための依存パッケージ
library(tesseract)
tesseract_download('jpn')#日本語パックをダウンロード
```

正常に動いているか確認します。

```{R}
>tesseract_info()
$datapath
[1] "C:\\Users\\XXXXXXX\\AppData\\Local\\tesseract4\\tesseract4\\tessdata/"

$available
[1] "eng" "jpn" "osd"

$version
[1] "4.1.1"

$configs
 [1] "alto"             "ambigs.train"     "api_config"       "bigram"           "box.train"        "box.train.stderr"
 [7] "digits"           "get.images"       "hocr"             "inter"            "kannada"          "linebox"         
[13] "logfile"          "lstm.train"       "lstmbox"          "lstmdebug"        "makebox"          "pdf"             
[19] "quiet"            "rebox"            "strokewidth"      "tsv"              "txt"              "unlv"            
[25] "wordstrbox" 
```
$availableに"jpn"が含まれていれば日本語パックのインストールは成功です。

## ではやっていきましょう
今回はEドライブの'PDFバックアップ'というディレクトリで実行しました。
tesseractの挙動は、  

  + PDFの各ページ個別に.pngファイルを生成する  
  + .pngファイルを生成後にOCRを実行する  

という挙動なので実行後に大量のpngファイルが残ります。なのでfor文の最後にpngファイルを消すスクリプトを書いています。

```{R}
current_dir <- "E:/PDFバックアップ/"
setwd(current_dir)
pdf_dir <- c(list.files()) #PDFを取得するディレクトリの一覧表を取得

for (j in 1:length(pdf_dir)){
  setwd(paste(current_dir,pdf_dir[j], sep=""))
        for (i in 1:length(pdfdata)){
          write(ocr(pdfdata[i], engine ="jpn"), paste(pdfdata[i],".txt", sep=""))
        }
  png_files <- c(list.files(pattern=".png"))
  file.remove(png_files)
}

```

## 参考にさせていただいた投稿
- [RでOCRしてみる（Tesseractパッケージ）](https://qiita.com/mamamashio/items/b3a1e24df31fbfd6ea93)