OmniAICreator/Qiita-1.07M huggingface dataset:
キャリアイメージとは、私自身を要件定義することである

# なんのための文章なの？
仕事で要件定義をしている際に気づいた大事なことを整理していたら、
これってキャリアイメージを描く際にも同じ考え方使えそうだよね？と思ってエディタを取り出した次第。
キャリアイメージが明確ではない人がキャリアイメージの描き方を考える際の参考になれば嬉しいです。

# 何について書くの？
要件定義における大事なことを整理し、比較しながらキャリアイメージを考える際に大事なことを整理する

# 要件定義における大事なこと
システム開発の要件定義時に大事なことは以下の３つ
## Why
なぜシステム化する必要があるのか

## What
誰のどんな課題を解決するのか

WhyとWhatは具体的には
- 現状困っていることは何か
- どこを目指しているのか
- 現状とゴールのギャップは何か

などを指す

## How
どんなシステムを作るのか
具体的には
- どんな機能が必要なのか
- どんな機能が不要なのか
- どんな風にシステムを使うのか
などを指す

これらが明確ではないシステムは
「作ったんだけどなんか使いづらい…」とか「なんかシステムできたけどこれで成功なんだっけ？」となってしまいがち

# キャリアイメージを考える上で大事なこと
## Why
なんのために働くのか

## What
私が解決したいのは誰のどんな課題か

## How
どんな仕事をしたいのか、どんな仕事をしたくないのか

雇用する側の目線に立てば、これらが明確な人は働くイメージがしやすいだろうと思う。
働くイメージがしやすいので、会社で活躍できる人材かどうかの判断がしやすい。
本人が求めているものが会社で実現できるかどうかが判断しやすいのでミスマッチを防ぐことにもつながる。

一緒に働く人の目線で考えた時に、これらが明確な人であるほど仕事の依頼がしやすい。
本人の求めているものに近いものを提供した方が仕事の意義が明確になりモチベーションも高まるからだ。
また、提供できる価値が明確になっている人ほど周囲の人間がどうサポートしていいのかが明確になる。

結果としてこれらが明確であればあるほど、働く本人にとっても一緒に働く人にとっても仕事がしやすくなると言えるだろう。
雇用者や一緒に働く人はユーザーであり、働く人間は商品である。そんな風に考えて見るのはどうだろうか。

もし機会があったらもう少し細かいフェーズに踏み込んでキャリアイメージを考える上で大事なことを整理してみようと思う。
Material-UI導入時のバンドルサイズ削減

## Material-UIを使用する際の高速化を測る。

役割に応じたコンポーネントが用意されておりそれらをimportしつつUIを作り上げていく非常に便利なMaterial-UI(以下MUI)ですが、

一つの問題としてバンドルサイズが大きくなることが挙げられ、結果として開発環境の動作が重くなり、特にiconsパッケージを使用する場合に顕著になります。これはimport文の記述法によって左右されます。通常公式ドキュメントのコード例として掲載されているのは一つ目の方法です。
(Option1)

```javascript
import Button from '@material-ui/core/Button';
import TextField from '@material-ui/core/TextField';
```

もう一つの記述法としては以下のようになり、こちらの方が速度は低下します。
(Option2)

```javascript
import { Button, TextField } from '@material-ui/core';
```

公式ドキュメントによれば、二つ目の記述法を採用することでコードの重複が可読性を向上させるとしています。また、Babelプラグインを使えばOption2もOption1と同じ速さになるとのことです。


