OmniAICreator/Qiita-1.07M huggingface dataset:
paizaラーニング レベルアップ問題集 ソートメニュー応用編 JavaScript プログラミングレベル

プログラミングレベル (paizaランク C 相当)

https://paiza.jp/works/mondai/sort_advanced/sort_advanced__problems_speedup_step1

JavaScriptで解いてみました。

# 解答例
問題は好きな順序で解くことができるので、考えやすいように、aを難易度が小さい順にソートしておきます。
あとは、問題文に従って、aの難易度が小さい順に、以下の条件を満たすか調べていきます。
>難易度 a_i の問題を解くには「プログラミングレベル」が a_i 以上である必要
>難易度 a_i の問題を解くと「プログラミングレベル」が a_i + 1 になる

変数flagを使って判定をします。
途中で解けなかったらfalse→No、全部解けたらtrue→Yesを出力します。
```javascript:JavaScript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//問題の個数 n
const [n, q] = lines[0].split(" ").map(Number);
//問題の難易度 a
const a = lines[1].split(" ").map(Number);

//問題は好きな順序で解くことができるので、考えやすいようにaを昇順にソート
const aSorted = a.sort((a, b) => a - b);

//aを難易度が小さい順に調べる
let kyoko = 1;//京子ちゃんのプログラミングレベル
let flag = true;//全ての問題が解けるか
for (let i = 0; i < n; i++) {
    //難易度 a_i の問題を解くには「プログラミングレベル」が a_i 以上である必要
    if (kyoko >= a[i]) {
        //難易度 a_i の問題を解くと「プログラミングレベル」が a_i + 1 になる
        kyoko = a[i] + 1;
    } else {
        flag = false;//解けなかった
        break;
    }
}
console.log(flag ? "Yes" : "No");
```
# 解答例(C++の場合の模範解答参考)
問題aを考えやすいように昇順にソートする。
京子ちゃんの初期レベルは1なので、難易度1の問題がないと解けない。
解いたらレベルが1上がるので、次に解く問題は+1以下でないと解けない。
以上を全て満たせばYes!満たさなかったらNo。

C++は`return`で処理を止められるが、JavaScriptは`return`ではなく、`try…catch`を使うとできる。しかし、少し煩雑になるので、flagでYesとNoの判定をした。

```javascript:JavaScript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//問題の個数 n
const [n, q] = lines[0].split(" ").map(Number);
//問題の難易度 a
const a = lines[1].split(" ").map(Number);

//問題は好きな順序で解くことができるので、考えやすいように
//aを昇順にソート
const aSorted = a.sort((a, b) => a - b);

let flag = true;//京子ちゃんが問題を全部解けるか
//京子ちゃんの初期レベルが1なので、問題レベル1がないと解けない
if (a[0] !== 1) {
    flag = false;
} else {
    //aを難易度が小さい順に調べる
    for (let i = 0; i < n - 1; i++) {
        //次に解く問題の難易度は同じか+1でないと解けない
        if (!(a[i + 1] <= a[i] + 1)) {
            flag = false;
        } 
    }
}    
console.log(flag ? "Yes" : "No");
```
sqliteの属性について

# 目的
US版のMicrosoftのドキュメントをあさる手間を考え備忘録として記載。
# 参考
下記を参考に記事を記載しています。
(JP版)
https://learn.microsoft.com/ja-jp/xamarin/android/data-cloud/data-access/using-sqlite-orm
(US版)
https://learn.microsoft.com/en-us/xamarin/android/data-cloud/data-access/using-sqlite-orm

# 属性の使い方
下記のようにテーブルにするクラスのメンバ変数に設定する。
~~~
using SQLite;
namespace sqliteDemo {
    // テーブルの物理名を設定
    [Table ( "DemoTable" )]
    public class DemoTable {
        // カラムの属性を設定
        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }
        [MaxLength ( 250 ), Unique]
        public string Name { get; set; }
    }
}
~~~
# 属性の種類
### PrimaryKey
主キーの設定。
複合主キーはサポートされないとのこと。（参照のmicrosoft公式ドキュメントより）
~~~
[PrimaryKey]
public int id { get; set; }
~~~
### AutoIncrement
データベースに挿入されるたびに該当するカラムがインクリメントされる。
~~~
[AutoIncrement]
public int id { get; set; }
~~~
### Column
カラムの物理名を指定する。
~~~
[Column("test_id")]
public int id { get; set; }
~~~
### Table
テーブルの物理名を指定する。
~~~
[Table ( "DEMO_TABLE" )]
public class DemoTable {
…
}
~~~
### MaxLength
カラムのサイズを指定する。
~~~
[MaxLength(10)]
public int id { get; set; }
~~~
### Ignore
データベースに挿入されないフィールドとする。
~~~
[Ignore]
public int hidden_id { get; set; }
~~~
### Unique
指定されたカラムのデータを一意とする。
~~~
[Unique]
public int id { get; set; }
~~~
## 複数設定
一つのカラムに複数設定することも可能
~~~
[PrimaryKey, AutoIncrement,Unique]
public int id { get; set; }
~~~
bertを使っているときにcuda out of memory にはまった。

## 解決策
コマンドで解決する方法
① cmd 上で nvidia-smi と打ち、GPUの使用量を確認
② かなり使っていた場合、cmd 上でtaskkill /im cmd.exe　と打ち、空き容量を増やす。
③　jupyter が落ちるので、再起動し、バッチサイズをなるべく小さくして再チャレンジ。 

jupyter上で解決する方法
①jupyterをシャットダウンする。jupyterlabの場合 File -> shutdown
②nvidia-smiでGPUが解放されているか確認
SQLのJOINについて改めて学ぶ

# SQLのJOINについて改めて学ぶ
新しくやることがJOINを多用するので、ふわっとしていたJOINについて整理する

## JOINは何をするものなのか
テーブルを結合するために使う
DBからデータを取得する際にテーブル①とテーブル②を組み合わせて取得したい際に使う

例文
`SELECT *(カラム名) FROM テーブル① JOIN テーブル② ON テーブル①.カラム名① = テーブル名②.カラム名①`

## JOINの種類
大まかに内部結合と外部結合が存在する
- 内部結合 ⇒ (INNER) JOIN  
- 外部結合 ⇒ LEFT or RIGHT (OUTER) JOIN
()内の INNER と OUTER は省略できる

下記のサンプルテーブルを基に実際の動きを確認する

**foodテーブル**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289347/832a700e-8cae-7107-8f84-3a21cd07421c.png)

**food_typeテーブル**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289347/43aa15f9-7e5e-5d68-3089-5c6886bc44a0.png)


### 内部結合について
内部結合はテーブル①(food)とテーブル②(food_type)を結合し、完全に一致したものを取得する
```
SELECT * FROM food
INNER JOIN food_type ON food.type_id = food_type.id
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289347/df78a203-0d26-3c23-75db-3da711a80303.png)
- foodテーブルにのみ存在するバニラアイスは出力されない
- food_typeテーブルにのみ存在する麺は出力されない


### 外部結合について
外部結合の中で"左"外部結合と"右"外部結合が存在する
基本的に使用されるのは左外部結合で、左外部結合をするためにテーブルの順序を入れ替えるほど(らしい)
左右のどっちを主体化するか、という考え方でよい

#### 左外部結合
```
SELECT * FROM food
LEFT JOIN food_type ON food.type_id = food_type.id
```
実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289347/287a0448-6116-94b4-cd3b-1f6095193742.png)
- バニラアイスのfood_type.idは存在しないが、左側に指定したfoodテーブルに存在する為food_type部分はnullとして出力される
- food_typeテーブルのみに存在する 麺 は出力されない

#### 右外部結合
```
SELECT * FROM food
RIGHT JOIN food_type ON food.type_id = food_type.id
```
実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289347/adc668b0-22aa-ea89-dcc7-bd063fbe1033.png)
- 麺のtype_idは存在しないが、左側に指定したfood_typeテーブルに存在する為food部分はnullとして出力される
- foodテーブルのみに存在する バニラアイス は出力されない

### 使用したSQL
```
CREATE TABLE food (
 id varchar(256),
 type_id varchar(256),
 name varchar(256),
 money int
 );
 
CREATE TABLE food_type(
 id varchar(256),
 name varchar(256)
 );
 
INSERT INTO food (id,type_id,name,money) VALUES
 ('1','1','リンゴ',300),
 ('2','3','白菜',800),
 ('3','2','豚肉',1000),
 ('4','2','牛肉',2000),
 ('5','4','カツオ',300),
 ('6','6','バニラアイス',298);


INSERT INTO food_type (id,name) VALUES
 ('1','果物'),
 ('2','肉'),
 ('3','野菜'),
 ('4','魚'),
 ('5','麺');

select * from food;

