メインコンテンツまでスキップ

合同研修の振り返り

森脇
ディアシステム(株)開発一部第1課

【合同研修の流れ】

4月8日から6月27日までの約3ヶ月間、合同研修に参加いたしました。
研修が始まって、最初は社会人マナーを学びます。
その後は、様々なプログラミング言語の講義を受け、個人開発演習を し、最後の1か月間は6人1チームでグループ開発演習行います。

【社会人マナー】

合同研修が始まって、最初は社会人マナーを学びました。
内容は7つの習慣から始まり、主に敬語の使い方、名刺交換、電話対応について学びました。
ほとんどが、隣の席の方とのペアワークであったり、4人で1つのグループになって、実際に 練習を行いました。どれもが初めての体験で、言葉遣いなど苦労することがたくさんありました。

【プログラミング言語の講義】

プログラミング未経験の状態で、この業界に入りました。
初めて学んだ言語がHTML/CSSで、講義スピードもかなり速く全くついていけていませんでした。
このままでは、何も習得できずに「ただ研修に通っているだけになってしまう。」と感じたので、週末に復習を行ったり、技術力のある人やサポーターの方に質問をたくさんするなど、リカバリー方法を考えるようになりました。
この行動を早い段階から始められたことによって、その後のOracle DatabaseやJava、Spring、JavaScriptなどの言語を学ぶときにわからない時はどのように行動すればいいのか、どんな質問の仕方だと相手に伝わりやすいのかを知ることができました。

【個人開発演習】

Spring までの講義を終えたあと、個人開発演習として今まで学んだ言語を使用しての開発が始まりました。
実装から成果報告するまで全て合わせて6日間で行いました。
実装はほぼ3日間ほどで終わらせて発表資料の作成などに取り掛かったため時間があまりに少なく、実装してみたかった機能までたどり着くことができなかった悔しさもあります。
しかし、自分の力でシステムを作ることができたという達成感と、目に見えての成長を感じることができました。

【グループ開発演習】

最後の1ヶ月間は6人グループに分かれて、学んだ言語すべて使用してホームページを作成するというグループワークがありました。
私のチームでは、「おもちゃ」をテーマにし、ページカラーや自作のキャラクターを作るなどの話し合いをしました。
最初の段階から、グループ内の連携が取れておらず一部のメンバーにかなり負担がかかってしまうこともあり、何度もグループで話し合いを行いました。
私の役職ではスケジュール管理者だったのですが、途中でサブリーダーを兼任しメンバーのサポートに入り、品質管理者の作業もサブで行うことも何度があり機能実装もとなると作業量がたくさんあって、正直なところ体調を少し崩すこともありかなりしんどかったです。
そんな中で、サポーターの方から「ただ報連相ができるだけじゃ伝わらない。相手がどんな人なのか、普段のコミュニケーションを重ねていかないとわからないよね」とアドバイスをいただきました。
そこから、グループ内での行動が一気に変わりました。チームみんなで協力していこうと、まとまり最後の成果報告会まで走り続けることができました。

【合同研修で成長したこと】

最も成長したと思えることは、コミュニケーション力です。
グループ開発のことを乗り越えたおかげで、どれだけ相手を理解し、どのように話すべきなのかを知ることができたからです。
さらに、グループの人だけでなく教室にいる受講生とたくさん話せるよう毎朝行っていた1分間スピーチのおかげで、話す機会が多くあったからです。

この研修を通して、最初はわからないことがたくさんあって、技術力のある方に何度も質問し教えてもらうことがほとんどでした。
しかし、自分で考える力が付き「どのように考えるのか・調べるのか」を行動に移すことができるようになりました。
その結果頼らないとできなかった作業も、教科書やインターネットを参照すると書くことができるコードの範囲が増えました。
ITスキル面では、まだまだ足りていないところが多くたくさん成長したとは言えませんが、どれだけ作業が大変でも、粘り強く諦めない気持ちをもって機能を実装し動いたときは嬉しさが強く、もっと頑張ろうと思えました。

【最後に】

 「静かにひたすら作業をこなす」というイメージを研修に対して持っていたのですが、実際は本当に学校のようで他社の方と仲良くなり楽しく学べる環境でした。
 技術面でたくさん講義を受け、知識を得たことで少しずつ成長していくだけでなく、社会人としても、人としても成長することができたと感じました。
 この合同研修で得たものは今後も継続して「できる」にし、実務に活かしていきます。

新人研修の振り返り

坂口
ディアシステム(株)開発二部第2課

開発二部 坂口です。
私は入社2年目で年が近いということもあり、新入社員教育のお手伝いをさせて頂く機会がありました。
その中で、研修当時の事を思い出したので、今回はそんな研修の内容や感想を記載していこうと思います。

新人研修の概要

 研修は大きく分けて2つあります。
 

 入社前研修:
 内定後、入社前に任意参加で先輩社員から、3カ月ほどプログラムや仕事の仕方について学びます。
 新人研修:  入社後、社内の研修制度としてOFF-JT(東京ITスクール)にて社会人マナーやプログラムについて学びます。  東京ITスクール  
 

OFF-JTの一連の流れ

 OFF-JTは入社後4月~6月末までの3ヶ月間で行いました。

 研修の最初の約1週間は社会人マナーを学びます。
 その後、各プログラム言語について講義を受けたうえで
 仕上げとしてチーム何人かで、グループワークを行います。
 

