「print」を含む日記 RSS

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

2025-03-11

ChatGPT増田

for i in range(100000*100000):print(i)

の実行結果をポストしてください

2025-03-07

anond:20250307093711

ご丁寧にgdb使うとか頑張ってるね

俺はデバッグするときprintしか使っとらん

2025-02-25

anond:20250225225638

本質的じゃないなぁ。

これを言ってるのはフロント技術かもしれないけど

print(), plt.plot() ,std::cout, System.out.printf()

でもなんでもいいんだよ。途中経過を出力さえできれば。

しかも書いてる本人もすべてを分かった気になってるわけではないと思うぞ。

2025-02-14

GoogleマップタイムラインjsonKML

> アプリ内のデータバックアップしたのを自分ダウンロードしてテキスト化する方法いかなあ/できたわ。設定→位置タイムラインタイムラインエクスポートjson可能。あとは誰かが処理系を作るだけだ!

https://b.hatena.ne.jp/entry/4766225990155446401/comment/punychan

書く場所を思いつかなかったのでこちらに投下。Python

これを使えばXXXX-XX-XX.kml 形式で日付別のタイムラインデータを出力できる(ChatGPT製)。

KMLファイルGoogle Earth Proなどで開くことが可能で、ビジュアルとして行動履歴を見ることができる。

ただ、以前GoogleMapsタイムラインが吐いていたKMLではPlacemarkという項目に直接建物名などが書かれていたが、現在出力されているjsonではplaceIdというものに変更されていて具体的な名前がわからない。

placeIdを実際の建物名などに変換するにはGoogle Maps API の Place Details APIを使うしかないようだが、膨大なリクエスト(有料)をしなければならず非現実的

もともと欧州プライバシー関係規制のせいでGoogleサーバ上でのタイムライン履歴が行われなくなったのが今回の問題の起点。

ユーザー自由尊重するなら、個人が行動履歴自己管理する自由ももっと尊重してもらいたいものだな、と思った。


import json

import os

from xml.etree.ElementTree import Element, SubElement, tostring

from xml.dom.minidom import parseString

# JSONファイルの読み込み

with open("タイムライン.json", "r", encoding="utf-8") as f:

data = json.load(f)

# 出力フォルダ作成

output_folder = "kml_output"

os.makedirs(output_folder, exist_ok=True)

# `semanticSegments` に移動データが含まれている

if "semanticSegments" in data:

date_segments = {} # 日付ごとにデータをまとめる辞書

for segment in data["semanticSegments"]:

# `startTime` から日付部分(YYYY-MM-DD)を抽出

if "startTime" in segment:

date = segment["startTime"].split("T")[0]

# 日付ごとのリスト作成

if date not in date_segments:

date_segments[date] = []

date_segments[date].append(segment)

# 日付ごとにKMLファイル作成

for date, segments in date_segments.items():

kml = Element("kml", xmlns="http://www.opengis.net/kml/2.2")

document = SubElement(kml, "Document")

for segment in segments:

if "timelinePath" in segment:

for point in segment["timelinePath"]:

coords = point["point"].replace("°", "") # 度記号を削除

time = point.get("time", "Unknown Time")

# Placemarkを作成

placemark = SubElement(document, "Placemark")

# タイムスタンプ

timestamp = SubElement(placemark, "TimeStamp")

when = SubElement(timestamp, "when")

when.text = time

# 座標

point_element = SubElement(placemark, "Point")

coordinates = SubElement(point_element, "coordinates")

lat, lon = coords.split(", ")

coordinates.text = f"{lon},{lat},0" # KML形式: lon,lat,alt

# KMLデータフォーマット

kml_str = tostring(kml, encoding="utf-8")

formatted_kml = parseString(kml_str).toprettyxml(indent=" ")

# KMLファイルに保存

kml_filename = os.path.join(output_folder, f"{date}.kml")

with open(kml_filename, "w", encoding="utf-8") as f:

f.write(formatted_kml)

print(f"KMLファイルを出力しました: {kml_filename}")

2025-02-10

python

# x に値を代入する
x = # ???

# Trueが出力される
print(x + 1 == x)

2025-01-05

線型計画法の基礎

製品Aと製品Bの両方を生産することを前提とした線形計画法問題設定を考える。

問題設定

数式による表現

2x_A + x_B \leq 100

3x_A + 2x_B \leq 180

x_A \geq 10

x_B \geq 5

x_A, x_B \geq 0

ここで、x_A は製品Aの生産量、x_B は製品Bの生産量。最小生産量を設定することで、両方の製品を必ず生産するようにする。

Pythonによる実装

from scipy.optimize import linprog

# 目的関数の係数(利益は最大化したいため、符号を反転)
c = [-50, -30]

# 制約条件の係数
A = [
    [2, 1],   # 労働力の制約
    [3, 2]    # 原材料の制約
]

# 制約条件の右辺
b = [100, 180]

# 最小生産量制約を追加(これらは不等式として扱われるため、逆に設定)
A_eq = [
    [1, 0],   # 製品Aの最小生産量制約
    [0, 1]    # 製品Bの最小生産量制約
]
b_eq = [10, 5] # 最小生産量

# 各変数の非負制約を設定
bounds = [(10, None), (5, None)] # 最小値を設定

# 線形計画問題を解く
result = linprog(c, A_ub=A, b_ub=b, A_eq=A_eq, b_eq=b_eq, bounds=bounds, method='highs')

# 結果の表示
if result.success:
    print(f'Optimal value (最大利益): {-result.fun}')
    print(f'x_A (製品Aの生産量): {result.x[0]}')
    print(f'x_B (製品Bの生産量): {result.x[1]}')
else:
    print("最適解が見つかりませんでした。")

