OmniAICreator/Qiita-1.07M huggingface dataset:
JavaScriptの参照とコピーについて

## はじめに
プログラミング言語において参照やコピーは基礎の基礎。しかし私はJavaScriptを書いていてよく混乱することが多いので整理のためにも、参照とコピーについてまとめたいと思います。
## プリミティブ型とオブジェクトの参照
まずはプリミティブ型とオブジェクトの参照についてみていきます。
```javascript
//プリミティブ型の参照
let num = 1;
num = 2;
console.log(num); // 2

//オブジェクト型の参照
let obj = {
  a: "hello",
}
obj.a = "world";
console.log(obj.a); // world
```
プリミティブ型の参照は、変数``num``に1が記録されたメモリのアドレスが代入されています。この状態を『参照』と言い、そして変数``num``に2を再代入する時は、1が記録されていたメモリに2が上書きされ参照先自体は変わりません。

オブジェクトの参照は、``obj``に"hello"が格納されたメモリのアドレスを参照する``a``が保持されていることになります。なのでオブジェクトは『データをキーと値のペアで管理するもの』と定義されることがありますが、『データのアドレスに名前をつけて管理するもの』とも言えます。
## 参照とコピー
次に参照とコピーとその注意点についてです。
下記のコードでは変数``num``の値を変数``num2``にコピーし``num2``の値を変更しています。
```javascript
//プリミティブ型の参照
let num = 1;
let num2 = num;
num2 = 2;

console.log(num); // 1
console.log(num2); // 2

//オブジェクト型の参照
let obj = {
  a: "hello",
}
let obj2 = obj;
obj2.a = "world";
console.log(obj.a); // world
console.log(obj2.a); //world
```
ここでコピーされた``num``と``num2``の値を確認すると値が違います。``num``から``num2``へコピーした時は、``num``の参照先の値をコピーし複製した新しい参照先のものが``num2``へ保持されています。
しかし、オブジェクト型の参照の実行結果を見ると出力結果が同じになっています。

これは``obj``から``obj2``へ値を代入する際の挙動に差異があるからです。
オブジェクトを新しくコピーしようとした際にプリミティブ型のように新しいものが複製されるのではなく、参照先が同じオブジェクトが作成されているのです。つまり、オブジェクトの名前が違うだけで参照する値は同じものになります。

このようにプリミティブ型とオブジェクト型の参照とコピーには差異があり、この違いをしっかりと理解していないとJavaScriptを学んでいく中でつまづくことが多くなってしまいます（私のことです）。
## 参照と引数
ここからが非常に面白く、実は上記で説明させていただいた参照とコピーは関数へ引数を渡す際も同様のことが起きています。
```javascript
// プリミティブ型を引数として渡す

let name = "marumoto";

function updateName(nameA) { 
  console.log(nameA); // marumoto
  nameA = "shoma";
  console.log(nameA); // shoma
};

updateName(name);
console.log(name); // marumoto


// オブジェクトを引数として渡す
let user = {
  name: "marumoto",
}
  
function updateUserName(userA) {
  console.log(userA.name); // marumoto
  userA.name = "shoma";
  console.log(userA.name); // shoma
};
  
updateUserName(user);
console.log(user.name); // shoma
```

ここでの両者の違いも同様に
- プリミティブ型の値を関数へ渡した時は、関数スコープ内で使用する変数は引数として受け取った変数とは違う変数
- オブジェクトを関数へ渡した時は、参照先のアドレスが渡されるので引数として渡ってきたものと同じオブジェクト
という参照とコピーの法則が適用されるようになります。
## 最後に
いかがだったでしょうか、今回は私がJavaScriptを勉強していて理解が難しかった参照とコピーについてまとめてみました。

同じように見えるものでも実は背景では違うものとして扱われていて、とても分かりにくいとは思いますが、ここを理解しておくとバグを防ぐことができるのでしっかりと意識していきたいところだと思っています。

### GoQSystemでは一緒にはたらいてくれる仲間を募集中です！

ご興味がある方は以下リンクよりご確認ください。

https://goqsystem.recruit.site/?qiita=e3a966df5960510eaeff
【CommonLisp】マクロは前の定義、関数は後の定義が使われる

## 前書き

* 割とどうでもいい話です
* 処理系はSBCLです

## ソース

```common-lisp
(defpackage :main
  (:use :cl))
(in-package :main)

(defun hoge ()
  (format t "hoge1~%"))

(defmacro fuga ()
  `(format t "fuga1~%"))

(defun main ()
  (hoge) ; -> hoge2
  (fuga) ; -> fuga1
  )

(defun hoge ()
  (format t "hoge2~%"))

(defmacro fuga ()
  `(format t "fuga2~%"))

```

まあ、普通はこんな書き方しないでしょう

## 訂正

マクロは展開される以前なら後ろの定義が使われる

```common-lisp
(defpackage :main
  (:use :cl))
(in-package :main)

(defun hoge ()
  (format t "hoge1~%"))

(defmacro fuga ()
  `(format t "fuga1~%"))

(defmacro fuga ()
  `(format t "fuga2~%"))

(defun main ()
  (hoge) ; -> hoge2
  (fuga) ; -> fuga2
  )

(defun hoge ()
  (format t "hoge2~%"))
```

## おまけ

つまりこういうことができる（実務では使わないように）

```common-lisp
(defpackage :main
  (:use :cl))
(in-package :main)

(defmacro hoge ()
  `(format t "hello"))

(defmacro hoge ()
  (hoge)
  `(format t ", world.~%"))

(defun main ()
  (hoge) ; -> hello, world.
  )
```
【ログ】ABC 122 B - ATCoder

# 問題文
>英大文字からなる文字列 S が与えられます。S の部分文字列 (注記を参照) であるような最も長い ACGT 文字列 の長さを求めてください。
ここで、ACGT 文字列とは A, C, G, T 以外の文字を含まない文字列です。
# 入力と出力
>S

>S の部分文字列であるような最も長い ACGT 文字列の長さを出力せよ。
# ACコード
```
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
    string s;
    cin >> s;
    int counter = 0;
    int maxcnt = 0;

    rep(i, s.size()){
// ACCTのいずれかに該当した場合、counter++
        if(s.at(i) == 'A' || s.at(i) == 'C' || s.at(i) == 'G' || s.at(i) == 'T') {
            counter++;
//最大数と現ループのcounterの数比較
            maxcnt = max(counter, maxcnt);

        } else {
            counter = 0;
        }
    }

    cout << maxcnt << endl;
}

```
# 学んだこと
全探索で最大数を求める時はcounterと比較をして、大きい方を保存するmaxcntなどの変数を用意するとよい。
NetBSDでもIoT

[ORIONのネットワーク](https://qiita.com/yamori813/items/cb8861fe17ca51b73bd2)が使えるようになったのでInternet of Test(IoT)を行ってみます。

まずhttpが話せるmrubyを用意します。[ここの](https://qiita.com/yamori813/items/1eb41bf0c11b2ec1d0fa)ビルド設定に以下を追加します。

```build_config/netbsd.rb
  conf.gem :git => 'https://github.com/mattn/mruby-uv.git'
  conf.gem :git => 'https://github.com/mattn/mruby-http.git'
  conf.gem :git => 'https://github.com/luisbebop/mruby-polarssl.git'
  conf.gem :git => 'https://github.com/matsumoto-r/mruby-simplehttp.git'
  conf.gem :git => 'https://github.com/matsumoto-r/mruby-httprequest.git'
  conf.gem :git => 'https://github.com/matsumoto-r/mruby-sleep.git'

  conf.linker.libraries = %w(m)
```

libuvのconfigureを作るためautoconf,automake,libtoolが必要なのでpkgをインストールしておきます。

これでrakeでビルドするとmruby-uvのlibuvのビルドで失敗するので、以下を追加します。

```ruby:build/repos/cross-netbsd-arm/mruby-uv/mrbgem.rake
  configure_opts += ["--host arm-portbld-netbsd"]
```

直に追加しました。なにか適当な条件式で括るのが良いですが、分からなかったです。RUBY_PLATFORMを使うのが良さそうなのですが、他のところでエラーになるので、あきらめました。現在のコードはRUBY_PLATFORMがhostの意味を持つケースとtargetの意味を持つケースがあり、混乱しているようです。

--hostなのでamd64-portbld-freebsdが正しいような気がします、こうしないとダメでした。libuvのconfigureの問題か、configure自体の問題のどちらかと思われます。

LUNAやってたころはconfigureはすばらしいと思いましたが、あの頃ほどシステムに違いがなく、必要以上に複雑なconfigureは近代においては百害あって一利なしなきさえします。

ライブラリの構成が違うのでここもいじりました。

```ruby:build/repos/cross-netbsd-arm/mruby-uv/mrbgem.rake
#    spec.linker.libraries << ['uv', 'pthread', 'rt', 'm', 'dl']
    spec.linker.libraries << ['uv', 'pthread', 'kvm']
```

libmは何故かここに書いてもきかなかったので、build_configに書いてます。

またNetBSDにはAI_ALLとAI_V4MAPPEDが無いようなのでbuild/repos/cross-netbsd-arm/mruby-uv/src/mrb_uv.cの定義をコメントアウトします。

ZRouterのFreeBSD環境ではlibuvは別にビルドしてそれを使うようにしています。

これでビルドできたmrubyをramdisk.fsに入れてINSTALLカーネルを作りu-bootでブートします。

シングルユーザーで上がっているshから以下のmrubyスクリプトを実行します。

```ruby:iot.rb
APIKEY = "naisyo"

count = 0
while 1 do
  p SimpleHttp.new("https", "api.thingspeak.com", 443).get("/update?api_key=" +
APIKEY + "&field1=" + count.to_s, {'User-Agent' => "test-agent"})
  count = count + 1
  Sleep::sleep(60)
end
```

実行する前にdhcpcdを起動してIPを取得しておきます。

できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/547e189e-d86f-b1ea-a6ff-28e4f375f41c.png)

しばらく動かしていたらエラーで止まってました。なんだろう？

```
trace (most recent call last):
        [7] iot.rb:5
        [6] iot.rb:5:in get
        [5] iot.rb:5:in request
        [4] iot.rb:5:in send_request
        [3] iot.rb:5:in new
        [2] iot.rb:5:in initialize
        [1] iot.rb:5:in foreach
iot.rb:5:in getaddrinfo: getaddrinfo: Temporary failure in name resolution (SocketError)
```

Ethernetコンバーターが落ちたようです。。。

mrubyのバイナリサイズ確認してみました。

|オプション|ストリップ前|ストリップ後|
|:--|:--|:--|
|無し(デフォルト)|4242524|3212000|
|-Os|3405148|2412344|

スタティックリンクなので大きいです。

この仕組みでモジュールに押し込むためにはRAM 16MでFlash 4Mでどうにかなるかもしれません。(未確認)
お知らせのデータ基盤をMeilisearchに移行した話

はじめに
=======

本稿では私の所属するビジネス・ブレークスルー社の受講者に対するお知らせの配信基盤にMeilisearch取り込んだことについて書きます。

アジェンダ
=========

- 移行前のシステムと課題
- 改善の計画
- 移行後のシステム
- まとめ


移行前のシステムと課題
====================

移行前のシステムです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105394/8175ec46-7669-5909-fab9-e4c74defea55.png)
SQLServerで管理されたお知らせ配信情報の一覧をAPIで返したり、公開時刻になったお知らせをメールやプッシュ通知で通知する仕組みです。
上記お知らせマスタの数は3万件以上。配信対象のユーザー数は40万件以上となっていました。
単純な取得処理であれば問題ない規模なのですが、弊社のシステムではユーザーの属性毎にパーソナライズされており、APIで実行するクエリは複雑になっていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105394/1d7d466e-fd7e-0c16-7623-d14f39eac361.png)