社会人マナー

 社会人マナーを学ぶ講義では、主に電話対応、名刺交換、敬語について学びました。
 

 電話対応:
 ペアの人と交互に、指定されたテーマに沿って電話対応の練習をします。
 名刺交換:  名刺を交換する順番や、受け渡しのやり方の講義を受けた後で、  グループを作り、名刺交換の練習をします。
 敬語:  尊敬後や謙譲語の違い、使い方についての講義を受けました。  謙譲語や尊敬語の違いを区別するのが難しかったです。  
 

初めてのプラグラミング

 プログラミング未経験の新人4名で、プログラミングという未知の世界へ飛び込みました。

 OFF-JTで最初に学んだHTML/CSSには、なんとかついていくことが出来ました。
 しかし、Javaへと移った途端に見たことのない文字列を目の当たりし「なるほど、これはだめなやつだ」と正直思いました。
 少しでも理解すべく講師の方の説明に食らいつくように聞き、不明点があれば周りの初対面の人に質問を重ねました。
  そのおかげでプログラミング言語の理解よりも先にコミュニケーション能力と質問力が身に付きました。
 

休憩時間

 講義は楽しかったのですがお弁当の時間はオアシスでした。
 受講している時は席が近い訳ではありませんので同期と話せるのはお弁当の時間だけだったからです。
 分からない部分の共感や雑談、相談、色々なことを話し、気分転換になりました。
 同期がいなかったら心細かったと思うので、同期がいてくれて良かったと感じる瞬間でした。
 

グループワーク

 残りの1カ月になると5人グループに分かれ、学んだJava,Oracle,HTML/CSSを実践するというグループワークがありました。
 グループごとで決めたテーマを元にWebページを作成していくというものです。

 私のチームではそれぞれ一つずつテーマを出し合い多数決で「車」のホームページを作成することに決定しました。
 ページのメインのカラーを決めるほかに、画像をどのように表示するなどの話し合いをします。
 決定した内容と処理の役割分担を詳細設計までとはいきませんが簡単にシートに記述していきます。

 1日の作業の終わる時は、講師の方に進捗報告をします。
 進捗報告で心掛けていたことは、正確に進捗報告が出来るということです。
 

 研修前:
 「〇〇ページ~〇〇ページまで進みました」と報告
 研修後:  「〇〇%達成し、次は△△%まで行いました」と具体的な数字を出して報告  
 達成出来なかった場合は「達成出来なかった理由、次はどう対処するか」を報告するようにしたら把握しやすいという指摘をいただきました。
 すぐに実践できた訳ではありませんでしたが、数をこなすにつれて徐々に出来るようになり、最後は褒めていただくことが出来ました。
 今思えば、この一連の工程は業務でも実践している内容なので大切だったんだなと実感しています。
 

身に付いたこと

 最も身に付いたと実感しているのは、コミュニケーション能力です。

 初対面の方とペアを組んで課題に取り組むことが多く、また講師の方と話す機会も多く設けられていたからです。
 コミュニケーションの中の一つともいえる進捗報告も入社前研修を受けていた時よりは上達したのではないかと思います。
 プログラミング言語については、正直身に付いたとまでは言えませんが、どうようなものかという外枠は理解することが出来ました。
 

最後に

 ITスクールは高校生活の様でした。
 朝は日直が挨拶運動、昨日の出来事を話し、お昼休憩はゴミの回収が行われていました。
 また、席替えなども行われていた為、本当に高校時代に戻ったみたいで楽しかったです。

 楽しい反面、プログラミング言語は覚えるものが多く途中で挫折しそうになる時もありますが、
 それと同じくらい出来た時の喜びと達成感があるので楽しいです。

 プログラマはプログラム言語を覚えるのはもちろん
 正確な情報を伝達するコミュニケーション能力も必須であることを研修・業務を通して学びました。

Streamlitを使ってデータ分析Webアプリを簡単に作成しよう

津村
ディアシステム(株)開発一部第4課

Streamlitとは

Streamlitは、Pythonで作成されたオープンソースのWebアプリケーションフレームワークです。
データサイエンスや機械学習の分野で、迅速にグラフィカルなWebアプリを構築し、公開するためのツールとして非常に人気があります。
HTMLやCSS、JavaScriptの知識がなくても、Pythonだけで美しいWebアプリケーションを作成できる点が魅力です。

インストール方法

まず、Streamlitをインストールしましょう。
最新のPython環境が整っている前提で、ターミナルより以下のコマンドを実行します。

Terminal
> pip install streamlit

インストールが完了したら、以下のコマンドで簡単なデモを実行してみてください。

Terminal
> streamlit hello

demo-1

demo-2

サンプルコード1:基本的なWebアプリの作成

最初に、基本的なWebアプリケーションを作成してみましょう。
以下のコードを使って、「Hello, Streamlit!」というメッセージを表示するアプリを作成します。

sample_1.py
import streamlit as st

st.title('Hello, Streamlit!')
st.write('これは基本的なWebアプリケーションの例です。')

「***.py」ファイルはPythonスクリプトと呼ばれ、Pythonコードが書かれたテキストファイルです。
インタプリタがこのファイルを読み込んで実行し、これにより、Pythonプログラムやスクリプトとして動作します。
上記のコードをsample_1.pyとして保存し、以下のコマンドで実行します。

Terminal
> streamlit run sample_1.py

ブラウザに「Hello, Streamlit!」というタイトルとメッセージが表示されれば成功です。 sample_1

サンプルコード2:データフレームの表示

次に、Pandasデータフレームを表示する方法を紹介します。
以下のコードでは、簡単なデータフレームを作成し、それをWebアプリ上に表示します。

sample_2.py
import streamlit as st
import pandas as pd