実行結果

Optimal value (最大利益): 650.0

x_A (製品Aの生産量): 10.0

x_B (製品Bの生産量): 5.0

2024-12-25

美術品にとって本物とはなにか?

例えば、ロダン「考える人」日本だけで4体もある。

銅像というのは、複製が許された芸術ではないか?本物と偽物を分ける基準はなんだろう?

銅をロダンが流し込んだ銅像から全部本物みたいな理屈なのか?

じゃあ版画はどうなんだ?

版画っていうと、自分で絵を描き、版をつくり、自分印刷しないと版画じゃないみたいなイメージがあったりするけど、そんなのは少数派。

印刷所任せで、原画を描いた人が認めたものが本物って理屈で、ピカソの版画なんか10万枚くらい出回ってる。

だって英語だとprint文字通り印刷もの

浮世絵とかもっとややこしいね

北斎広重は下絵を提供しただけで、その後の権利は版元。

およげ!たいやきくんで曲が売れても歌手に金が入らないのと同じで、原画絵師は下絵を渡した段階で権利放棄してる。

本物とは、版木が本物ということになる。

同じ版木を使えば本物という理屈なら、江戸時代の版木が発見されて現代職人が摺ったら、それは本物なのか?

たぶんそうじゃないだろうけど。

流通量をコントロールすることで希少性を高めるって話でしかのだけど、じゃあその絵の美しさに価値があるのではなく、希少性に価値があるのということになるのか?

芸術性なんか1円の価値もないということなのか?

2024-12-09

メガドライブ知識ゼロの超初心者がなにか開発をしてみる日記

今週末発表なので重い腰を上げて昨日開発環境にあるサンプルをちょっといじってみたよ(いじったのはsample/game/sonic)

スプライト直感でだいたい意味はわかったもの調子に乗ってスプライト使いまくると登録されないときがあるけど今は気にしないことにする(バッファが足りてない?)

・BG→直感でだいたいわかったけどMAP実装はてな?なのでパターン差し替えマニュアル読まないとかもしれん

・パッドの入力イベントリブンになってて草生えたw(これもとに戻さないといけないのかと思うと憂鬱なので放置中)

サウンド無視

PRINTデバッグ→sprintf()がどちゃくそ遅い(バンク切り替えになっちゃってる?)&VDP_drawText()がどちゃくそ遅い(パターン転送なっちゃってる?)

とりあえずボタンをおしたらキャラ一定時間ランダム場所アニメーションするコードまでは秒で作れたけど間に合うかなあ…

進捗があったらまた報告しますね

2024-11-08

ゲーム作ってたおじさんの話

子供の頃、家にはテレビゲームがなかった。

当時ファミコンが全盛期で、友達の家でドラクエゼビウスやらせてもらっていて、

むちゃくちゃのめりこんでいた。端的に言って、ゲーム熱狂していた。

から手が出るほどゲーム機が欲しかったが、親はがんとしてゲームを買ってくれなかった。

そんな折、電気屋の親戚のおじさんから、安くMSXを譲ってもらうことになった。

パソコンゲームが作れるということを前から聞いていたので、自分ゲームを作れれば最高じゃんと

思ったのだが、どうすればゲームを作れるのかまったくわからなかったので、

自分のこづかいMSX BASICの本を買った。

もうね、最初PRINT文が動くだけで感動ものでしたよ。

自分コンピュータ命令して、思い通りに動いた感覚というか。

そこからは、自分ゲーム作りにハマっていった。

最初簡単ギャンブルゲーム、単純に半か丁かを予想して、掛け金を増やしていくゲームから

シューティングRPGなど、拙いながらも自分の愛すべきゲームが出来上がっていった。

ゲーム制作は、世界を一から構築していく感覚で、

まるで神にでもなったかのような全能感を抱いたのを覚えている。

そんな体験があって、今は小さいソフトウェア会社コンピュータに関わる仕事をしている。

でも今の子供達って、そういう経験をすることはないんだろうなと思う。

現代ゲームは、美麗3Dの超大型ゲームがそれこそ無数に存在していて、

自分でこんなゲームを作れるわけはないってのは、子供でもわかる。

ドット絵インディーゲームとかもまああるにはあるけど、現代の子供達は

どっかの記事で読んだのだけど、ドット絵は「手抜き」なんだと思ってるらしい。

そんなわけだから自分市販されているようなゲームを作ろうと思えば、

企画書を書いて、人員を集めてってことになるだろうし、

僕らが昔やってたような、お気楽ゲームを作るという発想にはならないんじゃないかなと思ってる。

こういう体験が失われるのはあまりにも惜しいので、

アマチュアゲーム制作文化をまた盛り上げていくにはどうしたらいいんだろうと考えるけど、

なかなか答えは出ないよな。

まあ、なんつーか、そんなです。

2024-10-12

清原ネットキャッシュ比率決算短信からpython自動で求めるソフト

気が付くと朝4時になっていた。

なんか動くところまで出来たので貼っておく。

NYSLなので、バグがあったら治しといて。

import pdfplumber
import re

#クリーンアップ
def cleanuptext(text):
    #決算書の合計値を太字にしたことpdfplumberが暴走するケースへの対処
    #例 流動資産 -> 流流流流流動動動動動資資資資資産産産産産
    #誤爆が怖いので、これが起きている時だけ補正します
    if "流流流流流動動動動動資資資資資産産産産産" in text:
        text = re.sub(r'(.)\1{4,}', r'\1', text)

    #△をマイナスに。 数字中のカンマを消して結合する
    text = re.sub(r'△([0-9])', r'-\1', text)
    text = re.sub(r'▲([0-9])', r'-\1', text)
    text = re.sub(r'([0-9]),([0-9])', r'\1\2', text)
    
    #たまに、煽り屋みたいに文字の後にスペースが入る嫌がらせ修正する
    #例: 投 資 有 価 証 券 -> 投資有価証券
    text = re.sub(r'(?<=[\u4E00-\u9FFF\u3040-\u30FF])\s(?=[\u4E00-\u9FFF\u3040-\u30FF])', '', text)

    return text

