OmniAICreator/Qiita-1.07M huggingface dataset:
複数のテキストフォームの内容をファイルに保存する

##概要
1つのフォームタグ内にテキストフォームが複数ある場合、PHPに渡してテキストファイルに保存する。

##html
ファイル名はなんでもいい。

```html
<form method="post" action="data.php">
  <input type="text" name="name0">
  <br>
  <input type="text" name="name1">
  <br>
  <input type="submit" value="送信">
</form>
```
##PHP
PHPは上記フォームのaction=" "内のファイル名で保存する。
この場合だとdata.phpで保存する。

```php5
<?php
    $file_name="data.txt"; //ファイル名
    $file = fopen($file_name,"w");
    flock($file, LOCK_EX);

    $data1 = $_POST["name0"];
    $data2 = $_POST["name1"];

      fputs($file, $data1);
      fputs($file,"\n");
      fputs($file, $data2);
      fputs($file,"\n");

    flock($file, LOCK_UN);
    fclose($file);
?>
```
##参考文献
・PHPによるWebアプリケーションスーパーサンプル第２版
・速攻!図解プログラミングPHP+MySQL
MINDSTORMS EV3 をPythonで動かす環境構築 (MicroPython)

#MINDSTORMS EV3 をPythonで動かす環境構築 (MicroPython)

MINDSTORMS EV3 はMicroSDカードにファームウェアを書き込みそこから起動することでPythonプログラムが使えるようになります。EV3でPythonプログラムを動かせるようにする環境構築の解説になります。

# 必要なもの
- マインドストーム EV3 本体
- ダウンロード・ケーブル（USB type-C to micro USB, type-A to micro USB, etc..)
- microSDカード(SDHC　4GB～32GB)　※SDカードとは違うので注意

追加でmicroSDカードをインテリジェントブロックから取り出し易くするためにセロハンテープかマスキングテープなどあると良いです。

導入ですが、基本的には [MicroPython導入ガイド](https://www.mdstorm.com/products/Robotics/EV3/With_MicroPython_GettingStarted.html "MicroPython導入ガイド") を参考に進めていけば良いですが、一部古いものがあるためこの記事も参考に進めてみて下さい。


以下では、より新しいmicroSDカードにインストールするファームウェア、エディターの日本語化の方法など、追加の事項のみ解説しています。


# microSDカードにインストールするイメージファイルのダウンロード

LEGO社が提供しているEV3用のPythonファームウェアを以下からダウンロードします。

[EV3によるPythonプログラミング LEGO](https://education.lego.com/ja-jp/product-resources/mindstorms-ev3/%E5%85%88%E7%94%9F%E5%90%91%E3%81%91%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9/ev3-python%E3%81%A7%E3%81%AE%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0 "EV3によるPythonプログラミング")

こちらから入手できるファームウェアがレゴ社が提供している最新のものです。

![dounwlo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1419783/a6a6a6fb-5407-61f0-e049-a46f555fea17.png)

ダウンロードが終わったら、ファイルを解凍します。

# ブータブル micro SDカードの作成
Etcher というアプリを使って、事前に準備しておいた microSD カードに、先程解凍したイメージファイルを焼きつける。

Etcher インストーラーは公式サイトから入手する。
[Etcher 公式サイト](https://etcher.balena.io/)

# VSCode のインストールが終わったらすること

## VSCode の日本語化

VSCodeのインターフェース言語はインストール時点では英語なので、日本語にできる拡張機能をインストールします。全てのメニューが日本語になるわけではありませんが、見やすくなると思います。

![2021-11-06 21_50_16-Greenshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1419783/9a2c0ae0-7e7c-0a11-a51e-654ad99537f3.png)

![2021-11-06 21_50_33-Greenshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1419783/c37895a7-3112-6f83-8b43-4f9798f1865f.png)

## VSCode から EV3 にプログラムをダウンロードさせるための拡張機能を導入

日本語化パックをインストールした時と同様に、「拡張機能」メニューを開き "ev3" と検索します。
そこに出てくる、"LEGO® MINDSTORMS® EV3 MicroPython", "ev3dev-browser" の2つをインストールします。

"ev3dev-browser"は同じ名前の拡張機能が2つ出てくると思いますが、ダウンロード数の多い方を入手して下さい。

![2021-11-06 21_58_01-Greenshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1419783/1af60bab-32a6-f8df-108a-ee318e22e94a.png)



# 参考
- [MicroPython導入ガイド](https://www.mdstorm.com/products/Robotics/EV3/With_MicroPython_GettingStarted.html "MicroPython導入ガイド")
- [EV3によるPythonプログラミング LEGO](https://education.lego.com/ja-jp/product-resources/mindstorms-ev3/%E5%85%88%E7%94%9F%E5%90%91%E3%81%91%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9/ev3-python%E3%81%A7%E3%81%AE%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0 "EV3によるPythonプログラミング")
- [[ev3dev×Python] ev3dev開発環境の構築](https://qiita.com/masterkeaton12/items/938457911b0f3f25e161 "[ev3dev×Python] ev3dev開発環境の構築")
Ruby on Rails 6にTailwindCSSを導入（Gemを使わず）

## Yarnで必要なものをインストールする

```
yarn add tailwindcss@npm:@tailwindcss/postcss7-compat @tailwindcss/postcss7-compat postcss@^7 autoprefixer@^9
```

## tailwind.config.jsファイルを生成する

```
yarn tailwindcss init app/javascript/packs/tailwind.config.js
```

```javascript:app/javascript/packs/tailwind.config.js
module.exports = {
  purge: [
    './app/**/*.html.erb',
    './app/**/*.html.slim',
    './app/helpers/**/*.rb',
    './app/javascript/packs/**/*.js',
  ],
  // 省略
```

## postcss.config.jsファイルを編集する

```javascript:postcss.config.js
module.exports = {
  plugins: [
    require('tailwindcss')('./app/javascript/packs/tailwind.config.js'), // 追加
    require('autoprefixer'),                                             // 追加
    require('postcss-import'),
    require('postcss-flexbugs-fixes'),
    require('postcss-preset-env')({
      autoprefixer: {
        flexbox: 'no-2009'
      },
      stage: 3
    })
  ]
}
```

## TailwindCSSの必要なファイルをインポートする

```css:app/assets/stylesheets/application.scss
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
```

```javascript:app/javascript/packs/application.js
import '../../assets/stylesheets/application.scss'
```

**終わり**
個人(コピペ用) CSSでフッターをウィンドウ最下部に固定する方法　

```
<footer class="footer">
</footer>
```
```
* {
  box-sizing: border-box;
}
 
html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}
 
body {
  display: flex;
  flex-direction: column;
}
 
footer {
  margin-top: auto;
  padding: 30px 0;
  background: #89c7de;
  color: #fff;
  text-align: center;
}
```
複雑な内容をSQLで書く時のコツ！

###概要
データエンジニアとしてはPythonコードよりも必須のSQLについて、現場ではより複雑なコードの記載が求められますが長く複雑化したコードも本記法によりシンプルに整理されたクエリが実現可能です。


###工程を最初に記載する
まず最初に「最終的に何を求められているのか」という要件を記載すると良いでしょう。
逆算して「その為には何が必要で、何をどうすればいいのか」という内容を頭につければ
工程が明確化がするだけでなくレビュアーも読みやすいです。


```sql:sql
--④最終目標
--③その為に必要なjoin処理クエリ
--②その為に必要な処理クエリ
--①取得テーブルから最初に処理するクエリ
```

###FROM句よりもWITHを多用する事
FROMを使用すると読みづらいです。
WITH句を使用すると読みやすく処理も明確化して繋げる事が可能です。
WITH句を繋げる事かつ上記①〜④がを順々に記載する事で　複雑化したSQLが綺麗になりシンプルに理解する事が可能です。

```sql:sql
-------------------------------------
--④最終目標
--③その為に必要なjoin処理クエリ
--②その為に必要な処理クエリ
--①取得テーブルから最初に処理するクエリ
-------------------------------------
--①取得テーブルから最初に処理するクエリ
-------------------------------------
WITH A AS(
SELECT ~
FROM ~
),
-------------------------------------
--②その為に必要な処理クエリ
-------------------------------------
 B AS(
SELECT ~
FROM A
),
-------------------------------------
--③その為に必要なjoin処理クエリ
-------------------------------------
 C AS(
SELECT ~
FROM B
LEFT JOIN ~
ON ~
),
-------------------------------------
--④最終目標
-------------------------------------
 D AS(
SELECT ~
FROM C
)
SELECT *
FROM D

```
Python>Flask:YOLOV5を活用した物体検出アプリの作成 (1)Google Colaboratoryの利用

# <a id ="1">1.概要</a>
FlaskとYOLOV5を使って、物体検出を行うwebアプリを作成した。
(1)「ファイル選択」でjpgまたはmp4ファイルを選択して「送信」)
(2) 物探検出結果をグラフとgifで出力

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613560/ea242b60-82cb-38b8-d4a4-93aefd21c130.png)


以下3つの環境での立ち上げを紹介する。

* **Google Colaboratory環境でのWebアプリの立ち上げ【今回紹介】**
* [Local環境でのwebアプリの立ち上げ](https://qiita.com/k_koba619/items/7979208777499e4e76f0)
* herokuへのWebアプリのデプロイ(作成中)

# <a id ="2">2.Google Colaboratory環境でのWebアプリの立ち上げ</a>

## <a id ="2.1">2.1.ファイルの準備</a>

1. 以下URLにアクセス<br>
https://github.com/kkoba619/web_app_detect_to_graph
1. 下図のCodeボタンをクリック
1. Download ZIPをクリックしてファイルをダウンロード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613560/42e8cb58-a958-7dc1-1258-57ad4c2cc70e.png)

1. ダウンロードしたファイルを解凍
1. 解答したフォルダごとGoogle Driveにアップロード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613560/056ef0d6-2c1f-2c01-b9cc-2e28cd211ae9.png)

1. アップロード先のフォルダを開く

## <a id ="2.2">2.2.ファイルの実行</a>

1. 「Detect_ver2.ipynb」をGoogle Colaboratoryで開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613560/68af672f-2377-0105-4b5c-34954e8f3b8f.png)

1. コードを上から順に実行する<br>
(1) GoogleDriveをマウント

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613560/2f2080f2-bee5-10eb-8d90-635af4f23a64.png)

(2) パスは「5.」で置いたGoogleDrive上に置いたフォルダのパス(※)を上書きする(**下の赤線箇所の2か所**)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613560/3ffee56e-5caf-0682-765b-b94f4862007f.png)