>This option provides the best User Experience and Developer Experience:
>>UX: The Babel plugin enables top level tree-shaking even if your bundler doesn't support it.
DX: The Babel plugin makes startup time in dev mode as fast as Option 1.
DX: This syntax reduces the duplication of code, requiring only a single import for multiple modules. Overall, the code is easier to read, and you are less likely to make a mistake when importing a new module.
[Minimizing Bundle Size - Material-UI](https://mui.com/material-ui/guides/minimizing-bundle-size/#option-2)



今回はOption2の記載方法でMUIのコンポーネントをimportする際に、Babelプラグインを導入することで速度の問題を解決する方法について書いていきます。

まずは以下のパッケージをインストールします。
```
yarn add -D babel-plugin-import react-app-rewired customize-cra
```

次に.babelrc.jsファイルを以下の内容でルートディレクトリに作成します。
```javascript
const plugins = [
  [
    'babel-plugin-import',
    {
      libraryName: '@material-ui/core',
      // Use "'libraryDirectory': ''," if your bundler does not support ES modules
      libraryDirectory: 'esm',
      camel2DashComponentName: false,
    },
    'core',
  ],
  [
    'babel-plugin-import',
    {
      libraryName: '@material-ui/icons',
      // Use "'libraryDirectory': ''," if your bundler does not support ES modules
      libraryDirectory: 'esm',
      camel2DashComponentName: false,
    },
    'icons',
  ],
];

module.exports = { plugins };
```

そして次に、以下のconfig-overrides.jsファイルをルートディレクトリに作成します。
ESLintはデフォルトで無視されています。
```javascript
/* eslint-disable react-hooks/rules-of-hooks */
/* config-overrides.js */
const { useBabelRc, override } = require('customize-cra');

module.exports = override(useBabelRc());
```

最後に、package.jsonのstartコマンドを以下のように修正します。
![スクリーンショット 2022-05-01 14.14.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/770055/31da8c1b-c3c3-c722-c998-133da4d18483.png)

以上で、MUIでOption2のimport方法を使う準備が完了です。
現在のimport箇所を全て

```javascript
import { Button, TextField } from '@material-ui/core';
```
のように変更しましょう。
セッションハイジャック とは

## 勉強前イメージ

セッションを盗んで情報を取る的な？

## 調査

### セッションハイジャック とは

英語で  Session Hijacking と書き、ログイン中の利用者のセッションIDを不正に取得してセッションを乗っ取る攻撃になります。
ログインIDやパスワードを知らなくてもアカウント乗っ取りが可能になります。

### そもそもセッションとは

セッションとはwebサイトにアクセスして、ログインを行いログアウトを行うまでのやり取りのことで、アクセスの解析でも使われます。
一つのwebサイトの中で複数のページにアクセスを行い、ログアウトしたとすると
複数のページを見た一連の流れを1セッションと考えます。

セッションとはセッションIDをサーバに保持して、同じセッションIDであれば複数のページで同じ情報を共有できるものです。
例えばショッピングサイトにログインして、いくつかのページを遷移してカートに買うものを入れたとします。
そのカートに入れた情報を保持するのがセッションの機能になります。
セッションIDはログイン時に付与されて、同じセッションIDであれば上記のように同じ情報を保持します。

よってセッションハイジャックとして利用者のセッションIDを乗っ取られると
個人情報などが見えてしまうおそれがあります。

### セッションハイジャックの原因

- セッションIDの窃盗

セッションIDが類推し易いものの場合は解析して不正利用されることがあります。
また、総当たり攻撃やツールを使った攻撃で簡単に乗っ取りされてしまいます。

- webアプリケーションの脆弱性

webアプリケーションの脆弱性でwebアプリケーションを改ざんされセッションIDを見られてしまい、乗っ取りされてしまうことがあります。

- セッションIDの固定化

セッションフィクセーションといってセッションIDを攻撃者が固定化してそれを利用者が使用するという方法もあります。

### セッションハイジャックの例

- クロスサイトスクリプティングによるセッションハイジャック

管理者がクロスサイトスクリプティングによってセッションを盗むコードが含まれているURLをクリックしたことで管理者権限のセッションを奪われてしまいました。

## 勉強後イメージ

確かにセッションを盗まれたら、なりすましもされるし個人情報(クレカとか住所とか)も丸見えになってしまう・・・

## 参考

-[セッションハイジャック【Session Hijacking】とは｜図でわかる脆弱性の仕組み](https://www.ubsecure.jp/blog/session_hijacking)
-[セッションハイジャックとは？セッションIDを利用したなりすまし](https://www.lrm.jp/security_magazine/session_hijack/)
Qiita記事の全部転載をどう防ぐとよいか。

2022年5月1日

自分の記事の中のリンク切れURLを探すために作業していた。

技術士 researchmap 資料一覧

https://qiita.com/kaizen_nagoya/items/02286b43bfc9799f394b

そしたら、

https://jpdebug.com/p/2607862

というURLに出会った。

>Author And Source
この問題について(技術士 researchmap 資料一覧), 我々は、より多くの情報をここで見つけました https://qiita.com/kaizen_nagoya/items/02286b43bfc9799f394b
著者帰属：元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .

どう対応するか思案中。

slideshareのように、掲載したものを自由に見えなくする方が、ひどいかもしれないし。

自分の感情がからむと、冷静な判断はできないことがあるかもしれない。

他の方はどう判断されているのだろう。

Qiitaはどう判断されているのだろう。

p.s.
私のQiitaの記事は、ResearchmapまたはGithubから複写するようにしている。
私の記事は場合によっては、原記事ではなく、複写記事の場合がある。
なるべく、その旨追記しようと思っている。


情報ネットワーク法学会

https://in-law.jp/index-base.html

の他の発起人に相談しようかなって思っています。
キーボードスイッチ打鍵感を静音化

キーボードスイッチを静音化する場合には

静音キースイッチを使用する
静音用シリコン　Oリングをキーキャップに付ける
などの対応策があります。

その代わりの代償に
気にいったキースイッチに静音化ができない
Oリングの厚さ分のキーストロークが短くなる

この場合に有効な方法ができたので、
メモ代わりに記録しておく。

今回の方法はキースイッチを１度開けてボトムハウジングに
ある物を追加します。
接着剤や両面テープは使用しないので、取り外せば
ノーマルに戻ります。

ある物はシリコンチューブになります。
外径2mm 内径1mm のシリコンチューブを用意して
2mm幅程度で切り出し
ボトムハウジングのセンター穴の底に入れます。
外径2mm のチューブがボトムハウジング穴のサイズに
ピッタリと合うので接着は必要ありません。

ステムのピンがシリコンチューブに接触することで
ボトムハウジングにステムが接触せずに
底打ち音を軽減して静音化します。
シリコンチューブの切断長次第ですが、ノーマルより
キーストロークはわずかですが短くなります。

ボトムハウジングがクリア素材のキースイッチだと
ステムのピンだけ接触している状態を確認できます。

シリコンチューブ切り出しの断面を真っ直ぐに
切断したいので1mm の真鍮パイプなどに通して状態で
回転させながらチューブをデザインナイフで切ると
チューブが潰れず、切ったチューブも無くさずに
楽に切れます。

キーストロークを短くしたい場合は2mm幅を
3mm幅程度に長く切ると調整ができます。

2mm幅の切断長はキースイッチの種類により
切断する長さを調整します。
線形代数

## スカラーとベクトル
<b><font color=blue>スカラー</font> - 大きさを表す数値のこと
<font color=blue>ベクトル</font> - スカラーを一列に並べたもの
横方向に並べたものを<font color=blue>行ベクトル</font>、縦方向に並べたものを<font color=blue>列ベクトル</font>という。ベクトルの構成要素を<font color=blue>成分</font>という。
## 行列
<b>行と列から構成されたもの。横のまとまりが<font color=blue>行</font>で、縦のまとまりが<font color=blue>列</font>

### 行列の加算
<b>同じ位置の同じ成分同士を加算する。加算できるのは、行と列の数がそれぞれ同じ行列同士だけ。減算も同じ。
### 行列のスカラー倍
<b>2倍、3倍するときは、各成分にそれぞれに掛ける
### 行列同士の乗算
<b>行列Aに行列Bを乗算するときは、行列Aの列数と、行列Bの行数が同じである必要がある。
![lm-mn-matrix1811.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600460/c4a04a4f-48e3-3f96-b476-b03f390950dd.png)
### 逆行列
<b>行と列が同じ数になっている行列を<font color=blue>正方行列</font>また、左上からの対角線上の成分が1、それ以外の成分が0である正方行列を<font color=blue>単位行列</font>といい、Eで表す。
ある正方行列に単位行列を掛け合わせると、元の行列と同じになる。
行列Aに行列Bを掛けて単位行列が得られたら、行列Bは行列Aの<font color=blue>逆行列</font>といい、A⁻¹で表す。
A × A⁻¹ = E
CSSやJavaScriptの手動最小化方法

今や、minifyツールやpackerがありますが、
今は何かといってWebは肥大化の道を進んでしまっています。

それらのツールを使用したとしても、基本的な
手動圧縮方法を見直してみましょう。

1バイトでも圧縮するために

## CSS

### 数字を見直す

1000 または 100 を 使用するなら、999、99 を使用して、問題なければ使用する

0.9 (.9) を使用するなら 1を使用してみて、問題なければ使用する

:::note info
なお、辞書系の圧縮がかかる場合、逆に 999 等を使用せず、素直に 1000 を使用したほうが良い場合があります。
:::

### クラス名、ID名を短くする

今はわかりやすいように長い名前が使われることがありますが、クラス名やID名は短くしましょう

### HTML で指定された深い要素を使用しない

section.contents h3 .item

を

.item でよければ、これだけで済ましてみます。


### 可能な限り要素名で使用する

要素名は、例えば

- h3
- div
- h6

特に、h で始まる見出しは2文字ですので、HTML側も効率よくなります。

### 圧縮がかかる場合、nth-child(?) を活用する

ただし、この場合はクラス名やIDを指定しない場合です。

```
<h4>test</h4>
<div>
  <p>aaa</p><!-- p:nth-child(1) -->
  <p>bbb</p><!-- p:nth-child(2) -->
  <p>ccc</p><!-- p:nth-child(3) -->
</div>
```
等の場合、活用するとよいでしょう。

## JavaScript

### 変数名、関数名を短めに

単なるループ程度なら、変数が重ならない程度に、1文字にしましょう。

```
for (var i = 0; i < 10; i++) {}
```

### 辞書圧縮がかかる場合、絶対 let は使用しない
ライブラリがletに統一されているなら、letを使用したほうがよいですが、
var がひとつでもあれば、var を使用しましょう。

### 辞書圧縮がかかる場合、極力 const は使用しない
値が書き換わってしますが、変数の管理をしっかりしてれば、十分に var に代替できます

### forループや if 文で　<= => を使用しない
```
for (i = 0; i <= 8; i++) {}
```
ではなく

```
for (i = 0; i < 9; i++) {}
```
にすると、１文字節約できます。

### undefined の比較

今は、以下の記述で十分です。
辞書圧縮がかかる場合に有用です。

```
if(value === undefined) {}
```

### if 文の { } を取り除く

if文の条件一致した中でひとつしか実行しないのであれば、{ } を省略できます。

```
if (test == 1)
	alert("1");
else
	alert("no");
```

### うまくすると、; すら省略できる
各種JavaScript類のライブラリに散見されます。
```
if (test == 1) {
	exec1()
	exec2()
}
```

### みんなが使ってるフレームワークを極力使用する
例えば、jquery です。

フレームワークを使用することで、みんなが使用しているので
ブラウザのキャッシュから読み出され、高速であるとともに、
文字数が全体的に短くなるので、新たな転送量も少なくなります。

:::note info
ただし公開cdnを使用しないと意味がありません
:::

### packerを使用するとき、JavaScriptをすべて結合する

非常に利用されるcdnを除き、すべてのJavaScriptを順番通り結合しましょう

packerによって辞書化されますので、使用している同じJavaScriptのワードが大幅に圧縮されます。

```
copy a.js+b.js+c.js release.js

type a.js > release.js
type b.js >> release.js
type c.js >> release.js

cat a.js b.js c.js > release..js

等
```

## さいごに
大した転送量の削減でなくとも、
MTU (1500,1492,1454等）に溢れないように
1 MTU を削減できただけでも、小さな転送速度の改善となります。

例えば、MTUが1500で、1501バイトを転送しようとすると、
最終的に 1500から1溢れたために、3000バイト転送せざるえなくなります。

同じように、1バイトでも節約できれば、利用者の携帯電話（スマホ）のちょっとした低減にもつながりますし、もちろん、小さくした分高速化します。
3D描画ソフト自作 - シェーディング

# 概要
3Dゲームを作りたいので、3D描画ソフトから作っているのですが、  
シェーディングがすごかったからその話  
  
気が向いたら解説編も作るかもしれない  

# 結論
1番に結論
「シェーディングすげぇ!  」
  
シェービングを付けてないとき  
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1773714/ec573a1b-135e-781a-8331-2e0f6f697247.png)  
シェービングを付けているとき
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1773714/a6912dab-9d32-d9e0-cbb6-da7d2a06852a.png)  

# 動作環境
この写真は、firefoxを使って、javascriptのコードで描画しています
有名なブラウザならどれでも動くと思います

# 内容
シェーディングを付けてないときは、オブジェクトに設定した色がそのまま塗っています  
シェーディングを付けているときは、面の向いている方向と照明の方向に応じて明るさを変えながら縫っています  
これはフラットシェーディングというシェーディングを使っています  

# フラットシェーディングの簡単な仕組み
詳しく書くのはめんどいので、とりあえず簡単に書きます  
画像の中の3Dモデルは、大量の三角形でできています  
  
3角形の3つの点の中から1つ選んで、残りの2点にのびる2つのベクトルを計算します  
その二つのベクトルの外積から、三角形の法線が分かります  
　(法線が、その面の向いている方向です)  
その法線と、光の向きの内積を計算します  
内積をオブジェクトの色(RGB)に掛けると、光が斜めからあたるほど暗くなります  
これで陰ができるので、調整して完了です

# コード

github:
https://github.com/haruk1234/web3d

この記事を書いた時のコード
https://github.com/haruk1234/web3d/releases/tag/%231-flatshading
※ユーザー名を変えたのでURLを更新しました
  
167行目にある、
```js
light = normal*0.7+0.3;
```
を、
```js
light = 1;
```
にすると、シェーディングがオフになるはずです


# まとめ
シェーディングって凄いなと...
GCEのContainer-Optimized OSでdbt CLIを動かしてみる

# この記事はなに？

GoogleCloudPlatform(GCP)のGoogleComputeEngine(GCE)インスタンス上で、CLI版のdbtを動かしてBigQueryにテーブルを生成する過程をまとめた記事になります。

# GCEインスタンスの作成

基本的にはデフォルトの設定をいじらず、費用もかけたくなかったため[こちら](https://cloud.google.com/free/docs/gcp-free-tier/?hl=ja#compute)の情報をもとに選択しつつ、今回はDocker経由でdbtの実行環境を作るため、イメージとして`Container-Optimized OS`を選択し作成しました。

| 項目 | 値 |
| :-- | :-- |
| 名前 | dbt |
| リージョン | us-central1(アイオワ) |
| シリーズ | E2 |
| マシンタイプ | e2-micro(2 vCPU、1GBメモリ) |
| OS | Container Optimized OS |
| バージョン | Container-Optimized OS 85-13310.1453.1 LTS |
| ブートディスクの種類 | 標準永続ディスク |
| サイズ | 10 |

# 接続用のポートを開けておく

ファイアウォールからtcp:8081を許可するタグを作って、先程作ったGCEインスタンスに付与しておきます。

# ローカルからssh接続

ローカルPCにCloud SDKをインストールし、gcloudコマンドを使って先程作ったインスタンスにsshで接続します。
※ブラウザウィンドウでも接続はできるので、この辺はお好みで。

```shell
$ gcloud compute ssh --zone "us-central1-a" "dbt"  --project "{{GCPのプロジェクト名}}"

# 作業用のディレクトリを作成しておく
$ mkdir works
$ exit
```

# サービスアカウントの作成

dbtを通してBigQueryにテーブルを生成するため、BigQueryにアクセスする権限を持つサービスアカウントを作成しておきます。
本来は必要最小限の権限を付与するべきですが、今回は勉強用のため、サービスアカウントに対して`BigQuery管理者`の権限を付与しました。

また、dbtのコマンド実行時に認証が走るため、JSON形式で認証鍵をダウンロードし、GCEインスタンスにアップロードしておきます。

```shell
$ gcloud compute scp --project "{{GCPのプロジェクト名}}" --zone "us-central1-a" --recurse {{ファイルパス}} {{GCPのユーザー名}}@dbt:/home/{{GCPのユーザー名}}/works
```

# 必要なファイルを作成

作業用ディレクトリとして作ったworksディレクトリ配下に必要なファイルを作っていきます。

```Dockerfile:Dockerfile
FROM python:3.9.12-slim-bullseye

ARG dbt_bigquery_ref=dbt-bigquery@v1.0.0

# System setup
RUN apt-get update \
  && apt-get dist-upgrade -y \
  && apt-get install -y --no-install-recommends \
    git \
    ssh-client \
    software-properties-common \
    make \
    build-essential \
    ca-certificates \
    libpq-dev \
    vim \
  && apt-get clean \
  && rm -rf \
    /var/lib/apt/lists/* \
    /tmp/* \
    /var/tmp/*

# Env vars
ENV PYTHONIOENCODING=utf-8
ENV LANG=C.UTF-8

# Update python
RUN python -m pip install --upgrade pip setuptools wheel --no-cache-dir

# dbt-bigquery
RUN python -m pip install --no-cache-dir "git+https://github.com/dbt-labs/${dbt_bigquery_ref}#egg=dbt-bigquery"

COPY profiles.yml /root/.dbt/profiles.yml

WORKDIR /usr/app/dbt/
VOLUME /usr/app
ENTRYPOINT tail -f /dev/null
```

```yml:dbt_project.yml
name: 'sample_project'
version: '1.0.0'
profile: 'sample_project'
config-version: 2

models:
  sample_project:
    marts:
      schema: mart
      materialized: table
```

```yml:profiles.yml
sample_project:
  target: dev
  outputs:
    dev:
      type: bigquery
      method: service-account
      project: {{GCPのプロジェクトID}}
      dataset: analysis
      threads: 3
      keyfile: /usr/app/dbt/{{認証鍵のJSONファイル}}
```

models/martsディレクトリ配下に、モデル生成の検証用SQLを作っておきます。

```sql:modes/marts/sample.sql
SELECT 
  1
```

# コンテナに接続して、BigQueryにテーブルを生成する

```shell
$ docker build -t dbt-bigquery .
$ docker run -d -v $PWD:/usr/app/dbt -p 8081:8081 dbt-bigquery
$ docker exec -it {{コンテナID}} /bin/bash

$ dbt run
```
LGTMランキングと合わない記事一覧


【毎日自動更新】新人プログラマ応援 - みんなで新人を育てよう！（2022年04月） LGTMランキング！

https://qiita.com/torifukukaiou/items/18dad64ba99aa5a40f95

をお作りいただいて、記事の見直し、タグの選択にとても役立った。
自分でつけたタグをfollowしていないのは直すようにした。
知らないタグは現在、猛勉強中。

自己集計をしようとして、自分の記録と、記事の集計とが合わない。

次の記事が見当たっていない。タグは何をつけているか確認予定。

|No.|表題|views |LGTM|ストック|
|:----|:----|:----|:----|:----|
|1 |品詞: 新人応援　@kazuo_reve 新人の方によく展開している有益な情報（32)https://qiita.com/kaizen_nagoya/items/18bb9fdb1cf2ece2d2f3|201 |1|0|
|2 |デザインの4つの基本原則: 新人応援　@kazuo_reve 新人の方によく展開している有益な情報（34）https://qiita.com/kaizen_nagoya/items/d121774661f5b6be0000|378 |0|0|
|3 |Robin Williams, Design book: @kazuo_reve 新人の方によく展開している有益な情報（35)https://qiita.com/kaizen_nagoya/items/da7afca95a1040d0390a|372 |0|0|
|4 |認知 @kazuo_reve 新人の方によく展開している有益な情報（39)https://qiita.com/kaizen_nagoya/items/34fb97e2ca1d813381e2|292 |1|0|
|5 |オープンソース　@kazuo_reve 新人の方によく展開している有益な情報（44)https://qiita.com/kaizen_nagoya/items/bc3119118eb71a7d314f|232 |1|0|
|6 |土壌作り　@kazuo_reve 新人の方によく展開している有益な情報（48)https://qiita.com/kaizen_nagoya/items/b5104219040247bdbabf|345 |1|0|
|7 |共通点　@kazuo_reve 新人の方によく展開している有益な情報（55)https://qiita.com/kaizen_nagoya/items/f6fee9afbccabec84f1e|73 |1|0|
|8 |育成　@kazuo_reve 新人の方によく展開している有益な情報(74) https://qiita.com/kaizen_nagoya/items/0d028e7375c81f97be18|45 |0|0|
【Swift】指定した文字列の位置(location)を検索する

