OmniAICreator/Qiita-1.07M huggingface dataset:
Oracle マルチテナントDBでPDBの起動を自動化するコマンド

# PDBの自動起動

11gや12cから19cになるとマルチテナント構成が必須となるため、
不慣れだとPDBを起動し忘れることがある。
その場合はPDBを自動起動に設定することで解消される。

```sql:通常起動の場合
sqlplus / as sysdba
SQL>startup
SQL>show con_name

CON_NAME
------------------------------
CDB$ROOT

SQL>show pdbs
# CDBを起動するとPDBはMOUNT状態
    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 SAMPLEPDB                      MOUNTED

# ALTER文でOPENする必要がある
SQL>alter pluggable database SAMPLEPDB open;

SQL>show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 SAMPLEPDB                      READ ONLY  NO
```

```sql:自動起動の設定
SQL>alter pluggable database SAMPLEPDB save state;
```
**※上記のコマンドは現在の状態をセーブするため、PDBを起動した状態で実行する必要がある。**

```sql:自動起動の場合
sqlplus / as sysdba
SQL>startup
SQL>show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 SAMPLEPDB                      READ ONLY  NO
```
`npm install axios`したら404出たんだけど

「よーし、Rails API　× Vue.jsで簡単なTodoアプリ的なものを実装しよ」

・・・10分後・・・

「非同期でHTTP通信したいときには一般的に`axios`を使うのね。よーし、インストールしてみよ〜」ポチッと

```bash:ターミナル
❯ npm install --save axios            
npm ERR! code E404
npm ERR! 404 Not Found - GET https://registry.npmjs.org/@vue%2fvue-loader-v15 - Not found
npm ERR! 404 
npm ERR! 404  '@vue/vue-loader-v15@15.9.8' is not in the npm registry.
npm ERR! 404 You should bug the author to publish it (or use the name yourself!)
npm ERR! 404 It was specified as a dependency of '@vue/cli-service'
npm ERR! 404 
npm ERR! 404 Note that you can also install from a
npm ERR! 404 tarball, folder, http url, or git url.

```

「ほえ？なんだこれは...最近Vue.jsとやらを触り始めたばかりなんだが...」

## 結論

結論としては`vue-loader-v15`が`npm`の`registry`からセキュリティ上の理由により削除されたためのようですね〜

Nodeのバージョンを上げるか、`yarn`コマンドで実行すると上手くいくみたいです。

