OmniAICreator/Qiita-1.07M huggingface dataset:
swift講師を通じて学んだこと

#はじめに
筆者はメガベンチャー系の会社に務めていて、現在はアプリ開発を行っています.
現在のキャリアと繋がりからswift（iOS）の講師をする経験を今年やらせていただいたので、
その経験を記録する目的で書きます.

#本稿の内容
本稿では

- iOS初学者が躓くポイント紹介
- 講師の難しさ
- まとめ

で書いていきます.

#iOS初学者が躓くポイント紹介
1. init()がよくわからない
2. staticの使いどころがわからない
3. MainStoryBoardとViewControllerの関連性がわからない
4. frame/boundsの違い
5. シミュレータでキーボードが出てこない
6. optional（guard let）
7. enum
8. MVP（概念理解）
9. bundle installの関連エラー
10. API(HTTP)Client

この辺りに質問が集中していました.

初学者に教える際は、重点的に前置きで説明しておくと、良いかと思います.

#講師の難しさ
iOSに限らずですが、躓くポイントがどこか人によって違うのが講師の難しさでした.

1対多の場合、スピードを誰かに合わせると早かったり遅かったりするので、ある程度のカリキュラムを組んで、最初の2,3日の進捗を見て、徐々にチューニングしていく形になるのかなぁと思います.

個人的には、チームに入ってからSlackで #beginner-help チャンネルという何でも質問して良いチャンネルを活用して、良かったので、今回の講義で活用してみました.

そこで良いなと感じたのは、他の学習者同士でお互いの質問に回答しあって課題解決してる形でした.

イメージはStackOverFlowのような質問サイトを身内だけで行う感じです.

こうすることで、初学者が「こんな質問して良いのかな？」と感じるハードルを下げつつ、また質問に回答することで理解を深める、という両サイドでswiftの学習ができていた気がします.

教えることは、答えを与えることじゃないと僕は新卒の経験を気に学んだので、それ良い感じに活かせた経験でした.

#まとめ

今回は、swift講師を通じて学んだことを書かせてもらいました.

他の方のようにテックな内容ではなく、講師側の学び・経験を簡単に書かせてもらいました.

また同じような役割を行う際はより良い学習工程が組めればと思っています.

#その他
SNSは以下になります. 記事を読んで連絡してくださる方はDMしてください.

- Twitter: https://twitter.com/ko_watanabe_tw
- Facebook: https://www.facebook.com/ko.watanabe.fb/
- Instagram: https://www.instagram.com/ko_watanabe_ig

年の瀬ですが、お体にはお気をつけて！
【Android Studio】HUAWEI 端末で ログ出力がされない

# はじめに
Android アプリの開発をしている際にHUAWEI端末にて実機テストを行っていたところ Android Studio にログ出力がされなくてデバッグの際に困った。

ログ出力するためにはHUAWEI端末の設定を変更する必要があったので、そのとき行ったことを書きます。


# 実行環境
- Android Studio: 4.0.1
- 端末: HUAWEI P10 lite
- Androidバージョン: 7.0

# 端末設定を変更
HUAWEI端末で通話アプリを起動。ダイアル画面を開いて、謎の暗号めいた記号と番号``*#*#2846579#*#*``を入力します。
そして設定画面が開かれるので設定を変更するだけでOK。

1. 通話アプリで``*#*#2846579#*#*``を入力|
---|
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621162/fb7dd9bb-c143-c222-9c1e-e2e1326de0b2.png" width="320">|

2. ``1. Background Settings`` を選択|
---|
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621162/688d20c1-956d-2708-3c7b-2f513c448a39.png" width="320">|

3. ``LOG Settings`` を選択|
---|
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621162/2b47f7e5-d88e-0ccd-e80b-8530dbf2d007.png" width="320">|

4. ``AP Log`` にチェック|
---|
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621162/e19da768-1b8e-5c91-b7eb-23ac21287841.png" width="320">|

5. ``CLOSE`` すればOK|
---|
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621162/085a8051-f467-27cf-7061-3f0b6177ea3e.png" width="320">|


これで再度実行すれば、ログが出力されるはず！