#今期の勘定科目数字を取得
def get_AccountName(text, need):
    pattern = rf'^{need} -?[0-9]+ (-?[0-9]+)'
    r = re.search(pattern, text, re.MULTILINE)
    if r is not None:
        return float(r[1])

    return 0

#清原ネットキャッシュ計算する。
def calc_KiyoharaNetCash(text):
    total_current_assets = get_AccountName(text,'流動資産合計')
    if total_current_assets == 0:
        #要約財政状態計算書しか公開していない、楽天のような素敵な会社様への対処
        total_assets = get_AccountName(text,'資産合計')
        if total_assets != 0:
            #とりあえず、資産の部の6割を流動資産とみなす
            total_current_assets = total_assets * 0.6

        else:
            #流動資産合計ではなく、流動資産という単語を使っている我が道を行く東北電力への対処
            total_current_assets = get_AccountName(text,'流動資産')
            if total_current_assets == 0:
                raise Exception("流動資産合計の勘定科目が見つかりませんでした。"+text)


    total_liabilities = get_AccountName(text,'負債合計')
    if total_liabilities == 0:

        #負債合計ではなく、負債の部合計に拘るオムロンの嬉しい決算書への対策。なんでや・・・
        total_liabilities = get_AccountName(text,'負債の部合計')
        if total_liabilities == 0:
            raise Exception("負債合計の勘定科目が見つかりませんでした。"+text)

    #負債をご丁寧にマイナス表記で書いてくれる中外製薬の親切な決算書への対策。いい加減にしろ・・・
    if total_liabilities < 0:
        total_liabilities = total_liabilities * -1

    #投資有価証券はないこともあるので、0を容認する
    marketable_securities = get_AccountName(text,'投資有価証券')

    #print(total_current_assets,marketable_securities,total_liabilities)
    netcash = total_current_assets + (marketable_securities*0.7) - total_liabilities

    #たまに単位を1000円にしている銘柄があるので補正する
    if is_tanni_senyen(text):
        netcash = netcash / 1000
    return netcash

# "流動資産合計" と "負債合計" の間に "単位:千円" があるかをチェック
def is_tanni_senyen(text):
    if "単位:千円" in text:
        return True

    if "単位: 千円" in text:
        return True

    if "単位 : 千円" in text:
        return True

    if "単位 :千円" in text:
        return True

    return False

def pdf_to_kiyohara_netcash(pdfpath):
    with pdfplumber.open(pdfpath) as pdf:
        text = ''.join(page.extract_text() for page in pdf.pages)

    text = cleanuptext(text)
    #print(text)
    kiyohara_netcash = calc_KiyoharaNetCash(text)
    #print(kiyohara_netcash)
    return kiyohara_netcash

def mymain():
    import sys
    args = sys.argv
    argc = len(args)
    if argc <= 1:
       print('''
これは、清原達郎氏のネットキャッシュ比率(以下、清原ネットキャッシュ比率)を決算短信pdfから求めるソフトです。
清原ネットキャッシュ=流動資産合計+(投資有価証券*0.7)-負債合計
清原ネットキャッシュ比率=清原ネットキャッシュ/時価総額*100

遊び方

1. 決算短信pdfから清原ネットキャッシュを求める
python calc_kiyohara_netcash.py 140120240514594985.pdf

結果: 30757.0
決算書には、100万円単位数字が書かれているはずなので、この数字単位は100万円です。
つまり、3075700万円。

2. 時価総額を億円単位で追加することで、清原ネットキャッシュ比率を求める
時価総額が146億円なら146と書いてください。
python calc_kiyohara_netcash.py 140120240514594985.pdf 146

結果: 210.66%

このコードNYSLライセンスです。無保証自己責任ですが、ご自由に。
かぶ探とかとつなげるといいかもね。
       ''')
       return
    if argc <= 2:
       kiyohara_netcash = pdf_to_kiyohara_netcash(args[1])
       print(kiyohara_netcash)
       return
    if argc <= 3:
       market_cap=float(args[2])*100 #億円から百万円表記に
       kiyohara_netcash = pdf_to_kiyohara_netcash(args[1])
       ratio = round(kiyohara_netcash/market_cap*100,2)
       print(f"{ratio}%")
       return

if __name__ == '__main__':
    mymain()

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-10-06

ワイ:

x = torch.tensor([

[1.0,2.0,3.0],

[4.0,5.0,6.0]

])

最終次元が channel とし、この x を channel-wise 正規化してください。

Claude3.5 Sonnet:

はい、channel-wise 正規化チャネル方向の正規化)を行います。この場合、最終次元(dim=-1)がチャネルとなります。channel-wise 正規化では、各チャネルの平均を0、分散を1に正規化します。

PyTorchを使用して、以下のように実装できます

import torch

x = torch.tensor([
    [1.0, 2.0, 3.0],
    [4.0, 5.0, 6.0]
])

# チャネル方向(最終次元)の平均と標準偏差計算
mean = x.mean(dim=-1, keepdim=True)
std = x.std(dim=-1, keepdim=True)

# Epsilon を追加して、ゼロ除算を防ぐ
epsilon = 1e-5

# 正規化を実行
x_normalized = (x - mean) / (std + epsilon)

print("元のテンソル:")
print(x)
print("\n正規化後のテンソル:")
print(x_normalized)

