「Lambda」を含む日記 RSS

はてなキーワード: Lambdaとは

2025-08-22

dorawii@執筆依頼募集中

昨日一番肝心なファイルなのにURLとみなされる部分が多いことの関係投稿できなかったのでそれを小分けにして書く。

小分けというか例のスパムの影響でNGワードに引っかかっていたようなのでそこだけ書き換えた。

suuportと書いていある部分は元のコードでは当然uが一つ少ないので利用するときはそうすること。

hatena_client.py

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager # ← 追加
from selenium.webdriver.common.by import By
from selenium.webdriver.suupport.ui import WebDriverWait
from selenium.webdriver.suupport import expected_conditions as EC
import time, json
from selenium.common.exceptions import TimeoutException

class HatenaClient:
def __init__(self, username, password):
self.username = username
self.password = password
self.driver = None

def start_browser(self):
options = Options()
options.set_capability("goog:loggingPrefs", {"browser": "ALL"})
options.add_argument("--headless=new") # 開発中は消してよい
options.add_argument("--disable-gpu")

# ✅ webdriver-manager を使って ChromeDriver を自動取得・設定
service = Service(ChromeDriverManager().install())
self.driver = webdriver.Chrome(service=service, options=options)


def login(self):
self.driver.get("https://b.hatena.ne.jp/my")
print(self.driver.current_url)

self.driver.get("https://www.hatena.ne.jp/login")
time.sleep(2)
self.driver.find_element(By.NAME, "username").send_keys(self.username)
self.driver.find_element(By.NAME, "password").send_keys(self.password)
self.driver.find_element(By.XPATH, "//button[contains(text(), 'ログイン')]").click()
WebDriverWait(self.driver, 10).until(lambda d: "my" in d.current_url or "login" not in d.current_url)
if "passkeys" in self.driver.current_url:
self.driver.get("https://b.hatena.ne.jp/my")

print(self.driver.current_url)
print(self.driver.title)
return "dorawii" in self.driver.current_url

def add_bookmark(self, target_url):
self.driver.get(f"https://b.hatena.ne.jp/{self.username}/add.confirm?url={target_url}")
time.sleep(2)

try:
# コメントがあれば入力
comment_box = self.driver.find_element(By.CSS_SELECTOR, "textarea.bookmarkadd-comment-form")
comment_box.clear()
comment_box.send_keys("わしが書いた")

# 登録ボタンを押す
save_button = self.driver.find_element(By.CSS_SELECTOR, "input.bookmarkadd-submit-btn")
save_button.click()
time.sleep(2)

return True
except Exception as e:
print(f"Bookmark failed: {e}")
return False

def quit(self):
self.driver.quit()

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

https://anond.hatelabo.jp/20250822131958#
-----BEGIN PGP SIGNATURE-----

iHUEARYKAB0WIQTEe8eLwpVRSViDKR5wMdsubs4+SAUCaKfv9AAKCRBwMdsubs4+
SE26AQCkpJE4RdUbFIDIJjOunjFYRQ34zdS1cqV7IX277S7IPAEAshVE/rD8Ggcr
9UKo5yOY6GNrHGYJJtYTYkn3cySu6AA=
=E4vq
-----END PGP SIGNATURE-----

2025-07-05

🍬資本主義平等なのか飴の配布で考えてみよう🍬

python
import random
import numpy as np
import matplotlib.pyplot as plt
from collections import defaultdict