※ フォルダのパスは以下の画面操作でコピーして取得する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613560/eebeb42b-bc7e-2093-192e-7ced8bd26334.png)

 (4) 自身のngrokのtokenを「xxxxxxx」から置き換え <font color = 'green'>**(22/01/05追加)** </font>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613560/eafda9e5-c4bb-4098-173d-d7ab684c77a8.png)

tokenの取得については以下をご参照ください。

https://qiita.com/k_koba619/items/32ec04a04d1e37b86465#2ngroku%E3%81%AEtoken%E5%8F%96%E5%BE%97

 (5) 最後のコードを実行したあとに出てくるリンクをクリックしてアクセス(操作方法は「1.概要」(1),(2)ご参考)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613560/b66a149e-0615-4fa4-891a-6b2a83c0e768.png)

 (6)**【Webアプリ終了時】**Webアプリの使用後は□ボタンをクリックして動作を停止。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613560/e1809251-0ef8-21c0-982d-32fef3363614.png)






以上
djangoのMixinについて自分なりにまとめる

今回のお題
-
今回はdjangoのMixinという概念についてまとめます。

他の言語ではあまり見ない概念なので、自分の中での理解を深めるとともに自分と同じようにMixinという用語に面食らっている方のお役に立てればと思います。

概要〜Mixinとは
-
少しカジュアルな言い方になりますが、Mixinとは`クラスベースビューに装備させる便利アイテム`のようなものです。

クラスベースビューを実装する際にはTemplateViewクラス及びそのサブクラスを何かしら継承させると思いますが、その際にこの`Mixinも同時に継承`させることでビューにさまざまな機能を付与させることができるようになります。

Mixinの実態は`AccessMixin`というクラスを継承したサブクラスであり、`LoginRequiredMixin`, `UserPassesTestMixin`, `PermissionRequiredMixin`の3つが用意されています。

LoginRequiredMixin
-
ログインしていないユーザーをログインページにリダイレクトさせるためのMixinです。

`login_url`という属性値でリダイレクト先のURLを指定します。

```python:views.py
class UserUpdateView(LoginRequiredMixin, UpdateView):
  template_name = "xxxx"
  login_url = reverse_lazy("account_login")
  # ...以下略...
```
上記の例では、`UserUpdateView`が呼び出される際にログインしていないユーザーはリダイレクトされるようになっています。

また、リダイレクト先は`account_login`というルーティングnameで指定しています。

UserPassesTestMixin
-
ある特定の条件をクリアした場合にのみリクエストが成功するようにするためのMixinです（例えば性別が女性の場合にのみそのページにアクセスできるようにするなど）。

このMixinは`test_func`という関数を持っており、この関数の戻り値がTrueであればリクエストは成功、戻り値がFalseであれば`403エラー`が投げられます。

```python
class IndexView(UserPassesTestMixin, TemplateView):
  def test_func(self):
    return self.request.user.gender == "female"

  raise_exception = False
  login_url = reverse_lazy("account_login")
  # テンプレートビュー本体の定義は省略
```
`raise_exception`はfunc_testをクリアできなかった場合にエラーを投げるかどうかを決める値で、Falseであれば`login_url`で指定したページに遷移します（初期値はFalseなので省略も可能）。

ただしログイン済みであれば`raise_exception`の値に関わらず403エラーになります。

PermissionRequiredMixin
-
ログイン中のユーザーに特定の`Permission`が付与されていない場合に403エラーを投げるためのMixinです。

必要なPermissionは`permission_required`という属性値を用いてリスト形式で指定します。

```python:item/views.py
class ItemUpdateView(PermissionRequiredMixin, UpdateView):
  permission_required = ["item.change_item"]
  login_url = reverse_lazy("account_login")
  # ...省略...
```
`raise_exception`と`login_url`を用いた認証失敗時の挙動の制御については、`UserPassesTestMixin`と同様に可能です。

permission_requiredの指定方法や、ユーザーへのpermissionの付与の方法についてはまた別記事で取り上げます。

終わりに
-

以上、簡単にですがMixinの解説を終わりたいと思います。

欲を言えばリダイレクト先を自由に指定できるようにしてほしい・・・
点字翻訳機を作ってみたよ

# はじめに
初記事です。お手柔らかにヨロです。