指定した文字列の位置(location)を検索する！！
# ソースコード
```swift:usage
let text = "今日のお昼はカルボナーラを食べた！"
let searchString = "カルボナーラ"
let location = text.searchLocation(searchString: searchString)
print(location)      // 6
```
```swift:extension
extension String {
    func searchLocation(searchString: String) -> Int {
        let location = NSString(string: self).range(of: searchString).location
        if location >= self.count {
            return -1
        }
        return location
    }
}
```
位置が分かれば↓こういった文字列操作もできます
[【Swift】指定した文字列以前(以降)を削除する](https://qiita.com/hoshisuma/items/1a8f0823efc393e37f5f)
Flask についてまとめ3　仮想環境の作成

前々回の記事

https://qiita.com/TaichiEndoh/items/ca306560b928eddfc222

前回の記事となります

https://qiita.com/TaichiEndoh/items/7b7f82134a0333f8c8b9

全てこちらをベースに進めております

https://aiacademy.jp/media/?p=57

前回までは
ルーティングでURLとFlaskの処理を対応づけることで、URLと関数を紐付けることを細かく確認しました
今回は

### render_template() 関数による読み込み

から実行していこうと考えております
render_template() 関数とは

https://www.subarunari.com/entry/2017/09/30/003944


render_template() 関数を利用することで、Template(=雛形) である user.html に サーバのデータを組み込めます

render_template() 関数をを使う場合には、importによる記述と
templatesフォルダを新たに作成しそこにhtmlファイルを置きます

render_template() 関数をを用いる際には、templatesフォルダを作成する必要があり
作成していないとhtmlファイルを読み込むことが出来ませんのでご注意ください

そこでまず　templatesフォルダを作成します
```
- app.py(flaskでサーバー処理を行うpythonファイル)
- templates(HTMLファイルが沢山入るフォルダ)
　　　 └ index.html
```

ここでエラーが出るため　python のインタプリタを調整中です
また、ここまで基本　windows のデスクトップ環境で実施していたため
ubuntu の実施も検討します　

https://aiacademy.jp/media/?p=57

### Linux（ubuntu）で再検討

仮想環境の作成　ubuntu
```
python3 -m venv venv
```
仮想環境の有効化 ubuntu
```
source venv/bin/activate
```

### 仮想環境を有効にして　最小限のアプリを作成する

flaskbookフォルダを作成します
```
flaskbook
- apps
  - minimalapp
- venv
```

minimalapp配下にapp.pyを作成する
apps/minimalapp/app.py
```
#flask クラスをimport
from flask import Flask

#Flask クラスをインスタンス化する
app = Flask(__name__)
#URLと実行する関数をマッピングする
@app.route("/")
def index():
    return "Hello, Flask book like CEML"
```

app.py の環境変数を設定します

Linuxの環境変数とは、Linuxで動作するプログラムの設定値や読み込むファイルのディレクトリなどを設定した外部から参照できる変数のようなものです

最小限のアプリを起動する前に　環境変数FLASK_APP と　FLASK_ENV を設定する必要が有ります

FLASK_APP=アプリの場所
FLASK_ENV=development または production を指定する　
　　　　　　development　を設定すると　デバックモードがonになる

app.py のあるディレクトリに移動して　環境変数を設定　Linux
```
export  FLASK_APP=app.py
export  FLASK_EV=development
```
その後
```
flask run
```
で実装

右のローカルホスト上で　http://127.0.0.1:5000/

Hello, Flask book like CEML
と表示されます

exportコマンドで環境変数を設定しましたが　
それだとコンソールからのログアウト時に消えてしまいます

### アプリ単位で環境変数を設定する
.envを利用すると　アプリ単位で環境変数を設定できます
python-dotenvをインストールします

```
pip install python-dotenv
```
その後　- minimalapp　配下に

.envを作成し
```
FLASK_APP = app.py
FLASK_EV = development
```

### アプリケーションルート
アプリケーションルートとは、アプリを実行するディレクトリのことで
モジュールやパッケージを読み込むパスは

アプリケーションルートにより決まります

.env が有る場合　.envがあるディレクトリがアプリケーションルートとなります

```
flaskbook
- apps
  - minimalapp
  - .env
- venv
```

 minimalappの配下がアプリケーションルートとなります

今後　複数のアプリ開発をする際
その都度VSCodeのウインドウを切り替えなくてすむように

アプリケーションルートをflaskbookディレクトリに変更しましょう
```
flaskbook
- .env
- apps
  - minimalapp
- venv
```
これでアプリケーションルートがflaskbookに変わりました

flaskbookディレクトリにに移動し
flask run コマンドを実行

右のローカルホスト上で　http://127.0.0.1:5000/

Hello, Flask book like CEML
と表示されます

次はルーティングを利用してみます
NDLOCRのWebアプリを作ってみた【Gradio】

https://huggingface.co/spaces/tomofi/NDLOCR

NDLOCRを試せるWebアプリ作ってみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/e9bf7efd-a225-1ae7-b3f9-a2589fb9aefa.png)