select * from food_type;
```
Babylonjsで遊んでみた

# Babylonjsとは

強力で美しく、シンプルな、完全にオープンソースの Web レンダリング エンジン

[Babylon.js ドキュメント](https://doc.babylonjs.com/)より

# 特徴

## １. エコシステムが充実している

- ローカル環境なしでBabylonjsに触れられる[playground](https://playground.babylonjs.com/)
- ネイティブアプリ対応の[BabylonNative](https://github.com/BabylonJS/BabylonNative)やAR拡張の[BabylonAR](https://github.com/BabylonJS/BabylonAR)
- 充実のアセット[BabylonJS/Assets](https://github.com/BabylonJS/Assets)

## 2. Typescriptのサポート
- 型定義が同梱されているため、スタブを別で管理する必要がない。[@types/babylonjs](https://www.npmjs.com/package/@types/babylonjs)

# 基本的な書き方

:::note warn
chromeでは動かないかもしれないです。その時はEdgeでご覧ください。
:::
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="JjvNmXp" data-user="lapinChiro" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/lapinChiro/pen/JjvNmXp">
  Untitled</a> by チロ (<a href="https://codepen.io/lapinChiro">@lapinChiro</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## javascript部分の基本 

```javascript
function main () {
  /**
   * canvas要素を取得
   */
  const canvas = document.getElementById( 'renderCanvas' );
  
  /**
   * WebGLをjavascriptから扱うためのエンジンを初期化
   */
  const engine = new BABYLON.Engine( canvas );
  
  /**
   * カメラ、ライト、メッシュの入ったシーンを作成する
   */
  const buildScene = () => {
    /**
     * シーン自体の初期化。この中に物体を詰め込んでいく
     */
    const scene = new BABYLON.Scene(engine);
    
    /**
     * カメラの初期化
     */
    const camera = new BABYLON.ArcRotateCamera("camera", -Math.PI / 2, Math.PI / 2.5, 3, new BABYLON.Vector3(0, 0, 0), scene);
    
    camera.attachControl(canvas, true);
    
    /**
     * ライトの初期化
     */
    const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);
    
    /**
     * 物体の初期化。今回はただの立方体
     */
    const box = BABYLON.MeshBuilder.CreateBox( "box", {}, scene );
    
    return scene;
  }
  
  const scene = buildScene();
  
  /**
   * エンジンを動かして、カメラ、ライト、メッシュの入ったシーンをレンダリングする
   */
  engine.runRenderLoop( () =>
  {
    scene.render();
  });
  
  window.addEventListener('resize', () => {
    engine.resize();
  });
}

window.addEventListener('DOMContentLoaded', main);
```

# reactに組み込んでみた

https://babylon-app.vercel.app/


![qiita.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1625409/54402cf7-5f33-7e9b-c15b-d80bec91fe06.gif)
サイバーエージェントのインターンシップに参加した話

# 自己紹介
Swift歴1年ちょっとの文系大学生です。
普段はSwiftUIで個人開発をしていて、UIKitは全くの初心者です。
インターンシップに参加することに勇気が出ないよって方にインターンシップの雰囲気を伝えれたなと思います。

# [インターン詳細](https://www.cyberagent.co.jp/careers/students/event/detail/id=27497)
![27497_ext_03_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/44aba2c8-ec14-47f7-6262-55e0a96ea498.png)
期間: 9月16日〜9月18日
場所: Abema Towers
内容: 「無視できない！設計が学べるiOSハンズオン」

オフラインでの開催でした。

![IMG_1356.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/a143a35d-2507-c6a4-785f-b9d339f6e59b.jpeg)

### 1日目
10:30 **オープニング**
12:30 **ランチ**
13:30 **開発スタート**
16:30 **1on1 @メンター**
18:00 **夕会**
18:30 **日報タイム**

### 2日目
10:30 **オープニング**
12:00 **ランチ**
13:30 **開発スタート**
16:30 **1on1 @人事**
18:00 **夕会**
18:30 **日報タイム**

### 最終日
10:30 **オープニング**
12:00 **ランチ**
15:00 **コードフリーズ**
15:00 **資料作成開始**
16:00 **成果発表会**
18:30 **懇親会**

# 内容詳細
音楽再生アプリを運用できる状態にリファクタするというのが課題でした。
初期のコードはFatVCになっていて運用できない「悪いコード・悪い設計」になっていました。

ではどのようなコード・設計が「良いコード・良い設計」なのでしょうか
今回のインターンシップではこのように定義されていました。

- 責務がしっかりと分離されている (関心の分離)
    - View層 と ロジック層 がしっかりと分離されている
    - ディレクトリの構成もしっかりとできている
- テストしやすい (機能追加・仕様変更の際に副作用に気付きやすくなる)
    - MockでDIしやすいように作れているか
- アクセス修飾子もしっかり意識できている
    - internal で公開するものと private で閉じるものがしっかりと意識できている

上記の「良いコード・良い設計」になるようにアーキテクチャを決めてそれに沿って設計をしていくといった内容でした。

# 参加して良かったこと
### モチベーション爆上がり
まずモチベ爆上がりします。
実力不足を感じることで勉強意欲が上がります。

### 同じ分野で頑張ってる仲間と知り合える
これはマジででかいです。
自分は文系大学で開発してる友達がいないので、
インターンで開発友達できてまじ嬉しいです。
チーム開発しようって話も出てきててめっちゃワクワクしてます笑

### 今後の学習方向を知れる
メンターさんからのレビューで自分に足りてないスキルが何かを知ることができます。
自分が勉強しないといけない事がわかるので最短ルートで成長できます！

# 今後の課題
- RxSwiftを使えるようにする
- 個人開発アプリを全てMVVMにしてみる
- DIできるよう設計を意識する

# おわり
技術的に成長したことはもちろんなんですが、思考的にアップデートされた感じがします。
でも、正直UIKit初心者かつRxSwiftを触ったことのない私にとってかなりきつい内容でした笑
無理にRxSwiftを使うと設計を理解するという目的の妨げになるのではないかと思って、RxSwiftを使用するのをやめたんですけど、ちょっとチャレンジしても良かったかなとも思います笑
直近の目標はRxSwiftを使ってアプリをリリースしたいと思ってます。
実際に運用してみてどれだけ変わったかも記事にできたらと思います！

**おまけ**
めっちゃ驚いたことがあって共有したいんですけど、
1日目の昼食はしゃぶしゃぶ！！
2日目の昼食は焼肉！！
3日目の昼食は肉弁当、懇親会は居酒屋！！

豪華すぎない？

あとメンターさん達みんなめっちゃ面白くてすごい楽しかった！
様子見と自作関数【txtfile】

全くのQiita初心者なのでまずは様子見の記事を書いてみよう。

柄田鞘、もちろんハンドルネーム。

Python歴4年。
しかし全くの独学かつエンジョイ勢ゆえ実力で言ったら
**多少齧った小学生以下。**

わざわざこれを書くのは、
万が一 **"ガチ"** の方々に発見されて
レベルの低さをツッコまれたら心が折れてしまうから。

環境はipadでPythonista3。

PCも持ってるが使ってない。笑ってくれ。

向上心はそんなにない。
情報収集というより本当にただ備忘録として使いたいからアカウントを取得した。

目下の目標（目被り）は
**会話のできる人工知能型チャットボット**を作ること。

タメ口調なのはキャラが定まってないから。

以上です。

予防線張りまくりでダサいな。


…ここで終わろうかと思ったが怖くなって他の記事を読んだら

**ｱｧｰｰｯｯ！！**

皆様初投稿から予想を遥かに超えて読み応えのある記事を書かれておられる…(二重敬語)

仕方がないので以前作ったテキストファイルを読み込む自作の関数を開陳してひとまずはお茶を濁そう…

# txtfile関数

```
import glob
def txtfile(filename,second=False):
	if len(glob.glob(filename,recursive=True))!=0:
		file=open(filename,"r+",encoding="utf_8_sig")
	else:
		file=open(filename,'w')
	if second:
		file.write(str(second))
	else:
		txt=file.read()
		return txt
	file.close()
```

テキストファイルをいちいちopenしたりなんだりするのが面倒だなと思ったので関数化したものです。

第一引数にファイル名を指定し、その名を持つファイルが存在するか
globモジュールを使用して探します。

この関数書いたの数ヶ月前なんだけど、この**recursive=True**の意味を完全に忘却していたので復習。

ざっと調べたところコイツをつけることでディレクトリの垣根を越えて検索できるようになるらしい。(多分)

指定された名前のテキストファイルがなければ新たにファイルを作成、必要であれば第二引数に指定された内容を書き込みます。


**それだけ。**

こんなのでいいのか？！**大丈夫か自分！！**

というわけで初回はこんなもんにしておく。
Oculus Quest 2 版 Beat Saber でカスタム曲をプレイする方法 (SideQuest無し)

# はじめに
インストールする情報が調べた感じ古かったものが多いため最新の方法を記載
個人的に SideQuest を使いたくなかったので使わずにインストールする方法を載せます
また、BMBFでのBeat Saberの対応バージョンが分かりずらかったのでその確認方法も記載

# 0. Beat Saber の購入とインストール
Quest 2 版 Beat Saber を購入してインストールしておきます。

# 1. Developer登録

提供元不明のアプリをインストールする場合はQuestにログインしているOculusアカウントを開発者用アカウントみたいにしないといけないみたいなので下記サイトから設定します。

https://developer.oculus.com/

アカウントはQuestにログインしているアカウントで行います。
団体名を入力して作成します。

# 2. 開発者モード
QuestはAndroidなので、普通のAndroid同様に開発者モードにする必要があります。
スマホから操作できるみたいなので、開発者モードに設定します。

# 3. BMBFのインストールと対応バージョンの確認
BMBFの最新バージョンを下記サイトからダウンロードします。

https://bmbf.dev/stable

`Assets` 内の `com.weloveoculus.BMBF.apk` をクリックしてダウンロード

adbコマンドを使用してQuestにインストールして起動します。

インストールしているBeatSaberが対応していないと、下記のような警告文がでるため、そのバージョンを確認します。
対応している場合は、`Your verison of Beat Saber (1.24.0) is supported by BMBF!` と出るため、次の4のステップは飛ばしてステップ5に進みます。

下にスクロールすると、このように書かれている場所があるので確認します。

```
BMBF could not find any mod support for your version of Beat Saber! (which is v1.24.1)

