OmniAICreator/Qiita-1.07M huggingface dataset:
Cloud9でデバッグしてみよう

##転載元
当記事は以下ブログからの転載です。
[TECH BACK](https://techback.info/aws-cloud9-debug/)

##はじめに
Cloud9でデバッグする手順をまとめます。

Cloud9環境でプロジェクトをデバッグします。

##デバッグ環境設定

環境設定というか、前の環境に戻してデバッグしましょうといった内容です。

2020年の後半位で、Cloud9のアップデートがありました。コレにより、従来の方法でのデバッグができない（？）ため、旧バージョンの状態に戻してデバッグしましょうというのが、本手順です。

まずはデバッグの環境設定をします。環境設定は初回のみでOK。

**Cloud9アイコン → Preferences**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450952/2524dc1c-882e-0405-78c8-c783401136fb.png)

**AWS Settings → AWS Toolkit** をOFFにします

Cloud9のアップデートでこのAWS Toolkitが追加されました。コレを非表示にして従来のメニューを表示させます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450952/97681ebf-f968-a514-9b9e-b90f575f5e1e.png)

OFFにすると、左ツリーのAWSアイコンが消えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450952/5b229c01-7405-b32c-0915-6b446264eaf6.png)

セッティングは以上です。

##デバッグ方法

右ツリーの**Lambdaアイコン(λ)**をクリック。上に出る警告文は無視してOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450952/add99c2a-8d48-b385-d2ef-1576c12dc62e.png)


デバッグしたいプロジェクトで**右クリック → Run → Run Local**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450952/8f7207a3-dd3a-e551-b58a-89fcb5a61bb2.png)


Runボタンをクリックするとローカル環境で実行できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450952/a0709bbf-1c03-b1bf-a117-86a86dd20582.png)


Runの横の**虫アイコン**をONにしてRunすることで、デバッグが可能です。

ソースコード上でブレークポイントを貼って試してみてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450952/86a3acd2-f780-facb-6e89-3cf4478ce716.png)


以上で終了です。
CodeCommitからCloud9(EC2)にClone

