OmniAICreator/Qiita-1.07M huggingface dataset:
SpringBoot のapplication.propertiesで設定したdatasourceの一部を実行時に変更する方法

背景：
　application.propertiesで以下のdatasourceを設定していますが、
<pre>
     spring.datasource.driver-class-name=org.postgresql.Driver
     spring.datasource.url=jdbc:postgresql://localhost:5432/spring-sample
     spring.datasource.username=test
     spring.datasource.password=test
</pre>
SpringBoot起動時に、spring.datasource.urlを動的にApplicationNameを設定したいです。

解決方法は二つあります。

*方法１.  @Configuration を使用する*

```DataSourceConfig.java
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class DataSourceConfig {
	
	@Value("${spring.datasource.url}")
	private String url;
	
	@Value("${spring.datasource.username}")
	private String username;
	
	@Value("${spring.datasource.password}")
	private String password;
		
	@Bean 
	public DataSource getDataSource() { 
	    DataSourceBuilder<?> dataSourceBuilder = DataSourceBuilder.create(); 
            // url　にApplicationNameを追加する
	    dataSourceBuilder.url(url + "?ApplicationName=MyApp");
	    dataSourceBuilder.username(username); 
	    dataSourceBuilder.password(password); 
	    return dataSourceBuilder.build(); 
	}
}
```

御覧の通り、この方法では、変更不要のusernameとpasswordも設定する必要です。
今度、application.propertiesにdatasorceの設定を追加するたびに、
このクラスも併せて修正しないといけません。

*方法２．BeanPostProcessor　インタフェースを実装する*

```DataSourcePropertiesPostProcessor.java
import org.springframework.beans.factory.config.BeanPostProcessor;

@Component
public class DataSourcePropertiesPostProcessor implements BeanPostProcessor  {	
	@Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if (bean instanceof DataSourceProperties) {
        	DataSourceProperties properties = (DataSourceProperties) bean;
            String url = properties.getUrl();
            properties.setUrl( url + "?ApplicationName=MyApp");
        }
        return bean;
    }
}
```

方法1と比べると、スマートしコードもすっきりになりました。
開発環境にRailsをインストール・新規アプリ作成

