OmniAICreator/Qiita-1.07M huggingface dataset:
Game of Pods攻略(Tyro編)

# Game of Pods攻略~Tyro~
redisHAクラスターの構築です

Game of Pods関連のソースコードを挙げてます
https://github.com/hayama17/Game-of-Pods

# 作りたい環境
+ jekyll-SSG
    + PVC
        + PVはすでに作成済み
    + NodePort
        + targetport: 4000
        + port: 8080
        + NodePort: 30097
* user
    * ロールの作成
    * ロールの適用 

# PVCの作成からサービス作成まで

要件通りに作成
namespaceを統一しないとDNSが上手く動作しない...
## PVC

```yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: jekyll-site
  namespace: development
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
```

## Pods
```yaml
apiVersion: v1
kind: Pod
metadata:
  name: jekyll
  namespace: development
  labels:
    run: jekyll
spec:
  initContainers:
    - name: copy-jekyll-site
      image: kodekloud/jekyll
      command: [ "jekyll", "new", "/site" ]
      volumeMounts:
        - name: site
          mountPath: /site
  containers:
    - name: jekyll
      image: kodekloud/jekyll-serve
      volumeMounts:
        - name: site
          mountPath: /site
  volumes:
    - name: site
      persistentVolumeClaim:
        claimName: jekyll-site
```

## Service
```yaml
apiVersion: v1
kind: Service
metadata: 
  name: jekyll
  namespace: development 
spec:
  type: NodePort
  selector:
    run: jekyll 
  ports:
    - name: jekyll
      protocol: TCP
      nodePort: 30097
      targetPort: 4000
      port: 8080
```

# ロールの作成と適用
namespaceを忘れずに適用、ロールがアクセスできるリソースは作成した要件通りに

```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: development
  name: developer-role
rules:
- apiGroups: [""] # "" はコアのAPIグループを示します
  resources: ["pods","services","persistentvolumeclaims"]
  verbs: ["*"]
```
ロールの適用

```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: developer-rolebinding
  namespace: development
subjects:
- kind: User
  name: drogo
  apiGroup: rbac.authorization.k8s.io
roleRef:
  # 「roleRef」はRole/ClusterRoleへのバインドを指定します
  kind: Role #RoleまたはClusterRoleである必要があります
  name: developer-role # これはバインドしたいRole名またはClusterRole名とマッチする必要があります
  apiGroup: rbac.authorization.k8s.io
```
追加drogoユーザーを証明書を通じて認証する為、kube-configに追記

```yaml
- context:
    cluster: kubernetes
    user: drogo
    namespace: development
  name: developer

current-context: developer  

users:
- name: drogo
  user:
    client-certificate: /root/drogo.crt
    client-key: /root/drogo.key
```

# Podが見つからない...

```bash
controlplane $ kubectl get pods
No resources found in default namespace.
```
## 原因
namespaceがデフォルトである為、developmentのpodやサービスが確認できない
current-contextを設定していなかった


## 解決策
namespaceを変える
### 永続的に変更
configのcurrent-contextでnamespaceがdevelopmentであるcontextを指定する

### 一時的に変更

```bash
# -n namespace　でnamespaceを切り替える
kubectl -n mynamespace get all
```
# GitHub
https://github.com/hayama17/Game-of-Pods/tree/main/Redis%20Islands
Python3: Paramiko の使い方 （ssh 接続）

Python で ssh 接続をする方法です。

```py:ssh_exec.py
#! /usr/bin/python
#
#	ssh_exec.py
#
#					Jan/20/2022
# ------------------------------------------------------------------
import os
import sys
import paramiko
from dotenv import load_dotenv
# ------------------------------------------------------------------
dotenv_path = '.env'
load_dotenv(dotenv_path)
HOST = os.environ.get("HOST")
USER = os.environ.get("USER")
COMMAND = os.environ.get("COMMAND")
#
sys.stderr.write("*** start ***\n")
client = paramiko.SSHClient()
client.load_system_host_keys()

try:
	client.connect(HOST, username=USER, timeout=5.0)
#
	stdin, stdout, stderr = client.exec_command(COMMAND)
	str_out = ''
	for line in stdout:
		str_out += line
	print(str_out)

	client.close()
except Exception as ee:
	sys.stderr.write(str(ee) + "\n")
#
del client, stdin, stdout, stderr
sys.stderr.write("*** end ***\n")
# ------------------------------------------------------------------
```

```text:.env
HOST = "example.com"
USER = "scott"
COMMAND = "cd /home/scott/tmp/jan20 ; ls -l"
```

#スクリプトで実行する方法#

```bash:test.sh
cd /home/scott/tmp/jan20 ; ls -l
```

```bash
ssh scott@example.com < test.sh
```
Github Actions で、特定のブランチにリリースを発行した場合のみCI/CDを実行する

題名の通りです。
あまり綺麗だなとは思えないので、良い方法を知っている方がいたら教えて頂ければ幸いです。。

## 前提

検証環境と本番環境が存在していて、それぞれstagingブランチとmainブランチに対応しています。

- stagingブランチは、マージされたときにCI/CDが実行されます。
- mainブランチは、手動の承認フローをいれたいのと、Release管理を忘れないようにするために、Releaseが発行されたら実行するようにしたいです **<-今回はここの話**


## やりたいこと

GithubのReleaseで、**特定のブランチ(main)に対してリリースが発行された場合のみ**

に、Github Actionを実行させたい

**ただし、ヒューマンエラーで、発行先のブランチを(stagingなどに)間違えてしまった場合は、CIが実行されないようにしたい**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90487/0c15241f-9aaf-2640-afeb-46737bef9f3d.png)


## 設定方法

```yaml
name: リリースタグがついたときにデプロイする
on:
  release:
    types:
      - released

jobs:
  build_and_deploy:
    runs-on: ubuntu-latest
    # mainにリリースタグがついたときだけ、、はこれではできなかった
    #if: github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v2
      - run: git fetch --all
      # mainブランチ以外でタグが発行されたら失敗させる
      - run: diff <(git rev-parse HEAD) <(git rev-parse origin/main) && exit 0 || (echo "mainブランチではないためデプロイしません"; exit 1)
      - run: (デプロイ)
```


はじめ、コメントアウトしてある `if` を使おうとしましたが、リリースタグが付いた時のGithubのイベントでは、refがタグ名になってしまい、うまく動作しません


そこで、

1. stepsの中で `git fetch --all` し、ブランチ情報を引っ張ってくる
2. タグがついたコミットハッシュと、mainブランチのコミットハッシュが一致しないと、終了コード1で終了させ、次に進ませない

という形にすることで、やりたかったことは実現できました。


しかし、もっと簡単な方法があってもいいような...(見逃しているだけかもしれません)
Cloud-Based Moving Object Detection for Mobile Devices

#はじめに
クラウドコンピューティングは、インターネットを活用した計算モードです。遠隔処理の中心として、多くのクライアントをクラウドとして同時に接続することができる[1]。クラウドコンピューティングは、IT業界の中で戦略的に重視されるようになってきている。グローバルな IT 多国籍企業は、この傾向を観察し、自社をクラウドコンピューティングの組織へと変貌させている。現在、国内企業のクラウドコンピューティングは、BaiduのクラウドやAliのクラウドなどのように、ストレージや検索に重点が置かれていることがほとんどです。しかし、クラウドとメディアを組み合わせることは、一般消費者の間で広く応用され、採用されるには至っていない。最近、Prismaというモバイルアプリケーションが開発され、2016年6月現在、一般に公開されています。これは写真加工アプリケーションで、クライアントが自分のモバイル端末で写真を撮影し、その写真の真の加工はモスクワで行われるというものです。Prismaはこれまで成功を収めてきましたが、クラウドコンピューティングと組み合わせたマルチメディア情報処理は、クラウドストレージや検索機能に比べ、広く適用されているとは言えません。このような市場の現状を踏まえ、本論文の目的は、クライアント／サーバーのアーキテクチャのもと、クラウドを活用した映像システムを設計・実装することである。クライアントは映像の収集を担当し、サーバーは映像処理装置として機能する。本論文では、主に移動体検出機能について述べる。

現在、コンピュータビジョンの分野では、移動物体検出が注目されている。これは，位置，速度，軌跡などの運動情報をアルゴリズム的に取得することで，人間が他のタスクを完了するのを助けるものである[2]．現在、移動物体検出は、メディア、教育、医療、スポーツなどの分野で広く利用されている。しかし、映像の高画質化や検出精度の向上により、映像処理の演算能力への依存度はますます高まっています。このため、移動物体検出システムの大半は、固定されたワークステーション上でのみ動作しているのが現状です。そのため、現状では携帯端末の移動体検知機能には限界があります。