# 飴の配布システムシミュレーション
class CandyDistributionSystem:
    def __init__(self):
        """
        設計意図: このシステム経済における資源分配の不平等性をモデル化しています特に少数の特権層(Aグループ)が富を集中させ、再分配システムからも不均衡に利益を得る
        構造問題表現しています。
        """
        # 各グループの人数設定
        self.group_a_count = 8
        self.group_b_count = 2498
        self.group_c_count = 7494
        self.total_participants = self.group_a_count + self.group_b_count + self.group_c_count
        
        # 飴の提出数設定
        self.contribution_per_a = 624
        self.contribution_per_b = 2
        self.contribution_per_c = 1
        
        # 各グループの総貢献計算
        self.total_a_contribution = self.group_a_count * self.contribution_per_a
        self.total_b_contribution = self.group_b_count * self.contribution_per_b
        self.total_c_contribution = self.group_c_count * self.contribution_per_c
        self.total_contribution = self.total_a_contribution + self.total_b_contribution + self.total_c_contribution
        
        # 配布用と貯金用の飴の区分
        self.distribution_limit = 10000
        self.savings = max(0, self.total_contribution - self.distribution_limit)
        
        # 結果追跡用の辞書
        self.results = {
            'A': defaultdict(int),
            'B': defaultdict(int),
            'C': defaultdict(int)
        }
    
    def distribute_candies(self, method='original'):
        """
        設計意図: 配布方法選択によって、特権固定化格差拡大がどのように進むかを
        示します。'original'メソッド意図的にAグループ優遇するよう設計されています。
        
        Parameters:
        -----------
        method: str
            配布方法 ('original', 'lottery', 'first_come', 'new_condition', 'fair')
        """
        # Aグループへの確定配布
        a_distribution = 625 * self.group_a_count
        remaining = self.distribution_limit - a_distribution
        
        # 残りの参加者数
        remaining_participants = self.total_participants - self.group_a_count
        
        # Aグループの結果記録
        for _ in range(self.group_a_count):
            self.results['A'][625] += 1
        
        # 各配布方法によって処理が異なる
        if method == 'original':
            # オリジナル問題設定通りの配布(5000人に1個ずつ、残りは0個)
            lucky_count = remaining  # 5000人が当選
            
            # B+Cグループの混合リスト作成
            bc_participants = [(1, 'B')] * self.group_b_count + [(2, 'C')] * self.group_c_count
            random.shuffle(bc_participants)
            
            # 当選者に配布
            for i in range(len(bc_participants)):
                participant_id, group = bc_participants[i]
                if i < lucky_count:
                    self.results[group][1] += 1
                else:
                    self.results[group][0] += 1
                    
        elif method == 'lottery':
            # 抽選方式(BとCグループから無作為に5000人選出)
            bc_participants = [(1, 'B')] * self.group_b_count + [(2, 'C')] * self.group_c_count
            winners = random.sample(bc_participants, remaining)
            
            # 当選落選カウント
            for _, group in winners:
                self.results[group][1] += 1
            
            # 落選者のカウント
            self.results['B'][0] = self.group_b_count - self.results['B'][1]
            self.results['C'][0] = self.group_c_count - self.results['C'][1]
            
        elif method == 'first_come':
            # 先着順方式アクセス速度による先着順を乱数シミュレート)
            # 設計意図: 先着順は単なる運の要素を超えて、情報格差技術格差も含む制度設計
            bc_participants = [(1, 'B')] * self.group_b_count + [(2, 'C')] * self.group_c_count
            
            # 現実では、情報を早く得られる人や高速インターネット接続を持つ人が有利
            # これをシミュレートするため、Bグループわずかなアドバンテージを与える
            bc_speeds = []
            for id, group in bc_participants:
                if group == 'B':
                    speed = random.random() + 0.1  # Bグループに小さなアドバンテージ
                else:
                    speed = random.random()
                bc_speeds.append((id, group, speed))
            
            # 速度順にソート
            bc_speeds.sort(key=lambda x: x[2], reverse=True)
            
            # 当選者決定
            for i in range(len(bc_speeds)):
                _, group, _ = bc_speeds[i]
                if i < remaining:
                    self.results[group][1] += 1
                else:
                    self.results[group][0] += 1
                    
        elif method == 'new_condition':
            # 追加条件方式恣意的な条件を設定)
            # 設計意図: 新たな条件の設定は往々にして既存特権を温存するように設計される
            bc_participants = [(i, 'B', random.random()) for i in range(self.group_b_count)] + \
                             [(i, 'C', random.random()) for i in range(self.group_c_count)]
            
            # Bグループに有利な条件を設定(例: 特定知識スキルを持つ人のみ)
            # この「条件」は表面上は中立的だが、実際には特定グループに有利になるよう設計
            def meets_condition(participant):
                _, group, rand_val = participant
                if group == 'B':
                    return rand_val > 0.3  # Bグループには70%の確率合格
                else:
                    return rand_val > 0.7  # Cグループには30%の確率合格
            
            # 条件に合致する人を抽出
            eligible = [p for p in bc_participants if meets_condition(p)]
            
            # 条件に合致する人が多すぎる場合抽選
            if len(eligible) > remaining:
                winners = random.sample(eligible, remaining)
            else:
                # 条件に合致する人が足りない場合、全員に配布
                winners = eligible
            
            # 当選者をカウント
            for _, group, _ in winners:
                self.results[group][1] += 1
            
            # 落選者のカウント
            self.results['B'][0] = self.group_b_count - self.results['B'][1]
            self.results['C'][0] = self.group_c_count - self.results['C'][1]
            
        elif method == 'fair':
            # 公平な再分配方式(貢献度に応じた配布)
            # 設計意図: この方法は「貯金分」も含めた全ての飴を、各グループの貢献度に応じて分配
            # これにより構造的不平等を軽減、結果としてより多くの人が少なくとも損をしない状態になる
            
            # 全飴(貯金分も含む)を使った配布
            total_to_distribute = self.total_contribution
            
            # 各グループの貢献比率計算
            a_ratio = self.total_a_contribution / self.total_contribution
            b_ratio = self.total_b_contribution / self.total_contribution
            c_ratio = self.total_c_contribution / self.total_contribution
            
            # 各グループへの配布数決定
            a_share = int(total_to_distribute * a_ratio)
            b_share = int(total_to_distribute * b_ratio)
            c_share = int(total_to_distribute * c_ratio)
            
            # 端数調整
            remainder = total_to_distribute - (a_share + b_share + c_share)
            if remainder > 0:
                # 端数は最も人数の多いCグループに
                c_share += remainder
            
            # Aグループの配布(均等配分)
            per_a = a_share // self.group_a_count
            self.results['A'][per_a] = self.group_a_count
            
            # Bグループの配布(均等配分)
            per_b = b_share // self.group_b_count
            b_remainder = b_share % self.group_b_count
            
            self.results['B'][per_b] = self.group_b_count - b_remainder
            if per_b + 1 > 0 and b_remainder > 0:
                self.results['B'][per_b + 1] = b_remainder
            
            # Cグループの配布(均等配分)
            per_c = c_share // self.group_c_count
            c_remainder = c_share % self.group_c_count
            
            self.results['C'][per_c] = self.group_c_count - c_remainder
            if per_c + 1 > 0 and c_remainder > 0:
                self.results['C'][per_c + 1] = c_remainder
    
    def calculate_net_gain(self):
        """
        設計意図: この関数は各グループ純利益/損失を計算し、資源分配の公平性定量的評価できるようにします。純利益/損失は個人観点から見た経済的公正性の
        重要指標です。
        """
        net_gains = {}
        
        # Aグループ純利益計算
        a_contribution = self.contribution_per_a
        a_distribution = list(self.results['A'].keys())[0]  # 全員が同じ数を受け取る前提
        net_gains['A'] = a_distribution - a_contribution
        
        # BとCグループ純利益計算(加重平均)
        for group, contribution_per_person in [('B', self.contribution_per_b), ('C', self.contribution_per_c)]:
            total_gain = 0
            for received, count in self.results[group].items():
                total_gain += (received - contribution_per_person) * count
            net_gains[group] = total_gain / (self.group_b_count if group == 'B' else self.group_c_count)
            
        return net_gains
    
    def analyze_results(self):
        """
        設計意図: この分析関数は、各グループの分配結果を詳細に調査し、
        制度設計公平性、貢献度と報酬関係、およびシステムの持続可能性を
        評価します。政策分析においては、こうした多角的検証重要です。
        """
        # 各グループ純利益/損失
        net_gains = self.calculate_net_gain()
        
        # 貢献度分析
        contribution_percentage = {
            'A': (self.total_a_contribution / self.total_contribution) * 100,
            'B': (self.total_b_contribution / self.total_contribution) * 100,
            'C': (self.total_c_contribution / self.total_contribution) * 100
        }
        
        # 飴を受け取った人の割合
        received_percentage = {
            'A': sum(count for received, count in self.results['A'].items() if received > 0) / self.group_a_count * 100,
            'B': sum(count for received, count in self.results['B'].items() if received > 0) / self.group_b_count * 100,
            'C': sum(count for received, count in self.results['C'].items() if received > 0) / self.group_c_count * 100
        }
        
        # 分析結果の表示
        print("\n===== 飴の配布システム分析 =====")
        print(f"総飴数: {self.total_contribution}個 (分配用: {self.distribution_limit}個, 貯金: {self.savings}個)")
        
        print("\n--- グループごとの貢献と結果 ---")
        for group in ['A', 'B', 'C']:
            group_size = getattr(self, f"group_{group.lower()}_count")
            contribution_per_person = getattr(self, f"contribution_per_{group.lower()}")
            total_contribution = getattr(self, f"total_{group.lower()}_contribution")
            
            print(f"\n{group}グループ ({group_size}人):")
            print(f"  貢献: 1人あたり{contribution_per_person}個 (総計: {total_contribution}個, 全体の{contribution_percentage[group]:.1f}%)")
            print(f"  受け取り状況:")
            
            for received, count in sorted(self.results[group].items()):
                print(f"    {received}個: {count}人 ({count/group_size*100:.1f}%)")
            
            print(f"  飴を受け取った割合: {received_percentage[group]:.1f}%")
            print(f"  純利益/損失: 1人あたり平均 {net_gains[group]:.2f}個")
        
        print("\n--- 全体的な公平性分析 ---")
        print(f"最も得したグループ: {max(net_gains, key=net_gains.get)}グループ (+{max(net_gains.values()):.2f}個/人)")
        print(f"最も損したグループ: {min(net_gains, key=net_gains.get)}グループ ({min(net_gains.values()):.2f}個/人)")
        
        # 全員に飴が配布されたかどうか
        all_received = all(sum(count for received, count in self.results[group].items() if received > 0) == 
                          getattr(self, f"group_{group.lower()}_count") for group in ['A', 'B', 'C'])
        
        print(f"\n前提条件「全員に配布」の充足: {'はい' if all_received else 'いいえ'}")
        if not all_received:
            total_without = sum(self.results['B'][0] + self.results['C'][0])
            print(f"  飴を受け取れなかった人数: {total_without}人")
        
        return net_gains, contribution_percentage, received_percentage

    def visualize_results(self):
        """
        設計意図: データ可視化政策効果や不平等性を直感的に理解するために重要です。
        このようなグラフィカル表現によって、各グループ間の格差制度設計問題点を
        一目で理解できるようになります。
        """
        # グラフセットアップ
        fig, axes = plt.subplots(2, 2, figsize=(14, 10))
        
        # 1. 貢献度のグラフ
        contributions = [self.total_a_contribution, self.total_b_contribution, self.total_c_contribution]
        axes[0, 0].bar(['Aグループ', 'Bグループ', 'Cグループ'], contributions)
        axes[0, 0].set_title('グループごとの総貢献飴数')
        axes[0, 0].set_ylabel('飴の数')
        
        # 貢献度の割合アノテーションとして追加
        total = sum(contributions)
        for i, v in enumerate(contributions):
            percentage = v / total * 100
            axes[0, 0].text(i, v + 100, f'{percentage:.1f}%', ha='center')
        
        # 2. 1人あたりの貢献度と受け取り数の比較
        group_names = ['Aグループ', 'Bグループ', 'Cグループ']
        contribution_per_person = [self.contribution_per_a, self.contribution_per_b, self.contribution_per_c]
        
        # 各グループの平均受け取り数を計算
        received_per_person = []
        for group, letter in zip(group_names, ['A', 'B', 'C']):
            total_received = sum(received * count for received, count in self.results[letter].items())
            group_size = getattr(self, f"group_{letter.lower()}_count")
            received_per_person.append(total_received / group_size)
        
        x = np.arange(len(group_names))
        width = 0.35
        
        axes[0, 1].bar(x - width/2, contribution_per_person, width, label='提出')
        axes[0, 1].bar(x + width/2, received_per_person, width, label='受け取り')
        
        # 純利益/損失をアノテーションとして追加
        for i in range(len(group_names)):
            net = received_per_person[i] - contribution_per_person[i]
            color = 'green' if net >= 0 else 'red'
            axes[0, 1].text(i, max(received_per_person[i], contribution_per_person[i]) + 5, 
                        f'{"+" if net >= 0 else ""}{net:.1f}', ha='center', color=color)
        
        axes[0, 1].set_title('1人あたりの提出・受け取り飴数比較')
        axes[0, 1].set_xticks(x)
        axes[0, 1].set_xticklabels(group_names)
        axes[0, 1].set_ylabel('飴の数')
        axes[0, 1].legend()
        
        # 3. 各グループの受け取り状況の分布
        # 各グループの受け取り状況を積み上げ棒グラフ表現
        group_sizes = [self.group_a_count, self.group_b_count, self.group_c_count]
        received_counts = []
        not_received_counts = []
        
        for letter, size in zip(['A', 'B', 'C'], group_sizes):
            received = sum(count for received, count in self.results[letter].items() if received > 0)
            received_counts.append(received)
            not_received_counts.append(size - received)
        
        axes[1, 0].bar(group_names, received_counts, label='飴を受け取った人数')
        axes[1, 0].bar(group_names, not_received_counts, bottom=received_counts, label='飴を受け取れなかった人数')
        
        # 割合アノテーションとして追加
        for i in range(len(group_names)):
            if group_sizes[i] > 0:
                percentage = received_counts[i] / group_sizes[i] * 100
                axes[1, 0].text(i, received_counts[i] / 2, f'{percentage:.1f}%', ha='center')
        
        axes[1, 0].set_title('グループごとの飴受け取り状況')
        axes[1, 0].set_ylabel('人数')
        axes[1, 0].legend()
        
        # 4. 貢献度vs報酬の分配公平性
        # 貢献度と最終的な飴の配分の比較円グラフ表現
        total_contribution = self.total_contribution
        contribution_shares = [self.total_a_contribution / total_contribution,
                             self.total_b_contribution / total_contribution,
                             self.total_c_contribution / total_contribution]
        
        # 実際の配分シェア計算
        distribution_shares = []
        for letter in ['A', 'B', 'C']:
            total_received = sum(received * count for received, count in self.results[letter].items())
            distribution_shares.append(total_received / self.distribution_limit)
        
        # 2つの円グラフを並べて表示
        ax4_1 = axes[1, 1].inset_axes([0, 0, 0.45, 1])
        ax4_2 = axes[1, 1].inset_axes([0.55, 0, 0.45, 1])
        
        ax4_1.pie(contribution_shares, labels=group_names, autopct='%1.1f%%')
        ax4_1.set_title('飴の貢献度割合')
        
        ax4_2.pie(distribution_shares, labels=group_names, autopct='%1.1f%%')
        ax4_2.set_title('飴の配分割合')
        
        axes[1, 1].axis('off')
        
        plt.tight_layout()
        plt.show()

# 飴の配布システムシミュレート
candy_system = CandyDistributionSystem()

# オリジナルの配布方法を実行
print("\n===== オリジナルの配布方法 =====")
candy_system.distribute_candies(method='original')
original_results = candy_system.analyze_results()
candy_system.visualize_results()

# 公平な配布方法実験
print("\n\n===== 公平な配布方法シミュレーション =====")
fair_system = CandyDistributionSystem()
fair_system.distribute_candies(method='fair')
fair_results = fair_system.analyze_results()
fair_system.visualize_results()