>引用先
>[Railsチュートリアル](https://railstutorial.jp/)

#Railsをインストール

###Rubyドキュメントをインストールしないよう.gemrcファイルを設定

```
$ echo "gem: --no-document" >> ~/.gemrc
```

Railsをインストールするには、gemコマンドを使います。
Rubyドキュメントのインストールで無駄な時間を使わないよう、コマンドに設定を追加しています。

###バージョンを指定してRailsをインストール

```
$ gem install rails -v 6.0.3
```
バージョン6.0.3でインストール

```
$ rails -v
# Rails 6.0.3
```
バージョンの確認（指定してインストールした場合は合っているか確認）

###JavaScriptソフトウェアの依存関係を管理するYarnをインストール

```
$ source <(curl -sL https://cdn.learnenough.com/yarn_install)
```

####※警告メッセージがでた場合

```
========================================
  Your Yarn packages are out of date!
  Please run `yarn install --check-files` to update.
========================================
```

```
$ yarn install --check-files
```
上記を実行でOK

***
#新規アプリ作成

###Railsプロジェクト用のenvironmentディレクトリを作る

```
$ cd                    # プロジェクトのホームディレクトリに移動
$ mkdir environment     # environmentディレクトリを作成
$ cd environment/       # 作成したenvironmentディレクトリに移動
```

#rails newを実行

```
$ rails _6.0.3_ new <アプリ名>
```

###各フォルダの役割
>引用先
>[Railsチュートリアル 表 1.2: デフォルトのRailsディレクトリ構成の概要](https://railstutorial.jp/)

|ディレクトリ|用途|
|---|---|
|app/|モデル、ビュー、コントローラ、ヘルパーなどを含む主要なアプリケーションコード|
|app/assets|アプリケーションで使うCSS（Cascading Style Sheet）、JavaScriptファイル、画像などのアセット|
|bin/|バイナリ実行可能ファイル|
|config/|アプリケーションの設定|
|db/|データベース関連のファイル|
|doc/|マニュアルなど、アプリケーションのドキュメント|
|lib/|ライブラリやモジュール置き場|
|log/|アプリケーションのログファイル|
|public/|エラーページなど、一般（Webブラウザなど）に直接公開するデータ|
|bin/rails|コード生成、コンソールの起動、ローカルのWebサーバーの立ち上げなどで使うRailsスクリプト|
|test/|アプリケーションのテスト|
|tmp/|一時ファイル|
|README.md|アプリケーションの簡単な説明|
|Gemfile|このアプリケーションに必要なGemの定義ファイル|
|Gemfile.lock|アプリケーションで使われるgemのバージョンを確認するためのリスト|
|config.ru|Rackミドルウェア用の設定ファイル|
|.gitignore|Gitに取り込みたくないファイルを指定するためのパターン|

#Bundlerを実行
bundlerとは、gemのバージョンやgemの依存関係を管理してくれるgem。
bundlerを使うことで、複数人での開発やgemのバージョンが上がってもエラーを起こさずに開発できます。

###Gemfileに使用するgemを記入する
各開発環境によって使用するgemは異なるため必要なgemを記入する。
(例 bootsnap,byebug等）

###bundleをインストール
```
$ cd hello_app/
$ bundle install
```
エラーで[bundle update]と出たら、bundle updateを先に実行

***

ここまでが環境構築となります。
【Ruby on Rails】EC2でwheneverを使ってcrontabを設定する時のハマったことの解決

wheneverというのはRuby on Railsのgemであり、crontabを設定する時によく使われています。


# 使い方
使い方は[Githubホームページ](https://github.com/javan/whenever)に詳しく記載されていますが、主に使うのは下記になります。

**Gemfileに追加**

```ruby:Gemfile
gem 'whenever', require: false
```

**インストール**

```
bundle exec wheneverize .
```

**schedule.rbファイルの内容を確認する**

```
whenever
```

**開発環境でcrontabを更新する**

```
whenever --update-crontab --set environment='development'
```


# Capistranoに入れる

```ruby:config/deploy.rb
set :whenever_roles, -> { :app }
```

```ruby:Capfile
require 'whenever/capistrano'
```


# ハマったことなどの解決

### EC2では動かない

EC2にデプロイの後、crontabが動かず、ログ確認したらBundleバージョンが間違いなどの問題

job_typeを以下に設定すれば良い

```ruby:config/schedule.rb
set :output, environment == 'development' ? 'log/crontab.log' : '/deploy/apps/<アプリ名/shared/log/crontab.log'
job_type :rake, 'export PATH="$HOME/.rbenv/bin:$PATH"; eval "$(rbenv init -)"; cd :path && RAILS_ENV=:environment bundle exec rake :task :output'
```

### 時間通りに動かない

タイムゾーンが間違い可能性が高いです。

タイムゾーン設定方法は：

```ruby:config/schedule.rb
require 'active_support'
require 'active_support/core_ext/time'

def jst(time)
  Time.zone = 'Asia/Tokyo'
  Time.zone.parse(time).localtime($system_utc_offset)
end

every 1.day, at: jst('6:00 am') do # 日本時間毎朝6時に実行
  rake 'example:task'
end
```

### crontabのログにExecJS::RuntimeUnavailable エラーが出たとき

```
Could not find a JavaScript runtime. See https://github.com/rails/execjs for a list of available runtimes. (ExecJS::RuntimeUnavailable)
```

Gemfileに`mini_racer`を追加すればいいです。`therubyracer`でも大丈夫ですが、Macにはインストールが難しいので`mini_racer`を使います。
【Netlify】SPAサイトで簡単にOGPを付ける。

私は普段Nuxt.js(Vue)を使ってサイトを書いていますが、SPAサイトの一番大きな問題はTwitterでOGPがつかない事だと思っています。しかしながらOGPを付けるという目的のためにNuxt.jsでSSR(サーバーサイドレンダリング)する事は間違っていると考えています。理由としては、コストや安定性です。
その中でかなり悩んでいましたが、NetlifyにPrerenderingという機能がありました。今回はこの機能を用いてSPAサイトにOGPを付けていきたいと思います。**無料です。**

# 結果
まず初めに実際の結果です。かなり良いのではないでしょうか。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">【超難問AIテスト】<br>あなたの成績は3/5 問正解です！。もしかして未来人？？<br> <a href="https://t.co/1vN6gitUmy">https://t.co/1vN6gitUmy</a> <a href="https://twitter.com/hashtag/%E8%B6%85%E9%9B%A3%E5%95%8FAI%E3%83%86%E3%82%B9%E3%83%88?src=hash&amp;ref_src=twsrc%5Etfw">#超難問AIテスト</a><br>全問正解できひんかった</p>&mdash; ゆうもや (@takex5g) <a href="https://twitter.com/takex5g/status/1348584096717410305?ref_src=twsrc%5Etfw">January 11, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# Netlify Prerenderについて
Netlifyはgit pushでホスティングできる事でお馴染みのサービスです。HerokuやGithubPagesと同じ感じです。Netlifyの機能としてPrerender機能が提供されていました。Prerenderとは、予めNetlifyがjavascriptも実行させた静的キャッシュを取っておくことで、SPAの動的OGPも表示させるものです。
もしbot(Twitterクローラなど)の場合はprerenderさせたキャッシュしたページ、人間がアクセスした時は普通にページを表示させます。現在Netlifyではbeta版として提供されています。**料金は無料です。**その他のprerenderについての詳細は[公式ドキュメントを見てください。](https://docs.netlify.com/site-deploys/post-processing/prerendering/)
![prerender-example.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87186/3d99de64-e85e-d74a-4982-2395ceafb41f.png)

# 実装方法
### コード側の設定
Nuxtでの動的OGPの例です。特に難しい事はせず、headerのogpを書き換えているだけです。ここについては他の記事を見てください。SSRでOGP表示する例とかもそのまま流用出来るはずです。

```vue:index.vue
(抜粋)
  head() {
    return {
      meta: [
        {
          hid: "og:image",
          property: "og:image",
          content: "https://www.example.com/ogp/" + this.img + ".png",
        },
      ],
    };
  },
```

### Netlify側の設定
NetlifyのSettingにおいて、PrerenderingをEnableにします。
![2021-01-15_23h08_52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87186/4c666ff4-8108-278d-89be-adc46df804ac.png)

これで表示されるはずです。[TwitterValidator](https://cards-dev.twitter.com/validator)で確かめてみましょう。
# 所感
もうSPA時代のOGPはこれで良いなと思いました。firebaseFunction使ったり,SSRしたりと他にも方法はありますが、圧倒的にこの方法が楽でした。**無料ですし。**
気になる点は
・キャッシュのタイミングがわからない。（ブラックボックス）
・キャッシュを手動削除できない。（OGP画像を変えても前の画像が残る）
という点です。まぁこのくらいは目をつぶれるかなぁという感じです。**無料ですし。**

是非素敵なOGPライフを!


あ、もし時間があったら、AI/人間見分けるテストやってみて。OGPちゃんとつきますし。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">AIはここまで人間に近づきました。<br>合成音声か人間かを見分けるゲームです。<br><br>マジで難しいので挑戦してみてください！！！<a href="https://t.co/DSPxngYerM">https://t.co/DSPxngYerM</a> <a href="https://twitter.com/hashtag/%E8%B6%85%E9%9B%A3%E5%95%8FAI%E3%83%86%E3%82%B9%E3%83%88?src=hash&amp;ref_src=twsrc%5Etfw">#超難問AIテスト</a></p>&mdash; ゆうもや (@takex5g) <a href="https://twitter.com/takex5g/status/1348577010524688390?ref_src=twsrc%5Etfw">January 11, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
next.js heroku デプロイ　Error: Couldn't find that app.

next.jsをherokuにデプロイする日本語記事が見当たらなかったため投稿しました。

環境：
node.js
react
next.js

herokuへpushまでは省略します。
push後urlへアクセスすると拒絶されたところから
ログを確認してから出直せと言われたので、

```terminal
heroku logs -tail
Error: Couldn't find that app.
 ›
 ›   Error ID: not_found
```

で、結論から
https://github.com/mars/heroku-nextjs
を参考にしました。

```package.json
{
  "name": "next-yaninavi",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "next",
    "build": "next build",
    "start": "next start -p $PORT"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "next": "^10.0.5",
    "react": "^17.0.1",
    "react-dom": "^17.0.1"
  }
}
```

```procfile
npm run build
NODE_EV=production npm run start
```
heroku触ったことなかったのでビクビクしてたけど、ngrokみたいな感じかな
恐らく、localhostとurlを繋いでるけどそのルート記述が間違ってたのかな。。

理解したら追記します！
React Hooks ~ State Hookの使い方 ~

React を触っていて学んだことをまとめていきます。

## React Hooks とは

これを用いることで、クラスコンポーネントでこれまで利用されてきたReactの機能を関数コンポーネントでも利用できるようになります。

React は長年書かれるうちに、シンプルに簡潔に書くこと、テストの容易性から、関数コンポーネントで書くことが主流になった。
しかし、当時の関数コンポーネントは React のライフサイクルメソッドなどを利用することができず、クラスコンポーネントの利用や併用、ライブラリの利用で解決していた。

React v16.8 でReact Hooks が導入された。
React Hooks がもたらした恩恵は

- コンポーネントがシンプルになる
- 関数として、コンポーネントからロジックを抽出、使い回しが用意になる。
- class の `this` に悩まされなくなる

## State Hook とは

コンポーネントに状態(State)を持たせたいときに利用する。
State は設定したコンポーネント内でのみ呼び出しができる。もし他コンポーネントにpropsとして渡してあげれば他コンポーネントからの表示、更新などが可能ではある。

## State Hook の使い方

シンプルに書くならこんな感じで利用できる。

```jsx
// useState を import する。
import { useState } from 'react'

const  CountButton = () => {
   // State の変数、更新のためのメソッド名を定義する。
   // useState(0) で State の初期値を設定できる。
   const [count, setCount] = useState(0)
   return (
    <div>
      {// 変数名で呼び出しができる。
      }
      <button onClick={() => setCount(count + 1)}>{count}</button>
    </div>
  )
}
```

## TypeScript との併用

TypeSctipt との併用も、問題なく利用ができます。

```tsx
const [count, setCount] = useState<number>(0)
```

## 子コンポーネントから、親コンポーネントの状態を更新する。

子コンポーネントに、propsとして、状態の値、コールバック関数を用いることで可能です.
こうすることで、他のコンポーネントでも再利用が可能な子コンポーネントの作成ができそうです。

```tsx:App.tsx(親コンポーネント)
import React, { useState, useCallback } from "react"
import { InputForm } from "./InputForm"

export default function App() {
  const [ content, setContent ] = useState<string>("test")

  const onChangeContent = useCallback(
    (event: React.ChangeEvent<HTMLInputElement>) => {
      setContent(event.target.value)
    },
    [],
  )

  return (
    <div className="App">
      <InputForm content={content} onChange={onChangeContent} />
      <span>{content}</span>
    </div>
  )
}
```

```tsx:InputForm.tsx(子コンポーネント)
import React from "react"

interface Props {
  content: string;
  onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
}

export const InputForm = (props: Props) => {
  return <input defaultValue={props.content} onChange={props.onChange}></input>
}
```

[codesandbox](https://codesandbox.io/s/cranky-wind-i9s21?file=/src/InputForm.tsx:0-260) に実際にうごく様子を公開しています。
DXRuby 1.4.7 でエラーになった時の対処法とインストール方法

Windows向けのRuby用2Dゲームライブラリ「DXRuby」が1.4.7にバージョンアップして、最新のRuby 3.0.0に、そしてついに64bit版Rubyに対応しました。ただし、Windows10で使う場合、エラーになって焦ったので、注意点をメモしておきます。

- [DXRuby HP](http://dxruby.osdn.jp)
- [DXRuby GitHub](https://github.com/mirichi/dxruby)

→ 以前の記事
[DXRuby 1.4.6 をWindows10で使う時の注意点とインストール方法](https://qiita.com/noanoa07/items/0ce14c2404df38de94b7)

# 注意点
## ・ DXRubyは、Windowsでないと動かない
WindowsのDirectXを使うので、macOS、Linuxでは動きません。
Windows環境以外で、DXRubyとほぼ同じコードで動くようにするライブラリとしては、「[DXOpal](https://yhara.github.io/dxopal/doc/ja/index.html)」や「[Nyle-canvas](https://spoolkitamura.github.io/nyle-canvas/)」などがあります（ただし、完全互換ではない）。

Rubyのインストールには、「[RubyInstaller for Windows](https://rubyinstaller.org)」が便利です。DXRuby 1.4.7からは、64bit版Ruby（`"x64"`と書いてある版）に対応しました。
Devkit（MSYS2）付きでなくても、DXRubyはかまいません。

## ・ 64bit版では、Sound.newでエラーになる
→・[[DXRuby 1.4.7] 64bitでは、Sound.newでエラー · Issue #4 · mirichi/dxruby](https://github.com/mirichi/dxruby/issues/4)


## ・ Windows10では、d3dx9_40.dllを追加しないと動かない
これが原因で、DXRubyをインストールしたのに実行するとエラーが出て焦りました。

DXRubyでは、Windowsの`DirectX 9`ライブラリを使っています。（なので、Windows以外では動かない。）
Window10から、`DirectX 9`が付属しなくなったので、自分で追加する必要があります。

参考）
→・[Windows10では、DXRubyを動かすのに d3dx9_40.dllが必要 · Issue #3 · mirichi/dxruby](https://github.com/mirichi/dxruby/issues/3)

### ※ d3dx9_40.dllのインストール方法
`d3dx9_40.dll`は、公式のMicrosoftのサイトからダウンロードするのが安全。

1. `DirectX End-User Runtimes(June 2010)`をダウンロードする。
https://www.microsoft.com/en-us/download/details.aspx?id=8109

2. ダウンロードした `directx_Jun2010_redist.exe`をダブルクリック。
適当なフォルダを指定して、解凍する。

3. 必要なのは `d3dx9_40.dll`だけなので、解凍先のフォルダの中からRubyの64bit/32bitに合わせて必要なファイルを探す。
・`64bit版`Ruby（x64）　　　；`Nov2008_d3dx9_40_x64.cab`
・`32bit版`Ruby（x86、i386）；`Nov2008_d3dx9_40_x86.cab`

4. `Nov2008_d3dx9_40_x64.cab` または `Nov2008_d3dx9_40_x86.cab`をダブルクリックする。

5. 中の `d3dx9_40.dll`をダブルクリックして、適当なフォルダを指定して解凍する。

6. 解凍先のフォルダに `d3dx9_40.dll`ができる。

7. できた `d3dx9_40.dll`を Windowsのフォルダにコピーする。
やり方は2通りある。

　a）インストールしているRubyのフォルダの中の、binフォルダにコピーする。
　　　`C:\Ruby30-x64\bin` など

　b）Windowsのプログラムフォルダにコピーする。

　　・`64bit版`の d3dx9_40.dllの場合；
　　　`C:\Windows\System32`フォルダ（こちらが`64bit用`プログラムフォルダ）

　　・`32bit版`の d3dx9_40.dllの場合；
　　　`C:\Windows\SysWOW64`フォルダ（こちらが`32bit用`プログラムフォルダ）

　　　※プログラムフォルダ名が一見すると逆なので注意！

　　　> 「対象のフォルダーへのアクセスは拒否されました
　　　> 　このフォルダーへコピーするには管理者の権限が必要です」

　　　とパネルが出るので、
　　　`続行`ボタン
　　　を押すとコピーされる。

8.（必要ならWindows を再起動する。）

# DXRubyのインストール方法
DXRuby 1.4.7のインストールは、RubyGemsからできます。

```bash
> gem install dxruby
```


# DXRubyが動作するかの確認

```bash
> irb
irb(main):001:0> require 'dxruby'
=> true
irb(main):002:0> exit
```

`true`と表示されればOKです！

### 参考）
→・[グラフィックプログラミングにチャレンジしよう - Rubyではじめようプログラミング - コカネット（子供の科学 WEBサイト）](https://www.kodomonokagaku.com/experience/programming/9729/)
【Windows10】VScodeからリモートサーバ上のファイルを直接編集する方法

## はじめに
「Visual Studio Code Remote - SSH extension」というVSCodeの拡張機能を利用することで、サーバ上のファイルを直接編集できます。

## 環境
Windows10 ver2004
VSCode ver1.52.1

## 手順1. OpenSSHをWindows10にインストールする ※インストール済みなら不要
以下に詳細が記載されています。
https://docs.microsoft.com/ja-jp/windows-server/administration/openssh/openssh_install_firstuse
「PowerShell を使用した OpenSSH のインストール」

## 手順2. Visual Studio Code をインストールする ※インストール済みなら不要
以下からダウンロードすることが可能です。
https://code.visualstudio.com/

## 手順3. Remote Development extension pack をインストールする
以下を参照すると、Remote Development extension packは、①Remote - SSH、②Remote - Containers、③Remote - WSLの3つになります。
https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack

今回は、リモートサーバ上のファイルをSSH接続した上で編集したいため、上記①を利用します。
インストール後、VSCodeのアクティビティバーに「リモートエクスプローラー」という機能が表示されます。

## 手順4. 接続元PCのssh設定ファイルを編集する。
Windows10であれば、通常「C:\Users\ユーザ名\\.ssh\」にconfigファイルが配置されていると思いますので、そのファイルを以下のように編集します。※編集はVSCodeで行うと楽です。XXXはユーザー環境に合わせて修正して下さい。

```
Host XXX.XXX.XXX.XXX ※接続先IPアドレス
  HostName XXX.XXX.XXX.XXX ※接続先IPアドレス
  Port 22
  User user1 ※ユーザ名
  IdentityFile ~/.ssh/XXX.pem ※秘密鍵
```

## 手順5 リモートサーバに接続
VSCodeのアクティビティバーに「リモートエクスプローラー」から「SSH TARGETS」上で+ボタン(Add New)を押下し、「ssh user1@XXX.XXX.XXX.XXX」を入力しエンターキーを押下する。
「SSH TARGETS」配下に追加した接続先IPアドレスが表示されるので、その右側の別Windows表示ボタンを押下すると接続が可能になります。
その後、編集先フォルダパスに移動することでリモートサーバ上でファイルを直接編集することが出来ます。

## 参考
以下を参考にしました。
https://code.visualstudio.com/docs/remote/ssh
https://docs.microsoft.com/ja-jp/windows-server/administration/openssh/openssh_install_firstuse
https://code.visualstudio.com/
https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack
Git関連お役立ちリンク集

qiita初心者なので書き練習も含めSourceTreeを導入して、Gitを使うのに参考になったリンク集

* Gitのインストール方法
    * [いまさらGit for Windowsのインストール、GitHubに接続してみた。](https://qiita.com/manabu-watanabe/items/ecf1b434baf305adaa00)

    インストール時に専用エディタを選択させるので、Visual Studio CodeやAtomなど入れると良い。

* SourceTreeインストール方法    
    * [SourceTreeインストール手順＜Windows向け＞]
    (https://sukkiri.jp/technologies/devtools/git/sourcetree_win.html)
    * [git clone 出来ない( ﾉД`)…おぉー！出来たー( ;∀;)!!!](https://qiita.com/tedkuma/items/3b539e79010a4808337c)
    * [SourceTreeでGithubの認証に秘密鍵を使う (Windows)](https://qiita.com/reflet/items/4f7b5c4a312bc27df10e)
    * [Sourcetreeで変更内容をコミット、プッシュする](https://aadojo.alterbooth.com/entry/2020/04/13/101221?utm_source=feed)
    * [Sourcetreeでマージしよう](https://yttm-work.jp/git/git_0012.html#head_line_01)

     SourceTreeでバージョン管理を行う(commit, merge等）

* GitHubの使い方
    * [今さら聞けない！GitHubの使い方【超初心者向け】](https://techacademy.jp/magazine/6235#sec3)

qiitaって、普通の文章のインデントできないのかな・・。現状空白のみ？
[[Qiita]タブキーでインデントしたい](https://qiita.com/aosho235/items/cb3757be998ae69d3cdf)
オートフィルタで抽出した行を削除しデータをスリム化する方法

今回の目的は
何十万行と存在する大量のデータから必要なデータだけを残して
不要なデータを削除する方法。

ちなみにこの大量のデータは１ファイルではなく、複数のExcelファイルに
分かれているため、単一のファイル処理だけでは追いつかない。

今回行ったことは下記の通り。
１．不要なデータを抽出する指標のデータを用意
２．オートフィルタ機能を利用して不要なデータを抽出
３．不要なデータが入力された行を全て削除
４．オートフィルタを解除し必要なデータだけが残る。
上記１〜４の処理をフォルダ内の全てのExcelファイルに対して行う。
（繰り返し処理）

Sub Sample()
Dim LastRow As Long
Dim LastColumn As Long

' 指標の列を作成
Worksheets("Sheet1").Activate
    LastRow = Range("A" & Rows.Count).End(xlUp).Row '上方向に最終行を検索する
    LastColumn = Cells(7, Columns.Count).End(xlToLeft).Column + 1 '左方向に最終列+1を検索する
    Cells(5, LastColumn).Value = "指標"
    Cells(6, LastColumn).Value = "単位"
    Cells(7, LastColumn).Value = "=ABS(RC[-3]-RC[-1])"
    Range("J7").AutoFill _
        Destination:=Range(Cells(7, LastColumn), Cells(LastRow, LastColumn))
    
 ' オートフィルタで抽出した行を削除
    Range(Cells(6, 1), Cells(6, LastColumn)).AutoFilter LastColumn, ">2.9"
            With Range("A6").CurrentRegion.Offset(5, 0)
                    .Resize(.Rows.Count - 1).EntireRow.Delete
            End With
            ActiveSheet.ShowAllData
            
End Sub

以上です。
nuxtで書いたコードをGASで使えるよう変換

# 概要

- nuxtで作成したファイル（vueコンポーネント形式）をGASで利用できる形（x-template形式）に変換する
- これ自体がnuxtで動くプログラム。個人で使うなら自分のPCでローカルホストを立ち上げ、変換されたコードをコピペして使えば良い。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321960/a380411c-a582-8302-9461-ee5b9db562c7.png)


# 開発背景

- GASでフロントサイドを書くにあたって、GASのエディタはお世辞にも使いやすいとは言えません（最近のアップデートでだいぶ使いやすくはなりましたが）
- 多分GAS開発者の多くがしているように、claspで作成してGASにプッシュする方法がありますが、claspプッシュしてWebページをリロードして、、、というのは地味に面倒ですし、エラーが見つけにくいという欠点もあります。
- そこで、私はnuxtでUIをある程度作ってから、GASのhtmlファイルにコピーする方法をとっています。
- nuxtで作ったファイルをそのままコピーできれば良いのですが、nuxtはコンポーネントを.vue形式で作成するのに対して、GASでは.html形式にする必要があること、コンポーネントの書き方はnuxtは<template>〜</template>とexhast defaultに対してGASではx-templateを使った書き方であるなど、いくつかの修正する必要があります。
- もともとはこれらの作業を手でやっていましたが、コンポーネントファイルが多くなってくると面倒なので、プログラム化しました。

# 設計

## ユーザー操作

- ブラウザでnuxtアプリのフォルダをアップすると、html形式にしてダウンロードできるようにします。
- テキストの編集は全てjavascriptで実装しました。

## nuxtとGASの違い

- ファイル形式について、nuxtではコンポーネントファイルが.vue形式、一方でGASでは.html形式
- コンポーネントの書き方について、nuxtではHTMLに相当する部分を<template>で括りjavascriptをexport defaultで読み取れるようにしている。一方でGASのhtmlファイルでは、HTMLの部分を`<script type="text/x-template">`で括り、ローカルコンポーネントを変数に入れて親コンポーネントで読み取れるようにしている

## nuxt → GASへの変換

### componentsのファイル

1. ファイル名をsomething.vueからsomething.htmlに
2. `<template>`の部分を`<script type="text/x-template" id="something">`に
3. export default"を"const something =" に
4. template = "#something", を追加

### pagesのファイル

1〜4まではcomponentsと同じ

5. import ChildComponent from "~/components/ChildComponent.vue"を削除

### layoutsのファイル

- 私の開発ではSPAで作成しており、layouts/index.htmlは以下のような構造

```html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
      <?!= include("config") ?>
  </head>
  <body>
  <?!= include("components/EditComponent") ?>
  <?!= include("components/ImportMailList") ?>
  <?!= include("components/MailListHead") ?>
  <?!= include("components/MailPreview") ?>
  <?!= include("components/VarConfig") ?>

  <?!= include("pages/mailer") ?>

  <div id="app"></div>

  <script>
    new Vue({
      vuetify: vuetify,
      render: h => h(mailer)
    }).$mount("#app")
  </script>
    
  </body>
</html>
```

# 工夫点

## フォルダのアップロードとファイルの処理

- フォルダのアップロードにはinputタグにwebkitdirectry属性を追加する
- webkitdirectoryでフォルダをアップした後で、各ファイルを処理する方法は以下参照

```jsx
<template>
  <input type="file" @change="upload($event)" webkitdirectory>
</template>

<script>
(vue methods)
async upload(event){
      //ファイル一覧の取得と各ファイルの処理
      const files = event.target.files
      for(const file of files){
        //ファイルパスの取得
        const path = file.webkitRelativePath;

				//ファイルの読み取り等はPromiseを用いて同期処理すること
				const text = await this.editFile(file)
      }
},
editFile(file){
  return new Promise((resolve,reject)=>{
    const reader = new FileReader()
    reader.readFileAsText()
    reader.onload = function(e){
      const text = e.target.result
      resolve(text)
    }
  })
}

</script>
```

## nuxtのファイル一覧から必要なファイルの絞り込み

- nuxtのフォルダをアップすると、2万強のファイルがアップされる。
- そのうち、必要なvueファイルを絞り込むには以下のようにする

```jsx
const path = file.webkitRelativePath;
//不要なファイルをフィルタリング
if(!path.includes(".vue"))continue;
if(path.includes(".nuxt"))continue;
if(path.includes("node_modules"))continue;
```
ネタ・投資の「72の法則」は、「５年で億り人」となるための近似式ともなる（株式・先物３年生）。

久々のポエム。

老後に備え、億り人になっておこうと決意して、約2.5年（いろいろ損して得した・・・遠い目）。
ようやくに勝ちの方程式が見えてきたので、新年の目標として、*あと５年で億り人になろう*と考えた。
原資は100万円（年金代わりに積み立てているiDeCoの分は除く）。５年に特に根拠はない。

そうした時に、古来からいつつたえのある実に文系的（？）な「72の法則」、あるいは、「倍加時間」なるものを目にした。
以下のようなもの（ネットにいろいろ転がっている）
https://www.bank-daiwa.co.jp/column/articles/2017/2017_43.html

なんじゃこりゃと思い、コードを書く前に、Wikipediaを確認すると、以下のように冷静な解説が。
> 式は以下の通り。
年利（単位：%）× 年数（単位：年） = 72.
上記の式の「年利 (%)」に年利率（複利）を当てはめると元本が2倍になるのに必要な年数が求められる。逆に、「年数」に運用年数を当てはめると元本が2倍になるのに必要な年利が求められる。上記式は年利 (%) = 8% 付近で誤差が最も小さい。

出典 [72の法則](https://ja.wikipedia.org/wiki/72%E3%81%AE%E6%B3%95%E5%89%87)


なるほど、利率8%程度で近似的に成り立つ法則なのね、と納得。

一応、8%近傍をコードで検証してみる（小数点の誤差はさておく）。

```.py
#月あたりのリターン
r=0.0797751629    
N = 0.72 / r

#初期資金
init =100
print (f"月{r*100}%で運用した場合、資産2倍には72の法則だと約{N}月必要だというが...")

s = init
n = int(N)
for  x in range(1, 10*n):
    s = s*(1+r)
    if x % 10 ==0:
        print(f"{x}月目　:　原資{init}万円が、{s}万円に")

```


> 月7.9775162900000005%で運用した場合、資産2倍には72の法則だと約9.025365462462753月必要だというが...
10月目　:　原資100万円が、215.44347014505786万円に
20月目　:　原資100万円が、464.1588882814445万円に
30月目　:　原資100万円が、1000.0000159002664万円に
40月目　:　原資100万円が、2154.434735706665万円に
50月目　:　原資100万円が、4641.588956616946万円に
60月目　:　原資100万円が、10000.000318005334万円に
70月目　:　原資100万円が、21544.34769962752万円に
80月目　:　原資100万円が、46415.89030419448万円に

おおぅ、元手100万円で５年で億り人になろうとすると、月ほぼ8%でまわさんといんかのやね（厳密に計算する場合の方程式と誤差の少ないコードは誰か補ってくだされ）。月8%で回らない分を自己資金で補えるならば、このペースに近づく、と。

１５世紀から伝わるという「72の法則」、元手100万円で５年で億り人になろうとする際の計算には、かなり厳密に使える式ということは分かった。そのためにコードが果たす役割は...2年半後に投資資金1000万円になってから結果を書くとしよう（近時、お仕事以外は、絶賛投資＆結果測定中で委細を書く暇がない）。

まとめると、「元手100万円で５年で億り人になりたいなら、月8%くらいのリターンを得なくちゃね。こんなの、72の法則だとほぼ誤差なく暗算だよ」、ということらしい。

なお、当然ながら、年8%だと、億り人になった頃にはお亡くなりになっている可能性が高い模様。
> 10年目　:　原資100万円が、215.44347014505786万円に
20年目　:　原資100万円が、464.1588882814445万円に
30年目　:　原資100万円が、1000.0000159002664万円に
40年目　:　原資100万円が、2154.434735706665万円に
50年目　:　原資100万円が、4641.588956616946万円に
60年目　:　原資100万円が、10000.000318005334万円に
70年目　:　原資100万円が、21544.34769962752万円に
80年目　:　原資100万円が、46415.89030419448万円に

投資は自己責任でリスクを取り続けようね、ということかと。
pythonからgoogle cloud platformのinstanceを動かすまで

最初に認証キー作ってからでないとだめ
[サービス アカウントとして認証する  |  Google Cloud](https://cloud.google.com/docs/authentication/production)



[Python 用の Cloud クライアント ライブラリの使用  |  Compute Engine ドキュメント  |  Google Cloud](https://cloud.google.com/compute/docs/tutorials/python-guide)


> python3 -m pip install --upgrade google-api-python-client

[python-docs-samples/create_instance.py at master · GoogleCloudPlatform/python-docs-samples](https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/compute/api/create_instance.py)

動作テストにこのgithubのコード使った
__<span style="color:red">※そのまま動かすとインスタンスの料金かかるのでそこはコメントアウト推奨。</span>__

備考

- JSON形式のキーの生成はブラウザが楽、SSHクライアントでファイル移せば良いから（筆者はRLoginで移した
- 権限関係の問題と、プロジェクト名でコマンド打ってたからずっと認識されなかった。そりゃそうだ。

これで
自宅のRaspberryPiからGCPのインスタンスの起動が出来るぞ！！！
やったー
docker-ce導入(CentOS7.9)

# はじめに

よくインストールすることが多いのでメモ。
あと忘れがちなので...

|名称      | 説明|
|:-:      |:-:|
|docker-ce|コミュニティエディション (無償版)     |
|docker-ee|エンタープライズエディション (有償版) |

# docker-ceインストール

* MacBookAirで実行してるVagrant+VirtualBox+CentOS7.9で実施してます。
* vagrantユーザで実施しています。

### 1. 不要なパッケージを削除する。

```bash
$ sudo yum remove docker \
                  docker-common \
                  docker-selinux \
                  docker-engine
```

### 2. 必要なパッケージをインストールする。

```bash
$ sudo yum install -y yum-utils \
                      device-mapper-persistent-data \
                      lvm2
```

### 3. リポジトリを追加する。

```bash
$ sudo yum-config-manager --add-repo \
       https://download.docker.com/linux/centos/docker-ce.repo
```

### 4. docker-ceのインストール

```bash
$ sudo yum install docker-ce
```

### 5. dockerグループにユーザ追加

※ユーザ追加するとsudo無しで実行可能となるため影響ないかは注意する。

```bash
$ sudo usermod -aG docker $USER
```

※dockerグループがない場合は追加する。

```bash
$ cat /etc/group | grep docker
$ sudo groupadd docker
```

### 6. docker起動、自動起動有効化

```bash
$ sudo systemctl enable docker
$ sudo systemctl start docker
```

### 7. 完了

ターミナルからexitして再ログインするとグループ反映される。

----

# 参照
・[Docker v17.03がリリース。今月からバージョン番号制度が変更になり、毎月リリース体制に
](https://www.publickey1.jp/blog/17/docker_v1703.html)

・ [Docker CE の入手（CentOS 向け）](https://docs.docker.jp/engine/installation/linux/docker-ce/centos.html)
link_toメソッドのクリックできる部分を拡大させたい

#はじめに
link_toメソッドを使って、ページ遷移をしているが、クリックできる部分が文字のところだけだったことに不満を感じたので、調べて実装しました。

##CSSでブロック要素に変えて、padding

link_toメソッドにクラス名をつけます。
つける時は`class: "クラス名"`
そのクラス名に対して、CSSで`display: block;`のスタイルをつけます。
さらに、paddingで範囲を広げると、クリックできる部分が拡大します。

ちなみに、marginしてもクリックできる部分は広がりません。

```erb:erb
<ul>
  <li class="menu-list">
    <%= link_to 'マイページ', hoge_path, class: "menu-name" %>
  </li>
  <li class="menu-list">
    <%= link_to 'カレンダー', hoge_path, class: "menu-name" %>
  </li>
</ul>
```


```css:css
.menu-list {
  margin: 30px auto;
  border: black 3px solid;
  padding: 0px;
}
.menu-name {
  display: block; 
  padding: 30px;
}
```

`display: block;とpadding`が大事な部分です。
[Ruby] times, while繰り返し処理

#times問題
1〜10までの数値を順番に足し合わせて、最後に全て足した結果を出力させてください。

```ruby.rb
sum = 0
10.times do |num|
  sum = sum + num + 1
end

puts sum
```
10.times do |num|
end
で0~9まで10回処理を繰り返す処理を定義し、ブロック変数numに処理内容を代入しています。

sum = sum + num + 1で、① + 1とつける場合　・　②つけない場合
① 1, 3, 6, 10, 15, 21, 28, 36, 45, 55
② 0, 1, 3, 6, 10, 15, 21, 28, 36, 45



#FizzBuzz問題
1〜100までの数字をターミナルに出力してください。ただし、「3の倍数」のときは
数字の代わりに文字列でFizzと、「5の倍数」のときはBuzz、
3と5の倍数である「15の倍数」のときはFizzBuzzと出力してください。

```ruby.rb
def fizz_buzz
  num = 1
  while num <= 100 do
    if num % 15 == 0
      puts "FizzBuzz"
    elsif num % 3 == 0
      puts "Fizz"
    elsif num % 5 == 0
      puts "Buzz"
    else
      puts num
    end

    num = num + 1
  end
end

fizz_buzz
```
「倍数」を導き出すときは余りが０であることを証明するため剰余演算子 % を使います。

　繰り返し処理に条件分岐をつける場合は、whileというメソッドを使います。
[![Image from Gyazo](https://i.gyazo.com/b47480a5df95f4340e0d88526643be7d.png)](https://gyazo.com/b47480a5df95f4340e0d88526643be7d)
HTMLの基礎




1 <!DOCTYPE HTML>を先頭に記述
===
 

2 html要素`<html></html>`を記述
==
  HTML文章の始まりと終わりを示す要素

 

3 head要素`<html></html>`を記述
==
  ウェブサイトの情報を記載する要素

 

4 body要素`<body></body>`を記述
==
  画面上に表示したい情報を記載する要素

 

5 head要素内に`<meta charset="UTF-8">`と記述
==
  HTML文章に関する情報を指定する際に使用する要素

  閉じタグはない

  charset属性は文字コード指定

  UTF-8は最も一般的な文字コード

 

6 head要素内に`<link rel="stylesheet" href="ファイル名">`と記述
==
  外部情報を関連付ける際に使用する要素

  閉じタグはない

  rel属性はファイルがどのような関係か明らかにする

    cssを参照する場合はstylesheetと記述

  href属性は参照先のファイルの場所を明らかにする

    ファイル名、ファイルの場所を記述

 

7 head要素内に`<title>タイトル名</title>`と記述
==
  ウェブサイトのタイトルを指定する要素

  検索結果やブラウザのタブに表示される

 

8 body要素内に親にあたる要素を記述
==
  `<header></header>`

    Webページ最上部、ヘッダー専用の要素

  `<div></div>`

    特定の意味がない要素

  `<footer></footer>`

    Webページ最下部、フッター専用の要素

 

9 親要素内に子にあたる要素を記述
==
  `<div></div>`

  `<h1~6></h1~6>`

    文章の見出しを作る要素

    h1から順に文字の太さ、大きさが小さくなる

  `<p></p>`

    文章の段落を表す要素

    ひとからまりの段落として認識される

    見出しを除くテキストのほとんどで使用

  `<b></b>`

    囲まれている部分の文字を太くする要素

  `<br>`

    テキスト中に記述すると改行する要素

    閉じタグはない

  `<a href="~"></a>`

    囲ったテキストをリンクにする要素

    href属性にリンク先のURLを指定

  `<ul></ul>`

    リストを示す要素

    li要素と使用 

  `<li></li>`

    リストの項目を示す要素

    ul要素の小要素として使用

  `<img src="~" alt="~">`

    画像を表示する要素

    src属性に画像の場所を指定

    alt属性に画像が表示されなかった場合の代替テキストを指定

    閉じタグはない

  `<form></form>`

    フォーム関連要素の集まりを示す要素

    入力フォームや送信フォームを作成する要素を記述する

  `<input type="~" placeholder="~">`

    様々なフォーム部品を作れる要素

    閉じタグはない

    type属性の値によってフォームの種類を指定

      text 1行のテキスト入力欄

      checkbox チェックボックスを複数作成

      radio ラジオボタン作成

      submit 送信ボタン作成

    placeholder属性に、入力フォームの仮の文字列を指定

    submitを指定した場合はvalue属性に送信ボタンの文字を指定

 

10 CSSによる装飾をどの部分に適用するかを選択するための記述を行う
==
  class属性

    個別に名前を指定できる

  `<span class"~"></span>`

    テキストの一部を装飾する要素

 
11 コメントアウト
==
  <!-- ~ -->で囲んだ部分を無いものとあつかえる記述方

  メモを残したり、試しで記述を消したり、便利に使える

  コメントアウトしたい部分を選択して⌘+/ でも実行可能
M5StickC と MH-Z19B を使って、二酸化炭素濃度計を作りました

（この記事は[地平線に行く](https://yujisoftware.hatenablog.com/entry/2021/01/16/232841)とのマルチポストです）

ネットの情報をもとに、M5StickC とMH-Z19B （CO2センサー）を使って二酸化炭素濃度計を作りました。
作ったといっても、M5StickC と MH-Z19B をつないで、さくっとプログラミングしただけ。簡単でした。

一年ぐらい運用していますが、なかなか便利です。
![P_20200525_095646_vHDR_Auto.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205989/372bb12a-fbd4-b22d-403b-22cabba211af.jpeg)

グラフ表示モードも作ったので、こんな風に直近の濃度の変化もわかります。
![P_20200525_095559_vHDR_Auto.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205989/755f3ad5-a752-aa42-e768-4354414a7c90.jpeg)

ソースコードはこちら
https://gist.github.com/YujiSoftware/9274366a93f1ac7f9208bd4abf096527

:::note info
Arduino IDE の Sketch → Include Library → Manage Libraries から、MH-Z19 (by Jonathan Dempsey) をインストールしてください。
:::

# 実装した機能

* 現在の二酸化炭素濃度を表示
* 過去１時間ぐらいの二酸化炭素濃度の推移をグラフで表示
* 1,200ppm[^ppm]を超えたときに、LED 点滅してお知らせ
* 画面表示のオン・オフ

[^ppm]: 1,200ppm を超えると眠気を感じるといわれています。

# 用意したもの

* [M5StickC](https://www.switch-science.com/catalog/5517/)（1,980円）
* CO2センサー [MH-Z19B](https://www.winsen-sensor.com/sensors/co2-sensor/mh-z19b.html)（2,019円）
* ジャンプワイヤ

MH-Z19B[^MH-Z19B]は AliExpress で買いました[^akizuki]。
買うときに、取り付けが簡単かなと思って「MH-Z19B with Cable」を選んだのですが、これはおススメしません。というのも、このピンと M5StickC をつなぐようなケーブルというのはない[^cable]らしく、**コネクタとコンタクトピンを買ってきてケーブルを自作する羽目になりました。** 部品が細かくて、とてもめんどくさかったです…。

「MH-Z19B with Pin」ならば、[オス-メスのジャンプワイヤ](https://www.switch-science.com/catalog/209/) でつなぐだけだと思うので、こちらの方がよさそうです。

[^MH-Z19B]: 後継機 [MH-Z19C](https://www.winsen-sensor.com/sensors/co2-sensor/mh-z19c.html) が出ているそうです。
[^akizuki]: 今は秋月電子通商でも MH-Z19C の取り扱いがあるみたいです。https://akizukidenshi.com/catalog/g/gM-16142/
[^cable]: マルツ秋葉原本店で聞いて「ない」と言われました。

# 作り方

M5StickC と MH-Z19B のピンを以下の組み合わせでつなぎます。

|M5StickC|MH-Z19B|
|:--:|:--:|
|G36|Tx|
|G26|Rx|
|5V|Vin|
|GND|GND|

あとは、[Arduino IDE](https://www.arduino.cc/en/software) で冒頭のソースコードを M5StickC に流し込んで完成です。

# 感想

市販の二酸化炭素計と違って、自分で好きなようにプログラミングできるのが面白いです。

M5StickC なら、いろいろな機能（LED、LCD画面、ボタン、WiFi、Bluetooth、バッテリー など）が All in One で載っているので、難易度もかなり低いです。
みなさんにも、ぜひおススメです。
GoをHerokuにデプロイするときに Push rejected, failed to compile Go app. のエラー

# エラーについて
Goで作ったAPIをHerokuにデプロイしようと思い、
`git push heroku main`
コマンドをしたところ

```
!     Push rejected, failed to compile Go app.
!     Push failed
```
上のようなエラーで失敗。

# 解決した方法
ログを遡ってみると、

```
-----> 
 !!    The go.mod file for this project does not specify a Go version
 !!    
 !!    Defaulting to go1.12.17
 !!    
 !!    For more details see: https://devcenter.heroku.com/articles/go-apps-with-modules#build-configuration
 !!    
-----> New Go Version, clearing old cache
```

のような記述があった。最初はこれが原因だとは思っていなかったため放置していたのだが、試しに調べてみることにした。

調べてみると、Herokuでgoのバージョンを指定するには、go.modにて

```go.mod
module xxxx

// +heroku goVersion go1.15      <--追加
go 1.15

```
のように記述する必要があるようだ。
書き直してpushしなおしてみると、無事デプロイできた。
[python] yeojohnson変換の変換前後の値をプロット

```python:python
import numpy as np
import pandas as pd

# ここの式をコピー
# https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.yeojohnson.html
def yeojohnson(lmbda, x):
    if x >= 0 and lmbda != 0:
        y = ((x + 1)**lmbda - 1) / lmbda
    
    elif x >= 0 and lmbda == 0:
        y = np.log(x + 1)
    
    elif x < 0 and lmbda != 2:
        y = -((-x + 1)**(2 - lmbda) - 1) / (2 - lmbda)
        
    elif x < 0 and lmbda == 2:
        y = -np.log(-x + 1)
    
    else:
        # 到達しないはず
        raise
    
    return y

# 変換する値
x_ary = np.arange(21)-10

# 2パターンの lmbda の組み合わせを試す
for lmbda_ary in [np.arange(10)*0.25, np.arange(10)*0.5]:
    
    # 変換して df にまとめる
    X_dic = {}
    for lmbda in lmbda_ary:
        X_dic[lmbda] = [yeojohnson(lmbda, float(x)) for x in x_ary]
    df = pd.DataFrame(X_dic, index=x_ary)
    
    # 描画
    df.plot(cmap='viridis', marker='.')
    plt.xlabel('元の値（x）')
    plt.ylabel('変換後の値（y）')
    plt.title('lmbda を変えた時の変換後の値の変化')
    plt.show()
```

output:
![スクリーンショット 2021-01-16 午後11.22.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178570/3e3cbe44-c00f-c169-e59b-ec68aba0a89f.png)
Power Automateでフローの進行を待機させる方法

PowerAutomateで処理の進行が速すぎてエラーになってしまうことはありませんか？
こういう場合は「待機処理」を入れることができます。

#どんな時に処理の待機が必要？

例えば、
>**メールを受信した際に、添付ファイルがあれば、「受信日時と件名」のフォルダを新規作成し、そのフォルダ内に添付データを入れる**

といったフローの場合、
添付データを格納するフォルダが既に存在している訳ではなく、メール受信時に判断されて新規フォルダが生成されます。
新規フォルダを作成する操作が正常に実行されても、添付データをいれる処理に差し掛かった際にまだフォルダがあると認識できず、エラーとなってしまう場合があります。

これは、新規フォルダを作成する処理が実行されていも、**実際に生成されるまでに数秒時間が必要**で、後続のフローに進んだ時に**まだフォルダが生成されていない**ために生じるエラーです。

待機処理を入れて解消しましょう。

#待機を行うアクションを追加する
処理を「待機」するので、日本語では「待機」や「保留」などといった日本語を想像して検索しますが、見つかりませんでした。英語圏で開発されているシステムなので日本語訳されるとなんか少しポイントがズレていると感じるのは私だけではないはず、、と言い訳しつつ。。
要は「**遅延**」というアクションを探すと、処理を一定期間止める操作を行ってくれます。
日本語で言う「遅延」は、「不可抗力によって遅れる」という語感がありますが、英語でいうDelayは自ら遅らせるという意味もあるので当然ですね。(;'∀')
このアクションは、スケジュールアクションの「遅延」アクションで設定できます。

【スケジュール】コネクタ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322371/5e931c3a-db19-515e-7261-ac020d125b69.png)

【遅延】アクション
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322371/2b528874-3550-ba22-7379-b1182187b45b.png)
秒単位から、月単位まで遅延させることができます。
新規フォルダの作成は30秒もあれば確実に生成されて、PowerPlatform内で同期されるはずですから30秒に設定しました。

しかしながら、遅延アクションでは、フローの進行を、例えば3か月遅延させるという設定もできました。PowerAutomateの[「制限と構成」](https://docs.microsoft.com/ja-jp/power-automate/limits-and-config)では実行継続時間が最大30日とありますので、作成したいフローの処理を数週間単位で遅延されたいというユースケースがある場合は、どちらの制限が有効なのか検証作業が必要ですねー

以上、フローを待機させるときの「遅延」アクションの紹介でした！
M1チップ搭載MAC(Apple Silicon)でhomebrewをインストールする方法(2021/01/16現在)

#0.背景
m1チップ搭載のmacbookを購入し、今までの手順でhomebrewをインストールしてもうまくいきませんでした。
(brew not foundの文字が...)
どうやらm1チップではインストール方法が違うそうです。
２通りあるので紹介します。

※Xcodeインストール済み

#1.Rosetta2でのインストール
1.finderを開木、ターミナル上で右クリック。「情報を見る」を開きます
![スクリーンショット 2021-01-16 22.39.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647693/f4f36e6c-ada3-e0cb-868d-40e266025629.png)

2.「Rosettaを使用して開く」にチェックを入れます
![スクリーンショット 2021-01-16 22.40.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647693/92c36f09-f44b-8824-664d-da794c561a8e.png)

3.ターミナルを起動します
4.今までの手順でインストールできます
※今までの手順
 下記をターミナルで実行

```/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
```

これで終了です。

#2.ARM依存のインストール
1.上記と同じ方法で「情報を見る」を開き、「Rosettaを使用して開く」のチェックを外します。
2.ターミナルを起動し、下記コマンドを入力します

```cd ~```

```mkdir homebrew && curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C homebrew```

```sudo mv homebrew /opt/homebrew```

```cd /opt/homebrew/bin```

```./brew update```

3..zshrcを編集し、パスを記述します
　3-1.下記コマンドを実行
　```vim ~/.zshrc```
　3-2.「i」を押下し、編集モードに
　3-3.```export PATH="/opt/homebrew/bin:$PATH"```を追記
　3-4.escキーと:wqで保存&編集終了！

4.下記コマンドでパスを通します
```source .zshrc```

これで終了です。
※/opt/homebrew配下にインストールされています。

#最後に
思っていたよりも簡単にできました。
しかし、どちらがいいかと言われると.........
なんとも言えません。

個人的にはARM依存の方がパーフォーマンスもいいみたいなのでそちらを使う予定です。
ただhomebrewに紐づいているアプリケーションはうまく動くのか....
環境設定周りをいじらなければいけない気が...
と思っております。

以上！！
Luminousが上手く動かない件

ウェブサイトの復旧作業の中で、ギャラリーのページをカスタマイズする作業の中で、jQuery不要なLightboxスクリプトLuminousを知りました。

jQueryを使わないので、小規模のHTMLを手入力で作ったようなウェブサイトのギャラリーページのカスタマイズに最適だと思いました。

でも、下記のコードを設置しても、動かないです。

```HTML
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/luminous-lightbox@2.3.2/dist/luminous-basic.min.css">
<script src="https://cdn.jsdelivr.net/npm/luminous-lightbox@2.3.2/dist/luminous.min.js"></script>
<script>
new LuminousGallery(document.querySelectorAll('.luminous'));
</script>
```
複数の画像に対応するため、このコードを使いました。

このコードは、こちらの記事で見つけました。
[jQuery不要なLightbox代替スクリプトLuminousが本当に軽量](https://blog.ver001.com/javascript-luminous/)

こちらの記事を読んで、原因が分かりました。
Luminousを適用したいaタグの直下に、このコードを設置する必要があります。
理由は、他のCSSの影響を受けないように、最後にLuminousのCSSを適用させるためです。

[luminous がうまく動かない](https://teratail.com/questions/85543)

###設置例
```html
<div>
 <ul>
 
        <li><a class="luminous" href="./img/1_big.jpg"><img src="./img/1.jpg" alt="image" /></a></li>
        <li><a class="luminous" href="./img/2_big.jpg"><img src="./img/2.jpg" alt="image" /></a></li>

    </ul>


    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/luminous-lightbox@2.3.2/dist/luminous-basic.min.css" />
    <script src="https://cdn.jsdelivr.net/npm/luminous-lightbox@2.3.2/dist/luminous.min.js"></script>
    <script>new LuminousGallery(document.querySelectorAll('.luminous'));</script>

</div>
```
【Android/Kotlin】Gitに保存しないデータを扱う

# なんでそんなことするの？
github等でgitを共有する時に、データベース接続用パスワード等は公開したくない

# 説明
.gitignoreファイルに記載されているファイルはgitに保存されなくなる
AndroidStudioでプロジェクトを作成すると、自動的に.gitignoreとlocal.propertiesが作成され、
.gitignoreの中にlocal.propertiesも入っているのでそれをそのまま使用する

# 結論
[github](https://github.com/yuki-kamikita/LocalPropertiesSample)
この中にlocal.propertiesは入っていない

# コード
## gitの例外にするファイルを指定する
local.propertiesが入っていることを確認

```:.gitignore
/local.properties
local.properties
```

## 使用するファイルと定数名を指定
ここのやり方はわからなかったら`buildConfigField`でググってください

```build.gradle(app)
android {
    defaultConfig {
        // local.propertiesファイルを指定
        def properties = new Properties()
        properties.load(project.rootProject.file('local.properties').newDataInputStream())

        // buildConfigFieldで値を保存
        def LOCAL_PROPERTIES_SAMPLE = properties.getProperty("LOCAL_PROPERTIES_SAMPLE")
        buildConfigField("String", "LOCAL_PROPERTIES_SAMPLE", "\"${LOCAL_PROPERTIES_SAMPLE}\"")
    }
}
```

## 使用する値を入力
ここに隠したい値を入れる
文字列でもクォーテーションは要らない
半角スペースを使用できない

```local.properties
LOCAL_PROPERTIES_SAMPLE=SAMPLE
```

## 値を受け取る
今回はtext_viewでlocal.propertiesで指定した値を表示してみる

```xml:activity_main.xml
<TextView
    android:id="@+id/text_view" />
```

BuildConfigやその中の値は最初存在せず、赤くなってるけど、初回ビルド時にBuildConfig.javaが生成・更新され、使えるようになる

```kotlin:MainActivity.kt
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // BuildConfig.javaは初回ビルド時に生成される
        text_view.text = BuildConfig.LOCAL_PROPERTIES_SAMPLE
    }
}
```
SQLServer Express(サーバー)のインストール

# はじめに
個人使用目的でSQLServer Express 2019をインストールすることにした。
localdbで色々試したかったがPowerShellモジュールによるインスタンスコントロールができなかったので、サーバ製品を使うことに。いずれにせよ無償版の機能範囲から出ないので、良しとする。

# 1.インストーラのダウンロード
https://www.microsoft.com/ja-jp/sql-server/sql-server-downloads からインストーラを入手。
特に迷うことはないと思う。

# 2.インストール

1. [カスタム]をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/71ee8384-677f-2859-ac4a-a4a7a6799c5f.png)

2. メディアのダウンロード先を指定する。特に変えることがないのでそのまま[インストール]をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/5bf04150-1ab0-e148-3f71-15a6f6fe9111.png)

3. インストーラーのダウンロードが開始される。暫く待ち。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/4e0c575a-482c-b2c2-eba7-2a47dcc5d529.png)

4. [SQL Serverの新規スタンドアロン インストールを実行するか、既存のインストールに機能を追加]をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/be5fdfd2-70fe-762d-d934-22a22606f38c.png)

5. [ライセンス条項と次に同意します]をチェックし、[次へ]をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/3c20b203-d70f-0c31-ba73-187ec94b551b.png)

6. [Microsoft Updateを使用して更新プログラムを確認する]をチェックし、[次へ]をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/e1daae09-10ce-1e51-bf61-2c9650f8619a.png)

7. セットアプファイルのダウンロードが開始される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/4ed4c1e3-d09e-e8c0-d726-a46b215deb4b.png)

8. [次へ]をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/7e685056-3e63-0c36-6d41-07311299daa2.png)

9. インストール機能を選択し、[次へ]をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/951359ee-7dde-f530-f7aa-f8d34b603292.png)

10. インスタンス名を変え、[次へ]をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/504eec36-e1cd-b4c0-27c4-5f74c1ede6f3.png)
※インスタンス名はサービス名と同じが良い。

11. [次へ]をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/ab0166ef-7e66-2f69-6648-1a6c09942aa8.png)

12. SQLServerインスタンスの構成を変更する。認証モードを[混合モード]にし、saアカウントのパスワードを入力。よければ[次へ]をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/ad6de19d-646f-93a8-28a7-ff181fd98076.png)

13. [データディレクトリ]タブを選択し、[データルートディレクトリ]をユーザアカウントのドキュメントフォルダパスに作成した[sqlserver]に変更し、[次へ]をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/b9345b32-559c-bdb8-6533-5e7391f6a32b.png)

14. インスタンスの作成が開始される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/7e0b2bfd-6cc8-6d3c-75b9-0821d1245b3b.png)

15. インストールが完了したら[閉じる]をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/a876ca60-efb6-3245-6772-8c54f8848462.png)

16. SQL Server インストールセンターも[x]をクリックして終了させる。

# 3. 使用確認

SQL Server Management Studioからインスタンス[goodneighbor]にアクセスできるか確認する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/df294d26-432e-c7d7-67ae-d9b140b9bd44.png)

インスタンスに接続できればOK。
【AWS】認定クラウドプラクティショナー受験記録

気がついたら、2ヶ月くらい投稿してなかった。。。
という訳で久々の記事投稿です。

今月、AWS認定クラウドプラクティショナーを受験し、合格する事が出来ましたので、
それをネタにしようと思います。

## 経緯

昨年末にITパスポートを取得し、春の基本情報までの間に優先的に学習するものとして、
今回はAWS認定資格を選択しました。理由としては単純に業務でCloudfrontやLambdaを使う機会があるのと、新米が先輩方に追いつく隙がAWSにはあると思ったからです。

1年くらい前に受験目的ではなく、AWSの基礎知識を学びたくてUdemyの教材を購入して、ソリューションアーキテクトアソシエイト（SAA-C01）について学んだ経験はあったのですが、いっそベーシックから順番に制覇してやろうとまずはクラウドプラクティショナーを受験する事を決めました。

AWS認定資格については今更説明するまでもないと思うので、ここでの説明は割愛します。
https://aws.amazon.com/jp/certification/

また、受験の際に同意した受験者行動規範により、試験内容の開示、共有は禁止されていますので、あくまで試験に向けて行った準備とか感想とかを記していこうと思います。

## 本題

冒頭でも書きましたが、一応今回の試験は無事に一発合格しております。
スコアは882でしたので、目標900にはあと一歩という感じでしたが、ここは単純に総合力が足りなかったのかなと思っています。

![スクリーンショット 2021-01-16 21.56.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531606/08938c17-6a6a-7823-b177-ca161b1fddfc.png)

準備期間は大体3週間、学習時間は土日は3~5時間、平日は1~2時間だけど毎日ではないかな。教材も王道な感じなので、あまり参考にならないかもしれないですが、

書籍
・[AWS認定資格試験テキスト AWS認定 クラウドプラクティショナー](https://www.amazon.co.jp/AWS%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E8%A9%A6%E9%A8%93%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-AWS%E8%AA%8D%E5%AE%9A-%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%BC-%E5%B1%B1%E4%B8%8B-%E5%85%89%E6%B4%8B/dp/4797397403/?_encoding=UTF8&pd_rd_w=5WncL&pf_rd_p=63597d76-0215-4f5e-bb4d-851158766d92&pf_rd_r=FWD2FJB9G6V4ZH7HTT3X&pd_rd_r=a78e48a8-bd43-4fb2-8b9d-892b8c53e11a&pd_rd_wg=u01NN&ref_=pd_gw_ci_mcx_mr_hp_d)
Udemy
・[この問題だけで合格可能！AWS 認定クラウドプラクティショナー 模擬試験問題集（7回分455問）](https://www.udemy.com/course/aws-4260/)
・[AWS 認定デベロッパー アソシエイト模擬試験問題集（5回分325問）](https://www.udemy.com/course/aws-31955/)
・[これだけでOK！ AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座（SAA-C02試験対応版）](https://www.udemy.com/course/aws-associate/)
その他
・[AWS WEB問題集で学習しよう](https://aws.koiwaclub.com/)

書籍はインプットで1周と分からない単語を都度調べるのに。
Udemyはクラウドプラクティショナー模試を4周、ソリューションアーキテクトアソシエイトの模試2周、デベロッパーつまみ食い程度、AWS WEB問題集で学習しようはCLF（400問）を3周、SAAは出来る限りって感じでした。

当然間違えた問題もそうでない問題も解説や選択肢に出てきた単語の意味は全て調べて覚えました。正直、受かりたいだけならここまでやる必要はないかと思いますし、上位資格も取得する前提だったのでここまでコストをかけましたが、CLF試験自体に上位資格の勉強はあまり生きる部分はなかったように思うので、そこはお好みという感じでしょうか。

ホワイトペーパーよりBlack Belt Online Seminarで深堀したいものだけチョイスして見ましたが、1本のボリュームが大きいので、余力があれば見るでいいかも。

試験はピアソンVUEで近所のテストセンターでの受験を選択しました。
会場によって違うようですが、自分が受験した会場は緩い感じでカメラで監視されてるとかそういうのはなかったですね。

試験自体はゆっくり解いて40分くらいだったので、見直す時間は十分にありました。
試験終了時に合否だけ表示され、スコアが確認出来たのは受験から10時間後くらいでした。最長5日営業日ほどかかる事もあるようです。


## まとめ
試験の雰囲気や対策、アプローチの仕方が見えてきたので、上位資格取得に向けて良い弾みになったのではないかと思います。まずは合格を優先したい人はゴリゴリ問題集を解いてサービスの理解を深めるのが近道かもしれないですね。誰かの参考になれば幸いです、では。

## おまけ
会社で資格補助が出るような時に領収書を発行してもらう必要があると思いますが、
ピアソンで受験した時はオンラインで領収書発行フォームから申請する事で領収書がもらえます。
GitHub ActionsでAngularプロジェクトをGitHub Pagesにデプロイする

Angularプロジェクトで開発する際に、GitHub Pagesで公開する際の手順を備忘録として残しておきます。


※基本的なActionsの使い方は以前書いた「[GitHub ActionsでAngularプロジェクトの自動テストを実行してみる](https://qiita.com/teracy55/items/126797b14f701941f9f3)」を見てください。


# GitHub Actionsの設定

今回は個人開発を想定しているので、mainブランチにプッシュしたときに自動で本番ビルド → GitHub Pagesへデプロイと実行するようにします
※チーム開発の場合は任意のタイミングでデプロイできるように検討した方が良いです

```.github/workflows/deploy.yml
name: Node CI

on:
  push: 
    branches: main

jobs:
  build:

    runs-on: ubuntu-18.04

    strategy:
      matrix:
        node-version: [12.x]

    steps:
    - uses: actions/checkout@v1
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v1
      with:
        node-version: ${{ matrix.node-version }}
    - name: npm install, build, and test
      run: |
        npm install
        npm run build --if-present -- --prod
        npm test -- --watch=false --browsers=ChromeHeadless
        cp -a {angular.jsonのoutputPath}/index.html {angular.jsonのoutputPath}/404.html
      env:
        CI: true
    - name: Deploy 🚀
      uses: JamesIves/github-pages-deploy-action@3.7.1
      with:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        BRANCH: gh-pages
        FOLDER: {angular.jsonのoutputPath}
        CLEAN: true
```

<font color="red"><strong>*ポイント*</strong></font>

- 実行タイミングはmainブランチへのプッシュ時
- テストはHeadlessChromeで実行
    - ヘッドレスブラウザで実行しないと、ブラウザを開こうとしてエラーになります
- index.htmlをコピーして404.html
    - SPAのURL直打ち対策です
        - これやらないと画面リロードやURL直打ちしたときにNotFoundになります
- デプロイは以下を利用しています
    - https://github.com/marketplace/actions/deploy-to-github-pages
    - デプロイ対象のフォルダはangular.jsonで定義されているoutputPathと一致させる


### デプロイ用ブランチを作成します

`gh-pages`という名前のブランチを作成しておきます


# GitHub Pagesの設定

gh-pagesブランチを作成すると自動で有効になるっぽいので不要

一応、OptionsでGitHub Pagesの設定を確認しましょう。
URLが発行されていて、ブランチが`gh-pages`でディレクトリが`root`になっていればOKです。



# Angular側の設定

### angular.jsonの修正

- build.configurations.production下を修正
    - baseHrefを修正
        - 値は`/{project name}`
        - GitHub PagesのURLが`https://{username}.github.io/{projectname}`となり、baseHrefを修正しないとindex.htmlにアクセス不可となってしまうため
    - deployUrlを追加
        - 値は`/{project name}/`　※末尾のスラッシュを忘れないように注意
        - これ修正しないとindex.htmlにアクセスできても、JSやCSSファイルのパスがおかしくなって画面が出てこない



## プッシュする

mainブランチに変更をプッシュする
Actionsが自動で動作し、Pagesにデプロイされます

Optionsに公開URLが載ってるのでそこにアクセスするとデプロイされています。
Notionを使った情報管理(読書)

### Notionを使った情報管理

はじめまして
現在、某Sier企業に勤めています3年目のエンジニアです。
5人程の規模でNotionをTeamPlanにて使っています！
その中で得た自分の知見を発信していきます。

そもそもNotionとは？という方は下記の方のサイトが大変参考になります！
[知的生産ツール「Notion」は、現代人を悩ます“情報の散らかり”から私たちを救う](https://unleashmag.com/2019/01/31/notion/)


### 対象読者
- Notionが気になるが具体的な使い方がわからない

### HOME画面(個人利用)
/pageでいくつかページを作り中に詳細の情報を記載しています。
この中の読書記録について紹介します。
![](/Users/tomoya/Library/Application Support/typora-user-images/image-20210116223126999.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943494/444fc889-4406-7b37-c8f6-d6ca636e8d47.png)

### 読書管理
ツールを使う上でまず自分が大事にしているのは、何をまとめたいのか目的を明確にすることです。
読書管理においてまとめたい情報としては下記の情報

#### まとめたい情報
- 読んできた本の一覧。ジャンルと時系列を添えて
- 読んで印象に残った本を抽出(後で見返すため)
- 読みたい本のストック

#### これらを踏まえてページを作成
- 読んできた本の一覧。ジャンルと時系列を添えて
まずは一覧を作成します。
/tableテーブルを作成します。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943494/7f908684-b8f0-7a66-5951-6ad7c1ba31c2.png)

タイトル、著者、読み終わった日、ジャンル、評価、読破したかどうか？
上記の情報をカラムにもたせています。めんどくさがって、完璧には纏めていません。

Notionはレコードごとにページを作成できるので、読んだ感想など書いています

![](/Users/tomoya/Library/Application Support/typora-user-images/image-20210116223250387.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943494/fb87fdb0-073f-ee8a-401d-622d802d645c.png)

- 読んで印象に残った本を抽出(後で見返すため)
- 読みたい本のストック
評価5また、読みたい本は抽出して一覧化したいので/create linked databaseで読書記録テーブルにリンクさせたテーブルを作成します。
それらのテーブルをFilterで絞って一覧にします。

リンクテーブルを使いこなせるかどうかがNotionを最大限に使えるかどうかだと思っています。(この辺は凝りすぎると沼にはまるのでそこそこで。)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943494/06487cff-ac7c-978a-4061-cb3c8eecef2a.png)

これらの手順で読書記録ページの完成です。
下記にテンプレートを置いておきますので右上のDuplicateよければお使いください！

[読書記録](https://www.notion.so/26b13b32a6624198aa74486909f94daa)