OmniAICreator/Qiita-1.07M huggingface dataset:
Unity & GitHub Actionsを学んだときの成果物・役に立った記事【まとめ】

# はじめに

ここ１週間ほどでUnityとGitHub ActionsでのCIについて一通り学んだので、成果物や役に立った記事をまとめました。


## 成果物

### 記事

やったことに関する手順を解説した記事。

- [UnityとGitHubActionsを使って自動テストを行う](https://qiita.com/makihiro_dev/items/fda3fa840f5311d2b3d5)
- [UnityとGitHubActionsを使って自動テストを行い、結果をSlackに報告する](https://qiita.com/makihiro_dev/items/bc1885736b29a2eaa4bb)
- [UnityとGitHubActionsを使って自動ビルドする【複数プラットフォーム同時ビルド】](https://qiita.com/makihiro_dev/items/03208a83d4c3a1fb426b)
- [UnityとGitHubActionsを使って自動でunitypackageをエクスポートする](https://qiita.com/makihiro_dev/items/4e2d83ad0d268b43f4a4)
- [GitHubActionsでUnityライセンスのアクティベーションを行うためのULFファイルを入手するツールを作った【GUI操作のみ】](https://qiita.com/makihiro_dev/items/61f004e5481cef54b5a7)


### サンプルリポジトリ集

上手く動かなかったとき、比較対象となるリポジトリが無くて困ったことがありました。
なので、サンプルリポジトリを作りました。

- [Unity-GitHubActions-AutomaticTest-Example](https://github.com/mackysoft/Unity-GitHubActions-AutomaticTest-Example)
- [Unity-GitHubActions-Build-Example](https://github.com/mackysoft/Unity-GitHubActions-Build-Example)
- [Unity-GitHubActions-ExportPackage-Example](https://github.com/mackysoft/Unity-GitHubActions-ExportPackage-Example)
- [Unity-GitHubActions-Tutorials](https://github.com/mackysoft/Unity-GitHubActions-Tutorials)


## 役に立った記事（新しい順）

学ぶ際に役に立った記事です。
古い記事だとうまく動かなかった場合があるので、基本的には新しい記事を参考にした方がいいです。

### テスト

- [UnityとGithubActionsを使って自動テストをセットアップする手順の備忘録](https://qiita.com/kyourikey/items/df43b751b0ef7a681a42)
- [GitHub Actions を使った Unity の自動テスト](https://qiita.com/kumaS-kumachan/items/d5d44b04b5631154d11a)
- [【Unity】GithubActionsでUnityを起動してTestRunner実行後の結果を出力するまでの手順](https://qiita.com/ohbashunsuke/items/63f0007067a070869ca8)
- [【Unity】GitHub Actions v2でUnity Test Runnerを走らせて、結果をSlackに報告する【入門】](https://qiita.com/pCYSl5EDgo/items/690dd56ffb0fcf64e70b)

### ビルド

- [Github Actions で UnityPackage をビルドしたら快適だった話](https://qiita.com/TakenokoTech/items/4b22e9f1c14570306bb2)


### ライセンス認証

- [Unityでエディタ拡張を作っている人向けの「GitHub Actionsを使ったCI構築」](https://qiita.com/Sokuhatiku/items/5b80b133e559893adc45)
- [UnityをGitHub Actionsで動かす際にライセンス認証周りで注意するべき点](https://qiita.com/pCYSl5EDgo/items/7496f39eb1ab49a594bc)


### 公式ドキュメント

基本的には[Game CIのUnity Actions](https://github.com/game-ci/unity-actions)を使用することになります。
細かい制御をしたいときや、どうしても分からないときは公式を参考にしました。

- [Game CI - Activation](https://game.ci/docs/github/activation)
- [Game CI - Test runner](https://game.ci/docs/github/test-runner)
- [Game CI - Builder](https://game.ci/docs/github/builder)
- [Issues](https://github.com/game-ci/unity-actions/issues)


# さいごに

Unity & GitHub Actionsを学ぶ際の参考になれば幸いです。
ajax を使ってファイルのアップロード

jQuery の ajax を使ったファイルのアップロードです。
サーバーサイドは、PHP です。
![upload_ajax.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/4f18b8c3-2650-065f-6d28-21cee20ab380.png)


```html:upload_ajax.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="CONTENT-TYPE" content="text/html; charset=utf-8" />
<script src="/js/jquery-3.6.0.min.js"></script>
<script src="upload_ajax.js"></script>
<title>upload ajax</title>
</head>
<body>
<h2>upload ajax</h2>
<form id="foo">
	<input id="file" name="file" type="file" />
	<input id="send" type="submit" />
</form>
<br />
<div id="result"></div>
<br />
<hr />
<div id="outarea_aa">outarea_aa</div>
<div id="outarea_bb">outarea_bb</div>
<div id="outarea_cc">outarea_cc</div>
<div id="outarea_dd">outarea_dd</div>
<div id="outarea_ee">outarea_ee</div>
<div id="outarea_ff">outarea_ff</div>
<div id="outarea_gg">outarea_gg</div>
<div id="outarea_hh">outarea_hh</div>
<hr />
Apr/12/2021<p />
</body>
</html>
```

```js:upload_ajax.js
// ---------------------------------------------------------------
//	upload_ajax.js
//
//					Apr/12/2021
//
// ---------------------------------------------------------------
jQuery(function ()
{
	jQuery('#foo').submit(function(){
        var fd = new FormData(jQuery('#foo').get(0))

        jQuery.ajax({
		url: "upload_ajax.php",
		type: "POST",
		data: fd,
		processData: false,
		contentType: false,
		dataType: 'json'
        })
        .done(function( data ) {

		var str_out = ""
		for (it in data.message)
			{
			str_out += data.message[it] + "<br />"
			}

		jQuery('#result').html(str_out)

		jQuery('#outarea_cc').text(JSON.stringify (data))
	})
	return false
	})
})

//
// ---------------------------------------------------------------
```

```php:upload_ajax.php
<?php
// ------------------------------------------------------------------
//	upload_ajax.php
//
//					Apr/12/2021
//
// ------------------------------------------------------------------
if ($_FILES['file']) {
	$size = getimagesize( $_FILES['file']['tmp_name'] );
	$data = array ();
	$data = array( 'width' => $size[0], 'height' => $size[1] );
	$filename = $_FILES['file']['name'];
	$tmp_name = $_FILES['file']['tmp_name'];
	$data['filename'] = $filename;
	$data['tmp_name'] = $tmp_name;

	$message = array ();
	$message[] = "*** check ***";
	$path_target = "./data_work/" . $filename;
	$message[] = $path_target;

	if (move_uploaded_file ($tmp_name,$path_target) == FALSE)
		{
		$message[] = 'nothing is uploaded at ' . $_POST['now'];
		$message[] = $filename . " cannot be uploaded.";
		}
	else
		{
		$message[] = "*** success ***";
		$message[] = $filename . " is uploaded.";
		}

	$data['message'] = $message;

	header('Content-type: text/html');
	echo json_encode($data);
}

// ------------------------------------------------------------------
?>
```
【PHP8.0】function_exists('getdir')がtrueになるんだけどなにこれ？

# まとめ

PHP8.0.0からPHP8.0.3までの間、[`getdir()`という組み込み関数が存在する](https://3v4l.org/4CbIl)。


# [Stack Overflow](https://stackoverflow.com/questions/66854655/php-8-function-alias-compatibility-getdir)

## PHP 8, function alias compatibility `getdir()`

こんなコードを書いたらなんか[PHP8でエラーになる](https://3v4l.org/IvoL1)んだけど。

```php
function getDir($a, $o = 2) {
    $d = Floor($a / $o);
    return ($d % 2 === 0);
}
```

![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26088/6ba6f961-0b3c-39ef-fab5-a3046495debd.png)

んで調べてみたら`getdir`は[dirのエイリアスになってる](https://github.com/php/php-src/blob/4c6533c257cfabd5dd78988bb277f410b2778140/ext/standard/basic_functions.stub.php#L709)みたい。
[リリースノート](https://www.php.net/releases/8.0/en.php)にもエイリアスのこと全く書かれてないんだけど、なにこれ？

## Answer 2

`getdir`は[PHP4時代の非常に古い関数](https://github.com/php/php-src/blob/php-4.4.9/ext/standard/basic_functions.c#L714)なんだけど、最近仕様が変わったりしたのかね？

## Answer 4

[バグレポ出した](https://bugs.php.net/bug.php?id=80914)よ。
`getdir`はケースセンシティブだったのがケースインセンシティブになったせいかね？

## Answer 5

↑ちょっと待った、ケースセンシティブは関係ないんだ。
`getdir()`関数は[これまでずっと存在していなかった](https://3v4l.org/dCpeh)んだ。
でもソース中にはずっと存在していたんだ。
何か深刻なことが起こっているにちがいないぞ。


# [PHPメーリングリスト](https://externals.io/message/113982)

## Rowan Tommins

Stack Overflowの質問[https://stackoverflow.com/q/66854655/157957](https://stackoverflow.com/q/66854655/157957)およびそれに伴うバグレポート[https://bugs.php.net/bug.php?id=80914](https://bugs.php.net/bug.php?id=80914)において、不可解な現象が発生しました。
PHP8.0において、`dir()`関数の別名として`getdir()`が誤って追加されました。

実際はもっと奇妙なことになっています。
本当は`getdir()`が正しい関数名で、`dir()`はそのエイリアスです。
しかし、PHP7.4までは[エイリアスの方の関数しか存在しませんでした](https://3v4l.org/ZHJ9U)。

PHP8.0においては`getdir()`は呼び出し可能な関数であり、そしてユーザが同名の関数を定義することはできません。

これは以下が原因だと思われます。

まず、`dir()`はPHP3から存在する関数であり、それはコンストラクタを使わないおかしなオブジェクトを生成します。

`{"dir", php3_getdir, NULL},`

PHPの関数名がCの関数名と一致しないため、[PHP4のエイリアス機能](c0dce0196b5ca9209a54f534c#diff-a6738c9e7e606e49fc4e7225c281deca86191ada31a5dc077169418541541d1cL59)によって以下に置き換えられます。

`PHP_FALIAS(dir, getdir, NULL)`

しかし、これは実際にはエイリアスではありませんでした。
`PHP_FE`マクロに`getdir`が登録されていなかったためです。
そのため、コードで実際に使用できる関数名は`dir`だけでした。

この状況は、[PHP8でarginfoが追加される](https://github.com/php/php-src/commit/736b22dc0b2fc36e9bd87f2ee5af8c4b2be9fd3d#diff-96c05a0551ccbeca3ff610c111f88b54a0d727888cf353f477ea8dc951a18637R723)まで続きました。
Matéは`getdir()`にスタブが無いことに気が付き、それを追加してくれました。

そして20年の時を経て、ついに`getdir()`に関数エントリが追加されたのです。

```c
    ZEND_FE(getdir, arginfo_getdir)
    ZEND_FALIAS(dir, getdir, arginfo_dir)
```

問題は、これをバグとみなして元に戻すべきかということです。
答え合わせはおそらく20年前に行われるべきだったもので、公開されている関数名に合わせて内部名を変更すべきでしょう。

## Sara Golemon

PHP_NAMED_FEってマクロは当時も存在してたのに、Zeevはどうしてそのマクロを使わなかったのでしょう。
1999年当時はZend Engine1の開発真っ最中だったからてんやわんやだったのかな。

私なら、この文書化されていない関数は、PHP8.0.0から8.0.3までに存在していたバグとして葬ります。

## Rowan Tommins

異議はなかったので、[プルリクエストを提出](https://github.com/php/php-src/pull/6855)しました。
`getdir()`を削除し、`dir()`関数の内部名を`dir`にします。

# 感想

C素人なのでPHPのソース読むのつらい。

PHPの関数は、まず関数を定義して、その情報を別途インデックスに登録することで使用可能になります。
`getdir()`関数は、定義自体はずっと前から存在し、むしろ`dir()`が`getdir()`へのエイリアスという構造でした。
しかし、`getdir()`関数そのものはインデックスに登録されていなかったので、これまでずっと使えない状態でした。
PHP8実装に伴い気を利かせてソースを整理したら、その前世紀の遺物が意図せず現出してきたということです。

閉ざされていた古代遺跡が復活した感ありますね。
C# Ben.Demystifier でスタックトレースを読みやすくする

# このドキュメントの内容

例外のスタックトレースを読みやすく整形してくれるライブラリ `Ben.Demystifier` の紹介です。

近年 C# の機能は大きく進化し、async, LINQ, イテレータなどコーディングスタイルも変わってきています。それに伴い、スタックトレースが人間には読みづらい内容になることも多いです。そのような場面で便利なライブラリです。

https://github.com/benaadams/Ben.Demystifier

# 実行サンプル

## ソースコード

Exception に対する拡張メソッド Demystify を呼び出し、整形されたスタックトレースを出力します。

```c#
using System.Diagnostics;

private async void button1_Click(object sender, EventArgs e)
{
    try
    {
        await RunAsync().ConfigureAwait(false);
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine("----- StackTrace -----");
        System.Diagnostics.Debug.WriteLine(ex.StackTrace);

        System.Diagnostics.Debug.WriteLine("----- Demystify -----");
        System.Diagnostics.Debug.WriteLine(ex.Demystify());
    }
}

private Task RunAsync()
{
    // ローカル関数を介して処理を実行する
    Task RunTasks<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3)
    {
        // 例外をキャッチしてスローしなおす
        try
        {
            return Task.WhenAll(Execute001Async(arg1), Execute002Async(arg2, arg3));
        }
        catch (Exception ex)
        {
            throw new Exception("処理中に例外が発生しました。", ex);
        }
    }
    return RunTasks("abc", 1, DateTime.Now);
}

private Task Execute001Async<T>(T arg)
{
    return Task.CompletedTask;
}

private Task Execute002Async<T1, T2>(T1 arg1, T2 arg2)
{
    int[] values = new[] { 1, 2, 3, 0 };

    // ここでゼロ除算例外がスローされる
    foreach (var result in values.Select(x => 10 / x))
    {
    }

    return Task.CompletedTask;
}
```

## 出力結果

```console:Exception.StackTrace
   場所 WindowsFormsApp1.Form1.<RunAsync>g__RunTasks|2_0[T1,T2,T3](T1 arg1, T2 arg2, T3 arg3) 場所 E:\Source\Work\DemystifierSample\WindowsFormsApp1\Form1.cs:行 47
   場所 WindowsFormsApp1.Form1.RunAsync() 場所 E:\Source\Work\DemystifierSample\WindowsFormsApp1\Form1.cs:行 51
   場所 WindowsFormsApp1.Form1.<button1_Click>d__1.MoveNext() 場所 E:\Source\Work\DemystifierSample\WindowsFormsApp1\Form1.cs:行 25
```

* ローカル関数や LINQ 式がリーダブルな形式で展開されています。
* 内部例外が格納されている場合、内部例外も出力されています。

```console:Exception.Demystify()
System.Exception: 処理中に例外が発生しました。 ---> System.DivideByZeroException: 0 で除算しようとしました。
   at Task WindowsFormsApp1.Form1.Execute002Async<T1, T2>(T1 arg1, T2 arg2)+(int x) => { } in E:/Source/Work/DemystifierSample/WindowsFormsApp1/Form1.cs:line 64
   at bool System.Linq.Enumerable+WhereSelectArrayIterator<TSource, TResult>.MoveNext()
   at Task WindowsFormsApp1.Form1.Execute002Async<T1, T2>(T1 arg1, T2 arg2) in E:/Source/Work/DemystifierSample/WindowsFormsApp1/Form1.cs:line 64
   at Task WindowsFormsApp1.Form1.RunAsync()+RunTasks(T1 arg1, T2 arg2, T3 arg3) in E:/Source/Work/DemystifierSample/WindowsFormsApp1/Form1.cs:line 43
   --- 内部例外スタック トレースの終わり ---
   at Task WindowsFormsApp1.Form1.RunAsync()+RunTasks(T1 arg1, T2 arg2, T3 arg3) in E:/Source/Work/DemystifierSample/WindowsFormsApp1/Form1.cs:line 47
   at Task WindowsFormsApp1.Form1.RunAsync() in E:/Source/Work/DemystifierSample/WindowsFormsApp1/Form1.cs:line 51
   at async void WindowsFormsApp1.Form1.button1_Click(object sender, EventArgs e) in E:/Source/Work/DemystifierSample/WindowsFormsApp1/Form1.cs:line 25
```
railsの仕組み

こんばんは、taroです！

今日は自分用のメモとしてrailsのアウトプットをしていきます。

まずrailsには親玉としてapp/というディレクトリが存在します。
そして、その子分としてmodels」「views」「controllers」
という3つのサブディレクトリがいます。

ブラウザがRailsアプリと通信するとき、Webサーバーにリクエストを送ります。
リクエストはコントローラに渡されます。（そこでリクエストを処理。）
コントローラは、ビューを作ってHTMLをブラウザに送ります。

以上になります。
Webブラウザの基礎知識

## Cookie
CookieとはWebサイトへの訪問者の情報を一時的に保存する仕組みであり、それぞれのユーザーの識別を目的としている。
Webサーバーからユーザーが使用しているブラウザに送られる、ユーザーのデータを保存しておくためのファイル。
再訪問した際にCookieデータを使用して閲覧履歴を確認できたり、ログインが簡単になる。
Cookieはサイトごとではなく、ブラウザごとに保存されるので、最初Chromeでアクセスしても、次回異なるブラウザでアクセスした際には別のCookieが保存されることになる。
ブラウザ及びデバイスをまたいでCookieを保存することはできない。

## セッション
ユーザーがWebサイトへアクセスしてそのサイトから出て行くかブラウザを閉じるまでの一連の通信のこと。

## キャッシュ
Webページの情報を一時的に保存する仕組みのことで、よく訪問するぺーじの表示スピードが上がるというメリットがある。
ページを表示する際には、そのページのデータをダウンロードする必要があるが、画像やテキスト情報のキャッシュがブラウザに保存されることによって表示スピードが速くなる。
サイトの見た目などが変更された場合キャッシュ情報を更新（スーパーリロード）する必要がある


## HTTPリクエスト
- HTTPリクエスト行
    - HTTPメソッド
        - GET	指定したターゲットをサーバから取り出す
        - HEAD	指定したターゲットに関連するヘッダー情報を取り出す
        - POST	指定したターゲット（プログラム）にデータを送る
        - PUT	サーバ内のファイルを書き込む
        - DELETE	サーバ内のファイルを削除する
        - CONNECT	プロキシサーバ経由で通信を行う
    - データ本体（サーバーに対してデータを送信する場合 POSTなど）
- HTTPヘッダー
    - ユーザーエージェント
        - ブラウザの種類やOSの情報
    - リファラ
        - どのページから発生したリクエストなのか示す
    - Cookie

## HTTPレスポンス
- HTTPレスポンス行
    - ステータスコード
        - 200番台は成功
            - 200：OK、データを送ります
        - 300番台はリダイレクト
            - 301：新しい場所から取得してください（今後もずっと）
            - 302：新しい場所から取得してください（今回だけ）
            - 304：変更されていません（データ本体は送られない）
        - 400番台はクライアント側のエラー
            - 401：ユーザー認証が必要です
            - 403：アクセスが禁止されています
            - 404：見つかりませんでした
        - 500番台はサーバー側のエラー
            - 500：内部エラー
            - 503：現在はサービス提供不可能
- HTTPヘッダー
    - コンテントタイプ
        - データ本体の前に送られるデータの状態を示すデータがHTMLなのか、JSON形式なのかを示す。
        - キャッシュ制御
            - ブラウザや通信を橋渡しするプロキシが、データをのキャッシュをどう扱うかの情報


本当に基礎の基礎ですが、改めて振り返ってみてブラウザの知識が深まりました。
【Python】pandasというライブラリを使ってCSVファイルを読み込み、積上げ棒グラフを作成する。

pythonを使用してExcelファイルの操作を勉強しています。
本日の気づき(復習)は、CSVの読み込みとグラフ作成に関しての続きです。
pythonでExcelを操作するため、openpyxlというパッケージを使用しています。

```csvs:売上.csv
部門,１月,２月,３月
商品A,600,700,800
商品B,4100,3800,4500
商品C,2900,1800,3000
商品D,800,900,1000
商品E,600,550,720
```

前回同様、上記のようなCSVファイルを読み込み

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927441/5e437627-d794-1fa0-5483-e4dfaae394ac.png)


この様な積上げ棒グラフを作り貼り付けたいです。

# BarChartオブジェクトのgrouping属性と、overlap属性

```python
bar.grouping = 'stacked'
bar.overlap = 100
```

基本的には棒グラフを作成する場合と同じですが
grouping属性を'stacked'、overlap属性を 100
にすれば、積上げ棒グラフになるのですが
今回の表はもう一工夫必要です。

# グラフの参照データを、行/列で切り替え

```python
bar.add_data(Referenceオブジェクト, from_rows=True, titles_from_data=True)
```

先ずは、元となるデータの範囲を変更して
上記のように「from_rows=True」を記述すると
グラフの参照データを、行/列で切り替える事が出来ます。

# 最終的なコード

```python
import pandas as pd
from openpyxl import Workbook
from openpyxl.chart import BarChart, Reference
from openpyxl.utils.dataframe import dataframe_to_rows

wb = Workbook()
ws = wb.active

# CSVファイル読込み
df = pd.read_csv('売上.csv', encoding='utf-8')
for row in dataframe_to_rows(df, index=None, header=True):
    # データを１行ずつ追加
    ws.append(row)

# 棒グラフを選択
bar = BarChart()

# 横棒グラフに設定
bar.type = 'col'

# 積上げ棒グラフに変更
bar.grouping = 'stacked'
bar.overlap = 100

# グラフのデータ範囲を設定
data = Reference(ws, min_col=1, min_row=2,
                 max_col=ws.max_column, max_row=ws.max_row)

# ラベルの範囲を設定
labels = Reference(ws, min_col=2, min_row=1, max_col=ws.max_column)

# グラフにデータを追加(参照方法を行列で切り替え)
bar.add_data(data, from_rows=True, titles_from_data=True)

# 縦軸のラベルを追加
bar.set_categories(labels)

# 系列ごとにグラフの色を変更
bar.varyColors = True

# 凡例項目の位置を設定
bar.legend.position = 'b'

# 横軸(グラフ上では縦軸)タイトルを追加
bar.x_axis.title = '月度'

# 縦軸(グラフ上では横軸)タイトルを追加
bar.y_axis.title = '売上高(千円)'

# グラフのタイトルを追加
bar.title = '部門別売上高'

# 棒グラフをシートに追加
ws.add_chart(bar, 'A9')

wb.save('部門別売上_積上げ棒グラフ.xlsx')
```

前回、前々回と同じデータを基にグラフを作っていますが
表現方法でだいぶ印象が変わりますね。

どこで使うモノなのかを考えながら作成するといい感じですね。
Siderで解析ツールのエラーが出てるのにIssueにならずにコメントが付かない

# 解決したいこと
既存のRailsアプリにHaml Lintを入れてプルリクエスト時にSiderでチェックしてもらおうとしました。
ローカルでもSider内のログでも、Linterのエラーが出てるのに、プルリクエストにSiderからのコメントが付かなかったのです。

# 結論
Siderは変更分しか解析してくれない。

例えば、既存のアプリがLinterのルール違反を既に持っている状態で、Linterを導入し、プルリクエストを作成したとします。

このプルリクエストには、ルール違反の記述をもつ変更が含まれないため、Sider的にはIssue扱いにはならず、Greenでパスします。

# 詳細
Siderは以下リポジトリにあるSider Runnersという仕組みで解析が行われてます。
https://github.com/sider/runners

大枠として、以下の流れで解析が行われます。
exe/runners
↓
CLI（lib/runners/cli.rb）
↓
lib/runners/harness.rb
↓
lib/runners/workspace/git.rb
ここで変更内容を取得
https://github.com/sider/runners/blob/master/lib/runners/workspace/git.rb#L89
↓
lib/runners/processor.rb
解析ツールごとのDockerイメージを準備
↓
lib/runners/harness.rb
変更内容を前提に、解析ツールを実行。
https://github.com/sider/runners/blob/0.47.0/lib/runners/harness.rb#L62
↓
lib/runners/result.rb
変更内容で結果をフィルタリング
https://github.com/sider/runners/blob/master/lib/runners/harness.rb#L71
バッチファイルの遅延環境変数（簡単な例）

Y子です。

昨日は __[大長編](https://qiita.com/koiwaiwaiko/items/9013f98eeccbc5a43e14 "バッチファイルのif文やfor文の中で、変数の値がおかしい問題")__ を書いてしまったので、簡潔スッキリ版も書いてみます。内容はだいたい同じです。

https://qiita.com/koiwaiwaiko/items/9013f98eeccbc5a43e14

# 概要
「環境遅延変数」を使うべき例と、使い方をご紹介します。
うまく使わないと、`if`文や`for`文の変数の値が、期待通りになりません。

# コード
## よくある失敗例
「`str_a`に`bbb`を格納したが、`echo`で出力したら`bbb`にならないことがある」という例です。
（１）～（６）の順に、説明をお読みください。

```bat:delayedexpansion_sample_ng.bat
@echo off
set str_a=aaa
if 1==1 (　　　　　　　（１）if文中の %a% 形式の変数の値は、if文に入った時点の値に固定されるので、
  set str_a=bbb　　　 （４）ここで格納した「bbb」が %str_a% で取得できるのは、if文を出た後です。
  echo %str_a%　　　　（２）ここ（if文中）の %str_a% の値は、（１）時点の「aaa」です。
)
echo %str_a%　　　　　（５）if文を出た後なので、（４）で格納した「bbb」が取得できます。
```

```:実行結果
aaa　　　　　　　　　　（３）「aaa」です。　……（２）で書いた通り
bbb　　　　　　　　　　（６）「bbb」です。　……（５）で書いた通り
```
`if`文を例にしましたが、`for`文でも同じことが起きます。

## 改善例
前項から2か所修正しました。
・最初に`setlocal enabledelayedexpansion`宣言を追加
・`echo`出力に`!str_a!`を追加
（１）～（７）の順に、説明をお読みください。


```bat:delayedexpansion_sample_ok.bat
@echo off

rem 遅延環境変数の展開を有効にする
setlocal enabledelayedexpansion　（１）これを書くと、 !a! 形式の変数が使えるようになります。

set str_a=aaa
if 1==1 (　　　　　　　　 （２）if文に入ると、 %str_a% は固定ですが、 !str_a! は格納した値。
  set str_a=bbb　　　　　（３）%str_a% は「aaa」のままですが、!str_a! は「bbb」に変わります。
  echo %str_a% !str_a!　（４）if文中なので、%str_a%は（２）時点の値、!str_a!は（３）で格納した値。
)
echo %str_a% !str_a!　　（６）if文を出た後なので、（３）で格納した「bbb」が %str_a% でも取得できます。
```

```:実行結果
aaa bbb　　　　　　　　　（５）「aaa bbb」です。　……（３）（４）で書いた通り
bbb bbb　　　　　　　　　（７）「bbb bbb」です。　……（６）で書いた通り
```

`if`文を例にしましたが、`for`文でも同じ対策が有効です。

# おわりに
遅延環境変数を、なるべく少ない文章量で説明してみました。
わかりやすくなってるとよいのですが。


ではまた！
【ActiveStorage】アソシエーションを組んでいるのに画像が表示されない。

こんにちは、プログラミング初学者のkoheiです。

今日は

## Active Storageをインストールし、アソシエーションを組んでいるのに画像が表示されない。
ということがありました。

ビューファイルを制作するためにtestで１つだけレコードを作成。
Active Storageで画像は保存できています。
それなのにimage_tagで画像を呼び出せませんでした。

結論から言うと、
変数に代入したパラメーターへの認識の甘さが原因でした。

今回登場するのは"parts"コントローラーとビューのみです。

まず
partsコントローラーにて

```ruby
def index
    @parts = Part.all
end
```

ビューファイルにて

```
 <%= image_tag @parts.image if @parts.image.attached? %>
```

と記述しました。
するとNoMethodErrorがでます。
上記で既に間違っているので、慣れている方は普通に気付くんだと思います。

しかし、初心者の私は焦ります。笑

エラー文に
undefined method `image' for #<Part::ActiveRecord_Relation:0x00007f8566f76140>
とあったため

@partsのパラメーターを確認したところ、
imageが含まれていないじゃないか！　ということでモデルからマイグレーションファイルまで覗き始めました。笑
↑ちなみに含まれてないことは問題ではありませんでした！

色々探して最終的に間違いはコントローラーにあることに気づきます。
以下のように記述すべきでした。

```ruby
 def index
    @parts = find(2)  
 end
```

Part.allがダメだった理由としては
allとすることで＠partsに代入される値が**ハッシュ構造**となってしまうためです
確認するとパラメーターは以下の様になっていました。

```ruby
@parts
=> [#<Part:0x00007fb31f995b90
  id: 2,
  name: "test",
  info: "test"]
```
Part.find(2)だと以下の様になります。

```ruby
@parts
=> #<Part:0x00007fb31ffc6758
 id: 2,
 name: "test",
 info: "test"
```


アプリとしてはpartsを一覧表示させたいので
最終的にはPart.allとeach文で進めていきます。

とにかく、allの中身が１つでも配列で出力されるということが分かり、自分としてはとても勉強になりました。
同じく初心者の方はお気をつけ下さい。
[PHP] NULLか、それ以外か

#概要
PHPでNULLかそれ以外かを判定するための方法をメモします。


#方法

* NULLの場合は`NULL`を返す
* NULL以外の場合は`それ以外`を返す


```.php
<?php
$hoge = null;

if(is_null($hoge)){
    echo 'NULL';
}else{
    echo 'それ以外';
}
```

変数が未定義の場合もNULLになります。
【Twitter API】アプリからツイートした時アプリ名を表示させる方法（再）

前にTwitterAPIのアプリ名を表示させる方法の記事を投稿したのですが、誤りがあったので再投稿します。

<h3>1.<a href="https://developer.twitter.com/en/portal/dashboard">Twitter Developers</a>で自分のアプリにアクセスする。</h3>
![quiitascreenshot1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1086026/5dc71131-5e7b-70ce-9461-a8db373437ea.png)

Dashboardを展開するとこんな感じになって自分のアプリがあるはず。

<h3>2.Settingsタブを表示した状態で下にスクロールし、<br>Authentication settingsを見つける。</h3>

![quiitascreenshot2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1086026/eabbbc6c-739b-1daf-2d67-eafbfff19c16.png)
こんな感じのやつ。

<h3>3."3-legged OAuth is disabled"の "disabled" を "enabled"にする。</h3>
![quiitascreenshot3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1086026/08b0b88f-57cc-5c6e-7381-f5c18a2810f5.png)
ここ。


<h3>4.変更を保存し、ちゃんと変わっていることを確認する。</h3>
![quiitascreenshot4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1086026/4f8b7d32-e2de-97b6-f18c-1463dadf5680.png)
こうなっていればOK。

<h3>5.しばらく待った後、試しにそのアプリからツイートし、アプリ名が表示されていればOK。</h3>

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">TwitterAPIからのツイート</p>&mdash; カラボン.jpeg🤔💥🐟 (@Columba_Karasu) <a href="https://twitter.com/Columba_Karasu/status/1381536476710625283?ref_src=twsrc%5Etfw">April 12, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

disabledだと表示されないので注意。

<h2>※注意
・一度enabledにしたアプリは戻せないので気を付けてください。
Gtk-WARNING**(Theme parsing error)を消す

こんにちは, 初投稿です.
拙い文章かもしれませんが, 参考にしていただけると幸いです.

#はじめに
ubuntuのtweaksで外観をMacBuntuにしたあと, ターミナルでなにかを開こうとするとGtk-Warningとでるようになりました. 今まで特に害はなかったので放置し続けましたが, 正直毎回でてくるのがうざいなと思い始め, 解消しようと決意しました.

![terminal.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399333/42b86683-e8ee-ffb5-73c5-ff2bd41b180e.png)

#Warningの解消
##Warning文の意味
```Missing opening bracket in color definition```
をグーグル翻訳になげると,
```色の定義に開き角かっこがありません```
と返ってきます. :thinking:
正直何言ってるんだろうって気持ちです.
そこでコードを見てみることにしました.

##Warning箇所のコード
コードの場所は
```/usr/share/themes/{tweaksのアプリケーション名}/gtk-3.0/gtk.css```です.
(フォルダーによって異なるかもしれません)
![Screenshot from 2021-04-12 18-29-43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399333/dca4b906-f84e-b75f-1f20-f8611a9e3297.png)

コードのWarning箇所はこちらの３つです. 
![Screenshot from 2021-04-12 18-40-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399333/61666566-77cb-3a20-d440-9127c3c39fcc.png)


つまりこの書き方が悪いのかな？
ってことで周りの文を真似して書き換えます.

\#000がRGBで, 0.3や0.6が透明度(alpha)かなと考えて
```0 0 2px alpha #000, 0.3, 0 1px 2px alpha #000, 0.6```
から
```0 0 2px rgba(0, 0, 0, 0.3), 0 1px 2px rgba(0, 0, 0, 0.6)```
に3箇所とも変換します.

その結果, 
![result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399333/5405e4d7-e25b-a56d-b749-0df6242c7292.png)
無事, Warningを解消することが出来ました:clap:

#まとめ
やっぱりWarningが出ていると気になるので早めに解消しよう！
ただ, それぞれの値が示す意味はわかっていないので注意が必要です!!
(自己責任でお願いします)

#参考資料
https://developer.gnome.org/gtk3/stable/chap-css-properties.html
https://www.x68k.org/2017/10/crunchbangpp-avoid-gtk-warning/
URLSchemeのインテントをadbで実行する時に複数パラメータを渡す方法

adbでURLScheme起動する際、複数のパラメータを渡す必要があって困ったのでメモ

###adbでURLScheme起動を行う方法

```
adb shell am start -a android.intent.action.VIEW -d "{URL}"
```

###URLSchemeにパラメータを1つ渡す方法

```
adb shell am start -a android.intent.action.VIEW -d "{URL}?{KEY}={VALUE}"
```

###URLSchemeにパラメータを複数渡す方法

```
adb shell am start -a android.intent.action.VIEW -d "{URL}?{KEY}={VALUE}\&{KEY}={VALUE}"
```

```
adb shell am start -a android.intent.action.VIEW -d '"{URL}?{KEY}={VALUE}&{KEY}={VALUE}"'
```
FastAPI/SQLAlchemy初心者が1日で理解したこと(1週間だけ頑張る Day3of9)

# はじめに
1週間N(E)ETになった社会人の学習記録です。
今日はCRUDのサンプルを写経し、使い方を覚えます。
私のレベルは、「RailsのTutorialはやったことある。Rails3が主流なときにRails2の改修をやらされて、情報が全然なくてトラウマになっている。」です。

|使用技術   |私の状況                                                   |
|----------|-----------------------------------------------------------|
|python    |読み書きできなくはないが、自分で一から書くならrubyを選ぶ        |
|SQLAlchemy|完全に初見。RailsのActiveRecordは触ったことある。             |
|FastAPI   |完全に初見。RailsのapiモードでHello Worldを書いたことある程度。|

前日の記事（Dockerの学習）ではPostgreSQLのデータの永続化はできていないが、とりあえず先に進む。

https://qiita.com/tagawa0525/items/f9f89fe82ed4e16fea45


# CRUDの写経
Google先生に教えてもらった記事から、分かりやすそうなページを参考に写経する。

https://qiita.com/t-iguchi/items/d01b24fed05db43fd0b8

## 変更箇所

https://github.com/tagawa0525/prac/commit/b54865ba9a6038ff72cc5c5d843f8d6926101d4e?branch=b54865ba9a6038ff72cc5c5d843f8d6926101d4e&diff=split#diff-a465a15e2c3aefb20d5a02ff4e2dc9963853e60d215dadc872699a4d36ab914c

環境依存の所だけ自分の環境に合わせて適切に変更

|値      |旧        |新          |理由      |
|--------|----------|-----------|----------|
|DATABASE|postgresql|同左       |           |
|USER    |testuser  |postgres   |Dockerイメージのデフォルト|
|PASSWORD|secret    |p@assw0rd  |お好み設定 |
|HOST    |localhost |db         |docker-compose.ymlのservices内の名前がhost名になる[^1]|
|PORT    |5432      |同左       |          |
|DB_NAME |test_db   |document_db|お好み設定 |

[^1]: https://qiita.com/dyoshikawa/items/05d627b962da35f7d5b6

## Dockerfileの編集

https://github.com/tagawa0525/prac/commit/b54865ba9a6038ff72cc5c5d843f8d6926101d4e?branch=b54865ba9a6038ff72cc5c5d843f8d6926101d4e&diff=split#diff-b7e4331ba50d315e3c8748abd909eb8b1a593e8bf345cafa63e697dbb0e42618

SQLAlchemyに必要なパッケージとして以下追加する。
怒られたのでとりあえず入れた感じ。
Railsのように最初にドカッと入るよりは自分で選択して入れるほうが学習にはよさげ。

|管理|名前      |備考|
|---|----------|-|
|pip|sqlalchemy|今回使いたいやつ|
|pip|psycopg2-bynary|PostgresSQL用のpthonライブラリ<br>libpq5必要|
|pip|databases|非同期用のライブラリ？<br>後で調べるかも|
|apt|libpq5|PostgresSQL用のCライブラリ|

## 所感
とりあえず、コピペしただけだけど動いてなにより。
次回は、今回作ったFastAPIに対して、Reactを通じてCRUDできることを目標にします。

## 免責事項（言い訳）
上記の技術については初心者なので、あてにしないように!!!

# 今後の予定のための参考
## 多対多
このまどろっこしさは解消されないんですかね。

https://muoilog.xyz/web-development/sqlalchemy-many-to-many-save/

## Word
「python-docx」は使ったことあるので、たぶん行ける。
ちなみにExcelは「openpyxl」を使い、pdfは「pyPDF2」と「reportlab」を使い分ける。

https://gammasoft.jp/support/how-to-use-python-docx-for-word-file/

## E-Mail
とりあえずGoogle先生から以下を教えてもらったが、テストメールを準備するのがだるいので、ここには書かないかも。

https://pypi.org/project/fastapi-mail/
古いAndroidスマホ/タブレットで、GeforceNowを使ってAPEXがプレイできるのかを検証してみた

【本記事のテーマ】
FPSゲームで人気のAPEXを、古い型落ちAndroidタブレットでプレイできないか検証してみた。

【用意したモノ】
・[GeforceNow](https://cloudgaming.mb.softbank.jp/)アカウント（月額2000円弱）
・ホリ製のUSB接続ゲームパッド（3500円程度）
　[HORI ホリ ホリパッド for Nintendo Switch スーパーマリオ NSW-188](
https://www.amazon.co.jp/%E3%80%90%E4%BB%BB%E5%A4%A9%E5%A0%82%E3%83%A9%E3%82%A4%E3%82%BB%E3%83%B3%E3%82%B9%E5%95%86%E5%93%81%E3%80%91%E3%83%9B%E3%83%AA%E3%83%91%E3%83%83%E3%83%89-Nintendo-Switch-%E3%82%B9%E3%83%BC%E3%83%91%E3%83%BC%E3%83%9E%E3%83%AA%E3%82%AA%E3%80%90Nintendo-Switch%E5%AF%BE%E5%BF%9C%E3%80%91/dp/B07SPRDL89)
・ファーウェイ製のAndroidタブレット
　Huawei MediaPad T2 Pro 606HW
・OTGケーブル(700円程度）
[【2個入り】NIMASO USB C 変換 アダプタ ( Type C - USB 3.0 メス ) 20CM OTGケーブル タイプC 変換コネクター](
https://www.amazon.co.jp/gp/product/B07TJ38SDW/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1)

【筆者の概況】
筆者はAPEX歴３ヶ月のペーペーど素人。シルバーランクからゴールドに上がれないでもがき苦しんでいる。
以前いた職場の同期から、APEXを一緒にやろうとゴリ押しされ、始めようとする。
しかし、直近は仮想通貨マイニングの影響でグラボが高騰しており、お金のない私はゲーミングPCを用意できなかった。
仕方がないのでGeforceNowでひとまず凌ぎ、お金に余裕ができたらゲーミングPCを買うことにした。

【構築環境の様子画像】

【プレイしてみた結果】

【】
HerokuからAWSに移行後のActionCableの設定方法

#概要
本日、本番環境をHerokuからAWSに移行後、ブラウザ上で動作を確認したら、コメント機能の非同期通信で実装した所がうまく動作をしなかったので解決策をシェアしたいと思います。

#起きていたこと
Herokuでのデプロイ時とAWSでのデプロイ時でのproduction.rbの記述方法が異なる。

###Herokuでの場合
##
```production.rb
ActionCable.server.config.disable_request_forgery_protection = true
  config.action_cable.url = "wss://【Herokuアプリ名】.herokuapp.com/cable" 
  config.action_cable.allowed_request_origins = ['https://【Herokuアプリ名】.herokuapp.com', 'http://【Herokuアプリ名】.herokuapp.com'
```

###AWSでの場合
```production.rb
ActionCable.server.config.disable_request_forgery_protection = true
  config.action_cable.url = "ws://【Elastic IP】/cable" 
  config.action_cable.allowed_request_origins = ['http://【Elastic IP】']
```

##上記に加えてAWSの場合必要な対応

```/etc/nginx/conf.d/rails.conf
upstream app_server {
  server unix:/var/www/アプリケーション名/shared/tmp/sockets/unicorn.sock;
}

server {
  listen 80;
  server_name Elastic IP;

  root /var/www/アプリケーション名/current/public;

  location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
    root   /var/www/アプリケーション名/current/public;
  }

  try_files $uri/index.html $uri @unicorn;

  location @unicorn {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://app_server;
  }
# -------------------ここから-------------------
# /cableのパスに対してwebsocketの仕組みを用いるための設定
  location /cable {
    proxy_pass http://app_server/cable;
    proxy_http_version 1.1;
    proxy_set_header Upgrade websocket;
    proxy_set_header Connection Upgrade;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
# -------------------ここまでを追記-------------------
  error_page 500 502 503 504 /500.html;
```

#まとめ
今回の件ではAWSの場合だとWebサーバーとしてNginxを用意していたので、ActionCableを用いる場合、サーバーサイドへのリクエストを受け取る役目のあるWebサーバーにて、websocketの仕組みを用いるための設定をする必要があることを認識することが出来ました。
[Swift] クロージャとコールバック関数とは　分かりやすく解説

<h1>クロージャとコールバック関数について<h1>

Firebaseのユーザー登録のソースコードを読んでいて思った事がある。
それがここ。

```swift
Auth.auth().createUser(withEmail: email, password: password) { (res, err) in
     if let err = err {
           print("Auth情報の保存に失敗しました。\(err)")
           return
     }
```

まさにここで使われている構文の書き方がクロージャとコールバック関数を使っている。
つまり、この構文を理解するにはその２つを知る必要がある。

<h2>クロージャとは<h2>

**クロージャとは一言で言えば変数や処理を一つの{}で囲んだまとまり**

**クロージャの基本構文**

```swift
{(引数名1: 型, 引数名2: 型...) -> 戻り値の型 in
  クロージャの実行時に実行される文
  必要に応じてreturn文で戻り値を返却する
}
```

クロージャを実際に使ったプログラム

```swift
let double = { (x: Int) -> Int in
  x * 2
}
double(2)

//実行結果
4
```

クロージャは変数に入れることもできる。変数に入れられるのならそれを関数の引数にも渡すことも可能。
入れなくても直がきで渡せるけど。

こんな感じ

```swift
import UIKit

//乗算関数
let multi = {(x:Int,y:Int) -> (Int) in
    return x*y
}

//出力関数
func test(multifunc:(Int,Int) -> Int, b:Int, c:Int){
    let result = multifunc(b,c)
    print(result)
}


test(multifunc: multi,b: 5,c: 3)

//実行結果
15
```

コードを見ると
test関数の引数としてmulti変数（中身はクロージャ）が渡されている。
このような感じで関数を渡す事ができる。


<h2>コールバック関数とは<h2>

コールバック関数とは一言で言えば
**関数の呼び出し先から、呼び出しもとの関数を呼び出すこと（ややこしい）**

これはコードを見ればすぐに理解できるはず。

```swift
import UIKit

func test(x:Int,y:Int,callback:(String,Bool) ->()){

    if(x+y > 10){
        callback("二つの数字を足した結果は5より大きいです",true)
    }else{
        callback("二つの数字を足した結果は5より小さいため処理を中断します。",false)
        return
    }
    print("最後まで処理が実行されました。")  
}

test(x:4,y:6){(result,flag) in
    
    if(flag){
        print(result)
    }else{
        print(result)
    }
    return
}
```
これはコールバック関数で10未満の数字が入力されると処理が中断される。
実際この程度のプログラムならコールバック関数など描かなくてもいい、、、
じゃあどういった時に使うのかというと、ユーザーの認証情報を登録するときに
パスワードは何桁以上と言う制約を儲けたときに、登録情報にエラーが発生したとして
コールバック関数にエラー情報をのせて呼び出しもとに処理を移行させるとおいう使い方がある。
それがFirebaseで使われる。
createuser関数であり、エラーが発生すればその情報を取り扱う事ができるし、エラーではなく登録に成功すればresultと言う引数を受け取る事ができる。

以下がシンプル化したコールバック関数の認証情報登録のコード

```swift
//登録ユーザー情報
let name = "Matchan"
let password = "aiuio"


test(name: name, password: password){(err,res) in
    
    if let err = err {
        print(err)
        return
    }
    //オプショナル型のnilチェック
    guard let result = res else {
        return
    }
    print(result)

//登録が成功した後の処理を書く
    
}
//クロージャとコールバック関数を使った関数test
func test(name: String, password: String, callback:(String?,String?) -> ()){
    
    if(password.count<7){
        callback("パスワードが６文字以下のためセキュリティ上登録できません",nil)
        return
    }else
    {
        callback(nil, "認証情報の登録が成功しました")
    }
    
}
```

認証情報にエラーがあれば、
if let err = err {
        print(err)
        return
    }
エラー出力されて処理が中断される、処理が成功ならその後の処理が継続して行われる。
Service Cloud の効率性 ⇒ Field Service によるパーソナライズされたオンサイトサービスの実施

１．派遣作業員がサービスにおいて主要なタッチポイントである理由は次のどれですか?
２．Field Service は、派遣作業員の協業形態をどのように変えてくれますか?
３．フィールドサービスマネージャの最優先事項はどれですか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/51df189b-7772-a06e-1476-549d9a16e518.png)
MariaDB 5.5 で UTF8MB4 な Database をインポートする時にハマったメモ


とある本番サーバーが MariaDB5.5 という古いサーバーであったため、Concrete CMS (concrete5) の utf8mb4 なデータベースのSQL Dump をインポートしようとしても、

```
The database does not support index fields with a length up to 255 characters when using the collation utf8mb4.
```

とエラーが出てmysql インポートできませんでした。

MariaDB 5.5 や MySQL 5.5 から、MariaDB 10.5 や MySQL 5.7 ぐらいにアップグレードして欲しいものの、もしも MariaDB5.5 なのをどうしても使わないといけない時に行った対処方法です。

## STEP1: MySQL で utf8mb4 を使えるようにする

InnoDB でもろもろ必要な設定を適用させる。
今回、MariaDB/MySQL の root 権限はあるけれど、サーバーの sudo や root 権限がなくて my.cnf は書き換えできなかった場合です。

```
SHOW GLOBAL VARIABLES LIKE '%innodb_file_%';
SET GLOBAL innodb_default_row_format = dynamic;
SET GLOBAL innodb_file_per_table = on;
SET GLOBAL innodb_large_prefix = `ON`;
SET GLOBAL innodb_file_format = `Barracuda`;
SET GLOBAL innodb_file_format_max = `Barracuda`;
SHOW GLOBAL VARIABLES LIKE '%innodb_file_%';
```

my.cnf で設定して MySQL を再起動したらOKという方法はたくさんあるので・・・。


## STEP2: SQL Dump を書き換え

なぜか、サーバー側の設定を変えても、SQL Dump のテーブル構造を宣言するところに `ROW_FORMAT=DYNAMIC` を追加しないと同じエラーが出続けてしまった問題がありました。

なので、

```
ENGINE=InnoDB
```

をテキストで一斉検索して

```
ROW_FORMAT=DYNAMIC ENGINE=InnoDB
```

のようにすることで、SQL Dump のテーブルに全て、ROW_FORMAT=DYNAMIC の宣言を加えられるようになります。

これで、MariaDB 5.5 でも UTF8mb4 なデータベースをインポートすることができました。
もしかすると、MySQL 5.5 でも同じような問題があったら同じ手順で修正してすることも良いかもしれません。
Jenkins Pipeline (Multiple pipeline じゃない方) の注意点

Jenkins 2.235.1 かつ Windows の話。
普段 Multiple pipeline を使用しているのだが、Multiple じゃない方を使ったときに意外と差異が多くて詰まった。
詰まったポイントを書いていく。

# Lightweight checkout
repository clone 時の設定として "Lightweight checkout" という項目がある。デフォルトではチェックが付いているが、このとき Jenkins は Jenkinsfile のみを clone する。よって Jenkinsfile から他の bat 等を叩こうとしても bat は無い。そう言うことがしたい場合はチェックをオフにするか、自前で repository を clone してくる必要がある。
![jenkins.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197400/4fa067c5-5db8-355d-dfe5-f26a0e1bdded.jpeg)

# Declarative と Scripted の clone 先
最初に `pipeline{}` が来るのが Declarative syntax で、最初に `node{} ` が来るのが Scripted syntax。
仮に Job 名を `Jobname` とした場合、Declarative syntax では Jenkins workspace に `Jobname` フォルダが生成されるが、Scripted syntax では `JobName@script` というフォルダが生成される。さらにこの `Jobname@script` フォルダは clone がうまく行われないケースがある（clone 先は `Jobname@script` フォルダなのにカレントディレクトリは `Jobname` フォルダになっていると思われる。あまり検証していない。）
よって Lightweight checkout を Off にする場合は Declarative syntax の方が無難。なお Declarative syntax でも `script {}` を使用した場合は両方のフォルダが生成されるが、この場合は `Jobname@script` の方は使用されないっぽい。

# 使用できる環境変数
Multiple pipeline では `${env.BRANCH_NAME}` といった変数が使用できるが、Pipeline では殆どが使用できない。何が使用できないかは `${YOUR_JENKINS_URL}/pipeline-syntax/globals#env` から確認可能。
![jenkins2.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197400/0cd3913c-7cf4-1a7c-1e5e-0b624865f0fa.jpeg)

参照：https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#using-environment-variables
JQueryでURLパラメータ取得する方法

めもです。

引用元のサイト
https://www-creators.com/archives/4463


```sample.js
    /**
     * Get the URL parameter value
     *
     * @param  name {string} パラメータのキー文字列
     * @return  url {url} 対象のURL文字列（任意）
     */
    function getParam(name, url) {
        if (!url) url = window.location.href;
        name = name.replace(/[\[\]]/g, "\\$&");
        var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
            results = regex.exec(url);
        if (!results) return null;
        if (!results[2]) return '';
        return decodeURIComponent(results[2].replace(/\+/g, " "));
    }
```
一覧プラグインの実装方法

---
### StreamRelay.NET.exe の一覧機能を呼び出しているプラグインの実装方法について説明する

StreamRelay.NET.exe/StreamRelay.NET.x86.exeには、いくつかの機能をプラグインとして実装できるようにインターフェイスを公開している。

今回は、一覧(接続しているマイク一覧とか、インストールされている言語一覧とか・・・)を取得/表示するためのインターフェイスを使って、プラグインを作成する方法を記述する。

---
### 既存のプラグイン

マイクの一覧とか、音声合成する言語の一覧とか、いろいろなところに使われている。

プラグイン的には、このあたり。

- Plugins\Win32\stdioSoundRecordMDX.dll
- Plugins\Win32\stdioSoundRecordSlimDX.x86.dll
- Plugins\Win64\stdioSoundRecordSlimDX.x64.dll
- Plugins\stdioSpeachRecognition.dll

---
### 実装したプラグインの呼び出され方

プラグインで指定された引数が渡されると、一覧を取得して表示する。

という感じ。

---
### 実装するインターフェイス

以下のインターフェイスを継承したクラスを実装すればよい

- IPlugin.dll 中の jp.dip.rocketeer.Plugins.IPluginListing インターフェイス

このクラス一つだけ実装すればよい。

---
### jp.dip.rocketeer.Plugins.IPluginListing インターフェイス

StreamRelay.NET.exeが、引数/オプションの解析処理中に呼び出して、引数の指定内容によって有効化していれば、プロパティ「**CanListing=true**」にして、一覧を取得する。

そうすると、StreamRelay.NET.exeで、いろいろな一覧を表示する際に **String getListingString(String Header)** が呼び出される。

という感じ。

具体的には、起動直後の引数/オプションの解析処理中に、
**int Args(String iStr1, String iStr2);**
を呼び出すので、自分の引数であれば、プロパティ「CanListing=true」にしてくれればよい。
自分の引数でなければ、0を返す。

より、具体的には、
例えば、
`c:\>StreamRelay.NET.exe a b c d e f`
というコマンドラインで起動したら、

1. iStr1=a, iStr2=b,　iStr3=c, で、Args() を呼び出し、
2. iStr1=b, iStr2=c,　iStr3=d, で、Args() を呼び出し、
3. iStr1=c, iStr2=d,　iStr3=e, で、Args() を呼び出し、
4. iStr1=d, iStr2=e,　iStr3=f, で、Args() を呼び出し、
5. iStr1=e, iStr2=f,　iStr3=NULL, で、Args() を呼び出し、

という感じ・・・

例えば、iStr1=b, iStr2=c,　iStr3=d, の時、自分の引数ということで、iStr1=b, iStr2=c, を Args() で使用したら、2を返す。すると次は iStr1=d, iStr2=e,　iStr3=f, で、Args() が呼び出される。

ということになっている。

---
#### jp.dip.rocketeer.Plugins.IPluginListing インターフェイスで定義しているメソッド/プロパティ

実装する必要があるのは以下

jp.dip.rocketeer.Plugins.IPluginListingインターフェイスで定義されているのは、以下のとおり

<dl>
 <dt><b>String[] usage { get; }</b>
  <dd>ヘルプに引数を表示する
 <dt><b>int Args(String iStr1, String iStr2)</b>
  <dd>引数を解析して、自分のものだったかどうかを返す(「名前」「 値」の二つを必要とするバージョン)
 <dt><b>Boolean CanListing { get; }</b>
  <dd>一覧表示を実施するよう引数で指示されたかどうか
 <dt><b>String getListingString(String Header)</b>
  <dd>一覧表示の出力結果
</dl>

jp.dip.rocketeer.Plugins.IPluginBaseインターフェイスで定義されている分については、[インターフェイス IPluginBase について](https://qiita.com/tomoki0sanaki/items/60613c29f0d627353e67)を参照

---
### 目次へ戻る

[目次というか最初の一歩](http://qiita.com/tomoki0sanaki/items/85f20cbe18378e33cd6f)
Qiita投稿画面で画像をアップロードしたときに「Something went wrong」と表示されてアップロードできない

##Qiita投稿画面で画像をアップロードしたときに「**Something went wrong**」と表示されてアップロードできない

###環境
OS:MacOS
ブラウザ：Chrome

###試したこと
- 別の画像のアップロード→同症状
- 別ブラウザ(Safari)→同症状
- スーパーリロード(Command + Shift + R)

###[Qiita公式情報](https://help.qiita.com/ja/articles/qiita-image-upload#:~:text=%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89%E3%81%A7%E3%81%8D%E3%82%8B%E7%94%BB%E5%83%8F%E3%81%AE%E5%AE%B9%E9%87%8F,%E3%81%AF%E6%92%A4%E5%BB%83%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82)
>ファイル単体で10MBまでの画像ファイルをアップロードすることが可能です。
なお、過去には一定の容量を超えた場合自動で圧縮する、といった仕様もありましたが現在は撤廃されています。

画像ファイルは月に合計100MBまでしかアップロードできません。
制限を超えてしまった場合は次の月までお待ちください。

今月は画像をたくさんアップロードしたため上限に達したように思われます。
→**5月に入り次第確認いたします。**
print関数について

## 初めに
初学者です。学習した内容をアウトプットしていくことで定着するのが目的です。

### pythonについて
`phyton`とは機械学習やデータ分析などの分野で人気があるプログラミング言語です。
### 特徴
1.文法がシンプルで読みやすい
2.専門的なライブラリが豊富にあるそうです。
私のような初学者でもとっつきやすいそうです。

具体的に`python`でできることは
・組み込み開発
・wedアプリケーション
・デスクトップアプリケーション
・機会学習
などがあるそうです。

##print関数を使い文字を表示させます
では`python`で用意されている関数を使い文字列を表示させていきたいと思います。
ちなみに関数とは`python`に初めから用意されているもので、「コンピューターに命令できるもの」だそうです。
そして今回使う`print`は組み込み関数といい、最初から用意されている関数のことです。

####print関数とは
print関数とはコンピューターに`表示しろ`と命令することができる関数です。恐らく`ruby`で言うところの`puts`だと思います。
書き方は

```python
print('表示したい文字列')
```

'(シングルクォート）で囲んだ文字列が表示されます。ちなみに”（ダブルクォート）でもオッケーだそうです。
ターミナルに書いていきと以下のようになります。

[![Image from Gyazo](https://i.gyazo.com/ae3b0ff7c31b033d301d221abb1999a4.png)](https://gyazo.com/ae3b0ff7c31b033d301d221abb1999a4)

'ハロー'（シングルクォート）で囲われているハローが出力されました。
【SQL】SQLとNoSQLの違いをざっくり解説　no.1

![名称未設定のデザイン (10).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/09ea6474-7b69-65ad-4fd6-5babee94cd28.png)
こんにちは、まゆみです。

今回の記事から<font color="Red">『Database』に関する記事</font>をシリーズで書いていきます

今回は第1回目になります。

実は『Database』と一言で言っても、Database にはたくさんの種類が存在します。

Databaseを選ぶ時、まず問われることが『SQLベースかNoSQLベースか』になります

そこで今回の記事では、

<font color="Red">SQLとNoSQLの違い、長所・短所</font>にフォーカスを当てて書いていこうと思います

ではさっそく始めていきますね。
#SQL・NoSQLデータベースの例

|SQLデータベース  |NoSQLデータベース  |
|---|---|
|MySQL  | MongoDB |
|PostgreSQL  |Redit  |


#SQLとNoSQLの構造の違い
![見出しを追加 (100).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/4a5d67ac-d437-31b3-b9b7-994e9b99c43a.png)

ざっくりいうとSQLはテーブル型のデータベースで

NoSQLはSQLとは違うフォーマットで書かれたデータベース全て

のことになります


![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/6346e1b0-d38b-b520-e440-ebc5b82852c8.png)

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/4d1fb641-c700-a1e3-f204-da4ea4c58874.png)

ではさっそく例を上げながら説明します。

あなたはWebショップを運営している店長さんです

とりあえずSQLかNoSQLかどちらを使えば分からないから、SQLベースのデータベースを作りました。


![見出しを追加 - 2021-04-12T102858.245.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/e3e98d76-b88c-f17c-a6b5-f685dd4629c5.png)

ただ、たなか太郎さんは、自分の住所を教えたがらず、<font color="Red">住所の欄が空欄(null)</font> になってしまいます。
また、やまだ花子さんからは、DMは家の住所よりむしろEmailの方に送ってもらった方が助かると言っています。

このような状態で、SQLベースのデータ(テーブル型の四角形のデータ)を作ろうとすると、データがないところは自動的に『null』が挿入されてしまい、良くない結果を招く原因となってしまいます。(Email がnull というアドレスに送られてしまったり)

一方、NoSQLベースのデータベースを使えば(例えばMongoDBはJSONフォーマットで格納されている)

![見出しを追加 - 2021-04-12T104227.226.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/e3775cec-9efa-79e7-3ef8-afcb299eb695.png)
後で新しい項目を追加したり、柔軟性という点では優れています。


<font color="Red">フレキシブルにデータベースを作れるという点では、『NoSQL』に軍配が上がりそうです</font>が、NoSQLがSQLに劣っている点はあるのでしょうか？

#リレーショナル　or 非リレーショナル

SQLとNoSQLを比較するときに、

>リレーショナルか

>非リレーショナルか

ということはどこかで耳にされたことがあるかも知れません。

先ほどのWebショップの運営でデータベースを作る例に戻りましょう

あなたは、それぞれの<font color="Red">お客さんの個人情報・買ったもの・個数・価格などを盛り込んだリスト</font>を作ろうとしていますが、次の日に<font color="Red">同じお客さん</font>がまた別の物を買い、同じ顧客の名前・個人情報に加えてその日に買ったものをリストにする。。。

それは得策ではなく、

>顧客情報リスト

>商品リスト

>オーダーリスト

と分けて書くほうが、理にかなっていますよね。


![見出しを追加 - 2021-04-12T120409.550.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/d57cbaf8-aec9-02f0-33d3-ecc86016d60d.png)

上のイラストのように、それぞれユニークなidでそれぞれのテーブルをつなぐような関連を持たせれば、うまくデータを管理する事ができます。

SQLベースのデータベースはこのように複雑な関連をそれぞれつないでデータを管理したい時などに、力を発揮します

このように相互の関連をつなぐことが得意な方のデータベースを

<font color="Red">リレーショナルなデータベース</font>と言います。

ただ、事前に『どのような構造(専門用語で<font color="Red">スキーマ</font>と呼ばれます。)のテーブルにするべきか？』を考慮しなければいけませんが。

複雑な関連をつなぐのはNoSQLは可能ですが、苦手分野になります。



#まとめ

|SQL  |  NoSQL |
|---|---|
|テーブル構造 |ドキュメント・キーバリューペアー  |
|複雑な関連をつなぐのが得意  |複雑な関連は苦手  |
|事前に構造を考えないといけない |よりフレキシブル |
Python Selenium を使ってみる(VisualStudio Code)

参考：https://yasulab-pg.com/77-2/

###pipを最新版にする
```hoge.py
python -m pip install --upgrade pip
```


##seleniumをインストールする
VisualStudioCodeの[Terminal]-[NewTeaminal]でPowerShellを実行する

```hoge.py
pip install selenium
```


###BeautifulSoupをインストールする

```hoge.py
pip install beautifulsoup4
```

###lxmlパッケージをインストールする
```hoge.py
pip install lxml
```

###requestsパッケージをインストールする
```hoge.py
pip install requests
```

##chrome driverのダウンロード
ヘルプ-Chromeについて
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346533/57e55b43-7fac-ef33-82c6-f37439afd96d.png)

https://sites.google.com/a/chromium.org/chromedriver/downloads
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346533/7f8424ac-d450-0bbd-6093-bc914cb0089d.png)

ダウンロード＆解凍の後、実行ファイルと同じ場所に設置
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346533/da6908e3-2afa-a31f-689d-86de2e8c625d.png)

##Seleniumの基本構文

```hoge.py
from selenium import webdriver
from bs4 import BeautifulSoup


options = webdriver.ChromeOptions()

#headlessならflg=1とする
flg=1

if flg==1:
  options.add_argument('--headless')
  options.add_argument('--no-sandbox')
  options.add_argument('--disable-dev-shm-usage')

driver = webdriver.Chrome('chromedriver',options=options)

url="https://kaikan.co/shop/kinki/?p=2"

driver.get(url)

html = driver.page_source.encode('utf-8')
soup = BeautifulSoup(html, 'lxml')

results = soup.find_all("h2", class_="_shop_name")

cell_list=[]

# 結果を出力

#2秒待つ
time.sleep(2)

for result in results:

    txt = result.findAll("a")[0].get_text()
    href= result.findAll("a")[0].get('href')

    #cell_list.append(txt)
    #cell_list.append(href)

    print(txt+','+href)
    
driver.close()
driver.quit()

```

```hoge.py
hoge=driver.find_element_by_id("ex13")
hoge=driver.find_element_by_name("b2")
hoge=driver.find_elements_by_link_text('あいうえお')
hoge=driver.find_elements_by_xpath(".//a")

#クリック処理
element=driver.find_element_by_class_name('ticketSelect__actionLabel')
element.click()

#ドロップダウン処理
dropdown = driver.find_element_by_name('Y15-seatdata-seat_size_1')
select_element = Select(dropdown)
select_element.select_by_index(1)

```

###BeautifulSoup

```hoge.py
#BeautifulSoup
hoge=soup.findAll(class_="p-articles-list-item")
hoge=soup.findAll("a")[0].get('href')
hoge=soup.find(class_='p-item-most-important').get_text()
hoge=soup.find(class_='p-item-title').find("a").get('href')
【Windows】3年間使ってて知らなかったショートカットキー

#プログラミング勉強日記
2021年4月12日
コピーや切り取りといった基本的なショートカットキーは知っていたが、今日初めて知ったショートカットキーがあったので、備忘録としてまとめる。

#基本的なショートカットキー
　まずこれさえ覚えとけばいい？よく使うショートカットキーを紹介する。

| ショートカットキー | 説明 |
|:--:|:--:|
| Ctrl + C | コピー |
| Ctrl + X | 切り取り |
| Ctrl + V | 貼り付け |
| Ctrl + A | すべて選択 |
| Ctrl + S | 保存 |
| Ctrl + P | 印刷 |
| Ctrl + F | 検索 |
| Ctrl + Z | 直前の操作を取り消す |
| Ctrl + Y | 直前の操作を繰り返す |
| Ctrl + Shift + S | 指定した部分を画像で保存して貼り付け |
| Alt ＋ ← | 戻る(ブラウザ) |
| Alt ＋ → | 進む(ブラウザ) |
| Windows + L | パソコンのロック |


#これから使いたい便利なショートカットキー
　今日覚えたショートカットキーは`Windows + V`と`Windows + D`で、とても便利だと感じた。増えていく場合はその都度追記していく。

| ショートカットキー | 説明 |
|:--:|:--:|
| Windows + V | 過去にコピーした文字を履歴から張り付けられる |
| Windows + D | すべてのアプリを閉じる・開く |


#最後に
　このショートカットキーも便利！！というのがあれば、コメント等で教えて頂きたいです。よろしくお願いします。
コールバック関数って使用頻度高いのに今までちゃんと理解できていなかったのでまとめます。。

# コールバック関数とは
コールバック関数は他の関数に引数として渡される関数で、外側の関数で何らかの処理やアクションを実行します。（MDN参照:https://developer.mozilla.org/ja/docs/Glossary/Callback_function）

> MDNの説明では、私には意味がさっぱり理解できませんでした。（ ;  ; ）

いろいろ調べた結果、要は、
#####コールバック関数とは、高階関数に渡す関数のこと。
#####高階関数とは、関数に関数を渡すことが出来るやつ。

> はい。ここまで調べて見ても私にはしっくりきません😭

要の要は、
#####コールバック関数は、
**ボタンクリックした時に〇〇を実行して！**
**〇秒後に〇〇を実行して！**
というように、**今じゃなくて、任意のタイミングで何かを実行してほしい時に使える便利なもの**っていう理解に留まりました。(果たしてこの理解は合っているのかどうか...間違っていたらごめんなさい🙏)


# 構文
構文その1（関数宣言で書くとこれ）

~~~react
function 高階関数(コールバック関数){
   //処理
   コールバック関数();
};
~~~

構文その2（無名関数／匿名関数で書くとこれ）

~~~react
const 高階関数 = function(コールバック関数){
   //処理
   コールバック関数();
};
~~~

構文その3（アロー関数で書くとこれ）
※アロー関数は、`...=(コールバック関数)=>{...`の（）括弧は、中のコールバック関数（引数）が1つのみであれば、（）括弧の記載を省略出来る。

~~~react
const 高階関数 = (コールバック関数)=>{
   //処理
   コールバック関数();
};
~~~

# 
# 使用例

「おにぎりの具は何が好き？」というダイアログが表示されて、「梅」と入力した場合のみ、「だと思った！」とコンソールに表示するというものを実装しました。（自分でも意味わからないのですが、思いつくままに作ったら、こんなものになりました😅）
高階関数　-> onigiri
コールバック関数　-> (fn)
window.prompt -> テキストを入力することを促すメッセージを持つダイアログを表示(参照: https://developer.mozilla.org/ja/docs/Web/API/Window/prompt)


~~~react
function onigiri(fn) {
  const input = window.prompt("おにぎりの具は何が好き？");
  if (input === "梅") {
    fn();
  }
}

onigiri(function () {
  console.log("だと思った！");
});

~~~

setTimeoutメソッドという、「〇秒後に表示する」というメソッドを利用して、5秒後にコンソールに「Hello!」と表示するものを実装してみました。

~~~react
setTimeout(function () {
  console.log("Hello!");
}, 5000);
~~~

# まとめ
高階関数、コールバック関数について、勉強してみましたが、まだまだ完全理解には届いていないような気がします。
コールバック関数について調べていると、「同期処理、非同期処理」や「promise」など初めて耳にする用語が次から次に現れて、コールバック関数の奥の深さを知らしめられました💦
本投稿の内容に至らない点も多々あると思いますが、ご了承下さい。いつも皆さんが投稿して下さるQiitaの投稿を見て勉強させて頂いてます！プログラミングの勉強これからも頑張りましょう✨

# 参考文献
https://www.youtube.com/watch?v=B624WCMhLfA&t=93s&ab_channel=%E3%81%97%E3%81%BE%E3%81%B6%E3%83%BC%E3%81%AEIT%E5%A4%A7%E5%AD%A6

初学者にもとても分かりやすく説明してくれている Youtuberさんのチャンネルです♪

https://developer.mozilla.org/ja/docs/Glossary/Callback_function

https://sbfl.net/blog/2019/02/08/javascript-callback-func/
Koinで2つ以上のインターフェイスを継承しているクラスを注入する方法

```kotlin
interface SampleA

interface SampleB

class SampleImpl : SampleA, SampleB
```

インターフェイス`SampleA`、`SampleB`を継承している`SampleImpl`を`Koin`で注入します。

```kotlin
val modules = module {
  
  // 1つのinterface（SampleA）を継承している場合。
  factory<SampleA> { SampleImpl() }
  
  // 2つ以上のinterface（SampleA/SampleB）を継承している場合。
  factory { SampleImpl() }.binds(SampleA::class, SampleB::class)
}

startKoin {
  androidContext(context)
  modules(modules)
}
```