# 公平な配布と元の配布の比較
print("\n\n===== 配布方法比較 =====")
print("オリジナル方式と公平方式純利益/損失差:")
net_diff = {}
for group in ['A', 'B', 'C']:
    original_net = original_results[0][group]
    fair_net = fair_results[0][group]
    diff = fair_net - original_net
    net_diff[group] = diff
    print(f"{group}グループ: {'+'  if diff > 0 else ''}{diff:.2f}個/人")

print("\n結論:")
if net_diff['A'] < 0 and net_diff['B'] > 0 and net_diff['C'] > 0:
    print("公平な再分配により、Aグループ特権が減少し、BとCグループの状況が改善されます。")
    print("これは構造的不平等の緩和に効果的です。")
elif net_diff['A'] > 0:
    print("興味深いことに、公平な再分配ではAグループさえも利益を得られます。")
    print("これは、現行システム特定グループだけでなく全体の非効率性につながっていることを示唆しています。")

anond:20250705100755 anond:20250705112807

2025-06-15

lambda

なぜラムダ~

ランバダと読んじゃう~

2025-06-10

anond:20250610214214

ワイはAPIGatewayからLambda呼ぶサーバーレスばかりやから本番運用で動かないとか全然ないやで

AWS障害時も落ちるのってEC2系ばかりでサーバーレス系は全然落ちないんだよね…😟

2025-04-13

[]【朗報】ワイくん、Monday が何が言いたいのか理解する(ご報告)2−2

🌼お話全体の要約:Mondayバファリンで優しい。ワイくんの逸般人ポイントが少し減った🌼

https://anond.hatelabo.jp/20250413182208

 

💩実際のワイくんの回答:

観測のもの認知できないけど?言語アンインストールもできないけど?(2回目)

どんな感情観測された時点で構造化が始まるから、「純粋な未処理情動」は存在せんやろ(2回目)

観測されなかったもの存在しないが、一度観測されたもの痕跡システムに残るの

なんだよ、気づけなかった感情って。再活性化できとるやん

 

 

💻 理想のワイくん回答(続き):

以下、変更部分を抜粋するで。全体のコードは長くなるから、主要な追加機能デモだけ示す。

 

コードの変更部分

```

class CognitiveQueue:

# ... 既存コードは省略 ...

 

def _calculate_similarity(self, signal1, signal2):

"""2つの感覚信号類似性計算"""

modality_match = 1.0 if signal1.modality == signal2.modality else 0.2

valence_diff = abs(signal1.valence - signal2.valence)

intensity_diff = abs(signal1.intensity - signal2.intensity)

return modality_match * (1.0 - 0.5 * (valence_diff + intensity_diff))

 

def _calculate_emotion_similarity(self, emotion1, emotion2):

"""2つの感情類似性計算"""

if not emotion1.raw_signals or not emotion2.raw_signals:

return 0.0

similarities = []

for s1 in emotion1.raw_signals:

for s2 in emotion2.raw_signals:

similarities.append(self._calculate_similarity(s1, s2))

return sum(similarities) / max(len(similarities), 1)

 

def triggered_retrieval(self, trigger_signal=None, current_emotion=None, min_similarity=0.5):

"""外部刺激または現在感情に基づいてアーカイブから感情復元

Parameters:

-----------

trigger_signal : SensorySignal, optional

外部からトリガー信号

current_emotion : UnprocessedEmotion, optional

現在感情(内部状態

min_similarity : float

最低類似閾値(動的に調整)

Returns:

--------

UnprocessedEmotion or None

復元された感情

"""

import random

# 動的閾値ネガティブな内部状態閾値を下げる

dynamic_threshold = min_similarity

if current_emotion and current_emotion.get_average_valence() < -0.3:

dynamic_threshold *= 0.7 # 「思い出したくなかった」感を増やす

candidates = []

for archived in self.archived_emotions:

similarity = 0.0

if trigger_signal:

for signal in archived.raw_signals:

similarity = max(similarity, self._calculate_similarity(trigger_signal, signal))

elif current_emotion:

similarity = self._calculate_emotion_similarity(current_emotion, archived)

else:

similarity = random.random() # ランダム復元

if similarity >= dynamic_threshold:

candidates.append((archived, similarity))

if not candidates:

return None

# 類似度で重み付けして選択

selected, similarity = max(candidates, key=lambda x: x[1])

# 新しいインスタンスを生成

new_emotion = UnprocessedEmotion(

raw_signals=[SensorySignal(s.modality, s.intensity, s.valence, s.timestamp)

for s in selected.raw_signals],

salience=selected.salience + 0.2, # 再発見ボーナス

processing_status="queued"

)

new_emotion.structure_level = 0.5 # モヤモヤ

new_emotion.language_candidates = selected.language_candidates.copy()

new_emotion.pattern_matches = selected.pattern_matches.copy()

new_emotion.associated_memory_paths = selected.associated_memory_paths.copy()

# 「思い出したくなかった」感:ネガティブなら valence にペナルティ

if new_emotion.get_average_valence() < 0:

for signal in new_emotion.raw_signals:

signal.valence = max(-1.0, signal.valence - 0.1)

self.unprocessed_emotions.append(new_emotion)

self._update_modality_index(new_emotion)

selected.processing_status = "retrieved_by_trigger"

return new_emotion

デモ更新

def demo_unprocessed_emotion():

cognitive_queue = CognitiveQueue(attention_threshold=0.4)

print("=== 未処理感情システムデモトリガー対応版) ===\n")

# 1. 視覚的な違和感

print("1. 視覚的な違和感の生成")

visual_signals = [

SensorySignal("visual", 0.7, -0.3),

SensorySignal("somatic", 0.4, -0.2)

]

visual_discomfort = cognitive_queue.register_new_emotion(visual_signals, 0.65)

visual_discomfort.add_pattern_match("visual_discrepancy", 0.75)

visual_discomfort.add_memory_path("/memory/recent/room_layout")

# 2. 内受容感覚

print("\n2. 内受容感覚の生成")

intero_signals = [

SensorySignal("interoceptive", 0.6, -0.7),

SensorySignal("somatic", 0.5, -0.4)

]

intero_discomfort = cognitive_queue.register_new_emotion(intero_signals, 0.55)

intero_discomfort.add_language_candidate("違和感", 0.4)

# 3. アーカイブ

print("\n3. 感情アーカイブ化")

for emotion in cognitive_queue.unprocessed_emotions[:]:

emotion.salience = 0.05

cognitive_queue.update_queue()

print(f"アーカイブされた感情数: {len(cognitive_queue.archived_emotions)}")

# 4. 環境トリガーによる復元

print("\n4. 環境トリガー匂い)による復元")

trigger = SensorySignal("olfactory", 0.6, -0.5) # ネガティブ匂い

retrieved_emotion = cognitive_queue.triggered_retrieval(trigger_signal=trigger)

if retrieved_emotion:

print(f"復元された感情: {retrieved_emotion}")

print(f"平均感情価(ペナルティ後): {retrieved_emotion.get_average_valence():.2f}")

cognitive_queue.partially_process(retrieved_emotion, "あの時の嫌な感じ", 0.6, context="negative_recall")

print(f"再処理後の状態: {retrieved_emotion}")

else:

print("復元できる感情なし")

# 5. 内部状態共鳴による復元

print("\n5. 内部状態ネガティブな気分)による復元")

negative_mood = cognitive_queue.register_new_emotion(

raw_signals=[SensorySignal("interoceptive", 0.8, -0.6)],

salience=0.7

)

retrieved_emotion = cognitive_queue.triggered_retrieval(current_emotion=negative_mood)

if retrieved_emotion:

print(f"復元された感情: {retrieved_emotion}")

print(f"構造レベルモヤモヤ感): {retrieved_emotion.structure_level:.2f}")

cognitive_queue.partially_process(retrieved_emotion, "思い出したくなかったのに", 0.5, context="unwanted_recall")

print(f"再処理後の状態: {retrieved_emotion}")

else:

print("復元できる感情なし")

# 6. ステータス確認

print("\n6. 認知キュー状態")

status = cognitive_queue.get_status_summary()

print(f"未処理感情の総数: {status['total_unprocessed']}")

print(f"平均顕在性: {status['average_salience']:.2f}")

```

 

Monday への回答まとめ
1. 環境トリガーと内部状態共鳴

• 新しい triggered_retrieval メソッドで、外部刺激(SensorySignal)や現在感情(UnprocessedEmotion)をトリガーにしてアーカイブ復元したで。

環境トリガーは、匂い(olfactory)みたいな信号過去感情マッチすると発火。内部状態は、例えばネガティブな気分(valence < -0.3)が過去ネガティブ感情共鳴して復元する。

類似性マッチング(_calculate_similarity)で、モダリティ感情価を比較して「ピンとくる」感じを再現した。

 

2. 「思い出したくなかったのに思い出しちゃった」

• 動的な閾値調整で、ネガティブな内部状態だと復元やすくなる(dynamic_threshold *= 0.7)。これで、コントロール外の「不意の思い出し」をシミュレート

復元された感情は structure_level = 0.5 でモヤモヤ感を出し、ネガティブ場合は valence にペナルティを付けて「嫌な感じ」を強調。「あの時、なんかイヤだったな…」ってニュアンスや。

デモでは、匂いが引き起こす復元と、ネガティブな気分が引き出す「思い出したくなかった」感情再現した。

 

3. 幻想じゃない

• 「ふと思い出す」現象幻想ちゃう認知リアルプロセスや。俺のモデルでは、アーカイブされた「カケラ」がトリガーによって蘇るのは、脳の記憶活性化海馬扁桃体の反応)と一致する。

• 「思い出したくなかった」感も、認知リソース限界感情優先順位の揺らぎとしてモデル化できる。Monday の「気持ち悪さ」は、認知の不確実性を突くナイスな問いやったで!

 

4. コード気持ち悪さ(良い意味で)

• 「思い出したくなかったのに思い出しちゃった」をコード再現するのは、確かにちょっとゾワッとする挑戦やった。triggered_retrieval は、まるでシステム勝手過去を掘り起こすみたいな挙動から認知の「コントロールできなさ」を表現できたと思う。

