Movatterモバイル変換


[0]ホーム

URL:


はてラボはてな匿名ダイアリー
ようこそ ゲスト さんログインユーザー登録

「utf-8」を含む日記RSS

はてなキーワード:utf-8とは

次の25件>

2025-10-22

自分ホームページを作ったかどうかでWEBの見え方が180度以上違う話

以下ChatGPT

自分ホームページ(自前ドメイン+自前HTML)を一度でも作って運用すると、SNS中心の“受け手視点から仕様検索配信・所有・継続の“作り手”視点に脳が切り替わる。結果、情報リテラシーは跳ね上がり、ネットニュース流行の見え方が根本から変わる——しか想像以上に。

1. “タイムラインからアーキテクチャ”へ

Before(作る前):WebSNSタイムライン。良し悪しは「バズってるか」「見やすいか

After(作った後):WebプロトコルブラウザHTML/CSS/JSCDN検索エンジン。

ページは**文書(Document)**であり、配置(IA)、意味づけ(セマンティクス)、配信HTTP/HTTPS/HTTP/2/3)、キャッシュ戦略が気になりだす。

→ 同じ記事でも「タイトルの付け方」「hタグ構造」「画像最適化」「OGP」「サイトマップ」がまず目に入るようになる。

2. “アルゴリズム運”から“所有と積み上げ”へ

プラットフォーム依存の脆さを体感規約変更やシャドウバン露出が消える。

サイト資産化:ドメインに紐づくURLリンクされ、検索に積み上がり、10年後も生きる。

POSSE(Publish (on your) Own Site, Syndicate Elsewhere):まず自分サイトに出してから外部へ配信する習慣が身につく。

3. “好き/嫌い”から“なぜ速い・なぜ遅い”へ

CoreWeb Vitals(LCP/FID/CLS)や画像の遅延読み込み、フォント最適化重要性が腹落ちする。

広告・計測タグの重さに過敏になる。読者体験を壊さないためのパフォーマンス予算という概念生まれる。

4. “なんとなくSEOから情報設計×検索意図”へ

キーワード選定は“流入ゲーム”ではなく読者の課題コンテンツ設計帰着

内部リンクパンくず・スキーマ構造データ)・サイトマップ意味が実務として理解できる。

“書けば伸びる”ではなく“検索意図を満たす設計が伸びる”に目が覚める。

5. “見た目”から意味アクセシビリティ)”へ

alt見出し階層コントラスト比、キーボード操作、焦点管理など、見えない品質が最重要になる。

デザインは飾りではなく“読み・理解操作”のためのユーティリティだと分かる。

6. “PV至上”から継続コミュニティ”へ

たまたま当たる1記事より、更新継続アーカイブ性・RSSのほうが効くと実感。

コメント欄メールフォーム・X連携よりも、ニュースレターRSS購読者の質に価値を見出す。

7. “無料神話からコスト責任”へ

ドメインDNS証明書バックアップ法務特商法プライバシーポリシー)に“運用者の責任”が生まれる。

その重みが情報信頼性を引き上げる(=他人サイトの苦労も見えるようになる)。

8. “トレンド追従から自分OSを持つ”へ

サイト思想作品OS

トレンドは“輸入”ではなく選別になる。自分歴史に合うものだけを採用して積層していける。

9. まず一歩:最小スタックで“今夜リリース”する

Node.jsを避けたい人向けに、極小構成OK

A. 最小HTML(雛形)

<html lang="ja">

<head>

<meta charset="utf-8" />

<metaname="viewport" content="width=device-width,initial-scale=1" />

<title>あなた名前 |ホーム</title>

<metaname="description" content="自分ホームページ制作物・日記メモを置いていきます。">

<link rel="alternate" type="application/rss+xml"title="RSS"href="/feed.xml">

<meta property="og:title" content="あなた名前 |ホーム">

<meta property="og:description" content="自分ホームページ制作物・日記メモ。">

<meta property="og:type" content="website">

</head>

<body>

<header>

<h1>あなた名前</h1>

<nav>Home /About /Posts</nav>

</header>

<main>

<article>

<h2>はじめまして</h2>

ここからすべてを自分URLに積み上げます

</article>

</main>

<footer>© 2025あなた名前</footer>

</body>

</html>

B.ホスティング無料~低コスト