このコードを実行すると、以下のような結果が得られます

元のテンソル:
tensor([[1., 2., 3.],
        [4., 5., 6.]])

正規化後のテンソル:
tensor([[-1.2247,  0.0000,  1.2247],
        [-1.2247,  0.0000,  1.2247]])

ワイ:

x = torch.tensor([

[1.0,2.0,3.0],

[4.0,5.0,6.0]

])

最終次元が channel とし、この x を channel-wise 正規化してください。

ChatGPT o1-preview

import torch

x = torch.tensor([
    [1.0, 2.0, 3.0],
    [4.0, 5.0, 6.0]
])

# Compute mean and standard deviation along the batch dimension (dim=0)
mean = x.mean(dim=0, keepdim=True)
std = x.std(dim=0, unbiased=False, keepdim=True)

# Perform channel-wise normalization
x_normalized = (x - mean) / std

print("Normalized Tensor:\n", x_normalized)

Output:

Normalized Tensor:
 tensor([[-1., -1., -1.],
        [ 1.,  1.,  1.]])

Explanation:

Compute Mean:

The mean is computed along the batch dimension (dim=0), treating each column as a channel.

mean = x.mean(dim=0, keepdim=True)

This results in mean = [[2.5, 3.5, 4.5]].

Compute Standard Deviation:

The standard deviation is computed along the same dimension with unbiased=False to match the sample size.

std = x.std(dim=0, unbiased=False, keepdim=True)

This results in std = [[1.5, 1.5, 1.5]].

Normalize:

Subtract the mean and divide by the standard deviation for each channel.

x_normalized = (x - mean) / std

This yields the normalized tensor with standardized channels.

Note: Setting keepdim=True ensures that the mean and standard deviation tensors have the same number of dimensions as x, which is necessary for broadcasting during subtraction and division.

ChatGPTの方が正しいよね?

2024-08-17

anond:20240817001425

・・・できたけど木の組み立てがしんどすぎるー

class TreeNode:
def __init__(self, name, attributes=None):
self.name = name
self.attributes = attributes or {}
self.children = []

def add_child(self, child_node):
self.children.append(child_node)

def display(self, level=0):
indent = " " * level
print(f"{indent}{self.name} {self.attributes}")
for child in self.children:
child.display(level + 1)

def has_dependency(self):
# ルートノード属性を持たないノード依存関係を判定しない
if not self.children:
return False

for child in self.children:
# 子ノードがBusinessHourかScheduleかをチェック
if "start_at" in child.attributes and "end_at" in child.attributes:
child_start = child.attributes["start_at"]
child_end = child.attributes["end_at"]

# 現在ノードがBusinessHourで、子がScheduleの場合
if "start_at" in self.attributes and "end_at" in self.attributes:
self_start = self.attributes["start_at"]
self_end = self.attributes["end_at"]

if self_start <= child_start and self_end >= child_end:
print(f"{child.name} (start_at: {child_start}, end_at: {child_end}, room_id: {child.attributes['room_id']}) is dependent on {self.name} (start_at: {self_start}, end_at: {self_end})")
else:
print(f"{child.name} (start_at: {child_start}, end_at: {child_end}, room_id: {child.attributes['room_id']}) is NOT dependent on {self.name} (start_at: {self_start}, end_at: {self_end})")

# 現在ノードがRoomで、子がScheduleの場合
elif self.name.startswith("Room"):
print(f"{child.name} (start_at: {child_start}, end_at: {child_end}, room_id: {child.attributes['room_id']}) is dependent on Room {self.name[-1]}")
else:
child.has_dependency()

# 子ノード属性を持たない場合再帰的に依存関係をチェック
else:
child.has_dependency()

# ノード作成
root = TreeNode("Root")
office_node = TreeNode("Office")

# Roomノード作成
room1_node = TreeNode("Room1")
room2_node = TreeNode("Room2")

# BusinessHourノード作成
business_hour1_node = TreeNode("BusinessHour1", {"start_at": 9, "end_at": 12})
business_hour2_node = TreeNode("BusinessHour2", {"start_at": 13, "end_at": 17})

# Scheduleノード作成
schedule1_node = TreeNode("Schedule1", {"start_at": 10, "end_at": 11, "room_id": 1})
schedule2_node = TreeNode("Schedule2", {"start_at": 14, "end_at": 15, "room_id": 1})
schedule3_node = TreeNode("Schedule3", {"start_at": 10, "end_at": 11, "room_id": 2})
schedule4_node = TreeNode("Schedule4", {"start_at": 14, "end_at": 15, "room_id": 2})

# 木構造の構築
root.add_child(office_node)
office_node.add_child(room1_node)
office_node.add_child(room2_node)
office_node.add_child(business_hour1_node)
office_node.add_child(business_hour2_node)

# Room1にSchedule1, Schedule2を追加
room1_node.add_child(schedule1_node)
room1_node.add_child(schedule2_node)

# Room2にSchedule3, Schedule4を追加
room2_node.add_child(schedule3_node)
room2_node.add_child(schedule4_node)

# BusinessHour1にSchedule1, Schedule3を追加
business_hour1_node.add_child(schedule1_node)
business_hour1_node.add_child(schedule3_node)

# BusinessHour2にSchedule2, Schedule4を追加
business_hour2_node.add_child(schedule2_node)
business_hour2_node.add_child(schedule4_node)

# 木構造の表示
root.display()

# 依存関係のチェック
office_node.has_dependency()
room1_node.has_dependency()
room2_node.has_dependency()
business_hour1_node.has_dependency()
business_hour2_node.has_dependency()