本記事は、伊藤淳一氏主催の[アドベントカレンダー](https://qiita.com/advent-calendar/2021/ruby-challenge)に参加した記録です。

プログラムは[こちら](https://github.com/kyuki3rain/tenji-maker-challenge)

# 環境構築
面倒なので画像とか貼ってないけど、気が向けばおいおい貼る。
①VSCodeを起動すると、「gitリポジトリからのクローン」というメニューからcloneできる（初めて使った）

②左下の色がついた部分を押すと、「Reopen in Container」と出てくるので、ここからruby -> 3-bullseyeのように進めると、ruby3.0環境もゲットできる

③上の設定中にgitをインストールしておけば、そのコンテナのターミナルからgit pushするだけで更新も可能

VSCodeは便利だなあ。ということで本編行きます。

# 調査
せっかくなのでなるべくプログラミングらしい解決をしたい。

まずはサイトを見て点字の構造を紐解くと、今回のターゲットになる文字は下のルールで網羅できる。

①ヤ行、ワ行、ンを除けば、左上の３つが母音を、右下の三つが子音を表す（以後それぞれ母音成分、子音成分と呼ぶ）

②ヤ行、ワ行は、母音をできるだけ（！？）下に並行移動し、ヤ行の場合はさらに右上の一点を凸にする

③ンは子音成分が全て凸（=マ行の子音）

このルールをプログラミング的に解釈した時、一目でわかる困った点が二つある。

### 困った点１：　並行移動が固定値じゃない！
まずは、②のルールにある「できるだけ」という言葉。

ヤ行にある母音はa,u,oの三種類なのだが、このうち前者二つは凸の場所が一列に収まるため、下に２つ並行移動する。

一方oだけは、凸の場所が真ん中列にも存在するため、一つしか並行移動しない。

このように厳密な数字で決めにくいシステムをプログラミングで統一的にスパッと解決するのは、なかなか困難な気がする。

移動を全て一つだけにするとか、点対象に反転するとかで統一した動作があればいいのだが。。。

今回はここは別々の例外処理ではなくできるだけ統一的に扱うように工夫した。

### 困った点２：　ンがナ行の子音と一致しない！
ンはローマ字でnと1文字の表記をするが、これはある意味子音のみの文字と言える。

ここで、nを子音として用いるナ行の子音成分と同じ構造であれば、統一的に扱えるはずだったが、なんとまさかの、ナ行ではなくマ行（m）と同じ。

なぜ惜しいところでずれてしまったのか、、、と悲しんでいても始まらないので、一例しかないし例外処理で対応しよう。


# 構成
調査も済んだので、構成を考える。

### 基本構成
まずはとりあえず、①のルールを軸に、点字の各点に2の累乗の値を当てはめ、6bitの数字と対応づけることにした。

当てはめ方は下のような感じ
```
 8 32
16  2
 4  1
```
順番はぐちゃぐちゃなように見えるが、一応後述の都合があって綺麗にできなかったという理由もある。

これによって、ルール①に該当する母音と子音は、単純な足し算だけで一意な点字と対応する数字を得られることになる。

数字と点字の変換は1bitずつ読み出して対応関係から位置を決めれば実現できそうだ。

### 例外処理
次に、②、③のルールについて考える。

③に関しては1文字だけの話なので、n1文字だけの入力に対応する数字だった場合m1文字に対応する数字に変換する例外処理を書くことにした。

②はどうにかして①と似たような実装（母音と子音に割り当てられた値を足し算した数字と点字を対応させる）で乗り切りたい。

しかし、普通の方法ではすでに子音側の3bitの情報は使い尽くされている。どうしよう。。。

そこで今回は、yやwの場合は足す値を非常に大きくして、どの母音相手でも6bitではオーバーフローするようにした。

その上で、7bit目の値によって数字と点字の対応表を切り替えて実装した。

この時、7bit目を除いた6bitが各文字の点字となるべくシンプルに対応づけられるようにy,wの値と母音成分の値を調整した。

その結果、yに59、wに57を対応づけることで、次のように綺麗に区別できた。
```
ya: 8+59=67=64+2+1
yu: 24+59=83=64+16+2+1
yo: 48+59=107=64+32+8+2+1
wa: 8+57=65=64+1
(wo: 48+57=105=64+32+8+1)
```
上の値を点字に変換する対応表は、下のようなシンプルなもので済むようにできた。
なお、32はシンプルな対応表実現のため対応なしとしている。（表左上のxも同様）
```
 x  2
 4  8
 1 16
```

# 実装
まずは基本構成の実装から。

### テキストから各ひらがなを表す文字列を切り出す
```ruby
text.downcase.split(" ")
```
普通に空白でsplitした。

### 文字列から数字へ変換
```ruby
CharToNum = {
  "a" => 8, "i" => 24, "u" => 40, "e" => 56, "o" => 48,
  "k" => 1, "s" => 3, "t" => 6, "n" => 4, "h" => 5, "m" => 7, "y" => 59, "r" => 2, "w" => 57,
}

string.chars.inject(0) { |r, i| r + CharToNum[i] }
```
文字と数字の対応表をハッシュ定数TextToNumで定義し、文字列を1文字ずつ変換して足し合わせた。

### 数字から点字を表す配列に変換
```rb
Format = [5, 3, 4, 0, 2, 1]
array = [0,0,0,0,0,0]

Format.each do |f|
  array[f] = 1 if num & 1 == 1
  num = num >> 1
end
```
数字と点字位置の対応表を配列定数Formatで定義し、1bitずつ読み出すと同時にFormatから得た対応する点字位置にフラグを書き込んだ。

rubyでは1をtrueと呼んでくれないので、==1を書くのが見栄え悪くてちょっと嫌だった。

### 点字を表す配列から点字に変換
```ruby
tenjis = array.each_slice(2).map {|a| a.inject(""){ |r, i| r + (i == 1 ? "o" : "-")}}
```
二つずつ取り出して、それぞれフラグを文字に変換して結合することで、３列の文字にして返した。

### 点字から点字列に変換
```ruby
tenjis.transpose.map{|t| t.join(" ")}.join("\n")
```
この時点ではtenjisは一つのひらがなにつき３列の点字がある配列となっている。

このままでは点字を横に並べることができないので工夫が必要。

今回の実装では、transposeで行と列を反転させ、点字の３列を維持したまま横に結合して、最後に各行を結合することで、横並びを実現した。
Next.jsでLINEメッセージを送ってみる。【Let's ハンズオン！】

流行のNext.jsを使ってLINEメッセージを送信してみるやで。

# Next.js環境構築

まずはなにがともあれNext.jsのプロジェクトを立ち上げてみる。

```
npx create-next-app line-app --typescript
```

プロジェクトの作成が完了したら、とりあえず動かしてみるやで。

```
cd line-app
npm run dev
```
プロジェクトの構成はこんな感じ。
しんぷるいずべすと。

![スクリーンショット 2021-11-06 18.04.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326114/cde33d45-ce9c-be47-023c-8f659aa2ff71.png)

まずは、LINEのSDKを使用するので、以下をinstall

```
yarn add @line/bot-sdk
```

編集するのは、以下の3つ。
- pages/api/[word].ts
- pages/index.tsx
- .env.local

それぞれ紹介すると、pages/api/[word].tsがサーバー側でLINEのSDKを使用してメッセージを送信。
pages/index.tsxが画面表示となります。

```typescript:pages/api/[word].ts
import { NextApiResponse } from 'next'
import * as line from '@line/bot-sdk';

console.log(process.env.NEXT_PUBLIC_LINE_ACCESS_TOKEN!)

const config = {
  channelAccessToken: process.env.NEXT_PUBLIC_LINE_ACCESS_TOKEN!,
  channelSecret: process.env.NEXT_PUBLIC_LINE_CHANNEL_SECRET!
};

const client = new line.Client(config);

export default ({ query: { word } }: { query: { word: string } }, res: NextApiResponse) => {
  console.info('res data', word)
  client.broadcast({
    type: "text",
    text: word
  }).then(data => console.log(data))
    .catch(e => console.log(e))
  res.status(200).json({ message: `you requested for ${word} ` });
};
```

```typescript:pages/index.tsx
import { useState } from 'react';
import type { NextPage } from 'next';
import styles from '../styles/Home.module.css';

const Home: NextPage = () => {
  const [text, setText] = useState<string>('');
  const sendLine = async () => {
    const response = await fetch(`http://localhost:3000/api/${text}`);
    const data = await response.json();
    console.log('🚀 ~ file: index.tsx ~ line 11 ~ sendLine ~ data', data);
  };
  return (
    <div className={styles.container}>
      <main className={styles.main}>
        <h1>LINE message送信</h1>
        <br />
        <input type="text" onChange={(e) => setText(e.target.value)} />
        <button onClick={sendLine}>送信</button>
      </main>
    </div>
  );
};

export default Home;

```


```env:env.local
NEXT_PUBLIC_LINE_ACCESS_TOKEN="xxxxxxxxxxx"
NEXT_PUBLIC_LINE_CHANNEL_SECRET="xxxxxxxxxxxxxxx"
```

超絶シンプル画面ができましたか？

![スクリーンショット 2021-11-06 18.11.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326114/7a636178-1d2f-044e-ea60-443f855df346.png)

このテキストエリアに文字を入力して、送信ボタンをクリックでLINEのメッセージが飛びます。

![スクリーンショット 2021-11-06 18.12.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326114/f249e425-6569-2c2f-cc66-f7fad381d30b.png)

みんなもLINEBotを作ってみてね。
---
ゆうじろうが運営しているプログラミングスクールです。
是非遊びにきてね。

https://proaca.tech/
Android開発でハードコーディングすると怒られるのでstrings.xmlを使う


レイアウトファイルのactivity_main.xmlで以下のようなハードコードをした場合にAndroidStudioやIDEAで怒られます。

```kotlin

android:text="クリック"
```

strings.xml

```kotlin
<resources>
    <string name="app_name">addApp</string>
    <string name="btnName">クリック</string> // 追加
</resources>

```

strings.xmlに上記のように記述すると、```@string/btnName ```
というような書き方で定義した文字列を取得することができます。

```kotlin 
    <Button
            // android:text="クリック" 削除
            android:text="@string/btnName"  // 追加
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" android:id="@+id/btnAdd"
            app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/ed2" android:layout_marginTop="8dp"/>
```

これでワーニングが消えました。


![スクリーンショット 2021-11-06 18.08.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174952/092f0524-d32f-6d6d-c934-0e35609da5bc.png "スクリーンショット 2021-11-06 18.08.07.png")
Next.js(React)でAbobeフォントを使いたい！

## はじめに
[とあるクラファンプロジェクトのWebサイト](https://makeru-design.maeda-design-room.net/)をNext.jsで実装させていただきました。
サイトのデザイン上、Abobe Fontsを利用する必要があったのですが、どのようにNext.jsに導入したらいいのか少し悩んだのでこちらに対応方法を記載します。
 
## 対応方法
ReactのdangerouslySetInnerHTMLを利用して、<Head>タグ内に記述することでAdobe FontをNext.jsのプロジェクトでも利用できます。

```react
 
