OmniAICreator/Qiita-1.07M huggingface dataset:
Azure WebAppsにCeleryとRedisを設定する

ローカルで作成していたアプリ(Django)にCeleryとRedisで非同期処理をおこなっていた為、
WebAppsにどうデプロイすればいいか分からなかったのでその際の備忘録として。
個人学習用でとりあえず動いたからいいものの、あまり良い方法では無いかも。

## Azure Cache for Redisのセットアップ
検索窓にredisと入れると Azure Cache for Redisと出るので選択
![スクリーンショット 2022-09-04 2.49.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821082/af2fa0b3-d29b-2587-e2d1-4a8111404daa.png)
①　【作成】を選択して設定を進める。 > デプロイが始まるので少し待つ。
②　非SSLポートを有効化しておく。
![スクリーンショット 2022-09-04 2.54.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821082/48f50454-3b83-52e9-aa53-a94d835434b4.png)
③　アクセスキーを表示してプライマリキーをコピーしておく。
④　ホスト名もコピーしておく。

## ローカルのDjangoアプリからAzureRedisへの接続をテスト
settings.pyを変更
```
# この箇所を変更
CELERY_BROKER_URL = 'redis://:<プライマリキー>@<ホスト名>:6379/0'
```
起動してみて、うまくいった事を確認したら、隠す処理して次。

## Azure web appの設定
①　設定 > 構成　> アプリケーションの設定で「新しいアプリケーション設定」
②　「CELERY_BROKER_URL」 を　先程の redis://:<プライマリキー>@<ホスト名>:6379/0 にして保存
③　構成 > 全般設定 > スタートアップコマンドにstartup.sh としておく。※Azureにスタートアップファイルを実行するよう指示

