Loading [MathJax]/extensions/tex2jax.js

2025-03-12

Python: xapiでステートメントを登録する(Learning Locker)

 表題の通り、LRSとしてLearning Lockerを使うことになったので、まずはPythonでのデータ(ステートメント)の登録方法など。一般的には、MoodleなどのLMSからLRSに送るので、コードでガリガリということはあまりないと思いますが・・・。

留意点としては(Learning Lockerを前提にしていますが)、

  •  エンドポイントのportは8081
  • usernameとかpasswordは、Learning Lockerにある管理画面のKey, Secretなどが該当
  • headerには"X-Experience-API-Version"が必須
というところですね。

import requests
import json
from datetime import datetime, timezone
from base64 import b64encode
# Learning Locker LRS のエンドポイント情報
LRS_ENDPOINT = "http://localhost:8081/data/xAPI/statements"
LRS_USERNAME = "xxxxxxx"
LRS_PASSWORD = "xxxxxx"
# Basic認証ヘッダーの作成
def get_auth_header():
auth_string = f"{LRS_USERNAME}:{LRS_PASSWORD}"
auth_encoded = b64encode(auth_string.encode()).decode()
return {"Authorization": f"Basic {auth_encoded}"}
# xAPI ステートメントの作成
def create_xapi_statement():
statement = {
"actor": {
"mbox": "mailto:example@example.com",
"name": "John Doe",
"objectType": "Agent"
},
"verb": {
"id": "http://adlnet.gov/expapi/verbs/completed",
"display": {"en-US": "completed"}
},
"object": {
"id": "http://example.com/activities/lesson1",
"definition": {
"name": {"en-US": "Lesson 1"},
"description": {"en-US": "The first lesson"}
},
"objectType": "Activity"
},
"timestamp": datetime.now(timezone.utc).isoformat()
}
return statement
# xAPI ステートメントの送信
def send_xapi_statement():
headers = {
"Content-Type": "application/json",
"X-Experience-API-Version": "1.0.3", #これが必要です
**get_auth_header()
}
statement = create_xapi_statement()
response = requests.post(LRS_ENDPOINT, headers=headers, json=statement)
if response.status_code == 200 or response.status_code == 204:
print("xAPI ステートメントが正常に送信されました。")
else:
print(f"エラー: {response.status_code}, {response.text}")
if __name__ == "__main__":
send_xapi_statement()


2025-03-10

AWS Lambda: [ERROR] ProfileNotFound: The config profile (xxxx) could not be found

Chaliceを使ってPythonコードをlamdaにデプロイしたら、Internal Errorのリターンがあり、表題のようなエラーがCloud Watchで確認できました。エラーの意味は、xxxxってプロファイルがないよってことなんですが。。。。

原因と解決策

原因は、ローカルで指定している Crediencialのプロファイルが、サーバー側にはないよってこと。

解決策は、デプロイするコードにはprofileを指定する記述をなくす。。ということにようです。sonnnet3.7の回答がそうだったので、実際そうすると動きました。でも何かスマートじゃないな。




2025-03-07

ClineでBedrock(Sonnet3.7)を指定した際のAPI Request Failedへの対応

巷で話題のClineを使ってみました。モデルの選択にAWS BedRockを経由できるらしく、おちラボではBedrockを研究費で使っているので、ラボ内で本格的に利用しても予算的に安心ではあります。。。で、モデルはClaudeを使いたいわけで、最近はSonnet3.7が出ているようなのでそれを指定すると、API Request Failedのエラーが?!

400 Invocation of model ID anthropic.claude-3-7-sonnet-20250219-v1:0 with on-demand throughput isn’t supported. Retry your request with the ID or ARN of an inference profile that contains this model.

というエラーで。。。オンデマンド対応してない?もともと使っていたSonnet3.5v1ならOK。Sonnet3.5v2なら同様のエラー。なんだこりゃ?3.5v2から仕様が変更になったのかと思いましたが、正解は。。。

  • Use cross-region inference にチェックを入れる

でした。開発効率を上げる手段として生成AI利用は魅力。ゼミ生が有料のサービスの利用に躊躇しているようなので、希望すれば使わせたいなと思います。

ちなみに、個人的なClineの感想。まあ、便利そうだけど勝手に色々言ってくるのは正直鬱陶しいなというきますが、それは私が昭和な人間だからですかね。



2025-02-15

Windows:Macで圧縮されたZipをWindowsで文字化けなく解凍する方法

ここ最近、Macを使う比重が増えてきているんですが、とりあえず自宅のメインマシンがまだWindowsなので両刀使いでいますが、たまに表題の通り、Zipファイルの文字化け問題が起きます。Mac→Windowsの場合ですね。

解決策:CubeIceを入れましょう

フリーの解凍ソフト(CubePDF)で実績のあるCube社のCubeIceがオススメです。




PowerShellでCSVファイルを連結する際の文字化け対策

表題の通り。。。受け取った複数のcsvファイルをcatコマンドで1つにまとめようとしたら、文字バケが起きて、うまくいかなかったので。。。。

  • 入力ファイル ・・・ SJIS
  • 結合ファイル ・・・ SJIS
という条件です。cat コマンド、typeコマンドもいずれも文字コード指定がなさそう?で、リダイレクト(>)でファイル出力すると文字化けが発生。

解決策
下記のように、PowerShellのコマンドである Get-Contentでファイルを読み込み、パイプでSet-Content で渡せばいいらしい。文字コードの指定もできるようだ。

Get-Content *.csv -Encoding Shift-JIS | Set-Content all.csv -Encoding Shift-JIS

参考サイト



2025-02-09

Java:標準出力の内容をとってくる方法

 JavaでSystem.out.printlnなどで標準出力に出てくる内容を捕獲する方法です。コンソールへの出力をチェックしたいときに使えます

// 元の標準出力を保存
PrintStream originalOut = System.out;
// 出力を捕捉するためのバイト配列ストリームを作成
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream newOut = new PrintStream(baos);
// 標準出力を新しいストリームに変更
System.setOut(newOut);
//標準出力の例
System.out.println("aaaaa")
System.out.println("bbbbb")
// 標準出力を元に戻す
System.setOut(originalOut);
// 捕捉した出力を取得
String[] output = baos.toString().split(System.lineSeparator());
System.out.println(output[0]); // aaaaaが出力


2025-02-06

 FletでDropDownリストの選択された表示名を取得しようとしたら、意外と情報なかったのでメモ書き。要は、選択されたキーのオプションを探し出してtextを呼び出せばいいということらしい。もっとシンプルな方法ないのかな?

def dropdown_changed(e):
selected_fruit = e.control.value
for option in dropdown.options:
if(selected_fruit == option.key):
print(option.text) //表示名
print(option.key) //値
break