```python
import os
import torch

print(torch.__version__)
torch_ver, cuda_ver = torch.__version__.split('+')
os.system(f'pip install mmcv-full==1.4.0 -f https://download.openmmlab.com/mmcv/dist/{cuda_ver}/torch{torch_ver}/index.html --no-cache-dir')
os.system('cd src/ndl_layout/mmdetection && python setup.py bdist_wheel && pip install dist/*.whl')
os.system('wget https://lab.ndl.go.jp/dataset/ndlocr/text_recognition/mojilist_NDL.txt -P ./src/text_recognition/models')
os.system('wget https://lab.ndl.go.jp/dataset/ndlocr/text_recognition/ndlenfixed64-mj0-synth1.pth -P ./src/text_recognition/models')
os.system('wget https://lab.ndl.go.jp/dataset/ndlocr/ndl_layout/ndl_layout_config.py -P ./src/ndl_layout/models')
os.system('wget https://lab.ndl.go.jp/dataset/ndlocr/ndl_layout/epoch_140_all_eql_bt.pth -P ./src/ndl_layout/models')
os.system('wget https://lab.ndl.go.jp/dataset/ndlocr/separate_pages_ssd/weights.hdf5 -P ./src/separate_pages_ssd/ssd_tools')
os.system("wget https://i.imgur.com/fSL1CGG.jpg")
os.environ["PYTHONPATH"]=os.environ["PYTHONPATH"]+":"+f"{os.getcwd()}/src/text_recognition/deep-text-recognition-benchmark"

import gradio as gr
from PIL import Image
from uuid import uuid4
from pathlib import Path


def inference(im):
    dir_name = uuid4()
    Path(f'{dir_name}/img').mkdir(parents=True)
    im.save(f'{dir_name}/img/image.jpg')
    os.system(f'python main.py infer {dir_name}/img/image.jpg {dir_name}_output -s f -i')
    image_path = f'{dir_name}_output/image/pred_img/image_L.jpg'
    if Path(f'{dir_name}_output/image/pred_img/image_R.jpg').exists():
        image_L = Image.open(f'{dir_name}_output/image/pred_img/image_L.jpg')
        image_R = Image.open(f'{dir_name}_output/image/pred_img/image_R.jpg')
        dst = Image.new('RGB', (image_L.width + image_R.width, image_L.height))
        dst.paste(image_L, (0, 0))
        dst.paste(image_R, (image_L.width, 0))
        dst.save(f'{dir_name}_output/image/pred_img/image_LR.jpg')
        image_path = f'{dir_name}_output/image/pred_img/image_LR.jpg'
    with open(f'{dir_name}_output/image/txt/image_main.txt') as f:
        return image_path, f.read()

title = "NDLOCR"
description = "Gradio demo for NDLOCR. NDLOCR is a text recognition (OCR) Program."
article = "<p style='text-align: center'><a href='https://github.com/ndl-lab' target='_blank'>NDL Lab</a> | <a href='https://github.com/ndl-lab/ndlocr_cli' target='_blank'>NDLOCR Repo</a></p>"
gr.Interface(
    inference, 
    gr.inputs.Image(label='image', type='pil'), 
    ['image', 'text'],
    title=title,
    description=description,
    article=article,
    examples=['fSL1CGG.jpg', 'b3b3963f-d577-4a30-acb9-0b395d4d87f7.jpeg', '8016ed5e-c0c7-4979-b6c6-d6b6c3945d7f.jpeg']
).launch(enable_queue=True, cache_examples=True)
```

# 参考

https://huggingface.co/docs/hub/spaces
開発環境のメモ

# 開発を始める
忘れないようにメモがわりに使います。
Pythonを利用
[macos/python/vscodeのセットアップはこちらを参考にしています](https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter-renderers)
## 環境
- マシン：Mackbook air (M1,2020)　　
  - macOS Montery バージョン　12.3.1　　
  - 8GB
- 言語
  - Python 3.8.9