The latest version of Beat Saber currently supportted by BMBF is v1.24.0
```

この場合、インストールされているBeatSaberのバージョンは`v1.24.1`で、BMBFに対応しているバージョンは`v1.24.0`です。

# 4. BeatSaberのインストール

BMBFで対応バージョンを確認したら、その対応バージョンでインストールしなおします。
既存のBeatSaberをアンインストールして、下記サイトから対応バージョンをダウンロードしてadbでインストールします。

https://oculusdb.rui2015.me/guide/quest/pc

上記場合はゲーム名`Beat Saber`、バージョン`1.24.0`と入力します。

# 5. BMBFの設定

提供元不明のカテゴリからBMBFを起動して、設定を進めます。
設定の途中でBeatSaberのインストールが止められるので、設定を押してインストールを許可します。

インストールが終了したらロードが入り、BeatSaberを復元するかどうか聞かれますが、復元しないでください。

インストールが完了すると、起動するか聞かれますが、起動せずに終了し、BMBFの右上の`Sync`(同期)のボタンがあるのでそれをクリックして完了したら終了です。


# 6. 曲の追加

## 1. BMBFから追加

BMBFの上のタブのBrowserを開き、BeatSaverをクリックして検索してカスタム譜面をインストールできます。

## 2. PCから追加

下記サイトからカスタム曲のダウンロードができるのでダウンロードしてください。

https://beatsaver.com/

曲の追加はBMBFが追加用のサーバーをQuest内に建ててくれいているので、それを利用して追加します。

BMBFのToolsを開いて右上に書いてあるサーバーのリンクを確認して、PCのブラウザからアクセスします。

サイトが開くので、BeatSaverからダウンロードしたカスタム曲をD&Dして追加します。

# 以上
ADBの使い方などは各自調べてください。
Pythonでライブラリの調査をする際のメモ

## dirとinspect.getsourceがいい感じ
未知のライブラリとか、普段使ってるライブラリだけど他にどんなメソッドがあるんだろ？って時にオススメ。

```py
import importlib
import inspect
from pprint import pprint

library_name = input('調査対象のライブラリ名を入れてちょ :')

m = importlib.import_module(library_name)

print('-----<dir>-----')
for c,a in enumerate(dir(m)):
    print(f"{c:4}, {a:20}, {type(eval('m.' + a))}")

print()    
print(f"-----<inspect.getsorce [{ library_name }] >-----")
print(inspect.getsource(m))
```

## 出力結果
※inputに「pprint」を入れた場合(出力結果長いので途切れてるけど、ソースが長々と表示されてます)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203740/e1a548ea-6db6-6312-cdef-6e6dbfe5983f.png)
今日、翻訳サイトを比較した。英語(70)

C# 稀によく使う機能
https://qiita.com/KACHA/items/00a77c1829a15be6c041

「稀によく使う機能」を英語に変換することを検討した。　

|URL|日本語|English|
|:--|:--|:--|
|https://translate.google.com|稀によく使う機能|Rarely used functions|
|https://miraitranslate.com/trial/|稀によく使う機能|Frequently Used Features|
|https://www.deepl.com//translator|稀によく使う機能|Rarely used features, Rarely used function, Rarely frequently used features, Rarely used feature|
|https://translate.weblio.jp/|稀によく使う機能|Function to rarely use well., 
Function to rarely use it well., 
Function to be good, and to rarely use|
|https://www.bing.com/translator?to=ja&setlang=ja|稀によく使う機能|Rarely used features|
||||

# google
https://translate.google.com/?sl=ja&tl=en&text=稀によく使う機能&op=translate

「よく」が消えている。

# miraitranslate
「稀に」が消えている。

# 参考資料
【2022年】翻訳サイトおすすめ比較17選！無料のサービス・アプリも
https://boxil.jp/mag/a53/

### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。

#### Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
SvelteKitアプリを無料で簡単にBasic認証をかける方法

# 前提
## svelteって知ってますか？
reactやvueのようなもので、これらとはまた違った特徴を持つwebフレームワーク。
というかどちらかというと、コンパイラという立ち位置のよう。

> ReactやVueのような 従来のフレームワークがその作業の大部分を ブラウザ で行うのに対し、 Svelteはその作業を アプリをビルドする際の コンパイル時 に行います。

と、[公式](https://svelte.jp/)には書かれている。

```html
<script>
	let a = 1;
	let b = 2;
</script>

<input type="number" bind:value={a}>
<input type="number" bind:value={b}>

<p>{a} + {b} = {a + b}</p>
```

このように、 `コード量を減らす(Write less code)` という思想の通り、かなり少ないコード量で実現できるのがめっちゃ嬉しい！

## SvelteKitって？
そのsvelteで、Webアプリケーションを構築できるフレームワークがSvelteKit。
ここの[StackBiltz](https://stackblitz.com/edit/sveltejs-kit-template-default-k1xjok?file=src%2Fapp.html&terminal=dev)でお試しできるので興味ある方は。

期待感はとても高いですが、v1.0.0を目指して鋭意実装中のようで、まだまだ不備があるよう。
ですが、現状触ってみた感じで詰まった所をお話します。

# 何がやりたかったか
SvelteKitアプリに条件付けて認証を付けたかったわけです。
社内アプリとかで外部に公開したくない。仲間うちでのみ使いたい。そんな感じです。

# 困った点
なにがしかの認証機能を付けて公開したい。

どのような認証にしてどこにデプロイしようか？

結論としてはBasic認証でアプリ自体はvercelへデプロイすることとしました。
（プラスアルファでherokuも使ってるのですが後述）

## なぜvercel？
svelteのメイン実装者は実はvercel社の中の人。
というか、svelte実装者をvercel社がスカウトして引き込んだよう。（[参考記事](https://vercel.com/blog/vercel-welcomes-rich-harris-creator-of-svelte)）
vercel社はNext.jsもsvelteも開発してるとかアツい会社🔥


その関係もあってか、なんも設定してなくても `vercel`コマンドを叩けばそれだけでデプロイできました。
めっちゃ楽。楽過ぎる。
herokuとかも試して見たのですが、設定ファイルをイジイジしたりとちょっと大変だったのでやめました。
「簡単に」というのは結構大事。

## なぜBasic認証？
google認証とかでもよかったのですが、そのへんの機能を提供しているのは[sk-auth](https://github.com/Dan6erbond/sk-auth)というライブラリ。
これもまた開発途中のためか、一部不具合があってうまく使えませんでした。

何ができなかったかというと、vercelにデプロイしたアプリから、ユーザーセッションが取得できないという。。（致命的）
ローカルでは取得できたのになぜだろうなと。
[Issue](https://github.com/Dan6erbond/sk-auth/issues/104)も投げてるのですが反応が無いぃぃぃぃ。。

もしできた方いれば教えてください🙏

ということで、basic認証となりました。

## どうやってBasic認証をかける？
vercelでBasic認証をかけるには実装がひつようなよう。
ただ、sk-authもちょっと怪しく、参考記事も見当たらなかったため、他を探してみる。

- Basic認証を無料でかけられる
- 簡単にSvelteKitアプリを無料でデプロイできる

この2つを叶える方法が中々見つからなかった。。。

# 実現した構成
最終的にはこの構成で実現。
![BasicAuth-SvelteKit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11531/b85b9c06-d372-4698-9205-f30ca4074ca2.png)

## heroku & Basic認証
heroku側はこれだけで実現！
```static.json
{
  "basic_auth": true,
  "proxies": {
    "/": {
      "origin": "<domain_url>"
    }
  }
}
```
```.htpasswd
<ユーザ名>:<パスワードのhash>
```
パスワードhashの作成は[こちら](https://testpage.jp/tool/basic_auth_htpasswd.php)とかでできます。

## vercel & SvelteKit
vercelにアカウント作って、SvelteKitのディレクトリからvercelCLI使ってvercelコマンド叩けば速攻デプロイできます。
adapterも現段階だとデフォルトの`adapter-auto` のままでOK。

https://vercel.com/guides/deploying-svelte-with-vercel

heroku側からリダイレクトされるだけなので、普通にデプロイさえできれば大丈夫です。

# 終わりに
herokuとvercelを使うことで、SvelteKitアプリを無料で簡単にBasic認証をかける事を実現しました。
SvelteKit周りがもう少し整えば、vercelだけで完結できるかなーと期待はしてますが、現状はこの形が一番楽で安いかなと思います。

svelteの思想はめちゃめちゃ好きなので、もうちょっと開発が進むと嬉しいなー。

# Editor's Note
最近、ビジネススクールに入って事業構築の勉強進めてます。
開発と事業構築は違う。
だけど、「構築していく」という点においては似てる部分もあるかなと。

考えている事業の全体像はもちょっと大きく考えているが、とりあえずのは入りとしては、
「稼げるエンジニアの育成」で考えてます（笑）

エンジニアの稼ぎ方って色々あるけど、今よりもうちょっと収入増やしたいけどそれがうまくできていない人が多いんじゃないかなと。
興味がある人がいたら嬉しいな。

https://www.instagram.com/engineers_income_increaser/
分割コンパイルとMakefile

# [1] 分割コンパイルの仕方

## 前提
以下のファイルがあると仮定 
&nbsp;&nbsp; 1 showA.c
&nbsp;&nbsp; 2 showB.c  
&nbsp;&nbsp; 3 main.c
&nbsp;&nbsp; 4 show.h

```c:showA.c
#include <stdio.h>

void showA(){
    printf("A\n");
}
```


```c:showB.c
#include <stdio.h>

