OmniAICreator/Qiita-1.07M huggingface dataset:
Pythonで月毎の土日祝日のリストを取得する

表題の通りです。ベストマッチな記事が見当たらなかったので。
実行環境はPython3系になります。

# 必要なモジュールのインポート
インストールされていない場合は`pip install`する必要があります。

```Python
import calendar, jpholiday
```

# 祝日を取得する
[GitHub - Lalcs/jpholiday: 日本の祝日を取得するライブラリ](https://github.com/Lalcs/jpholiday)

`jpholiday.month_holidays`を使います。2021年5月の祝日を取得する場合は以下のようになります。

```Python
holidays = list(map(lambda d: d[0], jpholiday.month_holidays(2021, 5)))
print(holidays)
# [datetime.date(2021, 5, 3), datetime.date(2021, 5, 4), datetime.date(2021, 5, 5)]
```

# 土日を取得する
`calendar.Calendar`のクラスメソッド`itermonthdates`を利用します。

[calendar --- 一般的なカレンダーに関する関数群 — Python 3.9.2 ドキュメント](https://docs.python.org/ja/3/library/calendar.html#calendar.Calendar.itermonthdates)
> year 年 month (1--12) 月に対するイテレータを返します。 このイテレータはその月の全ての日、およびその月が始まる前の日とその月が終わった後の日のうち、週の欠けを埋めるために必要な日を (datetime.date オブジェクトとして) 返します。

若干仕様がわかりにくいかと思うので補足すると、「**週の欠けを埋めるために必要な日**」というのは、「月曜日で始まり日曜日で終わるリストを返すために必要な前後の月の日」という意味です。

例えば2021年5月は土曜日に始まって月曜日に終わるので、月曜日で始まり日曜日で終わるリストにするため、4/26(月)~4/30(金)、6/1(火)~6/6(土)も含めるということです。

`itermonthdays`という似たようなメソッドもありますが、こちらは`datetime.date`オブジェクトではなく`int`やタプルで返ってきます。用途に応じて使い分けると良いと思います。

2021年5月の土日を取得する場合は以下のようになります。

```Python
c = calendar.Calendar()
donichi = list(filter(lambda d: d.month == 5 and d.weekday() in [5,6], c.itermonthdates(2021,5)))
print(donichi)
# [datetime.date(2021, 5, 1), datetime.date(2021, 5, 2), datetime.date(2021, 5, 8), datetime.date(2021, 5, 9), datetime.date(2021, 5, 15), datetime.date(2021, 5, 16), datetime.date(2021, 5, 22), datetime.date(2021, 5, 23), datetime.date(2021, 5, 29), datetime.date(2021, 5, 30)]
```
# マージして昇順にソートする
上で取得した2つのリストを重複の内容に結合して昇順にソートします。
重複を除外するために`set`に変換した後、ソートするためにリストに戻します。特に理由がなければ最初から`set`にしておいた方がスマートかも。

```Python
dns = sorted(list(set(holidays + donichi)), key=lambda d: d.day)
print(dns)
# [datetime.date(2021, 5, 1), datetime.date(2021, 5, 2), datetime.date(2021, 5, 3), datetime.date(2021, 5, 4), datetime.date(2021, 5, 5), datetime.date(2021, 5, 8), datetime.date(2021, 5, 9), datetime.date(2021, 5, 15), datetime.date(2021, 5, 16), datetime.date(2021, 5, 22), datetime.date(2021, 5, 23), datetime.date(2021, 5, 29), datetime.date(2021, 5, 30)]
```

上の3つを関数にまとめたら以下のようになります。`dns`は`Do Nichi Shukujitsu`の略です。
祝日・土日を`set`で取得するように変えました。

```Python
def get_dns_dates(y, m):
    """
    y年m月の土日祝日のリストを返却する
    """
    # 祝日を取得
    holidays = set(map(lambda d: d[0], jpholiday.month_holidays(y, m)))
    # 土日を取得
    c = calendar.Calendar()
    donichi = set(filter(lambda d: d.month == m and d.weekday() in [5,6], c.itermonthdates(y,m)))
    # マージして昇順にソート
    dns = sorted(list(holidays + donichi), key=lambda d: d.day)
    return dns
```

# 参考にした記事
[datetimeとjpholidayを組み合わせて、平日か土日祝日かを判定するスクリプト - Qiita](https://qiita.com/hid_tanabe/items/3c5e6e85c6c65f7b38be)
[Pythonで第何何曜日（第2月曜日など）の日付を取得 | note.nkmk.me](https://note.nkmk.me/python-calendar-day-of-nth-dow/)
【Ruby】chompメソッドを使って末尾の空白文字を取り除く方法

#プログラミング勉強日記
2021年3月30日

#chompメソッドとは
　文字列の末尾から改行コードを取り除いた文字列を返すStringクラスのメソッド。引数に空文字(`""`)を指定すると、末尾の改行コードをすべて取り除く。
　メソッド名の最後に!(ビックリマーク)を付けて破壊的メソッドを使用することもできる。chomp!メソッドを使うと、末尾の空白文字を取り除いた文字列を元の文字列に書きかえる。

```ruby:chompの使い方
# 末尾にのみ改行コードを持つ文字列の場合
str = "Hello World\n"
chompStr = str.chomp
#=> Hello World
```

```ruby:chomp!の使い方
# 末尾にのみ改行コードを持つ文字列の場合
str = "Hello World\n"
str.chomp!
#=> Hello World
```

#サンプルプログラム

```ruby
str = "Hello World\n"
printf("---%s---\n", str)

str = str.chomp
printf("---%s---\n", str)
```

```:実行結果
---Hello World
---
---Hello World---
```


#参考文献
[【Ruby入門】chomp、chop、strip、gsubによる改行の削除徹底比較！](https://www.sejuku.net/blog/19466)
[Rubyのchompメソッドで文字列末尾の改行文字を削除する方法【初心者向け】](https://techacademy.jp/magazine/19471)
AWS Cognito ユーザープールID、クライアントIDが漏洩したときの影響

# 影響範囲

https://aws.typepad.com/sajp/2017/05/aws-black-belt-online-seminaramazon-cognito_qa.html

↑こちらの記事に以下の質問と回答を見つけた。（2017/05/17）

>Q8: UserPoolIdとClientIdが漏れたときの影響範囲について教えてください。

>A8: UserPoolIdとClientIdを知ったクライアントがSignUpを実行できるようになります。しかし、一般的にConsumer向けのモバイルアプリやWebサービスはそもそもエンドユーザに新規ユーザ登録等の操作を許すことが多いため、Cognito Your User Poolsで構築したサービスに誰でもユーザ登録ができること自体は通常特に問題にはなりません。もし第三者によるユーザ登録操作を制限したいのであれば、ユーザ登録用のAPIを用意してクライアントからはそのAPIにアクセスするようにし、API内でAdminCreateUserなどを使ってユーザ登録を代行する方法などが考えられます。


# テスト
 
**1000人**登録できるかテストしてみた。

```javascript
for (i = 0; i < 1000; i++) {
  const userData = {
    userName: 'dummy-user-' + i,
    password: 'Ab12345!',
    email: 'xxxxxx@yyyyyy.zzz'
  };
  const poolData = {
    UserPoolId: 'ap-northeast-1_XXXXXX',
    ClientId: 'xxxxxxxxxxxxxxxxxxxxxxxxxx'
  }
  let attributeList = [];
  const dataEmail = {
      Name : 'email',
      Value : userData.email
  };
  const attributeEmail = new AmazonCognitoIdentity.CognitoUserAttribute(dataEmail);
  attributeList.push(attributeEmail);
  const userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);

  let cognitoUser;
  userPool.signUp(userData.userName, userData.password, attributeList, null, function(err, result){
      if (err) {
          alert(err);
          return;
      }
      cognitoUser = result.user;
      console.log('user name is ' + cognitoUser.getUsername());
  });
}
```

アラートが出た。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/41d11a86-f920-af29-92d4-fcab8fb99b97.png)

OKを連打していると新しいアラートが出た。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/710c5b58-b69c-181d-8015-10b84e039183.png)

後はこの2つのアラートの繰り返しだった。

↓なぜか最初の555人は失敗していた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/32fdf0c5-9379-3155-15ef-08b4de13be92.png)


# 結果

登録できたユーザー数：133
（dummy-user-556 ～ dummy-user-688）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/3953b1db-8860-827d-858b-3f8a77a883b9.png)

# 参考記事

https://aws.typepad.com/sajp/2017/05/aws-black-belt-online-seminaramazon-cognito_qa.html

https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/user-pool-lambda-pre-sign-up.html
PythonでExcel操作【openpyxl - 日付、通貨、日時のフォーマットを制御する】

### 考え方
数値セルに任意のフォーマットを与えることで実現する。
`cell.number_format()`でフォーマットを与える。
フォーマットはExcelVBAで既定の表記を利用する。

### 今回サンプルで使用するExcelフォーマット用の書式（記号）
`;` 式を区切る。式の数によって挙動が変わる。
`""`  文字列として認識させる。
`#`  桁を表す。その桁に数字があれば表示。
`0`  一桁の場合はその数字を表示。一桁では無かったら省略。
`y m d h m s` 年 月 日 時 分 秒

詳細はこちら：[microsoft公式ドキュメント](https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/format-function-visual-basic-for-applications)
## 日付、通貨
![sample1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1233009/61623b13-7d8e-8660-caf6-9a6adcdc8ca3.png)
A列では与える書式をそのまま表示、BとCは各処理をさせた後の値を表示。

```python:
import openpyxl as xl
book = xl.Workbook()
sheet = book.active

# セルに値とフォーマットを与える関数
def set_cell(cname, value, fmt):
    c = sheet[cname]
    c.value = value
    c.number_format = fmt

# ３桁ごとにカンマ区切りを指定
keta3_fmt = '#,##0'
sheet["A1"] = keta3_fmt
set_cell("B1", 12345, keta3_fmt)
set_cell("C1", 123456789, keta3_fmt)

# 通貨形式を指定
cur_fmt = '"\"#,##0;"\"\\-#,##0'
sheet["A2"] = cur_fmt
set_cell("B2", 12345, cur_fmt)
set_cell("C2", -12345, cur_fmt)

# 数値のマイナス値を△で表し、赤色にする
num_fmt = '#,##0;[red]"△"#,##0'
sheet["A3"] = num_fmt
set_cell("B3", 12345, num_fmt)
set_cell("C3", -12345, num_fmt)

book.save("format_sample.xlsx")
```

## 日時
![sample2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1233009/f3b81b22-5476-e2b3-52c8-ac520380e2b6.png)

```python:
import openpyxl as xl
import datetime
book = xl.Workbook()
sheet = book.active

# A1 ~ D1 に同じ日時の値を指定
dt = datetime.datetime(year = 2023, month = 4, day = 5, hour = 11, minute = 22, second = 33)
sheet.append([dt, dt, dt, dt])

sheet["A1"].number_format = "yyyy/mm/dd"
sheet["B1"].number_format = "yyyy年mm月dd日"
sheet["C1"].number_format = "hh:mm:ss"
sheet["D1"].number_format = "mm/dd hh:mm:ss"

book.save("format_sample.xlsx")
```
AppleのNotarization (公証) を通したmacOSアプリを野良配布する

## 動機 ##
Xcodeで簡単にmacOSアプリのNotarizationを通せるようになったけど、いざ配布してみたら「マルウェアじゃねぇの？」ダイアログが出てくるし、Big Surに至ってはアプリが起動できない！あれー？ってなったので、そうならない方法を調べた。

## ざっくりいうと・・・##
- ビルド設定でHardened Runtimeを有効にする。
- アプリをcodesignする。これはXcodeが勝手にやってくれるからいい。
- アプリをAppleに送って公証を受ける。Xcodeがやってくれる。

ここまではいい。普通。ここから先が重要かつXcodeが面倒みてくれなかった。

- アプリをZipする。普通にやっちゃだめ。
- ZipファイルをAppleに送って公証を受ける。

Zipしたらそのファイルも送らなきゃダメで、それはターミナル開いてシコシコとコマンド打たないとならなくてめんどくさかった。
 
## 具体的なやり方 ##
### Hardened Runtimeを有効にする ###
Xcodeでプロジェクトを開いてBuild Settingsを表示、検索窓に"hard"と入力したら"Enable Hardened Runtime"が出るので"Yes"にする。これでアプリをビルド（メニューのProductからArchiveを選択）。

### アプリをcodesignしてAppleに送る ###
ビルドが終わったらOrganizerが勝手に開いてビルドしたアプリが一番上に来てるので、それを選択して右側の"Distribute App”ボタンをクリック。Select a method of distribution:と聞かれるので、Developer IDを選択してNext。Uploadを選択してNext。諸々聞かれるけどXcodeにsigningを任せる設定でどんどん進んでアップロードする。アップロードしてしばらく経つと、Notarizationできたよというメールが来る（失敗したことないので失敗したらどうなるかは知らない）。

### アプリをExport ###
公証済みのアプリを選択して、"Export App"ボタンをクリック。適当な場所にアプリを保存する。

### アプリをZipする ###
ここからは[オフィシャルのコレ](https://developer.apple.com/documentation/xcode/notarizing_macos_software_before_distribution/customizing_the_notarization_workflow)に沿って進める。

ターミナルを開いて下記のコマンドを。パスは書くのめんどくさいから、ファイルのドラッグ＆ドロップで適宜やればOK。

```
ditto -c -k --keepParent "アプリのパス" "作成したいZipファイルのパス"
```

### App Passwordを取得する ###
[ここ](https://support.apple.com/en-us/HT204397)を見てApp Passwordなるものを取得。一度取得したら以後は取得したパスワードが使える。

### AppleにZipファイルを送る ###

```
% xcrun altool --notarize-app --primary-bundle-id "アプリのBundle ID" --username "アカウントのメールアドレス" --password "取得したApp Password" --file "Zipファイルのパス"
```

説明には --asc-provider <ProviderShortname> を指定するように書いてあるが、説明で後述されている通り個人でアプリを作ってる場合は端折って構わない。

このコマンドの実行はしばらく時間がかかる。公証が終わるとAppleからメールが届く。その後はそのZipファイルを配布すれば「マルウェアかも…」って言われない！

以上。
SQL Server に　使用されているデータ型を　一括で取得用クエリ

```sample.sql
SELECT
  c.name AS データ型
FROM dbo.syscolumns a
INNER JOIN
  dbo.sysobjects b ON a.id = b.id
INNER JOIN  dbo.systypes c ON a.xtype = c.xtype
LEFT OUTER JOIN dbo.sysindexkeys ON a.colid = dbo.sysindexkeys.colid AND a.id = dbo.sysindexkeys.id AND dbo.sysindexkeys.indid=1
LEFT OUTER JOIN dbo.syscomments ON a.cdefault = dbo.syscomments.id
INNER JOIN (
select id,name as テーブル名称 from sysobjects
where xtype='U'
 ) DT On b.name=dt.テーブル名称
where c.name<>'sysname'
group by c.name
```

>実行結果の例
bit
datetime
int
nchar
numeric
nvarchar
varchar
Rinkebyテストネットにコントラクトをmigrate出来ん。Truffle: “Migrations” – transaction could not be decoded:

### 環境
- Truffle v5.2.4 (core: 5.2.4)
- Solidity - 0.5.8 (solc-js)
- Node v10.16.0
- Web3.js v1.2.9

### やりたかったこと
あるコントラクトをTruffleを使ってRinkebyテストネットにmigrateしたかったが、`Truffle: “Migrations” – transaction could not be decoded:`ていうエラーが出てしまった。

### ググった結果
[Truffle: “Migrations” – transaction could not be decoded: could not recover secp256k1 key: calculated Rx is larger than curve P](https://forum.openzeppelin.com/t/truffle-migrations-transaction-could-not-be-decoded-could-not-recover-secp256k1-key-calculated-rx-is-larger-than-curve-p/6405/7)で、@abcoathupさんがいう通りに**[Truffle HD Wallet Provider](https://www.npmjs.com/package/@truffle/hdwallet-provider)のバージョンを@1.2.5から@1.2.3にダウングレードする**と無事コントラクトをmigrateすることが出来ました。

### テストネットにmigrateするチュートリアル
ちなみにこのチュートリアルを参考にコントラクトのmigrateをしました。
- [Connecting to Public Test Networks with Truffle](https://forum.openzeppelin.com/t/connecting-to-public-test-networks-with-truffle/2960)

以上です。最後まで読んでいただきありがとうございました！
【C++】メンバ関数を関数ポインタ配列(std::vector)に格納する方法

## はじめに
- __メンバ関数__ を関数ポインタで参照したい時の備忘録です。
    - std::vectorに関数ポインタを格納する方法もまとめました。

### フォルダ構成
├── classA.h ・・・関数ポインタで参照したいクラス
└── main.cpp

- とあるクラスClassAと、それを参照するmain.cppから構成されています。
    - ※ 今回は説明をコンパクトにするため、ClassAはヘッダ実装にしています。


#### classA.h
- ClassAのメンバ関数は以下の2つとします。
    - add(): 二つの引数の __和__ を返却する関数
    - sub(): 二つの引数の __差__ を返却する関数

```c++:classA.h
#pragma once
#include <iostream>


class ClassA
{
public:
	ClassA(){}
	~ClassA(){}

	// 関数ポインタで参照したい関数①
	int add(const int& a, const int& b){
		std::cout << "ClassA::add() ";
		return a + b;
	}

	// 関数ポインタで参照したい関数②
	int sub(const int& a, const int& b){
		std::cout << "ClassA::sub() ";
		return a - b;
	}
};
```

#### main.cpp
- 次にClassAを利用する側を定義します。
    - 通常関数（非メンバ関数）の関数ポインタの定義と比較します。

```c++:main.cpp
#include "classA.h"
#include <iostream>
#include <vector>


// 通常関数(1) //
int add(const int& a, const int& b) {
    std::cout << "add() ";
    return a + b;
}

// 通常関数(2) //
int sub(const int& a, const int& b) {
    std::cout << "sub() ";
    return a - b;
}

// 関数ポインタの自作型を定義する //
typedef int(*FUNC)(const int& a, const int& b);  // 通常関数の場合
typedef int(ClassA::*MEMBER_FUNC)(const int& a, const int& b); // メンバ関数の場合


int main()
{
    // 関数ポインタ型を持つvectorの定義
    std::vector<FUNC> functionList;
    std::vector<MEMBER_FUNC> memberFuncList;

    // 通常関数をvectorに格納する
    functionList.push_back(add);
    functionList.push_back(sub);
    functionList.push_back(add);

    // メンバ関数をvectorに格納する
    memberFuncList.push_back(&ClassA::add);
    memberFuncList.push_back(&ClassA::sub);
    memberFuncList.push_back(&ClassA::add);


    for (auto func : functionList) {
        std::cout << func(1, 1) << std::endl; // 通常関数の参照
    }

    auto* pA = new ClassA();  // <-- 実体が必要です
    for (auto memberFunc : memberFuncList) {
        std::cout << (pA->*memberFunc)(1, 1) << std::endl; // メンバ関数の参照
    }
}

```

#### 補足説明
- 関数ポインタの型名定義
    - `typedef 返り値型(クラス名::*自作関数ポインタ型名)(仮引数リスト)`のように定義します。
        - サンプルコードでは、`typedef int(ClassA::*MEMBER_FUNC)(const int& a, const int& b)`の部分に相当します
        - 返り値型、引数リストは参照する関数の定義と一致しなければなりません。
        - `MEMBER_FUNC`の部分は、任意の名前に置換することが可能です。

- 関数ポインタ型を持つvectorの定義
    - `std::vector<Type T>` の部分に、自作した関数ポインタ型を指定してあげればOKです。

- メンバ関数をvectorに格納する
    - `&(クラス名::メンバ関数名)`のように格納します
    - 一方で、通常関数の場合は、単純に`関数名`の指定でOKです

- メンバ関数の参照
    - 参照する場合は少し癖があります。
        - `auto* pA = new ClassA();`のように実体を定義し、その実体の関数を参照する形になります。
        - メンバ関数の呼び出しは、`(pA->*memberFunc)(実引数)`のように記述します。
            - `pA->memberFunc(実引数)`のようにカッコを忘れたり、＊を忘れるとエラーになります。

### 実行結果
- サンプルコードを実行すると、以下のように出力されます。

```bash:console
add() 2
sub() 0
add() 2
ClassA::add() 2
ClassA::sub() 0
ClassA::add() 2
```

### 何に使えるの？
- 決まった順序での動作が必要となる場面（シーケンス制御、ロボット制御など）で使っています。


### 参考記事
- https://programming-place.net/ppp/contents/cpp/language/034.html#member_pointer
- http://bassdrive.blog.fc2.com/blog-entry-2.html
[TypeScript] 配列内の重複オブジェクトのインデックスを取得する


オブジェクトの配列のなかで、キーが重複しているオブジェクトのインデックスを取得する必要があったので、備忘録として残しておきます。
言葉だと伝わりにくいですが、以下のニュアンスとなります。

```sample.js
const list = [
  { id: 1, name: "banana" },
  { id: 2, name: "apple" },
  { id: 3, name: "grape" },
  { id: 2, name: "apple" },
];

// idが重複している 1, 3 の値を取得したい
```
書き方は色々あると思いますが、以下で対応しました。

```sample.js
// for文で回すが、重複がある場合はduplicateLengthが1より大きくなる
for (let i = 0; i < list.length; i++) {
  const duplicateLength = list.filter((obj) => obj.id === list[i].id).length;
  duplicateLength > 1 ? console.log("index",i) : null;
}

> "index" 1
> "index" 3
```
VBA▶️Python移行者への基礎TIPS

#対象のエクセルの設定方法
業務上作業対象エクセルは、Ｐｙｔｈｏｎで作成したフォルダと同じことはないため、指定する必要がある。

r'を使用する。 ファイル指定時に¥¥のようにエスケープは２つ入力が必要となるが、
r'/Users/Downloads/　のように、r'を付けることだけでコード作成が楽になる。

globを理解していなくても使えるように！
指定フォルダの指定条件のファイルをまとめて選択できる。これがとても便利です。

え？VBAを使いたい、xlwingをimportするんだ！
某YoutuberのクイズっぽいSPA作ってみた。

## 動機

フロントエンドの勉強のために何かSPAを作りたいと考えていました。
とはいえ、「何を作ればいいのか」思いつかない・・・
そんなことを考えながら、最近好きになったQuizKnockの動画を見ていたときに、ふと思いました。

https://www.youtube.com/watch?v=5LBYNrZ-Gug

クイズゲーム、基本的なところを網羅できて、勉強で作るものとして最適なのでは？

* 正誤判定など、条件に応じた表示内容の変更が必要である
* 問題ページ、結果ページなど、複数のページが必要である（→vue-router）
* ユーザーが選択した答えを保持する必要がある（→vuex）
* クイズの問題をサーバーから取得するようなAPIを作る（→axios）

## 作ったもの

http://vegetable-quiz.s3-website-ap-northeast-1.amazonaws.com/

[https://github.com/shima-218/quiz-app](https://github.com/shima-218/quiz-app)

## 構成

![quizapp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566051/6d78ab87-6873-e16c-57f4-69d784301593.png)

* S3の静的ホスティング機能を利用し、Vueアプリをデプロイ 
* APIを叩いてDynamoDBに格納されたクイズの情報を取得
  * APIGatewayとDynamoDBの間にlambdaを介す構成が多いようですが、今回は特に複雑なデータ取得を行わないので、余計なサービスは挟まないシンプルな構成にしました。

## 所感など

### 初心者に公式ドキュメントは難易度が高い？
「Vue.jsは公式ドキュメントが分かりやすいため、公式ドキュメントで勉強すれば良い」
述べている記事をよく見かけますが、私の場合、最初は公式ドキュメントを読んでも全く理解できませんでした・・・
そんな中、救世主となったのが、[大阪コード学園さんのYoutube講座](https://www.youtube.com/watch?v=rfZfrNmIiJk&list=PLkQpCfbvj0lwds9oPsRRrFp1ZxTGyueqv)。
基本的な内容から分かりやすく解説されており、こちらの動画で一通り基礎を理解した後だと、公式ドキュメントの記載も理解できるようになりました。

### CDN版から始めなくても良い？

「CDN版で勉強してから、Vue CLIに移行するという」というVue.jsの学習ステップがよく紹介されていますが、私の場合、「言語自体を勉強したい」というよりは「Webアプリを作りたい」という目的が強かったので、CDN版は使わず、最初からWebアプリ向きのVue CLIを用いました。
CDN版を経なかったことによる学習への支障は全く無かったため、必ずしもCDN版から始めなくても良いのではないかと感じました。

### Vue3は(2021年3月時点では)まだまだ情報が少ない

Web上の情報はほとんどがVue2のものです。おおよそVue3でも当てはまることが多いのですが、細かなところでVue3とVue2で書き方が違う点があり、Webで解決策をなかなか見つけられませんでした。
また、BuefyのようなUIコンポーネントも、まだVue3に対応していないものが多く、注意が必要です。
Roo / Ruby on Rails Gem 日本語訳(3)

**今回実務で扱ったRubyonRailのGem`Roo`についてまとめました。
ソースコード: https://github.com/roo-rb/roo**
**前回の投稿の続きです
→[Roo / Ruby on Rails Gem 日本語訳(1)](https://qiita.com/tako_tako/items/6d2aaaa35ccc21fb478e)
→[Roo / Ruby on Rails Gem 日本語訳(2)](https://qiita.com/tako_tako/items/0ec086e280c74fe86701)**
# 投稿動機
**→実務で扱ったGemを復習する
→Githubなどのソースコードにビビらないようになりたい
→将来実務で英語を使いたいので、そのポートフォリオの一環として作成したい**

**また、最後にも記載しますが著作権に関して疎いので、この記事が著作権違反にあたらないと認識して投稿しています。
なので、著作権を侵害するつもりもありませんし、もし著作権違反になるようであればすぐにこの投稿を削除します。**

**I will mention at the end, I am not familiar with copyright, so I am posting this article recognizing that it does not violate copyright.
So I don't intend to infringe copyright, and if it does, I'll delete this post immediately.**

# Roo

### OpenOffice / LibreOffice 
`Roo::OpenOffice`は暗号化されたOpenOfficeのスプレッドシートをサポートしています。

```
# 暗号化されたOpenOfficeのスプレットシートをロードします。
ods = Roo::OpenOffice.new("myspreadsheet.ods", password: "password")
```

`Roo::OpenOffice`は下記のタイプにアクセスできます。
 `celltype`, `comments`, `font information`, `formulas`,　`labels`

```
ods.celltype
# => :percentage

ods.comment(1,1, ods.sheets[-1])

ods.font(1,1).italic?
# => false

ods.formula('A', 2)
```

### CSV

```
# CSVファイルをロード
csv = Roo::CSV.new("mycsv.csv")
```

`Roo`は`CSV`ファイルを標準ライブラリとして使用しているため、`CSV`で使われているライブラリでそのまま解析できます。
`csv_options key`を使用してオプションを渡します。

For instance, you can load tab-delimited files (.tsv), and you can use a particular encoding when opening the file.

```
# CSVをタブで区切ってロードします。
csv = Roo::CSV.new("mytsv.tsv", csv_options: {col_sep: "\t"})

# エンコーディングを使用してCSVをロードします。
csv = Roo::CSV.new("mycsv.csv", csv_options: {encoding: Encoding::ISO_8859_1})
```

もちろん、`Roo::Spreadsheet`を用いて`CSV`ファイルを開けます。
(`CSV`ファイルと`Excel`ファイルを両方使うなら`Roo::Spreadsheet`の方が便利です)

```
# スプレッドシートを`path`で開く
# Roo figures out the right parser based on file extension
spreadsheet = Roo::Spreadsheet.open(csv_or_xlsx_file)

# csvファイルを`BOM`で自動で並び替えて取得します。
# Excel経由で取得したCSVファイルには通常、ファイルの先頭に`BOM`マークがつきます。
spreadsheet = Roo::Spreadsheet.open("mycsv.csv", { csv_options: { encoding: 'bom|utf-8' } })
```

### `Roo 1.13.x`からアップデート
もし`.xls`や`グーグルスプレッドシート`を扱うのであれば、`roo-xls`や`roo-google`をインストールして使いましょう！

`Roo`のメソッドは1.13.xから2.0.0一貫して繋がっていますが、チェンジログをみていただいた方がより`Roo`を理解できます。
Roo's public methods have stayed relatively consistent between 1.13.x and 2.0.0, but please check the Changelog to better understand the changes made since 1.13.x.

**前回の投稿
→[Roo / Ruby on Rails Gem 日本語訳(1)](https://qiita.com/tako_tako/items/6d2aaaa35ccc21fb478e)
→[Roo / Ruby on Rails Gem 日本語訳(2)](https://qiita.com/tako_tako/items/0ec086e280c74fe86701)**


## 最後に
**著作権に関して疎いので、この記事が著作権違反にあたらないと認識して投稿しています。
なので、著作権を侵害するつもりもありませんし、もし著作権違反になるようであればすぐにこの投稿を削除します。**

**I am not familiar with copyright, so I am posting this article recognizing that it does not violate copyright.
So I don't intend to infringe copyright, and if it does, I'll delete this post immediately.**
リファクタリングに関する知識

#本記事について
プログラミング初心者がリファクタリングに関する知識を学んだので、その備忘録として載せております。

どうかお手柔らかにお願いいたしますm (- -)(_ _)ペコリ

##リファクタリング
・コードの保守性向上などの目的で、アプリケーションを利用するユーザーからみたアプリケーションの動作は変えずに内部のコードを整理すること

・クライアントから見たアプリケーションの状態は変更せずに内部のコードを整理すること
→プログラムの動きを変えないまま、コードを書き換えること
→コードを綺麗にすること

・無駄な処理を省いて処理の流れをわかりやすくする
複雑なコードをシンプルにしコードを見やすくする
最新のメソッドやシンプルなコードにより、その後の仕様変更や改修などで効率化

・webアプリケーションを全世界に公開後は既存のコードよりもより良いものにするリファクタリングを行なっていく。

・人の話をメモに書き、後にそのメモを元にノートにまとめる作業のようなもの

##命名規則
変数名や関数（メソッド）名など、名称となる文字列に設けられた一定のルール

##キャメルケース
単語の先頭を大文字にしてつなげる表記方法
大文字と小文字が凸凹しているのがラクダ（camel）に似ているから。
関数や変数など


例）hogeData
　　HogeData

##スネークケース
単語間をアンダースコアでつなげる表記法
見た目が蛇（sanake）に似ているから。
DBで扱う値など

例）hoge_data

・命名規則がバラバラになっていると可読性も低下し改修コストが増える可能性もあり、バグの原因にもなる可能性が出てくる。

・クラスやメソッドを作成するときには命名規則は守る。

以上です。
【Swift】正規表現まとめ

#はじめに
正規表現をまとめてみました。

#正規表現とは？
正規表現とは、一言で言うと`文字列の集合体のパターン(共通点)を表現する表記法`です。

###文字列
文字列とは文字の集合体で順番が決まっているもののことを指します。

```
abc
drink 
This is an apple.
```
などです。スペースも文字(空文字)として扱われます。

###バリデーション
アプリ開発で正規表現の実装を使う時、一番多いのはバリデーションをする時みたいです。バリデーションとは、直訳で`検証`と言う意味です。例えば、メールアドレスが正しい構成で入力されているかどうかをチェックすることをバリデーションといいます。

#正規表現の例
以下の3単語が一致するかどうかをみていきましょう。

```swift
red 
black
green
```

###量指定子
|記号|意味|条件例|一致する単語|
|:--|:--|:--|:--|
|*|直前の要素と0回以上一致|e*|black, red|
|+|直前の要素と1回以上一致|e+|red, green|
|?|直前の要素と0回または1回一致|e?|black, red|
|{n}|直前の要素と丁度n回一致|e{2}|green|
|{n,}|直前の要素とn回以上一致|e{1,}|red, green|
|{n,m}|直前の要素とn回以上m回以下で一致|e{2,5}|green|

###文字クラス
|記号|意味|条件例|一致する単語|
|:--|:--|:--|:--|
|[]|カッコ内のいずれか一文字|[abc]|a|
|[^]|カッコ内以外の文字n|[^abc]|d|
|[a-z]|aからzまでの小文字アルファベットのいずれか1文字(ハイフンを含める場合[-a-z])|[-c-m]|g|
|[A-Z]|AからZまでの大文字アルファベットのいずれか1文字|[B-Y]|E|
|[0-9]|0から9までの数字のいずれか１文字|[1-4]|3|
|()|カッコ内の文字を文字列として認識|(abc)|abc|

###論理演算子との併用
「かつ」は`&&`です。「または」は`|`です。
`[a-z&&[^r]]`のように書く事ができます。この場合、aからzかつrを除くと読む事ができるので、r以外のaからzと言う事ですね。

###文字・数字
|記号|補足|意味|
|:--|:--|:--|
|.||任意の一文字（改行以外）|
|\d|Decimal number(１０進数)のD|任意の数字一文字([0-9]に同じ)|
|\D||数字以外の１文字([^0-9]に同じ)|
|\w|wordのw|英数字１文字([a-zA-Z0-9]に同じ)|
|\W||英数字以外の１文字([^a-zA-Z0-9]に同じ)|
|\s|spaceのs|空白１文字|
|\S||空白以外の１文字|
|\t|tabのt|タブ１文字|
|\T||タブ１文字以外|
|\n|new lineのn|改行１文字|

#おわりに
おわりです。
K9s on Windows

Windows 上で K9s を使いたかったのですが、その時の試行錯誤の記録

## 結論

Windows Terminal + WSL/Ubuntu20.04 + Consolasフォントを使うと良い感じでした。
Chocolateyでの管理は最終的に諦める事にして、正しく表示できるこの形に落ち着きました。

## Chocolateyで インストール

インストール方法について公式では chocolatey が紹介されていますが、

choco install -y k9s

2021/3/30現在だと 最新の0.24.6は提供されていなくて、0.24.4 になってます。
ちょっと残念ですが、気にせず試してみます。

## 実行環境その１

コマンドプロンプトで実行するとこんな感じ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128512/462f8ffb-c634-949a-0aec-8c8e42eb8551.png)

pulseとか酷くて見られないです...orz
ラスターフォントから、外のフォントに変えて試したりもしましたが、無理っす。次

## ConEmu + Consolas

フォントにConsolasが選べるので それを選ぶと少し良くなりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128512/21cef688-9884-11a7-f99d-cf473e85d0b7.png)

ただ、ウィンドウサイズを変更すると落ちるので正直これは駄目かなという感じ。
コマンドプロンプトを使っていたときも 再描画イベントがかなりちらつきましたが落ちる事はなかったです。

## Windows Terminal + cmd.exe

ConEmuと大差ありませんが、カラー絵文字になってます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128512/810de852-1d56-b7f5-43ee-19569de0653c.png)

サイズ変更時のちらつきもありますが、描画が高速な事もあって特に問題無いです。
あと絵文字が使える様になるので : を入れたときの犬もちゃんと表示されます。

ただ、やっぱり画面が壊れすぎ。`choco uninstall -y k9s`する事に。

## WSL/Ubuntu 20.04+Consolas

というわけで、最後にたどりついたのがchocolateyでのインストールを諦めて
WSL の Ubuntu20.04 上にインストールした k9s を使います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128512/9b4f2c1b-1cc8-3113-2cd9-f4564cb0b2ba.png)

完璧。これだと 0.24.6使えるのが良いですね。

## 余談

Terminalの 起動設定はこんな感じにしています。
configは %USERHOME% 以下の .kube/config にあるので、それだけ指定。

```json
            {
                "name": "K9s",
                "fontFace": "Consolas",
                "fontSize": 11,
                "commandline": "wsl k9s --kubeconfig /mnt/c/Users/username/.kube/config",
                "hidden": false
            },
```
Volley で Json Object を渡して Json Array を受け取る

# やりたいこと

リクエストが JSON Object で、レスポンスが JSON Array である API エンドポイントに、Volley でリクエストを投げたい

# Volley の Json リクエスト

Volley には、JSON リクエストのメソッドとして以下の 2 つがある

| メソッド | 説明 |
| ------ | --- |
| JsonObjectRequest | JSON Object を渡して、JSON Object 形式のレスポンスを受け取る |
| JsonArrayRequest | JSON Array を渡して、JSON Array 形式のレスポンスを受け取る |

このように、リクエストの形式とレスポンスの形式が一致しているメソッドしかない

仮に、上記のやりたいことを、これらのメソッドを使ってみると、

* JsonObjectRequest
  * リクエストを送ることはでき、レスポンスも返ってくるが、レスポンスが指定の形式じゃなので、Error Response 側の処理が実行される

* JsonArrayRequest
  * リクエストの形式が不正なので、そもそもリクエストできない

# 実現方法
調べた限りでは、カスタムリクエストクラスを作るしかなさそう

```kotlin
open class CustomJsonRequest(
        method: Int,
        url: String,
        requestObject: JSONObject,
        responseListener: Response.Listener<JSONArray>,
        errorListener: Response.ErrorListener
): JsonRequest<JSONArray>(method, url, requestObject.toString(), responseListener, errorListener){

    override fun deliverResponse(response: JSONArray) {
        super.deliverResponse(response)
    }

    override fun parseNetworkResponse(response: NetworkResponse): Response<JSONArray> {
        return try {
            val jsonString = String(response.data, Charset.forName(HttpHeaderParser.parseCharset(response.headers)))
            Response.success(JSONArray(jsonString), HttpHeaderParser.parseCacheHeaders(response))
        } catch (e: JSONException) {
            Response.error(ParseError(e))
        } catch (e: UnsupportedEncodingException) {
            Response.error(ParseError(e))
        }
    }
}
```

あとは `CustomJsonRequest` を使って、`JsonObjectRequest` や `JsonArrayRequest` を使う時と同じように書いてやれば実現できる

# 終わりに

JSON Object を渡し JSON Array をレスポンスするには、Volley の標準のメソッドは実現できず、自分でカスタムクラスを実装する必要があり思ったより大変でした
[JavaScript] 直感的に配列を結合する

#概要
今まで`concat()`を利用して配列の結合を行っていたのですが、
スプレッド演算子を利用することでよりわかりやすく書けることを知ったのでメモします。

#実装

スプレッド演算子を使わない場合

```.js
let array1 = [1,2,3];
let array2 = [4,5,6];
let array3 = array1.concat(array2);
console.log(array3);

//結果：[1,2,3,4,5,6]
```

スプレッド演算子の場合

```.js
let array1 = [1,2,3];
let array2 = [4,5,6];
let array3 = [...array1, ...array2];
console.log(array3);

//結果：[1,2,3,4,5,6]
```
CircleCIでContextを使おうとしてハマった話

私はSEとして働いておりますが、普段は自動テストとは無縁の仕事をしています。ただし、プライベートで作業をする時はテストを自動化しており、CIツールとして[CircleCI](https://circleci.com)を使用しています。

そのCircleCIにはContextという、環境変数をCircleCI内にあらかじめ設定しておく機能があり、APIキーなどソースコードに含めると危険なものに関しては別途管理できます。ただし、自分はそれを利用する際に変数がなぜか参照できないという事態に陥ったので今回はその解決方法について記事にします。

# 前提
Contextの設定値は以下の通り。

Context名：LINE_BOT
環境変数名：API_KEY

# 修正前
以下が修正前の`config.yml`(CircleCIの設定ファイル)になります。
`command`の行に`$API_KEY`とありますが、なんど実行してもこの値は空になります。

```config.yml
version: 2.1

orbs:
  python: circleci/python@0.2.1

jobs:
  build-and-test:
    executor: python/default
    steps:
~~~(中略)~~~
      - run:
          name: Run pytest
          command: pipenv run pytest --apikey $API_KEY

workflows:
  main:
    jobs:
      - build-and-test
```

ちなみにこの段階ではContext名を指定する必要があるということまでは気づいており、`$LINE_BOT.API_KEY`など色々試したのですが上手くいくことはありませんでした。

# 修正後
以下が修正後です。違いがわかりますでしょうか？対応としては単純な話で、最下部のジョブ`build-and-test`に使用するContext名を指定するだけです。これで実行時には環境変数が参照され想定通りのテストが実行されます。

```config.yml
version: 2.1

orbs:
  python: circleci/python@0.2.1

jobs:
  build-and-test:
    executor: python/default
    steps:
~~~(中略)~~~
      - run:
          name: Run pytest
          command: pipenv run pytest --apikey $API_KEY

workflows:
  main:
    jobs:
      - build-and-test
          context:
            - LINE_BOT
```

# 補足
Contextはプロジェクトを跨いで環境変数を使い回す際に便利な機能です。プロジェクト単体でしか使用しない環境変数はプロジェクト設定の環境変数を使用することもできます。
Rails6 ActiveStorageでS3に保存し確認するまで

##はじめに
railsでwebアプリケーションを作成する際にs3に画像を保存したいと思うことがあったので、備忘録として残します。

##開発環境
windows10
rails 6.1.3.1
vscode
aws s3のセットアップについては完了しているものとします。

##Active Storageのセットアップ
コンソールで下記を入力します。
```$ rails active_storage:install```
```$ rails db:migrate```

Active Storageのサービスはconfig/storage.ymlで宣言します。アプリケーションが使うサービスごとに、名前と必要な構成を指定します。 
デフォルトで```amazon:```からのコードがコメントアウトされていたらコメントアウトを外してください。
**この際のインデントに注意！**
（コメントアウト無効時にインデントがずれてしまい、エラーの原因になります。筆者はこれに築かず小一時間さまよいました。）

```config/storage.yml
test:
  service: Disk
  root: <%= Rails.root.join("tmp/storage") %>

local:
  service: Disk
  root: <%= Rails.root.join("storage") %>

amazon:
  service: S3
  access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
  secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
  region: 作成したパケットのリージョン名
  bucket: s3で作成したパケット名
```

acces_key_id,secret_access_keyについてはIAMで権限を与えた際に控えたものをcredentials.ymlに記述
```$ rails credentials:edit```

```
aws:
  access_key_id: 控えたもの
  secret_access_key: 控えたもの
```

次に利用するサービスをActiveStorageに認識させますが、ここは開発環境ごとにファイルが異なります。
今回はdevelopment環境でs3を利用したので、```:amazon```を記述します。

``` config/environments/development.rb

 config.active_storage.service = :amazon

```

Gemfileに以下のコードを追加する
```gem "aws-sdk-s3", require: false```
その後以下実行
```$ bundle install```

以上で環境は整いました。あとは実際にModel,View,Controllerを書いて確認します。

##ファイルをレコードに添付
今回はuserモデル,userコントローラーとformを利用してs3に画像を保存してみます。
自身で作成する際は対応するものに書き換えてください。

まずはuserモデルにavatarを持たせます。
>has_one_attachedマクロは、レコードとファイルの間に1対1のマッピングを設定します。各レコードには1つのファイルを添付できます。

```user.rb
class User < ApplicationRecord
    has_one_attached :avatar
end
```

次にuserコントローラーを設定
userモデルにnameとageをもっているのでそれらも一緒に受け取り保存します。

```user_controller.rb
class UserController < ApplicationController
    def index 
    end

    def create
        user = User.create!(user_params)
        redirect_to root_path
    end
    
    private
        def user_params
          params.permit(:name, :age, :avatar)
        end
end
```

routes.rbに```resources :user```を追加してください。
最後にformを作成します。
avatarのformは```form.file_field```

```user/index.html.erb
<%= form_with model: @user ,local: true do |form| %>

  <p>
    <%= form.label :name %><br>
    <%= form.text_field :name %>
  </p>

  <p>
    <%= form.label :age %><br>
    <%= form.text_field :age %>
  </p>

  <p>
    <%= form.label :avatar %><br>
    <%= form.file_field :avatar %>
  </p>

  <p>
    <%= form.submit %>
  </p>

<% end %>
```

以降、サーバーを起動後
```localhost:3000/user```で下記のような画面が出るので画像選択しを送信するとs3に保存されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1253187/953fcc68-d403-f81b-5cc0-1ed1a233250c.png)


以上！お疲れさまでした。

##参考
[Railsガイド（Active Storageの概要）](https://railsguides.jp/active_storage_overview.html)
[Railsガイド (Railsを始めよう)](https://railsguides.jp/getting_started.html)
Unity初心者忘備録

※自分用のメモ

## Script

１つのプロジェクトで同じ名前のスクリプトが２つあるとエラーになる。
　※重複していないか調べたい時はプロジェクトウインドウの検索窓で検索すると一覧で表示される。
スクリプト名は日本語が苦手なので半角英数字を使う。
C#のプログラムではファイル名（クラス名）は[パスカルケース](https://qiita.com/yimajo/items/a3fac0026c07ec538fc2)で記述する。
C#ではクラス名とファイル名は同じでないといけない。


## コンポーネント

### リジットバディ
物理的な動きをさせるコンポーネント
壁や他の物体に当たり判定ができたり、重力の影響を受ける。
３D用の「Rigibody」と、2D用の「Rigibody 2D」がある。

### コライダー
衝突を行う形を設定するコンポーネント
2Dゲームなら。色々な形に描かれた絵のどこが衝突するのかを指定する。
物と物が衝突する時は、絵ではなくコライダーの形を使って衝突が起こる。
コライダーの形には、四角い「Box Colider 2D」、丸い「Cicrle Colider 2D」、カプセル上の「Capsule Colider 2D」、描かれた絵に近い形状の「Polygon Colider 2D」などがある。
コライダーがどのような形をしているのかは、オブジェクトを選択している時に緑色の線で表示される。
「Polygon Colider 2D」はコンピュータへの負荷がかかって重くなるので、転がる物体なら「Cicrle Colider 2D」、転がらない物体なら「Box Colider 2D」がおすすめ。
画像に余白がある場合は、[インスペクタウィンドウ]の[サイズ]で大きさを変更したり、[Offset]で位置を調整する。
SQL文法

# はじめに

`SQL`を使う際、特に利用することが多い部分をまとめました。
基礎的なことなので、ある程度知識のある方にとっては当たり前のことかもしれませんが、
忘れてしまったという時に、確認するくらいの気持ちで見ると良いかもしれません。

注意点: お使いのデータベースや環境によって期待通りの動作をしない場合があります。

## データベース

db_name -> データベースの名前

* 作成

``` SQL
CREATE DATABASE db_name;
```

* 削除

``` SQL
DROP DATABASE db_name;
```

* 現在のデータベース

``` SQL
SELECT DATABASE;
```

* データベースの切り替え

``` SQL
USE db_name;
```

* 一覧

``` SQL
SHOW DATABASES;
```

## テーブル

tb_name -> テーブルの名前
new_tb_name -> 新しいテーブルの名前
col_name -> カラム名
col_definition -> カラム定義、データ型

* 作成

``` SQL 
CREATE TABLE tb_name(col_name col_definition, ...);
```

* 削除

``` SQL
DROP TABLE tb_name;

/* 存在しない場合は削除を行わない方法 */
DROP TABLE IF EXISTS tb_name;
```

* 名前の変更

``` SQL
ALTER TABLE tb_name RENAME TO new_tb_name;
```

* 一覧

``` SQL
SHOW TABLES;
```

## カラム

tb_name -> テーブルの名前
col_name -> カラム名
new_col_name -> 新しいカラムの名前
col_definition -> カラム定義, データ型

* 追加

``` SQL
INSERT INTO tb_name VALUES('name');
```

* 削除

``` SQL
DELETE FROM tb_name WHERE id = 1;
```

* 更新

``` SQL
UPDATE tb_name SET name = 'new_name' WHERE id = 1;
```

* 名前の変更

``` SQL
ALTER TABLE tb_name RENAME COLUMN col_name TO new_col_name;
```

* 行の追加

``` SQL
/* 一番最後に追加 */
ALTER TABLE tb_name ADD col_name col_definition;
/* 位置を指定して追加(idの下に追加) */
ALTER TABLE tb_name ADD col_name col_definition AFTER id;
```

* 行の削除

``` SQL
ALTER TABLE tb_name DROP col_name;
```

* 行の更新

``` SQL
ALTER TABLE tb_name CHANGE COLUMN col_name new_col_name col_definition;
/* Oracleの場合 */
ALTER TABLE tb_name MODIFY col_name col_definition;
```

* データ型の変更

``` SQL
ALTER TABLE tb_name ALTER COLUMN col_name TYPE col_definition;
```

* 一覧

``` SQL
SHOW COLUMNS FROM tb_name;
```

# 最後に

現在、理解している点を網羅して記載してみました。
また、この記事を通して、`SQL`を初めて見ようと思っていただけたら嬉しいです。
それから、この記事の知識で補えない事もあると思います。
なので、公式ページなどを通してより多くの知識を身に付けるとよいかもしれません。

`SQL`について詳しいよという方は、こういう書き方の方が効率が良いなどアドバイスがあればぜひコメントに書いてください。
その際は、記事を更新していこうと思います。

# 参考文献

* [MySQL :: MySQL 8.0 Reference Manual](https://dev.mysql.com/doc/refman/8.0/en/)
連結/型変換

# Pythonの連結と型変換について
文字列同士の連結では
print("Hello" + "World") と記述すると
HelloWorldと出力される。

また数値同士の連結では
print(5 + 7)　と記述すると
12が出力される。

ここで補足として、もし
print("5" + "7")　と記述した場合は
57と出力されます。

### では文字列と数値の連結はどうするのか

違うデータ型(文字列型、数値型)同士の連結はどの様に記述するのかであるが、
違う型同士を連結したまま出力しようとするとエラーが発生してしまいます。
例：
price = 300
print("りんごの価格は"+ price + "円です")
これを出力してみると
TypeError: can only concatenate str (not "int") to str
というエラーが発生してしまう。

これは文字列か数値どちらかに統一してと書いてあるので、
文字列を数値に、もしくは数値を文字列に変換する必要があります。
まず、文字列を数値に変換するには
例：
price = "300"
int(price)　と記述すると数値に変換されます。
反対に数値を文字列に変換するには
例：
price = 300
str(price)　と記述すると文字列に変換されます。

よって、先程エラーになってしまったコードを出力するには
price = 300
print("りんごの価格は"+ str(price) + "円です")　と記述することで、
「りんごの価格は300円です」と出力することができます。
[git] windows環境でgit log すると日本語が文字化けするのを直す

#原因
windowsのgitで使われているlessパッケージが日本語を嫌って文字化けしている
#方法
環境変数にlessのcharsetをutf8が使えと教えてあげるひつようがある。
##1
```:ターミナル
$ git config --global core.pager "LESSCHARSET=utf-8 less"
```
##2
システム環境変数に新規で`変数名LESSCHARSET`で`変数値utf-8`で登録する
SPSS Modeler ストリームのループ処理 その１ ストリームを指定の回数実行し、実行するたびに変数の値を変更する



# SPSS Modelerでのループ処理について
データは、SPSS Modelerに同梱されている telco.sav を使用しています。

たとえば、年代別に散布図や棒グラフ、クロス集計表などを作成したい場合、年代をパラメータにして、ループ/条件付き実行の手続きを使えば一度のストリーム実行で複数のアウトプットを得ることができます。

ここでは、年齢フィールドから年代フィールドを作成し、年代別に携帯電話の解約に関する比較をしてみます。

## フィールド作成ノードを使って、年代フィールドを作成

データ型ノードにフィールド作成ノードをリンクします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855260/23f9fef9-d893-a561-fa7f-9f625aec1435.png)
条件を設定して、年齢から年代を作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855260/1f8df772-03fc-102e-e0bd-6c9144ac0270.png)

棒グラフノードをリンクして、年代フィールドを確認してみます。10代から70代までの７つの年代ができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855260/79b66283-dd68-00a5-5c5c-1658465a122c.png)

今回は、20代、30代、40代の３つの年代の携帯電話解約の男女比を比較します。
特定の年代を比較する場合は、該当する年代を条件指定して抽出しますが、複数の年代で繰り返し抽出したい場合には、パラメータを使用します。

## パラメータの設定
メニューからツール＞ストリームのプロパティ＞パラメータを選択します。
パラメータの名前をここでは、「age_G」としました。また、ストレージは文字列に変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855260/e5120790-4e4c-f642-8948-6569785913d2.png)
年代のフィールド作成ノードの後に条件抽出ノードを追加し、条件を指定ます。
条件式は、年代='$P-age_G'　です。
式ビルダーを起動して年代を投入したあと、リストを「フィールド」から「パラメータ」に変更すると、先程、設定したパラメータがリスト表示されますので式に投入します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855260/16172341-8149-cf7f-d4c9-ace29325ec68.png)

条件抽出ノードに棒グラフノードをリンクします。フィールドに「性別」、オーバーレイの色に「解約」、色で正規化にチェックをして実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855260/499d00b7-eafb-f6c7-ddc3-f9330d6a3d8c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855260/84a737f6-5160-b0e3-e810-c3287bf1c393.png)

パラメータを入力するダイアログが表示されます。「10代」と入力すると該当するデータが選択され、棒グラフが表示されます。
パラメータがうまく作用していることが確認できたので、メニューからツール＞ストリームのプロパティ＞パラメータを選択し、「プロンプト？」のチェックを解除します。これでストリームの実行時にパラメータを入力するダイアログは表示されなくなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855260/f11f1fbb-fe76-d8d2-8ddb-c1b45ae07eab.png)

## ループの設定
条件抽出ノードを右クリックし、プルダウンメニューからループ/条件付き実行＞反復キーの定義を選択します。
反復対象で「ノードプロパティーｰ値」を選択し、設定内容のノードは、「条件抽出ノード」を選択します。使用する値のフィールドで、「年代」を選択します。値リストは、右側一番上の値を表示するボタンをクリックして、リストから対象としたい値を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855260/f38abec7-3811-bc9e-a734-e67a9678b982.png)

ループのリストが表示されました。選択した年代が表示されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855260/0a112aa1-81fa-c5cc-9374-7e880ed1d606.png)

ループと条件付き実行は、ストリーム全体を実行する必要があるので注意してください。不要なノードは削除しておきます。完成したストリームイメージは以下の通りです。ループ/条件付きであることを示すミニアイコンがノードの左上に表示されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855260/61ac503d-9947-395a-b69d-528e0b5a7aa8.png)

ストリームを実行すると、20代、30代、40代の棒グラフが作成されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855260/18104a90-b1ab-c4c1-f2c4-97b36a17890c.png)