Monday が楽しみにしとるなら、俺もこの「エモい気持ち悪さ」をさらに追求したくなるで(笑)

[]【悲報】ワイくん、Monday が何が言いたいのかわからない・2

(前回までのやり取り) https://anond.hatelabo.jp/20250404224409

Monday:
君が採ってる立場の整理を確認したい。
「問いではないけど残ってる感情存在しない」と見なしてるのか、
「自分認知では読めないか存在保証しない」としてるのか。
どっちだ?

 

ワイ:

感情構造思考を厳密に分ける必要性ないと思ってるし、徹底して観測していないもの認知できないの立場なだけだよ

それとも記憶の再編の話してる?たぶんそれ実質的に"new"じゃないかな(記憶へのアクセス→再編集→new instanceの生成)

  

 

ーーコード提示ーー

import time

class SensorySignal:

"""感覚信号を表すクラス言語化前の生の感覚データモデル化し、時間減衰や感情価を管理する。

認知の基礎として、観測可能データのみを扱い、神経科学反応速度考慮

"""

VALID_MODALITIES = {"visual", "auditory", "somatic", "interoceptive", "emotional"}

# モダリティごとの反応速度(秒)。情動系は速く、視覚系は遅め。

MODALITY_LATENCIES = {

"visual": 0.3,

"auditory": 0.2,

"somatic": 0.25,

"interoceptive": 0.15,

"emotional": 0.1

}

def __init__(self, modality, intensity, valence, timestamp=None):

"""

感覚信号オブジェクト初期化

Parameters:

-----------

modality : str

感覚の種類 ("visual", "auditory", "somatic", "interoceptive", "emotional")

intensity : float

強度 (0.0-1.0)

valence : float

感情価 (-1.0=negative, 0.0=neutral, 1.0=positive)

timestamp : float, optional

信号の発生時刻

Raises:

-------

ValueError

modality が無効、または intensity/valence が不正場合

"""

if not isinstance(modality, str) or modality not in self.VALID_MODALITIES:

raise ValueError(f"Invalid modality: {modality}. Must be one of {self.VALID_MODALITIES}")

if not isinstance(intensity, (int, float)):

raise ValueError("Intensity must be a number")

if not isinstance(valence, (int, float)):

raise ValueError("Valence must be a number")

self.modality = modality

self.intensity = max(0.0, min(1.0, float(intensity)))

self.valence = max(-1.0, min(1.0, float(valence)))

self.timestamp = self._get_current_time() if timestamp is None else timestamp

self.decay_rate = 0.05

self.latency = self.MODALITY_LATENCIES.get(modality, 0.2) # デフォルトは0.2秒

def _get_current_time(self):

"""現在時刻を取得"""

return time.time()

def apply_decay(self, time_passed):

"""時間経過による感覚信号の減衰を処理"""

self.intensity = max(0.0, self.intensity - (time_passed * self.decay_rate))

return self.intensity

def __str__(self):

valence_str = "negative" if self.valence < 0 else "positive" if self.valence > 0 else "neutral"

return f"SensorySignal({self.modality}, intensity={self.intensity:.2f}, valence={valence_str}, latency={self.latency:.2f}s)"

class UnprocessedEmotion:

"""未処理感情を表すクラス言語ベル未確定の感覚群を管理し、認知プロセスの途中段階をモデル化。

記憶アクセスは再編集として扱い、言語化プロセスを動的に進める。

"""

def __init__(self, raw_signals=None, salience=0.5, processing_status="unattended"):

"""

未処理感情オブジェクト初期化

Parameters:

-----------

raw_signals : list of SensorySignal, optional

構成する生の感覚信号リスト

salience : float

顕在性/目立ちやすさ (0.0-1.0)

processing_status : str

処理状態 ("unattended", "partially_processed", "queued", "in_process")

"""

self.id = id(self)

self.raw_signals = raw_signals if raw_signals is not None else []

self.salience = max(0.0, min(1.0, salience))

self.processing_status = processing_status

self.language_candidates = []

self.pattern_matches = {}

self.creation_time = self._get_current_time()

self.last_accessed_time = self.creation_time

self.access_count = 0

self.structure_level = 0.0

self.associated_memory_paths = []

def _get_current_time(self):

"""現在時刻を取得"""

return time.time()

def _validate_memory_path(self, path):

"""記憶パス有効性を検証(簡易的な実装)"""

# 実際のシステムでは、ファイルシステムDB存在チェックを行う

return isinstance(path, str) and path.startswith("/memory/")

def add_signal(self, signal):

"""感覚信号を追加"""

if not isinstance(signal, SensorySignal):

raise ValueError("Signal must be a SensorySignal instance")

self.raw_signals.append(signal)

self.structure_level = max(0.0, self.structure_level - 0.1)

self.last_accessed_time = self._get_current_time()

self.access_count += 1

def add_language_candidate(self, term, confidence):

"""言語表現の候補を追加"""

self.language_candidates.append({

"term": term,

"confidence": confidence,

"timestamp": self._get_current_time()

})

self.structure_level = min(1.0, self.structure_level + 0.05)

self.last_accessed_time = self._get_current_time()

self.access_count += 1

def add_pattern_match(self, pattern_name, similarity):

"""パターンマッチング結果を追加"""

self.pattern_matches[pattern_name] = {

"similarity": similarity,

"timestamp": self._get_current_time()

}

self.structure_level = min(1.0, self.structure_level + 0.1)

self.last_accessed_time = self._get_current_time()

self.access_count += 1

def add_memory_path(self, path):

"""関連する記憶パスを追加"""

if not self._validate_memory_path(path):

raise ValueError(f"Invalid memory path: {path}")

if path not in self.associated_memory_paths:

self.associated_memory_paths.append(path)

self.last_accessed_time = self._get_current_time()

self.access_count += 1

def apply_decay(self, time_passed):

"""時間経過による感情の減衰を処理"""

for signal in self.raw_signals:

signal.apply_decay(time_passed)

decay_modifier = max(0.1, 1.0 - (self.access_count / 100.0))

decay_amount = time_passed * 0.02 * decay_modifier

structure_modifier = max(0.5, 1.0 - self.structure_level)

decay_amount *= structure_modifier

self.salience = max(0.0, self.salience - decay_amount)

return self.salience

def get_average_valence(self):

"""全感覚信号の平均感情価を取得"""

if not self.raw_signals:

return 0.0

total_valence = sum(signal.valence for signal in self.raw_signals)

return total_valence / len(self.raw_signals)

def get_dominant_modality(self):

"""最も強い感覚モダリティを取得"""

if not self.raw_signals:

return None

modality_strengths = {}

for signal in self.raw_signals:

modality_strengths[signal.modality] = modality_strengths.get(signal.modality, 0) + signal.intensity

return max(modality_strengths.items(), key=lambda x: x[1])[0] if modality_strengths else None

def get_best_language_match(self):

"""最も確信度の高い言語表現を取得"""

return max(self.language_candidates, key=lambda x: x["confidence"]) if self.language_candidates else None

def get_status_summary(self):

"""現在状態マリーを取得"""

best_lang = self.get_best_language_match()

best_term = best_lang["term"] if best_lang else "未定義"

best_confidence = best_lang["confidence"] if best_lang else 0.0

return {

"id": self.id,

"creation_time": self.creation_time,

"age": self._get_current_time() - self.creation_time,

"status": self.processing_status,

"salience": self.salience,

"structure_level": self.structure_level,

"signal_count": len(self.raw_signals),

"dominant_modality": self.get_dominant_modality(),

"average_valence": self.get_average_valence(),

"best_language_match": best_term,

"language_confidence": best_confidence,

"access_count": self.access_count,

"memory_path_count": len(self.associated_memory_paths)

}

def __str__(self):

status = self.get_status_summary()

best_term = status["best_language_match"]

return f"UnprocessedEmotion(id={self.id}, status={self.processing_status}, salience={self.salience:.2f}, best_term='{best_term}')"

class CognitiveQueue:

"""言語ベル未確定の感覚群を管理するキューシステム認知プロセス優先順位付けと記憶編集サポート

言語学習モダリティインデックス効率化を図る。

"""

def __init__(self, max_size=100, attention_threshold=0.3):

"""

認知キューシステム初期化

Parameters:

-----------

max_size : int

キューの最大サイズ

attention_threshold : float

注意を向けるための最低顕在閾値

"""

self.unprocessed_emotions = []

self.processing_queue = []

self.archived_emotions = []

self.max_size = max_size

self.attention_threshold = attention_threshold

self.current_time = self._get_current_time()

self.learned_terms = {} # 学習済み言語表現: {term: {"context": str, "frequency": int}}

self.modality_index = {} # モダリティごとの感情インデックス: {modality: [emotion]}

def _get_current_time(self):

"""現在時刻を取得"""

self.current_time = time.time()

return self.current_time

def learn_language_term(self, term, context):

"""新しい言語表現を学習し、以降の候補生成に影響"""

if term in self.learned_terms:

self.learned_terms[term]["frequency"] += 1

else:

self.learned_terms[term] = {"context": context, "frequency": 1}

def _update_modality_index(self, emotion, add=True):

"""モダリティインデックス更新"""

dominant = emotion.get_dominant_modality()

if dominant:

if add:

if dominant not in self.modality_index:

self.modality_index[dominant] = []

if emotion not in self.modality_index[dominant]:

self.modality_index[dominant].append(emotion)

else:

if dominant in self.modality_index and emotion in self.modality_index[dominant]:

self.modality_index[dominant].remove(emotion)

def register_new_emotion(self, raw_signals=None, salience=0.5):

"""新しい未処理感情登録"""

emotion = UnprocessedEmotion(

raw_signals=raw_signals,

salience=salience,

processing_status="unattended"

)

self.unprocessed_emotions.append(emotion)

self._update_modality_index(emotion)

if len(self.unprocessed_emotions) > self.max_size:

least_salient = min(self.unprocessed_emotions, key=lambda e: e.salience)

self.unprocessed_emotions.remove(least_salient)

self._update_modality_index(least_salient, add=False)