void showB(){
    printf("B\n");
}
```

```c:main.c
#include <stdio.h>
#include "show.h"

int main(void){
    showA();
    showB();
    int n = retnum();
    printf("retnum : %d\n",n);
    return 0;
}
```


```c:show.h
void showA(void);
void showB(void);

int retnum(){
    return 1;
}
```

## コンパイルの仕方
以下を順番に実行する。

```terminal:ターミナル
$ gcc -c showA.c
```
```terminal:ターミナル
$ gcc -c showB.c
```
```terminal:ターミナル
$ gcc -c main.c
```
```terminal:ターミナル
$ gcc -o main showA.o showB.o main.o
```

まとめて実行すると、以下のとおり。

```terminal:ターミナル
$ gcc -c showA.c showB.c main.c
```
```terminal:ターミナル
$ gcc -o main showA.o showB.o main.o
```

# [2] Makefileの書き方

## Makefileとは
（ざっくりと）コンパイルを自動化するツール。
詳細 : https://www.gnu.org/software/make/manual/make.html#Reading

## Makefileを書く

Makefileの記述方法
```
記述方法
作りたいもの : 作るのに必要な材料
<TAB>作る方法
```

```:Makefile
all: main

showA.o: showA.c
	gcc -c showA.c

showB.o: showB.c
	gcc -c showB.c

main.o: main.c
	gcc -c showM.c

main: showA.o showB.o main.o
	gcc -o main showA.o showB.o showM.o

clean:
	rm -f *.o main
```

```:ターミナル
$ make showA.o     //gcc -c showA.c が実行される。

$ make all         //showA.o showB.o main.o　main が作られる。

$ make clean       //rm -f *.o main が実行される。
```

以上。
【Flutter / RESTAPI】簡単なAPIをFlutterで呼び出してみた！

## 初めに
iOSやAndroidの開発を今までやってきましたが、
ここ最近はFlutterを使用して開発をしている企業も
多いのではないかと感じます。

フリーランスの案件にもちらほら見かけるので、
今更かもですが勉強しなくては。。

Dartは簡単に触ったので、お馴染みのAPI操作を
やってみました！

## 使用するAPI
郵便番号をパラメータとして使うことで、
住所の情報がJson形式で返却されるAPIを使用します。

参考：郵便番号データ配信サービス

http://zipcloud.ibsnet.co.jp/

## 環境
・Android Studio
・url_launcher: 6.1.2
・flutter_html: 2.2.1
・http: 0.13.3

## 実装
全体のソースというよりは、テンプレート見たいな感じで
順に説明します。
### 0. 事前準備
```
// ①pubspec.yamlで使用するパッケージを入力
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
http: ^0.13.3 // 追加
```
:::note info
上記入力ができたら、右上の「Pub get」を動作させると
追加したライブラリを使用できるようになります！
:::

### 1. URLを準備
```
// zipCodeは任意の郵便番号
// ハイフンはあってもなくても可
String url = 'https://zipcloud.ibsnet.co.jp/api/search?zipcode=$zipCode'; 
```
### 2. APIを呼び出し、結果を受け取る
```
var result = await get(Uri.parse(url));
```
### 3. Json形式にパースする
```
// json形式(key/value)なのでMapを使用
Map<String> data = jsonDecode(result.body);