data = {
'列1': [1, 2, 3, 4],
'列2': [10, 20, 30, 40]
}
df = pd.DataFrame(data)

st.title('データフレームの表示')
st.write('以下はPandasデータフレームの例です。')
st.write(df)

同様にsample_2.pyとして保存し、以下のコマンドで実行します。

Terminal
> streamlit run sample_2.py

これにより、データフレームが表形式で表示されます。データの視覚化に非常に便利です。 sample_2

サンプルコード3:インタラクティブなウィジェット

最後に、インタラクティブなウィジェットを追加してみましょう。
以下のコードでは、ユーザーが選択したオプションに基づいてメッセージを変更します。

sample_3.py
import streamlit as st

st.title('インタラクティブなウィジェット')

option = st.selectbox(
'好きなフルーツを選んでください。',
['アップル', 'バナナ', 'オレンジ']
)

st.write('あなたの好きなフルーツは', option, 'です。')
Terminal
> streamlit run sample_3.py

このコードを実行すると、ドロップダウンメニューからフルーツを選ぶことができ、選択に応じてメッセージが更新されます。 sample_3-1 sample_3-2

まとめ

Streamlitは、シンプルかつ強力なWebアプリケーションフレームワークであり、Pythonのみを使用してデータ分析や機械学習のアプリケーションを迅速に作成できます。
今回紹介したサンプルコードを参考に、ぜひ自分のプロジェクトにStreamlitを取り入れてみてください。

ChatGPT-4oでデータ分析してみた

箕浦
箕浦
ディアシステム(株)開発二部

こんにちは。開発 2 部の箕浦です。
GPT-4oがリリースされてから3週間程たちますが、
今まで有料ユーザーしか使えなかった機能が、制限付きで無料ユーザーにも解放されており、より便利になっています。
無料ユーザーでも利用可能になっているいくつかの機能のうち、今回はデータ分析機能を試してみました。

試しにAWSの毎月のサービス利用料の内訳のcsvファイルをAWSのCost Explorerコンソールからダウンロードします。
csvファイルの中身は以下のようになっています。

csv

こちらをChatGPTにアップロードしてみます。
ファイルをアップロードするには、プロンプトを入力するボックスの左のアイコンをクリックし、 「コンピューターからアップロードする」を選択します。

upload

csvファイルをアップロードすると読み込んでくれました。

cost

では、ChatGPTに分析をお願いしてみます。

このデータについて分析してください

ざっくりお願いしたのですが、もう少し細かく指示を出せば、詳細な分析もしてくれそうです。 analize1 analize2

しっかり分析してくれて、考察まで出してくれています。

今度はグラフを作成してもらいます。

月々の各サービスのコストの変化をグラフにしてください

graph1