Root {}
Office {}
Room1 {}
Schedule1 {'start_at': 10, 'end_at': 11, 'room_id': 1}
Schedule2 {'start_at': 14, 'end_at': 15, 'room_id': 1}
Room2 {}
Schedule3 {'start_at': 10, 'end_at': 11, 'room_id': 2}
Schedule4 {'start_at': 14, 'end_at': 15, 'room_id': 2}
BusinessHour1 {'start_at': 9, 'end_at': 12}
Schedule1 {'start_at': 10, 'end_at': 11, 'room_id': 1}
Schedule3 {'start_at': 10, 'end_at': 11, 'room_id': 2}
BusinessHour2 {'start_at': 13, 'end_at': 17}
Schedule2 {'start_at': 14, 'end_at': 15, 'room_id': 1}
Schedule4 {'start_at': 14, 'end_at': 15, 'room_id': 2}
Schedule1 (start_at: 10, end_at: 11, room_id: 1) is dependent on Room 1
Schedule2 (start_at: 14, end_at: 15, room_id: 1) is dependent on Room 1
Schedule3 (start_at: 10, end_at: 11, room_id: 2) is dependent on Room 2
Schedule4 (start_at: 14, end_at: 15, room_id: 2) is dependent on Room 2
Schedule1 (start_at: 10, end_at: 11, room_id: 1) is dependent on BusinessHour1 (start_at: 9, end_at: 12)
Schedule3 (start_at: 10, end_at: 11, room_id: 2) is dependent on BusinessHour1 (start_at: 9, end_at: 12)
Schedule2 (start_at: 14, end_at: 15, room_id: 1) is dependent on BusinessHour2 (start_at: 13, end_at: 17)
Schedule4 (start_at: 14, end_at: 15, room_id: 2) is dependent on BusinessHour2 (start_at: 13, end_at: 17)
Schedule1 (start_at: 10, end_at: 11, room_id: 1) is dependent on Room 1
Schedule2 (start_at: 14, end_at: 15, room_id: 1) is dependent on Room 1
Schedule3 (start_at: 10, end_at: 11, room_id: 2) is dependent on Room 2
Schedule4 (start_at: 14, end_at: 15, room_id: 2) is dependent on Room 2
Schedule1 (start_at: 10, end_at: 11, room_id: 1) is dependent on BusinessHour1 (start_at: 9, end_at: 12)
Schedule3 (start_at: 10, end_at: 11, room_id: 2) is dependent on BusinessHour1 (start_at: 9, end_at: 12)
Schedule2 (start_at: 14, end_at: 15, room_id: 1) is dependent on BusinessHour2 (start_at: 13, end_at: 17)
Schedule4 (start_at: 14, end_at: 15, room_id: 2) is dependent on BusinessHour2 (start_at: 13, end_at: 17)

anond:20240816235943

高さ3の有向木で根からAという節点が生えAからBという葉が生える

class TreeNode:
def __init__(self, name, attributes=None):
self.name = name
self.attributes = attributes or {}
self.children = []

def add_child(self, child_node):
self.children.append(child_node)

def display(self, level=0):
indent = " " * level
print(f"{indent}{self.name} {self.attributes}")
for child in self.children:
child.display(level + 1)

def has_dependency(self):
# ルートノード属性を持たないノード依存関係を判定しない
if not self.children or "start" not in self.attributes or "end" not in self.attributes:
return False

# Aノードのstartとendを取得
start = self.attributes["start"]
end = self.attributes["end"]

# すべての子ノード(Bノード)に対して依存関係をチェック
for child in self.children:
if "position" in child.attributes:
position = child.attributes["position"]
if start <= position <= end:
print(f"{child.name} (position: {position}) is dependent on {self.name} (start: {start}, end: {end})")
return True
else:
print(f"{child.name} (position: {position}) is NOT dependent on {self.name} (start: {start}, end: {end})")
return False

# ノード作成
root = TreeNode("Root")
a_node = TreeNode("A", {"start": 10, "end": 20})
b1_node = TreeNode("B1", {"position": 15})
b2_node = TreeNode("B2", {"position": 25})

# 木構造の構築
root.add_child(a_node)
a_node.add_child(b1_node)
a_node.add_child(b2_node)

# 木構造の表示
root.display()

# 依存関係のチェック
a_node.has_dependency()

こうかー

2024-08-02

import os

import os

# ファイルパス指定

file_path = 'year_count.txt'

# ファイル存在するか確認し、存在しない場合は初期値を設定

if not os.path.exists(file_path):

with open(file_path, 'w') as file:

file.write('1') # 最初の年数を1に設定

# 現在の年数を読み込み

with open(file_path, 'r') as file:

year_count = int(file.read())

# メッセージを表示

print(f"{year_count}年間で最も暑い夏")

# 年数を+1してファイルに保存

with open(file_path, 'w') as file:

file.write(str(year_count + 1))

インデントつけれね

2024-06-26

if文は1個までにしてください!

以下のような条件は複雑なので読む人は混乱してしまます

if (原作者許可を得ている) {
    if (改変後の内容が面白い) {
        print('OK改変')
    } else {
        print('NG改変')
    }
} else {
    print(’NG改変’)
}

2024-05-24

anond:20240523100428

ダブスタ検証用のスクリプト簡単に書いたよ(AIで)

import requests
import json
from urllib.parse import quote

def fetch_bookmarks(url):
    try:
        # URLエスケープ
        escaped_url = quote(url, safe="")
        api_url = f"https://b.hatena.ne.jp/entry/json/?url={escaped_url}"

        response = requests.get(api_url)
        response.raise_for_status()

        try:
            return response.json()
        except json.decoder.JSONDecodeError as e:
            print(f"Error decoding JSON from {api_url}: {e}")
            print("Response content:", response.text)
            return []
    except requests.exceptions.RequestException as e:
        print(f"Error fetching bookmarks from {api_url}: {e}")
        return []