>参照：[GitHub Issues](https://github.com/vuejs/vue-cli/issues/7098)

```bash:ターミナル
$ yarn add axios
```

>参照：[Getting Started -axios-](https://axios-http.com/docs/intro)

```bash:ターミナル
$ yarn add axios                        
yarn add v1.22.17
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...
success Saved lockfile.
success Saved 5 new dependencies.
info Direct dependencies
└─ axios@0.27.2
info All dependencies
├─ asynckit@0.4.0
├─ axios@0.27.2
├─ combined-stream@1.0.8
├─ delayed-stream@1.0.0
└─ form-data@4.0.0
✨  Done in 2.52s.
```

```json:package.json
"dependencies": {
    "axios": "^0.27.2",
    "core-js": "^3.8.3",
    "vue": "^3.2.13",
    "vue-router": "^4.0.3",
    "vuex": "^4.0.0"
  }
```

「ふぅ〜、これでゴリゴリ進めていくぞ〜」

> 設定ファイルをいじるやり方もあるみたいです(記事が少し古いのでなんとも言えません)
> 参考：[npmでのインストールが404エラーになってたが原因はregistryの設定ファイルだった](https://webtobira.com/web/909/)

## 参考

- [@vue/vue-loader-v15](https://www.npmjs.com/search?q=%40vue%2Fvue-loader-v15)
Svelteに入門してみた

かなり前だけど社内で最強クラスのエンジニアが紹介していたのを聞いて面白そうだったので。
SSRは試してません。

# Svelteとは
Rich Harrisにより開発されたJavaScript Webフレームワーク。
ReactやVueなどはランタイムライブラリで仮想DOMを扱うが、Svelteを利用したアプリケーションは直接DOMを操作するコードに「コンパイル」される。

https://svelte.jp/

コンポーネントはVueのようにSFC（Single File Component）で構成する（拡張子は`.svelte`）。
Vueと異なり`<template>`タグではなくSFC内のトップレベルにHTMLを記述する。

TypeScriptもサポート。

# Svelteいいね
- 単にコンポーネント内の変数に代入するだけでDOMが更新される
  `useState`みたいなものはいらない
- ある値に依存して更新が必要な情報（いわゆるcomputed property）も`$`を用いて
  `$: doubled = count * 2`
  のように書くだけで`count`が更新されると`doubled`（を参照しているDOM）も更新される
- ストアが用意されている
  状態管理に何を使おうか悩む必要なし
  readable/writableがある
- イベントハンドラをインラインで記述してもパフォーマンス上のペナルティなし
  バンザイ
- 公式チュートリアルが秀逸
  動くチュートリアルで分かりやすく学べる
- 日本語ドキュメントが充実
  英語でも読めるけど母国語の方が圧倒的に速い。有志のみなさん、ありがとう

# Svelteつらいね
- 始め方が２通りある
  現時点で、`sveltejs/template`をdegitする方法とSvelteKitを使う方法とがあり、どっちにしたらいいのか迷う
  進化途中なので仕方ないかも
- これと関連するのかも知れないが、ライブラリの導入が手間取る
  UIライブラリはあれこれやって断念
  TailwindCSS入れるのにも苦労した
- ちょっとしたコンポーネントもSFC作る必要がある
  リスト項目とかテストで使うとか、ちょっとここに作りたいねん、ができない
  React、関数コンポーネントという選択は大正解やで・・・

# まとめ
速いのは正義。バンドルサイズが小さくて動作が速いSvelteは強いと思います。
既に広く利用されているようなので上に挙げたようなツラみも、自分が知らないだけでどうにかなるものかも知れません。

次は[2021 State of JS](https://2021.stateofjs.com/ja-JP/libraries/front-end-frameworks/)でSvelteより満足度の高かったSolidに入門してみようかな。
react-i18nをテストしたい

react-i18nを多言語化で使っていて、翻訳された結果の文字列をテストで確かめたかったのですが、key名しかテストではレンダリングされず、公式にも一応やり方は書いてあるのですが、分かりづらい上に動かなくて困っていました。

#### 公式では...

公式docに記載の情報だとこうです。このjest.mockを使う方法が紹介されているのですが、またkey名しか表示されず...

```index.test.js
jest.mock('react-i18next', () => ({
  // this mock makes sure any components using the translate hook can use it without a warning being shown
  useTranslation: () => {
    return {
      t: (str) => str,
      i18n: {
        changeLanguage: () => new Promise(() => {}),
      },
    };
  },
}));
```

で、参考にしたやり方がこちら。

```index.test.js
import React from 'react';
import i18n from '../../../i18n' // your i18n config file
import { render } from '@testing-library/react';
import ComponentName from './ComponentName';
import { I18nextProvider } from 'react-i18next'

test('renders all documents in the list', () => {
    render(
      <I18nextProvider i18n={i18n}> 
         <ComponentName />
      </I18nextProvider>
    );
    expect(screen.getByTestId('testId').getByText('ほげふげ')).toBeTruthy(); 
});
```

[参考記事](https://stackoverflow.com/questions/57148082/how-can-i-enable-react-i18n-translation-file-to-be-used-in-the-unit-tests-done-w)
【Django】models.pyでデフォルト値を作成時刻にする方法

よく作成時間のカラムを作成するのに、
デフォルト値を作成時間にすることがあるかと思います。
その際に発生したWARNINGメッセージについて記載します。

## 各バージョン

* Django: 4.0
* Python: 3.10.2

## WARNING発生時のmodels.py
デフォルト値を作成時間にした際のmodels.py
```models.py
from django.db import models
from datetime import datetime
# Create your models here.

class Todo(models.Model):
  title = models.CharField(max_length=100)
  description = models.TextField(blank=True, null=True)
  create_time = models.DateTimeField(default=datetime.now())
  update_time = models.DateTimeField(default=datetime.now())
  limit_date = models.DateField(null=False)
  status = models.BooleanField(default=False)
```
datetimeを使用してnowで作成された時間をcreate_timeカラムとupdate_timeカラムに入れようとします。

## WARNINGメッセージ
python manage.py makemigrationsを実行した時のログは以下です
```
WARNINGS:
todo.Todo.create_time: (fields.W161) Fixed default value provided.
	HINT: It seems you set a fixed date / time / datetime value as default for this field. This may not be what you want. If you want to have the current date as default, use `django.utils.timezone.now`
todo.Todo.update_time: (fields.W161) Fixed default value provided.
	HINT: It seems you set a fixed date / time / datetime value as default for this field. This may not be what you want. If you want to have the current date as default, use `django.utils.timezone.now`
```
翻訳してみると以下です
```
todo.Todo.create_time: (fields.W161) 固定されたデフォルト値が提供されています。
HINT: このフィールドにはこれは、あなたが望むものではない可能性があります。もし現在の日付をデフォルトにしたいのなら、 `django.utils.timezone.now` を使ってください。
todo.Todo.update_time: (fields.W161) デフォルト値が提供されるように修正されました。
	HINT: このフィールドには、固定された日付/時間/日時の値をデフォルトとして設定しているようです。これは、あなたが望むものではない可能性があります。現在の日付をデフォルトにしたい場合は、 `django.utils.timezone.now` を使ってください。
```
>もし現在の日付をデフォルトにしたいのなら、 `django.utils.timezone.now` を使ってください。

まさしくここですね

## models.py修正
以下に修正します
```models.py
from django.db import models
from django.utils import timezone
# Create your models here.

class Todo(models.Model):
  title = models.CharField(max_length=100)
  description = models.TextField(blank=True, null=True)
  create_time = models.DateTimeField(default=timezone.now())
  update_time = models.DateTimeField(default=timezone.now())
  limit_date = models.DateField(null=False)
  status = models.BooleanField(default=False)
```

## リトライ
```python manage.py makemigrations```をリトライすると同じWARNINGメッセージが、、、

## 再修正
 timezone.now()の()を削除します
```models.py
from django.db import models
from django.utils import timezone
# Create your models here.

class Todo(models.Model):
  title = models.CharField(max_length=100)
  description = models.TextField(blank=True, null=True)
  create_time = models.DateTimeField(default=timezone.now)
  update_time = models.DateTimeField(default=timezone.now)
  limit_date = models.DateField(null=False)
  status = models.BooleanField(default=False)
```

## リトライ
```python manage.py makemigrations```をリトライするとWARNINGが消えました

```
Migrations for 'todo':
  todo/migrations/0003_alter_todo_create_time_alter_todo_update_time.py
    - Alter field create_time on todo
    - Alter field update_time on todo
```
Reactのチュートリアル用のRepositoryを作りました(とハンズオンの感想)

# 初めに

社内でReactのチュートリアルハンズオン(オンライン)を実施した際の教材をご紹介します。
Reactってそもそも何？とか環境構築などについてはあえて省いています。単発のハンズオンで時間も限られていたため「Reactを利用する案件に配属された際にとりあえず右と左くらいは分かるようになっていよう」を目標に据えていたためです。

# 成果物

https://github.com/pbuchihori/react-tutorial

# ハンズオンについて

ハンズオンについての感想も簡単に書いておきます。

## 実施形態

ハンズオンはCodeSandBoxで(state管理など)題目ごとにディレクトリを分けて配置した教材を作成し、それぞれ簡単な説明を付けた後、課題を伝え手を動かしてコードを書いてもらいます。その後解説やフィードバックを行いました。

### CodeSandBoxって？

Webアプリのフロントエンドの環境・コードエディタをブラウザ上で提供してくれます。React・VueなどのフレームワークやJS/TSなど様々なテンプレートがあり、簡単な技術的検証や成果物の共有に利用できます。作ったサンドボックスはURLで共有できるので楽ちんです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619165/7cbb406b-3292-1ba1-894c-e674ef7ba332.png)
こんな感じでブラウザ上で開発に必要な機能が一通り提供されています。
左下から簡単にライブラリを追加でき、検証環境を作るのも楽ちんです。

## 感想

感想としては主に以下のようなことを思いました。

1. CodeSandBoxは強力だがハンズオン的には課題あり
1. ES2015(ES6)についての解説が必要だった…

### 1.CodeSandBoxは強力だがハンズオン的には課題あり

CodeSandBoxはハンズオン実施時に事前の環境構築等不要でURLを参照するだけでいいので、かなりハンズオンなどに使いやすいと思いました。
(GithubにもRepositoryとして教材を残せますし)

ただし、各人がどのようなコードを書いているか見えにくいのが課題のように感じました。学校のように黒板に答えを書かせるようなことが難しいということです。各課題ごとに数名を指名してどのようにコードを書いたかを尋ねましたが、この際に参加者全員が見えるところでコードを書いてもらうようにできるととより理解が深まるのかなと思いました。LiveShareの活用など色々試行錯誤してみたいです。

### 2.ES2015(ES6)についての解説が必要だった…

チュートリアルということで内容自体はかなり簡単にすることを心掛けたのですが、質問が出るまでES2015(ES6)が所与の知識になっていることに全く気付きませんでした。アロー関数、スプレッド構文、分割代入などやりたい放題ですね。チュートリアルという視点からいうとこの辺りは前提知識とせず古い書き方をしてもよかったかもしれません。


# 終わりに

ハンズオン自体は面白い経験だったので今後も発信を続けていきたいなと思いました。
SECCON Beginners 2022 textex (easy)

久しぶりにCTFの問題を触ったので1問だけだけどwriteup残しておく
beginnersなので、1時間もあれば全問解けるやろとか思ってたら、1時間起きてるのすら無理だった。
リハビリして行こうと思います。

---

textex (easy)

* texをpdf化するwebサービスが稼働している
* app.pyと同フォルダに存在するflagというファイルの中身をgetするのが目的

サーバのソースコードもzipで貰えるので、展開してdocker upとかすればローカルで実験出来ただろうけど、コード読んだら満足したのでやってない

~~~app.py
def tex2pdf(tex_code) -> str:
    # Generate random file name.
    filename = "".join([random.choice(string.digits + string.ascii_lowercase + string.ascii_uppercase) for i in range(2**5)])
    # Create a working directory.
    os.makedirs(f"tex_box/{filename}", exist_ok=True)
    # .tex -> .pdf
    try:
        # No flag !!!!
        if "flag" in tex_code.lower():
            tex_code = ""
        # Write tex code to file.
        with open(f"tex_box/{filename}/{filename}.tex", mode="w") as f:
            f.write(tex_code)
        # Create pdf from tex.
        subprocess.run(["pdflatex", "-output-directory", f"tex_box/{filename}", f"tex_box/{filename}/{filename}.tex"], timeout=0.5)
    except:
        pass
    if not os.path.isfile(f"tex_box/{filename}/{filename}.pdf"):
        # OMG error ;(
        shutil.copy("tex_box/error.pdf", f"tex_box/{filename}/{filename}.pdf")
    return f"{filename}"

@app.route("/pdf", methods=["POST"])
def pdf():
    # tex to pdf.
    filename = tex2pdf(request.form.get("tex_code"))
    # Here's your pdf.
    with open(f"tex_box/{filename}/{filename}.pdf", "rb") as f:
        pdf = io.BytesIO(f.read())
    shutil.rmtree(f"tex_box/{filename}/")
    return send_file(pdf, mimetype="application/pdf")
~~~

* 読んでいると、"flag"という文字列が空白に置き換えられてしまう
  * きっとtexでローカルファイルをincludeする的な問題だろうな～と思い始める
* ファイルが存在しないとか、texの文法がおかしいとか、何かあったら、error.pdfが表示されそう

ぐらいのところが判明したので、とりあえずコメントアウトでflagを指定してみたが、なぜかerror画面が表示される

~~~tex
\documentclass{article}
\begin{document}

This is a sample.

\input{f%
lag}

\end{document}
~~~

* しばらく試行錯誤したり、texの文法を眺めていると、どうやらinput{}は拡張子を指定しない場合、texとして読み込むらしい
  * つまり、flag = flag.texとして読み込まれるので、存在しないファイルとなる

その後も、inputに何か裏技とかオプションとかあるんじゃないかと文法等眺めるも見つからなかったので、リモートコード実行出来るプラグインが実は使えるのではとか色々試すものの刺さらず

諦めて寝る前になんとなくpdfとして呼んでみた

~~~tex
\documentclass{article}
\begin{document}

\pdffiledump offset 0 length \pdffilesize{f%
lag}{f%
lag}

\end{document}
~~~


とすると、エラーにならずに下記が表示された

~~~
63746634627B31355F3733785F7072306E30756E6333645F636830753F7D
~~~

あとは、cyberchefを利用して文字列に直せば

~~~
ctf4b{15_73x_pr0n0unc3d_ch0u?}
~~~

tex使いなら2秒で解けたのだろうなと思いながら寝落ちをしたのでした。

---

これ想定解・・・かな？
jQuery 特定の要素を取得 特定の要素の前後に要素を追加 eq()

## eq()

```html:例として使うhtml
<ul>
  <li>赤</li>
  <li>青</li>
  <li>白</li>
  <li>黒</li>
</ul>
```

```js:白を取得する
var color = $('li').eq(2).text();
 
console.log(color);
// 白
```

**解説**
`eq()` は
- 複数あるHTML要素の中からインデックス番号を指定することで特定の要素だけを取得できます。
- 引数には、取得したいインデックス番号を入力します。
- HTML要素のインデックス番号は０番から始まります。
なので最初の要素のインデックス番号は０、2番目の要素のインデックス番号は１になります。
- 例の場合は、「白」を取りたかったので引数に2を入れました。

### 特定の要素の前に要素を追加
```html:例として使うhtml
<ul>
  <li>赤</li>
  <li>青</li>
  <li>黒</li>
</ul>
```
```js:黒の上に白を追加する
$('li').eq(2).before('<li>白</li>');
```
```html:追加後のhtml
<ul>
  <li>赤</li>
  <li>青</li>
  <li>白</li>
  <li>黒</li>
</ul>
```
**解説**
黒の上に追加したいので `eq()` の引数には「2」を指定します。
`before()` は指定した要素の直前に要素を追加します。
`before()` の引数には追加したい要素を指定します。例の場合は、 `<li>白</li>`です。


### 特定の要素の後に要素を追加
```html:例として使うhtml
<ul>
  <li>赤</li>
  <li>青</li>
  <li>黒</li>
</ul>
```
```js:青の下に白を追加する
$('li').eq(1).after('<li>白</li>');
```
```html:追加後のhtml
<ul>
  <li>赤</li>
  <li>青</li>
  <li>白</li>
  <li>黒</li>
</ul>
```
**解説**
青の下に追加したいので `eq()` の引数には「1」を指定します。
`after()` は指定した要素の直後に要素を追加します。
`before()` の引数には追加したい要素を指定します。例の場合は、 `<li>白</li>`です。
【Rails】ActionCable~用語について~

## はじめに
実装の流れは長くなるので省略させていただきます。
自分が疑問に思ってノートに記録した物を記事にしていきます。

## 前提条件
Ruby 2.6.3
Rails 6.1.5

## 用語について
ActionCableとwebsocketを使用するにあたり、新しい用語がいくつか出てきました。
以下の通りです。

・コネクション
通信方式のこと。プロトコルとしてはTCPがコネクション型、UDPがコネクションレス型。
TCPは一般的なHTTP/HTTPSリクエスト&レスポンスの通信で使用されている。
websocketの通信方法でも使用されており、websocketコネクションをオープンすることで通信を確立する。

・コンシューマー
websocketコネクションのクライアントのこと。

・チャネル
MVCでいうコントローラーの役割を果たす。
ボタンなどで発火されるとチャネルのアクションが実行されるみたいなイメージ？
チャネルはコンシューマーをサブスクライブ（利用登録）できる。
コンシューマーは複数のチャネルにサブスクライブされることが可能。

・サブスクライバ
コンシューマーが、チャネルにサブスクライブされた後の振る舞いの事。

用語を理解すると処理の流れが理解しやすくなりました！
【Laravel】Requestをそのままコントローラー外に渡さない【リファクタリング】

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


## Bad

```$request```をそのまま引数として渡してしまっているのが問題。
引数1つで済むからいっか！とやってしまっていた。

```app/Http/Controllers/Api/PostController.php
public function store(PostRequest $request)
{
   $request->user()->givePost($request);

   return response()->json(Response::HTTP_OK);
}
```

```app/Models/User.php
public function givePost(Request $request): Post
{
   $post = $this->createPost($request->content, $request->title);
   // このあとの処理は省略

   return $post;
}
```

教訓：```Request```をそのままコントローラー以外に渡さない！

渡すには大きすぎるという例えで分かりやすかったのが、ホームセンターの例。
庭に木を植えたいとしたら、ホームセンターに売ってる木だけほしいのにホームセンターごと渡されてるようなものらしい。
そりゃデカいわと納得！



## Better

```$request```の中の何を渡すのかを明示する。
この場合は下記
>```$request->content```
```$request->title```

```app/Http/Controllers/Api/PostController.php
public function store(PostRequest $request)
{
   $user->givePost($request->content, $request->title);

   return response()->json(Response::HTTP_OK);
}
```

```app/Models/User.php
public function givePost(string $content, string $title): Post
{
   $post = $this->createPost($content, $title);
   // このあとの処理は省略

   return $post;
}
```
jQuery unwrap() 親要素を削除する

## unwrap()　親要素を削除

```html:例で使うhtml
<div class="hoge1">
  <span class="hoge2">子要素です</span>
</div>

<button class="button">要素を削除します</button>
```

```js:親要素を削除
$(".button").on("click", function(){
  $(".hoge2").unwrap();
});
```

```html:削除後のhtml
<span class="hoge2">子要素です</span>

<button class="button">要素を削除します</button>
```
**解説**
`unwrap()` は、指定した要素の親要素を削除し、指定した要素は残します。
例の場合は、親要素である `hoge1クラス` のみを削除して、指定された `hoge2クラス` は残します。
Next.jsの環境変数について、便利と感じたことメモ

## Next.jsの環境変数(.env)の種類
| ファイル名 | 実行環境 |
|:-:|:-:|
| .env | 常に読み込み |
| .env.development | 開発環境 |
| .env.production | 本番環境 |
| .env.local | 常に読み込み |
| .env.development.local | 開発環境 |
| .env.production.local | 本番環境 |

.envのファイル名に応じて、開発環境と本番環境で切り替えるとこができる。
僕が使ったのは`.env.local`だけでした。

### 使って便利だと思ったこと
フロント側とバックエンド側で開発環境を分けていて、
どちらもローカル環境で動かしていた時、
APIと叩く際に、呼び出すすべてのエンドポイントで、
`http://localhost/api/hoge`
のような形で記述していると、stg環境に反映させる場合、
`http://localhost/`
と記述したすべてのソースを直さなければならなくなり、かなり面倒です。
また、ある程度開発が進んでいって、ローカル環境のAPIを叩かず、
stg環境に反映されているAPIを使うようになると、これまたすべて変更しないといけないので、
これも面倒です。
※下記のような場合
```index.tsx
export async function test() {
  const res = await axios.get("http://localhost/api/hoge");
  console.log(res.data);
  return res;
}
```

なので、環境変数にAPIのパスを指定してあげて、
環境変数からパスを呼び出してあげれば、叩きたいパスが変わっても
環境変数を直してあげれば、すべてのパスが変わってくれます。

#### 環境変数の定義
下記が参考例になります。

```.env.local
ローカル環境のAPIを叩きたい時の例
NEXT_PUBLIC_API_ENDPOINT="http://localhost/"
```
```.env.local
stg環境のAPIを叩きたい時の例
NEXT_PUBLIC_API_ENDPOINT="http://stg/"
```

環境変数を使用した場合の例
```index.tsx
export async function test() {
  const res = await axios.get(`${NEXT_PUBLIC_API_ENDPOINT}api/hoge`);
  console.log(res.data);
  return res;
}
```
こうしてあげることで、定義された環境変数が反映されます。
localhostだったらこんな感じ
`axios.get("http://localhost/api/hoge");`

stgだったらこんな感じ
`axios.get("http://stg/api/hoge");`

以上、Next.jsの環境変数について、便利だと感じたことでした。
実際に動かしていないので、間違いなどあればご指摘いただけますと幸いです。🙇‍♂️
【Laravel・Rails】親が削除されたらリレーション先の子テーブルも削除する方法まとめ

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

## Laravel
### cascadeOnDelete()
マイグレーションファイルでやる方法。

```php
Schema::table('posts', function (Blueprint $table) {
    $table->foreignId('user_id')->constrained()->cascadeOnDelete();
});
```

https://readouble.com/laravel/9.x/ja/migrations.html?header=%25E5%25A4%2596%25E9%2583%25A8%25E3%2582%25AD%25E3%2583%25BC%25E5%2588%25B6%25E7%25B4%2584

### deleting()
modelにロジックを書く方法。
```app/Models/User.php
protected static function boot()
{
   parent::boot();

   self::deleting(function ($user) {
      $user->posts()->delete();
   });
}
```

## Rails
### on_delete: :cascade
マイグレーションファイルでやる方法。


```ruby
add_foreign_key :users, :posts, on_delete: :cascade
```

https://railsdoc.com/page/add_foreign_key

### dependent: :destroy

modelにロジックを書く方法。
個人的にこれをよく使ってた。
```models/user.rb
has_many :posts, dependent: :destroy
```

```models/post.rb
belongs_to :user
```
LaravelBreeze / 6 WARNINGS in child compilations (Use 'stats.children: true' resp. '--stats-children' for more details)のエラー

Laravel8でLaravelBreezeをインストールし、
npm installとnpm run devをした際にエラーが表示されました。
ほっといても問題ないかもですが…
なんとなくそのままにしておくのはちょっと…ということで色々調べて解決できたので、そのことを記事に残しておきます。

## エラーの内容
```
6 WARNINGS in child compilations (Use 'stats.children: true' resp. '--stats-children' for more details)
```
↓
webpack.mix.jsに下記を追記
```javascript
mix.webpackConfig({
    stats: {
         children: true
    }
});
```
↓
もう一度 npm install && npm run dev

## 新たなエラーが発生！
```
(1:1) autoprefixer: Replace color-adjust to print-color-adjust. The color-adjust shorthand is currently deprecated.
```
↓
autoprefixerが何やら原因らしい。

## 解決
```
npm install autoprefixer@10.4.5 --save-exact
```
上記を行ったらエラーが消えました！

参考記事
https://stackoverflow.com/questions/72083968/1-warning-in-child-compilations-use-stats-children-true-resp-stats-child
PHP array_column 連想配列の値を取得

## array_column()

```php:例として使う連想配列
$hoge = [
    0 => [ 'id' => 100, 'color' => 'red', 'team' => 'A'],
    1 => [ 'id' => 200, 'color' => 'blue', 'team' => 'B'],
    2 => [ 'id' => 300, 'color' => 'green', 'team' => 'C' ],
    3 => [ 'id' => 400, 'color' => 'yellow', 'team' => 'D' ],
];
```

### 特定の要素だけ取り出す
```php:例
$hoge = [
    0 => [ 'id' => 100, 'color' => 'red', 'team' => 'A'],
    1 => [ 'id' => 200, 'color' => 'blue', 'team' => 'B'],
    2 => [ 'id' => 300, 'color' => 'green', 'team' => 'C' ],
    3 => [ 'id' => 400, 'color' => 'yellow', 'team' => 'D' ],
];

var_dump(array_column($hoge, 'id'));

// array(size=4)
//  0=>int100
//  1=>int200
//  2=>int300
//  3=>int400
```
**解説**
`array_column()` の
`第1引数` に「対象の配列」
`第2引数` に「取り出す要素のキー名」
を指定すると `「キーのみの配列」` が取得できる。
例の場合はidのみの配列が取得できる。

### 特定の要素をキーに、特定の要素を値にした配列を取得
```php:例
$hoge = [
    0 => [ 'id' => 100, 'color' => 'red', 'team' => 'A'],
    1 => [ 'id' => 200, 'color' => 'blue', 'team' => 'B'],
    2 => [ 'id' => 300, 'color' => 'green', 'team' => 'C' ],
    3 => [ 'id' => 400, 'color' => 'yellow', 'team' => 'D' ],
];

var_dump(array_column($hoge, 'color', 'team'));

// array(size=4)
//  'A'=>string'red'(length=3)
//  'B'=>string'blue'(length=4)
//  'C'=>string'green'(length=5)
//  'D'=>string'yellow'(length=6)
```
**解説**
`array_column()` の
`第1引数` に対象の対象の配列
`第2引数` に値にしたい要素
`第3引数` にキーにしたい要素
を指定すると `「第3引数がキーで第2引数が値の配列」` が取得できる。
例の場合はteamがキーでcolorが値の配列が取得できた。
　
　
　
参考にした記事
https://qiita.com/harukasan/items/a0773aef27d838852e44
コンピュータ名の変更とドメイン参加（自動化）

コンサルやITベンダでは考えてもみませんでしたが、
事業会社のようにPCの設定が多いと大変ですよね。なるべく自動化したいものです。
ということで、まずコンピュータ名の変更とドメイン参加。
コンピュータ名にハイフンがある場合、下記のrename nameのようにダブルクォートで囲まないと「Verbスイッチが無効です」となりうまく入らないので注意。
ドメイン名や他情報は固定で入れる事が多いだろうから、対話型にはしていません。
~~~
@echo off
rem 管理者権限で実行要
rem ユーザ入力
set /p INP="コンピュータ名を入力して下さい >"
echo コンピュータ名を%INP%に変更しています
rem PC名変更
wmic computersystem where name="%computername%" call rename name="%INP%"

pause

rem ドメインへ参加する
wmic ComputerSystem WHERE "name='%computername%'" CALL JoinDomainOrWorkgroup Name="ドメイン名" Username="ユーザ名" Password="パスワード" FJoinOptions=3

pause
exit

echo パソコンを再起動します。	
pause

rem 1秒後に再起動
shutdown -t 1 -r
exit
HTML の基本

HTML の基本

HTML はハイパーテキストをマークアップするための言語で、テキストにさまざまな目印をつけてゆきます。目印をつけたテキストを 要素 (element) といいます。
ページの一番重要な見出しを HTML で表してみます。

<h1>見出し 1</h1>
「見出し 1」というテキストを <h1> と </h1> という目印で囲っています。
この目印を タグ といいます。

タグはタグ名を < と > で囲む
<[タグ名]> を開始タグという
</[タグ名]> を終了タグという
<[タグ名]>テキスト</[タグ名]> を 要素 という
また、要素の中に要素を入れる入れ子構造にすることができます。
この場合の外側の要素を 親要素 、内側の要素を 子要素 といいます。

<body>
<h1>見出し 1</h1>
</body>
body タグに h1 タグが囲まれています。
body タグが親要素、h1 タグが子要素です。

要素にいくつかの設定を追加する場合には 属性 (attribute) を使用します。
たとえばロゴ画像をマークアップする場合に img タグを記述します。
img タグに画像のパスを指定するのは src 属性を使用します。

<img>
💡 終了タグを省略できるタグ

タグの一部には終了タグの記述が省略できるものがあります。

img タグ
br タグ
他にもあるので、調べてみましょう。

img タグに src 属性で画像ファイルのパスを指定します。
src 属性でパスを指定することで HTML に画像が表示されます。

<img src="images/logo.png">
属性はタグ名の後ろに半角スペースを空けて記述する
属性は [属性名]="[属性の値]" の形式で記述する
属性は半角スペースで区切ることで複数記述できる
vue3 vuetify3のCDN使用について

あまり記事がなくて、すごく回り道をしたので同じような悩みを持つ方へのメモ

# vue3 vuetify3の最小構成について
npmとかvue cliとか迷宮に迷い込みやすいですね。。。。
とりあえず、自分でコード書く部分は最小構成あれば2ファイルで。vueとvuetify動きます。
```
/static/index.html
/static/index.js
```
index.htmlで適切なCDNを指定すれば、2ファイルで動きます。
公式サイトだとvuetify3のCDNなかったり、vueのサンプルCDNいつのまにか
vue3になったりと、回り道しました。



# 具体的なソース
index.html
```
<!DOCTYPE html>
<html>

<head>
    <link href="https://cdn.jsdelivr.net/npm/@mdi/font@6.x/css/materialdesignicons.min.css" rel="stylesheet">
    <link href="https://unpkg.com/vuetify@3.0.0-beta.3/dist/vuetify.css" rel="stylesheet">
        <meta name="viewport"
        content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui" />
</head>

<body>
    <div id="app">
        <v-app id="inspire">
            <v-navigation-drawer v-model="drawer" app>
                <!-- サイドメニューバー  -->
                <v-expansion-panels>
                    <v-expansion-panel
                      v-for="i in 3"
                      :key="i"
                      title="Item"
                      text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
                    ></v-expansion-panel>
                  </v-expansion-panels>
            </v-navigation-drawer>

            <v-app-bar app>
                <!-- ヘッドバー  -->
                <v-app-bar-nav-icon @click="drawer = !drawer"></v-app-bar-nav-icon>
                <v-toolbar-title>Application</v-toolbar-title>
                <div class='foo' style='margin-left: auto;'>

                </div>
            </v-app-bar>

            <v-main>
                <!-- メインコンテンツ  -->
                <v-row no-gutters>
                    <v-col v-for="n in 25" :key="n">
                        <v-card width="300" height="600" outlined></v-card>
                    </v-col>
            </v-main>
        </v-app>
    </div>

    <script src="https://unpkg.com/vue"></script>
    <script src="https://unpkg.com/vuetify@3.0.0-beta.3/dist/vuetify.js"></script>
    <script src="/static/index.js"></script>
</body>

</html>

```

index.js
```

vuetify = Vuetify.createVuetify({
  theme: {
    defaultTheme: 'dark'
  }
});




  const test1 = {
      data() {
        return {
          visual: false,
          info: {
            name: "",
            nickname: "",
            gender: "",
          },
          drawer: null,
        };
      },
    };

    app = Vue.createApp(test1);
    app.use(vuetify);
    app.mount("#app");

```



# もう少し補足
vuetify3公式のページでCDNの提供が無いですが、以下のページでCDN提供されているので、
適時最新のvuetify3を使うと良いと思います。

https://unpkg.com/browse/vuetify@3.0.0-beta.3/dist/

## ぐち
vue2とvue3で構文が変わってる関係で、ネットの情報がそのまま使えなかったです。
vuetify3はCDNの提供が無いし。一応npmで環境構築したんですが、私はフロントエンド開発したいんじゃなくて
Webアプリの画面お手軽に作りたいだけなんですよ～～～
フロントエンドのためのbuildとかやりたくない。。。。。
初心に帰り、Scikit-learnの背景を学んでみる

## はじめに
こんな面白そうな企画を見つけました。

https://qiita.com/official-events/97ae2edf9e1a01bde1fe

ただいきなり深層学習の論文を読むのはハードルが高いので、まずは簡単な？Scikit-learnの背景が書かれた論文を読むことにしました。
(余裕が合ったら深層学習もトライしたい)

## 論文
Fabian Pedregosa et al., 
"Scikit-learn: Machine Learning in Python", 
Journal of Machine Learning Research 12, 2825-2830i, 2011

## 内容

#### Scikit-learnとは

* 専門家でない人でも簡単に機械学習が使えることを目的に作られたツール。
* 下記の特徴をもつ。
①BSDライセンスを持ち、ツールを改変することが可能
②手続き型プログラミングをベースにしている

①：
その前のツールは勝手に改変してはいけないものが多かったようです。
著作権の表示は必要だけど、自分で色々いじれるというのは大きな特徴です。
②：
手続き型のメリットは学習コストが小さいことらしい。
説明するのが面倒になったので下記参照。
https://agency-star.co.jp/column/procedural-linguistics

まあとにかく、誰でも機械学習が使えるようになったということですね。

#### 技術的なアレ
使われているのは主に3つです。

* Numpy
数値計算用のモジュール。数値を配列表記で取り扱うことができる。
* Scipy
線形代数向けの計算ツール。ちなみに Fortranベースとのこと。
* Cython
Pythonの拡張ツールをC言語で扱えるようにしたプログラミング言語。C言語を使うことで数値計算の高速化を狙っている。

#### 他のツールと比較
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259951/929c397e-d8f1-9b1f-97b9-641ffe21f6fe.png)

代表的なモデルで比較すると、大体Scikit-learnを使った解析が早い。その中でもPCAは特に早いですね。

## まとめ
何気なく使っているけど、改めて見ると画期的なツールだということがわかりました。
この恩恵をこのまま受けていきましょう。
Accessを使った「担当割り」の自動化

#### やりたいこと
たまたま業務で表題機能を実装することになったんですが、ネットで調べてもなかなか思うようなヒントが得られず:confounded:
仕方ないので、自分であれこれ試行錯誤した結果のメモ。

要は、複数のメンバーに重み付けをして、案件ごとに自動的に担当割する仕組みを作るというものです。
案件が発生するたびに都度Access上の処理を動かし、担当を割り当てます。

以下、次のようなテーブルを前提に記します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170624/6f2d1e9b-0c98-2e3f-0b28-74f9ef97963e.png)

***
#### 1. 加重ラウンドロビン
まずやってみたのが、「加重ラウンドロビン」を使ったロジック。
「東京フレンドパーク」の最後で商品を決めるときの？ロジックですな。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170624/a874f707-f683-e03c-072c-4e3e36eaadbc.png)

``` VB
Private Function fPr_担当社員採番( )

    Dim 比率の合計 As Long
    比率の合計 = DSum("担当比率", "tbl_ユーザー")

    Dim rtn As Long
    Randomize
    rtn = Int((比率の合計 - 0 + 1) * Rnd + 0)    ' 0～比率の合計までの乱数を発生
    Set rs = CurrentDb.OpenRecordset("SELECT 担当比率, 社員番号 FROM tbl_ユーザー ORDER BY 担当比率")
    If rs.RecordCount < 1 Then
        MsgBox "社員担当者の情報が未設定です。", vbExclamation + vbOkOnly, "設定エラー"
        fPr_担当社員採番 = ""
        Exit Function
    End If

    Dim 累計 As Long
    累計 = 0
    rs.MoveFirst
    Do While (Not rs.EOF)
        累計 = 累計 + rs![担当比率]       ' 担当比率の小さい順に値を累積
        If rtn <= 累計 Then             ' ⇒担当比率の大きいメンバーほどここの条件にヒットしやすい
            fPb_担当社員採番 = rs![社員番号]
            Exit Function
        Else
            rs.MoveNext
        End If
    Loop
    rs.Close
        
End Function
```
***
#### 2. ただ・・・
この方法だと乱数に依存するため、短期的に特定のメンバーに付加が集中したり、ときに何連続かで割り当てられてしまいます。
都度処理するので、やはりその時点での割り振り状況は考慮すべきですね・・・

ということで、次のような処理を考えてみました。
①当日以降に割り当てられている案件数を担当者ごとに集計
②①より、各担当の割り当て済み件数の割合を計算
③設定した担当比率と2)の割合との差分が大きい＆前回割り当てが古い順に担当を割り振る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170624/68e2cd21-1b9b-471f-0ae6-f443bd4f4903.png)