- ソースコード管理：GitHub
- エディター：VSCode
  - Keymaps
    - [Vim v1.22.2](https://marketplace.visualstudio.com/items?itemName=vscodevim.vim) ：viライクのキーバインド
  - foromatters
    - [Prettire - Code formatter v9.5.0](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)　：色々な言語の自動フォーマット
    settings.jsonに`"editor.defaultFormatter": "esbenp.prettier-vscode"`を追加
  - git関連
    - [Git Graph v1.30.0](https://marketplace.visualstudio.com/items?itemName=mhutchie.git-graph)：リポジトリのGitグラフを表示し、グラフからGitアクションを簡単に実行できる
    - [Git History v0.6.19](https://marketplace.visualstudio.com/items?itemName=donjayamanne.githistory)：Git履歴、検索
    - [gitignore v0.7.0](https://marketplace.visualstudio.com/items?itemName=codezombiech.gitignore) :.gitignoreの編集支援
    コマンドパレットから`Add gitignore`
    - [GitLens - Git supercharged v12.0.6](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens)　：変更履歴を見やすくして理解を深める（個人開発だと、忘れた頃に見る時に重宝するかも）
    - [GitHub Pull Requests and Issues　v０.４０.0](https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-pull-request-github)　：プルリクエスト、チケット管理を楽にする。まだ使ったメリット感じていないので、共同開発向けかも
  - markdown(GitHubの記事を記載する用)
    - [Markdown All in One v3.4.3](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one)：Markdown記載のための色々機能（ショートカット、目次作成、プレビュー）
    - [markdownlint v0.47.0](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint)：Markdownのスタイルチェック
    - [Markdown Checkbox v1.8.0](https://marketplace.visualstudio.com/items?itemName=PKief.markdown-checkbox)：チェックボックスに特化した機能（使わないかも）
    - [Markdown Preview Enhanced　　v0.6.2](https://marketplace.visualstudio.com/items?itemName=shd101wyy.markdown-preview-enhanced)：高機能版プレビュー
  - [Python v2022.4.1](https://marketplace.visualstudio.com/items?itemName=ms-python.python)：ntelliSense(Pylance)、リンティング、デバッグ、コードナビゲーション、コードフォーマット、リファクタリング、変数エクスプローラ、テストエクスプローラなどの機能
  - [Pylance v2022.4.3](https://marketplace.visualstudio.com/items?itemName=ms-python.vscode-pylance)：Python3用のコード補完他
  - [Jupyter v2022.3.1000901801](https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter)
  - [Jupyter Keymap v1.0.0](https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter-keymap)
  - [Jypyter Notebook Renderers v1.0.6](https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter-renderers)
4.13 (標準) 連続確率変数と離散確率変数の同時分布

## 方針

Zは連続確率変数で，Wは離散確率変数なので，同時密度f_{Z,W}(z,w)のようなものを定義できない．Wは0か1なので，

```math
P[Z\leq z, W=1],\ \ \ P[Z\leq z, W=0]
```

に分けて考えればよい．これが求める同時分布である．

## 答案

![4.-18.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1702786/7dcb1d4e-f885-b682-317b-54497658cc80.jpeg)


## 参考文献

- 『[現代数理統計学の基礎](https://www.kyoritsu-pub.co.jp/bookdetail/9784320111660)』(久保川達也　著)
画像内の直線を検出する

# OpenCVで簡単にできる

### ハフ変換
![9b94cbc7-b2f6-4577-8067-ebd2d3b83113.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/cedd1153-cf32-79ea-9909-a497347f3850.jpeg)
```python
import cv2
import numpy as np

img = cv2.imread('photo.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray,50,150,apertureSize = 3)

lines = cv2.HoughLines(edges,1,np.pi/180,400)
print(lines)
for line in lines:
  for rho,theta in line:
      a = np.cos(theta)
      b = np.sin(theta)
      x0 = a*rho
      y0 = b*rho
      x1 = int(x0 + 1000*(-b))
      y1 = int(y0 + 1000*(a))
      x2 = int(x0 - 1000*(-b))
      y2 = int(y0 - 1000*(a))

      cv2.line(img,(x1,y1),(x2,y2),(0,0,255),2)

cv2.imwrite('houghlines.jpg',img)
```

lineは
(p,θ)の配列で返ってきます。(p = xcosθ + ysinθ)

### 確率的ハフ変換

![a4e57ab5-9a63-48e2-a8d9-e1008f2a3a03.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/bc39fdbc-e7a6-1ec0-c3ec-28abebaa0df7.jpeg)

```python
import cv2
import numpy as np

img = cv2.imread('photo.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray,50,150,apertureSize = 3)
minLineLength = 100
maxLineGap = 10
lines = cv2.HoughLinesP(edges,1,np.pi/180,100,minLineLength,maxLineGap)
for line in lines:
  for x1,y1,x2,y2 in line:
      cv2.line(img,(x1,y1),(x2,y2),(0,255,0),2)

cv2.imwrite('houghlines2.jpg',img)
```

結果は始点と終点の配列として返って来ます。
第４引数のThresholdを調整しながら使いましょう。

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLやARKitを使ったアプリを作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
[GitHub](https://github.com/john-rocky)
numpyとscipy.sparceの行列の積の関係性のメモ

# はじめに

現在、numpyのndarrayで書かれたプログラムを、疎行列に対応するべくscipy.sparceを使って書き直しています。
その中で、特に行列積の書き方が双方いろいろあり、しかも統一されていませんでした。
そこで、双方の大切そうな内容をまとめました。

結論から言うと、行列積は`@`を使用しましょう。

# 用語

https://qiita.com/PuchiCorner/items/201edc833eace5ee9c00

## 行列積
線形代数で習う、行列同士の掛け算

```math
A=\begin{bmatrix}
  3&4 \\ 
  5&6
\end{bmatrix},  
B=\begin{bmatrix}
  1&2 \\ 
  3&4
\end{bmatrix}
```

```math
A\cdot B=
\begin{bmatrix}
  3*1+4*3&3*2+4*4 \\ 
  5*1+6*3&5*2+6*4
\end{bmatrix}=
\begin{bmatrix}
  15&22 \\ 
  23&34
\end{bmatrix}
```




## アマダール積
行列の同じ位置の要素を掛け合わせる。


```math
A=\begin{bmatrix}
  3&4\\ 
  5&6
\end{bmatrix},  
B=\begin{bmatrix}
  1&2 \\ 
  3&4
\end{bmatrix}
```


```math
A\odot B=
\begin{bmatrix}
  3*1&4*2 \\ 
  5*3&6*4
\end{bmatrix}=
\begin{bmatrix}
  3&8 \\ 
  15&24
\end{bmatrix}
```

## おそらく
ネット上で解説記事がなく、自分でプログラムを作って確認。バージョンが古いこともあるかも。




# 結果

異なる型同士の演算は省略しました。
aは列名の行列、bはsparse行列を表します。
つまり、`a+a`は、
`numpy.ndarray`の列では、`numpy.ndarray` + `numpy.ndarray`
`numpy.matrix`の列では、`numpy.matrix` + `numpy.matrix`
`scipy.sparse`の列では、`scipy.sparse` + `scipy.sparse`
を意味します。

|  a:列要素 b:sparse    | numpy.ndarray | numpy.matrix | scipy.sparse | 
|:-:                  |:-:|:-:|:-:|
| a+a  | 要素ごとの和  | 要素ごとの和  | 要素ごとの和  |   |   |
| a-a  | 要素ごとの差  | 要素ごとの差  | 要素ごとの差  |   |   |
| a/a  | 要素ごとの商  | 要素ごとの商  | 要素ごとの商  |   |   |
|a ±スカラー           | すべての要素に  | すべての要素に  | エラー  |   |   |
|a /スカラー           | すべての要素に  | すべての要素に  | すべての要素に |   |   |
| a*スカラー           |各要素のスカラー倍   | 各要素のスカラー倍  | すべての要素に  |   |   |
|numpy.multiply(a,a)     | アダマール積  | アダマール積  | おかしくなる  |   |   |
| a*a  | アダマール積  | 行列積  |行列積   |   |   |
|numpy.dot(a,a)   | 1D内積　2D行列積(非推奨)  |おそらく行列積   | おかしくなる  |   |   |
|numpy.matmul(a,a)   | 1D内積　2D行列積  | おそらく行列積  |   |   |   |
| a@a  | 1D内積　2D行列積  | おそらく行列積  | おそらく行列積  |   |   |
| a**5  | アダマール積5回  | 行列積5回  | 行列積5回  |   |   |
| a**-1  | アダマール積(float)  | 逆行列  |   |   |   |
|numpy.linalg.inv(a)   | 逆行列  | 逆行列  |   |   |   |
| a.I  | I属性なし  | 逆行列  |   |   |   |
| numpy.linalg.det()  | 行列式  | 行列式  |   |   |   |
| b.dot(b)  |   |   | 行列積  |   |   |
| b.multiply(b)  |   |  | 行列積   |   |   |
| scipy.sparse.linalg.inv(b)  |   |  | 逆行列  |   |   |
| a.T  | 転置  |おそらく転置  | 転置  |   |   |


# 祖行列に関するTips

>なお、処理速度はcsr_matrix同士、または、csc_matrix同士が高速。異なるクラスを混在させたままにするよりもどちらかに統一して処理したほうがよい。

https://note.nkmk.me/python-scipy-sparse-calc-operation/


>csr_matrixは〜行目を取り出す操作、csc_matrixは〜列目を取り出す操作が高速である

https://hamukazu.com/2014/09/26/scipy-sparse-basics/

>同じ型同士の和・積は高速である。つまりcsr_matrix同士の和・積、csc_matrix同士の和・積はともに高速である

https://hamukazu.com/2014/09/26/scipy-sparse-basics/

>オブジェクトの生成は高速だが算術演算などはサポートされていない。CSRやCSCへの変換も高速なので、COOを生成後、CSRに変換し演算を行うのが基本的な使い方。

https://note.nkmk.me/python-scipy-sparse-matrix-csr-csc-coo-lil/


# 最後に

行列積について、`*`は挙動が違いますが、`@`は3つ型で同じ挙動なので、お勧めです。

穴抜けの部分、間違いなどありましたら教えてください。


# 参考

https://note.nkmk.me/python-numpy-matrix/

https://numpy.org/doc/stable/reference/generated/numpy.dot.html

https://numpy.org/doc/stable/reference/generated/numpy.matmul.html

https://qiita.com/ao_log/items/64768b67153e8fb6820b

https://note.nkmk.me/python-scipy-sparse-calc-operation/
抽象化

## 抽象化とは？

詳細を捨象し、一度に注目すべき概念を減らす仕組みです。

## 抽象度が高いとは？

抽象度が高いほど概念を表す情報量は多くなり、抽象度が低いほど概念を表す情報量は低くなる。
|  例  |  抽象度  |
| ---- | ---- |
|  動物 |  高い  |
|  犬  | 低い  |

## 抽象化は2種類

### 制御抽象化
動作の抽象化で、処理をモジュール化すること。

#### 詳細な情報をモジュール化するメリット

- モジュールを使う側で実装の詳細がなくなり、可読性が上がります。
- モジュール化することで他の箇所でも使えるようになり、再利用性が上がる。
- テストが作りやすくなり、保守性が上がる。

### データ抽象化
データの抽象化で、データを意味のあるデータと扱うこと

#### データの抽象度が低いモジュール、クラスのメリット

- 肥大化することを防ぎ、該当の処理を見つけやすくなります。見やすくなります。
- 値がシンプルになり、場合分けなどがなく、可読性が上がります。

|  例  |  抽象度  |
| ---- | ---- |
| 金額 |  高い  |
|  商品金額  | 低い  |
|  消費税  | 低い  |

## 参考資料

https://ja.wikipedia.org/wiki/%E6%8A%BD%E8%B1%A1%E5%8C%96_(%E8%A8%88%E7%AE%97%E6%A9%9F%E7%A7%91%E5%AD%A6) 

https://kuwamoto-coaching.com/archives/5136659.html

https://qiita.com/0w0/items/2cfaf3ca0b653960f5e9 

https://masuda220.hatenablog.com/entry/2020/06/26/182317#%E6%8A%BD%E8%B1%A1%E5%8C%96
特定のデータの名前を取得する方法：str.contains, srt.startswith

顧客IDがAから始まるデータだけ取り出したいなぁ
１学年から２学年のデータだけ取り出したいなぁ

なんてことが大量のデータの中から取り出すのなにかと面倒ですよね。
そんなときに用いるのが、
`str.startswith('文字列')`と`.str.contains( )`になります。
これをqueryメソッドと合わせて書き込むことで、特定の情報のみ取り出すことができます。

```Python
import pandas as pd
df01 = pd.DataFrame( {'name':['A', 'B', 'C'],
'学年':["１学年", "２学年", "３学年"],                      
'math':[60, 70, 80]})
df01
```
```
name	学年	math
0	A	１学年	60
1	B	２学年	70
2	C	３学年	80
```
これらの３学年のデータを取り出したいときは、以下の記述をします。
```Python
df01.query("学年.str.startswith('３')" , engine="python")
```
```
  name	学年	math
2	C	３学年	80
```
`startswith()`の()中身には最初の文字列を入力します。''で囲むことを忘れないようにしましょう。今回は`３`を検索しているので、上記のようになっています。
また、`engine="python`にしないと`.str`関数が使えないので必ず記述しましょう。

次に、１学年から２学年のデータのみ取り出しましょう。
今回は先にコードを記述していきます。
```Python
df01.query("学年.str.contains('^[１-２]',regex=True)" , engine='python')
```
先ほどの違う点としては`.contains('^[１-２]',regex=True)`
だと思います。
この ^や[]や-などは、正規表現といいます。簡単に説明していきます。

正規表現
様々なパターンで並んでいる文字列を特殊文字などを使って表現する表記法

また、基礎的な表記法もいくつか書いていきます。

任意の1文字：.
文字列の先頭：^
文字列の最後：$
同一文字の繰り返し：*, +, ?
範囲指定：-
角括弧に含まれるいずれか１文字にマッチ：[ ]
角括弧に含まれる文字以外にマッチ：[^]

このことから、先ほど記述した意味としては、
１から２から始まるデータを取り出す
ということになります。

正規表現はほかにもあるので、調べてみてください。

また、`regex=True`にしないと正規表現は使えないので必ず記述しましょう。

それでは、今回はここまでになります。またよろしくお願い申し上げます。
Postgresのデータをファイルへ書き出す (psqlでCopyコマンド)

# 概要

リモートのPostgreSQLサーバからローカルにCSVファイルとしてテーブルをExportする。


# `COPY`と`\copy`コマンド

## [COPY](https://www.postgresql.org/docs/current/sql-copy.html): テーブルとpostgresqlユーザ操作可能なファイル間

```sql
COPY (SELECT * FROM country WHERE country_name LIKE 'A%') TO '/usr1/proj/bray/sql/a_list_countries.copy';
```

> The file must be accessible by the PostgreSQL user (the user ID the server runs as) and the name must be specified from the viewpoint of the server.

リモートにPostgreSQLがある場合には、PostgreSQL userがローカルのファイルにアクセスできないので、`COPY`コマンドは使えない。

## [\copy](https://www.postgresql.org/docs/current/app-psql.html): データベースサーバとファイルのサーバが違くても大丈夫 (リモート可)

> Do not confuse COPY with the psql instruction \copy. \copy invokes COPY FROM STDIN or COPY TO STDOUT, and then fetches/stores the data in a file accessible to the psql client. Thus, file accessibility and access rights depend on the client rather than the server when \copy is used.

`\copy` は、`COPY FROM STDIN`や`COPY TO STDOUT`を実行し、それからそのデータを`psql`クライアントがアクセス可能なファイルから読み取り/に書き込む。

# 使い方

リモートインスタンスとローカルファイルの操作に関しては、 `psql -c` を使う:

```shell
psql <database> \
    -U <db_user> \
    -p <db_port> \
    -h <db_host> \
    -c "\copy <table> from '/path/to/table.csv' with DELIMITER ','"
```

# 具体例
## 例1. `\COPY FROM`: ファイルからテーブルへ書き込む場合

```sql
\copy <table> from '/path/to/table.csv' with DELIMITER ','
```

## 例2. `\COPY TO`: テーブルからファイルへ書き込む場合

```sql
\copy <table> to '/path/to/table.csv' with DELIMITER ','
```

## 例3. `\COPY TO`: SQLを使って必要なデータのみテーブルからファイルへコピーする場合

CopyしたいものをSQLで書くこともできる。

```sql
\copy (select field_a, field_b from table_a where field_c = 10;) to '/path/to/table.csv' with DELIMITER ','
```

## 例4. `\COPY TO`: CSVでHeaderをつける

```sql
\copy <table> TO '/path/to/table.csv' with delimiter ',' csv header
```

## 例5. テーブルをSTDOUTに出す

```sql
\copy <table> TO STDOUT with delimiter ','
```

## 例6. STDINからインポート

```sql
\copy <table> FROM STDIN with delimiter ','
```

# References

- [【PostgreSQL】一括でデータを入出力できるCOPYコマンド](https://tech.pscsrv.co.jp/2020/05/08/%E3%80%90postgresql%E3%80%91%E4%B8%80%E6%8B%AC%E3%81%A7%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E5%85%A5%E5%87%BA%E5%8A%9B%E3%81%A7%E3%81%8D%E3%82%8Bcopy%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89/)
- [COPY — copy data between a file and a table](https://www.postgresql.org/docs/current/sql-copy.html)
- [psql — PostgreSQL interactive terminal](https://www.postgresql.org/docs/current/app-psql.html)
- [\copy コマンドを使用して PostgreSQL DB インスタンスのテーブルにデータをインポートする
](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/PostgreSQL.Procedural.Importing.Copy.html)
- [Postgres: \copy syntax](https://stackoverflow.com/questions/48872965/postgres-copy-syntax)
カードをひっくり返しているように見せる！【css+jQuery】

初投稿です！！

初心者ですが一生懸命書いてゆきますので、間違っているところなどございましたらご指摘お願いいたします。


今回は、カードがひっくり返って見える実装をしました。

【HTML】

```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="./css/style.css">
    <title>くるっとさせるcss</title>
</head>
<body>
    <div class="card"> </div>

    <script src="./js/jquery-3.6.0.min (2).js"></script>
    <script src="./js/script.js"></script>
</body>
</html>
```


【CSS】

```css
/* スタイルのcss */
.card{
    width: 300px;
    height: 400px;
    background-color: aquamarine;
    margin: 100px;
}

/* クリックした時の動きのcss */
.card__item__active{
    transform:rotateY(360deg);    /*回転*/
    transition: 3s;              /*3秒かけて*/
}
```

【jQuery】
```js
$(".card").on('click', function(){
    $(".card").addClass("card__item__active");
});
```



このままだと、カードが360度回転して戻ってきてしまうと思います。
裏返して見えるようにしたいので、
```transform:rotateY(360deg)```の角度を
180度に変えていきます。

そして、回転している間にsetTimeoutでタイミングを調整しつつ好きな画像などを挿入すれば、裏返って見えるようになります。


【CSS】

```css
/* スタイルのcss */
.card{
    width: 300px;
    height: 400px;
    background-color: aquamarine;
    margin: 100px;
    transform:rotateY(180deg);   /*カードが裏返って見えるようにあらかじめ180度回転させておく*/
}

/* クリックした時の動きのcss */
.card__item__active{
    transform:rotateY(360deg);    /*回転*/
    transition: 3s;              /*3秒かけて*/
}

.card img{
    width: 300px;
    height: 400px;               /*画像のサイズ*/
}

```


【jQuery】

```javascript
$(".card").on('click', function(){
    $(".card").addClass("card__item__active"); //アクティブクラスを付与して回転
    setTimeout(() => {
        $(".card").html('<img src="./florist-g0d4688c17_640.jpg" alt=""></img>');
    }, 1000);                                  //1秒かけてcardクラスに画像を追加
});
```


カードを裏返す実装は、表と裏のdiv要素をHTMLで作るやり方もあるようですが、今回はこのようなやり方でチャレンジしてみました。
Mac + Lima + Debian + systemd-nspawn = CentOS7

CnetOS7の検証環境が急遽必要になったので今後の事を考えて Mac + Lima + Debian + systemd-nspawn でインストールした覚書

## 大まかな流れ
1. MacにLimaをインストール
1. LimaにDebian11をインストール
1. Debianにsystemd-nspawnをインストール
1. Debianにyumをインストール
1. DebianにCentOS7をインストール


### MacにLimaをインストール
```
% brew install lima
```

### LimaにDebian11をインストール
インストールしたバージョンと同一のものを [lima-vm/lima](https://github.com/lima-vm/lima) からもってくる
```
% limactl -v
limactl version 0.8.3

% curl -o debian.yaml https://raw.githubusercontent.com/lima-vm/lima/v0.8.3/examples/debian.yaml
% limactl start ./debian.yaml
```
起動時尋ねられるので `Proceed with the default configuration` を選択
```
? Creating an instance "default"  [Use arrows to move, type to filter]
> Proceed with the default configuration
  Open an editor to override the configuration
```

### Debianにsystemd-nspawnをインストール

Debianのシェルに入る。
```
% limactl shell debian
```

```
(debian11)$ sudo apt install systemd-container
```

###  Debianにyumをインストール

```
(debian11)$ sudo apt install dnf
(debian11)$ sudo tee /etc/yum.repos.d/CentOS7-Base.repo<<"EOF"
[base]
name=CentOS-7 - Base
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os&infra=$infra
enabled=0
gpgcheck=0
EOF
```

###  DebianにCentOS7をインストール

CentOS7 インストール
```
(debian11)$ dnf --releasever=7 \
    --installroot=/var/lib/machines/centos7 \
    --disablerepo='*' \
    --enablerepo=base \
    install systemd passwd yum sudo vi
(debian11)$ echo 7 > /var/lib/machines/centos7/etc/yum/vars/releasever
```

ネットワークをプライベートからホストネットワークに変更
```
(debian11)$ sudo mkdir -p /etc/systemd/nspawn/
(debian11)$ sudo tee /etc/systemd/nspawn/centos7.nspawn<<EOF
[Network]
VirtualEthernet=no
EOF
```

コンテナを起動
```
(debian11)$ systemd-nspawn -D /var/lib/machines/centos7
```
CentOS7のシェルでログインユーザーを作成する
```
# ユーザ作成
(centos7)$ useradd -m your-name -s /bin/bash

# パスワード設定
(centos7)$ passwd your-name

# sudo権限付与
(centos7)$ gpasswd -a your-name wheel

# コンテナから一旦ぬける
(centos7)$ exit
```

コンテナをブート
```
(debian11)$ systemd-nspawn -bD /var/lib/machines/centos7/
```

外部と接続できるか確認
```
(centos7)$ sudo yum update

# 「Ctrl+]」 x ３ で終了
```

コンテナ起動
```
# コンテナ起動
(debian11)$　sudo machinectl start centos7

# コンテナの起動状態確認
(debian11)$　sudo machinectl status centos7

# コンテナへログイン
(debian11)$　sudo machinectl login centos7
```
[Flutter] Google I/O 2022 Flutter まとめ

こんにちは
5月にある予定GoogleI/OのFlutterイベントをまとめてみました。

https://io.google/2022/intl/ja/


## 1日目

|  Title  | Tag  |  概要 |  スピーカー |  Link |
|-----------------------|---|---|---|---|
| Flutter の新機能 |  初級, 基調講演, Flutter | 複数のプラットフォームで動作する美しいネイティブ アプリを単一のコードベースからビルドする方法など、Flutter の最新情報を紹介します。  |  Andrew Brogdon, Tim Sneath |  https://io.google/2022/program/a2114fc4-10f7-4071-a065-69dc727aeaa5/intl/ja/ |
| Flutter アプリに WebView を追加する |  初級, Flutter, 設計, ワークショップ | このワークショップでは、WebView を Flutter アプリに追加する方法を説明します。  |  Andrew Brogdon | https://io.google/2022/program/b148d900-8bf4-49d0-aa6a-9b5596b81a3d/intl/ja/  |
| Flutter デスクトップ アプリケーションを作成する | 中級, Flutter, ワークショップ  | このワークショップでは、GitHub REST API を使用する Flutter デスクトップ アプリケーションを構築します。  | Justin McCandless  |  https://io.google/2022/program/eed4be55-068e-4cdd-b3e6-5cdd9ec5022f/intl/ja/ |
| 退屈な Flutter アプリを美しいアプリに変える | 中級, Flutter, iOS, Android, ワークショップ | うまく構築されたアプリでも、つまらなく見えることはありませんか？このワークショップでは、シンプルな手順で退屈なアプリを美しいアプリに変える方法について説明します。| Rody Davis, Khanh Nguyen | https://io.google/2022/program/7508cd2e-a0a3-4190-adf0-961d21b2424e/intl/ja/ | 

## 2日目

|  Title  | Tag  |  概要 |  スピーカー |  Link |
|-----------------------|---|---|---|---|
| Flutter での同時実行: Flutter でマルチスレッドを利用すべきタイミング、理由とその方法 | Flutter, 上級, iOS, Android | Dart のイベントループとアイソレートについて学びます。ジャンクをなくし、Flutter のパフォーマンスを向上させるために、この 2 つを活用する方法も紹介します。 |  Michael Goderbauer, Michael Thomsen |  https://io.google/2022/program/5b1811d3-3bcb-4d30-b2a1-a098225029a7/intl/ja/ |
| Flutter アプリのクラッシュを監視する | 中級, Flutter | 本番環境の Flutter アプリがどのように動作しているかに関して、知見を得る方法を学習します。| Andrew Fitz Gibbon | https://io.google/2022/program/0ff4783f-5a6c-403f-9fb4-e1c1d8e451be/intl/ja/ |
| Flutter ウェブアプリ: 最新ブラウザとの相性は抜群 | 中級, Flutter, ウェブ  | ウェブの Flutter が、どのように最新のブラウザ標準を活用しているかについて詳しく説明します。| Kevin Moore | https://io.google/2022/program/8d2af92f-0fab-4c42-8036-a9a964552f71/intl/ja/ | 
| Flutter デスクトップの展開 | 中級, Flutter | デスクトップ プラットフォームを対象とした Flutter アプリを構築するときの、細かな留意点について学びます。| Craig Labenz, Greg Spencer | https://io.google/2022/program/149d8583-1a73-4b3c-85be-500468c71bcd/intl/ja/ | 
| Flutter フェデレーション プラグイン開発の実際 | Flutter, 上級, iOS, Android |フェデレーション プラグインの実績のある手法を学び、Flutter デスクトップ開発に備えましょう。| Reid Baker, John McDole | https://io.google/2022/program/d5b1af75-eab5-4cf6-9f9d-01b83d9f4054/intl/ja/|
[備忘録]NUXT3でrootDirを変更する際の注意

Nuxt3のrc版が出たので、色々と備忘録を残していこうと思います。

# ルートディレクトリを変更

Nuxtではデフォルトでルート直下に各ディレクトリを配置するようになっているため、src下をデフォルトのディレクトリとする場合に`nuxt.config.ts`に`rootDir`を設定します

参考：https://v3.nuxtjs.org/api/configuration/nuxt.config#rootdir

```nuxt.config.ts
import { defineNuxtConfig } from 'nuxt3'

// https://v3.nuxtjs.org/docs/directory-structure/nuxt.config
export default defineNuxtConfig({
    rootDir: "src"
})
```

これで、srcディレクトリがルートディレクトリとして認識されるようになり、src下にコードを移動してビルドが通るようになります。

# 問題：VSCodeが組み込み関数を認識しない

ただ、VSCodeでVue3やNuxt3の組み込み関数（CompositionAPI等）が見つけられない状態となります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325108/7e01545c-d12a-bdf6-439c-a6efc2350cbc.png)

# 原因

結論から言うと、tsconfig.jsonでextendsしているjsonファイルが見つけられないために発生しています。

```tsconfig.json
{
  "extends": "./.nuxt/tsconfig.json",
}
```

rootDirを変更したことで`.nuxt`ディレクトリ（自動生成される）の出力位置も変わっていました。

↓rootDir変更後のディレクトリ構造

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325108/86127665-d4d6-1e1a-6378-08e876e2bb84.png)



# 解決法

extendsのパスをrootDirに合わせて変更します。

```tsconfig.json
{
  // nuxt.config.tsのrootDirに合わせる
  "extends": "./src/.nuxt/tsconfig.json",
}

```
【Golang】assignment to entry in nil mapで怒られる原因

# 概要
go初学者です。
assignment to entry in nil mapで怒られる原因と、空のsliceへの値の追加との差を調査しました。


# 疑問点
下の場合、なぜs（slise）には要素を追加できて、m(map)には追加できない？

```main.go
package main

import "fmt"

func main() {
	var s []int
	fmt.Println(s)
	s = append(s, 1)
	fmt.Println(s)

	var m map[string]int
	fmt.Println(m)
	m["first"] = 100
	fmt.Println(m)
}
```
### 出力

```
[]
[1]
map[]
panic: assignment to entry in nil map
```

### 原因

nilマップに要素を代入しようとしたから。

>Assigning to an element of a nil map causes a run-time panic.
[The Go Programming Language Specification](https://go.dev/ref/spec)



# なぜnilマップには要素を追加できないのか

これは成功する・・・

```main.go
package main

import "fmt"

func main() {
	var s []int
	fmt.Println(s)
	s = append(s, 1)
	fmt.Println(s)

	// これはassignment to entry in nil map
	// var m map[string]int
	// fmt.Println(m)
	// m["first"] = 100
	// fmt.Println(m)

	var m2 map[string]int
	fmt.Println(m2)
	m2 = make(map[string]int)
	m2["first"] = 100
	fmt.Println(m2)
}

```
### 出力

```
[]
[1]
map[]
map[first:100]
```

つまり、初期化しているか否かで結果が変わる。
では初期化の有無で何が異なるのでしょうか？
```
    var m map[string]int //要素を追加できない

	var m2 map[string]int = make(map[string]int) //要素を追加できる
```

```main.go
package main

import "fmt"

func main() {

	var s []int
	fmt.Printf("%p %T %v\n", s, s, s)

	var m map[string]int
	fmt.Printf("%p %T %v\n", m, m, m)

	var m2 map[string]int = make(map[string]int)
	fmt.Printf("%p %T %v", m2, m2, m2)
}

```
### 出力
```
0x0 []int []
0x0 map[string]int map[]
0xc0000981b0 map[string]int map[]
```
ここで、一番左側に16進数で出力されているのはポインタの値（アドレス値）です。
※アドレス値とは変数がメモリ上のどこに保持されているのかを指す値。

したがって、m2変数以外はメモリ上に保持のための場所が確保されていないことが分かります。

つまり、初期化していないマップmに要素を追加しようとして「assignment to entry in nil map」が発生する原因は、メモリ上に要素追加に必要な場所が確保されていないからです。

### ではどうすればよい？
下記のようにmake()で初期化し、場所を確保しましょう。

```go
	var m2 map[string]int = make(map[string]int)
```

>新しい空のマップ値を作るには、組み込み関数makeを用いる。makeは、マップの型とオプションの容量ヒントを引数にとる。
>マップは、nilマップを除いて、格納されているアイテムの数に合わせて大きくなる。nilマップは、要素が追加されないことを除けば、空のマップと同じである。
[The Go Programming Language Specification](https://go.dev/ref/spec#Map_types)

### スライスに要素が追加できた理由
append()で要素を追加する場合、スライスに十分な容量がない場合は、新しい基になる配列が割り当てられるからです。

下記のようにlen()で初期化していないスライスの容量は0であることが分かります。
一方append()後はアドレス値が付与されて容量が1になっています。
したがって、この場合はマップの初期化後と同様に、メモリ上に場所が確保されています。

```go
	var s []int
	fmt.Printf("%p %T %v\n", s, s, s)
	fmt.Println(len(s))
	s = append(s, 1)
	fmt.Println("append後")
	fmt.Printf("%p %T %v\n", s, s, s)
	fmt.Println(len(s))
```
```
0x0 []int []
0
append後
0xc0000160b8 []int [1]
1
```

>append組み込み関数は、スライスの最後に要素を追加します。十分な容量がある場合は、新しい要素に対応するために宛先が再スライスされます。そうでない場合は、新しい基になる配列が割り当てられます。Appendは、更新されたスライスを返します。したがって、多くの場合、スライス自体を保持する変数に、追加の結果を格納する必要があります。
>[The Go Programming Language Specification](https://pkg.go.dev/builtin#append)

# まとめ

- nilマップには要素を追加できない
- その理由はメモリ上に要素追加に必要な場所が確保されていないから
- スライスに要素を追加できたのは、append()によって新しい基になる配列が割り当てられたから
FIELD_INTEGRITY_EXCEPTION: The record does not exist in specified network.: Entity ID.


[同じフローでFeedItemとTopicAssignmentを作成できますか？](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000GiKWU)


私はついにそれを理解しました。これは、FeedItemを作成しているときに、NetworkScopeフィールドに入力しなかったためです。ただし、TopicAssignmentで指定していました。そのため、フローがTopicAssignmentを作成しようとしていた場所ではなく、FeedItemが作成されていました。
書籍「Pytorch&深層学習プログラミング」２章補足PART2　sum関数をmax関数に置き換えると何がおきるか？

# はじめに
この記事は、別記事[書籍「Pytorch&深層学習プログラミング」２章補足　sum関数で微分計算ができる理由](https://qiita.com/makaishi2/items/a6cf19add4b6d16b8483)の続編です。
前の記事では、$y=f(x)$の値の1階テンソルをsum関数で集約すると微分計算ができること、mean関数だと、微分計算ができるが、値は導関数値をデータ個数で割ったものになることを示しました。
この記事のテーマは、**代わりにmax関数を使うとなにがおきるか**ということです。

# 実装と結果

## 事前準備コード
事前準備で必要なコードを一つにまとめると以下のとおりです。

```py
!pip install torchviz | tail -n 1
import numpy as np
import matplotlib.pyplot as plt
import torch
from torchviz import make_dot

plt.rcParams['font.size'] = 14
plt.rcParams['figure.figsize'] = (6,6)
plt.rcParams['axes.grid'] = True

x_np = np.arange(-2, 2.1, 0.25)
```


## max関数を利用した場合

```py
# 勾配計算用変数の定義
x = torch.tensor(x_np, requires_grad=True, 
    dtype=torch.float32)

# 2次関数の計算
# 裏で計算グラフが自動生成される
y = 2 * x**2 + 2

# スカラー化のためにmax関数を利用する
z = y.max()

# 可視化関数の呼び出し
g= make_dot(z, params={'x': x})
display(g)

# 勾配計算
z.backward()

# 勾配値の取得
print('勾配値', x.grad)

# 元の関数と勾配のグラフ化
plt.figure(figsize=(6,6))
plt.plot(x.data, y.data, c='b', label='y')
plt.plot(x.data, x.grad.data, c='k', label='y.grad')
plt.legend()
plt.show()
```

結果は以下になります・

計算グラフ
<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/c2069c74-6740-a9de-0bbb-5af51267cf85.png' width=200>


勾配計算結果
<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/2992cdae-f841-3bd9-bf78-62c14efceab7.png' width=500>


# 数学的な解説
上の勾配計算の結果は、次の2つであると読み取れます。

(1) 両端の点を除いた15個の点では勾配値はゼロ
(2) $x=-2.0$と$x=2.0$の両端では、勾配値は、それぞれの導関数値の1/2

(2)は、[第1部](https://qiita.com/makaishi2/items/a6cf19add4b6d16b8483)のsum関数の結果と比較することでわかります。


今回の問題では、まずxとして、-2から2までの等間隔の17個の点を取りました。
具体的には
$x_0 = -2.0$
$x_1 = -1.75$
:
:
$x_{15} = 1.75$
$x_{16} = 2.0$

次に$y = f(x) = 2x^2+2$により、それぞれの点に対応するyの値を求めています。

$y_0 = f(x_0)$
$y_1 = f(x_1)$
:
:
$y_{15} = f(x_{15})$
$y_{16} = f(x_{16})$

そして、zは$y_0, y_1, ..., y_{15}, y_{16}$の最大値として定義しています。
最大値は、実際にはｘの端点($x_0とx_{16}$)で決まっている点に注意して下さい。

この前提で、(1)について考えてみます。
勾配値とは、
**注目している変数（今は$x_k$)を微少量変化させたとき、目的とする変数(今は$z$)がどの程度変化するかを元に計算される**
という点が重要でです。
$x_1$のような端点でない点を微少量変化させたとしても、最大値zは変化しません。
このことはつまり**端点以外の$x_k$では勾配値はゼロである**ことを意味します。

では、(2)についてはどうでしょうか？

端点の一つである$x_{16}=2.0$に注目し、この値を微少量増やしたとき、zがどう変化するか考えてみます。
現在は、$x_0とx_{16}$で同時に最大値10.0を取っていますが、 値を微少量増やすと、$x_{16}$だけで最大値を取るようになります。その増え方は、値の増分をhとすると、およそ$f'(x)\cdot h$になります。

今度は値を微少量減らすことを考えます。すると、面白いことが起きます。$f(x_{16})$の値は微少量減るのですが、最大値zということで考えると、$f(x_0)$の値は変化しないので、変化なしになります。

ここで、書籍でも示している以下の数値微分を考えてみます。

hを微少量としたとき、

$f'(x)=\dfrac{f(x+h)-f(x-h)}{2h}$

で計算しています。
$f(x+h)-f(x-h) = (f(x+h)-f(x)) + (f(x)-f(x-h))$
と分解して考えてみると、前半の
$f(x+h)-f(x)$の部分は普通通りの微少量の変化があり、その大きさはおよそ$f'(x)\cdot h$であるのに対して、後半の$f(x)-f(x-h))$の部分は、変化量がゼロということになります。
そのため、全体としての勾配値は通常の導関数値の1/2になるのです。

左側の端点である$x_0$に関しても、zの値が変化しない領域が逆になるだけで、あとは同じ考え方で、勾配値が通常の1/2になることが説明できます。

以上で、今回の事象の説明は100%できたことになります。
あわせて、著者として確認できたことがあります。数値微分の公式が上で示したものであることは、知識としては持っていたのですが、実はPyTorchで本当にこの実装をしているかは、ソースレベルで裏取りはしていなかったです。
今回の検証により、間接的ではありますが、PyTorchの勾配計算の実装で上の公式を使っていることがわかったことになり、著者としても一安心した次第です。