OmniAICreator/Qiita-1.07M huggingface dataset:
[Python] UnionFind ABC214D

#[ABC214D](https://atcoder.jp/contests/abc214/tasks/abc214_d)

以下では、辺の重みは相異なると仮定します。制約にそのような条件はありませんが、添字の大小による tie-break などを行えばよいです。

各 $i , (1 \leq i \leq N -1)$ ついて、$f(u, v) = w_i$ となる $(u, v)$ の総数を数えることを考えます。$f(u, v) = w_i$となるための条件は、頂点 $(u, v)$ を結ぶパスに辺 $i$ が含まれ、かつそのパスに含まれる他の辺の重みが $w_i$ より小さいことです。

重みが $w_i$ より小さい辺のみを張ったグラフを考えると、これは森（Forest グラフ理論の用語）となっており、$u_i$ と $v_i$ は必ず異なる連結成分に属します。これら二つの連結成分の一方に $u$、もう一方に $v$ が属することが、$f(u, v) = w_i$ となるための条件です。

よって、辺の重みの小さい順にグラフに追加していき、Union-Find などのデータ構造を用いて連結成分の大きさを取得することにより、この問題を解くことができます。

```python:サンプルコード
class UF:
  def __init__(self, N):
    # vertex → root, root → size
    self.uf = [-1] * N
    self.n = N

  # find root
  def find(self, x):
    if self.uf[x] < 0: return x
    self.uf[x] = self.find(self.uf[x])
    return self.uf[x]

  def size(self, x):
    return -self.uf[self.find(x)]

  def union(self, x, y):
    x, y = self.find(x), self.find(y)
    if x == y: return
    if self.size(x) > self.size(y): x, y = y, x
    self.uf[y] += self.uf[x]
    self.uf[x] = y
    self.n -= 1

N = int(input())
E = sorted([tuple(map(int, input().split())) for _ in range(N-1)], key=lambda x: x[2])

uf = UF(N)
ans = 0
for u, v, w in E:
  u -= 1
  v -= 1
  ans += uf.size(u) * uf.size(v) * w
  uf.union(u, v)

print(ans)
```
Arduino: Base64.h の使い方