``` SQL:クエリー：q_担当割集計1
-- 後ほどLEFT JOINするので、ここで案件情報を抽出します
SELECT 案件ID, 担当社員番号, 作成年月日
FROM tbl_案件
WHERE 担当社員番号 IS NOT NULL
AND 作業年月日 > Date();
```
``` SQL:クエリー：q_担当割集計2
-- 社員ごと割り当て済件数と最終割当日を集計
SELECT
    tbl_ユーザー.社員番号,
    tbl_ユーザー.担当比率,
    Count(q_担当割集計1.案件ID) AS 割当済件数,
    Max(q_担当割集計1.作成年月日) AS 直近割当日
FROM
    tbl_ユーザー LEFT JOIN q_担当割集計1
    ON tbl_ユーザー.社員番号 = q_担当割集計1.担当社員番号
GROUP BY
    tbl_ユーザー.社員番号,
    tbl_ユーザー.担当比率
```

``` SQL:クエリー：q_担当割集計3
SELECT
    社員番号,
    割当済件数,
    Iif(Nz([担当済件数], 0) = 0, 0, [割当済件数] * 100 / DCount("*", "q_担当割集計1") - [担当比率]) As 差分,
    担当比率,
    直近割当日
FROM
    q_担当割集計2
ORDER BY
    Iif(Nz([担当済件数], 0) = 0, 0, [割当済件数] * 100 / DCount("*", "q_担当割集計1") - [担当比率]) As 差分,
    担当比率 DESC,
    直近割当日;
````

``` VB
Private Function fPr_担当社員採番()

    Dim rs As DAO.Recordset
    With CurrentDb.QueryDefs("q_担当割集計3")
        Set rs = .OpenRecordset(dbOpenSnapshot)
        .Close
    End With
    If rs.RecordCount < 1 Then
        MsgBox "担当社員の割り当てに失敗しました。", vbExclamation + vbOKOnly, "エラー"
        fPr_担当社員採番 = ""
        Exit Function
    Else
        rs.MoveFirst
        fPr_担当社員採番 = rs![社員番号]
    End If

