OmniAICreator/Qiita-1.07M huggingface dataset:
PythonでBacklogAPIを使ってみた

# はじめに
最近、PythonでBacklogAPIを使用して簡単なアプリを作りました。
次にBacklog APIを使用するときや、他の人も使用できるようにメモ程度にまとめます。

# APIの使用方法
Backlog APIは2種類の認証と認可の方法が存在しています。
+ Backlogユーザ毎に発行されたAPIKeyを使用する方法
+ OAuth2.0を用いて取得したAPITokenを使用する方法

今回はAPIKeyを使用した方法を紹介します。

### API Key
APIKeyはユーザーの設定画面から取得することができます。
個人設定 -> API -> 登録
![Backlog_API.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603981/341d2c4d-0d1d-72ab-3686-98b7ae89c4bc.png)

登録ボタンを押下すると、APIキーを発行することができます。こちらのAPIKeyを使用して、BacklogAPIを利用することができます。

### スペース名
下の画像で囲まれているスペース名は後で使用するので控えておきます。
![Backlog_API2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603981/71ed19e2-4419-9a3b-3029-89c5b46cfba8.png)


# PythonでBacklogAPIを使用する
### 必要なライブラリ
基本的には、HTTPリクエストを送信してAPIを利用します。そのために必要な'requests'ライブラリを使用します。
```bash
pip install requests
```

## スクリプトの作成
まず、最初にあらかじめ用意したAPIKeyとスペース名を設定します。
```python
import requests

API_KEY = 'your_api_key_here'
SPACE_NAME = 'your_subdomain_here'
```

## 使用例1：課題一覧の取得
```python
def get_projects():
  payload = {
    'apiKey' : API_KEY
  }
  response = requests.get(f'https://{SPACE_NAME}.backlog.com/api/v2/issues', payload)
  if response.status_code == 200:
      return response.json()
  else:
      print(f'Error: {response.status_code}')
      return None

projects = get_projects()
if projects:
    for project in projects:
        print(f'ID: {project["id"]}, Name: {project["summary"]}')
```

## 使用例2：課題の作成
```python
def create_issue(project_id, summary, description, issue_type_id, priority_id):
  url = f'https://{SPACE_NAME}.backlog.com/api/v2/issues'
  payload = {
    'apikey' : API_KEY,
    'projectId': project_id,
    'summary': summary,
    'description': description,
    'issueTypeId': issue_type_id,
    'priorityId': priority_id
  }
  response = requests.post(url, json=payload)
  if response.status_code == 201:
    return response.json()
  else:
    print(f'Error: {response.status_code}')
    return None

# 課題の作成例
new_issue = create_issue(
  project_id='12345',
  summary='API経由での課題作成',
  description='これはAPI経由で作成された課題です。',
  issue_type_id='1',  # 課題タイプID（Backlogの設定で確認）
  priority_id='3'    # 優先度ID（Backlogの設定で確認）
)

if new_issue:
  print(f'Created issue: {new_issue["id"]}, {new_issue["summary"]}')
```

## 使用例3：課題の更新
```python
def update_issue(issue_id, updates):
  url = f'https://{SPACE_NAME}.backlog.com/api/v2/issues/{issue_id}?apiKey={API_KEY}'
  response = requests.patch(url, json=updates)
  if response.status_code == 200:
    return response.json()
  else:
    print(f'Error: {response.status_code}')
    return None

# 課題の更新例
updated_issue = update_issue(
  issue_id=74043178,
  updates={
    'summary': '更新された課題のタイトル',
    'description': 'この課題はAPIを使用して更新されました。'
  }
)

if updated_issue:
  print(f'Updated issue: {updated_issue["id"]}, {updated_issue["summary"]}')
```

# まとめ
Backlog APIを使用して、効率化しましょう。
GoogleのAPIの認証処理の用語が難しかった

# 記事投稿の経緯
業務内で、GoogleカレンダーAPIを使用した処理を実装した際に、OAuthによる認証で苦戦したので、OAuthについてまとめてみました。

# OAuthって何？
OAuthを使うと外部アプリケーションに対して、ユーザーに代わりWebサービスとやり取りする権限を付与してくれる機能です。


下記の記事がOAuthについて図解で説明されているためわかりやすいです。

https://qiita.com/TakahikoKawasaki/items/e37caf50776e00e733be

GoogleではAPIを使用する際の認証と認可にOAuth2.0プロトコルを使用しています。

# GoogleAPIを使用する方法
コンソール内で認証情報を作成する際、以下３種類の認証情報の作成方法がある。
### APIキーを使用する
他サービスでAPIを使用する際もこのAPIキーを発行して、やり取りを行います。
公開データへのアクセスをリクエストするために使用される一般的な方法です。

### OAuth2クライアントID
ユーザー所有データへのアクセスをリクエストするために使用される認証情報のこと。
Google Workspace APIを使用してデータへのアクセスをリクエストする際に使用されるメインの認証情報。ユーザーの同意が必要。

### サービスアカウント
サーバー間のやり取りに使用される認証情報。通常、クラウドベースのデータとオペレーションにアクセスするために使用される。ただし、ドメイン全体の権限の委任と併用すると、ユーザーデータにアクセスすることができる。

今回はGoogleカレンダー情報にアクセスして、予定を取得したり、予定の作成を行う必要があったため、`OAuth2クライアントID`を使用しました。
Redmineのバージョンをrequireせずに読み取る

とある処理を書いていて、Redmineのバージョンを知りたいな〜と思うタイミングがありました。

しかしRedmineの`version.rb`はsubversionの処理への依存関係を持っており、なんかrequireしたくないなーという感じでした。

https://github.com/redmine/redmine/blob/6a4abab8ce00b5b0cb6e0a161bfedf3366393308/lib/redmine/version.rb
```rb
require 'redmine/scm/adapters/subversion_adapter'
```

そこでパースして読み取ってみることにしました。

## Prism

まずはPrismを使ってみました。Ruby 3.3.0以上にはバンドルされていますが、それ以前のRubyでは自分でgem installする必要があります。

```rb
require 'prism'

class MyVisitor < Prism::Visitor
  def initialize
    @version_hash = {}
  end

  # node
  # @ ConstantWriteNode (location: (8,4)-(8,13))
  # ├── name: :MAJOR
  # ├── name_loc: (8,4)-(8,9) = "MAJOR"
  # ├── value:
  # │   @ IntegerNode (location: (8,12)-(8,13))
  # │   ├── flags: decimal
  # │   └── value: 5
  def visit_constant_write_node(node)
    super
    case node.name
    when :MAJOR then @version_hash[:major] = node.value.value
    when :MINOR then @version_hash[:minor] = node.value.value
    when :TINY then @version_hash[:tiny] = node.value.value
    end
  end

  def version
    "#{@version_hash[:major]}.#{@version_hash[:minor]}.#{@version_hash[:tiny]}"
  end
end

visitor = MyVisitor.new
Prism.parse_file('lib/redmine/version.rb').value.accept(visitor)
puts visitor.version
```

`Prism::Visitor`というクラスを継承して自分のVisitorを作ることで、自由に色々な処理を書けます。Prismのノードは色んな情報を持っているので、簡単にバージョンの情報を引っ張ってくることができました。

## Ripper

古いバージョンのRubyでも動くコードを書かなければいけない場合、Ripperが使えます。RipperにはコードをパースしてS式として返す使い方か、Prismのようにイベントベースの使い方の二通りあります。
最初はイベントベースでやってみたのですが、Prismのようにノードが豊富な情報を持っているわけではないので自前で情報を頑張って取る必要があり、非常に難儀したのでS式を使うやり方を試しました。

```rb
require 'ripper'
exp = Ripper.sexp(File.read("lib/redmine/version.rb"))

# expの中身は下記のようになっている
# このうち、`[:assign, [:var_field, [:@const, "MAJOR", [8, 4]]], [:@int, "5", [8, 12]]]`となっているあたりの情報が欲しい
#
# [:program,
#  [[:command,
#   [:@ident, "require", [3, 0]],
#   [...],
#  [:module,
#   [:const_ref, [:@const, "Redmine", [5, 7]]],
#   [:bodystmt,
#    [[:void_stmt],
#     [:module,
#      [:const_ref, [:@const, "VERSION", [7, 9]]],
#      [:bodystmt,
#       [[:void_stmt],
#        [:assign, [:var_field, [:@const, "MAJOR", [8, 4]]], [:@int, "5", [8, 12]]],
#        [:assign, [:var_field, [:@const, "MINOR", [9, 4]]], [:@int, "1", [9, 12]]],
#        [:assign, [:var_field, [:@const, "TINY", [10, 4]]], [:@int, "2", [10, 12]]],
#        [...],
#        [:defs,
#         [:var_ref, [:@kw, "self", [19, 8]]],

def sexp_walk(exp, &block)
  return unless exp

  if exp.is_a?(Array) && exp[0] == :assign
    yield(exp)
  else
    exp.each do |child_exp|
      if child_exp.is_a?(Array)
        sexp_walk(child_exp, &block)
      end
    end
  end
end

version = {}
sexp_walk(exp) do |exp|
  next unless exp[1][1][0] == :@const
  next unless exp[2][0] == :@int

  const_name = exp[1][1][1]
  const_value = exp[2][1]
  version[const_name] = const_value
end

"#{version['MAJOR']}.#{version['MINOR']}.#{version['TINY']}"
```

うーん、読み辛い…w イベントベースで書きたくなりますね。しかしS式にしてくれるので、今回のようなバージョンの数字を取りだしたいだけならこれで十分な気もします。
[open-jdk 22 + Gradle 8.7] エラー　"BUG! exception in phase 'semantic analysis' in source unit '_BuildScript_' Unsupported class file major version 66"

## 環境
- Windows10 
- open-jdk 22.0.1
- open-jdk 21
- Gradle 8.7

### エラー発生
まず、open-jdk 22.0.1　と　Gradle 8.7という組み合わせで、
`gradle clean build` を叩いた際に、下記のエラーが発生しました。