// 後は呼び出し元に返却でも出力でも任意の操作で！
print(data);
```

### 試しに郵便番号を指定すると。。。
```
// 北海道に旅行行きたいなぁ。。
String zipCode = '0010001';
```
Jsonで返ってきた！！
```
{
    "message": null,
	"results": [
		{
			"address1": "北海道",
			"address2": "札幌市北区",
			"address3": "",
			"kana1": "ﾎｯｶｲﾄﾞｳ",
			"kana2": "ｻｯﾎﾟﾛｼｷﾀｸ",
			"kana3": "",
			"prefcode": "1",
			"zipcode": "0010000"
		}
	],
	"status": 200
}
```

### ちなみに誤りの番号を入れると。。
```
// zipCode = '9999999';
{
	"message": "パラメータ「郵便番号」の桁数が不正です。",
	"results": null,
	"status": 400
}
```

:::note warn
警告
エラーケースもあり！
7桁以外の数字を入力した場合は別のエラーが
返却される。。
:::

```
// zipCode = '99999999999';
{
	"message": null,
	"results": null,
	"status": 200
}
```

## 最後に
以上がFlutterでAPIを呼び出す処理になります！
意外とシンプルですね！

ただ誤った番号を入力した際など様々なケースを
試したり、アプリに考慮すると色々実装も
楽しくなるのではないでしょうか？

この記事が参考になれば幸いです！
与件駆動執筆

# はじめに

思いつき駆動執筆 v.s. 与件駆動執筆

https://qiita.com/kaizen_nagoya/items/c320c248819acebeb6c1

データサイエンティストの気づき!「勉強して仕事に役立てない人。大嫌い!!」『それ自分かも?』ってなった!!!

https://qiita.com/kaizen_nagoya/items/d85830d58d8dd7f71d07

# 与件

【毎日自動更新】AdventCalendar2022 タグ LGTMランキング！

https://qiita.com/torifukukaiou/items/6cbea79ccf0eea8777d2

数値を見て、そこから文章を書き始める。　

引用記事のviews増加を目指して。　

## DOCAP
https://qiita.com/tags/docap

DoCAP（ドゥーキャップ）って何ですか？

https://qiita.com/kaizen_nagoya/items/47e0e6509ab792c43327

試行錯誤のことです。まずやり始めなければ、何も起こらない。　
受動測定ではない。能動測定。
 
## Data Scientist

Data Scientist の基礎(1)データ構造

https://qiita.com/kaizen_nagoya/items/27d8f5db34ff747d587b

Data Scientist の基礎(2)参考文献

https://qiita.com/kaizen_nagoya/items/8b2f27353a9980bf445c

## C++
C++ Error Message Collection(1)does not name a type, 11 articles

https://qiita.com/kaizen_nagoya/items/acb9f1a9b5aad6df06bd
リーダブルコードまとめ(第2章：名前に情報を埋め込む)

# 第2章:名前に情報を埋め込む
## 概要
本章のメインテーマは、「見ただけで情報を読み取れるような変数を命名することが重要」ということです。そして、それは以下の6つのテーマに沿って解説してくれている。
・明確な単語を選ぶ
・汎用的な名前を避ける
・抽象的な名前よりも具体的な名前を使う
・接頭辞や接尾語を使って情報を追加する
・名前の長さを決める
・名前のフォーマットで情報を伝える

### まとめ
・コードを読む人が考えなくても見ただけでその変数や関数が何を指しているのかを理解できるように命名をする。
・TPOを弁えて命名する。
・変数名をつけることを習慣化していく。

### 学んだ点
・名前は、短いコメントと考え、名前に情報を詰め込む。
・変数の意味を考えるコスト削減をする。
例えば、「GetPage」のような変数をつけても、「get」自体がどこからpageを取ってくるのかわからない。そのため、downloadPageやfetchPageの方がわかりやすい。加えて、変数に「Size」のような単語を用いても、何のsizeなのかを考えなければならず、非常に無駄。

・類似事典を用いてTPOに合った単語を用いる。明確で正確な単語を用いる必要がある。
・エンティティの値や目的を表した名前を変数につける。
・tmpという名前は、生存期間が短くて、一時的な保管が最も大切な変数にだけ使う。
・少しでも時間を使って良い名前を考える習慣をつけるようにすれば、すぐに「命名力」が高まるので、怠慢に簡単な意味のない名前を変数につけない。
・変数や関数などの構成要素の名前は、抽象的ではなく具体的なものにする。
・もし絶対に知らせなければいけない大切な情報がある場合は、「単語」を変数名に追加する。
・情報を変数名に追加した方がいいものがある。特にセキュリティのバグのような深刻な被害が出そうなものに使うべき。例えば、password→plaintext_password comment→unescaped_comment html→html_utf8 data→data_urlenc
・スコープが小さければ、短い名前でもいい。もちろん、スコープが大きければ、名前に十分な情報を詰め込んで明確にする必要がある。
・不要な単語を投げ捨てる。例えば、ConvertToString()をToString()で理解できるので後者で十分。

### 感想と振り返り
開発中に新たに変数を爆誕させる際に、「レビューしてくださる方がどのように解釈するか？」や「考えなくても理解できる変数か？」ということを念頭に入れて効率のいい(理解するのに時間をかけない)変数を命名すべきだと学べた。
少し話は変わるが、僕自身UILabelの変数を命名する際に~Labelとせずにレビューに出してしまった。少し考えたら、~Labelとすることで「この変数は何かのLabelのことを指す変数である」ということを見ただけで判断してもらうことができたよね。そのような小さな積み重ねですね。
【AWS】用語を整理しながら学ぶAWS - part9 AWS Glue DataBrew

# 【AWS】用語を整理しながら学ぶAWS - part9 AWS Glue DataBrew

## はじめに

この記事では AWS Glue DataBrew(以下、Glue DataBrew) を学習していく記事です。
主な内容としては実践したときのメモを中心に書きます。（忘れやすいことなど）
誤りなどがあれば書き直していく予定です。

## AWS Glue DataBrewとは

簡単にまとめるとGlueをさらに使いやすくしたサービスです。
[AWS Glue](https://aws.amazon.com/jp/glue)では次のように説明されています。(一部抜粋)

> データアナリストとデータサイエンティストは、AWS Glue DataBrew を使用して、コードを書くことなくデータを視覚的に強化、クリーンアップ、正規化できます。

同じGlueと名のつくサービスですが、できることは異なります。
では、GlueとGlue DataBrewにはどのような違いがあるのでしょうか。

## Glue と Glue DataBrewの主な違い

ドキュメントの比較、検証してみた結果から次の違いがあります。

|項目|Glue|Glue DataBrew|
|:---|:---|:---|
|対象|エンジニア|非エンジニア|
|データ変換機能|10~20個|250個|
|コードによる修正|できる|できない|
|ビジュアル|データのプレビューが見えにくい|データのプレビューが見えやすい|
|ジョブ|Glueジョブとして管理|Glue DataBrewジョブとして管理|
|スケジュール|Glueのスケジュールとして管理|Glue DataBrewのスケジュールとして管理|

大きな特徴としてはノーコードでデータ分析を非エンジニアに提供できることです。

:::note info
クローラーによって構築されるデータカタログはGlueと共有されます。
:::

Glue DataBrewで使われる用語はGlueとほぼ同じですが、使い方は全く持って異なります。
Glue DataBrewの使い方を把握していきましょう。

## 　Glue DataBrewを使ってデータを出力する流れ

Glueを使いつつ、Glue DataBrewも使う場合の流れは次の通りです。

1. 通常のGlue同様にデータへの接続を作成する
2. Glueデータセットへの接続を作成する
3. Glue DataBrewのプロジェクトを作成する
4. ステップを使い、データを加工する
5. レシピに従ってデータを出力する

### 通常のGlue同様にデータへの接続を作成する

Glue DataBrewの接続はすでに作成したGlueの接続を引用できます。
ない場合は作りましょう。

### Glueデータセットへの接続を作成する

データセットはGlueのクローラーで作成したデータカタログを使います。

:::note info
データカタログ = 利用できるデータセット一覧
:::

データカタログにないデータの場合はプロジェクトの作成時に新しいデータセットとして指定します。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/b71ae32a-0a9a-5cd5-5717-a6bce43297fc.png)

### Glue DataBrewのプロジェクトを作成する

データへの接続とデータセットが決まったら、Glue DataBrewでプロジェクトを作成します。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/478e5ead-506a-9b96-5bde-dec5ebc387d2.png)


プロジェクトはプロジェクト名を入力するところから始まります。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/2f34493f-9b9c-9eec-e906-2cb89072be0b.png)

:::note info
プロジェクトは1つ以上のデータ加工を保存できる単位のことです。
:::

プロジェクトにはデータへの接続とデータセット以外にも必要な設定があります。

- レシピ
- サンプリング
- IAMロール

プロジェクト作成のタイミングでレシピが存在しない場合は新規に作成するようにプロジェクトで設定します。

:::note info
レシピはデータ加工のルールを記録した設定のことです。
:::

サンプリングはデータ加工のプレビュー時に何行のデータを表示するかを決める項目です。

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/c6004aae-2872-ecf4-405f-9d4b7cd2029e.png)

Glue DataBrewではデータの加工手順をレシピという形で保存しますが、このレシピを作成する時に
レシピを適用した時のデータがどのように変化するかをプレビューすることができます。

:::note info
レシピ = データの加工手順を保存したもの
:::

IAMロールは接続するサービスを考慮してIAMポリシーを作成します。
IAMポリシーからIAMロールを作成して指定します。

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/3ad36924-3267-7919-2ccf-d4298161e43d.png)

ここまででプロジェクトの作成は以上です。
次はデータを加工する方法について見ていきましょう。

### ステップを使い、データを加工する

データを加工する方法ですが、Glue DataBrewではステップを追加してデータを加工します。

![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/d5a7971b-0fd1-901f-4898-3111575d0696.png)

そして、追加したステップを保存したものをレシピと言います。
レシピに従ってデータ加工を実行します。

:::note info
データを加工する　=　ステップを追加する　=　レシピを作成する
:::

### レシピに従ってデータを出力する

任意の場所にデータを出力します。
保存先は要件に合わせる形になりますが、出力先としてよく選ばれるのはS3です。

これでGlue DataBrewの一連の流れは以上です。

## まとめ

Glue DataBrew はGlueを万人向けにより使いやすくしたサービスという印象でした。
特にGlueはUIがレガシーページと分かれており、使いにくさが少しだけあります。
その印象を払拭したサービスがGlue DataBrewになりそうです。

## おわり
【UiPath】データテーブルのデータを維持したまま、各列のデータ型を自動検出で変換する

**データ テーブルを出力 (Output Data Table)** を使いデータテーブルをテキストに変換した後、
**テキストからデータ テーブルを生成 (Generate Data Table From Text)** を使ってテキストをデータテーブルに戻し、
この際にアクティビティのオプション機能で型を自動検出させる、という流れです。

### 実装例
範囲を読み込み (Read Range) で取得したデータテーブルは全列Object型で設定されます。
以下はExcelから範囲を読み込み、データテーブルの各列のデータ型とデータ内容を確認するワークフローです。
まずはこちらをご確認ください。
- ワークフロー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/8d3744b1-8a6a-cfe2-32ad-f1a4f83ea20d.png)
- 読み込むExcel
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/b2b8f213-8bcc-760c-e34e-832e6b9f2686.png)
- 実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/fd985fb5-a9ab-67dc-8a2f-3cc6139eb476.png)
 
全列Object型で設定されているのが確認できます。

#### データ型を変換する
Excelを読み込み、ログに出力した後、
**データ テーブルを出力** と **テキストからデータ テーブルを生成** を使いデータ型を変換し、
再度ログに出力します。

- ワークフロー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/d1ff13e4-66b2-dab4-c72b-9ceaae36e199.png)
- **テキストからデータ テーブルを生成** のプロパティ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/62933514-0fff-744f-7d83-a40abd4f9752.png)
- 実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/5ec9da4f-c1a3-4388-35ab-9775db403819.png)

データを維持したまま、数値はInt32型、文字列はString型、日付はDateTime型に変換できています。
**テキストからデータ テーブルを生成** のプロパティは上記の通り、
「列ヘッダーを使用」、「型を自動検出」、「CSV解析」をTrueにし、「列区切り」にカンマを指定してください。

#### 複数のデータ型（文字列と数値とか）が混ざっている列はどうなるの？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/5470995f-0405-b6aa-6ea4-6af93703969b.png)
データの件数次第かもしれませんが、今回の例程度の件数であればエラーにはならずString型に寄せてくれます。
ただし意図せぬデータ型になる可能性も否めませんので、列に入っているデータの型が特定できない時は使わないほうがよいでしょう。

#### 「型を自動検出」をオフにするとどうなるの？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/ffe353cd-9c29-4485-2579-8b85dcbb6312.png)
全部String型になるようです。
これはこれで何かの役に立つかも。

## 動作環境
UiPath.System.Activities 21.10.4

## 参考
https://docs.uipath.com/activities/lang-ja/docs/generate-data-table

https://docs.uipath.com/activities/lang-ja/docs/output-data-table
AWS Certified Machine Learning - Specialty を取得した

# 前回の試験

https://qiita.com/morio1101/items/3cb7af64e4350d3563e7

# 前回のAWS認定試験

https://qiita.com/morio1101/items/a011773073ecdc31600e

# はじめに

AWSの試験は有効期限があり、再認定時にどういった学習をしたらよいかを残すために本記事を作成しています

# 学習期間
7/26 - 9/19

## みちくさ(読み飛ばし推奨)

2021/11 AWS認定試験 Machine Learning を残して、諸事情から転職活動
その後、転職して仕事を覚える毎日、酒の肴にG検の学習をして取得したので、ついでにAWS MLSをチャレンジ
日々慣れない業務に取り組む＋AWSの中でも未知の分野の中でも苦手意識
色々ありましたが、、、酒の力を借りて試験を受けるところまで進めることができました
no alcohol no life. アルコールのない人生は考えれません

ただSAP on AWS なる試験が増えていたので、MLS を取得しても全種制覇とはなりませんでした（トホホ…

# 学習資材

* Udemy
    * AWS Certified Machine Learning Specialty Full Practice Exam
    * AWS Certified Machine Learning Specialty: 3 PRACTICE EXAMS
* Tech Stock（旧名：AWSで学習しよう）
    * #1～#22

# 学習方法

* Udemy の問題集
    * 大体6～8周実施
        * 80%ぐらい安定的にとれるようになってましたが100%は無理でした
* Tech Stock
    * 3周ぐらい実施
        * 9割以上安定的にとれるように学習した
    * 本試験モードは2回実施（960、945）

# 出題傾向と補足

* SageMaker
    * 様々なケースの問題が出題されて、しかもそこそこの割合
    * 線形回帰がどういうケースに適していて、何を解決するためのものかは理解すべき
    * ハイパーパラメータのチューニング方法は全く分からなかった
    * ground truth はラベル付けするためのものだけど、どうラベル付けするのかは頭の片隅にあると良い（私はなかった）
* Glue
    * 何ができるか、どういうケースにマッチするか
    * 大体のケースで、Glue使ってたら解決する問題が多く感じた
* ログ
    * CloudTrail、Cloudwatch がどういう役割か理解しておくこと
    * どういうフローでログを出すべきか、どうログを出すのが最適解か？
* 混同行列
    * 精度、再現性辺りは確実に理解
    * F1は頭の片隅にあると良い
    * 度数だったかな？は知っていると加点対象
* 過学習
    * 過学習の場合にどう対処すべきか？
    * 過学習とは何が出来ていない状態か？
* コスト面で安い・インフラメンテ少ない構成を選択する問題

覚えている範囲ではこういう形の問題が出題された
問題について書くことはできないので、参考程度にまとめておいた

いつも通りではあるが、Tech Stock の内容を理解した上で、確実に解けるようになっておくことが合格の第一歩
2～3割はほぼ似た問題が出題されるので、この問題は確実に抑えないといけない

Udemy の問題はそこまで出題されない＋全体的に難易度が高いように感じた
おかげでわからないながらも2択に絞り込んだり、勝率の高そうな選択肢を選択することができた
ただ何度見ても満点は取れなかった

# 感想

180分の試験で、1周60分、見直しで30分ぐらいと比較的時間に余裕のある試験運びでした

試験に関しても、以下の通りでした

* 6割は自信を持って解答できた
* 残り4割のうち半数以上は2択まで絞り込んだor多分正解だと思う選択をした
    * 全く分からない問題はその内数問ありました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532289/6cfe1bee-fbfa-14dd-6745-7381df2a553d.png)

スコアは上記の想定通りの結果が反映される形になりました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532289/d057d17f-c855-1aa7-cb6c-00d86aa6ac83.png)

ありがたいことに、すべてコンピテンシーを満たしていたので一安心です

さて、次の酒の肴は何にしよう。資格にするか技術にするか、それとも自己啓発か
面白そうなものに取り組みたいと思うものです
SPIKEprimeに自作モジュールを書き込む方法

SPIKE primeに自作のモジュールを書き込むことで、メインのPythonプログラムからimportする事が出来ます。本記事では、自作のモジュールをSPIKEに書き込む方法を紹介します。

# 今回書き込む自作モジュールのサンプル
今回例としてSPIKEprimeに書き込む自作モジュールは、Hello World!をprintする次の簡単なPythonのモジュールです。
```python:hoge.py
def hoge():
  print("Hello World!")