<Head>
  <script
    dangerouslySetInnerHTML={{
      __html: `
      .... // Adobe Fontのコードからコピー
        `}}
  />
</Head>
```

## Adobe Fontsを利用するまでの詳細手順

1. [Adobe Fontsのサイト](https://fonts.adobe.com/)を開く
1. 利用したいフォントを検索し、フォントの詳細ページへ遷移
1. [Webプロジェクトに追加]のボタンをクリック
![adobe-fonts.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584011/79cc2feb-e334-8c8c-eb82-f72c1425cf90.png)

1. [Webプロジェクトに追加]のボタンをクリック
1. [新規でプロジェクトを作成]または、[既存のプロジェクトを選択]して、[保存]をクリック
1. Webページで利用するためのコードが表示されるので、コピーする
![adobe-fonts2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584011/ee028461-3ae3-0bbf-535c-c04a544140f4.png)

1. 前述のようにNext.jsのHeadタグとscriptタグを入力
1. scriptタグのdangerouslySetInnerHTMLプロパティにコピーしたコードをペーストする
1. cssの`font-family`に`font-family: dnp-shuei-4go-std, sans-serif;` のように追加したフォントを記述

=> 
これで、Adobe Fontsで設定したフォントが利用できるようになります。
(Adobe Fonts利用するにはAdobeでサブスクリプション契約をする必要があるので、その点のみご注意ください)
 
## 最後に
これまでGoogle FontsぐらいしかWebフォントを使ってこなかったのですが、Adobe Fontsのフォントを利用するとかなりおしゃれなサイトが作れるのだなと学べて、いい経験になりました。
 
今回の学びを生かして、Next.jsやGatzbyでおしゃれなサイト/アプリケーションを色々作っていきたいです！

## 参考
* [Next.jsにAdobe Fonts（Typekit Webフォント）を導入する](https://blog.kimizuka.org/entry/2021/02/25/111922)
* [React:dangerouslySetInnerHTML](https://ja.reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml)
FreeFEMで熱伝導問題をパラメータースタディ

#熱伝導問題を解く　　
領域内の温度分布の熱伝導率依存性をパラメータースタディによって確認する。  

# 問題設定
2次元の熱伝導問題。
幅 30，高さ 5の2次元領域内の熱伝導を解いた。

FreeFEM 公式ドキュメントのThermal Conductionの例題に従って支配方程式、境界条件を設定。
https://doc.freefem.org/tutorials/thermalConduction.html

```freefem:thermal_conduction.edp
load "iovtk"

// Parameters
func u0 = 10. + 90.*x/6.;
func k = 1.8*(y<0.5) + 0.2;
real ue = 25.;
real alpha=0.25;
real T=5.;
real dt=0.1 ;

// Mesh
mesh Th = square(30, 5, [6.*x,y]);

// Fespace
fespace Vh(Th, P1);
Vh u=u0, v, uold;

// Problem
problem thermic(u, v)
    = int2d(Th)(
          u*v/dt
        + k*(
              dx(u) * dx(v)
            + dy(u) * dy(v)
        )
    )
    + int1d(Th, 1, 3)(
          alpha*u*v
    )
    - int1d(Th, 1, 3)(
          alpha*ue*v
    )
    - int2d(Th)(
          uold*v/dt
    )
    + on(2, 4, u=u0)
    ;

// Time iterations
int[int] Order = [1];
string DataName = "u";
ofstream ff("thermic.dat");
for(real t = 0; t < T; t += dt){
    uold = u; //equivalent to u^{n-1} = u^n
    thermic; //here the thermic problem is solved
    ff << u(3., 0.5) << endl;
    plot(u);
    savevtk("u"+ t*10 +".vtu", Th, u, dataname=DataName, order=Order);
}
```
FreeFEMのインストール、実行方法、Paraviewでの可視化方法はこちらの記事を参照。
https://qiita.com/banapa0610/items/2453155a7ef31c05e54c
https://qiita.com/banapa0610/items/3016e4c5357671d89454

## 熱伝導率の定義
ソースコード内のkが熱伝導率。kの値を変えパラメータースタディを行った。
 k = 1.8*(y<0.5) + 0.2;
の表記は解析領域内でyが0.5未満の場合kは 2.0
yが0.5以上の場合kは0.2となるという定義。
領域内のyの位置によって熱伝導率が異なるという境界条件。
（と認識してますが、もし違ってたらご指摘ください。）

#結果
初期状態から5秒後の領域の温度分布を示す。

1) k = 1.8*(y<0.5) + 0.2　
例題のデフォルトの数値
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368218/5c2727dc-5454-fd41-1a41-9f26a9cb43fd.png)

2)k = 0.05*(y<0.5) + 0.2;
熱伝導率を小さくした場合。熱が伝わりにくくなっている（高温の分布が狭い）ことが分かる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368218/6e9242af-2feb-e4b0-6d23-4bbdd483949e.png)

3)k = 398*(y<0.5) + 0.2;
熱伝導率を大きくした場合。y<0.5の範囲で熱が伝わりやすくなっている（高温の分布が広くなっている）ことが分かる。　　
y=1付近では熱が伝わりにくい様子もわかる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368218/1d817c5e-8673-f0fc-2a66-66a8e0b861d8.png)

4)k = 200*(y<0.5) + 400;
0.5<yの熱伝導率を大きくした場合。0.5<yでも熱が伝わりやすく（高温の分布が広くなっている）y方向で温度分布が同様になっている様子が分かる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368218/911046ce-787c-e88d-1110-8f3972a6e60a.png)

5)k = 1500*(y<0.05) + 0.2;
y＜0.05の熱伝導率を大きくした場合。3)の条件に比べ高温が分布している範囲がy方向下側にシフトしていることが分かる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368218/7628b1f0-20fa-1361-e48f-6a73373fccd4.png)

以上、WSL版FreeFEMとParaviewを使って、熱伝導問題における熱伝導率についてのパラメータースタディができた。 

# 参考文献
FreeFEMの理解のためにこちらの記事を参考させていただきました。

https://qiita.com/t_kemmochi/items/418bdc55e4937381711e
Google Compute Engine のフォルダーを同期する方法

/var/www/html 以下の aaa と bbb というフォルダーを同期させる例です。

```bash:go_sync.sh
SRC_ORG=uchida@example.org:/var/www/html
TARGET_ORG=/var/www/html
#
for folder in aaa bbb
do
	SRC=$SRC_ORG"/"$folder"/"
	echo $SRC
	TARGET=$TARGET_ORG"/"$folder
	echo $TARGET
	rsync -avzz --delete -e "ssh -i $HOME/.ssh/google_compute_engine" \
	      $SRC $TARGET
done
#
```

転送するデータを表示したくない時は、rsync のオプションを次のようにして下さい。

```text
-azz --delete -e
```
クリックして指定した矩形領域の通過回数を計測するPGM(PassedCountMeasurement)

<h3>クリックして指定した矩形領域の通過回数を計測するPGM(PassedCountMeasurement)</h3>

クリックして指定した矩形領域の通過回数を計測するJavaScriptPGMを作りました。
これでバスケットゴールの通過回数を自動で記録するようなプログラムも作れると思います。

<hr>
githubURL:https://github.com/NanjoMiyako/PassCount-Measurement
サンプルページURL:https://nanjomiyako.github.io/PassCount-Measurement/
<hr>
サンプルスクリーンショット
![screenshot.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412430/21105fb3-f76a-509d-008e-c21afb6d827a.jpeg)

![screensho2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412430/f6506fdb-fcfd-196e-91d9-18b135fce105.jpeg)


<hr>
使い方
ページ内のTest1ボタンをクリックしてから
矩形領域1,矩形領域2を登録して通過回数を自動測定します。
矩形領域の指定は左上の点、右上の点をそれぞれクリックしたあとに
指定ボタンをクリックしてから、それぞれの点を固定し、それぞれ
現在の矩形範囲を登録ボタンで登録します。
登録した矩形領域1の差分が一定以上→登録した矩形領域2の差分が一定以上
の状態が発生するたびに通過回数を1増やします

<hr>
難しかったところ
単純に矩形領域1の差分を取った後に矩形領域2の差分が一定以上
になったときにカウントをとるとカウントの重複が発生するため、
一度カウントを取った後、カウントを1秒間停止する処理をいれています。
Reactで\nが入った文字列を改行する方法


## 0. はじめに
タイトルの通り、Reactで\nが入った文字列を改行するのに一苦労したので、備忘録としてまとめます。

## 1. やりたいこと

以下のコード作成のようにpropsで渡した文字列を改行して表示したい

```jsx
import React from 'react'
import Background from './Background/Background'

