OmniAICreator/Qiita-1.07M huggingface dataset:
swiftのinoutについて(変数の中身の入れ替え方法)

# はじめに
こんにちは@kaneko77です。
世の中には参照渡し、値渡しといった言葉がありますが、
参照渡しの`inout`について共有していきたいと思います。

# 説明
まずは例題から...

ある二つの変数の中身を入れ変えたい時があったとします。
こんなふうに書くと思います。

```swift
func swap(hoge: Int, huga: Int){
    var evacuation = hoge
    hoge = huga
    huga = evacuation
}
var hoge: Int = 1
var huga: Int = 2

print("hoge", hoge)
print("huga", huga)

swap(hoge: hoge, huga: huga)

print("hoge", hoge)
print("huga", huga)
```

しかし残念ながらこれだと型の引数は定数な為　コンパイルエラーとなってしまいます。

そんな時に`inout`が必要になってきます。
`inout`で定義した引数には呼び出す際に`&`が必要になってきます。

```swift
func swap(hoge: inout Int, huga: inout Int){
    var evacuation = hoge
    hoge = huga
    huga = evacuation
}
var hoge: Int = 1
var huga: Int = 2

print("hoge", hoge)
print("huga", huga)

swap(hoge: &hoge, huga: &huga)

print("hoge", hoge)
print("huga", huga)
```
```text:ログ
hoge 1
huga 2
hoge 2
huga 1
```

上記で変数の値の入れ替えができるようになりました。

# 終わりに
今回は`inout`についてでした。
本来だとスコープ外の変数には何も加えられないですが`inout`使うことでできるようになりました。
使い方は気をつけた方が良いですね。
ここまで見ていいただきありがとうございました。
【Java】Listに格納した値の平均値を出力


ちょっと悩んだのでメモとして。

```Average.java
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Average{
	public static void main(String[] args) {
		
		//Listに値を格納（ランダムで）
		List<Integer> list = new ArrayList<>();
		for(int i=0; i<5; i++) {
			Random random = new Random();
			int randomNum = random.nextInt(101); //0～100
			list.add(randomNum);
		}
		System.out.println(list); //値が格納されているか確認(後で消す) -> 例：[62, 73, 43, 35, 58]
		
		//Listに格納した値の合計
		double sum = 0;
		for(int j=0; j<5; j++) {
			sum += list.get(j);
		}
		System.out.println("合計値：" + sum); //合計の確認(後で消す)　-> 例：合計値：271.0
		
		//平均値
		double average = sum / list.size();
		System.out.println("平均値：" + average);
	}
}
```

```実行結果.
[76, 75, 22, 63, 87]
合計値：323.0
平均値：64.6
```
LPICレベル1を勉強しているあなたへ - SysVinitのランレベルとsystemdのターゲット -

0→poweroff.target
1→rescue.target
2.3.4→multi-user.target
5→graphical.target
6→reboot.target
これらのターゲットは

「/lib/systemd/system」

配下に格納されています。

※システム起動時に最初に実行されるUnitは

「/etc/systemd/system/default.target」

です。

default.targetをSysVinitでのランレベルに
相当するUnitへのシンボリックリンクとして作成することで、
期待するサービス群を起動できるようになります。
Oracle Java SE8 Silverに合格するまで

2021年06月にOracle認定のJava SE8 Silverに合格したので、経緯を書き残していく。

<h1>概要</h1>
* 学習期間
    * 1ヶ月余り
* 1日あたりの学習時間
    * 2-3時間 (休日は5時間ほど)
* 使用した教材、環境
    * 徹底攻略 Java SE8 Silver 問題集 (黒本)
    * Paiza io
* 学習前のレベル
    * PaizaのスキルチェックでBランクが解ける程度

<h1>SE8 Silverを受験した理由</h1>
もとはBronzeの勉強をしていたが、

* いきなり Silverを受けられる。
* 試験範囲がほぼ同じ

という2点を知り、試しに Silver の問題集に目を通してみたところ、
「確かに解けそうだな」と感じたのでそのまま Silver の学習にスライド。

SE11 ではなく SE8 を受験したのは、
たまたま書店にSE11の問題集が売っていなかったという程度の理由。

<h1>勉強方法</h1>
* 1周目
通勤時間に解説文を読んでインプットしてた。
条件分岐や繰り返し処理についてはある程度心得ていたが、
例外処理やAPIの知識が抜けていたため6章以降が少し難しく感じた。

* 2周目～
本格的に反復演習。
プログラミング系の勉強では邪道かも知れないが、
ノートをとって間違えた部分を重点的にまとめていった。
(タイピングだとあまり頭に定着しないタイプなので、あえて面倒な方法を選択)

* 演習問題
9章まである程度わかったなと思ったあたりで演習問題に移行。
2周解いたあたりで「やっぱり継承あたりが苦手だな」と感じたため、
この辺りはPaiza ioで実際に打ち込んでパターンを覚えていった。
<br>ラムダ式あたりは「解けたら解こう」くらいのテンションで取り組んだ。

* 得点率の推移

|   | 10章 | 11章 |
|:----:|:-:|:-:|
| 1周目 | 73% | 73% |
| 2周目 | 84% | 92% |
| 3周目 | 94% | 96% |
| 4周目 | 97% | 91% |

<h1>いざ受験</h1>
オンライン試験を選択したが、いわゆる汚部屋の住民で、
PC周りを片付けるのがかなり大変だった。

* 事前に調べてたけど知らなかったこと
    * メモ用の紙、筆記用具もNG<br>→試験用アプリ内にホワイトボード機能があった。<br>→ラベル剥がした天然水は問題なかったっぽい。
    

* 受験中辛かったこと
    * フォントが読みづらかった。<br>→明朝体とかセリフ体だった気がする。<br>→余裕があったらそれらのフォントでコードを読む練習をしておくと吉。

巷で噂になっている通り、たしかに問題は黒本と同じもの多いなって感じた。
演習問題4周もしてしまった分、黒本の変数名に慣れてしまったので違和感は多かった。
多分2-3周でも良かったと思う。

演習のまんまじゃんって思ってサクサク解いた後、
あれ？ちゃんとコード読んでないな、って思ったところが少しあった。

<h1>結果</h1>
思っていたより正解率が高かった。
逆にそこ間違えたの？って感じだったので
もう少し注意していれば100%取れたのかもしれない。
![oracle_java_score_21_06_23-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1681658/e2de7891-9608-3029-728d-0af11cb48b58.png)

<h1>感想</h1>
IT系の資格検定は、高校時代の全商情報処理1級以来の合格なので嬉しかった。

難易度もマイルドに感じたので、問題集立ち読みして行けそうだと思った人は１ヶ月でも十分受かるかなと思う。

Goldも勉強してみたいけど、実務経験なしでどれくらいかかるかなぁ。
Docker上のRuby on Rails 6をVisual Studio Codeでデバッグするまでの手順

# 必要なもの

Docker Desktop
Visual Studio Code

今回の作業環境は以下になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/d4e8146f-3f4d-43ad-d6a7-e59104c4f379.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/a02cbc08-1e97-42df-32e1-19ee2df46c47.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/d56993c8-04d5-2630-75e5-a13124e19934.png)

# Docker ファイルを作成

```dockerfile:Dockerfile
FROM ruby
RUN apt-get update -qq
WORKDIR /app
COPY Gemfile* /app/
RUN bundle install
COPY . /app
EXPOSE 3000 1234 26162
CMD ["rails", "server", "-b", "0.0.0.0"]
```

# Gemfile ファイルを作成

```ruby:Gemfile
source 'https://rubygems.org'
gem 'rails', '~>6'
```

# Docker 内を Visual Studio Code で開く

# .devcontainer/devcontainer.json に下記の行を追加しvscodeを開きなおす

```json:devcontainer.json
	"extensions": [
		"rebornix.ruby",
		"wingrunr21.vscode-ruby"
	],
	"workspaceFolder": "/app",
	"workspaceMount": "source=${localWorkspaceFolder},target=/app,type=bind,consistency=delegated"
```

# バージョン確認

```bash:TERMINAL
# ruby -v
ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-linux]
# rails -v
Rails 6.1.4.1
```

# Railsプロジェクト作成

```bash:TERMINAL
rails new --api --minimal -S -J -T .
```

# 動作確認

```bash:TERMINAL
rails s
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/6abdf7ff-da23-9458-ddc1-b93cbbdb0b07.png)

ブラウザで http://localhost:3000 を開く

# デバッグ用 gem 追加しbundle install

```ruby:Gemfile
group :development do
  gem 'listen', '~> 3.3'
  gem 'debase', '0.2.5.beta2'
  gem 'ruby-debug-ide', '~> 0.7.2'
