OmniAICreator/Qiita-1.07M huggingface dataset:
Android Studioで静的解析のエラーが表示されない件

## きっかけ
会社でFlutterを使い始めたので勉強のために環境を用意したが、
なぜか個人用のプロジェクトだとソースコード上に静的解析のエラーが表示されなかった

## 結論
原因まではわからなかったが、gitで管理されていないと表示されないことがわかりました

ということでサンプルプロジェクトをgithubにpushすることで解決できました

使ったqiitaを載せておきます


GitHubが無料化されてた

https://qiita.com/wagase/items/4ed3e9998848cfa733be

めんどくさいからAndroid Studioからpushしよう

https://qiita.com/yuki0619/items/8579daff0663725a46dd

そのままやるとエラーになるから気をつけて

https://qiita.com/tetsu-upstr/items/e72147250701cf30ee72
The engine "node" is incompatible with this module.エラーが出力する時の対処方法

# 概要
- エラーが出た時の対応方法をメモ
- 根本的な話は分かっていないものです。

# 対応コマンド
```
yarn install --ignore-engines
```

# 参考サイト
https://stackoverflow.com/questions/56617209/the-engine-node-is-incompatible-with-this-module
【Linux】コマンドを連結して実行する

## 複数のコマンドを連結して実行する方法
シェルスクリプトにおいて、`;` `&` `&&` `||` でコマンドを連結することで複数のコマンドを連続して実行することができます。

### `;` (セミコロン)
`;`は前のコマンドが終了すると次のコマンドが実行されます。

```
$ command1 ; command2
```
上記の場合には`command1`が終了すると`command2`が実行されます。

### `&` (アンパサンド)
`&` は前のコマンドの終了を待たず次のコマンドが実行されます。

```
$ command1 & command2
```

上記の場合には`command1`を実行しながら`command2`を実行します。

### `&&`
前のコマンドが終了ステータス0で正常終了した場合に次のコマンドを実行します。
異常終了した場合は`command2`は実行されません。

```
$ command1 && command2
```

上記の場合には`command1`が正常終了した場合に`command2`を実行します。
`command1`が異常終了した場合には`command2`は実行されません。

### `||`
前のコマンドが終了ステータス0以外で異常終了した場合に次のコマンドを実行します。
前のコマンドが正常終了した場合には次のコマンドは実行されません。
```
$ command1 || command2
```

上記の場合には`command1`が異常終了した場合に`command2`を実行します。
正常終了した場合は`command2`は実行されません。
pythonでZoom APIを触ってみた

近年コロナウィルス感染症の流行以来、リモートワークが日本国内で進んでいる。
以前より広く使われている`Zoom`だが、APIが公開されており、
 1. ユーザー一覧の取得[^1]
 2. ユーザーのミーティングIDやウェビナーIDの生成[^1] が行える。

今回はpythonを使ってZoom APIを触ってみようと思う。
しかし、Python標準ライブラリ`urllib`, `json`等を使って、直接リクエストをZoom APIへ送って...とするのは非常に面倒である。
よって、`Zoom API`を体験することが目的であるため、`pyzoom`[^2]を使用し、Zoom APIを触っていく。

# 準備
Python 3.9.1
`venv`で仮想環境を作成し、`pip install pyzoom`にて`pyzoom`をインストールした。

Zoomのユーザー登録をしていない方はまず作成すること。
ZoomにsigninしてJWTアプリを作成する。[^3]
# ミーティング部屋・会議室を作ってみる
```create_room.py
from pyzoom import ZoomClient
client = ZoomClient('YOUR_ZOOM_API_KEY', 'YOUR_ZOOM_API_SECRET')
meeting = client.meetings.create_meeting('Auto created 1', start_time=dt.now().isoformat(), duration_min=60, password='not-secure')
print(meeting.id)
```
簡単に部屋のIDを生成できた。