# 参考サイト
[Stachoverflow](https://stackoverflow.com/questions/18124334/huawei-logcat-not-showing-the-log-for-my-app)
[初心者向け] コードでNavigationBarを実装する

# はじめに
`Storyboard`を使わずにアプリを作るために、色々と調べていたわけですが、ナビゲーションバーについてはネットに転がっているコードをコピペしても動きませんでした。

自分と同じような状況に陥っている方の助けになれば良いと思い、解決策を置いておこうと思います。

 ※この解決策で良くないよーってところがあれば指摘していただければと思います。

## 環境
- Xcode version 12.2
- Swift 5.3.1

## StoryBoardを使わずにナビゲーションバーを実装する
まず、`SceneDelegate.swift` にコードを追加します。

``` SceneDelegate.swift
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
//      初期設定では _ なので scene に書き換えます
        guard let scene = (scene as? UIWindowScene) else { return }
//      firstViewControllerは最初に表示される画面です(rootViewController)
        let firstViewController = ViewController()
        let navigationController = UINavigationController(rootViewController: firstViewController)
      
        window = UIWindow(windowScene: scene)
        window?.rootViewController = navigationController
        window?.makeKeyAndVisible()
    }
```

``window``はiOS13のアップデートで`AppDelegate`から`SceneDelegate`に移動してまして、検索しても`AppDelegate`にコードを追加している情報がほとんどです。
「今までは`AppDelegate`で実装していたが、今は`SceneDelegate`に記述する必要がある」という風に考えていただければ良いと思います。

次に、ナビゲーションバーを実装するコードを書いていきます。

``` ViewController.swift
class ViewController: UIViewController {
    
    var button: UIBarButtonItem!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = .white
        title = "First"
        button = UIBarButtonItem(barButtonSystemItem: .fastForward, target: self, action: #selector(click))
        navigationItem.rightBarButtonItem = button
    }
    
    @objc func click() {
        let second = SecondViewController()
        navigationController?.pushViewController(second, animated: true)
    }
    
}
```
```SecondViewController.swift
class SecondViewController: UIViewController {

    var button: UIBarButtonItem!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        title = "Second"
        view.backgroundColor = .systemTeal
        
        button = UIBarButtonItem(barButtonSystemItem: .fastForward, target: self, action: #selector(click))
        navigationItem.rightBarButtonItem = button
    }
    
    @objc func click() {
        let third = ThirdViewController()
        navigationController?.pushViewController(third, animated: true)
    }

}

```

```ThirdViewController.swift
class ThirdViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        title = "Third"
        view.backgroundColor = .purple
    }
}
```
動いてる感を出すために遷移の動作を2回入れてみました。
ちなみに、この記事はナビゲーションバーを実装することが目的なので、`UIWindow`や`@objc`については解説はしません。

**実際に動かしてみるとこんな感じです**

<img width="40%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/774264/d5de4fc6-cb35-a025-18c5-3806ec52dbe8.png">

<img width="40%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/774264/194c5d57-e9f3-95c6-dc75-41ce0ae92fa1.png">

<img width="40%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/774264/761896be-2243-58e4-4629-6e542ce57d2e.png">
Unity開発におけるView構造規約の紹介

「[Applibot Advent Calendar 2020](https://qiita.com/advent-calendar/2020/applibot)」 14日目の記事になります。
前日は@16choさんの[BLEで始める心臓の死活監視](https://qiita.com/16cho/items/e2d4b766241379061459)という記事でした!

# はじめに
- UnityのGameObjectの仕様
- デザインや演出の問題

などのため、スッキリしたViewの構造/クラスを作る事はなかなか難しい事だと感じています。
そこで、UnityでアウトゲームなどのViewを組む際、チーム内で定めた規約をご紹介します。

(View構造と書いていますが、広くMonoBehaviour継承クラスが他のgameObjectとの関係性をどう持つか、というテーマになります。)

# 狙い
ヒエラルキーに配置されたGameObjectは様々な箇所からアクセスする手段があり、global変数のようなものです。
GameObject.Find()などで、どういった構造であっても参照を取得する事が出来てしまいます。
今回ご紹介する規約は、何らかのGameObjectにアクセスできる経路を出来るだけ少なく絞り込む構造とし、メンテナンス性を高める事が狙いです。

### 説明に使うサンプルについて

```cs
public class Qiita : MonoBehaviour
{
    // 自分以外のgameObject
    [SerializeField] private GameObject _go;

    public void PlayXxx()
    {
        _go.xxx();
    }
}
```
こういったプログラムで自分以外のgameObject(ここでは_go)を管理している、MonoBehaviour継承クラスに関する決め事になります。
ImageやTextのような自身だけを処理する物は含みません。

# ① inspecterで参照を持ったり、GetComponentで参照を取得できるのは、自身の子供要素に対してのみ
![スクリーンショット 2020-12-11 18.21.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927410/7e93f386-706b-891e-f522-20e6f0cc2a02.png)
こういった構造があるとします。

**OKな例**

- AがA_1の参照を持つ
- A_1がXを参照に持つ

**NGな例**

- XがB_2の参照を持つ
- B_1がBを参照に持つ

親要素・兄弟要素へのアクセスを禁止し、子供要素へのアクセスのみ許可しています。
これにより依存関係を分かりやすくします。また「再利用のためにprefab化したい」となった時に、子要素以外に参照があるとprefab化するのが困難になるためです。


# ② 管理しているコンポーネントを飛び越して参照しない
![スクリーンショット 2020-12-11 18.21.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927410/bb193a4a-b23d-1630-ef03-3324798c7a70.png)
**NG**

- Aが、A_1 を挟まずにXの参照を取得するのはNG

```cs
public class A : MonoBehaviour
{
    public void Awake()
    {
        var x = transform.Find("A_1/X");
    }
}
```

- A_1がXを公開し、A-1.X の用にアクセスするのはNG

```cs
public class A_1 : MonoBehaviour
{
    [SerializeField] private GameObject _x;

    // 自分の子要素を公開
    public GameObject X
    {
        get { return _x; }
    }
}

public class A : MonoBehaviour
{
    [SerializeField] private A_１ _a_1;

    public GameObject Awake()
    {
        _a_1.X.SetActive(false);
    }
}
```

Xにアクセスできる存在を絞るための規約です。親の管理Componentだけが参照できる事とします。

# ①・②を踏まえて演出を考慮した構造を作ってみる
最後は規約というより、①と②を守りながら演出を考慮した際の構造を考えてみます。
アニメーション等の演出のため、各Viewパーツをプログラム制御する場面を考えます。
![スクリーンショット 2020-12-11 18.44.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927410/068c925c-370e-a844-eaff-f4c6cbf3323e.png)
パーツが色々な箇所に散らばっていると制御が困難になるため、共通の親を用意します。
例えばA_1とA_2が同時に動いたり、相互に影響しあうアニメーション演出が考えられる際、A_1とA_2の参照を持つ親のAnimationRootを作り、子要素達の動きを制御します。

![スクリーンショット 2020-12-11 19.08.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927410/11f4eece-1ba9-209a-63ca-f9ef54086f98.png)
更にAnimationRootAとAnimationRootBが関連するアニメーションを作るには、AとBの参照を持つ親Rootコンポーネントを用意し、子要素のComponentへ指令を出してタイミング等を制御します。


# 最後に
規約により、分かりやすさ・メンテナンス性は上がりますが、記述は冗長になり面倒が増える側面もあります。
より良い構造設計があれば是非教えて下さい！

また、皆さんのチームのView設計規約があれば、合わせて紹介いただけると幸いです。

「[Applibot Advent Calendar 2020](https://qiita.com/advent-calendar/2020/applibot)」 14日目の記事でした。
明日は @lokiunybg さんです。
急に難しくなったJavascript

そう言えば皆さん気が付きましたか。
昔一番簡単だったのがJavascriptでした。
残念ながら一番言語体系がぐちゃぐちゃになったのはJavascriptになってしまいました。
 [JavaScript Advent Calendar 2020](https://qiita.com/advent-calendar/2020/javascript "JavaScript Advent Calendar 2020")13日目です。
#昔はクラスとかオブジェクト指向型言語ではなかった
そうなんですよね。
昔は本当に静的言語で使いやすかったです。
一番はやったのはなぜかというとみんなが一番触りやすく一番手に馴染む言語だったからです。
無茶ができたのも一番の特徴です。

```Javascript
Console.log('Hallow world');
````
こんな形で書けました。
#なぜここまで難しくしなければいけなかったのか
正直言うとHTMLの進化とも言えましょう。
動的に作れなければいけないという現状が出てきます。
そこで考え出されたのがJavascriptの動的言語化。
クラスやアロー関数を使えるようにしようとする動きが出てきました。
Javascriptはシンプルなクラス構成を狙っていたんでですが。
いろんな派生言語を生む結果になったのです。
#なぜECMAを忌み嫌うのか
正直言うとECMAの登場でガラリと変わったのは現実です。
だがめんどくさいことが発生してしまいました。
クラスの書き方はJavascriptと違う。
フレームワークの組み込み方まで全て変えてしまいました。
そこで生まれたのはBabelというトランスパイラーです。
トランスパイラーはECMAをJavascriptに書き換えると言った動きをやってました。
この部分を早くする前にECMAが変わってしまったりというイタチごっこでした。
#TypeScriptの登場
ECMAが難しい。
ならどうすればいいのか。
Javascriptを進化させるしかないということになります。
それを担ったのがTypescriptとなりました。
TypescriptがECMAとの差を埋めることができたかというと少しどころかECMAが減っていったことになります。
ですがTypeScriptでJavascriptに書き直す作業は出てきますが。
ECMAよりは軽微なもので済みました。
正直言うとECMAの難しさよりTypeScript容易さを選ぶということになりましたが。
とっつきづらい言語Javascriptの脱却はできませんでした。
それはどちらにしてもJavascriptへのTypeScriptからのトランスパイルが必要なので結局babelの世話になると言うことになります。
それはクラスの書き方とアロー関数の書き方を容易化する試みが複雑さを生んでしまっていたのです。
#これからJavascriptはどうあるべきなのか
Javascriptは簡単な言語に戻るべきだと自分は思います。
クラスの書き方の統一とアロー関数の使い方の統一ということが必要だと思います。
各派生言語ごとに書き方が変わるのは痛いです。
正直jQuery・React並に簡単にかける言語を狙えばもっと楽だったかもしれません。
正直一度オブジェクト指向化を失敗するのは自分なりのやり方を多くすればみんながついてきてくれるわけじゃないんです。
一番悩まされたのはクラス・アロー関数・フレームワークの組み合わせがもっと簡単になればもっと人口は増えるはずです。
自分はJavascriptもPHP・C#と同じくらい使っています。
もっと簡単なオブジェクト指向言語になるべきだと思います。

今日なここまでにします。

明日は[saka212](https://qiita.com/saka212 "saka212")さんです。
期待しています。
Nextcloud の Google Authenticator 認証ができなくなったときの救済方法(その2)

[先日の記事](https://qiita.com/S_Katz/items/6af09cf7a2fdfdc0db58)で、2要素認証ができなくなったユーザーへの対応方法として、代理ログイン機能を利用した方法を記事にしましたが、この方法だと、認証行為なしでこのユーザーの操作権限を管理者に渡すことになるため、これをよしとしないケースもあると思います。
今回は、別の方法でこのユーザーの救済を行う方法をまとめました。

# 対応手順をざっくりまとめ
1. [Two-Factor Admin Support](https://apps.nextcloud.com/apps/twofactor_admin) アプリを利用して管理者が申告ユーザーのワンタイムパスワードを作成、申告ユーザーに通知。
2. 申告ユーザーはこのワンタイムパスワードを利用してログイン。

# もう少し詳しく
## ①システム管理者の操作
1. 2要素認証できなくなった時のワンタイムパスワードを生成するための[Two-Factor Admin Support](https://apps.nextcloud.com/apps/twofactor_admin)をインストール、有効化。
2. 管理者権限をもつユーザー (="admin" グループに属しているユーザー ) で Nextcloud にログイン。
3. 設定画面で管理メニューの「セキュリティ」をクリック。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/bf0b177e-99b1-43ed-6988-ff1abbad511e.png)
4. 「Two-Factor Admin」の「User ID」に申告ユーザーのユーザー名を入力して「Generate」ボタンをクリック。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/b024244c-8931-49f0-357f-9f8fba05e99f.png)
5. "The generated code is 【ワンタイムパスワード】." で表示されるワンタイムパスワードを確認し、これを申告ユーザーに通知。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/580de3d7-6f9a-1e15-0e78-97f17ae383fc.png)

## ②申告ユーザーの操作
1. ログイン。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/4886fb29-4ee0-20ee-092e-f45e4b4d238b.png)
2. "Admin code" をクリック。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/37e85eb0-a61e-9e1f-b5f6-b1063155b930.png)
3. "Authentication Code" の入力欄に システム管理者から通知されたワンタイムパスワードを入力し "Submit" をクリック。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/85d296ed-aeef-8a90-7acc-cb829efb706b.png)

# 補足
この手順は、[Nextcloud 唯一の管理者アカウントが2要素認証でログインできなくなったときの対処方法](https://qiita.com/S_Katz/items/e57b32e9807aeff581a5) で記事にした手順のうち、ワンタイムパスワードを Nextcloud 画面で発行できる手順となります。
[Laravel]RFC違反のメールアドレスにメールを送る

## はじめに
仕事でLarvel5.2から6に移行するプロジェクトを進めていた際、
Larave5.2では送信できていたメールアドレスに対して、RFC違反のため送信できなくなった問題が発生しました。
そこで、RFC違反のメールアドレスにも送信できる対応を行いました。
参考記事: [Laravel RFC違反のメールアドレスにメール送信できるようにする](https://qiita.com/ucan-lab/items/e86eb725facd38467a60)

## 環境
PHP7.4
Laravel6

## エラー内容
以下のエラーが発生しました。

```json
Address in mailbox given [RFC違反のメールアドレス] does not comply with RFC 2822, 3.6.2.
```

## 対応
SwiftMailerのバリデーションEmailValidatorを継承しisValid()をオーバーライドします。
以下のコードでは、ピリオドが2つ以上連続で使用されたメールアドレスを許容するようにしています。

```PHP
use Egulias\EmailValidator\EmailValidator;
use Egulias\EmailValidator\Exception\DotAtEnd;
use Egulias\EmailValidator\Exception\ConsecutiveDot;
use Egulias\EmailValidator\Validation\EmailValidation;

class NewValidator extends EmailValidator
{
    /**
     *
     * @param string $email
     * @param EmailValidation $emailValidation
     * @return bool
     */
    public function isValid($email, EmailValidation $emailValidation): bool
    {
        if (!parent::isValid($email, $emailValidation)) {
            switch ($this->getError()->getMessage()) {
                case ConsecutiveDot::REASON:
                    return true;
                default:
                    return false;
            }
        }
        return true;
    }
}

```

RFC違反と判断される原因は複数あり、その原因によってコードナンバーと理由が定義されています。
`$this->getError()->getMessage()`の結果と許容する理由`ConsecutiveDot::REASON`が一致する場合に`true`を返すようにしています。

他にも以下を含めた原因が20種以上ありますので、条件に合うものを選んでいただけたらと思います。
@の直前にピリオドが使われている→`DotAtEnd::REASON`
メールアドレスがピリオドで始まっている→`DotAtStart::REASON`
ドメイン内にカンマが使われている→`CommaInDomain::REASON`

## 参考
[Laravel RFC違反のメールアドレスにメール送信できるようにする](https://qiita.com/ucan-lab/items/e86eb725facd38467a60)
Unityで「おきあがりこぼし」を作ってみる

[PONOS Advent Calendar 2020](https://qiita.com/advent-calendar/2020/ponos)の14日目の記事です。
昨日は@nissy_gpさんの「オーストラリアのサマータイムからtz databaseを読み解く」でした。

###はじめに
今日はUnityで「おきあがりこぼし」を作ったお話をさせていただきます。
![daruma5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538709/18ae0360-70c1-c0fa-41a2-582e2acfd3da.png)
おきあがりこぼしとは、倒そうとしても倒れない人形のことです。

ストレス解消の「パンチングバルーン」と呼ばれるものも仲間ですね。
我が家にもアンパンマンの玩具があったなぁと探してみたのですが、流石にもう捨ててしまったたようです。

ちなみに英語で「Roly-poly toy」だそうで、韻を踏んでていい感じ。

###作ってみる
不意にそのおきあがりこぼしを作ってみたくなりました。
リアルに工作してもいいのですが...今回はUnityの画面上で表現してみます。
頭に描いたイメージを気軽に形にできちゃうってのはUnity最大の魅力ですよね！

###Prefabの構造
既に完成形ですが、RolyPolyToyと名付けたPrefabです。
![スクリーンショット 2020-12-14 9.58.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538709/5f78700c-fae6-f110-a10c-6685c607a514.png)
親の「RolyPolyToy」という空オブジェクトの子要素に「Body」、孫要素に「Weight」を配置します。
![スクリーンショット 2020-12-13 15.12.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538709/dca567ae-010f-b959-2959-9176b7424732.png)
※Unity標準の3D Objectですが、構造が把握しやすいよう半透明にしています。下部の黒い球体が重りです。

###Inspectorの設定
それぞれの設定は以下の通りです。

RolyPolyToy　・・・　Transformだけの空オブジェクトです。初期位置を浮かせています。
![スクリーンショット 2020-12-13 15.18.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538709/51aaa3f6-44e6-2413-df4f-29e8cce6702b.png)

Body　・・・　本体になります。CapsuleにRigidbodyを追加しています。
![スクリーンショット 2020-12-13 15.31.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538709/4951504d-644a-44cb-c6df-a2d2f6e9929f.png)

Weight　・・・　重りになります。SphereにRigidbodyとFixedJointを追加しています。
![スクリーンショット 2020-12-14 9.58.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538709/f62b8382-03b3-619a-78d3-e9fb96f3e018.png)


ポイントは、以下の2点。
**1.WeightのRegidbody.MathをBodyより明らかに大きな値にする**
**2.WeightにFixedJointコンポーネントを追加し、Bodyとジョイントする**

UnityのJointクラスの中にあるFixedJointを使いましたが、Rigidbodyを持つオブジェクト同士を繋ぐことができます。ジョイントしないと、Rigidbodyを持ったオブジェクトはそれぞれバラバラになります。
https://docs.unity3d.com/ja/current/ScriptReference/Joint.html
(他にもバネのように伸び縮みするSpringJointや、関節のようなHingeJointなどがあります。)

あと、カプセル形状の場合は、重りの中心点をなるべく外側に配置することも重要です。下図でいうとマゼンタの線より内側に配置した場合は横に倒れたまま起き上がりませんが、この挙動は現実の事象と同じですね。
![スクリーンショット 2020-12-13 16.34.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538709/f012f515-5b17-88c6-9dd5-88e993d62c19.png)

重りを視覚化していましたが、WeightのMeshRendererとSphereColliderは不要なのでOFFにしましょう。
![スクリーンショット 2020-12-14 9.56.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538709/90b873b1-d36f-9f32-9853-1b2bf75fb1dc.png)

###完成形
![スクリーンショット 2020-12-13 16.45.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538709/bfd669de-4e4d-3d3a-3169-d2b8cdd95d38.png)
パンチングバルーン的な物体が揺れながら立ち上がります。
動画でお見せできないのが残念ですが、イメージ通りのものができました！

他にも実現する方法はあるでしょうけど、UnityのPhysicsを使ったお手軽な方法として紹介しました。

以上

明日は@loveRiceさんです。
【AWS】Capistranoを用いた自動デプロイの注意点

# 概要
- 発生した問題のエラーログ
- デプロイ前にunicornを停止する
- EC2インスタン再起動の際にはWEBサーバーを再起動する

# 発生した問題のエラーログ
- TOPページ意外のページへ遷移するとエラーが発生
    - N+1問題修正のためにコントローラーを修正した後に発生
    - DB関連には問題なさそう・・・

```production.log
[log]$ tail -f production.log 
DEBUG -- :    (0.1ms)  SELECT GET_LOCK('303837913129081065', 0)
DEBUG -- :    (19.0ms)  SELECT `schema_migrations`.`version` FROM `schema_migrations` ORDER BY `schema_migrations`.`version` ASC
DEBUG -- :   ActiveRecord::InternalMetadata Load (1.5ms)  SELECT `ar_internal_metadata`.* FROM `ar_internal_metadata` WHERE `ar_internal_metadata`.`key` = 'environment' LIMIT 1
DEBUG -- :    (0.1ms)  SELECT RELEASE_LOCK('303837913129081065')
DEBUG -- :    (14.4ms)  SET NAMES utf8,  @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'),  @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
DEBUG -- :    (0.1ms)  SET NAMES utf8,  @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'),  @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
DEBUG -- :    (0.1ms)  SELECT GET_LOCK('303837913129081065', 0)
DEBUG -- :    (1.4ms)  SELECT `schema_migrations`.`version` FROM `schema_migrations` ORDER BY `schema_migrations`.`version` ASC
DEBUG -- :   ActiveRecord::InternalMetadata Load (0.7ms)  SELECT `ar_internal_metadata`.* FROM `ar_internal_metadata` WHERE `ar_internal_metadata`.`key` = 'environment' LIMIT 1
DEBUG -- :    (0.1ms)  SELECT RELEASE_LOCK('303837913129081065')
```

# 解決方法
- appサーバーを停止させてからデプロイ

```
$ ps aux | grep unicorn
$ kill [process number]
```

# 備考
- EC2インスタンス再起動の際にはWEBサーバーの再起動が必要

```
$ sudo systemctl restart mariadb 
$ sudo systemctl restart nginx
```

以上
【Macユーザー】コーダー からフロントエンドになるまでに使ったツール　~コーダー 編~

## 筆者について
実績も何もない所から、知り合いのツテで下請けという形で働いていました。全て在宅のため、自分でツールを揃える必要があり、話を聞いたり自分で調べながら揃えたツールです。

## コーダー時代
###環境構築
・Local: WordPressのローカル環境構築。とにかくセットアップが早い。スムーズに行けば10分以内で終わる。
###デザイン
・Photoshop
・AdobeXD
ツールの使い方を覚えました。書き出しはよく使います。
###IDE
・VSCode:駆け出しの頃Atom使ってましたが速攻変えた方がいいって言われました。おかげで結構恩恵ありました。

###Chrome拡張機能
・UI Build Assistant: YouTubeで有名なしまぶーさんの作ったツールです。border,padding,marginの概念がよく分からなかった頃に勉強になりました。

・What Font:使っているフォント、テキストサイズがすぐに分かります。

・Fire Shot:サイト全体のキャプチャをしたい時にすぐに撮れます。

###WordPressプラグイン
・All in One Migration:バックアップ出来て、サイト移行も出来て最強ツール。
・All in One SEO: メタ設定とか簡単に
・ContactForm7: メールフォームはとりあえずはこれ。

### コミュニケーション
・Slack
・ChatWork
・Zoom
取引先相手によって違うので、最初から両方使えた方が良い。

###インフラ
・Xserver:安定している。WordPressのセットアップが早い。ドメイン無料でついてくるキャンペーンをやってたりする。
###FTP・SFTP
・FileZilla: サーバーとのファイル通信に

###最後に
いかがでしたでしょうか。コーダーとしての歴はそれほど長くないので、ざっくりですが参考になれば幸いです。
Googleで英語の検索結果を表示するブックマークレット

ブックマークに登録し、Googleの検索結果画面でクリックしてください。
URL の hl パラメータを en に設定すると英語の結果が表示されるようです。

```js:Googleで英語の検索結果を表示
javascript:location.href+="&hl=en"
```
アルゴリズム力UP!『ARC 029 A 高橋君とお肉 』を解いてみよう

# 記事を読むとわかること
- 記事の作者の『ARC 029 A 高橋君とお肉』の解法がわかる
- 記事の作者のアルゴリズム問題全般へのアプローチがわかる

# 今回の問題 

**ARC 029 A 高橋君とお肉**　→ [問題文はこちら](https://atcoder.jp/contests/arc029/tasks/arc029_1)

# 記事の作者の回答のコード
```python

from typing import List
  
def solve_takahashi_and_meat(meat_time_list: List[int]) -> int:

  # ==============================================================
  # return: 焼き時間の違う複数のお肉のリストが入力されると、２枚のグリルで焼く最小時間を返す
  # pre: [4, 6, 7, 10] 
  # post:　14 → aのグリルに[4, 10] bのグリルに[6, 7] で焼く。
  # ==============================================================

  # ★ step1 お肉の焼き時間の配列を降順に並び替える
  # ★ step2 焼き時間が大きい順からfor文で回し、２枚のグリルで焼き時間が小さい方にお肉を追加させる
  # ★ step3 最終的にa, bで焼き時間が大きい方を返す


  # 10, 7, 6,1 と降順で配列に格納する
  sorted_meat_time_li = sorted(meat_time_list, reverse = 1)

  #2枚のグリル初期値の設定をする
  gril_a = [0]
  gril_b = [0]

  #焼き時間が大きい順から回す
  for meat_time in sorted_meat_time_li:
    #現時点での総焼き時間を比較し小さい方にお肉を追加
    if sum(gril_a) >= sum(gril_b) :
      gril_b.append(meat_time)
    else :
      gril_a.append(meat_time)
  #aとbで総焼き時間が大きい方を返す
  return max(sum(gril_a), sum(gril_b))


N = int(input())
meat_time_list = [int(input()) for _ in range(N)]
print(solve_takahashi_and_meat(meat_time_list))

```

# 回答の解説

## 記事の作者が思う今回のアルゴリズム問題の回答ポイント

- 焼き時間が大きい順に並び替え、調理が厄介なお肉からグリルで焼くようにする
- グリルaとグリルbで、お肉を追加する毎で総焼き時間をその都度比較し、小さい方にお肉を追加する
- グリルaとグリルbで総焼き時間が大きい方を返す

今回の回答の発想として、「調理が厄介なお肉からグリルで焼く」扱いにくいものから処理させる方針を考えた。イメージ、何か料理をする際に野菜から炒めずお肉や魚などから焼いていくような発想(笑?)。

#このコードの課題感

- 今回は再現性が難しいため、全文検索で解くのが無難だし力がつきそう。([4,6,7,10]という4つのお肉でも2^4通りなので)
SSL証明書のOV証明書(ファイル認証)についてのまとめ

##～最初に～
・今回行ったのはwebの証明書
・webサーバ(apache)は稼働しているものでopensslはインストール済み

なので１～１０まで書いていくことにする

##まず証明書とはざっくり##
クライアントとサーバ間の通信を暗号化する
証明書のランクによって発行する認証局が証明してくれるものが変わってくる

今回のOV証明書の例だと
企業が実在するかどうかを証明してくれるものになる
これがあると企業に成りすましたサイトかどうかを見分けることができる

##大雑把に作業内容をば
・秘密鍵を作成する
・CSRを作成する
・CSRを認証局に提出する
・認証局からアクティベート申請を求められる(CSRでは埋めきれない企業情報)
・認証局からの電話に対応する
・認証局からファイル証明書用のファイルをメールで渡される
・サーバ側で指定された場所に設置する
・認証局がそのファイルを確認する
・認証局が証明書ファイルの内容を送ってくる
・サーバ側で指定された位置に秘密鍵と証明書を設置する
終わり
全体通してやった感想としては勉強になる~~結構長くてだるいな~~と思った

##実際の作業手順
秘密鍵の作成(2048ビット長)

```
root#openssl genrsa -out server.key 2048 
```
CSRの作成(聞かれたことに淡々と答えていく)

```
root#openssl req -new -key server.key -out server.csr
```
***CSRの提出***
***認証局からアクティベート申請を求められる(CSRでは埋めきれない企業情報)***
***認証局からの電話に対応する***
***認証局からファイル認証用のファイルをメールで渡される***
***所定の位置にファイル認証用のファイルを設置する(必要に応じてディレクトリとパーミッションを調整する)***
※この際に認証用のファイルをBOM形式にしておく

bomファイルかどうかの確認

```
root#file 認証用ファイル
```
bomファイルに書き換え(UTF-8)

```
root#nkf --overwrite --oc=UTF-8-BOM 認証用ファイル
```
※centos7では標準リポジトリではnkfが入ってないからepel-releseリポジトリをインストールする必要があるのでインストールしておく
***送られてきた証明書を設置する前にsslのconfigをいじる必要がありそうならバックアップをとる***

届いた証明書と秘密鍵のペアがあってるか検証する


```
証明書のチェックサムの検証
root#openssl x509 -noout -modulus -in server.crt | openssl md5
秘密鍵のチェックサムの検証
root#openssl rsa -noout -modulus in server.key | openssl md5
各々で出力された値が同じならペアという検証が完了する
```

(ちなみにどのように検証しているかというと秘密鍵と証明書に含まれている公開鍵の部品みたいなものをmd5形式でハッシュ化して比べている)

***ペアという確認が取れたらファイルを設置する***
この際にファイルを設置するまたは書き換える前にconfigファイルのバックアップファイルを作成しておく

***念のため構文チェックを行う***

```
httpd -t
構文に問題がなければ下記が出力される
Syntax OK
```

***サーバーを再起動させる***

```
systemctl restart httpd
```

対象サーバのページを見て証明書が更新されていればOK
自前EDR その8

#概要

vistaにedrを構築する。
時系列で取得なsysmonを入れた。
sysmonのlogから、シーケンス図を作ってみた。

#環境

windows vista 32bit

#写真

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/577dc2e4-6dda-69a1-1072-4d0503388ac3.jpeg)


#成果物

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


以上。
Reactで表現するUIモーションデザイン【モーションスタイリング】

以下記事の続きとなります。

> [Reactで表現するUIモーションデザイン【デュレーション & イージング】](https://qiita.com/stranger1989/items/f18e4b85d9b0b6a5ef01)

前回の記事でモーションの速度・変動率を調整するデュレーションとイージングについて学びました。
今回は引き続き`react-spring`を使用しながら、CSSのスタイリングを動的に変更することでどのようなモーション表現ができるか検証を行っていきます。

## <font color="LightSeaGreen">モーションスタイリング手法</font>

ここで紹介しているのは基本的な動きですが、組み合わせで複雑なモーションを実現することもできます。
また、ここでは機械的で無機質な動きになっていますが、自然界に存在する動き・質感・配色を意識することでより人間的で親和性の高いUIを提供できるようになります。
これについてはまた別記事でまとめようと思います。

※ codesandboxにて実際のコードを確認できます。

### 移動 （move）

https://codesandbox.io/s/move-fjs2z
![MBNrF7ZmJG1T73qgOOlY1607817861-1607818111.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498345/24dfe3c0-42b7-a26a-3186-e07c8ce8e141.gif)


### 変形 （scale）

https://codesandbox.io/s/scale-jo5xk
![wD111Jw56XW29iXgrtfC1607818349-1607818443.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498345/69c977f5-9df4-a2a1-eac2-484dbeb8368c.gif)


### 回転 (rotate)

https://codesandbox.io/s/rotate-xqlo5?file=/src/App.tsx
![rkJReNB0pKyMBMfb1HET1607818733-1607818814.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498345/7b14fb33-b9d6-033a-f91c-304882de21ab.gif)


### 透過 (fade)

https://codesandbox.io/s/fade-7shbj
![ruUoDqDE5Ud8EsG9jlqJ1607819148-1607819221.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498345/94925209-b29f-ebe3-907c-73a898163f28.gif)


### 浮遊 (shadow)

https://codesandbox.io/s/shadow-8c3po
![yV6leOLcHiuWwP1vrQRz1607819465-1607819557.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498345/53d031c0-ecf2-98a7-83f5-e778b2bd8804.gif)


### 色調 (color)

https://codesandbox.io/s/color-hn2hn
![F4TgbUctFv8vqde8Xfuz1607819802-1607819891.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498345/e604bd11-2169-dedb-005e-dde1dc96e0d5.gif)


### パス トラッキング （path-tracking）

https://codesandbox.io/s/path-tracking-m7xwr
![z0J7RBNP4GBtitmVk7yy1607820059-1607820110.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498345/c3fc05ef-30f5-8849-2301-a54493e69e97.gif)



### 文字 （text）

https://codesandbox.io/s/count-cc363
![f5afa63421811099c2e89a2f5ca8c847.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498345/edd9caf4-f89e-bedf-bac8-08a1df242033.gif)

## <font color="LightSeaGreen">スタイリング複数 + デュレーション・イージングと組み合わせる</font>

一例を実装してみました。

### 変形 + 回転 + friction

https://codesandbox.io/s/check-scale-f92qg
![vrOk3gInwmfK0IP5DgVT1607825682-1607825802.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498345/28e0e07f-ee13-38c4-c480-49d3a2b86681.gif)

### 浮遊 + パストラッキング + easeExpInOut

https://codesandbox.io/s/shadow-track-zgk61?file=/src/App.tsx
![Ng9WP7Tx5GnAuAiWatlB1607838341-1607838491.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498345/42a34515-c928-8d72-6b13-ea4f018629ea.gif)

### 移動 + 色調 + easeQuadInOut

https://codesandbox.io/s/light-on-olkbo
![ydOyH31itEJhfC1fqF931607842241-1607842312.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498345/65a41f54-6e1a-0a1e-c60c-c76e31b8b4dc.gif)


この他にも、組み合わせ次第で様々なモーションを組み立てることができます。
GsonでStackOverFlowErrorがでて困った話

Gsonを使ってAjax通信をしようとしたら、stackOverFlowErrorがでて数時間溶けてしまったので、備忘録として残しておきます。
コードの状態は以下のようでした

```javascript
        $('#login').on('click', () => {
          let jsonString = {
            'userName': $('#userName').val(),
            'password': $('#password').val()
          };
          $.ajax({
            type: 'POST',
            url: '/tutorial/auth/login',
            data: JSON.stringify(jsonString),
            contentType: 'application/json',
            dataType: 'json'
          }).done(function (data) {
              // なんかの処理
            }
          }).fail(function (data) {
　　　　　　　　// なんかの処理
             }
          }).always(function (data) {
　　　　　　　　// なんかの処理
             }
          });
        });

```

```java
  public String login(@RequestBody UserForm form) { 
    // ログインフォームに入力されたユーザ名とパスワードに一致するユーザを取得してフロントに返す
    User user = userService.findUser(form.getUserName(), form.getPassword()); 
    return gson.toJson(user);
  }
```

```java
@Entity
@Table(name = "mst_user")
@Getter @Setter
public class User implements Serializable {
  private static final long serialVersionUID = 4867739830142183022L;

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "id")
  private int id;

  @Column(name = "user_name")
  private String userName;

  @Column(name = "password")
  private String password;

  @Column(name = "mail_address")
  private String mailAdress;

  // 説明に不要なフィールドは省略

  @OneToOne(cascade = CascadeType.ALL)
  @JoinColumn(name = "id")
  private Destination destination;
 
  // おそらくこいつが原因
  @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
  private List<PurchaseHistory> purchaseHistoryList;

}
```
これで行ったところ、stackOverFlowErrorが出ました。調べたところ、原因はと言うと、Entityに双方向性の関係を持ったフィールドがあるためのようでした。
[こちらのページ質問の回答](https://stackoverflow.com/questions/43410654/gson-tojson-throws-stackoverflowerror-in-servlet/43410950#43410950)によると、何やら、バックエンドからフロントエンドにオブジェクトを送る際には、gsonがそのオブジェクトをシリアライズ化？(データを受けて私するために形を変えること?)するらしく、双方向性の関係のフィールだとそれが無限に続いてしまうようです。そのため、stackOverFlowErrorが起きたのだそう。
この問題を解消するには、以下のようにすればいいみたい

```java
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "id")
  @Expose // フロントに送りたいデータだけに@Exposeをつける
  private int id;

  @Column(name = "user_name")
  @Expose
  private String userName;

  @Column(name = "password")
  @Expose
  private String password;

  @Column(name = "mail_address")
  private String mailAdress;