End Function
```

幸い、上記のロジックで約２ヶ月ほど無事に稼働しております。
Go の rune 型を試してみる

## 前回

https://qiita.com/BitterBamboo/items/14a0d667ed4dbe2d549b

文字列を for-range で回す際に、
繰り返しの要素（1文字1文字）が `string` 型として現れることを期待していたのですが、
なんと **`rune` 型という気味の悪い型**（[元ネタ](https://www.itmedia.co.jp/news/articles/1806/08/news065.html)）が代わりに現れて少々困惑してしまいました。

今回はそんな `rune` 型の基本的な挙動を確認してみました。

## `rune` 型の入出力

まず大前提として、`rune` は `int32` のエイリアスであり、
さらに Unicode のコードポイント（10進数表記）に該当するのでした。

`rune` 型の変数に格納できる値は2種類あります。

* `int32` 型の数値
* `rune` リテラル

### `int32` 型の数値

```go:int32 型の数値
package main

import "fmt"

func main() {
	var num int32 = 4649

	var r1 rune = 946
	var r2 rune = num

	fmt.Printf("r1 = %v (%c)\n", r1, r1) // r1 = 946 (β)
	fmt.Printf("r2 = %v (%c)\n", r2, r2) // r2 = 4649 (ሩ)

	var r3 rune = int(num) // error!
	// cannot use int(num) (value of type int) as type rune in variable declaration
}
```

`rune` 型の値を `%c` で出力すると、該当する Unicode 文字が表れて胸が熱くなりますね。
そして、rune 型の変数に `int` の格納は許されないことに注意しましょう。


### `rune` リテラル

```go:rune リテラル
package main