実行結果の確認は、[https://zoom.us/meeting#/upcoming](https://zoom.us/meeting#/upcoming)もしくは、手持ちのスマホZoom AppからIDが生成されたか確認する。
ここで出力した`meeting.id`を次で使うので控えておくこと!

# 部屋の名前を変えてみる
``` update_name.py
from pyzoom import ZoomClient
client = ZoomClient('YOUR_ZOOM_API_KEY', 'YOUR_ZOOM_API_SECRET')
meeting = client.meetings.update_meeting('日本語に変える', meeting_id = meeting.id ,start_time=dt.now().isoformat(), duration_min=30,password='aiueo')
```
さきほどの`meeting.id`を使用して、部屋を編集してみる。
実行後に部屋名・期間・パスワードの変更ができたことが分かる。

# pyzoomの内部を覗いてみる
```pyzoom/_base.py
@attr.s
class APIClientBase:
    api_key: str = attr.ib(repr=False)
    api_secret: str = attr.ib(repr=False)

    name = "zoom_api_client"
    user_id: str = "me"
    base_url: str = "https://api.zoom.us/v2"
```
Zoom APIのドキュメント[^4]にあるとおり、`https://api.zoom.us/v2`を使用している。

```pyzoom/_base.py
    def bearer_token(self) -> str:
        return self.generate_jwt(self.api_key, self.api_secret)
```
また、`API_Key`と`API_Secret`からトークンを生成していることも分かる。
JWTを使用したこのラッパーは、残念ながらZoomの都合により2023年6月頃にJWTapp廃止とともに使えなくなると思われる。
非常に簡単にAPIへアクセスできるため、OAuthへの対応が望まれる。

ただし、[はじめてのZoom API - OAuth編](https://qiita.com/yosuke-sawamura/items/514e791afb4cb02fd956)にあるようにOAuth自体の仕組みは単純であるため、実装することは可能である。

駆け足ではあるが今回は`Zoom API`を触ってみた。
`Flask`や`Django`を使い、ウェブアプリから簡単に、直接Zoomを起動しなくても部屋を作成・編集・管理を行うことができる。
次回は`Zoom Video SDK`や`Zoom Meeting SDK`を使用したいと思う。

[^1]:[あのビデオ会議ツール「Zoom」がAPIとSDKを提供！Zoom Developer Programとは何か【デブサミ2022】](https://codezine.jp/article/detail/15638), 2022.3.30
[^2]:[Python wrapper for Zoom API](https://github.com/licht1stein/pyzoom),
[^3]:[はじめての Zoom API - JWT編](https://qiita.com/yosuke-sawamura/items/d8ec07ac8b7b0335a22b)
[^4]:[Zoom API](https://marketplace.zoom.us/docs/api-reference/zoom-api/)
【Laravel】sweetalert2の導入

## 公式・参考にした記事

- [SweetAlert2 - a beautiful, responsive, customizable and accessible (WAI-ARIA) replacement for JavaScript's popup boxes](https://sweetalert2.github.io/#download)
- [Import SweetAlert2 into Laravel with NPM - DC Blog](https://dcblog.dev/import-sweetalert2-into-laravel-with-npm)

## 環境
Laravel 8.38.0
docker  desktop v5

## インストール

npmを使用したインストールを推奨します。
cdnのスクリプトをそのまま読み込むと、
対象のパッケージが将来メンテナンスされなくなると動かなくなるため。

```
npm install sweetalert2
```

package.jsonのdependenciesにsweetalert2が追加されていたら、
インストールは成功です。

## Laravelでsweetalert2を使用できるようにする

resources/js/app.js にsweetalertをインポートするよう記述を追記します。

```
import swal from 'sweetalert2';
```

またSweetAlert2をグローバルに使用する場合は、ウィンドウオブジェクトに追加できます。

```
window.Swal = swal;
```

記述が終われば変更をapp.js にコンパイルする必要があるので、
以下を実行します。

```
npm run dev
```

public/js/ 配下にコンパイルされたapp.jsが生成されていれば完了です。

## bladeでsweetalert2使用する

assetを使用してscriptタグに埋め込みます。

```
<script src="{{ asset('/js/app.js') }}"></script>

プロジェクトにLaravel Mixが導入されてされているならば下記にする
<script src="{{ mix('/js/app.js') }}"></script>
```

プロジェクト全てにsweetalert2を使用するのであれば、
共通のbladeにscriptタグを配置した方が良いです。。

使用方法はドキュメントを読みながら案件に合わせて導入しましょう。
https://sweetalert2.github.io/#examples

ps.
おそらくsweetalert無印もこのインストール方法で動きます。
今回はnpmを使用して導入しましたが、composerを使用して導入する方法もあるみたいです。
public/js/ 配下にダウンロードしてきたjsファイルを置いてもおそらく動きます。
【Laravel】laravel intervention imageの導入

laravel intervention imageとはimage magickのようなライブラリのlaravel版。
フロントエンドにはLaravel Livewireを採用しているが、
おそらくLaravel Controllerでも動くはず。
記事はv2になっているが、自分がこのパッケージをインストールしたときはv1だったので、
公式を見ていただいた方が早いかも（）

## インストール

https://image.intervention.io/v2/introduction/installation
composer requireする

```
$ composer require intervention/image
```

config/app.php に以下を追記

providersに

```
Intervention\Image\ImageServiceProvider::class
```

aliasesに

```
'Image' => Intervention\Image\Facades\Image::class
```

これでlivewireコンポーネントで
use Image;で呼ぶだけで、laravel intervention imageが使用できる。

## リサイズの使用法

リサイズだけでなく、各関数の使用法はサイドメニューから見れる。
ちなみにリサイズ。
[Intervention Image - Resize](http://image.intervention.io/api/resize)

W * Hのアスペクト比を維持したまま画像を加工したい場合は、
最下部の記述を用いる。

```
// resize the image so that the largest side fits within the limit; the smaller
// side will be scaled to maintain the original aspect ratio
$img->resize(400, 400, function ($constraint) {
    $constraint->aspectRatio();
    $constraint->upsize();
});
```

第一引数がwidthで第二引数がheight。

## ImageMagickを使用したい場合

もしImageMagickを使いたい場合は、以下の手順を行ってください。

```
$ php artisan vendor:publish --provider="Intervention\Image\ImageServiceProviderLaravel5"
```

config/image.php を開いてdriverをimagickへ変更。

```
// 'driver' => 'gd'
'driver' => 'imagick'
```

※環境にImageMagickがインストールされている必要がある。


## 参考記事

[Intervention Image | Intervention Image v2 | intervention.io](https://image.intervention.io/v2)
[Laravelでintervention/imageを使う - Qiita](https://qiita.com/masuda-sankosc/items/874f6128de29ece021d5)
【Laravel】【PostgreSQL】typeをnumericでマイグレーションしたい

$table->decimalを採用する。
https://readouble.com/laravel/5.7/ja/migrations.html

```
$table->decimal('amount', 8, 2);

有効（全体桁数）／小数点以下桁数指定のDECIMALカラム
```

本当にこれでいいのかと思い一応postgresの公式を調べる。

```
decimalとnumeric型は等価です。 2つのデータ型はともに標準SQLに従っています。
```

postgresqlではdecimalとnumeric型は等価らしいので、マイグレーションする際の記述はこれで問題ないかと。

参考：
https://www.postgresql.jp/docs/9.2/datatype-numeric.html
https://qiita.com/windows222/items/5c5a7ef3beb6f1d8f8aa
【laravel】seederである期間からある期間までランダムでtimestampを入れたい場合の記述

## ランダムで期間のデータを作成する

対象のmodelにfactoryを作成する。
database/factories/ 配下に生成されていれば問題ない。
definition()内に下記を記述する。

```
            'created_at' => $this->faker->dateTimeBetween($startDate = '-2 year', $endDate = '+2 year'),
            'updated_at' => $this->faker->dateTimeBetween($startDate = '-2 year', $endDate = '+2 year'),
```

上記は2年前から2年後までのデータをランダムで生成する場合の記述。
期間を変更したい場合はstartDateとendDateの数値を変更する。

月間で期間を指定したい場合はyearではなくmonth
日間ならdayで指定する。


## formatを使用する

下記のように指定すればそのフォーマットで登録してくれる。
dateフォーマットなら自分なりにカスタム可能。

```
'date'=> $faker->dateTimeBetween($startDate = '-2 year', $endDate = '+2 year')->format('Y-m-d H:i:s'),
```


## 参考
https://zenn.dev/kota111/articles/d877d14e96ccd67f222a
https://qiita.com/ttn_tt/items/f34809575f808f685a91
python グラフを色をつけたり -csv-

<H1>作成したグラフに色や年代を追加</H1>

```python
import tkinter
import csv

root = tkinter.Tk()
root.title("売り上げの推移")
ca = tkinter.Canvas(width=800, height=480, bg="white")
ca.pack()

f = open("売り上げデータ.csv",encoding="utf-8")
cr = csv.reader(f)
dat = list(cr)
f.close()

FNT = ("Times New Roman", 12)
bar_x = 40
bar_b = 320
for ye in range(1,6):
    ca.create_rectangle(bar_x, bar_b+5, bar_x+140, bar_b+25, fill="gray", width=0)
    ca.create_text(bar_x+70, bar_b+15, text=dat[0][ye], fill="white", font=FNT)
    ca.create_rectangle(bar_x, bar_b, bar_x+140, bar_b-int(dat[13][ye])/24, fill="skyblue", width=0)    
    for mo in range(1,13):
        h = int(dat[mo][ye])/6
        ca.create_rectangle(bar_x, bar_b, bar_x+6, bar_b-h, fill="blue")
        bar_x = bar_x + 12
root.mainloop()
```
![スクリーンショット 2022-07-15 2.31.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1614609/c94cbd9b-7cbb-9a07-1c7f-9fa469c7235b.png)
データを削除するAPIを作る

今回は削除用のAPIを作成します。APIの使用としては以下のようにします。

```:APIの仕様
メソッド DELETE
エンドポイント /api/delete/{id}
```

## やりたいこと
・一覧の行に「削除」ボタンを設置して押下するとDELETEのリクエストを送る
・サーバ側でリクエストを受け取りデータを削除する

修正内容

https://github.com/kusakari-kai/rgforcommunication/commit/a26e8df513c47e55d8d6969c9d2e5cf3268ecc45

### 画面を整備する
途中で改行されてしまっていたので一列に表示して削除ボタンを表示する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110457/73f21d83-6661-d388-733b-782e35a36c58.png)

### DELETEボタンを押下する際の関数のCall元のイベントハンドラを作る
押下するとchecktstという関数を参照して引数経由で各列データのIDを渡すようにします

```tsx:list.tsx
import { Button } from "@mui/material";
import { checktst } from ".";

export const ListItemValue = props => {
  const {id, name, create_at} = props;
  return (
    <tr>
      <td>{id}</td>
      <td>{name}</td>
      <td>{create_at}</td>
      <td><Button variant="contained" color="error" onClick={() => checktst({id})}>delete</Button></td>
    </tr>
  )
}
```

### 関数を作る
一覧画面から削除するので一覧画面のテンプレに関数を定義する

```tsx:index.tsx
export function checktst(value) {
  axios.delete("/api/delete/" + value.id).then((res) => {
  });
}  
```

### サーバ側でリクエストを受けてデータを削除する
/api/delete/{id} URLの中からIDを受け取りIDが存在するか確認してデータがあればDELETEします

```tsx:/work/[id].tsx
import { NextApiRequest, NextApiResponse } from "next";

type User = {
  id:string,
  name:string,
  create_at:string, 
}

export default (req: NextApiRequest, res: NextApiResponse) => {
    const method = req.method;
    switch (method) {
      case 'DELETE': {
        const value = req.url.substring(12);
        const sqlite3 = require("sqlite3");
        const db = new sqlite3.Database("./test.db");
        const check = new Promise((resolve, reject) => {
          db.serialize(() => {
            db.all(`select * from Test where id = ?`, value , (err, tests) => {
                if (err) return reject(err)
                return resolve(tests)
            })
            db.close();
          })
        })

        check.then((selectRes:User[]) => {
          if(res != undefined) {
            const check = new Promise((resolve, reject) => {
              const sqlite3 = require("sqlite3");      
              const db = new sqlite3.Database("./test.db");
              db.serialize(() => {
                db.run(`delete from Test where id = ?`, selectRes[0].id , (err, tests) => {
                    if (err) return reject(err)
                    return resolve(tests)
                })
                db.close();
              })
            });
          } else {
            res.status(404).json({})
          }
        }).then(deleteRes => 
          res.status(200).json({})
        );
        break;
      }
      default: {
        res.status(403).end();
      }
    }
}
```

削除した後で一覧を更新する仕様にしたかったが、自分の作りが悪すぎて気軽に修正できませんでした。Contextの制御の仕方が特定の部分に依存している（疎結合になってない）ので、柔軟性がなくうまく作れていません。NodeやReactに実際に触れて言語の仕様やコンセプト含めて毎日すごく勉強になります。
あまり選り好みせず横断的に試していきたい。。
AWS 一般的な設計原則について（自分用メモ

・一般的な設計原則
クラウド上における適切な設計を可能にするために、以下の項目を満たす設計を目指します。

・必要なキャパシティーの推測が不要に
必要なときに必要なリソースを素早く入手できるので、需要の増減に応じて段階的にスケールアップ/スケールダウンする前提で設計を行う。

・本番規模でシステムをテストする
オンプレミス環境で本番環境と同等のテスト環境を構築するには時間も費用もかかる。AWSでは本番相当のテスト環境を一時的に作成し、テスト完了後に環境を破棄できるため、容易に本番環境をシミュレートできる。

・自動化によってアーキテクチャでの実験を容易にする
システムの作成や複製作業を自動化することで、同じ環境を手軽に作成できるようになる。同じ環境を容易に作成できるので、新機能の適用や動作確認といった実験的な作業を安全に何度でも実行できる。また、自動化設定の変更点を管理することで、以前の環境を簡単に再現できる。

・発展するアーキテクチャが可能に
顧客へのサービスを停止せずにテストできるため、設定変更やバージョンアップによって発生するリスクを軽減し、システムを常に進化させることができる。

・データに基づいてアーキテクチャを進化させる
各リソースのメトリクス（システムのパフォーマンスに関するデータ）を自動的に収集させることにより、収集したデータに基づいてシステムの改善ができる。

・ゲームデーを利用して改善する
本番環境のイベントをシミュレート（ゲームデー）することで、改善箇所の発見やイベントに対応する運用者の経験を積むことができる。
LINE Bot×with makeを使ってチームで画像をGoogleドライブへ共有保存

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2717626/2fa15819-c1ea-cab1-e3de-1ff243819e82.png)
皆さんこんにちは。
今年は一度梅雨明けしたのにも関わらず再度梅雨入りしたような天気が続いていますね・・・・

私は食品スーパーマーケットに努めている[Yuuuuichi](https://twitter.com/yuuuuuichi69)です。最近、プロトタイピングデビューをしました。本日は2本目の投稿しちゃいます！
# まず完成品 
LINE Bot×with makeを使ってチームで画像をGoogleドライブへ共有保存！メモはスプレットシートに保存！

https://twitter.com/yuuuuuichi69/status/1547606844117766144

# なぜチーム画像保存LINEBotを作ったか 
皆さんはスマートフォンで撮影した写真をPCで使用したい時はどうされていますか。
私はここ最近から仕事でプレゼン資料を作る機会が多く、画像や写真をスマホから転送することが多いです。やり方はいくつかありますが、皆さんはどうでしょう？
1,スマホから直でGoogleドライブですか？
2,自分にメールを送りますか？
3,PCとコードでつなぎますか？
***どれも、めんどくさいと感じる私でございます。***
ましてや、他人がとった写真の共有もLINEでわざわざ送ってもらいPCに・・・・

**ああああぁぁぁぁぁ～～～～～めんどくさい！！**
**そんな時に！！！！**
LINEのトークに写真を送ればそのまま**Googleドライブ**に保存されていくものがあると便利だと思い、作りました。
メンバー内でLINEを友達登録
　→常に業務で使用した写真などをチーム全員で**共有**や資料で使いたい写真を送ってと依頼
　　→LINEに送る
　　　→Googleドライブに保存される
というように、お手軽にPCに取り込む事ができました。
また、メモも取り込めるように設計しました！
思いついたアイデアを書き込んだりすれば**Googleスプレットシートにカキカキ。**
# 作り方
1,用意するもの

・makeのアカウント
・LINEDeveloperアカウント
・Googleアカウント（Googleドライブ）

2,#with makeで作ります！全体はこのような設計です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2717626/3dd32775-73c0-a226-44a7-2fddb5c2680a.png)

2-3,次に一つ一つの設定値を表しております。**上の列**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2717626/218fda06-b76b-0c72-be49-7e400a38240e.png)
**下の列**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2717626/62771785-cd57-29c6-7867-dcd38d2ca395.png)
**上の列**でメモをカキカキ
**下の列**で写真をGoogleドライブへカキカキ
# 完成品
**ポイっと！**

https://twitter.com/yuuuuuichi69/status/1547606844117766144

**ドライブに写真IN！！**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2717626/fb96e530-379a-f6b0-0385-1d0fa7f7fa37.png)
**メモも書き込まれている！！**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2717626/a7aed5f3-09cb-c73f-51ed-938a3693028f.png)
ひとまず、成功です～改善点はまだまだありますが、勉強してより良いものにしていきます！
# 最後に・・・
皆さんからご意見をいただき、より快適に使えるようにしていきたい！
`私が感じたこと`
&emsp;1.シーン別で写真の仕分けができると余計使いやすい
&emsp;2.名刺をバンバン入れてスプレッドシートにリスト化も行いたい
`周りから頂いたご意見`
&emsp;1.画像の容量が大きいから圧縮しながら格納できるといいね
&emsp;2.メモ機能はもう少し使い勝手良いものにしてほしい

以上、記事を読んでいただきありがとうございます☆
引き続き勉強しながら開発を進めたいと思ってます～！
Byebugについて

# はじめに


Railsでは最初から開発環境とテスト環境でByebugが使えるようになっているという記事を見かけまして、デ


バッガがやりやすくなるかなと思い試してみました！


勉強がてらByebugについてまとめてみた記事です。



# 具体的な内容



RailsにはGemファイルに標準でByebugが最初から入っています。


byebugとpry-byebugがあり、微妙に違います。irb上で動くのがbyebugでpry上で動くのがpry-byebugです。



# irbとは



IRBはInteractive Rubyの略です。対話形式でプログラムを実行できるコマンドです。


Rubyのコードの動作確認をしたいときに使います。ちょっとした短いコードの動作確認をするときに便利ですね。



# pryとは



Pryとは、RubyのirbのようにRailsのコンソールでメソッドなどを使えることができるようになる機能です。



# byebugとは



byebugとは、デバッグツールの１つです。Railsにはデフォルトでインストールされています。
インストールされていない、何らかの手違いで消してしまったという方は簡単ですので早速インストールしてみてください。



# インストール方法
インストールはGemfaileに

```
gem 'byebug'
```

を追記するだけです。 

追記したら

```
bundle install
```

でgemをインストールしてきます。



# byebugを使ってみて


gemとしてRailsには最初からインストールされているので使いやすく、コマンドも多いので便利ですね。
SlackでCHにfileをアップロードする方法

`Slack Appの作り方はある程度知っていることを前提とした情報になります。`

# Slackでのファイルアップロード
いくつか方法はあります。

https://api.slack.com/methods/files.upload

詳しくはここにSlack APIの記載があります。

1. JenkinsのPlugin、Slack Notification Plugin を使った方法
1. Slack APIを使ったアップロード方法

で、やり方は色々あるんですが1は結構簡単です。
ただし問題点は、どこのURLにあがったのか、ファイルのアップロードURLとかは取れません。
responseとかね。
そういうのがとりたい場合は、2が必要。

# JenkinsのPlugin、Slack Notification Plugin を使った方法
取り急ぎこの方法。

```
slackUploadFile channel: '#hoge',
    credentialId: 'slack_token',
    filePath: './test.png'
```
こんな感じ。credentialsIdはslack appとかのtoken。

# Slack APIを使ったアップロード方法

https://api.slack.com/methods/files.upload

さっきのこれに色々記載がある。
- HTTP
- JavaScript
- Python
- Java

python的にだとーを説明すると。

もちろん前提としてpipでslack入れておく。
```
%pip3 install slackclient
```
色々あるのだけど、Python的にはこういう。
```hoge.py
import os
import sys
from slack import WebClient
from slack_webhook import Slack
from slack.errors import SlackApiError

# params
channel = sys.argv[1] # アップロード先CH
botToken = sys.argv[2] # slack App Token
filePath = sys.argv[3] # ファイル指定

##
## ファイルのアップロード
##
client = WebClient(token=botToken)
url = ''

try:
    response = client.files_upload(
        channels=channel,
        file=filepath,
        initial_comment='Hey! finished upload.',
        filename=filePath,
        filetype="png") # 用途に応じて

    assert response["file"]
    url = response["file"]["url_private"] # urlが返ってくる
except SlackApiError as e:
    assert e.response["ok"] is False
    assert e.response["error"]
    print(f"Faied To Upload!!!: {e.response['error']}")

# 出力
print(url)
```
こうすると、urlにupload先のurlが返ってくる。
filePathとfilenameかぶってんけど・・（はしょったYO）

jenkinsで使うときはこんな感じ
```groovy
withCredentials([string(credentialsId:'bot_token', variable: 'token')]) {
                    
    def command = "python3 hoge.py ${url} ${token} ${filePath}"
    def url = sh(script:command, returnStdout:true)
    println "url : " + url
}
```
みんな大好きリーダブルコードまとめ①

# 対象者
当方と同じく、駆け出しエンジニアの皆様。また、初級エンジニアの方もこんな内容だったなと思いながらお読みいただければ幸いです。
※当方、駆け出しエンジニアですので間違いやご指摘あれば、コメントいただければ幸いです。

# リーダブルコードとは？
駆け出しエンジニアや、初級エンジニアの方々のバイブル的書物。
以前、エンジニアの方とお話しさせていただく機会がありやはりこちらの本は読んでおいて損はないとのことで、購入して少しずつ読み進めていこうと考えています。

# 第1章　理解しやすいコード
#### メインテーマ
本章のメインメッセージは、『良いコードとは、ただ簡潔に書けば良いということではなく、共通認識しやすいコード(著書の中では、「安心」と言われる)が良いコードなんだよ〜。』と4ページほどで説明してくれています。

#### ディテール
具体的な例で話すと、本章には動作が同じコードを2種類記載されています。
一方は2行ほどで記述されているがエンジニアの直感で書かれたコードで読めなくはないが、どのような動作が行われるのかを理解するには少し時間がかかります。
他方、7行のある一定のルールを考慮して書かれたコードで、一見長く見えるがどのような動作が行われるか一目で理解できる。

このように、「コードは他の人が最短時間で理解できるように書かなければならない。」という鉄則を説明してくれている。

# 感想
当方は、短ければ短いほどいいコードだと考えていたので、こちらの文面は衝撃的でした。
ある一定の法則をチームで共有して「直感的に書く」<<<<「直感的に理解できる」を意識してコードを書く必要があると学びました！（この4ページだけでも学びは大きい。)
また、チームで開発する機会が今後あるのでこの考えを意識して自己開発も行っていきます！
【yocto】kernelのソースコードを確認する方法

# 方法
(1) 以下のコマンドで、イメージに含まれるカーネルのレシピ名を確認する
~~~
bitbake -e <イメージのレシピ名> | grep "PREFERRED_PROVIDER_virtual/kernel"
~~~
(2) 以下のコマンドで、kernelにパッチを当てた状態でビルドを停止させる
~~~
bitbake -c do_patch <カーネルのレシピ名> 
~~~
(3) tmp/work-shared/\<アーキテクチャ名>/kernel-sourceを確認する
※展開されない場合、bitbake -e \<カーネルのレシピ名> | grep '^S='で展開先が確認できる

# 動作確認
- bitbake準備
~~~
takeshi@X250:~/yocto/poky$ source oe-init-build-env 

### Shell environment set up for builds. ###

You can now run 'bitbake <target>'

Common targets are:
    core-image-minimal
    core-image-sato
    meta-toolchain
    meta-ide-support

You can also run generated qemu images with a command like 'runqemu qemux86'

Other commonly useful commands are:
 - 'devtool' and 'recipetool' handle common recipe tasks
 - 'bitbake-layers' handles common layer tasks
 - 'oe-pkgdata-util' handles common target package tasks
~~~
- imageにどんなkernelが採用されているかを確認する
~~~
takeshi@X250:~/yocto/poky/build$ bitbake -e core-image-minimal | grep "PREFERRED_PROVIDER_virtual/kernel"
# $PREFERRED_PROVIDER_virtual/kernel
PREFERRED_PROVIDER_virtual/kernel="linux-yocto"
~~~
- kernelのソースコードの展開先がどこかを確認する
~~~
takeshi@X250:~/yocto/poky/build$ bitbake -e linux-yocto | grep '^S='
S="/home/takeshi/yocto/poky/build/tmp/work-shared/qemux86-64/kernel-source"
~~~
- kernelのビルドをパッチを当てた時点で停止する
~~~
takeshi@X250:~/yocto/poky/build$ bitbake -c do_patch linux-yocto
WARNING: Host distribution "zorin-15" has not been validated with this version of the build system; you may possibly experience unexpected failures. It is recommended that you use a tested distribution.
Parsing recipes: 100% |##################################################################################################################################| Time: 0:00:44
Parsing of 772 .bb files complete (0 cached, 772 parsed). 1298 targets, 41 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies

Build Configuration:
BB_VERSION           = "1.44.0"
BUILD_SYS            = "x86_64-linux"
NATIVELSBSTRING      = "zorin-15"
TARGET_SYS           = "x86_64-poky-linux"
MACHINE              = "qemux86-64"
DISTRO               = "poky"
DISTRO_VERSION       = "3.0"
TUNE_FEATURES        = "m64 core2"
TARGET_FPU           = ""
meta                 
meta-poky            
meta-yocto-bsp       = "my-yocto-3.0:94f6b31befda5c496f65e863a6f8152b42d7ebf0"

Initialising tasks: 100% |###############################################################################################################################| Time: 0:00:00
Sstate summary: Wanted 2 Found 2 Missed 0 Current 0 (100% match, 0% complete)
NOTE: Executing Tasks
NOTE: Setscene tasks completed
NOTE: Tasks Summary: Attempted 22 tasks of which 16 didn't need to be rerun and all succeeded.

Summary: There was 1 WARNING message shown.
~~~
- 展開されたソースコードを確認する
~~~
takeshi@X250:~/yocto/poky/build$ ls tmp/work-shared/qemux86-64/kernel-source/
COPYING  Documentation  Kconfig   MAINTAINERS  README  block  crypto   fs       init  kernel  mm   samples  security  tools  virt
CREDITS  Kbuild         LICENSES  Makefile     arch    certs  drivers  include  ipc   lib     net  scripts  sound     usr
~~~
流行りのSolid.js触ってみた

## 概要
Solid.jsがReactに変わるライブラリとして注目されてるらしいので流行りに乗っていきます。

## Solid.jsとは
Reactに大きく影響を受けたかなり新しいライブラリです。
フロントエンドフレームワークのランキングでは新興ながら満足度はかなりの人気ぶり
[The State of JS 2021](https://2021.stateofjs.com/ja-JP/libraries/front-end-frameworks/#front_end_frameworks_experience_ranking)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614068/0c768e90-d8ff-8126-7c55-707a69185c59.png)

### パフォーマンス

[公式サイト](https://www.solidjs.com/)によると他のライブラリと比べてかなり早い。
公式曰く
>頑張らなくても速くなるということです。

らしい。
![スクリーンショット 2022-07-14 23.34.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614068/ac8cc27c-ee2e-8763-6cd6-fbc21e191152.png)

### 仮想DOM
ReactやVueなどは仮想DOMを使用して高速なSPA(シングルページアプリケーション)を作成できているのだろうと思っている方も多いと思います。
はい、私も思ってました。
しかしSolidの作成者は、仮想DOMをライブラリのパフォーマンスを低下させるだけの純粋なオーバーヘッドとして説明しています。
そしてSolidでは、この仮想DOMを使用せずにDOMを直接制御することで、さらに高速なSPAの作成が可能となっています。
Solidすごい！！

## 導入
※今回はnodeやnpmのインストールなどは済んでいる前提で進めます。
- OS：Mac


ターミナルで

```bash
// JavaScriptの場合
npx degit solidjs/templates/js my-app

// TypeScripteの場合
npx degit solidjs/templates/ts my-app
```

これ以降はTypeScript使用で進めていきます！

## 起動
```
npm install
npm start
```
[http://localhost:3000/](http://localhost:3000/)で確認

![スクリーンショット 2022-07-14 15.22.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614068/8a7cc773-ebb5-dda9-a674-884c6927d95b.png)

## createSignal
***Reactで言うuseState***

createSignalで得られるものは、getter関数とsetter関数であるため、値にはcount()とカッコつきでアクセスする。
簡単なup、down画面
```typescript:App.tsx
import { Component, createSignal } from 'solid-js';

const App: Component = () => {

  // 左がgetter、右がsetter
  const [count, setCount] = createSignal<number>(0);

  const countUp = () => {
    setCount(count() + 1)
  }

  const countDown = () => {
    setCount(count() - 1)
  }

  return (
    <>
      <div>Count: {count()}</div>
      <button onClick={() => countUp()}>up</button>
      <button onClick={() => countDown()}>down</button>
    </>
  );
};

export default App;

```
![スクリーンショット 2022-07-15 0.13.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614068/520ddb3e-309f-427b-b3a1-7ff51ff77d54.png)

## createEffect
***Reactで言うuseEffect***

埋め込まれたSignalを自動で検知してくれる。
便利！
```typescript:App.tsx
import { Component, createSignal, createEffect } from 'solid-js';

const App: Component = () => {

  // 左がgetter、右がsetter
  const [count, setCount] = createSignal<number>(0);

  const countUp = () => {
    setCount(count() + 1)
  }

  const countDown = () => {
    setCount(count() - 1)
  }

  createEffect(() => {
    // countの変化を自動検知する
    console.log(count());
  });

  return (
    <>
      <div>Count: {count()}</div>
      <button onClick={() => countUp()}>up</button>
      <button onClick={() => countDown()}>down</button>
    </>
  );
};

export default App;
```

![スクリーンショット 2022-07-15 0.23.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614068/4b128b60-43d6-8c5c-1a36-52ff18e1bba9.png)

## まとめ
今回は簡単にSolid.jsの入門をしてみました。
React経験がある人は理解しやすそうですね。
ReactやVueが流行ったと思ったらもう新しいライブラリなんて、、、
特にフロントの技術の進みがえぐいので皆さん頑張りましょう（泣）
AndroidのMediaExtractorで映像・音声のソース確認

# はじめに
株式会社THIRD IT開発部でモバイル開発チームでアプリ（Android及びiOS）の開発を行なっているエンジニアです。
弊社では不動産の点検や作業報告などをスマートフォンで行うためのアプリとして，管理ロイド等のアプリを開発及びリリースしています。

管理ロイドではマンション等の各種点検業務でビデオデータを添付する事があります。
添付したビデオデータがごく稀に壊れている場合があるため`MediaExtractor`を使用しメディアデーター内のソースを確認する事としました。


# ビデオ撮影について
ビデオ撮影については[ACTION_VIDEO_CAPTURE](https://developer.android.com/reference/android/provider/MediaStore#ACTION_VIDEO_CAPTURE)を使用してカメラアプリに撮影してもらっています。

> カメラアプリ呼び出し例

```kotlin
val intent = Intent(MediaStore.ACTION_VIDEO_CAPTURE)
startActivity(intent)
```

# 撮影されたビデオデータが問題ないかのチェック
ビデオデータが正しいかどうかを確認するために下記を確認する

* Videoソース及びAudioソースがある事を確認
* 各ソースのdurationが0より大きいこと

## 実装方法
[MediaExtractor](https://developer.android.com/reference/android/media/MediaExtractor)を使用し、Video及びAudioデーターソースを確認します。


下記がサンプルコードになります。

```kotlin
    fun checkVideoSource(path: String): Boolean {
        val extractor = MediaExtractor()
        extractor.setDataSource(path)
        val trackCount = extractor.trackCount
        if (trackCount < 2) return false

        var audioFormat: MediaFormat? = null
        var videoFormat: MediaFormat? = null
        for (i in 0 until trackCount) {
            val format = extractor.getTrackFormat(i)
            val mime = format.getString(MediaFormat.KEY_MIME)
            if (mime?.startsWith(MIMETYPE_AUDIO) == true) {
                audioFormat = format
            } else if (mime?.startsWith(MIMETYPE_VIDEO) == true) {
                videoFormat = format
            }
        }
        var result = false
        if (audioFormat != null && videoFormat != null) {
            result = (audioFormat.getLong(MediaFormat.KEY_DURATION) > 0L) && (videoFormat.getLong(MediaFormat.KEY_DURATION) > 0L)
        }
        extractor.release()
        return result
    }
```

# まとめ
`ACTION_VIDEO_CAPTURE`で撮影したデータが壊れていたという事はそうそう発生しないとは思いますが、
後で確認したらデータが壊れていたとなると、再度現場へ行き撮影するのは多大なコストになるため、
撮影後に簡単なチェックをし、問題がある場合には再度撮影してもらうためのアラートを出す事で不足の事態に備えています。
Rails備忘録#2 Bootstrap/slim左右に余白を開けたい


bootstrapを使い、Railsのアプリケーション作成中に
下記サイトのような左右に空白が開かなく困っていました。

https://teratail.com/questions/186696


前回
https://qiita.com/takerunagasaki/items/62918a0758de67b23d00

こんな記事を書いたけど、インデントをいくら合わせても解消されず困っていました。

しかし、コードをよーく見ると
```ruby:application.html.slim
  body
    .app-title.navbar.navbar-expand-md.navbar-light.bg-light
      .navbar-brand Taskleaf
    .container
    - if flash.notice.present?
      .alert.alert-success= flash.notice
    = yield

```

```ruby:application.html.slim
    .container
    - if flash.notice.present?
      .alert.alert-success= flash.notice
    = yield

```
インデントがおかしい・・・
.continer に属していないことになっていた。。。
正解としては、

```ruby:application.html.slim
    .container
      - if flash.notice.present?
        .alert.alert-success= flash.notice
      = yield
```
こう。

ちょっとした、インデントの差でどこの属しているのかが変わってくるので
十分に注意する必要がありそうだ。
特にslimを使って記述しているときは、インデントでどのタグに属しているのかが
決まるらしいので、慣れないうちは、ERBを使うのがいいかもしれない。


最終的なインデントを正したものがこちら。
```ruby:application.html.slim
  body
    .app-title.navbar.navbar-expand-md.navbar-light.bg-light
      .navbar-brand Taskleaf
    .container
      - if flash.notice.present?
        .alert.alert-success= flash.notice
      = yield
```
Airflow資料抄訳(11)：エグゼキューター（Executor）

恥ずかしながら最近になって知ったワークフローエンジン [Apache Airflow](https://airflow.apache.org/)。日本語の紹介記事もちらほら出てきていますが、[公式ドキュメント](https://airflow.apache.org/docs/)をちょっとずつ抄訳しながら読んでいこうと思います。

11回目の今回は[エグゼキューター](https://airflow.apache.org/docs/apache-airflow/stable/executor/index.html)（Executor）。
バージョン2.3.3時点のものです。

---

# エグゼキューター（Executor）

エグゼキューターはAirflowが[タスク・インスタンス](https://airflow.apache.org/docs/apache-airflow/stable/concepts/tasks.html)を実行する仕組みです。エグゼキューターには複数の種類がありそれらは共通のAPIとプラグイン機構を持っています。必要に応じてエグゼキューターを差し替えることができるということです。

同時に複数のエグゼキューターを使用することはできません。使用するエグゼキューターは[構成ファイル](https://airflow.apache.org/docs/apache-airflow/stable/howto/set-config.html)の`[core]`セクション内にある`executor`オプションで指定します。

組み込みのエグゼキューターは名前で指定します。例えば次のように：

```
[core]
executor = KubernetesExecutor
```

カスタムメイドのエグゼキューターも指定することができます。その場合はフルパスで指定します：

```
[core]
executor = my_company.executors.MyCustomExecutor
```

:::note info
Note
Airflowの構成（コンフィギュレーション）についてより詳しくは[構成オプションの設定]( https://airflow.apache.org/docs/apache-airflow/stable/howto/set-config.html)をご覧ください。
:::

現在設定されているエグゼキューターが何かを確認したい場合は、`  airflow config get-value core executor `コマンドを使用します：

```sh
$ airflow config get-value core executor
SequentialExecutor
```

## エグゼキューターの種類（Executor Types）

エグゼキューターには2つのグループがあります。1つ目はローカルで（`schedular`プロセスの内部で）タスクを実行するもので、2つ目はリモートで（一般にワーカー・プールで）タスクを実行するものです。Airflowはデフォルトでは` SequentialExecutor  `を使用する設定になっています。これはローカル・エグゼキューター群に属するもので、もっとも安全なタスク実行方法ですが、低スペックの、単一マシンでの稼動には` LocalExecutor  `を、そして複数マシンないしクラウド環境での稼動にはリモート・エグゼキューター群に属するいずれかを使用するのを強く推奨します。

### ローカル・エグゼキューター

* [デバッグ用エグゼキューター](https://airflow.apache.org/docs/apache-airflow/stable/executor/debug.html)（Debug Executor）
* [並列処理をサポートするローカル用エグゼキューター](https://airflow.apache.org/docs/apache-airflow/stable/executor/local.html)（Local Executor）
* [直列処理専用のローカル用エグゼキューター](https://airflow.apache.org/docs/apache-airflow/stable/executor/sequential.html)（Sequential Executor）

### リモート・エグゼキューター

* [非同期タスクキュー・システムCeleryを利用するエグゼキューター](https://airflow.apache.org/docs/apache-airflow/stable/executor/celery.html)（Celery Executor）
* [CeleryExecutorとKubernetesExecutorを併用するエグゼキューター]( https://airflow.apache.org/docs/apache-airflow/stable/executor/celery_kubernetes.html)（CeleryKubernetes Executor）
* [並列処理ライブラリDaskを利用するエグゼキューター](https://airflow.apache.org/docs/apache-airflow/stable/executor/dask.html)（Dask Executor）
* [コンテナ・オーケストレーション・システムKubernetesを利用するエグゼキューター](https://airflow.apache.org/docs/apache-airflow/stable/executor/kubernetes.html)（Kubernetes Executor
* [LocalExecutorとKubenetesExecutorを併用するエグゼキューター](https://airflow.apache.org/docs/apache-airflow/stable/executor/local_kubernetes.html)（LocalKubernetes Executor）

:::note info
Note
Airflowにはじめて触れる方がよく混乱するのは、Airflowがタスクを実行するのに独立した`executor`プロセスは必要ないということです。これはエグゼキューターのロジックは`schedular`プロセスの内部で実行されるためです。スケジューラーを動かすということは、すなわちエグゼキューターを動かすということです。
:::

---

このセクションを読んでみて、スケジューラーとエグゼキューターの違いがなんとなくわかりました。
「スケジューラーを動かすということは、すなわちエグゼキューターを動かすということ」という旨の記述があり、「だったらなぜ概念を分けるのか？　一緒でいいではないか」となりそうなところですが、それはまさにこのセクションで説明されているように、タスクの実行形態を柔軟に変更できるようにするためそうなっているわけです。
[iOS]サンドボックスでテスト課金が急にできなくなった！！

# はじめに
あるとき突然、「テスト課金ができない。特に課金周りのコードはいじっていないのに...」ということがあったので記事を書いておこうと思います。

# この記事で問題を解決できるかもしれない人
以下の3つ条件に当てはまればおそらく解決できます。
逆に以下の3つの条件を満たさない場合は、この記事で問題を解決できない可能性が高いです。
- サーバー側、アプリ側のコードをいじっていないのに、消費型の課金テストが急にできなくなった
- レシート検証で「21003」が返ってくる
- 直近で`サブスクのアイテム`をAppStoreConnectに追加した

※レシート検証時のstatusの値のそれぞれの意味は以下のドキュメントに記載があります。

https://developer.apple.com/documentation/appstorereceipts/status



# 結論
- レシート検証の時に`App用共有シークレット`をレシート情報と一緒に送れば解決！

# 解決方法
## ①AppStoreConnectから該当アプリの「App用共有シークレット」の値を取得する
- AppStoreConnectにログインします
- 課金ができなくなってしまったアプリのメニューの`サブスクリプション`を開きます（以下の画像参照）
※画像は2022年7月14日現在のもので、この記事をご覧いただいている時点では場所が変わっているかもしれません
- App用共有シークレットの`管理`をクリックします

![スクリーンショット 2022-07-14 23.30.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2644705/9fab8b78-34da-040b-bc1d-4f9d8b2fd49f.png)

- 以下の画像のような画面が表示されると思います
- もし`共有シークレット`が表示されていない場合は作成してください
- `共有シークレット`の値をコピーします

![スクリーンショット 2022-07-14 23.31.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2644705/a7eba538-e862-c61b-d5e8-98cd315723cf.png)

## ②レシート検証時に共有シークレットをリクエストのBodyに入れる
- レシート検証を行う際には自前のサーバーからAppleに対して「`"receipt-data": "Base64エンコードしたレシート情報"`」を送っているはず
- そこに「`"password": "取得したApp共有シークレット"`」も追加する
これで、テスト課金ができるようになっているはずです。

※レシート検証時リクエストとレスポンスのbody
- リクエスト
https://developer.apple.com/documentation/appstorereceipts/requestbody

- レスポンス
https://developer.apple.com/documentation/appstorereceipts/responsebody

※一応レシート検証用のエンドポイントも載せておきます
本番課金のレシート検証用エンドポイント
https://buy.itunes.apple.com/verifyReceipt

テスト課金のレシート検証用エンドポイント
https://sandbox.itunes.apple.com/verifyReceipt

# 原因
結論から言うと詳細はよくわかりませんでした。しかし、消費型の課金のみの場合はレシート検証時に`password`をレシート検証時のパラメータに追加しなくても大丈夫なようですが、サブスクを追加すると消費型課金のレシート検証においても`App共有シークレット`を`password`のキーと共にパラメータとして入れておかなければならないみたいです。
もし、詳細情報を知っている方がいたら教えてほしいです....

# 終わりに
もし誰かの役に立っていたら嬉しいです。
おーわーり。

# 参考記事
https://techblog.zozo.com/entry/ios_premium_validation
【PHP初級㉚】for文応用2

[問題]　　　(参照：http://www.cc.kyoto-su.ac.jp/~mmina/bp1/hundredKnocksPrimary.html)　
整数値を入力させ、その個数だけ*を表示するプログラムを作成せよ。入力値が0以下の値の場合は何も書かなくてよい。


# コード
```php
$m = intval(fgets(STDIN));
for($a = 1; $a <= $m; $a++){
    echo '＊';
}
echo "\n";
```


↓「10」と入力


# 結果
```
＊＊＊＊＊＊＊＊＊＊
```
Node.jsでString.ReplaceAllが使えないんだが！！

## 使えなかった

- とある案件を引き継ぎ、Express.jsで書かれたサーバーサイドを書いていた。
- CSV的にカンマで区切られた数値列をスペース区切りに変更したかったので、


```javascript
const nums = '0.0,10.0,20.0,30.0,40.0,50.0,60.0'
// こんな感じの文字列を

// 0.0 10.0 20.0 30.0 40.0 50.0 60.0
// ↑こんな感じのスペース区切りにしたい

// ということで
const nums_space = nums.replaceAll(',', ' ')
// こんな感じで処理したい
```

- こんな感じのことをした

- すると `nums.replaceAll(...) is not function` みたいな感じで怒られた


## Node.jsのバージョンが古かった

- 調べてみると単純な話、Node.jsのバージョンが古くて `String` 型に`replaceAll`が実装されていないということだった
- `replaceAll`は比較的新しいES2015で追加された関数で、自分が使っていたNode.jsは`v14.17.0`だったので古すぎ！！ということだった。

- Node.jsのバージョンが古いのは、引き継ぎ案件だったのもあってで、継ぎ足し継ぎ足しの秘伝のタレ的コードなので、その辺バージョンあげると逆に他のところが動かなくなる、という事情だったりした

- もしバージョンが関係なければ、nodebrewとか使っているなら

```shell
$ nodebrew use v16.x.0
```

- とか適当に新しいものに切り替えればいいと思う


## String.replace()での置き換え
- とまぁNode.jsのバージョンをとにかく変更できなかったので、以下の方法で代替した

```javascript
const nums = '0.0,10.0,20.0,30.0,40.0,50.0,60.0'

const nums_space = nums.replace(/,/g, ' ')
```

- `replace()`は昔から実装されているので、使える
- 「すべて」をヒットされる`g`をつけて、第一引数に正規表現を与えると、目的のスペース区切りの数値列が手に入った

## 参考
- Node.jsの各バージョンで対応しているES2015の記述方法はここにまとめられているので、もし困ったらここをみると良い
  - https://node.green/
railsのmigrationfileについてのメモ

# 概要
railsのmigrationfileは変更したいことを
ファイルの名前に設定し実際の変更を加える
## なぜそのようなことを行うのか？
 チーム開発においてmigrationfileは
共有されるものであるため、
自分がなにをやったのかということをわかりやすくするため
### 気をつけるべき点
変更を加えてからもとに戻そうとして
rails db:migrate:resetをしてしまうと
一緒に開発している人との環境に
齟齬が生じるので
概要に記したやり方で実装しないと後々面倒なことになる
#### 上記を踏まえて今日自分が学んだこと
まだチーム開発は経験せず一人で実装を進めているが
チーム開発の学習にいずれは入るため、
上記のことを考えすぎて
一度`rails db:migrate`したmigrationfileはいじれないと思いそこを変更しないまま
ファイルの名前だけ変えた中身が同じファイルを`rails:db:migrate`しようとしてエラーが出てしまい、
メンターの方に聞いたとき
今は個人でやってるからまだやらなくて大丈夫と言われあっさり解決した。
原因はメンターの方に教わったことを
もう自分がやっていて
その後に名前が違うだけのファイルを`rails db:migrate`しようとしたせいだと思う。
ちょっとテンパってしまいschemaファイルも変更を加えたが
これも後々同じことをやると大変なことになる気がするので
今後はやらないようにする。
ActiveRecordのorderをハッシュで指定した際に、syntax errorが出る

# 発生した問題
以下のように[Rails ドキュメント](https://railsdoc.com/page/model_order)に従って記述したところ`syntax error`出た. 

```ruby
Page.order(:category_id :asc)
# SELECT "pages".* FROM "pages" ORDER BY category_id ASC
```

# 解決策
以下のように直したら実行された。ドキュメントの誤植なのかもしれない。

```ruby
# 動かない。rails docに書いてある方法
Page.order(:category_id :asc)

# 動く
Page.order(category_id: :asc)
```
【React / Next】POST と PUT をカスタムフックで1つにまとめて、使用側はどちらかを意識しないようにする

個人的な備忘録です。

# 環境
- react: 17.0.2
- react-hook-form: 7.28.0
- next: 11.1.3

# サンプルコード
```tsx:postHandler
export const useProfileNew = () => {
  const { httpClient } = useHttpClient();

  const profileNewHandler = async (data: FormData) => {
    const requset: Request = {
      title: data.title,
      body: data.body,
    };

    const response = await httpClient.post<Response>(API_PATH);

    return response?.data;
  };

  return {
    profileNewHandler,
  };
};
```

```tsx:putHandler
export const useProfileEdit = () => {
  const { httpClient } = useHttpClient();

  const profileEditHandler = async (data: FormData, id: string) => {
    const requset: Request = {
      title: data.title,
      body: data.body,
    };

    const response = await httpClient.put<Response>(
      `${API_PATH}/${id}`,
      request
    );

    return response?.data;
  };

  return {
    profileEditHandler,
  };
};
```

```tsx:まとめるためのcustomHook
export const useProfileHandler = (isEdit: boolean) => {
  const { profileEditHandler } = useProfileEdit();
  const { profileNewHandler } = useProfileNew();

  const profileHandler = async (data: FormData, id: string) => {
    if (isEdit) {
      return await profileEditHandler(data, id);
    }
    return await profileNewHandler(data);
  };

  return {
    profileHandler,
  };
};
```

```tsx:component
export const Component = () => {
  const { profileHandler } = useProfileHandler(isEdit);

  const onSubmit = async () => {
    // 使用側はどちらかを意識しなくて良い
    await profileHandler(data, id)
    reset();
  }

  // 省略

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      {/* 省略 */}
      <button type={'submit'}>
        保存する
      </button>
    </form>
  );
};
```
素晴らしい1on1の秘訣

![FB26ACAA-8B92-4A9A-BB7C-2442B62DD429.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406339/44290f33-147a-2e47-99e8-66f483aa434c.png)


https://learning.oreilly.com/library/view/the-secrets-behind/9781491995112/

## この本を読んだ理由
- 1on1の基本・気をつける事を知りたかったから
- 薄い本(書籍だと約20ページ程度)で読みやすそうだったから


## 読んだ感想
- とりあえず基本的なやり方は把握できた気がします
    - とはいえ、まだ上っ面をなぞっただけだと思いますので、もう何冊か読んでみたいと思います

## 内容
個人的に気になった点のみをまとめています

### 1on1の基本
- 1on1の目的
    - 決断を下す事**ではない**
        - 二人のダンスのようなもの
    - マネージャー・メンバーの間で信頼関係を築く
    - 協調的な問題解決
        - メンバーのトラブル(即対応するほどでもないもの）に目を向ける
    - ビジネス情報の非公開での共有
    - メンタリング・フィードバック
        - フィードバックは両方に与えられる
        - ふりかえりと改善状況の確認
    - ガス抜き
- 1on1のやり方
    - 【頻度】定期的(週1が目安)
        - 不定期だと心理的安全性が損なわれる
        - 話すことがなくてもとりあえず開催する
            - 話していれば何かしら沸いてくる
            - キャンセルする場合はメンバー側からのみ
    - 【時間】30分～60分程度
    - 【ルール】
        - 主体はメンバー
            - スケジュールの変更は部下からのみ可
                - 上司側からリスケ可なのは関係性を築き上げた後でのみ可
            - テーマは事前にメンバーから提示
                - メンバーの不安を軽減するため
        - 議事メモをとる
            - 当事者意識を強める効果がある
            - メモはメンバーが記録し二人に共有する
            - 次の週でメモを振り返りフォローアップを行う
                - フォローアップを行わないと前の1on1で得られた効果が損なわれる
## 1on1のポイント
- 何について話すか？
    - 基本はメンバーが提示したテーマを話すが、必ずしもそれに限定する必要はない
    - [話のネタを引き出すTips] とりえあず「調子はどうですか？」とメンバーに聞いてみて、その答えを待つ
    - 沈黙が生じても答えを待ち続ける事
- フィードバックについて
    - フィードバックは双方向
    - 相手に関心を持って、素直にほめる
- 禁止事項
    - その場にいない人をディスる👿
    - プライベートすぎる話をする
    - 泣き言😿は発展的ではない。真に受けすぎずどうすれば改善できるかという方向にもっていく
        - 激おこ🤬の場合はまだまし。そのエネルギーを改善に向かわせる
    - オープンにできない秘密🤐はそれを黙るというストレスを抱えなければならない。できるだけ避ける
【Unity】Cast ShadowsのTwo Sidedとは

UnityのMeshRendererのCast Shadowsの設定項目にTwo Sidedという設定があります(図1)。
この設定は一体なんなのでしょうか？
**[図1]**
![Two sided.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167635/b63c4e77-5f0f-823d-469d-413d02de62b8.png)
Cast ShadowsはMeshRendererが描画するメッシュをシャドウマップに書き込むかどうかの設定です。
これをOnにしていると図2のように影が落ちます。
しかし、よく見てみるとちょっと違和感のある影の落ち方をしています。
**[図2]**
![teapot shadow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167635/4d5e61f6-47e9-2d3c-c7d2-e24328399413.png)
このような現象はCastShadowの設定をTwo Sidedに変更すると解決することができます(図3)。
**[図3]**
![teapot shadow2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167635/1abacf71-3a3f-1619-e055-464369bff672.png)
では、なぜ図2のような現象が起きるのでしょう？
答えはシャドウマップに描画する際に背面カリングを行う設定でメッシュを描画しているからです。
背面カリングとはポリゴンの裏面を描画しない設定です。
閉じているモデルであれば、本来背面は映らないので、背面を描画しない設定でいいのですが、開いているモデルはカメラの位置によって、背面が見えてしまいます。
図4を見てみてください。実はこのティーポットのモデルはティーポットの蓋と本体との間に隙間があって、ティーポットの底が見える形状になっています。
ティーポットの底のメッシュは裏側が表示されているので、背面カリングで描画されていません。
このため、図2のような違和感のある影ができてしまっていたのです。
**[図4]**
![teapot shadow3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167635/fe013fae-6091-bb69-6661-62908d16ba2c.png)
Caster Shadowsの設定をTwo Sidedにすると、カリング設定がオフになり、表面、背面ともに描画されるようになります。
このため、Two Sided(両面)という設定が用意されているわけです。
RenderDocで確認すると、TwoSidedの時はちゃんとカリングがオフになっていました(図5)。
**[図5]**
![teapot shadow4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167635/822bad8e-45c7-6d75-5acd-d597e921f8bd.png)
Visual Studio CodeのInlay Hintsについて Java編

# 今回の事象について
Visual Studio CodeでJavaのコーディングをしてたら、println関数内に勝手に「x:」が勝手に表示されてなんだこれは？
と思ったので調べてみました。
![スクリーンショット 2022-07-14 22.34.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737484/4f85d989-dbc3-898b-b0c8-194d81b2a5b7.png)

# 調べてわかったこと
どうやらこれは、javaの拡張機能が提供してる「Inlay Hints」という機能がオンになっていて
メソッドに対して指定する引数のパラメータ名を親切に表示してくれてるみたい。
![スクリーンショット 2022-07-14 22.40.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737484/42c922e7-bd11-3606-7016-35cea7a65839.png)
上記の場合だと、println(String x)のxという引数名を表示してくれてるっぽい。

# 設定変更して機能をOFFにしてみる
この表示いらないよって場合は、設定 > 検索バーに「java.inlayhints」と入力する。
すると、以下のような設定項目が表示されるので、これを「none」に設定すれば表示されなくなります。
※デフォルト値は「literals」になってるはずです。
![スクリーンショット 2022-07-14 22.45.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737484/a9805a75-f5cf-bfa0-3a09-c74c8fef4fe3.png)

設定値をnoneに変更したら表示されなくなった！！
![スクリーンショット 2022-07-14 22.51.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737484/85df9a37-a617-06e3-3709-4f60f8c15115.png)


# 最後に
便利な機能ではあるけど、この画面をコードレビューとかの場画面共有した時、機能を知らない人が見たら突っ込んできそうだなと思いました笑
引数名の表示がなくても困らないよって人は、上記手順で設定をOFFにして対応してみてください。




# 参考サイト

https://stackoverflow.com/questions/71945961/what-does-x-and-a-mean-in-java-in-visual-studio-code




https://github.com/redhat-developer/vscode-java/issues/2412#issuecomment-1099792332
citygml-to-3dtiles


citygml-to-3dtiles
https://npmmirror.com/package/citygml-to-3dtiles


https://gis.stackexchange.com/questions/272484/what-is-difference-between-b3dm-and-gltf

Introducing 3D Tiles Next, Streaming Geospatial to the Metaverse
https://cesium.com/blog/2021/11/10/introducing-3d-tiles-next/#direct-gltf-references-from-3d-tiles
【unity】接地判定について

# はじめに
以前衝突判定についてピックアップしていたが、地面との衝突判定（接地判定）についてはやや工夫が必要なので、メモしておくことにする。
オブジェクトとの衝突判定に関する記事は[こちら](https://qiita.com/kouheyHEY/items/bee668cffe37857bab08)。

# 内容
オブジェクトとの衝突判定はタグを使用していたが、接地判定では衝突している時間が多いので別方法となる。
具体的にはunityの機能である「Ray」を使用する。

```c#:接地判定
        // 接地判定
        onGround = Physics.Raycast(
            new Ray(transform.position, Vector3.down),
            Main.PLAYER_ONGROUND_DIST
        );
```
# 詳細
`Raycast(Ray, distance)`を使用している。このメソッドは、指定した方向に指定した長さだけ光線を飛ばす。この光線が「何か」に当たればtrueを返却する。
この「光線」にあたるものが`Ray`となる。

`Ray(Rayの始点, 方向ベクトル)`にてRayを定義している。今回は地面との衝突を検知したいので、下方向に`Ray`を発射し、接地判定を取得している。

# まとめ
ぶっちゃけ、斜め方向に地面に衝突するなどした場合は判定が取れない場合があるが、こだわり始めると面倒なことになってしまうのでいったん無視をしてみる。
MS Forms の 応答結果に「データ型」を利用して回答者情報を展開する

# 背景
**リンクされたデータ型**　の使いどころをイメージしてもらえるように、利用例の一つである Forms のユーザー（回答者）情報展開の例を記事にしてみた

**リンクされたデータ型** を使った、ユーザーの「データ型」の作り方は以下

https://qiita.com/baku2san/items/43f541cd970cc98890d7

# 前提
Forms の回答結果 Excel を開くと以下のようになっていて、ユーザー情報が不足している。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/08e8d80c-28ae-0ca9-9d7a-c7364347c360.png)

この為、所属や役職などで、結果を分析したい人達は、以下のように、手入力を要求する Forms を作ってきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/4cc4c61a-9015-a367-d4b5-183ac5969dbc.png)

必要なら Automate とか Power Query とかで自分でなんとかしろやーって叫びたいけど、この手の人達には無駄

```math
自分の作業工数　＜　他者の工数　ｘ　人数分
```

という単純な計算すらせず、自分の作業工数を減らす為だけに行動するので。

だからといって、それを放置もしたくない！

そんな時に、今回の技が使えます。

利他的になると、良いことありますよ！　愛せよ、されば愛されん :laughing: 

# 方法
1. [ここ](https://qiita.com/baku2san/items/43f541cd970cc98890d7) でデータ型を作成する
1. Forms の回答結果 Excel を開く << ここからが、下の動画範囲
1. 変換対象の情報を選択
1. 追加したい情報を選択していくだけ
![リンクされたデータ型.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/3fcecfbf-79a9-7af8-71d3-0f2d4ef7088e.gif)

:::note 
動画内は「メール」だけだが、テーブル内のテキストなら結構いい感じで拾ってくれます。部分一致した場合は一致内容の選択肢候補から選べます
:::

# あとがき
最近の IT 技術はほんと凄いなぁと思います。
自分の周りから少しずつでも変えていけたら素敵ですよね。

# keyword
how to expand user information in Microsoft Forms Results
React初心者　忘却録　＃１

本投稿はプログラミング初心者の忘却録を兼ねた勉強の一部です。
問題点、ミスなどがありました。時に厳しく時に優しくご教示いただけると大変助かります。
（割合は厳しさ２：優しさ８でお願いします）

# React とは
UI（簡単にいうと見た目や使いやすさ）のライブラリ（ある機能を一つにまとめたもの）で
コンポーネント（システムを構築するための要素）を組み合わせることによってWebの見た目（View)を作っていくものです。

・・・？
よくわからん。
つまりコンポーネントというものを組み合わせて見た目を作ることに特化したライブラリということでしょうか。

# Reactはどんな時に使えるの？
Java ScriptのようにViewページを再読み込みせず別のViewをレンダリング（再描画）させたい時に使用します。
また、Reactのコンポーネントは状態を持たせることができるため再生ボタンを押したらボタンが停止ボタンのマークに変化しつつ映像を流すなどができます。

→なめらかな動きをWebにさせたい時に使いましょう（差分描画）

# 用語
UI ：　見た目や機能などユーザーが実際に触ったり見たりする場所
（UXとはUIを使って体験できること。見た目のいい写真を載せることで商品を買いたくなるなど）

ライブラリ　：　ある機能をひとまとめにしたもの。

コンポーネント　：　システムを構築する要素。Reactではコンポーネントに情報を持たせることができる

レンダリング　：　再描画。Reactは差分描画という概念がある。

# 最後に
とりあえず今回は初期の初期でした。
もし、間違っている解釈などがあればご指摘いただけると幸いでございます。
よろしくお願いいたします。
【Laravel】現在の環境を判断する方法


使う機会があったのでメモ。

## 本番環境の場合

```
if (app()->isProduction()) {
    // 本番環境の場合の処理
}
```

## ローカル環境の場合

```
if (app()->isLocal()) {
    // ローカル環境の場合の処理
}
```

参考：https://zenn.dev/naoki_oshiumi/articles/85fc131475b8b8
【Laravel】1番簡単なエラーメッセージの日本語化

## 環境
Laravel v9.5.1 (PHP v8.1.3)

## やり方
上からコマンドを実行していくだけ！

```
php -r "copy('https://readouble.com/laravel/8.x/ja/install-ja-lang-files.php', 'install-ja-lang.php');"
php -f install-ja-lang.php
php -r "unlink('install-ja-lang.php');"
```
エラーメッセージの日本語化のやり方はさまざまあるけど、公式ドキュメントのやり方が一番簡単で安心な気がする。



## 参考

https://readouble.com/laravel/9.x/ja/auth-php.html
【Laravel】Session store not set on request.【Socialite】

## 環境
Laravel v9.5.1 (PHP v8.1.3)

## 状況
Socialiteを使ってGoogleログイン機能を実装し、デプロイ後```/auth/google/redirect```にアクセスした際下記のエラー。

```
RuntimeException
Session store not set on request.
```

```api.php
Route::get('auth/google/redirect', function () {
  return Socialite::driver('google')->redirect();
});

Route::get('auth/google/callback', [OAuthController::class, 'authGoogleCallback']);
```

## 解決法
```web.php```にルーティングを記載する。
```Socialite```はセッション認証なので```api.php```ではなくて```web.php```に記載しないと動かない。

```web.php
Route::get('auth/google/redirect', function () {
  return Socialite::driver('google')->redirect();
});

Route::get('auth/google/callback', [OAuthController::class, 'authGoogleCallback']);
```

## web.phpとapi.phpの違い
api.phpには```VerifyCsrfToken```ミドルウェアがないので動かなかった。

```app/Http/Kernel.php
   /**
     * The application's route middleware groups.
     *
     * @var array<string, array<int, class-string|string>>
     */
    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            // \Illuminate\Session\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

        'api' => [
            // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
            'throttle:api',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
    ];
```


## 参考
https://laracasts.com/discuss/channels/laravel/session-store-not-set-on-request-when-authenticating-via-socialite

https://readouble.com/laravel/9.x/ja/socialite.html
パイ村 Tips1 Excelピポットテーブル


# はじめに

Pythonからは離れますが、エクセルで使う集計やデータ分析で必要になりそうな機能を復習したいと思います。
SUM関数とか、IFとかそんなのは復習しなくても分かるので、
ピポッドテーブルとかVLOOKUPとかそんなやつを復習していこうかなと思います。

あくまで、データ分析観点で使いそうなやつ。

今回はピポットテーブル。

# ピポッドテーブル（クロス集計）のつくり方

- 表を選択
- メニューのピポットテーブルをクリックし、テーブルまたは範囲からをクリックします。

<img width="60%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/b324eed1-9c80-fc3a-fdd5-fbff6c8139d4.png">

- テーブルまたは範囲からのピポットテーブルダイアログでOKをクリック

<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/cd3f00b9-f5da-2d90-3432-e25ea88e6c5d.png">

- 右側のピポットテーブルのフィールドのところで、`性別を行`に`フルーツ`を`列`と`値`のところにドラッグ＆ドロップします。

<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/6b3cd80f-a8a3-182b-556a-f31612908303.png">

クロス集計が出来ました。

ついでにグラフにしてみましょう。

- ①範囲を選択します。
- ピポットテーブル分析メニューの中のピポットグラフをクリックします。

<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/0f370a67-f3ca-92a1-dc98-1a16d03cc7d7.png">

- 適当なグラフを選択しOKをクリックします。

<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/cdc67b7e-83f1-5ac0-5415-84d653d885a0.png">

簡単にグラフも作成できました。


<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/4ff44250-6849-2428-e9b5-f809aee2b454.png">