def find_common_bookmarks(bookmarks1, bookmarks2, url1, url2):
    common_users = set(bm["user"] for bm in bookmarks1 if bm["comment"]) & set(bm["user"] for bm in bookmarks2 if bm["comment"])
    common_bookmarks = []
    for user in common_users:
        comments = []
        for bm in bookmarks1:
            if bm["user"] == user and bm["comment"]:
                comments.append({"url": url1, "comment": bm["comment"], "timestamp": bm["timestamp"]})
                break
        for bm in bookmarks2:
            if bm["user"] == user and bm["comment"]:
                comments.append({"url": url2, "comment": bm["comment"], "timestamp": bm["timestamp"]})
                break
        if len(comments) == 2:
            common_bookmarks.append({"user": user, "comments": comments})
    return common_bookmarks

if __name__ == "__main__":
    url1 = "https://news.yahoo.co.jp/articles/f9966c4ccc374fc88babbb50175a9ea844c99638"
    url2 = "https://www.asahi.com/articles/ASN6K7F64N6KUJHB00L.html"

    data1 = fetch_bookmarks(url1)
    data2 = fetch_bookmarks(url2)

    common_bookmarks = find_common_bookmarks(data1["bookmarks"], data2["bookmarks"], url1, url2)

    print(json.dumps(common_bookmarks, indent=2, ensure_ascii=False))

url1, url2のところを対象としたいものに変えれば使えるよ

抽出対象となるのは以下のユーザーだよ

バグあったら直して使ってね

※てかはてな匿名ってシンタックスハイライト記法使えないんだね、使って表示確認したら500エラーになったわ

2024-03-27

今日運勢は: 吉

od -vAn -tu4 -N4 /dev/random | awk '{$1=$1%4+1;print ($1==1)?"凶":(($1==2)?"吉":(($1==3)?"小吉":(($1==4)?"中吉":"大吉")))}'

2024-03-17

小3の先日のテストに出た問題の一つ。大学受験でも解けない学生がいっぱいいるだろうし、数学好きを除き多くの大人は解けないだろう。 - Togetter

https://togetter.com/li/2332954

さくっとコード解決

let box = new Array(30).fill(0);
for(let i = 1; i <= 30; i++) {
	for(let j = i; j <= 30; j += i) {
		box[j - 1]++;
	}
}
print("1. ", box.filter(v => v === 2).length);
print("2. ", box.filter(v => !(v % 2)).length);

1. 10

2. 25

https://ideone.com/MCcW3D

2024-03-02

エクセルマクロのお作法計算用シートという諸悪の根源について)

前置き

この日記の内容は、会社の後輩から最近エクセルマクロ勉強し始めて(キラキラ)」という話を聞いて、先輩ムーブかますために話した内容になります

とにかくこれから説明する「計算用シート」が憎くて憎くてたまらず、ちょっと引かれるほど熱弁してしまいました。

ただ、他の方がどうされているのかや、逆に「計算用シート」を愛用する方の意見も聞きたくなり、増田に書いてみました。

増田の経歴

この記事趣旨

エクセルマクロのお作法とか書きましたが、要するにエクセルマクロで「計算用シート」って色々な意味でよくないよね、という話をしたいです。

3行でまとめます

〇 エクセルシートはユーザーインターフェースインプット)か出力結果(アウトプット)のためのものとすべき

〇 データ加工をする場合には、原則配列辞書配列連想配列)に格納して加工を行い、最後の結果だけシートに出力するべき

〇 何事にも例外はある。

計算用シートとは

この記事では、エクセルシートを下記の通り分類します。

エクセルマクロにも色々あると思いますが、今回は下記を想定します。

日付や人物名などを入力し、データベースや別のエクセルファイル、別のシートから取得したデータ入力された値を基に加工し、加工後のデータをシートに出力する

この場合入力欄があり編集可能なシートがユーザーインターフェース、最終的に加工されたデータが出力されるシートが出力結果です。

(もちろん、ユーザーインターフェースの別の欄(セル)に出力する場合もあるし、その場合ユーザーインターフェース出力結果が一体のものとみなします。)

また、データ用シートは同じエクセルファイル内に基となるデータが含まれ場合を想定します。

(これ自体が非推奨で、SQLデータベースかせめてAccessを使え、という意見はありますがそれは別にして…)

ではここで定義する計算用シートとはなにかというと、文字通り計算を行うためのシートです。

例えばイメージするのはこんなマクロです。

1.元となるcsvファイルエクセルに読み出してシートに格納

2.そのデータは日付が数値型になっているので、日付(数値型)の入った列を文字列に変換した日付(文字列型)列を新たに作成

3.その列をキーとして対象となるデータを取り出すvlookup関数を各行に格納した列を新たに作成

4.その列で特定された列をさらに加工した列を新たに作成し、…

これは極端な例ですが、とにかく変数配列定義せず(あるいはエクセルセルオブジェクト変数のように扱い)、エクセルに値を入力し、それを直接加工することで目的となるデータ加工をしたり、様々な処理をします。

その舞台となるのが、計算用シートです。

なんかこんな感じの処理をしているエクセルマクロ、どこの会社でも腐るほどあるんじゃないでしょうか。

ある程度マクロに慣れた気の利く人なら、このシートはロック非表示にして、ユーザーから触れないようにするでしょう。

・・・これ、やめたほうが良くないですか?

こいつが日本生産性を落とす諸悪の根源だと思います

駄目な理由

ある程度詳しい人なら同意してくれると思いますが、このやり方でダメ理由はいっぱいあります