const About = () => {
  return (
		<div>
      <Background description='テスト1\nテスト2' />
    </div>
  )
}

export default About
```

そのままpropsで渡しても改行されないようなので、以下を参考に `\n` を `<br />` に変換するロジックを入れてみた。

[https://chaika.hatenablog.com/entry/2020/07/12/083000](https://chaika.hatenablog.com/entry/2020/07/12/083000)

```jsx
import React from 'react'
const Background = props => {
  const { description } = props
  return (
    <div>
			{ 
				description.split(/(\n)/).map((item, index) => (
          <React.Fragment key={index}>
            {item.match(/\n/) ? <br /> : item}
          </React.Fragment>
        ))
			}
		</div>
)
}
```

出力結果として、以下となることを期待

```jsx
テスト1
テスト2
```

## 2. 困ったこと

実際は以下のように、改行コードが残ったまま表示される

```jsx
テスト1\nテスト2
```

## 3. 試したこと

### 3A. そもそも、propsで渡す前の改行付き文字列は改行されるのか

以下のように `console.log('テスト1\nテスト2')`　をしてみる→改行される

```jsx
import React from 'react'
import Background from './Background/Background'

const About = () => {
  console.log('テスト1\nテスト2')
  return (
		<div>
      <Background description='テスト1\nテスト2' />
    </div>
  )
}

export default About
```

### 3B. propsする前に、同じ文字列&ロジックで改行するか確認する

以下のコードで改行されることを確認

```jsx
const tmp1 = 'テスト1\nテスト2'
  console.log(tmp1)

  const tmp2 = tmp1.split(/(\n)/).map((item, index) => {
    return (
      <React.Fragment key={index}>
        { item.match(/\n/) ? <br /> : item }
      </React.Fragment>
    )
  })

  console.dir(tmp2)
```

参考
[https://chaika.hatenablog.com/entry/2020/07/12/083000](https://chaika.hatenablog.com/entry/2020/07/12/083000)

考察
propsで値を渡す際になんらか課題がありそう

## 原因

Propsで値を渡す際に`{ value }`としていなかったため。

## 対処法

以下のように、propsで値を渡す際に`{}`を使う。
具体的には以下。

```jsx
import React from 'react'
import Background from './Background/Background'

const About = () => {
  return (
		<div>
      <Background description={'テスト1\nテスト2'} />
    </div>
  )
}

export default About
```

参考
[https://pretagteam.com/question/line-break-in-react](https://pretagteam.com/question/line-break-in-react)
【Unity】変数の受け渡し まとめ【入門】

# はじめに
Unity初心者の方向けに、スクリプトやシーンをまたいで変数を共有する方法について
できるだけわかりやすくまとめました。

# 目次

1．同じシーンのスクリプト間で変数を共有する
　　1.1.　同じオブジェクトの別スクリプト
　　1.2.　別オブジェクトの別スクリプト
2．別シーンのスクリプト間で変数を共有する
　　2.1.　public static 変数として宣言する【お手軽】
　　2.2.　プロパティを使って呼び出す【安全】
　　2.3.　ゲームオブジェクトを破壊せずに保持する【BGMにおすすめ】

# 1. 同じシーンのスクリプト間で変数を共有する
## 1.1. 同じオブジェクトの別スクリプト

例：Playerにつけた別スクリプトに、PlayerについているPlayerScript.csを読み込みたい
→スクリプトをGetComponentで読み込む

```C#:PlayerScript.cs
//＠呼ばれる方のスクリプト
public int speed=1;
```

```C#:ChangingSpeed.cs
//＠呼ぶ方のスクリプト
void Start()
    {
        Invoke("Change", 3); //3秒経ったら実行する
    }
void Change()
    {
        Debug.Log("例1成功！スピードアップ！");
        PlayerScript playerscript = GetComponent<PlayerScript>();
        playerscript.speed = 10;
    }
}
```

## 1.2. 別オブジェクトの別スクリプト

例：空のGameObjectにつけたスクリプトに、PlayerについているPlayerScript.csを読み込みたい
→特定のゲームオブジェクトを.Findで探し、スクリプトをGetComponentで読み込む

```C#:PlayerScript.cs
//＠呼ばれる方のスクリプト
public int speed=1;
```

```C#:SpeedChanger.cs
//＠呼ぶ方のスクリプト
void Start()
    {
        Invoke("Change", 3);
    }
void Change()
    {
        Debug.Log("例2成功！スピードアップ！");
        PlayerScript playerscript; //呼ぶスクリプトにあだなつける
        GameObject obj = GameObject.Find("Player"); //Playerっていうオブジェクトを探す
        playerscript = obj.GetComponent<PlayerScript>(); //付いているスクリプトを取得
        playerscript.speed = 10;
    }
}
```

# 2. 別シーンのスクリプト間で変数を共有する
## 2.1. public static 変数として宣言する【お手軽】
→ゲーム全体に変数が保存される＝シーン遷移でオブジェクトが破棄されても変数が生き残る

```C#:Script1.cs
//＠呼ばれる方のスクリプト
public static int a=100;
```

```C#:Script2.cs
//＠呼ぶ方のスクリプト
int number = Script1.a; // ＝変数を呼び出したい元のスクリプトのクラス名、変数名；
void Start()
    {
        Debug.Log(number + "成功！！");
    }
}
```

注意点：どのスクリプトにStatic変数を書いたか忘れずに把握しておくこと


## 2.2. プロパティを使って呼び出す【安全】

→外部からは変数をいじることができないのでバグが起こりづらい
（プロパティとはGetとSetを用いたプログラムの名称！）

```C#:Script1.cs
//＠呼ばれる方のスクリプト
private int num;
public int GetSetProperty  //public 戻り値 プロパティ名
    { 
        get { return num; } //get {return フィールド名;}
        set { num = value; } //set {フィールド名 = value;}
    }
```

```C#:Script2.cs
//＠呼ぶ方のスクリプト
int number = Script1.a; // ＝変数を呼び出したい元のスクリプトのクラス名、変数名；
void Start()
    {
        Script1 script = new Script1(); //インスタンス化する
        script.GetSetProperty = 10; //set、numを10に書き換える
        Debug.Log(script.GetSetProperty); //get、numを取得してConsoleに表示
    }
}
```


## 2.3. ゲームオブジェクトを破壊せずに保持する【BGMにおすすめ】
→DontDestroyOnLoadを使ってそもそもシーンをまたいでも破棄されないようにする

```C#:BGM.cs
AudioSource audioSourceBGM;
void Start()
    {
        audioSourceBGM = GetComponent<AudioSource>();
    }
void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            DontDestroyOnLoad(this.gameObject);
            SceneManager.LoadScene("Scene2");
        }
    }
}
```

注意点：同じオブジェクトが重複する（ex.BGMが二重に聞こえる）が起こりうるので、不要になったら Destroy (this); などで削除する


### 参考
[遷移しても大丈夫！Unityの変数を異なるシーン間で共有する方法](https://freesworder.net/unity-variable-unchange/)
[Unityで他のスクリプトの変数や関数を利用する](https://htsuda.net/archives/1702)
[C#のプロパティについて調べてみた](https://qiita.com/ShirakawaMaru/items/5f8bd065b1a4d2fdc8e0)
[【Unity】スクリプトを他のスクリプトから参照する方法](https://pengoya.net/unity/script/)
[【Unity】よく出てくるprivate, public, static,[SerializeField]についてまとめてみた！](https://turedureengineer.hatenablog.com/entry/2018/10/01/124330)
arm64 向け Debian11 Root File System を amd64+QEMU で作成する時は qemu-user-static のバージョンを 6.1 以降にしてください


# はじめに

次のようにして Ubuntu (18.04等) 上で QEMU を使って arm64 向けの Debian11(bullseye) Root File System を ビルドする場合

```console
shell$ mkdir debian11-rootfs
shell$ sudo chown root debian11-rootfs
shell$ sudo debootstrap --arch=arm64 --foreign bullseye debian11-rootfs
     :
     :