## プロジェクトフォルダにstartup.shファイルを作る
プロジェクトのルートフォルダにstartup.shという名前のスタートアップファイルを作成。
以下内容。[公式はこちらに。](https://docs.microsoft.com/en-us/azure/developer/python/configure-python-web-app-on-app-service "公式")
```
gunicorn --bind=0.0.0.0 --timeout 600 <module>.wsgi & celery -A <module> worker -l INFO
```
## Azure Web Appsにコミット！
あとは好きな方法でコミット！
動いた！やった！

とはいえ、内容よくわかってないな…精進します！！

### 参考

https://syaifulsabril.medium.com/django-celery-setup-on-microsoft-azure-46629179f8b3

https://docs.microsoft.com/en-us/azure/developer/python/configure-python-web-app-on-app-service

https://docs.microsoft.com/en-us/azure/azure-cache-for-redis/cache-python-get-started#enable-the-non-ssl-endpoint/
頻出関数をまとめよう

ワイの覚書シリーズ

複数のページを作成する際、タイトルやヘッダー情報、ファビコンリンクなどを一括で変更できるよう、リンクをまとめた関数を呼び出す用のphpを作った。

▽呼び出されるphp

```php
function site_assets(){  //サイトの情報類
    $assets = array(
        'site_title' => 'tomeivideo',
        'site_favicon' => './image/favicon.png'
    );
    return $assets;
}
```
▽呼び出す側のphp

```php
require_once('./assets.php');

$site_meta = site_assets();
foreach ($site_meta as $key => $value) {
    $$key = $value;
}
```

呼び出される側で連想配列に格納したキー名・要素が、呼び出す側でそのまま変数・内容として利用できる。

## 呼び出される側にアクセスされると？
呼び出される側のphpでは関数が呼び出されていないため、ご想像の通り真っ白なページが表示される。
なんとなくダサいため、任意のエラーページを表示するようにした。

```php
$url = end(explode("/", $_SERVER['REQUEST_URI']));
$running = end(explode("/", __FILE__));
switch(True){
    case "${url}.php" == $running:
        $match = true;
        break;
    case $url == $running:
        $match = true;
        break;
    default:
        $match = false;
        break;
}
if($match){
    readfile('./404.html');
    die();
}
```
呼び出される側のphpファイルの名前と現在のURLを取得し、拡張子あり・なしのそれぞれのパターンで一致しているかを検証する。一致していれば真・一致していなければ偽を$match変数に格納し、下のif文により真であれば任意のhtmlを表示するようにした。
今年中に水色になりたい緑コーダーが「初中級者が解くべき過去問精選 100 問」を解く

Qiita初投稿。不慣れなので色々ダメな部分がありそうなのでお手柔らかにお願いします。

今年初めに
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">4.プログラミング能力向上<br>本当に、今年こそはatcoder水色!! 不足ratingは126。<br>速解きはあんまり伸ばせなさそうな感じなので、緑/水色問題を確実に解けるようにしたい。<br>緑～青の問題をどんどん解いて修行するぞ!<br>あと今年中に典型90問埋めたい。</p>&mdash; とーのもとひで (@tonomotohide) <a href="https://twitter.com/tonomotohide/status/1477297506405199874?ref_src=twsrc%5Etfw">January 1, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

と意気込んだにも関わらず

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">tonomotohideさんのAtCoder Beginner Contest 266での成績：2617位<br>パフォーマンス：942相当<br>レーティング：1115→1099 (-16) :(<a href="https://twitter.com/hashtag/AtCoder?src=hash&amp;ref_src=twsrc%5Etfw">#AtCoder</a> <a href="https://twitter.com/hashtag/ABC266?src=hash&amp;ref_src=twsrc%5Etfw">#ABC266</a> <a href="https://t.co/uYGxQlxmzU">https://t.co/uYGxQlxmzU</a> <br>うにゃー、また微減ー… 図形と期待値の問題は苦手なんよー。復習して備えよう…</p>&mdash; とーのもとひで (@tonomotohide) <a href="https://twitter.com/tonomotohide/status/1563536768502476801?ref_src=twsrc%5Etfw">August 27, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

な状況…
年始の意気込み通り典型90問を埋めようかとも思ったけど、「100 問全部解けたら、水色コーダーどころか青色コーダーくらいの実力が付く」らしいので
[初中級者が解くべき過去問精選 100 問](https://qiita.com/e869120/items/eb50fdaece12be418faa#2-3-%E5%88%86%E9%87%8E%E5%88%A5%E5%88%9D%E4%B8%AD%E7%B4%9A%E8%80%85%E3%81%8C%E8%A7%A3%E3%81%8F%E3%81%B9%E3%81%8D%E9%81%8E%E5%8E%BB%E5%95%8F%E7%B2%BE%E9%81%B8-100-%E5%95%8F)を解きつつ、理解を深めるのと自分のメモのために解説する記事です。

# 全探索:全列挙
→ [今年中に水色になりたい緑コーダーが過去問精選 100 問の「全探索:全列挙」を解いた](https://qiita.com/tonomotohide/items/6ee235212d70dc34d487)
| 問題番号 |  問題  |  回答  |
| ---- | ---- | ---- |
|  1  |[ITP1_7_B - How Many Ways?](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ITP1_7_B&lang=ja)|  [AC](https://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=6937946#1)  |
|  2  |  [AtCoder Beginner Contest 106 B - 105](https://atcoder.jp/contests/abc106/tasks/abc106_b)|  [AC](https://atcoder.jp/contests/abc106/submissions/34498283)  |
|  3  | [AtCoder Beginner Contest 122 B - ATCoder](https://atcoder.jp/contests/abc122/tasks/abc122_b)  |  [AC](https://atcoder.jp/contests/abc122/submissions/34497740)  |
|  4  |  [パ研杯2019 C - カラオケ](https://atcoder.jp/contests/pakencamp-2019-day3/tasks/pakencamp_2019_day3_c)  |  [AC](https://atcoder.jp/contests/pakencamp-2019-day3/submissions/34497916)  |
GitLabのArtifactsをHomebrewで配信したい

# 前提

- あなたはGitLabにて、アプリのパッケージをCIのArtifactsで保存しています。
- そのアプリをbrewで配信したいとします。

そんな悩みを解決します。

# 解決

大体はこれに書いてあるんですが、いくつか注意点があります。

https://wheniwork.engineering/creating-a-private-homebrew-tap-with-gitlab-8800c453d893

新しいリポジトリを用意して、ルートに次のような Formula を用意します。

```foo.rb
class Foo < Formula
  desc "<<なんかイカす説明>>"
  homepage "<<よさげなホームページのURL>>"
  version "<<バージョン>>"
  license "<<ライセンス>>"

  url "https://<<GitLabホスト>>/api/v4/projects/<<プロジェクトID>>/jobs/artifacts/<<タグ名>>/raw/<<tar.gzまでのパス>>?job=<<ジョブ名>>&private_token=#{ENV['HOMEBREW_GITLAB_TOKEN']}"
  sha256 "<<tar.gzファイルのssh256>>"

  def install
    bin.install "<<tar.gzに含まれる実行ファイル名>>"
  end
end
```

ここで2点注意点があります。

- url に指定するのは api で artifacts を取ってくるようにします。
- 環境変数は `HOMEBREW_GITLAB_TOKEN` です。
  - 完全に愚痴ですが、元記事は `GITLAB_HOMEBREW_TOKEN` になってて、この調査に3時間溶かしました。
  - https://docs.brew.sh/Formula-Cookbook#using-environment-variables

## 使用方法

read_api にチェックを入れたパーソナルアクセストークンを作成します。

```shell
export HOMEBREW_GITLAB_TOKEN="<<作ったアクセストークン>>"
brew tap "<<ユーザー名>>/<<リポジトリ名>>" "ssh://git@<<GitLabホスト>>/<<ユーザー名>>/<<リポジトリ名>>.git"
brew install "<<アプリ名>>"
```

# まとめ

社内のリポジトリをbrew tapできると、社内ツールもbrewでインストール&バージョン管理できるようになるので、たくさん社内ツール作りたくなりますね。
Embulkのembulk-output-bigqueryのインストールエラー回避方法

Embulkのpluginの`embulk-output-bigquery`をインストールする際に詰まったのでその回避方法をメモしておきます。

環境
Embulk v0.9.24

内容：representable
```
ERROR:  Error installing embulk-output-bigquery:
	representable requires Ruby version >= 2.4.0.
```
回避方法：
```
embulk gem install representable -v 3.0.4
```
関連isssue:[こちら](https://github.com/embulk/embulk-output-bigquery/issues/129)

内容：
```
ERROR:  Error installing embulk-output-bigquery:
	public_suffix requires Ruby version >= 2.6.
```
回避方法：
```
embulk gem install public_suffix -v 4.0.7
```


内容：
```
ERROR:  Error installing embulk-output-bigquery:
    multipart-post requires Ruby version >= 2.6.0.

回避方法：
embulk gem install multipart-post -v 2.1.1
```

内容：
```
ERROR:  Error installing embulk-output-bigquery:
    jwt requires Ruby version >= 2.5.0.
```
回避方法：
```
embulk gem install jwt v2.3.0
```
関連issue:[こちら](https://github.com/embulk/embulk-output-bigquery/issues/144)

ruby関係のバージョンの追従あたりが問題で、
https://rubygems.org/gems/
ここやgithubでgemを検索して、どのようなアップデートでrequireが変わったのか見ると応用が効きそうです。
VS Remote-Containers を使用した簡単な Astro 環境

VS リモート コンテナーを使用してさまざまな言語をテストし始めましたが、これが Astro.build の新しい開発環境をセットアップする簡単な方法であることがわかりました。

### ステップ 1 - フォルダーを作成する
```
mkdir astrodev

cd astrodev
```
`astrodev` フォルダーの中で、`.devcontainer` という名前の新しいサブフォルダーを作成します。

「Dockerfile」を作成します.
```dockerfile
FROM node:16-alpine 

WORKDIR /app

RUN apk update && \
    apk add git && \
    apk add openssh

ENV HOST 0.0.0.0
EXPOSE 3000

```
devcontainer.json」という名前の新しいファイルを作成します
```json
{
    "name":"astro",
    "build": { "dockerfile": "Dockerfile" },
	"forwardPorts": [
		3000
	],
	"customizations": {
		"vscode": {
			"extensions": [
				"astro-build.astro-vscode"
			]
		}
	}
}
```

実行すると、VS コードは astro 拡張機能を自動的にインストールします。

あとは、Visual Studio Code を開いて `astrodev` フォルダーを開くだけで、`remote-container` で開くかどうかを尋ねられます。

初めて実行するときは、docker イメージをダウンロードしてビルドする必要があるため、しばらく時間がかかります。

イメージのビルドが完了したら、VS Code 内から新しいターミナルを開き、`node`がインストールされていることを確認できます。

`node --version`

正しくインストールされていることを確認したら、公式の Astro.build ドキュメントを参照して、新しいプロジェクトを作成できます。

```
yarn create astro
.....
.....
cd <my-astro-project>
yarn dev
```

astro をお楽しみください。

現在、個人サイト [dabiddo.net](www.dabiddo.net) の制作に使用しています。
RxSwift の subscribe 内の処理を共通化する

# はじめに
あまり発生しないケースかもしれないですが、 RxSwift の subscribe 内の処理を共通化したいと思ったことはないでしょうか。例えば、 API 通信でエラーが発生したらダイアログを出す処理や Firebase Crashlytics にエラー情報を送信する処理などです。その共通化の方法を実装する機会がありましたので、備忘録として残します。

# 実装

## Observable の場合
共通処理を置いておく独自 Observer を用意します。そして、 subscribe の引数にその observer を入れるだけです。

```swift:SampleObserver.swift
import RxSwift

class SampleObserver<T> {
    let onNext: ((T) -> Void)?
    let onError: ((Error) -> Void)?
    let onCompleted: (() -> Void)?
    
    init(onNext: ((T) -> Void)? = nil,
         onError: ((Error) -> Void)? = nil,
         onCompleted: (() -> Void)? = nil) {
        self.onNext = onNext
        self.onError = onError
        self.onCompleted = onCompleted
    }
    
    func handle(_ event: Event<T>) {
        switch event {
        case .next(let value):
            // 共通処理を入れる
            self.onNext?(value)
        case .error(let error):
            // 共通処理を入れる
            self.onError?(error)
        case .completed:
            // 共通処理を入れる
            self.onCompleted?()
        }
    }
}
```

```swift:SampleViewController.swift
import UIKit
import RxSwift

class SampleViewController: UIViewController {
    let presenter: SamplePresenter
    let disposeBag = DisposeBag()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        presenter.callAPI()
            .subscribe(SampleObserver(
                onNext: {[weak self] value in
                    // 独自の処理
                },
                onError: {[weak self] error in
                    // 独自の処理
                }).handle)
            .disposed(by: disposeBag)
    }
}
```

## Single や Completable の場合
ほぼ Observable と変わりませんが、 Single や Completable の場合の独自 Observer を載せておきます。

```swift:SampleSingleObserver.swift
import RxSwift

class SampleSingleObserver<T> {
    let onSuccess: ((T) -> Void)?
    let onError: ((Error) -> Void)?
    
    init(onSuccess: ((T) -> Void)? = nil,
         onError: ((Error) -> Void)? = nil) {
        self.onSuccess = onSuccess
        self.onError = onError
    }
    
    func handle(_ singleEvent: SingleEvent<T>) {
        switch singleEvent {
        case .success(let value):
            // 共通処理を入れる
            self.onSuccess?(value)
        case .error(let error):
            // 共通処理を入れる
            self.onError?(error)
        }
    }
}
```

```swift:SampleCompletableObserver.swift
import RxSwift

class SampleCompletableObserver {
    let onCompleted: (() -> Void)?
    let onError: ((Error) -> Void)?
    
    init(onCompleted: (() -> Void)? = nil,
         onError: ((Error) -> Void)? = nil) {
        self.onCompleted = onCompleted
        self.onError = onError
    }
    
    func handle(_ completableEvent: CompletableEvent) {
        switch completableEvent {
        case .completed:
            // 共通処理を入れる
            self.onCompleted?()
        case .error(let error):
            // 共通処理を入れる
            self.onError?(error)
        }
    }
}
```

# まとめ
RxSwift の subscribe 内の処理を共通化する方法を書きました。私自身も人から教えてもらいそれを Swift で書き直したものですが、 独自 Observer を用意するという部分がミソなのかなと思います。同じような悩みを持つ方の助けになりましたら幸いです。
OGPの利用をするための知識

# はじめに
自分で作るシステムで、URLを入力したら、SlackでURLを入力した後にサマリが出るようにしたいなーと思い、それを実現するためにどうしたらいいかを調べました。

Slackで https://www.tokyo-np.co.jp/article/199815 を投稿すると出てくる、こういう情報 ↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/556b9caf-3089-0ad9-b592-563ca7eb31a9.png)

# 最初に結論
OGPでググれ！（Open Graph Protocol）
metaタグの`og:title`とか`og:description`とかを抽出すればよい。

# 詳細
上の方に張ったが記事サイトはそのうち消えるかもですが、OGPは一般的な話なので、ほかの記事・サイトでも通用すると思います。
その要素を１つずつ抜き出す方法を書いていきます。

## アイコン
- faviconといわれているアイコンです。ブラウザのタイトルのとこにも出る小さなアイコンです。
- OGPではなく、大昔からある仕組みです。
```html
<link rel="icon" href="https://static.tokyo-np.co.jp/tokyo-np/appconfig/favicon.ico">
```

## サイト名
- OGPの`property="og:site_name"`。
```html
<meta property="og:site_name" content="東京新聞 TOKYO Web ">
```

## タイトル
- OGPの`property="og:title"`。
- titleタグでもいいかもしれませんが、タイトルってサイト名と一緒に、"最新のニュースがわかる"とかそういうことがしつこく書かれていることがありますね。ここに書かれてないという保証はありませんが。
```html
<meta property="og:title" content="＜新型コロナ・3日＞東京都で1万2561人感染、10歳未満男児、30代男性ら27人死亡：東京新聞 TOKYO Web">
```

## 本文
- OGPの`property="og:description"`。
- これが一番大事。本文から抜くのは至難の業。
- あんまり長くない方がよい（長いと利用者が見てくれなくなる）ということから、下記の例でも、途中で「...」と途切れています。なので省略するロジックとかをわざわざ入れる必要はなく、そのまま使えます。
```html
<meta property="og:description" content="東京都は3日、﻿新型コロナウイルスの新たな感染者1万2561人と、10歳未満の男児1人と30代男性１人を含む27人の死亡を確認したと発...">
```

## 容量
- 不明。普通に取得したサイズを出しているのでは。
- でもそもそも必要なのか、よくわからない。私なら表示しない。

## 画像
- OGPの`property="og:image"`。
- 記事を作った人が、多数の画像の中から一番見せたい画像を置いているので、これを使うべき。
- これもこの情報がなかったら、数多くの画像の中から１つを選ぶのは至難の業。
```html
<meta property="og:image" content="https://static.tokyo-np.co.jp/image/article/size1/4/5/b/f/45bf413fe14e5f166d7a130c9914c4c1_1.jpg">
```

# そもそもOGP(Open graph Protocol)とは
サイトを作る側の人が、webで少しでも自分のサイトを見つけてもらいやすくするための仕組み。マーケティングの技術です。なので、サービス側の見やすくしたいという要件と合致していて、サービス側としては是非利用した方がいい仕組みです。

正式にはこちら。[The Open Graph protocol (https://ogp.me)](https://ogp.me/)


# 所感
私はOGPというもの自体を知りませんでしたので、最初は「url 展開 画像」とかで検索してました。当然ですが全然見つけられなかったですｗ
Slackでいくつか実験してみて、htmlソースのどこにこの情報があるのか調べたら`<meta property="og:description"`とかに入っていることがわかって、`og:description`をググってみたらOGPにたどり着いた次第です。

何気なく利用している機能ですが、いろいろな知らない技術に支えられているなと思いました。
DockerでコンテナのCreatingが終わらないときはFile sharingを確認する

# 発生した事象
`docker compose up --build` コマンドを実行すると、コンテナのCreatingが終わらない。

# 環境
- Docker for Windows

# 原因
- Docker for Windowの設定でFile sharingに該当ディレクトリが追加されていなかった。

# 対応方法
- Docker for Windowsを開きます。
- 画面右上の歯車アイコンをクリックし、Resources→File sharingを選択します。
- 該当のディレクトリが一覧にない場合は、最下部の+アイコンから追加してください。
![スクリーンショット 2022-09-04 1.16.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127338/03a2335c-e84d-0ead-af95-cc7183cd628c.png)

未検証ですがmacでも同じ設定があるので、同様の事象が発生するかもしれません。
普通に使用している限りは、自動的に追加されるようなので、あまり起こらないとは思いますが、ちょっとつまづいてしまったので、同じ問題で悩んでいる人がいれば、ご参考になればと思います。
Windowsでキーボード入力の不具合

**2023年2月11日改訂（問題は以下の以前の記事参照）**

改めて調べたところ，[**AutoHotkey**](https://www.autohotkey.com/) に関わるよく知られた問題で，[こちら](https://did2memo.net/2013/10/03/autohotkey-ctrl-key-is-stuck/)に情報がありました．「押しっぱなし病（stuck）」「ホットキーすり抜け病」と呼ばれているようです．完全な解決法はないようでしたが，以下の方法で私の環境（ダイアモンドキー）ではほぼ問題が解消しました．若干キー動作が遅いのが難点ですが．
なお，この問題は ThinkPad X1-Extremeで発現しましたが，ThinkPad T480では発現しませんでした．マシン依存なのも不明です．
この記事はAutoHotkey v1.1に基づくものです．2022年12月にv2がリリースされていましたので，もしかすると改善しているのでしょうか（未確認）？

#### AutoHotkey スクリプトの編集
以下の様に `Sleep` を入れました．数値（以下では `2` としましたが，`1` では以下に述べるキーボードの表示の間隔をさらに一段遅くする必要がありました）は試行錯誤で決めます．

```
#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
^h::
Send,{BS}
Sleep,2
return
^g::
Send,{Del}
Sleep,2
return
^e::
Send,{Up}
Sleep,2
return
^x::
Send,{Down}
Sleep,2
return
^d::
Send,{Right}
Sleep,2
return
^s::
Send,{Left}
Sleep,2
return
```

#### ケーボードの設定の変更

Windows 11 の **キーボードのプロパティ** において，**表示の間隔** を以下のように少し遅くします．これまでは最速にしていました．文字の連続入力では特に遅いとは感じませんが，ダイアモンドカーソルの動きはやや遅くなりました．この点が不満ですが，この解決策は分かりません．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341422/8e09b9be-2b50-d3ec-9fc8-c98f5167afee.png)

#### 参考資料
- [AutoHotkey：キー押しっぱなし病・ホットキーすり抜け病対策の研究](https://did2memo.net/2013/10/03/autohotkey-ctrl-key-is-stuck/#i-14)，情報科学屋さんを目指す人のメモ　（2023年2月11日参照）


### 以前の記事（不要ですが，記録として）
Windows 10（2023年2月11日現在，Windows 11 でも同様です） で文字をキーボード入力していると，いつの頃からか，突然，キー入力がショートカットのような（窓が開く），編集モードのような（例えば，eを押すとカーソルが上に動く）挙動となり，文字入力ができなくなりました．Windowsキーも反応しなくなり，マウスで再起動させる必要がありました．

根本的な解決方法は不明ですが，~~マウスで~~  **「Windowsキー」を押しながら「Lキー」** を押してロック状態にし，パスワードを入力（または指紋認証）してロック解除すると，問題が解決しました．

**2023年2月11日追記** これは「押しっぱなし病」と呼ばれるもので，もう一度 **Ctrl** キーを押せば直るようです．

[AutoHotkey](https://www.autohotkey.com/)を使用しており，その設定の不具合の可能性があるため，再インストールして設定し直しました．不具合が起きなくなればこれが原因と考えられます．ちなみにAutoHotkeyは [ダイヤモンドーカーソル化](https://estuarine.jp/2014/09/autohotkey_diamond/) に使っています．

**2022年9月7日追記**

対応後不具合の頻度は下がりましたが，1度同様の不具合が再発しました．上記の対処法で解決しましたが，原因は不明です．
Javaのお勉強 プログラミング基礎＃1

### Javaとは？
サン・マイクロシステムズがC言語を元に開発したプログラミング言語です。
1995年にリリースが開始され、2010年に同社がオラクルに吸収合併されたのを期にJavaの版権がオラクルに移行されました。

### 主な特徴
- write once, run anywhere（一度書けばどこでも実行できる）
プログラムとOSの間に依存関係がないので別のパソコンにプログラムを移動しても動かすことができる
- 実行環境で動く
プログラムはJVM(Java Virtual Machine：Java仮想マシン)上で実行されます
コンパイラがプログラムを解釈し、OSで実行可能な形式に変換したプログラムをJVMで実行します
- オブジェクト指向を取り入れた開発
Javaはオブジェクト思考の考え方で設計・実装が可能となっています

### JDK
JDK(Java Development Kit：Java開発キット)はJavaのソフトウェア開発をするツールをまとめたモジュール。
コンパイラやデバック等の開発者向けのツールが含まれます。
### JRE
JRE(Java Runtime Environment：Java実行環境)はJavaのプログラムを実行するためのツールをまとめたモジュール。
JVMやAPIがセットになっていてJavaアプリが実行できる環境が構築できます。
以前は単体で配布されていましたが、現在は配布するアプリケーションに同梱されています。
UnityでMeta Quest2にビルドした際に起きるMRTKshaderエラーの直し方

# はじめに
この記事は、Unityのver依存で頻繁に起こっていたMRTKv2シリーズのshaderエラーを直す方法を
書いている記事です。

Meta Quest2にビルドする際に起こってしまう場合の助けになればと思います。

※MRTK3では使えるかわかりません。


# 開発環境


| 機材やソフト | バージョン |    
|:-:|:-:|
|Meta Quest2   |  |
|  Unity |  2021.3.4f1 ~ 3.5f1 |
|  Windows10 |   |
|  Visual Studio 2019 |   |
|  Mixed Reality Feature Tool | v1.0.2111.0 Preview  |

※Unityのバージョンは記載してあるバージョンでしか試せてないです。
他のバージョンでも起こる可能性はあります。


#### Mixed Reality Feature Tool

| Mixed Reality Toolkit| バージョン |
|:-:|:-:|
| Mixed Reality Toolkit Foundation  | 2.8.2  |
|  Mixed Reality Toolkit Standard Assets |  2.8.2 |
| Mixed Reality Toolkit Test Utilities  |  2.8.2 |
| Mixed Reality Toolkit Tools  |  2.8.2 |
| Mixed Reality Toolkit Extensions  |  2.8.2 |

| Platform Support | バージョン |
|:-:|:-:|
| Mixed Reality OpenXR Plugin |  1.4.4 |

# 起こったエラー

![image (10).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627129/1f98c741-4016-56c3-a4dc-aa533455e1d2.png)

1. Shader error in 'Mixed Reality Toolkit/Standard': Non system-generated input signature parameter () cannot appear after a system generated value. at line 775 (on gles3)


2. Error building Player: Shader error in 'Mixed Reality Toolkit/Standard': Non system-generated input signature parameter () cannot appear after a system generated value. at line 775 (on gles3)


# 解決方法


このエラーの内容でMixedRealityToolkit-Unityリポジトリーのisuueに上げている方々がおられました。

https://github.com/microsoft/MixedRealityToolkit-Unity/issues/5844

https://github.com/microsoft/MixedRealityToolkit-Unity/issues/10449

エラー内容を見てもMixedRealityStandard.shaderの775行目が問題の箇所になっているみたいなので
見てみると画像のようなコードになっています。

![ga.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627129/4e2208b7-470f-38d4-485c-db1b309ede39.png)

**issueでもこの行に言及しており、自分は応急処置として下の画像の様に**

**775行目 fixed4 frag(v2f i<font color="blue">, fixed facing : VFACE</font>) : SV_Targetの**

**<font color="blue">, fixed facing : VFACE </font>を<font color="red">**コメントアウト**</font>してみました**

![komennto.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627129/d37b6a51-e03a-6b83-c371-743e1e904401.png)


### **すると今まで通りにビルドできるようになっています！！**

# 終わりに
shaderの問題の箇所についてちゃんとした説明をできていないですが
エラー解消はできると思うので試してみてください。
もしできなければ、UnityやMRTKの修正やverで変わったかもしれないと
理解していただけると助かります。
parcelでライブラリをbuildするときにnode_modulesが含まれずError: Cannot find module...と表示される問題の解決法

# Parcelでライブラリをビルドする

## 最近のtypescript
だいたいビルドはparcelに任せてます。webpackの設定が面倒くさいので。まあ一度環境をつくってしまえばなんとかなるんですけど。

## parcelでライブラリモードでbuildするとnode_modulesが含まれない
ので、tsファイルをビルドして、他のディレクトリに移動してからnodeで起動しようとするとmoduleが見つかりませんというエラーが出る。例としてrambdaを入れてビルドした場合。
```sh
Error: Cannot find module 'rambda'
```

## ライブラリモードはnode_modulesが基本的には含まれないのだ
> Determines whether to bundle node_modules or treat them as external. The default is true for browser targets, and false for library targets. Possible values are:

簡単に訳すとブラウザーターゲットのときはnode_modulesをバンドルしてくれるが、ライブラリモードのときはバンドルしてくれないらしい。ということで明示する必要がある。

```JSON
 "targets": {
    "main": {
      "context": "node",
      "includeNodeModules": true,
      "optimize": true
    },
    "module": {
      "context": "node",
      "includeNodeModules": true,
      "optimize": true,
      "distDir": "./dist/module.js"
    }
  },
```

こんな感じでincludeNodeModulesをtrueにしておくとnode_modulesが含まれてくれる。


## そういえばなぜかparcelがたまにpnpmだとうまくいかない
のでyarnにしてます。pnpmでparcelうまく動かんな〜という人はnode_modulesを消してyarnにしてみてください。
思考エンジンの思考ログ仕様（きふわらべ2022年以降）

チェスや将棋のAIで、
局面を与えると、次の一手を示すようなプログラムを Engine と呼ぶ。  
日本語では 思考エンジン と呼ぶ  

**通信プロトコル** や、 **記録のフォーマット** には、いろいろな仕様がある  

チェスには 📖 [UCI](https://www.chessprogramming.org/UCI), 📖 [FEN](https://www.chess.com/terms/fen-chess) 、
ライフゲームには 📖 [RLE](https://conwaylife.com/wiki/Run_Length_Encoded)  
ドラフツ（チェッカー）には 📖 [PDN](https://en.wikipedia.org/wiki/Portable_Draughts_Notation)  
碁には 📖 [GTP](http://www.lysator.liu.se/~gunnar/gtp/)  
将棋には 📖 [USI, SFEN](http://shogidokoro.starfree.jp/usi.html), 📖 [CSA](http://www2.computer-shogi.org/protocol/)  

それに比べ、  

**思考ログのフォーマット** は 好きにしたらええやん、という状況だ。  
そこで自分用に仕様を決める。  
仕様の名前は `Thinking log format` 、略して `TLF` とでもしておく

`TLF` が参考にしたのは `CSA` と `GTP` だ  

## 使用例

📖 [Tic Tac Toe Engine Test](http://tic.warabenture.com:8000/tic-tac-toe/vol2.0/engine-manual/ver1.0/)  

# 思考エンジン内コマンドラインからコマンド入力

開発者がコマンドラインにコマンドを入力したら、  
それが単一行か、複数行かに関わらず、  
行頭に `# ` を付ける。  


## 例: 単一行 board

Input:  

```
board
```

Log:  

```
# board
```

## 例: 複数行 board

Input:  

```
board:'''
..x
.x.
o..
'''
```

Log:  

```
# board:'''
# ..x
# .x.
# o..
# '''
```

# 思考エンジン内コマンドラインからコメント入力

開発者がコメントを入力したかったら、行頭に常に `#` を付ける  

コメントが単一行か複数行かに関わらず、  
ログの行頭には `# ` を付ける  

## 例: 単一行コメント

Input:  

```
#飯が食いたい
```

Log:  

```
# #飯が食いたい
```

## 例: 複数行コメント

Input:  

```
#飯が食いたい
#何食お
```

Log:  

```
# #飯が食いたい
# #何食お
```

# 思考エンジンからの返事

思考エンジンが何か返事をしたかったら、ログの行頭に `= ` を付ける
複数行なら、２行目以降のログの行頭に `. ` を付ける  

## 例: 空返事（からへんじ）

空返事は Ok の意味を表す  

Output & Log:  

```
=
```

## 例: 返事

座標 A1 という返事なら  

Output & Log:  

```
= A1
```

* この `A1` はメッセージと呼ぶ

Output & Log:  

```
= coord:'A1'
```

* `文字列:` で始まるなら、プロパティと呼ぶ

## 例: 複数プロパティの返事

Output & Log:  

```
= profile name:'nihon taro' weight:92.6
```

* 先頭から読んで `文字列:` が出てきたとき、プロパティのリストの始まりとする
* プロパティのリストより前の部分をメッセージと呼ぶ
  * メッセージは省略してもよい
* プロパティ名と値の間に `:` を置く。スペースは開けない
  * プロパティ名に `msg` を使うのは避ける。 `msg` はメッセージを指す
* 複数のプロパティは半角空白区切りで置くことができる
* 文字列型の値のクォーテーションの `"` と `'` の違いや、エスケープシーケンスは TOML の考え方に倣う

## 例: 複数行の返事

Output & Log:  

```
= board:'''
. ..x
. .x.
. o.o
. '''
```

* ```'''``` から ```'''``` まで
* エスケープシーケンスは使えない
* 文字列型の値のクォーテーションの `"` と `'` の違いや、エスケープシーケンスは TOML の考え方に倣う

# 思考エンジンからのコメント

思考エンジンはコメントを出力しないが、ログには書く。  
常に行頭に `# ` を付ける。  

開発者のコメントは、打鍵の手間を考えて `#` の右隣にスペースを入れる必要はないが、  
思考エンジンのコメントは `#` の右隣にスペースを入れる必要がある  

基本的に、開発者のコメントか、思考エンジンのコメントかを、出力から区別しようとしていない  

## 例: 思考エンジンの単一行コメント

座標 J10 というコメントなら  

Log:  

```
# # J10
```

## 例: 思考エンジンの複数行コメント

Log:  

```
# # .xx
# # .x.
# # o.o
```

# 思考エンジンのパニックの返事

思考エンジンが　返答に困っているときは 出力の行頭に `? ` を付ける  

## 例: エラーメッセージ

Output & Log:  

```
? unknown_command
```

* スネークケースでもよい

Output & Log:  

```
? internal error
```

* 単語間にスペースを開けても良い
* コロン `:` はプロパティを書くときに使うので、メッセージ内に使うのは避ける

## 例: プロパティ付き

Output & Log:  

```
? unexpected_profile name:'nihon taro' weight:92.6
```

* 解説は `思考エンジンからの返事` を参照

## 例: 複数行文字列付き

Output & Log:  

```
? unexpected board:'''
. xxx
. xox
. xxx
. '''
```

* 解説は `思考エンジンからの返事` を参照

# 設計思想

**思考エンジンの返事** は、大会サーバーに送る必要がある。  
それ以外は 前後の文脈 や 計算途中の記録 などとして付属しているだけで、  
大会サーバーに送ると失格になることがあるだろう。  

そこで、大会サーバーに送らないものは 行頭が `# ` で始まり、  
大会サーバーに送ったものは行頭が `= ` か、 `. ` で始まり、  
エラーなら `? ` で始まるようになっている
django-admin startprojectができない

## はじめに
初投稿です。
この度仕事でDjangoをやらせていただくことになったので、とりあえずドキュメントのアプリ作成からやってみようと思ったエンジニア歴2年ほどの者です。

まだまだ経験が浅く投稿経験も少ないので、間違いやアドバイスあればコメントいただけますと幸いです！

## 本記事で話すこと
- Djangoドキュメントの「[はじめての Django アプリ作成、その 1](https://docs.djangoproject.com/ja/4.1/intro/tutorial01/)」
`django-admin startproject mysite`ができない

## django-admin startproject mysiteができない
まさかの初歩の初歩でいきなり足止めくらいました。

ドキュメントの流れとしては
1. ``$ python -m django --version``
Django がインストールされているかどうか・どのバージョンがインストールされているかを調べるコマンドです。
（先頭の $ は入力待ちを示す記号ですので入力不要）

2. コマンドラインから、コードを置きたい場所に cd 

3. ``$ django-admin startproject mysite``
これでプロジェクト作成できる。

・・・はずがなぜかいきなり``zsh: command not found: django-admin``の文字。

軽く調べたら「PATHが通ってないから通す必要がある」とかの記事もありましたが、
こん辺ざっと本では読んだけどあまり知識がないしやだなーと思って萎えかけたところ、
よくよくドキュメントをみたらすぐ後の文に[トラブルシューティング](https://docs.djangoproject.com/ja/4.1/faq/troubleshooting/#troubleshooting-django-admin)のリンクがありました。


（作業してたのが1日動いた後の夜中だったので単純に頭が動いてなかったですね。
にしてもこういった数分・数十分の調べる時間がもったいないので先に言ってほしいところ。笑）

トラブルシューティングには、
> django-admin should be on your system path if you installed Django via pip. If it's not in your path, ensure you have your virtual environment activated and you can try running the equivalent command python -m django.

とありました。

とりあえず``python -m django``すると、使えるサブコマンドが色々出てきまた。

その中に``startproject``があったので、
試しに``python -m django startproject mysite``としたらコマンドが通ってプロジェクトが作成できました。

ひとまずめでたし。


## 参考記事
- [Djangoドキュメント](https://docs.djangoproject.com/ja/4.1/intro/tutorial01/)

- [【Python/Django】django-admin が実行できない場合の対処法（”コマンドが見つかりません”の対処法）](https://daeudaeu.com/python-django-admin/)
こちらの記事、丁寧に解説されておりわかりやすいと思います。
GitHubの矢印のフォルダの問題とその解決

a問題
git pushしたフォルダに矢印がついていてgithub上でフォルダの中身が見れない。
b原因
.gitが入っているため矢印が出ていた。
c解決
.gitを削除した。そのうえでgit add git commit git pushをしたら矢印が消えた。
d問題の発生理由と解決の理由
なぜ問題が発生したのかというと.gitが含まれるフォルダを別のフォルダ(つまり別のリポジトリ=git initを実行したフォルダ)にコピーしたからです。
ということはレポジトリはgithub上(加えてgit上も？)で区別されて別のリポジトリから今使っているリポジトリにコピーすることはできないと考えていいはずです。コピーしたいリポジトリはフォルダ（リポジトリ）にある.gitを削除してリポジトリではなく単なるフォルダにすればいい。
現場で覚えたGit知識【備忘録】 ①


# 初めに
これまでSVNばかりをソース管理で使っており、そもそもGit自体を業務で使ったことがありませんでした。個人で本を買って、一読し、個人操作でGit Hubしか使ったことがありませんでした。
4月から現場でソース管理でGitを使うようになったため、CUIでよく使う最低限のコマンドを記載します。所感の使い方レベルの説明のみ記載します。
（細かいソースの確認はSource Treeを使用しています。）
ちなみにリモートリポジトリはAWSのCodeCommitを使用しております。

## ●開発時によく使用する流れです

### ①$ git clone <リモートリポジトリのブランチURL>
→開発開始時にリモートリポジトリより、ローカルPCに資材をクローンする時に使うコマンド。
 これを実行することでローカルPCにローカルリポジトリが作成でき、開発のスタート地点に立てます。

### ② $ git branch --all
→ローカルリポジトリ内に含まれるブランチの一覧を確認できます。
 これで自分が着手する元になるブランチを確認します。

### ③ $ git checkout <開発したいブランチ名>
→②で対象を確認し、自分のローカルPC内でメイン開発したいブランチに切り替えを行えます。

### ④ $ git pull
→③でローカルリポジトリを対象のブランチを切り替えた後に、リモートリポジトリの同一のブランチより、最新の内容を取得し、ローカルリポジトリの対象ブランチへ内容をマージします。
（この時点でpullをする必要性は①〜③までに他のメンバーがリモートリポジトリの対象ブランチに内容を更新した場合）

### ⑤ $ git checkout -b  <新たなブランチ名>
→ ④までに使用したブランチを新たな名称で別ブランチとして派生させる場合に使用します。
　④で開発しても良いが、他メンバーとの内容の競合を防ぐために同様の内容で別ブランチを切り起こして、
　開発をした方が良いため、使用する。

### ⑥ $ git commit
→ 現在の変更内容をローカルリポジトリの内容をコミットします。変更はあくまでもローカルリポジトリのブランチ内だけ。

### ⑦ $ git merge <取り込みたいブランチ名>
→ 自分のブランチ内に別ブランチ（派生の元になった④の時点でのブランチ）の内容を取り込む時に使います。
（※事前に別ブランチ（派生の元になった④の時点でのブランチ）にcheckoutで切り替えて、pullしてから、
 mergeを実行するブランチに（⑤の開発ブランチ）切り替えてから、⑦のmergeを行います。）

### ⑧ $ git push origin/ <現在のブランチ名>
→　これで自分の開発中の新たなブランチをリモートリポジトリにアップします。
（※⑦のマージで、派生の元になった④の時点でのブランチに切り替えて、そこに（⑤の開発ブランチ）をマージして、プッシュしても良い）
自分の現場の場合は開発ブランチから元のブランチへのマージは、
CodeCommit側でプルリクエストでマージ元（⑤）、マージ先（④）を設定し、変更内容を再確認してからのマージをしています。
（その際に、スカッシュや３ウェイマージなど選べます）

### ⑨ $ git branch -d  <削除したいブランチ名>
→⑧まで終わった後は自分のローカルの開発ブランチは不要のため、削除するために実行します。


# 終わりに
まだまだ細かいコマンドは使用しますが、よく使うのは上記となります。
操作があまりわからないので、GUIに頼って使うことも多いです。
【Stable Diffusion】M1 MBAでimg2imgを動かす

# はじめに

Stable Diffusionのimg2imgで絵力（えぢから）を身につけた気分になりたい。
虎と狐のなんとやらだ。

# ファイルの編集

## img2img

```diff_python:img2img.py
@@ -40,7 +43,8 @@ def load_model_from_config(config, ckpt, verbose=False):
         print("unexpected keys:")
         print(u)
 
-    model.cuda()
+    # model.cuda()
+    model.to("mps")
     model.eval()
     return model

@@ -200,13 +208,29 @@ def main():
     model = load_model_from_config(config, f"{opt.ckpt}")
 
-    device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")
+    # device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")
+    device = torch.device("mps") if torch.backends.mps.is_available() else torch.device("cpu")
     model = model.to(device)
```

## pytorch

```diff_python:python3.10/site-packages/torch/nn/functional.py
@@ -2503,7 +2503,7 @@
-     return torch.layer_norm(input, normalized_shape, weight, bias, eps, torch.backends.cudnn.enabled)
+     return torch.layer_norm(input.contiguous(), normalized_shape, weight, bias, eps, torch.backends.cudnn.enabled)
```

# 結果

7回（世代）繰り返した。
1枚あたり生成時間は20分くらい。

## 入力

プロンプト

```
PYTORCH_ENABLE_MPS_FALLBACK=1 python scripts/my_img2img.py --prompt "A gray cat looking at me is standing in front of a tree with green leaves on light green grass under the blue sky" --init-img INIT_IMG_PATH --strength 0.6 --n_samples 1
```

素晴らしい灰色の猫と木の絵

![input1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629180/b310db98-b8bb-716b-970f-bd2f13cf2815.jpeg)

## 出力画像

赤枠がそれぞれの世代で選んだもの。それを次の世代の入力にした。
ときどき、生成に失敗するのか黒い画像が生成された。

![16.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629180/9b813536-bb69-6078-ddd1-ea27f1511305.jpeg)
![22.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629180/5d420253-36f1-0167-2920-094d07586686.jpeg)
![28.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629180/883565e0-a3ea-a5a8-4f4e-0e315eda16e2.jpeg)
![34.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629180/7267e732-8840-bb05-8f0a-c322f0aecf0b.jpeg)
![40.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629180/b682d2ce-fc85-c3b9-65d0-21601a64b8d2.jpeg)
![46.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629180/8b328f2b-6411-1e5c-fb59-1faa19b9c4db.jpeg)
![52.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629180/4a27592e-0445-f45d-68e4-93ca0f306fef.jpeg)

# まとめ

えらいフォトリアルな絵になった。
タッチの指定をプロンプトに入れたほうが良かったかもしれない。
【Ruby on Rails】GUI でのアップロードを介さず CarrierWave にファイルを保存する方法

Rails アプリで画像などのファイルを保存したいと思った際、有力な候補として上がる gem としては [CarrierWave](https://github.com/carrierwaveuploader/carrierwave) などが挙げられるでしょう。

で、多くの記事においては

```ruby:./app/uploaders/file_uploader.rb
class FileUploader < CarrierWave::Uploader::Base
  storage :file
end
```

```ruby:./app/models/post.rb
class Post < ApplicationRecord
  mount_uploader :file, FileUploader
end
```

```erb:./app/views/posts/_form.html.erb
<%= f.file_field :file %>
```

```ruby:./app/controllers/posts_controller.rb
class PostsController < ApplicationController
  def create
    post = Post.new(post_params)
    post.save!
  end

  private

  def post_params
    params.require(:post).permit(:file)
  end
end
```

といった GUI でのアップロードを前提としたやり方が説明されていると思います。

しかし、コード上で生成したファイルを CarrierWave に保存する場合、どうすれば良いのか...。気になったので調べてみました。

たとえば、以下のようなケースでこのやり方は有効になると思います。

1. 何かしらのサービス（運営とユーザーが存在）を想定
1. 管理画面から「ユーザーに〇〇（PDF）を送信」というボタンを押す
1. その場で PDF ファイルが自動生成され、ダイレクトメッセージ（DirectMessage）に添付してユーザーに送信

`「PDF ファイルが自動生成され」` という部分がキモです。ここが「GUI でのアップロードを介さずに」が意味するところですね。

## StringIO クラスを使用

結論から言うと、[StringIO クラス](https://docs.ruby-lang.org/ja/latest/method/StringIO/s/new.html) を使います。
参照: [RubyのStringIOから値を回収する](https://qiita.com/jkr_2255/items/c1f24b3a09d3b06aa6ab)

まず、StringIo クラスを継承した CarrierwaveStringIO というクラスを作成。
```ruby:./lib/carrierwave_string_i_o.rb
class CarrierwaveStringIO < StringIO
  def initialize(filename, content_type, data)
    super(data)
    
    @filename = filename
    @content_type = content_type
  end 

  def original_filename
    @filename
  end

  def content_type
    @content_type
  end
end
```

あとは次のような感じで実装していけば OK です。
あくまでイメージなので、適宜自分のコード向けに調整してください。

```ruby:./lib/pdf_generator.rb
# PDF の生成には Prawn（gem） を使用するのを想定
# https://github.com/cortiz/prawn-rails
class PdfWorkingConditionNoticeGenerator < Prawn::Document
  def initialize
    super(
      page_size: "A4",
      margin: 20
    )

    font Rails.root.join("app/assets/fonts/mplus-2p-regular.ttf")

    header
    move_down 30
    
    contents
  end
  
  private

  def header
    text "Test PDF"
  end

  def contents
    text "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
  end
end
```

```ruby:./app/models/direct_message.rb
class DirectMessage < ApplicationRecord
  mount_uploader :file, FileUploader

  # GUI からアップロードされたファイルではなくコード上で生成したファイルを carrierwave に渡すためのメソッド
  def attach_file_not_via_gui_upload(filename, content_type, data)
    self.file = CarrierwaveStringIO.new(filename, content_type, data)
  end
end
```

```ruby:./app/controllers/direct_messages_controller.rb
class DirectMessagesController < ApplicationController
  def send_pdf_to_user
    direct_message = DirectMessage.new(
      user_id: params[:user_id],
      body: "〇〇（PDF）を送信しました"
    )
    
    filename = "test.pdf"
    pdf = PdfGenerator.new
    
    direct_message.attach_file_not_via_gui_upload(filename, "application/pdf", pdf.render)
    direct_message.save!
  end
end
```

## あとがき

以上、GUI でのアップロードを介さず CarrierWave にファイルを保存する方法でした。
同じような疑問を抱えていた人は参考にしてみてください。
泥臭いRuby on Rails

- ひとつの会社でRuby on Railsを4年やっていたがRailsとは名ばかりの泥臭い仕事ばかりだった。技術力の基礎や、仕事の基礎力のようなものは身についたように思う。
- プロジェクトを掛け持ちしてもスイッチングコスト分を期待から差し引いてくれる開発現場はない。
- プロジェクトを掛け持ちしていた頃、2日は会議に使い、1日は他メンバーのサポートに使い、1日はレビューに使わなくてはいけなかった。残り1日はスイッチングコストに費やされた。実装に使える日数は0日だった。僕は武器として土曜日と日曜日を使うことにした。「休日へのコミット」！
- AさんがBさんをすごい人だと言っている。僕もBさんをすごい人だと思わなくてはいけない。例え思っていなくても思っているかのように振る舞おう。これが同調圧力だ。
- やけに専門用語を使う話し方には、その用語がどれだけ人に理解されるかというフィードバック機能が欠けているのだ。
- 瞑想経験が長いのに感情が落ち着かない。エンジニア経験が長いのに単純な処理で間違う。「のに」は厄介だ。
- 瞑想によって電動ノコギリで切り刻まれても動じない心を育てたい。とても無理な気がする。1億年ほど瞑想し続けなければ。
- 何もせずにモテるのは高身長の男だけではないだろうか。僕が思い返しても黙っていてもモテる男は総じて高身長だったと思う。彼らは人間的魅力ではなく身長でモテていたのかもしれない。つまり身長は人間的魅力と交換可能だ。
- スターバックスで店員さんが「モバイルオーダーペイでお待ちのカナダ様」「モバイルオーダーペイでお待ちのカナダ様」と店に響く声でお客さんを呼んでいた。このセリフの響きを口に出すなんて。何かのギャグだろうか。いやモバイルオーダーの仕組みは分かっているのだけど。
- 人とのつながりが癒しになる。僕らはつながりを痛み止めとして利用する。
- LINEオープンチャットというものがある。その中で僕は一時期、好きな漫画について語る大規模なルームに入っていたことがある。そこでは漫画の知識量が多い人ほど偉いというような暗黙の風潮があった。僕がハンターハンターの作者とセーラームーンの作者が結婚しているのを知らなかったと言うと、チャットの管理者から「君はモノを知らなすぎるので勉強した方が良い」と言われた。いや知らんがなっていう。あの風潮は何だったのだろうか。人はあらゆる場所にヒエラルキーを作るようだ。
- 傷つきやすい生身のままで世界に生きている感覚がある。心を守る鎧がない。
- スターバックスでの電源席にまたPCを広げる男が座った。先程に続いて二人目だ。少し取り憑かれたように画面を覗き込み、慌ただしくキーボードを叩き、物音もうるさい。生き急いでいるのだろうか。PCを操るのではなくPCに魂を奪われているかのような民族。彼らの名前をなんと呼ぼうか。

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
DigisparkでパトランプのフラッシュみたいなLチカ

Digisparkは、マイコンのATTiny85の小さなボードです。LEDも付いているのでLEDを点滅させてみたいと思います。せっかくなのでパトランプで使われてそうなフラッシュ（点滅）にしてみます。

## Lチカ

マイコンを使ってLEDの点灯と消灯を繰り返すプログラムを書いて動かすことです。プログラミングの練習によく使われています。

## パトランプのフラッシュ（点滅）

パトランプのフラッシュの仕方にいろいろあるのがわかりました。以下のサイトを参考にさせていただき、LEDの点滅を作成しています。

https://lcarsmania.hatenadiary.org/entry/20150411/p1


## 用意するもの

1. Digispark
1. Arduino IDE
1. PC

## プログラム

DigisparkはのLEDは、P1につながっていたので、PB1を指定しています。

```c:Blink.ino
// Digispark の LED のピン番号
#define LED_PIN PB1

void setup() {
  pinMode(LED_PIN, OUTPUT);
}

void loop() {
  // LED を点灯と消灯を繰り返すタイミング。単位はミリ秒です
  // ランダムフォーのような点滅
  const int sequence[12] = {
      40,   // On
      40,   // Off
      40,   // On
      40,   // Off
      40,   // On
      40,   // Off
      40,   // On
      160,  // Off
      100,  // On
      120,  // Off
      50,   // On
      150,  // Off
    };
  bool ledOn = false;

  for (int i = 0; i < 12; i++) {  // sequence の個数を繰り返す
    ledOn = !ledOn;               // LED の点灯と消灯の切替
    digitalWrite(LED_PIN, ledOn);
    delay(sequence[i]);
  }
}
```

`sequence` でLEDの点灯と点滅の時間を書いて、その順番でLEDを点灯と消灯をしています。
3回の点滅（トリプルフラッシュ）を繰り返す場合は、次のようになります。

```c:Blink.ino
// Digispark の LED のピン番号
#define LED_PIN PB1

void setup() {
  pinMode(LED_PIN, OUTPUT);
}

void loop() {
  // LED を点灯と消灯を繰り返すタイミング。単位はミリ秒です
  // トリプルフラッシュのような点滅
  const int sequence[6] = {
      50,   // On
      75,   // Off
      50,   // On
      75,   // Off
      50,   // On
      500,  // Off
    };
  bool ledOn = false;

  for (int i = 0; i < 6; i++) {  // sequence の個数を繰り返す
    ledOn = !ledOn;              // LED の点灯と消灯の切替
    digitalWrite(LED_PIN, ledOn);
    delay(sequence[i]);
  }
}
```

`sequence` の個数を繰り返すところに数字を直接書いていますが、いろいろ修正して試すのなら`(sizeof(sequence)/sizeof(int))`を書いたほうが間違えが少なくなるのでそのほうがよいです。

```c:sequence の個数を繰り返す部分の修正
  for (int i = 0; i < (sizeof(sequence)/sizeof(int)); i++) {
    ledOn = !ledOn;
    digitalWrite(LED_PIN, ledOn);
    delay(sequence[i]);
  }
```

Lチカでも点滅の仕方を変えれば面白いです。
`sequence`は、点灯と消灯の時間をミリ秒で書いていました。
`sequence`を10ミリ秒単位で書くこともできます。

```c:Blink.ino
#define H true
#define L false
#define LED_PIN PB1  // Digispark のLED

void setup() {
  pinMode(LED_PIN, OUTPUT);
}

void loop() {
  // LED を点灯と消灯を繰り返すタイミング
  const bool sequence[] = {
    H, H, H, H,  // 40ms
    L, L, L, L,  // 40ms
    H, H, H, H,  // 40ms
    L, L, L, L,  // 40ms
    H, H, H, H,  // 40ms
    L, L, L, L,  // 40ms
    H, H, H, H,  // 40ms
    L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L,  // 160ms
    H, H, H, H, H, H, H, H, H, H,  // 100ms
    L, L, L, L, L, L, L, L, L, L, L, L,  // 120ms
    H, H, H, H, H,  // 50ms
    L, L, L, L, L, L, L, L, L, L, L, L, L, L, L,  // 150ms
  };
  bool ledOn = L;

  for (int i = 0; i < (sizeof(sequence)/sizeof(bool)); i++) {  // sequence の個数を繰り返す
    if (ledOn != sequence[i]) {
      ledOn = sequence[i];
      digitalWrite(LED_PIN, ledOn);
    }
    delay(10);  // 10ms
  }
}
```

これは、`sequence` を書くのが面倒です。
Cypress inputに入力後の値をexpectで検証する

Cypressでinput1とinput2に入力した値を加算とし、その呼び出し元でonChangeをコールバック関数として値を取得するテストをCypressで組んでいるとonChangeが走る前にexpectが走ってしまうという現象があった。

```AddNum.tsx
import React, { useState,useEffect } from 'react'

type AddNumParams = {
  num1?: number
  num2?: number
  onChange?: (e: string) => void
}
// function AddNum(num1: Number, num2: Number) {
export default function AddNum(props: AddNumParams) {

  //ステート保持
  const [num1, setNum1] = useState(props.num1);
  const [num2, setNum2] = useState(props.num2);
  const [num3, setNum3] = useState(0);

  const add = () => {
    setNum3((!!num1 ? num1 : 0) + (!!num2 ? num2 : 0));
  }
  

  const onChangeNum1 = (e: React.ChangeEvent<HTMLInputElement>) => {
    setNum1(Number(e.target.value));
    
    console.log("num1:"+num1);
    console.log("num2:"+num2);

  }
  const onChangeNum2 = (e: React.ChangeEvent<HTMLInputElement>) => {
    
    setNum2(Number(e.target.value));
    
    console.log("num1:"+num1);
    console.log("num2:"+num2);
  }

  //初回時
  useEffect(()=>{
    add();
  },[num1,num2])

  useEffect(()=>{
    if (!!props.onChange) {
      props.onChange(String(num3));
    }
  },[num3])

  return (
    <>
      <input data-cy="p1" value={num1} onChange={onChangeNum1}></input>
      <input data-cy="p2" value={num2} onChange={onChangeNum2}></input>
      <p data-cy="p3">{'計算結果：' + num1 + '+' + num2 + '=' + String(num3)}</p>
    </>
  );
}

```

```AddNum.cy.tsx
describe('計算結果の値を戻す', () => {
    it('callback関数を指定し、計算結果が取れる', () => {
        let calcResult = "-1";
        const onChange = (value: string) => {
            calcResult = value;
        }
        cy.mount(<AddNum onChange={onChange} num1={0} num2={0} />);
        cy.get('[data-cy=p1]').type('100');
        cy.get('[data-cy=p2]').type('200');
        expect(calcResult).to.eq(300); //ここでcalcResultが-1のまま


    })
})
```

結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653035/6ceac086-946c-3734-cb8c-3d5c03cb3d7f.png)

当たり前っちゃ当たり前なのだが、
expectは通常の関数であり(非同期でない）、
cy.get('[data-cy=p2]').type('200');
を待たずして処理が流れてきてしまうのでtypeが完了する前に
expectが先に処理されてしまう。
そのためcalcResultが更新されず、期待値が取得できなかったのである。

正しくは以下のように、typeの後でthenをかまし、
その中でexpectを行えばよい。

```AddNum.cy.tsx
describe('計算結果の値を戻す', () => {
    it('callback関数を指定し、計算結果が取れる', () => {
        let calcResult = "-1";
        const onChange = (value: string) => {
            calcResult = value;
        }
        cy.mount(<AddNum onChange={onChange} num1={0} num2={0} />);
        cy.get('[data-cy=p1]').type('100');
        cy.get('[data-cy=p2]').type('200').then(() => {
            expect(calcResult).to.eq("300");
        });

    })
})
```

結果上手く行った。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653035/ab47bd08-db91-b98d-472e-8142597a7bf9.png)
PostgreSQLで英数字の全角・半角・大文字、小文字を区別せずに検索するための関数を定義する

こんにちは、kumaです！

この間実務で、PostgreSQLで英数字の全角・半角を区別せずに検索できるようにしてほしい。という要望をお客様からいただいて、実際に実装を行ったのでその方法をアウトプットしたいと思います！

この記事が、似たようなことを実現したい方のお役に立てれば幸いです💦

## 環境

- CentOS 7.6
- PostgreSQL 12.3

## 結論

以下のSQL文を入力する。

```sql
drop function if exists no_separate_translate(text);
create function no_separate_translate(
    p_src text
) returns text as $$
declare
    text_result text := upper(p_src);
    text_zenkaku_nums text := '０１２３４５６７８９';
    text_hankaku_nums text := '0123456789';
    text_zenkaku_upper_alphabets text := 'ＡＢＣＤＥＦＧＨＩＪＫＬＭＮＯＰＱＲＳＴＵＶＷＸＹＺ';
    text_hankaku_upper_alphabets text := 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
begin
    text_result := translate(
        text_result
        , text_hankaku_nums || text_hankaku_upper_alphabets        
        , text_zenkaku_nums || text_zenkaku_upper_alphabets
    );  

    return text_result;
end;
$$ language plpgsql immutable
```

## PostgreSQLでの関数の作り方

以下のような書き方で書きます。

```sql
create function 関数名(引数1, 引数の型, ・・・）

returns 戻り値の型 as $$

declare
  引数の定義
begin
  関数の処理
end;

$$
```

## 結局今回の関数では何をやっているか？

```sql
text_result text := upper(p_src);
```

text_resultに、p_srcの中身を大文字にしています。

```sql
text_zenkaku_nums text := '０１２３４５６７８９';
text_hankaku_nums text := '0123456789';
text_zenkaku_upper_alphabets text := 'ＡＢＣＤＥＦＧＨＩＪＫＬＭＮＯＰＱＲＳＴＵＶＷＸＹＺ';
text_hankaku_upper_alphabets text := 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
```

変数に全角数字と半角数字、全角英語と半角英語を格納しています。

```sql
text_result := translate(text_result, text_hankaku_nums || text_hankaku_upper_alphabets, text_zenkaku_nums || text_zenkaku_upper_alphabets); 
```

`||`で文字列の結合をおこなっています。
`translate（置換対象の文字列, 検索文字列, 置換文字列）`で置換対象の文字列中に入っている検索文字列を、置換文字列に置換します。
例： translate（"hogehoge", "ho", "ab"） → "abgeabge"


## 最後に

今回みたいに、DBMSの標準機能で実現できないことを関数を定義して対応することも今後ありうるので、少しずつ理解を深めて自分の武器を増やしていきたいと思います！
virbr0 だけを無効化する

RHEL ( linux ) を導入すると勝手に作られる virbr0 。
無効化したつもりだったのに、再起動したら復活していた。
Webで調べたところ、ヒットしたのはことごとく仮想環境そのものの無効化方法。
そうじゃない、仮想環境は使いたいんだけど virbr0 がいらないんだよ。
ということで、そういうニーズのための備忘録です。

元々 virbr0 を無効化するために人から教えられて使ったコマンドがこれ。

sudo virsh net-destroy default

このあと

nmcli c s
brctl show

を実行しても virbr0 が表示されなくなり、めでたく無効化できたかと思ったのだが、実は再起動後に密かに復活していた。
改めて調べたところ、以下のコマンドで勝手に復活しなくなるらしい。

sudo virsh net-autostart default --disable

実際、上記を実行後、再起動しても virbr0 は現れなくなった。

参照:
libvirt導入で作成される仮想ブリッジvirbr0を無効化/有効化する方法(Ubuntu)
https://l-w-i.net/t/ubuntu/virbr_001.txt
先輩エンジニアに質問するときに気を付けること

# はじめに
今回は、自分が実装で行き詰った時に先輩に実装の仕方を聞くときに気を付けるといいことを紹介していこうと思います。
### 本文
まず一番重要なのが、***自分が何を実装したくてどうして実装ができていないか***を伝えることです。
これがないと実装の着地点も分からずどこで詰まってるのかすらもわからないので助言のしようがありません
こうなってくると次に出てくるのが***どうして実装できないかすらわからない***という部分だと思います。
そうした場合は自分が参考にした記事や、サイトのURLを共有しつつコードを直接見せましょう。
ただし、ここで気を付けてほしいのが***URLやコードの共有のみを行って説明も何もしないこと***です。
そうすると、先ほどと同じように得られる情報が少なく、先輩側がコードやURLからどう実装したいのかなどを読み取らないといけなくなります。
それでは本末転倒です。
いろいろと書きましたが、実は***自分が持ちうる情報をなるべくわかりやすくすべて共有する***という部分に気を付けておけばいいだけなのです。
### 最後に
今回は、コードではなくエンジニアとして一生使っていくであろうコミュニケーション能力について記事を書かせていただきました。
今回のように時々コード以外にも記事を書いていこうと思っているのでぜひ参考になればうれしいです
'変数名''datasets' is not defined とESlintに怒られる場合の対処法


ESLintを挿入してReact でアプリケーションを作っている時の話。こんなエラーが出てずっと対処法に困っていた。
![スクリーンショット 2022-09-03 21.32.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/976325/2ed2dc0e-bdb2-0351-0e2e-b0ba7c0c91f6.png)


```
Compiled with problems:X

ERROR

[eslint] 
src/App.tsx
  Line 17:5:   'datasets' is not defined     no-undef
  Line 18:9:   'label' is not defined        no-undef
  Line 19:9:   'data' is not defined         no-undef
  Line 20:9:   'borderColor' is not defined  no-undef
  Line 41:3:   'prefCode' is not defined     no-undef
  Line 42:3:   'prefName' is not defined     no-undef
  Line 67:60:  'NodeListOf' is not defined   no-undef

Search for the keywords to learn more about each error.
```
[お世話になった記事（なっく日報さんから）](https://yukidarake.hateblo.jp/entry/2015/11/11/200221)

歴史的経緯により存在しているglobal変数を弾いてくれるための仕組みなんだそう。今回は必要ないのでエラーが出ないようにしたい。
.eslintrc.json　ファイルを変更しglobalに値を記入するとエラーが消える仕組み。この事象の場合このように記載するとエラーが消える。

```.eslintrc.json
{
	"env": {
		"browser": true,
		"es2021": true
	},
	"extends": ["eslint:recommended", "prettier"],
	"parserOptions": {
		"ecmaVersion": 12,
		"sourceType": "module"
	},
	"globals": {
		"datasets": false,
		"label": false,
		"data": false,
		"borderColor": false,
		"prefCode": false,
		"prefName": false,
		"NodeListOf": false,
		"Props": false,
		"labels": false
	},
	"rules": {
		"no-console": "off"
    }
}
```

そんじゃま！(´･ω･)ﾉｼ
Typescript でcheckbox の値を取得するときに使う型

React Typescript にて複数個あるcheckboxからチェックされているcheckboxのvalueを格納するためのコード

```.tsx:
  const elements = document.getElementsByName("select");
  let posts :number[]= [];

  for (let i=0; i<elements.length; i++){
//any
//プロパティ 'checked' は型 'HTMLElement' に存在しません。
    const checked :boolean = elements[i].checked;
//any
//プロパティ 'value' は型 'HTMLElement' に存在しません。
    if  (checked){
      const valuenum= Number(elements[i].value); 
      posts.push(valuenum);
    }
  }
```
なんだこのエラーは？と思い調べてみるとHTMLを取得するための特殊な型定義があるそう。


```.tsx:
  const elements = document.getElementsByName("select") as  NodeListOf<HTMLElement>;
  let posts :number[]= [];

  for (let i=0; i<elements.length; i++){
//any
//プロパティ 'checked' は型 'HTMLElement' に存在しません。
    const checked :boolean = elements[i].checked;
//any
//プロパティ 'value' は型 'HTMLElement' に存在しません。
    if  (checked){
      const valuenum= Number(elements[i].value); 
      posts.push(valuenum);
    }
  }
```
何も変わっていない。。。仕方ないのでエンジニア質問サイトに聞いてみた。それでたどり着いたのがこれ。
```.tsx:
  const elements = document.getElementsByName("select") as NodeListOf<HTMLSelectElement>;
  let posts :number[]= [];

  for (let i=0; i<elements.length; i++){
//any
//プロパティ 'checked' は型 'HTMLElement' に存在しません。
    const checked :boolean = elements[i].checked;
    if  (checked){
      const valuenum= Number(elements[i].value); 
      posts.push(valuenum);
    }
  }
```
ぐぬぬ... なぜか一つしか消えない。これでもダメなのか。。。　地道に調べてみた結果ようやくたどり着いたのがこれ

[参考記事](https://developer.hatenastaff.com/entry/2020/12/12/121212)



```.tsx:
  const elements = document.getElementsByName("select") as  NodeListOf<HTMLInputElement>;
  let posts :number[]= [];

  for (let i=0; i<elements.length; i++){
    const checked :boolean = elements[i].checked;
    if  (checked){
      const valuenum= Number(elements[i].value); 
      posts.push(valuenum);
    }
  }
```
やっと解決した！初投稿なので大目に見てください。
そんじゃまた！　(´･ω･)ﾉｼ
TypeScriptを極めよう (1)

# TypeScriptを極めよう (1) - 環境構築
## 環境構築
作業用のディレクトリを用意、移動。
```
mkdir typescript-sandbox
src typescript-sandbox
```
typescript-sandboxでpackage.jsonを生成。--yesを指定すると、全てのオプションがデフォルト値で設定される。
```
npm -init --yes
```
TypeScriptを使うのに必須のパッケージをインストール
```
npm install --save-dev typescript @types/node
```
tsconfig.json（TypeScriptをJavaScriptにコンパイルする際のオプションを指定するファイル）を生成
```
npx tsc --init
```
tsconfig.jsonのCompile
```
{
  "compilerOptions": {
    "target": "es2020", /* JavaScriptの仕様 */
    "module": "ESNext", /* ES Modulesを解釈できるようにする" */
    "moduleResolution": "node",/* npmでインストールしたモジュールをTypeScriptに認識してもらう */
    "outDir": "./dist", /* コンパイルされた**.jsファイルたちの行き先を指定 */
    "skipLibCheck": true, /* 全ての.d.tsファイルたちの型チェックをスキップ */
  },
  "include": ["./src/**/*.ts"]/* srcディレクトリ以下のファイル全てをコンパイルする対象に指定 */
}
```
## 次回
TypeScriptを極めよう (1) - .tsファイルを.jsにコンパイルしてみよう