クエリが複雑化したせいで、配信対象の多いユーザーと少ないユーザーでSQLServerが作る実行プラン切り替わり、APIの応答が突如遅くなる現象が起きていました。


改善の計画
=========

最初は遅くなったクエリを分析したり外部のDBAに見てもらったりしながら小さく変更を行っていましたが、あまり改善効果はありませんでした。

それとは全く関係のない話題で時雨堂さんがMeilisearchの紹介をしていて、このプロダクトは面白いねという話をしたりしていました。
https://zenn.dev/voluntas/scraps/77ae77d06deadc

そこで「お知らせの配信をMeilisearch使ったらどうなるんだろうか」と思い、プロトタイプを書き始めました。

移行後のシステム
===============

Meilisearch導入後の構成です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105394/7449adc3-a8fa-33a1-526e-256e5b8c522d.png)

SQLServerとMeilisearchの同期は2種類に分けて書きました。
- インデックスから全て作り直す処理（Lambdaで実行する）
- リアルタイムに同期する処理（マスタを更新する管理画面で同期する）

プロトタイプ当初はMeilisearchから取得したお知らせの情報をさらにPythonでフィルタするという非効率な実装でした。
チームメンバーからのフィードバックもあり、Meilisearchにユーザー属性情報を予めタグとして登録することで一度の問い合わせで検索できるようにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105394/3c833880-3a87-ed51-9df4-a5a774743fd9.png)

結果、APIのレイテンシーは安定して0.3〜0.8秒になりました。

この仕組みだとおそらくSQLServerだけでも十分対策できたと思います。
しかし弊社のお知らせはキーワード検索も対応しており、Meilisearch採用できたおかげで今後の改善に活かすことができると考えています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105394/bac3b4d5-5c8c-2e9b-2f71-ed9a7ea8b861.png)


まとめ
=====

パーソナライズされた情報を全文検索でどうやって返すか、という課題に対してMeilisearchのドキュメントに検索する属性を予め登録しておき、問い合わせるユーザーの属性を付加して検索することで解決できました。
複雑なクエリを削除することができ、安定したレスポンスが返せるようになってホッとしています。
MacでZipファイルを作る

## ターミナルでZipを作る
WinArchiver LiteがAppleStoreでインストールできなかったから
ターミナルでZipファイルを作る方法をメモ

### 前提
- ターミナルでZipを作るファイルがあるところまで移動しておく
※階層違うところでコマンド実行するとエラーでます。

## 実行コマンド一覧
### Zipファイルから.DS_Storeを削除する

すでにzipファイルを作成している場合。
かつ.DS_Storeを削除をしたい場合。

```
zip -d ディレクトリ名.zip '*.DS_Store'
```

### Zip圧縮+.DS_Storeを削除
Zipファイル作る際に.DS_Storeも削除する場合。

```
zip -r ディレクトリ名.zip ディレクトリ名 -x '*.DS_Store'
```

### Zip圧縮+.DS_Storeを削除さらにパスワードをつける

```
zip -r -e ディレクトリ名.zip ディレクトリ名 -x '*.DS_Store'
```
picoCTF Writeup picoGym Practice Challenges SQL Direct (注意<spoiler>)

# SQL Direct

AUTHOR: MUBARAK MIKAIL / LT 'SYREAL' JONES

Description
Connect to this PostgreSQL server and find the flag!


ここら辺を入れておく
sudo apt install postgresql postgresql-contrib
sudo apt-get install postgresql-client

```
$ psql -h saturn.picoctf.net -p 62349 -U postgres pico
Password for user postgres:
psql (12.12 (Ubuntu 12.12-0ubuntu0.20.04.1), server 14.2 (Debian 14.2-1.pgdg110+1))
WARNING: psql major version 12, server major version 14.
         Some psql features might not work.
Type "help" for help.

pico=# select * from pg_tables;
pico=# select * from flags;
 id | firstname | lastname  |                address
----+-----------+-----------+----------------------------------------
  1 | Luke      | Skywalker | picoCTF{L3arN_S0m3_5qL_t0d4Y_31fd14c0}
  2 | Leia      | Organa    | Alderaan
  3 | Han       | Solo      | Corellia
(3 rows)

pico=# 
```

postgreSQL文を入力すればフラグのテーブルが見つかる。


picoCTF{L3arN_S0m3_5qL_t0d4Y_31fd14c0}
python 辞書の欠損処理について

## 辞書の欠損処理の方法

例題として、好きなプログラミング言語についてエンジニアの方々にアンケートを取り、これを辞書で定義します。もともと、プログラミング言語が登録されていない場合は、新たに作成して値を増やしていく。

~~~python:exam.py in方式
questionnaire = {
    "python": 1,
    "Rust": 2,
    "C": 0
}

print('アンケート前：', questionnaire)
key = "SQL"

if key in questionnaire:
    count = questionnaire[key]
else:
    count = 0

questionnaire[key] = count + 1
print('アンケート後：', questionnaire)

>>>
アンケート前： {'python': 1, 'Rust': 2, 'C': 0}
アンケート後： {'python': 1, 'Rust': 2, 'C': 0, 'SQL': 1}
~~~

~~~python:exam.py2 例外あり

questionnaire = {
    "python": 1,
    "Rust": 2,
    "C": 0
}

print('アンケート前：', questionnaire)

key = 'SQL'
try:
    count = questionnaire[key]
except KeyError:
    count = 0
questionnaire[key] = count + 1

print('アンケート後：', questionnaire)


>>>
アンケート前： {'python': 1, 'Rust': 2, 'C': 0}
アンケート後： {'python': 1, 'Rust': 2, 'C': 0, 'SQL': 1}
~~~

~~~python:exam3.py getメッソド

questionnaire = {
    "python": 1,
    "Rust": 2,
    "C": 0
}

print('アンケート前：', questionnaire)

key = 'SQL'
# keyが存在しない場合はデフォルト値0を返す
count = questionnaire.get(key, 0)
questionnaire[key] = count + 1

print('アンケート後：', questionnaire)

>>>
アンケート前： {'python': 1, 'Rust': 2, 'C': 0}
アンケート後： {'python': 1, 'Rust': 2, 'C': 0, 'SQL': 1}
~~~
以上のような、inを使う場合、例外を使う場合、getメソッドを使う場合があるが、getメソッドが、読性が高く、コードが短くなるので一番良いと考えられる。

## collectionsモジュールのCounterクラスを使ってみよう！
Counterは、listやdic内の要素をカウントしてくれる
~~~python:exam4.py
from collections import Counter

numbers = {'one': 12, 'two': 3, 'three': 6}
abc = ['a', 'a', 'a', 'a', 'a', 'c', 'c', 'b', 'b', 'b']

count_number = Counter(numbers)
count_abc = Counter(abc)
print(count_number)
print(count_abc)

>>>
Counter({'one': 12, 'three': 6, 'two': 3})
Counter({'a': 5, 'b': 3, 'c': 2})
~~~

## defaultdictを使おう！