携帯端末の移動体機能の限界に対応するため、本論文ではクラウド型移動体検出システムを提案する。このシステムでは、ユーザがモバイル端末でビデオシーケンスをキャプチャし、ユーザはそのビデオをクラウドサーバに転送してオブジェクトを検出することができるようになる。同時に、多くのモバイルクライアントがクラウドサーバに接続し、リモートアクセスを得ることができる。これにより、マルチスレッドでの物体検出が可能となり、モバイル端末の演算能力不足を補うとともに、リソースの効率的な利用を実現します。クラウドコンピューティングと映像処理技術、特にモバイル電子機器による映像のキャプチャを組み合わせることで、クラウド技術の適用機会を大幅に拡大することができます。また、メディア処理モジュールは、その構造上、エンドユーザーのニーズに応じて、任意の機能に効果的に置き換えることが可能です。システムの性能は、依然としてネットワーク伝送特性に依存しています。しかし、ネットワーク伝送技術やデータ圧縮技術により、同じ帯域幅での性能は向上しています。そのため、モバイル機器よりもクラウドコンピューティングの方が効率的に映像処理を行えることが分かっています。

#クラウドを用いた物体検知システム
##全体像
本論文では、モバイル機器向けのクラウド型移動物体検出システムを提案する。この設計システムは、クライアントとクラウドサーバの2つの部分から構成される。クライアントがモバイル電子機器にログインした後、クライアントは内蔵のカメラを使ってビデオを撮影する。撮影された映像はサーバーにアップロードされます。クラウドサーバーは、ビデオを受信すると、その処理を開始します。処理が終わると、ビデオはクライアントに返されます。最後に、クライアントは処理されたビデオを受信し、表示します。システム全体の構成は、図1のようになります。

##モバイル機器
モバイルクライアントは主に、ユーザーログイン、映像撮影、映像送受信、映像再生の4つのモジュールで構成されています。クライアントのアーキテクチャを図2に示す．クライアント側では、ユーザーログインモジュールで、サーバアドレス、ユーザ名、パスワードの入力が必要である。また、最後に入力したログオン情報を保存することも可能です。ビデオキャプチャモジュールは、ローカルカメラを実装し、ビデオをキャプチャすることができます。一方、ビデオデータ送受信モジュールは、ユーザーがサーバーに生のビデオデータを送信することができ、また、サーバーから返されるプロセスビデオデータを受信することができます。ビデオ再生モジュールは、ビデオのプレビューと処理済みビデオの再生に利用される。

##クラウドサーバ
クラウドサーバーは、ログイン認証、映像の送受信、映像処理の3つの主要モジュールで構成されています。サーバのアーキテクチャを図3に示す．サーバーのログイン認証モジュールは、新しいユーザーのパスワードを監視し、確認するために使用されます。一方、映像送受信モジュールは、クライアントとの映像データの送受信に利用されます。最後に、映像処理モジュールはオブジェクト検出を実現する。コア機能は、移動物体検出モジュールに依存します。このモジュールでは、移動物体検出を実現するためのアルゴリズムが利用される。この論文で説明したシステムの目的は、クラウドコンピューティングとマルチメディア処理を組み合わせたアーキテクチャを提供することであることに留意する必要があります。したがって、移動物体検出モジュールは、任意の形式のメディア処理に置き換えることができる。
ASP.Net MVC エラーメッセージを赤字で表示　CSS　ValidationMessageFor

##エラーメッセージを赤字で表示したい
どうやらエラーになるときは、勝手にクラスが付与されるのでそれを利用する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348805/187c601e-e4f9-95bd-b869-dcaf7641fbe8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348805/5faa0d6d-b782-e9a0-9f24-614172ad4347.png)


```css:Site.css
.field-validation-error{
    color: #ff0000;
}

.field-validation-valid{
    display:none;
}
```


エラー文が出るHTMLファイルにCSSファイルを読み込むようにする

```html:Send.cshtml
@model WebMVC.Models.Homes
@{
    ViewBag.Title = "受注登録画面②";
}
<link rel="stylesheet" href="../Content/Site.css" runat="server" />
```

##参考サイト

https://qiita.com/koob/items/f36976773fc6dd189604


https://atmarkit.itmedia.co.jp/fdotnet/aspnetmvc3/aspnetmvc3_04/aspnetmvc3_04_03.html
SPSS Modeler ノードリファレンス 7-2 Excelエクスポート

# 7-2 Excelノード[エクスポートタブ]
<img width="200" alt="107_89エクセル.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/65cb9b88-7c98-7863-052e-d1bb7c35c570.png">

## 1.ノードの目的
Excelファイル形式（拡張子xlsx）でデータをエクスポートします。


## 2.解説動画（60秒）

<iframe width="560" height="315" src="https://www.youtube.com/embed/7EUmewsVxhE" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


## 3.クイックスタート

[可変長ファイル]に[データ型][Excel]エクスポートノードの順で接続します。
＊サンプルデータ（CSV）は[5.参考情報]からダウンロードできます。
![スクリーンショット 2022-01-20 11.20.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/6dea07f7-fe61-8f88-e553-b059fd9d761e.png)

[データ型]で[値の読み込み]ボタンを押します。
![スクリーンショット 2022-01-20 11.20.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/24797843-f152-8370-b8f9-ea3d4a1bf1dd.png)

[Excel]エクスポートノードで保存先とファイル名を設定します。Widows版SPSS ModelerではExcelを起動することができるのでチェックを入れます。
![スクリーンショット 2022-01-20 11.35.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/47aacfb0-b90f-0918-8c49-813f2e4186ce.png)

赤枠のボタンで[Excel]エクスポートノードを実行します。任意の場所にExcelファイルが作られ入力ノードがストリーム領域に生成されます。
![スクリーンショット 2022-01-20 11.41.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/d5fe4f53-d281-b8db-9ee6-64153b02151e.png)

### うまくいかない場合のヒント

[データ型]ノードを直前に配置して値を確定していないとエラーになります。
![スクリーンショット 2022-01-20 11.34.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/9a7f47f3-69df-f894-3882-3030019e4488.png)

Mac版では[Excel]ノードからExcelを直接起動できないため、出来上がったExcelファイルから起動します。
![スクリーンショット 2022-01-20 11.43.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/9ee43b0d-81ca-ef89-51aa-39a9f162fb1c.png)

## 4.Tips

#### Excelとレガシースクリプトでフィールド名を一括変換
Excelの関数とModelerレガシースクリプトでフィールド名の整理する方法を紹介しています。

https://www.ibm.com/blogs/solutions/jp-ja/modeler-tips-11/



## 5.参考情報

#### 利用データ

右クリックでリンク先を保存してください。

https://raw.githubusercontent.com/yoichiro0903n/blue/main/productmaster_mac.csv

#### ノードのヘルプ

https://www.ibm.com/docs/ja/spss-modeler/18.3.0?topic=nodes-excel-export-node

#### SPSS Modeler 逆引きストリーム集（データ加工）

https://qiita.com/416nishimaki/items/4bf813e6cba84b2a1008

#### SPSS Modeler ノードリファレンス目次

https://qiita.com/416nishimaki/private/503037195081d3323eee
systemテストで Net::ReadTimeout が出るときの対応

テスト用のCIサービスにHeroku CIを使ったところ、systemテストで`Net::ReadTimeout`が頻発しました。

driven_byメソッドにoptionsオプションを加え、`timeout: 秒数` を指定したところ治りました。

```rails_helper.rb
  config.before(:each) do |example|
    if example.metadata[:type] == :system
      driven_by :selenium, using: :headless_chrome, screen_size: [2000, 3000],
        options: { timeout: 120 }
    end
  end
```

以下、各種ライブラリのソースコードから。driven_byメソッドのoptionsオプションは、Capybara::Selenium::Driver に渡されます。

```actionpack-6.1.4.4/lib/action_dispatch/system_testing/driver.rb
        def browser_options
          @options.merge(options: @browser.options).compact
        end

        def register_selenium(app)
          Capybara::Selenium::Driver.new(app, **{ browser: @browser.type }.merge(browser_options)).tap do |driver|
            driver.browser.manage.window.size = Selenium::WebDriver::Dimension.new(*@screen_size)
          end
        end
```

Capybaraでは、options[:timeout] は read_timeout の値として、Capybara::Selenium::PersistentClient（Selenium::WebDriver::Remote::Http::Defaultのサブクラス）に渡されます。

```capybara-3.36.0/lib/capybara/selenium/driver.rb
        if options[:timeout]
          ::Capybara::Selenium::PersistentClient.new(read_timeout: options[:timeout])
        else
          ::Capybara::Selenium::PersistentClient.new
        end
```

Seleniumでは、read_timeout の値は、Net::HTTPのインスタンス（下のコードのhttp）に渡されます。

```selenium-webdriver-4.1.0/lib/selenium/webdriver/remote/http/default.rb
          def initialize(open_timeout: nil, read_timeout: nil)
            @open_timeout = open_timeout
            @read_timeout = read_timeout
            super()
          end
# 略
          def http
            @http ||= begin
              http = new_http_client
              if server_url.scheme == 'https'
                http.use_ssl = true
                http.verify_mode = OpenSSL::SSL::VERIFY_NONE
              end

              http.open_timeout = open_timeout if open_timeout
              http.read_timeout = read_timeout if read_timeout

              start(http)
              http
            end
          end
```

