OmniAICreator/Qiita-1.07M huggingface dataset:
自作npm の css ファイルを import できない原因は package.json の sideEffects 設定だった話

npm を自作していたら css 関連でかなりハマってしまったので備忘録を残します。

**① パッケージ内で css モジュールを import したら型定義ファイルが無いとエラーになる
② 完成したパッケージ内の css が import されない**


# 結論：package.json の sideEffes に注意！

`package.json` に `"sideEffects": false` を記載していたのが原因でした。

変更前
```json:package.json
"sideEffects": false
```

変更後
```json:package.json
"sideEffects": [
  "*.css"
]
```


# ①パッケージ内で css モジュールを import したら型定義ファイルが無いとエラーになる

Vite + TypeScript + Vue3 という環境で `.vue` ファイル内に cssモジュールを読み込もうとしたら下記のようなエラーが表示されました。

```shell
Cannot find module './foo.module.css' or its corresponding type declarations.
モジュール './foo.module.css' またはそれに対応する型宣言が見つかりません。
```

## cssモジュールの型定義をインストールする

`@types/css-modules` をインストールし、その後 `tsconfig.json` に追加します。

```shell
yarn add --dev @types/css-modules
```

`tsconfig.json` の `compilerOptions.typeRoots` に追加。

```json:tsconfig.json
"compilerOptions": {
  "typeRoots": ["./node_modules/@types"]
```

## package.json に css を定義

`dist/style.css` を置き、`package.json` にも記載します。

```
/my-npm
+-- /dist
    +-- style.css
    +-- my-npm.es.js
```

```json:package.json
"exports": {
  ".": "./dist/my-npm.es.js",
  "./css": "./dist/style.css"
},
"sideEffects": false
```

この時はまだ `"sideEffects": false` が原因だったとは気付いてませんでした……。


# ② 完成したパッケージ内の css が import されない

```js
import "my-npm/css";
```

上記のように css を import したのですがビルドされた js には css が含まれてませんでした。

## 原因は `"sideEffects": false`

今まで自作 npm 内で css モジュールを利用してなかったので `sideEffects: false` にしていたのですが、それをすっかり忘れていました。

下記のように変更することで解決できました。

```json:package.json
"sideEffects": false
↓
"sideEffects": [
  "*.css"
],
```

`sideEffects` は副作用の有無を指定するものです。
このへんのページが詳しいです。

https://kde.hateblo.jp/entry/2019/02/25/043852#%E5%89%AF%E4%BD%9C%E7%94%A8side-effect%E3%81%A8%E3%81%AF

https://www.kabuku.co.jp/developers/tree-shaking-in-2018
オブジェクトリストから削除リストにある項目以外を抽出する（非破壊）