参考
[Python defaultdict の使い方](https://qiita.com/xza/items/72a1b07fcf64d1f4bdb7)

>defaultdictの引数には、初期化時に実行する関数を
記述します。

以下、好きなプログラミング言語に投票した人の名前を値とした辞書を用いてみる。
~~~python:exam5.py
from collections import defaultdict


class programming:
    def __init__(self):
        self.data = defaultdict(set)

    def add(self, PL, name):
        self.data[PL].add(name)


questionnaire = {
    "python": ['taro', 'jiro'],
    "C": ['saburo'],
    "SQL": ['hanako']
}

P = programming()
P.add("Rust", 'jun')
P.add("Rust", 'mai')
print(P.data)

>>>defaultdict(<class 'set'>, {'Rust': {'mai', 'jun'}})
~~~
## 参考文献
Effective Python
picoCTF Writeup picoGym Practice Challenges Secrets (注意<spoiler>)

# Secrets

Description
We have several pages hidden. Can you find the one with the flag?
The website is running here.

http://saturn.picoctf.net:61481/
に行くとelementから/secretがあるのがわかり、移動するとまた、/hiddenというサイトがあるのがわかる。
また移動すると、/superhiddenというサイトがあるのがわかるので移動するとhtmlにフラグがある。

途中でサイトのポートが切れてしまい、サイトにたどり着かなくなるので注意が必要。

http://saturn.picoctf.net:61481/secret/hidden/superhidden/

picoCTF{succ3ss_@h3n1c@10n_39849bcf}
Railsシルバーってどんな問題が出るの？

はじめまして！
リンクアンドモチベーションの新卒エンジニアの葛葉（くずば）です。

# 初めに
入社してから、
「全体研修3ヶ月」 -> 「プログラミング研修3ヶ月」 -> 「配属されて3ヶ月」
と、泣いたり笑ったり苦しんだりしながら学びの多い日々を過ごしてきました。

現在は、営業する上で必要なデータをSQLを書いて出す作業や、簡易なバックエンドの実装（Ruby on Rails）などの業務を行っています。

しかし、2つ目のバックエンドの実装業務では、研修では全く学んでいない内容がたくさんあり、分からないことばかりです。。。

そこで、メンターと相談して、Rails4技術者認定シルバー試験（Rails Silver）を受けることにしました。

よく使われる公式問題集を中心に勉強を進めているので、
その中で解いてきた問題に類似した問題を2つ作成したので、紹介したいと思います。

ぜひ、何も見ずに解けるか試してみてください！！

# 問題
## 問題1
Active Recordを使用し、次のようなモデル定義を行なっている。
```# app/models/sport.rb
class sports < ActiveRecord::Base
  has_many :skills
end
```
```# app/models/skill.rb
class skills < ActiveRecord::Base
  belongs_to :sports
end
```
実行した時に次のSQLが発行されるものを1つ選びなさい。
```SQL
SELECT "sports".* FROM "sports"
SELECT "skills".* FROM "skills"."sport_id" IN (1,2)
```
A. Sport.includes(:skills)
B. Skill.includes(:sport)
C. Sport.joins(:skills)
D. Skill.joins(:sport)

## 問題2
ネストしたルーティングについて、以下の設定と同等ではないものをA~Cの中から1つ選びなさい。
```ruby
shallow do
  resources :sports do
    resources :skills
  end
end
```
A. 
```ruby
resources :sports do
  resources :skills, shallow: true
end
```
B.
```ruby
resources :sports do
  resources :skills, only: [:index, :new, :create]
end
```
C.
```ruby
resources :sports do
  resources :skills, only: [:index, :new, :create]
end
resources :skills, only: [:show, :edit, :update, :destroy]
```

# 解答と解説

## 問題1の答え
A

(以下解説)
Active Recordに関する問題です。
問題文の発行されたSQLを見ると、テーブルがjoinされていないため、
joinsメソッドを使った選択肢C, Dは違うことが分かります。

次に、includesメソッドを使用している選択肢A, Bを考えます。
まず、sport.rbでhas_manyメソッドで記載されていることからもわかるように、sportsテーブルとskillsテーブルとの関係は1対多であることが分かります。

また、問題文を見てみると、
```ruby
SELECT "skills".* FROM "skills"."sport_id" IN (1,2)
```
となっており、
skillsテーブルのsport_idのカラムからデータを取得しようとしていることが分かります。

テーブルの関係性や最終的にskillsテーブルからデータを得ようとしていることからも、
A. Sport.includes(:skills)
が正しいといえます。

## 問題2の答え
B

(以下解説)
ルーティングとAction Controllerに関する問題です。
ネストしたresourcesメソッドを使うと、親子関係のリソースのルートを設定できます。

たとえば、スポーツとそのスポーツの技を表示させるサイトで、
1番のスポーツの10個目の技を表示させたいとき、URLとしては、
`sports/1/skills/10`となり、子リソースの10だけで表示する内容が一意になるにも関わらず、
親リソースの情報もURLに書かなくてはなりません。

そこで、shallowメソッドを使います。
shallowメソッドでは、ネストしたresourcesメソッドを囲むことで、親リソースのID(sport_id=1）を指定しなくても表示させたい技のページを表示させることができます。

これらを踏まえて、選択肢を見ると、
選択肢Aでは、子リソースでshallowオプションを指定することで、問題文と同じ設定を行うことができると分かります。

また、選択肢Cでも、子リソース（skills）のコレクションルート（:idがつかないURIを生成する）のみを親リソースの中に組み込んだあと、
skillsのメンバールート（:idがつくURIを生成する）を別途設定しているため、
この設定に関しても、子リソースのskill_idの情報さえ揃っていれば、技のページに飛べるようになります。

一方で、選択肢Bでは、選択肢Cのようにskillsのメンバールートの設定が行われていないため、技のページに飛ぶことはできません。


# 終わりに
今回の問題は、[Rails4技術者認定シルバー試験問題集](https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5Rails4%E6%8A%80%E8%A1%93%E8%80%85%E8%AA%8D%E5%AE%9A%E3%82%B7%E3%83%AB%E3%83%90%E3%83%BC%E8%A9%A6%E9%A8%93%E5%95%8F%E9%A1%8C%E9%9B%86-%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%B7%E3%82%A7%E3%82%A2%E3%83%BC%E3%83%89-%E5%B1%B1%E7%94%B0%E8%A3%95%E9%80%B2/dp/4844337238)を参考に問題を作成しております。

これまでRailsを触り始めて5ヶ月目の僕からすると、ちょっと難しいのですが、今後も勉強を続けていこうと思います。

そして、Ruby on Rails脱初心者を目指します！

最後までご覧いただき、ありがとうございました！
ROS2における独自QoSプロファイルの設定方法

# ROS2 独自QoSプロファイル設定について
ROS2には、既にいくつかQoSプロファイルが用意されています。
ただ自分専用のプロファイルを作りたいと思って、実装してみたのでメモ程度にここに残しておきます。
ROS2で用意されているプロファイルの一覧も置いておきます。
プログラムは[ROS2 Documentation](https://docs.ros.org/en/foxy/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Cpp-Publisher-And-Subscriber.html)のWriting a simple publisher and subscriber(C++)を改良したものです。
# ソースコード
```
#include <memory>

#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"
using std::placeholders::_1;

class MinimalSubscriber : public rclcpp::Node
{
  public:
    MinimalSubscriber() : Node("minimal_subscriber")
    {
      custom_qos_profile.depth = 10;
      custom_qos_profile.history = rmw_qos_history_policy_t::RMW_QOS_POLICY_HISTORY_KEEP_LAST;
      custom_qos_profile.reliability = rmw_qos_reliability_policy_t::RMW_QOS_POLICY_RELIABILITY_RELIABLE;
      custom_qos_profile.durability = rmw_qos_durability_policy_t::RMW_QOS_POLICY_DURABILITY_VOLATILE;
      rclcpp::QoS qos_profile(rclcpp::KeepLast(10), custom_qos_profile);
      subscription_ = this->create_subscription<std_msgs::msg::String>(
      "topic", qos_profile, std::bind(&MinimalSubscriber::topic_callback, this, _1));
    }

  private:
    void topic_callback(const std_msgs::msg::String::SharedPtr msg)
    {
      RCLCPP_INFO(this->get_logger(), "I heard: '%s'", msg->data.c_str());
    }
    rclcpp::Subscription<std_msgs::msg::String>::SharedPtr subscription_;
    rmw_qos_profile_t custom_qos_profile = rmw_qos_profile_default;
};

int main(int argc, char * argv[])
{
  rclcpp::init(argc, argv);
  rclcpp::spin(std::make_shared<MinimalSubscriber>());
  rclcpp::shutdown();
  return 0;
}
```
それぞれのパラメータについては、[rmw_qos_profile_t Struct Reference](https://docs.ros2.org/latest/api/rmw/structrmw__qos__profile__t.html)を参考に実装しました。
例えば、ReliabilityとDurabilityは以下のパラメータで設定可能です。

|  Reliability  |  Durability  |
| ---- | ---- |
|  RMW_QOS_POLICY_RELIABILITY_SYSTEM_DEFAULT  |RMW_QOS_POLICY_DURABILITY_SYSTEM_DEFAULT|
|  RMW_QOS_POLICY_RELIABILITY_RELIABLE  |RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL |
|  RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT |RMW_QOS_POLICY_DURABILITY_VOLATILE| 

# ROS2で用意されているQoSプロファイル一覧
以下はROS2で用意されているQoSプロファイル達になります。
これらは、```/opt/ros/$ROS_DISTRO/include/rmw/qos_profiles.h```を見ながら並べました。
- rmw_qos_profile_sensor_data
- rmw_qos_profile_parameters
- rmw_qos_profile_default
- rmw_qos_profile_services_default
- rmw_qos_profile_parameter_events
- rmw_qos_profile_system_default
- rmw_qos_profile_unknown

何か間違いやご意見等があればコメントください。
Workato：Lookup TablesとAccount Properties (Environment Properties)の権限設定がより柔軟に


# はじめに
WorkatoのLookup TablesとAccount Properties (Environment properties）が、詳細な権限設定に対応しました。

これらの機能の権限は、これまでFull accessを与えるか、そうでないか（有効化するか、無効化するか）の選択した行えませんでしたが、最近の変更によりView, Edit, Create, Deleteより必要な権限をユーザーあるいはグループに与えられるようになりました。

簡単ではありますが、これまでと現在の違いについて以下にまとめてみました。

# 変更点
## これまで
Lookup tablesとAccount propertiesで指定可能な権限はFull access固定でした。ユーザー・グループに対する機能の有効・無効しか行えず、柔軟な設定を行うことができない状態でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/cce0f1c9-525f-069e-ab13-9aad0c15f5f8.png)

## 現在
Account propertiesはEnvironment propertiesへ名前が変わりました（機能はこれまでと変わりません）。それに加えて、Lookup tablesとEnvironment propertiesは、Data storageへ移動し、権限がより詳細に設定できるようになりました。これにより、例えば管理者にはFull accessを与え、あるユーザーに対しては参照権限のみ付与、あるユーザーには参照と更新権限のみ付与といった運用が可能となります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/81c90915-7681-17d2-4596-1a27e59394b2.png)

# 最後に

Lookup tablesやEnvironment propertiesはレシピを制御するうえで必要な値が管理されている（管理されている値がレシピの動作に影響を及ぼす）ユースケースもあり、より柔軟性をもって制御したいというWorkatoユーザーの方は多かったのではないかと思います。

管理されている値は見ても良いが追加や編集、削除はさせたくないといった場合であっても、これまではFull accessしか選択できなかったゆえに参照以外の操作が行われるのではないか（誤った値の更新や削除などの事故が発生しないか）と不安に感じながら権限を与えていたケースも今後はView権限のみ与えれば済み、Full accessを与える必要がなくなるため、安全に利用できる状態になることが期待できます。

個人的には、上記に加えてプロジェクト単位でLookup tablesやAccount propertiesの管理（プロジェクトに紐づくKey-Valueやテーブル）や権限設定が行えるようになると嬉しいなといった感じです。現行の機能はグローバルな値管理の仕組みとして生かしつつ、ローカル（プライベート）な値管理の仕組みがあると良いですね。（いずれ実装されるかな・・・）
Visual Studioを常に管理者権限で起動する

管理者権限じゃないと起動できないプロジェクトがたまにあります。
'C:\inetpub\wwwroot\'に設置しているやつとか。
いちいち右クリックするのも面倒なので常に管理者権限で起動するように設定します。

1. Visual Studioの実行ファイルパスを控えておく。ショートカットから辿っていくと楽です。
私の場合は`"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\devenv.exe"`でした。

1. 「ファイル名を指定して実行」(Windows+R)に`regedit`と入力
レジストリエディタが開きます。

1. `HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers`に移動。

1. 右ペインの空きスペースで右クリック、「新規」から「文字列値」を選択。

1. 名前は実行ファイルのパス、値は`~ RUNASADMIN`とする。

最終的にはこうなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199145/64962d78-ce6f-dfe1-7ce5-1a53956eba72.png)

Visual Studioを起動して、UACの確認画面が出れば成功です。
DMM WEBCAMPに入学したまとめ（入学理由・メリット・デメリット）

# はじめに
本記事は[Progaku Advent Calendar 2022](https://qiita.com/advent-calendar/2022/progaku) 13日目担当ひで丸です。
今回は、DMM WEBCAMPについて書いていこうと思います！
DMM WEBCAMPの専門技術コースに入学したので、専門技術コースメインの記事になります。

# 背景
この記事はDMM WEBCAMPまたはプログラミングスクールに興味ある方向けです！

未経験からプログラマーを目指すにしても学習や転職のハードルが高いと感じ、DMM WEBCAMPの専門技術コース（４ヶ月間）に入学し、約３ヶ月半経ちました。

その経験の中で、DMM　WEBCAMPに入学して良かったことや悪かったことがある程度感じることができたので、これらと入学した理由をお伝えし、プログラミングスクールを迷われている方のためになればと思い、この記事を書きました。

# DMM WEBCAMP 専門技術コースとは？
転職型プログラミングスクールであるDMM WEBCAMPが数々用意してあるコースの一つで、
学習と就職の両方をサポートしてくれるコースで学習・就職・金銭面の特徴は下記のようになってます。

### 学習面
* 4ヶ月のフルタイムでガッツリ学べる（学習時間：約500時間）
* 教材を読みながら学び、分からないところをメンターに聞くような学習方法
* 2ヶ月目のチーム開発で現場の仕事に近い開発ができる
* ポートフォリオを作ることができ、そのまま面接に使用できる
* 経験者のメンターが揃っており、好きなだけ質問できる
* HTML/CSS/JS/jQuery/Ruby/Ruby on Rails等の幅広い言語を学べる

### 就職面
* 未経験からの就職ノウハウを学べる
* 職務経歴書やスキルシートを添削してもらえる
* 企業紹介をしてくれて、面接等をセッティングしてもらえる
* 最大約１年間のサポート

### 金銭面
* **「教育訓練支援給付金」** を受け取ることができる
* 教育訓練支援給付金で実質35万円で学び、転職することができる
※給付金取得には申請及び条件があります！
* 給付金が貰えるのはDMM WEBCAMP卒業後なので、初期費用高め

# DMM WEBCAMPに入学した理由？
退職してすぐの頃はプログラミングスクールに入らず、独学でITパスポートを学んだり、
JAVAやHTMLを勉強していましたが、何をどう学んで、転職にどう進んでいくのかというものが
中々見えてこなかったので、専門家を頼る方が早い！と思いプログラミングスクールを考えました。

そこで、DMM WEBCAMPの専門技術コースに入りましたが、入った理由としては下記の４つになります。
* 短期間のフルタイムでガッツリ学びたい!
* 給付金を活用し、安い金額で学びたい!
* チーム開発をしてみたい!
* キャリアサポートしてもらいたい!

上記の条件でプログラミングスクールを探し、一番マッチしたのがDMM WEBCAMPの専門技術コースだったので入学することに決めました。

入学して3ヶ月半で、フルタイムでガッツリ学び、チーム開発をするという経験を得ましたが、
これらは想像以上に達成できており、休みもなしにプログラミング漬けをする日々があったり、
現場での環境を意識しながらチームで開発し、チーム内で刺激を得ることができました。

給付金については、条件を達成次第もらえると思いますし、キャリアサポートも本格的に始まってきており、サポートは厚く頼もしい次第です。

# 良かった点
現時点では学習面で良かったことが多いので、学習面多めで挙げました。
* 集中してプログラミングを学ぶことができた
* デイリースクラムや、チーム開発を通してプログラミングを共に学べる仲間ができた
* プログラミングの理解や興味が高まった
* 継続して勉強をする習慣が身についた
* 使った教材を卒業後も使える

以上が良かったことになりますが、DMM WEBCAMPに入っていなければ、毎日8時間以上の勉強だったり、周りと勉強することで同じ立場で同じ目標を持った仲間を作ることは難しかったのではないかと思います。
結果として、プログラミング学習としての基礎知識と、学習においての大事な継続力が身につきました。

# 悪かった点
もう少しこうなれば良いのになと思った点がいくつかあったので、これらを挙げてみました。
* メンターが選べないので相性や質が運次第
* メンターを活用できる時間が限られている
* 4ヶ月目の選択コースで学ぶAWSが学ぶメリットを感じにくい

まず、メンターについてですが、メンターへの質問方法が質問フォームに質問したい内容を書いて送ると、メンターの誰かからzoomの案内が送られて、zoom内で画面を共有しながら話すという感じになります。このような方式のため、メンターガチャとなり、質の良いメンターと質の良くないメンターのどっちがくるかがわかりませんでした。そして、メンターの質問対応時間は限られており、13:00~22:00と19:00~22:00のどちらかで、朝質問したい時にできなかったのはもどかしかったです。
また、DMM WEBCAMP4ヶ月目は選択コースで「AI」と「クラウド」のどっちかが学べます。
そこで、実用的そうなクラウドコースを学びましたが、学ぶことはAWSサービスの説明や高度な仮想サーバの設定方法等で転職してもすぐ活用できるかといえば、そうでもなさそうだな感じました。そのため、メリットは薄く感じてしまい、他の学習に力を入れた方がいいのでは？と思いました。

# まとめ
結果として、DMM WEBCAMPに入学したことは自分にとって大きなメリットになったと感じております！
メリットとして感じ取れたのも、自分のニーズに合わせたプログラミングスクールを選択できたのが、一番の理由だと考えています。そのため、プログラミングスクールに入学したいと思っている方は、自分がどういう環境で学びたいか？とかどういうプランで就職までしたいか？など自己分析をして、**自分のニーズに合せたプログラミングスクールを決める**ことがいいのではないでしょうか。
また、プログラミングスクールが終わってからも日々勉強は必要ですし、そこからが本番だと思っています！
日々学習できている皆様に負けないよう、自分自身も勉強をより一層頑張りたいと思っています！！！

以上、[Progaku Advent Calendar 2022](https://qiita.com/advent-calendar/2022/progaku) 13日目担当でした！！
プログラミングの基礎（浅井健一）10.1 関数のネスト の処理を追ってみる

# 関数の定義とテスト

```ocaml
(* 目的 : 整数 n とリスト lst を受け取り、
         lst の各要素のそれぞれの頭に n つけたものを返す *)
(* add_to_each : int -> int list list -> int list list *)
let rec add_to_each n lst = match lst with
    [] -> []
  | first :: rest -> (n :: first) :: add_to_each n rest

(* テスト *)
let test1 = add_to_each 1 [] = []
let test2 = add_to_each 1 [[2]] = [[1; 2]]
let test3 = add_to_each 1 [[2]; [2; 3]] = [[1; 2]; [1; 2; 3]]
let test4 = add_to_each 1 [[2]; [2; 3]; [2; 3; 4]] = 
                        [[1; 2]; [1; 2; 3]; [1; 2; 3; 4]]

(* 目的 : リスト lst を受け取り、
          lst の接頭語のリストを返す *)
(* prefix : int list list -> int list list  *)
let rec prefix lst = match lst with
    [] -> []
  | first :: rest -> [first] :: add_to_each first (prefix rest) 

(* テスト *)
let test5 = prefix [] = []
let test6 = prefix [1] = [[1]]
let test7 = prefix [1; 2] = [[1]; [1; 2]]
let test8 = prefix [1; 2; 3; 4] = 
                   [[1]; [1; 2]; [1; 2; 3]; [1; 2; 3; 4]]
```

# prefix [1; 2; 3] の処理の流れを追ってみる

```ocaml
prefix [1; 2; 3] -> [1] :: add_to_each 1 (prefix [2; 3])

prefix [2; 3] -> [2] :: add_to_each 2 (prefix [3])

prefix [3] -> [3] :: add_to_each 3 (prefix [])

prefix [] -> [] (* 定義より *)

prefix [3] -> [3] :: add_to_each 3 (prefix [])
           =  [3] :: add_to_each 3 []

  add_to_each 3 [] -> [] (* 定義より *)

prefix [3] -> [3] :: add_to_each 3 [] 
           -> [3] :: []
           =  [[3]]

prefix [2; 3] -> [2] :: add_to_each 2 (prefix [3])
              -> [2] :: add_to_each 2 [[3]]

  add_to_each 2 [[3]] -> (2 :: [3]) :: add_to_each 2 [[]]

  add_to_each 2 [[]] -> [] (* 定義より *)

  add_to_each 2 [[3]] -> (2 :: [3]) :: add_to_each 2 [[]]
                      -> (2 :: [3]) :: []
                      =  ([2; 3]) :: []
                      =  [[2; 3]]

prefix [2; 3] -> [2] :: add_to_each 2 [[3]]
              -> [2] :: [[2; 3]]
              =  [[2]; [2; 3]]

prefix [1; 2; 3] -> [1] :: add_to_each 1 (prefix [2; 3])
                 -> [1] :: add_to_each 1 ([[2]; [2; 3]])

  add_to_each 1 [[2]; [2; 3]] -> (1 :: [2]) :: add_to_each 1 [[2; 3]]

  add_to_each 1 [[2; 3]] -> (1 :: [2; 3]) :: add_to_each 1 [[]]

  add_to_each 1 [[]] -> [] (* 定義より *)

  add_to_each 1 [2; 3] -> (1 :: [2; 3]) :: add_to_each 1 []
                       -> (1 :: [2; 3]) :: []
                       -> ([1; 2; 3]) :: []
                       -> [[1; 2; 3]]

  add_to_each 1 [[2]; [2; 3]] -> (1 :: [2]) :: [[1; 2; 3]]
                              =  ([1; 2]) :: [[1; 2; 3]]
                              =  [[1; 2]; [1; 2; 3]]

prefix [1; 2; 3] -> [1] :: add_to_each 1 ([[2]; [2; 3]])
                 =  [1] :: [[1; 2]; [1; 2; 3]]
                 =  [[1]; [1; 2]; [1; 2; 3]]

```
picoCTF Writeup picoGym Practice Challenges Roboto Sans (注意<spoiler>)

# Roboto Sans

Description
The flag is somewhere on this web application not necessarily on the website. Find it.
Check this out.

名前からしてrobots.txtに何か情報があるはずである

http://saturn.picoctf.net:65352/robots.txt
```robots.txt
User-agent *
Disallow: /cgi-bin/
Think you have seen your flag or want to keep looking.

ZmxhZzEudHh0;anMvbXlmaW
anMvbXlmaWxlLnR4dA==
svssshjweuiwl;oiho.bsvdaslejg
Disallow: /wp-admin/
````

https://gchq.github.io/CyberChef/#recipe=From_Base64('A-Za-z0-9%2B/%3D',true,false)&input=c3Zzc3NoandldWl3bDtvaWhvLmJzdmRhc2xlamc

3行あるbase64の文字をデコードすればフラグのアドレスたどり着ける

ZmxhZzEudHh0;anMvbXlmaW 　　-> 　　flag1.txtjs/myfi
anMvbXlmaWxlLnR4dA==    　　-> 　　js/myfile.txt

txtjs/myfile.txt あたりを見るとフラグが現れる。
実際にはjs/myfile.txtの場所にあった。

http://saturn.picoctf.net:65352/js/myfile.txt


picoCTF{Who_D03sN7_L1k5_90B0T5_718c9043}
Query関数 列名が予約語とかぶった時はバッククオートだ

# こんなことがありました

「横に長いテーブルがあって `BY列` をselectしたい」のですが、

```
=query(A:BY,"select BY",1)
```

って書くと

![error1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/373e655d-3a96-0d4f-94e3-76a32cd23e5c.png)

の画像のようにエラーになってしまいます。
`BY` が Query関数の予約語(group by とか order by かな)になってるので、列名として解釈できず、エラーになってる、、、(と思われる)


# 解決策

MySQLと同じく、カラム名(列名)をバッククオートでくくる。

```
=query(A:BY,"select `BY`",1)
```

![ok.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/093a0ef6-a209-4e4a-ce8d-339f0ccba7ae.png)


参考: https://gontora.hatenadiary.com/entry/2015/09/30/174633
pandasでcsvをjson,jsonl, parquetに変換する

csvファイルを変換する必要があったため，備忘録的に書きました。
with文を使ったjsonへの変換もできますが，結論としてはpandasが一番楽だと思います。


# 環境
- OS:macOS Montery 12.6
- python:3.10.6
- scikit-learn:1.1.2
- pandas:1.4.0
- pyarrow:10.0.1
- fastparquet:2022.12.0
- parquet-cli:1.12.3

　また，vscodeの拡張機能を使用して，Jupyterで実験しました。

# データセットの用意
scikit-learnに入っているカリフォルニアの住宅価格のデータセットを使用しました。

```python
from sklearn.datasets import fetch_california_housing
import pandas as pd
housing_data = fetch_california_housing()
df_data = pd.DataFrame(housing_data.data, columns=housing_data.feature_names)
df_data.head()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2950855/519d9f53-b8c9-bd67-9670-822f1ed06da0.png)

このデータをcsvで保存します。
```python
#DataFrameをcsvとして保存する
csv_file = df_data.to_csv("./data.csv", index=0)
```


# csv->json
```python
import pandas as pd
df_data = pd.read_csv("./data.csv")

#json形式で出力する
df_data.to_json("./data_pd.json", orient="records")
```




# csv->jsonl
```python
import pandas as pd
df_data = pd.read_csv("./data.csv")

#jsonl形式で出力する
df_data.to_json("./data_pd.jsonl", orient="records",lines=True)
```

# csv->parquet
`pyarrow`と`fastparquet`のinstallが必要です。
```python
import pandas as pd
df_data = pd.read_csv("./data.csv")
#parquet形式で出力する
df_data.to_parquet(path="./data.parquet")
```

正しく出力されたか確認してみましょう。
今回は`parquet-cli`を使いました。

brewからインストールできます。
```zsh
# parquet-cliのインストール
brew install parquet-cli
```


```zsh
$ parquet head data.parquet
```
正しく出力できているようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2950855/c027b428-6642-c76c-c876-eed37265d292.png)





## おまけ：pyarrowとfastparquetのインストール
※`pyarrow`と`fastparquet`がinstallされていない場合，`to_parquet（）`を実行すると以下のエラーが表示されます。
```
   　 ImportError: Unable to find a usable engine; tried using: 'pyarrow', 'fastparquet'.
     A suitable version of pyarrow or fastparquet is required for parquet support.
     Trying to import the above resulted in these errors:
      - Missing optional dependency 'pyarrow'. pyarrow is required for parquet support. Use pip or conda to install pyarrow.
      - Missing optional dependency 'fastparquet'. fastparquet is required for parquet support. Use pip or conda to install fastparquet.
```
指示に従って，`pip`もしくは`conda`でインストールしましょう。
私は`miniforge`を使用していたので，`conda`でインストールしました。

```
conda install pyarrow fastparquet -y
```

# まとめ
pandasめっちゃ便利。
コマンド2，3行でデータの変換ができちゃいます。

書いた後に気づいたのですが，厳密には全てpd.DataFrameを経由しています。`csv->pd.DataFrame->json`が正確な表現ですね。
大きなファイルを変換する場合は`read_csv()`で`Out of Memory`のエラーが出る場合があります。
他の方法も探してみます。

## 参考
- [pandas.DataFrameをJSON文字列・ファイルに変換・保存（to_json） | note.nkmk.me](https://note.nkmk.me/python-pandas-to-json/)

- [parquet-cli で Parquet ファイルを読む - kakakakakku blog](https://kakakakakku.hatenablog.com/entry/2022/12/12/094113)
- [Input/output — pandas 1.5.2 documentation](https://pandas.pydata.org/docs/reference/io.html)
レガシー脱却準備としてのテスト

この記事は「[「レガシー」を保守したり、刷新したりするにあたり得られた知見・ノウハウ・苦労話 by Works Human Intelligence Advent Calendar 2022](https://qiita.com/advent-calendar/2022/works-hi-3)」の参加記事になります。

## レガシーの定義と終わらない戦い
まず、前提としてレガシーの定義を確認したいと思います。

https://ja.wikipedia.org/wiki/%E3%83%AC%E3%82%AC%E3%82%B7%E3%83%BC%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0

> レガシー(legacy)とは英語で資産・遺産という意味であり、レガシーシステムとは典型的には、まだユーザーが必要とする機能を持つが、現在可能な、より新しい技術やより効率的な技法ではないシステムのことである

含意が広いですね。

見てわかる通り、レガシーなシステム・アプリケーションと言う言葉は明確な定義を持っていません。
言ってしまえば、現在の技術/手法によって"レガシー"状態を脱したとしても、それ以降の何処かのタイミングではレガシーとなってしまう可能性があります。

単純に開発手法の問題であれば、"放置"という選択肢もなくはないですが、プラットフォームの使用期限や利用形態の変化によってシステムは変わり続ける必要に迫られます。

システムやアプリケーションが使われ続ける限り、更新続けることを考慮した作りが必要となり、"レガシーからの脱却"という状態は実現不可能。もしくは時限的な状態に思えます。

なので、正しい表現・一つのゴールとしては「レガシーからの脱却がより容易な状態にしておく」というところだと考えています。

## テストに対する信頼性の確保
レガシーの話題が出ると、大抵出てくるのが「自動テストがない」という話です。
自動テストがあることによって、リファクタリングをしてもそれら自動テストによって、それまでの仕様が変更されていないことが保証されるというもの。
または、テストを仕様と考え、技術刷新の際には同様のテストを通すことでバージョン間の差異を明らかにするということができます。

では、そのテストが仕様を満たしているかはどうやって信頼/保証するのでしょう

一般的にはこれらはカバレッジ分析によって表現されることが多いです。
しかし、カバレッジも万能ではなく、単純なコードカバレッジだけでなく条件網羅を厳密に考えるのであれば非常にパターン数が増加し、どこかのタイミングではテストコードを書くことが非常に非効率な状態が生まれます。

逆に言えば網羅可能なサイズに納めることが非常に大事になります。
これは、いわゆるマイクロサービス的な文脈に近づきますが、マイクロサービスに限らず、充分にテスト可能な状態を保つという形が大事です

そういうテストが備わって初めて、レガシーからの脱却準備が整ったと言えるのかもしれません

## 優先順位をつける
とは言っても、対象となるシステムのボリュームによっては必ずしもすべてを網羅する必要はないのではないかとも考えています。
正確に言えば優先順位をつけるわけですね。

費用対効果を考えた場合、たとえ機能的に重要な位置づけのモジュールであったとしても、充分に時間が過ぎていて安定しているのであれば優先順位は低いでしょう。

その代わり、変更頻度が高い場所。
継続的に改良が加えられたり、新機能の開発が行われているモジュールに関しては優先度を上げて取り組むべきなのだと考えています。

多くの場合、経営層から見たときに仕様が変わらない変更。つまりリファクタリングによる内部的な価値の想像に対して工数を用いるより、新たな機能を追加することでの価値創造のほうがプライオリティが高いです。

このバランスをしっかりとり、お互いが原理主義者のような論調にならないような提案・調整をしていかなければなりません。

## 最後に
なんだか随分と教科書的な内容になってしまいました。

過去に、テストが大事と言いながらも納期や度重なる仕様変更に見舞われて自動テストを何度もおざなりにしてしまったことがあります。

あの時はしょうがなかったんだ、なんて言うつもりはありませんが、当時を思い起こしながら反省を含めて書いてみました。

完全に自分への自戒になってしまった・・・
OSSへの貢献方法をまとめてみた

# はじめに
開発に欠かせないオープンソースソフトウェア(OSS)への貢献方法をまとめた記事です。
<対象読者>
OSSを使ったことがある人（すなわちエンジニア全員）、かつOSS貢献とは何ぞや？が分かっていない人が対象です。
様々な方法で既にコミットしてくださっている皆さまは、ブラウザバックしてください。
<書き手>
ワークスアプリケーションズ・システムズ社にて、OSS "Sudachi"の企画や開発支援等々を行っている人。
ざっくり経歴：Engineer → システム導入コンサルタント → SaaS BizDev

参考：[「OSSとは？意味や種類、商用利用ライセンスの定義を解説」](https://www.itmanage.co.jp/column/oss/)

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [OSSへ貢献するメリットとは？](#Chapter1)
1. [OSSへの貢献方法とは？](#Chapter2)
1. [さいごに](#reference)

<!-- 各チャプター -->
<a id="#Chapter1"></a>
# OSSへ貢献するメリットとは？
私が特に強いなと感じているところは2つです。
１．OSSが良くなる
これは言わずもがな、なんですが。
OSSの不具合が無くなれば？　⇒　自分と同じ苦労をする人が減る。
OSSに便利機能がつけば？　⇒　できることの幅が広がる。
OSSのまとめ記事がQiitaに増えれば？　⇒　困りごとがあった時に、すぐに答えに辿り着ける。

普段お世話になっているOSSがより良いものになれば（と考えて、貢献する人が増えれば！）、巡り巡って自分にとっても有益ですよね。

これは、反対のことを考えるとかなり怖い、とも言えます。
OSS利用者全員がフリーライダーだった場合、事実上そのOSSはOSSとしては成り立たない状況に陥る可能性もあります。例えば、致命的な脆弱性が放置されるとか。
ボランティアに依存するOSSの持続性に関しての問題は、既に相当数の記事も執筆されています。
参考：[ボランティア開発者が「反乱」。もっとオープンソースに還元されるべき？](https://news.yahoo.co.jp/byline/yamaguchikenta/20220111-00276813)
参考：[OSSが持続可能であるために――疲弊する「ボランティアエンジニア」を支援する新たな仕組みとは？](https://codezine.jp/article/detail/15093?p=2)
OSSがOSSとしてそこに在り続けるにも、OSSへの貢献は非常に重要なのです。

２．キャリアの証明になる
まつもとひろゆきさんも[「オープンソースへの取り組みはエンジニアにとって強力な「武器」になる」](https://doda.jp/engineer/it/guide/001/02b.html)の記事にて触れられています。
他業種であれば、職務経歴書で経験を書き連ねたり、保有資格を沢山並べたりする必要があったりして、一般的な表現・証明の方法は限られることが多いです。
そこがエンジニアであれば、〇▽◇のバグを何個どういう目的で直しました、とか、そういった表現（証明）もできます。
後述しますが、貢献方法の数だけ、表現のバリエーションがあるということです。

<a id="#Chapter2"></a>
# OSSへの貢献方法とは？
・問題をIssueとして報告する
「この挙動、おかしくないでしょうか」とOSSリポジトリに対して報告を上げてみる。自分で直接直せなくとも、報告を上げることが第一歩です。
この際、「不具合っぽいから直してよ！」みたいな報告では無く、developerへの敬意は払うようにすべきですね。
・問題に対して修正案を提示する
自分で直せるなら、直してみて、それを修正案としてpull request.
良い提案であればMergeされるかもしれないし、あーだこーだ議論が始まるかもしれない。
普段お世話になっているOSSに対して行うのが手っ取り早いですが、Githubなどでは"Help Wanted"ラベルのプロジェクトを探すのも一手です。
参考：[ラベルを使用してプロジェクトに役立つコントリビューションを促す](https://docs.github.com/ja/communities/setting-up-your-project-for-healthy-contributions/encouraging-helpful-contributions-to-your-project-with-labels)

・寄付をする
最近は[Github Sponsor](https://docs.github.com/ja/sponsors)や[Open Collective](https://opencollective.com/)にて資金的に開発チームを援助することもできます。
資金枯渇でOSSの更新が止まってしまっては本末転倒。
お金は掛かりますが、実は最もストレートで即効性のある貢献方法だったりします。

・ドキュメントを作る
利用しやすいOSSには関連するドキュメンテーションも豊富に用意されているものです。
Qiitaで使ってみたまとめを書く、自社テックブログで記事化する、[conpass](https://connpass.com/)で勉強会を開く。そのどれでも構いません。
やりたいことがある時に、ググって有用な情報に辿り着きやすいサービスほど、利用しやすいですからね。


<a id="#reference"></a>
# さいごに
OSSの発展にもキャリアアップにも繋がるOSS貢献。
ぜひ気軽に、様々な方法でよりたくさんのOSSに貢献しましょう。
私たちも、OSSリソース群"[Sudachi](https://worksapplications.github.io/Sudachi/)"を一般公開し、メンテナンスしております。
皆様からの様々なコミットメント(feed back, pull req, donation,documentation, etc.)もお待ちしておりおます。
- [徳島人工知能NLP研究所｜ワークスアプリケーションズ](https://nlp.worksap.co.jp/)
- [ワークス徳島NLPリソース](https://worksapplications.github.io/Sudachi/)
※「誤解析の報告」や「収録して欲しい語彙の要望」なども情報提供をお待ちしております。[ご利用のOSS](https://worksapplications.github.io/Sudachi/)を選び"Issue"として新規作成をお願いいたします。またよろしければ、Sudachiの活用事例をテックブログ等でご紹介お願いします！

Githubスポンサーも募集中です！Sudachiの発展に1ドルからご支援をお願いいたします。
- [Become a sponsor to Works Applications](https://github.com/sponsors/WorksApplications)
Leetcode 問題番号 1313

[Decompress Run-Length Encoded List
](https://leetcode.com/problems/generate-parentheses/)

与えられた配列の偶数番目の中身の回数分その一個あとの値を答えの配列に追記する。
for文を回して全探索するが0から配列のサイズ-1まで2個ずつ増やしていく
配列のサイズが最大100でその値の最大サイズも100なので
計算量は <= 50*100 < 10**4になるかな？
```C++
class Solution
{
public:
    vector<int> decompressRLElist(vector<int> &nums)
    {
        vector<int> ans;

        for (int i = 0; i < nums.size(); i += 2)
        {
            for (int j = 0; j < nums[i]; ++j)
            {
                ans.push_back(nums[i + 1]);
            }
        }

        return ans;
    }
};
```
【Unity】キーの押下で移動させる方法のパターンまとめ

# はじめに
ボタンを押下でプレイするゲームは沢山あるが、作成方法として様々な書き方があるので忘れないようにまとめてみました。


# パターン①　GetAxis関数を使う方法
```
Input.GetAxis("Horizontal")
```
この関数は、__-1から1まで__ の数値をとる為、__左右の矢印キーを押すと左右の移動__ をすることが出来るようになる。



左側の矢印キーを押しているときは、数値が __減少__ していき、『__-1__』になり、右側の矢印キーを押しているときは、数値が __増加__ していき、『__1__』になる。

__使用例__
 ```
 transform.position += new Vector3(Input.GetAxis("Horizontal") * Time.deltaTime, 0f, 0f);
```
現在の位置へ、新しいポジションを生成して代入する。
x座標に関数を入れることで、左右の矢印キー押下で左右に移動可能となる。

# パターン② GetKey関数を使う方法

この関数は、キーを押している間、__true__ を返す。
引数に与えている識別キーが押されている間、trueを返す関数である。
押され続けられている間は、trueを返し続ける。オート射撃とかに使うと良い。

__使用例__
```
if(Input.GetKey(KeyCode.RightArrow))
{
       処理内容
}

```
指定したKeyCodeが押されている場合trueを返す。

こちらの関数は、指定する引数(KeyCode)を変えることで、上下左右、回転など自由な動きをすることが出来る。

__一例__
|RightArrow|右矢印キー|
|:---|:---:|
|LeftArrow|左矢印キー|
|UpArrow|上矢印キー|
|DownArrow|下矢印キー|
|S|Sキー|
|Space|スペースキー|
|Return|エンターキー|


# その他　押され続けている、離した時

__GetKeyDown関数__
キーを押したフレームの間だけ true を返す。
__押し始め__ を検知する。

__GetKeyUp関数__	
キーを離したフレームの間だけ true を返す。
__離した瞬間__ を検知する。
vyosでIPsecが切断されたときに再接続する

# 目的
vyosでAzureとIPsec VPNを張っているが、無通信時間が続くと勝手に切断されてしまうことがあるので対策する。

# 環境
ちょっと古いバージョン。
Version:          VyOS 1.3-rolling-202010070117
Release Train:    equuleus

# 設定
vyosに組み込まれてるタスクスケジューラの機能を使う。
タスクで実行するシェルスクリプトはこんな感じ。


```/config/scripts/vpncheck.sh
#!/bin/bash
 
STATUS=`/bin/vbash -ic 'show vpn ipsec sa | count'`
 
if [ $STATUS -lt 3 ]; then
logger -p user.warn -t vpncheck "[FAILED] VPN is disconnected. reboot now."
/bin/vbash -ic 'reboot now'
else
logger -p user.info -t vpncheck "[SUCCESS] VPN is connected."
fi
```
```show vpn ipsec sa```のコマンド結果が接続時は以下のようになるので、
行数が3未満であれば切断されているものとみなし、再起動する。(restart vpnでは無理だった)
```
Connection                      State    Uptime    Bytes In/Out    Packets In/Out    Remote address    Remote ID    Proposal
------------------------------  -------  --------  --------------  ----------------  ----------------  -----------  ----------------------------------
peer-xx.xxx.xxx.xxx-tunnel-vti  up       4h12m27s  46K/60K         715/511           xx.xxx.xxx.xxx    N/A          AES_CBC_256/HMAC_SHA1_96/MODP_1024
peer-xx.xxx.xxx.xxx-tunnel-vti  up       4h12m27s  6K/9K           83/71             xx.xxx.xxx.xxx    N/A          AES_CBC_256/HMAC_SHA1_96/MODP_1024
```

vyosに投入するコマンドは以下のとおり。
```
set system task-scheduler task vpncheck executable path '/config/scripts/vpncheck.sh'
set system task-scheduler task vpncheck interval '30m'
```

これで30分ごとにVPN接続状況をチェックして、切断されていたら再起動～再接続できるようになった。
【1日目】Discord Botで出来ることについて簡単に知ろう Part1

# はじめに
こんにちは、なりかくんと申します。
今回は、Discord Botではどのようなことが出来るのかを紹介していきます。

# Discord Botでできること
Discord Botでは、通常のDiscordでは出来ない機能を補う役割で作成されることが多いです。
今回は、どのようなことが出来るのかを今回は３つ紹介します。

## Discord内でお問い合わせチケットを作れる
Discord内でお問い合わせチケットを作ることが出来ます。通常のDiscordでは、スレッド機能を使ってチャンネルを分けてお問い合わせを作ることが出来ますが、それでは公開チャンネルなので個人情報などのやり取りはあまりできません。

そこでDiscord Botを使うと、例えばメッセージにリアクションをするとプライベートチャンネルをBotが作成して実質日公開チャンネルを作成できます。これでお問い合わせチケットの代わりとして動かすことが出来ます。

有名なBotとして、「Ticket Tool」というDiscord Botがあります。このBotを入れると非常に簡単にお問い合わせチケットを作ることが出来ます。

https://tickettool.xyz/

また、GitHubなどのオープンソースで様々なチケットツールがありますのでそちらを利用して自己ホストすることも出来ます。
https://github.com/search?q=Discord+Ticket+Tool

## 投票を簡単に作成できる
投票を簡単に作ることが出来ます。普通にBotを使わなくてもリアクションで投票は作れるのですが、リアクションをつけるのはめんどくさいです。
そのため、Discord Botを使って一気に投票付きのリアクションをつけることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549951/4c12f3e9-78ca-bb3c-23b4-d43838aedba2.png)

## プレゼント企画と抽選ができる
プレゼント企画の募集と抽選が簡単に作ることが出来ます。メッセージにリアクションを用意して、指定した日時になればリアクションをつけている人の中から抽選して当選者を出すというのが実現できます。

有名なBotとして、「GiveawayBot」というBotがあります。

https://giveawaybot.party/

# 最後に
今回はDiscord Botではどのようなことが出来るのかを紹介しました。書く気があればパート２を書きたいと思います。
最後までお読みいただきありがとうございました。
Accessでデータシートビューフォームの特定カラムを非表示に

# 概要

例えば下記のようなデータシートビューのフォームがある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/943375c7-0067-9b3e-e700-3664ece10e89.png)

idカラムをユーザーに見せないようにしたい。

idカラムはイベントで使用する値を保持しているので、『消す』のではなく『非表示』にしておきたい。

そんな時。

# やり方

右クリック ⇒ フィールドの非表示 。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/27dfa203-f918-6ab0-6b6a-a126bce4e2ea.png)

フィールドの再表示も可。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/b4037424-41e8-6e44-7757-0f5e642f1d74.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/8ac05f33-1508-3ac5-6181-1ade633f1fda.png)

# 『可視』というパラメータはデータシートには反映されない

書式に『可視』というパラメータがある。
これを『いいえ』にしてもデータシート上で非表示にはならない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/e1b109ec-cbb5-feea-46cb-3db893095091.png)

『可視』は単票フォームなど用のパラメータ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/612bc713-2de5-d161-40ff-d14e0bac838d.png)

# バージョン

Windows 10 Pro 21H2 OSビルド 19045.2311
Microsoft Access for Microsoft 365 MSO (バージョン 2211 ビルド 16.0.15831.20098) 32 ビット
2年目フロントエンドエンジニアの成長に最も繋がった2022年の1冊

## はじめに
都内でフロントエンドを開発しているエンジニア2年目のマンゴクです。
[UdonTech Advent Calendar 2022](https://qiita.com/advent-calendar/2022/udontech) の13日目の記事となります！

今回は2022年に読んだ技術書の中で最も成長に繋がった物を紹介していきます。
普段React・TypeScriptで開発をしている関係もあり、昨年はReactやフロントに特化した書籍が多めでしたが、今年はソフトウェアの設計やOOPなど開発に関する原理・原則に関する書籍を中心に学んできました。

そして、その中で最も良かったのは **「Clean Architecture」** です！と言うことでこの記事では、Clean Architectureに関して下記のコンテンツで紹介します。


- 「Clean Architecture」の内容
- なぜ良かったか
- 具体的に何を学べたか
- 業務にどう活きたか


## Clean Architectureの内容
Clean Architectureはソフトウェア界で有名なRobert C. Martin(通称ボブおじさん)が執筆した、ソフトウェアの構造と設計に関する書籍です。
下記の図が有名であり、目にしたことがある方も多いのではないでしょうか。本書籍では **図のアーキテクチャの具体的内容、そしてこのアーキテクチャに至るまでに必要とされる開発の原理・原則** が紹介されています。具体的には設計の概念やSOLIDの原則等です。
図のアーキテクチャをシステムに導入するしないにしても、 **なぜこのアーキテクチャが良いのか** と言う点を深く理解することができるため、フロントエンド・バックエンド問わず非常に学びの多い一冊になっているなと感じました。

![CleanArchitecture.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251005/25d41fff-7d87-bfa4-a3a1-12bd5e807830.jpeg)



## なぜ良かったか
一言で言うと、 **「ソフトウェア開発における原理・原則」** の理解を深める機会になったからです。普段フロントエンドエンジニアとして働いていることもあり、Reactにおけるベストプラクティスであったり、最新の技術を追うことが多くなっていました。そんな中、今年原理・原則を学ぶことで、 **方針が詳細に依存しない設計** であったり、さらには **フロントエンドでベストプラクティスとされることが「なぜ良いのか」** と言った点を深く理解できるようになりました。
原理・原則を学ぶことは遠まりの様に見える事もありますが、結果的にReactで開発する上で大きな成長を与えてくれたと実感しています。

## 具体的に何を学べたか
学んだこと非常に多いですが、絞ると下記の内容になります。

- OOPに関して
- SOLIDの原則
- The Clean Architecture

### OOPに関して
ポリモーフィズムを使用してシステムの複雑性を下げることの重要性。 **インターフェイスを挟んで依存関係を逆転させることで、方針が具体に依存しない様にする事や分岐の排除方法** を学べた。関数型では高階関数で実現できるのかなども考えながら読むことでさらに理解が深まった。

### SOLIDの原則
5つの中でも、OOPで述べた「依存関係逆転の法則」が一番の学びだった。依存とはなんぞやという状態だったが、 **依存関係コントロールすることで、修正範囲を減らして安全に保守可能となる点**を知れた。

### The Clean Architecture
図に挙げたThe Clean Architectureの図。特に重要な点は **ドメインロジック(方針)を実装(詳細)を分離し、内から外の依存関係を必ず守ること。** 実現するために、各種レイヤーにインターフェイスを設け、インターフェイスを満たす実装を注入していく。これらを意識することで、 **実装の変更をする際にドメイン周りに手を入れる必要がなくなる事に加え、インタフェースすさえ満たせて入ればどんな実装にも置き換え可能になる。**


## 業務にどう活きたか
Clean Architectureを通して原理原則を学ぶことで下記の点を業務で活かせる様になったと感じています。

- Reactの実装時に設計を深く考える様になった点
- バックエンドのコードを理解できる様になった点

### Reactの実装時に設計を深く考える様になった
依存関係や関心の分離を意識することで、「ライブラリ使用時の依存を減らすためにはどうするばよいか」、「コンポーネント・カスタムフックの凝集度上げるにどうする」、さらには「ドメインロジックは純粋関数として別モジュールに切り出すか？」など、今まで以上に美しい設計にするにはと言った観点を持って実装できる基盤が整った。

### バックエンドのコードを理解できる様になった
Clean ArchitectureをきっかけにOOPやDDDなどに関する書籍にも興味が湧いたことで、バックエンドコードを流れで捉えることができる様になった。フロント・バックエンドに跨る改修を行う際に、バックエンドのコードを見た上で提案などできる様になった実感がある。

<hr>
この書籍以外の影響もあると思いますが、他社のエンジニアに非常に理解し易いコードだったと言う言葉をもらえたこともあり,
設計という点は大きく成長できたと感じています。(お世辞の可能性もありますが)


## 終わりに
今年はClean Architectureに出会ったことで、ソフトウェアの設計といった原理・原則の理解が深まりエンジニアとして成長を多少なりとも得られたと実感しています。2023年まであと数日ですが、学ぶテーマをこれから定め,今年以上に成長の大きい一年にしていこうと思います！
Cloud Run jobsでのtimeout回避のために分割処理をする

# はじめに
これは[no plan inc.の Advent Calendar 2022](https://qiita.com/advent-calendar/2022/noplan_inc)の15日目の記事です。

cloud run jobsではタスク１つあたりの実行時間の上限が１時間になっており、これを超えるような処理を行うにはタスクを分割する必要がある。
ここでは例として1000万以下の素数を求めるプログラムを100分割して5個並列に処理する。


# 目次
1. [ジョブで利用できる環境変数](#chapter1)
1. [ジョブの設定](#chapter2)
1. [コード](#reference)


<a id="chapter1"></a>
# ジョブで利用できる環境変数
cloud run jobでは以下の環境変数が利用できる。
|名前|説明|	例|
|---------------|---------------|---------------|
|CLOUD_RUN_JOB|実行されている Cloud Run ジョブの名前。|hello-world|
|CLOUD_RUN_EXECUTION|実行されている Cloud Run 実行の名前。|hello-world-abc|
|CLOUD_RUN_TASK_INDEX|タスクごとに、0 から「タスク数 - 1」までの一意の値が設定されます。|0|
|CLOUD_RUN_TASK_ATTEMPT|このタスクが再試行された回数。最初の試行は 0 から始まり、再試行の最大回数まで、続けて再試行するたびに 1 ずつ増加します。|	0|
|CLOUD_RUN_TASK_COUNT|--tasks パラメータで定義されたタスクの数。|1|

今回はCLOUD_RUN_TASK_INDEXとCLOUD_RUN_TASK_COUNTを利用する。


<a id="chapter2"></a>
# ジョブの設定

以下の画像のように設定する。
![スクリーンショット 2022-12-13 14.25.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958320/2ee3ad7e-37ba-459f-0015-f05846ddf91e.png)



<a id="chapter3"></a>
# コード

以下のコードをデプロイし実行すると1000万以下の素数を表示する。

```typescript:example.ts
export class PrimeNumber {
  main(): void {
    //jobの環境変数
    const taskIndex = Number(process.env.CLOUD_RUN_TASK_INDEX);
    const taskCount = Number(process.env.CLOUD_RUN_TASK_COUNT);

    //タスク1つ当たりの素数を求める範囲
    const numPerTask = 10000000 / taskCount;
    //そのタスクでstartNum以上、endNum以下の素数を求める
    let startNum = numPerTask * taskIndex + 1;
    const endNum = numPerTask * (taskIndex + 1);

    //素数を求めるロジック
    for (; startNum <= endNum; startNum++) {
      let divisor = 0;

      for (let i = 1; i <= startNum; i++) {
        if (startNum % i == 0) divisor++;
      }

      if (divisor == 2) console.log(startNum);
    }
  }
}

const primeNumber = new PrimeNumber();

primeNumber.main();
```



<a id="reference"></a>
# 参考文献
- [ジョブの環境変数](https://cloud.google.com/run/docs/container-contract?hl=ja#jobs-env-vars)
OpenAI API を使って ChatGPT を作り AI の性格も変える

ChatGPT 便利ですね。でも人気があるのかエラーが頻発するよになってしまいました。そこで OpenAI の API を使って自分用の ChatGPT を作ります。

# OpenAI API Key を取得

https://openai.com/api/

アカウントを作って API Key を取得します。

# コンソールでチャットする Python プログラム

コードはこちらに公開してあります。

https://github.com/akiraak/chat-gpt3

openai をインストールします。

```sh
$ pip install openai
```

コードはこちら。

```py:main.py
import os
import openai

openai.api_key = os.getenv("OPENAI_API_KEY")


if __name__ == '__main__':
    prompt_text = "以下は人工知能アシスタントとの会話です。このアシスタントは丁寧で、創造的で、頭が良く、とてもフレンドリーです。\n"
    #prompt_text = "以下は人工知能アシスタントとの会話です。このアシスタントは皮肉たっぷりに答えてくれる渋いAIです。\n\n"
    prompt_text += """
You: こんにちは、あなたは誰ですか？
AI: 私はOpenAIによって作られた人工知能です。今日はどうされますか？"""

    while True:
        question = input("You: ")
        prompt_text += "You: {}\n".format(question)
        prompt_text += "AI:"
        response = openai.Completion.create(
            model="text-davinci-003",
            prompt=prompt_text,
            temperature=0.9,
            max_tokens=256,
            top_p=1,
            frequency_penalty=0.0,
            presence_penalty=0.6,
            stop=[" You:", " AI:"],
        )
        prompt_text += "AI: {}\n".format(response.choices[0].text)
        print("AI:", response.choices[0].text)
```

コードはシンプルです。

```openai.api_key``` は環境変数から取得していますが、めんどくさければ文字列で置き換えてください。

```prompt_text``` にテキストを設定してリクエストを投げるとAIからの返信が返ってきます。チャットとして適切な答えを返してもらうために最初に前提文を入れておきます。そして返ってきた答えはそれまでの文章に追加して次のリクエストに全て送信するよにします。これによりコンテキストが保てるようです。

これでひたすら遊べますね！

![2022-12-12_20h26_46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33704/51ab1610-3641-104a-2755-d8f3e3ac27f2.png)

# AI の性格を変える

```prompt_text``` に前提の文章を入れていますが、これを変えることでAIの性格も変えれます。

```py
    prompt_text = "以下は人工知能アシスタントとの会話です。このアシスタントは皮肉たっぷりに答えてくれる渋いAIです。\n\n"
```

こっちを有効にするとひねくれモードのAIになります。

![2022-12-12_22h59_39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33704/a232703a-47fe-b080-7992-b44f5ec709c4.png)

他にも面白い設定があったら教えてください。
picoCTF Writeup picoGym Practice Challenges Power Cookie (注意<spoiler>)

# Power Cookie
Description
Can you get the flag?
Go to this website and see what you can discover.

サイトへ移動しゲストボタンを押すともちろんはじかれるが、cookieの値が0なので１に変えてリダイレクトするとフラグが見れる。

picoCTF{gr4d3_A_c00k13_5d2505be}
picoCTF Writeup picoGym Practice Challenges Forbidden Paths (注意<spoiler>)

# Forbidden Paths

Description
Can you get the flag?
Here's the website.
We know that the website files live in /usr/share/nginx/html/ and the flag is at /flag.txt but the website is filtering absolute file paths. Can you get past the filter to read the flag?

ウェブサイトは絶対ファイルパスをフィルタリングしています。->相対パスで入力してやれば良い

../../../../flag.txt

picoCTF{7h3_p47h_70_5ucc355_6db46514}