```
FAILURE: Build failed with an exception.

* What went wrong:
BUG! exception in phase 'semantic analysis' in source unit 
'_BuildScript_' Unsupported class file major version 66
```

### エラーについての情報

このエラーについては、下記のISSUEが立っていました。
下記ISSUEはJavaではなくReactに対してのISSUEですが、
Gradle 8.7を動かすのにJava22ではエラーになるとのことです。

`Java21に落とせば、エラーが出なくなる`
とのことで、実際にjdk21に切り替えたら正常にビルドされました。

#### Unsupported class file major version 66 error. #2348
https://github.com/react-native-community/cli/issues/2348


#### Compatibility Matrix (Gradle+JDKとのバージョンの対応一覧)

確かにJava22では「Support for running Gradle」が「N/A」になっていますね。


https://docs.gradle.org/current/userguide/compatibility.html

-----以上
【DeviseTokenAuth】メールアドレス変更時に古いメールアドレスに変更通知メールを送信する方法

## 設定を記述

設定を記述する。

```rb:config/initializers/devise.rb
Devise.setup do |config|
  # ...
  config.send_email_changed_notification = true
end

```

## メール内容の変更

メール内容を変更する。

```erb:app/views/devise/mailer/email_changed.html.erb
<p><%= t(:hello).capitalize + '、' + @resource.name %>さん。</p>

<% if @resource.try(:unconfirmed_email?) %>
  <p>
    メールアドレスの変更がリクエストされました。<br />
    <%= @resource.unconfirmed_email %>にメールアドレス確認用のメールを送信しています。<br />
    内容を確認し、メールアドレスを認証してください。
  </p>
<% else %>
  <p>メールアドレスが<%= @resource.email %>に変更されました。</p>
<% end %>

```

## 参考ページ

https://github.com/heartcombo/devise/blob/a259ff3c28912a27329727f4a3c2623d3f5cb6f2/lib/generators/templates/devise.rb#L131C2-L132C51

https://github.com/heartcombo/devise/blob/a259ff3c28912a27329727f4a3c2623d3f5cb6f2/app/views/devise/mailer/email_changed.html.erb#L4
rbenv versionで指定Versionが変更しても、ruby -vでVersionが変更されていない

# サマリ
Ubuntu22.04LTS にはRubyがプリインストールされていますが、後からインストールしたbenvとrubyとのバージョンに齟齬が発生しました。
どうやらMacOSとかでもこういう現象がままあるようです。
```
 ~$ rbenv local 3.2.3
 ~$ ruby -v
 ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-linux-gnu]
```

# 環境
WSL2(windows11)
Ubuntu22.04LTS

# 原因
ちゃんとrbenvのREADMEに書いてありました。穴があったら入りたい。

https://github.com/rbenv/rbenv?tab=readme-ov-file#installation

要はrbenvが環境変数を利用するために必要な設定が抜けてました。
rbenvが管理するRubyのバージョンを適切に切り替えるためのコマンドを通すためのパスが通ってなかったことになります。

# 対策
rbenvが参照にしているユーザー設定ファイルを確認します。
```
 $ rbenv init
 # Please add the following line to your `~/.bashrc' file,
 # then restart your terminal.
 
 eval "$(rbenv init - bash)"
```
というわけで`~/.bashrc`の末尾に`eval "$(rbenv init - bash)`と追記しましょう。
なお`eval "$(rbenv init - bash)`はシェルに拡張コマンドを追加する機能です。

``` 
$ sudo vim ~/.bashrc
 ※末尾
 eval "$(rbenv init -bash)"
```

設定ファイルを再読込します。
```
$ source ~/.bashrc
```

確認してみましょう。
```
$ ruby -v
 ruby 3.2.3 (2024-01-18 revision 52bb2ac0a6) [x86_64-linux]
```
できましたー。<br>
ちゃんと公式ドキュメントを読めという話でした。
Word2013以降 日付の一部を抜いたり、日付の一部だけ全角にする場合のフィールドコード

日付けを令和６年５月１５日のようなすべて全角にする場合次のようにする。

```vb
MERGEFIELD  2024/6/15 \@"ggge年M月dd日" \* DBCHAR
```
DBCharが全角
gggeeが令和2桁年
Mが月、dが日である。

# 日付が確定しない場合
　文書を作成してるときは必ずしも日付が確定しない状態でも、先にレイアウトだけは揃えるケースは往々にして存在する。
 そうした場合は日付は入らないので後から入れたい。
　そうした日付だけ抜いた場合はどうすればいいのか？

# 答え、フィールドコードの日付の部分にスペースを入れる
この場合のスペースは<font color = "Deep Red">DBCharのため半角と全角のどちらでもよいでもよい</font>