```

# 書き込むためのコードを生成する
以下のサイトにアクセスします。

https://instpyspi-atworks.web.app/

次のように書き込みたいpythonコードとモジュール名を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513482/1bb82f4b-5b4e-e346-cf9f-c2863219e0d0.png)


入力後、「CONVERT」ボタンを押すと次のような画面になりますので、上の方のボタンを押してコピーをします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513482/322866e3-d9f0-453b-042f-2d5ccceed7bd.png)

# コピーしたコードをSPIKE appを使ってSPIKE primeに書き込む

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513482/40a72658-7f90-da3d-c736-6212fea30e8f.png)

貼り付け後、右下の実行ボタンを押します。
SPIKE primeが再起動すれば、自作モジュールの書き込み完了です。
自作モジュールが使えるかどうか確かめるために、今回書き込んだ、hoge.pyの関数hoge()をSPIKEで呼び出してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513482/63bbf0eb-f97c-5424-4ada-76322ec4f8f2.png)

しっかりと、Hello World!が出力されていることがわかります。
これで、自作モジュールを書き込めたことがわかりました。

# instPySPIについて
このwebアプリは今回私が作成したアプリとなっています。
オープンソースとしてGithubで公開していますので興味がある人は見てください。
Windows10のバッチでマルチディスプレイの出力方法（ミラーリング or 拡張など）を変更

# やり方

『DisplaySwitch.exe』という奴がいるので、引数を渡して起動してあげればOK。

```bat:メインディスプレイのみ出力
"C:\Windows/System32/DisplaySwitch.exe" /internal
```

```bat:ミラーリング
"C:\Windows/System32/DisplaySwitch.exe" /clone
```

```bat:拡張
"C:\Windows/System32/DisplaySwitch.exe" /extend
```

```bat:サブモニターのみ出力
"C:\Windows/System32/DisplaySwitch.exe" /external
```

# 引数無しでexeを起動するとどうなるか

メインモニターの右側に下記メニューが出てくるだけ。
```Windowsマーク + P``` のキーボード操作をした時と同じ状態になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/098c99eb-47d0-3293-effc-95978a91c79d.png)

# 蛇足（Windowsマーク + Pについて）

下記参照。

https://qiita.com/waokitsune/items/7ac5cff6b3645fc8dece

# 参考サイトさん

https://qwerty.work/blog/2018/11/multidisplay-mode-change-command.php

# バージョン

Windows 10 Home 21H1 OSビルド 19043.2006
This does not look like a tar archive 今日のdocker error

Posix Test Suite docker downloads, tar, install。docker(110)

https://qiita.com/kaizen_nagoya/items/f1e24be04a2405ede00f

```ubuntu:bash
# mv NP_distr.Z.exe NP_distr.Z   
# tar zxvf NP_distr.Z 
tar: This does not look like a tar archive
tar: Skipping to next header
tar: Exiting with failure status due to previous errors
```

docker: Error response from daemon: error while creating mount source path 今日のdocker error

https://qiita.com/kaizen_nagoya/items/9daad44a8a0e03afca9d

# 文書履歴(document history)
ver. 0.01 初稿 　20220919
DXとデジタル化

# はじめに
IT×ビジネスという視点で週1本記事を投稿しています。
もし興味のある方は下のリンクから他の記事も見ていただければ幸いです。
 [@7_inai_](https://qiita.com/7_inai_)
# DXとデジタル化の定義の違い
- デジタル化：従来のアナログシステムや、業務プロセスをデジタルに置き換えることで、__業務効率化__ を図ること
- DX：デジタル技術やデータを用いて、__ビジネスモデルを変える__ こと
つまり、デジタル化は業務効率を目的としますが、DXは単に部分的な業務プロセスを変更するのではなく、ビジネスを根本から変えるようなことを指します。

# デジタイゼーション × デジタライゼーション × デジタルトランスフォーメーション
DXには、デジタイゼーション、デジタライゼーションという2つのStepを踏んでその先にデジタルトランスフォーメーション(DX)があります。
Step1.デジタイゼーション：アナログ情報をデジタル化することで、データを蓄積できる
Step2.デジタライゼーション：業務プロセスをデジタル化すること
Step3.デジタルトランスフォーメーション：デジタル技術を用いてビジネスモデルを変えること

# DXの事例
- SGホールディングス(佐川急便グループ)
AIを利用した伝票の自動入力とデジタル化、配送ルート最適化、倉庫内作業の自動化などを実現。
- JR東日本
新幹線のチケットレス化、スマホアプリによる山手線内の混雑予測情報。
- 株式会社小松製作所
建設現場の情報を吸い上げることで、データを取得・分析し、安全性と生産性の向上を実現。


# 終わりに
この記事を書き終えてから気づいたのですが、以前[DX(デジタルトランスフォーメーション)でビジネスはどう変わる？](https://qiita.com/7_inai_/items/c365a3dfc8637d35c014)という内容で私が書いた記事がありました。不覚にも似たような内容の記事を書いてしまいましたが、そちらも見ていただけると幸いです。

最後までお付き合いくださりありがとうございました。
docker: Error response from daemon: error while creating mount source path  今日のdocker error 

Posix Test Suite docker downloads, tar, install。docker(110)

https://qiita.com/kaizen_nagoya/items/f1e24be04a2405ede00f

```macOS:bash
$ docker run -v /Users/administrator/work:/home/work -it gcc /bin/bash
Unable to find image 'gcc:latest' locally
latest: Pulling from library/gcc
23858da423a6: Pull complete 
326f452ade5c: Pull complete 
a42821cd14fb: Pull complete 
8471b75885ef: Pull complete 
8ffa7aaef404: Pull complete 
0dbd3d90c419: Pull complete 
c8360ea64db4: Pull complete 
65bba72ff1de: Pull complete 
a615a380ba22: Pull complete 
Digest: sha256:4f8717c532f9c07d6258e3d17faf0df97ffe0c18628d7769c1e25ca20c237a1e
Status: Downloaded newer image for gcc:latest
docker: Error response from daemon: error while creating mount source path '/Users/administrator/work': mkdir /Users/administrator: operation not permitted.
ERRO[0072] error waiting for container: context canceled 
```

フォルダ名に存在しないものを指定。

```macOS:bash
docker run -v /Users/ogawakiyoshi/work:/Users/ogawakiyoshi/work -it gcc /bin/bash
#
```
# 文書履歴(document history)
ver. 0.01 初稿 　20220919
### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。
#### Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
[Xcode 14] SwiftUI の List に背景色を付ける

`Xcode 14` までは、以下のようなコードで `List` に背景色を付けていたと思います。

```swift
import SwiftUI

struct ContentView: View {

    init() {
        UITableView.appearance().backgroundColor = .clear
    }

    var body: some View {
        List {
            Text("コンテンツ1")
            Text("コンテンツ2")
            Text("コンテンツ3")
        }
        .background(.red)
    }
}
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402114/faedbec4-a32b-c418-3e51-8f7effab4eed.png" width="300">

`Xcode 14` からは、上記のコードでは背景色が変わらず、以下のようなコードを書く必要があります（`.scrollContentBackground(.hidden)` を利用）。

```diff_swift
import SwiftUI

struct ContentView: View {

-   init() {
-       UITableView.appearance().backgroundColor = .clear
-   }
-
    var body: some View {
        List {
            Text("コンテンツ1")
            Text("コンテンツ2")
            Text("コンテンツ3")
        }
        .background(.red)
+       .scrollContentBackground(.hidden)
    }
}
```

これは、`List` の裏で `UITableView` が利用されているか、`UICollectionView` が利用されているかの違いのようです。

興味本位で、以下のコードを試してみましたが、背景色は変わりませんでした。

