ChatGPT生成コード¶
https://qiita.com/yoshiweb/items/b46de8ca85bb59921f67
aws lambda関数のinvokeをmockするmotoのpythonテストコード¶
import unittest
from unittest.mock import patch
from moto import mock_lambda
import boto3
class TestLambdaFunction(unittest.TestCase):
@mock_lambda
def test_invoke_lambda_function(self):
# モックされたLambda関数を作成
lambda_client = boto3.client('lambda', region_name='us-east-1')
lambda_client.create_function(
FunctionName='test_function',
Runtime='python3.8',
Role='test-role',
Handler='lambda_function.lambda_handler',
Code={'ZipFile': b'...'}
)
# Lambda関数を呼び出し、モックされたレスポンスを取得
with patch('lambda_function.lambda_handler') as mock_lambda_handler:
mock_response = {'statusCode': 200, 'body': 'Mock Response'}
mock_lambda_handler.return_value = mock_response
# テスト対象のコードでLambda関数を呼び出す
result = lambda_client.invoke(FunctionName='test_function')
# モックされたレスポンスを確認
self.assertEqual(result['StatusCode'], 200)
self.assertEqual(result['Payload'].read().decode('utf-8'), 'Mock Response')
if __name__ == '__main__':
unittest.main()
pytest利用版
import pytest
from moto import mock_lambda
import boto3
@pytest.fixture
def lambda_client():
with mock_lambda():
yield boto3.client('lambda', region_name='us-east-1')
def test_invoke_lambda_function(lambda_client):
# モックされたLambda関数を作成
lambda_client.create_function(
FunctionName='test_function',
Runtime='python3.8',
Role='test-role',
Handler='lambda_function.lambda_handler',
Code={'ZipFile': b'...'}
)
# Lambda関数を呼び出し、モックされたレスポンスを取得
with patch('lambda_function.lambda_handler') as mock_lambda_handler:
mock_response = {'statusCode': 200, 'body': 'Mock Response'}
mock_lambda_handler.return_value = mock_response
# テスト対象のコードでLambda関数を呼び出す
result = lambda_client.invoke(FunctionName='test_function')
# モックされたレスポンスを確認
assert result['StatusCode'] == 200
assert result['Payload'].read().decode('utf-8') == 'Mock Response'
Pythonでリクエストにタイムアウトを設定し、エラーが発生した場合にリトライを行うコード¶
import requests
from retrying import retry
# リトライの条件を設定するデコレータ
@retry(stop_max_attempt_number=3, wait_fixed=2000) # 最大3回のリトライを行い、2秒ごとにリトライを行う
def make_request_with_timeout(url, timeout):
try:
response = requests.get(url, timeout=timeout)
response.raise_for_status() # エラーコードが返ってきた場合は例外を発生させる
return response
except (requests.Timeout, requests.ConnectionError) as e:
print(f"Error: {e}")
raise # 例外を再度発生させてリトライを行う
# 使用例
try:
response = make_request_with_timeout("https://example.com", timeout=5)
print("Success:", response.text)
except Exception as e:
print("Failed to make request:", e)
PythonでExponential Backoffをしたかったのでretryingモジュールを調べてみた
import requests
try:
response = requests.get("https://example.com", timeout=5)
response.raise_for_status()
status_code = response.status_code
print("Success - Status Code:", status_code)
except requests.exceptions.RequestException as e:
status_code = getattr(e.response, 'status_code', None)
if status_code:
print("Error - Status Code:", status_code)
else:
print("Error - No status code available")
print("Error:", e)
JavaScriptを使用してMicrosoft TeamsボットでFileConsentCardを利用してファイルをダウンロードするサンプルコードです。¶
const { ActionTypes, CardFactory } = require('botbuilder');
const { TeamsInfo } = require('botbuilder-core');
// FileConsentCardを作成する関数
function createFileConsentCard(fileUrl, fileName, fileSize) {
const consentCard = CardFactory.fileConsentCard(
{
description: `You are about to download: ${fileName} (${fileSize} bytes)`,
sizeInBytes: fileSize,
acceptContext: { fileUrl, fileName, fileSize },
declineContext: {}
}
);
return consentCard;
}
// ボットからファイルを送信するメイン関数
async function sendFile(context) {
const fileUrl = 'https://example.com/sample.pdf'; // ダウンロードするファイルのURL
const fileName = 'sample.pdf'; // ファイル名
const fileSize = 1024; // ファイルサイズ(バイト単位)
const consentCard = createFileConsentCard(fileUrl, fileName, fileSize);
await context.sendActivity({ attachments: [consentCard] });
}
// ユーザーのファイル承認/拒否のイベントを処理するハンドラー
async function handleFileConsent(context) {
const reply = context.activity.value;
if (reply.action === 'accept') {
// ファイルを承認した場合の処理
const fileUrl = reply.context.fileUrl;
// ファイルをダウンロードする処理を実行
// 例: ダウンロードリンクを送信する
await context.sendActivity(`You accepted the file download. Here is the download link: ${fileUrl}`);
} else {
// ファイルを拒否した場合の処理
await context.sendActivity('You declined the file download.');
}
}
// Bot Frameworkのハンドラーを登録
bot.onMessage(async (context, next) => {
if (context.activity.type === ActionTypes.Message) {
await sendFile(context);
}
await next();
});
bot.onEvent('fileConsent/invoke', async (context, next) => {
await handleFileConsent(context);
await next();
});
tmp¶
const fs = require('fs'); const path = require('path'); // ファイルを保存するディレクトリパスを指定 const saveDirectory = './tmp'; // 保存するファイル名を指定 const fileName = 'example.txt'; // 保存するデータを指定 const fileData = 'This is example file data.'; // ファイルを保存する関数 function saveFileToDisk(data, callback) { // ファイルパスを作成 const filePath = path.join(saveDirectory, fileName); // ファイルを書き込み fs.writeFile(filePath, data, (err) => { if (err) { console.error('Error saving file:', err); callback(err); } else { console.log('File saved successfully:', filePath); callback(null, filePath); } }); } // 保存するファイルを作成 saveFileToDisk(fileData, (err, filePath) => { if (err) { console.error('Error saving file:', err); } else { console.log('File saved successfully:', filePath); } });
const { CardFactory } = require('botbuilder'); // Adaptive CardのJSONデータ const cardData = { "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", "type": "AdaptiveCard", "version": "1.0", "body": [ { "type": "TextBlock", "text": "Hello, Adaptive Card!", "size": "large", "weight": "bolder" }, { "type": "Image", "url": "https://adaptivecards.io/content/adaptive-card-50.png", "size": "medium" }, { "type": "TextBlock", "text": "This is an Adaptive Card.", "wrap": true } ] }; // Adaptive Cardを作成する const adaptiveCard = CardFactory.adaptiveCard(cardData); // このAdaptive Cardを含むメッセージを作成する const messageWithAdaptiveCard = { type: 'message', text: 'Here is an Adaptive Card:', attachments: [adaptiveCard] };
async function fetchWithRetry(
url: string,
options: RequestInit = {},
retries: number = 3,
delay: number = 1000
): Promise<Response> {
for (let i = 0; i < retries; i++) {
try {
const response = await fetch(url, options);
if (response.status >= 400) {
throw new Error(`HTTP Error: ${response.status}`);
}
// ステータスコードが400未満の場合は、成功としてレスポンスを返す
return response;
} catch (error) {
if (i < retries - 1) {
console.warn(`Request failed (attempt ${i + 1}), retrying in ${delay}ms...`);
await new Promise((resolve) => setTimeout(resolve, delay));
} else {
console.error('Max retries reached. Throwing error.');
throw error;
}
}
}
throw new Error('Unexpected error'); // ここに到達することはないはずですが、型の安全性のために追加しています
}
// 使用例
(async () => {
try {
const response = await fetchWithRetry('https://example.com/api/data', { method: 'GET' });
const data = await response.json();
console.log(data);
} catch (error) {
console.error('Final error after retries:', error);
}
})();
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyAccessToSpecificBucket",
"Effect": "Deny",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::test-hidden-774313473161-1",
"arn:aws:s3:::test-hidden-774313473161-2",
"arn:aws:s3:::test-hidden-774313473161-1/*",
"arn:aws:s3:::test-hidden-774313473161-2/*"
]
}
]
}
sed ':a;N;$!ba;s/\("[^"]*\)\n\([^"]*"\)/\1 \2/g' input.csv > output.csv sed ':a; /"$/!{N; s/\n/ /; ba}' input.csv > output.csv
awk '{ if (match($0, /"$/)) { print gensub(/\n/, " ", "g") } else { printf gensub(/\n/, " ", "g") } }' RS='"' ORS='"' input.csv > output.csv
import React, { useState } from 'react';
const TextAreaComponent: React.FC = () => {
// useStateフックを使用して、入力値を管理するstateを定義
const [text, setText] = useState<string>('');
// textareaの入力値が変更されたときに呼び出される関数
const handleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
setText(event.target.value);
};
return (
<div>
<textarea
value={text}
onChange={handleChange}
placeholder="ここにテキストを入力してください"
/>
<p>入力内容: {text}</p>
</div>
);
};
export default TextAreaComponent;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@RestController
@RequestMapping("/api/pdf")
public class PdfController {
@GetMapping("/download")
public ResponseEntity<byte[]> downloadPdf(HttpServletResponse response) {
try {
// PDF生成 (今回は簡易的に空のPDFファイルを生成)
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
// サンプルのPDFファイルの生成(Apache PDFBoxやiTextなどのライブラリを使用可能)
// ここでは空のPDFを作成する例
outputStream.write(new byte[]{ 0x25, 0x50, 0x44, 0x46, 0x2D, 0x31, 0x2E, 0x34 }); // %PDF-1.4
// ヘッダーを設定してレスポンスに書き込み
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Disposition", "inline; filename=sample.pdf");
headers.add("Content-Type", "application/pdf"); // Content-Typeをapplication/pdfに設定
return ResponseEntity
.status(HttpStatus.OK)
.headers(headers)
.body(outputStream.toByteArray());
} catch (IOException e) {
e.printStackTrace();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
}
import { visit } from 'unist-util-visit'; import { Root, Text } from 'hast'; // AST の型定義 // 角括弧で囲まれた数式を $...$ に変換する関数 export function rehypeCustomKatex() { return (tree: Root) => { visit(tree, 'text', (node: Text) => { // 角括弧で囲まれた数式を $...$ に変換 node.value = node.value.replace(/\[([^[\]]+)\]/g, (_, math) => `$${math}$`); }); }; }
// Strategy インターフェース
interface PaymentStrategy {
pay(amount: number): void;
}
// ConcreteStrategy クラス:クレジットカードで支払う戦略
class CreditCardPayment implements PaymentStrategy {
private name: string;
private cardNumber: string;
constructor(name: string, cardNumber: string) {
this.name = name;
this.cardNumber = cardNumber;
}
pay(amount: number): void {
console.log(`Paid ${amount} using Credit Card. Name: ${this.name}, Card Number: ${this.cardNumber}`);
}
}
// ConcreteStrategy クラス:PayPalで支払う戦略
class PayPalPayment implements PaymentStrategy {
private email: string;
constructor(email: string) {
this.email = email;
}
pay(amount: number): void {
console.log(`Paid ${amount} using PayPal. Email: ${this.email}`);
}
}
// Context クラス:支払い方法を保持し、操作する
class PaymentContext {
private strategy: PaymentStrategy;
constructor(strategy: PaymentStrategy) {
this.strategy = strategy;
}
setStrategy(strategy: PaymentStrategy): void {
this.strategy = strategy;
}
processPayment(amount: number): void {
this.strategy.pay(amount);
}
}
// クライアントコード
const creditCardPayment = new CreditCardPayment("John Doe", "1234-5678-9012-3456");
const payPalPayment = new PayPalPayment("john.doe@example.com");
const paymentContext = new PaymentContext(creditCardPayment);
paymentContext.processPayment(100); // クレジットカードで支払い
paymentContext.setStrategy(payPalPayment);
paymentContext.processPayment(200); // PayPalで支払い
const str = "[123]";
const regex = /\[(\d+)\]/;
const match = str.match(regex);
if (match) {
console.log(match[1]); // "123" (括弧内の数値にアクセス)
}
type Item = { id: number; name: string }; const array: Item[] = [ { id: 1, name: "xxx" }, { id: 2, name: "yyy" }, ]; const dictionary = array.reduce((acc, item) => { acc[item.id] = item; return acc; }, {} as { [key: number]: Item }); console.log(dictionary);
package com.example.demo;
import java.net.URL;
import java.nio.file.Paths;
public class Main {
public static void main(String[] args) throws Exception {
URL resourceUrl = Main.class.getProtectionDomain().getCodeSource().getLocation();
String absolutePath = Paths.get(resourceUrl.toURI()).toAbsolutePath().toString();
System.out.println("絶対パス: " + absolutePath);
}
}
import React, { useState } from "react"; import pako from "pako"; const GzipComponent: React.FC = () => { const [inputText, setInputText] = useState<string>(""); const [compressedData, setCompressedData] = useState<string>(""); const [decompressedText, setDecompressedText] = useState<string>(""); // Gzip圧縮 const handleCompress = () => { try { const binaryData = new TextEncoder().encode(inputText); // 文字列をバイナリに変換 const compressed = pako.gzip(binaryData); // Gzip圧縮 setCompressedData(Buffer.from(compressed).toString("base64")); // Base64エンコード } catch (error) { console.error("圧縮エラー:", error); } }; // Gzip解凍 const handleDecompress = () => { try { const binaryData = Buffer.from(compressedData, "base64"); // Base64デコード const decompressed = pako.ungzip(binaryData, { to: "string" }); // Gzip解凍 setDecompressedText(decompressed); } catch (error) { console.error("解凍エラー:", error); } }; return ( <div style={{ padding: "20px", maxWidth: "600px", margin: "auto" }}> <h2>Gzip 圧縮・解凍デモ</h2> <textarea value={inputText} onChange={(e) => setInputText(e.target.value)} placeholder="ここにテキストを入力" rows={4} style={{ width: "100%" }} /> <button onClick={handleCompress} style={{ margin: "10px" }}> 圧縮 </button> <button onClick={handleDecompress} disabled={!compressedData}> 解凍 </button> <h3>圧縮データ(Base64):</h3> <textarea readOnly value={compressedData} rows={4} style={{ width: "100%" }} /> <h3>解凍後のテキスト:</h3> <textarea readOnly value={decompressedText} rows={4} style={{ width: "100%" }} /> </div> ); }; export default GzipComponent;
function sortByKeyDesc(array, key) {
return [...array].sort((a, b) => (b[key] > a[key] ? 1 : -1));
}
// 使用例
const data = [
{ name: "Alice", age: 25 },
{ name: "Bob", age: 30 },
{ name: "Charlie", age: 22 }
];
const sortedData = sortByKeyDesc(data, "age");
console.log(sortedData);
// 出力: [ { name: 'Bob', age: 30 }, { name: 'Alice', age: 25 }, { name: 'Charlie', age: 22 } ]
function formatUnixTime(unixTime: number): string { // Unixタイムが秒単位の場合、ミリ秒に変換 if (unixTime < 1e10) { unixTime *= 1000; } const date = new Date(unixTime); // フォーマットされた日付文字列を生成 const formattedDate = date.toLocaleString("ja-JP", { year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", hour12: false, }); // `yyyy/MM/dd HH:mm` 形式になっているので、`-` に置換 return formattedDate.replace(/\//g, "-").replace(" ", " "); } // テスト const unixTime = 1710514800; // 例: 2024-03-15 12:00 UTC (秒単位) console.log(formatUnixTime(unixTime)); // 2024-03-15 21:00(日本時間)