import "fmt"

func main() {
	var r rune

	r = '🥺'
	fmt.Printf("%v (%c)", r, r) // 129402

	r = '💃🕺' // error!
	// more than one character in rune literal
	
	r = "🥺" // error!
	// cannot use "🥺" (untyped string constant) as rune value in assignment
}
```

`rune` リテラルは、文字列リテラルと違って **シングルクォート(`''`)** で囲みます。
囲む対象となれるのは、**1文字のUnicode文字** や **`\`で書き始める文字コード**です。

ちなみに文字列リテラルは、ダブルクォート(`""`)やバッククォート(` `` `)で囲んで書きます。


## `rune` 型の演算

さて、 `rune` 型を用いた演算ですが、以下の2点さえ覚えておけばいいと思います。
* 所詮 `int32` である
* `rune` リテラルと `int` 型変数との演算では、`rune` リテラルが `int` 型にキャストされる

```go:所詮 int32 説と rune リテラルの int へのキャスト
package main

import "fmt"

func main() {
	var r rune = '🥺'
	var num int32 = 1232

	result1 := r - num // 所詮 int32 である

	fmt.Printf("%v (%c) : %T型\n", result1, result1, result1)
	// 128170 (💪) : int32型

	result2 := r + 'a' // 所詮 int32 である

	fmt.Printf("%v (%c) : %T型\n", result2, result2, result2)
	// 129499 (🧛) : int32型

	var justIntNum int = 334
	result3 := justIntNum + '虎' // rune リテラルの int へのキャスト
	fmt.Printf("%v (%c) : %T型\n", result3, result3, result3)
	// 34716 (螜) : int型
}
```

ぴえん（🥺）から 1232 を引くと、筋肉（💪）になります。
これ期末試験に出ますよ＾＾

ぴえん（🥺）に a を足すと、ドラキュラ（🧛）になります。
これはあまり大事ではありません。

そして役に立つのが、`rune` リテラルの `int` 型へのキャストですね。
例えば、関数の戻り値を `int` に縛っている場合、関数の中身の処理を `int32` でひたすら行っていくのは煩雑でしんどみがあります。

## 終わりに

JavaScript や Python などの動的型付け言語に慣れていたのであれば、
Go の静的型付け成分に（ほんのちょっぴり）悩まされることがあるでしょう。
特に `rune` 型は、Go 言語に特有(??)で、その扱いを直感的に理解しづらいと思います。
そのように感じる方々にとって、この記事が役立つものでありますように🙏
あなたは予習派、復習派？

小学校、中学校時代、あなたは予習派でしたか、復習派でしたか。

学校の勉強に対して、５つの分類をしてみます。

1. 予習派
2. 復習派
3. 予習・復習両方
4. 授業時間に集中（予習も復習もしない）
5. 授業時代もさぼっている（予習も復習もしない）

# 予習派
あらかじめ、教科書を読んでおくのは、予習です。

読んで、知らない単語があれば、書き出しておくのもいいでしょう。
知らない単語で頻度が高いものを調べてもよい。

60年前、自宅に百科事典があった。
教科書に載っている項目は、百科事典をあらかじめ読んだ。

その項目に知らない単語があれば、その項目も読んだ。
その項目に、さらに下ない単語があれば、その項目も読んだ。

少なくとも３段階までは掘り下げる。
読み進めるうちに、知らない単語だらけになると、途端に眠くなるかもしれない。

受験科目だけでなく、全科目予習していたことは覚えている。
受験科目じゃない技術を予習していて、技術の先生にすごくかわいがられたような気がする。

ぼくの先生「人がやらないことをやれ」プログラマになるまで。仮説（37）

https://qiita.com/kaizen_nagoya/items/53e4bded9fe5f724b3c4

# 復習派
宿題をまずやる。

授業時間中にできなかった演習問題をやり直す。

授業時間でわからなかったことを知らめる。

実は、自分が予習派で、復習とか宿題とかしなかったので、復習派のことはよく知らない。


小学校、中学校の頃は、ひょっとしたら、試験前１週間前か、２週間前から、試験勉強という名の復習をしていたかもしれない。高校、大学も同様。試験勉強を復習に入れれば復習していたことになる。

# 予習・復習両方
予習・復習、両方やる人がいたような気がする。

どういう時間配分をしているのだろう。
どれだけの時間、勉強に費やしているのだろう。

詳しく聞いたことがない。
存在していることだけ確認した気がする。

試験勉強を、復習に分類すると、小学校と中学校は予習と復習両方していたことになる。
宿題をあまりしていなかったが。

#  授業時間に集中（予習も復習もしない）
板書を帳面に書き出しながら、わからないことは辞書、参考書を持ち込んで、調べたり、先生に質問したりして、その場だけでなんとかした。宿題に出そうなところも、授業時間にやって、はずれたら休み時間だけでやり、家には持ち帰らない。

予習も、復習もしなくても、試験は通る科目は存在した気がする。

高校、大学のいくつかの科目は、授業時間だけでなんとかしていた。
すべtの科目ではない。

# 授業もさぼっている（予習も復習もしない）
試験前の一夜漬けも、ここに分類させてください。
試験の過去問を入手し、試験前日に解く。

高校、大学で、ほとんど授業を出ずに単位を取った科目があるかもしれない。
高校の頃は、出席日数が１０分の９から３分の２までは、レポート提出が必要だった。
３科目から５科目くらい、レポートを提出した気がする。

放送部室で部活をしていて、授業に出ていなかった。
３年生の時は、生徒会の役員をしていたかもしれない。

一つ目の大学は、通信教育で、授業がスクーリング必須単位以外は授業はない。
レポートと、筆記試験だけ。高校時代の経験が役立ったかもしれない。

二つ目の大学では、出欠を取らない科目は、予習か、復習だけで乗り切ったり、結局単位が取れなかったりした気がする。

なぜ経済学徒を辞め、計算機屋になったか（経済学部入学前・入学後・卒業後対応） 転職(1)

https://qiita.com/kaizen_nagoya/items/06335a1d24c099733f64

# あなたは予習派、復習派？

まとめると、小学校、中学校は予習派。
高校は、予習派と、さぼり派。
大学は、予習派と、授業だけと、さぼり派。

凡人は天才、秀才と違うことをして生きていく

https://qiita.com/kaizen_nagoya/items/0502aebb7610fef584f5
Google Business Profile について調べてみた

Google Business Profile(旧Google My Business)でできることを調べてみました。
## 管理画面でできることを確認
コンソール上で取得可能なデータを一覧化します　。
* パフォーマンス
* 口コミ
* インサイト
### パフォーマンス
パフォーマンスでは
* 閲覧数
    * 検索経由
    * マップ経由
* 検索数
    * 直接
        * ビジネスの名前や住所で検索してお客様のビジネス プロフィールを見つけたユーザー
    * 間接
        * 業種や商品、サービスで検索してお客様のビジネス プロフィールを見つけたユーザー
* アクティビティ数
    * ウェブサイトへのアクセス
    * 通話
    * 写真の閲覧
    * マップでのルート検索

が把握できるようになっています。
### 口コミ
全ての口コミを管理できます。
内容としては「評価」、「口コミ内容」です。
しかし、コンソール上で評価の集計などができる画面が見当たりませんでした。
口コミへの返信もコンソール画面上でできるようです。
### インサイト
インサイトでは顧客がどのようにビジネスを見つけ、どのような接点をもったかを確認できます。
* ユーザーがあなたのビジネスを検索した方法
    * 直接
        * ビジネスの名前や住所で検索してお客様のビジネス プロフィールを見つけたユーザー
    * 間接
        * 業種や商品、サービスで検索してお客様のビジネス プロフィールを見つけたユーザー
    * ブランド名
        * お客様のビジネスに関連するブランドを検索してお客様のリスティングを見つけたユーザー
* ユーザーがビジネスを見つけた Google サービス
    * 検索での表示回数
    * マップでの表示回数
* ユーザーの反応（ユーザーがリスティングに対して行ったアクション）
    * ウェブサイトへのアクセス
    * ルートの検索
    * 電話をかける
* ルートのリクエスト（ユーザーがビジネスまでのルートを検索した地域）
    * 市単位でのルート検索回数
* 電話
* 混雑する時間帯
* 写真の閲覧
    * 同業他社の写真閲覧数
    * 自社の写真閲覧数
* 写真の枚数
    * オーナーが投稿した写真
    * 顧客が投稿した写真
以上のデータをグラフ化した状態で見ることができます。
写真については同業他社との比較もできるようです。

その他に投稿や広告の管理、口コミへの返信、写真の投稿等々ができるようです。
## Business Profiel APIについて
Google Business ProfileはAPIを用いた管理も可能となっています。
APIを使用するにはGoogleに申請し、承認される必要があります。
承認の条件は明示されていないようですが、Google My Businessであった頃は２００社以上の施設を管理している必要があるようでした。
https://www.promost.co.jp/meo-tools-gmbapi/
しかし2018年の記事ですので、現在は条件が変わっているような気がします。
以下の2021年2月の記事では以下のことが必須条件であると書かれています。
https://paraworks.jp/blog/593/#:~:text=Google%20My%20Business%20API%E3%82%92%E4%BD%BF%E3%81%86%E3%81%AB%E3%81%AF,-Google%20My%20Bussiness&text=%E7%94%B3%E8%AB%8B%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0%E3%81%A7%E3%81%AF%E3%80%81%E4%BA%8B%E5%89%8D%E3%81%AB,%E6%89%BF%E8%AA%8D%E3%81%8C%E5%BE%97%E3%82%89%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82
* Google My Busines API を使った開発スキル
* 開発・修正できるだけのリソース・資金
* 申請時・トラブルが起こった際に質問できる程度の英語力
### Business Profiel APIを用いてできること
下記のGoogleが出しているガイドでは以下のことができるようです。
https://developers.google.cn/my-business/content/googlelocations-api-guide?hl=ja
<img width=300 alt="スクリーンショット 2022-06-09 18.43.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2704333/a24e2af2-4dae-3976-6d00-cc0f387aacd1.png">
Linux学習 Day 1 仮想化 memo

LPIC level-1受験のためのメモ

UUID　一意な値
オブジェクトストレージ　データをオブジェクトとして扱うストレージの仕組み

仮想化
仮想マシン＝インスタンス
テンプレートを利用可能
ブログサービス環境などのように、ユーザの用途に応じて利用可能なコンテナをアプリケーションコンテナと呼ぶ

コンテナ型：Docker , LXC
オーバーヘッドが少なく、リソース・構築・管理の面がシンプル
Linuxカーネルの機能によってコンテナごとのユーザ管理やリソース制限ができる

ハイパーバイザー型：
ゲストOSの種類に制限はない
物理マシン上でHVを起動し、その上で仮想マシンとゲストOSを動作させる
【Laravel】環境変数を呼び出すときはconfig()を使おう

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

## 概要
環境変数を```env()```で直接参照せずに```config()```を使って呼び出そう！

## Bad

```env
SITE_LINK="https://sample_app.com"
```
環境変数をenvで直接参照しようとすると```php artisan config:cache```したあと```null```になってしまい、呼び出せない。

```shell
% docker-compose exec laravel.test php artisan tinker
>>> env('INVITATION_LINK')
=> "https://sample_app.com"
                                                                                                                                                                                                                            