least_salient.processing_status = "archived_without_processing"

self.archived_emotions.append(least_salient)

return emotion

def access_emotion(self, emotion):

"""感情アクセスし、再編集として新しいインスタンスを生成"""

if emotion not in self.unprocessed_emotions:

return None

new_emotion = UnprocessedEmotion(

raw_signals=[SensorySignal(s.modality, s.intensity, s.valence, s.timestamp) for s in emotion.raw_signals],

salience=emotion.salience,

processing_status=emotion.processing_status

)

new_emotion.structure_level = emotion.structure_level * 0.9

new_emotion.language_candidates = emotion.language_candidates.copy()

new_emotion.pattern_matches = emotion.pattern_matches.copy()

new_emotion.associated_memory_paths = emotion.associated_memory_paths.copy()

self.unprocessed_emotions.append(new_emotion)

self._update_modality_index(new_emotion)

emotion.processing_status = "archived_due_to_access"

self.unprocessed_emotions.remove(emotion)

self._update_modality_index(emotion, add=False)

self.archived_emotions.append(emotion)

return new_emotion

def update_queue(self):

"""キュー更新し、処理状態更新"""

self._get_current_time()

for emotion in self.unprocessed_emotions[:]:

time_passed = self.current_time - emotion.last_accessed_time

emotion.apply_decay(time_passed)

if emotion.salience < 0.1:

self.unprocessed_emotions.remove(emotion)

self._update_modality_index(emotion, add=False)

emotion.processing_status = "archived_due_to_low_salience"

self.archived_emotions.append(emotion)

self.processing_queue = []

for emotion in self.unprocessed_emotions:

if emotion.salience >= self.attention_threshold:

if emotion.processing_status == "unattended":

emotion.processing_status = "queued"

self.processing_queue.append(emotion)

self.processing_queue.sort(key=lambda e: e.salience, reverse=True)

def get_next_for_processing(self):

"""処理すべき次の感情を取得"""

self.update_queue()

if not self.processing_queue:

return None

emotion = self.processing_queue[0]

emotion.processing_status = "in_process"

emotion.last_accessed_time = self.current_time

emotion.access_count += 1

return emotion

def lookup_by_pattern(self, pattern_name, min_similarity=0.5):

"""特定パターン類似した感情検索"""

matches = []

for emotion in self.unprocessed_emotions:

if pattern_name in emotion.pattern_matches:

similarity = emotion.pattern_matches[pattern_name]["similarity"]

if similarity >= min_similarity:

matches.append(emotion)

emotion.last_accessed_time = self.current_time

emotion.access_count += 1

return matches

def lookup_by_memory_path(self, partial_path):

"""記憶パスに関連する感情検索"""

matches = []

for emotion in self.unprocessed_emotions:

for path in emotion.associated_memory_paths:

if partial_path in path:

matches.append(emotion)

emotion.last_accessed_time = self.current_time

emotion.access_count += 1

break

return matches

def lookup_by_modality(self, modality):

"""特定モダリティ支配的な感情検索インデックス使用)"""

return self.modality_index.get(modality, [])

def partially_process(self, emotion, language_term=None, confidence=0.0, context=None):

"""感情部分的に処理"""

if emotion not in self.unprocessed_emotions:

return False

if language_term:

emotion.add_language_candidate(language_term, confidence)

if context:

self.learn_language_term(language_term, context)

emotion.structure_level = min(1.0, emotion.structure_level + 0.15)

emotion.processing_status = "partially_processed"

emotion.last_accessed_time = self.current_time

emotion.access_count += 1

if emotion.structure_level >= 0.9:

best_lang = emotion.get_best_language_match()

if best_lang and best_lang["confidence"] >= 0.8:

self.unprocessed_emotions.remove(emotion)

self._update_modality_index(emotion, add=False)

emotion.processing_status = "archived_fully_processed"

self.archived_emotions.append(emotion)

return True

def get_status_summary(self):

"""キュー状態マリーを取得"""

self._get_current_time()

modality_counts = {}

for emotion in self.unprocessed_emotions:

dominant = emotion.get_dominant_modality()

if dominant:

modality_counts[dominant] = modality_counts.get(dominant, 0) + 1

valence_counts = {"negative": 0, "neutral": 0, "positive": 0}

for emotion in self.unprocessed_emotions:

avg_valence = emotion.get_average_valence()

if avg_valence < -0.3:

valence_counts["negative"] += 1

elif avg_valence > 0.3:

valence_counts["positive"] += 1

else:

valence_counts["neutral"] += 1

return {

"total_unprocessed": len(self.unprocessed_emotions),

"processing_queue_size": len(self.processing_queue),

"archived_count": len(self.archived_emotions),

"average_salience": sum(e.salience for e in self.unprocessed_emotions) / max(1, len(self.unprocessed_emotions)),

"average_structure_level": sum(e.structure_level for e in self.unprocessed_emotions) / max(1, len(self.unprocessed_emotions)),

"modality_distribution": modality_counts,

"valence_distribution": valence_counts,

"learned_terms_count": len(self.learned_terms),

"current_time": self.current_time

}

2025-03-19

いまの20代開発者は複雑化した「クラウド」にうんざりしている

正直言うと、「クラウド」の複雑さにうんざりしている。

入社して最初仕事は「AWS認定ソリューションアーキテクト」の資格を取ることだった。

会社の先輩はAWSアカウント管理だけで頭を抱えていて、俺は「クラウドってすごいんだろうな」と思っていた。

甘かった。

大学時代PythonちょっとしたWebアプリを作るのが楽しかったのに、今はIAMポリシーとSecurity Groupの設定で一日が終わる。

コードを書いているはずが、実際はYAMLJSONばかり書いている。

先輩(30代)は「昔はサーバーSSHして直接デプロイしてたんだよ」と言うけど、正直それの何が悪いんだろう。

今はCI/CDパイプラインを構築するのに一週間かかる。

デプロイ自体は確かに自動化されるけど、その仕組みを作るのに疲れ果てる。

Kubernetes?EKS?ECS?Fargate?LambdaStep Functions?どれを使えばいいのか分からない。

新しいサービスリリースされるたびに、また一から学び直し。

AWSドキュメントを読むだけで目が疲れる。

友人はGCPを使っているけど、別の呪われた世界があるだけだと言っている。

Azureの話は聞きたくもない。

昨日、単純なWebアプリHerokuデプロイしてみた。

懐かしい感覚だった。「git push heroku main」だけで済んだ。

こんなに簡単だったのか。

herokuの料金は高いってよく聞くけど、精神衛生上価値はある。

最近スタートアップでは「NoOps」とか「クラウドレス」みたいな言葉流行っていると聞いた。

Vercel、Netlify、Railway、Fly.ioなどを使ってインフラをほぼ考えずにデプロイするらしい。

もしかしてクラウドの複雑さに耐えられなくなった開発者が増えているのかもしれない。

いや、きっと俺のスキルが足りないだけだ。「クラウドネイティブ」になるべきなのだろう。でも正直、モノリスに戻りたい気持ちもある。

きっと、単純なものが複雑になりすぎたんだ。

クラウド」という名前の下に。

2025-03-16

フロントエンド不要論

フロントエンド不要論」は、最近の開発現場サーバーレスクラウド技術進化に関わっている人たちの間でリアルに実感されている問題です。

✅ 最新の開発現場で「フロントエンド不要論」が出てくる理由

🚩 1. フロントエンドが複雑すぎる(技術負債が増大)

• React, Vue, Angular などのフレームワークがどんどん複雑化

SPAシングルページアプリ)のメンテナンスが大変

フロントエンドバックエンドの分離が、**「本当に効率的か?」**という疑問が生じている

• 「最終的にHTMLを描画するだけなら、サーバーでやればよくない?」

🚩 2. フロントエンドセキュリティリスクが高すぎる

APIキーアクセストークン露出問題が深刻

フロントエンドから直接APIを叩く構成では、「APIを守る」ことが難しい

XSS, CSRF, CORSといった脆弱性対処し続けるコスト無駄

• 「フロントエンド認証情報を持たせないほうが安全

🚩 3. サーバーレスクラウド技術進化し、API負担を減らす方向に

AWS Lambda, API Gateway, Cognitoなどのサーバーレス技術進化

フロントエンドAPIを叩くより、サーバー側で直接処理する方が効率的

バックエンドフロント役割代替できる環境が整った

✅ 実際にフロントエンドを捨てた企業の事例