## 転載元
当記事は以下ブログからの転載です。
[TECH BACK](https://techback.info/aws-cloud9-codecommit-clone/)

## はじめに

[前回](https://qiita.com/teckback/items/70fbad957e98c91b9252)の記事で、Cloud9で開発しているプロジェクトをCodeCommitにPushしました。今度は、Cloneしてくる側の手順をまとめます。

## この記事で出来ること

CodeCommitにあるプロジェクトを、Cloud9環境にCloneして来ます。 今回CloneしてくるCodeCommitのリポジトリは下記の記事で作成したものを使っています。 

[Cloud9のプロジェクトをCodeCommitで管理](https://qiita.com/teckback/items/70fbad957e98c91b9252)
 
## Cloud9で環境作成

Cloud9を開き、**Your enviroment** → **Create enviroment**[![](https://techback.info/wp-content/uploads/2021/02/img_603416c9f3eab-1024x122.png)](https://techback.info/wp-content/uploads/2021/02/img_603416c9f3eab.png)

Nameに名前を入れて **Next step** をクリック。 [![](https://techback.info/wp-content/uploads/2021/02/img_60341727a759c-1.png)](https://techback.info/wp-content/uploads/2021/02/img_60341727a759c-1.png)環境設定は初期のままで、、、 [![](https://techback.info/wp-content/uploads/2021/02/img_6034179e3e93b.png)](https://techback.info/wp-content/uploads/2021/02/img_6034179e3e93b.png)

下のほうにスクロールし、**Next step** をクリック [![](https://techback.info/wp-content/uploads/2021/02/img_6034180b4f6f7.png)](https://techback.info/wp-content/uploads/2021/02/img_6034180b4f6f7.png)

**Create enviroment** をクリック [![](https://techback.info/wp-content/uploads/2021/02/img_6034186d053f4.png)](https://techback.info/wp-content/uploads/2021/02/img_6034186d053f4.png)

環境作成がはじまるので、しばし待ちます。 [![](https://techback.info/wp-content/uploads/2021/02/img_603418abe3b97.png)](https://techback.info/wp-content/uploads/2021/02/img_603418abe3b97.png)

## CodeCommitからClone

立ち上がったら、左ツリーの**Gitアイコン** → **Clone Repository**
[![](https://techback.info/wp-content/uploads/2021/02/img_603419095c62d.png)](https://techback.info/wp-content/uploads/2021/02/img_603419095c62d.png)

Repository URL を聞かれるので、、、 
[![](https://techback.info/wp-content/uploads/2021/02/img_603419302f300.png)](https://techback.info/wp-content/uploads/2021/02/img_603419302f300.png)

CodeCommitに移動して **リポジトリ** で接続するリポジトリの**HTTPS**をクリックしてURLをコピー 
[![](https://techback.info/wp-content/uploads/2021/02/codecommit-2.png)](https://techback.info/wp-content/uploads/2021/02/codecommit-2.png)
先ほどコピーしたURLを貼り付けて**Enter**
[![](https://techback.info/wp-content/uploads/2021/02/codecommit-3.png)](https://techback.info/wp-content/uploads/2021/02/codecommit-3.png)
フォルダアイコンをクリックして、リポジトリの内容が表示されれば成功です。 
[![](https://techback.info/wp-content/uploads/2021/02/codecommit-4-1-1.png)](https://techback.info/wp-content/uploads/2021/02/codecommit-4-1-1.png)
以上で終了です。あとはバリバリ開発しましょう！
PostgreSQL -よく使うコマンド一覧-

# はじめに
はじめまして。
今回はPostgreSQLで自分がよく使うコマンドなどをメモがてらまとめてみました。
## 環境
MacOS Catalina 10.15.7
PostgreSQL 12.5
## PostgreSQLのバージョン確認

>```terminal:terminal
$ psql --version
```

# データベース
### データベース作成

>```terminal:terminal
$ createdb データベース名
```
>```sql:psql
#  CREATE DATABASE データベース名;
```

---
### データベース削除

>```terminal:terminal
$ dropdb データベース名
```
>```sql:psql
#  DROP DATABASE データベース名;
```

---
### データベースに接続

>```terminal:terminal
$ psql データベース名
```

---
### データベース一覧表示

>```terminal:terminal
$ psql -l
```
>```sql:psql
# \l
```

---
### 他のデータベースに接続

>```sql:psql
# \c データベース名
```

# テーブル
### テーブル作成

>```sql:psql
# CREATE TABLE テーブル名(
      カラム名 データ型,
      カラム名 データ型
);
```

---
### テーブル一覧表示

>```sql:psql
# \d
```

---
### テーブルの構造を表示

>```sql:psql
# \d テーブル名
```

---
### テーブルにデータを入力

>```sql:psql
# INSERT INTO テーブル名 VALUES (1, '文字データ');
```

---
### テーブル内のデータを全て表示

>```sql:psql
# SELECT * FROM テーブル名;
```
- 「＊」は全てという意味
- 「＊」の部分をカラム名に変えれば指定したカラムだけ表示できる
- カンマ( , )で複数指定も可

---
### ある単語がカラムに含まれているテーブルを表示

>```sql:psql
# SELECT * FROM テーブル名 WHERE カラム名 LIKE '%ある単語%';
```

# PostgreSQLを終了

>```sql:psql
# \q
```
kintoneでJavaScript開発を行う

# kintoneとは
kintoneとは、サイボウズ株式会社が提供しているwebデータベース型のビジネスアプリ構築クラウドサービスです。
システム開発初心者でも簡単にシステムを構築することができ、また豊富なAPIやプラグイン、JavaScript等により細かい用途に沿ったカスタマイズも行うことが出来ます。
更にSNSのようなコミュニケーションツールも搭載しており、チームで使いやすいサービスとして今注目されています。

kintone -- https://kintone.cybozu.co.jp/

# 本記事の目的
本記事では、kintoneでJacaScript開発を行うための準備、また簡単な処理を行ってみます。
先述の通り、kintoneは開発無しでも利用できるサービスですが、細かい用途に沿ったシステムを構築するためにはJavaScript開発が必要となってきます。

# 準備するもの
kintoneでJavaScript開発を行うためにプラグインを追加します。
プラグインとは、kintoneをカスタマイズするためのJavaScriptやCSSファイルをパッケージングしたものです。
今回は「JSEdit for kintone」というプラグインを追加します。

kintoneヘルプ : プラグインを追加／削除する(アプリ設定） -- https://jp.cybozu.help/k/ja/user/app_settings/plugin.html
cybozu developer network : JSEdit for kintone -- https://developer.cybozu.io/hc/ja/articles/205452653

# JavaScript記述
では、実際にJavaScriptを書いてみます。
JavaScript編集画面は、下記手順で開きます。
「任意のアプリ」⇨「アプリ設定」⇨「設定」⇨「プラグイン」⇨「『JSEdit for kintone』の設定ボタン」

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1526064/d1f1f39b-7399-6f3e-b2d5-0bce0a786c07.jpeg">

このような画面が開きました。
「新規作成」ボタンから、jsファイルを作成することが出来ます。

次に、kintoneでjavascriptを記述をする際の作法ですが、
下記の流れで記述する必要があります。

イベントを指定（どのタイミングで処理を実行するか、いわゆる発火点）
↓
処理内容を記述

では実際に書いてみましょう。

```javascript
(function() {
  'use strict'; //お作法のようなものなので気にせずOK

  // レコード一覧画面の表示時のイベント処理
  kintone.events.on('app.record.index.show', function(event) {
    window.alert('おはようございます');
  });

})();
```

このJavaScriptは、
任意アプリで「レコード一覧画面を開く」というイベント発生時に
ウィンドウに「おはようございます」を表示する、という処理を実行する、
という内容になります。

イベントの詳細については、下記URLを参照して下さい。

cybozu developer network : イベント処理の記述方法 -- https://developer.cybozu.io/hc/ja/articles/201941954


では、このJavaScriptを保存し、
実際にkintoneでレコード一覧画面を開いてみましょう。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1526064/3c5ea423-09a7-a6b0-a51f-fe11d62bc59a.jpeg">

無事、表示されました。

# まとめ
今回は基礎的な部分を紹介しました。
次回は、応用的な処理を出来ればと思います。
草野球の出欠確認Webアプリを作ろう！　part.10

これから作っていく簡単なWebアプリの作成メモ（自分の備忘）です。
自分用なのであまり凝りすぎないように書いていきたい。

[<<前回の記事](https://qiita.com/tomodachi_uec/items/b78bf0acabe8f0bf23de)

##今回やったこと

###ユーザーの削除

削除についてもスケジュールと同様に実装する。

```rb:app/controllers/users_controller.rb
def destroy
  @users = User.find(params[:id])
  @users.destroy
  redirect_to users_url, notice: "ユーザーを削除しました。"
end
```

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534558/d12559f9-2e1a-2294-22c4-3d582d77dd86.png)

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534558/bd5afd76-6180-71aa-f472-5e08e5e3e036.png)

動作も確認できた。


###小リファクタリング

前回記事で触れたが、

>...また、意図していないことだったが、ユーザー用のjavascriptを用意しなくともユーザー一覧のテーブルの行をクリックするとユーザー詳細画面に遷移できてしまった。
>これは現状でどの画面でもschedules.jsが読み込まれており、スケジュールの実装の時と同様にクラスやデータ属性を整えると、同じように遷移できてしまうようになっていることが原因。
>→理想的には、全画面共通のjavascriptが基本処理としてあり、そこに画面ごとに個別処理のjavascriptを使って実装を進めるのが良いと思う。

これは保守性の面でダメなので、ひとまず画面共通用の処理を作ってそこにテーブル行からの遷移処理を移設する。

```bash
$ mkdir ./app/javascript/application
$ touch ./app/javascript/application/yaque_app.js
```

↑これを共通処理の置き場所にしていこう。

```js:app/javascript/packs/application.js
（略）
require("application/yaque_app.js")
```

```js:app/javascript/application/yaque_app.js
jQuery(document).on('turbolinks:load', function() {
  $(".clickable-row").css("cursor","pointer").on('click', function() {
    location.href = $(this).data("href");
  });
});
```

こんな感じに整理していくことにした。
※下記はいろいろ試しているときに探して読んだWeb記事。
[Ruby on RailsにおけるJavascriptファイルの取り扱い(Rails6)](https://nobunobu1717.site/?p=1292)
[railsのapp.jsで使う「//=」と「import」の違いがわかりません](https://teratail.com/questions/242956)

特に下は、なんか今までなあなあで済ませてきた部分が少し分かったので、個人的にはためになった。


今回は時間ないのでここまで。
次回はいよいよBootstrapを導入して、コードも手入れしていこうと思う。
（むしろなぜ今までやらなかったのか...）



[次回の記事>>](https://qiita.com/tomodachi_uec/items/9e99dcc0222892dc5ca7)
Vue+VueRouter+Vuex+Vuetify+LaravelでCMS管理画面作ってみた(仮)

取り急ぎ投稿のみ。
記事はまた今度書く。（多分）

#リポジトリ
https://github.com/torabe/basic-cms

#デモ
http://18.181.175.104/admin
ログインID:developer
パスワード:1234

※毎日00:00にDBが初期化されます。
Touch Barからワンタッチで使えるパスワード生成ツール

※初めての投稿です！

先日某Webメディアに会員登録をしようと思った時思いました。「Macが提案してくれるパスワード長すぎね？ Windowsで打つ時めんどくさくね？」と。
MacおよびiPhone, iPadが提案してくれるパスワードは20桁で、覚える必要がないにしろ、iCloudキーチェーンが使えないデバイスで入力するのはめちゃくちゃだるいです。(特にOculus Quest!!)
あとたまにパスワードの提案をしてくれない場合もあります。
てことで**Touch Barから使える、ワンタップの、提案してくれるやつより短い、パスワード生成ツール**を作ってみることにしました。

#何が必要か
前述のツールにはどんな機能が必要かをまず考えます。

+ 複雑なパスワードを生成すること
+ 毎回違うものが生成されること
+ クリップボードにコピーされること
+ Touch Barをタッチするだけで済むこと

この機能があれば要件は満たせますね。

#何で作ろうか。
##パスワードの生成
提案してくれるパスワードは20桁で、相当なセキュリティだと思います。それを短くするわけですから、もちろんそれなりに複雑なパスワードを生成しなければなりません。
そこでぱっと思いついたのはやはりPython(というかPythonしか知らない)。
調べてみるとパスワードを生成してくれるようなライブラリ、クリップボードに保存してくれるライブラリがあったので、Pythonに決定！

##ツールの起動
生成してくれてクリップボードに保存できても、いちいちターミナル開いてディレクトリに飛んで実行なんてしてられないので、Touch Barから実行できるようにします。
Touch Barのアプリみたいなのも作ってもいいかなと思いましたが、Swiftとかよくわからないので、Apple謹製自動化ソフトのAutomatorを使うことにしました。これならとても簡単です。

#いざツール作成開始
##パスワード生成〜クリップボード保存
使ったライブラリ
+ string
+ secrets
+ pyperclip

コード

```Python:password.py
import string
import secrets
import pyperclip

#中身①
def password(size=12):
   chars = string.ascii_uppercase + string.ascii_lowercase + string.digits

   return ''.join(secrets.choice(chars) for x in range(size))

#中身②
result = password(10)

#中身③
pyperclip .copy(result) 
```

###コードの説明
####ライブラリ/モジュール
+ string: 小文字/大文字アルファベットや数字、記号をまとめた変数のライブラリ(例えばstring.digitsは0〜9の数字の変数)
+ secrets: セキュリティ向けの強い乱数を生成してくれるモジュール
+ pyperclip: クリップボードの書き込み読み出しとかしてくれる

####中身
1. 大文字/小文字アルファベットと数字からランダムな文字列を生成してくれる関数を定義
2. 一回それを保存
3. クリップボードにコピー

##実行(Automator)
1. Launchpadに"Automator"と入れて、Automatorを起動
1. 「クイックアクション」を選択して
![スクリーンショット 2021-05-21 2.18.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423241/b011c899-9748-c573-3029-48332aaea2d3.png)

1. 「シェルスクリプトを実行」をドラックアンドドロップでワークフロー(右側)に追加
1. 以下のように書く(xxxはユーザー名)

```
cd /User/xxx/・・・/password.pyのあるフォルダ
/Users/xxx/opt/anaconda3/bin/python3 password.py
```

Pythonの場所は which python で出てきます。

これで実行側は完成なんですが、これでTouch Barから起動するとなぜか Operation not permitted というエラーが出ます。
SIP(システム整合性保護)が悪さをしているみたいで、それを解除すれば動きます！
(解除の仕方はGoogleでエラー名検索したら出てきます)

##Touch Barに追加
システム環境設定>キーボード>Touch Barに表示する項目 でControl Stripにチェックを入れたらすぐに使えます！

#実行の様子
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">もうちょいわかりやすい動画 <a href="https://t.co/8RdjkWFAp5">https://t.co/8RdjkWFAp5</a> <a href="https://t.co/6Q8qjMymGW">pic.twitter.com/6Q8qjMymGW</a></p>&mdash; Hiro (@hayahiro416) <a href="https://twitter.com/hayahiro416/status/1394316852151480320?ref_src=twsrc%5Etfw">May 17, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

動画にもありますが、[KasperskyのPassword Checker](https://password.kaspersky.com/jp/)で上の下くらいの評価なんでそれなりにいいんじゃないですかね。

#終わりに
なんといってもSIPの問題を解決するのにめちゃくちゃ時間がかかりました。Automatorの方でインライン化するとかすれば解決できたかもしれません。SIPの解除のリスクも高いですしね。何か解決案があれば教えてくださるとありがたいです。

##参考にした記事
+ [Pythonで複雑なパスワードを簡単に生成する](https://gammasoft.jp/blog/generate-password-by-python/)
+ [Automatorを使うと、クリック1つでPythonとかのプログラムを起動させられるんだってさ（Mac）](https://qiita.com/takatoshi0905/items/0a4abf3e1ecd483db911)
+ [Pythonでクリップボードを操作！pyperclipを使ってコピーしたデータを取得する](https://tonari-it.com/python-pyperclip-paste/)
powershellスクリプトで日付取得してテキストファイルの日付を書き換え



日報の日付を書き換えるのがいちいち面倒だったので。

- 日付を取得
- テンプレートファイルのYYYY/MM/DDを書き換える

ことを目指す。

内容的には以下の記事の続きです。  
[powershellスクリプトでテキストファイルを文字列置換](https://qiita.com/alphajinsei/items/cd5967848feb6a9bb84c)


# powershellで日付を取得する方法
`Get-Date`コマンドを用いる。単にこの`Get-Date`コマンドを打つと、以下のように表示される。

```console:console
PS > Get-Date

2021年5月21日 1:38:54
```

オプションをつけることで、細かく情報を抜き出すことができる。  
オプションのつけ方にも色々ある。
詳細は以下の記事を参照。  
https://cheshire-wara.com/powershell/ps-cmdlets/system-service/get-date/

```console:console
PS > (Get-Date).Year
2021
PS > Get-Date -UFormat %Y
2021
PS > Get-Date -Format yyyy
2021
PS > (Get-Date).Month
5
PS > Get-Date -UFormat %m
05
PS > Get-Date -Format MM
05
```

今回は月, 日も2桁で欲しいので、`Get-Date -UFormat %m`の形式を使う。

# ファイルに書き出す
本題。手順としては、


1. テキストファイルから文字列を読み込んで、
1. powershellで日付を取得し、
1. 文字列中の`YYYY, MM, DD`を日付に置き換え、
1. 新しいテキストファイルに出力する

の4ステップを行う。

コードと実行結果は以下。

```txt:template.txt
今日はYYYY年MM月DD日です
```

```powershell:create_report_without_args.ps1
$yyyy = Get-Date -UFormat %Y #年(西暦四桁)。ちなみに%yだと西暦下二桁。
$mm = Get-Date -UFormat %m #月(01～12)
$dd = Get-Date -UFormat %d #日(01～31)

Get-Content  -Encoding UTF8 ./template.txt `
| ForEach-Object {$_ -replace "YYYY", $yyyy} `
| ForEach-Object {$_ -replace "MM", $mm} `
| ForEach-Object {$_ -replace "DD", $dd} `
| Out-File -Encoding UTF8 $yyyy$mm$dd.txt -NoClobber
```

```txt:20210521.txt
今日は2021年05月21日です
```
今日の日付を反映できたことがわかる。

# まとめ
シェルスクリプト、便利だが覚える機会がない…
apcuを導入するためのDockerfileの書き方

## はじめに
apcuを導入するためのdockerfileの書き方に関する記事です。

## 対象
- PHP 8.0

## 手順
PHPコンテナ用のDockerfileに下記を追記する

```
# php拡張パッケージのapcuをインストールし有効化
RUN pecl install apcu && docker-php-ext-enable apcu
```

php.iniに下記を追記する

```
[apc]
# コマンドラインでのapcの使用有無(0：使用しない 1：使用する)
# APCのキャッシュはプロセスごとに独立しているのでCLIで使えたところであまり意味はないので0にしておく
# なお、CLIを1にしたとしても処理実行が終わる度にキャッシュは破棄される
apc.enable_cli=0

# apcの使用有無(0：使用しない 1：使用する)
apc.enable=1

```

## 補足
Dockerを使ったPHP環境の構築については、下記の記事がとても勉強になります。
[最強のLaravel開発環境をDockerを使って構築する](https://qiita.com/ucan-lab/items/5fc1281cd8076c8ac9f4)
【Rust】Rustのビルドツール”Cargo”についての自分的備忘録

##概要
Microsoft LearnでRustの勉強を始めてみた。
以前、Rustの環境構築時に`rustc`と同時にインストールした`cargo`がよくわからなかったが、今回それに触れてくれていたので備忘録的な記事を書く。

##Cargoとは
Rustプロジェクトの「ビルドツール」＆「パッケージマネージャ」


##備忘録
下記、Microsoft Learnから引用
>`rustc`コンパイラは、単純なプログラムには適していますが、Rust コンパイラを直接使用するプロジェクトはほとんどありません。 代わりに、Rustのビルド ツールであり、依存関係マネージャーである `Cargo` を使用します。幸いなことに、rustup をインストールすると、Cargo の最新の安定バージョンも入手できます。


|  コマンド  |  実行内容  |
| ---- | ---- |
|cargo new |  新しいプロジェクト テンプレートを作成する。  |
|cargo build|  プロジェクトをビルドする。 |
|cargo run|  プロジェクトをビルドして実行する。 |
|cargo test|  プロジェクトをテストする。 |
|cargo check|  プロジェクトの種類を確認する。 |
|cargo doc|  プロジェクトのドキュメントをビルドする。 |
|cargo publish|  crates.io にライブラリを発行する。 |

##（気になる！）`cargo test`
Rustはfnの前に`#[test]`を付ければそれがテストコードになる。`cargo test`を実行すると`#[test]`が付いてるものがマルチスレッドで実行されていく。
（Java/C#のAttributeみたいなものと解釈。他にもあるのか？）
TiDB and Database online meetup this Friday 3pm

# TiDB and Database 

Have you ever heard about [TiDB](https://github.com/pingcap/tidb) ? the most popular distributed database open source project, who is highly scalable, support hybrid transaction and also it's kernel KV store [TiKV](https://github.com/pingcap/tikv) , recently graduated from CNCF.

Technical organization 幽谷大学堂 invited PingCAP's CTO *Ed Huang* to share the story behind TiDB this Friday 3pm. 

We'll see you at Zoom ID 857 9807 5427 : )

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594699/e80cd55d-0a33-2be3-484a-5cd9544353bc.png)
【php】BMI算定アプリを作成せよ

１・身長をセンチメートル単位で変数に代入しておく
２・体重をキログラム単位で変数に代入しておく
３・BMIを出力する。フォーマットは「[身長]センチ、[体重]キログラムのあなたのBMIは[bmi]です。」
４・BMIの計算式は BMI ＝ 体重(キログラム単位) / 身長(メートル単位)の２乗
５・BMIは小数点第３位四捨五入で表示する。



```Html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>BMI.php</title>
</head>
<body>
<h1>BMI（肥満度）を求める</h1>
<form action="" method="post">
    身長：<input type="text" name="cm"> cm<br>
    体重：<input type="text" name="kg"> kg<br>
    <input type="submit" value="計算ボタン">
</form>
<hr>
```
```php
<?php
    if ($_POST) {
    $cm = isset($_POST['cm']) ? intval($_POST['cm']) : 0;
    $kg = isset($_POST['kg']) ? intval($_POST['kg']) : 0;
    
    if ($kg ===0 or $cm ===0) {
    print '入力が不正です';
    } else {
        $bmi = round(($kg * 10000)  / ($cm * $cm), 2);
         print $cm."センチ".$kg."キログラムのあなたのBMIは".$bmi."です。";
        if ($bmi >= 25.0 ) {
            print '太り気味です';
        } else if ($bmi < 18.5) {
            print 'やせ気味です';
        } else {
            print '標準体重です';
        }
    }
}

?>
</body>
</html>
```

実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954863/d15d2454-90e8-d271-5689-e42e56e0f79c.png)
Phoenix

Octave. The nonic toothbrush is a brand that works towards the environment and for the environment. We aim to launch other eco-friendly products, like biodegradable pens, bamboo bottles, baskets, and other plastic substitute products.
 The company is committed to developing products that would be a direct eco-friendly alternative to single-plastic products. The nonic toothbrush is biodegradable, long-lasting, and also improves oral hygiene. We wish to bring a strong impact through this and eliminate single-use plastics. The bamboo toothbrush is just one step towards making this planet clean, healthy, and sustainable. We aim to launch other eco-friendly products, like biodegradable pens, bamboo bottles, baskets, and other plastic substitute products. The bamboo used to make these toothbrushes are harvested with local farmers' help from various countries. Once the bamboo is cultivated, the land is cleared, and the new are harvested on the same land. ![Octave.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1527841/e868078e-00ad-d497-abd7-ba20fc5560f6.jpeg)
pipenvからrequirements.txtを生成する

# 経緯
ローカルの環境で開発していたプロジェクトをcloud Functionsで使用したくなったため、requirements.txtが必要になりました。
そこでpipenvの環境からrequirements.txtを生成する方法を調査しました。
※プロジェクトにPipfileが存在することが前提です。
## 出力手順
以下のコマンドを実行する。

```
pipenv lock -r > requirements.txt
```

開発用の依存関係だけのrequirements.txtを生成したい場合は以下のコマンドを実行する。

```
pipenv lock -r --dev > requirements.txt
```
powershellスクリプトでテキストファイルを文字列置換

表題の通り。powershellを全く触ったことがない人向け。  

powershellの文字列置換を使って、テンプレートファイルのYYYY/MM/DDを書き換えることを目指す。

初めてpowershellスクリプトを触って、詰まったことをメモ。

# 始める前に
powershellスクリプトは`*.ps1`の形式で保存する。

【重要】スクリプトの実行ができるようにポリシーを変更しておく。詳細は以下。  
https://qiita.com/opengl-8080/items/bb0f5e4f1c7ce045cc57


# 標準入力 -> 置換 -> 標準出力

単に文字列を置換したい場合は、次のように書く。

```powershell:simpleReplace.ps1
$a = "abc"
$b = $a -replace "a","A"
Write-Output $b
```

実行すると、確かにa->Aになっていることがわかる。

```:console
> .\simpleReplace.ps1 

Abc
```


あるいは、標準入力の一部を置換して標準出力に出したい場合は、以下のように書く。

```powershell:simpleReplaceWithArgs.ps1
Param([String]$a)
$b = $a -replace "a","A"
Write-Output $b
```

```:console
> .\simpleReplaceWithArgs.ps1 abc

Abc
```

余談だが、`Write-Output`は`echo`と書いてもよい。言い換えれば、`echo`は`Write-Output`のエイリアスとして設定されている。

また、powershellでは、変数の大文字小文字を区別しないことも知られている。

従って、次のコードでも同様に動作する。

```powershell:simpleReplaceWithArgs2.ps1
Param([String]$a)
$b = $a -replace "a","A"
echo $B #echoはWrite-Outputのエイリアス、$Bは$bと同じ
```

# テキストファイル -> 置換 -> テキストファイル
上から少し発展して、

1. テキストファイルから文字列を読み込んで、
1. 一行ずつ文字列置換の判定を行い、
1. 新しいテキストファイルに出力する

ことを考える。

要件として、

- 引数を`年 月 日`の形で与える。(例 : `2021 05 21`)
- template.txtから文字列を読み込む
- 文字列中のYYYY, MM, DDを引数で与えた日付に置き換える
- 書き出し先のファイル名は引数で指定した`[年月日].txt`とする(例 : `20210521.txt`)
- すでに同名のファイルがある場合は何もしない

コードと実行結果は以下。

```txt:template.txt
今日はYYYY年MM月DD日です
```

```powershell:create_report.ps1
Param([String]$yyyy, [String]$mm, [String]$dd)
Get-Content  -Encoding UTF8 ./template.txt `
| ForEach-Object {$_ -replace "YYYY", $yyyy} `
| ForEach-Object {$_ -replace "MM", $mm} `
| ForEach-Object {$_ -replace "DD", $dd} `
| Out-File -Encoding UTF8 $yyyy$mm$dd.txt -NoClobber
```

```txt:20210507.txt
今日は2021年05月07日です
```
日付が正しく書き換えられたことがわかる。

以下、はまったことに関するメモ。

- 引数の型  
引数を指定する際、単に`Param($mm)`とすると、powershellが勝手にキャスティングを行ってしまう(`05` -> `5`など)。これを防ぐために、`Param([String]$mm)`と書いてあらかじめ型を指定しておく。


- エンコーディング  
特に日本語のファイルを読み書きするときは、`Get-Content`と`Out-File`の両方のオプションに`-Encoding UTF8`をつけておくべき。指定しないと、出力先のファイルのファイル形式がUTF16になるなど、とにかく予想できない動きをする。

- 上書きの禁止  
`Out-File -NoClobber`にオプションをつけておくとファイルの上書きを禁止してくれる。次のサイトが良くまとまっている  
https://tech.guitarrapc.com/entry/2014/02/11/061627

- 表記関係
  - `ForEach-Object`のエイリアスとして`%`を使用可能
  - `$_`はパイプラインに渡されるオブジェクトを表す。
  - コマンド途中での改行はバッククォートを使う

# まとめ
powershellの可能性を感じる。
将来的には、引数無しでpowershellから日付を取得するコードに書き換えたい。
->書き換えました([powershellスクリプトで日付取得してテキストファイルの日付を書き換え](https://qiita.com/alphajinsei/items/a7568f1602f72428b11c))
【JupyterNotebook】インストールしたはずなのにModuleNotFoundError

#環境
MacbookPro M1
OS BigSur 11.2.1
メモリ 16G
言語 Python


#発生した問題
Jupyter Notebookにて`missingno`というモジュールをインストールしたはずなのに`ModuleNotFoundError: No module named`エラー


#原因を探す

まずは適切にインストールされているか確認

```
pip list
```
![スクリーンショット 2021-05-21 0.33.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218168/03b61037-1b93-86bc-f576-ef0a2ea6b3f3.png)
インストールされてた



次にモジュールのインストールした場所の確認

```
pip show missingno
```
すると以下のようなエラー文

``
WARNING: Package(s) not found: missingno
Note: you may need to restart the kernel to use updated packages.
``


パッケージをアプデするにはKernelを再起動しないといけないみたいなので`Kernel` -> `Restart`で再起動

しかしいくら再起動しても同じエラー文。ググってもこれ以上の解決策が見つからなかったのでいっそAnacondaごと再インストールしようと考えた。


#解決方法
Anaconda Navigatorを立ち上げて、`Environments`から直接missingnoをインストール
![スクリーンショット 2021-05-21 0.51.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218168/c35786e4-2069-be17-cc9d-d79e6634eeb4.png)

するとなぜかエラーが吐かなくなった。
pip installで予め入れてあった他のモジュールもエラー吐いていましたが、missingno一つをインストールしたら他のモジュールもエラー吐かなくなりました。割と謎...
(誰か具体的な原因わかる方いたら教えてください)
［Outlook VBA］リボンをクリックして返信先の指定（Reply-To:）を設定する

#備忘メモ：Outlook VBAを使って返信先の指定(Reply-To:)を設定

## 説明
Outlookのメッセージ編集画面で「返信先の指定」（Reply-To:）を設定する際の、オプション
＞返信先＞返信先の指定にアドレス入力、の一連の操作が煩わしいので、リボン用のマクロを作成し、自動設定できるようにする。

##動作確認環境
Microsoft® Outlook® 2016 MSO (16.0.13929.20206) 32 ビット 

##コード
```vb
Sub Set_Replyto()

    '登録されている返信先をいったんすべて削除
    Do While ActiveInspector.CurrentItem.ReplyRecipients.Count > 0
        ActiveInspector.CurrentItem.ReplyRecipients.Remove 1
    Loop
    
    '返信先アドレスを追加
    ActiveInspector.CurrentItem.ReplyRecipients.Add ("myname@hoge.fuga")
    
End Sub
```
Solr 9.0をソースコードからビルドしてIntelliJでデバッグする



# ソースコードをclone

ソースコードをcloneしてくる。
https://github.com/apache/solr

IntelliJでCloneしたソースコードをプロジェクトとして開いておく。


# ビルド

READMEに書いてある通りビルドコマンドを実行。

```
./gradlew assemble
```

実行ファイルなどはルートディレクトリから見て solr/packaging/build/solr-9.0.0-SNAPSHOT/にできる。
ここによく見かけるbinディレクトリとかがある。

```
$ ls
LICENSE			buildSrc		gradle.properties	settings.gradle
README.md		dev-docs		gradlew			solr
build			dev-tools		gradlew.bat		versions.lock
build.gradle		gradle			help			versions.props
$ ls solr/packaging/build/solr-9.0.0-SNAPSHOT/
CHANGES.txt	NOTICE.txt	bin		dist		docs		licenses
LICENSE.txt	README.md	contrib		docker		example		server
```


# debugモードで起動

-aオプションでJVMのオプションを追加で指定できるのでそれで起動する。
実際にSolrが起動するのは次の手順で説明するIntelliJから虫マークを押したタイミングで、solr startしてから180秒以内にそれをしないと多分起動プロセスが中断するので注意。

```
./bin/solr start -a "-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=4044"
```

# IntelliJでCloneしたソースコード
Edit Configration→Add New Configrationでデバッグ用のコンフィグを追加
![スクリーンショット 2021-05-21 0.21.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147530/fbd1d657-bfb7-b0ef-49de-6661e3cd6c6e.png)
![スクリーンショット 2021-05-21 0.21.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147530/e40a017b-9b6e-765a-1893-80d310758845.png)

↓の虫のアイコンを押せばSolrが起動する
![スクリーンショット 2021-05-21 0.25.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147530/9b507966-5d17-96d1-89fe-d3b0a0f52a45.png)




# コアとコレクションを作る
以下からSolr Adminにアクセス
http://localhost:8983/solr/#/


以下からコアを追加する。
今回はコア名new_coreで追加。
![スクリーンショット 2021-05-21 0.29.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147530/52153557-2385-e0b0-6b78-ea9a1e86e441.png)

ただし、初回実行時は以下のようなエラーが出る。

```
Error CREATEing SolrCore 'new_core': Unable to create core [new_core] Caused by: Can't find resource 'solrconfig.xml'
```

以下のディレクトリにコア名と同じディレクトリが作成されている。

```
$ ls server/solr/
README.md	configsets	new_core	solr.xml	zoo.cfg
```

server/solr/configsets/_default/ にsolrconfigなどが用意されているのでnew_coreにまるごとコピーしてくる。

```
$ cd server/solr/new_core/
$ mkdir data 
$ cp -r ../configsets/_default/ .
```

# ドキュメントを追加

UIからid=1というドキュメントを追加

![スクリーンショット 2021-05-21 0.38.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147530/43f7c824-91e7-0a54-d7fa-e930f29c3d47.png)

検索できることを確認

```
$curl http://localhost:8983/solr/new_core/select?q=*%3A*
{
  "responseHeader":{
    "status":0,
    "QTime":0,
    "params":{
      "q":"*:*",
      "q.op":"OR"}},
  "response":{"numFound":1,"start":0,"numFoundExact":true,"docs":[
      {
        "id":"1",
        "_version_":1700292289915518976}]
  }}

```

# ブレークポイントをおいてデバッグしてみる

検索処理を行うコードにブレークポイント置いてみる
https://github.com/apache/solr/blob/f36262d7426b52c07a4fe12ebb21919ac2447006/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java#L178

検索リクエストを実行

```
curl http://localhost:8983/solr/new_core/select?q.op=OR&q=*%3A*
```

IntelliJでちゃんとブレークポイントで止まることが確認できる。
![スクリーンショット 2021-05-21 0.47.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147530/21eb9d4e-016a-85ff-fb02-5456426b67c5.png)
STM32L010とMCP3425で0から2.048000Vまで62uV単位をシリアル出力(MCP3425A0T-E/CH 16bitADC)(電圧)


STM32L010用に軽量コンパクト

xNJL5513Rの実験で必要になったために開発
x工夫いろいろ　mbedのリビジョンは125
xRawSerialを使用
x すべては、容量削減(勝利?)のために　ジ〇クジオン

構成
STM32L010F4P6　I-15689
MCP3425A0T-E/CH　I-07638

1.SCLとSDAを接続、プルアップも忘れずに
2.電源の接続
3.下記のソースコードを書き込む
4.コンパイル実行で表示されたら終了
5.おわり

```c++

#include "mbed.h"

//10の割り算 0から1028までは、正しい。主に0から999
#define DVI10(n) ((n*205)>>11)

//16ビットadcの4ビットの変換テーブル
#define ADC4BIT { 0   , 62 ,125 ,187 ,250 ,312 ,375 ,437 ,500 ,562 ,625 ,687 ,750 ,812 ,875 ,937 }

#define ADDR        (0xD0)   //  address

//I2C i2c(I2C_SDA, I2C_SCL); //767
//I2C i2c(dp5, dp27); //1114
I2C i2c(PA_10, PA_9); //010

//Serial pc(USBTX, USBRX); // tx, rx
//Serial pc(SERIAL_TX, SERIAL_RX); //767
//Serial pc(PA_2, PA_3); //010
//Serial pc(PA_9, PA_10); //010
RawSerial pc(PA_2, PA_3); //010

char    data_read[8];   //i2cバッファー

char ch_hex_a_b[5];
char *ch_hex_a(int l_num)
{
    int a,b,c;

    b=DVI10(l_num);
    c=l_num-(b*10);
    a=DVI10(b);
    b=b-(a*10);

    ch_hex_a_b[0] = '0' + a;
    ch_hex_a_b[1] = '0' + b;
    ch_hex_a_b[2] = '0' + c;
    ch_hex_a_b[3] = 0;

    return(ch_hex_a_b);
}//ch_hex_a

//文字列の表示
int pc_printf(char *str1) {

    //文字の中身がゼロか
    while(*str1){

        //一文字出力
        pc.putc(*str1 ++);

    } //while

    //戻り値
    return(0);
}//pc_printf

int ii;     //ループカウンタ

int main()
{
    //pc_printf("\r\n-767-\r\n"); //767
    
    //MCP3425の初期化
    i2c.write(ADDR, "\230", 1); //16bit 15sps PGA x1
    
    int s;   //101

    short bit4[]=ADC4BIT;

    while (1) {
        
        //データの読み込み
        i2c.read(ADDR | 1, data_read, 2);

        s = (data_read[0] * 256 ) + data_read[1];
        //s = (65536/2)-1; debug

ii=(s >> 4);
if     ( ii >= 2000 ) { ii = ii - 2000; pc_printf("2.");    }
else if( ii >= 1000 ) { ii = ii - 1000; pc_printf("1.");    }
else                  {                 pc_printf("0.");    }

        //pc.printf(" o=%s\r\n",ch_hex_a( ii )                ); //767
        pc_printf( ch_hex_a( ii ) );

        //pc.printf(" t=%s\r\n",ch_hex_a( (bit4[ s & 0xf ]) ) ); //767
        pc_printf( ch_hex_a( ( (int)bit4[ s & 0xf ])) );

        pc_printf( "\r\n" );

        //1秒の待ち
        wait_ms(1000);
    }//while

}//main

//容量削減
void error(const char* format, ...){}



```

![serial_raw_mcp_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/25154a2c-7d4a-287b-b71d-ae5812da8e55.jpeg)
Ruby on Rails6 学習メモ

#form関連（特にform_with）
###データベース上の値をセレクトボックスで出力させる

```slim:slim
= f.collection_select :project_id, current_user.projects, :id, :name, {include_blank: "プロジェクトを選択してください"}, class: 'form-control'
```

このように記述する。
書き方の公式としては、

```slim:slim
= f.collection_select :保存先のカラム名, 表示したいデータベースのモデル.all, :保存したい値, :表示させる文字列, {include_blank: "プロジェクトを選択してください"}, class: 'form-control'
```

#link_toの使い方

```erb
<%= link_to 'アカウント設定', "/users/edit" %>
```

これが基本的な使い方。

###戻るボタン
```erb
<%= link_to '戻る', :back %>
```

###data: { confirm: "削除してもよろしいですか？" }
リンクの先に行く前にメッセージを提示してくれる

```
= link_to '削除', task_path(@task), method: :delete, data: { confirm: "削除してもよろしいですか？" }
```

こんな感じで削除リンクとかで使うと便利かも。

#deivse関連
###ログアウトのリンク

```erb
<%= link_to 'ログアウト', destroy_user_session_path, method: :delete  %>
```

###devise（認証機能）のviewを取得する方法

`divise.rb`にて

```ruby:devise.rb
  config.scoped_views = false
```

をコメント外して、trueに変更する。そのあとに

```:terminal
rails g devise:views
```

とコマンドを打つ。

###サインしていたら〜の処理

```erb
<% if user_signed_in? %>
処理
<% end %>
```

このように`user_signed_in?`メソッドを使用する

###current_userについて
ログイン中の自分のアカウント情報を取得できる`current_user`だが、`user`の部分は
変化する。
例えば、devise機能でモデル名をuserとしたら、`current_user`となるが、
モデル名をcompanyとしたら、`current_company`となる。
idを取り出したい時は`current_company.id`で取得することができる。

current_userは`user = User.find(current_user)`と同じなので、そのままアソシエーションにも使用できる。

```ruby:例
my_name = current_user.profile.name

# user = User.find(current_user.id)
# my_name = user.profile.name
#これと同じような動きになる
```

といったようにできる

#マイグレーション
###マイグレーションを完全リセットして、変更を反映させる

```
rake db:migrate:reset
```

###上のコマンドでエラーが出た時

```:terminal
rails db:environment:set
```
を打てば治る


#モデル
###ログイン中の自分の情報を取得（二通りある）
####一つ目

```ruby
@user = User.find(current_user.id)
```

モデルのfindメソッドで引数に現在ログイン中の自分のdeviseの情報を格納する。
deviseの自分のアカウント情報は`current_user`で取得できる。その中でもidを取得したいのであれば、
`current_user.id`とする。
ちなみに、コントローラーとモデルで関係ないモデルも使用することができる。

####二つ目

```ruby
@user = current_user
```

で自分のアカウント情報が取得できる。
しかし、これはモデルを通してないから、DBのリレーションをする際には、ひとつ目の方法で行うこと。

##バリデーション
###belongs_toによる勝手に設定されるバリデーションを防ぐ

```ruby:モデル
# project_id変更時のnilを許可する
  belongs_to :project, optional: true
```

このように`optional: true`というオプションを追加すると値のnilを許可する。

#コントローラー
###特定のカラム（値）のみUpdateする方法（controller上で値を変更する）

```ruby:controller
user = User.find(current_user.id)
user.age = 50
user.save
```

通常はviewでフォームを作成して、updateするが、controller上で値を変更する場合は、このような記述で変更することができる。

###アカウント削除の時に関連するデータも削除する方法
dependent => :destroyを記述することで、退会時にユーザID情報(user_idを持つもの）を持つデータを削除する。

```ruby:User.rb
has_many :messages, :dependent => :destroy#退会時コメントも削除
```

#左上のやつを消す方法

`/?pp=disable`をURLの最後に追加する
一定期間の間は、一回追加するだけで消える。
また再び左のやつが現れたら上のをURLに追加してリロードする

#Railならではの省略系
###@userの正体

```erb:view
<% link_to 'リンク名', @user %>
```

このような書き方がある。これはいわゆる

```ruby:controller
@user = User.find(2)
url_for(@user)
# => "/users/2"
```

このような内容となっている。
恐らく、usersコントローラーでuser.idを指定していると考える。

#routes.rb
###resourcesの考え方

```
index 
new
create
edit #対象のデータ
update　#対象のデータ
show　#対象のデータ
destroy　#対象のデータ
```

対象のデータが必要なアクションには`id`が必要となる。

###リソースとは
`データベースのテーブルに保存される、レコード1行分の情報`のこと。
計算量入門

#計算量入門
コンピュータアルゴリズムにおいて、計算量という値がある。
これはそのアルゴリズムの処理にどれくらいの計算コストが必要かということを表す。
領域計算量と呼ばれる必要なメモリの量を表すものもあるが、もっぱら計算量をというと**時間計算量**を表すことが多い気がする。

##計算量の評価法
計算量の評価法としては、そのアルゴリズム１ステップにおいて行える処理を決め、実行回数を計測し、その結果を入力長の関数として表す。その関数の発散具合から評価を行う。

###時間計算量の種類
時間計算量とは、名前の通り、その処理にどれくらいの時間(ループ)がかかるかということである。
最悪時間計算量、平均時間計算量、最善時間計算量という３種類の定義がある。
最善と平均に関しては、その評価が難しいためあまり実用的ではなく、最悪計算量が基本的に使われることが多い。アルゴリズムによっては平均を使う場合もある。

####計算量の表記
評価法で計算量は入力長の関数として表せるとした。
実際に計算量を表記する時には、その関数がどのような関数で抑えれるかで記述する。
この時、O（ビックオー）を用いたビックオー記法で記述する。
単純な例を挙げると、1~nまでの数の順に足し合わせていくようなアルゴリズムでは、その計算量はnとなり
**O(n)**と表せる。

#####メモ
**多項式時間認識可能な言語全体を表すPについて勉強している中での疑問とその説明**
Pの例題として入力{x,y}が互いに素であるかの判定を行う時について考えた時、
x,yは共に２進数整数の時、データの入力長、つまり、
TMが入力された文字を読むのにかかる計算量はO(logx+logy)である。（この時底は２）
これはデータ入力長とデータの桁数とほぼ等しいという考えから導ける。
簡単のため、10進数の場合を考える。
x = 10000 = 10 ** 4 という入力が与えられた時、
それを表すにはn = log x = 4　だけ必要である。（ここで底は10）
つまり、一般に
10進数において入力長nの文字列を読み込むにはO(log10 n)だけかかる。
2進数において入力長nの文字列を読み込むにはO(log2 n)かかる。

未解消な疑問点として、TMでの四則演算などがPに属するのはなぜかという点が解消できていないので、解消出来次第追記します。
[Java]誕生日と現在日から年齢を求める

# はじめに
今回はユーザ入力により誕生日を取得し、現在日と比較することで年齢を計算するプログラムを考えていきます。

# 計算の流れ
誕生日の計算の方法は様々あるようですが、今回は「驚き早技で求めました！」みたいなものではなく、地道に計算するものとなります。
それでは早速流れを確認していきます。
1. [現在年ー生まれ年]により基準となる年齢を計算する。
2. 今年誕生日を迎えているかを判断する。
　　2.1. [現在月 < 誕生月]であれば年齢を−１する。
　　2.2. [現在月 = 誕生月]ではあるが[現在日 < 誕生日]であれば年齢−１する。

以上が、計算の流れになります。やること自体は簡単ですよね。

# 計算部分のコード
それでは実際に年齢計算をするコードを確認していきましょう。
今回の年齢計算メソッドは、Date型で誕生日、現在日の2つの引数をとるものとします。
最初に引数で与えられたDate型の変数をCalendar型に変換します。
その後の計算部分は全てCalendar型で行っています。

実際にコードを動かす際は、Date型やCalendar型のパッケージをインポートする必要があるのでご注意ください。
そのあたりは、まとめコードを参照してくださいね。

```Java
// 年齢を計算するメソッド（第１引数：誕生日、第2引数：現在日）
public static int calcAge(Date birthday, Date now) {
	// Calendar型のインスタンス生成
	Calendar calendarBirth = Calendar.getInstance();
	Calendar calendarNow = Calendar.getInstance();

	// Date型をCalendar型に変換する
	calendarBirth.setTime(birthday);
	calendarNow.setTime(now);

	// （現在年ー生まれ年）で年齢の計算
	int age = calendarNow.get(Calendar.YEAR) - calendarBirth.get(Calendar.YEAR);
	// 誕生月を迎えていなければ年齢-1
	if (calendarNow.get(Calendar.MONTH) < calendarBirth.get(Calendar.MONTH)) {
		age -= 1;
	}else if (calendarNow.get(Calendar.MONTH) == calendarBirth.get(Calendar.MONTH)) {
		// 誕生月は迎えているが、誕生日を迎えていなければ年齢−１
		if (calendarNow.get(Calendar.DATE) < calendarBirth.get(Calendar.DATE)) {
			age -= 1;
		}
	}

	return age;
}
```

# まとめコード

```CalcBirthday.java
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class CalcBirthday {

	public static void main(String[] args) throws ParseException {
		// Scannerクラスのインスタンス作成
		java.util.Scanner scan = new java.util.Scanner(System.in);

		// 誕生日を入力する
		System.out.println("誕生日を入力してください（yyyy/mm/dd）");
		String day = scan.next();

		//日付クラスの書式を設定したSimpleDateFormatクラスのインスタンスを作成する
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");

		// 誕生日をDate型に変換する
		Date birthday = sdf.parse(day);

		//現在日時の取得
		Date now = new Date();

		System.out.println("年齢は" + calcAge(birthday, now) + "歳です");
	}

	// 年齢を計算するメソッド（第１引数：誕生日、第2引数：現在日）
	public static int calcAge(Date birthday, Date now) {
		// Calendar型のインスタンス生成
		Calendar calendarBirth = Calendar.getInstance();
		Calendar calendarNow = Calendar.getInstance();

		// Date型をCalendar型に変換する
		calendarBirth.setTime(birthday);
		calendarNow.setTime(now);

		// （現在年ー生まれ年）で年齢の計算
		int age = calendarNow.get(Calendar.YEAR) - calendarBirth.get(Calendar.YEAR);
		// 誕生月を迎えていなければ年齢-1
		if (calendarNow.get(Calendar.MONTH) < calendarBirth.get(Calendar.MONTH)) {
			age -= 1;
		}else if (calendarNow.get(Calendar.MONTH) == calendarBirth.get(Calendar.MONTH)) {
			// 誕生月は迎えているが、誕生日を迎えていなければ年齢−１
			if (calendarNow.get(Calendar.DATE) < calendarBirth.get(Calendar.DATE)) {
				age -= 1;
			}
		}

		return age;
	}

}
```

# 参考ページ
[Javaの日付データ型変換（Date, Calendar, String）](https://qiita.com/ayaka105/items/1a68ed7ad84743dde7d5)
code --list-extensions を共有する記事

棚卸しも兼ねて今入れてるVSCodeのエクステンションを紹介

# とりあえず全部出す

```
kanchu@Kanchus-Macbook-air ~ % code --list-extensions
2gua.rainbow-brackets
batisteo.vscode-django
budparr.language-hugo-vscode
cameronbieganek.julia-color-themes
cschleiden.vscode-github-actions
Dart-Code.dart-code
Dart-Code.flutter
DiemasMichiels.emulate
donjayamanne.python-extension-pack
DotJoshJohnson.xml
eamodio.gitlens
ecmel.vscode-html-css
Gruntfuggly.todo-tree
HitkoDev.vscode-remark-hugo
humao.rest-client
Ikuyadeu.r
Jarga.apib
jebbs.plantuml
jeremyrajan.react-component
julialang.language-julia
lextudio.restructuredtext
localizely.flutter-intl
lonefy.vscode-JS-CSS-HTML-formatter
magicstack.MagicPython
mariomatheu.syntax-project-pbxproj
mhutchie.git-graph
mosapride.zenkaku
ms-python.python
ms-python.vscode-pylance
ms-toolsai.jupyter
ms-vscode-remote.remote-ssh
ms-vscode-remote.remote-ssh-edit
ms-vscode-remote.remote-wsl
ms-vscode.cpptools
msjsdiag.debugger-for-chrome
njpwerner.autodocstring
oderwat.indent-rainbow
platformio.platformio-ide
rebornix.ruby
redhat.vscode-commons
redhat.vscode-xml
REditorSupport.r-lsp
rusnasonov.vscode-hugo
rust-lang.rust
shd101wyy.markdown-preview-enhanced
tht13.python
VisualStudioExptTeam.vscodeintellicode
vncz.vscode-apielements
vsls-contrib.codetour
wholroyd.jinja
wingrunr21.vscode-ruby
yzhang.markdown-all-in-one
```

# 詳細説明

## 無いと死ぬ群
// TODO:
MY SQL 基本　It 's　mine

〜データの取り出し〜


全てのデータを取り出す（XXXはデータ名)
SELECT * FROM xxxxxx ;

一部取り出し(AAAは項目のタイトル、2個目はBBB）
SELECT AAA,BBB level FROM xxxxxx;

一部だけ取得（5以上を取得の場合）
SELECT * FROM xxxxxx WHERE AAAA >=　5;

複数の条件を組み合わせる
SELECT * FROM xxxxx WHERE AAAAA >= 7 AND BBBBB <> 6;

条件指定とカラム選択を組み合わせる
SELECT AAAA, BBBB FROM xxxxxx WHERE BBBBB >= 7;

データ件数を表示する
SELECT COUNT(*) FROM xxxxx;

条件に合ったデータの件数を表示する
SELECT COUNT(*) FROM xxxxx WHERE AAAAA = 6;

データを並び替えて取得する(昇順）
SELECT * FROM xxxxx ORDER BY AAAAAA;

データを並び替えて取得する(逆順)
SELECT * FROM xxxxx ORDER BY AAAAA DESC;

上位3件だけ表示す
SELECT * FROM xxxxx ORDER BY AAAAA DESC LIMIT 3;

AAAAAごとに人数を集計する
SELECT AAAAAA COUNT(*) XXXXXX GROUP BY AAAAA;


〜データの更新、削除〜

データを追加する
INSERT INTO xxxxxx(AAAAA,BBBBB,CCCCC) VALUES(aaaa, "bbbbb", "c", 1);

表示
SELECT * FROM XXXXXX;

複数追加もできる
INSERT INTO xxxxxx(AAAAA,BBBBB,CCCCC)
VALUES
(aaaa, "bbbbb", "c", 1),
(dddddd, "dfdfdfd", "f", 2)
;
SELECT * FROM XXXXXX;

更新(AAA+1と打てぼAAAは1増える）
UPDATE xxxxx SET AAAA = 10 WHERE BBB = 11;
SELECT * FROM xxxxx;

データを削除する
DELETE FROM xxxxx WHERE AAAA = 13;
SELECT * FROM xxxxx;
NodejsでDynamoDB使ってみた

## 背景
はじめて業務でDynamoDBを使用したため、基本的なものだがメモを残して、自身のナレッジとして蓄えようかと

## 環境
- node.js
- DynamoDB
- Lambda

## 経験した関数
### 登録
 - put

#### パラメータ
 - TableName: テーブル名
 - Item: 登録対象

```
ex))
TableName: 'test-table',
Item: {
  'id': 1,
  'name': 'test',
}
```
### 取得
 - get

#### パラメータ
 - TableName: テーブル名
 - Key: AttributeValueのカラム名(一般的なTableのprimary key)

```
ex))
TableName: 'test-table',
Key: {
  'id': 1
  'sort': 1
}
```
### 検索
 - scan

#### パラメータ
 - TableName: テーブル名
 - FilterExpression: SQLの条件式
 - ExpressionAttributeValues: SQLの条件式に設定する値

```
ex))
TableName: 'test-table',
FilterExpression: 'created_at = :now',
ExpressionAttributeValues: {
  ':now': '2021-01-01 00:00:00'
}
```
### 削除
 - delete

#### パラメータ
 - TableName: テーブル名
 - Key: AttributeValueのカラム名(一般的なTableのprimary key)

```
ex))
TableName: 'test-table',
Key: {
  'id': 1
}
```
## ハマったこと
- 動作確認で`ListTables`を使ったが、廃止になっていた。。
https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/API_ListTables_v20111205.html

- Scan関数１回で取得できる容量は最大`1MB`。最大容量以上のデータを取得する場合は複数回関数を呼び出さなければ正常な動作をしない
https://qiita.com/naoko_s/items/e88928a95bb7f76e1bf0

- Scan関数の`FilterExpression`はScanで全件取得した後にFilterExpressionの条件でフィルタをかけるので、場合によっては期待通りの結果にならない場合があった。。

## 今後のチャレンジ
- 参考リンクに他の関数もあったので、使ってみようかな

## 参考リンク
- https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB.html
- https://xp-cloud.jp/blog/2019/10/24/5698/
IBM Cloud Code Engineでのアプリケーションの更新

# はじめに

当記事では、「[IBM Cloud Code EngineにQuarkusのサンプルアプリケーションをデプロイしてみる](https://qiita.com/hisato_imanishi/items/45c83963fa44c34e0255)」でデプロイしたアプリケーションに変更を加え、それをIBM Cloud Code Engine上で更新(デプロイ)します。

また、アプリケーションの更新が無停止で行えることも確認します。

# アプリケーションの更新方法

変更済みのアプリケーションのコンテナイメージが、latestタグで既にレジストリ上にpush済みであるという前提で進めます。

[Code Engineのプロジェクト一覧ページ](https://cloud.ibm.com/codeengine/projects)にアクセスします。

更新対象のアプリケーションの属するプロジェクトを選択します(今回は「quarkus-sample」)。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/6705ef26-d4e8-d217-18cc-9435989e59a8.png)


更新対象のアプリケーションを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/e3d7db4b-cec4-3f57-6c8b-8ed982c175ed.png)


現在のアプリケーションのリビジョンは、「app-getting-started-00003」です。新バージョンをデプロイするため、「新規リビジョン」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/1c8a9336-08ac-e707-d289-1d63d58151f2.png)


すると、新規リビジョンが「app-getting-started-**00004**」になっています。イメージのタグは更新前・更新後ともに latest のため、「イメージ参照」は変更せず、この状態で「保存してデプロイ」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/f2694546-aada-0b83-02b3-51b6d354652f.png)


しばらく待つと、ステータスが「準備完了」、「選択されたリビジョン」が「app-getting-started-**00004**」となり、これでデプロイが完了しました。アプリケーションの更新は非常に簡単な手順で実施できますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/897a0b90-a47d-d929-d4bc-b673b1e30938.png)


なお、この手順の実施中、更新対象のアプリケーションのREST APIを、[hey](https://github.com/rakyll/hey) でリクエストし続けた結果が以下になります。全リクエストのレスポンスがレスポンスコード200で返っており、**デプロイが無停止で行われていることが分かります**。

```zsh
❯ hey -z 2m https://<ホスト名>/hello

Summary:
  Total:	121.0551 secs
  Slowest:	2.1116 secs
  Fastest:	0.0162 secs
  Average:	0.1202 secs
  Requests/sec:	412.8122
  
  Total data:	799568 bytes
  Size/request:	16 bytes

Response time histogram:
  0.016 [1]	|
  0.226 [44675]	|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
  0.435 [4577]	|■■■■
  0.645 [553]	|
  0.854 [98]	|
  1.064 [50]	|
  1.273 [13]	|
  1.483 [2]	|
  1.692 [2]	|
  1.902 [0]	|
  2.112 [2]	|


Latency distribution:
  10% in 0.0448 secs
  25% in 0.0629 secs
  50% in 0.0939 secs
  75% in 0.1338 secs
  90% in 0.2438 secs
  95% in 0.3219 secs
  99% in 0.5076 secs

Details (average, fastest, slowest):
  DNS+dialup:	0.0001 secs, 0.0162 secs, 2.1116 secs
  DNS-lookup:	0.0000 secs, 0.0000 secs, 0.0029 secs
  req write:	0.0000 secs, 0.0000 secs, 0.0009 secs
  resp wait:	0.1199 secs, 0.0161 secs, 2.1115 secs
  resp read:	0.0001 secs, 0.0000 secs, 0.3310 secs

Status code distribution:
  [200]	49973 responses
```


また、「選択されたリビジョン」をクリックすると、過去のリビジョンが選択リストとして表示されます。過去リビジョンを選択することで、そのリビジョンにロールバックできそうな雰囲気ですが、実際には過去リビジョンをクリックしても何も起こりません。今後ロールバック機能も実装されるのかもしれません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/c2f98862-418e-032b-4f31-4fdd8e546622.png)
AdMobで問い合わせ時にエラーになった時に問い合わせられるようになった話

# 前置き
- どうしてもAdMobに問い合わせがしたい状況に……
- マイページ,[ヘルプセンター](https://support.google.com/admob/gethelp?authuser=0)から問い合わせしようとした
- そうしたらエラーが……
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87713/63657993-af3a-a149-bf59-5a5a87947c4e.png)

# 解決方法
- AdMobを申し込んでないアカウントで、[ヘルプセンター](https://support.google.com/admob/gethelp?authuser=0)からアクセスすると大丈夫！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87713/eb335540-5db6-af33-259d-af6ff78c2936.png)
  - 問い合わせ内容にパブリッシャーIDとか指定できるので、紐づいたアカウントで問い合わせしなくても良さそう

## 解決までに試してみたこと
1. ブラウザのキャッシュ削除
    - 特に変わらず
1. 別のAdMobアカウントでアクセス（間違って作成したやつ）
    - 同様にエラー
1. 別PCで別Googleアカウントでアクセス（会社のやつ）
    - エラーにならない！なんやて！
1. 2の間違って作成したアカウントをAdMob解約した状態でヘルプセンターアクセス
    - エラー……

**→ 結論：AdMobに紐づかないGoogleアカウントでヘルプセンターにアクセスすれば行ける！！**



# 感想
- なんでや
SwiftUI 表と裏を切り替えてカードめくりを表現する

# はじめに

ちょっと便利なものを作ってみました。カードゲームを作ったり、面白いUIをアプリに組み込みたいときにどうぞ。

![fb.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/982650/7c39492d-564a-19d0-9b0a-9e733c9fe9ac.gif)

# 使い方

### 表: true,    裏: false

- ```@State var isFront = true``` みたいな感じで、 **表裏の状態を表す変数** を作っておいてください。
ボタンを押した時とかにこの変数を変更すれば 表裏が切り替わります。

### Flip

- ```Flip(変数, { 表 }, { 裏 })``` を使います。
- duration: めくるスピードを調整できます。設定しなくてもOK。

```Sample.swift

...
// 裏と表がある View
Flip(isFront: isFront, // 先に作っておいた変数 isFront
     front: {

         Image("H1") // 表面 ハートのA
     },
     back: {

         Image("Back") // カード裏面
     })
...
```

# コピペ用コード

丸々コピペしてプロジェクト内のどこかにおいてください。

```Flip.swift

import SwiftUI

struct Flip<Front: View, Back: View>: View {
    var isFront: Bool
    @State var canShowFrontView: Bool
    let duration: Double
    let front: () -> Front
    let back: () -> Back
    
    init(isFront: Bool,
         duration: Double = 1.0,
         @ViewBuilder front: @escaping () -> Front,
         @ViewBuilder back: @escaping () -> Back) {
        self.isFront = isFront
        self._canShowFrontView = State(initialValue: isFront)
        self.duration = duration
        self.front = front
        self.back = back
    }
    
    var body: some View {
        ZStack {
            if self.canShowFrontView {
                front()
            }
            else {
                back()
                    .rotation3DEffect(Angle(degrees: 180), axis: (x: 0, y: 1, z: 0))
            }
        }
        .onChange(of: isFront, perform: {
            value in
            DispatchQueue.main.asyncAfter(deadline: .now() + duration/2.0) {
                self.canShowFrontView = value
            }
        })
        .animation(nil)
        .rotation3DEffect(isFront ? Angle(degrees: 0): Angle(degrees: 180), axis: (x: CGFloat(0), y: CGFloat(10), z: CGFloat(0)))
        .animation(.easeInOut(duration: duration))
    }
}

```

# さいごに
「めくる」って何か良い響きですよね
Docker(WSL2) + Rails6 + webpacker でめちゃくちゃハマった

Docker(WSL2)でRailsコンテナを作り、webpackerを導入しましたが、
更新されたjavascriptやcssを監視してwebpackのコンパイルをするwebpack-dev-serverが
どうもうまく動かず数時間悩んだので、自分が解決できた方法を記載します。

# 事前にしたこと
## docker-compose.yml

```yml
version: '3'
services:
  web: &web
    build:
      context: .
    environment:
      WEBPACKER_DEV_SERVER_HOST: webpacker
  webpacker:
    <<: *web
    environment:
      WEBPACKER_DEV_SERVER_HOST: "0.0.0.0"
    ports:
      - '3035:3035'

```

※端折って書いています、別途RailsコンテナのDockerfileが必要になります。

### webpackerコンパイル用のコンテナを作成
Railsコンテナを作成しますが、Railsコンテナをクローンするようなかたちでwebpackerコンパイル用コンテナも作成します。

以下のように

```yml
web: &web
```

コンテナに対してのエイリアスを設定し、

```yml
  webpacker:
    <<: *web
```

とすることでエイリアスに紐づくコンテナの設定を全て継承することができます。


### webpackerのコンテナでコンパイルをするための設定

Railsコンテナでwebpackerのコンパイルをするコンテナに接続するために以下の設定をします。

```yml
WEBPACKER_DEV_SERVER_HOST: webpacker
```

webpackerでコンパイルした結果をRailsコンテナに戻すために以下の設定をします。

```yml
WEBPACKER_DEV_SERVER_HOST: "0.0.0.0"
```

こちらのソースを確認すると環境変数WEBPACKER_DEV_SERVER_HOSTを使って接続先を制御しているのが分かります。

https://github.com/rails/webpacker/blob/HEAD/lib/webpacker/dev_server.rb

## config/webpacker.yml

dev_serverのhostをwebpackerとします。

```yml
development:
  <<: *default
  compile: true

  # Reference: https://webpack.js.org/configuration/dev-server/
  dev_server:
    https: false
    host: webpacker
```

#ここまでやった結果
webpack-dev-serverが起動時にコンパイルが動作するだけで、以降は全く動かん・・・。
ここから数時間ハマった・・・。

# そして解決方法
config/webpacker.yml の watch_options にpollの設定値を追加。

```yml
development:
  <<: *default
  compile: true
  dev_server:
    # ～省略～
    # https://webpack.js.org/configuration/watch/#watchoptions 
    watch_options:
      ignored: '**/node_modules/**'
      poll: 1000 # ファイル更新を何m秒間隔で監視するかの設定
```

私の場合は、前述に記載した通りrailsコンテナと全く同じコンテナをwebpakcerコンパイル用コンテナとしてビルドし、

```bash
./bin/webpack-dev-server
```

を実行して、ファイルの変更を監視するようにしていましたが、
どうやら前述のpollオプションが設定されていないとファイルの変更を検知しないようです。

[こちら](https://webpack.js.org/configuration/watch/#watchoptions)を見ると、webpackerのコンパイルが動作しないときはこの辺の値を調整してみてくれ！って書いています・・・。

# 参考にさせていただいた記事
https://webpack.js.org/configuration/watch/#watchoptions

https://github.com/rails/webpacker/blob/5-x-stable/docs/docker.md

https://qiita.com/MoguraStore/items/ca80c99c5542898ec3b5
MinecraftForgeでprivate変数を取得、変更する方法

Minecraftのmodを作っていたらMinecraft側のコードにあるprivate変数を取得したくなります。
そんな時にこの方法を使います。

# データの取得
## コード例

MinecraftデフォルトのクラスであるChatScreenのdefaultInputFieldTextを取得したい

``` java:ChatScreen.java
public class ChatScreen extends Screen {
     (省略)
     private String defaultInputFieldText = "";
     (省略)
}
```

そんなとき、ObfuscationReflectionHelper.getPrivateValueを使用します。
引数にはクラスオブジェクト、インスタンス、変数名をStringで指定します。

``` java:Example.java
String  str  = ObfuscationReflectionHelper.getPrivateValue(
             ChatScreen.class,
             chatScreen,
             "defaultInputFieldText");
```

## 使用時の注意点

しかし、このままのコードをビルドすると実際の環境で動かないという問題が発生します。
これは実際のコードは難読化されていて、開発環境の変数名と違うからです。
そのため、目的の変数が難読化された後の変数名を知る必要があります。

難読化後の変数名を知るためには[MCPbot](https://mcpbot.unascribed.com/)を利用します。

基本的には[安定版リスト](https://mcpbot.unascribed.com/mcp_stable/)から、欲しいバージョンがリストになければ[Snapshot](https://mcpbot.unascribed.com/mcp_snapshot/)からcsvファイルをダウンロードします。
zipを回答すると3つのcsvが入っています。変数はfields.csv、関数はmethods.csv、引数はparams.csvで、それらを開いて検索し、難読化後の名前を特定します。
難読化後の名前がわかればgetPrivateValueの引数を差し替えます。

``` java:Example.java
public class Example{
     public String GetDefaultInputFieldText(ChatScreen chatScreen){
            String  str  = ObfuscationReflectionHelper.getPrivateValue(
                        ChatScreen.class,
                        chatScreen,
                        "field_146409_v");
            return str;
     }
}
```

# データの変更

ObfuscationReflectionHelper.setPrivateValueを使用します。
上記と同じように変数名の取得をします。

```java:Example.java
ObfuscationReflectionHelper.setPrivateValue(ChatScreen.class,chatScreen,"テスト","field_146409_v");
```