ArduinoUNO で Base64.h を使ってみました。
参考ページ
>[Base64/examples/Base64Encode/Base64Encode.ino](https://github.com/agdl/Base64/blob/master/examples/Base64Encode/Base64Encode.ino)

```text:base64_test/base64_test.ino
// ---------------------------------------------------------------
/*
	base64_test.ino

						Aug/15/2021
*/
// ---------------------------------------------------------------
#include <Base64.h>

// ---------------------------------------------------------------
void setup()
{
  Serial.begin(19200);
	delay (1000);
	Serial.println("*** start ***");
	delay(500);
	Serial.println("*** Base64 example ***");
	delay(500);
	
	char Buf[50];

	int llx = 8;
	String str_array[] = {"A","AB","ABC","ABCD","ABCDE","ABCDEF","ABCDEFG",
		"ABCDEFGH"};


Serial.println ("llx = " + String(llx));
delay(1000);

 for (int itt=0; itt < llx; itt++)
 {
		str_array[itt].toCharArray(Buf, 50);	
		String str_encoded = encode_proc(Buf);
		Serial.println(str_encoded);

   delay(300);
		}

	delay(500);
	Serial.println("*** setup *** end ***");
}

// ---------------------------------------------------------------
String encode_proc(char* input)
{
	Serial.println(input);

	int inputLen = strlen(input);
	
	int encodedLen = Base64.encodedLength(inputLen);
	char encoded[encodedLen];

	Base64.encode(encoded, input, inputLen); 
	
	return String(encoded);
}

// ---------------------------------------------------------------
void loop()
{
	Serial.println("*** loop ***");
	delay (3000); 
}

// ---------------------------------------------------------------
```

実行結果

```text
*** start ***
*** Base64 example ***
llx = 8
A
QQ==
AB
QUI=
ABC
QUJD
ABCD
QUJDRA==
ABCDE
QUJDREU=
ABCDEF
QUJDREVG
ABCDEFG
QUJDREVGRw==
ABCDEFGH
QUJDREVGR0g=
*** setup *** end ***
*** loop ***
```

ライブラリーのインストール方法
>ツール -> ライブラリを管理
![library_base64.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/727e69e9-3b76-43a8-4375-ac4dfea34663.png)
has_one型のデータを表示させたくて

こんにちは！！
ユーザー登録が完了したら、ライブ情報を
投稿できるアプリを作成中です。
今回はhas_one型のデータの表示方法について
自分のメモ用としてアウトプットしていきたいです。

# アソシエーション

作成中のアプリには3つのエンティティが存在します。
deviseを使って実装したユーザー登録をするadmin_usersテーブル、
ユーザーの詳細なプロフィールを保存するadmin_profilesテーブル、
ライブ情報を投稿できるeventsテーブルが存在します。

3つのテーブルのアソシエーションは以下の通りです。
Admin_user has_one admin_profiles.
Admin_user has_many events.
Admin_profile belongs_to admin_user.
Event belongs_to admin_user.

ユーザー登録はウィザード形式で保存する為、
AdminProfileモデルに

```rb
belongs_to :admin_user, optional: true
has_one_attached :admin_image
```
と記述しました。
また、ライブハウスの画像を保存したかったので、
Active Strageを利用してadmin_imageとしました。

# 実装したいこと

訪れたユーザーが、ライブハウスの詳細ページ(admin_users/show)にいくと
ユーザーの詳細な情報（admin_profilesテーブルに保存された情報）を
見ることができるように試みました。

admin_users_controllerには以下のように記述

```rb
class AdminUsersController < ApplicationController
  def show
    admin_user = AdminUser.find(params[:id])
    @store_name = admin_user.store_name
    @admin_profile = admin_user.admin_profile
  end
end
```

# NoMethodError

ウキウキでブラウザを更新してみると以下の表示が。

![スクリーンショット 2021-08-07 16.26.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1435543/1161db5d-0af3-bf31-30c0-550e7f064d56.png)

ふざけやがって。

![スクリーンショット 2021-08-07 16.26.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1435543/eef6f2c1-8085-5bf0-9df9-f87048e70686.png)

ナンジャそりゃ。
NoMethodErrorですって。

悩みすぎてrubyが嫌いになったのでやめてしまおうかと考えてました。

# optional trueによる弊害

今回のエラーはウィザード形式でbelongs_toの外部キーのnilを許可する
optional: trueを記述したことで起こったようです。

ターミナルでコンソールを立ち上げて
pluckを確かめてみると

```rb
[1] pry(main)> AdminUser.pluck(:id)
   (0.3ms)  SELECT `admin_users`.`id` FROM `admin_users`
=> [5, 16, 7, 14, 12, 15, 6, 8, 13, 1, 11, 9, 4, 18, 3, 17, 2, 10]
[2] pry(main)> AdminProfile.pluck(:admin_user_id)
   (0.3ms)  SELECT `admin_profiles`.`admin_user_id` FROM `admin_profiles`
=> [4, 6, 7, 13, 14, 15, 17, 18]
```

admin_userとadmin_profileで紐付けられていないidが
いますねえ。

# ぼっちを使う

もう今更ユーザー登録をウィザード形式で実装してたのを
やめて実装し直すとかめんどくさいんでやりたくなかったので
ボッチ演算子を使用することにしました。

```rb
<div class="profile-contents">
    <p class="shop-name"><%= @store_name %></p>
    <p class="postal-code">
      〒
      <%= @admin_profile&.postal_code %>
    </p>
    <p class="prefecture-text">
      <%= @admin_profile&.prefecture&.name %><%= @admin_profile&.municipality %>
    </p>
    <p class="address-text">
      <%= @admin_profile&.address %><%= @admin_profile&.building_name %>
    </p>
    <%= link_to "Google mapで見る", "#", class:"map-link" %>
    <p class="tel">
      TEL:
      <%= link_to @admin_profile&.phone_number, "#", class:"phone-number" %>
    </p>
    <p class="admin-profile">
      <%= @admin_profile&.profile %>
    </p>
  </div>
```
レシーバーであるオブジェクトに対してあるメソッドを実行する時にエラーを出さずにメソッドを
表示することができるぼっち演算子を使うことで解消できました。
rubyおもしろい。
docker-compose.yml内で環境変数の展開

# 変数展開

docker-composeファイル内でホストの環境変数が展開されます。内容は公式ドキュメントそのままなので、最新情報は公式ドキュメントを参照してください。

[Variable substitution（公式）](https://docs.docker.com/compose/compose-file/compose-file-v3/#variable-substitution)

## 基本パターン

シェルと同じ書き方で展開されます。

```shell
$VARIABLE
${VARIABLE}
```

## デフォルト値指定

未定義、空白の場合、デフォルト値を設定できます。`:-`と`-`の2パターンあり変数の評価方法はシェルの仕様と同じです。

```shell
# 変数が未定義、または、空白の場合デフォルト値を代入します。
${VARIABLE:-default}

# 変数が未定義の場合デフォルト値を代入します。
${VARIABLE-default}
```

## 必須チェック

必須チェックを行います。エラーの場合、`docker-compose`コマンドは失敗します。これも`:?エラーメッセージ`と`-?エラーメッセージ`の2パターンあり変数の評価方法はシェルの仕様と同じです。

```shell
# 変数が未定義、または、空白の場合異常終了します。
${VARIABLE:?err}

# 変数が未定義の場合異常終了します。
${VARIABLE?err}
```

## $$

`$`をエスケープするには`$`を2つ重ねます。

```shell
"$$VAR_NOT_INTERPOLATED_BY_COMPOSE"
```

# 使用不可

以下はエラーになることを確認しました。

`=` `:=` デフォルト値代入
`+` `:+` 定義時の代入
`:offset` `:offset:length` 展開の部分指定

以下は未対応です。

`${VARIABLE/foo/bar}` 変数の置換

---

すでに同内容の投稿がありました。

[案外知られてないdocker-composeの環境変数定義の記法](https://qiita.com/fagai/items/b944950b26af19453c02)
FlutterのWorkManagerのcallbackDispatcherをstaticで宣言するとエラーになる

問題のライブラリはこちら
https://pub.dev/packages/workmanager

> The callbackDispatcher needs to be either a static function or a top level function to be accessible as a Flutter entry point.

この公式の指示に従ってstaticでcallbackDispatcherを宣言したらこんなエラーが・・・

```
E/flutter ( 2580): [ERROR:flutter/shell/common/shell.cc(103)] Dart Unhandled Exception: NoSuchMethodError: No top-level getter 'callbackDispatcher' declared.
E/flutter ( 2580): Receiver: top-level
E/flutter ( 2580): Tried calling: callbackDispatcher, stack trace: #0      NoSuchMethodError._throwNew (dart:core-patch/errors_patch.dart:214:5)
E/flutter ( 2580): 
E/flutter ( 2580): [ERROR:flutter/runtime/dart_isolate.cc(713)] Could not resolve main entrypoint function.
E/flutter ( 2580): [ERROR:flutter/runtime/dart_isolate.cc(192)] Could not run the run main Dart entrypoint.
E/flutter ( 2580): [ERROR:flutter/runtime/runtime_controller.cc(415)] Could not create root isolate.
E/flutter ( 2580): [ERROR:flutter/shell/common/shell.cc(588)] Could not launch engine with configuration.
```

# 結論
トップレベルに宣言すれば治ります。

**検証環境**
Flutter 2.2.3 
Dart 2.13.4
Workmanager 0.4.1
Kotlin 1.4.32
GitHubでSSH接続できない場合のチェック項目

2021年8月13日以降、パスワードでの接続を利用してリポジトリのプッシュやプルができなくなりました。
パスワード接続からSSHへ変更するにあたって、`チェック項目がまとめられた記事が見つからない`＆`いくつかの項目は探してもなかなか見つかりづらい`ように感じたので、つまづいた箇所をチェック項目としてまとめます。

- 私は主にMacで作業をしているのですが、他のOSの場合など、チェック項目が漏れている場合は、随時追加し、更新していきたいと思います。
- CLIでGit操作をする場合や、GitHubDesktopやSourceTree、GitupなどのGUIを使う場合も、以下の内容ができていれば、接続できると思います。


**チェック項目**
1. .git/configでurlが`git@github.com:ユーザー名/リポジトリ名.git`になっているか
2. ssh鍵が正しく作成、登録できているか（.ssh/configも忘れずに）
3. 【mac】keychainにパスワードが設定されていないか


## 1. .git/configでurlが`git@github.com:ユーザー名/リポジトリ名.git`になっているか

まずは、ローカルリポジトリ（自分のPC上のアプリのディレクトリ）の`.git/config`ファイルの内容を確認します。
ここには、Gitで送信する際の送信先のURLが記載されています。

`.git/config`の内容例

```
[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
        ignorecase = true
        precomposeunicode = true
[remote "origin"]
        url = git@github.com:●●●/■■■.git
        fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
        remote = origin
        merge = refs/heads/master
```

上記で重要なのが、`url = git@github.com:●●●/■■■.git`の部分です。
ここの書き方が上記のようになっていないと、他の設定がちゃんとできていたとしても、GitはSSHで接続しようとはしてくれません・
ここのurlの書き方は、以下のようにGitHubのリポジトリページから確認できます。
※矢印をつけた箇所で、SSHを選択していることが重要です。

![20210815-104950.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102360/fc4b4e3c-92c4-2066-6163-47739e812602.png)

## 2. ssh鍵が正しく作成、登録できているか（.ssh/configも忘れずに）

こちらは多くの方が記事を書かれているので、私が作業する際に参考にさせていただいた方のリンクを貼っておきます。
[Mac GitHub SSH接続設定](https://qiita.com/ucan-lab/items/e02f2d3a35f266631f24)

## 3. 【mac】keychainにパスワードが設定されていないか

こちらは、GitHubの[公式ページ](https://docs.github.com/ja/github/getting-started-with-github/getting-started-with-git/updating-credentials-from-the-macos-keychain)に載っています。
公式ページの指示の通り、keychainの中にあるgithubの`internet password`の登録を削除しましょう。
（ブラウザーからのログインは従来通りパスワードを使用するので、そちら（Webフォームパスワード）は削除しないように注意しましょう！）



## 最後に
以上が私がGitHubにSSH接続する際につまづいた箇所です。
上記の設定がちゃんとできていれば、ローカルからの接続も、サーバーからの接続も、同じ手順で設定できるのではないかと思います。

重要なのは、`.ssh/config`と`.git/config`ですね。
【Swift】コールバックを使ってAPIを叩いた結果毎に処理を分岐させる

業務の中で使われていた手法を理解するために自分なりに単純化してみました。

# 擬似API処理

```swift
// APIを叩くメソッド
func api(closure: (ApiResult) -> Void) {
  // APIを叩く処理
  
  // APIから返ってきた結果
  closure(.SUCCESS)
}

// APIの通信結果
enum ApiResult {
  // 成功
  case SUCCESS
  // 失敗
  case ERROR
}
```

`enum`を使って発生しうる結果分岐を用意しておきます。作成した分岐経路を擬似的に作ったAPIを叩くメソッドの`closure`に渡し、結果がどの`case`に当てはまるかを返してもらいます。

# メソッドの呼び出し

メソッドを呼び出して、switchを使い結果毎にやってほしい処理を追加します。

```swift
api { result in
// resultにapi()の結果が入っている　
switch result {

// 成功だった時の処理
case .SUCCESS:
    print("SUCCESS")
    
// 失敗だった時の処理
case .ERROR:
    print("ERROR")
}

// 出力結果　"SUCCESS"
```

`api()`で`.SUCCESS`を返しており、`result`の中には`.SUCCESS`が入っているので、
結果として`"SUCCESS"`が返されます。

参考記事
[Swiftのクロージャによるコールバックの説明 - Qiita](https://qiita.com/maztak/items/ac668f5d8a47a46b8cb5)

間違っている点等あればご指摘いただけると幸いです。
【JavaScript】 海外Teck系YouTuberを真似てみた！(part 5) Typing Game

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/7533369e-2ef6-9b36-2243-819d852dc5dc.png" width="300">

#１，はじめに
この記事は、海外Teck系YouTuberの動画を参考に、同じプロジェクトを作成してみたものになります！
簡単にですが、動画を通して学べた技術や知識をまとめました！

今回の完成品は、下記に載せています:bangbang:

#２，学んだこと
**async await**の記述方法
**fetch**の記述方法

#３，参考動画
<iframe width="300" height="300" src="https://www.youtube.com/embed/R-7eQIHRszQ" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

#４，完成:tada:
![2021-08-14_19h06_55.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/c0f07400-b0af-0182-4cdd-2a63709adb2b.gif)
M1macでdocker pullしたときのエラー

個人メモ。

mysql:8をdocker pullしたときに下記のエラーが出力された。latestでも同じ。

```
latest: Pulling from library/mysql
no matching manifest for linux/arm64/v8 in the manifest list entries
```

https://docs.docker.com/docker-for-mac/apple-silicon/#known-issues

pullコマンドをオプション--platformをつけて実行する。

```
docker pull --platform=linux/x86_64 mysql:8
```

runするときにも同じオプションをつける。

```
docker run -d -it --platform=linux/x86_64 -e MYSQL_ROOT_PASSWORD=[任意のパスワード] mysql:8  
```

何回もrunする場合はdocker-composeファイルを書く。
https://stackoverflow.com/questions/65456814/docker-apple-silicon-m1-preview-mysql-no-matching-manifest-for-linux-arm64-v8

とはいえ前述のdockerのドキュメントによると、動くけどエミュレータ上で動かしてるから性能は落ちるので、M1チップでも動くイメージできるだけ使ってね、とのこと。
【iOS14】UITableViewをUICollectionViewに書き換える練習

UITableViewが非推奨の方向らしい？

https://twitter.com/takashings/status/1276102251849764864

資料を参考にすれど、む・・・むずかしい。

https://qiita.com/shiz/items/4227accc7d13ae439d1d

こういうときは、簡単なサンプルを書いてみようと思い
そういう事をされている方の記事を見つけました。

https://qiita.com/hiiragi252/items/70b02bf22bec51f3b97a

こちらの記事を参考させて頂き、今回はセクションを使わない
UICollectionLayoutListConfiguration.Appearance.plain
なものを作りたかったので、改変した結果がこちらです。
 
自分の分かる範囲では、Sectionは完全に消せなかったのでIntにして
layoutConfig.headerMode = .none としてみました。

【新しい疑問点】
dataSourceは新しくなったけどdelegateはそのまま？
=> そのままらしい

```swift
import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var collectionView: UICollectionView!

    let data = ["A", "B", "C"]

    var collectionViewDataSource: UICollectionViewDiffableDataSource<Int, String>!

    override func viewDidLoad() {
        super.viewDidLoad()

        var layoutConfig = UICollectionLayoutListConfiguration(appearance: .plain)
        layoutConfig.headerMode = .none

        let layout = UICollectionViewCompositionalLayout.list(using: layoutConfig)
        collectionView.collectionViewLayout = layout

        collectionViewDataSource = createDataSource()
        reloadList()
    }

    func createDataSource() -> UICollectionViewDiffableDataSource<Int, String> {
        let normalCell = UICollectionView.CellRegistration<UICollectionViewListCell, String> { (cell, indexPath, text) in
            var content = cell.defaultContentConfiguration()
            content.text = text
            cell.contentConfiguration = content
        }

        return UICollectionViewDiffableDataSource<Int, String>(collectionView: collectionView) {
            (collectionView, indexPath, text) -> UICollectionViewCell? in

            return collectionView.dequeueConfiguredReusableCell(using: normalCell, for: indexPath, item: text)
        }
    }

    func reloadList() {
        var snapshot = NSDiffableDataSourceSnapshot<Int, String>()
        snapshot.appendSections([0])
        snapshot.appendItems(data)
        collectionViewDataSource.apply(snapshot)
    }
}

```

![simulator_screenshot_4C5C79E2-9E70-4A5C-A989-3FAE112A802E.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6678/ae8f2268-aaa9-4df3-f5ec-fb5a297965fa.png)
【npm】キャッシュが壊れてnpm installに失敗する

# はじめに
久しぶりにcreate-react-appを叩いたら、失敗しました。
調べたことを簡単にメモメモ。
※認識間違っている所があれば、ご指摘お願いします。

# 現象
下記コマンド実行時にエラーが発生。
コマンド：
`npx create-react-app {プロジェクト名} --template typescript`

エラー：
`ERR! cb() never called!`

環境は以下の通り。
・OS  ：Docker上のUbuntu:20.04
・nvm ：0.38.0
・node：14.17.4
・npm ：6.14.14

# 原因
[まとめてくださっている記事](https://qiita.com/holdout0521/items/ebf836fc11e864177628)によると、どうやらnpmのキャッシュの不具合らしい。（キャッシュが壊れている？）
この現象は`create-react-app`に限ったものではなく、`npm install`でも発生するそうです。

#### npmのキャッシュとは？
[npmのDoc](https://docs.npmjs.com/cli/v7/commands/npm-cache)によると、
`npm install`によってインストールしたパッケージのhttpリクエストデータや、パッケージに関連するデータを格納している。らしい。
※英語の読解が甘いかもしれません。。。

また、
> The npm cache is strictly a cache: it should not be relied upon as a persistent and reliable data store for package data. npm makes no guarantee that a previously-cached piece of data will be available later, and will automatically delete corrupted contents. 

とありました。
内容としては、下記のようなことが書いてあります。
・npmのキャッシュは永続的で、信頼性の高いデータストアとして扱うべきではない。
・npmは以前にキャッシュしたデータに関して、後で利用可能なことは保証しない。
・破損したコンテンツを自動的に削除する。

最後の「自動的に削除する」というのはやって貰えていない気がしますが、ひとまず以前のキャッシュが正しくない場合は対応が必要になりそうです。



# 解決方法
キャッシュが壊れている場合は下記コマンド実行後、再度create-react-appを叩けばok。
`npm cache verify`

もし上記コマンドでうまくいかない場合は下記コマンドでキャッシュをクリアする方法でもうまくいくらしいです。
※こちらはverifyでうまくいったため、試してはいません。
`npm cache clean --force`
※手動でキャッシュをクリアする際は、`--force`で強制的に削除する必要があるようです。

# 参考
・[npm-cache](https://docs.npmjs.com/cli/v7/commands/npm-cache)
・[Node.js と npm 再入門（その４：便利コマンド）](https://lazesoftware.com/blog/180331/)
・[npm install実行時、 ERR! cb() never called!エラー対処](https://qiita.com/holdout0521/items/ebf836fc11e864177628)

以上ですー。
Arduino で HelloWorld

Arduino で Hello World を行う方法です。
ボーレートは 19200 にしました。

シリアルモニタに次の表示を出します。
![arduino_aa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/e4148cff-0bde-01c8-7f3f-19d21811f3ab.png)

## Arduino IDE の画面
![arduino_bb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/b347c817-91dc-644c-7979-8344f6925bb6.png)

## プログラム

```text:hello_world/hello_world.ino
// ---------------------------------------------------------------------
/*
	hello_world.ino

						Aug/15/2021
*/
// ---------------------------------------------------------------------
int count = 0;

void setup()
{
	// put your setup code here, to run once:

	Serial.begin(19200);
	Serial.println("*** start ***");
}

// ---------------------------------------------------------------------
void loop() 
{
	Serial.println("Hello World! " + String(count));
	delay(1000);
	Serial.println("Good Morning! " + String(count));
	delay(1000);
	Serial.println("こんにちは " + String(count));
	delay(1000);
	count++;
}

// ---------------------------------------------------------------------
```

## Arduino にプログラムを書き込んだあと、端末と通信する方法

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/c9234618-c862-211d-3565-c1ec479c73d7.png)

```text
$ cu -s 19200 -l /dev/ttyACM0
Connected.
*** start ***
Hello World! 0
Good Morning! 0
こんにちは 0
Hello World! 1
Good Morning! 1
こんにちは 1
Hello World! 2
Good Morning! 2
こんにちは 2
Hello World! 3
cu: Got hangup signal
```

>cu: Got hangup signal は、USB を端末から抜いたことで発生しています。
AtCoderログ：0076 - ABC 214 に参加しました

この記事は 2021年08月14日(土)21:00-22:40 に開催された [AtCoder Beginner Contest 213 (ABC 214)](https://atcoder.jp/contests/abc214) に参加した記録です。

# 問題
https://atcoder.jp/contests/abc214

# 結果
- 得点：600 (=100+200+300)
- 時間：60:36 (= 50:36 + 05:00 × 2)
- 順位：3761 / 8405
- パフォーマンス：668
- レーティング：307 → 354 (+47) Highest更新！
- 段級位：9級

![2021-08-14_abc214.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1589302/08d495ce-cfdf-09ec-0d2c-feb91c80367b.png)

# 詳細
|問題|得点|時間|提出コード|復習|
|:--:|:--:|:--:|:--:|:--:|
|[ABC 214 A](https://atcoder.jp/contests/abc214/tasks/abc214_a)|100|03:30|[○](https://atcoder.jp/contests/abc214/submissions/25022034)|[AtCoderログ：0078](https://qiita.com/RoadLynton/items/f9484704e348f334ea22)|
|[ABC 214 B](https://atcoder.jp/contests/abc214/tasks/abc214_b)|200|21:32|[○](https://atcoder.jp/contests/abc214/submissions/25034892)|[AtCoderログ：0080](https://qiita.com/RoadLynton/items/6e8f9b592e331bd9e7ca)|
|[ABC 214 C](https://atcoder.jp/contests/abc214/tasks/abc214_c)|300|50:36(2)|[○](https://atcoder.jp/contests/abc214/submissions/25044685)|[AtCoderログ：0082](https://qiita.com/RoadLynton/items/96771109d3be9993587d)|
|[ABC 214 D](https://atcoder.jp/contests/abc214/tasks/abc214_d)|400|---|---|---|
|[ABC 214 E](https://atcoder.jp/contests/abc214/tasks/abc214_e)|500|---|---|---|
|[ABC 214 F](https://atcoder.jp/contests/abc214/tasks/abc214_f)|600|---|---|---|
|[ABC 214 G](https://atcoder.jp/contests/abc214/tasks/abc214_g)|600|---|---|---|
|[ABC 214 H](https://atcoder.jp/contests/abc214/tasks/abc214_h)|600|---|---|---|

# 感想
- A, B, C まで完答できました。
- A, B は素直に回答して正解。
- C も素直な問題だったのですが、WA となる例を思いつくのに手間取ってしまいました。
- D を調べながら解いている所で時間切れ。何となくですが問題が8問になって D が勘案になった気がします (それでも手が出ない...)
 
# リンク
## 前後の記事
- 前の記事 → [AtCoderログ：0075 - ABC 085 C](https://qiita.com/RoadLynton/items/1316db69d335d0b3f38e)
GitHubのパスワード認証廃止でSourcetreeで403エラーが発生して解決策がわからなかったのでまとめておく

#目次
 - Sourcetreeで403エラー発生...
 - 何が起こっているか？
 - Github上で行ったこと
 - Sourcetree上の解決方法がわからなかった
   - ひとまずSourceTreeの認証をSSHに変更
   - 再度実行でエラー、最終的な解決方法

#Sourcetreeで403エラー発生...
403エラーが起こったのは2021/08/15でした。
いつもどおりSourcetreeで、コミットからプッシュしたときのこと。

![messageImage_1628946103425.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1893618/3b8d9090-5fca-3160-7903-6f9a6b1b893a.jpeg)

#何が起こっているか？
エラー発生の直接原因は403エラーですが、403エラーの原因は、以下のログにすべて書かれています。

```
remote:Support for password authentication was removed on August 13, 2021.Please use a personal access token instead.
```

早速Google英語翻訳してみました。

```
remote：パスワード認証のサポートは2021年8月13日に削除されました。代わりに、個人用アクセストークンを使用してください。
```
Githubで何かしらの変更があった可能性があるということだけはわかりました。
エンジニアの友人に聞いたところ、8月13日にGithubのパスワード認証が廃止になったとのことでした。

#Github上で行ったこと
以下の方の記事を参考に作業しました。
記事のとおりに作業すれば、Github上での作業は完了です。

[GitHubがパスワード認証を廃止するらしいので](https://qiita.com/shiro01/items/e886aa1e4beb404f9038)

#Sourcetree上の解決方法がわからなかった
トークンの設定もできたし、もう大丈夫だろうと再度Sourcetreeからプッシュしてみると、まだ403エラーが発生しました。

##ひとまずSourceTreeのSSHクライアントを変更
[ツール]→[オプション]→[全般]→[SSHクライアントの設定]から、[SSHクライアント]を「OpenSSH」に変更します。
SSHキーの場所は~/ssh/id_*****です。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1893618/7252875d-4789-9245-db98-001b98fa71d2.png)

##再度実行でエラー、最終的な解決方法
リモートのパスを書き換えなければいけませんでした。
私はこれに3時間考え続けてました...（終わってみれば馬鹿だなあと思います笑）

SourceTreeの画面右上の設定をクリック。
![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1893618/2f898fb5-6921-7ec3-ae5a-2c298902c8b9.png)

表示されているリモートリポジトリを選択して、[編集]をクリック。
![b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1893618/b61b8f03-7b5c-ba9f-e7f3-c0f7b7064454.png)

こちらの画面の[URL/パス]を書き換えます。
![c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1893618/538d0f21-b431-1758-77ef-0fba17cd192f.png)

書き換え方は以下です。
通常どおり設定している方は以下のようになっているかと思います。

```
https://github.com/[ユーザ名]/[リポジトリ名].git
```

「https://」と「github.com...」の間にGithubの[Setting]→[Developer Settings]→[Personal access tokens]からコピーできるアクセストークンを貼り付けて末尾に「@」を追加する。

```
https://[アクセストークン]@github.com/[ユーザ名]/[リポジトリ名].git
```

以上、こちらで解決しました。
少しでもお役に立てれば、幸いです。
Pythonのバージョンを簡単に切り替えられる！pyenvのチートシート

pyenvでトラブルがあったこともあり、[README.md](https://github.com/pyenv/pyenv/blob/master/README.md)と[Command Reference](https://github.com/pyenv/pyenv/blob/master/COMMANDS.md)を読んだので、備忘録として使い方をまとめてみました！

######  参照元
- 2021年7月27日が最終更新の[README.md](https://github.com/pyenv/pyenv/blob/master/README.md)
- 4月9日が最終更新の[Command Reference](https://github.com/pyenv/pyenv/blob/master/COMMANDS.md)



# そもそもpyenvとは
- いくつもあるPythonのバージョンをPCに複数入れて、その時々で切り替えて使いえたらいいな
- バージョンをいくつも入れ過ぎてカオスになってきた！整理したい！

という時に活躍する、複数バージョンを整理して管理できるツール？です。
入れると確実に使いやすくなります。

Pythonの色々な環境を構築してみては消してみた私が今現在、最も使いやすいと感じている管理方法です。


# コマンドチートシート
### まずpyenvそのものをインストール
Homebrewを使ってインストールするなら、ターミナルに以下を入力する。

```terminal
$ brew install pyenv
```



### pyenvでインストールすることができるバージョン一覧表示
pyenvが入っていることが確認できたら、以下のコマンドでAnaconda、Jython、pypy、stacklessなど、利用可能なすべてのPythonのバージョンを一覧表示することができる。

```terminal
$ pyenv install --list
```
ずらっと出る大量のバージョンから、入れたいバージョンを決めよう。


### Pythonの特定のバージョンをインストールする方法
`$ pyenv install --list`をして、インストールしたいバージョンが見つかったら、そのバージョン名を使って以下を入力してインストールしよう。

```terminal
$ pyenv install 入れるバージョン名
```


### pyenvでインストールした特定バージョンをグローバルに指定する方法
使いたいバージョンをインストールしたら、グローバルのバージョンを切り替えないと使えない。
以下のコマンドで切り替えよう。

```terminal
$ pyenv global 使いたいバージョン名
```

これを実行すると~/.pyenv/versionファイルにバージョン名を書き込むことにより、すべてのシェルで使用されるPythonのグローバルバージョンを設定してくれるらしい。

複数指定することもできるらしい。
それで実際に使うバージョンはどうやって指定するんだろうか。。同時使用ができるとか？ここは詳しく書いてなくてわからな買った。また調べてみます。



### pyenvで管理中のpythonバージョン一覧を表示
これまで、pyenvでインストールしたPythonのすべてのバージョンと、アクティブなバージョンを表示するコマンドと、その出力結果の例。
アスタリスク(＊)がついてるバージョンが、今Globalに指定されているバージョン。

```terminal
$ pyenv versions
  system
* 3.7.5 (set by /Users/saya/.pyenv/version)
  3.9.5
```



### pyenvで入れた特定のバージョンを消したい
これまでpyenvでインストールしたPythonのバージョンのうち、いらないものを消すコマンド。

```terminal
$ pyenv uninstall 消すバージョン名
```
GitHub Error "Support for password authentication was removed. Please use a personal access token instead." for windows

パスワード認証の有効期限が2021年8月23日までらしく、アクセストークンを利用したログイン方法に変更する必要があるとのこと。

## エラー内容

```cmd
PS C:\XXXXXXXX/XXXXXXXX/XXXXXXXX/XXXXXXXX.git/> git push
Logon failed, use ctrl+c to cancel basic credential prompt.
remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.
remote: Please see https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/ for more information.
fatal: unable to access 'https://github.com/XXXXXXXX/XXXXXXXX.git/': The requested URL returned error: 403
```

## 結果

以下を実施することで、いつも通りに利用できるようになりました。

- githubで二段階認証のを設定。
- githubでアクセストークン(repo権限)を発行。
- Windows資格情報のパスワードをアクセストークンに変更。

## 実施内容の詳細

### 二段階認証の有効化

エラーログのURLを確認し、二段階認証を有効化しました。

→[github blog](https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/)

スマホの認証アプリは`google 認証システム`を利用しました。

```text
Go to setting from github => Account security => Two-factor authentication => Enable
```

### アクセストークンの発行

有効期限は無期限も設定できるようです。

```text
Go to setting from github => Developer settings => Personal access tokens => Generate new token
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238338/2373d0d9-1139-b105-fec9-6c3d3998cf9b.png)

アクセストークンはこちら

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238338/00c2ac67-78cb-e7d4-db3d-49ca574d96bc.png)

### windows認証情報の修正

```text
Go to Credential Manager from Control Panel => Windows Credentials => find git:https://github.com => Edit => On Password replace with with your Github Personal Access Taken => You are Done
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238338/7f778bfb-1280-590a-1dbe-44839cd096e8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238338/e8462664-285b-cb12-d53e-91e03e390b0e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238338/012741c4-c8c6-3835-7838-ee0943baf92a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238338/9052c747-ea13-02c4-270c-3ec3c24b25b2.png)

`パスワード`に`githubで発行したアクセストークン`を設定する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238338/22dd79ae-1152-f6a8-2b0a-ba0549837bea.png)

以上です。
Selenium（JavaScript環境）のtakeScreenshotでエラーが出たときの対応


JavaScript環境でScreenshot撮ろうと思ったらエラーが出たので対応メモ。

### 場所の準備

```
cd
mkdir ss_test
cd ss_test

npm install selenium-webdriver chromedriver dayjs
```

>dayjsはおまけ。

### 実装

```js
const { Builder, By } = require("selenium-webdriver");
require("chromedriver");
const fs = require("fs");
const dayjs = require("dayjs");

(async()=>{
    const driver = await new Builder().forBrowser("chrome").build();
    await driver.get("http://www.yahoo.co.jp");
    const img = await driver.takeScreenshot();
    const fileName = "evicence_" + dayjs().format("YYYYMMDDHHmmss") + ".png";
    await fs.writeFileSync(fileName,img,"base64");
    await driver.quit();
})();
```

### エラー

ECONNREFUSED connect...的なエラーが出た。


### 原因と対応

どうやらwebdriver-managerなるもんが起動してないことによるものらしい。

```bash
npx webdriver-manager start --standalone
```
MuleSoft日本語の学習リソース

### MuleSoftの概要

https://www.youtube.com/watch?v=b9b6IU4h72g

### 公式開発ドキュメント

https://docs.mulesoft.com/jp/general/

### 資格トレーニング

https://training.mulesoft.com/course/development-fundamentals-mule4-japanese

https://training.mulesoft.com/course/development-fundamentals-mule4/quiz-diy-japanese

### MuleSoftの公式資格(MuleSoft Certified Developer)ー日本語で受験できます

https://training.mulesoft.com/certification/developer-mule4-level1-japanese

有効期間は2年間で、有効期間を延長するにはメンテナンス試験を受ける必要があります。メンテナンス試験は1回まで無料で受けられます。

https://training.mulesoft.com/certification/developer-mule4-level1-maintenance-japanese
【Ruby on Rails】Time.currentメソッドを使って簡単に時間表示をする方法


#対象者

* 時間の表示方法を知りたい方


#目的

* Time.currentメソッドを使って時間を表示する

#実際の手順と実例
###1.結論

**Time.current**メソッドを使えば簡単に時間が表示できます。
rails cで確認すると

````
$ rails c
Running via Spring preloader in process 6425
Loading development environment (Rails 5.2.6)
[1] pry(main)> Time.current
=> Sat, 14 Aug 2021 23:20:51 UTC +00:00
[2] pry(main)> 
````

上記のように今日の時間が取得できます。


###2.応用編

```
Time.current.all_month #今月
Time.current.all_week  #今週
Time.current.all_day   #今日
```


#参照

>[時刻や日付を扱うメソッドの基本情報まとめ【Ruby】【Rails】](https://fuchiaz.com/ruby-rails-time-date/#Time)


####投稿者コメント

時間どのように表示すればいいんだろうって前に悩んでたんですけど、これで一発なんですね。。。勉強になりました。。。


####My Profile
プログラミング学習歴３ヶ月目のアカウントです！
プログラミングスクールで学んだ内容や自分が躓いた箇所等のアウトプットの為に発信しています。
また、プログラミング初学者の方にわかりやすく、簡潔にまとめて情報共有できればと考えています。
もし、投稿した記事の中に誤り等ございましたら、コメント欄でご教授いただけると幸いです。
Swift NSAttributedString 

NSAttributedString
--
storyboardやUILabelのプロパティを操作して装飾をすることができるが、NSAttributedStringを使用することでより細かい装飾をすることができる。

 辞書型で指定した文字列の装飾をNSAttibutedStringの引数にいれることによって描画できる

```swift
var dictionary:[NSAttributedString.Key: Any] = [
        NSAttributedString.Key.font: NSFont.systemFont(ofSize: 40),
        NSAttributedString.Key.foregroundColor: NSColor.orange,
        NSAttributedString.Key.strokeColor: NSColor.black,
        NSAttributedString.Key.strokeWidth: -3
    ]
//辞書型を引数(attributeds)に入れる。
let attrString = NSAttributedString(string: "Swift", attributes: dic)
```

storyboardだとどうしてもうまく表現されないことも多々あったり、動的に文字列をうまく変更したい場合はよく使うものかな
それぞれのvalueは色が入ったり、サイズが入ったり、セットで描画されるのもあるので拡張機能として、再利用可能な形にしてから使い回す使用方法が多い。
[Android]思考停止で使っていたViewBindingを掘り下げる

#ViewBindingとは？
>ビュー バインディングとは、ビューを操作するコードを簡単に記述できる機能です。

簡単に言語化すると「簡単操作」です。
ViewBindingはappモジュール内で設定すると、ファイルの数だけバインディングクラスという「仲介役」が静的に？生成されます。

そうすることで、xmlファイル内の（ID名のあるViewのみ）Viewを簡単にクラスから参照でき、簡単に「操作」出来るわけです。

ちなみに、生成されたバインディングクラスの名前は、xmlファイル名のキャメルケースになります。


#設定
```gradle:build.gradle(app)
android {
      // (省略)

     viewBinding {
          enabled = true
   }
}
```
モジュール単位で設定すると前述したので、このように。

#使い方
###Activityで用いる場合
```kotlin
private lateinit var binding : MainActivityBinding

// (省略)
    override fun onCreate(savedInstanceState: Bundle) {
        super.onCreate(savedInstanceState)
        binding = MainActivityBInding.inflate(layoutInflater)
        setContentView(binding.root)
    }
```
inflateメソッドで、バインディングクラスのインスタンスを生成していることになります。
そして、getRootメソッドでルートビューの参照を取得します。
それをいつものようにsetContentViewにセットすれば、画面レイアウトの生成が完了です。

###Fragmentで用いる場合
殆どActivityと同じなのですが、FragmentのライフサイクルはViewよりも長いので少し手を施す必要があります。
onDestroyViewで、Viewの参照を止める必要があります。
ドキュメントの書き方も、まぁ目的は達成しているのですが、手動でクラッシュ回避しているのと若干冗長できなので、自動で出来る方法を下記に記します。

https://github.com/DroidKaigi/conference-app-2020/pull/294/files#diff-1820f2621c3c6a75287e876d8d3a8c8ec0044e77a89a2a18fd11553d5ac403e1

```kotlin
var binding by autoCleared<HogeFragmentBinding>()
```
こちらで、初期化すればViewが破棄されると同時にバインディングの参照もクリーンアップされます。


#終わりに
inflateとfragmentのライフサイクルについて深堀したいな。

#参考

https://developer.android.com/topic/libraries/view-binding?hl=ja
画像のアップロード【PHP】

##はじめに
PHPで画像のアップロードから表示までの一連の処理を
備忘録としてこちらまとめさせていただきます。

##手順
①FORMから画像を選択してPOSTで送信
②送信した画像が存在するかチェック
③ファイル名をユニーク化
④画像ファイルかのチェック
⑤DBではなくサーバーのimageディレクトリに画像を保存
⑥DBにはファイル名保存
⑦DBのファイル名を元に画像表示

##ファイル構造
```
test
|-images(画像ファイル保存ディレクトリ)
|-image.php（画像表示ファイル）
|-upload.php（画像アップロード処理するファイル）
```

##画像アップロード処理するファイル(upload.php)
**①FORMから画像を選択してPOSTで送信**

```ccp:upload.php
<form action="upload.php" method="POST" enctype="multipart/form-data">
  <input type="file" name="image">
 　　<button><input type="submit" name="upload" value="送信"></button>
</form>

```

**②~⑥**

```ccp:upload.php
<?php
$dsn = "mysql:host=localhost; dbname=xxx; charset=utf8";
$username = "xxx";
$password = "xxx";

try {
    $dbh = new PDO($dsn, $username, $password);
} catch (PDOException $e) {
    echo $e->getMessage();
}

if (isset($_POST['upload']))　{
　　　　　　　　$temp_file = $_FILES['image']['tmp_name'];
　　　　　　　　$dir = './images/';

	if (file_exists($temp_file)) {//②送信した画像が存在するかチェック
		$image = uniqid(mt_rand(), false);//③ファイル名をユニーク化
		switch (@exif_imagetype($temp_file)) {//④画像ファイルかのチェック
			case IMAGETYPE_GIF:
				$image .= '.gif';
				break;
			case IMAGETYPE_JPEG:
				$image .= '.jpg';
				break;
			case IMAGETYPE_PNG:
				$image .= '.png';
				break;
			default:
				echo '拡張子を変更してください';
		}
        //⑤DBではなくサーバーのimageディレクトリに画像を保存
		move_uploaded_file($temp_file, $dir . $image);
	}
　　　　 　　　//⑥DBにはファイル名保存
    $sql = "INSERT INTO images(name) VALUES (:image)";
    $stmt = $dbh->prepare($sql);
    $stmt->bindValue(':image', $image, PDO::PARAM_STR);
    $stmt->execute();
}

?>
```
##セキュリティ
**画像アップロード**
ファイルアップロードを使った攻撃があり、悪意あるコードを注入した不正ファイルをアップロードし、そのファイルにアクセスすることで成立する。この攻撃は、XSSを使って第三者に接続させる方法や攻撃する側が自らサーバにコードを注入して実行させる方法がある。

脆弱性を防ぐために...
1.アップロードされたファイルを非公開ディレクトリに移す(悪意あるスクリプトを実行できなくする)
2.アップロードされたファイル名をrenameする(拡張子などを変えることによって悪意あるスクリプトを実行できなくする)

##画像表示ファイル（image.php）
**⑦DBのファイル名を元に画像表示**

```ccp:image.php
<?php
$dsn = "mysql:host=localhost; dbname=xxx; charset=utf8";
$username = "xxx";
$password = "xxx";
$id = 1;

try {
    $dbh = new PDO($dsn, $username, $password);
} catch (PDOException $e) {
    echo $e->getMessage();
}
//⑦DBのファイル名を元に画像表示
$sql = "SELECT * FROM images WHERE id = :id";
$stmt = $dbh->prepare($sql);
$stmt->bindValue(':id', $id);
$stmt->execute();
$image = $stmt->fetch();
?>

<h1>画像表示</h1>
<img src="images/<?php echo $image['name']; ?>" width="300" height="300">

```

##まとめ
画像アップロード自体は簡単にできます。ですが、脆弱性を意識しながらコードを書こうとすると様々な書き方があり、それを読み解くことでセキュリティに対しての理解を深めることができました。
AppCenterのReleaseIdを取得する方法

jenkinsの App CenterプラグインだとreleaseIDが取得できなかったので、方法を模索。

したところ、App Center CLIが結局必要だった。(jenkinsのプラグインだけでは厳しい）
配布した後に、そのAPPページの最新リリースIDを取得するという方法。

```
RELEASE_ID=`appcenter distribute releases list --app $OWNER_NAME/$APP_NAME --token $APPCENTER_API_TOKEN --output json | jq '. | sort_by(.uploadedAt) | reverse | .[0].id'`
echo $RELEASE_ID
```

https://docs.microsoft.com/ja-jp/appcenter/cli/
git configするときにユーザー名/パスワード入れてアクセスする方法

```
git config submodule名 "https://user名:パスワード@gitのURL"
```
ユーザー名や、パスワードに@などが入っている場合は、URLエスケープする必要がある。

参考：[TECHNICAL MANUAL](https://www.seil.jp/doc/index.html#tool/url-encode.html)

例えば、user名にメアドが入ってたりしたら(user@hogex.co.jp)

```
git config submodule名 "https://user%40hogex.co.jp:パスワード@gitのURL"
```

みたいな感じ。
Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.　エラーが発生したら

日本時間で8/15 6:00くらいに、自身レポジトリにgit pushしようとしたら
以下のようなエラーが発生しましたので残します。

```
git push
remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.
remote: Please see https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/ for more information.
fatal: unable to access 'https://github.com/zukaishi/linebot.git/': The requested URL returned error: 403
```

# 解決方法
![20210815_gittokens_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188508/7d9646fd-d075-9963-9bde-838ed4ba3a84.png)

右上のアイコンクリック　→ 「Settings」→ 「Developer settings」 →「Personal access tokens」の順番でクリック。
その後、「Generate new token」クリックで、トークンを発行。コピーする。

## 2021/9/14追記
https://docs.github.com/ja/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token

![Screen Shot 2021-09-14 at 8.17.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188508/fecf383e-925c-793e-ea37-f71f1b9aef03.png)

コピーしたtokenをpassword求められる時に貼り付けて完了。
以下の手順はGUIで対応する時の場合だったみたいです。




![20210815_token_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188508/58f96bb8-5de6-ac90-4ec5-e07ba38e873d.png)

ローカルで、キーチェーンアクセスから、githubを検索。
github.comをクリックし、パスワードを表示にチェック。ロックを解除すると現在のパスワードが表示される。
先ほどコピーしたトークンを、候補のところに貼り付けて、保存。
これでいつも通りgit pushできました。


# 参考
https://zenn.dev/suzuki_hoge/articles/2021-08-github-access-f732e5b9868137
Info.plistからバージョン情報を取得する

バージョン情報の取得方法

# VersionNameの場合(1.2.3.4的なやつ）
```
VERSION_NAME=(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" hoge.app/Contents/Info.plist`)
echo $VERSION_NAME
```
VersionCodeの場合は、CFBundleShortVersionStringをCFBundleVersionに置き換える。
画像Idファイルと画像同士の経路ファイルからランダムな移動パターン画像リストを作成するPGM

<h3>画像Idファイルと画像同士の経路ファイルからランダムな移動パターン画像リストを作成するPGM</h3>

画像Idファイルと画像同士の経路ファイルからランダムな移動パターン画像リストを作成するPGMを作成しました
<hr>
githubURL:https://github.com/NanjoMiyako/pathAndImage

<hr>
使い方

画像Idファイルと画像同士の経路ファイルを作成し、以下のコマンドライン引数を指定して
PGMを実行します

python PathAndImage.py 画像Idファイルのパス 画像同士の連結経路データファイルのパス  出力ファイル名 経路移動回数

画像Idファイルの形式
画像Id名, 画像ファイルのURL
（以下同様の行が続く)...

画像同士の連結経路データファイルの形式
移動元画像Id名,移動可能画像Id1, ..., 移動可能画像Idn
（以下同様の行が続く)...

<hr>
参考にしたサイト
<a href="https://www.javadrive.jp/python/file/index3.html#section1">Python | テキストファイルへ書き込む</a>
<a href="https://techacademy.jp/magazine/15821">ランダムに出力！Pythonでrandomを使う方法【初心者向け】 | TechAcademyマガジン</a>
<a href="https://atmarkit.itmedia.co.jp/ait/articles/2012/25/news023.html">［解決！Python］リスト（配列）の使い方まとめ：解決！Python - ＠IT</a>
<a href="https://www.python.ambitious-engineer.com/archives/670">map関数 listの全て要素に対して同じ処理を行う | Python学習講座</a>
C から ECPG を使って PostgreSQL に接続してみる

C から ECPG を使って PostgreSQL に接続するプログラムの作成方法について説明します。

環境は CentOS 7 または 8、PostgreSQL 9.6 以降を対象とし、PostgreSQL に接続できる状態になっていることを前提とします。PostgreSQL のインストールや設定がまだであれば、インストール方法は [こちらの記事](https://qiita.com/tom-sato/items/e1903cb974fb6c6d5664)、ローカルホスト以外からの接続受けつけに必要な設定方法は [こちらの記事](https://qiita.com/tom-sato/items/d5f722fd02ed76db5440) を参照してください。

1. GCC、PostgreSQL ヘッダファイル・開発ライブラリをインストールします。

    CentOS 7 で PostgreSQL 11 以降の場合には、EPEL、SCL リポジトリをインストールします。理由は [こちらの記事](https://qiita.com/tom-sato/items/b5f1263911fdedd5e81b) を参照してください。

    ```shell-session:CentOS&nbsp;7&nbsp;の場合
    $ sudo yum install -y epel-release centos-release-scl
    (省略)
    Complete!
    ```

    続いて、GCC、PostgreSQL ヘッダファイル・開発ライブラリをインストールします。

    ```shell-session
    $ sudo yum install -y gcc postgresql13-devel
    (省略)
    Complete!
    ```

    パッケージ名に含まれる `13` は PostgreSQL のバージョンです。ご自身の環境に合わせて書き替えてください。バージョン 9.6 以前は `96` のように 2 つの数字からなるバージョンから . を取り除いたものとなります。

1. プログラムを作成します。

    プログラムの内容はデータベースの一覧を出力するというものです。エラー処理は原因特定に必要最低限のことしか行っていません。

    ```c:test_ecpg.pgc
    #include <stdio.h>
    #include <stdlib.h>
    
    EXEC SQL WHENEVER SQLERROR CALL die();
    EXEC SQL WHENEVER NOT FOUND DO BREAK;
    
    void
    die(void)
    {
        fprintf(stderr, "%s\n", sqlca.sqlerrm.sqlerrmc);
        exit(1);
    }
    
    int
    main(void)
    {
        EXEC SQL BEGIN DECLARE SECTION;
        const char *target = "postgres@localhost:5432";
        const char *user = "postgres";
        const char *passwd = "password";
        char dbname[64];
        EXEC SQL END DECLARE SECTION;
    
        EXEC SQL CONNECT TO :target USER :user USING :passwd;
        EXEC SQL DECLARE cur CURSOR FOR SELECT datname FROM pg_database;
        EXEC SQL OPEN cur;
        while (1)
        {
            EXEC SQL FETCH cur INTO :dbname;
            printf("%s\n", dbname);
        }
        EXEC SQL CLOSE cur;
        EXEC SQL COMMIT;
        EXEC SQL DISCONNECT ALL;
    
        return 0;
    }
    ```

    ホスト変数の `target` には `データベース名@ホスト名:ポート` 形式で接続先、`user` にはユーザ、`passwd` にはパスワードを指定します。ご自身の環境に合わせて書き替えてください。

1. プログラムをビルドします。

    ```shell-session
    $ /usr/pgsql-13/bin/ecpg test_ecpg.pgc
    $ gcc -Wall -I/usr/pgsql-13/include -L/usr/pgsql-13/lib -lecpg -o test_ecpg test_ecpg.c
    ```

    `-I`、`-L` オプションにはそれぞれ PostgreSQL ヘッダファイル、開発ライブラリ格納先のパスを指定します。パスに含まれる `13` は PostgreSQL のバージョンです。ご自身の環境に合わせて書き替えてください。

    エラーメッセージが出力されず、C プログラム `test_ecpg.c` が生成され、そこから実行ファイル `test_ecpg` が生成されれば、プログラムのビルドは成功です。

1. プログラムを実行します。

    ```shell-session
    $ ./test_ecpg
    postgres
    template1
    template0
    ```

    エラーメッセージが出力されず、データベースの一覧が出力されれば、プログラムの実行は成功です。

以上でプログラムの作成は完了です。
NVIDIA Jetson nano 2G 開封の儀とセットアップ

機械学習が行える NVIDIA Jetson nano 2G が60ドルというお手軽価格で手に入るので購入してみました。

こんな感じでカメラを接続したら物体を検知できるようです。
![IMG_20210814_134558.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33704/532a96e1-f65a-d657-2c0a-59c3653ee9a4.jpeg)

Jetsonと合わせてこちらの書籍も購入。上の写真はこの本のものです。
[Jetson Nano 超入門](https://www.amazon.co.jp/dp/B082SN87QP)

それでは開封と起動までの設定を行っていきます。

![DSC01739.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33704/f3a80cc2-d393-95ff-17b9-7e8ecd979555.jpeg)

![DSC01741.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33704/d588eea0-44b8-2427-c60c-6fe8c9ee642f.jpeg)

![DSC01742.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33704/15476003-9b48-931a-7ecd-bcc55db98c5f.jpeg)

高さのあるラズパイみたいな感じですね。

他のチップを並べて比較してみます。

![DSC01744.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33704/0ab96f6b-2cdc-d0e0-8b02-0b3ce5087f86.jpeg)

Jetson nano と Raspberry Pi nano が上下に並ぶと、ナノとは何なの？という複雑な気持ちになります。

## JetPack(OS)のインストール

Jetson は JetPack という NVIDIA の OS で動きます。それをSDカードに書き込んで Jetson に刺すと動きます。Raspberry Pi で Linux を動かすのと同じです。

まずはOSイメージをダウンロードします。
[NVIDIA JETPACK SDK](https://developer.nvidia.com/embedded/jetpack)

![2021-08-14_14h18_17.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33704/ff1ef8af-7895-948d-475a-55308af13c75.jpeg)

次にSDカードにOSイメージを書き込むツールをダウンロードしインストールします。
[balenaEtcher](https://www.balena.io/etcher/)
![2021-08-14_14h23_36.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33704/47b9c035-52f9-7aee-a259-0a8d6915496d.jpeg)

あとはSDカードをPCに刺してbalenaEtcherを起動してOSイメージを書き込めば完了！
![2021-08-14_14h25_50.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33704/acc556c5-996a-d608-6a7f-805833f0f334.jpeg)

## JetPack の起動
SDカードを刺して
![DSC01748.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33704/e0559e49-33b5-bf94-66c6-e66faa902b25.jpeg)

キーボード、マウス、LANケーブル、HDMIケーブルを繋ぎ
![DSC01749.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33704/5b6b4de8-b96a-2785-0aca-94fdcc67a2d9.jpeg)

電源ケーブルを繋いだらJetsonが起動します！
![DSC01753.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33704/78b16409-cd4c-32eb-f514-f70bd02245f0.jpeg)

初回起動時にはアカウントやら言語やらリージョンやらをポチポチする必要があります。

## おわり
さて、何をやりますか？とりあえずUSBカメラを繋いで画像認識かな？イケてるコーヒー豆とイケてないコーヒー豆の選別ってのをやってみたいんだよねぇ。その場合はJetsonで学習データも作るのかな。

![234628914_10226741424667206_6390951032398761740_n.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33704/a2362456-0a4e-dce1-b0a7-f2fd042dc3c7.jpeg)
Vue Router, Vuexまとめ

#Vue Router

##手順
Vue.jsとVue Routerの読み込みを行う
↓
リンクを作成するために
router-linkコンポーネント＝ページ遷移する時に使うものでレンダリングされるとaタグになる
↓
リンク先に紐づいた内容を表示するために
router-viewコンポーネント＝コンテンツが描画される
↓
コンポーネントの設定
↓
Routerインスタンスを生成をしてroutesオプションにpathとcomponentを記述することでルーティング設定を行う
↓
上記を全て行うことで
ページ遷移した時にページ全体は更新されずに部分的に切り替わる

##Vue CLIでのVue Routerの設定
App.vue（全体に適用される場所）にrouter-linkを追加           （リンクを作成）

viewsディレクトリの下にファイルを作成する                      （リンクの中身を作成）

/router/index.jsでpath:とname:の設定をしてvueの読み込み処理を書く
（ルーティングの追加）

#Vuex
##手順
JavaScript: 画像から色を抽出してくれるColor Thief

[10 Trending projects on GitHub for web developers - 13th August 2021](https://dev.to/iainfreestone/10-trending-projects-on-github-for-web-developers-13th-august-2021-4bf2) で紹介されていた Color Thief というもの。

https://lokeshdhakar.com/projects/color-thief/#examples

https://github.com/lokesh/color-thief

「例」引用: 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/6e985eb5-208e-b8b0-7432-396c3d40d91f.png)


## 画像から色を抽出してくれる Color Thief

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/9cf331a1-f247-f272-5c93-594916e93f0c.png)


お試し。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
</head>
<body>

<h2>https://lokeshdhakar.com/projects/color-thief/<h2>
<img id="thomas" src="thomas.png" width=30% height=30% crossorigin="anonymous" />
<label id="label1">Do you like Train?</label>
<img id="scene" src="lime.jpg" width=40% height=40% crossorigin="anonymous" />
<label id="label2">So beautiful.</label>

<script src="https://cdnjs.cloudflare.com/ajax/libs/color-thief/2.3.0/color-thief.umd.js"></script>
<script>
    const colorThief = new ColorThief();
    const img1 = document.querySelector('img#thomas');
    var color;
    // Make sure image is finished loading
    if (img1.complete) {
      color = colorThief.getColor(img1);
    } else {
      image.addEventListener('load', function() {
        color = colorThief.getColor(img1);
      });
    }
    var rbg = color[0] + "," + color[1] + "," + color[2];
    document.getElementById("label1").style.color = "rgb("+ rbg +")" ;//機関車の画像の色
    
    
    const img2 = document.querySelector('img#scene');
    if (img2.complete) {
      color = colorThief.getColor(img2);
    } else {
      image.addEventListener('load', function() {
        color = colorThief.getColor(img2);
      });
    }
    rbg = color[0] + "," + color[1] + "," + color[2];
    document.getElementById("label2").style.color = "rgb("+ rbg +")" ; //レモンの画像の色
</script>
</body>
</html>
```

## Trouble using Color Thief?

[疑問があったらStackoverflowを使おうという潔さ](https://lokeshdhakar.com/projects/color-thief/#support)

> 1. Search Stackoverflow to see if other people have run into the same issue you are having.
> 2. If your issue is unique, then post a new question on Stackoverflow. Use the color-thief tag to make it easier to find.

> 1.Stackoverflowを検索して、あなたが抱えている問題と同じ問題に他の人が遭遇していないかを確認しましょう。
> 2.問題がみつからない場合は、Stackoverflowに新しい質問を投稿しましょう。検索しやすいようにcolor-thiefタグを使いましょう。


以上、触ってみたところのメモ書きです。参考になればさいわいです。
[2021年]githubにHTTPSアクセスで拒否される場合


# 何が起こったか
どうやらgithubのログインID/PWでのアクセスをセキュリティが低いとして無効化されてしまったようです。
その際のメッセージがこちら

```
remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.
remote: Please see https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/ for more information.
fatal: unable to access 'https://github.com/repo': The requested URL returned error: 403
```

# 対応

対応方法は書いてあるとおり、https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/ にアクセスして設定したトークンを取得するだけです。

詳細はこちら

https://docs.github.com/ja/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token

一応転記しておきます。

> まだ検証していない場合はメールアドレスを検証します。
> 
> 任意のページの右上で、プロフィール画像をクリックし、続いてSettings（設定）をクリックしてください。
> ユーザバーの [Settings（設定）] アイコン
> 
> 左サイドバーで [Developer settings] をクリックします。
> 開発者設定
> 
> 左のサイドバーでPersonal access tokens（個人アクセストークン）をクリックしてください。
> 個人アクセストークン
> 
> [Generate new token] をクリックします。
> [Generate new token] ボタン
> 
> トークンにわかりやすい名前を付けます。
> トークンの説明フィールド
> 
> このトークンに付与するスコープ、すなわち権限を選択します。 トークンを使用してコマンドラインからリポジトリにアクセスするには、[repo] を選択します。
> 
> トークンスコープの選択
> 
> [Generate token] をクリックします。
> [Generate token] ボタン
> 
> をクリックしてトークンをクリップボードにコピーします。 セキュリティ上の理由から、ページから移動した後は、トークンを再度表示することはできません。
> 
> 新しく作成されたトークン
> 
> 警告: トークンはパスワードのように扱い、秘密にしてください。 API を操作する場合は、トークンをプログラムにハードコーディングするのではなく、環境変数として使用してください。
> 
> SAML SSO を使用する Organization への認証にトークンを使用するには、Organization への SAML シングルサインオンに使用できるようトークンを認証します。

そして通常通りgit cloneをHTTPSで行いパスワードのフェーズでトークンを入力するだけです。
毎回、入力が必要になるのが嫌だ！と思う人もいると思うのでそういう人は

`git https credential helper`

でググると幸せになれると思います。

まぁぶっちゃけ
`git config --global credential.helper store` とか打っておけば大概なんとかなりますがセキュリティとか気になる人は自分で調べてください。