% docker-compose exec laravel.test php artisan config:cache
Configuration cache cleared successfully.
Configuration cached successfully.

% docker-compose exec laravel.test php artisan tinker      
>>> env('SITE_LINK')
=> null
```

公式ドキュメント
> 開発過程の一環としてconfig:cacheコマンド実行を採用する場合は、必ずenv関数を設定ファイルの中だけで使用してください。設定ファイルがキャッシュされると、.envファイルはロードされません。したがって、env関数は外部システムレベルの環境変数のみを返すだけです。

https://readouble.com/laravel/9.x/ja/configuration.html?header=%25E8%25A8%25AD%25E5%25AE%259A%25E3%2582%25AD%25E3%2583%25A3%25E3%2583%2583%25E3%2582%25B7%25E3%2583%25A5


## Better
```env
SITE_LINK="https://sample_app.com"
```

configディレクトリ下にファイルを作成し、下記のように環境変数を定義する。

```config/hoge.php
<?php

return [
  'site_link' => env('SITE_LINK'),
];
```

configメソッドを使ってドット記法で呼び出す。

```shell
% docker-compose exec laravel.test php artisan tinker
>>> config('hoge.site_link')
=> "https://sample_app.com"
                                                                                                                                                                                                                            
% docker-compose exec laravel.test php artisan config:cache
Configuration cache cleared successfully.
Configuration cached successfully.