後で説明する配列辞書配列連想配列)と比べると格段に処理が遅いです。

わざわざエクセル操作しているから当然ですね。

ちょっと詳しい人が知っている「画面更新非表示」を駆使しても、配列を使った処理からみれば止まったハエです。

(参考)VBAで作ったマクロの高速化① 配列を使う

  • 可読性が下がる

いったんエクセルシートにデータを格納して加工しているので、コードエクセルシートを両方見る必要があり、とても読みにくいです。

変数として命名されていないのも致命的で、処理の意図が余計に分からなくなります

計算用シートを事前に用意して、別のセル関数を格納しておき、マクロ関数を使ってデータ加工をするものも見たことがあります

これは懲役刑に処したほうがいいと思います

まり知られていませんが、セルの最大文字数は32,767 文字です。

セルの最大文字数を超えると自動的に隣のセルに値が入り、シートが滅茶苦茶になります

他にもエクセルの数値を丸め自動変換の仕様とか文字列→日付の自動変換とか、いくつものバグに苦しめられます

できる人だと、いちいち最大文字数が多い場合の処理を書いたり自動変換機能を殺したりしてくれますが、そんなことに手間をかけているか日本GDPは上がらないんだと思います

他にも、データが大きくなると処理が重くなり不安定になる、計算用シートを人が触ってしまリスクがある、などいくらでも理由は上げられます

(逆に利点は、目の前でガチャガチャ動いてスーパーハッカーになった気分になれるくらいしか思いつかない・・・

じゃあどうするの

配列を使いましょう。

配列とは何ぞや、という人はググってください。

配列データを入れて、データ加工は配列変数に対して行い、一番最後の出力だけセルに値を格納する。

他のプログラミング言語なら普通にやっていることです。

個人的オススメしたいのは辞書配列連想配列)で、うまく使うとデータ管理簡単になり、処理も爆速になります

(参考)【VBA】大量データから高速で値を検索【Dictionaryを使う】

csvファイルもなまじエクセルで開けるだけに別のブックやシートで開きがちですが、これは悪魔のささやきです。

直接ファイルを読み出してLine InputやSplitで配列に格納しましょう。

エクセルとして開くやり方はコード書くのは簡単でも、実行時間に天と地ほどの差が出ますエクセル開くと処理もめちゃ不安定です。

(参考)Excel VBAでCSVオープンするときのパフォーマンス比較

いや、冒頭のマクロを書く人の気持ちも分かるつもりです。自分コードを書き始めたころは全部シート上で操作していました。

冒頭のマクロのほうが直感的なんですよね。自分が手で書くことをマクロやらせる、というマクロ本来趣旨にはあっていますし。

途中の計算過程もすべて目の前で展開されるから分かりやすいです。

ただ、それではダメなんです。。。処理は遅いし挙動不安定だし後で改修・保守する人が死にます

あと、エクセルシートやセルは当然エクセルしかないので、エクセルマクロVBAから他の言語に移れなくなります

自分エクセルマクロの里の出なので、計算用シート脱却には苦労しましたが、苦労して会得した配列辞書配列連想配列)のスキルはそのまま他の言語に活かすことができました。

配列の中身を見る方法別にある(ローカルウィンドウやDebug.printを使うなど)ので、リハビリに取り組んでほしいです。

(参考)VBA デバッグの仕方

もちろん例外もあります

計算用シートを許容できる、使うべきケースもあると思います。。

個人的には、

最後のは、なんでも自分確認しないと気が済まない上司発注で、意味不明と思いましたしたがしぶしぶやりました。)

などの場合計算用シートを使ってもよいと思います

この場合インプットエクセルシートに直接加工するのは論外なので、計算用(加工用)のシートを用意してそこで操作を行うことは必要だと思います

他にも、こういうときは「計算用シート」があったほうが良い、という状況があれば教えてもらえると嬉しいです。

最後

そもそもツッコミとして、「データ加工するならエクセルマクロを使わずpythonとかRとかもっとまともな言語使えよ」という言葉が来そうな気がします。

ただ、個人的にはエクセルマクロVBA)は大好きですし、初心者にもおすすめしたいです。

自分のような非エンジニアだと、セキュリティ関係などでPythonの開発環境とかすごく用意しにくいんですよね。

(あと、コマンドプロンプトの真っ黒な画面が怖かった)

その点エクセルマクロは、開発環境の用意はプロパティでチェック項目を一つオンにするだけだし、入門書がたくさんあるし、セル挙動を追えば視覚的にプログラム理解できるし、初心者に優しいです。

(そのやさしさが上述したとおり悪魔の罠なわけですが。)

最初計算用シートに頼ってでもエクセルマクロからプログラミングを始めて、本格的なデータ加工をし始めたあたりで計算用シートという諸悪の根源から脱却する。

さらに本格的なデータ処理を行うために、PythonやRなど別の言語習得したり、エクセルからSQLデータベースやACCESSなどに切り替えていく、というプロセスがいいのではと個人的に思います

2024-01-22

ブコメダブスタをチェックするためのスクリプト適当Pythonで書いた

エラーハンドリングは省略。標準ライブラリのみで動く。

import json
import urllib.request


# True にするとユーザー名を隠す
hide_user = False
# 以下を書き換える。sys.argv 使ってもいいんだけど
url1 = "https://www.cygames.co.jp/news/id-23172/"
url2 = "https://mtg60.com/archives/palworlddoujinsi.html"


def get_bookmarks(url: str):
    req = urllib.request.Request(f"https://b.hatena.ne.jp/entry/json/{url}")
    with urllib.request.urlopen(req) as res:
        dict = json.loads(res.read())

    user_comments = {}

    for bookmark in dict["bookmarks"]:
        if bookmark["comment"]:
            user_comments[bookmark["user"]] = bookmark["comment"]

    return user_comments