```diff_swift
import SwiftUI

struct ContentView: View {

    init() {
-       UITableView.appearance().backgroundColor = .clear
+       UICollectionView.appearance().backgroundColor = .clear
    }

    var body: some View {
        List {
            Text("コンテンツ1")
            Text("コンテンツ2")
            Text("コンテンツ3")
        }
        .background(.red)
    }
}
```

今回は、開発中のアプリで `Xcode 14` に移行後、`List` の背景色がおかしくなったので、備忘録的に書きました。では、また次の記事で！
それぞれの名前IT用語「：」「；」「””」「’’」「.」「,」「.」「/」の意味について考える

メンターに教えてもらう時に、これしてこれしてと指示をもらった場合に、すぐに頭に浮かばない
ため、覚えるために備忘録として作成した。
　また、コードを書いているが、感覚的に、ここでは「""」　、ここでは「;　」と入力しているが、
コンピューターの記号について、どうゆう意味なのかを考えてみたいと思う。
なぜ、ここでこれを使うのか？？公式的にはこうだからではなく、コンピューターでは

▼「;」   セミコロン
意味
・プログラミング言語では区切りに使われる


▼「：」   コロン
意味
URL記入時に使用する


▼「""」  ダブルコーテーション
意味
日本語の「」と同じ意味ような意味
プログラミング言語では文字列を示す時に使用する


▼「''」  シングルコーテーション
意味
プログラミング言語では文字列を示す時に使用する

▼「.」   ドット
意味
・文書の終わりに使用される
略語や略記語の最後に終止符と言う意味でつかわっれる
現在のフォルダーを示す時に使用される
..は、現在のフォルダーの親を示す（./yamayama.htmlなど）


▼「,」   カンマ
意味
・コードの途中で区切り
・タグの区切り

▼「{}」　 波括弧
意味
・[] を入れ子にするときに外側の括弧を波括弧を使用する
・プログラミング言語やスクリプト言語では関数やif文・for文などの構文・命令等や変数のローカルスコープを
表現する時に使用する

▼「 () 」　丸括弧
・式をグループ化して演算の優先順位の明示・変更を行うときに用いる。プログラミング言語でも同様の用途で使用する言語が多い
・プログラミング言語で、関数の引数を明示するのに用いる
・配列の要素を指定するのにも用いる

▼「 [] 」　角括弧
・数式においては、丸括弧()を入れ子にする場合に外側の括弧を角括弧とするほか、丸括弧の代わりに角括弧を用いる様式もある





〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
パラメーターとは...
URLパラメーター
▼WebブラウザなどがWebサーバに送信するデータを、
送信先を指定するURLの末尾に特定の形式で表記したものを
URLパラメータ（リクエストパラメータ/クエリ文字列）という。

▼URLの末尾に「?」（クエスチョンマーク）を付け、
続けて「名前=値」の形式で内容を記述したもので、
ブラウザ側からサーバ側にデータを送って何らかの処理を行わせ、
Webページの内容に反映させることができる。

関数パラメータ〜
▼プログラミングでは、関数やメソッドなどが呼び出し元から渡された値を受け取るために宣言された変数のことをパラメータという。この意味では「仮引数」（formal argument）と呼ばれることもある。

▼関数やメソッドの定義の先頭などで変数名を列挙して宣言されることが多い。呼び出し側で関数などに引き渡す値などは「引数」（argument）あるいは「実引数」（actual argument）と呼ばれる。
Deep Learnig for Engineer 2022 #2（E資格）の合格体験記

# はじめに
- 筆者について
30代前半。新卒でエネルギー系の会社に入り、SE（Sales Engineer）として勤務しています。職業はIT系を連想させますが、プログラミング経験は無く、AIは凄そうだけど良く分からん！という感じでした。
- E資格を受けるに至った経緯
海外赴任時に、手に職のある人生に憧れを持ちました。AI技術があれば、食いっぱくぐれないだろうという安直な考えから、キカガクさんの”自走できるAI人材育成コース”を受講。コースは半年間で、費用は給付金を活用しても20万円程と高価でしたが、AI技術だけでなく、アプリ作成まで経験が出来、一気にITスキルが上がったと満足しています。コースは卒業したものの、ITエンジニアでもないので、自分のスキルを証明できるものが欲しいと思い、E資格に挑戦しました。

# E資格について（自分的注意点）
- 誰でも受けれる訳ではありません。JDLA公認プログラムを受講する必要があります。※詳細は公式ホームページ[こちら](https://www.jdla.org/certificate/engineer/)から
- 上記公認プログラムも含めて、いちいちお金がかかります。受験料も3万円ほどしますし、教本も5000円近くするのが当たり前です。　
- 合格率が高そうですが、そこそこ勉強が必要です。特に、新シラバスへの移行時は過去の分野と新分野を網羅的にやらなければいけないので、勉強量がかなり増えると思います。（新シラバスに載っていないからと言って、学習を怠ると新分野の理解に支障が出る事があります）なお、E資格の難易度に関して、巷では応用技術情報者相当との声が多い様です。

# E資格学習期間
- 21年10月~22年3月：キカガクさんの”自走できるAI人材育成コースを受講（E資格とはあまり関係ないですが、AI技術の基礎を学べました）
- 22年4月~22年6月：キカガクさんの”E資格対策コース”、”E資格事前問題集”を受講（これがいわゆるJDLAの公認プログラムでこれの受講後に受験資格をもらいました）
- 22年7月：キカガクさんの”G検定対策コース”（AIビジネスをバックグラウンドや全体像をとらえるためにG検定の勉強はとても役にたちました）
- 22年8月28日まで：ひたすら黒本を解く※4週しました。名著です。<img width="400" alt="mojikyo45_640-2.gif" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1269186/b998ec15-0720-2332-eaa0-af5571e61fa6.png>
引用元：https://www.amazon.co.jp/dp/4295011584

# E資格勉強を振り返って
- 数式や原理は暗記するくらい理解した方がいいです。テストでは時間が無く、瞬発的な判断が求められる事が多いです（AIエンジニアの実務現場もそうなのでしょうか？）
- Pythonのコードに慣れないと実装問題はかなり厳しいと思います。自分はいまだに良く分かっておらず、これからゼロつくを使って学習を進める予定です。
- AI技術は日進月歩、勉強に追いついていくのが大変でした。特に新シラバス対応で、Numpyだけでなく、TensorFlowやPyTorchも出題範囲に含まれており、新分野は教材も少なかったため、キャッチアップするのが大変でした。

# 最後に
- 色々とハードルのあるE資格でしたが、私は受講してよかったです。自分が知らない世界を体系的に学べ、視野が広がったと思います。ただし、既に現場で活用されている方には不要かもしれないです。初学習者や学生の方には非常にお勧めです。
- 最後に私の得点です。多分ギリギリ合格レベルだと思います。
応用数学：70 ％
機械学習：56 ％
深層学習：76 ％
開発環境：91 ％
ラズパイ Ubuntu 20.04 server + Desktop 化

# Ubuntu 20.04 の Desktop 版が欲しい！
ラズパイ用の Ubuntu 20.04 Desktop 版のイメージが見当たらず。

Ubuntu 20.04 Server を Desktop 化するスクリプトを使いましょう。

ROS Noetic をラズパイで使いたかったので、行った作業を書いておきます。

（参考にした記事にありますが、基本は公式の apt install ubuntu-desktop で、元 Ubuntu Desktop Team らしき方のスクリプトを追加実行する形です。）


# 手順

## 1. Raspberry Pi Imager

https://www.raspberrypi.com/software/

Raspberry Pi Imager で、Ubuntu 20.04 (64bit) server を選びSDカードに書き込みました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478524/5fd02c3a-d9e9-eea2-fc91-17dcdbf6ace7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478524/efe06d47-254e-97ea-ca38-dfc1b553f737.png)

（時間がたつと古いOSはこのメニューに出てこなかったりするので、下記URL等から-raspi- とついた別のイメージを探してきてもOKです）

https://old-releases.ubuntu.com/releases/20.04/


## 2. 起動して Desktop 化スクリプト実行

スクリプトやapt インストールのために LAN ケーブル接続して実行します。
（WiFi にコンソールから設定して接続してもOKですが、面倒だったので）

```
ID: ubuntu
pass: ubuntu
# 新しいパスワード実行

# ログインできない場合は、なにやら画面１ページ分のログが出たあとじゃないとログインできない？
```

```
sudo apt update
sudo apt install ubuntu-desktop

# 何やら最初のアップデートが裏で動いて、apt できない時があります。待つ or 強制再起動
# Waiting for cache lock: Could not get lock /var/lib/dpkg/lock-frontend. It is held by process 3250 (unattended-upgr) ... 43s
# といった表記

git clone https://github.com/wimpysworld/desktopify.git
# 英語キーボード設定になっていると、Shift + [;]が : コロンになりました
cd desktopify

sudo ./desktopify --de ubuntu --oem          #--oem オプションをつけて、初期設定できるようにしてる

sudo reboot
```


## 3. 以上♪



# 参考

https://gihyo.jp/admin/serial/01/ubuntu-recipe/0624
何年か前の今日の日経春秋を検索するブックマークレット

入力した[数値]年前の今日の日経春秋を検索する。

以下のどちらかで設定。

## 方法1

https://caiorss.github.io/bookmarklet-maker/

上記の生成ツールに下記のソースをコピーアンドペーストし、タイトルをつける。
Generate Bookmarklet ボタンを押し、作成された「春秋検索」リンク（下図青文字箇所）をブックマークバーなどにドラッグアンドドロップする。

