OmniAICreator/Qiita-1.07M huggingface dataset:
Laravel Sailで作成したファイルをGitHubにpush

先人の方達のありがたい記事が沢山あるのですが、2021年8月13日にGitHubの仕様が変わり、トークンを発行しなければならなくなりました。
そしてトークン発行記事を探すのに時間がかかるので自分の忘備録としてまとめます。


Laravel Sailを用いた環境構築は[こちら](https://qiita.com/YKhojo/items/12c17afb6ca8e60d1b96)

## GitHubにリモートリポジトリを作成

- (必要であれば)private設定

READMEは作ると面倒なので、後で。

## ローカルリポジトリ作成

事前にローカル環境を作ります
ここでは事前に作ったフォルダをexample-appとします

```
% cd example-app
% git init
% git branch -M main
% git add .
% git commit -m "first commit"
% git remote add origin https://github.com/自分のアカウント名/example-app.git
```

Username for　←　自分のアカウント名(いつもどおり)
Password for　←　新システムのトークンが必要

トークン発行の公式ページ
https://docs.github.com/ja/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token

> 個人アクセストークンは HTTPS Git 操作だけにしか使用できません。 SSH リモート URL を使用するリポジトリの場合、リモートを SSH から HTTPS に切り替える必要があります。

```
% git push -u origin main
```

<br>

## GitHub Desktopにローカルリポジトリを追加する

GitHub Desktopの'add exsisting repository...'からローカルリポジトリを指定
画面遷移せずにformを送信する方法

##画面遷移せずにformを送信する方法

formを送信する際にaction属性を自身に返す場合、入力した内容はそのまま表示させておきたいですよね。

```html
<form action="" method="post">
    <input type="text" name="name">
    <input type="text" name="address">
    <input type="submit" value="保存">
</form>
```
上記の例はaction属性が空なので自身に遷移します。
phpのみで入力した値を保持したい場合はinputのvalue属性にPOSTで渡ってきた情報を出力してやる必要があります。

```php
<?php
if(isset($_POST["save"])){
    echo "<script>alert('保存しました')</script>";

    $name = htmlspecialchars($_POST["name"], ENT_QUOTES); 
    $address = htmlspecialchars($_POST["address"], ENT_QUOTES); 
}
?>
<form action="" method="post">
    <input type="text" name="name" value="<?= $name;?>">
    <input type="text" name="address" value="<?= $address;?>">
    <input type="submit" name="save" value="保存">
</form>
```

今回の例は入力項目が2つしか無いので作業は少ないですが、入力項目が１００個とかになればめんどくささは半端ないです。

そこで私がめんどくささを解消するために使っている方法は以下の通りです。

```php
<?php
if(isset($_POST["save"])){
    echo "<script>alert('保存しました')</script>";
    exit;
}
?>
<iframe id="iframe" name="iframe" style="display: none;"></iframe>
<form action="" method="post" target="iframe">
    <input type="text" name="name" value="">
    <input type="text" name="address" value="">
    <input type="submit" name="save" value="保存">
</form>
```

formの送信先をiframeタグに設定しcssでiframeタグの表示を隠しています。
iframeタグについてはこちら
>HTML のインラインフレーム要素 \<iframe> は、入れ子になった閲覧コンテキストを表現し、現在の HTML ページに他のページを埋め込むことができます。

>>https://developer.mozilla.org/ja/docs/Web/HTML/Element/iframe

```html
<form action="" method="post" target="iframe">
```
formタグのtarget属性にiframタグのname属性の値を入れてあげます。
そうするとiframタグの中のHTMLがaction属性に指定したPathで読み込まれます。
iframタグの中身が遷移したとしても本体のHTMLは何も変化しませんので、結果として画面遷移せずにformが送信できるといったからくりです。

遷移した先ではphpのプログラムだけ実行したいので余計なHTMLを読み込まないように

```php
exit;
```
としてプログラムを終了させています。

画面が遷移しない！！ということは入力した内容もそのままですので、わざわざphpでPOSTの値を取得してechoで出力するといった手間が省けます。

これでめんどくさい作業も省略できますし、表示ミスといった不具合も未然に防ぐことができますね♪
【React】particles.js で動く背景を作る

<!-- =================================================== -->
# 概要
<!-- =================================================== -->
**particles.js**を使うと、背景が動くちょっと面白いサイトを作ることができます。

![output(video-cutter-js.com) (3).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358498/87ba3b17-6698-0829-7b0f-f51678be3184.gif)

公式デモサイトで、パラメーターをいじりながらアニメーションを試すことができます。

https://vincentgarreau.com/particles.js/#default

<!-- =================================================== -->
# 環境
<!-- =================================================== -->
* React － 17.0.2
* TypeScript － 4.4.2
* react-particles-js － 3.5.3
* npm － 7.23.0

<!-- =================================================== -->
# インストール
<!-- =================================================== -->
プロジェクトフォルダを作成して、Create React Appでプロジェクトを作成します。

```:cmd
npx create-react-app . --template typescript
```

**[react-particles-js](https://www.npmjs.com/package/react-particles-js)**をインストールします。

```:cmd
npm i react-particles-js
```
:::note warn
react-particles-jsがReact（17.x）に対応していない場合、--forceオプションを付けてインストールできます。
:::

<!-- =================================================== -->
# 実装
<!-- =================================================== -->
### コーディング
コーディングはとても簡単です。
スタイリングは、CSS-in-JSとして[emotion](https://emotion.sh/docs/@emotion/css)を使っています。

```.tsx
import React, { VFC } from 'react';
import Particles from 'react-particles-js';
import { IOptions, RecursivePartial } from 'tsparticles';
import { css } from '@emotion/css';
import ParticlesParams from '../assets/particles-default.json';

export const CustomParticles: VFC = () => {
	return (
		<Particles
			className={styles.particles}
			params={ParticlesParams as RecursivePartial<IOptions>}
		/>
	)
}

const styles = {
	particles: css`
		position: absolute;
		width: 100%;
		height: 100%;
	`
}
```

### 設定

**params**として、インポートしたjsonファイルを指定しています。
このjsonファイルで、色やノードの大きさ、マウス操作時のアニメーションなどの設定を行います。
これらの設定は、公式デモで試しながら調整することができます。また、その設定をjsonファイルとしてエクスポートすることができます。

![スクリーンショット 2021-09-11 221947.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358498/32d99872-02f5-9dbe-a27e-af17f44442d8.png)

### 設定のテンプレート
公式デモにはいくつか設定のテンプレートが用意されています。
例えば、**[Snow]**を選択すると、雪が降っているようなアニメーションになります。
![スクリーンショット 2021-09-11 222658.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358498/723462d1-b86c-e8f2-0368-6035891ece55.png)

<!-- =================================================== -->
# まとめ
<!-- =================================================== -->
アニメーションはいざ実装しようとすると複雑になりがちなので、particles.jsのような簡単に使うことのできるパッケージは本当にありがたいです。
何より使ってて楽しいです:upside_down:
OAK-D on LXD

# 背景
今流行りの[OAK-D](https://www.switch-science.com/catalog/7222/)を買ったのだけれど、常用の環境がUbuntu 21.04なのでROS Noeticが入る20.04を使いたい。
普段遣いしている開発環境としてはLXDを使っているので、これの上のUbuntu20.04でOAK-Dを使いたい。

# 稼働のチェック方法
[ここ](https://docs.luxonis.com/projects/api/en/latest/install/#test-installation)にテストのやり方があるので、これに従う。
LXD上でGUIを利用するにはX11 fowardingを利用してもいいし、[ここ](https://qiita.com/nindanaoto/items/0ea1dd8206716da0ece2)にあるようにデスクトップ環境を入れてもいい。私は後者で試した。

```
git clone https://github.com/luxonis/depthai-python.git
cd depthai-python
cd examples
python3 install_requirements.py
python3 rgb_preview.py
```

# 問題点
LXDは仮想環境に近いコンテナなのでこれにUSBをパススルーしないといけない。

## 引っかかりポイント1
LinuxでOAK-Dを使うためには、[USBのモードを666にするようにudev ruleでpermissionを与え](https://docs.luxonis.com/projects/api/en/latest/install/#vmware)ないといけない。
これをしないとホストでもスクリプトが動かない。

```
echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="03e7", MODE="0666"' | sudo tee /etc/udev/rules.d/80-movidius.rules
sudo udevadm control --reload-rules && sudo udevadm trigger
```

## 引っかかりポイント2
[Virtual Box用の記述](https://docs.luxonis.com/projects/api/en/latest/install/#virtual-box)で触れられているのだが、OAK-Dはアクセスしてファームウェアが起動すると接続時と違うUSBデバイスとして振る舞うらしい。なので、接続時のUSBデバイスと起動時のUSBデバイスの両方を渡さないといけないらしい。例えば今`noetic`という名前のコンテナを使っているとすると、以下のようなコマンドを叩く必要がある。oak-d-loopのほうがファームウェア起動後のデバイスである。oak-d-loopはモード666への切り替えもしているが、なぜ接続時のデバイスであるoak-dのほう流行らなくていいのかよくわかっていないので、環境によってはそっちも設定する必要があるかもしれない。

```
lxc config device add noetic oak-d usb vendorid=03e7 productid=2485
lxc config device add noetic oak-d-loop usb vendorid=03e7 productid=f63b
lxc config device set noetic oak-d-loop mode 0666
```

# 終わりに
この２つの引っかかりポイントさえ避ければLXDのクリーンな環境で簡単にテストができるので良さげなカメラな感じがある。Virtual Boxは最近さわってないのでパススルーの設定がよくわからなかったが、Windowsだとそっちのほうがいいかもしれない。
そのうちVisual SLAMも試すつもり。
Jetpack Compose でキーボードを閉じる方法

`LocalSoftwareKeyboardController.current.hide()` を呼ぶことでキーボードを閉じることができる。

```kotlin
@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun Greeting() {
  val keyboardController = LocalSoftwareKeyboardController.current
  var text by remember { mutableStateOf("") }
  TextField(
    value = text,
    onValueChange = { text = it },
    keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
    keyboardActions = KeyboardActions(onDone = {
      keyboardController?.hide()
    }),
  )
}
```

`LocalSoftwareKeyboardController` は実験的機能であるため、コンパイルエラーを回避するために `@OptIn(ExperimentalComposeUiApi::class)` を付ける必要がある。
[Flutter]画像を表示する

#概要
画像を表示する時、画像ファイルを扱うための準備が少し手間なので、手順をまとめました。
#画像ファイルを準備する

最初に画像を入れるフォルダを用意します。
Projectの一番上の項目で右クリックしてNew > Directory
![スクリーンショット (718).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/013a4751-a584-cca7-8890-4256e22c921d.png)
今回はこの様なフォルダ構成にしました。
![スクリーンショット (719).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/adac1bf0-4b14-bb1b-e932-3de0af620140.png)
画像は「ドラッグ＆ドロップ」もしくは「コピー＆ペースト」で登録してください。

#pubspec.yamlファイルを編集する
pubspec.yamlファイルに「画像が保存されているディレクトリ」を指定します。
![スクリーンショット (720).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/048c93f1-b590-3fe9-59ad-2251ff1e0735.png)

```dart
flutter:

  uses-material-design: true
  assets:
    - assets/images/
```

※　インデントによっては正常に動かないかもしれません。コピペした事でうまく動作しなかった時は直接入力してみてください
※　assets/images/の頭にある『-』を書き忘れるとエラーになりますので注意してください
#画像を表示するコードを追加する
画像を表示したい位置にコードを追加します。

```dart
Image.asset('assets/images/dog.png'),
```

![スクリーンショット (721).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/03ed1f4c-d943-5d3a-3595-74361c246a5e.png)

![Screenshot2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/8a5de598-aa90-68c9-16c7-85d67af33d7e.png)




#補足1
ネットワーク上に用意された画像を表示したい場合は、以下のコードを記述するだけで出来ます。

```dart
Image.network('https://picture/test.png');
```

#補足2

![スクリーンショット (722) - コピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/d34af41e-ea86-3af7-1d6f-79c02c3a85ca.png)

画面の上側にこういうのが表示されるかもしれません。pubspec.yamlファイルを編集した事で「パッケージ情報などに変更が必要かもしれませんが更新しますか？」というお知らせですが、今回の場合は無視しても大丈夫です。
railsチュートリアル第４章 組み込みクラスの変更

####組み込みクラスの変更
継承を使わずにpalindrome?メソッドを直接実行できるのか？

```rb
>> "level".palindrome?
NoMethodError: undefined method `palindrome?'  for "level":String
```
上のようにエラーになる。

Rubyでは組み込みの基本クラスの拡張が可能
Ruby のクラスはオープンで変更可能
クラス設計者でない開発者でもこれらのクラスにメソッドを自由に追加することが許されています。

```rb
>> class String
>>   # 文字列が回文であればtrueを返す
>>   def palindrome?
>>     self == self.reverse
>>   end
>> end
=> :String
>> "deified".palindrome?
=> true
```
真に正当な理由がない限り、組み込みクラスにメソッドを追加することは無作法
ailsの場合、組み込みクラスの変更を正当化できる理由

```rb
>> "".blank?
=> true
>> "      ".empty?
=> false
>> "      ".blank?
=> true
>> nil.blank?
=> true
```
文字列は```空（empty）とは認識されない```が、```空白（blank）```であると認識
Railsが実はblank?メソッドをStringクラスではなく、そのさらに上の基底クラスに追加していることが推測できる

###演習
1.メソッドを使い、回文かどうかを確認

```rb
>> class String
>>   def palindrome?
>>     self == reverse
>>   end
>> end

=> :palindrome?
>> "racecar".palindrome?
=> true

>> "onomatopoeia".palindrome?
=> false
```
クラスでメソッドを定義しなければ```plindrome?```がエラーになる。
組み込みクラスとはこういうことだろうか？

2.クラスに新たなメソッドを追加

```rb
 class String
>>   def shuffle
>>     self.split('').shuffle.join
>>   end
>> end
=> :shuffle

>> "irohanihoheoto".shuffle
=> "ihieootorhnaho"
>> "irohanihoheoto".shuffle
=> "ihtenhhoooraoi"
>> "irohanihoheoto".shuffle
=> "oiroiaehhoothn"
```

3.作成したメソッドの```self```を消しても正しく動くか確かめる

```rb
>> class String
>>   def shuffle
>>     split("").shuffle.join
>>   end
>> end
=> :shuffle
>> 
>> "irohanihoheoto".shuffle
=> "iernhthiaoooho"
>> "irohanihoheoto".shuffle
=> "aothnhhooroiie"
>> "irohanihoheoto".shuffle
=> "niheohoithroao"
>> "irohanihoheoto".shuffle
=> "hraionoheohoti"
```
正しく動いた。
9.11振り返り　#オブジェクト

<h2>new画面で入力データが、show画面で違うデータを持ってくる　idが違う</h2>
<h2>∵パスの記載順が違ってた　_path(@patient,@record)</h2>
```ruby
def show
: 
  #redirect_to staff_patient_record_path(@record,@patient)  ：エラー
  ↓↓↓↓↓↓↓↓↓↓↓                           ↓↓↓↓↓↓ここ変えた↓↓↓↓↓
　　 redirect_to staff_patient_record_path(@patient,@record)
end
```
<p>routes.rbでルーティングを確認すると</p>
<p>/staff/patients/:patient_id/records/:id(.:format)</p>
<p>patients/:patient_id　　と　records/:id　が<span>この順番で</span>必要</p>

```:ターミナル
Prefix Verb                  URI Pattern                                     Controller#Action                                                                           
staff_patient_record GET    /staff/patients/:patient_id/records/:id(.:format)  staff/records#show 
                                  　　　　 ↓↓↓↓↓　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　↓↓↓↓↓↓ 　　
　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　 先　patients/:patient_id 次 records/:id
　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　 ↓↓↓↓↓↓↓↓↓↓↓ 
           redirect_to staff_patient_record_path(@patient,@record)
```
<h2></h2>

```ruby:ほしいルーティングを限定指定する
:rails routes | grep ほしい名前
```
<h2>enumの書き方</h2>
enum カラム名:{"選択肢":"表示させたい文字","選択肢":"表示させたい文字",,}

```ruby:models/-.rb
enum カラム名:{"選択する":"表示させたい文字"}
enum adjacent: { "acceptable":"問題なし""erythema":""びらん,"erosion":"水疱膿疱"}, _prefix: true
```
<h2>オブジェクトの定義　　　と　enumの書き方2</h2>
<p>enum adjacent: { "acceptable":0,"erythema":1,"erosion":2,"blister":3,"ulceration":15}, _prefix: true</p>
<p>整数値部分を取りたい場合　　　　{{カラム名}}_before_type_cast　で持ってくる</p>

<p>config/locales/ja.ymlファイルで日本語化しておく</p>
<p>show画面では　@record.barrier_i18n　のように_i18nで呼び出す</p>
```ruby:models/-.rb
enum adjacent: { "acceptable":0,"erythema":1,"erosion":2,"blister":3,"ulceration":15}, _prefix: true
enum barrier: {"acceptable":0,"erythema":1,"erosion":2,"blister":3,"ulceration":15}, _prefix: true


#オブジェクトをpointとしてをここで定義する
#　{{カラム名}}_before_type_cast 整数値部分を持ってこれる
def point
  adjacent_before_type_cast + barrier_before_type_cast
end
```
```config/locales/ja.yml
ja:
record:
      adjacent:
        acceptable: 障害なし
        erythema: 紅斑
        erosion: びらん
        blister: 水疱・膿疱
        ulceration: 潰瘍・組織増大
      barrier:
        acceptable: 障害なし
        erythema: 紅斑
        erosion: びらん
        blister: 水疱・膿疱
        ulceration: 潰瘍・組織増大
```
```show.html.erb
#_i18nで日本語化できる
<th>B:皮膚保護剤部:皮膚保護剤が触れていた範囲</th>
<td><%= @record.barrier_i18n%></td>
```

<h2>undefined method `id'エラー </br>
<h2>∵ログインしていない&バリテーションまだかけてない</h2>
<p>下の部分でエラー　　patientがnillになる</p>
```
 @dialy.patient_id = current_patient.id
```
Webシステムのセキュリティについてのまとめ②

# 振り返り
情報セキュリティとは3要素あり、どういった要素が満たされていれば情報セキュリティがしっかりしているといえるのかが理解できました。今回は「情報セキュリティリスク」について学習したことをまとめて行きたいと思います。
なぜ、リスクを考えるべきかと言うとこれらのセキュリティが甘いと損害やシステムに影響を起こりうる為、「情報セキュリティリスク」を知る必要性があるため今回学びました。

https://qiita.com/kinoshitaken123/items/f36d28ae80b8f9dede5b

情報セキュリティとは3要素って気になった人は、こちらを参照ください。

#情報セキュリティにおける「リスク」とは

情報セキュリティにおける「リスク」とは、損害や影響を発生させる可能性のこと。

![images.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1572216/4432e752-b762-4852-68e5-61512e008165.jpeg)

情報セキュリティの構成要素は、不正アクセスなどの「脅威」とセキュリティホールなどの「脆弱性」に分けられる。

>セキュリティホールとは、情報セキュリティを脅かすような、コンピュータの欠陥をいう。
引用:Wikipedia

#情報セキュリティの脅威
情報セキュリティリスクを顕在化させるものが「脅威」。
脅威には、大きく分けて人に起因するもの、作業環境に起因するものがあります。人に起因する人為的脅威は、さらに意図的に起こされるものとそうでないものとに分類されます。
![56E75375-4699-4713-8053-4E0BDD3AE67E.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1572216/3f5baa74-98d5-bc90-c1a2-d55c43155cf4.jpeg)

##意図的脅威
外部の人間による悪意ある行為として、標的型攻撃やマルウェア感染、Webサイトの改ざんなど・・・
また、内部不正も、意図的脅威にあたる。
従業員や元従業員が機密データを持ち出し行為など。
![images (1).jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1572216/61458f63-4dab-ed06-08f4-8b1c5763bfc2.jpeg)

##環境的脅威
環境的脅威とは、地震や台風、落雷、火事といった自然災害のこと。
災害によってサーバーなどのハードウェアが使えなくなり、情報システムの停止に繋がる。


#情報セキュリティの脆弱性
__脆弱性とは、脅威によって突かれる弱点を指す。__

情報セキュリティの脆弱性としては、

* ソフトウェアの脆弱性

メールの開封Webサイトを閲覧したりすることによりマルウェアに感染し、PCが使えなくなる、別のPCへ感染を広げるなどの現象が起こります。

#情報セキュリティ対策として

* 標的型攻撃メールへの対策
* 従業員による機密データの持ち出しへの対策
* クラウドサービスにおけるデータ管理への対策

__標的型攻撃メールへの対策__
→標的型攻撃メールとは、メールにマルウェアが添付され、悪意あるメール。
情報を盗み出すマルウェアに感染し、機密情報が漏洩する恐れがある。これらを回避する方法として、
ウイルス対策ソフトは常に最新のバージョンに保つことが必要。

__従業員による機密データの持ち出しへの対策__
→企業の関係者による不正への対策としては、ユーザーアカウントを配布し、適切なアクセス権限を設定することが有効。

__クラウドサービスにおけるデータ管理への対策__
→十分な情報セキュリティ対策を行っているサービスを選定するのはもちろんのこと、サービス停止時のことも考え、定期的なバックアップの実施や代替システムの検討を行う。

#まとめ
今回は、情報セキュリティにおけるリスクである「脅威」と「脆弱性」について、学習しました。具体的にどんな対策が必要なのか気になったので補足で入れさせて頂きました。一部の紹介となります。ご了承ください。
パスベースルーティングとは

## 勉強前イメージ

pathでルーティングを決めるやり方？

## 調査

### ALBのパスベースルーティングとは

URLでは、 `https://xxxxxxx.YY.XX/test/ab.txt` っていうのがあったとします。
このYY.XX以降がパスになり、 `test配下のab.txt` になります。
パス毎にルーティングさせるのがパスベースルーティングになります。

### どういうときに使用する？

どういうときにパスベースルーティングを使用するのかというと
例として以下があります。

一つとしては
同じFQDNだけど、パス毎に違うサーバに振り分けたいとき です。

例として
同じAAA会社では aaa-kaisya.YY.XX を使用しており
採用では https://aaa-kaisya.YY.XX/saiyou/index.html を表示
ブログでは https://aaa-kaisya.YY.XX/blog/202010909-blog.html を表示させたい が、
採用とブログのwebサーバは違うところにある・・・
というときに
saiyou/index.html → webサーバ1
blog/202010909-blog.html → webサーバ2 を使用する
というのが出来ます。

また、2つ目は
同じサーバだけどポートごとに割り振りを変えたいとき に使用されます。

例として
aaa-kaisya.YY.XX では、
採用の saiyou/index.html は8080ポートで受ける
ブログの blog/202010909-blog.html は8081ポートで受ける ということも出来ます。

上記2つが、ALBのパスベースルーティングで設定することで可能になります。

## 勉強後イメージ

パスベースルーティングッテの初めて聞いたかも。
でもpathをベースにルーティングする、そのまま・・・

## 参考

- [ALBでパスベースのルーティングができると何が嬉しいのか~前置き編~](https://www.simpline.co.jp/recruit/blog/tech_ty/alb%e3%81%a7%e3%83%91%e3%82%b9%e3%83%99%e3%83%bc%e3%82%b9%e3%81%ae%e3%83%ab%e3%83%bc%e3%83%86%e3%82%a3%e3%83%b3%e3%82%b0%e3%81%8c%e3%81%a7%e3%81%8d%e3%82%8b%e3%81%a8%e4%bd%95%e3%81%8c%e5%ac%89/)
- [ALBでパスベースのルーティングができると何が嬉しいのか~中継ぎ編~](https://www.simpline.co.jp/recruit/blog/tech_ty/alb%E3%81%A7%E3%83%91%E3%82%B9%E3%83%99%E3%83%BC%E3%82%B9%E3%81%AE%E3%83%AB%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0%E3%81%8C%E3%81%A7%E3%81%8D%E3%82%8B%E3%81%A8%E4%BD%95%E3%81%8C%E5%AC%89-2/)
画面をスワイプした事を検知（UISwipeGestureRecognizer）

#今回の内容　

* 画面をスワイプした事を検知

#コードと簡単解説

* `.direction`には、`.down` `.left` `.right` `.up`から選択して使用します。

 * `.down`は下に向けてスワイプしたことを検知します。 
 * `.left`は左側に向けてスワイプしたことを検知します。 
 * `.right`は右側に向けてスワイプしたことを検知します。 
 * `.up`は上に向けてスワイプしたことを検知します。
 
* 4つ全てを使用する場合は、4つ分インスタンスを作成します。
 
* `.direction`を設定しないで使用すると、右側に向けてスワイプした時に検知しました。


```Swift:
 override func viewDidLoad() {
        super.viewDidLoad()

        let swipeDetection = UISwipeGestureRecognizer(target: self, action: #selector(screenSwipe))
        swipeDetection.direction = .down

        view.addGestureRecognizer(swipeDetection)
 }

@objc func screenSwipe(){
        
        //スワイプを検知した時の処理
    }

```

# 終わり
ご指摘、ご質問などありましたら、コメントまでお願い致します。
AtCoderログ：0109 - ABC 138 C

# 問題

https://atcoder.jp/contests/abc138/tasks/abc138_c

## 問題文
> あなたは鍋と $N$ 個の具材を持っています。各具材は 価値 と呼ばれる実数の値を持ち、$i$ 個目 $(1 \le i \le N)$ の具材の価値は $v_i$ です。
> $2$ 個の具材を鍋に入れると、それらは消滅して新たに $1$ 個の具材が生成されます。この新たな具材の価値は元の $2$ 個の具材の価値を $x,y$ として $(x+y)/2$ であり、この具材を再び鍋に入れることもできます。
> この具材の合成を $N−1$ 回行うと、最後に $1$ 個の具材が残ります。この具材の価値として考えられる最大の値を求めてください。

## 制約
> ・$2 \le N \le 50$
> ・$1 \le v_i \le 1000$
> ・入力中の値はすべて整数である。

## 収録されている問題セット
- [AtCoder Problems Boot camp for beginners Easy 100](https://kenkoooo.com/atcoder/#/training/Boot%20camp%20for%20Beginners/1) [#017]

# 回答
## 回答1 (AC)
価値が $x,y$ の具材を合成してできた具材の価値は $(x+y)/2$ になるので、失われた価値は $x+y-(x+y)/2 = (x+y)/2$ となります。従って、具材がたくさんある場合、価値が最小の2つの具材を合成するのが良いことがわかります。

次に、価値が $x < y < z$ である3つの具材を考えます。このとき3つの具材を合成する方法は3通りあり、(1) x,y を合成してから z を合成 → 最終的な価値は $(x+y+2z)/4、(2) x,z を合成してから y を合成 → 最終的な価値は $(x+2+z)/4、(3) y,z を合成してから x を合成 → 最終的な価値は $(2x+y+z)/4、となり、(1)の価値が最も大きいことがわかります。

以上の考察により、全ての具材の価値を昇順(小さい順)にソートし、小さい方から順に合成していけば良いことがわかります。コードは以下のようになりました。

```C++:abc138c-1.cpp
#include <bits/stdc++.h>
using namespace std;
 
int main() {
  int n;
  cin >> n;

  vector<int> v(n);
  for ( int i=0; i<n; i++ ) {
    cin >> v.at(i);
  }
  
  sort( v.begin(), v.end() );
  
  float value = v.at(0);
  for ( int i=1; i<n; i++ ) {
    value = (value+v.at(i))/2.0;
  }
  
  cout << value << endl;
}
```

# 調べたこと
## [AtCoder の解説](https://atcoder.jp/contests/abc138/tasks/abc138_c/editorial) → [ユーザ解説](https://blog.hamayanhamayan.com/entry/2019/08/19/024028)
回答1と同じ方針でした。

## [AtCoder の解説](https://atcoder.jp/contests/abc138/tasks/abc138_c/editorial) → [コンテスト全体の解説](https://img.atcoder.jp/abc138/editorial.pdf)
回答1と同じ方針でした。

# リンク
## 前後の記事
- 前の記事 → [AtCoderログ：0108 - ABC 142 C](https://qiita.com/RoadLynton/items/c69fcdc4bf2256f9bf0f)
- 次の記事 → [AtCoderログ：0110 - ABC 218 に参加しました](https://qiita.com/RoadLynton/items/79e45efdc0a06123255d)
[未経験必見]これを読んだらドベンチャー企業で一人で開発することになっても大丈夫な気がする記事！！

# はじめに
どうも、webエンジニアになって2年目の山﨑祥太郎です。そんな私が今までどのような実務経験をしてきたのか箇条書きでまとめてみるとします。

# 時系列

[入社〜3ヶ月目]
・β版のECサービスをRailsで開発しているときに入社
・実際にコードを書くエンジニアが私一人でした
・Railsは入社が決まってから勉強しました
・フロントもバックもインフラも残されたタスクがあり、いきなりフルスタックになりました（できるとは言っていない）
・業務時間外でも、お構いなしに作業をやっていた記憶があります（これは自主的にであり、自分が不甲斐なかったからです）
・インフラは当時はHerokuを使っていたので、救われた感はありました
・コードの仕様を教えてもらえる方もおらず、試行錯誤の日々でした

[3ヶ月目〜6ヶ月目]
・ちょっと、Railsが分かってきて楽しくなってきたのはこの時期だったと思います
・AWSのクレジットをゲットしたので、サーバーをAWSに切り替えることに
・当時はHeroku=>EC2にしましたね。今思えば、ECSの方が超絶楽ちんです
・凄腕フリーランスアドバイザーがやってくる
・凄腕フリーランスアドバイザーとの会話が全く成立せず、自信消失
・凄腕フリーランスアドバイザーの言われるがままにタスクをこなしていく
・気づいたら開発が便利になっていて、凄腕フリーランスアドバイザーの凄さをまじまじ感じる
・そして、凄腕フリーランスアドバイザーは去っていった

[6ヶ月目〜12ヶ月目]
・開発が便利になって少し手が空く
・ベンチャーのエンジニアイベントに参加して、Shopifyの凄さを持ち返ってくる
・開発しているサービスもShopifyに切り換えられるのではないかと思い社長に希望
・Shopifyの開発に切り替わる
・具体的には、Shopify + RailsAPI + Rails
・結果的には愚策でした笑　微妙な仕様変更に凄い時間がかかってしまった
・開発・運用していたサービスが終了を告げる
・新規グローバルECサービス立ち上げ
・１０ヶ月目あたりで、ようやく出社をする
・開発の段階で、本当にニーズがあるのか確かめるために街角アンケートをする（週3ぐらい）
・もちろんグローバルサービスなのでアンケート相手は外国人

[12ヶ月目〜現在]
・一人暮らしを始める
・β版をリリースする
・小規模で試行したいということでSNSマーケティングを友人に依頼
・おかげさまで、初の売り上げが経つ
・人事採用にもアシスタントとしてつく
・VCとの面接にもアシスタントとしてつく
・売り上げが軌道にのる！
・現在に至る

# まとめ
ドベンチャーはいろいろな経験を積むことができます。エンジニア目線での考えも大事ですが、顧客目線になって考えることはもっと大事です。もっと言えば会社全体を考えないといけないので、「ゆくゆくは社長になりたい」と考えてる人はドベンチャーという選択は良いのではないでしょうか。
最近物忘れのひどい私が書いた、二重登録防止のためにMySQLでロックを使ったPHPのサンプルコード

## 結論

1. InnoDBのテーブル
2. トランザクションを開始する
3. SELECT ... FOR UPDATEをする
4. 新規追加もしくは更新のクエリを実行する
5. トランザクションを終了する

## 概要
１件だけの登録、１件のだけの更新時の処理用
同時登録、同時更新によりデータの整合性が取れなくなる事を防ぐ事が目的
行ロックなのかテーブルロックになってしまうかなどは、考えていない

## サンプル用テーブル

idとnoだけのテーブル。InnoDBである事。

```SQL
CREATE TABLE test (
  id int NOT NULL AUTO_INCREMENT,
  no int NOT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB;

-- １件入れておく
INSERT INTO test (no) VALUES (1);
```

## 新規作成

仕様はnoは重複してはならない（ユニークインデックスを貼れば済むが）とします。なので挿入するnoが存在していない事をチェックしてから挿入します。「伝票番号などのnoが重複してはならないという仕様ならユニークインデックス張っておいたら？」と思いますか？思いますよね？私も思うんです。でも世の中にはユニークインデックス使用禁止というシステムが存在するので、存在する事を覚えておいてください。

```PHP
// 伝票番号など 例)100番
$no = 100;

$pdo = new \PDO(略);

try {

    $pdo->beginTransaction();

    // ロックを取得する
    // FOR UPDATEで他のセッションがロックを取得している場合、解除されるまで待つ
    // FOR UPDATEの後ろにNOWAITを付けている場合、解除されるまで待たずに例外がスローされる
    $stmt = $pdo->query("SELECT COUNT(*) as cnt FROM test WHERE no = {$no} FOR UPDATE");
    // $stmt = $pdo->query("SELECT COUNT(*) as cnt FROM test WHERE no = {$no} FOR UPDATE NOWAIT");

    // ３秒以内に別ブラウザで叩いて確認する。FOR UPDATE を付けてないと二重登録されてしまう
    sleep(3);

    $r = $stmt->fetch(\PDO::FETCH_OBJ);
    if (0 < $r->cnt) {
        echo "<h1>no({$no})のデータが既に存在しています。</h1>";
        exit;
    }

    // 新規追加
    $pdo->exec("INSERT INTO test (no) VALUES ({$no})");
    $pdo->commit();

    echo '<h1>正常に登録されました</h1>';
}
catch (\Exception $e) {
    $pdo->rollBack();
    echo '<h1>エラーが発生しました</h1>';
    echo $e->getMessage();
    // NOWAITでロックが取得できなかった時の例外メッセージ
    // SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction
}
```

## 更新処理

なんらかの処理が行われたらnoがインクリメントされる処理があるとします。
もし完全に同時に２回行われた時、１回分のインクリメントしかされない事がないようにロックを取得します。

```PHP
$pdo = new \PDO(略);

try {
    $pdo->beginTransaction();

    // idが1のデータのnoをインクリメントするため現在の値を取得
    $stmt = $pdo->query('SELECT no FROM test WHERE id = 1 FOR UPDATE');
    // $stmt = $pdo->query('SELECT no FROM test WHERE id = 1 FOR UPDATE NOWAIT');

    // ３秒以内に別ブラウザで叩いて確認する。FOR UPDATEが入っていないと２回のインクリメントのはずが１回分しか増えない
    sleep(3);

    // 値をインクリメントする更新処理
    $r = $stmt->fetch(\PDO::FETCH_OBJ);
    $new_no = $r->no + 1;
    $pdo->exec("UPDATE test SET no = {$new_no} WHERE id = 1");
    $pdo->commit();

    echo '<h1>正常に更新されました</h1>';
    echo "{$r->no}から{$new_no}へ更新";

}
catch (\Exception $e) {
    $pdo->rollBack();
    echo '<h1>エラーが発生しました</h1>';
    echo $e->getMessage();
}
```
【初心者向け】ソースコードの自動整形（VSCode）

#はじめに
これを知らなかった頃は整えたい行を選択してインデントを整えていました。
このショートカットキーがあれば、一気にコード全体のインデントを整えることができるので、知っているのと知らないのは全然違います。

#ショートカットキー
| OS | ショートカットキー |
|:-:|:-:|
| Mac | [Shift]　+　[option]　+　[F] |
| Windows | [Shift]　+　[Alt]　+　[F] |

#おわりに
ショートカットキーを知っているとかなり時間を短縮できるので、これ以外のショートカットキーもググってみましょう。
Chakra UIテーマのカスタマイズ方法

## Chakra UIとは

![Chakra UI](https://raw.githubusercontent.com/chakra-ui/chakra-ui/main/logo/logo-colored@2x.png?raw=true)

[Chakra UI](https://chakra-ui.com/)とは、React用のコンポーネントライブラリです。
React用のコンポーネントライブラリの中で、多分一番使われていると思われるのがGoogoleが提唱する「Material Design」というガイドに沿って作成っされた[Material-UI](https://material-ui.com/)では無いかと思います。
今回は、Chakra UIを利用させて頂きました。選んだ理由としては、Githubのスター数、コンポーネントの豊富さ、コンポーネントに手を入れなくても比較的そのままで使えるか、ドキュメントが整ってるかなどです。
しかし、いざChakra UIを導入して、テーマのを変更するのにかなり苦戦したので、同じ所でハマっている方がいれば参考にしていただければ幸いです。

## themeファイルでテーマのをカスタマイズ
Chakra UIはドキュメントがしっかりしているので、問題なく利用できると思いますが、コンポーネントをオーバーライドする場合の説明があまりなく、苦戦しました。
[こちら](https://chakra-ui.com/docs/theming/customize-theme
)のページにコンポーネントのオーバーライド方法が記載されてはいるのですが、ボタン以外のコンポーネントで期待通りに動かない結果になりました。

記載されているButtonコンポーネントを参考に、他コンポーネントも設定しましたが、全然適用されませんでした。調べていくとどうやら、コンポーネント事に微妙に記述の違いがある様です。

結果的に動いたファイルは下記

```
// theme.js
import { extendTheme } from "@chakra-ui/react"
const theme = extendTheme({
    styles: {
    	global: {
	    	body: {
	    		fontFamily: "'游ゴシック体', YuGothic, '游ゴシック', 'Yu Gothic', 'メイリオ', 'Hiragino Kaku Gothic ProN', 'Hiragino Sans', sans-serif",
	    		fontSize: "0.8125rem",
	    		lineHeight: "1.5",
	    	},
    	},
    },
    components: {
    	Heading: {
    		baseStyle: {
    			fontWeight: 'normal',
    		},
    		sizes: {
    			sm: {
    				fontSize: '1.125fem',
    			},
    			md: {
    				fontSize: '1.375fem',
    			},
    			lg: {
    				fontSize: '1.625fem',
    			},
    			xl: {
    				fontSize: '1.875fem',
    			},
    		},
    	},
    	Text: {
    		sizes: {
    			xs: {
    				fontSize: '0.625rem',
    			},
    			sm: {
    				fontSize: '0.8125rem',
    			},
    			md: {
    				fontSize: '0.8125rem',
    			},
    			lg: {
    				fontSize: '0.625rem',
    			},
    			xl: {
    				fontSize: '1.125rem',
    			},
    		},
    	},
    	Table: {
    		baseStyle: {
    			table: {
    				color: 'gray.400',
    			},
    			th: {
    				fontWeight: 'normal',
    				bgColor: 'gray.100',

    			},
    		},
    	},
    },
})
export default theme
```
上記のthemeファイルをappファイルに読み込めば、適用されました。

components→コンポーネント名→baseStyleで動くコンポーネントもあれば、components→コンポーネント名→baseStyle→要素名で動く場合もあり、そこが苦戦しました。

是非上記を参考にしていただければ幸いです。
Docker for Mac 設定

### Macの環境
- 機種:MacBook Air(M1,2020)
- CPU:Apple M1
- Memory:16Gb
- OS:macOS Big Sur
- SHELL:zsh
- docker:20.10.8

### CUI tab補完
[docker公式のコマンドライン補完](https://docs.docker.jp/compose/completion.html)の設定は**curl**のリンクが死んでいて利用できなかった。そのため、dockerをインストールした際に存在している補完ソースを利用した。今回は、自身の環境で成功した、**zsh**について書く。

#### zsh-completionsの確認

**zsh-completions**を使うため、インストールされているか確認する。

```zsh
$ brew list | grep zsh-completions
# 存在していなければ、下記を実行
$ brew install zsh-completions
```

#### 補完ソースのシンボリックリンクを作成

```zsh
# ~/.zsh/completionsの階層がなければ、下記を実行
$ mkdir -p ~/.zsh/completions
# 補完ソースの保存場所作成
$ touch _docker
$ touch _docker-compose
$ ln -s /Applications/Docker.app/Contents/Resources/etc/docker.zsh-completion ~/.zsh/completions/_docker
$ ln -s /Applications/Docker.app/Contents/Resources/etc/docker-compose.zsh-completion ~/.zsh/completions/_docker-compose
```
#### zsh-completionsの有効化

```zsh:.zshrc
# 下記の追記
fpath=(~/.zsh/completion $fpath)
autoload -Uz compinit && compinit -i
```

#### zshの再起動
```zsh
$ source ~/.zshrc
```
pyautoguiで全角入力されて困った経験

#概要
pyautoguiで入力自動化をしようとしていたところ、半角情報が全角入力されて困った

```python
import pyautogui
import time

pyautogui.click(228, 50)
pyautogui.write('https:/')  #URL指定  全角入力になる
```

https://teratail.com/questions/328041

に解決方法があった。

1. 無変換キーにIMEオフの設定をつける

2.

```
pg.press("nonconvert")
```
を実行し、プログラム動作時はIMEオフにする

#無変換キーにIMEオフの設定をつける方法
1. キーボード入力の"A"または"あ"に右クリック
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/4d9ea381-2480-0efc-a607-7647f14c3068.png)

2. ”プロパティ"を選択
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/d2afc6cb-7401-5837-cbfd-d3f4f75de580.png)

3. 詳細設定を選択
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/72a736e0-39a1-d688-ee7f-257ced5c8ed4.png)

4. 変更を選択
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/9019b9ee-baec-a083-4275-ec1aad4615f8.png)

5.　無変換をIME-オフ　に変更
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/ac867e7e-47ff-7ac7-b1e8-3050f94dafb8.png)

"OK"で完了です

実際に、日本語入力後、無変換を押して半角になったら成功です！

#テストプログラム

Chromeのweb検索を自動入力するものです

```python
import pyautogui
import time

pyautogui.click(228, 50)
print(pyautogui.position())
pyautogui.press("nonconvert")
pyautogui.write('https://')  #URL指定
pyautogui.press('enter')
```
テックキャンプを受講した感想

## はじめに
私はテックキャンプに通い、プログラミング未経験から学習、及び転職活動を始め、10社様から内定をいただきました。

本記事ではテックキャンプを受講した感想について、記事にしております。

これから、エンジニア転職を検討されている方、プログラミングスクールに通うか検討されている方、プログラミング学習・転職活動をされている方のご参考になればと思い本記事を作成しました。

## 目次
・総括
・テックキャンプでは人とのつながりの大切さも学べる
・テックキャンプは自走力が身に付く環境
・プログラミング未経験からエンジニア転職するハードルの高さ
・他力本願はやめる
・あらゆる才能より、続けることの重要さ
・プログラミングスクールでの学習方法について
・転職活動するなら、就活テクニックもある程度必要
・これからプログラミング学習を始めようとしている方へエールを！

## 総括
テックキャンプではプログラミング学習を挫折せず、楽しく勉強できる仕組み、転職活動支援などがあります。

また、カリキュラムにはありませんが、エンジニアリング以外のビジネスマンや人としてのスキル、マインドも同時に学べる場でもありました。

人とのつながりの大切さを学べ、私は通ってよかったと思っております。

プログラミング未経験からエンジニアを目指すことは本当に難しく、決して楽な道ではありませんでした。

ただ、テックキャンプのサービスを十分に自分のスキルにし、体現できれば、転職活動の難易度は下がると思います。

スクールで学んだことは、これからのエンジニアもしくはビジネスマンとしての人生の基盤になります。

これから際なる飛躍ができるよう、入社後も日々精進して参ります！！

## テックキャンプでは人とのつながりの大切さも学べる
テックキャンプでは様々な人との関わり合いがあります。
以下の方々とともに、学習ができ、支援もいただけます。

・同じ目標がある同士がいるので切磋琢磨できる
・モチベーション高く学習するために支えてくださるライフコーチがおり、独りよがりにならない
転職活動支援をしてくださるキャリアアドバイザーがおり、転職活動の相談、職務経歴書・面接等のアドバイスを受けられる
・プログラミングスキルをご教示くださるメンターがおり、質問形式で正しい知識得られ、プログラミング学習の疑問点を解消できる

おそらく、私は皆さんのお力添えがなければプログラミング学習、転職活動を挫折していたかもしれません。
上記の方々とは密なコミュニケーションをとり、刺激や勇気、支援、情報提供などいただけました。

チームの方々とはカリキュラム以外のプライベートの話をしたり、カリキュラムが終わった後でも転職活動状況を話し合ったりと、とても楽しい３ヶ月半でした。

ただ、相手の支援をただ待つだけでなく、自分から行動し周りを巻き込むことが重要になると思いました。

## テックキャンプは自走力が身に付く環境
テックキャンプでは、学習は講義形式ではなく、カリキュラムを自分で進めて、わからない箇所、疑問点などをメンターに質問するという形式です。

なので、能動的に自身で行動する必要がある環境です。
言い換えれば、学習が身についきやすい環境であり、自走した分だけ成長できる場です。

その多くは質問だけでなく「自身の理解のアウトプット」という形で、自分の学んだことをメンターに説明しておりました。
自分の誤認だけでなく、理解の定着にも繋がりまりました。

自走した中で、質問やアウトプットで表現力・論理的思考能力が培え、能動的な思考がつきました。

相乗効果で成長できる環境がありました。

成長できたと言えど、まだまだ未経験エンジニアであり、エンジニア転職するハードルの高さは凄まじいものでありました。

## プログラミング未経験からエンジニア転職するハードルの高さ

応募数に対しての内定率は約10%でした。

お見送り理由はコロナ禍での人材需要の変化もあったのだと思います。

以前までは未経験でも雇っていただけるだけの余裕が企業様にはあったと思いますが、このコロナ禍で未経験を教えながらのプロジェクト進行はとてもコストがかかり、コロナ前では可能であったこともだんだんと厳しくなってきているように感じます。

## 他力本願はやめる
マインドの１つに他力本願をやめることを挙げます。
スクールに通ったから内定をいただけるという他力本願はやめるということです。

スクールに通うと求人案件の紹介もあり、スクールがなんとかしてくれるという気持ちで面接に挑めば落ちてしまいます。

企業からしても未経験よりも経験者を雇う方が、利益にもなります。
しかし、未経験エンジニアにも求人があります。

その理由を考え、内定という目標から逆算し考え、就活対策をすることが転職活動を成功させると思っています。

そのためには諦めず継続することが必要不可欠です。

## あらゆる才能より、続けることの重要さ
才能による効率は大抵２~3倍異なると言われていますが、人よりも続けることで10倍以上の効率を生み出すそうです。

なので、転職活動をしていてお見送りになっても、めげずに挑戦し続けることが内定につながってくると思います。

これは転職活動だけでなく、今後のエンジニアリングにも同様のことが言えます。

マインドも重要ですが、もちろん学習方法も大切になってきます。

## プログラミングスクールでの学習方法について
私は、テックキャンプに通う中で、勉強方法を工夫したことが、内定にもつながったかと思います。

というのも学習の質が高ければ、より質の高いポートフォリオを作成できるからです。

学習も重要ですが、就活テクニックで選考で自分を魅せることも重要になりました。

学習も重要だが、就活テクニックもある程度必要

## これからプログラミング学習を始めようとしている方へエールを！
エンジニアを目指して日々転職活動をされている方、学習されている方は本当に素晴らしいと思っています。
特に未経験からチャレンジされている方は、それほど決断力があって今も努力されていることはとても素晴らしいことですし、誰しもできることではないです。

皆さんは素晴らしですし、これからエンジニアとして活躍していくことが目標かと思いますので、諦めないことが一番大切かと思います！！

諦めずに納得いく就職活動をしていきましょう！！
M1 Mac環境へTrace Compassインストール


# はじめに

Spresense SDK環境でタスクトレースを使いたくてM1 Macで環境構築したときのメモです

https://developer.sony.com/develop/spresense/docs/sdk_tutorials_ja.html#_feature_tasktrace

# Trace Compass
こちらからダウンロードしてインストールする

https://www.eclipse.org/tracecompass/

* trace-compass-7.0.0-20210609-2151-macosx.cocoa.x86_64.tar.gz
 * arm64ネイティブ版は用意されていない
 * x86_64版をインストールして、Rosetta2前提で動かす

起動すると「ファイルが壊れているため開けません。ゴミ箱に入れる必要があります。」と注意されるので、実行を許可しておく

````
sudo xattr -rd com.apple.quarantine /Applications/trace-compass.app
````

# Java VM

Trace Compassツールを使うためには、別途JVM環境が必要になります

各種OpenJDK環境を入れてみたり、/Applications/trace-compass.app/Contents/Info.plistを編集したりと試行錯誤するも、"libdjvm.dylib does not contain the JNI_CreateJavaVM symbol"のエラーを解消できず。。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/432852/bf8bb72e-d385-e141-b09e-f28f69c1982e.png">

最終的に、こちらからmacOS/x64をインストールして、無事、Trace Compassツールが起動できるようになりました

https://jdk.java.net/16/
Giteaで毎日S3に最新バックアップを取るためのお手軽crontabシェル芸

### 設定方法

```sh
0 10 * * * sh -c "gitea dump -c /etc/gitea/app.ini && ls | xargs -I@ aws s3 cp @ s3://path-to-your-s3 && rm ~/*"
```


お手軽にシェル芸。痒いところに手が届くのがいいですね！
継承.part1

##メソッドのオーバーライト
今回は継承の中のメソッドのオーバーライトについて解説したい。
アプリケーションを作っていく中で基底のクラスに定義されたメソッドでは機能が不足しそのままでは`利用できない`場合も考えられる。

そんなときは`virtualキーワード`と`overrideキーワード`を使う必要がある。

基底クラスでvirtualキーワードを使いメソッドを定義すると、そのメソッドを派生クラスで上書きすることができる。

```C#
 class Person //基底クラス
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string FullName
        {
            get { return LastName + FirstName; }
        }
        public string Email { get; set; }
        public virtual void Print() //virtualキーワードをつけると派生クラスでオーバーライトできる
        {
            Console.WriteLine($"名前: {FullName} {Email})");
        }
    }
    class Employee: Person //派生クラス
    { 
        public int Number { get; set; }
        public DateTime HireDate { get; set; }
        public override void Print() //overrideキーワードでメソッドを上書き定義
        {
            Console.WriteLine($"{Number}:{FullName} {Email} {HireDate.Year}年入社");
        }
    }
```

基底クラスでvirtualキーワードを使いメソッドを定義すると、そのメソッドを派生クラスで上書きすることができます。
このメソッド`オーバーライド`と言います。

```C#
public virtual void Print()
```
の部分がそれに当たります。

```C#
public override void Print()
```
の部分がオーバーライドしている箇所です。

```C#
class Program
    {
        static void Main(string[] args)
        {
            Practice_13_3_2();
        }
        public static void Practice_13_3_2()
        {
            var person= new Person
            {
                FirstName = "はるか",
                LastName = "佐々木",
                Email = "hsasaki@example.com"
            };
            person.Print();
            var employee = new Employee
            {
                Number = 132,
                FirstName = "涼太",
                LastName = "田中",
                Email = "rtanaka@exmple.com",
                HireDate = new DateTime(2015, 10, 1)
            };
            employee.Print();

        }
    }
```
##結果は
名前: 佐々木はるか hsasaki@example.com)
132:田中涼太 rtanaka@exmple.com 2015年入社
となります。
全探索

#bit全探索

###プログラムの書き方

```c++

for (int i = 0; i < (1 << 100); i++) {
  bitset<100> s(i);
  if (i & (1 << 2)){} // 2桁目のビットが1かどうかチェックする

}
```


###bitsetとは
ビット集合を表わす型（クラス）のこと． N桁の2進数を定義することができると思ってくれたら良い．


|プログラム|説明|
|:---|:---|
|a = (a ^ b) など|	int 型などと同じように、ビット演算（and, or, xor）をすることができます。|
|a.set(x)|	a の x 桁目（2進数）を 1 に変更します。|
|a.reset(x)|	a の x 桁目（2進数）を 0 に変更します。|
|a[i]|	配列と同様、a の i 桁目（2進数）にアクセスすることができます。a[i] は必ず 0 か 1 です。|
|a.count()|	a の全ての桁のうち、1 となっている桁の個数を返します。|

---
###練習問題
[ARC061 C - たくさんの数式 / Many Formulas](https://atcoder.jp/contests/arc061/tasks/arc061_a)
[ABC079 C - Train Ticket](https://atcoder.jp/contests/abc079/tasks/abc079_c)
[ABC104 C - All Green](https://atcoder.jp/contests/abc104/tasks/abc104_c)
[ARC029 A - 高橋君とお肉](https://atcoder.jp/contests/arc029/tasks/arc029_1)
[ABC002 D - 派閥](https://atcoder.jp/contests/abc002/tasks/abc002_4)
Ruby 3.1 で { a: a } が { a: } とかけるようになったらしい

[ブログ記事](https://secret-garden.hatenablog.com/entry/2021/09/11/192242)からの転載です。

以前から山のように提案があった Hash のショートハンドが RubyKaigi の感想戦で matz を説得して入ったらしい。

* チケット：[[Feature #14579] Hash value omission](https://bugs.ruby-lang.org/issues/14579)
* コミット：https://github.com/ruby/ruby/commit/c60dbcd1c55cd77a24c41d5e1a9555622be8b2b8
* 感想戦のログ：https://hackmd.io/Mmse5ybASq-6c2kQoJQdMQ

これによって Ruby 3.1 で Hash が以下のように書くことができます。

```ruby
name = "homu"
age = 14

# { name: name, age: age } のシンタックスシュガー
{ name:, age: }
# => {:name=>"homu", :age=>14}

# 一部だけ値を割り当てることもできる
{ name:, age: 16 }
# => {:name=>"homu", :age=>16}


def tokyo
  "東京"
end

# メソッド呼び出しも可能
{ tokyo: }
# => {:tokyo=>"東京"}


def user(name:, age:)
  { name:, age: }
end

# user(name: name, age: age) になる
user(name:, age:)
```

めっちゃ便利ですね！！！！
このショートハンドは `{ a: } -> { a: a }` になるというよりかは `a: -> a: a` になる、と認識するとよさそうです（なので `[a:] -> [a: a]` となる。

matz を説得している時にちょうど離席していたのでどのような経緯で matz を説得したのかがすごく気になる…。  
既に本体にコミットされているので `rbenv install 3.1.0-dev` などで最新の Ruby を落としてくるとすぐに使えます。
今すぐ早く使いたい。


## おまけ

感想戦で `binding.local_variable_get(:if)` の変わりに `{if:}[:if]` が使えるようになると言及されててワロタ

```ruby
def foo(if:)
  # if はキーワードなので変数にアクセスする時は Binding#local_variable_get を使う必要があった
  if_ = binding.local_variable_get(:if)

  # このショートハンドを使うとこうかけるようになる
  if_ = {if:}[:if]
end
```

便利そう。
AtCoderで必要な知識一覧

AtCoderで必要な知識を一覧にまとめたものです．
それぞれの知識の詳細は今後更新していく予定です．

#目次

1. [全探索](https://qiita.com/ui0079/items/bce6276679883d631391)
    * bit全探索
    * 順列全探索
    * 二分探索
    * 深さ優先探索
    * 幅優先探索
1. 動的計画法
1. bitDP
1. 区間DP
1. 期待値DP
1. 桁DP
1. 文字列DP
1. 隣接リスト・隣接行列
1. ダイクストラ法
1. ワーシャルフロイド法
1. トポロジカルソート
1. 木の直径
1. UnionFind
1. エラトステネスの篩（ふるい）
1. 素数判定
1. 約数列挙
1. 素因数分解
1. 繰り返し自乗法
1. 約数・倍数に関する性質
1. MODの性質
1. 内積・外積
1. マンハッタン距離の性質
1. 逆元
1. 写像12相
1. 包除原理
1. 二項定理
1. 累積和
1. しゃくとり法
1. セグメント木
1. 遅延セグメント木
1. kD木
1. ローリングハッシュ
よく間違えるコマンド

<h3>Mysqlの接続</h3>
```
mysql -u root -p -h rds-mysql-server.xxx.ap-no-1.rds.amazonaws.com

mysql -u root -p -h 　「RDS→データベース→エンドポイントのrdsで始まるとこ」

```

<h3>EC2接続</h3>
```
ssh -i ~/.ssh/practice-aws.pem ec2-user@xx.xx.xx.xx

ssh -i ~/.ssh/practice-aws.pem ec2-user@「パブリックIPアドレス　ipv4のこと」
```
<h3>viの操作</h3>
```
$ sudo vi  ファイル名
で操作
$ sudo nginx -t
でどこがエラーかわかる
```

```viファイル内操作
:w  で保存
:q!　　で脱出
:set number で行数わかる
```
STM32L010のソフトウェアシリアルでHello Worldと出力 1200bps TX PA2 STM32 HAL


目的
つくれそうだから作ってみた。
通信がづれる時はUART_DELAYの値を1足したり1引いたりして調整してね

x mbedのリビジョンは、143


![h_con62.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/1b2ce684-0213-9bb9-a942-96a0238ccd04.jpeg)



![h_con61.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/45e394a5-2c04-b476-8f76-d44d3df121f1.jpeg)



```c++


#include "mbed.h"

#define UART_DELAY 832 //  1/1200

#define DW(AAA,BBB)  HAL_GPIO_WritePin(GPIOA,AAA,BBB)

GPIO_PinState bi1[]={GPIO_PIN_RESET,GPIO_PIN_SET};


//仮想シリアルへの一文字出力 9600bps
int pc_putc(char ch) {

    DW(GPIO_PIN_2,GPIO_PIN_SET);
    DW(GPIO_PIN_2,GPIO_PIN_RESET);//START
    wait_us(UART_DELAY);

    for(int ii=0;ii<8;ii++){          
        DW(GPIO_PIN_2, bi1[  ( (ch>>ii)&1 )  ]);
        wait_us(UART_DELAY);
    }; //for

    DW(GPIO_PIN_2,GPIO_PIN_SET);//Stop
    wait_us(UART_DELAY);

    return(0);

} //pc_putc


int main() {

    //ポートをhiにする 初期化
  __HAL_RCC_GPIOA_CLK_ENABLE(); 
  GPIO_InitTypeDef GPIO_InitStruct = {0}; 
  GPIO_InitStruct.Pin = GPIO_PIN_2;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);

    char *ss1; //文字のポインター
    int ii; //ループカウンター

    //無限ループ
    while(1) {

        ss1="Hello World !\r\n";
        ii=0; //ループカウンター
        while(ss1[ii]!=0){

            //一文字出力
            pc_putc(ss1[ii]);ii++;

        } //while

        //1秒の待ち
        wait_ms(1000);

    } //while

} //main





```
[JavaScript] named export と default export の違い

export とか import の構文をES Modulesと呼びます。
ES Modulesを使うために、Deno 環境を用意するとよいです。

Node.js でも package.json 記載すればうまく動きます。
この記事ではどちらでも動かしてみます。

```js:fileA.js
export const funcA = () => {
  console.log('funcA output')
};
```
これが named export 。関数名付きでファイルからexportしています。

```js:fileB.js
const funcB = () => {
  console.log('funcB output')
};

export default funcB;
```
これが default export 。名前なしでファイルからexportしています。

使い方はそれぞれこんな感じ。全て同一ディレクトリ内に配置してください。

```js:index1.js
import { funcA } from './fileA.js'
import funcB from './fileB.js'
console.log('index.js');  // index.js
funcA();                  // funcA output
funcB();                  // funcB output
```

`> deno run index1.js`

上記コマンドで、コメントに示している通りの出力が行われます。

これらの名前を変更して利用する場合は次のようにします。

```js:index2.js
import { funcA as funcA1 } from './fileA.js'
import funcB1 from './fileB.js'
console.log('index.js');  // index.js
funcA1();                  // funcA output
funcB1();                  // funcB output
```

`> deno run index2.js`

funcAは名前が指定されているので別名で定義するときは as を使います。

funcBの方は、fileBから出力されているってだけで名前なしなので、別名の変数に代入するだけで使えます。


Node.js で ES Modules を動かすためには、.js の拡張子の場合、package.json の記載が必要です。

```json:package.json
{ "type": "module" }
```

`> node .\index1.js`
`> node .\index2.js`

それぞれのコマンドで動作確認できます。


参考

Node.js で ES Modules 記法を動かしてみる - Neo's World
https://neos21.net/blog/2020/09/02-02.html


以上です。
GolangでAirを使ってホットリロードを実現する

[realize](https://github.com/oxequa/realize)を愛用していましたが、開発が止まっているようなので[air](https://github.com/cosmtrek/air)を使ってホットリロードを実現します

## 環境
- go version
    - 1.15.7

## プロジェクト作成
```
$ mkdir go-hotreload-sample && cd go-hotreload-sample
$ go mod init go-hotreload-sample
```

フレームワークはサンプルとして[echo](https://github.com/labstack/echo)を使ってみます

```
$ go get github.com/labstack/echo/v4
```

```go:main.go
package main

import (
  "net/http"
  "github.com/labstack/echo/v4"
  "github.com/labstack/echo/v4/middleware"
)

func main() {
  // Echo instance
  e := echo.New()

  // Middleware
  e.Use(middleware.Logger())
  e.Use(middleware.Recover())

  // Routes
  e.GET("/", hello)

  // Start server
  e.Logger.Fatal(e.Start(":8080"))
}

// Handler
func hello(c echo.Context) error {
  return c.String(http.StatusOK, "Hello, World!")
}
```

## 起動してみる
go runコマンドで起動してみます

```
$ go run main.go
```

ターミナルの別ウィンドウからリクエストを送ると、レスポンスが返ってくることを確認します

```
$ curl http://localhost:8080
Hello, World!
```

## airでホットリロードを実現する
### ダウンロード
```
$ go get -u github.com/cosmtrek/air
```

### 確認
```
$ air -v

  __    _   ___
 / /\  | | | |_)
/_/--\ |_| |_| \_ , built with Go
```

airが確認できたら、go runを使わずにairで起動します

```
air
```

以下のような感じで立ち上がることを確認します

```
⛄ air

  __    _   ___
 / /\  | | | |_)
/_/--\ |_| |_| \_ , built with Go

mkdir /path-to-dir/go-hotreload-sample/tmp
watching .
watching bin
!exclude tmp
building...
running...

   ____    __
  / __/___/ /  ___
 / _// __/ _ \/ _ \
/___/\__/_//_/\___/ v4.5.0
High performance, minimalist Go web framework
https://echo.labstack.com
____________________________________O/_______
                                    O\
⇨ http server started on [::]:8080
```

起動できたことを確認したら、
main.goのレスポンス返却部分を変更してみます

```
// Handler
func hello(c echo.Context) error {
	return c.String(http.StatusOK, "hogehoge")
}
```

curlで再度確認します

```
$ curl http://localhost:8080
hogehoge
```

ホットリロードできていることを確認できました

## 参考
- Go + Air でホットリロード
    - https://qiita.com/sogafish/items/69cd70ec2660a8335bfc
- labstack/echo
    - https://github.com/labstack/echo
- cosmtrek/air
    - https://github.com/cosmtrek/air
Module parse failed: Unexpected string in JSON at position 93 while parsing と表示された時の対処

## jsonファイルを手動で弄ると起こるエラー

```
Module parse failed: Unexpected string in JSON at position 93 while parsing '{
  "name" : "text",
  "sex": {
    "'
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
SyntaxError: Unexpected string in JSON at position 93 while parsing '{...
```

このエラーが起こった時の対処です。

## カンマ(,)が無かった
```json
{
  "name" : "abc" 
  "sex": {
    "male": "true"
  }　
  "age": "123"
}
```

カンマ(,)が足りていなかっただけでした。
不必要な箇所にカンマがあっても同様のエラーが発生するようです。
簡単ですが、オブジェクトが長くなると見逃しがちです。

## jsonエディターで解決
json用のeslintなど検証ツールが入っていれば悩まないはずですが、私はちょうど導入してなくてこのエラーが出ました。
そんな時はWebアプリのjsonエディターを使って解決しましょう。

https://jsoneditoronline.org

これに入れると、エラー箇所を教えてくれるので解決です。
ALBでCookieをもとに公開範囲を限定する

# はじめに
サービスを開発していると、社内の人だけ見れるように公開したいということが多くあると思います。
その際に、接続元のIPをNetwork ACLやSecurity Groupで絞ってアクセスを制限するという方法があります。これは、社内ネットワークがしっかり構築されていてIPが統一されればいいですけど、そうでない場合各自のIPを許可していくのは面倒かなと思います。
そこでCookieでアクセスを絞れば各自ブラウザにセットするだけでいいので良いかなと思いました。それを実現するために行ったことを記載します。
# ALBのリスナールールを利用する
アクセスの制限はALBのリスナールールで行います。
リスナールールについてはこちら
https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/listener-update-rules.html

　 - host-header
　 - http-request-method
　 - path-pattern
　 - source-ip
　 - http-header
　 - query-string

 の条件でアクセス先を振り分けることができます。
# Cookieをもとにアクセス先を振り分ける
リスナールールで`http-header`をもとにアクセス先を振り分けられうことがわかったので、ここでCookieを利用します。

ここからはALB構築されている前提で話します。
まず、ALBのリスナーというタブから「ルールの表示/編集」をクリックします。
![スクリーンショット 2021-09-11 18.08.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218021/4ccb5f2b-ebb2-6582-e1bf-e9d8f56c28d3.png)

すると、リスナールールを変更できると思うので以下のように設定します。
![スクリーンショット 2021-09-11 18.15.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218021/4d173132-bd8f-7b8c-eefe-3733b9979d1f.png)

ルールID:1でHTTPヘッダーを選択して`Cookie=alb-listener-value=hoge`と設定します。Cookieの名前や値は各自に任せます。なるべく推測されないものの方がより安全でしょう。
そして、デフォルトのルールは固定レスポンスで503とか返すようにしておけばいいと思います。
設定はこれで終わりです。

これでCookieに何もセットしないとアクセスできないけど、`alb-listener-value=hoge`をセットするとアクセスできるようになったと思います。
GitLab CI/CDでビルド後の成果物を違うステージで再利用する方法

# ユースケース
例えば、stage1でビルドを行い、その実行ファイルをstage2で単体テストなど行うユースケースで便利です。

## GitLab Runnerの生成物に対するデフォルトの挙動
GitLab Runnerのデフォルトでは、**stage1での生成物は、stage2に遷移するタイミングで消される**ため、stage2でパスを指定してもFile Not Foundエラーが出ます。これは、常に環境をクリーンに保つという設計上の方針だとは思いますが、初心者にはつまづきやすいです。

# 対処
生成物(=artifacts)をdependenciesを用いて明示的に引き継ぐ旨を`.gitlab-ci.yml`にぶち込みましょう

```yaml:前のステージ(.gitlab-ci.yml)
stage1:
  artifacts:
    untracked: true
```

```yaml:次のステージ(.gitlab-ci.yml)
stage2:
  dependencies: 
    - build-job
```

# 参考文献

https://stackoverflow.com/questions/38140996/how-can-i-pass-artifacts-to-another-stage
git コマンド覚書

# 初期設定

```
git clone
git add .
git commit -m
git push origin main

git pull
git fetch → git merge
```
ワークディレクトリがクリアになった状態のファイルは
pullすると同期される。
リモートで削除されていればローカルでも削除される。
ただし、ローカルで変更を加えたファイルはpullしても変更はない。

# コミットの構成
`圧縮ファイル` - `ツリーファイル` - `コミット`

|ファイル|内容|
|:-|:-|
|圧縮ファイル|圧縮されたファイルデータ|
|ツリーファイル|今のワークディレクトリ内の圧縮されたファイルのデータの一覧|
|コミット|ツリーファイル・親コミット・作成者・日付・コミットメッセージ|

#変更点の確認

## git add する前の変更分
```
git diff
git diff "ファイル名"
```
## git addした後の変更分

```
git diff --staged
```

#  変更履歴
```
git log
git log --oneline
git log -p "ファイル名"
git log -n "表示するコミット数"
```

#ファイル操作
## リポジトリからのファイルの削除
```
git rm
git rm (--cached)
```
##ファイルの移動
```
git mv
- mv "旧ファイル名" "新ファイル名"
- git rm "旧ファイル名"
- git add "新ファイル名"
```
##ワークツリーのファイルへの変更を取り消す
###最新のステージの情報でワークツリーを上書きする
```
git checkout -- "ファイル名"/"ディレクトリ名"
```
##ステージに追加した変更済ファイルを追加前に戻す
###最新のコミットでステージを上書きする
```
git reset HEAD <ファイル名>/<ディレクトリ名>
```
##直前のコミットをやり直す(直前のコミットを上書きする)
```
git commit --amend
```
##リモートの情報を表示する
```
git remote -v
git remote show
```
##gitのリモート名を変更
```
git remote rename origin origin2
```

#ブランチ操作
##全てのブランチを表示
```
git branch -a
```
##ブランチ作成
```
git branch "ブランチ名"
git checkout -b "ブランチ名"（作成＆移動）
```
# ブランチ削除
```
git branch -d "ブランチ名"（mainにマージされてない変更がある場合は削除されない）
git branch -D "ブランチ名" (強制削除)
```
##リモートブランチの削除

##今いるブランチのブランチ名変更
```
git branch -m "ブランチ名"
```
# merge
マージとは変更分を取り込むこと。
mainにfeatureを取り込むにはmainブランチに移動して`git　merge　feature` とする。

# マージの種類
|マージ方式|処理内容|
|:-|:-|
|fast-forward|ブランチが枝分かれしていない。先に進めるだけ|
|auto-merge|複数のブランチを統合。マージコミットが作成される。|
|conflict|同じ行に対して複数人が異なる変更を実施した。修正方法はToBEの状態に実際にファイルを編集する。|

コンフリクトを起きないようにするには


・複数人で同じファイルを編集しない
・PullやMergeの前に変更中の状態を無くしておく（commitやstashをしておく）
・Pullするときは、Pullするブランチに移動してから実行する

# 変更取込みはmergeとrebaseがある
`rebase`：ブランチのbase（親コミット）となるコミットを別のコミットにする
利点：履歴を一直線にできる

```
git rebase "ブランチ名"
```

##git rebese の一連の流れ

```
git checkout feature
git rebase main
git checkout main
git merge feature
```
# tag
##軽量版

```
git tag "タグ名"
```

## 注釈版

```
git tag -a "タグ名"
git tag -a "タグ名" -m "注釈"
```
GitLab CI/CDでGitLab Runnerのタグを正しく指定する方法

Shell Executorを指定したにも関わらず、なぜかパイプライン実行時にDockerイメージが利用されることがあります。

# 対処法
GitLab Runnerでは、Specific Runnerを利用するには、`.gitlab-ci.yml `において、そのRunnerを明示する必要があります。そのため、GitLab Runnerセットアップ時にタグをつけておいて、`.gitlab-ci.yml `でタグを指定する必要があります

## register時に初めからタグをつけておく

ですので、GitLab Runnerを初期化するときには初めから以下のようにすべきです。

```bash
sudo gitlab-runner register
```
の後にtokenなどを対話的に入力し、適当に`local-runner`でもなんでもいいのでタグをつけてください。

あとはGitLabのCI/CD Editorにて以下のようにタグを明示するだけ。

```yaml:.gitlab-ci.yml
some-kinda-job:
  tags:
    - local-runner

```

### Tips: タグを最速でリセットするにはunregisterするしかない
タグをregister後から変更する方法はググっても簡単に見つかりませんでした。
ですので、以下のようにRunnerを消して、後で再度セットアップしましょう。

```
sudo gitlab-runner unregister --url='XXX' --token='YYY'
```

なお、url, tokenはGitLabのSetting->Runnerのところから再度確認してください

# 参考文献
公式ドキュメントが最強です

https://docs.gitlab.com/runner/register/#linux
【初歩中の初歩】Rubyで掛け算をしてみよう★

今回はRubyを使って掛け算をしてみます。

問題：2つの正の整数a, bが改行区切りで入力されるのでaとbを掛け算した数値を出力してください。

解答

```ruby:解答コード
a = gets.to_i
b = gets.to_i

puts a*b
```

解説

```ruby:解説
a = gets.to_i
```

to._iでaの保存形式をinteger型にしています。
これによって、puts a*bで数値の計算が行われることになります。

解説

```ruby:解説
puts a*b
```

putsメソッドによって実際に出力を行います。
Rubyでは「*」が「×(かける)」の意味を持ちます。