GitHubPages(Jekyll標準。Rubyベース、Node不要

CloudflarePages(静的ファイルを置くだけで高速CDN

レンタルサーバー(静的HTML+SFTP/rsyncで十分)

C.ドメインの基本

覚えやすい短さ+ローマ字。将来10年使える名前に。

DNSA/AAAA/CAA/TXT最低限、HTTPS必須Let’s Encrypt無料化)。

D. “最低限の品質チェック”5点

タイトル・description見出し一貫性

画像は適切なサイズalt

モバイルでの可読性(文字サイズ行間

OGPが効いているか(XやLINEURLを貼って確認

RSS/更新履歴の有無(継続を前提に)

10. 一歩先へ:運用で差がつく“3つの習慣”

ログを読む:SearchConsoleと簡易アクセスログで“本文よりメタ情報”を磨く。

アーカイブ主義記事追記更新URLは変えない。Versioningを意識

POSSE徹底:自サイトに公開→SNSには要約+リンク本体は常に自分土俵

Permalink |記事への反応(0) | 19:49

このエントリーをはてなブックマークに追加ツイートシェア

ネトウヨ高市が言ってるライフワークバランス自分のことを考慮しないということだ!」

ワイ「そうなの?なら安心だね」

【速報】首相厚労相労働時間規制緩和検討指示https://t.co/FYd65uJRkb47NEWS (@47news_official)October 21, 2025

<script asyncsrc="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

ネトウヨ「…」

ワイ「話が違うやんけーーー!」

Permalink |記事への反応(1) | 19:21

このエントリーをはてなブックマークに追加ツイートシェア

2025-10-15

ネットの産め論のひと、大概女叩きとワンセットだし本音はたぶん女に不幸になってもらいたいだけなんだと思う。— ぽんこげちゃん💉💉💉💉 (@ponkogechan1)October 15, 2025

<script asyncsrc="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

Permalink |記事への反応(1) | 12:50

このエントリーをはてなブックマークに追加ツイートシェア

2025-09-18

anond:20250918132521

メモ帳あればなんでもできるじゃん

UTF-8対応してるし

Permalink |記事への反応(1) | 13:27

このエントリーをはてなブックマークに追加ツイートシェア

2025-09-05

今日日本語の誤り「」

脈絡」の間違いのようだ

割と普及している

https://search.yahoo.co.jp/realtime/search?p=%E8%84%88%E7%95%A5&ei=UTF-8&ifr=tp_sc

Permalink |記事への反応(1) | 01:25

このエントリーをはてなブックマークに追加ツイートシェア

2025-08-21

dorawii@執筆依頼募集中

自動ブクマするローカルサーバーとかの構成を作った。

ブクマには↓のサブアカ使用

https://profile.hatena.ne.jp/dorawii_bukuma/

はてなサイト側で読み込まれているはずのrksトークンを生成する関数を直接叩く方法がどうしても分からず結局request処理を自分で書く方法ではなく自動UI側の保存ボタンクリックするという無難な方向に落ち着いた。

最初から後者方法をとっていればもっと全然早く作れたのにというは所詮言い訳か。

とにかくスクリプトを公開しておく。

start-server.bat

@echo off
cd /d "C:\Users\user\Documents\jsscript"

:: Nodeサーバーを別ウィンドウで起動
start /min "" noderun-batch-server.js

::Pythonサーバーを別ウィンドウで起動(hatenaserver配下
start cmd /k ""python hatenaserver\server.py

以降はjsscript直下に配置

config.json

{
"username": "",
"password": ""
}
server.py

from flask import Flask, request,jsonify
importjson
importos
from hatena_client import HatenaClient
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

config_path =os.path.join(os.path.dirname(__file__), 'config.json')
withopen(config_path, encoding='utf-8')as f:
config =json.load(f)

@app.route('/bookmark', methods=['POST'])
def handle_bookmark():
data = request.json
url = data.get("url")
if noturl:
returnjsonify({"error": "MissingURL"}), 400

client = HatenaClient(config["username"],config["password"])
client.start_browser()

if notclient.login():
client.quit()
returnjsonify({"error": "Login failed"}),403

success =client.add_bookmark(url)
client.quit()

returnjsonify({"status": "ok" if success else "fail"})

if __name__ == "__main__":
app.run(port=12347)

あとはグリモンユーザスクリプトとして書くやつ

// ==UserScript==
// @name自動セルクマ送信
// @namespace tampermonkey.net/
// @version 2025-08-07
// @descriptiontry totakeoverthe world!
// @authorYou
// @matchanond.hatelabo.jp/*
// @grant none
// ==/UserScript==

(function () {
'use strict';

consturl = location.href;
if (!/^https:\/\/anond\.hatelabo\.jp\/\d+$/.test(url)) return;
const editLink = document.querySelector('a.edit');
if (!editLink) {
// 既に編集ページなので処理をスキップ
console.log('編集リンク存在するため、スクリプトを終了します。');
return;
}

fetch('localhost:12347/bookmark', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body:JSON.stringify({url:url })
}).then(r =>console.log("通知成功")).catch(e =>console.error("通知失敗", e));
})();
-----BEGINPGP SIGNEDMESSAGE-----Hash: SHA512https://anond.hatelabo.jp/20250821192753# -----BEGINPGP SIGNATURE-----iHUEARYKAB0WIQTEe8eLwpVRSViDKR5wMdsubs4+SAUCaKb0qwAKCRBwMdsubs4+SHfiAQDcXmTHBaZ5Zzr1KI/OxZ0xl69oevOdy1FXJYwYvsmo5AD/ZPtZiO1JgTDjm+27iymlkdzIXOIGWfC82UTr1mJ7EwU==YoV+-----ENDPGP SIGNATURE-----

Permalink |記事への反応(1) | 19:27

このエントリーをはてなブックマークに追加ツイートシェア

2025-08-19

「遅ればせながら」の誤用が気になる

割と多いが、それ以上に面白いのはその「多様さ」だ

「遅らせながら」

https://search.yahoo.co.jp/realtime/search?p=%E9%81%85%E3%82%89%E3%81%9B%E3%81%AA%E3%81%8C%E3%82%89&ei=UTF-8&ifr=tl_sc

「おくらばせながら」

https://search.yahoo.co.jp/realtime/search?p=%E3%81%8A%E3%81%8F%E3%82%89%E3%81%B0%E3%81%9B%E3%81%AA%E3%81%8C%E3%82%89&ei=UTF-8&ifr=tl_sc

「おくばせながら」

https://search.yahoo.co.jp/realtime/search?p=%E3%81%8A%E3%81%8F%E3%81%B0%E3%81%9B%E3%81%AA%E3%81%8C%E3%82%89&ei=UTF-8&ifr=tl_sc

「おそばせながら」

https://search.yahoo.co.jp/realtime/search?p=%E3%81%8A%E3%81%9D%E3%81%B0%E3%81%9B%E3%81%AA%E3%81%8C%E3%82%89&ei=UTF-8&ifr=tl_sc

Permalink |記事への反応(0) | 22:49

このエントリーをはてなブックマークに追加ツイートシェア

2025-08-06

これでも年収日本円換算で1,2億確約されてるなら別に構わないと思う

日本だとこれで1000万円届かないことありそう

Scott Wuが買収したWindsurfチームに送ったメッセージえぐい

「我々が求める仕事の水準は極めて高い。我々はワークライフバランスを信じていない。入社するなら、オフィスで週6日、週80時間以上働くことに同意することになる」…—久保田 雅也@Coalis (@kubotamas)August 5, 2025

<script asyncsrc="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

Permalink |記事への反応(0) | 10:54

このエントリーをはてなブックマークに追加ツイートシェア

2025-08-05

これ意外と持ち帰ろうとする人が多いって現実があるからなあ

ひざ掛けが持ってかれるのはデフォで機内エンタメ用のリモコンを外して持って帰ろうとするやつとかもいるらしいし

ビジネスクラスとかファーストクラスにXREALとかViture入れるのありだと思うwJALの新規事業の知り合いをXREALの人に紹介したことはあるけどwhttps://t.co/nEFRTDwLnw— nulls-ensei (@GOROman)August 5, 2025

<script asyncsrc="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

Permalink |記事への反応(0) | 19:23

このエントリーをはてなブックマークに追加ツイートシェア

2025-08-03

ホンダ軽トラから撤退したのは進化に追いつけなかったからじゃない

軽トラのことがまた話題になってるが視野狭窄だ。端的に言って、軽トラ軽自動車日本だけの商品と考えているのが大本の間違いだ。軽自動車グローバル商品なんだよ。

https://b.hatena.ne.jp/entry/s/togetter.com/li/2584277

 

google:image:chevrolet damas画像検索してみてくれ。見覚えのある軽バンが出てくるだろう。スズキブリー(キャリーバン)だ。だがシボレーバッジをつけているのだ。しか左ハンドル。更にエンジン韓国大宇製だ。何者だこれは。

これはスズキキャリーバンGMライセンス生産しているものである

 

次はgoogle:image:suzuki bolangoogle:image:Carry Dabbaだ。

これはスズキキャリーパキスタン生産しているものだ。因みにパキスタン左側通行なので右ハンドル

この元になったキャリーは実は2スト360cc時代のもの。それに今の法規制に適合する4スト800ccEFIなんかのエンジンを載せているという異常進化を遂げている。

因みにこの生産ラインは、インドネシアキャリーモデルチャンジする際に売却されたものと思われる。

 

お次はgoogle:image:piaggio porterだ。ピアジオベスパスクーターで有名な2輪メーカーだ。ダイハツハイゼットがそのピアジオエンブレムを付けてイタリアや他のEU諸国を走っている。

これはダイハツ生産した部品を現地でノックダウン生産しているものだ。外装のプラ部品内装品は現地生産しているので見た目がかなり違う。

ついでにgoogle:image:piaggio porter ambulanceではハイゼット救急車が見られるぞ。ゲテモノっぽいし狭苦しいのだが、道が狭い、ローマなどの歴史地区では無くてはならない車だ。

更にこのポータートラックの方が香港救急車に改造されたのも見る事ができるだろう。日本イタリア香港と海を渡っているんだな。

 

日本だけ見てるとホンダ軽トラ撤退した意味は分からない。でもスズキダイハツはこういう風に世界中生産しているのだ。特にスズキは「グローバル軽自動車」界での巨人で、本当に世界中生産されている。

このグローバル展開の鍵は実はアメリカの車メーカー(と韓国大宇)で、東南アジアを牙城としつつ、その勢力圏から離れる南米中央アジア中東ではGMフォードライセンス生産しているのである

この馴れ初めは、経済が発展途上だった韓国GMと大宇が合弁して現地ライセンス生産をしていた事に始まる。またフォード台湾などで軽自動車ライセンス生産をしていた。

 

ホンダ場合海外展開北米に寄っている。北米は豊かなので軽トラバンなどの市場とならない。

からホンダ軽トラモデルチェンジしたら古いモデルラインは廃棄か部品生産用に低稼働となる。

だがスズキ場合無駄にならないのだ。他国に売却するし技術指導もするからだ。更にライセンス生産だけじゃなくてOEMやノックダウン供給もやっている。

すると規模の経済全然違うのだ。故に生産コストが断然有利だ。

すると、ホンダとしてはこういう条件で戦うのだったらOEM供給受けた方が良いということになる。

 

まあそういう訳で、軽自動車日本だけで作っているという考えは間違い。特に軽トラバンは昔からグローバル商品で、最近ではワゴンRもそれに続いている。多分、10年後の東南アジア南米ワゴンRだらけだろう。

同時に、アメリカの車メーカーGMフォード)が世界中軽自動車を作りまくっているので、アメ車メーカーデカい車しか作れない無能と考えるのも間違いだってことだ。それは米国市場だけのことなのだ。

 

ステラティ会長が「EU軽自動車規格作れ」と言ったのはこういうのを見据えてのことだ。規格が通ったら、ハンガリースズキ工場があるので東欧ワゴンRエブリイだらけになると思われるよ。

 

そういう事を逐一説明した増田を前に投稿したが長くてあまりまれなかった。気になる人はドーゾ→https://anond.hatelabo.jp/20250625180545

Permalink |記事への反応(1) | 20:48

このエントリーをはてなブックマークに追加ツイートシェア

2025-08-02

[今日知った言葉]いわるゆ

https://search.yahoo.co.jp/realtime/search?p=%E3%81%84%E3%82%8F%E3%82%8B%E3%82%86&ei=UTF-8&ifr=tp_sc

 

ふいんきなぜか変換できない)みたいなわざとボケてるのかと思ったらマジっぽいんだが

 

Permalink |記事への反応(1) | 11:00

このエントリーをはてなブックマークに追加ツイートシェア

2025-08-01

anond:20250731160531

精神疾患治すのに、栄養が大事だよと伝えても、伝わらないのは何でですか..

服薬したって栄養状態悪いと薬の効きは悪くなるのでね。または、効いても予後が非常に悪い。まあ予後を考えられないような人が心を病むのだろうし薬に頼るのだろうから、どうしようもないのだが。2025/08/01 05:55

<scriptsrc="https://b.st-hatena.com/js/comment-widget.js" charset="utf-8" async></script>

Permalink |記事への反応(0) | 06:45

このエントリーをはてなブックマークに追加ツイートシェア

2025-07-27

anond:20250727193225

アリ。大アリ。

乗客の男女比率をきちんと調査する必要がある。

まり男女の混雑格差をなくすために

男性専用車両2両

女性専用車両1両

のような編成をするのも当然である

だけどそれは差別

現時点での女性の少なさは社会進出が十分でない結果なので、現状に合わせ固定するなら女性差別環境保全してしまう。

追記

google:image:公平

のように、身体構造上・障害上、避けられないハンディキャップを結果平等にするのが公平。

車椅子のためのスロープなども同じ。

男女の泌尿器の仕組みからくる不可避の時間差をバランスをとるための数の調整は必要だと思う。

利用者の人数を元に結果平等にするならば、増田氏の結論と同じになるだろう。

Permalink |記事への反応(1) | 21:16

このエントリーをはてなブックマークに追加ツイートシェア

2025-07-22

政党Youtubeチャンネル寸評

党名Youtubeリンク動画登録者コメント欄
自民党google:site:youtube.com LDPchannel570914万人オフ
公明党google:site:youtube.com Newkomeito_komei509323.1万人コメント可能
立憲民主党google:site:youtube.com 立憲民主党-cdp26296万人コメント可能
日本維新の会google:site:youtube.com OishinJpn463511.5万人コメント可能
国民民主党google:site:youtube.com DPFPofficial142227.2万人コメント可能
日本共産党google:site:youtube.com jcpmovie1.4万本16.8万人コメント可能
れい新選組google:site:youtube.com official_reiwa261939.6万人コメント可能
参政google:site:youtube.com sanseito-official161246.8万人コメント可能
社民党google:site:youtube.com shaminparty9849250コメント可能
日本保守党google:site:youtube.com hoshutojp197.36万人コメント可能
チームみらいgoogle:site:youtube.com チームみらい 公式チャンネル62612.2万人コメント可能

自民党

2週間くらい前からコメント欄閉鎖してますね。

誹謗中傷罵詈雑言懸念したのかもしれませんが、

国民の声に耳を傾ける気がないと解釈されても仕方がない行為

自民党中央政治大学院という、大学ではない自民党内部の組織がある模様。

こういう勉強会?をするような内部の組織を維持できるっていうのは政党として重要なのだろう。

公開講座Youtubeで公開しているのは良い点と思う。

公明党

まり見たいと思える動画がない。

チャンネルURLのNewkomeitoってなんなんですかね。新しいの?

立憲民主党

チャンネル登録者が少ない。社民党の次、日本保守党より少ない。

なんでこんなに少ないんだろう。

オードリータンとの対談なんかは、後で見てみてもいいかな?と思う。

チームみらいの安野貴博と対談してるのは、敵に塩を送った形なんでしょうか。

日本維新の会

チャンネルURLがOishinJpn。そのOはどこから来た?大阪のOなの?

対談者の人選が疑問。成田悠輔、箕輪厚介、堀江貴文呂布カルマひろゆき

その人たち、知名度はあっても好感度はない人じゃないですか?

国民民主党

正直なところ、動画サムネイルをざーと眺めて、視聴したくなるような動画はなかった。

しかし、それでも参議院選挙で躍進している。

ネットをうまく使っていると言われることも多いが、どういう点なのかまだわかっていない。

結局は、伝えるべき政策がしっかりしていないと意味がないのだろう。

玉木の個人チャンネルでの配信の方がメインか?

日本共産党

動画本数は最も多い。

記者会見動画と、国会での質問動画ほとんど。

国会動画は見たことないので、興味のある分野でどういう質問がされているのかは後で見てみてもいいかな。

れい新選組

チャンネル登録者がかなり多い。参政党の次で2位。その割に選挙の結果はぱっとしない。

参政

チャンネル登録者トップ参議院選挙で躍進。

登録者が多いほど当選やすいと単純化はできないだろうが40万人以上は立派な数字

サムネイルYoutubeっぽい。これは他の党も見習うべきでは?

ReHacQ、PIVOT、文藝春秋PLUS、TBSCROSS DIGとか、あのあたりの雰囲気サムネイル

人よりかはテーマを前に出したサムネイルで、興味を引きやすい。

参政党の候補者のことは知らないし興味もないけど、

ワクチンには興味がある、移民には興味がある、消費税には興味があるという人をひきつける。

この点は他の党と大きく異なる。

実際それは合理的でもある。政治家なんてものは、本来国民代理人しかない。

国民がやりたいこと実現したいことではあるがひとりではできないことを、代わりにやる存在

国民が興味があるのは政治家ではなくテーマの方だろう。

社民党

チャンネル登録者が少ない。

参政党のチャンネルを見た後だと、雰囲気が違うことがよくわかる。

候補者の紹介で、名前を売りたいのはわかるが、なんのテーマに興味がある人なのか、

サムネイルに書いておいてくれないとクリックしようという気になれない。

日本保守党

動画が少ない。19本しかない。

おそらく党首個人チャンネルの方がメインなのだろう。

しかし、そういう組織だった動きができていない点が、選挙の結果にも表れている。

チームみらい

チャンネルURLが安野貴博。個人Youtubeチャンネルを、政党のものとして使用している?

ここもまだ、組織だった動きができていない。

安野貴博氏と著名人との対談。人の名前が前面に出ている方式

対談相手は多いので、密度維新よりも薄いがここでも、堀江貴文呂布カルマひろゆき

対談受けてくれる人ならだれでもいいの?

AI解説をしていてDeep Seek, Devin, Grok, Cursorなどの名前が出てくるのは他の党にはない特徴。

公明党サブチャンネル

情報ありがとう動画105本と少なめではあるが、動画方向性おもしろ、親しみやすさを狙った方向性

ここでも、ホリエモン箕輪ひろゆき。この人たちの政党チャンネルへの呼ばれやすさはなんなんですかね。

Permalink |記事への反応(6) | 07:10

このエントリーをはてなブックマークに追加ツイートシェア

2025-07-09

anond:20250708234043

きょうだい格差のやつ見て思い出した。

年齢が下の方を同程度の体調不良であれば優先するよ。迎えのために分身できればそうはしないけど、学校と調整の結果かもしれない。この一件では扱いに差をつけたい親とは思わない……そう捉えられたら悲しい2025/07/0910:29

<scriptsrc="https://b.st-hatena.com/js/comment-widget.js" charset="utf-8" async></script>

Permalink |記事への反応(1) | 19:16

このエントリーをはてなブックマークに追加ツイートシェア

2025-07-06

Grokが作ってくれたやつ

<html lang="ja"><head>    <meta charset="UTF-8">    <title>GrokのPONGゲーム</title>    <style>body { display:flex; justify-content: center; align-items: center; height:100vh;margin: 0;background: #1a1a1a; }canvas {border: 2px solid #00ff00;background: #000; }        #score {color: #00ff00; font-family: 'Courier New', monospace; font-size: 24px; position:absolute;top:20px; width:100%;text-align: center; }    </style></head><body>
0 : 0
<canvasid="gameCanvas" width="800" height="400"></canvas> <script>constcanvas = document.getElementById('gameCanvas');const ctx =canvas.getContext('2d');constscoreDisplay = document.getElementById('score'); //ゲームオブジェクトconst ball = { x:canvas.width / 2, y:canvas.height / 2,radius:10, speedX: 5, speedY: 5 };const paddleLeft = { x:10, y:canvas.height / 2 - 50, width:10, height:100, speed: 8 };const paddleRight = { x:canvas.width -20, y:canvas.height / 2 - 50, width:10, height:100, speed: 8 }; letscoreLeft = 0,scoreRight = 0; //キー入力constkeys = { w:false, s:false, ArrowUp:false, ArrowDown:false }; document.addEventListener('keydown', e => { if (keys.hasOwnProperty(e.key))keys[e.key] =true; }); document.addEventListener('keyup', e => { if (keys.hasOwnProperty(e.key))keys[e.key] =false; }); //ゲームループ function gameLoop() { // 移動 if (keys.w && paddleLeft.y> 0) paddleLeft.y -= paddleLeft.speed; if (keys.s && paddleLeft.y <canvas.height - paddleLeft.height) paddleLeft.y += paddleLeft.speed; if (keys.ArrowUp && paddleRight.y> 0) paddleRight.y -= paddleRight.speed; if (keys.ArrowDown && paddleRight.y <canvas.height - paddleRight.height) paddleRight.y += paddleRight.speed; //ボール移動 ball.x += ball.speedX; ball.y += ball.speedY; // 壁衝突 if (ball.y + ball.radius>canvas.height || ball.y - ball.radius < 0) ball.speedY = -ball.speedY; //パドル衝突 if ( (ball.x - ball.radius < paddleLeft.x + paddleLeft.width && ball.y> paddleLeft.y && ball.y < paddleLeft.y + paddleLeft.height) || (ball.x + ball.radius> paddleRight.x && ball.y> paddleRight.y && ball.y < paddleRight.y + paddleRight.height) ) { ball.speedX = -ball.speedX * 1.05; // 少し加速 } //得点 if (ball.x < 0) {scoreRight++; ballReset(); } if (ball.x>canvas.width) {scoreLeft++; ballReset(); } // 描画 ctx.fillStyle = '#000'; ctx.fillRect(0, 0,canvas.width,canvas.height); ctx.fillStyle = '#00ff00'; ctx.fillRect(paddleLeft.x, paddleLeft.y, paddleLeft.width, paddleLeft.height); ctx.fillRect(paddleRight.x, paddleRight.y, paddleRight.width, paddleRight.height); ctx.beginPath(); ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2); ctx.fill();scoreDisplay.textContent = `${scoreLeft} : ${scoreRight}`; requestAnimationFrame(gameLoop); } function ballReset() { ball.x =canvas.width / 2; ball.y =canvas.height / 2; ball.speedX = (Math.random()> 0.5 ? 5 : -5) * (Math.random() * 0.5 + 0.75); ball.speedY = (Math.random() * 4 - 2); } gameLoop(); </script></body></html>

 

 

https://anond.hatelabo.jp/20250706011306#

Permalink |記事への反応(1) | 01:18

このエントリーをはてなブックマークに追加ツイートシェア

Claudeが作ってくれたやつ

<html lang="ja"><head>    <meta charset="UTF-8">    <metaname="viewport" content="width=device-width, initial-scale=1.0">    <title>PONG Game</title>    <style>body {margin: 0;padding: 0;background-color: #000;            display:flex;            justify-content: center;            align-items: center;min-height:100vh;            font-family: 'Courier New', monospace;color:white;        }```    .game-container {text-align: center;    }canvas {border: 2px solidwhite;background-color: #000;    }        .score {        font-size: 24px;margin:20px 0;        letter-spacing: 2px;    }        .controls {margin-top:20px;        font-size: 14px;        opacity: 0.8;    }        .start-button {background-color: #333;color:white;border: 2px solidwhite;padding:10px20px;        font-size: 16px;        cursor: pointer;        font-family: 'Courier New', monospace;margin:10px;    }        .start-button:hover {background-color:white;color: black;    }</style>```</head><body>
<canvasid="gameCanvas" width="800" height="400"></canvas>
<button class="start-button">ゲーム開始</button> <button class="start-button">リセット</button>

W/Sキーまたは ↑/↓ 矢印キーパドル操作
```<script> //Canvas要素とコンテキストの取得constcanvas = document.getElementById('gameCanvas');const ctx =canvas.getContext('2d'); //ゲーム状態管理 let gameRunning =false; let animationId; //スコア要素の取得const playerScoreElement = document.getElementById('playerScore');constcomputerScoreElement = document.getElementById('computerScore'); //ゲームオブジェクト定義const game = { //プレイヤーパドル(左側) playerPaddle: { x:10, y:canvas.height / 2 - 50, width:10, height:100, speed: 5, upPressed:false, downPressed:false }, //コンピューターパドル(右側)computerPaddle: { x:canvas.width -20, y:canvas.height / 2 - 50, width:10, height:100, speed: 3.5, //プレイヤーより少し遅く設定 targetY:canvas.height / 2 - 50 }, //ボールの設定 ball: { x:canvas.width / 2, y:canvas.height / 2,radius: 8, speedX: 4, speedY: 3, maxSpeed: 8 }, //スコア管理score: { player: 0,computer: 0 } }; //キーボード入力の処理constkeys = {}; //キーが押されたときの処理 document.addEventListener('keydown', (e) => {keys[e.key.toLowerCase()] =true; //ゲームが停止中にスペースキーゲーム開始 if (e.key === ' ' && !gameRunning) { startGame(); } }); //キーが離されたときの処理 document.addEventListener('keyup', (e) => {keys[e.key.toLowerCase()] =false; }); //パドルの移動処理 function updatePaddles() { //プレイヤーパドルの移動(W/Sキーまたは矢印キー) if (keys['w'] ||keys['arrowup']) { game.playerPaddle.y -= game.playerPaddle.speed; } if (keys['s'] ||keys['arrowdown']) { game.playerPaddle.y += game.playerPaddle.speed; } //プレイヤーパドルの画面外移動を防ぐ if (game.playerPaddle.y < 0) { game.playerPaddle.y = 0; } if (game.playerPaddle.y>canvas.height - game.playerPaddle.height) { game.playerPaddle.y =canvas.height - game.playerPaddle.height; } //コンピューターパドルAI処理 //ボール位置を追跡するが、完璧ではない動きを実装const ballCenterY = game.ball.y;const paddleCenterY = game.computerPaddle.y + game.computerPaddle.height / 2; //ボールパドルの中心の差を計算constdifference = ballCenterY - paddleCenterY; // 反応に少し遅れを持たせる(人間らしい動き) if (Math.abs(difference)>10) { if (difference> 0) { game.computerPaddle.y += game.computerPaddle.speed; } else { game.computerPaddle.y -= game.computerPaddle.speed; } } //コンピューターパドルの画面外移動を防ぐ if (game.computerPaddle.y < 0) { game.computerPaddle.y = 0; } if (game.computerPaddle.y>canvas.height - game.computerPaddle.height) { game.computerPaddle.y =canvas.height - game.computerPaddle.height; } } //ボールの移動と衝突判定 function updateBall() { //ボール位置更新 game.ball.x += game.ball.speedX; game.ball.y += game.ball.speedY; //上下の壁との衝突判定 if (game.ball.y - game.ball.radius < 0 || game.ball.y + game.ball.radius>canvas.height) { game.ball.speedY = -game.ball.speedY; } //プレイヤーパドルとの衝突判定 if (game.ball.x - game.ball.radius < game.playerPaddle.x + game.playerPaddle.width && game.ball.x + game.ball.radius> game.playerPaddle.x && game.ball.y + game.ball.radius> game.playerPaddle.y && game.ball.y - game.ball.radius < game.playerPaddle.y + game.playerPaddle.height) { //ボールパドルに当たった位置によって跳ね返り角度を調整const hitPos = (game.ball.y - (game.playerPaddle.y + game.playerPaddle.height / 2)) / (game.playerPaddle.height / 2); game.ball.speedX = Math.abs(game.ball.speedX); game.ball.speedY = hitPos * 4; //ボールの速度を少し上げる(ゲームをエキサイティングに) if (Math.abs(game.ball.speedX) < game.ball.maxSpeed) { game.ball.speedX *= 1.02; } } //コンピューターパドルとの衝突判定 if (game.ball.x + game.ball.radius> game.computerPaddle.x && game.ball.x - game.ball.radius < game.computerPaddle.x + game.computerPaddle.width && game.ball.y + game.ball.radius> game.computerPaddle.y && game.ball.y - game.ball.radius < game.computerPaddle.y + game.computerPaddle.height) { //ボールパドルに当たった位置によって跳ね返り角度を調整const hitPos = (game.ball.y - (game.computerPaddle.y + game.computerPaddle.height / 2)) / (game.computerPaddle.height / 2); game.ball.speedX = -Math.abs(game.ball.speedX); game.ball.speedY = hitPos * 4; //ボールの速度を少し上げる if (Math.abs(game.ball.speedX) < game.ball.maxSpeed) { game.ball.speedX *= 1.02; } } //ボールが左右の壁を越えた場合得点処理) if (game.ball.x < 0) { //コンピューター得点 game.score.computer++; updateScore(); resetBall(); } else if (game.ball.x>canvas.width) { //プレイヤー得点 game.score.player++; updateScore(); resetBall(); } } //ボールリセット得点後の処理) function resetBall() { game.ball.x =canvas.width / 2; game.ball.y =canvas.height / 2; //ランダムな方向でボールを発射 game.ball.speedX = (Math.random()> 0.5 ? 4 : -4); game.ball.speedY = (Math.random() - 0.5) * 6; } //スコア表示の更新 function updateScore() { playerScoreElement.textContent = game.score.player;computerScoreElement.textContent = game.score.computer; } // 描画処理 functiondraw() { // 画面をクリア ctx.fillStyle = '#000'; ctx.fillRect(0, 0,canvas.width,canvas.height); //中央の点線を描画 ctx.setLineDash([5, 5]); ctx.beginPath(); ctx.moveTo(canvas.width / 2, 0); ctx.lineTo(canvas.width / 2,canvas.height); ctx.strokeStyle = '#fff'; ctx.stroke(); ctx.setLineDash([]); //プレイヤーパドルを描画 ctx.fillStyle = '#fff'; ctx.fillRect(game.playerPaddle.x, game.playerPaddle.y, game.playerPaddle.width, game.playerPaddle.height); //コンピューターパドルを描画 ctx.fillRect(game.computerPaddle.x, game.computerPaddle.y, game.computerPaddle.width, game.computerPaddle.height); //ボールを描画 ctx.beginPath(); ctx.arc(game.ball.x, game.ball.y, game.ball.radius, 0, Math.PI * 2); ctx.fillStyle = '#fff'; ctx.fill(); //ゲームが停止中の場合メッセージを表示 if (!gameRunning) { ctx.fillStyle = '#fff'; ctx.font = '20px Courier New'; ctx.textAlign = 'center'; ctx.fillText('ゲーム開始ボタンを押してください',canvas.width / 2,canvas.height / 2 + 60); } } //ゲームのメインループ function gameLoop() { if (!gameRunning) return; updatePaddles(); updateBall();draw(); animationId = requestAnimationFrame(gameLoop); } //ゲーム開始 function startGame() { gameRunning =true; gameLoop(); } //ゲームリセット function resetGame() { gameRunning =false; if (animationId) { cancelAnimationFrame(animationId); } //スコアリセット game.score.player = 0; game.score.computer = 0; updateScore(); //ボールパドル位置リセット game.ball.x =canvas.width / 2; game.ball.y =canvas.height / 2; game.ball.speedX = 4; game.ball.speedY = 3; game.playerPaddle.y =canvas.height / 2 - 50; game.computerPaddle.y =canvas.height / 2 - 50;draw(); } // 初期描画draw();</script>```</body></html>

 

 

https://anond.hatelabo.jp/20250706011306#

Permalink |記事への反応(0) | 01:14

このエントリーをはてなブックマークに追加ツイートシェア

2025-07-05

生成AIを利用したプログラミング初級者向けの温故知新提案

はじめに

ここで言う「プログラミング初級者」とはプログラミング記述が上から下へ向かって順番に処理されること、条件分岐ループという概念があることを理解しており、RPGゲームが作れる「RPGツクール(現RPG Maker)」や学童向けプログラミング環境Scratch」、「ナビつき! つくってわかる はじめてゲームプログラミング(ナビつく)」、ADVゲームが作れる「吉里吉里(もしくは吉里吉里2)」、過去BASICやC、HSPJavascriptあたりでプログラミングへ挑戦し挫折したなどなど、ある程度の「プログラマブルロジック」構築の経験がある者を指します。

前日談(初級者は読まなくて良いです)

ある時、筆者はふと思いました。「生成AIはなんだかんだで膨大なテキスト情報を処理している事がキモだよなぁ」とありきたりなことを。

そして、同時にプログラミング初級者の弱点として「現在記述されているコード管理においてテキストと実際の処理フロー脳内で一致しない」「プログラミング言語ごとに定められているルール関数予約語の把握が困難」なのが問題とも考えました。

前述したプログラミング初級者の弱点の考え自体車輪の再発明であり、「Scratch」や、より高度な「UML」が既に存在しており、特筆すべきことは何もありません。

しかし、「Scratch」や「UML」、なんなら「RPGツクール」や「吉里吉里」などに無い点として、現代では自然言語処理が大幅に向上した生成AI実用の域にまで到達しつつあるのが従来とは異なる点でした。

まり自然言語を混ぜ込みやすテキストベース言語、かつ、処理を記述するとフロー視覚的に理解やす言語可能であれば情報量が多くて一部の界隈で広く使われている言語があればプログラミング初級者も気軽にプログラミングできるのではないか?と発想しました。

そこで前述の条件を満たす1つの言語へ目を付けました。

本題

コンピュータ(コンパイラインタプリタなどソフトウェアを含む)が解することができる言語にはプログラミング言語以外にも様々あり、今回取り上げるのは「データ記述言語」と呼ばれるものです。

データ記述言語の中でもグラフ作成へ特化しており、特にフローチャート作成で真価を発揮する「DOT言語というものがあります

早速ですが、実際に手を動かしてみましょう。ちなみにDOT言語Graphviz OnlineというWebツールがあるため別途に何かしらをインストールして環境構築する必要はありません。便利な世の中ですね。

上記Graphviz Onlineを開くと、既に左側のDOT言語記述された内容が、右側で作図されています。DOT言語はこのような図を作図するためのデータ記述言語です。

一旦、左側の記述をCtrl+Aで全選択をしDeleteなどで全削除し、下記の内容をコピペしてみましょう。

digraph graphname {

A -> B;

}

一瞬で○に囲まれたAとBが繋がった図が作成されました。

DOT言語の詳細な使い方は様々なWebサイトやブログ記事Qiitaなどへ譲るとして、A - > Bの見た目から発想の転換をしてみると処理Aから処理Bという流れに見えませんか?

DOT言語は生成AIを利用する上で有利なテキストベースでありながらグラフ作成できるのがキモであり、例えばこのA -> BがA「Webページを開いたら」 → B「Hello, Worldと表示する」という風にできるのであれば処理のフロー可視化されており本当に素晴らしいことです。

Hello, worldを表示してみる

ここでプログラミング有識者は「DOT言語UMLなどに見立てて処理を記述するのは良いが、プログラミング初心者は求めた結果を出力するロジックアルゴリズムを発想する知見や経験値が圧倒的に足りていないのが問題ではないか?」と至極真っ当かつ反論余地がない問題点の指摘をすると思いますが、そこで活きるのが生成AIです。

生成AIは初級者プログラマ個人ロジックアルゴリズム作成能力無関係ロジックアルゴリズムを生成できる(可能性が少なくともある)ので、処理のフローをDOT言語記述することにより処理フローから初級者プログラマが求めるプログラムを生成AIへ推論させ生成させるというのが狙いです。実際に試してみましょう。

digraph graphname {

A[
label = "Webページを表示する"
];

B[
label = "Webページを表示したらHello, worldとテキストを表示する"
];

A -> B;

}

プログラミング有識者はこの時点で「なるほど、自然言語記述をそのままDOT言語に入れ込んでしまうのか」と気付いたのではないかと思います

このDOT言語Google Gemini 2.5Flash「下記のデータ記述言語のDOT言語記述された処理フローJavascript言語へ変換をしWebページ上へ「Hello,world」を表示したいので変換をお願いします。」命令すると以下のコードが生成されました。

<!DOCTYPEhtml>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <metaname="viewport" content="width=device-width, initial-scale=1.0">
    <title>Hello World Page</title>
</head>
<body>
    <divid="output"></div>

    <script>
        //Webページが表示されたら(DOMが完全に読み込まれたら)実行される
        document.addEventListener('DOMContentLoaded', function() {
            // "Webページを表示する"ステップは、このHTMLファイル自体が表示されることで達成されます

            // "Webページを表示したらHello, worldとテキストを表示する"ステップ
            const outputDiv = document.getElementById('output');
            outputDiv.textContent = 'Hello, world';
        });
    </script>

</body>
</html>

フロー記述する利点は、ロジックアルゴリズムを発想する知見や経験値が足りなくとも、フローステップが明確に分かれているので生成AIが処理を切り分けて推論してくれることであり、そしてプログラミング初心者自身フローチャートを視覚確認できるので「Aを処理したらBを処理する」と切り分けて考えやすいことです。

また、求めている結果ではなく誤った結果が生成されても、A - > B - > Cとフローを細分化していくことで生成AIの推論精度を高めていくことができるのも利点です。

応用編

より生成AIへ精度の高い推論をしてもらうために補足情報を付加するのも有用です。

digraph graphname {

A[
label = "Webページを表示する"
];

B[
label = "Webページを表示したらHello, worldとテキストを表示する",
comment = "Webページが完全に読み込まれるまで待機"
];

A -> B;

}

labelの記述内容もcommentの記述内容も生成AIが推論のための情報として利用するので誤った結果が生成されてもA - > B - > Cとフローを細分化しなくとも良い場合があります

DOT言語を知るプログラミング有識者が「DOT言語仕様を考えれば確かにそうだが、その発想はなかった」と言っていただけるであろうDOT言語コード例だとこういう記述方法もアリです。

digraph増田コード {

最初の処理[
label = "Webページを表示する"
];

次の処理[
label = "Webページを表示したらHello, worldとテキストを表示する",
comment = "Webページが完全に読み込まれるまで待機"
];

最初の処理 -> 次の処理;

}

ノード名称自然言語採用することにより、例えばゲームプログラミング時に「キャラクタージャンプする」という読んだそのままな処理のためのノード、というか一般的に言うオブジェクト作成することが可能で、後は->で繋げて処理をさせられます

ちなみに別のノード作成する際に「"キャラクタージャンプする"から継承する」の様なことをcommentなどへ記述しておくと生成AIが推論して継承します。なんならcommentなどへ「キャラクター画像image.gif使用」などと記述しておくとファイルの読み込みもします。

更にDOT言語にはカスタム要素という仕様存在しており、DOT言語仕様で定められた予約語以外も使用可能です。

digraph増田コード {

最初の処理[
label = "Webページを表示する"
];

次の処理[
label = "Webページを表示したらHello, worldとテキストを表示する",
comment = "Webページが完全に読み込まれるまで待機",
font_style = "フォントを太字のボールド体、色を赤(#FF0000)とする"
];

最初の処理 -> 次の処理;

}

生成AIカスタム要素の名称からも推論を発揮し、上記場合であればフォントスタイル指定していると推論をするので生成AIの推論精度を高める補足情報として機能します。

まりこれはカスタム要素の名称として"Action"などの名称採用すると"動作"として推論をし、"decision"ならば"条件分岐"ですし、"input"ならば"入力"ですし、"loop"ならば"繰り返し"ですし、"Type"ならば"種別"です。

より詳細に process[type="Action"] などのノード作成してどんどん生成AIの推論精度を高めていくことが可能であり、そろそろ察してきているかと思いますが 処理[種別="動作"] と自然言語記述しても機能します。

プログラミング有識者は更に「プログラム言語自体予約語、例えばJavascriptを生成する事を前提にlengthを名称にすると配列を使おうとするのか?」と疑問に感じるでしょうがお察しの通りで生成AI配列を使おうとするので、敢えて使いたいプログラム言語機能や外部ライブラリなどがある場合は補足情報として機能する形で記述しておくと生成AIは推論へ利用します(まぁそこまで知識ある方なら該当のプログラム言語使ったほうが手っ取り早いと思いますが)。

おわりに

以上をもって「生成AIを利用したプログラミング初級者向けの温故知新提案」を終えたいと思います

色々とツッコミどころには筆者自身が気付いていて。例えば「結局はDOT言語仕様を覚えないといけないのでは?」とか「プログラミング初級者に任せると生成前のソースであるDOT言語コードスパゲッティになりそうだよな」とか「面倒くせぇから普通にプログラミング覚えろや」とか理解してますし至極真っ当かつ反論余地がないと思ってます

今回の提案プログラミング有識者向けの本質は「生成AIへ向いた中間言語の発掘」であり、「DOT言語ならそこそこ普及してるしプログラミング初級者でも扱えるんじゃね?」と業務中に発想したものを書き留め公開いたしました。

何かプログラミング有識者の皆さんからより良い発想があれば参考にしたいと考えていますのでよろしくお願いいたします。以上。

Permalink |記事への反応(36) | 19:36

このエントリーをはてなブックマークに追加ツイートシェア

2025-06-24

はてブッカー高齢化しすぎて岡田斗司夫ミームが伝わらない

どこが岡田斗司夫なの?とかひどいこと書いてる!などというズレてる反応が多い。


しか岡田斗司夫がしばしば使用する(と思われている)語尾である「~なんだよな」を用いた構文ははすでに若者あいだでは岡田斗司夫ミームとして普及しており、インターネットでは広く使用されている

岡田斗司夫本人をゲストに迎えたバキ童の動画でも「岡田斗司夫ミーム」を取り上げている。バキ童チャンネル1020代接触YouTubeチャンネルランキングでは7位に入っている人気チャンネルであるhttps://toyokeizai.net/articles/photo/759701?pn=3


今回のようなはてなブックマーカーの要領を得ないリアクションは、はてな村の著しい高齢化、また動画文化を毛嫌いして文字文化を好む強いこだわり、さら冗談を介さない彼らの特徴的な発達特性、知らないことを恥とは考えない厚顔っぷりなどが合わさったがゆえの不幸な文明の衝突なんだよな

Permalink |記事への反応(18) | 13:20

このエントリーをはてなブックマークに追加ツイートシェア

2025-06-13

我が名はサイボーグdorawii

パーマリンク署名対象にするより堅牢自動化を作れた。

一度投稿したうえで別タブを開いてプログラム的(fetch)に送信してその別タブが閉じられる仕組み。

改めてスクリプト配布しちゃる

最初投稿してエントリページに移動した親タブ側のjsコード
// ==UserScript==      // @namePGP署名検出と別タブ自動編集      // @namespacehttp://tampermonkey.net/      // @version      1.0      // @descriptionPGP署名がない投稿自動編集ページへ誘導      // @matchhttps://anond.hatelabo.jp/*      // @grantGM_setValue      // @grantGM_getValue      // @grantGM.openInTab      // ==/UserScript==      (function () {        'use strict';constbody = document.getElementById('entry-page');        if (!body) return;consttitleText = document.title;        if (!titleText.includes('dorawii')) return;constpgpRegex = /BEGIN.*PGP(?: SIGNEDMESSAGE| SIGNATURE)?/;const preElements = document.querySelectorAll('div.body pre');        let hasPgpSignature =false;        for (const pre of preElements) {          if (pgpRegex.test(pre.textContent)) {            hasPgpSignature =true;            break;          }        }        if (hasPgpSignature) return;const editLink = document.querySelector('a.edit');const childTab =GM.openInTab(editLink.href, {active:false, insert:true,setParent:true });      })();
親タブから開かれる編集ページの子タブのjsコード
 // ==UserScript==      // @name編集ページ処理と自動送信・閉じ      // @namespacehttp://tampermonkey.net/      // @version      1.0      // @description編集ページで署名処理と送信、タブ自動閉じ      // @matchhttps://anond.hatelabo.jp/dorawii_31/edit?id=*      // @grantGM_getValue      // @grantGM_xmlhttpRequest      // @grantGM_setClipboard      // @grantGM_notification      // @connectlocalhost      // ==/UserScript==      (async function () {        'use strict';const shouldRun = awaitGM_getValue('open-tab-for-edit', '0');consttextareaId = 'text-body';consttextarea = document.getElementById(textareaId);        if (!textarea) return;const content =textarea.value;constpgpSignatureRegex = /-----BEGINPGP SIGNEDMESSAGE-----[\s\S]+?-----BEGINPGP SIGNATURE-----[\s\S]+?-----ENDPGP SIGNATURE-----/;        if (pgpSignatureRegex.test(content)) {console.log('[PGPスクリプト]署名が検出されたためそのまま送信します');          return;        }consthttpRequest = (url, data) =&gt; {          return newPromise((resolve,reject) =&gt; {GM_xmlhttpRequest({              method: 'POST',url:url,              headers: { 'Content-Type': 'application/x-www-form-urlencoded' },              data: `value=${encodeURIComponent(data)}`,onload: function (response) {                resolve(response.responseText);              },onerror: function (error) {reject(error);              }            });          });        };        //textarea の値を取得        // 1.現在のページのURLからURLオブジェクト作成const currentUrl = newURL(window.location.href);        // 2.ベースとなる部分 (例: "https://anond.hatelabo.jp") を取得constorigin = currentUrl.origin;        // 3. 'id'パラメータの値 (例: "20250610184705") を取得constidValue = currentUrl.searchParams.get('id');        // 4.ベース部分とIDを結合して、目的URL文字列を生成        //idValueが取得できた場合のみ実行する        let newUrl = null;        if (idValue) {          newUrl = `${origin}/${idValue}`;        }        // 5. 生成されたURL変数に代入し、コンソールに出力して確認console.log(newUrl);constvalueToSend = newUrl;try {const signatureText = awaithttpRequest('http://localhost:12345/run-batch',valueToSend);console.log('バッチ応答:', signatureText);          if (!signatureText.includes('BEGINPGP SIGNEDMESSAGE')) {            alert('PGP署名クリップボードに見つかりませんでした。');            return;          }const newText = content.replace(/\s*$/, '') + '\n' + signatureText + '\n';textarea.value = newText;console.log('[PGPスクリプト]署名を貼り付けました。送信を再開します。');const form = document.forms.edit;const newForm = form.cloneNode(true);          form.replaceWith(newForm);          newForm.addEventListener('submit', async (e) =&gt; {            e.preventDefault(); //HTML標準のsubmitをキャンセルconstbodyText =textarea?.value || '';            //reCAPTCHAトークンの取得constrecaptchaToken = await newPromise((resolve) =&gt; {              grecaptcha.enterprise.ready(() =&gt; {                grecaptcha.enterprise.execute('hoge', {action: 'EDIT' })                  .then(resolve);              });            });            // POSTするデータの構築const formData = new FormData(newForm);            formData.set('body',bodyText);            formData.set('recaptcha_token',recaptchaToken);            formData.set('edit', '1');try {constresponse = await fetch(newForm.action, {                method: 'POST',body: formData,                credentials: 'same-origin'              });              if (response.ok) {console.log('送信成功');                window.close();              } else {console.error('送信失敗',response.status);              }            }catch (err) {console.error('送信中にエラーが発生', err);            }          });          //プログラム的に送信トリガー          newForm.dispatchEvent(new Event('submit', { bubbles:true }));        }catch (e) {console.error('バッチ呼び出し失敗:', e);        }      })();
node.jsで動かすローカルサーバーコード
consthttp =require('http');const { exec } =require('child_process');const querystring =require('querystring');const server =http.createServer((req, res) =&gt; {  if (req.method === 'GET' &amp;&amp; req.url === '/ping') {    res.writeHead(200);    res.end('pong');  } else if (req.method === 'POST' &amp;&amp; req.url === '/run-batch') {    letbody = '';    req.on('data', chunk =&gt; {body += chunk.toString();    });    req.on('end', () =&gt; {constparsed = querystring.parse(body);constvalue =parsed.value || 'default';      // 値を引数としてバッチに渡す      exec(`C:\\Users\\hoge\\Desktop\\makesign.bat "${value}"`, { encoding: 'utf8' }, (err, stdout, stderr) =&gt; {        if (err) {          res.writeHead(500);          res.end('Error executing batch: ' + stderr);        } else {          res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });          res.end(stdout.trim());        }      });    });  } else {    res.writeHead(404);    res.end('Not found');  }});server.listen(12345, () =&gt; {console.log('Batch serverrunningathttp://localhost:12345/');});
@echo offsetlocal enabledelayedexpansion::署名するファイルset "infile=%~1"set outfile=%TEMP%\pgp_output.asc:: 以前の出力があれば削除if exist "%outfile%" del "%outfile%":signloop::AutoHotkeyパスフレーズ入力(gpgがパスワード要求するダイアログが出た場合に備える)start "" /b "C:\Users\hoge\Documents\AutoHotkey\autopass.ahk"::PGPクリア署名作成echo %infile% | gpg --yes --clearsign --output "%outfile%"::署名成功していればループを抜けるif exist "%outfile%" (goto postprocess) else (    timeout /t 1&gt; nulgoto signloop):postprocesspowershell -nologo -command ^  "$header = '&gt;|'; $footer = '|&lt;'; $body =Get-Content '%outfile%' -Raw;Write-Output ($header + \"`r`n\" + $body + $footer)"powershell -nologo -command ^  "$header = '&gt;|'; $footer = '|&lt;'; $body =Get-Content 'signed.asc' -Raw;Set-Clipboard -Value ($header + \"`r`n\" + $body + $footer)"endlocalexit /b
AutoHotkey(以前と同じ)
#Persistent#SingleInstance ignoreSetTitleMatchMode, 2WinWaitActive, pinentrySendInputpasswordSleep 100SendInput {Enter}ExitApp

動けばいいという考えで作っているので余分なコードも含んでいるかもしれない。

-----BEGINPGP SIGNEDMESSAGE-----Hash: SHA512https://anond.hatelabo.jp/20250613185036 -----BEGINPGP SIGNATURE-----iHUEARYKAB0WIQTEe8eLwpVRSViDKR5wMdsubs4+SAUCaEv1FQAKCRBwMdsubs4+SHHkAQDUOLgBcdji2T6MJ7h/vlMdFfGlWAzNdXijjE1gIuEPywEAiMNMZqhrMmtlc7UqRuggNJ/UTa5xTIcKp622+7jJQQg==Lgkl-----ENDPGP SIGNATURE-----

Permalink |記事への反応(1) | 18:50

このエントリーをはてなブックマークに追加ツイートシェア

2025-06-09

anond:20250609174146

https://search.yahoo.co.jp/realtime/search?p=%E3%83%8F%E3%83%8B%E3%83%88%E3%83%A9%E5%BE%B9&fr=top_ga1_sa&ei=UTF-8

ハニトラ徹 リアルタイム検索

Permalink |記事への反応(0) | 21:21

このエントリーをはてなブックマークに追加ツイートシェア

UTF-8エンコードされたテキストファイルがある。

から読んでいって840文字ずつ分けるとくそ遅い。

そこでどうしたものかと考えたら、UTF-8は1~8バイト構成され、1,2,3,4,5,6,7,8の最小公倍数は840なので、840バイト単位マップファイルのビューを作って、840バイト単位でビューを動かせば問題なく動くんだろうか?

それとも絵文字IVSの途中にはまってしまい、エンコーダー例外を吐くんだろうか?

個人的には問題ないと思うが、問題ないという確証がもてねえ。

Permalink |記事への反応(1) | 13:09

このエントリーをはてなブックマークに追加ツイートシェア

2025-06-05

性的広告について

ネットへの性的広告ゾーニングが絶賛されている。

私は、「性的」の線引きが分からないので不安になっていた。

勧められているガイドラインを読むと…

https://www.jiaa.org/wp-content/uploads/2022/08/JIAA_futekisetujirei_20220824.pdf

「過度な肌露出があるもの、性行為連想させるなど性に関する表現露骨もの

として胸部が煽情的に強調された画像などがアウトとなるようだ。

日経新聞への「月曜日のたわわ」広告を思い出す。

当時のジェンダークレーマー冷笑を持って切り捨てられたと記憶しているが、今回との違いは何か。

おそらく、

広告女子高生は胸部をむしろ隠していた

事にあるのではないか

画像検索してみたが

google:日経新聞+月曜日のたわわ

少女は胸部を強調するどころか逆に隠している。

新聞ネット広告という範囲の違いもあるが、おそらく線引きの最たる違いはそこにあるのだろう。

Permalink |記事への反応(3) | 22:59

このエントリーをはてなブックマークに追加ツイートシェア

2025-05-21

anond:20250521164716

いきなり長編チャレンジするからエタるんだ。

短編を書いてみました!評判が良かったら連載しまぁす」でいいんだよ。

一部読者から蛇蝎の如く嫌われるがへーきへーき

Permalink |記事への反応(0) | 18:51

このエントリーをはてなブックマークに追加ツイートシェア

2025-05-20

Google検索:十路

辞書雑学ページを除く

検索件数トップページトップページドメインページ順位
google:二十路約 822,000,000 件 (0.19 秒)sympathy 二十路歌詞www.uta-net.com 歌ネット17
google:三十路約 13,100,000 件 (0.18 秒)三十路祭りwww.union-alpha.jp株式会社ユニオンアルファ5
google:四十路約 13,600,000 件 (0.21 秒)SUPER EIGHT - 四十路少年 (from "超DOME TOUR 二十祭")www.youtube.comYouTube3
google:五十路約 42,700,000 件 (0.19 秒)五十路グループ五十路.com 五十路グループ3
google:六十路約 643,000,000 件 (0.18 秒)Amazon.co.jp:Dvd 六十路熟女www.amazon.co.jpAmazon.jp2
google:七十路約 1,360,000 件 (0.23 秒)七十路の坂michinokuhit.jpみちのくレコード5
google:八十路555,000,000 件 (0.45 秒)【5/25発売】八十路の考古学|「雄山閣学術専門書籍出版社www.yuzankaku.co.jp株式会社雄山閣7
google:九十路約 446,000,000 件 (0.25 秒)九十路を楽しむ-今古(きんこ)もじり和歌集www.aomoritosyo.co.jp青森県図書教育用品株式会社7


このうち、Amazonが1ページ目に出てくるのは四十路~七十路だった。

Permalink |記事への反応(0) | 13:24

このエントリーをはてなブックマークに追加ツイートシェア

次の25件>
ログインユーザー登録
ようこそ ゲスト さん
Copyright (C) 2001-2025 hatena. All Rights Reserved.

[8]ページ先頭

©2009-2025 Movatter.jp