shell$ sudo cp /usr/bin/qemu-aarch64-static debian11-rootfs/usr/bin
shell$ sudo cp /etc/resolv.conf             debian11-rootfs/etc                 
```

以下のようなエラーが発生する場合があります。

## 現象1

debootstrap の second-stage で次のようなエラーが発生する。

```console
shell$ sudo chroot debian11-rootfs
I have no name!@ubuntu:/# distro=bullseye
I have no name!@ubuntu:/# export LANG=C
I have no name!@ubuntu:/# /debootstrap/debootstrap --second-stage
W: Failure trying to run:  /sbin/ldconfig
W: See //debootstrap/debootstrap.log for details
```

## 現象2

python3-minimal をインストールする時、segmentation error が起きる。

# 原因と対策

いずれの場合も、qemu-user-static のバージョンが古い場合に起きます。

現象１を避けるためには buster-backports 以降で提供されている 5.2 以降が必要です。
現象２を避けるためには 6.1 以降が必要です。

どちらも避けたい場合は、6.1 以降を使ってください。私は [qemu-user-static_6.1+dfsg-8_amd64.deb](https://debian.pkgs.org/sid/debian-main-amd64/qemu-user-static_6.1+dfsg-8_amd64.deb.html) を探してきて、dpkg -i でインストールして使いました。


# 参考資料

 * [Bug#982422: debootstrap: segmentation fault around ldconfig during debootstrapping bullseye/arm64 on a buster/amd64 host](https://linux.debian.maint.boot.narkive.com/zEiCDD1x/bug-982422-debootstrap-segmentation-fault-around-ldconfig-during-debootstrapping-bullseye-arm64-on)
 * [Bug#988174: /usr/bin/qemu-aarch64-static: Segfaults sometimes on python3-minimal on arm64](https://linux.debian.bugs.dist.narkive.com/2PWcEkkK/bug-988174-usr-bin-qemu-aarch64-static-segfaults-sometimes-on-python3-minimal-on-arm64)
 * [AMD64 マシン用 qemu-user-static_5.2+dfsg-9~bpo10+1_amd64.deb のダウンロードページ](https://packages.debian.org/buster-backports/amd64/qemu-user-static/download)
 * https://debian.pkgs.org/sid/debian-main-amd64/qemu-user-static_6.1+dfsg-8_amd64.deb.html
SharePlayの画面共有時にViewを制御する

# 概要
おはこんばんにちは！和尚です:sunny:

iPhone15.1からSharePlayが使えるようになりましたね〜:iphone:
FaceTimeを全く使うことがないので個人的には関わりが今後もなさそうな機能ではありますが、対応しなければならなそうなアプリがいくつかあって制御方法を調べたので記事にしました:v:

## 読者想定　　
- SharePlayで画面共有した時にViewを制御したい人
- SharePlayって何？って人

## SharePlayとは
簡単に言うとFaceTimeを使ってテレビ電話している人に画面共有ができる機能です。自分の端末の画面がそのまま相手の画面に共有されるためSharePlayはアプリで特別な実装をする必要はなく、この機能を使うだけでアプリを相手に見せながらテレビ電話で会話することが可能です。
また画面をそのまま相手に共有するだけではなく、音楽や動画は再生・停止・シークなどを相手と同期させることが可能になります。
*※DRM動画などの制御されたコンテンツはアプリ側でSharePlayの対応をさせないと相手と共有することは出来ません。*

公式サイト：https://developer.apple.com/jp/shareplay/

# 制御方法
自分の画面がそのまま相手に共有されるSharePlayですが、画面共有時に特定のViewを非表示にしたい場合があると思います。その時の制御方法を見ていきましょう。

## 制御プロパティ
UIScreenに画面共有中かどうかを示す真偽値があるので、こちらを使って制御していきます。

```swift
UIScreen.main.isCaptured
```
この値はSharePlayの画面共有中だけではなく、ミラーリングやAirPlayでのストリーミング中でも値がTRUEになるので、これらを制御したい場合も同じ値を使って制御することが可能です。

## Viewの制御方法
簡単に画面を制御するサンプルコードをSwiftUI書いたので、実装の参考にしてみてください。

*※iOS14以上をターゲットとした書き方をしています。iOS13以降をターゲットにしたいかたは`@StateObject`の部分を`@ObservedObject`に変更してください。*
### View
```swift:ContentView.swift  
import SwiftUI

struct ContentView: View {
    @StateObject private var viewModel = ContentViewModel()
    
    var body: some View {
        Group {
            if viewModel.isChaptured {
                Text("シェアプレイ中")
            } else {
                Text("シェアプレイ中ではありません")
            }
        }
        .onAppear(perform: viewModel.onAppear)
        .onDisappear(perform: viewModel.onDisappear)
    }
}
```
### ViewModel

```swift:ContentViewModel.swift

import Combine
import UIKit

final class ContentViewModel: ObservableObject {
    // TRUE = 画面共有中、 FALSE = 画面共有中ではない
    @Published var isChaptured: Bool = false
    
    private var cancellable: AnyCancellable?
    
    // 画面表示時の処理：呼び出したメソッドのコメント参照
    func onAppear() {
        updateIsCaptured()
        subscribeIsCaptured()
    }
    
    // 画面非表示時の処理：監視をキャンセルします
    func onDisappear() {
        cancellable?.cancel()
    }
    
    // 画面共有中の状態を更新します
    private func updateIsCaptured() {
        isChaptured = UIScreen.main.isCaptured
    }
    
    // 「UIScreen.capturedDidChangeNotification」は画面共有された時と、
    // 共有が停止された時に送信される通知なので、監視します。
    private func subscribeIsCaptured() {
        cancellable = NotificationCenter.default
            .publisher(for: UIScreen.capturedDidChangeNotification)
            .sink { [weak self] _ in
                self?.updateIsCaptured()
            }
    }
}
```

# 終わりに
いかがでしたでしょうか。
やってること自体はかなりシンプルなので、もしSharePlayで画面共有した時にこの画面は見せたくないといった仕様があった場合は参考にしてみてください！
acts-as-taggable-onのtag_listでN+1問題が起きる時の対処

## 概要
簡単にタグ機能を実装できる[acts-as-taggable-on](https://github.com/mbleigh/acts-as-taggable-on)というgemがあり、とても便利だが、as_jsonなどのシリアライズするメソッドを使用した際ににN+1問題を引き起こす原因となることがあるのでメモ

## 詳細
この[issue](https://github.com/mbleigh/acts-as-taggable-on/issues/1029)にも書いてあるが

- `acts_as_taggable_on`メソッドは、引数に指定した値に対応する`*_list`という属性と、メソッドを自動的に定義する(例えば:tagsと指定すると、`tag_list`というインスタンスの属性とメソッドが追加される)
- このtag_listメソッドはincludesなどを用いてクエリ回数を減らすことができない(ここの詳細はそこまで深く追ってない)
- [as_jsonは、SomeModel.attributes.keysで返ってくる値それぞれに対して、sendメソッドでメソッド化して実行した結果をハッシュにする](https://github.com/rails/rails/blob/83217025a171593547d1268651b446d3533e2019/activemodel/lib/active_model/serialization.rb#L126)

要は、複数のインスタンスに対して、関連するタグを取得するために毎回クエリを発行してしまうのだが、それをうまく回避するための策がない

解決策として、`as_json(except: [:tag_list])`したり、同様の結果を返すメソッドを定義すればいいと思ったが、インターフェースを変えたくなかった(`tag_list: [タグ1, タグ2...]`という結果をもうすでに他の場所で利用していた)ので、影響を与えないように、内部の処理だけを変える方法を考えてみた


## 回避策
いくつか考えたが、自分の環境では、モデルでオーバーライドするのが簡単かつ現実的であった。(あまりしたくないのはもちろんだが)
この`tag_list`メソッドが[実際に定義](https://github.com/mbleigh/acts-as-taggable-on/blob/master/lib/acts_as_taggable_on/taggable/core.rb#L123)されているのは、モデルに`include`されている無名モジュールなので、モデルで同名メソッドを定義してオーバーライドできる

```ruby:some_model.rb
acts_as_taggable_on :tags

def tag_list
  tags.map(&:name)
end
```

実行してみる

```ruby
SomeModel.includes(:tags).as_json

# @controller
render json: {
  some_models: SomeModel.includes(:tags)
}
```

これでN+1問題は発生しないようにできた


## 気持ち
いっぱいソースコード読んだのでせっかくなのでメモっとこう
WSL(Ubuntu 20.04 LTS) に、Ｄockerインストール

# 環境
Windows10 + WSL(Ubuntu 20.04.3 LTS) 

```shell
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.3 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.3 LTS"
VERSION_ID="20.04"
・・・
```
※Ubuntu 20.04.4 LTSでも動作確認済み

# はじめに
題名以上のせつめいはありません。
毎回調べるハメになるので、書き残し。

# 手順

## 事前に
wslのバージョンを2にする(1or2のどちらかで問題ない)
1. 初回立ち上げ前にPowershell(管理者実行)で以下を行う
```shell
wsl --set-default-version 2
```

※永続設定

2．仮想環境単体にPowershell(管理者実行)で以下を行う
```
wsl --shutdown
wsl --set-version <WSL管理名称> 2
```
※WSL管理名称 は `wsl --list --verbose` とかで確認


## コマンド
```shell
# update
sudo apt-get -y update