ということで、driven_byメソッドのoptionsオプションに指定したtimeoutの値は、最終的に [Net::HTTPのread_timeoutの値（デフォルトは60）](https://ruby-doc.org/stdlib-2.7.5/libdoc/net/http/rdoc/Net/HTTP.html#read_timeout-attribute-method) となります。
Konyにおけるplistの追加方法（iOS）

#目次
1. はじめに
2. 概要
3. まとめ
4. 参考

# はじめに
iOSではカメラを利用するときや写真ライブラリを開くときにplistにアクセス権を許可する記述を行わないとアプリがクラッシュします。
そこで本記事ではKonyにおけるplistの追加および記述方法をご紹介します。

# 概要

#### **①plistの追加および記述方法**

**1. ファイルを開く**
iosではカメラを利用するときにplistに許可する記述をしますが、konyの場合は以下のファイルを作成します。
infoplist_configuration.json

以下のパスに移動
ProjectName > resources > common
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/09eb1f2f-8e8e-0b64-c25a-17820564aa22.png)

infoplist_configuration.jsonを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/b9a46b41-3177-9381-a3e3-bfd0b8cffcc4.png)

**2. ファイル修正**
infoplist_configuration.jsonを開き、コードを修正

```infoplist_configuration.json
{
    "NSAppTransportSecurity" :
    {
        "NSAllowsArbitraryLoads" : true ,
        "NSExceptionDomains" :
            {
                "example.com" :
                    {
                        "NSIncludesSubdomains" : true ,
                        "NSExceptionAllowsInsecureHTTPLoads" : true
                    }
            }
    } ,
 
    "NSCameraUsageDescription" : "This is a dummy description",
    "NSPhotoLibraryUsageDescription": "This is a dummy Photo description"
} 
```

上を説明します。
**NSCameraUsageDescription**：カメラの使用権限
**NSPhotoLibraryUsageDescription**：写真ライブラリにアクセスする権限

#### **②画面の作成**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/898fc40e-3fbb-97cd-8d48-c83cae90a79d.png) 

cameraをタップするとカメラが起動します。
Galleryをタップすると写真ライブラリが開きます。

#### **③コーディングとアクションの紐付け**

```frmCameraOverlay.js
onselectioncallback:function(rawbytes, permStatus, mimeType){
    if(rawbytes !== null) {
        //access the rawbytes
        alert("file format: " + mimeType);
    } else if (permStatus === kony.application.PERMISSION_DENIED) {
        alert("Permission Denied to Access the Photo Gallery");
    }
  },

  onlick: function () {
    var querycontext = {
      mimeType: "image/*"
    };
    kony.phone.openMediaGallery(this.onselectioncallback, querycontext);
  }
```
上のサンプルコードによってユーザが写真ライブラリにアクセスする際に許可するかどうかのダイアログが表示されます。