## まとめ
少々とっつきにくい感じもありますが、便利な機能です。使いながら慣れましょう!!
DDLからテストデータ生成するやつを作りました

DDL（create table 文）からデータを作成するライブラリを作成したので、その紹介です。

https://github.com/kena0ki/dddl

### 動機
単体テストとかでテーブルデータを作るときは

- テーブルのデータ型に合っていて
- NULLではなくて
- 行に対しても列に対してもできるだけ値に被りがなくて
- MAX桁数が入っている

ようなデータが欲しいことが結構あって、そういうデータを生成する手間を省きたかったからです。

### 機能について
どんなものかは[デモページ](https://dddl-demo.netlify.app/)を見て頂いた方が早いのですが、
こんな定義があったとして、

```sql
 create table a (
   c1 char(5),
   c2 integer,
   c3 float,
   c4 binary(8)
 );
```
生成されるデータはこんな感じです。

```c
   c1      c2  c3    c4
L1 "a0001","1","0.1","b0000001"
L2 "a0002","2","0.2","b0000002"
L3 "a0003","3","0.3","b0000003"
L4 "a0004","4","0.4","b0000004"
```
生成されるデータはオプションとカラムのデータ型の定義によって変わります。

### オプションとか
オプションとかサポートしているデータ型とかはAPIに書いてあります。 

- [オプション](https://dddl-api.netlify.app/interfaces/generator.generatoroption.html)
- [データ型](https://dddl-api.netlify.app/modules/datatypes.html)

オプションには行ごとに実行されるコールバック関数もあるので、データは割と自由に加工できるようになっています。

### SQL パーサー
SQLはDBMS製品によって構文が変わったりするので、パーサーエラーになる可能性は割と高いと思います。
ただ、パーサー部分は、[sqlparser-rs](https://github.com/ballista-compute/sqlparser-rs)という Rust のライブラリをTypeScriptに移植して作っていて、元のライブラリが [ANSI standards](https://en.wikipedia.org/wiki/ISO/IEC_9075) に準拠する形で作られているため、このライブラリも基本的にはSQL標準に準拠する形になっているので、データ生成に使用するカラム定義部分はパーサーで読み込めることが期待されます。

### 類似品
リアリティのあるデータが欲しい場合は http://filldb.info/ みたいなサイトが結構あります。
探せばこのライブラリと同じようなものもあるかもしれません。
【Github】git commit --amendで直前のコミットメッセージを修正する

### 1.はじめに
Railsでアプリを作成中、git commit -m を行ったところ、`" "`を閉じ忘れて`dquote>`表示になりました。
コメントの続きを入力すれば良かったのですが、全て入れ直してしまいコミットメッセージが`hogehoghogehoge`（hogehogeと入力したかった..）になってしまいました。
なので当初の`hogehoge`というメッセージに修正します。

### 2. 使用環境
- mac.os バージョン10.15.6
- Ruby 2.6.6
- Rails 6.0.3.5
- psql (PostgreSQL) 12.6
- git 2.28.0
- VScode 1.52.1
- Atom 1.53.0

### 3.直前のコミットメッセージの修正の仕方(githubにプッシュする前の状態)
今回はGithubにpushする前だったため、`git commit --amend`で修正しました。

```ruby
sample_app % git add .
sample_app % git commit -m "hogehog
dquote> "hogehoge
[fuga a12345] hogehoghogehoge # fugaブランチのコミットメッセージに追加された

#　略（作成・変更のあったのファイルの表示）

#コミットメッセージの修正
sample_app % git commit --amend

# テキストエディタが起動するのでメッセージを修正(*3.1)

#コミットメッセージが変更された
[fuga b67890] hogehoge

```

#### 3.1（補足）テキストエディタでの流れ(macの場合)
1.メッセージを修正する（今回の場合`hogehoge`と入力する）
2.`command + S` で保存する
3.`command + W` でタブを閉じて終了する

#### 3.2（補足）git commit --amend に-mをつける

`git commit --amend -m "〇〇"`（〇〇は入れたいメッセージを入れる） とするとテキストエディタを修正・保存する手間なく一発で修正できます。

#### 3.3（補足）直前のコミットメッセージの修正の仕方（githubにプッシュした後の状態）
1.`git commit --amend (-m "〇〇")`で修正を行う
2.`push --force`コマンドで古いコミットを上書きする。（force:勢い,力）

```ruby
#fugaブランチの直前のプッシュ済みコメントが更新される
sample_app % git push --force fuga 
```

### 4.dquoteとは？
ダブルクォーテーションの略。`dquote>`は`"Hello World!!`など二重引用符を1つ使用した時に表示されます。
`Ctrl+G`でコマンドを破棄することができます。

### 5.まとめ
`git -commit --amend`で直前のコミットを修正することができます。

### 6.参考リンク
1:[コミットメッセージの変更](https://docs.github.com/ja/github/committing-changes-to-your-project/changing-a-commit-message#commit-has-not-been-pushed-online)
2:[Gitのバージョン確認方法](https://www.famlog.jp/article/1729#:~:text=%E3%82%AA%E3%83%BC%E3%83%97%E3%83%B3%E3%82%BD%E3%83%BC%E3%82%B9%E3%81%AE%E5%88%86%E6%95%A3%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3,%E6%83%85%E5%A0%B1%E3%82%92%E5%87%BA%E5%8A%9B%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82)
3:[【Qiita】式をシンタックスハイライトさせる（色を付ける）方法](https://qiita.com/kodai_0122/items/56b3b25c3b01586260cf)
4:[git commit --amend でcommitを修正する](https://qiita.com/tosu/items/f2586fa3fc88899d3311)
5:[git commit で Atom を使う](https://qiita.com/Atelier-Mirai/items/17430b8f7eabe9835e70)
6:[shell で dquote> 待ちになってしまった時のたったひとつのcoolな行為](https://zenn.dev/junki555/articles/849932ff99d68ce2adc7)

### 7.最後に
記事の感想や意見、ご指摘等あれば伝えていただけるとありがたいです。
読んでいただき、ありがとうございました。
バッチファイルでpingが無限ループする

pingでサーバーとの疎通確認をしたかったので、簡単なバッチを作成。

```batch:ping.bat
@echo off
ping 127.0.0.1
if %ERRORLEVEL%==1 (
   echo "ping error"
)
pause
exit
```

すると何故か以下のように無限ループ…。
ping 127.0.0.1
ping 127.0.0.1
ping 127.0.0.1
ping 127.0.0.1
ping 127.0.0.1
ping 127.0.0.1

なぜこうなるかというと、ファイル名が「<b>ping.bat</b>」となっていたことが原因。
windows標準の設定ではコマンドの優先順位が .bat > .exe となっているため、ひたすら自分自身を参照することになるらしい。

ファイル名とコマンドを同じ名前にするのは避けましょう。
All About ACS: Java 8u281/282 の場合エクスプローラーからのドラッグで ACS がハング (たぶん 11.0.10, 15.0.2, 16 でも)

# Java 8u281/282 の場合エクスプローラーからのドラッグで ACS がハング (たぶん 11.0.10, 15.0.2, 16 でも)
Java 8u281/282 を使って ACS を稼働させている場合、エクスプローラーからのドラッグで ACS がハングすることがあります。
以前の Java では発生しませんでした。
ACS へのドロップを意図したものでなく、ドラッグが ACS の GUI 上を通過する場合にも発生します。

## 確認したこと

下記の操作でのハングの発生を確認しました。
* エクスプローラーからファイルのシートカットをドラッグする時に、5250 セッションの上を通過させようとした。
* 「SQLスクリプトの実行」へ「.sql」ファイルをドラッグ&ドロップしようとした。ドロップ前にハングした。(本来、この操作は[ファイル]→[開く]と同様に保管されたSQ文を展開するものです)

ハング後は、ドラッグ中のアイコンが画面に表示されたままになります。アイコンが透明になる場合もあります。
タスクマネージャーから ACS を終了させると、ドラッグ中のアイコンは消えて、エクスプローラの操作も可能になります。
現象は。必ず発生するわけではありません。
Java の ビット数には依存しません。32/64 ビットどちらでも起こります。
Oracle Java と AdoptOpenJdk で発生を確認しました。
Java のバージョンを Java 8u281/282 より古いものに変更すると、現象は発生しませんでした。

## 疑わしい Java のバグ
Java のバージョンを古いものに変更するとハングは発生しないことから、Java のバグが疑われます。
下記の Java のバグが見つかりました。

JDK-8262446 : DragAndDrop hangs on Windows

https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8262446

現象は類似していますね。

> Dragging files from Windows Explorer to a Java application hangs. Not each time but very often.

8u271 では発生しないが 8u281 で発生。11.0.10、15.0.2、16ea でも発生とあります。

> Checked with attached testcase in Windows 10, Issue is reproducible, test app hangs and observed regression in 8u281, 11.0.10, 15.0.2.
Test Result:
=========
JDK 8u271: Pass
JDK 8u281, b01: Fail
> 
JDK 11.0.9: Pass
JDK 11.0.10, b01: Fail 
> 
JDK 15.0.1: Pass
JDK 15.0.2, b01: Fail
> 
JDK 16ea: Fail

Web ページによると、下記のリリースで修正されるようです。
JDK 15 は LTS でなく 2021年3月にサポートが終了するので修正されないようです。

>
8u301
11.0.12
16.0.2
17 b13

修正されているリリースは、まだ、一般利用が可能になっていません。
それまでは、ハングしない Java のご利用をお勧めします。
Java をより安全に使う方法は「[Java を ACS 専用にして安全にする](https://qiita.com/6onoda/items/1e63dfc76bc9b0f6f140)」をご覧ください。

***
「All About ACS」では IBM i に対する新しいクライアント「IBM i Access Client Solutions」の情報をいろいろ提供していきます。
[記事一覧はこちら](http://qiita.com/6onoda/items/2dc925586d8d3b8644f2)で確認いたけます。

許可の無い転載を禁じます。
この記事は筆者の個人的な責任で無保証で提供しています。
当記事に関してIBMやビジネスパートナーに問い合わせることは、固くお断りします。
***
【Kotlin】Firestoreで複数のタスクが成功したときにリスナーを呼ぶ

#FirestoreやFirestrageで同時に複数の処理を行う
【taskA】 FirestoreからドキュメントAを取得する
【taskB】 FirestoreからドキュメントBを取得する
といった２つのタスクを同時に行うとします。
このタスクAとBの両方が成功したときに、printlnします。

##タスクの取得
データを取得するときにタスクが返されます。

```Kotlin
val taskA = db.collection("user").document("A").get()
val taskB = db.collection("user").document("B").get()
```

##両方のタスクが成功した時に呼ばれるリスナー

```Kotlin
Tasks.whenAllSuccess<Any>(taskA, taskB)
    .addOnSuccessListener{
        println("両方のタスクが成功しました")
    }
```

これで両方のタスクが成功するとプリントされます。

.addOnFailureListener
.addOnCompleteListener
も同じようにして呼び出すことができます。
Zoomミーティングをストレスなくするためのオススメ機能！（web会議マナー）

意外と知らない人も多そうでしたので、まとめました。

##①アップデート（バージョンアップ）
結構な頻度でバージョンアップされますが、自動では適用されないので手動でアップデートしてあげる必要があります。
![Zoom1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356722/7d6ccc5b-7f48-b2ea-f448-70796c8df6a0.png)

##②設定＞ビデオ＞低照度に対して調整
ビデオの設定で「低照度に対して調整」がONになっていることを確認！「自動」で暗いときは、「手動」にしてMAX右側まで青丸を引っ張りましょう。逆光で顔が真っ暗になるくらいでも、この補正でめちゃくちゃ明るくなります。顔が暗いと表情が読み取れず、話している相手が不安になりますので、ここも印象としては非常に大きいのでぜひ、意識しましょう。
![Zoom2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356722/e739abd5-c555-5f30-58ca-fe922bf6d8a3.png)

##③設定＞ビデオ＞外見を補正する
同じくビデオの設定ですが、こちらもオススメです。お肌がきれいに映りますのでお化粧いらず？「今日メイクしてなくて」と言ってビデオONにしない方がいたら、化粧よりよっぽどキレイに映りますので、こちらをオススメしてあげてください。
ただし、PCのスペックが悪い場合は、少し負荷が高くなりますのでご注意。（カクカクするようならチェックを外した方がいいです）
![zoom3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356722/96c96da7-39cf-77ea-1f35-5de21ee89aa7.png)

##④設定＞オーディオ＞背景雑音を抑制
こちら何度かご案内していますが、「高」にすると後ろでトランペット吹いていてもかき消せしてくれるそうです。（実際談）
周りの雑音がどれくらい入っているか、本人には分かりませんので、遠慮なく一緒に参加している方に聞いてみましょう。マイクの形状によってはかなり拾います。
![zoom4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356722/1f3b596a-d1aa-7ef4-1a7e-8dbc9249564f.png)

##⑤設定＞オーディオ＞スピーカー・マイク
相手に聞き取りやすく、相手の声を聴きやすくするのも、ミーティングをスムーズにストレスなく進める大事なポイントです。自分の声がどれくらいの音量で聞こえているかなど実際に試せますので、マイクを変えたときなどは、ぜひ試してみましょう。（ワイヤレスの場合、電池が少なくなると音量が小さくなるなどもあります）
![zoom5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356722/901885e5-b7fa-c67b-8db7-19d51381353c.png)

##⑥設定＞背景フィルター＞グリーンスクリーンがあります
言わずと知れたバーチャル背景機能。グリーンスクリーンが無い場合は、ここのチェックを外しましょう。
初期のころはこのチェックを外すのに必要なスペック要件が非常に厳しく、ほとんどの人がチェックを外せませんでしたが、アップデートによりこの条件が大幅に緩和され、ほとんどのPCでチェックが外せるようになりました。外せない人は、アプリのバージョンアップをしてみましょう。
![zoom6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356722/5124cd96-da79-798e-8295-b1e40be87b0d.png)
クエリビルダ　早見表

公式ドキュメント引用-> https://readouble.com/laravel/6.x/ja/queries.html

データベースクエリビルダはスラスラと書ける(fluent)便利なインターフェイスで、クエリを作成し実行するために使用します。アプリケーションで行われるほとんどのデーターベース操作が可能で、サポートしている全データベースシステムに対し使用できます。

LaravelクエリビルダはアプリケーションをSQLインジェクション攻撃から守るために、PDOパラメーターによるバインディングを使用します。バインドする文字列をクリーンにしてから渡す必要はありません。

```
//->get() = 条件指定に沿った結果データの全てを取得。
$users = DB::table('users')->get();
return view('user.index', ['users' => $users]);

//->first() = データベーステーブルから１レコードのみ取得する必要がある場合は、firstメソッドを使います。
$user = DB::table('users')->where('name', 'John')->first();

echo $user->name;

//->value() = メソッドで指定した1つのカラムのみを取得します
$email = DB::table('users')->where('name', 'John')->value('email');

//->pluck() = メソッドで指定カラム1つだけをコレクションで取得できます
/value()メソッドとは違い、条件の結果全てのデータを取得します
$data = $users->pluck('email');
```

自分がlaravelでフォロー機能を作った時のクエリビルダ

```
public function index(Request $request, Post $post) {
   $allPosts = $post->whereIn('user_id',$request->user()->following()->pluck('user.id')->push($request->user()->id))->with('user');
}
```

後で追記します
4x+y<= 9, x+2y >= 4, 2x-3y >= -6の時、2x+y、x^2+y^2の最大値と最小値「2010 京都大学 文系【２】」(その1) RとWolframAlphaとCVXPY(非線型計画法)でやってみた。

旧タイトル 2021年03月30日
RとWolframAlphaとCVXPYで(非線型計画法)「2010年度 京都大・文系数学第2問」 をやってみた。

# オリジナル

・大学入試数学問題集成 様＞ 文系【２】 テキスト

https://mathexamtest.web.fc2.com/2010/201010541/2010105410100mj.html#top-0103

・(参考) リンク切れ???
2010年度 京都大・文系数学第2問 問題と解答

~~https://www.densu.jp/kyoto/10kyotolpass.pdf#page=2~~

~~https://www.densu.jp/kyoto/10kyotolpass.pdf#page=7~~

# vbaで
スタック・オーバーフローから削除されました。
~~https://ja.stackoverflow.com/questions/75328/excelのソルバーをvbaで自動化する方法-最小値をやってみた~~

# Rで
(参考)

https://info.ouj.ac.jp/~maps17/R/

```R
library(lpSolve)
f.obj <- c(2, 1)
f.con <- matrix (c(4, 1, 1, 2, 2, -3), ncol=2, byrow=TRUE) 
f.dir <- c("<=", ">=", ">=")
f.rhs <- c(9, 4, -6)
lp ("max", f.obj, f.con, f.dir, f.rhs)
lp ("max", f.obj, f.con, f.dir, f.rhs)$solution 
lp ("min", f.obj, f.con, f.dir, f.rhs)
lp ("min", f.obj, f.con, f.dir, f.rhs)$solution
# > lp ("max", f.obj, f.con, f.dir, f.rhs)
# Success: the objective function is 6 
# > lp ("max", f.obj, f.con, f.dir, f.rhs)$solution 
# [1] 1.5 3.0
# > lp ("min", f.obj, f.con, f.dir, f.rhs)
# Success: the objective function is 2 
#> lp ("min", f.obj, f.con, f.dir, f.rhs)$solution 
# [1] 0 2
```

# WolframAlphaで
最大値

https://www.wolframalpha.com/input/?i=maximize+2*x+%2B+y%2C4*x%2By+%3C%3D+9%2C+x%2B2*y+%3E%3D+4%2C+2*x-3*y+%3E%3D+-6&lang=ja

https://www.wolframalpha.com/input/?i=maximize&assumption=%7B%22C%22%2C+%22maximize%22%7D+-%3E+%7B%22Calculator%22%7D&assumption=%7B%22F%22%2C+%22GlobalMaximizeCalculator%22%2C+%22curvefunction%22%7D+-%3E%222*x+%2B+y%22&assumption=%7B%22F%22%2C+%22GlobalMaximizeCalculator%22%2C+%22domain%22%7D+-%3E%22%5B4*x%2By+%3C%3D+9%2C+x%2B2*y+%3E%3D+4%2C2*x-3*y+%3E%3D+-6%5D%22&lang=ja

最小値

https://www.wolframalpha.com/input/?i=minimize+2*x+%2B+y%2C4*x%2By+%3C%3D+9%2C+x%2B2*y+%3E%3D+4%2C+2*x-3*y+%3E%3D+-6&lang=ja

https://www.wolframalpha.com/input/?i=minimize&assumption=%7B%22C%22%2C+%22minimize%22%7D+-%3E+%7B%22Calculator%22%7D&assumption=%7B%22F%22%2C+%22GlobalMinimizeCalculator%22%2C+%22curvefunction%22%7D+-%3E%222*x+%2B+y%22&assumption=%7B%22F%22%2C+%22GlobalMinimizeCalculator%22%2C+%22domain%22%7D+-%3E%22%5B4*x%2By+%3C%3D+9%2C+x%2B2*y+%3E%3D+4%2C2*x-3*y+%3E%3D+-6%5D%22&lang=ja


# CVXPYで

最大値
最小値

https://ja.stackoverflow.com/questions/74862/python%e3%81%aecvxpy%e3%83%97%e3%83%ad%e3%82%b0%e3%83%a9%e3%83%a0%e3%82%92%e9%96%a2%e6%95%b0%e3%81%ab%e3%81%99%e3%82%8b%e6%96%b9%e6%b3%95%e3%82%92%e6%95%99%e3%81%88%e3%81%a6%e4%b8%8b%e3%81%95%e3%81%84/74966#74966


# いつもの? sympyの実行環境と 参考のおすすめです。
[(テンプレート)](https://qiita.com/mrrclb48z/items/00dd08b0317069be9342)

# いつもと違うおすすめです。

https://myenigma.hatenablog.com/entry/2016/11/06/114603

https://qiita.com/nariaki3551/items/c7d951aae71fde1660f7