% docker-compose exec laravel.test php artisan tinker      
>>> config('hoge.site_link')
=> "https://sample_app.com"
```

## 参考

https://tektektech.com/laravel-environment-variable/
ワープデフォーマの真ん中で変形するつもりが移動になるやつ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2704221/55611f9c-c5bc-6885-1b15-27ea522cfe05.png)
ワープデフォーマの真ん中を掴んで変形させるつもりが

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2704221/baf8d9ae-6d4d-0512-8d18-3ae1b76dd8ab.png)
ついてきてしまう・・・

真ん中で緑のワープデフォーマの点と赤い枠の点が被っているためですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2704221/81892f7d-19c8-67c1-b537-d0bba2c94b4d.png)
この場合は右下の赤い×印をクリックすると・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2704221/90d6481e-02b7-5790-bbff-41d88027769e.png)
赤い枠が消えて無事ワープデフォーマのみを操作することができるようになりましたね。
赤い枠を復活させたい場合はもう一度メッシュを選び直すことで出てきます。
STM32G031で二進固定小数点で遊ぶ2(四則演算)


x 動作確認済み2022/6/10 7:42

x OBでGPIOがわかる人むけ

目的　
適当にごもごもするから四則演算をまともに
した時は、ないが今後の為

二進固定小数点　2ビット　0.25 ←→ 1/4　の話


二進固定小数点の時は、とりあえず4倍するんや!!
そうすると精度が4倍になり0,.25,.5,.75がねじ込めるるんや!!



足し算と引き算は、そのまま

A + B = C

A - B = C

例

1.25 + 1.50 = 2.75

2.75 - 1.50 = 1.25

足し算

1.25 + 1.50 = 2.75

1.25 → (1 * 4)+(1) = 5(101B)
1.50 → (1 * 4)+(2) = 6(110B)

101B + 110B = 11(1011B)

2.75 →　(2 * 4)+(3) = 11(1011B)

引き算

2.75 - 1.50 = 1.25

2.75 →　(2 * 4)+(3) = 11(1011B)
1.50 →  (1 * 4)+(2) =  6 (110B)

1011B - 110B = 5(101B)

1.25 → (1 * 4)+(1) = 5(101B)


掛け算は、小数点分右にシフト

小数点N

A * B = C

C >> N


2.0 * 1.5 = 3.0

2.0 →　(2 * 4) + (0) = 8
1.5 →　(1 * 4) + (2) = 6

8 * 6 = 48

48 /2 = 24
24 /2 = 12

12 →　( 3 * 4 )+(0)

3.0

割り算

割り算は、小数点分左にシフトして割る

小数点N

( A << N ) / B = C
 
3.0 / 1.5 = 2.0
 
3.0 →　(3 * 4) + (0) = 12
1.5 →　(1 * 4) + (2) = 6

(12 * 4) / 6 = 8
  48     / 6 = 8

8 →　(2 * 4) + (0)

2.0



https://paiza.io/ja/projects/new?language=c


```c++

#include <stdio.h>
int main(void){
    
    
    int a,b,c;
    char *f4[]={".0",".25",".5",".75"};
    
    
    //1.25 + 1.50 = 2.75
    
    a = (1<<2)+(1); //1.25
    b = (1<<2)+(2); //1.5
    c = a+b;
    printf("%d",c>>2);
    printf("%s\r\n",f4[c & 0x03]);
    
    
    //2.75 - 1.50 = 1.25
    
    a = (2<<2)+(3); //2.75
    b = (1<<2)+(2); //1.25
    c = a-b;
    printf("%d",c>>2);
    printf("%s\r\n",f4[c & 0x03]);
    
    
    //2.0 * 1.5 = 3.0
    
    a=(2<<2)+(0); //2.0
    b=(1<<2)+(2); //1.5
    c = a*b;
    c = c>>2;
    printf("%d",c>>2);
    printf("%s\r\n",f4[c & 0x03]);
    
    
    //3.0 / 1.5 = 2.0

    a = (3<<2)+(0); //3.0
    b = (1<<2)+(2); //1.5
    c=(a<<2)/b;
    printf("%d",c>>2);
    printf("%s\r\n",f4[c & 0x03]);
    
}



```

```

2.75
1.25
3.0
2.0

```


![o_con530.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/3173d12a-ebff-951d-2120-0055191c89f1.jpeg)



```c++



//SER_f4_4_031_1


#include <Arduino.h>
#include <HardwareSerial.h>


//初期化
void setup() {

  delay(3000); //not delete

  Serial.setTx(PA2_ALT1);
  Serial.setHalfDuplex();
  Serial.begin(9600);


}//setup

int a,b,c;
char *f4[]={".0",".25",".5",".75"};