#### **④実装の確認**
ではアプリがクラッシュしないかどうか確認しましょう。
![Video_20220117_111442_AM (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/d6c2cefc-fee0-1ed5-ff54-315cca20b5ed.gif)

アプリがクラッシュすることなく、正常に動いていますね！

# まとめ
plistを追加および記述することで、今後も安心してcamera widgetが使えます。
同じようにアプリが落ちて困っている方の参考になると嬉しいです:wave:

# 参考
画像データの取得：https://docs.kony.com/konylibrary/visualizer/viz_api_dev_guide/content/kony.phone_functions.htm

アクセス権の付与：
https://docs.kony.com/konylibrary/visualizer/viz_api_dev_guide/content/runtime_permissions.htm

ファイル：info.plistの変更方法
https://docs.kony.com/konylibrary/visualizer/visualizer_user_guide/Content/BuildAnAppForiOS.htm#AutoModInfoPlist
Go : 名前付き返り値がある状態で、returnのみ記述したときの挙動


* 名前付き返り値が設定されている状態だと、`return`だけ記載することができ、その場合は名前付き返り値が暗黙的に返却される。

```go
func example()(ret string){
    ret = "hello world"
    return
}

func main(){
    fmt.Println(example()) // hello world
}

```

* 一方で、名前付き返り値を設定しておきながら、別の変数を返却することも可能

```go
func example() (ret string) {
	ret = "hello world"
	ret2 := "goodbye world"
	return ret2 //新たに定義した変数を返す
}

func main() {
	fmt.Println(example()) // goodbye world
}
```

* コンパイルエラーにならない。名前付き返り値を設定している意味がないし、予期せぬ挙動を招いてしまう可能性があるので、名前付きの方を返却するように修正するか、あるいは元から名前付きにしないようにする。
Reactでお絵描き掲示板を作るのを諦めた話

## 結局ダメだった件

まえこんなの書いたんですよ。
[Reactでお絵かき掲示板（の表示部分）を作る話](https://zenn.dev/sakots/articles/c9765457ff90ce)
いろいろ考えてるうちに、「あれ、これダメじゃね？」ってなったのでそのいきさつを書きます。

## ダメポイント

### 全部CDNに頼らざるを得ない

Reactといえばjsxなわけですが、jsxというかBABELをCDNで使うとそりゃ重いのです。
jsxだけならいいんですが、配布するスクリプトなのでReactもCDNを使わないといけない。むむむ？

### 結局PHPは必要、ならPHPで全部やったほうが良くね？

PHPで配列とか吐いてReactで…
などと考えていたのですが、結局Bladeかませて直接書いちゃうしかなかった。

それがこちらです。（宣伝）
[oekakibbs.moe](https://oekakibbs.moe/)

## 今後

サーバーが自前でのサービスでならできるかもしれない。資金的に微妙だけど。
Githubの新しいgit push 2022

2021年8月からhttpsのlocalでpushできなくなった（パスワードでアクセルできない）ので

変更点と新しいgit pushの仕方を説明します。

先にファイルに入れたアプリを作成しておきます。

githubでレポジトリを作成します。

httpsとsshがありますがhttpsのままで大丈夫です。

次にホーム画面の右上のマイアイコンからsettingを選びます。

developer settingを選び、personal access tokenを選びます。

名前をmytoken20221010などとしておき、

setting optionでrepoだけを選ぶ。

入力が完了したら、generate tokenをクリック

tokenが発行されたらコピーして控えておきます。

それからコマンドラインでcd test-appのようにアプリまで場所を移動して

git init

git add　.

git commit -m "first commit"

it remote add origin https://github.com/githubのユーザ名/アプリ名.git

git branch -M main

git push -u origin main

これをコマンドラインで入力し終えたら、githubのユーザ名とパスワードが訊かれます。

githubのユーザー名はそのまま入力して構いません、

パスワードはgithubのではなく先ほどコピーして控えておいたtokenを貼り付け入力します。

これでgithubにアプリをpushできました。

参考にしたサイト


https://howpon.com/5308

https://zenn.dev/yuri0427/articles/9587ae6a578ee9
Python と C++ で websocket 通信するメモ

## 背景

Python と C++ のプロセス間で numpy データや画像などそこそこ大きめのデータを扱いたい...
ローカルネットワーク越しで別 PC に処理させたいとか.
 
websocket(バイナリデータ扱える) を使ってみます.

## C++ client, server

server も client も, 組み込みやすい civetweb が楽そうです!

https://github.com/civetweb/civetweb

websocket 有効にするには, `USE_WEBSOCKET` を define する必要があります.
また, デフォルトでは SSL 有効(SSL ライブラリとのリンクが必要)なので, ローカル PC やローカルネットワークでの利用で `wss` 不要であれば `NO_SSL` も define しましょう.

## Python 側


client は `websocket-client` がよいでしょうか. `websocket` モジュールとは異なりますので注意です!

websocketとwebsocket_clientの競合でうまくimportできないのを解決する
https://qiita.com/ikentoh/items/34b980da07bfc8abfd81

server なら `websocket-server` かしら.

## Note

CivetWebSocketHandler では, close の要求があると, `handleClose` が呼ばれるまえに `handleData` の bits に `OPCODE_CONNECTION_CLOSE` が立って 2 bytes のデータが来るようです.

```c++
        virtual bool handleData(CivetServer *server,
                                struct mg_connection *conn,
                                int bits,
                                char *data,
                                size_t data_len) {

                if (bits & MG_WEBSOCKET_OPCODE_CONNECTION_CLOSE) {
                  printf("WS close\n");
                  return 0;
                }
         ...

```

と判定するとよいでしょうか.
Python+MongoDBメモ

# Python+MongoDBメモ

Pythonを使ってMongoDBを操作したかったので色々調べたのでメモ
随時更新予定

https://www.mongodb.com/atlas/database

## Pythonドライバをインストール

```bash
pip install pymongo dnspython
```

https://pymongo.readthedocs.io/en/stable/index.html

## MongoDB接続

```python
import pymongo

client = pymongo.MongoClient(
"mongodb+srv://[User]:[Password]@cluster0.8tpbm.mongodb.net/myFirstDatabase?retryWrites=true&w=majority")
```

## DB追加、選択

testが存在しない場合は新規作成

```python
db = client.test
```

## コレクション追加、選択

testが存在しない場合は新規作成

```python
collection = db.test
```

## データ追加

```python
account = {
	'account_id': 100001,
	'limit': 9000,
	'products': ['TEST1', 'TEST1-1']
}

result = collection.insert_one(account)
print(result.inserted_id)
```

## 複数件のデータ追加

```python
accounts = [
	{'account_id': 100002, 'limit': 9000, 'products': ['TEST2', 'TEST2-1']},
	{'account_id': 100003, 'limit': 9000, 'products': ['TEST3', 'TEST3-1']}
]

result = collection.insert_many(accounts)
print(result.inserted_ids)
```

## データ取得

```python
account = collection.find_one({"account_id": 123456})
print(account)
```

## 複数件のデータ取得

```python
accounts = collection.find({'$or': [{'account_id': 100002}, {'account_id': 100003}]},
sort=[('account_id', pymongo.ASCENDING)])
result = [v for v in accounts]
print(result)
```

## データ更新

```python
update = collection.update_one({"account_id": 100001}, {'$set': {'limit': 8000}})
print(update.matched_count)
```

## 複数件のデータ更新

```python
update = collection.update_many({'$or': [{'account_id': 100002}, {'account_id': 100003}]},
{'$set': {'limit': 9000}})
print(update.matched_count)
```

## データ削除

```python
result = collection.delete_one({"account_id": 100001})
print(result.deleted_count)
```

## 複数件のデータ削除

```python
result = collection.delete_many({'$or': [{'account_id': 100002}, {'account_id': 100003}]})
print(result.deleted_count)
```
[Stripe Updates] Invoiceのstatement_descriptorをFinalize後も変更できるようになりました

Stripeを利用してクレジットカード決済を実行した場合、顧客のクレジットカード利用明細に任意のデータを入力するには、`statement_descriptor`を利用する必要があります。

これまでは、この`statement_descriptor`はInvoiceがFinalizeされる前のみ変更可能でした。

```js
    // 変更できる
    await stripe.invoices.update('in_xxxx', {
      statement_descriptor: "DUMMY ITEM 111",
    })

    // Finalizeする
    await stripe.invoices.finalizeInvoice('in_xxxx')

    // 変更できない（エラーになる）
    const invoice = await stripe.invoices.update('in_xxxx', {
      statement_descriptor: "DUMMY ITEM",
    })
```

今回のAPIアップデートから、Finalizeが完了しているInvoiceについても、`statement_descriptor`を変更できるようになりました。

```js
    // 変更できる
    await stripe.invoices.update('in_xxxx', {
      statement_descriptor: "DUMMY ITEM 111",
    })

    // Finalizeする
    await stripe.invoices.finalizeInvoice('in_xxxx')

    // 変更できる
    const invoice = await stripe.invoices.update('in_xxxx', {
      statement_descriptor: "DUMMY ITEM",
    })
```

# ユースケース

Invoice / Billingどちらも多くの場合は作成時に`statement_descriptor`を設定しているケースが多いとは思います。

が、SaaS側のシステムデータを利用して追加の情報を設定したい場合などでは、Invoiceのwebhookを利用して`statement_descriptor`を更新することができます。

そしてこれまでは、Finalizeされて更新できなくなっているケースを考慮する必要がありましたが、今回の更新後は考慮する必要がなくなります。

# 関連記事・ドキュメント

https://stripe.com/docs/statement-descriptors

https://stripe.com/docs/api/invoices/update

# [PR] Stripe開発者向け情報をQiitaにて配信中！
2021年12月よりQiitaにて、Stripe開発者のためのブログ記事更新を開始しました。

- [Stripe Updates]：開発者向けStripeアップデート紹介・解説
- ユースケース別のStripe製品や実装サンプルの紹介
- Stripeと外部サービス・OSSとの連携方法やTipsの紹介
- 初心者向けのチュートリアル(予定)

など、Stripeを利用してオンラインビジネスを始める方法について随時更新してまいります。

-> [Stripe Organizationsをフォローして最新情報をQiitaで受け取る](https://qiita.com/organizations/stripe)
写真から邪魔なものを消す　－－　例の機能が簡単に使える　

#画像補完モデルを簡単に使う方法です
画像の欠落部分を機械学習で補完します。

<img src="https://user-images.githubusercontent.com/23278992/150260192-a5cefdef-93c0-453b-8861-ee320ed8a379.gif">


#写真にうつりこんだものを消したい
背景に意図しないものが映り込んでしまったり、写真の一部分を消したいときってありますよね。

#LaMaがすごい
有名な画像編集ソフトとかにあるアレですが、あの機能がPythonで簡単に使えます。
Lamaは高解像度画像に対応したインペインティングライブラリです。

#手順

リポジトリをクローンして、必要なモジュールをインストール、事前トレーニング済みの重みをダウンロードします。

推論を実行します。

```python
python3 bin/predict.py model.path=${pre_trained_model_path} indir=${input_images_path} outdir=${result_images_path}
```

Colabで簡単に実行することもできます。

https://colab.research.google.com/github/saic-mdal/lama/blob/master/colab/LaMa_inpainting.ipynb#scrollTo=-VZWySTMeGDM

![ダウンロード (28).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/5c666294-daad-c2bc-5557-6a6d9bac6a7a.png)
<img src=https://user-images.githubusercontent.com/23278992/150260872-750f8013-30f5-40ac-9878-9569ee34d0dd.png>

#画像編集アプリケーションや、デザインに
これだけ簡単に使えると、デザインなど様々な用途に使えますね。

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

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

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
UTF-8文字列を1文字単位に分割

## tl;dr
split('') ではUTF-8の4バイト文字を分割できません。
すべての文字を分割するには `spred operetor` 等を使用します。

## split('')を使用した場合

```Javascript
console.log('3バイト文字は分割できる'.split(''));

// output: [ '3', 'バ', 'イ', 'ト', '文', '字', 'は', '分', '割', 'で', 'き', 'る' ]

console.log('4バイト文字（𠀋）の場合'.split(''));

// output: [ '4',  'バ', 'イ', 'ト', '文', '字', '（', '�',  '�',  '）', 'の', '場', '合' ]

```
4バイト文字である `𠀋` が正しく分割されていません。

## 正しい方法

### spread operator を使う
```Javascript
console.log([...'4バイト文字（𠀋）の場合']);
  
// output: [ '4',  'バ', 'イ',  'ト', '文', '字',  '（', '𠀋', '）',  'の', '場', '合' ]
```


### Array.from を使う
```Javascript
console.log(Array.from('4バイト文字（𠀋）の場合'));
  
// output: [ '4',  'バ', 'イ',  'ト', '文', '字',  '（', '𠀋', '）',  'の', '場', '合' ]
```

### RegExpのuフラグを使う
```Javascript
console.log('4バイト文字（𠀋）の場合'.split(/(?=[\s\S])/u));
  
// output: [ '4',  'バ', 'イ',  'ト', '文', '字',  '（', '𠀋', '）',  'の', '場', '合' ]
```
rails assets:precompile RAILS_ENV=productionでThe engine "node" is incompatible with this module. Expected version "xx.xx.x". Got "zz.zz.z"とerrorになった時の対処方

```package.json
"node": "xx.xx.x"
```
この"xx.xx.x"をエラー表示の"zz.zz.z＂にバージョンを合わせると解決！
久しぶりに goto をゴリゴリ使ってみた

N88-BASIC からプログラムを始めた自分にとっては goto が使えないのは手足をもがれたようだ！と思ったものです。
C言語の初学で goto はヤバいから使うなと教わり、今ではコーディングスタイルも安定してきただろうところですが、小さなマイコン組み込みにおいては UART によるコンソールを作るだけでも速度と容量の戦いで goto を使いたいという衝動を抑えられませんでした。
一回使ってしまったらもう何個使っても同じですよね。ということで、「性能のためには goto が必要」という考えのもとに実装してみました。

## why goto?
いわゆる構造化プログラミングには邪魔とされる goto ですがそもそも構造化プログラミングってなんぞや、と今更ながらに疑問になりました。軽く調べると「制御構造を抽象化していくこと」のようです。確かに、goto を使いまくるプログラム（の範囲）は非常に具体的ですね。しかし快適にプログラムを組むことを考えたとき、goto の何が悪だったのでしょうか。
この問題を考えるときに制約条件を整えておく必要があるでしょう。今回の私の例では、

* C言語
* 小さなマイコンなのでリソースが少ない
* 標準ライブラリは使わない
* 速度が絶対だがメンテナンス性も必要

というところでしょうか。実のところ、いちばん重要なのは「C言語」ではないでしょうか。C言語で goto を書いてもそれほど恐ろしいことにならないんですよね。C言語では関数間の goto はできません。N88-BASIC ではサブルーチン間も飛べた（と記憶している）のでC言語の goto なんてザコも同然！意図的に読みにくくしない限り大丈夫じゃないでしょうか。

## how goto?

ではどのように使ったかという話ですが、概要を示しましょう。

```c
	switch( param )
	{
	case A:	step = 0;	goto CASE_A;
	case B:	step = 0;	goto CASE_B;
	case C:	step = 0;	goto SKIP;
	case D:	step = 1;	goto END;
	default:break;
	}

	if( step != 0 )
	{
		switch( param )
		{
			case E:	if( step == 1 )	{ step = 2; }
						else		{ step = 0; }
						goto END;

			case F:
			case G:
				if( step == 2 )
				{
					evaluate = param;
					step = 0;
					goto PROCESS_C;
				}
				step = 0;
				goto END;

			default:
				step = 0;
				goto END;
		}
	}
	else
	{
		goto PROCESS_DEFAULT;
	}
```
これが飛び元のコードですね。もう少し改善できそうですが。
そして下が飛び先のコードです。ちょっと怒られそうです。

```c
	if(0)
CASE_A:
	{
		...
	}
	else if(0)
CASE_B:
	{
		...
	}
	else if(0)
PROCESS_C:
	{
		...
	}
	else if(0)
PROCESS_DEFAULT:
	{
		...
	}
	else
SKIP:
	{
	}

END:
	...
```

goto を使用したコードとしては非常に一般的な「下へ下へといく」コードです。...にはそれぞれ複数行入ります。
あえて一般的でないところを挙げるとしたら if(0) でしょうか。
この部分、もともとはフラグを使用してコーディングしていたのですが、goto に置き換え中に気づいたんです。
「if文の中(then節)に飛んだらelse節どうなるんだ！？」
単純に考えれば then 節の最後には else 節を回避するためのコードが埋め込まれなければならないため、狙った部分だけ実行できます。そのため離脱のための goto を書く必要もなく、あえて if文の形式を残しました。（もし怒られたときはフラグに戻しやすいし...）

if(0) は goto が無ければ絶対に実行されない箇所です。コンパイルするとマシンコードからは消えてなくなるのが一般的ですが、goto によって使われる可能性があるとちゃんと残りますね。素晴らしい。

これで「ラベルへ飛んで、{} の中だけ実行する」という悪さしにくい goto 文ができたわけです。やったね。

## wow, switch...
いざ goto を使ってコーディングし、その高速化を確認すべく逆アセンブルのコードを確認してみたところ...

**switch の case ラベルに全部詰め込んでた！！** (というのと等価だった)

そりゃそうかーそうだなーはははー
しかし switch の case はインデントが深くなりやすい問題があります。また case が俯瞰できた方が良いし breakし忘れない等の言い訳から 今回の件は「効果あり」と判定しました。

いろいろと学びのあった goto ですが、便利なのでみなさんも是非使いましょう！
[PHP]PDOによるデータベース接続

# PHPのデータベース接続
PHPでデータベースに接続する方法は調べたかがり3種類ある
1. mysql_connectによる接続
2. mysqli_connectによる接続
3. PDOによる接続

1.の接続方法はPHP 5.5.0 で非推奨になり、PHP 7.0.0 で削除されたので、使うのは避けた方がいい。 
https://www.php.net/manual/ja/function.mysql-connect.php
ちなみに使用PHPのバージョンは7.4.27。XAMMPを立ち上げて、そこにPHPから接続する。今回は2.のPDOによる方法でデータベースに接続する。

## ファイル構成
ファイルは以下の感じ。

```
db_connect/
  config.php      // DB情報
  dbConnect.php   // DB接続
  select_view.php // DBからデータを取得して表示
```

## データベースに接続
簡単なデータベースを作成

```
テーブル名: test
+--+------+--------+
|id|title |content |
+--+------+--------+
| 1|TITLE1|content1|
| 2|TITLE2|content2|
+--+------+--------+
```

config.phpにデータベースに接続するための情報を記述。

``` config.php
<?php
// データベースの情報
define('DB_HOST', 'localhost'); // ホスト名
define('DB_NAME', 'test');      // データベース名
define('DB_USER', 'root');      // ユーザー名
define('DB_PASS', 'pass');      // パスワード
```

dbConnect.phpに接続するコードを書いていく。

``` dbConnect.php
<?php
// 設定ファイルの読み込み
require_once ('config.php');

function dbConnect(){
  global $pdo, $e;

  $host = DB_HOST;  // ホスト名
  $dbname = DB_NAME // データベース名
  $dns = 'mysql:host=' . $host . ';dbname = ' . $dbname . ';charset=utf8';
  $user = DB_USER;  // ユーザー名
  $pass = DB_PASS;  // パスワード

  try
  {
    $pdo = new PDO(
      $dns, 
      $user, 
      $pass, 
      [
        // オプション
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,      // 例外をスロー
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // カラム名をキーとする連想配列で取得
      ]
    );
  } catch (PDOException $e) {
    header('Content-Type: text/plain; charset=UTF-8', true, 500);
    exit($e->getMessage()); 
  }
}
```

オプションなどは以下の記事を参考に記述
[PHPでデータベースに接続するときのまとめ](https://qiita.com/mpyw/items/b00b72c5c95aac573b71#pdoattr_errmode)

データベースから取り出して、表示。

``` select_view.php
<?php
// DB接続ファイルの読み込み
require_once ('dbConnect.php');

// DB接続関数呼び出し
$db_conn = dbConnect();

// testテーブルからデータを取得
$sql = 'SELECT * FROM test';
$stmt = $pdo->query($sql);
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);

// DB切断
$pdo = null;
?>
// HTML
<html>
 <head>...</head>
 <body>
  <h1>値を表示</h1>
  <?php foreach($results as $item): ?>
   <p><?= $item ?></p>
  <?php endforeach; ?>
 </body>
</html>
```

# まとめ
PHPでデータベースからデータを取得して表示することができた。
`select_view.php`のPHP部分とHTML部分をわけるとさらに良くなりそう。
cscの作法 その49

#概要

cscの作法、調べてみた。
guid生成やってみた。

#サンプルコード

```
using System;

class Gen1
{
	static void Main(string[] args) {
		Guid guidValue = Guid.NewGuid();
		Console.WriteLine(guidValue.ToString().ToUpper());
	}
}


```


以上。
Pytorchの再現性最強チェックポイントの作り方メモ

再現性を担保するために脳死で最強のチェックポイントを作るためのメモ。
僕の環境では以下で全部ですが、他にも追加した方が良いものがあればコメントください。

## 全部盛り

とりあえず以下をコピペすれば再現性は最強になる。

### 保存

~~~python3
import random
import torch
import numpy as np
from apex import amp

model_to_save = model.module if hasattr(model, "module") else model # DataParallelを使用している場合はmodel.moduleを取り出す。
checkpoint = {
    "model": model_to_save.state_dict(),
    "optimizer": optimizer.state_dict(),
    "scheduler": scheduler.state_dict(),
    "amp": amp.state_dict(), # apex混合精度を使用する場合は必要
    "random": random.getstate(),
    "np_random": np.random.get_state(), # numpy.randomを使用する場合は必要
    "torch": torch.get_rng_state(),
    "torch_random": torch.random.get_rng_state(),
    "cuda_random": torch.cuda.get_rng_state(), # gpuを使用する場合は必要
    "cuda_random_all": torch.cuda.get_rng_state_all(), # 複数gpuを使用する場合は必要
}

torch.save(checkpoint, "checkpoint.bin")
~~~

### 読込

~~~python3
checkpoint = torch.load("checkpoint.bin") 

if hasattr(model, "module"):  # DataParallelを使用した場合
    model.module.load_state_dict(checkpoint["model"])
else:
    model.load_state_dict(checkpoint["model"])
optimizer.load_state_dict(checkpoint["optimizer"])
scheduler.load_state_dict(checkpoint["scheduler"])
amp.load_state_dict(checkpoint["amp"])
random.setstate(checkpoint["random"])
np.random.set_state(checkpoint["np_random"])
torch.set_rng_state(checkpoint["torch"])
torch.random.set_rng_state(checkpoint["torch_random"])
torch.cuda.set_rng_state(checkpoint["cuda_random"]) # gpuを使用する場合は必要
torch.cuda.torch.cuda.set_rng_state_all(checkpoint["cuda_random_all"]) # 複数gpuを使用する場合は必要
~~~


以下でそれぞれについて簡単に説明する。


## モデルと学習関連

modelとoptimizerは当然保存。
schedulerも使用するなら保存しておいた方が吉。

保存

~~~python3
model_to_save = model.module if hasattr(model, "module") else model # DataParallelを使用している場合はmodel.moduleを取り出す。
checkpoint = {
    "model": model_to_save.state_dict(),
    "optimizer": optimizer.state_dict(),
    "scheduler": scheduler.state_dict(),
}
~~~

読込

~~~python3
if hasattr(model, "module"):  # DataParallelを使用した場合
    model.module.load_state_dict(checkpoint["model"])
else:
    model.load_state_dict(checkpoint["model"])
optimizer.load_state_dict(checkpoint["optimizer"])
scheduler.load_state_dict(checkpoint["scheduler"])
~~~

## 混合精度(apex)

apexを使って混合精度で学習する場合は、スケーリング変数とかを保存する必要がある。

保存

~~~python3
checkpoint = {
    "amp": amp.state_dict(),
}
~~~

読込

~~~python3
amp.load_state_dict(checkpoint["amp"])
~~~

## 乱数状態(Random State)

乱数状態はこれで完璧なはず。
使用しないモジュール関係は取り除いて良し。

保存

~~~python3
checkpoint = {
    "random": random.getstate(),
    "np_random": np.random.get_state(),
    "torch": torch.get_rng_state(),
    "torch_random": torch.random.get_rng_state(),
    "cuda_random": torch.cuda.get_rng_state(), # gpuを使用する場合は必要
    "cuda_random_all": torch.cuda.get_rng_state_all(), # 複数gpuを使用する場合は必要
}
~~~

読込

~~~python3
random.setstate(checkpoint["random"])
np.random.set_state(checkpoint["np_random"])
torch.set_rng_state(checkpoint["torch"])
torch.random.set_rng_state(checkpoint["torch_random"])
torch.cuda.set_rng_state(checkpoint["cuda_random"]) # gpuを使用する場合は必要
torch.cuda.torch.cuda.set_rng_state_all(checkpoint["cuda_random_all"]) # 複数gpuを使用する場合は必要
~~~
【PyTorch】１次元転置畳み込み（逆畳み込み層）の出力長の計算

# ConvTrans1dの出力長を計算したい

公式ドキュメントを参照すれば書いてありますが
https://pytorch.org/docs/stable/generated/torch.nn.ConvTranspose1d.html

```Convtrans1d.py
def deconv1d_outshape(Lin,kernel_size,stride=1,padding=0,padding_output=0,dilation=0):
    return (Lin-1)*stride-2*padding+dilation*(kernel_size-1)+padding_output+1
```
【PyTorch】１次元畳み込み層の出力長の計算

# Conv1dの出力長を計算したい

普通に公式ドキュメントを見れば書いてありますが
https://pytorch.org/docs/1.9.1/generated/torch.nn.Conv1d.html

```conv1d.py
def conv1d_outshape(Lin,kernel_size,stride=1,padding=0,dilation=0):
    return ((Lin+2*padding-dilation*(kernel_size-1)-1)/stride)+1
```
Runtime FabricでPersistenceオブジェクトストア

#Runtime FabricでPersistenceオブジェクトストアを利用する方法

Anypoint PlatformのCloudHub導入では、Object StoreでPersistenceオプションを利用することが出来ます。

↓のPersistentに✔です。

| Object Store Configuration |
|:-:|
| ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615564/7690daea-5803-0163-2d58-ea9dd7f41f9c.png)  |


古いバージョンのRuntime Fabric（オンプレミス導入）では、Object Store機能自体を利用することは出来てもメモリー上のデータ保持となっており、アプリケーションのリスタートによりデータが失われていましたが、下記のRuntime Fabric 1.9.1のリリースノートにある通り、Persistence機能が追加されています。
これは、Runtime Fabric on VM / BareMetalでも、Runtime Fabric on Self-Managed k8sのどちらでも利用可能となっています。

| Runtime Fabric 1.9.1 リリースノート |
|:-:|
| ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615564/30c59914-b2c8-ad25-4749-0a524e857aa2.png) |

CloudHub含め、Anypoint Platformで利用可能なObject Storeについては、[こちらの記事](https://help.mulesoft.com/s/article/The-Different-Types-of-Object-Stores-Explained)を参照ください。

##Persistence Gatewayの構成
Runtime Fabricで、Persistence Object Storeを利用するためには、Persistence GatewayというPodを構成する必要があり、また、データを保持しておく入れ物であるPostgreSQL（バージョン指定あり）を別途用意する必要がありますのでご注意ください。

具体的な手順は[こちら](https://docs.mulesoft.com/runtime-fabric/1.9/persistence-gateway)に紹介されていますが、下記、簡単に説明します。

1. Runtime FabricでSecretを作成する
RTF on VM / BareMetalの場合は、Controllerノードからkubectlコマンドを実行していきます。
```kubectl create secret generic <Secret名> -n rtf --from-literal=persistence-gateway-creds='postgresql://<DBユーザー名>:<DBパスワード>@<DBホスト>:<DBポート>/<DB名>'```
DBのパスワードには、@や#等が混ざらないようにしてください。
尚、エントリを削除する場合は、
```kubectl delete secret generic <Secret名> -n rtf```です。

1. Pod構成用yamlファイルを作成する（テンプレートは、[こちら](https://docs.mulesoft.com/runtime-fabric/1.9/persistence-gateway#k8-custom-resource-template)にあります。）
```apiVersion: rtf.mulesoft.com/v1
kind: PersistenceGateway
metadata:
  name: default
  namespace: rtf
spec:
  objectStore:
    backendDriver: postgresql
    maxBackendConnectionPool: 20
    replicas: 2
    secretRef:
      name: <Secret名>
    resources:
      limits:
        cpu: 250m
        memory: 250Mi
      requests:
        cpu: 200m
        memory: 75Mi```

1. Persistence Gateway作成
次のコマンドで構成していきます。
```sudo kubectl create -f <Pod構成用yamlファイル名>```
尚、誤った設定などで実行してしまった場合は、createの部分をdeleteに置き換えて削除します。

1. 稼働の確認
次のコマンドを実行することで、RTF関連Podの一覧が得られます。
```sudo kubectl get pods -n rtf```
この中で、"persistence-gateway-xxxxxxxxxx-xxxxx"といったエントリがありますので、このIDを保存します。
そして、このIDを利用して、バックエンドのPostgreSQLデータベースへの接続に成功していることを確認します。
```kubectl logs -f persistence-gateway-xxxxxxxxxx-xxxxx -nrtf```

1. アプリケーションのデプロイ時に、Persistence Object Storeオプションに✔を入れて有効にします。

| RTFアプリケーションデプロイ |
|:-:|
|  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615564/f916ac62-729a-f7af-9ac9-4109b855338e.png) |
FreeDOSでMSKermit

Lunaやってた頃にKEKの方が移植された、PC-9801版のkermitを使っていました。この頃はいろいろパソコン通信用のターミナルソフトがありましたが、KEK版kermitが一番エスケープシーケンスがしっかりしていて、漢字やFEPへの対応もちゃんとしていた記憶があります。FreeDOSにも入っているようなので、久しぶりに試してみました。

まずFreeDOSの入ったAptivaとFreeBSDのi386のマシンのRS232Cをクロスケーブルで接続します。

FreeBSD側では/etc/ttysのttyu0のgettyをon secureにしてkill -HUP 1します。

FreeDOSのFDIMPLESでNETにあるMSKERMITをインストールします。

C:\NET\MSKERMITにファイルがあるのでKERMITを実行します。

```
[C:\NET\MSKERMIT] MS-Kermit>set term byte 8
[C:\NET\MSKERMIT] MS-Kermit>connect
```

![IMG_20220120_092735.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/1d60559b-f79a-0080-2476-299a0dbcfeb6.jpeg)

古式ゆかしい80文字のVTターミナルです。最近は大きなディスプレーを並べている人もいますが、プログラムは80文字の端末でもちゃんと読めるように書きましょうね。

kermitはファイル転送機能もあり、当時はときどき使っていました。今は[mTCPでTFTP](https://qiita.com/yamori813/items/bc92aa911ead570ca2c8)が使えるので、シリアルでファイル転送する必要はありません。

MS-Kermitにはpktドライバーを使ったTCP/IPスタックも入っているようですが、落ちました。pktドライバーと相性が悪いのかもしれません。

```
[C:\NET\MSKERMIT] MS-Kermit>set tcp/ip address dhcp
[C:\NET\MSKERMIT] MS-Kermit>set tcp/ip host 192.168.0.100
[C:\NET\MSKERMIT] MS-Kermit>connect
 Requesting a DHCP server
JemmEx: exception 06 occures at ...
```

mTCPにもtelnetはあり使えるので、必要なときはそちらを使うことにします。

パソコンとUNIXを組み合わせて使うのが、ライフワークです。
BIOSなどについて調べてみた。

#ファームウェアとは
一言でいえばソフトウェアの一種です。さまざまな機器に内蔵されているハード制御のためのソフトウェアです。ソフトウェアの中でも一番ハードウェアに近いものです。PCにおいてはマザーボードにあるROMなどの記憶装置に組み込まれています。

#BIOSとは
特にコンピュータのファームウェアとしてよく知られているのがBIOS(Basic Input Output System)です。BIOSはマザーボードにあるROMなどの記憶装置に組み込まれています。
PCが不具合を起こしたときによく見る、いじると危険そうな青い画面のあれです。（笑）

#BIOSの役割
主な役割はコンピュータの起動(OSのブート)です。パソコンに電源が入ると最初にBIOSが起動します。BIOSのプログラムをもとにそれぞれの接続されている機器が使用可能な状態になります。次にHDDやSSDに保存されているOSがメインメモリに呼び出されて、いつものようにPCが使える状態になります。
BIOSの設定画面でブートディスクを変更することも可能です。

#OSはHDDにどのように保存されているのか
OSはHDDなどの補助記憶装置に保存されています。USBメモリやCD・DVDに保存して、そこからブートすることも可能です。
OSが起動されていない状況ではHDDのファイルシステムも使えない状態です。なのでOSの起動情報はHDDで一番最初に読み込まれる先頭のセクタに保存されています。この最初に読み込まれるセクタをMBR(Master Boot Record)セクタと言います。このMBRの情報をもとにしてOSがインストールされているパーティションにアクセスしOSを起動するのです。

#パーティションとは
HDDやSSDなどのストレージの内部を複数の独立した区画に分割することができます。この分割された区画のことをパーティションと言います。多くの場合はシステム領域と保存データ領域で分割します。
WindowsにおいてはCドライブやDドライブなどのドライブレター単位で分割します。
Linuxにおいてはsda1、sda2・・・のように分割して、/bootや/usrなどの任意のディレクトリにマウントすること一般的です。
パーティションごとに異なるファイルシステムを扱うこともできます。

#MBRとGPT
パーティションにはMBRとGPTという2種類の方式があります。MBRは古い方式でGPTは新しい方式です。

###MBR
MBRでは分割できるパーティションの数が最大４つまでという限りがあります。これはディスクパーティションテーブルの容量が64バイトなのに対して、パーティション情報が16バイトであるからです。また、1つのパーティションを論理的なパーティションに分割することも可能です。そうすることでMBRでも4つ以上のパーティションを作成することができます。
またMBRの場合最大で2TBまでのディスクしか対応できません。

###GPT
GPTにおいても先頭セクタはMBRセクタですが前述したMBRセクタとは役割が違います。MBRベースのディスクユーティリティがGPTディスクを間違って認識したり上書きしたりするのを防ぐ役割があります。それらに加えて、自身と第２GPTヘッダーのサイズと場所を記録するプライマリGUIDパーティションテーブルヘッダー、プライマリGUIDパーティションエントリ配列、バックアップGUIDパーティションエントリ配列、およびバックアップGUIDパーティションテーブルヘッダによって構成されます。
GPTは無制限にパーティションを作成することが可能ですがOSによって制限が設けられている場合もあります。
また2TB以上のディスクにも対応しています。

昔のBIOSではMBRしか対応していません。またUEFIではMBRとGPTの両方に対応しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1549760/e0937d43-18bb-9d3d-2d04-0f23eca32a94.png)

（画像引用：https://jp.minitool.com/partition-disk/mbr-vs-gpt-guide.html ）


#UEFIとBIOSの違いとは？
技術進歩についていけなくなったBIOSをパワーアップさせたのがUEFI(Unified Extensible Firmware Interface)です。BIOSとUEFIは全く別のものだと思われがちですが、BIOSをグレードアップさせたのもがUEFIというイメージです。厳密にいえばBIOSとOSを接続するインターフェース部分をUEFIという新たなものに変えたという感じです。
なので、BIOSもUEFIも総称してBIOSと呼ぶことが多いです。

#参考サイト

https://pc-farm.co.jp/pc_column/pc/4351/

https://jp.easeus.com/partition-manager/mbr-gpt-features-differences-convert-methods.html

https://jp.minitool.com/partition-disk/mbr-vs-gpt-guide.html
Xcodeのデバッガーで長いStringをprintする方法

LLDBのコンソールで以下のコマンドを実行します。
10000は文字数で、もっと大きな値にすることも可能です。

```
setting set target.max-string-summary-length 10000
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18273/b6522c49-842a-08ae-c8a4-200fbe0f450a.png)

すると、`p longString` で長い文字列を見切れることなく表示することができます。

### 参考
https://stackoverflow.com/questions/31402092/print-long-string-in-xcode-6-debugging-console
docker run すると401エラーが返される

# 概要

- 下記の記事に記載されている方法でDockerfileを作成してDockerイメージをつくり、Docker runでコンテナを立ち上げようとしたところエラーが発生した。
    - [https://qiita.com/miriwo/items/110ea6fb3f6b9d79882c](https://qiita.com/miriwo/items/110ea6fb3f6b9d79882c)

# 出力されたエラー

```
docker: you are not authorized to perform this operation: server returned 401.
See 'docker run --help'.
```

# 原因

1. どうやらDocker Content Trust; DCTというセキュリティ系の機能がdocker runをブロックしたらしい
1. 下記記事に記載されている内容をもとにイメージが信頼できることを確認してDCTを無効化する。
    1. [https://qiita.com/nasuB7373/items/9d841f2bd46ec9fc10d5](https://qiita.com/nasuB7373/items/9d841f2bd46ec9fc10d5)

        ```terminal
        export DOCKER_CONTENT_TRUST=0
        ```

# 参考文献

- [https://qiita.com/taxin/items/1d9e6b0770a87af7d8c8](https://qiita.com/taxin/items/1d9e6b0770a87af7d8c8)
Nokogiriのエラーで泣きそうなあなたへ

## 目的
Railsアプリを作成し、Herokuへデプロイし、さぁ開発しようと思ったら以下のようなNokogiriのエラーに悩まされたので、覚えている範囲でやったことを記述していく。

## 環境
```
$ sw_vers
ProductName:    macOS
ProductVersion: 11.6
BuildVersion:   20G165
```

### Homebrew

```
$ brew -v
Homebrew 3.3.11
Homebrew/homebrew-core (git revision a430b2abcc1; last commit 2022-01-19)
Homebrew/homebrew-cask (git revision b3964fe823; last commit 2022-01-19)
```
### rbenv 

``` 
$ rbenv 1.2.0
rbenv 1.2.0
```

### rubyコマンドが置かれているディレクトリ

```
$ which ruby
/Users/xxx/.rbenv/shims/ruby
```

### bundler
なお、「bundle install --path vendor/bundle」で個々のアプリケーションに分けてGemを管理しているので、インストールしたものは全てアプリケーション直下の「vendor/bundle」の中に入っております。

```
$ which bundle
/Users/xxx/.rbenv/shims/bundle
$ which bundler
/Users/xxx/.rbenv/shims/bundler
```

### Rails
```
$ bundle exec rails -v
Rails 7.0.1
```

# 解決策
とりあえず自分が解決した方法を載せておきます。

```
$ bundle exec gem install nokogiri

Fetching nokogiri-1.13.1-x86_64-darwin.gem
Successfully installed nokogiri-1.13.1-x86_64-darwin
Parsing documentation for nokogiri-1.13.1-x86_64-darwin
Installing ri documentation for nokogiri-1.13.1-x86_64-darwin
Done installing documentation for nokogiri after 14 seconds
1 gem installed
```

その後rails sなどを起動してもエラーは出なくなりました。

# エラー内容
エラー文が長すぎるので、真ん中のあたりは割愛しております。

```terminal
/Users/xxx/xxx/アプリ名/vendor/bundle/ruby/3.0.0/gems/nokogiri-1.13.1-x86_64-darwin/lib/nokogiri/extension.rb:30:in `require': cannot load such file -- nokogiri/nokogiri (LoadError)
        from /Users/xxx/xxx/アプリ名/vendor/bundle/ruby/3.0.0/gems/nokogiri-1.13.1-x86_64-darwin/lib/nokogiri/extension.rb:30:in `rescue in <top (required)>'

(長いので割愛)

        from /Users/xxx/xxx/アプリ名/vendor/bundle/ruby/3.0.0/gems/railties-7.0.1/lib/rails/command.rb:48:in `invoke'
        from /Users/xxx/xxx/アプリ名/vendor/bundle/ruby/3.0.0/gems/railties-7.0.1/lib/rails/commands.rb:18:in `<top (required)>'
        from bin/rails:4:in `require'
        from bin/rails:4:in `<main>'
```

# エラーの原因はどこにあったのか
まず参照されるべきnokogiriがどこにあるべきで、どこにないのかを見つけないといけない

エラー内容にここでLoadErrorだよと書いてので見にいく

```
$ cd /Users/xxx/.../アプリ名/vendor/bundle/ruby/3.0.0/gems/nokogiri-1.13.1-x86_64-darwin/lib/nokogiri/3.0

$ la
./ ../ .nokogiri.bundle.icloud*
```
「.nokogiri.bundle.icloud*」とはなんなんだ？と感じた。
もしかしたら「vendor/bundle」の方にnokogiriないのかもしれないと感じ
「bundle exec gem install nokogiri」コマンドを実行して、解決した。

その後、上のnokogiriの場所を見にいくと
「.nokogiri.bundle.icloud*」だとものが、「.nokogiri.bundle*」に変わっているのがわかった。

```terminal
$ cd /Users/xxx/.../アプリ名/vendor/bundle/ruby/3.0.0/gems/nokogiri-1.13.1-x86_64-darwin/lib/nokogiri/3.0

$ la
./ ../ .nokogiri.bundle*
```
何に変わったのかまだわからないので、これから探求していきたい。

## 参考

https://takuya-1st.hatenablog.jp/entry/2015/12/07/120638
Amazon EMRを実務で使って大事だと思うことを綴ってく。

# EMRとは何か？
> Elastic Map Reduce の略称です。
Amazon EMR は、オープンソースのフレームワークを使用して、ビッグデータを迅速に処理、分析し、そして機械学習 (ML) を適用するためのプラットフォーム
[Amazon EMR 公式リファレンス](https://aws.amazon.com/jp/emr/)


ビッグデータや膨大なデータを素早く処理するためのプラットフォームだということです。

このプラットフォームではSpark、Hadoopなどの分散処理のオープンソースを利用して処理をおこないます。
以前Spark関係の内容についてまとめましたのでご覧ください。
[Sparkについて(Python,Java,JVM,RDD)](https://qiita.com/noss08327439/items/e35c6162412e2599eefc)

# EMRの基本的な概念
* マスターノード
* コアノード(スレーブノード)

基本的には上の２つに分かれます。

EMR上で処理を実行する際にはAWS CLIで
> aws emr add-steps　「〜〜」　というコマンドを利用します。
この際に様々なオプションを設けますが、

##### 気をつけたいのが、クラスタモードとクライアントモードが存在しているということです。

* depoy-mode cluster
* depoy-mode client

この２つの実行方法では中で動く方法に違いが生まれてしまいます。

* クラスタモードは分散処理を行う処理
* クライアントモードは分散処理を行わない処理

となります。

上記の記述で何が変わるのか？

> クラスタモード
マスタノードからコアノード(スレーブノード)に処理が実行されるため分散処理扱いとなる

> クライアントモード
マスターノード上のみで処理が実行されるため分散処理にはならないということです。

aws emr add-steps コマンドではpython(pyspark)の処理を行います。その際に実行する環境が地味に異なります。

#HDFS(hadoop database file server)について
EMRを作成した段階で作られるデータサーバです。、ここではhadoopコマンドなどを使うことでAWSs3などとの連携が可能となります。
一時的にファイルを保存する場合、中間ファイルを生成して後続処理に使う場合など。

hadoopコマンドは2種類あります。
hadoop fs -lsこれはLinuxでいう lsコマンドです。

もしくはhdfs dfsコマンドとなります。基本的処理は同じですが、使用できるオプションが少し異なります。

#EMRって結局Ec2のこと。
Ec2を複数台起動し親のサーバから子のサーバにタスクを割り振り処理を分散化し処理性能をトータル的に上げているということになります。
一つのノードではできないけど複数のノードがあれば大規模なデータでも処理できるよねってことです。

#EMRを扱う上で必要なAWSのサービスについて
・VPC
・IAM(ロール、ポリシーなどの権限)
・s3(EMRのログ出力先)
・Ec2
・AWSCLI
・Boto3を利用したpythonアプリケーションの作成
##それ以外にあると良い知見
・Pysparkによる分散処理の知識
・メモリ関連
・Javaの知見
・jmepath(awscliでよく使います。)
・linux
credentials.yml.encをRubyMineで編集する

# 前提環境

```
$ ruby -v
ruby 3.0.3p157 (2021-11-24 revision 3fb7d2cadc) [x64-mingw32]
$ rails -v
Rails 7.0.1
```
OSはWindows10 64bitです。

# RubyMineの実行ファイルパスを取得する

スタートメニューなどからRubyMineのアイコンを探して、[ 右クリック->(その他)->ファイルの場所を開く ]を`rubymine64.exe`ファイルが出てくるまで行います。

そうしたら、ファイルをコピーしてエクスプローラーのアドレス欄に張り付けて、その文字列をコピーしてください。

# 環境変数を設定する

値の例: `"C:\...\rubymine64.exe --wait"`

- 一時的

```
set EDITOR=先ほど取ってきたパス --wait
```

- 恒久的

```
setx EDITOR 先ほど取ってきたパス --wait
```

# 編集

```
rails credentials:edit
```
【スキルの棚卸し】未経験から受託企業に入り2.5年経ったので、学んだことを書いてみる

##前回の記事

https://qiita.com/m_masashi/items/55d16f1070914c52803f

#はじめに　

2019年7月にキャリアをスタートさせました。
エンジニアとして2.5年でいろいろなことを学びました。

前回から半年たったので振り返りつつ学んだこと、反省点、次に改善することをまとめてみます。

いろいろなキャリアの積み方があるのでどれほど成長できてるのかは不明ですが、ほんの一例としてご参考ください。

#経歴

- 2018/10〜　某エンジニアスクールで学習開始
- 2019/01〜　卒業
- 2019/07〜　色々あって就職
- 2020/07〜　1年
- 2021/01〜　1年半
- 2021/07〜　2年
- 2022/07〜　2年半


#半年で学んだこと(できるようになったこと)


##１）技術関連


### Terraform

やったこと

- AWSリソースの作成

学んだこと

- モジュール化の方法
- Terraformを通してAWSのリソース同士の関係（依存関係など）
感想
IaCには興味があり業務で触れる機会があり、結論非常に勉強になった
GUIの操作だと曖昧なまま進められてしまうことがあるがコードに落とし込みたい場合はより深い理解を必要にするためチャレンジすることをお薦めする
上記にも書いたがTerraformを通してAWSのリソース同士の関係（依存関係など）を学ぶことがより深いAWSの理解に繋がった
コード化する過程で「GUI上では見えないこんな機能があるのか！」という気づきが得られるのでおすすめ！

###動画作成

前回
あるPJでpremier proを使って動画を作成しました。
社内での勉強会を動画にし、社内の一体感、知識を共有する雰囲気作りに貢献できたと思います。

今回
スポットで案件があり動画を作成したがそれ以外はなし

##２）顧客対応,スケジュール管理
###タスク/スケジュール管理

前回
WBSを書くことは慣れたのですが初めて触る言語、FWの場合は見積もりが甘くなることが多く、反省しています。
あと一度できた実装に関してはスピードが上がるので作業時間の見積もりの精度を上げていきたいです。

今回
前回よりも早く書けるようになった


#反省(できなかったこと)

前回

- チームマネジメント→なし


#改善案

### 具体的に

自分は新しいことを学ぶのに時間がかかってしまうタイプ。普段から少しずつ勉強しておくこと

## 次の半年で学びたいこと

前回

- インフラ関連
- AWSのSAAに合格します
- Ansibleサーバの構成ツールについての学習

前回の振り返り

- インフラ関連→PJでも触れることができた
- AWSのSAAに合格→達成！
- Ansibleサーバの構成ツールについての学習→独学した

今回

- 検証周りの知見（単体、結合）
- 資格：JSTQBの取得


### 検証

今回

- 単体試験で証跡を取得する業務があった。


### JavaScript

前回
Codewarsで引き続き学習する


[開眼！ JavaScript――言語仕様から学ぶJavaScriptの本質](https://www.oreilly.co.jp/books/9784873116211/)→読んでない
[改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで](https://www.amazon.co.jp/%E6%94%B9%E8%A8%82%E6%96%B0%E7%89%88JavaScript%E6%9C%AC%E6%A0%BC%E5%85%A5%E9%96%80-%E3%83%A2%E3%83%80%E3%83%B3%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB%E3%81%AB%E3%82%88%E3%82%8B%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E7%8F%BE%E5%A0%B4%E3%81%A7%E3%81%AE%E5%BF%9C%E7%94%A8%E3%81%BE%E3%81%A7-%E5%B1%B1%E7%94%B0-%E7%A5%A5%E5%AF%9B/dp/477418411X)
[JavaScript Primer](https://jsprimer.net/)→読んでない

今回
必要になったら学ぶ

### IT基礎

前回
slackチャンネルで1日1問形式で問題を解く→やった

今回
続ける

### チームリーダー

前回
顧客対応が任せられるようになること→なし

今回
任せられるように努力

### 突破力

ググり力はそのまま、コードを読む力は前よりも上がったと思います。
頭の中でコードをつなげる力がまだまだ弱いです。（脳内メモリ少なさも原因かも）
多くコードを読んで鍛えて行くしかありません。日々精進
→低いまま