```JavaScript
var defaultSub = "3";
var subYaer = prompt("何年前の記事を検索しますか？（半角数字を入力）", defaultSub);

var today = new Date();
var year = today.getFullYear();
var month = today.getMonth() + 1;
var day = today.getDate();
var calcYear = year - subYaer;

var baseUrl = 'https://www.nikkei.com/search?keyword='
  + 'to%3A' + calcYear + '%2F'
  + month + '%2F' + day
  + '++from%3A' + calcYear + '%2F'
  + month + '%2F' + day
  + '++%E6%98%A5%E7%A7%8B&volume=10';
window.open(baseUrl);
```

![春秋.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19223/e4908fd5-09c8-513a-966b-76393145e52b.png)


## 方法2


もしくはブックマークのページを追加を行い、URLに下記をペーストする。

```JavaScript
javascript:(function()%7Bvar%20defaultSub%20%3D%20%223%22%3B%0Avar%20subYaer%20%3D%20prompt(%22%E4%BD%95%E5%B9%B4%E5%89%8D%E3%81%AE%E8%A8%98%E4%BA%8B%E3%82%92%E6%A4%9C%E7%B4%A2%E3%81%97%E3%81%BE%E3%81%99%E3%81%8B%EF%BC%9F%EF%BC%88%E5%8D%8A%E8%A7%92%E6%95%B0%E5%AD%97%E3%82%92%E5%85%A5%E5%8A%9B%EF%BC%89%22%2C%20defaultSub)%3B%0A%0Avar%20today%20%3D%20new%20Date()%3B%0Avar%20year%20%3D%20today.getFullYear()%3B%0Avar%20month%20%3D%20today.getMonth()%20%2B%201%3B%0Avar%20day%20%3D%20today.getDate()%3B%0Avar%20calcYear%20%3D%20year%20-%20subYaer%3B%0A%0Avar%20baseUrl%20%3D%20'https%3A%2F%2Fwww.nikkei.com%2Fsearch%3Fkeyword%3D'%0A%20%20%2B%20'to%253A'%20%2B%20calcYear%20%2B%20'%252F'%0A%20%20%2B%20month%20%2B%20'%252F'%20%2B%20day%0A%20%20%2B%20'%2B%2Bfrom%253A'%20%2B%20calcYear%20%2B%20'%252F'%0A%20%20%2B%20month%20%2B%20'%252F'%20%2B%20day%0A%20%20%2B%20'%2B%2B%25E6%2598%25A5%25E7%25A7%258B%26volume%3D10'%3B%0Awindow.open(baseUrl)%3B%7D)()%3B
```

![春秋ブラウザ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19223/f48bd664-4627-991a-4ba4-22fdfa3ebfd9.png)
YouTube Data API v3 で Queries per day がゼロになっているとき

# はじめに
日本語の情報が無かったので書いておきます。参考元は [stack overflow: Youtube Queries per day becomes to zero](https://stackoverflow.com/questions/62125548/youtube-queries-per-day-becomes-to-0) です。

# 起きた問題
久しぶりに YouTube Data API v3 でチャンネルの動画一覧を得る python コードを走らせたら、 quotaExceeded という表示とともに HttpError が出ました。
Google Cloud Platform を確認してみると、Queries per day がゼロになっていました。
![スクリーンショット 2022-09-19 19.54.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/982991/21f5532c-0c20-b7a1-069d-21f81ab5f66d.png)
同様の報告は
* [teratail: YouTube Data API v3が登録したばかりなのにquotaExceededが返ってくる](https://teratail.com/questions/270779)
* [最初から「quotaExceeded」で割当超過 - YouTube Data API v3](https://shattered-blog.com/archives/43752)
にもありました。


# 解決法
プロジェクトを新たに作り、APIキーを新たに発行することで解決しました。別アカウントである必要はありませんでした。
![スクリーンショット 2022-09-19 19.54.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/982991/cab515dc-e075-bfbd-2de5-d2b208ba3c00.png)
PHP、functionの呼び出し方法

function.phpにある関数をmain.phpへ呼び出す方法は下記の方法になる。

※呼び出す〜〜phpの<?php のすぐ下に
「   require_once('common/function.php');　　　　　」
を入れることによって呼び出すことができるようになる。 


```javascript
<?php
require_once('common/function.php'); 
//main.php
session_start();  //サーバーの値を保持するためにsession_start~を使用する

require_once('common/function.php');  //commonファイルのfunction.phpを接続する
if(!isset($_SESSION['csrf_token'])) {  ///csrf_token変数に値が入っているかどうかを確認するためのisset関数
★  $_SESSION['csrf_token'] = random();  //ランダムにsessionが変わるごとにcsrf_tokenが発行される。
}
...
...
...
...
...
...
...
...
<?php foreach($todos as $todo): ?>
 ★ <p><?php echo h($todo["id"]) ?></p>  <!-- h()関数でハッキング対策する。 -->
 ★ <p><?php echo h($todo["todo"])?></p> 
 ★ <p><?php echo h($todo["created_at"] )?></p> <!--  -->
  <a href="edit.php?id=<?php echo $todo['id'] ?>">編集</a>
<?php endforeach ?>


//function.php
function h($str) {
    return htmlspecialchars($str, ENT_QUOTES|ENT_HTML5, "UTF-8");
}

function random($length = 16) {
    return substr(bin2hex(random_bytes($length)), 0, $length);
}
?>

```

main.phpからfunction.phpを呼び出す方法。

・function.phpの中にある「random関数」を呼び出す場合は
main.phpで「　random();　」をすることで呼び出すことができる。

　

・function.phpの中にある「h関数」を呼び出す場合は
main.phpで「　h();　」をすることで呼び出すことができる。
ラズパイ（Ubuntu）モニタレスで VNC

# 超便利　モニタレス VNC

モニタレスでラズパイをリモートデスクトップ操作すると便利　＼（＾＾）／

ページ最後の方の「モニタレスの設定」をすることで、ラズパイ起動前後の関係無しにHDMIモニタケーブルの抜き差しをしても大丈夫です（これ大事）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478524/2eb73dec-226f-629f-ce2e-4afa5c35fdb7.png)
メインPCからリモートデスクトップ


# 環境
Raspberry Pi 4
Ubuntu 20.04 (64bit) server + desktop 化


# セットアップ

### VNC 設定

* 最初はHDMI等モニタを接続して、ラズパイを起動します。
* WiFi や LAN ネットワークに接続します。
* VNC をUbuntu 設定から有効にします。

   + アプリケーション　→　設定
   + 共有　→　画面共有
   + スライダーをONにして有効にします。
   + コンピュータ名も設定します。
   + VNC用のパスワードを設定しましょう。
   + 利用するネットワークの項目のスライダーをONにして有効にしましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478524/993ef6b0-1835-cd71-a89a-884a2cce59f3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478524/f5ef4bbb-776c-5135-d2ad-ed0b966d7db2.png)

   + ↑ LAN から WiFi にするときは、改めて有効にしないといけません。接続タイプごとに有効にする。

### SSH 設定

* ついでに下の リモートログイン（SSH）も有効にしましょう。設定を誤った時に便利です。 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478524/4280f438-de5f-c6c8-09c4-9b28fa030407.png)


### 自動ログイン設定

* また、ユーザーログインを自動ログインにしましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478524/0244ee0b-4189-cbd6-5cc8-47aac37b7d3a.png)



### セキュリティコマンド設定

* ターミナルを起動し、下記コマンド１行を実行します（セキュリティの設定を変更します。）
* これを実行しないと VNC はつながりません。

```
gsettings set org.gnome.Vino require-encryption false

# Vino の頭文字は大文字です。
# sudo は無しで行わないといけないようです
```

### クライアントから接続

* 再起動して、お好きな VNC クライアントソフトから先程設定したコンピュータ名で接続してみましょう。
* クライアント例：　Remmina（for Ubuntu）、VNC Viewer / UltraVNC （for Windows）



## モニタレスの設定

* 上記設定だけでは、モニタケーブルを外してラズパイ起動した際に、VNCが利用できません。（リモート接続するデスクトップが設定されていない感じ）
* /boot/firmware/config.txt に下記を追加して再起動します。

* これで、モニタケーブルを接続しないでラズパイ起動しても大丈夫です。

```
hdmi_force_hotplug=1
hdmi_group=2
hdmi_mode=27
```

* hdmi_mode=27 は 解像度設定(1280x800)です。（下記URL参照）

https://www.raspberrypi.com/documentation/computers/config_txt.html#video-options

* 電源を切り、改めて起動をするのですが、その際HDMIケーブルは外して試してみましょう。
* うまくいかない時は再度HDMIケーブルをつなげて設定を確認します。
* モニタに上記解像度がうまく表示できなくて表示すらされなくなった際には、SSH ログインして vi などコンソールテキストエディタを利用し設定をやり直しましょう。

### samba

ついでに Win とのファイル共有 samba 設定もすると最強便利です

https://qiita.com/devemin/items/483e89c334c9944fa24e


### ssh -YC 

ssh -YC コマンドというものもあるそうです。便利そう！

https://twitter.com/porizou1/status/1570021948977197057?s=20&t=oz3rQd_4w7Hnj9o16usCMw



### おかしくなったら

接続できない場合は、WiFi接続、機能の有効無効確認、モニタを再度接続したり、SSH接続から設定したり、設定ファイルの修正やり直しなど、戻って確認してみてください。
(SDカードを別のPCなどにつないで設定ファイルを編集することもできます。そのときは /system-boot/config.txt というパスになる)

# 参考

https://twitter.com/devemin/status/1540127124837003264?s=20&t=s4xdHBWSOYOHbFSG6-ASJw