b1 = get_bookmarks(url1)
b2 = get_bookmarks(url2)

common = set(b1.keys()).intersection(b2.keys())

print(f"[1] {url1}")
print(f"[2] {url2}")
print()

for user in sorted(common):
    if hide_user:
        print(user[0] + "*" * (len(user) - 1))
    else:
        print(user)
    print(f"[1] {b1[user]}")
    print(f"[2] {b2[user]}")
    print()

2023-12-29

増田納め 2023年のマイ日記集計

こんます

2023年も残すところわずかとなりましたが、皆様方におかれましてはいかがお過ごしでしょうか。

一年間の振り返りなどはされましたでしょうか。

 

私、一年間に書いた増田を振り返ってみましたところ、

2423件の日記を綴っており、

頂いた総ブクマ数は1893、総トラバ数は1060となりました。

これもひとえに皆様方のご支援ご声援のおかげであります

本年も大変お世話になりました。

 

最期に、ポンコツの私がChatGPTの手となり足となり作成した増田集計コード掲載します。

日記URLタイトル投稿日時、文字数、被ブクマ数、被トラバ数を取得しCSVファイルに出力するものです。

お暇な方はお使いください。

 

それではよいお年をお迎えください。

import requests
from bs4 import BeautifulSoup
import time
import csv
import os
import re


# ログインURL
login_url = 'https://hatelabo.jp/login'

# ログイン情報
login_data = {
    'key': 'あなたユーザ名またはメールアドレス',
    'password': 'あなたパスワード',
    'mode': 'enter'
}

user_name = 'あなたユーザ名'

# User-Agent ヘッダー(例:Google Chrome)
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
}

# セッションを開始
session = requests.Session()
# ログイン
response = session.post(login_url, data=login_data, headers=headers)
print('login',response.status_code)

# 集計データ
item = {
    'url': '', # URL
    'title': '', # タイトル
    'datetime': '', # 投稿日時
    'characters': '', # 文字数
    'bookmark': '', # 被ブクマ数
    'trackback': '', # 被トラバ数
}

# CSVファイル名
output_file = 'masuda_output.csv'
# CSVファイル存在しない場合はヘッダーを書き込む
if not os.path.exists(output_file):
    with open(output_file, 'w', newline='', encoding='utf-8') as file:
        writer = csv.DictWriter(file, fieldnames=item.keys())
        writer.writeheader()


# 集計
page_start = 1
page_end = 3
for i in range(page_start, page_end+1):
    
    # 待機
    time.sleep(3)

    # 増田一覧取得
    page = session.get(f'https://anond.hatelabo.jp/{user_name}/?page={i}')
    print(page.url)
    
    # 応答のHTMLをBeautifulSoupで解析
    soup = BeautifulSoup(page.content, 'html.parser')
    
    entries = soup.find_all('div', class_='section')
    for entry in entries:
        header = entry.find('h3')

        timestamp = header.find('a').get('href')[1:]
        item['url'] = 'https://anond.hatelabo.jp/'+timestamp
        item['title'] = header.get_text()[:-1]
        item['datetime'] = f"{timestamp[0:4]}/{timestamp[4:6]}/{timestamp[6:8]} {timestamp[8:10]}:{timestamp[10:12]}"

        footersection_text = entry.find_all('p')[-2].get_text()            
        item['characters'] = len(entry.find('p').get_text().strip(footersection_text))
        item['trackback'] = int(re.search(r'\((.*?)\)', footersection_text).group(1) if re.search(r'\((.*?)\)', footersection_text) else '')
        if item['title'] == '■':
            item['title'] = entry.find('p').get_text().strip(footersection_text)[:35]

        # 待機
        time.sleep(3)

        bookmark_page = session.get(f'https://b.hatena.ne.jp/entry/button/?url=https%3A%2F%2Fanond.hatelabo.jp%2F{timestamp}&layout=basic-label-counter&lang=ja')
        soup_b = BeautifulSoup(bookmark_page.content, 'html.parser')
        item['bookmark'] = int(soup_b.find('a', class_='count').get_text())

        # CSVファイル追記
        with open(output_file, 'a', newline='', encoding='utf-8') as file:
            writer = csv.DictWriter(file, fieldnames=item.keys())
            writer.writerow(item)

追記

わー。ごめんなさい。文字が何か所か変わっていました。

\ → \

& → アンドマーク(打てない←なんで~?)

anond:20231229001458

def もらった関数を実行する関数を返す(もらった関数):

 def もらった関数を実行する関数():

  print("開始")

  もらった関数()

  print("終了")

 return もらった関数を実行する関数

def あげる関数():

 print("これはあげる関数です")

あげた関数を実行する関数 = もらった関数を実行する関数を返す(あげる関数)

あげた関数を実行する関数()

あげた関数を実行する関数を実行したんだからあげ関数を実行して"これはあげる関数です"になる

pythonわからん

このpythonプログラム

def func1(f):

 def wrapper():

  print("開始")

  f()

  print("終了")

 return wrapper

def func2():

 print("これは func2です")

func = func1(func2)

func()

実行結果が

開始

これは func2です

終了

なんだけど

なんで最後

func()からdef wrapper()が呼び出されるの?

スコープはどうした?って思ってしま

実際func()をwrapper()に書き換えて実行するとエラーになる

そりゃそうだよねスコープ的におかしいもんね

なのにfunc()だと行ける

returnでwrapperを返したから行けるんだろうけどそれがわからん

returnしたってことはスコープ的にどういう状態なんだ?

func()の階層関係ないってこと?

pythonっていうかプログラムがよくわからん

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