# このスキルのめちゃくちゃな点
こうすると、日付を入れるために残した空白になんと日付をそのまま入力することができる。
つまりわざわざフィールドコードを再度開いて編集するなどという必要はない。
どうでもいいがこの場合のDBCharはDouble-Byte 文字という意味で全角で文字が太いからデブチャーなどと覚えてはいけない。
[NUMPAGES・PAGEを全角で表示する－\*DBCHARスイッチ:Word(ワード)の使い方/フィールドコード](https://www.relief.jp/docs/018413.html)

# 古のフィールドコードの均等割り付けは日付は入力できない
[Word2010：均等割り付けをフィールドで行う（EQフィールド） - 教えて！HELPDESK](https://office-qa.com/Word/wd790.htm)
この古い方法がこちら。全角スペースは10個入っている
```vb
{ eq \o \ad({MERGEFIELD  2024/6/15 \@"ggge年M月dd日" \* DBCHAR},         )}
```
この方法はノンブレークスペースが入り、改行しないスペースになるようだ。ちょっと見た目もおかしい。また日付も入らない。
# 普通の均等割り付けは入力した日付は均等割り付けにならない
なので、<b><font color = "RED">フィールドコードではなく、普通の均等割り付けを使用する</font></b>
いわゆるこういうの。
[Wordで文字を均等割り付けする方法 | できるネット](https://dekiru.net/article/5751/)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/f2aca268-eee5-89fd-9ec3-f696b4ec2f07.png)

# 均等割り付けまでやる場合は、日付を表示してからスペースに置換する
均等割り付けの幅まで正確にしたい場合は次のようにする
まず普通にフィールドコードを挿入する
```vb
MERGEFIELD  2024/6/15 \@"ggge年M月dd日" \* DBCHAR
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/6bd05a17-5d3a-9f84-9a16-c79c5a4e4287.png)

次にこの日付を全角スペースに変換する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/ba2a8abb-6af4-2cae-98a3-c9489166f721.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/158dbff3-34e0-28d3-17c9-efad41e30d7b.png)
フォントや字間の設定等にもよると思うが、画像で見る限り同じ幅になる。

#  F9を押すと日付が復活する
このフィールドコードは本来正しい日付を表示するようになっており、F9で日付を更新するとまた日付が復活する
。このため、更新しないように注意する必要がある。

# まとめと応用
均等割り付け等に若干不満があるが、日付の一部を抜くフィールドコードが見つかったのは便利だ。
均等割り付けの時は正しい日付をいれて上から書き換える方が取り上げるが
特に一桁の月日は全角で、２桁は半角というルールをとる場合があるという。
このような場合は\*SBCharスィッチで半角に定義し、１桁の日付だけ全角入力する方法も考えられる。
更新されると値が消えるため。あくまでも編集を効率的に行うための一時的なスキルである。
[プログラミング初心者でもOK]UEFN Verseオリジナルの仕掛けの作り方

## はじめに
UEFNでオリジナルの仕掛けを作る方法をプログラミング初心者でもわかるようにシンプルに書きます。
UEFN、Verseで何かしようとするとドキュメントが少なく苦労するので、私が理解したことを皆さんにも情報共有できればと思います。
（なかなか時間が取れないので、ひとまず短い記事をいくつか出したいです・・・。）
## 1.UEFNでVerseのファイルを追加
### 1)「VerseExploler」タブの、プロジェクト名のところで右クリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630930/90e42c57-8535-4f51-398f-70195b37976d.png)
### 2)Verseスクリプトを作成
①右下の「Device Name」を好きな名前に変更
②左側のテンプレート選択で「Verse Device」を選択
③右下の「作成」ボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630930/8bec55a6-8f79-3396-234b-cab7621fad01.png)
## 2.作成されたVerseのファイルの中身を見てみよう
### ①「using {XXX}」は、XXXという既存の機能を使いますよ、という宣言
### ②「[クラス名] := class(creative_device):」は、オリジナルのクリエイティブの仕掛けを定義するクラス
### ③OnBegin<override>()\<suspends>:void=は、ゲームがスタートしたときに実行される処理を定義できる関数
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630930/182ff338-a957-5b78-dc48-48ef43c967bf.png)

## 3.仕掛けを自分の島に置く
### 1)コンテンツブラウザを開いて、ALLの下にある「[プロジェクト名]コンテンツ」というフォルダを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630930/356f1bcf-dd93-1d32-1a51-89ec383be30a.png)
### 2)先ほど作ったVerseのファイルと同じ名前のデバイスをビューポートにドラッグアンドドロップ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630930/a26644d2-9e33-c78c-c1e2-6256ab9249fd.png)
## 4.ゲームを起動して動作していることを確認
### 1)「セッションを開始」をクリックしてゲームを起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630930/4fdb850e-db6e-5502-a2ce-e3e64281925f.png)
### 2)ログを確認
FORTNITE側でマップを開くと、ログというタブがあるので以下の表示が出ていたらOKです！
Hello, world!
2 + 2 = 4

## 5.さいごに
ここまで読んでくださりありがとうございます。
私も勉強中の身ではありますが、有益な情報を皆さんと共有したいと思いますので、もしよかったらご質問、ご指摘などいただけたら幸いです。
AIはベーシックインカムというインフラ整備を加速させ、より良い未来を作ってくれるというお話し

## AIとベーシックインカムの融合：未来社会の実現に向けて

AIの進化とともに、私たちの生活は劇的に変化していますが、その一方で一部の仕事が失われることも認めざるを得えない現状にあります。自動化によって仕事を失った人々のためには、セーフティネットが必要不可欠であり、その一例として今再びベーシックインカムというワードが話題になってきています。

## ベーシックインカムの重要性

ベーシックインカムは、全ての市民に無条件で一定の収入を提供する制度で、これにより自動化の影響を受けた人々が最低限の生活を保障されます。多くの人達は、「たったそれだけでしょ！」と思ってしまいますが、この制度の利点は、それだけに留まりません。ベーシックインカムは、個人に新しいスキルを学ぶための時間と機会を提供し、さらなる経済的自立をサポートします。フィンランドでの実験（Kangas et al., 2020）によると、ベーシックインカムが受給者の幸福感を34%向上させ、精神的なストレスを17%減少させたことが報告されています。また、受給者の45%が新しい職業訓練や教育プログラムに参加したことが示されており、これらの数値は、ベーシックインカムが個人と社会全体の福祉を向上させる可能性を強調しています。

## AIとベーシックインカムの相乗効果

AIとベーシックインカムの融合は、未来社会における重要な要素となり得ます。それはAIの導入により一部の職業が自動化される一方で、新しい職業や産業が生まれる可能性があります。しかし、昨今の円安続きとこの移行期において失業の不安や経済的不安が広がることは避けられません。ベーシックインカムは、この不安を和らげる強力な手段となります。

例えば、AIが小売業や製造業において多くの業務を自動化し、人々がこれまでの仕事を失った場合、ベーシックインカムがあることで、失業者は生活の基本的なニーズを満たすことができ、次のステップに進むための余裕を持つことができます。彼らは新しいスキルを学び、新しい職業に挑戦することができるでしょう。さらに、ベーシックインカムは起業やクリエイティブな活動の促進にもつながります。経済的な安定があることで、多くの人がリスクを取って新しいビジネスやプロジェクトに挑戦することが可能になります。このことは、2020年の世界経済フォーラム（WEF）のレポートにもあるように、AIと自動化が2025年までに8500万人の仕事を置き換える一方で、9700万人の新しい仕事を創出する可能性があるとされています（WEF, 2020）。これにより、AIは単に労働力を削減するだけでなく、新たな経済機会を提供する力を持っていることが示されています。

さらに、カナダのオンタリオ州で行われたベーシックインカムの試験プログラム（Forget, 2011）では、受給者の健康状態が25%改善し、高校卒業率が20%向上したことが報告されています。これらの結果は、ベーシックインカムが社会全体に与える積極的な影響を裏付けています。

## 持続可能な未来への道

AIとベーシックインカムが融合する時代は、単なるテクノロジーの進化に留まりません。それは人間中心の社会構築を意味します。AIが自動化の効率を高め、人々がルーチンワークから解放される一方で、ベーシックインカムはその過渡期における社会的安定を提供します。この相互作用により、社会はより革新的で創造的な方向へと進化することができます。

## 結論

AIとベーシックインカムの融合は、持続可能な未来社会を実現するための鍵となります。テクノロジーの進化に対応するためには、柔軟かつ包括的な経済政策が必要です。ベーシックインカムはその一環として、全ての人々が新しい時代の恩恵を享受し、自らの能力を最大限に発揮できる社会を目指すための基盤となるでしょう。

このように、AIとベーシックインカムが融合する時代は、私たちの生活をより豊かにし、経済的な安定と革新を同時に実現する可能性を秘めています。未来の社会を築くために、これらの制度を積極的に取り入れ、共に進化していくことが求められます。
2023年秋　ITWeekレポート　スーパーアプリ

2023年秋に
ITWeek参加してきました。

スーパーアプリの話題がありましたので、話題として紹介します。

スーパーアプリとは？1つのスマートフォンアプリの中に、複数のミニアプリが多数存在するアプリを定義している様です。
メジャーなものであれば、LINEですね。

各アプリの概要は以下です。
■Alipay（アリペイ）
中国を拠点とする大手IT企業のアリババグループが提供する、中国の通貨「人民元」で支払いを行うQRコード決済サービスです。
タクシーの呼び出しや飛行機の予約、医療・保険関連といった様々なミニアプリ（ミニプログラム）が統合されています。
このセミナーでは、アント・フォレストについて紹介されていました。

■佐賀市スーパーアプリ
佐賀市の防災案内や図書の貸し出し予約、電子申請、ごみカレンダー等
市政に関わる内容の情報の連絡ができるアプリ。
市や区の電子化のフォーマットとして実施するのは有りかも。

「佐賀市公式スーパーアプリ」
https://prtimes.jp/story/detail/DbDkKlU5ylr

■ＪＲ東日本アプリ
乗り換え検索や混雑状況の状態確認など
他社の垣根を越えて、データの連携などを裏で行っているようです。
初めに作った際は、評判は最悪だったようです。

「JR東日本アプリ」
https://www.jreast-app.jp/


★スーパーアプリのメリット
・ユーザーを獲得しやすく、利用定着につながる
・アプリが削除されにくい
・様々なサービス展開ができる
・同一アカウントで複数のミニアプリを利用できる

★スーパーアプリのデメリット
・セキュリティ面で穴があると、すべて利用されてしまい、情報漏洩リスクが高い。
・ミニアプリのインターフェイスがスーパーアプリのベースに制限されてしまう。
・参入障壁が高い

★スーパーアプリの今後について
・今後はやるのか？
　すでにあるアプリ（ユーザ確保済み）については、そのままでいいのかもしれません。
　ですが、新規でスーパーアプリをこれから作ろうという会社にとっては
　障壁が高いものと思われます。
OpenCvを.NETで使う_OpenCvSharp4

OpenCVが.NETで使えるライブラリを試してみました。
読込んだ画像に輪郭を描画します！


# 準備
vscodeでやっています。
- dotnet new winforms -n OpenCv_winforms
- cd OpenCv_winforms

# 必要なパッケージ
OpenCvSharp4
（Apache License 2.0）
https://github.com/shimat/opencvsharp

- dotnet add package OpenCvSharp4.Windows
  - WindowsというのがAllInOneとなってるのでそれだけでいいのかなと思ったけど、Extensionsを入れないとダメなのもあるようです
- dotnet add package OpenCvSharp4.Extensions

# コード
## 画像の処理
適当な画像を保存して、それに輪郭を描画する。
```C#
public static void GetImage()
    {
        // 画像の読込み
        using var srcMat = new Mat(@"image\10.jpg", ImreadModes.Color);
        // 画像サイズの調整
        Cv2.Resize(srcMat, srcMat, new OpenCvSharp.Size(), 0.1, 0.1, InterpolationFlags.Area);
        // グレースケール
        var grayMat = srcMat.CvtColor(ColorConversionCodes.BGR2GRAY);
        // 大津の二値化
        var thresholdMat = grayMat.Threshold(0, 255, ThresholdTypes.Otsu);
        //平準化(中央値フィルタ)
        var mediaBlur = new Mat();
        Cv2.MedianBlur(thresholdMat, mediaBlur, 3);
        //ジャグ配列
        OpenCvSharp.Point[][] contours;
        OpenCvSharp.HierarchyIndex[] hierarchyIndexes;
        // 輪郭の取得
        // Externalは外側のみの輪郭　Listはすべて
        Cv2.FindContours(thresholdMat, out contours, out hierarchyIndexes, RetrievalModes.List, ContourApproximationModes.ApproxSimple);

        // 輪郭の描画
        Cv2.DrawContours(srcMat, contours, -1, new Scalar(0, 255, 0));
        // 画像の表示
        Cv2.ImShow("src", srcMat);
        // 画像の保存
        Cv2.ImWrite("image/src.png", srcMat);
    }
```

![src.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2383487/00854263-608b-a522-eab0-fdbeca4d66b1.png)

お～すごい！
今度はガタガタなのをキレイにするのもやってみたいですね。

## ボタン
ボタンクリックで画像の処理を実行するようにする。
```Form1.cs
    void Button_Click(object sender, EventArgs e)
    {
        OpenCvMain.GetImage();
    }
```

```Form1.Designer.cs
private Button button1;
    private void InitializeComponent()
    {
        this.button1 = new Button();

        button1.Text = "クリック";
        button1.Location = new Point(10, 10);
        button1.Size = new Size(100, 100);
        button1.Click += new EventHandler(Button_Click);
        this.Controls.Add(button1);

        this.components = new System.ComponentModel.Container();
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(800, 450);
        this.Text = "Form1";
    }
```

# 参考
- https://github.com/shimat/opencvsharp
- https://aoblog-miz.com/copencvsharp-noise/
- https://water2litter.net/rye/post/c_opencvsharp_findcontours/
Oracle Analytics Cloud：DBテーブルからデータセットを作成するときに一括でメジャー／属性を変更する

はじめに
---
OACでは、DBテーブルからデータセットを作成します。データセットを作成するときに一括でメジャー／属性を変更してみます
DB表をもとにデータセットを作成する際にDB表の列で、NUMBER型のデータ型の場合は"メジャー項目"、テキスト型の場合は"属性項目"にセットされます
表に項目が多い場合に、一つづつ変更すると手間がかかるので一括で変更してみます
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/9adeb6c9-192e-f75f-8f39-5045b969b497.jpeg)

記載時のOACバージョン：OAC 2024 March版

前提
---
Autonomous DatabaseのSHスキーマを元に日本語化したSHJPを利用します
Autonomous Databaseへの"接続"を作成しています

データセットの作成
---
OACにデータセットの作成権限を持つユーザーでサインインします
左上部、メニューアイコンをクリックします。データをクリックします
![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/93412f1e-2d5e-7b55-e746-6ae394d0237a.jpeg)

上部の"接続"タブをクリックします
作成されている"接続"が表示されます
作成されている"接続"の右下部にマウスカーソルを移動すると"・・・(縦)"アイコンが表示されますのでクリックします。"データセットの作成"をクリックします
![3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/bf7cf2f1-3a0f-46b6-1e06-a9042c51e38f.jpeg)

DBテーブルをドラッグし、右部にドロップします
SHJPスキーマからPRODUCTSテーブルを右部にドロップします
![4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/46422b61-9178-586e-ad2f-760d524a3bb7.jpeg)

各列名の左部に"A"(属性列)アイコンや"#"(メジャー列)アイコンをクリックすると、メジャー／属性を変更できます
![5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/bd768d51-245b-b758-97e7-47516a26a37b.jpeg)


変更する列が多いときに一括するには、下部の表をクリックします
"PRODUCTS"をクリックします
![6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/02f0a2ec-55b6-2075-7d44-3364084df15c.jpeg)

上部の"メタデータ"アイコンをクリックします
![7.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/1ec9f5b6-9f43-8186-2065-e64a2dde8073.jpeg)

対象の列を選択します。Ctrlキーを押下しながらクリックすると複数選択できます
![8.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/23ee2d9f-8d1b-7a1b-e49d-1571743649e2.jpeg)

最初に選択した項目に"▼"が表示されており、"▼"をクリックします。メジャー／属性を変更します。"属性"をクリックします。
![9.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/d3c32130-1f35-e40a-8603-7353ea84a6e3.jpeg)

一括で変更できました
保存をクリックし、データセットに名前をつけて保存します
![10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/5a6bed5d-eec9-165c-a1d1-df2dae281a7a.jpeg)

まとめ
---
DataVisualizationでは列のメジャー／属性をもとにグラフへの配置箇所などが決まります
DBテーブルの列数が多い場合にNUMBER型だとメジャーがデフォルトでセットされるため、一括で変更する手順を知っておくと便利です

以上
秀丸の正規表現置換

#　C++文字列に含まれる半角括弧を全角括弧に置き換える
```C++
void main()
{
    // コメント（あいうえお）abcdef : 全角括弧
    // コメント (あいうえお) abcdef : 半角括弧
    // コメント（あいうえお）abcdef : 全角括弧
    // コメント (あいうえお) abcdef : 半角括弧
    // コメント（あいうえお）abcdef : 全角括弧
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3527548/5df0719a-bf4d-ce51-1b19-ca87bc377dca.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3527548/eb6314fd-e514-11e9-b4bc-1b37d844935b.png)


```C++
void main()
{
    // コメント(あいうえお)abcdef : 全角括弧 -> 半角括弧
    // コメント (あいうえお) abcdef : 半角括弧
    // コメント(あいうえお)abcdef : 全角括弧 -> 半角括弧
    // コメント (あいうえお) abcdef : 半角括弧
    // コメント(あいうえお)abcdef : 全角括弧 -> 半角括弧
}
```
今日から続けられる人になろう！！

多くの人は、ダイエット、資格勉強、趣味など、始めたことをすぐに諦めてしまう傾向があります。そして、それに陥ってしまった人達は「自分は続けられない」というネガティブな意識を持ってしまいがちです。

では、このネガティブな意識を取り除くための方法をいくつか紹介します。

## ネガティブな意識を取り除くための2つの方法

#### 正しい努力をやめる

人は、物事を始める時、最初から効率的に、正しくしようとします。しかし、そうすると、何かを続けることが修行のように感じられ、億劫になってしまいます。それを防ぐためには、目標を下げてでも、とにかく続けることに集中することが重要です。改善は後からでも十分に考えることができます。カーネギーメロン大学の2010年の研究によると、短期間の目標を設定した人々の方が長期間の目標を設定した人々よりも継続率が高いことが示されています。具体的には、短期目標グループの継続率は80%であったのに対し、長期目標グループは60%でした。この20%の差は小さいと思う人もいるかもしれませんが、その差に気づかないままでネガティブな感情を自ら背負い込んでいる人も多いのです。

#### 最初から効率を求めない

物事を続けるためには、自分なりのやり方を見つけることが重要です。最も簡単で効率的な方法を見つけようとこだわらないでください。これほど強く言う理由は、スタンフォード大学の2012年の研究で、自己流のアプローチを取り入れた人々の方が新しいスキルの習得においてモチベーションを維持しやすいことが明らかになっているからです。また、自己流のアプローチを取ったグループのモチベーション維持率は75%であるのに対し、標準的なアプローチを取ったグループは55%でした。

## 今日から実践できる2つの習慣

#### 曜日ごとにやることを決める

曜日ごとにやることを決めておくことで、体がルーティンに慣れ、続けやすくなります。ハーバード大学の2014年の研究によると、ルーティン化した行動が習慣化されることで、継続率が高まったという結果が示されています。具体的にはルーティン化した行動の継続率は90%であるのに対し、ルーティン化されていない行動の継続率は50%だったそうです。

#### 毎日仕事をする

1日1時間でもいいので、毎日仕事をすることで、「仕事をしたくない」という気持ちがなくなりやすくなります。えっ、嘘でしょと思ったかもしれませんが、オックスフォード大学の2016年の研究によると、毎日少しずつでも取り組むことが、長期的な目標達成に効果的であることが確認されています。具体的には毎日1時間の取り組みを続けたグループの成功率は85%であったのに対し、週に1度の取り組みをしたグループの成功率は45%だったそうです。「継続は力なり💪！」という言葉もあるように、やはり継続することはとても意義があります。

## それでも難しいなら・・・
それでも続けられない場合はこの魔法の言葉を思い出してください。それは「休みたいなら明日だけ休む、でも今日はやる」という言葉です。この言葉を使うことで、自分をだまして、毎日少しずつでも続けることができます。このテクニックは、プロクラスティネーション（先延ばし）の心理学的対策として知られており、一度始めることで「イニシャル・フリクション」を克服しやすくなります。

## まとめ

以上の方法を実践することで、続けられないというネガティブな意識を取り除き、目標達成に向けた持続的な努力が可能になります。大切なのは、自分に合ったやり方を見つけ、無理なく続けることです。毎日の小さな積み重ねが大きな成果を生むことを忘れずに、今日から少しずつ取り組んでみましょう。
Amazon ElastiCache

# 1.ElastiCacheとは
ElastiCacheは[Memcached](https://memcached.org/)と[Redis](https://redis.io/)(レディス)の2種類のエンジンをサポートしている<font color="red">**ステートフルな**</font>インメモリデータベースサービス。そのため、node.jsのアプリケーションを実行することはできません。

## 1.1.インメモリ

インメモリキャッシュは高速で低レイテンシが求められるアプリケーションに適しており、非インメモリキャッシュは大容量データを長期間保持する必要がある場合に適しています。

## 1.2.ステートフルとステートレス

ステートフルシステムは、各リクエスト間の状態を保持し、ユーザーの連続した操作を追跡するのに適しています。一方、ステートレスシステムは、各リクエストが独立しており、スケーラビリティとリソース効率の点で優れています。

セッション情報をEC2などのサーバーに保管するとステートフルになってしまいスケーラビリティがなくなるため、これを回避する方法として、ElastiCache（もしくはDynamoDB)にセッション情報を保管するシナリオもあります。

# 2.Memcached
Memcachedとは、キーと値のための高速なメモリのキャッシュサーバーです。

Pythonでも簡単にimportできます。

```python:
!pip install python-memcached
import memcached
```

Memcachedは<font color="red">**マルチAZに対応していません。**</font>

# 3.Redis

Memcachedとは異なり、Redisは次のことを実行できます。

- ディスクにデータを保存できるので信頼性が高く、再起動できる
- 古いデータを消さずに残しておける
- 単純な文字列以外のデータ構造もある

# 3.1.Amazon ElastiCache for Redis
Amazon ElastiCache for Redis は、ミリ秒未満のレイテンシーを実現する非常に高速なインメモリデータストアで、インターネット規模のリアルタイムアプリケーションを強化できます。（ネットゲームのランキングのリアルタイム更新など)

セッションをクライアントが接続しているEC2インスタンスだけで管理している場合、サーバーがダウン時すると継続して処理を行うことが出来なくなってしまいます。しかしながら、Amazon ElastiCache For Redisでセッション管理しておくと継続して処理が行えるようになります。

 データの永続性を提供するため、ディスク上にデータを保存できます。また、データ構造を操作できるため、より複雑なデータ処理が可能です。
 
 Pub/Subをサポートしています。

予算のことを特に心配しなくてよい時はこれを使います。



## 3.2.Redisに関するQiitaの記事

以下の記事が凄く参考になりました。

- [初心者による初心者のためのRedis解説](https://qiita.com/keinko/items/60c844bcf329bd3f4af8)

Pythonでも簡単にimportできます。

```python:
!pip install redis
import redis
conn = redis.Redis()
```
MacBook の 3.5mmヘッドフォンジャックにマイクをつなぎつつ別のマイクを同時に使うための物理的な接続

## はじめに

↓こういうことをやりたくて、実践した内容です。

https://x.com/youtoy/status/1793781419791258061

複数のマイク（今回は 2つのマイク）を同時に使う、という内容です。

### 【余談】 PC・ブラウザ側の実装用の準備
また、PC・ブラウザ側の実装を進めていく上では、以下の記事に書いた内容を試していたりもします。

- [PC で利用できるマイクなどのオーディオ入力のリストを p5.js Web Editor上で見てみる（ブラウザの MediaDevices） - Qiita](https://qiita.com/youtoy/items/8339313b561c503ffe39)
- [PC で利用できるマイクなどのオーディオ入力のリストで特定の名前のもののみ取得（p5.js Web Editor上で試す） - Qiita](https://qiita.com/youtoy/items/1d6dd1abae4eb70b7a4b)

## 2つのマイクを同時に使うための準備
複数のマイク（今回は 2つのマイク）を同時に使う方法を、Web検索で調べてみました。

その中での前提条件や、今回使った方法を以下で書いていきます。

###  3.5mmヘッドフォンジャックにつなぐ
まず前提として、2つのうちの 1つは MacBook に標準搭載されている 3.5mmヘッドフォンジャックにつなぐことにします。

これに関して、自分の MacBook のコネクタはヘッドフォン用になっているので、マイクを直接接続するというわけにはいきません。ちょうど、自宅に 4極 ミニプラグを「マイク ＋ イヤホン」に分岐するものがあったので、それを使って接続しました（※ 記事のうしろのほうに写真も掲載します）。

### USB接続のアダプタを使う
あとは、それと別系等で認識されるマイクを用意する形です。

手っ取り早く、シンプルな方法の 1つは「USBオーディオ変換アダプタ φ3.5mm（USB と ステレオミニジャックのアダプタ）」とマイクの組み合わせです。

https://x.com/youtoy/status/1793254093907280355

USB接続のマイクを使う、という方法でも良さそうでしたが、マイク部分を取り替えて使える構成にしたかったがあり、この方法にしました。

## 物理的な接続
上記を全てつないだ全体の様子を写真で示します。

![マイク445386571_1126974485022153_4709880694341478419_n.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/38a2e224-6978-249a-32ef-405c7a3811d7.jpeg)

矢印などでポイントになる部分を示すと、以下のような感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/2a1acdbd-64d0-3229-abdb-eef8ce5dc9b7.png)

なお、今回使った USB接続のアダプタは MacBook に直接ささらないため、このとき近くにあったハブを介して接続しました（Type-C と Type-A の変換）。

もちろんハブではなく、もっとシンプルな変換アダプタでも大丈夫です。

## 【余談】 Scratch でやってみた（押し込みの強弱を区別できるようにしつつ）
その後、マイク 1つを使う構成と Scratch を組み合わせてみました。
冒頭に掲載した例と少し違う要素を入れてみたくて、押し込みの強弱を区別できるようにする、というのを試してみました。

https://x.com/youtoy/status/1794364623422190040
[過去記事]アンテクに入ってからの自分をふりかえる

## 転職活動〜入社（2020年03月09日）

簡単にアンテクとの出会いや、当時の技術力なんかをまとめてみたいと思います！

2019年頃からプログラマとして働くべく準備を進めていました！未経験ということもありかなり苦戦、、前職を続けながらの技術キャッチアップは本当に苦労した覚えがあります。。！

転職については下記で詳しく語っているので良ければこちらも、、！

https://miriwo.hatenablog.com/entry/2020/03/09/110917

技術力としては、ほぼ皆無、、実践レベルには一切到達していませんでした。かろうじてサーバサイドフレームワーク（Ruby on Rails や laravel）でCRUDの機能を作れるレベルでした。DBもちゃんと設計できない。認証？！どうやって実装するの！？そもそもデプロイって何！？AWS怖い！Qiitaの記事みながら見様見真似でherokuでデプロイしたのはいい思い出です。。！

そんな状態だったので転職活動は当然難航、、未経験なので簡単ではないことは分かっていましたが結構絶望していました。。！

この時の状況をまとめるとこんな感じ↓

| 項目 | 状況 | 今の自分からのつっこみ |
| --- | --- | --- |
| 心持ち | 「なんで書いてあるとおりにやってもエラーが出るんや、、！どうしたらいいんや、！」 | そりゃそうだろ。根本を理解しろ |
| サーバサイド | チュートリアル通りにやればなんとかCRUDが作れる、、！ <br>WebサーバーとDBの関係が分かっている | 最初は真似っこから始まるからひとまずOK<br>でもエラー出たらエラーを読もうな |
| 開発環境 | Dockerとかまじでわからん。ひとまずMacに直接環境構築、、 | まあ最初はこれでいいかも |
| その他ツールなど | コマンドラインでの操作 → 前職で経験あったからなんとか、、！<br>Gitの操作・概念 → 前職で経験あったからなんとか、、！ | ほんとここだけ救われた。コマンドラインに抵抗がないのは良かった。 |

## 入社1年目（2020年03月09日〜2021年03月）

先輩エンジニアさんに教わりながらDBの設計思想やその他基礎的な考え方を学びました、、！試用期間中ということもあり、出された課題がうまくこなせない → 試用期間後に正社員になれないんじゃないかっていう焦り、、、思い出しました。。！ｗ

特にDBの正規化とかの部分苦労した覚えがあります。「正規化しなくてもデータ入っていればいいじゃん、、！データがないレコードのカラムはnullでいいじゃん、、！」とか思ってました。（なるべくnullableは避けましょうねの原則知らなかった。。）

実際の案件に近いコードを読むことをしていました。お勉強のコードと商用コードの違いを感じ卒倒思想になりました。

そして2021年の秋ごろ初めて案件でのお仕事がスタートしました。

最初は先輩と一緒に一つのチケットの内容を実施し、できたタイミングで先輩と答え合わせをするようなやり方を取っていました！徐々にめっちゃ簡単なチケットなら先輩と答えが合うようになってきました。

その後訳合ってその案件の先輩エンジニア2名が抜けてしまい、ほぼ自分ひとりみたいな状態になりましたｗ更に、自分がその案件のリーダーを任せていただき焦り散らかしました。

ただ、クライアントさんと近いところで仕事をすることで、誠実であることの大切さを学びました。

この時の状況をまとめるとこんな感じ↓

| 項目 | 状況 | 今の自分からのつっこみ |
| --- | --- | --- |
| 心持ち | やばい！「できること」と「お願いされていること」の差がありすぎる、、！ | しっかりサポートしてもらえたから大丈夫やで |
| サーバーサイド | チケット割り当てられた部分を読むだけでもかなり時間がかかる。。終わらないのではと焦る。 | 焦る必要ないよ〜時間通り終わらないなら「〇〇が原因で時間がかかっている」と報告してendを調整してもらおう<br>ちょっと時間かかっても極力自分で終わらせましょう |
| 開発環境 | 先輩が作ってくれたDockerで環境構築はできる、、！でもなんで動いているかわからん、、！ | なんで動いているかは流石にわかるけど、今でも一回キャッチアップしないとイチから構築はきついよ |
| 案件 | お客さんが使う用語がわからない、、！どうしよう、、！ | これからも出てくるけど「分からないことは分からない」といいましょう。聞いた上で時分でキャッチアップもしましょう |

## 入社3年目（2022年03月〜2023年03月）

案件が変わりました！ゼロスタートのAPI開発でプログラマとしてjoin！先輩プログラマに混ざって日々勉強の毎日でした、、！初めてのドメイン駆動開発、初めてガッツリテストを書く開発、初めて自動化を積極的にしている案件に入ったので最初は非常に大変でした、、！案件進めていくと徐々に慣れてきたりドメイン駆動開発の利点も分かってきて良い経験になりました！自分の「プロジェクトの土台はしっかり作って自動化できるところ自動化しようぜ」の考え方はこの時に爆誕しました。

| 項目 | 状況 | 今の自分からのつっこみ |
| --- | --- | --- |
| 心持ち | エンジニアリングの知識が足りてない気がする | もっと「興味」をもって一段深く探るといいかもね。時間少しかかってもいいから意識してみよう |
| サーバーサイド | チェックの自動化最高！（ルール、静的解析、テスト）<br>ドメイン駆動開発難しい、、！ | 自動で任せられる部分はなるべく任せたほうがいいよね<br>難しいけど、本格的なオブジェクト指向を案件で体験できたことはデカイと思うで |
| 案件 | プログラマだとクライアントさんからは離れてしまうからちょっとさみしい | そこはトレードオフでしょ。しょうがない |

## まとめ

こうして振り返ると、入社時から比べてちょっとは自分も成長していたようです、、！お仕事ではほぼPHPしか書いたことが無いので言語や領域（バック・フロント）を広げていければと思っています。

自分はアンテクい入れていただき、技術的な部分もさることながら、精神的な部分を多く学ばせていただいたと思っています。弊社の行動指針を自分用にちょっとだけアレンジして「自分の仕事が、自分やその他のメンバーが見て全員から誠実であるとお墨付きを貰えること」として、これを常に思い出すようにしています。

技術的なキャッチアップを止めることはもちろん考えていません。しかし、それを上回る重要度でアンテクで培った「誠実さ」「責任感」「知っているふりをしない」などを忘れないようにしたいと思います。

次の3年はフロント側にも技術領域を広げたりインフラ側も噛み付いて行こうと思っています。環境が変わっても自身のキャッチアップ方法は改善はしますが改悪はしないつもりなので着実に焦らずやっていこうと思います！
NVIDIA Jetsonでdocker compose V2 を使う方法

# はじめに
　docker compose V1 (docker-compose コマンド)は、[以前の記事](https://qiita.com/ntrlmt/items/c001f0f98da426715cbd)で紹介したが、V1は開発されておらず、V2を利用したかったため、docker compose V2のインストール方法を紹介する。

　互換性は[こちら](https://docs.docker.jp/compose/cli-command-compatibility.html#:~:text=%E3%81%A4%E3%81%BE%E3%82%8A%E3%80%81%20V2%20%E3%81%A7%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B,%E3%81%AF%E3%80%81%E5%86%8D%E3%81%B3%20_%20%E3%82%92%E4%BD%BF%E3%81%86%E3%80%82)を参照。また、V1とV2の違いは下記の記事を参照。

https://qiita.com/zembutsu/items/d82b2ae1a511ebd6a350

# 動作確認環境
* Jetpack 5.1.1 (Ubuntu 20.04)

# 方法

　バイナリでは提供されていない(2024/5/2時点)ので、下記の公式の手順を参考に手動インストールする。

https://docs.docker.com/compose/install/linux/#install-the-plugin-manually

1. インストールするバージョンの設定  
   最新版は[docker-composeリポジトリのリリース](https://github.com/docker/compose/releases)を参照。

    ```bash
    DOCKER_COMPOSE_VER=v2.27.0
    ```

2. インストールするディレクトリを作成

    ```bash
    DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
    mkdir -p $DOCKER_CONFIG/cli-plugins
    ```
3. バイナリをインストールディレクトリへインストールして、実行権限を付与

    ```bash
    curl -SL https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_VER/docker-compose-linux-aarch64 -o $DOCKER_CONFIG/cli-plugins/docker-compose
    chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose
    ```

4. バージョン確認

    ```bash
    docker compose version
    ```
    下記のようになれば成功(v2.27.0をインストールした場合)。
    ```
    Docker Compose version v2.27.0
    ```

# まとめ
　NVIDIA Jetsonでdocker compose V2をインストールする方法を紹介した。バイナリでは提供されていないが手動で問題なくインストールできることを確認できた。docker compose V1は新規機能リリースされないので、V1を使っている方は、V2への移行を推奨する。

# 参考

https://docs.docker.com/compose/install/linux/#install-the-plugin-manually

https://wisenetwork.net/archives/3330

https://qiita.com/ntrlmt/items/c001f0f98da426715cbd

https://qiita.com/zembutsu/items/d82b2ae1a511ebd6a350
Ubuntuにpipでtensorflowをインストールする

# 公式サイトのコピペだとエラーが出る
https://www.tensorflow.org/install/pip?hl=ja

```sh
$ python3 -m pip install tensorflow[and-cuda]
```

``` sh
zsh: no matches found: tensorflow[and-cuda]
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'tensorflow'
```

# これで解決した
``` sh
$ python3 -m pip install 'tensorflow[and-cuda]'
```
Pythonのガントチャート生成ライブラリeleganttでGoogle Colab上にガントチャートを描く

追記：もっと楽に書けるという記事を書きました

https://qiita.com/usop4/items/56476ac92b7b521fe29a

---

eleganttというガンチャート生成ライブラリがありますが、これを使ってGoogle Colab上でガントチャートを書くためにはコツが必要ですので、ちょっとポイントを書いておきます。

まず、ライブラリのインストールと同時にフォントもインストールしておく必要があります。こちらは[公式のREADME](https://github.com/usop4/elegantt)にも書いてある通り。

```sh
!pip install elegantt
!apt install fonts-noto-cjk
```

それから、公式READMEではpng形式でファイル名を指定して保存していましたが、eleganttはPIL/Pillowと同じ形式ですので、IPythonを使ってインラインで画像が表示できます。

```py
from IPython.display import display
import elegantt

# Define chart properties
chartsize = (720,320)
bgcolor = (255,255,255)

# Create a Gant chart object
gchart = elegantt.EleGantt( chartsize, bgcolor, today="2019-10-15")

# Draw calendar and campains
gchart.draw_calendar()
gchart.draw_campain("2019-10-15","2019-10-18","Task 1")
gchart.draw_campain("2019-10-20","2019-10-23","Task 2")
gchart.draw_campain("2019-10-24","2019-10-30","Task 3")

display(gchart.im)
```

eleganttの0.0.5からはMermaid書式にも対応してるので、こういった書き方もできます。

```py
s = """
task a            :done,    des1, 2024-05-15,2024-05-18
task b            :active,  des2, 2024-05-20, 4d
task c            :         des3, after des2, 7d
"""

gchart = elegantt.EleGantt()
parsed_events = gchart.parse_mermaid(s)
gchart.auto_resize(parsed_events)
gchart.draw_calendar()
for event in parsed_events:
    start = event["start"].strftime("%Y-%m-%d") if event["start"] else None
    end = event["end"].strftime("%Y-%m-%d") if event["end"] else None
    gchart.draw_campain(start,end,event["title"])
display(gchart.im)
```



追記：もっと楽に書けるという記事を書きました

https://qiita.com/usop4/items/56476ac92b7b521fe29a
PostgreSQLでコンテナを作成する

## 概要

PostgreSQLのデータベースをDockerコンテナ上で運用する。
WebアプリケーションのDBとして扱うための設定を行う。

1. コンテナを起動する
1. ボリュームマウントを設定する
1. PGAdminからコンテナ内のデータベースにアクセスする
1. Docker Composeを設定する

## コンテナを起動する

今回は、コンテナ内のファイルシステムなどの設定を変更しないため、Dockerfileは作成せず、[PostgreSQLの公式イメージ](https://hub.docker.com/_/postgres)から直接コンテナを起動する。

```bash
$ docker run --name some-postgres -e POSTGRES_PASSWORD=secret postgres
```

- `--name`
    - コンテナ名を設定する
- `-e POSTGRES_PASSWORD=secret`
    - 必須設定の環境変数
    - 特権管理者のパスワードを設定する
- `postgres`
    - コンテナを起動するイメージを指定する

コンテナ内のDB操作は、以下のコマンドから実行可能

```bash
$ docker exec -it ${container_id} psql -U postgres
```

## ボリュームマウントを設定する

ボリュームマウントを設定することで、コンテナを削除した場合にも、データを残すことができる。
以下の手順から、生成したボリュームをコンテナ内のファイルシステムにマウントすることができる。

```bash
# 名前付きボリュームを作成する。
$ docker volume create postgresDB

# コンテナ起動時にボリュームマウントする。
$ docker run --name db_container \
  -dp 127.0.0.1:5432:5432 \
  --mount type=volume,src=postgresDB,target=/var/lib/postgresql/data \
  -e POSTGRES_PASSWORD=secret \
  postgres
```


**`/var/lib/postgresql/data`**
PostgreSQLのデータは、コンテナ内の上記ディレクトリに保存される。

## PGAdminからコンテナ内のデータベースにアクセスする

PGAdminでは、コンテナ内で起動しているPostgreSQLのデータベースに対して、リモート接続することができる。

PGAdminの設定画面のConnectionタブにて、適切なホスト名とポート番号を入力する。
以下、設定例を示す。
![スクリーンショット 2024-01-02 19.08.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3791376/a85195ee-3cca-3f77-c804-1261fd18e27a.png)

## Docker Composeを設定する

`docker run`コマンドの設定内容を`docker-compose.yml`に置き換えた。

```yaml
services:
  db:
    image: postgres
    ports:
      - 127.0.0.1:5432:5432
    volumes:
      - postgresDB:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: 'secret'
volumes:
  postgresDB:
```

## 参考文献

- https://hub.docker.com/_/postgres
ITパスポート 技術戦略

・技術戦略
企業や組織が研究開発した高度な技術を核とした戦略

・イノベーション
今までにない、画期的な新しいものを創り出すこと

・MOT
技術革新による経営

・技術ロードマップ
将来の技術動向を予測して進展の道筋を時間軸上に表した図
・デルファイ法
複数の専門家からの意見を収集する、収集した意見を集約する、集約した意見をフィードバックする、という流れを繰り返すことで意見を収束させていく手法

・技術ポートフォリオ
技術の重要度や保有技術の水準などを軸としたマトリクスに、市場における自社の技術の位置づけを表した図

・API
アプリケーションの機能を外部から利用できるようにする仕組み
・マッシュアップ
公開されているAPIを組み合わせて新しいサービスを作ること
・APIエコノミー
企業同士がAPIを使ってサービスを連携させることで生まれる新しい経済圏

・オープンイノベーション
企業や組織内部にとどまらず、他企業や他業種、大学、地方自治体、官公庁などと協力して、互いの専門知識を活かしてイノベーションを起こそうという考え

・ハッカソン
開発者やデザイナーなどが集まってチームを組み、数時間や数日間の日程で、与えられた課題にチャレンジするイベント

・デザイン思考
利用者も気づかないような潜在的なニーズを掘り起こし、イノベーションを生み出そうとする考え方

・リーンスタートアップ
低コストで最小限の機能の試作品やサービスを市場に出し、顧客の反応をフィードバックして改善していく方法

・魔の川
基礎研究が製品開発に結び付かないこと
・死の谷
製品開発が事業に結び付かないこと
・ダーウィンの海
事業化できても産業化できないこと

・イノベーションのジレンマ
優良な大企業が、既存製品の改良を進めることでシェアの確保に注力している間に、別基準で評価される新技術を用いた新製品に敗北してしまう現象
自宅サーバーに簡単に SSH できるようにしたいっす（これでいいんだっけ？編）

自宅サーバーに KVM で直接アクセスすることができたとしても別端末に表示されてる手順書のコマンドを一つひとつ正確に入力していく作業は辛い、、コピペしたい。。という人のためのメモ。（なお GitHub をよく使っている人）

```sh
GITHUB_ID="<あなたの GitHub ID>" && mkdir ~/.ssh && curl -o ~/github_keys "https://github.com/${GITHUB_ID}.keys" && cat ~/github_keys >> ~/.ssh/authorized_keys && rm -f ~/github_keys && chmod 700 ~/.ssh && chmod 600 ~/.ssh/*
```

上記をできたてほやほやの自宅サーバー上で実行すれば GitHub に公開鍵を登録した端末でSSHできるようになる（はず）

やったね！（本番系ではやめようね！）
SpringBootでDockerコンテナを作成する

## 概要
SpringBootをベースとしたアプリケーションをコンテナ化する。

:::note
なお、M1 Macを使用しているため、`platform: linux/x86_64`の対応をしている。
:::

## APPコンテナを作成する

**対応手順**
1. Spring Initializrで新規プロジェクトを作成する
1. Jarファイルを作成する
1. Dockerfileを作成する
1. イメージをビルドし、コンテナの起動する

### Spring Initializrで新規プロジェクトを作成する

[Spring Initializr](https://start.spring.io/)を使用すると、GUIもしくは、VSCode上の拡張機能からプロジェクトのテンプレートを作成することができる。

以下のように依存関係などの設定を行い、`Generate`をクリックすることでZipファイルとしてプロジェクトのテンプレートをダウンロードすることができる。
![スクリーンショット 2024-05-27 20.37.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3791376/ab040e3c-e7cc-3b8c-b985-c9f2792f072c.png)

### Jarファイルを作成する

作成したプロジェクト内で以下のコマンドを入力し、Jarファイルを作成する。
この後、生成したJarファイルを使用して、コンテナ上でアプリケーションを起動する。

```bash
$ ./gradlew build
```

:::note
Jarファイルは、`./build/libs`に生成される。
:::

### Dockerfileを作成する

以下が作成したDockerfileである。

```dockerfile
# from the base image of a jdk 17 container.
FROM eclipse-temurin:17-jdk-alpine

# create a work dir.
WORKDIR /app

# copy a jvm app.
COPY ./build/libs/docker_spring_boot-0.0.1-SNAPSHOT.jar app.jar

# open port 8080 for a jvm app.
EXPOSE 8080

# startup a jvm app.
ENTRYPOINT ["java","-jar","app.jar"]
```

現時点では、生成したJarファイルをコンテナの`/app`ディレクトリに配置し、これをもとにアプリケーションを起動している。

### イメージをビルドし、コンテナの起動する

```bash
# イメージを作成する。
$ docker build --no-cache --tag app-hello-spring-boot .

# コンテナを起動する。
$ docker run -dp 127.0.0.1:8080:8080 --name app_container app-hello-spring-boot
```

## 例外対応

一応これらの一連の流れからDockerコンテナの生成までは可能となる。
M1 Macを使用しているがために、以下のエラーが表示された。

```bash
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
```

CPUのアーキテクチャが対応していないイメージを使用している場合に発生するエラー。
以下を設定することで、このエラーを回避することができる。

```bash
$ docker build --platform=linux/amd64 -t app-hello-spring-boot .
```

`--platform`を指定しない場合には、自身のプラットフォーム向けのイメージを取得する。
しかし、M1 Macでは、ARM64に対応していないイメージを選択した場合には、エラーとなってしまう。

`--platform`は、イメージの構築対象のプラットフォームを指定することができ、このエラーの回避が可能。

## 参考文献

- https://spring.pleiades.io/guides/topicals/spring-boot-docker
- https://docs.docker.jp/engine/reference/commandline/buildx_build.html#id7
- https://zenn.dev/suzuki_hoge/books/2021-12-m1-docker-5ac3fe0b1c05de/viewer/2-arm
７・気づけば一週間

私のこの活動を始め一週間が経ちました。
総括すると、まだ私は知らないことが多すぎる。
それは何を当たり前のことをと思う人もいるかもしれないが、これは私にとっての重要な気づきである。
きっとここに書き込む人たちの気持ちもきっと同じなのだろう。
私も指南書を書く者としていつか必ず、あまり気づかれてないようなコードや、気をつけるべきポイントを書きたい。

そんな感じで前段は終わりにし、これからは私の本日の学びを書いていこうと思います。
今日は、progateにて初段の道場というコースに入ることができた。
ここでは、これまで習ったものを活かし書いていくことが求められるのだが、結論から言うととんでもないくらい覚えていなかった。
    <h>Youtube</h>くらいの簡単なものしか書けなかった。
    明日は必ずこれまで習ったものを自分のものにする。
確率と確率変数

##  確率(probability)とは
・ある試行を同じ条件で何度も繰り返したときにある事象が起こる相対頻度の極限値

ex) サイコロを例にすると
ある試行・・・サイコロを振る
ある事象・・・"1"が出る
相対頻度・・・"1"が出た回数÷サイコロを振った回数

相対頻度を無限回繰り返したものが確率になります。

## 確率変数(random variable)

・値が確率的に変動する変数
・通常$X$で表す
・それぞれの値に確率$P(X)$が対応

| サイコロの目 | 1 | 2 | 3 | 4 | 5 | 6 |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| 確率$P(X)$  | 1/6  | 1/6 | 1/6 | 1/6 | 1/6 | 1/6 |

## 確率分布(probability distribution)
・確率がどのように分布しているのかを表したもの
・確率変数は、確率分布から生成された値だとイメージする

![確率分布.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780659/d681e0ec-e6d1-047e-c36f-3d60488fd2ff.png)

サイコロのように全ての確率変数の確率値が同じ値である確率分布のことを**一様分布**という。(サイコロの目は一様分布に従う)

**Pythonで実践**

確率分布
・　stats.<確率分布>.<メソッド>


確率分布とメソッドには様々なものが用意されているのですが、今回は一様分布からランダムにデータを生成してみましょう。
・stats.randint.rvs(low, high)
randintは整数(離散型)を生成します。
```
from scipy import stats
# random variates(rvs)：確率変量

stats.randint.rvs(1, 7)

# ※下記のように書くこともできます。
# stats.randint(1, 7).rvs()
```
結果
3

サイコロのように、1〜6の整数がランダムに返ってきます。

また、連続した値を生成する確率分布を紹介します。
・stats.uniform.rvs(loc, scale)

```
stats.uniform(0, 1).rvs()
```
結果
0.2332625638624527

上記を実行すると、連続した値がランダムに返ってきます。


## 離散型確率変数と連続型確率変数
・とびとびの値をとる確率変数は、離散型確率変数
・連続の値をとる確率変数は、連続型確率変数

ex)
　サイコロを振って出た目→離散型確率変数

 ![離散型確率分布.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780659/b8711a52-2be8-a0c5-0ea7-0e232ad955db.png)

関数$f_X(x)$を確率質量関数(PMF:Probability Mass Function)という
($f_X(x) = P(X = x)$)

ex)
　ランダムに選んだ成人男性1人の身長→連続型確率変数

 ![連続型確率分布.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780659/6d86c982-5a1c-d8d9-a208-6747e29147f2.png)

関数$f_X(x)$を確率密度関数(PDF: Probability Density Function)という


**Pythonで実践**
一様分布を描画してみましょう
・離散型：stats.randint(low, high).pmf(x)

```
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

# x軸を設定
x = np.arange(1, 7)
# y軸を設定
y = stats.randint(1, 7).pmf(x)
# 描画
plt.plot(x, y, 'o')
# 縦線を引く
plt.vlines(x, 0, y)
```
![スクリーンショット 2024-05-27 20.53.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780659/3a22d41b-4b08-dda6-c475-b8c744e7db34.png)
グラフを見ると、1, 2, 3, 4, 5, 6のときだけ確率があり、それ以外は確率が存在しないことがわかります。

では続いて、連続型の一様分布を描画してみましょう。
・連続型：stats.uniform(loc, scale).pdf(x)

```
# x軸を設定
x = np.linspace(-2, 2, 100)
# y軸を設定
y = stats.uniform(loc=0, scale=1).pdf(x)
# 描画

plt.plot(x, y)
```
![スクリーンショット 2024-05-27 20.59.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780659/f8ae9a4e-beab-40d0-9fed-12ba58a128d9.png)
グラフを見ると、0~1の間の確率は1.0であり、それ以外の値は確率が0であることがわかります。
【Terraform入門】インフラ自動化ツールの基本と使い方

# ■ はじめに
近年、クラウド時代の到来とともに```インフラ構築の自動化```が注目を集めています。その中でもHashiCorp社の```Terraform```は、コード化によるインフラ管理の実現で人気の高いオープンソースツールです。この記事では、Terraformの基本概念から使い方までを解説します。

# ■ Terraformとは何か
Terraformは、```インフラリソースのプロビジョニングを宣言的に記述し管理するためのツール```です。AWS、Azure、GCPなどマルチクラウド環境に対応しており、コードによってインフラ構成を定義します。これにより、インフラ構築の自動化とバージョン管理が可能になります。

# ■ Terraformの基本概念
Terraformは以下のような基本概念で成り立っています。

- ```Provider```：各クラウドプロバイダやサービスとの連携を行うプラグイン
- ```Resource```：管理対象となるインフラリソース（VM、ネットワーク、ストレージなど）
- ```Variables```：リソースで使う変数の定義
- ```Data Source```：参照専用の情報源
- ```Module```：再利用可能なリソースのセット
- ```State```：構築したリソースの状態管理用ファイル

コードは```HCL（HashiCorp Configuration Language）というTerraform専用の記述言語```を使います。

# ■ Terraformのインストールと環境構築
TerraformはWindows、macOS、Linuxで動作します。各OSごとにバイナリをダウンロードしてパスを通すだけでセットアップ完了です。クラウドのアクセスキーは環境変数や別ファイルで管理します。エディタはVS CodeにTerraformプラグインを導入すると便利です。

# ■ Terraformの使い方
実際にTerraformを使ってインフラ構築を進めていきます。

1. プロジェクトフォルダ内で`terraform init`を実行し、必要なプロバイダをダウンロードする。プロバイダ追加時は再実行が必要。
2. `*.tf`ファイルにHCLでリソース定義を記述する。変数は`variables.tf`や`terraform.tfvars`に切り出すのが一般的。
3. `terraform plan`で実行計画を確認し、変更内容をチェックする。
4. `terraform apply`を実行し、インフラをデプロイする。
5. `terraform destroy`でリソースを削除できる。

State（terraform.tfstate）は運用フェーズではバックエンドを使ってリモートに保存・管理するのが推奨されます。

■AWS上での活用例
AWSを使った一連の流れを見てみましょう。VPC、サブネット、インターネットゲートウェイ、セキュリティグループ、EC2インスタンスを構築し、WebサーバーをデプロイするユースケースをTerraformで実装します。

```hcl
provider "aws" {
  region = "us-east-1"
}

data "aws_ami" "ubuntu" {
  most_recent = true
  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
  }
}

# VPC
resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
}

# Public Subnet 
resource "aws_subnet" "public_1" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.1.0/24"
}

# Internet Gateway
resource "aws_internet_gateway" "main" {
  vpc_id = aws_vpc.main.id  
}

# EC2 Instance
resource "aws_instance" "web" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = "t2.micro"
  subnet_id     = aws_subnet.public_1.id

  user_data = <<EOF
    #!/bin/bash
    sudo apt update
    sudo apt install -y apache2
    sudo systemctl start apache2
    sudo systemctl enable apache2
  EOF
}
```

AMIはデータソースを使って動的に取得し、`user_data`でApacheの自動起動設定も追加しました。コードを記述したら`terraform apply`を実行すれば、AWS上にインフラが構築されます。

# ■ さいごに 
この記事ではTerraformの基本と使い方について解説しました。インフラのコード化は運用の効率化とミス防止に大きく貢献します。実際のプロジェクトではモジュール化による再利用やCI/CDパイプラインとの連携など、より実践的なスキルが求められます。ここで培った知識を生かし、学習を深めていきましょう。
【備忘録】プリミティブ型とラッパークラス

私は業務に入ってもうすぐ1年たつことになるんですが、いまさらプリミティブ型とラッパークラスの違いを理解した（6割ぐらい）のでここにまとめていこうと思います。

絶対に研修でもやったんでしょうけど、実際にやってみて困りださないと理解できないもんですねぇ。

<h2>プリミティブ型</h2>
プリミティブ型ってのは<a href = https://e-words.jp/w/%E3%83%97%E3%83%AA%E3%83%9F%E3%83%86%E3%82%A3%E3%83%96%E5%9E%8B.html> この記事</a>によると
<p>
<strong>
プログラミング言語などが仕様として提供する基本的なデータ型。または、定義に他のデータ型を用いない独立したデータ型。</strong></p>

ということらしいです。

どんな方があるかは、いくらでもまとめているサイトがあるのでそちらを参照してもらって、、、

頭文字が小文字になってるやつがそれです。（int,longとか）

<h2>ラッパークラス</h2>
一方で、ラッパークラスは
<p>
<a href = "https://recursionist.io/learn/languages/java/data-type/wrapper-class#:~:text=%E3%83%A9%E3%83%83%E3%83%91%E3%83%BC%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%A8%E3%81%AF%E3%80%81Java,%E3%81%9F%E3%82%81%E3%81%AB%E4%BD%BF%E7%94%A8%E3%81%95%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82">
<strong>
ラッパークラスとは、Javaにおいてプリミティブなデータ型を包む、または囲むクラスです。これらのクラスは、Java言語においてプリミティブなデータ型にオブジェクト指向のインターフェースを提供するために使用されます。
</strong>
</a>
</p>

らしいです。

これは頭文字が大文字になってるやつです。（Integer,Long,Stringとか）

<h2>何が違うの？</h2>
何か色々違うようですが、一旦

プリミティブ型はnullが入らなくて、ラッパークラスはnullが入る

ぐらいの理解で良いと思います。

要は、その変数にnullが入る可能性があるならラッパークラスを使いましょうってことです。

プリミティブ型にnullを入れようとすると別の値が入ってしまいます。
（例えばlong形にnullを入れようとすると、nullが入らず0が入ってしまいます）

<h2>まとめ</h2>
変数に正しくnullが入らないと、nullポチェックを抜けていてしまうことがあるので気をつけましょうや。
未来のCreatorが会得すべきアウトプット法

昨今の現代情報化社会において、単に情報を収集する（インプット）だけでは差別化が非常に難しくなってきています。というのも、AIが導入されたことにより今は情報量が何100～1000倍も増えており、今覚えた情報が一瞬にして古いもの、時代遅れのものになってしまうからです。重要なのは、学んだ情報をアウトプットし、行動可能な洞察に変換することです。

## アウトプットの重要性

以前は、知識の蓄積が成功の鍵と考えられていました。しかし、現代社会では情報が溢れ、誰もが同じ知識にアクセスできます。違いを生み出すのは、情報を処理し、それを活用して創造的なアウトプットを生み出す能力が必要とされてきています。

## 順番を逆にする

従来なら、人はまず情報を収集（インプット）してから処理（アウトプット）する傾向がありました。でもそれは今となってはナンセンスな思考になっています。では、今はどんな思考回路をした人がハイセンスなのかと言いますと、この順番を逆にすることなのです。その方法として、まず達成したい目標（アウトプット）を明確にし、その目標を達成するために必要な情報（インプット）のみを収集します。なぜそうするかと言いますと、情報収集に集中し、情報過多を避けるためなのです。これにより、アウトプットを達成するために必要な情報だけを収集し、そしてそれが目的達成への近道にもなります。

## アナログを活用する

世界がデジタル化していく中で、アナログ的な方法を情報処理のワークフローに取り入れることこそが仕事では多く求められてきています。例えば、対面での会話を通じて情報を収集したり、自分の考えや洞察を紙に書き出したりすることなどです。これを意識して行っているクリエーターは、情報をより深く理解し、よりユニークで洞察力のあるアウトプットを生み出している現状が今まさにこの記事を読んでいる時にも起きているのです。またさらに優秀なクリエーターたちは、インターネットなどの二次情報に頼るのではなく、一次情報（直接の情報源）を収集することを心掛けており、アウトプットの信頼性と説得力が高まるよう努力をし続けているのです。


## まとめ
  - 現代の情報化社会では、単に情報を収集するだけでは差別化が難しい
  - 重要なのは、学んだ情報をアウトプットし、行動可能な洞察に変換すること

**現代情報化社会の課題**
  - 情報の単なる収集（インプット）では差別化が難しい
  - AIの導入により、情報量が何100～1000倍も増加
  - 新しい情報がすぐに古くなる

**アウトプットの重要性**
  - 知識の蓄積だけでは成功が難しい
  - 情報の処理と創造的なアウトプットが求められる

**順番を逆にする**
  - 従来のインプット→アウトプットの順番はナンセンス
  - まず達成したい目標（アウトプット）を明確にする
  - 必要な情報（インプット）のみを収集
  - 情報過多を避ける（問題解決に直結しない情報収集は行わない）

**アナログの活用**
  - デジタル化の中でアナログ的な方法をうまく取り入れる
  - 対面での会話や紙に考えを書く意識をすること
  - アナログ的な方法を取り入れることで情報の深い理解とユニークなアウトプットにつながる
  - 優秀なクリエーターほど一次情報を重視
  - 一次情報を重視しているからこそアウトプットの信頼性と説得力が向上する
N_1_Arduino_エッジ側デバイス_flipper's circuit Project -電子工作人口を増やすためのプロジェクト-

エッジ側デバイス比較のまとめ書きます m(_ _)m
ちょっと疲れています。
そして内容てんこ盛りになるので、代表的なデバイスの価格比較とArduinoの特徴までで切ります。

# エッジ側デバイスの種類

あくまでも代表的なもので機能が揃っているワンボードデバイスについてまとめます

| No | 名前 | 種類 | 価格（概算）|
|:-:| - |-| -: |
|1| Arduino UNO R3 | ワンボードマイコン| 4000円 |
|2| Arduino UNO R4 WiFi | ワンボードマイコン | 5000円 |
|3| M5Stack Core2 | オールインワンデバイス | 8500円 |
|4| Raspberry Pi Pico W | ワンボードマイコン | 1500円 |
|5| PIC16/18マイコン | ワンチップマイコン | 数百円 |
|6| Raspberry Pi 4B | ワンボードLinuxコンピュータ | 13000円 |

## 1 Arduino UNO

| 項目 | Arduino UNO　R3 | Arduino UNO R4 WiFi |
| - | - | - |
| MCU | 8bit 16MHz | 32bit 48MHz |
| メモリSRAM | 2kB | 32kB | 
| メモリFlash | 32kB | 256kB | 
| USB | Type-B | Type-C |
| GPIO | デジタルI/O×14 | デジタルI/O×14 |
| ADC | 10bit×6ch | 12/14bit×6ch |
| Wi-Fi | なし | あり|
| シリアル | UART×1 | UART×1 |
|  | I2C×1　SPI×1 | I2C×1　SPI×1 |
| RTC | なし | あり |
| 電源 | 5v 3.3v出力あり | 5v 3.3v出力あり |
|  | 外部入力7～12V | 外部入力6～24V |

**【備考】**
大きな違いはWiFiの有無です。R3でWiFiを使用する場合は、別途ESP32というマイコンが必要になります。R4はESP32内蔵型のワンボードマイコンです。
（ESP32が1000円するので、ケチらないほうがよいかもしれません）
互換品（Generic）のArduinoはR3モデルです。

### Arduinoの特徴
#### 1 簡単な回路構成で分かりやすい

ビギナー向けの所以はここです。簡単な回路で構成されているので、とても分かりやすくなっています。

#### 2 オプションで各種シールドボードが用意されている

外部接続用のソケット配置の互換性が保たれているため、オプションボードとして用意されている多くのセンサや表示器を使うことができます。しかし、シールドボードにないものは、何らかのオプションボードを用意しないと接続ができません。

#### 3 スケッチで簡単にプログラムできる

スケッチと呼ばれる言語で書かれていますが、比較的わかりやすい言語なのでプログラミングしやすくなっています。

#### 4 多くのライブラリがある

スケッチで使えるライブラリが沢山あるので、センサやアクチュエータ、通信を比較的簡単に使用できます。一方、ライブラリにない場合の開発は難易度が高いです。

#### 5 メモリサイズは少な目

特にR3はメモリが少ないので、大きなプログラムや大量のデータを扱うことができません。R4の場合は、SDカードのシールドがあるため、SDカードを追加すれば大量データも処理可能です。

#### 6 時刻の扱い

リアルタイムの時間はR3では使えませんが、R4ではリアルタイムクロックが実装されています。Wi-Fiで、ネットワークから時刻を入手することも可能です。

#### 7 リアルタイムOS（RTOS）の実装が可能

R4であればFreeRTOSが実装可能です。（μITRONも実装可能だとか？）

## Arduinoのデータシート

Arduinoのデータシートのリンクは以下通りです

■ Arduino UNO R3

https://docs.arduino.cc/resources/datasheets/A000066-datasheet.pdf

■ Arduino UNO R4 WiFi

https://docs.arduino.cc/resources/datasheets/ABX00087-datasheet.pdf

次回はRaspberry Piについてまとめます
#プログラミング #Javascript # バグネタ

バグを生みそう・生んだもの。

もしやと思ったら(笑)

```
a=2;b=a*3;b
6
a="2";b=a*3;b
6
a="_2";b=a*3;b
NaN
a="   2   ";b=a*3;b
6
```