日本語のフォントは文字化けしていますがこちらは、 Google Fonts( https://fonts.google.com/) などで日本語のTTFファイルをダウンロードしてChatGPTにアップロードすれば解消できるようです(今回は試してません)

別のグラフもお願いしてみます。

5月におけるサービスの利用料の内訳を円グラフにしてください

graph2

こちらも文字が潰れてしまっているところもあるみたいです。

指示の仕方を工夫すれば、そこそこ使えるグラフも作ってくれそうです。
画像もダウンロードできるようなので、資料作成の際は検討してみてもいいかもしれません。

ChatGPTが4o(omni)になってから、かなり高性能になっており、無料ユーザーでも利用できる範囲が広がりました。
利用回数に制限があるので、限度に達したら、数時間おく必要がありますが、非常に便利なツールとなっています。
他にも便利な使い方あれば、紹介していきたいと思います。

ライブラリやフレームワークの使い方はCursorエディタのDocsに任せよう

箕浦
箕浦
ディアシステム(株)開発二部

こんにちは。開発 2 部の箕浦です。
皆さんはエディタに何をお使いでしょうか?
Visual Studio Code(以下、VSCode)をお使いの方も多いと思います。

もし VSCode をお使いの方は、今すぐ Cursor に乗り換えましょう!
Cursor は、ご存じの方もいるかもしれませんが、VSCode の操作性そのままに、ChatGPT などの AI が搭載されたエディタです。
無料版では AI 機能を利用するためのクレジットに制限がありますが、その便利さに一度慣れると VSCode には戻れなくなります。

VSCode から Cursor に乗り換える際、拡張機能もそのまま引き継げるので、使い慣れた設定を維持しながら移行が可能です。
Cursor を起動すると以下のように VSCode とほぼ同じ UI となっています。

top

Cursor の特徴を簡単に説明しますと、AI がコード生成やコード補完を行い、コーディング中にチャットでアドバイスを受けることができます。
また、エラーの修正方法も教えてくれるため、コーディングの効率化に大きく貢献し、開発作業がスムーズに進みます。

現時点で選択可能なモデルは、先日登場したばかリの話題の GPT-4o の他に Anthropic の Claude 3 opus や GPT-4 turbo、GPT-3.5 等が選択可能なうえ、追加することも可能なようです。

gpt

ちなみに 無料版では、GPT-4 なら 50/月、GPT-3.5 なら 200/月 のクレジットが提供されています。
以下の管理画面から、現在使用したクレジットが確認可能です。

credit

機能に関しては、 GitHub Copilot も同様の機能を持っていますが、現時点で Cursor にしかない特に便利な機能をご紹介します。

それは、 Docs と呼ばれる、外部 URL 参照機能です。 サンプルコードや、公式ドキュメントなどがネット上にある場合、それらを参照して回答させることができます。

高性能の AI といえど、最新の情報は持っていないため、補完するための機能が必要です。 これは一般的に RAG(Retrieval Augmented Generation。検索拡張生成) と呼ばれ、新しい情報を取り込むことで AI の回答精度を高める仕組みです。

開発を進める中で、利用経験のないライブラリやフレームワークの実装が必要な局面があります。
また、利用中のライブラリであっても、バージョンアップ等によって、使い方を再度調べる必要がある場合もあります。
そのたびに、膨大な量の公式ドキュメントや関連サイトを調べて実装するのはなかなかしんどい作業かと思います。

そんなときにこの機能を利用すれば、AI がドキュメントを取り込んでくれて、それを元に回答をしてくれたり
コードも生成してくれます。

この機能を利用するには、 チャットの欄に@を入力すると以下の画面になります。

docs1

Docs を選択します。
デフォルトでいくつかの公式ドキュメントがあるようです。

docs2

一番下の「Add new doc」を押下すると以下の画面になります。
ここで、取り込みたいサンプルコードやドキュメントの URL を入力します。
試しに FastAPI の公式サイトを入力しています。

docs3

取り込みが完了すると、以下のように取り込んだページのリンクの一覧が表示されています。

docs4

これで、チャットウィンドウ上で @ +ドキュメント名 を入力し、今までどうりAIに質問してみましょう。
取り込んだドキュメントを参照して、回答を返してくれることかと思います。

answer

GitHub Copilotも同じように 「Copilot for docs」(https://githubnext.com/projects/copilot-for-docs/) という機能がありますが、こちらは現時点では、プレビュー終了しており、今後のアップデートで 実装される可能性はあります。

今回はCursorの便利機能のほんの一部を紹介しましたが、まだまだ便利な機能はありますので、これからも紹介していきたいと思います。
皆さんも一度試してみてください。

生成AIでWebサイトの画面をデザインする

箕浦
箕浦
ディアシステム(株)開発二部

こんにちは。開発 2 部 箕浦です。
今回はWebのUIデザインを生成AIが自動で作成してくれる「v0」(https://v0.dev/ )という画期的なサービスについて紹介します。

我々システム開発を行うデベロッパーにとって、どのような画面デザインにすればいいかという課題は頭を悩ませる要因となっています。
大規模なプロジェクトであれば、通常デザイナーに依頼してデザインを作成しますが、小規模なプロジェクトではデザイナーに頼れない場合もあります。
そのような場合、開発者自身が優れたUIデザインを考える必要があります。

そんなときは今流行りの生成AIにUIデザインをしてもらおうという試みになります。

この「v0」というサービスは、チャットのようにテキストで指示をすることで、自動的にWebページのUIを作成してくれて、さらに細かい修正も追加で指示することで行ってくれます。

生成されたUIはコードとして出力されますので、 それをそのままコピーもしくはCLIのコマンドでプロジェクトに取り込むことが可能です。

なお、生成されたUIのコードは、 React(Next.js)とhtmlのどちらでも可能で Tailwind CSSやshadcn/uiを利用していますので、こちらをプロジェクトで利用していることが前提となっています。

利用するには、Vercel のアカウント(無料)が必要になります。
無料のFreeプランと有料のPremiumプラン(月20$)があり、利用できるクレジット数や、ハイクオリティやUIが生成可能等の差があるようです。 プランの比較はこちら

今回は無料のFreeプランでやってみます。

ログインすると、以下の画面になります。

top

非常にシンプルでこのプロンプトから指示を送信することでAIがUIを提案してくれます。

画面の下の方に行くと、 Exploreの欄に指示したテキストと、実際に生成されたUIの例がいくつかあります。
この中から、イメージに近いものを選んで採用する方法もあります。

explore

今回は試しにYouTube風のUIを作ってもらうことにします。
プロンプトには、日本語で指示することも可能です。
試しに「YouTubeのようなUIを作って」 と指示してみます。

first

すると、AIが3つの提案をしてくれます。 まず一つ目。 no1

次に2つ目 no2

最後に3つ目 no3

結構それらしいUIを作ってくれました。
提案してもらったUIを選んでさらに追加の指示を行うことも可能です。

ここでは3つ目のUIを採用することとして、
追加で日本語のUIにしてもらいます。

second

すると、ちゃんと指示通りに日本語化してくれました!

japanese

右上にあるテーマアイコンから、フォント等を変更することが可能です。

テーマ

タブレットや、スマートフォンで確認した際の表示のされ方もここで確認可能です。
以下はタブレットの場合。

タブレット

codeをクリックすると、Reactとhtmlのコードが確認できます。
ここで直接コードを編集して微調整することも可能です。

code_react

こちらはhtmlの場合。

code_html

こちらのコードを今回はNext.jsのプロジェクトに取り込んでみることにします。
取り込み方法は、CLIコマンドによる方法と、手動でコードをコピペする方法がありますが、 コマンドの方が楽なので今回はそちらでやってみます。
(現在CLIによる取り込みはNext.jsのみサポートされているようです)

コードの上の方にある 「npx v0 add ・・・」 とあるコマンドをコピーします。

Next.jsのプロジェクトを作成し、プロジェクトフォルダ直下で以下のコマンドを実行します。
Tailwind CSSを利用していますので、Tailwind CSSも組み込んでおきます。

npx v0@latest init

次に先ほどコピーしたコマンドを実行します。

npx v0 add 7ulmWSS039r

コードを確認すると、先ほどのコードがプロジェクトにコピーされています。

code

そして、起動して確認してみます。

Nextjs

すばらしい!YouTube風のUIが一発で作成できました。
ここまで3分ほどしかかかってません。

さらに、このサービスのすごいところは、画像をアップロードすることでその画像に近いUIも作成してくれます。
こちらは無料では1回のみしか試すことができなかったので、いずれ紹介してみたいと思います。

今回は無料プランで試しましたが、いずれは有料プランのハイクオリティ出力も試してみたいと思います。

このサービスをうまく使えば、デザイナーさんに頼れない状況でも、開発者側でUIの生産性の向上が見込めると思います。

WPFで棒グラフを表示する

土井
ディアシステム(株)開発一部第2課

プロジェクトでWPF内での棒グラフの実装を行うことになり、苦労したことですし、せっかくなので調査した内容等をこちらで紹介します。
WPFで棒グラフを表示するためには様々な方法がありますが、
その中の一つとして、WPF内でWindows Form用のコントロールを使う方法があります。
今回MVVMモデルで記載しております。

動作環境:.NetFramework4.7.2 + xaml

ソリューションエクスプローラーのプロジェクトを右クリックし、「追加」→「参照」をクリックしてください。その後表示される「参照マネージャー」内の「アセンブリ」から以下の項目の参照を追加してください。

  • WindowsFormIntegration
  • System.Windows.Forms
  • System.Windows.Forms.DataVisualization

画像1

※上記の方法でWindowsFormIntegrationの参照ができなかった場合
「参照マネージャー」を開き、参照ボタンを押下します。
その後、以下のフォルダ内にある「WindowsFormsIntegration.dll」を選択してください。
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\WPF

XAMLに以下のコードを追記します。

MainWindow.xaml
<Grid>
<WindowsFormsHost x:Name="Chart1" />
</Grid>

コードビハインド(MainWindow.xaml.cs)には以下のコードを追加します。

MainWindow.xaml.cs
public MainWindow()
{
InitializeComponent();
MainWindowViewModel vm = new MainWindowViewModel();
this.DataContext = vm;

Chart1.Child = vm.chart1;
}

ViewModelには以下のコードを追加します。

MainWindowViewModel.cs
public class MainWindowViewModel
{
public Chart chart1;
Title title;
ChartArea chartArea1;
Series series1;

public MainWindowViewModel()
{
chart1 = new Chart();
title = new Title("タイトル");
chartArea1 = chart1.ChartAreas.Add("Area1");
series1 = new Series();

// 数値
Random rdm = new Random();

// X軸表示用の名前
string[] memberList = { "Aさん", "Bさん", "Cさん", "Dさん", "Eさん" };

// グラフの設定
SettingChart();

// グラフ要素の追加
for(int i = 0; i < 5; i++)
{
series1.Points.AddY(rdm.NextDouble());
series1.Points[i].AxisLabel = memberList[i];
}
}

private void SettingChart()
{
// グラフタイトル、軸ラベルの設定
title.DockedToChartArea = "Area1";
chartArea1.AxisX.Title = "X軸ラベル";
chartArea1.AxisY.Title = "Y軸ラベル";

// グラフの種類
series1.ChartType = SeriesChartType.Column;

// ChartにTitle,Seriesを追加
chart1.Titles.Add(title);
chart1.Series.Add(series1);
}
}

以下の棒グラフが表示されます。

画像2

またViewModelにSeriesを追加すると各個人の二つのデータを比較するということも行うことができます。

MainWindowViewModel.cs
        public MainWindowViewModel()
{
chart1 = new Chart();
title = new Title("タイトル");
chartArea1 = chart1.ChartAreas.Add("Area1");
series1 = new Series();
series2 = new Series();

・・・

// グラフ要素の追加
for(int i = 0; i < 5; i++)
{
series1.Points.AddY(rdm.NextDouble());
series2.Points.AddY(rdm.NextDouble());
series1.Points[i].AxisLabel = memberList[i];
}

・・・

// ChartにTitle,Seriesを追加
chart1.Titles.Add(title);
chart1.Series.Add(series1);
chart1.Series.Add(series2);

画像3

またグラフの上に数値や文字を表示する場合はseries1.Points[0から始まるグラフの順番].labelに表示させたい文字を入れることで可能です。
以下はグラフに自身の値をグラフの上に表示させている内容となります。

double value1;
double value2;
// グラフ要素の追加
for(int i = 0; i < 5; i++)
{
value1 = rdm.NextDouble();
value2 = rdm.NextDouble();
series1.Points.AddY(value1);
series1.Points[i].Label = Math.Round(value1,2).ToString();
series2.Points.AddY(value2);
series2.Points[i].Label = Math.Round(value2,2).ToString();
series1.Points[i].AxisLabel = memberList[i];
}

画像4

このグラフを使用する際の注意点ですが、2点あります。

  • コントローラが画面の最前面に表示されるため、グラフの前面に要素を配置することができない。
  • X軸の数を10個以上にすると全てのX軸の各グラフ名が表示されなくなる。

以上の2点です。

特に二つ目の点ですが、例えば以下のように グラフを10人分表示させようとした場合です。

            string[] memberList = { "Aさん", "Bさん", "Cさん", "Dさん", "Eさん","Fさん","Gさん","Hさん","Iさん","Jさん" };

// グラフの設定
SettingChart();

double value1;
double value2;
// グラフ要素の追加
for(int i = 0; i < 10; i++)
{
value1 = rdm.NextDouble();
value2 = rdm.NextDouble();
series1.Points.AddY(value1);
series1.Points[i].Label = Math.Round(value1,2).ToString();
series2.Points.AddY(value2);
series2.Points[i].Label = Math.Round(value2,2).ToString();
series1.Points[i].AxisLabel = memberList[i];
}

表示は以下のようになり、5人の名前しか表示されなくなってしまいます。

画像5

このX軸の表示ですが、10以上からはグラフの数が増えるほど表示するX軸の数も減っていくようです。

AWS SDK for JavaScript v3 への移行

箕浦
箕浦
ディアシステム(株)開発二部

こんにちは。開発 2 部 箕浦です。
サーバーレスの開発には欠かせないAWS Lambdaですが、ランタイムバージョンのサポートが切れると、
AWSはセキュリティパッチ等を適用しなくなり、サポート切れの関数はテクニカルサポートの対象ではなくなります。
さらに、新規作成や更新もできなくなるので、ランタイムのバージョンアップが必要になってきます。

今回はとある案件で、構築時はNode.js 16.xで作成していたLambda関数でしたが、
Node.js 16.x の 2024 年 6 月 12 日のサポート終了に伴い、Node.js 20.x へ移行いたしました。
その際、AWS SDKのバージョンもv2からv3へ移行する必要がありました。

v3自体は、Node.js 18.x から登場し、利用可能だったようですが、16のまま放置していたので、今回初めて移行を試みました。
今更な情報かもしれませんが、その際、いろいろソースコードを変更する箇所がありましたので、一部紹介します。

今回SDKにて利用しているサービスは、Lambda、S3、Cognito、DynamoDB、SES でしたのでこれらをピックアップします。

ポイントとしては、

  • ①インポート
  • ②呼び出し
  • ③エラーハンドリング

の3か所です。

インポート

従来は以下のように aws-sdk 自体をインポートして、それぞれのサービスのクライアントを生成する必要がありました。

aws-sdk v2
const aws = require('aws-sdk');
const documentClient = new aws.DynamoDB.DocumentClient();

v3 では以下のように個別のモジュールをインポートする必要があります。 面倒ですが、SDKをまるごとインポートするよりも個別にインポートした方がサイズを削減することが可能です。

aws-sdk v3
const { DynamoDBClient } = require("@aws-sdk/client-dynamodb");
const { DynamoDBDocumentClient, DeleteCommand } = require("@aws-sdk/lib-dynamodb");
const documentClient = DynamoDBDocumentClient.from(new DynamoDBClient({ region: 'ap-northeast-1' }));

cognito, lambda, s3, ses の場合は、

aws-sdk v3
const {
CognitoIdentityProviderClient,
AdminCreateUserCommand,
AdminDeleteUserCommand,
} = require("@aws-sdk/client-cognito-identity-provider");
const { LambdaClient, InvokeCommand } = require("@aws-sdk/client-lambda");
const { S3Client, GetObjectCommand } = require("@aws-sdk/client-s3");
const { SESClient, SendEmailCommand } = require("@aws-sdk/client-ses");
const cognito = new CognitoIdentityProviderClient({});
const lambda = new LambdaClient({});
const s3 = new S3Client({});
const ses = new SESClient({ region: 'ap-northeast-1' });

このような感じです。

呼び出し

v2では、各サービスのAPIの呼び出し方は、一般的には クライアントが提供しているAPIに対応しているメソッドにパラメータを直接渡す方法でした。

aws-sdk v2
    const params = {
TableName: TABLE_NAME,
Key: {
UserName: user_id,
},
};
await documentClient.delete(params).promise();

v3 では、APIに対応しているCommandにパラメータを渡してコマンドを生成して、 それをクライアントのsendメソッドに渡してやります。

aws-sdk v3
    const params = {
TableName: TABLE_NAME,
Key: {
UserName: user_id,
},
};
await documentClient.send(new DeleteCommand(params));

さらにLambdaの場合は、戻り値のPayloadのParseの部分にも修正が必要でした

aws-sdk v2
    const ret = await lambda.invoke(params).promise();
const result = JSON.parse(ret.Payload);
aws-sdk v3
    const ret = await lambda.send(new InvokeCommand(params));
const result = JSON.parse(Buffer.from(ret.Payload).toString());

エラーハンドリング

v2 では、以下のように、例外が発生した際に、catchに渡される例外オブジェクトのcodeメンバを参照することで、
エラーハンドリングが可能でしたが、v3ではこの記述はだめでした。

aws-sdk v2
    try {
const ret = await cognito.send(new AdminCreateUserCommand(params));
} catch (e) {
if (e.code === 'UsernameExistsException') {
response.statusCode = 400;
body.resultCode = 'E0007';
} else if (e.code === 'InvalidPasswordException') {
response.statusCode = 400;
body.resultCode = 'E0016';
} else {
response.statusCode = 500;
body.resultCode = 'E0001';
}
response.body = JSON.stringify(body);
callback(null, response);
return;
}

v3では以下のように、instanceof を使ってハンドリングする必要がありました。

aws-sdk v3
    try {
const ret = await cognito.send(new AdminCreateUserCommand(params));
} catch (e) {
if (e instanceof UsernameExistsException) {
response.statusCode = 400;
body.resultCode = 'E0007';
} else if (e instanceof InvalidPasswordException) {
response.statusCode = 400;
body.resultCode = 'E0016';
} else {
response.statusCode = 500;
body.resultCode = 'E0001';
}
response.body = JSON.stringify(body);
callback(null, response);
return;
}

今回取り上げたサービスはほんの一部ですが、それ以外のサービスでは他にも変更点はある可能性はあります。
もし、同じ境遇の方いましたら、ご参考までに。

Webプッシュ通知についてブラウザ間の挙動の違いを調べてみた(フロントエンド編)

箕浦
箕浦
ディアシステム(株)開発二部

こんにちは。開発 2 部 箕浦です。
現在、関わっている案件でWebプッシュ通知について調べる機会がありましたので
実装の仕方からブラウザ間の挙動の違いを調査した結果を紹介します。
本記事は、後編であるフロントエンド編になります。

今回はフロントエンドはReactで実装します。

Service Worker

Webプッシュ通知は、ユーザーがウェブサイトを見ている状態だけでなく、他のサイトを見ているときや、別のアプリケーションを動かしているときなどにも通知されてほしいです。
WebアプリケーションはReact(Javascript)でブラウザ上で動作するものなので、基本的にはユーザーがウェブサイトを閲覧していないときは動作しません。
そのため、Webプッシュ通知を受け取ったときの動作は、本体のWebアプリケーションとは別のプロセスで動かしておいて、プッシュ通知の処理を行う仕組みが必要となります。
その役割を担うのがService Workerです。
Service Workerは、プッシュ通知だけでなく、バックグラウンドで何か処理をさせたいときなど用途はいろいろあります。
ただし、ブラウザの種類やバージョンにより、サポート状況や挙動が変わることがありますので事前に動作確認が必要となります。

publicフォルダ配下に以下の service-worker.js ファイルを作成します。 簡単に説明すると、
push イベントに対して、タイトルやメッセージなどを受け取り、 showNotification を使って、デスクトップにプッシュ通知を表示します。
notificationclick イベントに対して、通知がクリックされた際に、指定したURLへ遷移するようにしています。

service-worker.js
addEventListener('push', (event) => {
console.log('[Service Worker] Push Received.');
console.log(`[Service Worker] Push had this data: "${event}"`);

if (!(self.Notification && self.Notification.permission === 'granted'))
return;

var data = {};
if (event.data)
data = event.data.json();

console.log(data)

self.clients.matchAll().then(clients => {
clients.forEach(client => {
client.postMessage({
data: data
});
});
});

var title = data.data['pinpoint.notification.title'];
var message = data.data['pinpoint.notification.body'];
var icon = data.data['pinpoint.notification.imageIconUrl'];
var image = data.data['pinpoint.notification.imageUrl'];
var options = {
body: message,
icon: icon,
image: image,
data: data,
};
event.waitUntil(self.registration.showNotification(title, options));
});

addEventListener('notificationclick', (event) => {
event.notification.close();
event.waitUntil(
clients.openWindow(event.notification.data.data['pinpoint.url'])
);
});

React

React側ではまず、firebase のライブラリをインストールします。

npm install firebase

App.jsに前編でFirebaseコンソールからコピーしたコードスニペットをそのまま貼り付けます。

src/App.js
import { initializeApp } from "firebase/app";
import { getAnalytics } from "firebase/analytics";

const firebaseConfig = {
apiKey: "APIキー",
authDomain: "webpush-c7bed.firebaseapp.com",
databaseURL: "https://webpush-c7bed.firebaseio.com",
projectId: "webpush-c7bed",
storageBucket: "webpush-c7bed.appspot.com",
messagingSenderId: "586895317040",
appId: "アプリ ID",
measurementId: "G-SPL1GEMWDJ"
};

const app = initializeApp(firebaseConfig);
const analytics = getAnalytics(app);

同じく、以下のコードを追記します。
「サーバーキー」には、前編でFirebaseコンソールからコピーしたサーバーキーを設定します。
今回はサーバーキーや上記の設定は、ソースコードにハードコーディングしていますが、本番環境で使用する場合は、外から読み込むなどの仕組みが必要です。

src/App.js
import { getMessaging, getToken, isSupported } from "firebase/messaging";
const messaging = getMessaging(app);

const vapidKey = "サーバーキー"
var registeredServiceWorker;
navigator.serviceWorker.register('/service-worker.js').then((reg) => registeredServiceWorker = reg)

function App() {

useEffect(() => {

function requestPermission() {
isSupported().then((isSupport) => {
if (!isSupport) {
console.log('Messaging is not support.');
return
}

console.log('Requesting permission...');
Notification.requestPermission().then((permission) => {
if (permission === 'granted') {
console.log('Notification permission granted.');
getTokenRequest()
}
})
})
}

async function getTokenRequest() {
// Add the public key generated from the console here.
getToken(messaging, {
vapidKey: vapidKey,
serviceWorkerRegistration: registeredServiceWorker
})
.then((currentToken) => {
if (currentToken) {
// Send the token to your server and update the UI if necessary
// ...
console.log(`token: ${currentToken}`);
// ここで取得したトークンをサーバーへ送信する
} else {
// Show permission request UI
console.log('No registration token available. Request permission to generate one.');
// ...
}
}).catch((err) => {
console.log('An error occurred while retrieving token. ', err);
// ...
});
}
requestPermission();
}, []);

return (
<div className="App">
<div>
・・・
</div>
</div>
);
}

ここまでで実装は完了です。

プッシュ通知の送信

フロントエンドをローカルで起動します。

npm run start

ブラウザが起動すると、画面上部にプッシュ通知を許可もしくはブロックするがポップアップで表示されます。
ここで許可を選択しておきます。
ブロックを選択すると、プッシュ通知が届かなくなります。

permission

すると、トークンが払い出されます。 今回はわかりやすいようにトークンをデバッグコンソールに出力しています。

token

本来であれば、このトークンをサーバーへ何らかの方法で送り、サーバー側でユーザーと紐づけて管理しておきます。
今回はサーバーは省略しているので、このトークンをコピペすることにします。

今回はプッシュ通知の送信は簡単に確認するため、Amazon Pinpointのコンソール画面から送信します。
デバイストークンには先ほどコピーしたトークン
プッシュ通知サービスには「FCM」
を入力し、メッセージの内容を入れて、プッシュ通知を送信します。

pinpoint_1 pinpoint_2

送信を行うと、デスクトップの右下に無事プッシュ通知が表示されました!!

push-disp

ブラウザによる挙動

ここからは、ブラウザによるプッシュ通知の挙動を確認していきます。
今回はChrome、Edge、FireFoxの3種類で確認することにします。

デフォルトの状態でのプッシュ通知の表示

まずはデフォルトの状態でのプッシュ通知の表示は、

Chromeの場合

push-disp

Edgeの場合

push-edge

Firefoxの場合

push-firefox

こちらは、同じ結果となりました。

requireInteractionを有効

ユーザーがクリックするか閉じるかするまで、通知が自動的に閉じずに残る設定である requireInteraction を有効にした場合、

Chromeの場合

push-crome-with-button

Edgeの場合

push-edge

Firefoxの場合

push-firefox-with-button

こちらは、Edgeの場合は「閉じる」ボタンが表示されず、25秒ほどで通知の表示が消えました。 Edgeの場合、requireInteractionの設定だけではだめなようです。

プッシュ通知を閉じずに、連続して何回か送信した場合

プッシュ通知の「閉じる」ボタンを押さずに、連続して何回か送信した場合の動作を見てみます。

Chromeの場合

push-crome-with-button-3

Edgeの場合

push-edge

Firefoxの場合

push-firefox-with-button-3

ChromeとFirefoxでは、連続して送ると、3つまではデスクトップに表示されますが、それ以降は、 デスクトップに表示せず、通知管理に溜まっていく動作となっていました。
その状態で閉じるボタンで通知を閉じると通知管理に溜まっていたものが、 順番に表示されます。
Edgeでは、通知管理には溜まっていきますが、どれだけ送っても、デスクトップには1つまでの表示となっています。

ブラウザを起動していない状態でのプッシュ通知

ChromeとFirefoxでは、即時に通知表示されず、ブラウザを開いて、20秒ほど待っていると、 それまで溜まっていたものが一度に通知されてくる動作となっています。
それに対し、Edgeでは、ブラウザを起動していない状態でも、プッシュ通知が表示されました。

ブラウザによって、プッシュ通知のサポート状況や、実装は以後のバージョンアップで動作は変わる可能性がありますが、 現時点ではこのような差異がありました。
他にもいろいろな設定がありますので、今後も色々触ってみようと思います。

Webプッシュ通知についてブラウザ間の挙動の違いを調べてみた(バックエンド設定編)

箕浦
箕浦
ディアシステム(株)開発二部

こんにちは。開発 2 部 箕浦です。
現在、関わっている案件でWebプッシュ通知について調べる機会がありましたので
実装の仕方からブラウザ間の挙動の違いを調査した結果を紹介します。
本記事は、前編であるバックエンド設定編になります。

Webプッシュ通知とは

Webプッシュ通知とは、ウェブサイトからユーザーに対して通知を送信する仕組みです。
画像のようにウェブサイトにアクセスした際、通知の許可を求めるポップアップで「許可」を選択し、
デスクトップ右下にポップアップされるあれのことです。
ブラウザがサポートしている場合、ユーザーはウェブサイトから通知を受け取ることができます。

iOS16.4から既にサポートされており、iPhoneでもWebプッシュを受けれるようになっています。

webpush-permission

webpush

Webプッシュ通知を実装するには、バックエンド側の実装が必要になるのですが、Webプッシュといってもいろいろな方法があり、サービスも複数あります。

今回は、簡単に、Firebase Cloud Messaging と Amazon Pinpoint というサービスを組み合わせて実装します。 Firebase Cloud Messaging だけでもWebプッシュは可能ですが、管理コンソール画面からプッシュ送信することを考え、Amazon Pinpointの管理コンソールからの方が送りやすいため、Amazon Pinpointを組み合わせました。

さらに、今回は詳しく取り上げませんが、Amazon Pinpointを利用すると、ある特定のユーザグループのみWebプッシュを送信するという使い方ができますので、特定の地域に住む人のみとか、特定の年齢層の人のみにWebプッシュを送信するといったことも可能です。

Firebase

まずは、Firebase にプロジェクトを作成します。 Firebase を利用するにはGoogleアカウントが必要になります。

firebase-project

続いて、上記で作成したプロジェクトにウェブアプリを追加します。 今回は下のようなアプリを作成しました。

firebase-webapp

下の方の「SDKの設定と構成」の欄にnpm、CDN、Configでそれぞれ実装するときのコードスニペットが表示されていますので、フロント側にこれを組み込みます。
今回はReactで実装しますので、npmを選択します。

firebase-config

また、「Cloud Messaging」タブでAPIが有効になっていることを確認し、 「サーバーキー」もメモっておきます。

firebase-serverkey

Firebase Cloud Messagingの設定は以上です。

Amazon Pinpoint

つづいて、Amazon Pinpointの管理コンソールに入り、
こちらもプロジェクトを適当に作成し、 プッシュ通知の設定にてFirebase Cloud Messaging (FCM)の キー認証情報のAPIキーの欄に先ほどメモした「サーバーキー」を設定します。

pinpoint-config

Amazon Pinpointの設定は以上です。簡単ですね。

次回の記事では、フロント側の実装方法について解説し、実際の挙動を確認します。

お楽しみに!

未経験から始める
システムエンジニア

一生モノのITスキルを身につけよう

あなたの経験とスキルを
ディアシステムで発揮してください!