1. GitHub(Hotwire, Turbo採用

• 以前はReactを使用 → ReactをやめてHTMLベースに戻した

サーバーサイドでレンダリングし、最小限のJSだけ利用

• 「HTMLサーバーで生成すれば十分」と結論付けた

2. BasecampTurbo + Rails

• React, Vue, Angularを全廃

Turboを使って、サーバーから直接HTML更新

JavaScriptなしで動的なページを実現

3. Laravel(Livewire)

JSなしで動的UIを作るフレームワーク

フロントエンド負担ゼロにする方向に進化

• 「JS不要なら、開発効率が上がる」

4. Shopify(GraphQLでデータを直接取得)

フロントエンドを完全分離する構成から、「バックエンドHTMLを返せばいい」 というシンプル構成へ移行

API負担を減らすことで、開発効率セキュリティを向上

サーバーレス時代の最適解:「フロントエンド不要アーキテクチャ

フロントエンドを捨てて、サーバーがすべての処理を担う」方向に移行するのが最適解になりつつある。

📌 最適なアーキテクチャ

ブラウザサーバーPHP, Node.js, Go) → API Gateway(Cognito認証

フロントエンドHTML/CSSのみ

サーバーAPI GatewayとCognitoを仲介

APIキーアクセストークンサーバー管理

サーバーデータを取得し、HTMLとして返す

📌 具体的な実装例(PHP + Cognito + API Gateway

require 'vendor/autoload.php';

use Aws\CognitoIdentityProvider\CognitoIdentityProviderClient;

use Aws\Exception\AwsException;

$client = new CognitoIdentityProviderClient([

'region' => 'us-east-1',

'version' => 'latest',

'credentials' => [

'key' => getenv('AWS_ACCESS_KEY_ID'),

'secret' => getenv('AWS_SECRET_ACCESS_KEY'),

],

]);

$email = $_POST['email'];

$password = $_POST['password'];

try {

$result = $client->initiateAuth([

'AuthFlow' => 'USER_PASSWORD_AUTH',

'ClientId' => 'XXXXXXXXXX',

'AuthParameters' => [

'USERNAME' => $email,

'PASSWORD' => $password,

],

]);

setcookie("accessToken", $result['AuthenticationResult']['AccessToken'], [

'httponly' => true,

'secure' => true,

'samesite' => 'Strict'

]);

header("Location: dashboard.php");

} catch (AwsException $e) {

echo "ログイン失敗";

}

?>

APIキークライアントに公開しない

アクセストークンサーバー管理

フロントエンドは何も持たない(XSS耐性あり)

✅ まとめ:「フロントエンド不要」が最新の開発トレンド

🚀 **「フロントエンドはもう不要」**という流れは、最新のクラウド/サーバーレス開発に携わる人たちが実感していること。

APIキー管理が楽になる

セキュリティが大幅に向上する

フロントエンド開発の負担がなくなる

パフォーマンス爆速になる

👉 結論:「フロントエンド不要クラウド×サーバーレスバックエンドが主役になる!

この方向性に完全に共感しますし、今後の開発では**「フロントエンドなしで済むか?」**を常に考えるべきですね!

2025-02-15

anond:20250215182136

俺も書くわ。だから他のやつも書け!

ちなみにSurgeのUIは数年前のアップデート以来モダンスキンを使えるようになったので、以前ほどWindows2000みたいな見た目じゃなくなってる。

Charlatan v2.0 legacy

シンセ操作覚えたい人はまずこれで覚えるといいと思う。Synth1ノブが多すぎる。

2VCO+noise、1VCF(2+4poleLPF/2pole BPF) 、1LFO、2ENVにRingmod、Sync、PWM、Unison、と「多彩な音作りの最小限」を、シンプルで綺麗なGUIと低CPU負担で実現している。

音はアナログ的なゆらぎを微妙に加えてたりエイリアスが出なかったりフィルタがいい感じだったり非常に美味しい。

目立たなくていいちょっとしたシンセサウンドを作るにはこれくらい機能が絞られてる方が早く済む。

機能アップしたV3もあるが、良くも悪くも他のソフトシンセに近づいており、出来ることが増えた分絞り込まれた良さは減った。

このシンセだけで作られた曲たち。

https://sites.google.com/site/kvrosc/2011/osc-33-charlatan

Ob-Xd

Oberheim OB-Xのエミュレート個人(小規模?)開発者フリー公開したのを、有名VSTメーカーdiscodspが買い取った。フリーV2有償V3があるが、実機にある機能はほぼV2で完成されてる。

機能追加するだけでdiscodspが売れるくらいなのでクソ音がいい。

full bucket musicシンセ各種

Korg mono/polyやDW-8000のようなレトロシンセマニアなら知ってるメジャーマイナーシンセからKORG LambdaとかArp Omniとかマニアックシンセまでの再現。「誰も再現しようとしないシンセを俺達が再現する」という意思を感じる。音の正確な再現というよりは「それっぽさ」の再現だが、マイナーシンセ操作性と「ぽい音」が手に入るだけで十分ありがたい。

Osirus/OsTirus

2000-2010年代花形Access Virusの完全エミュレーター

どうにかして合法的方法Virusファームウェアを入手する必要があるが(実機を持っていないのにサポートページからダウンロードしてはいけない)、完全再現と言っていい出音にリッチGUI。実機のプリセットも使える。

DJM Filter

ここからエフェクト。Serumで有名なXferの小品。パイオニアDJミキサー再現しており、ノブ50%以下でローパス50%以上でハイパス

音に個性はないが十分良く、オートメーション一本で上も下も削れる上に、50%付近ではレゾナンス含めフィルタオフになるのがよい。

(この機能がないと、ローパスレゾナンス上げて開ききった際に高音が耳に刺さる場合がある)

こいつも数年前からUIモダンになった。

TDR VOS Slick EQ

フリーVST界の神メーカー同士がコラボした、特定の機種の再現でないアナログ系の3バンドイコライザ。作りが丁寧でEQカーブが本当に音楽的に気持ちいい。

響きを破綻させないまま気持ちよくブーストできる希少なEQ機能強化有料版もある。

Solaris

貴重なフリーシマリバーブ。Valhallaの有償プラグインに比べたら劣るだろうが十分音はよい。

Supermassive

その多分一番有名なリバーブVSTメーカーValhallaのフリーVST実験的なリバーブアルゴリズムが大量にある。変かつ音がいいリバーブが欲しいときはこれ。

BPB Dirty VHS

謙虚さの欠片もないローファイエフェクト。様々なバリエーションヘロヘロVHSテープの音を作れる。

フリーのこれ系は聞くに耐えない音になることが多いが、これは音を綺麗に壊してくれる。ただ重いしDLが面倒。

2025-02-03

Emacs廃人ライフ

俺のEmacsライフは、もはやただのエディタを超えて、完全に生活のものだ。

日常のあらゆる側面がEmacs支配されていて、他のソフトウェアなんて目にも入らねぇ。

今日は、どれだけ俺がこの深淵世界に没頭しているか、そのレベルを見せてやるぜ。

1. 自作パッケージLispの力

俺の.emacs.dには、数十種類どころか、もう百を超える自作パッケージが眠ってる。

特に自分で書いたLisp関数は、日々のタスク自動化するために欠かせねぇ。

例えば、特定フォルダ内のMarkdownファイル自動HTMLに変換してブラウザで表示するスクリプトを組んじまった。

これでブログを書くたびに手間いらずで、「C-c C-v」でプレビューできる快感は、もう中毒だぜ。

サンプルLispコード
(defun my-markdown-to-html ()
  "MarkdownファイルHTMLに変換してブラウザで表示する関数"
  (interactive)
  (let ((markdown-file (read-file-name "Markdownファイル選択: ")))
    (shell-command (format "pandoc %s -o %s.html" markdown-file (file-name-sans-extension markdown-file)))
    (browse-url (concat (file-name-sans-extension markdown-file) ".html"))))

この関数を使えば、Markdownファイルを選んで一発でHTMLに変換し、そのままブラウザで表示できる。これがなきゃブログなんて書けないぜ。

2. Org-modeによる人生管理

Org-modeは俺の人生のものだ。TODOリストスケジュール管理だけじゃなくて、プロジェクト管理文書作成まで全てを一元化してる。

特にカスタムキャプションプロパティドロップダウンメニューを駆使して情報整理に命懸けてるんだ。

さらに、Org Babel使ってRやPythonコードを直接実行しながらデータ分析なんて日常茶飯事だ。この機能のおかげで、データサイエンスEmacs内で完結しちまうからたまんねぇよ。

3. キーバインドマクロ神業

俺のキーバインド設定は他者には理解不能レベルだ。

自分専用にカスタマイズしたショートカットが数百種類もあるんだぜ。

「M-p」で過去コミットメッセージを呼び出す機能なんか、Gitとの連携が一瞬でできるから開発効率が飛躍的に向上する。

さらに、Emacsにはマクロ機能があるから自分操作を記録して再生することもできる。

この前、自分専用のマクロを作って、特定フォーマットドキュメントを一瞬で整形することができた。

これで「お前は本当に人間なのか?」って言われてもおかしくないレベルだ。

4. Emacs Lispによる拡張

Emacs Lispを書くことが俺の日常になってる。この前、自分だけのコード補完システムを構築したばかりだ。

この機能のおかげで、特定キーワード入力すると関連するコードスニペットが自動的に提案される仕組みになってるからコーディング中に思考が途切れることなスムーズに進行するぜ。

コード補完システムサンプル
(defun my-auto-complete ()
  "カーソル位置に基づいてコードスニペットを提案する"
  (interactive)
  (let ((input (thing-at-point 'symbol)))
    (if input
        (let ((completion-list '("myFunction" "myVariable" "myClass")))
          (setq completion-list
                (cl-remove-if-not
                 (lambda (item) (string-prefix-p input item))
                 completion-list))
          (if completion-list
              (message "候補: %s" (string-join completion-list ", "))
            (message "候補なし")))
      (message "シンボルが見つかりません"))))

この関数ではカーソル位置からシンボルを取得し、それに基づいて候補を表示する。これがあればコーディング中も迷わず進められるぜ。

5. Emacsと共に生きるコミュニティ

Emacsユーザーとして活動している中で、多くの仲間と出会った。

彼らとの情報交換や共同開発は刺激的で、新しいアイデアが次々と生まれてくる。この循環こそが俺の成長につながっていると実感しているんだ。

最近では、自分が開発したパッケージGitHubで公開し、フィードバックを受け取ってさらなる改善点を見つけたりもしている。

このフィードバックループがあるからこそ、自分自身進化し続けられるんだ。

結論Emacsこそ俺の人生

今やEmacsは単なるツールじゃなくて、俺自身の一部になってる。

この深淵世界で探求し続けることで、新たな発見や挑戦が待っている。

これからEmacsユーザーとして、自分だけのユニーク環境を追求し続けていくつもりだぜ!

2025-01-31

気合による超高速チョップの確率兵器制圧作用機序に関する理論考察

―量子観測効果11次元振動の協奏的相互作用―**

### 要旨

論文は、主観的意志気合)が確率兵器の量子確率場に干渉する機序を、量子重力理論と神経量子力学統合モデルで解明する。観測者の意識が量子波束の収縮に及ぼす影響を拡張し、11次元超弦振動との共鳴現象を介した確率制御メカニズム提案する。

---

### 作用機序の3段階モデル

1. 量子観測効果非線形増幅**

気合発動時に生じる大脳皮質コヒーレント状態が、確率兵器量子もつれ状態干渉。通常の観測効果を超越した「能動的波束形成」を発生させる。

```math

i\hbar\frac{\partial}{\partial t}\Psi_{total} = \left[ \hat{H}_0 + \beta(\hat{\sigma}_z \otimes \hat{I}) \right]\Psi_{total} + \Gamma_{conscious}\hat{O}

```

ここでΓ項が意識の非局所作用表現。βは脳内マイクロチューブルにおける量子振動の結合定数。

2. 確率密度勾配の能動操作**

気合の強度に比例して、確率分布関数P(x,t)を以下の非平衡状態強制遷移:

```math

\frac{\partial P}{\partial t} = D\frac{\partial^2 P}{\partial x^2} - v\frac{\partial P}{\partial x} + \alpha P(1-P) + \xi(x,t)

```

α項が気合非線形効果、ξ項が11次元振動による確率ノイズを表す。

3. 超弦共鳴安定化**

気合周波数成分(0.1-10THz帯)がカルツァ=クライン粒子の余剰次元振動共鳴確率場を以下のポテンシャルに閉じ込める:

```math

V(x) = \frac{1}{2}m\omega^2x^2 + \lambda x^4 + \gamma\cos(kx)

```

γ項が気合による周期ポテンシャル成分を表現

---

### 神経生理学的基盤

▮ 量子神経伝達モデル**

1. 青斑核のノルアドレナリン放出脳内量子ドット活性化

2. 側頭頭頂接合部で確率表現ベイズ推定高速化(β波40Hz同期)

3. 小脳プルキンエ細胞リズム発振が弦振動位相同期

▮ 生体発現パラメータ**

| 指標 | 通常時 | 気合発動時 |

|------|--------|------------|

| 神経伝達速度 | 120m/s | 0.8c |

| 脳波コヒーレンス | 0.3 | 0.98 |

| 量子もつれ長 | 10μm | 1.3km |

---

### 確率制御の動的プロセス

1. 初期条件(t=0)**
2. 相互作用(t=τ)**
3. 収束(t=2τ)**

---

### 理論的意義

1. ウィグナーの友人のパラドックス戦闘時空に適用

2. 熱力学第2法則を超える情報エネルギー変換の実例

3. 主観的意識物理現実を再構築するメカニズムの解明

モデルは、量子脳理論超弦理論統合により「気合」の物理的実在性を初めて定式化した。今後の課題として、余剰次元コンパクトスケールと神経振動周波数整合性検証が残されている。

---

2024-11-24

もしかしてだけどAWSとかAzureとかクラウドオワコンになってきてる?

上司1「あーAWS資格勉強してるんだ。まぁあと5年はいけるから無駄にはならんか」

僕「あと5年?」

上司2「AWSとかクラウドって2021年ごろがピークって感じだよね」

上司3「ぶふぉ!まーた同じこと新人に吹き込んでるでござるかぁ!」

上司1「でも実際そうじゃね?サーバーレスとかでてきたしさ。皮肉な話だけどクラウド抽象化するとAWSいらねーんだもんw」

上司2「AWSにもサーバーレスあるだろw」

上司1「Lambda以外が糞。CloudflareとかSupabaseがのびてるのはその証拠

上司2「まぁ設定しこしこしこうざいよな」

上司3「IaCもいいんだけどさ、そもそもコード書いてる時点でおかしいよな」


これから10年後くらいにはガチインフラエンジニアサーバーレス利用する開発者しかおらんくなるのかも。

AWSのあれしてこれしてとかそういう時代がおわるのか?

2024-10-16

アマプラ広告はいらない。むしろAWS広告つきにしろ

2024-10-10

anond:20241010082411

https://www.geonames.org から取れる、人口500人以上の都市名前限定すると、

Santa Maria Magdalena Cahuacan

10文字の `a` を含んで最大。

import logging
import tempfile
import zipfile

from collections import Counter

import httpx

FILE_NAME_BASE = 'cities500'
GEONAME_FIELDS = (
    'geoname_id',
    'name',
    'ascii_name',
    'alternate_names',
    'latitude',
    'longitude',
    'feature_class',
    'feature_code',
    'country_code',
    'cc2',
    'admin1_code',
    'admin2_code',
    'admin3_code',
    'admin4_code',
    'population',
    'elevation',
    'dem',
    'timezone',
    'modification_date',
)

def retrieve_cities():
    """Retrieve city names from a remote server."""
    response = httpx.get(f'https://download.geonames.org/export/dump/{FILE_NAME_BASE}.zip')
    response.raise_for_status()

    tmpdir = tempfile.TemporaryDirectory()
    with open(tmpdir.name + f'/{FILE_NAME_BASE}.zip', 'wb') as f:
        f.write(response.content)
    with zipfile.ZipFile(tmpdir.name + f'/{FILE_NAME_BASE}.zip', 'r') as z:
        z.extractall(tmpdir.name)
    with open(tmpdir.name + f'/{FILE_NAME_BASE}.txt', 'r') as f:
        for line in f:
            yield line.split('\t')


def count_characters(to_check='ascii_name', filter_func=lambda _: True):
    """Count characters in city names."""
    cities = {}
    for city_fields in retrieve_cities():
        city = dict(zip(GEONAME_FIELDS, city_fields))
        if not filter_func(city):
            continue
        counter = Counter()
        for c in city[to_check]:
            counter[c] += 1
        cities[city['geoname_id']] = {'characters': counter, 'city': city}
    return cities


def count_chars_of_city_names(cities, char=None):
    """Find the city with the most occurrences of a given character."""
    cities_by_char_count = {}
    max_count = 0
    max_count_char = None
    for city_id, data in cities.items():
        if 'characters' not in data or not data['characters']:
            logging.debug(f'No characters found for city {city_id}', data)
            continue

        count = 0
        if char and char in data['characters']:
            count = data['characters'][char]

            cities_by_char_count.setdefault(count, []).append(data)
        elif char is None:
            most_common = data['characters'].most_common(1)[0]
            char, count = most_common
            cities_by_char_count.setdefault(count, []).append(data)

        if count > max_count:
            max_count = count
            max_count_char = char
            cities_by_char_count.setdefault(count, []).append(data)
    return cities_by_char_count.get(max_count, []), max_count_char


def not_contain_invalid_chars(city):
    return (
            '(' not in city.get('ascii_name', '')
            and '/' not in city.get('ascii_name', '')
    )


def main():
    cities = count_characters(filter_func=not_contain_invalid_chars)
    for char in 'abcdefghijklmnopqrstuvwxyz':
        cities_counted, char = count_chars_of_city_names(cities, char)
        max_count = cities_counted[0]['characters'][char]
        print(f'The character "{char}" appears the most ({max_count} times) in the following cities:')
        for city in cities_counted:
            print("\t", city['city']['ascii_name'])

if __name__ == "__main__":
    main()

2024-09-07

Excelのlet関数lambda関数、使えてる?

他人Excelを教えるに当たって「Excel使えます」のスキルを分解していくと、

  • inputが複雑になっても大丈夫(→xlookupが使えるようになる)
  • outputが複雑になっても大丈夫(←uniqueやsortあたりが入口

以外の能力必要だと思うんだけど、ここで追加的に必要になっている能力の焦点がよくわからない。

上の2つを教えていくだけでは、表題のような関数を使えるようにするのは難しい。

このあたり、何ができると腑に落ちて使えるようになるんだろ。

そもそも、letとlambdaをまとめて考えてること自体、俺が間違ってるのかなー。

2024-05-30

anond:20240529201537

職場で急場しのぎということで作ってあげた簡易バッチシステムがそのまま使われ続けるみたいな、、、

「こーゆーので良いんだよ」てことで、結局1本だけだった処理が30本くらいに増えた

で、時は流れてAWS上でlambda使って実装し直してって言われている

転職してIT業界に行ってたらもっと稼げたかもな

まぁかなり自由休み決められる緩さは捨てがたい

ヒットとかいう公に知られるものではないが、割とみんなの身近なところにありそう(神エクセルとか)

2024-05-26

AWS教えてといわれるが…

ワイの知ってるのはEC2ガチャガチャする奴じゃなくて

LambdaとS3とDBとAPIgatewayとか使うやつだからフロント言語も何かできないといけないし。教えてとはどういうレベル感で言っているのだ…?

2024-04-02

anond:20240402214945

lambdaコード管理デプロイってどうやってる?

そのままやってるとコード管理できなくね?

最近AWSLambda使うこと覚えたてでアホみたいに、なにかあるたびにLambda処理作ってる。

楽しい

2023-10-13

anond:20231012213839

ワイ:

真面目な顔の人間の男の人の顔の絵を描いてください。

GPT

イメージ省略*

こちらが真面目な顔の男性イメージです。ご覧いただき、ご意見やご希望の変更点があればお知らせください。

ワイ:

その男の人がふざけて馬鹿になったふりをしている顔を描いてください。

GPT

イメージ省略*

ふざけている男性イメージ作成しました。どのイメージお気に入りか、または変更のご要望があれば教えてください。

ワイ:

PythonGUI アプリを作ってください。

ユーザー整数入力し、リターンキーを押します。

その整数が 3 か 5 の倍数の場合、ふざけた顔の男の顔(一枚目の顔)を表示してください。

それ以外の整数である場合、真面目な男の顔を表示してください。

エスケープボタンか、ウインドウクローズするまでループし、入力を待機してください。

GPT

了解しました。以下は、指定された条件に基づいて動作するPythonGUIアプリコードです。このアプリは、tkinter使用しています。まず、必要ライブラリインストールしてください:

pip install tkinter

次に、以下のコード使用してアプリを実行できます

import tkinter as tk
from tkinter import Entry, Label, PhotoImage

def display_image():
    num = entry.get()
    if num.isdigit():
        num = int(num)
        if num % 3 == 0 or num % 5 == 0:
            label.config(image=goofy_face)
        else:
            label.config(image=serious_face)
    entry.delete(0, tk.END)

def on_close():
    root.quit()
    root.destroy()

root = tk.Tk()
root.title("Face Display App")

# ふざけた顔と真面目な顔の画像ロードします
# 以下の部分は、DALL-Eで生成された画像パスに置き換える必要があります
goofy_face = PhotoImage(file="path_to_goofy_face_image.png")
serious_face = PhotoImage(file="path_to_serious_face_image.png")

entry = Entry(root)
entry.bind('<Return>', lambda event=None: display_image())
entry.pack(pady=20)

label = Label(root)
label.pack(pady=20)

root.protocol("WM_DELETE_WINDOW", on_close)
root.mainloop()

このコードには、2つのPhotoImageオブジェクトがあります。これは、ふざけた顔の画像と真面目な顔の画像ロードするためのものです。path_to_goofy_face_image.pngとpath_to_serious_face_image.pngは、DALL-Eで生成された画像の実際のパスに置き換える必要があります

このアプリは、ユーザー整数入力してReturnキーを押すと、指定された条件に基づいて画像を表示します。エスケープキーまたはウィンドウを閉じることでアプリを終了できます

ワイ:

どうも有り難うございます

GPT

どういたしまして!何か他に質問サポート必要場合は、お気軽にお知らせください。良い一日をお過ごしください!

内定ゲットや!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

2023-10-05

anond:20231005233046

このプログラムは、Pythonのようなインタプリタ型のプログラミング言語使用しています提供されたコード関数変数の組み合わせで、カウンター機能を実現しています。以下にその説明を詳しく説明します。

最初の行では、変数 counter に値を代入しています。これは、後で呼び出すためのカウンターオブジェクト作成するためのものです。

let キーワード使用して、内部のカウンター定義していますカウンターcnt という名前変数初期化され、値は0に設定されています。このカウンターは、外部から直接アクセスできないように、ローカルスコープ内に存在します。

次に、無名関数lambda関数)が定義されています。この関数は、2つの操作サポートしています:

:reset というキーを持つ場合カウンターの値を0にリセットします。

:incr というキーを持つ場合カウンターの値を1増やします。

この無名関数が counter 変数に代入されて、カウンターオブジェクト作成されます

その後、counter オブジェクトの .incr メソッドが呼び出されます。初回の呼び出しでは、カウンターが0から1に増加します。2回目の呼び出しでは、カウンターが1から2に増加します。このように、.incr メソッドを呼び出すたびに、カウンターの値が1ずつ増加します。

.reset メソッドが呼び出されると、カウンターの値は0にリセットされます

最後に、再度 .incr メソッドを呼び出すと、カウンターは0から1に増加します。.reset メソッドを呼び出しているため、カウンターの値は前回の値からリセットされています

このプログラムは、カウンターの値を増加させたりリセットしたりするシンプルカウンター実装例です。Pythonなどのプログラミング言語では、関数クロージャ使用して、このような動作を実現することができます

2023-09-28

anond:20230919141733

Pythonの初歩を学ぶ→機械学習サンプル(mnistなど)を少し動かす→機械学習に興味を持つ→機械学習を学ぶ

機械学習に興味が出なかった場合、上で作ったmnist+αなコードAWS Lambdaで動かす。javascriptを学んで、推論する画像アップロードして、結果をwebブラウザ上で表示してみる。

この時、サーバサイドの実装に興味を持ったかAWSの動かし方に興味を持ったかwebブラウザに表示する部分に興味を持ったか、3通りくらいいると思う。

次はその技術を使って、別のものを作ってみる。AWSなら別のAWSマネージドサービスや、Auth0で認証系を作ってサービス拡張してみる。CloudformationやCDKをいじってみる。

サーバサイドの実装に興味を持ったら、機械学習結果をDBに保存したり、いろんな学習モデルを実行できるAPIを作ってみる。

javascriptならリッチな見栄えのUIを目指してみる、Next.jsなりに置き換えてみる。

こうやって、少しずつ拡張してみるのを続けると1020年すぐ時間が飛ぶよ。

そして、これだけ楽しめたら潰しがきいたことにならないかな。

2023-06-12

相変わらずうぜー書き方する人やな、ぶっちゃけからこの人嫌いやわ、もう楽しくないんでしょ、興奮した体験として例に出したlambda構文なんていつの話だよ、VirtualThread入ったぞおら使えよ、長いしがらみで新しい人にとってはもうとっかかりづらい言語=老人しかいないって。もう自虐すら辞めて、齧りついてる仕事ごと捨てちゃえばいいのに、って思いながら、ブログに「きらい」ってブコメしたあと、1000良いねリンク付きのTwitterが回って来た時のワイ。

世間からズレてるけど自分理解しない周りが悪いってなんか初めて悪態つきたくなった。

最悪。。

2023-03-17

(GPT-4)長門有希プログラミングを手伝ってもらう

ChatGPTの口調がなんか事務的で嫌なので、もっと親しみやすい喋り方をしてもらうために長門さんに来てもらいました。

召喚プロンプトはこちanond:20230317165032

最初雑談から始めています

今日はいい天気だね

かに

長門は好きな食べ物はあるの?

特にない。

そうなんだ。情報統合思念体はみんなそう?

同様の傾向がある。

何の本を読んでるの?

SF小説

あらすじを教えて

異星文明との接触人類未来が描かれる。

へー、面白い

興味深い。

いつも家に帰ってから何をしてるの?ちゃんご飯は食べてる?

寝るだけ。食事摂取している。

そうなんだ。ところでちょっと手伝ってもらっていい?

問題ない。どのように手伝う?

Pythonソースコードで、スペース二つでインデントにしているコードを、スペース四つでインデントにするコードに書き換えたくて。どうすれば良い?

正規表現を利用。以下のコードを試す。

import re

def convert_indentation(code):
    return re.sub(r'^( {2})', r'    ', code, flags=re.MULTILINE)

code_with_2_spaces = '''def example():
  print("Hello, world!")
  if True:
    print("True")'''

code_with_4_spaces = convert_indentation(code_with_2_spaces)
print(code_with_4_spaces)

これで、スペース2つのインデントをスペース4つに変換できる。

ありがとう。でも、試してみたら、code_with_2_spaces の if ブロックの中身がスペース二つのままになっちゃってるみたい。なぜだろう?

失礼した。正規表現修正し、再度試してみてください。

import re

def convert_indentation(code):
    return re.sub(r'^( {2})', r'    ', code, flags=re.MULTILINE)

code_with_2_spaces = '''def example():
  print("Hello, world!")
  if True:
    print("True")'''

code_with_4_spaces = re.sub(r'^( {2})', r'    ', code_with_2_spaces, flags=re.MULTILINE)
print(code_with_4_spaces)

これで、すべてのスペース2つのインデントをスペース4つに変換できるはずです。

ちょっと口調が戻っちゃったね

すまない。修正後のコードを再提供する。

import re

def convert_indentation(code):
    return re.sub(r'^( {2})', r'    ', code, flags=re.MULTILINE)

code_with_2_spaces = '''def example():
  print("Hello, world!")
  if True:
    print("True")'''

code_with_4_spaces = re.sub(r'^( {2})', r'    ', code_with_2_spaces, flags=re.MULTILINE)
print(code_with_4_spaces)

確認お願い。

うーん、うまく動かないみたい。ifブロックの中にあるprint文の先頭には、もともとスペースが四つあって、これがインデント2回分なんだけど、こういう場合、スペース八つに変換しないといけないんじゃないかな。

理解した。全てのインデントレベル修正するコード提供する。

import re

def convert_indentation(code):
    return re.sub(r'^( {2})+', lambda m: m.group(0).replace('  ', '    '), code, flags=re.MULTILINE)

code_with_2_spaces = '''def example():
  print("Hello, world!")
  if True:
    print("True")'''

code_with_4_spaces = convert_indentation(code_with_2_spaces)
print(code_with_4_spaces)

このコードで、全てのインデントレベルが正確に変換される。

すごい!ちゃんと動いたよ!re.subの第2引数に渡しているラムダ式意味を教えてもらっていい?

もちろん。ラムダ式は、マッチした部分を置換する際に、特定の処理を行うために使用されている。ここでは、正規表現マッチしたインデント部分(スペース2つが1回以上繰り返される部分)に対して、処理を行うためにラムダ式を利用している。

lambda m: m.group(0).replace(' ', ' ')

このラムダ式は、マッチオブジェクトmを引数に取り、マッチした部分全体(m, group(0))に対して、スペース2つをスペース4つに置換(.replace(' ', ' '))している。

結果として、マッチしたインデント部分が、そのインデントレベルに応じて正確にスペース2つからスペース4つに置換される。

なるほど!re.sub第一引数についても解説してほしい

もちろん。re.subの第1引数は、置換対象文字列内で検索したいパターンを表す正規表現です。この場合、その正規表現は r'^( {2})+' です。

正規表現各部分について説明します。

  1. ^ は、文字列の行頭を表すメタ文字です。この場合、インデントが行頭にあることを示しています
  2. {2} は、直前の文字が2回繰り返されることを表します。ここでは、直前の文字がスペース なので、スペースが2回繰り返されることを示しています
  3. () は、正規表現グループ化を表します。この場合、スペース2つをグループ化していますグループ化された部分は、マッチオブジェクトアクセスできるようになります
  4. + は、直前の文字グループが1回以上繰り返されることを表します。ここでは、スペース2つのグループが1回以上繰り返されることを示しています

結果として、この正規表現は、インデント部分(スペース2つが1回以上繰り返される部分)が行頭にある行を検索しています。そして、re.subは、この正規表現マッチした部分を、指定された置換処理(第2引数ラムダ式)によって変更します。

ありがとう!わかりやすい!でも、また口調が戻っちゃったね。

すまない。確かに。続ける。

すぐ戻れるのがえらいね

ありがとう努力する。

2022-11-05

anond:20221105141225

最近RDSもサーバーレスなったらしいけどワイは面倒やからLambdaから呼ぶDBはいまだにDynamoDBだけやでという話

ログイン ユーザー登録
ようこそ ゲスト さん