[teratailの質問](https://teratail.com/questions/m43rf4vgtj91xw)に回答したコードを、Qiitaにも残しておきます。

元データを変更せず（非破壊）に、除外リストで指定された項目を取り除いたオブジェクトリストを新たに作る方法です。

1. オブジェクトリストを`map`して別のオブジェクトリストを作る
1. 各オブジェクトから`Object.entries`で`[key, value]`リストを列挙する
1. 削除**しない**項目を`filter`で抽出する
1. `Object.fromEntries` でオブジェクトにする

```js
const members = [
    { firstname: 'Taro', lastname: 'Yamada', age: 20 },
    { firstname: 'Hanako', lastname: 'Hanako', age: 10 },
];

const secrets = [ 'lastname', 'age' ];

const anonymous = members.map(member =>
    Object.fromEntries(Object.entries(member)
                             .filter(([key, value]) => !secrets.includes(key))))
console.log(anonymous)
```

```js:実行結果
[ { firstname: 'Taro' }, { firstname: 'Hanako' } ]
```
@IBActionfunc と prepare はどちらが先に呼び出されているのか？


## 気になったこと
表題の通りです。
segueで次の画面に値を引き渡す時、次の画面にうつるボタンにメソッドを呼び出す@IBActionを別に関連付けした時、prepareか@IBActionどちらが先に呼び出されるのか気になりました。

もう少し具体的にアプリの実装を説明すると、
ボタンを押した時に、TextFieldに入っている値を変数に値を代入するタイミングをどこにしようか悩んだのでコンソールに出力して、ボタンを押した時にどこのメソッドがはやく呼び出されているのかを検証してみました。

私の予想では@IBActionでprepareを呼び出していると思うのでIBActionが先に呼び出されている気がします。

## 検証結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665837/a056ce83-d13e-d270-71b3-056c88372a28.png)

ということで結果は **prepare の方が先に呼ばれてる** でした〜〜〜！！

prepare → 関連付けされてる @IBAction が呼ばれるんですね！！
どういう原理になってるか説明してやるぞ！という方いらっしゃいましたらぜひコメントください！以上！
Variatinal AutoEoncoderをSubclassing APIで書いてみた

Variatinal AutoEoncoderを使う機会がありまして、tensorflowで書いてるコードをいろいろなサイトで見ていたのですが、だいたいのサイトでは、Sequential APIかFunctional APIで書いている気がします。なぜだ。。。
そこでSubclassing APIで書いてみようとしました。

Variatinal AutoEoncoderを理解したい方は下のサイトへGO
[Variational Autoencoder徹底解説](https://qiita.com/kenmatsu4/items/b029d697e9995d93aa24)

この記事では、ほぼコードだけ

[tensorflow公式のVAEコード](https://www.tensorflow.org/tutorials/generative/cvae)
上記のコードでは、Sequentialを使ってるのかな。これを一部変えてSubclassingにします。

Reparameterization Trick、エンコーダー、デコーダーに分けて書きます。

# Reparameterization Trick
```
class Reparameterize(tf.keras.layers.Layer):

  def call(self,inputs):
    mean, logvar = inputs
    batch = tf.shape(mean)[0]
    dim = tf.shape(mean)[1]
    eps = tf.keras.backend.random_normal(shape=(batch, dim),mean=0., stddev=1)
    return mean + tf.exp(0.5*logvar) * eps	
```

# エンコーダー
```
class Encode(tf.keras.layers.Layer):

  def __init__(self , latent_dim):
    super(Encode, self).__init__()
  
    self.conv_layer_1 = tf.keras.layers.Conv2D(filters=32, kernel_size=3, strides=(2, 2),padding='same', activation='relu')
    self.conv_layer_2 = tf.keras.layers.Conv2D(filters=64, kernel_size=3, strides=(2, 2),padding='same', activation='relu')


    self.flatten_layer = tf.keras.layers.Flatten()
    self.dense_1 = tf.keras.layers.Dense(32,activation='relu')
    self.dense_mean = tf.keras.layers.Dense(latent_dim)
    self.dense_logvar = tf.keras.layers.Dense(latent_dim)
    self.sampling = Reparameterize()

  def call(self,inputs):
    #pdb.set_trace()
    cx = self.conv_layer_1(inputs)
    cx = self.conv_layer_2(cx)
    x = self.flatten_layer(cx)
    x = self.dense_1(x)
    mean = self.dense_mean(x)
    logvar = self.dense_logvar(x)
    z = self.sampling((mean, logvar))
    return mean,logvar,z
```
# デコーダー

```
class Decode(tf.keras.layers.Layer):

  def __init__(self):
    super(Decode,self).__init__()
    #元の次元に戻している
    self.dense_z_input = tf.keras.layers.Dense(units = 7*7*64, activation='relu')
    self.reshape_layer = tf.keras.layers.Reshape((7,7,64))
    self.conv_transpose_layer_1 = tf.keras.layers.Conv2DTranspose(filters=32, kernel_size=(3,3),  strides=(2,2),padding='same',activation = 'relu')
    self.conv_transpose_layer_2 = tf.keras.layers.Conv2DTranspose(filters=16, kernel_size=(3,3),  strides=(2,2),padding='same',activation = 'relu')
    self.conv_transpose_layer_3 = tf.keras.layers.Conv2DTranspose(filters=1, kernel_size=(3,3),  padding='same',activation = 'sigmoid')

  
  def call(self,z):
    #pdb.set_trace()
    x_output = self.dense_z_input(z)
    x_output = self.reshape_layer(x_output)
    x_output = self.conv_transpose_layer_1(x_output)
    x_output = self.conv_transpose_layer_2(x_output)
    x_output = self.conv_transpose_layer_3(x_output)
    return x_output
```
それぞれ書きました。これを最後に一つにします。
# 統合
```
class VAE(tf.keras.Model):

  def __init__(self,latent_dim):
    super(VAE,self).__init__()
    self.encoder = Encode(latent_dim)
    self.decoder = Decode()
```
これでモデルは一応動きます。あとは損失関数とか加えたら動きます。今度、そこらへんしっかり書こうかな。
Subclassingでどう書くかはいろいろなサイトで見てやりました。__init__関数に使うレイヤーを書いて、call関数でそれを呼び出す。これだけなのかな?そもそもこれはSubclassingなのかどうか自分ではわかりませんが、とりあえずこんな感じなのではないでしょうか。もし違ってたらタイトル詐欺になる。。。
【Flutter】「flutter create」実行時に「"XXXXXXX" is not a valid Dart package name」が発生

## 概要
Flutterのプロジェクトを作成する際に「flutter create プロジェクト名」のコマンドを実行すると思いますが、指定したプロジェクトの名称によっては、`"XXXXXXX" is not a valid Dart package name`というエラーが発生します。
このエラーに関するメモ書きです。

## 対応
エラー内容の通り指定したプロジェクトの名称がいけないわけですが、[こちら](https://dart.dev/tools/pub/pubspec#name)のDartのpackage命名規則のドキュメントに沿って、プロジェクト名称を設定する必要があります。
以下は、規則に関する補足です。


### 1. 数字・小文字アルファベット・アンダースコアのみ使用可
`[a-z0-9_]`の、正規表現にある文字だけが設定可能です。例えば`MyProject`、`myProject`、`my-project`のような指定を行うとエラーになります。

### 2. 最初の文字に数字の使用は不可
例えば`1myproject`のように、最初の文字に数字を指定するとエラーになります。

### 3. 予約語の使用は不可
例えば`abstract`や`interface`のような予約語を使用すると、エラーになります。予約語の一覧は[こちら](https://dart.dev/guides/language/language-tour#keywords)になります。
Next.js+TypeScript+tailwindcssの開発環境構築

標記の開発環境構築を試したので作業ログを残す。

## 確認環境
- MacBook Pro (16-inch 2019)
- macOS Monterey 12.0.1
- Node.js v14.17.1


## 手順

以下のコマンドを実行する。

```sh
# Next.js+TypeScriptの環境構築
npx create-next-app@latest --ts my-app

# tailwindcssの環境構築
cd my-app
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
```

次に`tailwind.config.js`を以下のように書き換える

```js
module.exports = {
  content: [
    "./pages/**/*.{js,ts,jsx,tsx}",
    "./components/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
```

そして、`./styles/globals.css`の一番上にこのコードを挿入。


```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

これでいったん完了。
以下のコマンドによりブラウザで実行できる。

```sh
npm run dev
```

## さらにCSSコードを除去し、tailwindcssのみの記述にする

この状態だとまだCSSで書かれたコードが残っているので、[Next.js + Tailwind CSS Example](https://github.com/vercel/next.js/tree/canary/examples/with-tailwindcss)を参考に、tailwindcssのみの記述にしていく。

`./styles/globals.css`のコードを全部消し、以下のコードで置き換える。

```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

`./styles/Home.module.css`は削除する。

`pages/index.tsx`を以下のコードで置き換える。

```tsx
import type { NextPage } from 'next'
import Head from 'next/head'
import Image from 'next/image'

const Home: NextPage = () => {
  return (
    <div className="flex flex-col items-center justify-center min-h-screen">
      hello world!
    </div>
  )
}

export default Home
```

これで最低限のCSSファイルを除き、tailwindcssのみのコードになった。

以上

## 参考

- [Next - TypeScript](https://nextjs.org/docs/basic-features/typescript)
- [Install Tailwind CSS with Next.js](https://tailwindcss.com/docs/guides/nextjs)
- [Next.js + Tailwind CSS Example](https://github.com/vercel/next.js/tree/canary/examples/with-tailwindcss)
ナップサック問題

[問題](https://algo-method.com/tasks/308)　[dpイメージ](https://camo.qiitausercontent.com/1317fe91bc0476997781b068f8ab3d8c750793af/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3138323936332f66636433633239612d396633652d373938342d333534392d3231666131313366616232362e6a706567)

dp[i][w] :  
i 番目までの品物の中から (選ぶ、選ばない 選択)
重さが w を超えないように選んだときの、
価値の総和の最大値


```c++
// 入力
ll n, W; //荷物の数、許容容量
ll weight[110], value[110]; //重さ、価値

ll dp[110][10010]; //個数、重さ

int main() {
    cin >> n >> W;
    for (ll i = 0; i < n; ++i) cin >> value[i] >> weight[i];

    // DP初期条件: dp[0][w] = 0
    for (ll w = 0; w <= W; ++w) dp[0][w] = 0;

    // DPループ
    for (ll i = 0; i <= n; ++i) { //荷物の数
        for (ll w = 0; w <= W; ++w) { //許容容量
            if (w >= weight[i]) dp[i + 1][w] = max(dp[i][w - weight[i]] + value[i], dp[i][w]);
            else dp[i + 1][w] = dp[i][w]; //最初のみ使用
        }
    }

    cout << dp[n][W] << endl; //n以下 W以下 の最大値
}
```
画像の類似度を測る楽な方法 imgsim 

画像の類似度を測りたいなーと思い、何か楽な方法はないかと調べるとimgsimというものがありました。

参考にしました方の記事を載せます。
[参考元](https://qiita.com/john-rocky/items/12949f1408cb703df081#%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%83%A2%E3%83%87%E3%83%AB%E3%82%92%E3%81%A4%E3%81%8B%E3%81%A3%E3%81%A6%E7%94%BB%E5%83%8F%E9%A1%9E%E4%BC%BC%E5%BA%A6%E3%82%92%E6%95%B0%E5%80%A4%E5%8C%96%E3%81%97%E3%81%A6%E3%81%8F%E3%82%8C%E3%82%8Bimgsim)

# インストール編

さっそく使おうと思い、インストール
```
pip install imgsim
```
で、さっそくインポート
```
import imgsim
```
動くか見てみると
```
Traceback (most recent call last):
省略
ModuleNotFoundError: No module named 'torchvision'
```
ありゃ、なんかエラー出る
torchvisionがないというのでインストール
```
pip install tourchvision
```
するとエラーが出る
```
ERROR: Could not find a version that satisfies the requirement tourchvision
ERROR: No matching distribution found for tourchvision
```
pip installじゃダメなのか、なぜだ、、
ではconda installで
```
conda install torchvision -c pytorch
```
これで入ったので、動くようになりました！

# 実行編

MNISTで挙動を見てみたいと思います。
(60000,28,28)から(60000,786)に変換して、正規化
```
def preprocess_images(images):
  images = images.reshape((images.shape[0], images.shape[1]*images.shape[2])) / 255.
  return images
train_images = preprocess_images(train_image)
```
さて類似度を測っていきます。結果をdistという変数に入れます。
```
dist = imgsim.distance(train_images[0], train_images[0])
print(dist)
結果：0
```

類似度が高ければ、値は小さく、類似度が低ければ、値は大きくなるようです。
これは同じ画像をみているので当然、値は0になりますね
次に、この0番目の画像に対して、一番似ている画像を探しましょう。

```
dist_list=[]
for number in range(train_images.shape[0]):
  dist = imgsim.distance(train_images[0], train_images[number])
  dist_list.append(dist)
np.where(dist_list==np.sort(dist_list)[1])[0][0]
結果：32248
```
np.whereを使って一番近い画像のナンバーを表示しました。(これ以外のやり方を知らない)
さて、一番近い画像の番号がわかったことですし、これを可視化してみましょう。

0番目の画像
![image0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2119275/3276c48f-9490-aeee-7cf1-9a0ec87dce6b.png)
32248番目の画像
![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2119275/12bde864-59a0-5eaa-d91d-419508bcdacb.png)
ふむ、似てますね。これは信頼してもいいのでは。

以上です。
カラー画像もできるみたいですね。カラー画像を使う際は、[参考元](https://qiita.com/john-rocky/items/12949f1408cb703df081#%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%83%A2%E3%83%87%E3%83%AB%E3%82%92%E3%81%A4%E3%81%8B%E3%81%A3%E3%81%A6%E7%94%BB%E5%83%8F%E9%A1%9E%E4%BC%BC%E5%BA%A6%E3%82%92%E6%95%B0%E5%80%A4%E5%8C%96%E3%81%97%E3%81%A6%E3%81%8F%E3%82%8C%E3%82%8Bimgsim)にやり方が載っています。
Create React App+TypeScript+tailwindcssの開発環境構築

標記の開発環境構築を試したので作業ログを残す。

## 確認環境
- MacBook Pro (16-inch 2019)
- macOS Monterey 12.0.1
- Node.js v14.17.1

## 手順
以下のコマンドを実行する。

```sh
# react + TypeScript
npx create-react-app my-app --template typescript
cd my-app

# tailwindcssの導入
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
```

次にtailwind.config.jsを以下のように書き換える

```js
module.exports = {
  content: [
    "./src/**/*.{js,jsx,ts,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
```

そして、src/index.cssの一番上にこのコードを挿入。

```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

これで完了。

以下のコマンドによりブラウザで実行できる。

```
npm run start
```

## 参考

- [Create React App - Adding TypeScript](https://create-react-app.dev/docs/adding-typescript/)
- [Install Tailwind CSS with Create React App](https://tailwindcss.com/docs/guides/create-react-app)
インスタンス化とは　[簡単にまとめてみた]

# インスタンス化とは
クラスというのはただの「型」です。
型だけではクラスの中身というのは読み込まれません。
だけど、そのクラスをインスタンス化したら、そのクラスは読み込まれます。

それだけです。インスタンス化しないと読み込むことはできません。
# まとめ

クラスはただの「型」であり、
クラスの中身を使うには。「インスタンス化」する必要があります。
Personalized News Recommendation: Methods and Challenges

# Personalized News Recommendation: Methods and Challenges

近年のニュース推薦モデルについてまとまっている論文。困ったらコレをみれば解決しそう。
https://arxiv.org/pdf/2106.08934.pdf
2022/02
　
### ニュース推薦の運用システム

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343913/cc7676af-3a13-05e6-9c4c-4b9f40351f3c.png)


### ニュース推薦モデル

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343913/aac23ac1-e01c-2880-fd2c-cb7b665d815c.png)


### ニュースに関する特徴量

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343913/e854d30c-16ca-d9ba-cbe4-4b8b5079221f.png)


### 主要な特徴量を用いた研究

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343913/9e6fa4da-fb08-257d-98a4-50a35b3c7037.png)

### ニュース推薦モデル

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343913/296d71fe-04d6-4313-18d3-92bf256b86c1.png)

### オプション的な特徴

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343913/0834e857-bab1-b5cd-2d32-6b8351849bde.png)

## ユーザーモデリングに利用する特徴

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343913/01587137-b3f7-21bb-19c2-00547909d864.png)

## 評価指標

```math
\mathrm{AUC}=\frac{\left.\mid\left\{(\mathrm{i}, \mathrm{j}) \mid \operatorname{Rank}\left(\mathrm{p}_{\mathrm{i}}\right)<\operatorname{Rank}\left(\mathrm{n}_{\mathrm{j}}\right)\right)\right\} \mid}{\mathrm{N}_{\mathrm{p}} \mathrm{N}_{\mathrm{n}}}
```

```math
\begin{aligned}
\text { Precision } &=\frac{T P}{T P+F P}, \\
\text { Recall } &=\frac{T P}{T P+F N}, \\
\mathrm{~F} 1 &=\frac{2 * \text { Precision } * \text { Recall }}{\text { Precision }+\text { Recall }},
\end{aligned}
```

```math
\begin{aligned}
\mathrm{AP} &=\frac{1}{N_{p}} \sum_{i=1}^{N_{p}} \frac{\left|\left\{k \mid \operatorname{Rank}\left(p_{k}\right) \leq \operatorname{Rank}\left(p_{i}\right)\right\}\right|}{\operatorname{Rank}\left(p_{i}\right)}, \\
\mathrm{HR} @ \mathrm{~K} &=\frac{\left|\left\{k \mid \operatorname{Rank}\left(p_{k}\right) \leq K\right\}\right|}{K}, \\
\mathrm{MRR} &=\frac{1}{N_{p}} \sum_{i=1}^{N_{p}} \frac{1}{\operatorname{Rank}\left(p_{i}\right)}, \\
\mathrm{nDCG} @ \mathrm{~K} &=\frac{\sum_{i=1}^{K}\left(2^{r_{i}}-1\right) / \log _{2}(1+i)}{\sum_{i=1}^{N_{p}} 1 / \log _{2}(1+i)}
\end{aligned}
```

以下、多様性指標

```math
I L S(L)=\frac{\sum_{b_{j} \in L} \sum_{b_{j} \in L, b_{j} \neq b_{i}} S\left(b_{i}, b_{j}\right)}{\sum_{b_{j} \in L} \sum_{b_{j} \in L, b_{j} \neq b_{i}} 1}
```
```math
\begin{aligned}
\text { Senti }_{M R R} &=\max \left(0, \bar{s} \sum_{i=1}^{N} \frac{s_{i}^{c}}{i}\right) \\
\text { Senti@5 } &=\max \left(0, \bar{s} \sum_{i=1}^{5} s_{i}^{c}\right) \\
\text { Senti@10 } &=\max \left(0, \bar{s} \sum_{i=1}^{10} s_{i}^{c}\right)
\end{aligned}
```
```math
\begin{aligned}
E A G F &=\sum_{i=1}^{|g|} \sqrt{|L(i)|}, \\
S P D &=\frac{\sum_{i=1}^{|g|}\left|\frac{|L(i)|}{|L|}-\frac{|A(i)|}{|A|}\right|}{|g|}
\end{aligned}
```

## データセット

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343913/007afd8d-b8ab-387a-c521-5c5d573bc9b5.png)
[Mac] 画面分割アプリShitItをインストールする（Big Sur）

### ShiftItをインストール
まずは、HomebrewにShiftItがあるか確認してみましょう。
```
brew search shiftit
```
結果、何も表示されませんでした。
しかし、かまわずインストールすると、インストールに成功します。
```
brew install shiftit
```
GUIツールなので、インストール先は`/usr/local/Caskroom`フォルダになります。CUIツールの場合は`/usr/local/Cellar`フォルダですね。

ただ、ShiftItの開発は終了したみたいで、こんな注意書きが出てきます。残念です。
```
==> Caveats
shiftit has been officially discontinued upstream.
It may stop working correctly (or at all) in recent versions of macOS.
```

ちなみに、Homebrewには、**cask**、**cellar**、**formula**といった特殊な用語がいくつか出てきますが、そのあたりについては、「[Homebrew完全に理解した](https://blog.ottijp.com/2020/05/23/homebrew/)」がすばらしく分かりやすかったです。用語の関係性を示した「全体の関係図」は必見です！

### インストール後に必要な設定
起動しようとすると警告が出てきます。

:::note warn
"ShiftIt.app"は、開発元を検証できないため開けません。…
:::

この警告を一旦キャンセルして、起動できるようにしましょう。
- `システム環境設定 > セキュリティとプライバシー > 一般タブ`と進みます。
- `"ShiftIt.app"は開発元を確認できないため、使用がブロックされました。`と表示されているので、`変更するにはカギをクリックします`のカギマークをクリックしてパスワードを入力します。
- 編集可能になるので、`このまま開く`をクリックします。
- すると、`"ShiftIt.app"は、開発元を検証できないため開けません。…`のポップアップが再び出てきますが、今度は、`開く`が選択できるようになっているのでクリックしてShiftItを起動します。

### ログイン時に自動起動させるための設定
メニューバーのShiftItアイコンから`環境設定`を起動して、`ログイン時に開く`にチェックを入れます。

以上になります。
[react-hook-form] reset関数を使う場合は、setValueにオプションを設定した方がいい。

入力フォームを作る際に、デフォルトで値を入れときたいとか、リセットをしたいとかそういったケースは結構あると思います。

react-hook-formでは、reset関数を使うとデフォルト値を設定でき、簡単にリセットできるようになります。 

```tsx
import { useForm } from 'react-hook-form';

const SampleComponent: React.FC = () => {
  const {control, handleSubmit, reset, formState} = useForm();

  useEffect(() => {
    reset(initialValue);
  }, [reset]);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      ...
      <button type="submit" disabled={!formState.isDirty}>保存</button>
      <button type="button" onClick={() => reset()}>リセット</button>
    </form>
  );
}
```
簡単ですね。
なお、フォームの値を変更すると、isDirtyがtrueになり、保存ボタン押せるようになります。

## setValueのオプションにshoudDirtyを設定する。

かなり簡単なコードでリセットができて便利なのですが、setValueを使う場合はオプションを設定しないと、resetがどうやら、反映しないみたいです。


こちらですが、shouldDirty: trueを設定してあげると、反応するようになります。
```tsx
setValue(FieldName, targetNewValue, { shouldDirty: true });
```
golang template

テンプレートの定義にはdefineを使う。

```html
{{ define "TemplateName" }}
{{ template "child" }}
{{ end }}
```
テンプレートの使用
```html
{{ tempalte "TemplateName" }}

{{ define "child" }}
HTML Text
{{ end }}
```

## 追記
ginのrouterでテンプレートを読み込むと
上記のやり方だと１つのファイルの内容しか反映されない。
解決方法は

```base.tmpl.html
{{ define "top" . }}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
{{ end }}

{{ define "bottom" .}}
</body>
{{ end }}
```

```some.tmpl.html
{{ template "top"}}
<h1>Your contents.</h1>
{{ template "bottom }}
```

一般的に使われてる命名
layouts/
base.tmpl
header.tmpl
footer.tmpl
100日でSQLの達人になる@LeetCode! Day43 <UNION ALLとUNIONの違い>

## 1205. Monthly Transactions II （問題レベル: Medium）要課金
今日の問題はこれ。
会計取引の表とチャージバックの表から月・国毎のテーブルを作成するという問題。

試行錯誤はしましたが、お馴染みになってきた`WITH`句を使って解決しました。
全てが0の表は除くなど細かい指定があり苦労しました。

```:SQL
WITH cte AS ((
SELECT t.id, t.country, t.state, t.amount, LEFT(t.trans_date,7) AS month
FROM transactions t)
UNION ALL
(SELECT c.trans_id AS id, t2.country, 'chargeback' AS state, t2.amount AS amount, LEFT(c.trans_date,7) AS month
FROM chargebacks c
LEFT JOIN transactions t2
ON c.trans_id=t2.id))

SELECT c.month, c.country, 
SUM(CASE WHEN c.state='approved'   THEN 1      ELSE 0 END) AS approved_count,
SUM(CASE WHEN c.state='approved'   THEN amount ELSE 0 END) AS approved_amount,
SUM(CASE WHEN c.state='chargeback' THEN 1      ELSE 0 END) AS chargeback_count,
SUM(CASE WHEN c.state='chargeback' THEN amount ELSE 0 END) AS chargeback_amount
FROM cte c
GROUP BY c.month, c.country
HAVING SUM(CASE WHEN c.state='approved' THEN 1 ELSE 0 END) +SUM(CASE WHEN c.state='chargeback' THEN 1 ELSE 0 END)  !=0
```

今日のポイントは`UNION ALL`と`UNION`の違いとしました。
端的には、`UNION ALL`は重複を許して`UNION`は許さないというのがポイントです。
重複を検索しない分、重複が無いことが予め分かっている今回のような例の場合は、`UNION ALL`の方が処理が早くなります！

* [LeetCode](https://leetcode.com/)の問題は、`MS SQL Server`で解いています。
td-agentでjsonログ内の特定のキーの値をs3のパスとして利用する

# 概要

jsonログの特定のキーの値をS3のオブジェクトのパスの一部として利用する方法を紹介します。
具体的には以下ようなjsonログの`mykey`の値で、`s3://バケット/myvalue1/xxx.log`、`s3://バケット/myvalue2/xxx.log`のように動的にパスを生成します。

```json:sample.log
{"date":"2022/02/17 07:55:38","mykey":"myvalue1"}
{"date":"2022/02/17 08:55:38","mykey":"myvalue2"}
{"date":"2022/02/17 09:35:38","mykey":"myvalue1"}
{"date":"2022/02/17 12:10:43","mykey":"myvalue3"}
```

# 方法

jsonの値をそのまま`out_s3`プラグインでパスとして利用できない。
jsonの値をタグに含める。forestプラグインを使用することで`out_s3`プラグインでもタグを変数として使えるようになるので、タグ名をパスとして展開する。

# コード

[Docker版サンプルコード](https://github.com/comefigo/fluentd-s3-dynamic-path-sample)

```config:fluent.conf
<source>
    @type tail
    path /tmp/logs/sample.log
    tag json.logs
    read_from_head true
    <parse>
        @type json
    </parse>
</source>

# キー値をタグに追加する
<match json.*>
    @type rewrite_tag_filter
    <rule>
        # json内のmykeyキーを取得する
        key $.mykey
        pattern ^(.+)$
        # ${tag}はsourceで指定したtag(json.logs)である
        tag ${tag}.$1
    </rule>
</match>

# デバック用
# <match json.**>
#     @type stdout
# </match>

<match json.**>
    @type forest
    subtype s3
    <template>
        @type s3
        # デバック時にログレベルを変更
        @log_level info

        # AWS認証鍵
        aws_key_id xxxxxxxxx
        aws_sec_key xxxxxxxxxxxx
        
        # S3バケット名
        s3_bucket xxxxxxxxx
        s3_region ap-northeast-1

        # tag_parts[0]がjson
        # tag_parts[1]がlogs
        # tag_parts[2]がmykeyの値
        path ${tag_parts[2]}/
        s3_object_key_format %{path}%{time_slice}.%{file_extension}
        store_as text
        <buffer tag,time>
            @type file
            path /fluentd/log/s3/buffer/${tag_parts[2]}
            timekey 10s
            timekey_wait 10s
            timekey_use_utc false
            chunk_limit_size 256m
            flush_mode interval
            flush_interval 10s
        </buffer>
    </template>
</match>
```
PRML 演習6.2

## 解答翻訳
下記資料から。
https://hughchristensen.com/papers/academic_papers/BISHOP%20PRML_solution_all.pdf

初期値$\boldsymbol{w}=0$とする。パーセプトロン学習アルゴリズムでは$\boldsymbol{w}$を$t_n \phi( \boldsymbol{x}_n)$でインクリメントする。ただし$n$は現在のモデルで誤分類されたパターンのインデックスである。したがって重みベクトルは$t_n \phi( \boldsymbol{x}_n)$の線形結合で表される。
```math
\boldsymbol{w}=\sum_{n=1}^{N}\alpha_n t_n \phi(\boldsymbol{x}_n) \tag{1}
```
ただし$\alpha_n$は$n$番目のパターンが訓練時$\boldsymbol{w}$の更新に使用された回数を表す。したがって学習済みパーセプトロンによる予測は下式によって与えられる。
```math

\begin{align}
y(\boldsymbol{x})&= \rm{sign} (\boldsymbol{w}^T \phi(\boldsymbol{x})) \\
&= \rm{sign} \left( \sum_{n=1}^{N}\alpha_n t_n \phi(\boldsymbol{x}_n)^T \phi(\boldsymbol{x}) \right) \\
&=\rm{sign} \left( \sum_{n=1}^{N} \alpha_n t_n k(\boldsymbol{x}_n, \boldsymbol{x}) \right)\\
\end{align}

```
以上より予測関数がカーネル関数の形で表現されることが示された。パーセプトロンの学習アルゴリズムは誤分類されたパターン$n$に対して同様にして

```math
\alpha_n \rightarrow \alpha_n + 1 \tag{2}
```

と更新される。言い換えると、次を満たすパターンである。

```math
t_n(\boldsymbol{w}^T \phi(\boldsymbol{x}_n)) \geq 0
```
> 誤分類されたパターンならば、$t_n(\boldsymbol{w}^T \phi(\boldsymbol{x}_n)) < 0$になるのでは？

(1)と$\alpha_n \geq 0$よりこれはカーネル関数を用いて書ける。
```math
t_n \left( \sum_{m=1}^{N} k(\boldsymbol{x}_m, \boldsymbol{x}_n) \right) \geq 0
```
したがって学習アルゴリズムはグラム行列の要素のみに依存する。
>$t_m$ はどこにいった

## 追記
演習で聞かれてることは(2)までで一応答えられてるがその後がよく理解できていない。
ドットインストールでCSS 変数編をやってみた

# ドットインストールCSS 変数編です
要点だけまとめてみたので、後で振り返り用としておきます

# CSS変数とは
スタイルにおいて同じ値を一箇所で管理することが出来る仕組み
※最近導入されつつある機能なので、 caniuse.com というサイトでブラウザの対応状況を見ておく

#### 変数の宣言時のルール
1. 必ず`--`から始める
2. `var()`関数を使って、そちらに変数名を渡してあげる
:::note
宣言した変数はその要素の中だけでしか使えないので、違う要素で指定したい場合はその親要素で変数を宣言する必要がある
<strong>CSS変数は継承されるプロパティ</strong>
:::
:::note worm
文書全体で使用したい場合はルート疑似クラスが良く使われる
`:root` -> body のさらに親要素である html 要素を示す
:::

#### 変数使用時の注意点
- 変数はプロパティの値に使うものであって、プロパティ名に指定は出来ない
- 単位を後から付け足すことが出来ないので、宣言時に単位を指定する必要がある
    - どうしても後から付けたい場合、`calc()`関数を使用し、それに例: 1pxをかける　という手もある
- 個別で色を指定したい場合(ボタンだけ色を変えたいなど)にも`calc()`関数で色(+ 60~180)を足してあげる処理をする事も出来る
> あまりcalc()関数は使用しないような感じではあったが、
> 結構使用頻度は高そうな気はしている...
MacでElixirの環境構築

## 開発環境

- macOS Big Sur 11.6.4
- zsh
- Homebrewインストール済み

## 手順

```
$ brew install asdf
$ echo -e "\n. $(brew --prefix asdf)/libexec/asdf.sh" >> ${ZDOTDIR:-~}/.zshrc
$ asdf plugin-add erlang https://github.com/asdf-vm/asdf-erlang.git
$ asdf plugin-add elixir https://github.com/asdf-vm/asdf-elixir.git
$ asdf list-all erlang
$ asdf install erlang 24.3
$ asdf global erlang 24.3
$ asdf list-all elixir
$ asdf install elixir 1.13.1
$ asdf global elixir 1.13.1
$ elixir --version
```

asdf知らなかった。他の言語でも使いやすいみたい。Elixir頑張るぞ:v:

## 参考

https://asdf-vm.com/guide/introduction.html



## おまけ

shellは下記で確認できます

```
$ echo $SHELL
```
Golangでは暗黙的な型変換もあることを知ってた?


## 環境

```bash
Go version: go1.17.8
```

## コード

下記のコードにあるように、
明示的に変換しないとエラーになるタイプ (`int`) と
変換せずにそのまま代入できるタイプ (`map[string]int`) があることがわかります。

```golang
package main

import (
    "fmt"
    "runtime"
)

type MyInt int
type MyMap map[string]int

func main() {
    fmt.Printf("Go version: %s\n", runtime.Version())

    var x MyInt
    var y int
    x = y // コンパイルエラー: cannot use y (type int) as type MyInt in assignment

    var m1 MyMap
    var m2 map[string]int
    m1 = m2 // 　OK
    m2 = m1 // OK
}
```

## 理由

Golang の仕様書の [代入可能性(Assignability)](https://go.dev/ref/spec#:~:text=different%20from%20%5B%5Dstring.-,Assignability,-A%20value%20x) のところでちゃんと書いてありました。

> x's type V and T have identical underlying types and at least one of V or T is not a defined type.

a と b が同一の**underlying type** (基底型、背後霊的な型 w)を持ち、
a または b の少なくとも一方が **defined type** (派生型)でないなら、お互い代入可能のようです。
派生型は名前の通りで、別の型から`type`で新たに定義された方です。

そうすると、`m1` と `m2` はお互いに代入できることは明白ですが、

```golang
    var m1 MyMap
    var m2 map[string]int
    m1 = m2 // 　OK
    m2 = m1 // OK
```

| 変数                  | 基底型         | 派生型? |
| :-------------------- | :------------- | :------ |
| var m1 MyMap          | map[string]int | Yes     |
| var m2 map[string]int | map[string]int | No      |

問題は`MyInt` ですね。

```golang
    var x MyInt
    var y int
    x = y // コンパイルエラー: cannot use y (type int) as type MyInt in assignment
```

| 変数        | 基底型 | 派生型?                     |
| :---------- | :----- | :-------------------------- |
| var x MyInt | int    | Yes                         |
| var y int   | int    | No じゃなかった! ← ここ重要 |

`int` は 一見派生型じゃないように見えますが、
実は Golang の都合上、[ソースコード](https://github.com/golang/go/blob/master/src/builtin/builtin.go#L75)にあるように、`int` も(自分自身の...)派生型になります。

```golang
type int int
```

ちなみに、上記のリンク先にあるように、
`int`以外に`bool`、`string` などの predeclared type が全て **defined type** (派生型)になるようです。

## 参考記事

[入門 Go 言語仕様 Underlying Type / Go Language Underlying Type](https://speakerdeck.com/dqneo/go-language-underlying-type?slide=25)
[惊了！原来 Go 语言也有隐式转型](https://mp.weixin.qq.com/s/IYKx4NkHSLKn2s-0g5_TRw)

## 元記事

[Golangでは暗黙的な型変換もあることを知ってた?](https://aifan.jp/2022/03/14/golangでは暗黙的な型キャストもあることを知ってた/)

## Credits

[Photo by Chinmay Bhattar](https://unsplash.com/photos/fd9mIBluHkA)
【iOS】TableViewのCell をスワイプして削除する

# はじめに
これは半分メモ書きのような記事です。そこまで内容は深くありませんのでご了承のほどよろしくお願いいたします。

# 前提内容
画像のような簡単な ToDo アプリを作成中です。タップしたらチェックマークが付き、再度タップするとチェックマークが外れる。iOS アプリ開発で入門的存在といて扱われるようなアプリです。
![Simulator Screen Shot - iPhone 11 - 2022-03-14 at 21.59.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/707293/ed2a8233-c749-278d-6758-b5aab3927da5.png)

# 目標
画像のように、削除用のボタンを左にスライドさせると出現します。
タップもしくはそのまま左にスライドさせると Cell が削除されます。
![Simulator Screen Shot - iPhone 11 - 2022-03-14 at 22.20.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/707293/1dd52103-259e-0d90-19df-3fe39cd8b5f9.png)

# やり方
方法はとてもシンプルです。``ViewController.swift`` の中に次の方法を追加します。
```swift
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        // 1
        items.remove(at: indexPath.row)

        // 2
        let indexPaths = [indexPath]
        tableView.deleteRows(at: indexPaths, with: .automatic)
    }

```
`items` は配列です。この `items` の中に `TableView` の Cell にある `Walk the dog`、`Brush my teeth` などの文字列やチェックマークについての情報が入っています。

## 説明
簡単に説明します。
まず、1 の `items.remove(at: indexPath.row)` で配列からアイテムを削除します。

次に、2 の `let indexPaths = [indexPath]` と `tableView.deleteRows(at: indexPaths, with: .automatic)` 注目する。
ここから、`TableView` から対応する行を削除します。

# 注意
`items.remove(at:)` を呼び出すと配列から取り出すだけでなく、オブジェクトへの参照がなくなるため、永久的に破棄されます。

# 最後に
今回は簡単なメモ投稿になります。最後まで読んでいただきありがとうございます。
cancancanでモデル名に紐づかない制御をする方法

# はじめに

権限制御のgemとして、[cancancan](https://github.com/CanCanCommunity/cancancan)があると思います。
基本的な使い方はいろいろなところで記事になっていますが、「コントローラ名通りのモデルがないとき」の権限制御方法について記載します。

# 例

コントローラで次のように記載

```rb
class ProfilesController
  authorize_resource  class: :profile # ここではコントローラ名と同じprofileにしていますが、コントローラと名前を揃える必要もないです

  def new 
    ...
  end

  def edit
    ...
  end

end
```

シンボルの形で描くことで、モデルがなくても権限管理することができます。
あとは通常の使い方と同じで、abilityクラスで定義していきます。

```rb
class Ability
  include CanCan::Ability
  
  def initialize(user)
    if user.admin? # もしユーザーがadminなら全ての権限を付与
      can :manage, :profile
    elsif user.company? # もしユーザーがcompanyなら閲覧のみ可能
      can :read, :profile
    else # いずれでもなければ全てのアクションを不許可
      cannot :manage, :profile
    end
  end
end
```

## 参考
基本的な使い方は以下などを参考にすると良いと思います。
[Rails|CanCanCanの使い方解説](https://weseek.co.jp/tech/1211/)
MongoDBについてまとめてみた

# MongoDBとは？
Mongo DBは、NoSQL(RDBMSではないデータベースシステム)の一種になります。
JSON形式でデータを管理しています。
C++で開発されています。

# なぜMongo DBが生まれたのか？
Mongo DBはRDBMSの弱点を補うために生まれました。
昨今、ログやソーシャルゲームなどで大量のデータを保持する必要性が生まれてきました。
すると、RDBMSのように毎回 テーブルの定義を行う必要性があるデータ形式ではデータを保持するのが大変になります。
そこで、テーブル定義(スキーマ)を必要としないNoSQLが生まれてきており、その1種がMongo DBになります。

# Mongo DBのデータ

「データベース > コレクション > ドキュメント」という構造でデータを管理しています。

わかりにくいので解説します。
ドキュメントとは、下記のような形でデータを保存するものです。
左側にkeyというデータを取り出すときの番号みたいなもの、
valueというところに実際のデータを配置します。
学校で言うと、keyが出席番号で、valueがその出席番号に紐づく生徒の情報に当たります。

**ドキュメント**
<img width="300" alt="グラフ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201104/b718e90a-17bd-5da2-4806-6e2c9ca3f2a1.png">


コレクションは、このドキュメントを複数所有しているものになります。RDBMSでは、テーブルにあたります。

**コレクション**
<img width="200" alt="グラフ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201104/aa143961-5296-a81f-d1e5-f26e539c911b.png">

データベースは、このコレクションを複数所有している大本になります。

<img width="800" alt="グラフ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201104/d9d28c39-67a8-e75a-0c7d-1170e7778a68.png">

# シャーディング
シャーディングとは、データを複数サーバーに分散展開させる仕組みのことです。
Mongo DBはこのシャーディングを使って、簡単にスケールアップ(CPUやメモリ・ストレージなどを高性能にすること)を行えます。

流れを確認します。

まずはシャーディングを行いたいコレクションを指定します。
指定後は、コレクション内のデータにシャードキーというものが付与されます。
シャードキーの範囲からある程度の塊をチャンクとします。(下記参照)


<img width="500" alt="グラフ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201104/3b53559d-cbd2-2a5f-f8d8-b7281379a080.png">


チャンクをそれぞれ別のサーバーに保管していきます。

<img width="500" alt="グラフ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201104/84278ff2-fac3-909e-82c1-022032816ea8.png">

このようにデータを複数サーバーに分散展開させる仕組みをシャーディングと呼びます。

# メリット/デメリット

メリット
* keyで指定できることによる、高速なレスポンス
* シャーディングやレプリケーションにより、障害耐性が高い

デメリット
* データの整合性を保つのが大変


# 向いているシステム
下記のようなシステムに向いていると言われています。
* Webサイトのログ蓄積
* 負荷の低い読み取り・更新処理が大量にあるシステム(ゲームなど)

# まとめ
いままでRDBMSばかりだったので、Mongo DBの仕組みが面白かったです。
もし誤りなどがあれば、コメントで指摘いただけると助かります。
SwiftUIで角丸ボタン

## 作りたい角丸ボタン
![](https://storage.googleapis.com/zenn-user-upload/cbe38c35e21cae4a3533ccc4.jpeg)

### 実装コード
```swift:button.swift
Button(action: {
	// アクション
}){
	Text("ボタン")
	// 枠線のフレームを作成
	.frame(width: 130, height: 50, alignment: .center)
	// フレームのコーナー設定と枠線の太さ設定
	.overlay(
		RoundedRectangle(cornerRadius: 10)
			.stroke(Color.blue, lineWidth: 2)
	)
	// ボタンの背景色を設定
	.background(RoundedRectangle(cornerRadius: 10).fill(Color.white))
	.padding(20)
}
```

## 重要ポイント
通常のようにボタンに背景色を設定しようとすると、角丸のフレームからはみ出した矩形の背景が表示されます。
![](https://storage.googleapis.com/zenn-user-upload/87d660ca727df7656f49cf7e.jpeg)
```swift
// ボタンの背景色を設定
.background(Color.white)
```

そこで、backgroundにRoundedRectangleで同様の角丸を設定し、fillで塗りつぶしカラーを設定してあげます。
```swift
// ボタンの背景色を設定
.background(RoundedRectangle(cornerRadius: 10).fill(Color.white))
```

これで角丸ボタンを作成できました。
DeepRacer 報酬関数 all_wheels_on_track

# all_wheels_on_track
[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/deepracer/latest/developerguide/deepracer-reward-function-input.html#reward-function-input-all_wheels_on_track)

車両がトラック内にあるのかトラック外にあるのかを示すBoolean型フラグです。
ホイールが1つでもトラックの外に出るとFalse、全てトラック内にある場合はTrueを返します。

# 実装
デフォルトの報酬関数にトラック内を走行すると報酬が貰えてコースアウトすると貰える報酬が減るように処理を追加しました。

``` 
def reward_function(params):
    
    # パラメータ取得
    all_wheels_on_track = params['all_wheels_on_track']

    reward = 0
    
    #トラックアウトすると報酬減
    reward_on_track = 0
    if all_wheels_on_track == False:
        reward_on_track = 1e-3
    elif all_wheels_on_track == True:
        reward_on_track = 5

    reward += reward_on_track
    return float(reward)
```

# all_wheels_on_track実装の結果

▼トレーニング結果
![トレーニング結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2239199/7d0a040d-e1dd-de14-aa17-817ca1c4ec0a.png)


▼評価結果
![評価結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2239199/710bdd57-439b-8db8-67c2-8d18d257a682.png)


デフォルトの報酬関数のみ実装の場合とあまり変わらない結果となりました。
どちらにしてもカーブを曲がりきることが出来なかったのでカーブの対策と合わせて使用する必要がありそうです。
３６０度写真を撮影してGoogleストリートビューに公開するまでの流れとかコツ。

３６０度写真を撮影してGoogleストリートビューに公開するまでの流れとかコツ。

３６０度カメラのTHETA Sで撮影してGoogleストリートビューに公開をするというのは結構前からかやってたんですが、久しぶりにやってみたらどうも勝手が違って迷ってしまったのでやり方のコツとか手順とかの紹介というていでのメモ。

【撮影時】
まず、撮影時です。
自撮り棒があると撮影しやすいです。
三脚もいいんだけど機動性重視で歩き回って撮影なら自撮り棒がオススメです。
三脚があるとねレンズの反対側に回って二枚撮影しておいて後から一枚に合成するとかそういうテクニックも使えますが、今回は自撮り棒で撮影してくることを前提で書きます。
自撮り棒もいろいろありますが１ｍ前後のものが使いやすいです。

もう少し長い物の方が後で自分の姿を消すときに小さくなるので消しやすいけど持ち歩くのがすこし邪魔よね。
オススメは１メートルくらいあって邪魔にならない程度の長さのものが良いです。
長い物だと意外と面白い使い道があったりもしますけどね。

歩き回って撮影するのに楽な方法はiphone用のBlueToothカメラリモコンボタンで撮影する方法。

あらかじめiphoneアプリとTHETASを無線接続しておきリモコンでシャッターが切れることを確認しておく。
そしてiPhoneをスリープモードにしないままで、ポケットに突っ込んでおく。
こうすると自撮り棒を上に掲げて、リモコンボタンを押すだけで位置情報の付属した360度写真が撮影できる。
この方法がシンプルで良いと思う。

BlueToothカメラリモコンだと、たまに反応しなかったり少しタイムラグがあったりするので
有線リモコンを使うって手もあるけど、やっぱり少し邪魔になるなーという印象。
シャッターを切った後のタイムラグは少ないからアリっちゃーありかな。

もう一つお手軽な撮影方法としてTHETASをセルフタイマーモードで起動しておいて、シャッターボタンを押し、すかさず自撮り棒で上にかざす方法ってのがあって
こっちのほうが楽なんだけど、これだとiPhoneと連携してないので位置情報が記録されないのよね。
なのでGoogleストリートビューに公開時にGPSロガーと連携して後で位置情報を埋め込まないといけなかったりして少し面倒くさいのでおススメはしない。

【撮影場所の選定のコツ】
撮影時の足元が芝生とか、砂利とか、土とか、コンクリート、アスファルトなど模様が目立たない、不定のパターンのような場所を選んでおくと後で自分の姿を消すときに処理しやすい。
逆に石畳とか、地面に描かれた絵の上とかだとあとで辻褄を合わせるのが大変なので、そう言うとこは避けた方が楽です。
自撮り棒もなるべく手をいっぱいに伸ばして撮ろう。ほんの数センチ伸ばして撮るだけで、写真に写りこむ自分の姿は小さくなるので加工しやすくなります。

【撮影データのPCへの取り込み】
そんで、撮影し終えたデータは一旦PCに取り込む。
THETAで写真を撮るとどうしても自分の姿が入り込んでしまうのでスマホアプリでぼかしを入れたりすることもできるけれど、どうせならきれいに姿を消してから公開したい。
THETAからデータを転送するパソコンはWindowsPCがいい。
MACでデータを転送するとなぜか位置情報が削除されてしまうみたい（ぐぬぬ）
ということでPCに写真データをコピー転送しておく。

そして撮影データの加工。
写りこんだ自分の姿を消すにはフリーソフトのGIMPが良い。ネットで探してインストールしてくれ。
それで撮影した写真データをGIMPで開く。
そうすると画面下の方に自分の姿が引き延ばされた形で写っていると思う。
このまま画像を加工して消してもいいんだけど
３６０度写真としてみた場合に画像の上下端は横方向にすごく引き伸ばされて、よっぽどうまくやらないと360度表示した時に破綻してしまうので加工前にひと工夫すると良い。

ひと工夫の方法は
GIMPのメニューのフィルタ→変形→極座標を選ぶ。
すると表示していた画像が丸く奈多ハズだ。
ここでさらに「map from top」というチェックを外す。
そうすると中心付近に自分、外周方向に空という形の円形の画像になったと思う。
ここで「ｏｋ」を押して確定

こうするとTHETAで撮影したときの足元方向が中心付近に集まっている
後は、その中心付近をスタンプツールで周辺をコピーしつつ自分の姿を消していく。
このとき使用するブラシは周辺がぼけている、少し大きめのもの(ブラシサイズ30ー80ピクセルくらいかな)を使うとやりやすい。

そして自分の姿を消し終わったら。

またGIMPのメニューのフィルタ→変形→極座標を選ぶ
ここで今度は「top polar」というチェックを外す。
すると写真が元の形に戻るはず。

こうやって加工しておくと３６０度写真として表示したときにも破綻がないものにできる。

そして、THETAで撮影した写真はピントの眠い写真になりがちなので
ほんのすこしフィルタでシャープにしておくと見栄えがする。

後は明るさをいじったり、色味をいじったり好きにすると良い。

そんで、気が済んだら書き込みだ。

GIMPのメニュー→ファイル→エクスポートで書き出す。

エクスポートで書き出すと、元の画像に上書きしてしまうので注意。
上書きしたくない場合、別名でエクスポートしてください。

それでエクスポートする際に「XMPデータの保存」にチェックが入っていることを確認する。
ここに位置情報が格納されているのでチェックを外すと、位置情報を設定し直さないとならないので注意。

これでGoogleストリートビューに投稿する360度写真の準備はオッケー。

【Googleストリートビューに写真を登録する】
Googleストリートビューに写真を登録する方法なんだけど
以前はパソコンからGooglePhotoにアップロードして公開ってのができたハズなんだけど、最近はできなくなったみたい。

なので、こういう手順でやるとできますよってことを公開します。
まず、iPhoneでGooglePhotoとGoogleストリートビューのアプリを入れて使えるようにしておきます。

そしてPC側でGooglePhotoのサイトを開いて
先ほど作成したTHETAの写真を加工したものをドラッグ＆ドロップで登録します。

その後、Googleストリートビューを開いて、360度写真のインポート→Googleフォトと選ぶと
先ほどGooglePhotoに登録した写真が出てくるので、選んでインポートします。

そんで公開する画像を選んで公開する。

すると「登録しています」とか「公開しています」とか表示が出るので
これでGoogleストリートビューに公開できたことになります。

自分が登録した写真はすぐに確認できるけど、他の人にも見れる一般公開されるには少し時間がかかるみたい。

短いときには３０分くらい、長いときには数時間くらいかかるっぽいので
登録した翌日くらいには見れると思って気長に待ってみましょう。

３６０度写真を撮影してGoogleストリートビューに公開するまでの流れとかコツの公開でした。
make(旧integromat)を使ってLambdaを実行する

## 1.はじめに
make(旧integromat, 以下本記事ではmakeで記します)からLambdaを呼び出す手順です。
ただそれだけなのですが、makeに関する情報が少なく難儀したので、やったことを書き留めました。

## 2.今回やること
こんな感じのパイプラインを作ってLambdaを実行します。
Slackのチャンネルに投げたメッセージをトリガーにして、OutgoingWebhooksからmakeのWebhooksを呼び出す。
WebhooksはSlackやGmailに代替しても同じことができると思います。

![スクリーンショット 2022-03-14 21.25.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278897/4f82290b-f3e2-c090-332e-6b27ad24e777.png)


## 3.アプリの設定
一般的な手順で各アプリに対して設定を行い、パイプラインを作ります。

### 3-1.Slack
適当なチャンネルを作成する。パブリックとプライベートどちらでも構いません。
このチャンネルにキーワードを投げるとmakeが反応するようにします。

### 3-2.make
この段階ではサインアップしてアカウントだけ作っておく。
リージョンはUS, EUどちらでもOKです。

### 3-3.AWS(Lambda)
Lambdaの実行ログに文字列をprintするだけのかんたんなpythonプログラムです。
公式に良い感じのコードがあったのでそれをコピペして不要な箇所を削除しただけ。

```python:okome_make_dev_function
import boto3

def lambda_handler(event, context):
    print('started your instances: ')
```

けどちゃんと動くのでAWSすごいな！っていつも思います。
引用元はこちら。EC2の起動・停止プログラムのサンプルです。
https://aws.amazon.com/jp/premiumsupport/knowledge-center/start-stop-lambda-eventbridge/

テストで動かして、CloudWatch Logsに`started your instances: `が出力されればLambdaの準備は完了です。

### 3-4.AWS(IAM)
今回はmake専用のIAMユーザを作成します。
GUIは使用しないのでCLIのみ、LambdaのFullAccessをアタッチする。
いつも使ってるユーザとかシステムユーザ的なアカウントがあればそちらでもいいと思います。

アクセスキーとシークレットキーをmakeの設定で使います、控えておいてください。

## 4.Scenarioを作る
ここからmakeの設定を行います。

### 4-1.Webhooksモジュール
適当に作る。GUIがわかりやすいので迷わないはず。
このタイミングでhookするURLが生成されるので、SlackのOutgoingWebhookを先ほど作ったチャンネルにアプリ追加で紐づけてあげます。
手順は一般的なやり方で設定する。キーワードも任意で構いません。

### 4-2.Lambdaモジュール
関数の呼び出しにはInvoke a Functionを使います。

![スクリーンショット 2022-03-14 20.25.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278897/d9d11ff6-f400-5a72-0f19-be0e462153b6.png)

`Connection`に先ほど作成したIAMユーザのアクセスキーとシークレットキーを入力、認証が通ればリストからLambdaが選べます。

### 4-3.補足：Bodyについて
`Body`には{ "key":"value" }形式でLambdaに値を渡せます。
渡せる値はWebhooksで確認できます。

![スクリーンショット 2022-03-14 21.51.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278897/65431cb3-bdff-bd34-fe48-b380e34cc84c.png)

実際に設定する時はこんな感じ。

![スクリーンショット 2022-03-14 22.07.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278897/e0bcb54b-0f7f-2972-54c5-df668e52acdf.png)


Lambda側で`key`を変数として宣言してあげれば、渡した値(今回だと文字列`Run Function`)をプログラムで利用可能です。

## 5.実行してみる
あとはシナリオを保存し、Run onceでテストしてみたり、シナリオをONにして実行してみてください。
Slackのチャンネルにキーワードをメッセージすると、make経由でLambdaが動くと思います。

Errorが出てもGUIがわかりやすく教えてくれます。エラーログも出力される。
読んで対処してみてください。

## 6.おわりに
実際に業務で使うとなるとRouterやFilterを使ったりしてもっと複雑になると思いますが、ベースはこれでOKかと。
細かいところを端折っていますが、makeのGUIがめちゃくちゃわかりやすいのであまり迷わないと思います。

以上、ぼくもしばらくこの手のSaaSを使う機会が無さそうなので備忘録を兼ねた記事でした。
どなたかのお役に立てると嬉しいです！
【後日談】〜MacでRStudioを使用するために「.Rprofile」を設定

# 再度「.Rprofile」

[先日の投稿](https://qiita.com/tex_owleyes/items/1051a5f88787e1fe6fb5)でコメントを頂き、「system関数を使いRのコンソールからターミナルへコマンドを送する」方法を教えて頂きました。
使用しました。

前回同様にRStudioの左上のコンソールで下記を記述し、

~~~
library(stats)
library(tidyverse)
library(ggplot2)
library(GGally)
library(patchwork)
library(lubridate)
library(dplyr)
~~~

「.Rprofile」という名称で保村しました。
「.Rprofile.R」という名称に変わってしまいます。
以下、RStudioの右下の画面です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/abfb5e83-d6f4-465a-d3be-9c7ac3d648a7.png)

# system関数利用

左下のコンソールからsystem関数を使います。

~~~
system("mv .Rprofile.R .Rprofile") 
~~~

ファイル名を「.Rprofile」に変換できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/96680e83-9afa-d6df-4e5d-67bfeda8a058.png)

**了**
WordPressでサブループをよく使う場面

普段仕事でWordPressを使用するので、サブループをよく使用する場面をメモ。

## トップページでカスタム投稿の記事を3件だけ出力したい

3件じゃなくてもいいのですが…コーポレートサイトではほぼ間違いなくあるんじゃないでしょうか。

例えば「新着情報」として、informationというカスタム投稿を出力したい場合
```php
<?php
$paged = get_query_var('paged', 1);
$query = new WP_Query(
array(
'paged' => $paged,
'posts_per_page' => 3,
'post_type' => 'information'
));
if ( $query->have_posts() ):
while ( $query->have_posts() ) : $query->the_post();?>

// ループの内容

<?php endwhile; ?>
<?php wp_reset_postdata(); ?>
<?php endif; ?>

```

ちなみにifとwhileは一緒の場所に書く必要ないです。

例えばinformationの記事がなければ、セクションごと表示しなくてもいいなら
```php
//ここまで省略
<?php if ( $query->have_posts() ): ?>

<section>
<div>
<h2>新着情報</h2>
<ul>
<?php while ( $query->have_posts() ) : $query->the_post();?>

<li>hogehoge</li>

<?php endwhile; ?>
</ul>
</div>
</section>
<?php wp_reset_postdata(); ?>
<?php endif; ?>

```
みたいにすれば、記事がなければセクションごと表示されなくなるはず。
EC2 の Retirement 対応でインスタンスの停止・起動ではなく再起動をしたらハマった

# 背景

以下のようなメールが届いた。EC2 を動かしているハードウェアの問題で、期日までにインスタンスを停止→起動してほしいとのこと。

> EC2 has detected degradation of the underlying hardware hosting your Amazon EC2 instance (instance-ID: i-xxxxx) associated with your AWS account (AWS Account ID: xxxxx) in the ap-northeast-1 region. Due to this degradation your instance could already be unreachable. We will stop your instance after 2022-03-28 10:00:00 UTC. Please take appropriate action before this time.
> 
> (中略)
> 
> What do I need to do?
> We recommend that you stop and start the instance which will migrate the instance to a new host. Please note that any data on your local instance-store volumes will not be preserved when you stop and start your instance. For more information about stopping and starting your instance, and what to expect when your instance is stopped, such as the effect on public, private and Elastic IP addresses associated with your instance, see Stop and Start Your Instance in the EC2 User Guide (https://docs.aws.amazon.com/en_us/AWSEC2/latest/UserGuide/Stop_Start.html). However, if you do not need this instance, you can stop it at any time yourself or wait for EC2 to stop it after the retirement date.

# やったこと

インスタンスを再起動。(停止→起動ではない。これが間違いだった。)

# 起きたこと

## Retirement の問題が解消しない

EC2 のマネージドコンソールの「イベント」で、本来解消するはずの Retirement 通知が解消されていない。
つまり、再起動ではインスタンスを動かすハードウェアが変わらなかった。

## インスタンスが起動しない

ハードウェアの問題か、インスタンスが一向に起動されなかった。具体的には「ステータスチェック」がいつまで経っても合格しなかった。

## 停止が効かない

ようやく再起動がまずかったと気付いたため、改めてインスタンスの停止を試みたが、インスタンスが一向に停止されなくなった。

# 解決策

アクションに「インスタンスの強制停止」があったため、ダメ元で実行してみたら 4～5 分ほどかかってようやくインスタンスが停止された。
その後インスタンスを起動させたところ、問題は生じなかった。

マネージドコンソールの「イベント」欄で、Retirement 通知が「Completed」になった。

# 参考

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/TroubleshootingInstancesStopping.html

もし「強制停止」でもダメだった場合は、フォーラムかサポートセンターに問い合わせるとよいとのこと。

以上のように、EC2 における「再起動」は「停止→起動」の代替ではないので、要注意。
初心者ブロックチェーンに挑戦する　14

#  とても低いプラトー

## でも何もしていないわけではない

　第一章のテキストが終了したのに、作品が提出できず、結果、次の章にも進めない足踏み状態にある。
　でも、何もしなかったわけではなく、まずコミュニティで、提出済みの作品のコードを共有してくれる人を募った。何人かがGitHubを公開してくれた。中で一番自分のやりたいことに近そうな人のコードに絞って熟読開始。すぐに、公開されているのはフロントエンドだけだと気づいた。すみません、スマートコントラクトも見せてもらえますか。

　ただ見せてほしいというだけでなく、「こういうことがしたいから」と宣言もしてしまったので、もう後には引けない。自分で自分を追い詰めた感満載。
　私が滞っている間にも、続々と作品が提出されていく。
　やっぱり集中力や持続力は落ちてきたなと、ちょっと自分を恨めしく思うが、変な競争心を発揮していらついてもしようがないので、ここはじっくり腰を据えて。

- 妥協せずに、やろうと思ったことをやろう。

## 明日はなにか、目に見える進捗がありますように。
SS1（資産管理ソフト）: 内部 View についてのメモ

# 背景
ss1 のデータを吸い上げて処理しようとしたくなったので、少しばかり調査した記録

https://www.dos-osaka.co.jp/ss1/

# 環境
ss1 version 11

# 管理アプリで見るデータの在処
Table/View が大量にあって、どこに格納されてるの？ってなるんですが、
とりあえず、必要そうな情報は以下二つの View にありそうだった

## SS1V30 - Views 
### V_F_Kikijh
各機器の情報
- REE17_JH　［その他］タブの50個はこれ。番号で
- BitLocker_ProtectionStatus　BitLocker が有効か？
- OS + ReleaseID 　で、 WIndows 10 Enterprise 1909 みたいにとれる

### V_F_Softjh_Export
インストールソフトはここに集約
- SOFT_NM　インストール名でフィルター出来る
- VERSION_NO　ソフトのバージョン

# 列名一覧取得用 SQL
kikijh は列名多過ぎなので、列名一覧から探す為に、以下を利用すると便利

```sql:列名取得 N'V_F_Kikijh
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = N'V_F_Kikijh'
ORDER BY COLUMN_NAME
```

```sql:列名取得 V_F_Softjh_Export
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = N'V_F_Softjh_Export'
ORDER BY COLUMN_NAME
```

# あとがき
これを必要とする人はあまりいないと思います :laughing:
【Laravel】attachとsyncWithoutDetachingの使い分け

この記事は移行しました！[最新の内容はこちら](https://naoqoo2.github.io/blog/Laravel-attach%E3%81%A8syncWithoutDetaching%E3%81%AE%E4%BD%BF%E3%81%84%E5%88%86%E3%81%91/)をご覧ください😀


## はじめに
多対多のリレーションで関連付けたいときは`attach`!と覚えていたのですが
中間テーブルにユニーク制約を貼ってる場合に`attach`を連続で実行してしまうとエラーになる。。
（ユニーク制約がなければ同一レコードが複数できる）
うーん、困った。
そんなときは`syncWithoutDetaching` を使いましょう。

## 挙動の違い

- `attach`
    - 常にinsert
- `syncWithoutDetaching`
    - なければinsert、あれば何もしない

ということで、AとBの関係性が
- 複数あり得る場合は`attach`
- 最大1つの場合は`syncWithoutDetaching`

が良いよ！

[公式のサンプル](https://readouble.com/laravel/8.x/ja/eloquent-relationships.html?header=%25E9%2596%25A2%25E9%2580%25A3%25E3%2581%25AE%25E5%2590%258C%25E6%259C%259F#attaching-detaching)ではユーザーにロールを与える際に`attach`をしていますが
一人のユーザーに同じ権限を複数与える（Aさんにadmin権限2個）といったことはないので
`syncWithoutDetaching` がオススメ。


## attachの使い所

- 買い物カゴに商品を入れる
    - 同じ商品を複数入れる可能性があるため
- （パッと思い付かないな）

## syncWithoutDetachingの使い所

- 商品をお気に入り登録する
- ユーザーにロールを与える
ASP.NET Core Web APIのURLにケバブケースを使いたい


## やりたいこと

ASP.NET CoreでWeb APIを作成した時は、標準ではURLがPascal Caseになります。

例えば、以下の例では、`/SubscriptionManagement/ListAll` がURLのパスになります。

```cs
public class SubscriptionManagementController : Controller
{
    [HttpGet("[controller]/[action]")]
    public IActionResult ListAll()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }
}
```

これを`/subscription-management/list-all` にようなケバブケース(kebab case)にしたい場合があります。

## ケバブケースにする方法

公式ページの
[ASP.NET Core でのコントローラー アクションへのルーティング](https://docs.microsoft.com/ja-jp/aspnet/core/mvc/controllers/routing?view=aspnetcore-6.0#use-a-parameter-transformer-to-customize-token-replacement) の「パラメーター トランスフォーマーを使用してトークンの置換をカスタマイズする」に書かれています。

### IOutboundParameterTransformer インターフェースを実装

まず、やることは、IOutboundParameterTransformer インターフェースを実装したクラスを定義します。公式ページのコードそのままです。

```cs
using System.Text.RegularExpressions;

public class SlugifyParameterTransformer : IOutboundParameterTransformer
{
    public string? TransformOutbound(object? value)
    {
        if (value == null) { return null; }

        return Regex.Replace(value.ToString()!,
                             "([a-z])([A-Z])",
                             "$1-$2",
                             RegexOptions.CultureInvariant,
                             TimeSpan.FromMilliseconds(100)).ToLowerInvariant();
    }
}
```

### Program.cs でSlugifyParameterTransformerを追加

そして、Program.cs に以下のようなコードを追加します(.NET 6の場合)。

```cs
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews(options =>
{
    options.Conventions.Add(new RouteTokenTransformerConvention(
            new SlugifyParameterTransformer()));
});
```

これにより、パラメーター トランスフォーマーをアプリケーションのすべての属性ルートに適用します。

.NET 5、.NET Core 3.1の場合は、Startup.csのConfigureServicesメソッドで、以下を追加します。

```cs
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews(options =>
    {
        options.Conventions.Add(new RouteTokenTransformerConvention(
                                     new SlugifyParameterTransformer()));
    });

}
```

これで、ケバブケース(kebab case)になります。
【Python3】pytestで例外を検出する方法

メモ書きです

### 環境
- python3.8.10
- pytest6.2.5

### 実装例

```py
# pytestモジュールをimport
import pytest


def target(int):
    
    
    if int > 100:
        # 100より大きい数値の場合例外を送出
        raise ValueError("不正な値です")
    return int * 2

def test_target():
    
    test_int = 101
    # ValueErrorを検知
    with pytest.raises(ValueError) as e:
        target(test_int)
        
    # エラーメッセージを検証
    assert str(e.value) == "不正な値です"

```

``` with.pytest.raises(例外クラス) ``` で例外を検知します。
注意点は以下の2点です。

- pytest.raises()の引数にExceptionを指定すると、関係のない例外がキャッチされるので本来検証したい観点が検証できない
- assert文はwith句と同じインデントレベルにする

あたりです。