end
```

# デバッグ用ファイルを作成

```js:.vscode/launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Rails server",
            "type": "Ruby",
            "request": "attach",
            "cwd": "${workspaceRoot}",
            "remoteWorkspaceRoot": "/app",
            "remoteHost": "0.0.0.0",
            "remotePort": "1234"
        }
    ]
}
```

# デバッグ起動

```bash:TERMINAL
bundle exec rdebug-ide --host 0.0.0.0 --port 1234 --dispatcher-port 26162 -- bin/rails s -p 3000 -b 0.0.0.0
```

デバッグタブでデバッグ開始
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/383b71db-23cc-1433-4d66-c3ff2ccd7f64.png)

# テスト用コントローラ作成

```ruby:app/controllers/todos_controller.rb
class TodosController < ApplicationController
    def index
        todos = ['歯磨き', '掃除']
        render json: todos
    end
end
```

```ruby:config/routes.rb
Rails.application.routes.draw do
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
  resources :todos
end
```

# ブレークポイント設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/31ad17bd-cb74-1fe9-77e3-6e0705e1ce40.png)


# ブレークポイントで止めて変数を確認

ブラウザで http://localhost:3000/todos を開く

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/6e7d7a23-6268-0db3-5e33-98cff789f185.png)

# ステップ実行、再開
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/27236413-c56f-6fc6-2caa-b71f37e5efa1.png)
ドメインモデルの作り方（現場で役立つシステム設計の原則まとめ）

# 概要

現場で役立つシステム設計の原則 変更を楽で安全にするオブジェクト指向の実践技法　を読んで、一度読んだだけでは身につかないと思ったため、大事なところをまとめてガイドラインとして利用できるようにしたいのが狙い。

実際に読んでみて、自分で理解して噛み砕いた文章に起こすと同時に、簡単に自分でも実装をしてみてTipsを掴む。

ひとまず４章までをまとめました。続きは本書の購入を検討してみてください。
５章以降は４章までを踏まえて実際にドメインモデルを使ってアプリケーションをどう実装するのか。と言う内容になってます。
本書はJava＋SpringBootが題材となっていますが、個人的にはTypeScriptでのフロントエンドの実装についても参考になる点が非常に多いと思います。

[Amazon - 現場で役立つシステム設計の原則 ~変更を楽で安全にするオブジェクト指向の実践技法~ 　著：増田 亨](https://www.amazon.co.jp/%E7%8F%BE%E5%A0%B4%E3%81%A7%E5%BD%B9%E7%AB%8B%E3%81%A4%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E8%A8%AD%E8%A8%88%E3%81%AE%E5%8E%9F%E5%89%87-%E5%A4%89%E6%9B%B4%E3%82%92%E6%A5%BD%E3%81%A7%E5%AE%89%E5%85%A8%E3%81%AB%E3%81%99%E3%82%8B%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E3%81%AE%E5%AE%9F%E8%B7%B5%E6%8A%80%E6%B3%95-%E5%A2%97%E7%94%B0-%E4%BA%A8/dp/477419087X)

## まとめ中に思った感想

- Chapter 1 〜 2 はドメイン駆動設計に関わらずオブジェクト指向プログラミングにとって重要なリファクタリング思想だと思った。
- ドメインモデルについてわからなくなったらChapter3を見返す
- ドメインモデルの設計については繰り返し改善活動を行うしかないが、基本パターンはChapter4で押さえておく

# Chapter. 1　小さくまとめてわかりやすくする

https://qiita.com/Regpon/items/72377746abab0e75760a

# Chapter. 2 場合分けのロジックを整理する

## Chapter. 2.1
https://qiita.com/Regpon/items/34382949a5dd0ea104cd

## Chapter. 2.2
https://qiita.com/Regpon/items/730ffe5ea06ce5667659


# Chapter. 3 業務ロジックをわかりやすく整理する

https://qiita.com/Regpon/items/c30a7a6b51586c9cc1cc

# Chapter. 4 ドメインモデルの考え方で整理する

https://qiita.com/Regpon/items/6e309aae05a796b09508

# ここまでで学んだ内容を業務で実践

https://qiita.com/Regpon/items/239c9a830bf40f61466b
大きなサービスのためのMicro Frontend 

# Micro Frontend

次のリンクはMicro Frontendを開始する方法を説明しています。

https://present.do/decks/60d20b8dffff3c06649f7a18

## Reference
* https://lucamezzalira.com/category/micro-frontends/
* https://github.com/module-federation/nextjs-mf
自作パッケージをCarthageに対応する方法

「Swift Packagesによるライブラリの作成方法」は4部構成です。
記事を順番に読み進めると、Swift Packagesでライブラリを自作して公開できるようになります。

- 第1部: [Swift Packagesでライブラリを自作する](https://qiita.com/uhooi/items/2f36b85f5f41cbd35189)
- 第2部: [自作パッケージをSwift Package Indexに追加する](https://qiita.com/uhooi/items/689801dad2cf2e0a37b4)
- 第3部: [自作パッケージをCocoaPodsに追加する](https://qiita.com/uhooi/items/5ce382cb0c1c6bc018d9)
- 第4部: 自作パッケージをCarthageに対応する　__←イマココ__

## はじめに

自作パッケージをCarthageに対応する方法を紹介します。

## 環境

- OS： macOS Big Sur 11.4
- Xcode：12.4 (12D4e)
- Swift：5.3.2
- swift-tools：5.3

## Carthageへの対応方法

自作パッケージがあれば、CarthageへはXcodeプロジェクトを生成するのみで対応できるので、その手順を紹介します。

### パッケージを自作する

自作パッケージがなければ始まりません。

以下の記事を参考にパッケージを自作します。

https://qiita.com/uhooi/items/2f36b85f5f41cbd35189

### Xcodeプロジェクトの生成

`swift package generate-xcodeproj` でXcodeプロジェクトを生成します。

```shell-session
$ swift package generate-xcodeproj
warning: Xcode can open and build Swift Packages directly. 'generate-xcodeproj' is no longer needed and will be deprecated soon.
generated: ./StringTransform.xcodeproj
```

これだけでOKです。
私はプロジェクトの設定を変更すらしませんでした。

`generate-xcodeproj` はもうすぐ非推奨になるとのことです。
パッケージの開発は `Package.swift` をXcodeで開いて行い、Xcodeプロジェクトは使わないようにします。

### Xcodeプロジェクトをバージョン管理する

すでに `.xcodeproj` ファイルをバージョン管理の対象外にしている場合、削除するかコメントアウトします。

```diff:.gitignore
- /*.xcodeproj
+ # /*.xcodeproj # Use only with Carthage
```

私はXcodeプロジェクトをCarthageのみで使っていることを明示するために、コメントアウトしてコメントを書いています。

これでCarthage対応は完了です。

### おまけ：Carthageのバッジ

以下のバッジをREADMEに付けることで、Carthageに対応していることを表せます。

[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg)](https://github.com/uhooi/swift-string-transform)

## おわりに

自作パッケージをCarthageに対応することができました！
自分のパッケージがCarthageで使えるようになるのはとても嬉しいです :relaxed:

## 参考リンク

- [Carthage/Carthage: A simple, decentralized dependency manager for Cocoa](https://github.com/Carthage/Carthage#supporting-carthage-for-your-framework)
- [Gedatsu/Gedatsu-Carthage.xcodeproj at 1.2.0 · bannzai/Gedatsu](https://github.com/bannzai/Gedatsu/tree/1.2.0/Gedatsu-Carthage.xcodeproj)
- [[Swift] 自作のパッケージをCocoaPods、Carthage、Swift Package Manager対応させる | エンジニアもどきの技術メモ](https://e-tec-memo.herokuapp.com/article/241/)
- [Release Carthage by uhooi · Pull Request #9 · uhooi/swift-string-transform](https://github.com/uhooi/swift-string-transform/pull/9)
- https://twitter.com/the_uhooi/status/1405866818355359744?s=20
【Mac terminal】SSH接続でパーミッションエラーになる

#  はじめに
<!-- 発端や概要を記載 -->
Mac使い一日目、いつも通りAWSのインスタンスにterminalを使ってログインしようとしたらパーミッションエラーが発生する。

```
Warning: Permanently added '52.196.196.190' (ECDSA) to the list of known hosts.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/Users/yanagimorisatsuki/Documents/SAA/udemy-sample-mac.pem' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
```

「パーミッションが644です！！！」
え？何が悪いん？AWSが作成してダウンロードしたペアキーですけど。

# 権限を600にしたら成功した
<!-- タイトルとアンカー名を編集 -->
所有者以外権限つけたらダメらしい。
Windowsではこんなこと気にしたことなかったのにな。。

### 権限変更

```
chmod 600 [キーファイルのパス]
```

再度ログイン。

```
ssh ec2-user@[接続先IP] -i [鍵ファイルパス]

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
```

うまくいきました。
pdfファイル処理：ページ単位で一行のテキストへ変換（シェルスクリプト）

こんにちは
pdftotextコマンドを用い、pdfファイルのページ単位で一行のテキストへ変換するシェルスクリプトを作りました。

これを用い、指定した単語の検索を行い、それが出現するページ番号を得ました。

```console
$ ./pdftotext.sh example.pdf | grep -n -e "search_word" | cut -d: -f1
1
2
$
```


```pdftotext.sh
#!/bin/sh

# constant
FF=$(printf '\f')

# functions
remove_form_feed_f() {
  str="${1#$FF}"
  echo "$str"
  [ "$str" != "$1" ]; return $?
}

pdftotext_f() {
  file="$1"
  pdftotext "$file" - | while read -r line; do
    line=$(remove_form_feed_f "$line") && echo
    printf "%s" "$line"
  done
  echo
}

# main
for file in "$@"; do
  [ -d "$file" ] || [ "${file##*.}" != "pdf" ] && continue
  pdftotext_f "$file"
done
```
WindowsでPythonでMeCab（mecab-ipadic-NEologd）

## 前提
Windows10
Python3.9

## 1. MeCabのインストール
https://taku910.github.io/mecab/#download

Binary package for MS-WindowsをDL・インストール
文字コードはUTF-8にしておく

## 2. mecab-ipadic-NEologdをインストール
最新の辞書とかもあって便利なのでいれる

https://github.com/neologd/mecab-ipadic-neologd/blob/master/README.ja.md

→WindowsはWSLに入れろって感じだけど普通にインストールできる

### NEologd辞書のダウンロードとコンパイル

```
git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git
cd mecab-ipadic-neologd\seed
7z X *.xz
```


### 辞書ファイルのコンパイル

```
mecab-dict-index -d "c:\Program Files (x86)\MeCab\dic\ipadic" -u NEologd.20200910-u.dic -f utf-8 -t utf-8 mecab-user-dict-seed.20200910.csv
mkdir "C:\Program Files (x86)\MeCab\dic\NEologd"
move NEologd.20200910-u.dic "C:\Program Files (x86)\MeCab\dic\NEologd"
```

### mecabrcファイルの編集
mecabの辞書は`C:\Program Files (x86)\MeCab\etc`にある`mecabrc`で指定できる

NEologd辞書はユーザー辞書として設定する

```
dicdir = $(rcpath)..\dic\ipadic
userdic = C:\Program Files (x86)\MeCab\dic\NEologd\Neologd.20200910.dic
```

参考：https://qiita.com/zincjp/items/c61c441426b9482b5a48

## 4. PythonでMeCabを使う

```
$ pip install mecab-python3
```

```py
import MeCab

mecab = MeCab.Tagger()

text = '解析したいテキスト'
mecab.parse('')#文字列がGCされるのを防ぐ
node = mecab.parseToNode(text)
while node:
    #単語を取得
    word = node.surface
    #品詞を取得
    pos = node.feature.split(",")[1]
    print('{0} , {1}'.format(word, pos))
    #次の単語に進める
    node = node.next
```


参考：https://qiita.com/taroc/items/b9afd914432da08dafc8
残プロ　第-22回　~PythonとHTMLを接続する~

# flask.url_for

これを使って簡単にビュー(表示ページ)の切り替え，pyファイル内の関数の実行を実現します．


### .py

前回同様，render_templateを使ってhtmlを表示しています．
デコレータをつける際に\<string:message>のようにしてやることで引数が得られます．


~~~ python:hello.py
from flask import Flask, render_template, url_for

app = Flask(__name__)

@app.route('/')
def hello():
    return render_template("hello.html", msg="Hello")

@app.route('/bye')
def bye():
    return render_template("bye.html")

@app.route('/back/<string:message>')
def back(message):
    print(message)
    return render_template("hello.html", msg=message)


if __name__ == '__main__':
    app.run(debug=True)
~~~


### .html

url_forで変数を渡すことができます．
routeに従った関数が実行できるので処理を追加すればcsvファイルの読み込み等様々なことができます．


~~~ html:hello.html
<!DOCTYPE html>
<html>
<body>
    <p>{{ msg }}</p>
    <a href="{{ url_for('bye') }}">Bye</a>
</body>
</html>
~~~


~~~ html:bye.html
<!DOCTYPE html>
<html>
<body>
    <p>Bye</p>
    <a href="{{ url_for('back', message="Welcome Back") }}">Back</a>
</body>
</html>
~~~
LPICレベル1を勉強しているあなたへ - Unitとは -

Unitとは設定ファイルであり、
Unitの設定に従ってsystemd自体が処理を実行します。

SysVinitのようにスクリプトを実行するわけではありません。

Unitには各機能ごとに拡張子が割り当てられており、
拡張子を見ることでどういった機能のためのUnitかが
判別できるようになっています。

device→各種デバイスを管理するユニット
mount→ファイルシステムのマウントを管理するユニット
service→サービスを制御するユニット
swap→スワップ領域を管理するユニット
target→複数のサービスを一つのグループにするユニット
【Oracle】最適な釣り銭の枚数を求めるストアドプロシージャ

# はじめに

以前に投稿した[【Oracle】うるう年を判定するストアドファンクション](https://qiita.com/nkojima/items/81a664b69eaf21982e9b)に続いて、勉強がてらPL/SQLで簡単なアルゴリズムを実装してみることにしました。

まずは私でも簡単に実装出来そうなアルゴリズム...ということで、今回はグリーディー法（貪欲法）を使って「最適な釣り銭の枚数を求める処理」を実装してみました。

# グリーディー法（貪欲法）とは

* 評価値の高い順に取り込んでいくことで解を得る方法で、得られる解は最適解（厳密解）とは限らない。（Wikipediaより）
* グリーディー法を釣り銭の計算に当てはめた場合は、「使用可能な貨幣（硬貨）の中で、一番額面の高いものから順に使っていく」ということになります。
 * 釣り銭として紙幣と硬貨の両方を使う場合でも、5000円→1000円→500円→100円...と額面の高いものから順に釣り銭として使っていきます。

# 使用した環境

* Oracle社が提供している[Oracle Live SQL](https://livesql.oracle.com/)でOracle19c（19.8.0.0.0）を利用しました。

# 作成したコード

* 今回作成したコードでは、使える釣り銭は「硬貨のみ」としています。
 * 紙幣が1000円しか使えない自販機をイメージしています。
* 「硬貨の種類ごとに必要な枚数」「必要な硬貨の枚数の合計」の両方を標準出力しています。
 * OUTパラメーターに配列を使うとややこしいので、標準出力させる形にしました。

```sql:give_change.sql
-- 釣銭として必要な硬貨の枚数の最小値を求めるストアドプロシージャ。
-- change: 釣銭額
CREATE OR REPLACE PROCEDURE give_change(change IN NUMBER)
-- 宣言部
IS
  TYPE AR1 IS VARRAY(6) OF NUMBER;
  jp_coins AR1 := AR1(500, 100, 50, 10, 5, 1);
  
  change_buff NUMBER;
  number_of_coins NUMBER;
  total_number_of_coins NUMBER;
-- 処理部
BEGIN
  change_buff := change;  -- INパラメータは変更できないため、ここでバッファに入れておく。
  total_number_of_coins := 0;  -- 初期値を設定しておかないと正しい結果を得られない。
  
  DBMS_OUTPUT.PUT_LINE('釣り銭：' || change_buff || '円');
  
  FOR i IN jp_coins.first..jp_coins.last LOOP
    number_of_coins := TRUNC(change_buff / jp_coins(i));  -- i番目の硬貨の必要枚数を求める。
    total_number_of_coins := total_number_of_coins + number_of_coins;
    DBMS_OUTPUT.PUT_LINE(jp_coins(i) || '円：' || number_of_coins || '枚');
    change_buff := TRUNC(MOD(change_buff, jp_coins(i)));
  END LOOP;

  DBMS_OUTPUT.PUT_LINE('必要な硬貨の枚数の合計：' || total_number_of_coins);
END;
```

```sql:実行用SQL
-- 宣言部
DECLARE
-- 処理部
BEGIN
  give_change(786);
END;
```

```text:実行結果
釣り銭：786円
500円：1枚
100円：2枚
50円：1枚
10円：3枚
5円：1枚
1円：1枚
必要な硬貨の枚数の合計：9
```


# 関連URL

* [【Oracle】PL/SQL入門](https://qiita.com/nkojima/items/93a9c01741965f11bb8c)
* [【Oracle】ストアドプロシージャ入門](https://qiita.com/nkojima/items/2f793251e4465a3a8da2)
* [貪欲法 - Wikipedia](https://ja.wikipedia.org/wiki/%E8%B2%AA%E6%AC%B2%E6%B3%95)
Chrome Developer Tools で Web サイトの一部からリンクの一覧を取得する

## 手順

要素を選択した後にこのコマンドをコンソールで実行するだけです。

```js
$$('a', $0).map(a => a.href)
```

## 使ってみた

### Yahoo News のトピックス一覧

コマンドはそのまま使えます。

[![](https://raw.githubusercontent.com/KtoZ/gif/main/20210623230112.gif)](https://raw.githubusercontent.com/KtoZ/gif/main/20210623230112.gif)

### TechCrunch Japan の新着順一覧

無駄なリンクを取り除くために selector に h2 を追加します。

```js
$$('h2 a', $0).map(a => a.href)
```

[![](https://raw.githubusercontent.com/KtoZ/gif/main/20210623232247.gif)](https://raw.githubusercontent.com/KtoZ/gif/main/20210623232247.gif)
Railsチュートリアル 第７章 リスト7.23のテストでArgumentError: wrong number of arguments (given 2, expected 1)

# はじめに
Railsチュートリアル7章のリスト7.23のテストで
`ArgumentError: wrong number of arguments (given 2, expected 1)`
とエラーが出たので、解決した方法をまとめておきます。

自分の環境
- ryby: 3.0.1
- rails: 6.1.3.2

## エラーが出た原因
ruby3.0以上を使っていると、キーワード引数の書き方が変わったため、書き方の問題でひっかかったぽいです。

## エラーがでたコードとエラーメッセージ

```ruby
require 'test_helper'

class UsersSignupTest < ActionDispatch::IntegrationTest

  test "invalid signup information" do
    get signup_path
    assert_no_difference 'User.count' do
      post users_path, params: { user: { name:  "",
                                         email: "user@invalid",
                                         password:              "foo",
                                         password_confirmation: "bar" } }
    end
    assert_template 'users/new'
  end
end
```

```
$ rails test
Running via Spring preloader in process 4852
Started with run options --seed 46915

ERROR["test_invalid_signup_information", #<Minitest::Reporters::Suite:0x00007f81d2250d18 @name="UsersSignupTest">, 2.133824999909848]
 test_invalid_signup_information#UsersSignupTest (2.13s)
Minitest::UnexpectedError:         ArgumentError: wrong number of arguments (given 2, expected 1)
            test/integration/users_signup_test.rb:8:in `block (2 levels) in <class:UsersSignupTest>'
            test/integration/users_signup_test.rb:7:in `block in <class:UsersSignupTest>'

  19/19: [=========================================] 100% Time: 00:00:02, Time: 00:00:02

Finished in 2.36285s
19 tests, 37 assertions, 0 failures, 1 errors, 0 skips
```

## 解決法
自分の場合はrubyのバージョンを2.7.3に変更しました。
どこかの記事で、8行目の`post users_path,`の`,`を削除すればテストが通ったみたいなのですが、その方法では10章で詰むみたいです。
いったんはバージョン下げて対応しました。
Mockoloをmintで使っているときに遭遇するエラー

Mockoloをmintで実装する際に、
Fatal error: The operation couldn’t be completed. (SwiftSyntax.ParserError error 1.)
というエラーに遭遇する。
これは、Xcodeとmockoloのバージョンがあっていないので、
[公式のリリースノート](https://github.com/uber/mockolo/releases)
からバージョンを確認し、
```
mint install uber/mockolo@1.4.0
```
のようにバージョンを指定してインストールする。
Mintfileでバージョンを指定すれば完了。
PowerAutomateでQuery stringを解析

#概要
Power AutomateでURIクエリ文字列を解析してフローで利用する方法の検証と覚え書きです。
例：```action=buy&itemid=111```
今のところ「クエリ文字列の解析」みたいなアクションやパース関数は見当たりませんので、現状のものを組み合わせて実現します。

#使いどころ
LINEと連携するフローで、「ユーザーがメッセージ内のボタンまたは画像をタップしたときに、実行されるアクションとしてpostbackアクション」があります。
以下のようなjsonがWebhookに送られるのですが、data部分に文字列でパラメータを渡してあげると、Automate側で受け取って様々な処理が可能です。
サンプルのjsonに合わせ、Power Automateでクエリ文字列を解析する必要がありました。
他の用途は思いつきませんｗ

https://developers.line.biz/ja/reference/messaging-api/#postback-action

```JSON
{
   "type":"postback",
   "label":"Buy",
   "data":"action=buy&itemid=111",
   "text":"Buy"
}
```

#方法

###フロー全体
・&でSplitしてForeach
・key,valueに分解
・AddPropertyでオブジェクトに追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/b005a2e4-3bdf-7be8-e7bb-d8215c116013.png)

###解説

まずは変数の初期化でオブジェクト型変数を作成します。
このオブジェクトに、```{ key1:value1, key2:value2 }```の形でパラメータのマッピングしていきます。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/ca2247aa-3315-07e2-415a-c0dc8d340612.png)

次にApply to eachを使います。
split関数により&で分割した配列を作り、一要素ずつ処理します。

```JavaScript
split(URIクエリ文字列,'&')
```
<br>
作成アクションを2つ追加し、それぞれ以下のように設定し、Key,Valueを抜き出しておきます。
Valueが%エンコーディングされている場合はdecodeUriComponent()でデコードします。

```JavaScript
//作成：key
substring(item(),0,indexOf(item(),'='))

//作成：Value
substring(item(),add(indexOf(item(),'='),1))
```
<br>
次に、addProperty関数を使ってオブジェクトにプロパティを追加します。
使い方はaddProperty(オブジェクト,key,value)です
一旦作成アクションを使って代入します。
※「変数の設定」により自身のオブジェクトをaddPropertyで書き換えようとするとエラーになるため。

```JavaScript
//作成：Add Property
addProperty(variables('QueryObject'),outputs('作成_Key'),outputs('作成_Value'))
```

最後に、オブジェクト型の変数を先程の「作成 Add Property」の出力で書き換えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/d9ef457d-89f0-bee1-0284-895219433b32.png)

これで以下のようにパラメータ名で値を取り出せるようになります。
```variables('QueryObject')?['ItemID']```


#ほかの方法

選択アクションでオブジェクトにマッピングする方法です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/ee800889-7b6b-b8fe-ad11-a80f3d33863b.png)

```JSON:出力
[
  {
    "key": "action",
    "value": "buy"
  },
  {
    "key": "itemId",
    "value": "111"
  }
]
```

アレイのフィルターアクションで、パラメータ名でフィルターし配列の1要素目を変数にセットします。
Apply to Eachより高速とはいえ、中々面倒ですね・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/2b91898d-8aa6-147d-8ea9-3885a9f57905.png)

```JSON:出力
{"key":"ItemID","value":"111"}
```

#その他
色々検証してみましたが、最終的にエスケープしたJSONを渡して「JSONの解析」でマッピングする方法に落ち着きました・・

```JSON
{
    "postback": {
        "data": "{ \"itemId\": \"57\", \"action\": \"buy\"}"
    }
}
```
【TypeScript】エラー「オブジェクトは 'null' である可能性があります。ts(2531)」

#　エラー内容

**GoogleMapsApi**を使って、クリックした箇所にマーカーを立てる機能を実装しているのですが、タイトルのようなエラーが下記コードの`marker` `maps` `map`のあたりで発生しました。

```GoogleMap.tsx
type SetLatLngProps = {
    [key: string]: any | number;
  };

  //地図クリックでの緯度経度取得
  const setLatLng: FC<SetLatLngProps> = ({ x, y, lat, lng, event }) => {
    if (marker) {
      marker.setMap(null); //ココ
    }
    const latLng = {
      lat,
      lng,
    };
    setMarker(
      new maps.Marker({ //ココ
        map,
        position: latLng,
      })
    );
    map.panTo(latLng); //ココ
    return <></>;
  };

```

> Object is possibly 'null'.  TS2531


# 対処法
https://www.fixes.pub/program/104994.html

上記サイトを参考に、`tsconfig.json`に下記コードを追記したところ、エラーは消えました。

```tsconfig.json
{
  "compilerOptions": {
    "strict": false,
    "strictPropertyInitialization": false,
    "strictNullChecks": false,
  }
}
```

**jsonファイル**などを変更した場合はターミナルにて`ctrl + C`で一旦サーバーをストップして、`yarn start`で再起動すると、変更が適応されました。

# まとめ
明確に「改善できた理由」はつかめていないのですが、引き続き開発を続ける中で理解していこうと思います。
JsonInclude(Include.NON_NULL)のNULLカラムをObjectMapperで強制出力

本稿は `JsonInclude(Include.NON_NULL)` を指定したclassのオブジェクトに対して、
値がnullでもデシリアライズ時に強制的に表示する方法についてのメモである。

# 背景と動機

ObjectMapperではなく、class定義でメンバごとに表示制御を行う場合、
基本的にObjectMapperに関係なく、nullメンバは表示されなくなる。
オブジェクトで指定してるのだからその動作は当然ではあるのだが、
私は開発環境向けにどうしても強制的に表示したくなった。
しかし、nullメンバを表示しない方法はたくさん見つかるが、
逆は全然情報が見つからなかった。

# nullメンバを非表示

オブジェクトの全メンバに対してnullの場合に表示しないようにするには
以下のようにクラスにJsonIncludeを付与すれば良い。
https://fasterxml.github.io/jackson-annotations/javadoc/2.9/com/fasterxml/jackson/annotation/JsonInclude.Include.html

```java
@JsonInclude(JsonInclude.Include.NON_NULL)
@Data
class MyObject {
  private String name;
  private Integer age;
}
```

このクラスのオブジェクトを値をnullにしてJSONデシリアライズすると
以下のように空のJSONになる。

```json
{}
```

# nullメンバを強制表示

今回の方法が必要になった経緯から説明すると、
私はデバッグ画面の入力用にメンバを含むJSONを用意したかったのだ。
正攻法で考えると初期化メソッドを持つinterfaceを作り、
それをimplementsさせれば有意な値を含めたJSONを作ることができるだろう。
しかし今回は、既に動いているアプリに対する修正を最小限にしたかったため、
"{}"をシリアライズし、そこから今度はデシリアライズして、
以下のような値を作りたいと考えた。

```json
{
  "name": null,
  "age": null
}
```

いろいろな方法を試した結果、AnnotationIntrospectorをカスタムで用意する方法で
実現できた。

```java
public class Hoge {
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper()
          .setAnnotationIntrospector(new CustomAnnotationIntrospector());

    private static class CustomAnnotationIntrospector extends JacksonAnnotationIntrospector {
        @Override
        public JsonInclude.Value findPropertyInclusion(Annotated a) {
            return JsonInclude.Value.empty();
        }
    }
}
```
https://fasterxml.github.io/jackson-databind/javadoc/2.8/com/fasterxml/jackson/databind/introspect/JacksonAnnotationIntrospector.html#findPropertyInclusion(com.fasterxml.jackson.databind.introspect.Annotated)

尚、上記のObjectMapperだと "{}" からのシリアライズはうまくいかないため、
私の要求を満たすにはシリアライズとデシリアライズでObjectMapperを別にする必要があった。
CocoaPods installed but not working のエラーの解決法


## 概要
パソコンを新しくした際に新しくflutterの環境を作るときに一瞬詰まった時のメモ

ターミナル上で```flutter doctor```コマンドを打った時に以下のエラーが出た

```
CocoaPods installed but not working.
You appear to have CocoaPods installed but it is not working.
This can happen if the version of Ruby that CocoaPods was installed with
is different from the one being used to invoke it.
This can usually be fixed by re-installing CocoaPods.
To re-install see
https://guides.cocoapods.org/using/getting-started.html#installation for instructions.
```

書いてある通りにCocoapodsをre-installしようとして、

```
sudo gem install cocoapods
```

を打ったが、以下のエラーが。

```
Function.c:867:17: error: implicit declaration of function 'ffi_prep_closure_loc' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
    ffiStatus = ffi_prep_closure_loc(closure->pcl, &fnInfo->ffi_cif, callback_invoke, closure, code)
```

どうやらc言語の部分でエラーが出ている？っぽい
ググったらxcodebuildのバージョンの違いで起こることがある模様。
Xcodeのバージョンを変えたら解決されるとも書いてあったが、それはしたくない。

他のやり方を模索しているとhomebrew経由でcocoapodsをインストールすればいいらしい

```
brew install cocoapods
```

いけた。ただその後の ```pod setup ``` コマンドで以下の新たなエラーが発生

```
rbenv: pod: command not found

The `pod' command exists in these Ruby versions:
  2.6.3
```

これはpodが入ってないな。。仕方ないので上のエラーを再度解決しに行く。
`-- --disable-system-libffi` オプションをつけて再度実行

```
sudo gem install cocoapods -- --disable-system-libffi
```

いけた！

最後に`pod setup` して `flutter doctor` でめでたしめでたし

```
flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.2.2, on macOS 11.4 20F71 darwin-x64, locale
    en-JP)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
[✓] Xcode - develop for iOS and macOS
[✓] Chrome - develop for the web
[✓] Android Studio (version 4.0)
[✓] VS Code (version 1.57.1)
[✓] Connected device (1 available)

• No issues found

```


### 参考記事
https://developer.apple.com/forums/thread/670189
https://github.com/flutter/flutter/issues/14293
https://qiita.com/ashketcham/items/980a61f4e2de2ae1bf21
ReactのInput × UseStateで便利な機能を実現

#Input×UseState

```
const [text, setText] = useState();

const onChangeText = (e) => {
  setText(e.target.value);
}

const onClickButton = () => {
  setText("");
}

return (
  <input placeholder="Textを入力" value={text} onChange={onChangeText}/><br />
  <button　onClick={onClickButton}>クリア</button>
);
```

上記のように、コンポーネントの中で、ステート変数を一つ宣言します。
そして、returnの中でinputタグを使って入力フォームを作ります。
inputの入力欄に文字を入力すると、onChangeに渡したonChangeText関数が実行され、入力した文字がステート変数にセットされるという処理になっています。

また、buttonタグでクリアボタンを作成したとします。
ボタンを押すと、onClickに渡したonClickButton関数が実行され、textの設定値が""になり、初期化されるようになっています。

inputのvalue={text}という箇所があることで、このようなクリアボタンを設置すると、ボタンを押すことでinputの入力欄を空白にリセットすることもできます。

onClickButton関数の中の処理に、textの値を使って何らかの処理を行うことで、inputに入力した値に応じた処理が適宜実行でき、また、同時にinputの入力欄もリセットできます。

#まとめ
Reactの勉強をしていて、これ便利だなと思ったので、忘れないように記事にさせていただきました。
初学者の方の参考になれば、とても嬉しいです。
起動画面のStoryboardを分岐させる

## やりたいこと
初回起動と2回目以降で、表示させるStoryboardを分岐させる。
開発の途中で「初回画面を追加したい」となり、起動時に遷移させる画面を変更するのに割と手こずってしまいました。

## 環境
Swift5, Xcode12

## やり方

メインとなる画面をMain.Storyboardで作っていたので、そこにViewControllerを追加するのが一番シンプルなやり方のようです。

![スクリーンショット 2021-06-23 22.45.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506559/af153ea4-cab6-c1e0-86e4-607c9f96cd1f.png)

作成した両方のStoryboardにidentifierを設定します。
![スクリーンショット 2021-06-23 22.49.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506559/255b7696-d2fc-f054-b882-89f420e01908.png)


SceneDelegateにコードを加えます。

```swift
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let _ = (scene as? UIWindowScene) else { return }
        
        //以下を追加
        let window = UIWindow(windowScene: scene as! UIWindowScene)
        self.window = window
        window.makeKeyAndVisible()
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        
        if lanchIsFirstTime() {
            logFirstLanch()
            let vc = storyboard.instantiateViewController(identifier: "初回起動で表示させたいViewのIdentifier")
            window.rootViewController = vc
        } else {
            let vc = storyboard.instantiateViewController(identifier: "2回目以降に表示させたいViewのIdentifier")
            window.rootViewController = vc
        }
}

//UserDefaultsをセット
func logFirstLanch() {
    return UserDefaults.standard.set(true, forKey: STORED_KEY)
}
func lanchIsFirstTime() -> Bool {
    return !UserDefaults.standard.bool(forKey: STORED_KEY)
}

```

あとは初回起動画面にsegueを追加するか、メインの画面への遷移処理を書けば完了です。

## 参考

- https://teratail.com/questions/222269
- https://kouki-hoshi.hatenablog.com/entry/2018/08/20/021107
【TP転職市場PJ日記その7】ついにβ版リリースとトラップ

#ここまでのTPサービスは…
バッチとかめっちゃがんばってCronとかにはまりつつも
どーにかこーにかcronの対応も何とか出来て
さて全体の動作確認をして開発環境＆本番環境つくってリリースまでいきまっしょい。
ってとこまで書いた気がするｗｗ

#動作確認
ひとまず主要な画面での動作確認に留めて登録・更新・削除ができるかといった物までは
確認スピード感を優先してライトな感じでのテストのみを行った。

#というわけで環境構築
テストも早々に終わらせ本番・開発環境構築
予算の都合上ConohaVPSでサーバー借りてそこに展開していくことに。

ちなみに環境は以下

OS:Debian
メモリ：1GB
CPU: 2Core
ストレージ：100GB

早々に借りてまずはdocker関連のインストール
案外公式で事足りた。

https://matsuand.github.io/docs.docker.jp.onthefly/engine/install/debian/

docker-compose up が叩けるようになったらgitも使うのでgitもインストール

git もインストールできたら一旦手動でリポジトリーをクローンしたりする。
この辺りの情報はネットにごろごろしているのでそちらをご覧になられたほうがよろしいよ。
ちなみにsshでクローンするようにしたら色々と都合よかったよ。

#ついでに自動デプロイも構築

https://kahoo.blog/github-actions-php-deploy/

実際に職場でも上記のActionsを使ってやっていたので真似してみた。
職場のクオリティとは雲泥の差かもしれないけど、一応 ``git pull``してdockerを再起動まで
一気通貫で自動でできるようにはしてみた。自動化ってかっこいい＾＾ 

#httpsで罠があって終わった件

さて、このサービスはセンシティブな情報を扱うサービスではないが
一応、一般的にhttps等使われているものは漏れなく合わせていきたいところ
というわけでhttps-portalを使うことに
※先人の方の記事を参考に実施

https://qiita.com/Yuttti/items/2a985174583e71ba46a0

※しかし、この方法で実施した際にdockerの再起動の度にhttpsの再発行が走ってしまい
リリース前にhttpsの証明発行ができなくなってしまう事態に…よく読んでなかったのが失敗だったわ。
リリースを優先したかったので一旦httpで行くことに。

#そしてリリース！今後について
とまぁ、httpsの発行等でつまずいたりしましたがまずはサービスの提供を優先
して、ひとまずはやり切った形で第１フェーズは終えられたんじゃないかなと思う。

そして今後は、ユーザー数の傾向を見ながら機能追加や性能改善にして行こうと思うが
ふむ、このサービスをより発展させる方法について考えていこうと思う。
（機能追加やそのほかナレッジあったらまた記事化を予定）

という訳でいったんおつかれちゃん～～＾＾
Power BI Free版はやっぱり 共有できなかった・・

# 概要
Premium/Pro 版を使えない、そんな悲しい環境にある人でも、ちょっと頑張れば何もない状態よりは共有化がましになりますよ、と~~いうメモ~~思ったら、試行期間中だったという愚かなお話でした・・

- ~~Power BI のレポートをメールで定期受信~~ Premium/Pro じゃないとダメでした。一時的な試行期間中だった為、自身への転送が出来ていただけでした。すみませんでした。😢
- Power Automateで、メールを転送

# Power BI のレポートをメールで定期受信
1. マイワークスペースに発行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/730ae31b-1852-172c-61d3-e33ed703d51a.png)
1. データセットの定期更新
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/1be3a557-44d8-8329-151e-727abdfe761f.png)
1. ~~メールの定期受信~~ [Premium/Proじゃないとダメでした。ごめんなさい](https://docs.microsoft.com/ja-jp/power-bi/consumer/end-user-subscribe)<br>
<code>自分用のサブスクリプションを 作成する には、Power BI Pro または Premium Per User の ライセンスが必要です。</code>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/6305a481-25c2-ff1a-9bf8-0eeedf15f951.png)
  - 自分以外をサブスクしようとすると・・premium 版にしろよーってメッセージ😂<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/3b612a21-9f83-e02b-8f1c-6a570599b077.png)

# Power Automateで、メールを転送
Premium版無くて頑張る人用

1. Mail 受信 Trigger
1. 添付の画像ファイルを取得
1. OneDriveにUpload <code>base64(contentBytes)にするとサイズが大きすぎるので・・</code>
1. Thumbnail取得
1. TeamsへPost<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/dba22c4c-a319-07a4-bb69-5616896908d1.png)

```json:postSample.json
{
    "type": "AdaptiveCard",
    "body": [
        {
            "type": "TextBlock",
            "wrap": true,
            "text": "Subscription for testForBI"
        },
        {
            "type": "Image",
            "url": "@{outputs('Get_file_thumbnail')?['body/Url']}"
        }
    ],
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "msteams": {
        "width": "full"
    },
    "version": "1.2"
}
```

# 実際の受信例
ってことで、無事、共有できるようになりました。
といっても、画像だけなので、BIとしては微妙です。
これを元に、Premium/Pro の購入を認めてもらう活動を地道にしていきますかね・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/c4e2f22e-9118-a70e-f376-6ec1738bdcd8.png)
【バックもフロントもNodeを使う人向け】monorepoで、コマンド一発でインストールを完了させる色々な方法

# TL;DR
npmやyarnの標準機能のみを使って、「ローカルで、コマンド一発で複数ディレクトリのパッケージインストール」を実現する。また、CIを実行しやすいように、それぞれのディレクトリにlockファイルができるようにする。

# はじめに
monorepoは複数のプロジェクトを一つのリポジトリで管理する手法です。例えば、Web開発ではフロントエンドとバックエンドを以下のように、同じリポジトリ内で管理することがあります。

```text:モノレポのディレクトリ
web/
server/
```
monorepoのメリットとしては、
- フロントとバックエンドでコードを共有しやすい(とくにTypeScriptの型定義)
- issueやPull requestがひとつのリポジトリに集まるため管理しやすい

などがあります。

# やりたいこと
- コマンド一発で、`web/`と`server/`の`yarn install`（もしくは`npm install` or `npm ci`）を完了させたい。あわよくば、コマンド一発でフロントとバックエンドを両方起動したい。
- `web/`と`server/`それぞれでlockファイルを持ちたい(「CIでweb側だけpackageをインストールをしてテストを走らせる」といったことがやりたいため)

# 解決方法
## 1. Docker Composeの利用
複数のコンテナを良い感じに扱える技術。環境による差異もなくせて便利です。ただし、Docker環境で開発するのは普通のローカル環境よりも実行速度が遅い(特にMacで顕著)のが難点です。チームメンバー全員がWindows or LinuxならばDockerでも良いのですが、Macで開発している人が多い場合は、「DBはDockerで、アプリケーションはローカルの環境で」という構成にしたいです。

## 2. Workspace機能を使う
npm v7やyarnのworkspaceを使うことで、ルートディレクトリでインストールコマンドを走らせるだけで良くなります。

```json:workspaceの設定例(package.json)
"workspaces": [
  "web",
  "server"
]
```
しかし、ルートディレクトリに1つのlockファイルがまとまってできてしまう問題が発生します。
webディレクトリで`yarn install`をすると、ルートのlockファイルは無視されてしまいます。かといってルートディレクトリでインストールすると、「フロント側のテストを走らせたいだけなのに、バックエンドのpackageもインストールされてしまう」という事態を招きます。


## 3. ルートディレクトリのnpm scriptsで解決(結論)
`yarn --cwd <ディレクトリ> <コマンド>`とすることで指定したディレクトリでコマンドを実行することができます([参考](https://classic.yarnpkg.com/en/docs/cli#toc-cwd))。
例えば、`yarn --cwd web install`とすると、webディレクトリで`yarn install`が実行されます。
npmの場合は`npm --prefix <ディレクトリ> <コマンド>`です。
この機能を使って、以下のようにルートディレクトリのpackage.jsonを設定します。

```json:package.json(yarnの場合)
"scripts": {
  "all:install": "yarn install && yarn --cwd web install && yarn --cwd server install",
  "all:dev": "run-p dev:*",
  "dev:web": "yarn --cwd dev",
  "dev:server": "yarn --cwd server"
},
"devDependencies": {
  "npm-run-all": "^4.1.5"
}
```
`run-p`はコマンドを並列実行します。
これにより、`yarn all:install`をするだけで、ルート・フロント・バックのパッケージインストールが終わります。また、`yarn all:dev`とすると、フロントとバック両方のdevサーバーが起動します。

# 最後に
他に良い方法がございましたらご教授いただけますと幸いです。
Python Challenge level 2

続けて[Python Challenge](http://www.pythonchallenge.com/) を解いていきます。

level 2: http://www.pythonchallenge.com/pc/def/ocr.html

# Level 2
![ocr.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62130/4a1944fa-d63c-565e-97b7-d37cde2c4914.jpeg)

本の画像にキャプションがついています。
>recognize the characters. maybe they are in the book, but MAYBE they are in the page source.

これがヒントでしょう。文字を認識せよ。多分その本の中にある、もしくは「多分」このページのソースコードの中にあるだろう。ぐらいの意味ですので、ヒントに従いソースコードを見てみましょう。

```html:ocr.html

<html>
<head>
  <title>ocr</title>
  <link rel="stylesheet" type="text/css" href="../style.css">
</head>
<body>
<center><img src="ocr.jpg">
<br><font color="#c03000">
recognize the characters. maybe they are in the book, <br>but MAYBE they 
are in the page source.</center>

<br>
<br>
<br>

<font size="-1" color="gold">
General tips:
<li>Use the hints. They are helpful, most of the times.</li>
<li>Investigate the data given to you.</li>
<li>Avoid looking for spoilers.</li>
<br>
Forums: <a href="http://www.pythonchallenge.com/forums"/>Python Challenge Forums</a>, 
read before you post.
<br>
IRC: irc.freenode.net #pythonchallenge
<br><br>
To see the solutions to the previous level, replace pc with pcc, i.e. go 
to: http://www.pythonchallenge.com/pcc/def/ocr.html

</body>
</html>

<!--
find rare characters in the mess below:
-->

<!--
%%$@_$^__#)^)&!_+]!*@&^}@[@%]()%+$&[(_@%+%$*^@$^!+]!&_#)_*}{}}!}_]$[%}@[{_@#_^{*
@##&{#&{&)*%(]{{([*}@[@&]+!!*{)!}{%+{))])[!^})+)$]#{*+^((@^@}$[**$&^{$!@#$%)!@(&
+^!{%_$&@^!}$_${)$_#)!({@!)(^}!*^&!$%_&&}&_#&@{)]{+)%*{&*%*&@%$+]!*__(#!*){%&@++
!_)^$&&%#+)}!@!)&^}**#!_$([$!$}#*^}$+&#[{*{}{((#$]{[$[$$()_#}!@}^@_&%^*!){*^^_$^
]@}#%[%!^[^_})+@&}{@*!(@$%$^)}[_!}(*}#}#___}!](@_{{(*#%!%%+*)^+#%}$+_]#}%!**#!^_
)@)$%%^{_%!@(&{!}$_$[)*!^&{}*#{!)@})!*{^&[&$#@)*@#@_@^_#*!@_#})+[^&!@*}^){%%{&#@
...続く
```

謎の記号列が延々とあります。ヒントとして
>find rare characters in the mess below
下部の乱雑記号の中から珍しい文字を探せ。

とあるのでこの中から探していけばいいようです。ただ、どう探していけばいいでしょうかというところで出てくるのが前問で使ったstr.maketransメソッドです。

- [str.maketrans](https://docs.python.org/ja/3/library/stdtypes.html#str.maketrans)

>第 3 引数を指定する場合、文字列を指定する必要があり、それに含まれる文字が None に対応付けられます。

Noneに対応づけられるというのがわかりにくですが、要するにmaketransの第３引数に指定した文字列はtranslateしたときに削除されるということです。

というわけで、pythonプログラムの方針は固まりましたので書いてみましょう。

#解答
```python:2.py
#!/usr/bin/env python3

removeChars = "#_!$@*+()[]{}%&^\n"
table = str.maketrans("","",removeChars)

coText="""
%%$@_$^__#)^)&!_+]!*@&^}@[@%]()%+$&[(_@%+%$*^@$^!+]!&_#)_*}{}}!}_]$[%}@[{_@#_^{*
#省略
#@}&$[[%]_&$+)$!%{(}$^$}*
"""

print(coText.translate(table))

```

## 出力結果
```
equality
```

# Level 3
ocr.html を equality.html に書き換えると次のレベルの扉が開かれました。

http://www.pythonchallenge.com/pc/def/equality.html
【TypeScript】エラー「型 'void' を型 'ReactElement<any, any> | null' に割り当てることはできません。」の解決法

# 該当コードとエラー文
```GoogleMap.tsx
  type SetLatLngProps = {
    [key: string]: any | number;
  };

//地図クリックでの緯度経度取得
  const setLatLng: FC<SetLatLngProps> = ({ x, y, lat, lng, event }) => {
    console.log(lat, lng);
  };
```

```
型 '({ x, y, lat, lng, event }: PropsWithChildren<SetLatLngProps>) => void' 
を型 'FC<SetLatLngProps>' に割り当てることはできません。
型 'void' を型 'ReactElement<any, any> | null' に割り当てることはできません。ts(2322)
```

上記コードを書いていたところ、`const setLatLng`に、↑のようなエラーが発生しました。

# 解決方法
```GoogleMap.tsx
  const setLatLng: FC<SetLatLngProps> = ({ x, y, lat, lng, event }) => {
    console.log(lat, lng);
    return <></>
  };
```
とりあえず空のオブジェクトをreturnしたらエラーは消えました。
Web技術の基本 Chapter3

* HTTPはHTMLなどのテキストファイルや、画像などのコンテンツやりとりするときに使われるプロトコル。
* HTTPメッセージはWebブラウザからの要求であるHTTPリクエストと、Webサーバーからの応答であるHTTPレスポンスの2種類に分けることができる
    * HTTPリクエストはリクエスト行、メッセージヘッダー、メッセージボディの3つに分けることができる。
    * WebブラウザからHTTPリクエストを受け取ったWebサーバーはリクエストを処理して、その結果をHTTPレスポンスとして応答する。
* HTTPリクエストを用いてWebサーバーに具体的な要求内容を伝えているのはHTTPリクエスト内に含まれるHTTPメソッド。
    * HTMLファイルなどをコンテンツを取得したい場合は、GETメソッド。
    * データをWebサーバーに対して送信する場合はPOSTメソッド。
* HTTPレスポンス内には、HTTPリクエストに対するWebサーバー内での処理結果が含まれている。それをステータスコードという。(404とか)
* HTTPリクエストとHTTPレスポンスはいずれもメッセージヘッダーを利用することで詳細な情報を送信することができる。
    * メッセージヘッダーは複数のヘッダーフィールドと呼ばれる行から成り立っている。
* TCPではまずクライアントとサーバーがお互いに通信できる状態なのかを確認し、コネクション呼ばれる通信経路を確立したうえでデータのやりとりをする。
    * クライアントからサーバーに対して、接続を要求するためのSYNパケットと呼ばれるデータを送る。
    * 信頼性のある通信を実現するために、データを送信した後、必ず送信相手からの確認応答を受け取ってデータの送信が完了したと判断する。その確認応答がACKパケットという。
* HTTP/1.1以降ではコネクションを継続して利用する方式となった。その機能をHTTPキープアライブと呼ぶ。
    * またHTTPにおけるデータのやりとりを効率化のために、HTTPパイプラインと呼ばれる機能がサポートされている。
* HTTP/2では1つのTCPコネクション上にストリームと呼ばれる仮想的な通信経路を複数生成し、それぞれのストリーム内でHTTPリクエストとレスポンスのやりとりを可能としている。
* HTTPSとはHTTPの通信において暗号化方式であるSSLやTLSを利用することで安全にWebサイトを使うことができる。
    * 盗聴防止
    * 改ざん防止
        * ネットバンキングにおいて振込先情報が書き換えられてしまうといった対策に対してメッセージダイジェストが利用される。
    * なりすまし防止
        * Webサーバーに配置されたSSLサーバー証明書と呼ばれる電子証明書を接続時に検証することで会社の身元を確認できる。
        * 証明書は信頼された認証局で発行される。
* ショッピングサイトなどで状態を保持し管理する必要がある場合はCookieと呼ばれるデータが用いられる。有効期限が設定されていないCookieはセッションCookieと呼ばれる。
    * WebサーバーはHTTPレスポンスにSet-CookieヘッダーでCookieを送信できる。
    * WebサーバーはHTTPリクエストにCookieヘッダーを含めることで送信できる。
* WebブラウザとWebサーバーのやりとりにおいて一連の関連性のある処理の流れをセッションと呼ぶ。
    * セッション管理においてWebブラウザを識別するための情報をセッションIDと呼ぶ。
* 情報やデータといったリソースを識別するための記述方法をURIと呼ぶ。
    * リソースが存在する場所を示すものをURLと呼ぶ。
    * URIのうち場所は問わずにリソースの名前示すものをURNと呼ぶ。
* HTTPにおいてもリソースを特定するためにURIが利用されている。HTTPリクエストの場合、URIはリクエスト行のメソッドに続いて記述され、リクエストURIと呼ばれる。
    * リクエストURIにはURIすべてを含める絶対URI形式と一部を相対URI形式がある。
* 予約文字でも非予約文字でもない文字をURIで利用する場合は、パーセントエンコーディングと呼ばれる方式を用いて文字を変換する必要がある。
時変データを２値化して変化の時間間隔をもとめる

```python
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

#データ読み込み
df = pd.read_excel('sampdata.xlsx')

#変数格納　1行目（時間）と２行目（電圧）
time = df.iloc[:,0]
volt = df.iloc[:,1]

#1,0のデータに変換
volt[volt>1] = 1
volt[volt<1] = 0

#電圧の微分を求める
volt_diff = np.diff(volt.values)

#電圧の微分と時間の数を合わせる
time2 = time[1:]

#電圧の微分が１以上の時間間隔と-1以下の時間間隔を求める
time_diff_p = np.diff(time2.values[volt_diff>0])
time_diff_m = np.diff(time2.values[volt_diff<0])

#グラフ描画
fig = plt.figure(figsize=(6, 4),
                dpi=72,
                facecolor='skyblue',
                linewidth=10,
                edgecolor='green')

ax = fig.add_subplot(1,1,1)
ax.plot(time2[volt_diff>0].values[1:], time_diff_p/np.max(time_diff_p), marker='o', color='tomato', linestyle='None')
ax.plot(time2[volt_diff<0].values[1:], time_diff_m/np.max(time_diff_m), marker='x', color='aqua', linestyle='None')
ax.plot(time, volt, marker='None', color='orange', linestyle='-')

#グラフ保存
fig.savefig('edge.png')
```
returnとputsの違い

## return と putsの違い
どちらも文を表示させる機能だが、メソッドを終了させるかどうかという点が異なる。

## return
・メソッドから脱出できる
・戻り値を受け取るだけ（putsしないと表示されない）

## puts
・メソッドを終了させない

## returnを使うとdefから脱出できる
```
def condition(money = "")
return "お金がない" if money.empty?
 "お金持ち"
end
puts condition("")
```

## returnを使わないとdefから脱出できない
```
def condition(money = "")
 "お金がない" if money.empty?
 "お金持ち"
end
puts condition("")
```
最後の文だけが機能するため、どんな値を入れても「お金持ち」しか表示されない



##selfの重要性
selfを用いた場合

```
class Menu
  attr_accessor :name
  attr_accessor :price
    end
  
  def info
    return "#{self.name} #{self.price}円"
  end
```

selfを用いない場合

```
class Menu
  attr_accessor :name
  attr_accessor :price
    end
  
  def info
    return "#{name} #{price}円"
  end
```

これらは出力値が同じだが、文法的にselfを使う意味はあるのか？

## 【結論】同名のローカル変数があるときに区別するためにselfを使用する
上記の例で言えば、複雑なプログラムを書くときにどの「name」か判別するためにselfを使用する
netcatで各種転送(図解)

# 凡例
- i: stdin
- o: stdout
- si: socket in
- so: socket out

nc は i を so に、si を o に繋げる。

# ポートフォワーディング
client:1111 と server:2222 を繋げる。

```bash:client
mkfifo fifo
<fifo nc -l 1111 | nc server 2222 >fifo
```

while ... done を付けると、1度のコネクションで終了しない。

### 実行例

以下の順番通りに実行する必要がある。

```bash:server
python3 -m http.server 2222
Serving HTTP on 0.0.0.0 port 2222 (http://0.0.0.0:2222/) ...
11.11.11.11 - - [23/Jun/2021 04:18:07] "GET / HTTP/1.1" 200 -
```

```bash:client
rm -f fifo && mkfifo fifo && while true; do <fifo nc -l 1111 | nc server 2222 >fifo; done
```

```bash:client
curl localhost:1111
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Directory listing for /</title>
</head>
<body>
<h1>Directory listing for /</h1>
<hr>
<ul>
<li><a href="fifo">fifo</a></li>
</ul>
<hr>
</body>
</html>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101023/7df08447-b729-76b7-1dde-21f1faf48a73.png)

# client同士を接続
client1 と client2 を server を介して接続。

```bash:server
mkfifo fifo
<fifo nc -l 1111 | nc -l 2222 >fifo
```

### 実行例

server を最初に実行する必要がある。それ以外は順不同。

```bash:server
rm -f fifo && mkfifo fifo && while true; do <fifo nc -l 1111 | nc -l 2222 >fifo; done
```

```bash:client1
nc server 1111
```

```bash:client2
nc server 2222
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101023/643f5d80-8aa3-da5e-b19b-ddcfd1f27c3b.png)
SerializableのserialVersionUIDが原因で発生するInvalidClassExceptionの対処方法

# serialVersionUIDとは

serialVersionUIDはSerializableなオブジェクトに定義するバージョン番号のようなものです。データのシリアライズ/デシリアライズする際に、互換性を確認するためにこのserialVersionUIDを使用します。

また、serialVersionUIDを定義しない場合、自動で計算されることになります。

## `InvalidClassException`

これは、Serializableなオブジェクトをデシリアライズする際、serialVersionUIDが異なる場合に発生します。

```
java.io.InvalidClassException
com.sample.data.SampleSerializableData; 
Incompatible class (SUID): 
    com.sample.data.SampleSerializableData: 
    static final long serialVersionUID =4092797215335171425L;
but expected com.sample.data.SampleSerializableData:
    static final long serialVersionUID =5140160798577733211L;
```

今回、SerializableなJavaクラスをKotlin化した際、誤ってserialVersionUIDを削除してしまったため、アプリバージョンアップの際にデータのデシリアライズができなくなってしまいました。

# 回避方法

今回、既にアプリのバージョンアップを何度か挟んでしまっていたため、serialVersionUIDを復活させてしまうと、今後はKotlin版のSerializableオブジェクトがデシリアライズできなくなってしまいます。そのため、以下の記事を参考にデシリアライザをカスタマイズすることで回避しました。

https://stackoverflow.com/questions/1816559/make-java-runtime-ignore-serialversionuids

## カスタムInputStream

`ObjectInputStream` をextendsして `readClassDescriptor`をoverrideしています。戻り値の
 `ObjectStreamClass` はSerializationの情報を持つオブジェクトです。クラス名とserialVersionUIDを含んでいます。

内容はコード内のコメントに記載しました。

```kotlin:CustomInputStream
class CustomInputStream(inputStream: InputStream) : ObjectInputStream(inputStream) {
    @Throws(IOException::class, ClassNotFoundException::class)
    override fun readClassDescriptor(): ObjectStreamClass? {
        // streamからクラス記述子を読み出します
        val resultClassDescriptor = super.readClassDescriptor() ?: return null

        // Class名を取得
        val localClass = try {
            Class.forName(resultClassDescriptor.name)
        } catch (e: ClassNotFoundException) {
            return resultClassDescriptor
        }

        // クラス名を、現在のアプリバイナリの中から探します
        val localClassDescriptor = ObjectStreamClass.lookup(localClass)
        // only if class implements serializable
        if (localClassDescriptor != null) {
            // 現在のアプリバイナリと、streamの中のそれぞれのserialVersionUIDを比較します
            val localSUID = localClassDescriptor.serialVersionUID
            val streamSUID = resultClassDescriptor.serialVersionUID
            // serialVersionUIDが異なる場合
            if (streamSUID != localSUID) {
                // streamのserialVersionUIDが正として、localClassDescriptorを使います
                return localClassDescriptor
            }
        }
        return resultClassDescriptor
    }
}
```

```kotlin:利用するとき
val objectInputStream = CustomInputStream(byteArrayInputStream)
val data = objectInputStream.readObject() as? SampleSerializableData
```

かなり強引な技ではあるので、どうにも回避方法がなくなってしまった場合の奥の手として使うのが良いと思います。また、利用箇所も限定的にして、他のSerializableには影響が出ないようにしましょう。