```

```java
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(); 
```

こんな感じで必要なところにだけ@Exposeをつけて、コントローラでのGsonのインスタンス化のやり方はこんな感じにすればいいみたい。
UITextView が表示されないとき (Swift, Xcode)


メモです。

# UITextView が表示されないとき (Swift, Xcode)

### 問題

Xcode の Storyboard で UITextView を追加したのですが、Simulator では表示されませんでした。

### 解決法

Storyboard で UITextView の constraints に height を追加した。 

### 参考

https://stackoverflow.com/questions/37632829/uitextview-not-visible-on-screen
ぼっち演算子 (&.)

現場で使える Ruby on rails 5 速習実践ガイドの参考書で学んだぼっち演算子(&.)を勉強の記録用として記事にしてみました。

#ぼっち演算子 (&.) とは
<span>&.</span>という演算子を使ってメソッドを呼び出すと、レシーバーがnilであった場合でもエラーが発生しなくなります。

```ruby
class User
  def name
    '名前'
  end
end
```

```ruby
> user = User.new
> user.name
=> '名前'


#①
> object = nil
> object&.name
=> nil

#②
> object.name
Traceback (most recent call last):
...
NoMethodError (undefined method `name' for nil:NilClass)
```

②ではぼっち演算子を使わず、レシーバーであるオブジェクトがnilの場合はエラーになります。
①ではぼっち演算子を使うことでnilが返ってきてエラーにはなりません。

#参考
・現場で使える Ruby on rails 5 速習実践ガイド
社内用システムを機械屋さんが自作するまでの記録

#この記事に関して ( 何が書かれているのか )
## はじめに
　近年、国を挙げてのデジタル化もあり検討しました。数社検討するも何処かピンとこない。。。　今はMicrosoftTeamsを使ってますがMicrosoft365に無料でついてたからです。決して使いやすくなく、解りづらい。このツールをもてはやすようなネット記事なんかを見ますがいまいち飲み込めない。
　悩みに悩んだ挙句、自作する事に決めました。その構築時の備忘録がこの記事です。

　なので更新は不定期、かつ正確性と見やすさわかりやすさは求めないでと言ったところです。
記事を書きつつ自作しつつ、使えるツールが無いかなーと探すので、見つかり次第開発中断もあり得ます。

## 書いている人物像
　京都で計測装置を販売している会社の社長です。
　小さいながらも従業員数名と共に装置販売をしております。

　もともと機械設計者として装置設計をメインにしていますが、装置システムの話しなども仕事上避けて通れないので一通りはお話しできるレベルではあります。
　運用システムに関しても興味があったり、効率化できないかなーといった観点で見聞きするので実際に触ってみたり試したりもします。またデスクトップアプリも作った事があります。

##作成方針
###指針
　基本は既存のフリーコンテンツ、フリーライブラリを基本としてその組み合わせを基軸にします。決して「車輪の再発明」にならぬように。ただし調査しきれずに自作する場合がありますがご愛敬、もしくはご連絡いただくと組込を試みる可能性があります。

###構想
　ユーザー管理とアクセスレベル管理の観点でWordpressを使おうかと考えています。
各種ツールがプラグインとして機能出来れば万々歳です。ここまで出来るのなら相当のスキルがあると思うので、そのレベルはプロに任せてその触り部分に特化出来ればと思います。

###初めに  ... 何を作りたいか？
基本は社内用システムであるため、現状エクセルで管理されている部分でシステム化できそうなもの、または希望を込めてのリストが下記です。順は必要順位で並んでますが状況に応じて多少入れ替わります。
　(1) 業務日報
　(2) 労務管理
　(3) コスト管理
　(4) 引合管理
　(5) 発注管理
　(6) タスクスケジュール管理
　(7) ToDo
　(8) 出張申請
　(9) 作業報告
　(10) 見積管理
何処まで出来るのか心配になるほど項目があがってます。従って完成までの目標日程は立てません。
cinemachine

## Cinemachineについて

Unity公式のAsset。PackageManagerからダウンロードできる(2018.4.17f1 以降)。
カメラの挙動をコントロール(オブジェクトを追純したり、決められたルートを走らせたり)できてとても便利。
Timelineとの連携ができてとても良いそう(自分は使ってない)。
untiy公式がcinemachineをフル活用して作ったプロモーションproject [BoatRace](https://youtu.be/eYRid0DuGu0)
## 活用法(自分の作品への使用例)
[CarRace] (https://youtu.be/pjomQPaIyGY)  一人称と三人称を切り替えられるところがポイント
[CarPV(CM風)] (https://youtu.be/fU_SE7iV5xE)　車の躍動感が素晴らしい

## Cinemachine Priorityを活用する
複数のバーチャルカメラを切り替えるためには、InspectorにあるPriorityという数値を変更します。数値が高いカメラが優先されてGame画面に表示されます。
今回はPriorityをScript上から変更し、カメラを楽に切り替える仕組みにしました。

```ChangeCamera.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;

public class ChangeCamera : MonoBehaviour
{

    public CinemachineVirtualCamera vcamera;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.R))
        {
            if (vcamera.Priority == 10)
            {
                vcamera.Priority = 80;
                return;
            }

            if(vcamera.Priority == 80)
            {
                vcamera.Priority = 10;

            }
        }
        
        
        }
    }
```


## 最後に
3Dゲームを作りたいなら絶対導入してください。機能が豊富で使いやすいです。
CentOS8にrsyncインストール（バージョン確認）してファイルバックアップ（同期）

#まずはrsyncをインストールしてバージョン確認
下記でインストール。
（CentOS8からインストールはdnfが標準になったようです）

```sh:コマンド
dnf -y install rsync
```

インストール終了したら下記でバージョン確認してみましょい。

```sh:コマンド
rsync --version
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/13be5df1-7592-4759-39b3-de539a881061.png)



#まずは1ファイルコピーの動作確認
『/from/test1.txt』ファイルを『/to/』フォルダーへコピーする場合のコマンド。
ただし **実際にコピーはせずに動作確認だけ** をするもの。

```sh:コマンド
rsync -vn /from/test1.txt /to/
```

* ```v``` = rsyncの動作を端末に表示しなさいよオプション
* ```n``` = 実際に処理はやらずにリハーサルだけしなさいよオプション（dry run）

結果はこんな感じ。（ファイルコピーは行われません）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/7d211513-9b1b-6eb8-e878-53084b390cd9.png)
慣れないうちは ```-vn``` 付けるのがよいかと思います。


#オプションを見てみよう

```sh:コマンド
rsync -help
```
結果…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/b3022e64-8e97-5a7b-950c-b4821bb0ff5e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/45dcac34-9e6d-b465-cfe7-8dfb55d9b51e.png)
（トータルはこの画像の倍くらいあるよ…）


#とりあえずフォルダーをミラーリングするオプションだけ覚えよう
『/to』フォルダの中身を『/from』と同じにしたいな！っていうオプション。

```sh:コマンド
rsync -acv --delete /from/ /to/
```

* ```a``` = ファイルの所有権や作成日等を維持したままコピーしなさいよ、あとサブフォルダーも再帰的に処理しなさいよオプション（アーカイブ）
* ```c``` = コピーするかどうかはファイルサイズや更新日じゃなくてチェックサムを比較して判定しないさいよオプション
* ```delete``` = コピー元に無いファイルやフォルダーはコピー先から削除しないさいよオプション

フォルダーを同期させる時はコピー元のファイルパス最後に『/』を付けるのを忘れないように注意。
付けないと『/to/from』フォルダが作成されてその中にコピーされちゃう…。
 


#蛇足
今回もDocker Desktop使って確認しました。


#参考サイトさん
https://www.server-world.info/query?os=CentOS_8&p=rsync
https://www.atmarkit.co.jp/ait/articles/1702/02/news031.html


#バージョン
Windows10 Pro バージョン1909 OSビルド19042.685
Docker Desktop:3.0.0（50684） Engine:20.10.10 Compose:1.27.4
CentOS Linux release 8.2.2004 (Core)
rsync version 3.1.3 protocol version 31
プリンシプルオブプログラミング

アドベントカレンダー12/1〜12/21までの記事を書くにあたって、以下の書籍を参考にさせていただきました。
1人で20記事近くの記事を短期間に書くには限度があり・・・。
こちらの内容から特に共感できるものを抜粋して今回の記事作成に活用させていただきました。
この書籍を執筆した上田勲さんに深く敬意を評するとともに感謝致しております。

[プリンシプル オブ プログラミング3年目までに身につけたい一生役立つ101の原理原則 | 上田 勲 |本 | 通販 | Amazon](https://www.amazon.co.jp/dp/4798046140)
※アフィリエイトコードなんてついていないので安心して踏んでください

プログラミングやシステム開発に関する心構えや気をつけるポイントなど事細かに説明されていて、新人はもちろんベテランの方が読んでも大変面白い本です。

こちらの書籍も、過去の他の書籍で紹介されている内容から引用されており、まさに**エンジニアの戦いから学んだ兵法の歴史**を学ぶような1冊です。

今回のアドベントカレンダーで紹介した内容以外にも面白い内容がたくさん載っていますので、すべてのエンジニアにぜひ読んでみてもらいたいです。
アルゴリズム力UP!『ABC 045 C たくさんの数式 』を解いてみよう

# 記事を読むとわかること
- 記事の作者の『ABC 045 C たくさんの数式 』の解法がわかる
- 記事の作者のアルゴリズム問題全般へのアプローチがわかる

# 今回の問題 

**ABC 045 C たくさんの数式**　→ [問題文はこちら](https://atcoder.jp/contests/abc045/tasks/arc061_a)

# 記事の作者の回答のコード
```python

def solve_many_formulas(num: int) -> int :
    # ==============================================================
    # return: ある整数値を代入すると、数と数の間に+を入れてできる数式の和の合計を返す
    # pre: 125
    # post:176 = (125) + (26 = 1+25) + (17 = 12+5) + (8 = 1+2+5) 
    # ==============================================================

    # ★ step1 整数値を文字列にし、数と数の間に+を入れられるようにする
    # ★ step2 文字列にした数の長さを取り、インデックスで+をいれる場所を指定できるようにする。
    # ★ step3 再帰関数を用いて、+が入れられる場所を、+をいれる/入れない時で全通り調べる
    # ★ step4 数と数の間に+を入れてできる数式の和を返す

    #整数値を文字列にする
    str_num = str(num)
    #文字列にした数字の長さを取る
    len_str_num = len(str_num)

    #idxがlen_str_numの文字列のインデックス, sentenceが+と数値を含む文字列
    def dfs(idx: int , sentence: str, str_num: str, len_str_num: int) -> int: 

        # 文字列idxが一番後ろに到達したかどうかを判定
        if idx == len_str_num - 1:
            #+で挟んでいるところで数字をわけ、数値に変更し合計値を出す
            return sum(list(map(int, sentence.split("+"))))
        #間に+を入れるか入れないかで分岐させ、全通り検索できるようにする
        #最終的に佐伯関数からreturnした値を足算していく
        return (
                dfs(idx + 1, sentence + "+" + str_num[idx + 1], str_num, len_str_num) 
              + dfs(idx + 1, sentence + str_num[idx + 1], str_num, len_str_num) 
        )
     
    #初期値として文字列の最初のインデックス, 文字列にした数値の0行目の値, 
    return dfs(0, str_num[0], str_num, len_str_num)

N = int(input())
print(solve_many_formulas(N))
```

# 回答の解説

## 記事の作者が思う今回のアルゴリズム問題の回答ポイント

- +を入れられるように、整数値を文字列にする
- +を入れられる場所を指定できるように、文字列にした数字の長さを取る
- 全文検索で+を間に入れるかどうかで分岐をさせつつ、最終的に合計値を返す

## 記事の作者が思うコードのみで理解しにくい部分の解説

### 再帰関数"dfs"のreturn部分の処理

**対象のコード**

```python
 return (
                dfs(idx + 1, sentence + "+" + str_num[idx + 1], str_num, len_str_num) 
              + dfs(idx + 1, sentence + str_num[idx + 1], str_num, len_str_num) 
        )
```
ここでは+がある/なしのdfsを返り値に置いているが、イメージ

- 1回目dfs
- + 2回目の(プラスありdfs + プラスなしdfs) 
- + 3回目の(プラスありの(プラスありのdfs + プラスなしのdfs) +  +  プラスなしの(プラスありのdfs + プラスなしのdfs))　

とどんどん分岐して、最終的に dfs + dfs + dfs + ・・・・ と 合計値を返すようになる。

#このコードの課題感

- 再起関数を利用しているためメモリを食い、現場での実用性がそこまで高くない。
- dfsの引数がやや冗長的な印象。
素性がよくわからない闇システムの解析方法

#はじめに
システムというものは、ある日突然おかしくなるものです。また、そういうものに限って担当者が退職していて引き継ぎも行われていないとか、古すぎてメーカーがサポートしてくれないとか、色々と困った状態になっていることが多いです。

こういった話は、Qiitaでよく見るイマドキのIT企業ではあまりないかもしれませんが、筆者が所属する製造業の業界ではよくあることのようです。

今回は、そんな「闇システム」をどうにか解析し、なんとかするための手順をまとめてみたいと思います。

#まずは相手を知る
よくわからないシステムを相手にしないといけないときは、まず環境を確認しましょう。確認すべき項目としては

## システムを構成するコンピューターの仕様を確認する
まずは、サーバーなりクライアントなりが動いているコンピューターのCPUアーキテクチャ、OS等を確認しましょう。x86やx64とWindowsの組み合わせなら良いですが、それ以外の場合は身構える必要があります。

## 使用されているミドルウェアを確認する
OSとアーキテクチャが分かったら、次はミドルウェアに何が使用されているか確認しましょう。

ミドルウェアを確認する方法は色々とありますが、今回は実際に端末を操作できることを前提として考えてみます。

### とりあえずnetstat
とりあえず、netstatで使用しているポートを確認してみましょう。

Well Known Portを勝手に使ってるようなお行儀の悪いソフトじゃなければ、何が動いてるかくらいはわかります。

### できればパケットキャプチャ
あと、できればクライアントでWiresharkを動かして、通信内容を確認してもいいと思います。キャプチャ内容を見れば、アプリケーションの挙動がなんとなく分かるかもしれません。

もし、いろいろな理由でクライアントにWiresharkを忍ばせる事ができない場合は、ミラーポート機能のあるスイッチングハブを使用するのも一つの手ですが、こちらのほうが現実的に難しいかもしれません。

### 知ってそうな人に聞く
これは最終手段ですが、古参社員とか、少しでも導入時の事情を知ってそうな人に聞くのもありです。

# 障害の再現性を確認する
障害対応の基本中の基本ですが、起きた障害の再現性を確認する必要があります。

つまり、問題となっている障害が「時々起こる」のか「とある操作をしたときに起こる」のかを特定する必要があります。

# 対応可能な障害かどうかを判断する
再現性を確認して、問題の特定ができたら、最後にその障害が対応可能な障害かどうかを判断します。

例えば、データベースの障害が起こっていたとして、それが論理障害ならなんとかなるかもしれませんが、ディスクの不良セクタがちょうどDBのファイルが置いてあるところに発生している等、どうしようも無い場合も多々あります。

そういった場合は、上層部にそれらしい説明をする準備をせねばなりません。ここで一つおすすめな方法として、「できないことは無いけど高く付く」と説明する方法です。

先のデータベースの例を使うと、単に「ファイルが破損しているので復旧できません」と報告してしまうと、大抵の場合納得してくれません。酷いときには責任転嫁されて自分が悪いことになります。

ですが、「復旧することは可能ですが、業者に依頼する必要があります。今見積もり途中です」と返答すれば、とりあえず進捗がある事を強調することができます。

言い方の問題ですが、ただでさえ立場が弱い情シスで生き残るには、こういった手法も必要になってきます。

#おわりに
はじめは技術的な事を書くつもりだったのですが、そういったネタが全く思いつきませんでした。よく考えてみればそれもそのはずで、障害対応というのは結構経験則やカンに頼っている部分が大きく、特に闇システムに対しては、情報工学的なアプローチは全くと言って良いほど効果がありません。

RPGで相手の弱点属性を探るために、ひたすら魔法を当てまくる事がありますが、闇システムに対しても、そういった地道な作業が必要なのだと思います。

技術成分少なくてすみません・・・
[Java] 再帰的ジェネリクスでEntityから不要なデータを省きつつCloneする

# 概要
DBからデータを読み込み、ある一部分を変更したあと新しいデータとして保存する時に、`clone()`メソッドを使うと思います。
本記事は、再帰的ジェネリクスを活用してイイ感じにcloneしてみようというものです。

# 再帰的ジェネリクスとは

型パラメータをもつクラスを継承するときに、その型パラメータに対して自身のクラス名を指定するアレです。
コードでいうとこういうものです。

```java
public class Entity<T extends Entity<T>> {
}
```
とするやつですね。
こうすることで何が嬉しいのかというと、戻り値が親クラスである継承元のメソッドをオーバーライドしたときに、その戻り値を自分のクラスにすることができます。
今回のcloneメソッドを例にすると、

```java
public class Entity<T extends Entity<T>> implements Cloneable {

    @Override 
    public T clone() {
        return (T) super.clone();
    }
}
```
このクラスを定義する時点でキャストする必要が一回ありますが、以降継承するときには意識する必要がなくなります。

# Spring用のBaseEntityをつくる
複合キーを想定しない作りにはなるのですが、新しくEntityをコピーするときに`ID`だけ省いたEntityをクローンすると言ったことが可能です。
単純に、先程の`clone()`内で`ID`を`null`にしてあげればいいだけです。

```java
@Data
@MappedSuperclass
public class BaseEntity<T extends BaseEntity<T>> implements Cloneable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Override
    @SuppressWarnings("unchecked")
    public T clone() {
        try {
            T clonedEntity = (T) super.clone();
            clonedEntity.setId(null);

            return clonedEntity;
        } catch (CloneNotSupportedException e) {
            // Cloneableを実装しているためスローされない。握り潰し方をJavaAPIにあわせる。
            throw new InternalError(e);
        }
    }
}
```
これを継承したクラスでは、常に`ID`が`null`になっているEntityをクローンすることができるようになります。
先程の`BaseEntity`を継承してもう一枚クラスを重ねることもできます。
フィールドの意味合いをまとめたいときに有効だと思います。
下記コードは監査証跡を自動で残すクラスで、クローン時は先のクラスに渡さないというものです。

```java

@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
public class AuditingEntity<T extends AuditingEntity<T>> extends BaseEntity<T> {

    @CreatedBy
    protected String createdBy;
    @CreatedDate
    protected LocalDateTime createdAt;
    @LastModifiedBy
    protected String updatedBy;
    @LastModifiedDate
    protected LocalDateTime updatedAt;

    @Override
    public T clone() {
        T clonedEntity = super.clone();
        clonedEntity.setCreatedBy(null);
        clonedEntity.setCreatedAt(null);
        clonedEntity.setUpdatedBy(null);
        clonedEntity.setUpdatedAt(null);

        return clonedEntity;
    }
}
```

# おわりに
Entityをクローンした時にいちいち不要なフィールドを`null`にしてから使う必要がなくなるので、ロジック側のコードがすっきりすると思います。ぜひ活用してみてください。
コミュニティの今年一年を振り返る。

この記事は <A HREF=https://qiita.com/advent-calendar/2020/alibabacloud target=_blank>Alibaba Cloud Advent Calendar 2020</A> の13日目です。皆様の参加をお待ちしております。



# 0. はじめに

旅人の岡崎です。
アリババクラウドのユーザコミュニティ AliEaters の運営をしています。
東京支部を拠点として全国各地の地方支部を旅して歩いてきました。
しかし今年はコロナ元年、そんな今年を振り返ります。


# 1. コロナで開催激減

会場開催イベントは全国でわずか４回でした。

|開催日 |支部 |イベント名|
|---|---|---|
|1/24 |札幌 |<A HREF=https://alieaterssapporo.connpass.com/event/161756/ target=_blank>AliEaters Sapporo #4</A> |
|1/30 |名古屋 |<A HREF=https://alieaters-nagoya.connpass.com/event/161346/ target=_blank>Alibaba Cloud in Nagoya #4</A> |
|2/12 |大阪 |<A HREF=https://alieaters-osaka.connpass.com/event/163984/ target=_blank>Alibaba Cloud in Osaka #6</A> |
|12/11 |東京 |<A HREF=https://alibabacloud.connpass.com/event/195452/ target=_blank>AlibabaCloud Developers Meetup #16 AliEaters</A> |


オンライン開催イベントは全て東京で５回開催。

|開催日 |支部 |イベント名|
|---|---|---|
|3/25 |東京 |<A HREF=https://alibabacloud.connpass.com/event/170657/ target=_blank>AlibabaCloud Developers Meetup #15 AliEaters Live</A> |
|4/22 |東京 |<A HREF=https://alibabacloud.connpass.com/event/173630/ target=_blank>大!!オンライン飲み会-AliEaters Live #2</A> |
|6/2 |東京 |<A HREF=https://alibabacloud.connpass.com/event/177161/ target=_blank>AliEaters Live #3 大!!オンライン飲み会</A> |
|7/28 |東京 |<A HREF=https://alibabacloud.connpass.com/event/182468/ target=_blank>AliEaters Live #4 大!!オンライン飲み会</A> |
|9/18 |東京 |<A HREF=https://alibabacloud.connpass.com/event/187464/ target=_blank>AliEaters Live #5 Apsara Conference裏番組解説を聞こう！</A> |


残念ながら今年開催が無かった支部
- 仙台
- 九州
- 広島
- 沖縄


コロナで活動が制限されるとオンラインへシフトするのは一部で、そもそも活動しなくなる・活動が減ってしまいました。



# 2. オンラインによる東京集中

これはAliEatersに限ったことでは有りませんが最近気になっていること。
オンライン勉強会は場所を問わず参加できます。
東京開催のオンライン勉強会に地方の方が多く参加するようになりました。
それ自体は良いのですが、同時に地方開催の勉強会が減りました。
地方では東京からコンテンツが配給されることでそれに依存してしまう状況が見られるようになりました。

AliEatersも東京だけはオンライン開催と合わせ例年には及ばずともそこそこの回数を開催出来ましたが、地方は残念な結果に終わりました。



# 3. 対面あっての地方

地方コミュニティは対面あってこそです。
学ぶだけならば東京から配給されるコンテンツを見ていれば足りるし、実際そうなっているのが現状だと思います。
しかし地方の勉強会は対面で顔を合わせ懇親会で人脈を広げるのが主目的であり、これが無くては地方コミュニティが崩壊してしまいます。
徐々に復活の兆しがありますが、早期復活したいですね。


# 4. オンライン疲れ？

これも同じくAliEatersに限らずコミュニティ全般に見られる傾向ですが、
９月頃からかオンライン開催の集まりが悪くなってきました。
テレワークの普及が進み、仕事中は殆どオンライン会議アプリの画面を見て過ごした後にオフも同じ画面を見るのは嫌だという人が増えてきたのだと推測しています。

仕事だけでもテレワークで精神的に病んで産業医に相談するケースがちらほら出ている現在、当然の結果かもしれません。



# 5. まとめ

復活のコロナな昨今ですが、来年は会場開催を少しずつ増やしていきたいと思います。
ブルックスの法則

# ブルックスの法則とは

***遅れているソフトウェア開発プロジェクトに後から人員を追加しても、かえって遅らせることになる***

外注に依存している企業が陥りがちなトラップではないでしょうか。

人員が増えてるのになぜ早くならないかと言うと、以下の問題があるからです。

* 新しい人員への教育
  * 配置されてすぐに仕事できるわけではない。教育する人の工数もかかるので、その間開発が止まってします。
* コミュニケーションコストの増大
  * 人員が増えた分、全員の進捗把握や情報共有・意識共有に時間がかかるようになる
* タスクの分解には限度がある
  * 1人だと100日かかるタスクに、99人追加したら1日で終わるかと言うとそうではないという話

# 人月の神話

多くの企業の工数計算で**人月**が使われていると思います。1人の人間が1ヶ月で完了できるなら1人月です。
この方式はもともとは建築業などの肉体労働の工数計算に使われていたところから来たと言われています。肉体労働の場合、人数と期間が反比例する（多ければ多いほど早く終る）事が多いため、計算しやすかったと思います。

システム開発においてこの方式が全くうまくいかないのは容易に予想できると思います。単純に**人によって1ヶ月にこなせる作業量はぜんぜん違う**からです。新人エンジニアとベテランエンジニアの1人月は場合によって10倍くらいの差があるかもしれません。

この人月計算の数値が**「多ければ早く終る」の誤解**の元凶になっている気がします。

# システム開発の進捗遅れは取り戻せない

システム開発の進捗遅れを途中から取り戻すのは極めて難しいです。
現チームの労働時間を月160時間のところを月320時間に増やしたら開発スピードが2倍になるかというとそんなことはなく、人間の体力や集中力には限度があり、無理にそういうことをやっても、開発スピードの低下やバグの多発などで、実際にはせいぜい良くても1.5倍くらいではないでしょうか。
ところが、感情論が高く評価される日本では**「進捗遅れを取り戻すため最大全努力する姿勢を見せないといけない」**という配慮から、効率悪いと知っていても長時間労働で誠意を見せる傾向があります。

# 違う解決策を見つける

スケジュールが遅れたときにできる解決策は2つだけだと思います。

* スケジュールを伸ばす
* スケジュールに間に合う内容に変える
  * 段階リリースにするとか
[TypeScript] 引数の個数も型定義で制限させる



『プログラミングTypeScript(p82) 4.2.5 制限付きポリモーフィズム』のメモ。

引数の個数を型定義上できちんとハンドリングしてあげる例について。

- ポイント
  - 配列のジェネリクスは `T[]` ではなくて `T extends unknown[]` で表現する
  - スプレッド演算子で引数の処理をしてあげる

```ts
// JSでのcallに相当するものを作る
// 第１引数　：実行する関数
// 第２引数〜：第１引数の関数を実行するときの引数
function call<T extends unknown[], U>(
    f: (...args: T) => U,
    ...args: T
): U{
    return f(...args)
}
```

これを実行すると下記のようになる　

```ts
// 適当な関数つくって、これで稼働確認
const add = (a: number, b: number) => a + b

call(add, 10, 20)     // => 30
call(add, 10, 'a')    // ERROR: Argument of type 'string' is not assignable to parameter of type 'number'.
call(add, 10)         // ERROR: Expected 3 arguments, but got 2.(2554)
call(add, 10, 20, 30) // ERROR: Expected 3 arguments, but got 4.(2554)
```

addの関数の型定義だけではなくて、add関数の引数の個数もきちんと見てくれてる。おわり。
【Discord.py】スプラトゥーン2のブキランダムBOTを作りました。

<h2>はじめに</h2>
今更ながらスプラトゥーン2のブキをランダムで選んでくれるDiscord用のbotを作りました。
<a href="https://discord.com/api/oauth2/authorize?client_id=787464198086328380&permissions=67584&scope=bot">ここ</a>から招待できます
<h2>ソースコード</h2>

ブキのリストは<a href="https://fuwapan.com/data/buki_list.csv">これ</a>です。

```buki_random.py
import discord
from discord.ext import commands
import pandas as pd
import logging
import random

token = "botのトークン"
client = commands.Bot(command_prefix='.')

def random_buki(num):
    df = pd.read_csv('buki_list.csv')
    buki = df.sample(n=num)['Name'].apply(lambda x: [s.strip() for s in x.split(',')])
    return buki.iloc[0][0]

def random_hensei():
    df = pd.read_csv('buki_list.csv')
    hensei = []
    #前衛
    hensei.append(df[df['position'] <= 2].sample().iloc[0][0])
    hensei.append(df[df['position'] <= 2].sample().iloc[0][0])
    #中衛
    hensei.append(df[df['position'] == 3].sample().iloc[0][0])
    #後衛
    hensei.append(df[df['position'] >= 4].sample().iloc[0][0])
    random.shuffle(hensei)
    return hensei

@client.event
async def on_ready():
    print("started " + client.user.name)
    
@client.command()
async def hensei(ctx):
    buki = random_hensei()
    cnt = 0
    mes = ""
    for name in ctx.author.voice.channel.members:
        if not name.bot:
            mes = mes  + name.name + ' => ' + buki[cnt] + '\n'
            cnt += 1
            if cnt == 4:
                break
    await ctx.send(mes)

@client.command()
async def buki_a(ctx):
    mes = ""
    for vc in ctx.guild.voice_channels:
        for name in vc.members:
            if not name.bot:
                buki = random_buki(1)
                mes = mes  + name.name + ' => ' + str(buki) + '\n'
    await ctx.send(mes)

@client.command()
async def buki(ctx):
    buki = random_buki(1)
    print(buki)
    n = ctx.author.name
    mes = n + ' => ' + str(buki)
    await ctx.send(mes)

client.run(token)
```

<h2>使い方</h2>
「.buki」と入力すれば発言した人のブキをランダムで選んでくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/896190/d644d8ad-4d2d-540b-7416-ea5d838575b6.png)
「.buki_a」でボイスチャンネルに接続している人全員のブキを選びます。

「.hensei」で発言した人と同じボイスチャンネルにいる人4人のブキを前衛・中衛・後衛のバランスをある程度考えて選んでくれます。
（同じボイスチャンネルに4人以上いると選ばれない人が出てきます）

<h2>最後に</h2>
編成のランダムについては、武器のポジションだけでなく、ブキ種や塗りの強さ、スペシャル被り等も考慮した編成を生み出す処理も考えましたが、変な編成が生み出されることも武器ランダム系botの醍醐味かなと思ってやめました。
プラベやリグマで楽しめたらいいなと思います。
リポジトリごとにGitユーザーを変更する

会社用とプライベート用でGitアカウントを使い分けたい…ってことがあったので調べてやってみました。

### グローバル設定を確認

`git config --global -l`

まず、上記コマンドでグローバル設定を確認してみます。

```
...(略)
user.name=Shibuchaaaan1
user.email=name@company.co.jp
...(略)
```

私のグローバル設定では会社用アカウントになっていたので、上記とは別にプライベートのアカウントを特定のリポジトリに設定していきます。

### 今いるリポジトリにGitユーザー設定

下記コマンドで、今いるリポジトリのGitユーザーを個別に設定できます。

```
git config user.name "Shibuchaaaan2"
git config user.email "maillAddress@mail.com"
```

すると、今いるリポジトリの`.git`>`config`ファイルに`[user]`の記述が追加されます。

```
[core]
	...(略)
[remote "origin"]
	url = git@github.com:xxxxxxxxx/xxxxxxxx-xxxxxx.git
	fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
	remote = origin
	merge = refs/heads/main
[user]
        name = Shibuchaaaan2
        email = mailAddress@mail.com
```

今いるリポジトリに`Shibuchaaaan2`のGitユーザーが設定されました。

グローバル設定は変更していないので、`Shibuchaaaan1`のアカウントのままになっています。

これで、特定のリポジトリにだけプライベートのGitアカウントを設定することができました！