# 事前に必要なものを取得
sudo apt-get -y install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

# GunPG(暗号通信)設定
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# GunPG(暗号通信)分をupdate
sudo apt-get -y update
# dockerインストール
sudo apt-get -y install docker-ce docker-ce-cli containerd.io docker-compose
# バージョン指定の場合
# sudo apt-get -y install docker-ce=<VERSION_STRING> docker-ce-cli=<VERSION_STRING> containerd.io

# 自身をDockerユーザーに登録
sudo usermod -aG docker $(whoami)

# 起動
sudo service docker start
```
※一回、`exit`(wslコンソール終了) or `wsl --shutdown`等で終了させないと、ユーザーの登録反映ができないはず

## 確認
```shell
docker run -d -p 8000:80 nginx
```
※実行したら、ブラウザ等で localhost:8000 にアクセスして確認
※permission denied がでたら、ユーザー追加がうまくいっていない

# 更新
- 2022/07/02
    - wsl上げてなくて、見事に起動しなかったので、追加
    - ユーザー関連を一部修正
    - 20.04.4 でも問題なかったので、一部修正

# 最後に
docker desktop ではないから、例の上限を上回っていても関係ない（ハズ
中規模以上の会社さんは意外と上回るのかなと、、、
Fleet Manager から Red Hat ナレッジベースへアクセスする

## はじめに
2021/11/3 のアップデートで Red Hat ナレッジベースへのアクセスがワンクリックで可能になりました。EC2 上でEnterprise Linux のサブスクリプションを実行しているユーザーは AWS Systems Manager の Fleet Manager から簡単にナレッジベースへアクセスできます。

https://aws.amazon.com/jp/about-aws/whats-new/2021/11/amazon-ec2-red-hat-knowledgebase/

## やってみる
Fleet Manager は AWS Systems Manager のマネージドインスタンス (SSM Agent がインストールされた EC2/オンプレミスインスタンス) を管理する機能です。インスタンスのヘルスステータスや詳細情報 (ファイルシステム、OS ユーザー) なども確認することができます。

つまり、起動している RHEL のインスタンスがマネージドインスタンスとして Systems Manager に登録されている必要があります。RHEL の AMI にはデフォルトで SSM Agent がインストールされていないため、今回はインスタンス起動時の User data に以下を入力してインストールを行いました。

```sh
#!/bin/bash
cd /tmp
sudo dnf install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm
sudo systemctl enable amazon-ssm-agent
sudo systemctl start amazon-ssm-agent
```

https://aws.amazon.com/jp/premiumsupport/knowledge-center/install-ssm-agent-ec2-linux/

また SSM Agent がインストールされた EC2 が Systems Manager と通信を行うためには、適切なポリシーが設定された IAM ロールを EC2 にアタッチする必要があります。手順は割愛しますが、必要な場合は以下のドキュメントを参考にしてください。

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/setup-instance-profile.html

インスタンス起動後に Systems Manager のコンソールからノード管理のフリートマネージャーを選択して、対象のインスタンスが正常に登録されていることを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/1386e79b-7f94-467c-1252-0380f7c45827.png)

インスタンス ID をクリックして詳細画面に進むと、インスタンスの概要に **(RHel) ナレッジベースのコンテンツへのアクセス** というリンクがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/7f80511e-e160-1f04-35f6-28b337f9ecb2.png)

このリンクをクリックすると、Red Hat のナレッジベースへリダイレクトされます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/01d81234-4328-564c-c0d1-36a9b9751840.png)

:::note warn
コンソールアクセス時に使用する IAM ユーザーまたはロールのポリシーで `rhelkb:GetRhelURL` アクションが許可されていない場合は権限エラーになりますのでご注意ください。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/f5bf03f6-c0e0-27f3-567c-b8c97792084b.png)

## ドキュメント
https://docs.aws.amazon.com/systems-manager/latest/userguide/fleet-rhel.html

簡単ですが、以上です。
【Python】ディレクトリ・パス取得関連（os, pathlib, glob）

## 概要

Pythonのパスやディレクトリを取得する方法よく忘れてしまうので、
備忘録として残しておきます。
今回は**os**や**pathlib**、**glob**モジュールあたりの話です。

## osモジュール
__ file __はPythonファイル（今回でいうpath.py）の絶対パスです。

### 絶対パスを取得（os.path.abspath()）
```python:path.py
path = os.path.abspath(__file__)
print("Absolute Path: {}".format(path))
# Absolute Path: /Users/.../path.py
```

### 相対パスを取得（os.path.relpath()）
第２引数は対象としたい相対基準のパス。

```python:path.py
relPath = os.path.relpath(__file__, "./")
print("Relative Path: {}".format(relPath))
# Relative Path: path.py
```

### 現在地のディレクトリを取得（）
```python:path.py
dire = os.getcwd()
print("Directry: {}".format(dire))
# Directry: /Users/...
```

### ディレクトリ名とファイル名を分割（os.path.split()）
```python:path.py
path = os.path.split(__file__)
print("Directry: {}, FileName: {}".format(path[0], path[1]))
# Directry: /Users/..., FileName: path.py
```

### ディレクトリ名取得（os.path.dirname()）
```python:path.py
dire = os.path.dirname(__file__)
print("Directry: {}".format(dire))
# Directry: /Users/...
```


### ファイル名取得（os.path.basename()）
```python:path.py
fname = os.path.basename(__file__)
print("FileName: {}".format(fname))
# FileName: path.py
```

## pathlibモジュール

### 相対パス→絶対パス
```python:path.py
absPath = pathlib.Path("./path.py").resolve()
print("Absolute Path: {}".format(absPath))
# Absolute Path: /Users/.../path.py
```

### 相対パス→絶対パス
```python:path.py
relPath = pathlib.Path(__file__).relative_to(os.getcwd())
print("Relative Path: {}".format(relPath))
# Relative Path: path.py
```

## globモジュール
変数filesは**リスト**型です。
filesの並びがテキトーなので、整形したものが欲しい場合は**sorted**を使用。

### 該当するファイルリストを取り出し
```python:path.py
files = glob("test/*.py")
for f in files:
    print("File: {}".format(f))
# File: test/test4.py
# File: test/test1.py
# File: test/test7.py
```

```python:path.py
files = sorted(glob("test/*.py"))
for f in files:
    print("File: {}".format(f))
# File: test/test1.py
# File: test/test4.py
# File: test/test7.py
```


## その他

全てまとめたソースコードをGitHubに置いています。

https://github.com/khfkd/python_get_path
【Laravel】ラジオボタンの実装と値の保持

#はじめに
値がちゃんと保持されるようにラジオボタンを実装してみます。

#コード

```php:create.blade.php
<div class="form-group">
    <label>{{ __('投稿') }}
    <div class="form-check form-check-inline">
        <input type="radio" name="release" class="form-check-input" id="release1" value="投稿しない" {{ old ('release') == '投稿しない' ? 'checked' : '' }} checked>
        <label for="release1" class="form-check-label">投稿しない</label>
    </div>
    <div class="form-check form-check-inline">
        <input type="radio" name="release" class="form-check-input" id="release2" value="投稿する" {{ old ('release') == '投稿する' ? 'checked' : '' }}>
        <label for="release2" class="form-check-label">投稿する</label>
    </div>
    </label>
</div>
```

```php:edit.blade.php
<div class="form-group">
    <label>{{ __('投稿') }}
    <div class="form-check form-check-inline">
        <input type="radio" name="release" class="form-check-input" id="release1" value="投稿しない" {{ old ('release', $menu->release) == '投稿しない' ? 'checked' : '' }}>
        <label for="release1" class="form-check-label">投稿しない</label>
    </div>
    <div class="form-check form-check-inline">
        <input type="radio" name="release" class="form-check-input" id="release2" value="投稿する" {{ old ('release', $menu->release) == '投稿する' ? 'checked' : '' }}>
        <label for="release2" class="form-check-label">投稿する</label>
    </div>
    </label>