//メインループ
void loop() {

    //1.25 + 1.50 = 2.75

    Serial.println("1.25 + 1.50");
    a = (1<<2)+(1); //1.25
    b = (1<<2)+(2); //1.5
    c = a+b;
    Serial.print(c>>2);
    Serial.println(f4[c & 0x03]);
    
    
    //2.75 - 1.50 = 1.25

    Serial.println("2.75 - 1.50");
    a = (2<<2)+(3); //2.75
    b = (1<<2)+(2); //1.25
    c = a-b;
    Serial.print(c>>2);
    Serial.println(f4[c & 0x03]);
    
    
    //2.0 * 1.5 = 3.0

    Serial.println("2.0 * 1.5");
    a=(2<<2)+(0); //2.0
    b=(1<<2)+(2); //1.5
    c = a*b;
    c = c>>2;
    Serial.print(c>>2);
    Serial.println(f4[c & 0x03]);
    
    
    //3.0 / 1.5 = 2.0

    Serial.println("3.0 / 1.5");
    a = (3<<2)+(0); //3.0
    b = (1<<2)+(2); //1.5
    c=(a<<2)/b;
    Serial.print(c>>2);
    Serial.println(f4[c & 0x03]);


  delay(4000);

}//loop





```
qiita apiを叩く。その4

# 概要
javascriptで、qiita apiを叩いてみた。
searchで、取得してみた。

# サンプルコード

```

var app = new Vue({ 
  el: '#app', 
  data: { 
    items: null, 
    keyword: '', 
    message: '' 
  }, 
  watch: { 
    keyword: function(newKeyword, oldKeyword) { 
      this.message = 'waiting for you stop typing...' 
      this.debouncedGetAnswer() 
    } 
  }, 
  created: function() { 
    this.debouncedGetAnswer = _.debounce(this.getAnswer, 1000) 
  }, 
  methods: { 
    getAnswer: function() { 
      if (this.keyword === '')
      { 
        this.items = null 
        this.message = '' 
        return 
      } 
      this.message = 'Loadng...' 
      var vm = this 
      var params = { 
        page: 1, 
        per_page: 10, 
        query: this.keyword
      } 
      axios.get('https://qiita.com/api/v2/items', {
        params
      }).then(function(response) { 
        vm.items = response.data 
      }).catch(function(error) { 
        vm.messae = 'Error!' + error 
      }).finally(function() { 
        vm.message = '' 
      }) 
    } 
  } 
}) 




```

# 成果物

https://embed.plnkr.co/plunk/UvjK0REGe5cogJHKJ7BH

以上。
Low Order を利用した攻撃

## 考え方
楕円曲線の加法の群の位数が素数でない場合は、点を素因数を位数とした部分群にマップすることができるので、大きな数でも、小さな素因数が掛け合わさった数である場合は、それぞれの素因数を位数にした部分群に点をマップして、その上で離散対数問題を解き、中国剰余定理を使って、その答えを組み上げることで、元の数に対する答えもわかってしまう。

## 点を部分群にマップする方法
1. cofactor を計算する。楕円曲線の加法の群の位数を、マップ先の群の位数（素数）で割った数が cofactor
1. 点に cofactor を掛ける

例
```
# 楕円曲線の加法の群の位数 = 966
# マップ先の群の位数 = 23
cofactor = 966 / 23 = 42
[42]P = (890, 665) 
```

## 具体例

### ベースとなるフィールド
$\mathbb{F}_{1021}$

### 楕円曲線の式
$y^2 = x^3 + 905x + 100$

### 加法の群の位数
$ \\# E(F_q)  = 966 = 2 \cdot 3 \cdot 7 \cdot 23$

### ジェネレーター
$P=(1006, 416)$

### 攻撃内容
$Q=[k]P=(612, 827)$

の $k$ を見つける

### 手順
#### 1. 群の位数の素因数ごとに、部分群を作り、そこに点をマップして、そのレベルでの答えを見つける

##### 素因数 2
$cofactor = 966/2 = 483$
$P_2 = [483]P = (174, 0)$
$Q_2 = [483]Q = (174, 0)$

$[k_2]P_2 = Q_2$ 
$P_2$ と $Q_2$ は同じなので、$k_2=1$

##### 素因数 3
$cofactor = 966/3 = 322$
$P_3 = [322]P = (147, 993)$
$Q_3 = [322]Q = O$

$[k_3]P_3 = O$ 
$P_3$ に掛けて $O$ になる数なので、$k_2=0$

##### 素因数 7
$cofactor = 966/7 = 138$
$P_7 = [483]P = (906, 201)$
$Q_7 = [483]Q = (906, 201)$

$[k_7]P_7 = Q_7$ 
$P_7$ と $Q_7$ は同じなので、$k_7=1$

##### 素因数 23
$cofactor = 966/23 = 42$
$P_23 = [42]P = (890, 665)$
$Q_23 = [42]Q = (68, 281)$

$[k_23]P_23 = Q_23$ 
$k_23$ については、すべての数を試す。すると、$k_23=20$ であることがわかる。

#### 2. 中国剰余定理を使って 1 の全ての結果を満たす数を計算する

$k \equiv (k_2 = 1) \pmod 2$
$k \equiv (k_3 = 0) \pmod 3$
$k \equiv (k_7 = 1) \pmod 7$
$k \equiv (k_23 = 20) \pmod {23}$

を、中国剰余定理で解くと、$k \equiv 687$

## 参考文献
Pairings for beginners / Craig Costello
PythonでGCSをトリガーにBQデータ格納

## やること
GCSにファイルがアップロードされたことをトリガーに、そのファイルをBQに格納する

## GCS
GCSのコンソール上で「バケットを作成」
※今回は名前が`test`
その下の階層に「フォルダを作成」
※こちらも名前が`test`

あげるファイル
`test20220606.csv`

    date,id,name,click
    2022-06-06,111111,Aki,4
    2022-06-06,222222,Haru,10
    2022-06-06,333333,Natu,23
    2022-06-06,444444,Huyu,19
    2022-06-06,555555,Oto,1

## BigQuery
プロジェクトからデータセットだけ作成
データセット名：`test`

## コード
requirements.txt 

    google-cloud-bigquery

`pip install -r requirements.txt`

main.py

    from google.cloud import bigquery

    def import_bq(event, context):
        file = event['name']
        bucket = event['bucket']
        bq_client = bigquery.Client()
        
        # スキーマの設定
        schema_json = [
            bigquery.SchemaField("date", "DATE"),
            bigquery.SchemaField("id", "STRING"),
            bigquery.SchemaField("name", "STRING"),
            bigquery.SchemaField("click", "INTEGER"),
        ]
        
        job_config = bigquery.LoadJobConfig(
            schema=schema_json,
            # 宛先テーブルがすでに存在する場合、上書き
            write_disposition=bigquery.WriteDisposition.WRITE_TRUNCATE,
            # CSV形式でBQに格納
            source_format=bigquery.SourceFormat.CSV,
            # null許容フィールドをスキーマに追加できるようにする
            schema_update_options=[bigquery.SchemaUpdateOption.ALLOW_FIELD_ADDITION],
            # 今回CSVなのでカラムの部分をスキップ
            skip_leading_rows=1,
            # パーティションを日毎で分割
            time_partitioning=bigquery.TimePartitioning(
                type_=bigquery.TimePartitioningType.DAY,
                field="date", 
            ),
        )
        # TODO $20220606でパーティションを切っているので変数にする必要あり
        table_id = bq_client.dataset('テーブルセット名').table('report$20220606')
        uri = f'gs://{bucket}/{file}'
        load_job = bq_client.load_table_from_uri(
            uri, table_id, job_config=job_config
        )
        return load_job.result()

## Function

プロジェクト設定

    gcloud config set project プロジェクト名

下記コマンドでデプロイ

    gcloud functions deploy import_bq \
    --runtime python39 \
    --trigger-resource GCSのバケット名 \
    --trigger-event google.storage.object.finalize \
    --project プロジェクト名 \
    --region us-central1 \
    --allow-unauthenticated \
    --memory 512MB

## 確認
GCSのコンソールからtestフォルダの中に`test20220606.csv`のファイルをアップロード
BQのデータセット名:'test'の中に`report`が入っていてデータがあればOK！

## 最後に
ドキュメント探すのに時間かかったので、使ったものは全て参考文献に記載しました。
(また、コードにも何をしているかコメント残してます)


## 参考文献

https://cloud.google.com/functions/docs/calling/storage?hl=ja

https://cloud.google.com/bigquery/docs/loading-data-cloud-storage-csv#details_of_loading_csv_data

https://cloud.google.com/python/docs/reference/bigquery/latest/google.cloud.bigquery.job.LoadJobConfig

https://googleapis.dev/python/bigquery/latest/generated/google.cloud.bigquery.job.LoadJobConfig.html#google.cloud.bigquery.job.LoadJobConfig.time_partitioning

https://cloud.google.com/bigquery/docs/reference/rest/v2/Job

https://googleapis.dev/python/bigquery/latest/generated/google.cloud.bigquery.job.SchemaUpdateOption.html