</div>
```

このように記述することで、登録画面においては、バリデーションエラー発生時に入力していた値を保持し、編集画面においては、登録した値を保持しつつ、バリデーションエラー発生時には直前に入力されていた値を保持することができます。

#おわりに
１人でも多くの方の参考になれば幸いです。
laravel 「Add [カラム名] to fillable property to allow mass assignment on [モデル名]」エラーの解決

# 目的

- `Add [カラム名] to fillable property to allow mass assignment on [モデル名]`エラーの解決方法をメモ的にまとめる

# 解決方法

- エラーに記載されている`モデル名`のクラスが記載されているファイルを開く。
- 当該モデルクラス内に下記の内容を記載する。

    ```php
    protected $fillable = ['エラーで表示されているカラム名'];
    ```

- 記入後の例を下記に記載する。

    ```php
    <?php
    
    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Factories\HasFactory;
    use Illuminate\Database\Eloquent\Model;
    
    class Hoge extends Model
    {
        protected $fillable = ['エラーで表示されているカラム名'];
    }
    ```
Shopifyで決済アイコンの並び替え

#Shopifyのfooterにある決済アイコンの並び替え
![スクリーンショット 2021-11-06 15.02.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/432662/3b5c1660-1291-63c9-cac5-aa68d42d6c8b.png)

##並び替えの方法は2通りあります。
* コードから並び順を変更する
* CSSから並び順を変更する

###コードから並び順を変更する
こちらの方法は[公式ヘルプサポート](https://help.shopify.com/en/manual/online-store/themes/os/customize/add-credit-card-icons)でも公開されているのでご確認ください。

もし配列の中身を出力したい場合は、footer.liquidの中にある下記の部分の{% endfor %}下に{{shop.enabled_payment_types | join: ', '}}を追加し、ブラウザ画面をみると、配列の中身がすべて表示されていると思います。

``` liquid
{% for type in shop.enabled_payment_types %}
 <li class="payment-icon">
{{ type | payment_type_svg_tag: class: 'icon icon--full-color' }}
</li>
{% endfor %}
{{shop.enabled_payment_types | join: ', '}}
```
そして、ブラウザに表示された配列をコピーして覚えておき、公式のページにあるように

``` liquid
liquid
{% for type in shop.enabled_payment_types %}
```
の部分を

``` liquid
liquid
{% assign enabled_payment_types = 'visa,master,american_express,paypal' | remove: ' ' | split: ',' %}
{% for type in enabled_payment_types %}
```
に置き換えます。
そして、assign enabled_payment_types = 'visa,master,american_express,paypal'の部分を、先程出力した配列を希望の並び順にして並び替えて入れ替えて上げれば、並びが変わります。

※注意点としては、このコードに変更した後に、決済方法を追加しても自動で出力はされないので、
作業したことを忘れないようにしましょう。


###CSSから並び順を変更する
配列を触ると、後に決済手段を追加した時に、表示されずに焦るような気がしたので、私の場合はCSSで並びを変更することにしました。

私の場合は、flexとnth-of-type()を利用して、並び変えました。
（テーマによってCSSのクラスが異なると思いますので、コピペでは効かない事があると思いますので、あくまで参考にどうぞ）

``` scss
//payment
.payment-icons.list--inline.site-footer__icon-list{
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  @media screen and(max-width:999px){
    justify-content: center;
  }
  li{
    &:nth-of-type(16){
      //visa
      order: 1;
    }
    &:nth-of-type(10){
      //master
      order: 2;
    }
    &:nth-of-type(7){
      //jcb
      order: 3;
    }
    &:nth-of-type(1){
      //amex
      order: 4;
    }
    &:nth-of-type(4){
      //diners
      order: 5;
    }
    &:nth-of-type(14){
      //seven
      order: 6;
    }
    &:nth-of-type(5){
      //family
      order: 7;
    }
    &:nth-of-type(8){
      //lowson
      order: 8;
    }
    &:nth-of-type(12){
      //ministop
      order: 9;
    }
    &:nth-of-type(3){
      //daily
      order: 10;
    }
    &:nth-of-type(2){
      //daily
      order: 11;
    }
    &:nth-of-type(6){
      //daily
      order: 12;
    }
    &:nth-of-type(13){
      //paypay
      order: 13;
    }
    &:nth-of-type(11){
      //linepay
      order: 14;
    }
    &:nth-of-type(9){
      //merupay
      order: 15;
    }
    &:nth-of-type(15){
      //shoppay
      order: 16;
    }
  }
}

```

並び替えの結果、クレジットカード、コンビニ支払い、スマホ決済の並びに整頓できました。

![スクリーンショット 2021-11-06 15.36.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/432662/982a2146-a8cc-2d53-872e-ad6c76d5348b.png)
文系卒が数学オリンピックをPythonで解く（2020年予選編）

#これまでのあらすじ
- 文系卒の私。でも数学になじみたい。
- ふむふむ、数学オリンピックというのがあるらしい。やってみますか。
- 紙とペンを使ってマジメに解く文系卒。えらい、えらいぞ！
- ５分後にふと衝撃走る。「これPythonでやったほうが早くない？」
- そんな、いつか 誰かに 本気で怒られそうな気づきを 実行したのであった──。

#ルール
- 数学オリンピックの問題をPythonで解く。
- ライブラリは可能な限り使わない。例外的にitertoolsは使う。
- 図形の問題は挑戦しないかも。許してね。
- 式変形すれば解けるようなものも面白味がないので対象外。

#引用元
問題はこちらから引用しております。

[第30回(2020年)JMO予選の問題 - 数学オリンピック](https://www.imojp.org/archive/mo2020/jmo2020/problems/jmo30yq.html)

https://www.imojp.org/archive/mo2020/jmo2020/problems/jmo30yq.html


#Q1
##問題
>千の位と十の位がともに2であるような4桁の正の整数のうち、7の倍数はいくつあるか。
>*[第30回(2020年)JMO予選の問題 - 数学オリンピック](https://www.imojp.org/archive/mo2020/jmo2020/problems/jmo30yq.html)*

####考える
これは考えるより書くが易しですね。

####仕様
- 千の位と十の位がともに2であるような4桁の正の整数を作成する。
- 作成した整数に対して、7で割り切れるかを判定する。
- 7で割り切れる場合、リストに格納する。
- リストの要素数を数える。

####コーディング
特に変わったことはしていません。
（itertoolsのデカルト積を使えば二重のfor文は防げますが、割愛。）

```py
nums =[]
for n in range(10):
    for m in range(10):
        num = '2'+str(n)+'2'+str(m)
        num = int(num)
        if num % 7 == 0:
            nums.append(num)
print(nums)

# 実行結果 -> [2023, 2121, 2128, 2226, 2324, 2422, 2429, 2520, 2527, 2625, 2723, 2821, 2828, 2926]
```

要素数の表示。

```py
print(len(nums))

# 実行結果 -> 14
```

:::note
答え：14個
:::


#Q4
##問題
> 正の整数nであって、n<sup>2</sup> とn<sup>3</sup> の桁数の和が8であり、 n<sup>2</sup> とn<sup>3</sup> の各桁合わせて1以上8以下の整数がちょうど1個ずつ表れているようなものを全て求めよ。
>*[第30回(2020年)JMO予選の問題 - 数学オリンピック](https://www.imojp.org/archive/mo2020/jmo2020/problems/jmo30yq.html)*

####考える
こういう問題はプログラミング向きで楽しいですね。
初手コーディングでいきましょう。

####仕様
- 整数nを作成する。
- `n**2`と`n**3`を計算し、以下の条件を満たすか判定する。（AND条件）
    - 合計が8桁か判定する。
    - その8桁に1,2,3,4,5,6,7,8が1回ずつ登場する。
- 条件に合致すれば、nを`print`する。
- 条件に合致しなければ、整数nに1を加算する。


####コーディング

```py
n = 1
while n < 1000:
    str_n = str(n**2)+str(n**3)
    if len(str_n) == 8:
        results = []
        for _ in range(1,9):
            result = str(_) in str_n
            results.append(result)
        if sum(results)==8:
            print(n)
    n += 1

# 実行結果 -> 24
```

なお、n=24の場合、n**2とn**3は以下のようになります。

```py
str(n**2),str(n**3)

# 実行結果 -> ('576', '13824')
```

:::note
答え：24
:::



#続く──。
React Router の"Switch"や"exact" が使用できない時の対処法

#参考

https://remix.run/blog/react-router-v6

https://stackoverflow.com/questions/63124161/attempted-import-error-switch-is-not-exported-from-react-router-dom


正確な詳しい情報を知りたい方はこちらを参照してください

# エラー

```
Module '"react-router-dom"' has no exported member 'Switch'.
```

```
型 '{ children: element; exact: true; path: string; }' を型 'intrinsicattributes & (pathrouteprops | layoutrouteprops | indexrouteprops)' に割り当てることはできません。 プロパティ 'exact' は型 'intrinsicattributes & (pathrouteprops | layoutrouteprops | indexrouteprops)' に存在しません。
```

#原因
React Router v6を使っている場合に起こるエラー


#解決策

## 1. 記述を変える

- "Switch"を"Routes"に変える
- exactを使わない

## 2. バージョンを下げる

```
npm install react-router-dom@5
```