Movatterモバイル変換


[0]ホーム

URL:


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

「parse」を含む日記RSS

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

次の25件>

2025-12-16

anond:20251215235034

AIとかまあ使い捨てしか使わないけど

タスクタイプENUMタスク内容のStringと日付をDBに保存するコマンドプログラムを書いて タスク内容はタスクタイプによっては固定になる場合任意String場合がある

これで下のようなものが出たがENUM側に持たせてるので言い方の問題だと思うよ

public class TaskCommandApp {

public staticvoidmain(String[] args) {

Scanner scanner = new Scanner(System.in);

System.out.println("Task type:");

for (TaskType type : TaskType.values()) {

System.out.println("- " + type.name());

}

TaskType taskType = TaskType.valueOf(scanner.nextLine().trim());

String taskContent;

if (taskType.hasFixedContent()) {

taskContent = taskType.getFixedContent();

System.out.println("Task content fixedas: " + taskContent);

} else {

System.out.print("Enter task content: ");

taskContent = scanner.nextLine();

}

System.out.print("Enter taskdate (yyyy-MM-dd): ");

LocalDate taskDate = LocalDate.parse(scanner.nextLine());

Task task = new Task(taskType, taskContent, taskDate);

new TaskDao().save(task);

System.out.println("Task saved successfully.");

}

}

publicenum TaskType {

DAILY_REPORT("Daily report submission"),

MEETING(null),

MAINTENANCE("Systemmaintenance task");

privatefinalString fixedContent;

TaskType(String fixedContent) {

this.fixedContent = fixedContent;

}

public boolean hasFixedContent() {

return fixedContent != null;

}

publicString getFixedContent() {

return fixedContent;

}

}

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

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

2025-12-05

Parser」とはどういう意味ですか?

パーサ【parser】パーザ

パーサとは、コンピュータプログラムソースコードXML文書など、何らかの言語記述された構造的な文字データを解析し、プログラムで扱えるようなデータ構造集合体に変換するプログラムのこと。 そのような処理のことを「構文解析」「パース」(parse)という。2025/08/29

パーサ(パーザ)とは -IT用語辞典e-Words

IT用語辞典e-Words

https://e-words.jp › パーサ

「Purser」とはどういう意味ですか?

なお、かつては女性の「客室乗務員」のことを「スチュワーデス」、男性の「客室乗務員」のことを「スチュワード」や「パーサー」と呼んでいたが、今では旅客機に限らず鉄道客船の中で、乗客接客サービスをする「客室乗務員」を統率する立場にある者を「パーサー」や「チーフパーサー」と呼んでいる。

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

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

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) => {          return newPromise((resolve,reject) => {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) => {            e.preventDefault(); //HTML標準のsubmitをキャンセルconstbodyText =textarea?.value || '';            //reCAPTCHAトークンの取得constrecaptchaToken = await newPromise((resolve) => {              grecaptcha.enterprise.ready(() => {                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) => {  if (req.method === 'GET' && req.url === '/ping') {    res.writeHead(200);    res.end('pong');  } else if (req.method === 'POST' && req.url === '/run-batch') {    letbody = '';    req.on('data', chunk => {body += chunk.toString();    });    req.on('end', () => {constparsed = querystring.parse(body);constvalue =parsed.value || 'default';      // 値を引数としてバッチに渡す      exec(`C:\\Users\\hoge\\Desktop\\makesign.bat "${value}"`, { encoding: 'utf8' }, (err, stdout, stderr) => {        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, () => {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> nulgoto signloop):postprocesspowershell -nologo -command ^  "$header = '>|'; $footer = '|<'; $body =Get-Content '%outfile%' -Raw;Write-Output ($header + \"`r`n\" + $body + $footer)"powershell -nologo -command ^  "$header = '>|'; $footer = '|<'; $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

dorawii

ようやく(ほぼ)すべてが自動化された。

あとはローカルサーバーの起動をスタートアップに設定する(方法AIに聞いて指示に従う)だけの消化試合

ここにほとんどAI頼りのコードを公開しておく。

事前にインストールしておくもの

autohotkey

nodejs

ユーザースクリプトを実行できる拡張機能

パスとかの注意

署名要求してくるパスワードを自動入力するahkファイルドキュメントAutoHotkey配下に置いた。

バッチファイル(make.sign.bat)はデスクトップに置いた。

以下コード

autopass.ahk
#Persistent#SingleInstance ignoreSetTitleMatchMode, 2WinWaitActive, pinentrySendInput お前のパスワードSleep 100SendInput {Enter}ExitApp
run-bacth-server.js
//run-batch-server.jsconsthttp =require('http');const { exec } =require('child_process');const server =http.createServer((req, res) => {  if (req.url === '/ping') {    res.writeHead(200);    res.end('pong');  } else if (req.url === '/run-batch') {    exec('C:\\Users\\you\\Desktop\\makesign.bat', (err) => {      res.writeHead(200);      res.end(err ? 'Error' : 'OK');    })    ;  } else {    res.writeHead(404);    res.end('Not found');  }});server.listen(12345, () => {console.log('Batch serverrunningathttp://localhost:12345/');});
makesign.bat
@echo offsetlocal enabledelayedexpansion::ミリ秒単位UTC時刻を取得for /f %%a in ('powershell -nologo -command "[int64]::Parse((Get-Date).ToUniversalTime().ToString('yyyyMMddHHmmssfff'))"') doset timestamp=%%a::署名するファイルset infile=%TEMP%\pgp_input.txtset outfile=%TEMP%\pgp_output.asc:: 以前の出力があれば削除if exist "%outfile%" del "%outfile%"::タイムスタンプを原文として保存echo %timestamp%> "%infile%":signloop::AutoHotkeyパスフレーズ入力(gpgがパスワード要求するダイアログが出た場合に備える)start "" /b "C:\Users\infini\Documents\AutoHotkey\autopass.ahk"::PGPクリア署名作成gpg --yes --clearsign --output "%outfile%" "%infile%"::署名成功していればループを抜けるif exist "%outfile%" (echo [INFO]署名成功goto postprocess) else (echo [WARN]署名失敗、再試行します…    timeout /t 1> nulgotosignloop):postprocess::PowerShellで余計な改行なしに |< をつけてクリップボードコピーpowershell -nologo -command ^  "$header = '>|'; $footer = '|<'; $body =Get-Content '%outfile%' -Raw;Set-Clipboard -Value ($header + \"`r`n\" + $body + $footer)"echo Done.signed.asc created and clipboard updated (no extra blankline).endlocalexit /b
tempermonkeyとかに登録するユーザースクリプト
// ==UserScript==// @namePGP署名自動付加スクリプト(GM_xmlhttpRequest版)// @namespacehttp://tampermonkey.net/// @version      1.0// @description投稿前にPGP署名を付けてから送信(fetch未使用)// @matchhttps://anond.hatelabo.jp/dorawii_31/edit*// @grant        GM_xmlhttpRequest// @grant        GM_setClipboard// @grant        GM_notification// / @connectlocalhost// ==/UserScript==(function () {  'use strict';const submitId = 'submit-button';consttextareaId = 'text-body';const localServer = 'http://localhost:12345/run-batch';constpgpSignatureRegex = /-----BEGINPGPSIGNEDMESSAGE-----[\s\S]+?-----BEGINPGPSIGNATURE-----[\s\S]+?-----ENDPGPSIGNATURE-----/;consthttpRequest = (url) => {    return newPromise((resolve,reject) => {      GM_xmlhttpRequest({        method: 'GET',url:url,        onload: function (response) {          resolve(response.responseText);        },        onerror: function (error) {reject(error);        }      });    });  };const interceptClick = () => {constbtn = document.getElementById(submitId);    if (!btn ||btn.dataset.pgpIntercepted === 'true') return;btn.dataset.pgpIntercepted = 'true';btn.addEventListener('click', async function (e) {consttextarea = document.getElementById(textareaId);      if (!textarea) return;const content =textarea.value;      if (pgpSignatureRegex.test(content)) {console.log('[PGPスクリプト]署名が検出されたためそのまま送信します');        return;      }      e.preventDefault();      e.stopImmediatePropagation();console.log('[PGPスクリプト]署名が見つからないため処理を停止し、署名を取得します');try {        awaithttpRequest(localServer); //バッチ実行constsignatureText = await navigator.clipboard.readText();        if (!signatureText.includes('BEGINPGPSIGNEDMESSAGE')) {          alert('PGP署名クリップボードに見つかりませんでした。');          return;        }const newText = content.replace(/\s*$/, '') + '\n' +signatureText + '\n';textarea.value = newText;console.log('[PGPスクリプト]署名を貼り付けました。送信を再開します。');btn.click(); //イベント再発火      }catch (err) {        alert('PGP署名の取得または貼り付けに失敗しました。\n' + err);      }    },true);  };  window.addEventListener('load', () => {setTimeout(interceptClick, 1000);  });})();

プロミスメソッドとか全然まだ理解してなくてそのなかに関数代入したその関数オブジェクトプロパティresponseを?いやまあそのあたりのコードが示すデータの流れが全然理解できないような人間でもここまでできちゃった。

AIすごいなと思うよ。そして思うのは今後重要になってくるのは文法とか自体に詳しいことじゃなくて、そのプログラムの処理内容を指示できるシステムエンジニア的な言語化能力のほうじゃないかなと思った。

-----BEGINPGPSIGNEDMESSAGE-----Hash: SHA51220250609111559680 -----BEGINPGPSIGNATURE-----iHUEARYKAB0WIQTEe8eLwpVRSViDKR5wMdsubs4+SAUCaEbCbwAKCRBwMdsubs4+SLueAPwOv7PBk4voAe5qlcCEvs/PJhmKc5QAb/1R43JMQFuDZgD/UTPEKsL/PhK9jFGv2HDXK1dVjLNwvosgX9uYJh5xxwY==qiOE-----ENDPGPSIGNATURE-----

Permalink |記事への反応(2) | 20:16

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

2025-06-08

dorawii

ChatGPTにバッチファイルを作ってもらったのでこれから署名捗るぞ。これだけ手軽化できたらレスバに入っても署名つけるのも億劫にならずできそうだ。

なにせ文章を書き折ったらあとはバッチダブルクリックしてCtr+Vするだけだ。

原文には現在日時のミリ秒表示を使うことにした。

名乗る人が増えることを期待して作らせたものを公開しておく。

@echo offsetlocal::ミリ秒単位UTC時刻を取得for /f %%A in ('powershell -nologo -command "[int64]::Parse((Get-Date).ToUniversalTime().ToString('yyyyMMddHHmmssfff'))"') doset timestamp=%%A::PGPクリア署名作成echo %timestamp% | gpg --yes --clearsign> signed.asc::PowerShellで余計な改行なしに |< をつけてクリップボードコピーpowershell -nologo -command ^  "$header = '>|'; $footer = '|<'; $body =Get-Content 'signed.asc' -Raw;Set-Clipboard -Value ($header + \"`r`n\" + $body + $footer)"echo Done. signed.asc created and clipboard updated (no extra blankline).
-----BEGINPGP SIGNEDMESSAGE-----Hash: SHA51220250608045542542 -----BEGINPGP SIGNATURE-----iHUEARYKAB0WIQTEe8eLwpVRSViDKR5wMdsubs4+SAUCaEUXzgAKCRBwMdsubs4+SCvuAQDjRjPVCO1F9DgmAKoqKYG7qB9r4e7y2Ky+/umT/OhnygEA8h2NL8zIczSphcOk/MaDWJJ2Y7WDA3d6gxFakW8TKAw==HE4/-----ENDPGP SIGNATURE-----

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

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

2025-05-18

官報ダウンロード

令和7年4月1日以降、官報帰化情報が90日経過で閲覧不可になった。

プライバシー配慮」とのことだが、最近の不自然戸籍不要発言などと合わせて考えると嫌な予感しかしない。

そこでとりあえず官報を保存できるプログラムを作った。自分ダウンロードして保存すること自体は全く問題ない行為

官報は平日の8:30に公開されるので、cronで8:31かに実行すると良いのでは。

#官報PDFデータを入手して保存するimport requestsimportosimporttimefrom bs4 import BeautifulSoupfromurllib.parse importurljoin#対象URLindex_url = "https://www.kanpo.go.jp/index.html"base_url = 'https://www.kanpo.go.jp/'#ダウンロードフォルダdownload_dir = 'pdfs'os.makedirs(download_dir, exist_ok=True)# ページ取得response = requests.get(index_url)response.encoding = 'utf-8'text =response.text#HTMLを解析soup = BeautifulSoup(text, "html.parser")results = []# 「本日官報」を対象PDF情報を取得するtoday_box = soup.find('div', class_='todayBox')if today_box:dl = today_box.find('dl')dt =dl.find('dt')    ifdt:        # 日付の抽出date_text =dt.get_text(strip=True).split('\n')[0].replace(" ","").replace("全体目次はこちら","").replace("※インターネット官報","").strip()dd =dl.find('dd')        ifdd:            for li indd.find_all('li', class_='articleBox'):title_tag = li.find('a', class_='articleTop')pdf_link = li.find('a', class_='pdfDlb')                iftitle_tag andpdf_link:title =title_tag.decode_contents().replace("<br/>", "").strip()url =pdf_link['href']                    results.append({                        '日付':date_text,                        'title':title,                        'url':url                    })# 結果の表示for r in results:date = r['日付']title = r['title']url = r['url']     #pdfファイルURL作成url_parts =url.rsplit("/", 1)url_base =url_parts[0]    filename =url_parts[1].replace("f.html", ".pdf")    converted_url = f"{url_base}/pdf/{filename}"        #pdfURLファイル名を作成    full_url =urljoin(base_url, converted_url)    base_filename =date + "_" +title + "_" + filename.replace("f.html", ".pdf")    #ダウンロードして保存print(f'Downloading {full_url} ...')try:response = requests.get(full_url)response.raise_for_status()        withopen(os.path.join(download_dir, base_filename), 'wb')as f:            f.write(response.content)print(f'Saved: {base_filename}')time.sleep(10)    except Exceptionas e:print(f'Failed todownload {full_url}: {e}')

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

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

2025-03-23

はてな匿名ダイアリーを非公開でブクマするbot作成方法

はてなブックマークAPIを利用して 非公開 でブックマークする方法をご説明します。

1.はてなAPI認証情報を取得

1.はてな開発者向けページ でAPIキーを取得。

2.OAuthトークンを発行する。(個人用のスクリプトなら「パーソナルアクセストークン」推奨)

2.APIリクエストパラメータ

ブックマークを 非公開 にするには、APIリクエストボディに privateフィールドを 1 に設定します。

エンドポイント:

POSThttps://bookmark.hatenaapis.com/rest/1/my/bookmark

リクエストボディ(JSON): {    "url": "https://anond.hatelabo.jp/xxxxxxx",    "comment": "自動ブックマーク",    "private": 1}

これで 非公開のブックマーク になります

3.Pythonスクリプト

以下のコードを実行すれば、10分以内の匿名ダイアリー記事ランダムに 非公開 でブックマークできます

import feedparserimport requestsimport randomimporttimefrom datetime import datetime,timezone,timedelta#はてなAPI認証情報HATENA_API_KEY = "あなたAPIキー"HATENA_USERNAME = "あなたはてなID"#はてな匿名ダイアリーRSSURLRSS_URL = "https://anond.hatelabo.jp/rss"#10分以内の投稿を取得def get_recent_entries():    feed = feedparser.parse(RSS_URL)    recent_entries = []now = datetime.now(timezone.utc)    for entry in feed.entries:        published_time = datetime(*entry.published_parsed[:6], tzinfo=timezone.utc)        if (now - published_time) <timedelta(minutes=10):            recent_entries.append(entry.link)    return recent_entries#はてなブックマークに非公開で追加def bookmark_entry(entry_url):url = "https://bookmark.hatenaapis.com/rest/1/my/bookmark"    headers = {        "Authorization": f"Bearer {HATENA_API_KEY}",        "Content-Type": "application/json"    }    payload = {        "url": entry_url,        "comment": "自動ブックマーク",        "private": 1  # 非公開設定    }response = requests.post(url,json=payload, headers=headers)    returnresponse.status_code# メイン処理whileTrue:    entries = get_recent_entries()    if entries:        entry = random.choice(entries)        status = bookmark_entry(entry)print(f"非公開ブックマーク: {entry},ステータス: {status}")time.sleep(600)  #10分ごとに実行

4. 注意点

• 実行環境:Python 3.x が必要。requests と feedparser をインストール (pip install requests feedparser)

• 実行間隔:time.sleep(600) で10分ごとに実行

API制限:はてなAPIにはリクエスト制限があるため、短時間で大量に実行しないように注意

OAuth認証:APIキーだけでなく、OAuthトークンを使うほうがより安全

このスクリプトを実行すれば、最新の匿名ダイアリー投稿10分以内のものからランダムに選び、非公開でブックマークする ことができます

はてな匿名ダイアリーbotブクマするのは運営も認めてる行為なので、みんなでbotを使ってブクマしよう!

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

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

2025-03-06

コマンド区切り文字TABだったら世界平和だった

OSコマンドプロンプトはどうしてスペースを区切り文字としたのだろうか?もしタブを区切り文字として採用していれば、混乱はもっと少なかったと思うのだけど。

と、いう素朴な疑問からスタートし、タブが唯一の由緒正しい区切り文字として採用されていた世界線考察しました。

https://grok.com/share/bGVnYWN5_aa43b346-0185-4f3e-ac4f-7712a59545c8

この世界線で、TABのみが由緒正しく使える使える区切り文字です。

そうなると、ファイル名の半角スペース問題もなくなる。

tsvデータが主流となりcsvデータparseで悩む人にいなくなる。

スペースとタブを区別するために[TAB]のようなフォントも作られるだろう。

さらに、プログラムのインデントもスペースではなく、すべてタブで行われるようになり、タブ幅は2なのか4なのか8なのか論争も起きなかっただろう。個人エディタの設定で変えればいいだけですしね。

世界平和になったはずです。

もちろん、ASCII規格のUS(Unit Separator,ASCII31):ユニット(フィールド)の区切り、に相当するキーキーボードに搭載されていたとしたら、それを使うのが最良だったと思う。

しかしながら、多くのキーボードにはスペースキーかタブキーぐらいしかなく、これを使うことはできなかったでしょうね。

まとめ

コマンド区切り文字にスペースを使ってしまった、インデントにスペースを使ってしまった。

この辺りの失敗が多くの人を悩ませていると思う。

もしコンピュータ歴史をやり直せるのであれば、この時にタブを採用していればねえ。

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

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

2024-05-24

anond:20240523100428

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

import requestsimportjsonfromurllib.parse import quotedef 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:            returnresponse.json()        exceptjson.decoder.JSONDecodeErroras e:print(f"Error decodingJSON from {api_url}: {e}")print("Response content:",response.text)            return []    except requests.exceptions.RequestExceptionas 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 = []    foruser 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        iflen(comments) == 2:            common_bookmarks.append({"user":user, "comments": comments})    return common_bookmarksif __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エラーになったわ

Permalink |記事への反応(1) | 10:38

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

2023-12-14

架空言語、という事にしておいてほしいんだが

    List<Record> rows =DBから持ってくる();    // 合計金額を求めるStringtotal = "0";    for (Record r : rows) {BigDecimal temp =BigDecimal.parse(カンマを削除する関数(total) );BigDecimal temp2 = temp + r.金額;total =カン区切り文字列にする関数(temp2);     }    // やったー合計金額計算してカン区切り文字列にできたよー    returntotal;

とか

    // async await は非同期処理を同期してくれる魔法言葉だって!よく知らんけど    await axios.get('/foo')        .then(function(result) {             // やったー結果が得られたよー        });

とか

正直なところ、こういうコードのお守りするの、そろそろキツい。。。

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

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

2023-08-14

anond:20230813211225

たとえは、0 / float.Parse("0") とかすると、Infinity になるんじゃね?まずいと思うが。

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

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

2023-08-13

anond:20230813185410

なんかおかしいか

信用できない文字列に対してこそ、よくテストされ尽くしたfloat.Parse()を使うのは当然だと思うんだが。。

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

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

2023-07-18

気象庁バグがずっと放置されてる

この時期になるとずっと気象庁の気温ランキングを眺めて「今日暑いなー」って見てるんだが

https://www.data.jma.go.jp/obd/stats/data/mdrr/rank_daily/data00.html

このページの「観測値」が昔からずっとバグっててめっちゃ気になってる

「35.9 ]」っていう感じで、「]」が入ってる

もうバグの原因はほぼほぼ目に見えてて、ここはJSONで「 [ 34.0, 34.5, 35.0, 35.9 ]」っていう値が入ってて

それをJSON.parseするんじゃなくてsplit()とか使ってしかもlength-1とかで最新値を取ってる

なので後ろの括弧がそのまま入ってしまってる

こんなのめちゃくちゃわかりやすバグだし、多分気象庁側も把握してるんだろうけど

多分発注しないとダメとかテスト必要だとかでずっと放置されてる

めっちゃ気になるのにずーーーーーっとこのままなのが凄くダサい

何がダサいってこういうのをアジャイルに直すことができない日本ソフトウェアに対する態度がすげーダサい

Permalink |記事への反応(2) | 11:09

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

2023-04-19

strftime

strptime

がどっちが文字を日付にするやつか

日付を文字にするやつか

もう何年も忘れ続けて

その都度検索してたんだけど

わかった!!!

Format のfとParseのpだわ!!!!!!!

これで検索しなくても覚えられる😁

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

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

2022-08-18

俺はみずほと同じぐらいのコードしか書けないのに気が付いた

話題ホットエントリ問題、解いてみた。

結論タイトルの通り

不正解score += 0; と書いているのは静的解析がelse節を省略すると指摘してくるから

何もしていない、はそのとおり。

不等号がいい具合に化けてるのでそのままにしておく。

importjava.util.*;public classMain {    public staticvoidmain(String[] args) {        //入力parse       (中略:int numに問題の数、String list[i][] に問題リストを格納している)        // 採点        intpoint = 0;        for (int i = 0; i < num; i++) {String question = list[i][0];Stringanswer   = list[i][1];                        if (question.equals(answer)) {                // 完全一point += 2;            } else {                if (question.length() ==answer.length()) {                    //文字数は等しい(部分点の可能性がある)point += scoring(question,answer);                                    } else {                    //不正解point += 0;                }                            }        }        System.out.println(point);    }    // 長さが同じ文字列を採点する    // 長さが違う文字列を受け渡したときは正しく動作しない    private static int scoring(String question,Stringanswer) {        int length = question.length();        intscore  = 2;        for (int i = 0; i < length; i++) {          (中略:文字が違うたびにscoreを-1して、socreが0以下になったらそのままreturn)        }        returnscore;    }}

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

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

2021-01-10

このような文章は、MTLはおろか、ほとんどの人には解析できないでしょう。

A sentencelike this would be impossible formost people toparse, let alone MTL.

DeepLすげーな、最後無視してるしニュアンスは全部落ちてるけど

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

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

2020-11-28

プログラミング勉強、詳細の疑問大事だけどあとでもいいじゃん?

C#入門書を読んでいて、第4章くらいに4ページくらい割いて書いてあるキャスト

( )で変換するのと int.Parse() で変換するのとどう違うのか(どちらか片方でいいのではないか)をネットで調べ、

なんかas とか int.TryParse() とか出てきてあーんー参照型と値型がーになってダウンキャストとポリフォーニズムでお昼ごはん夜ご飯になったところで切り上げた

オーケー、とりあえず現状詳細わからんでいいわ

型の違う数値同士のときが ( ) で、文字列から数値に変換したいときが int.Parse() とかだな

入門書に書いてあるそのまんまだな

プロの取捨選択最高

もういいや次ページ行こう全然進まん

Permalink |記事への反応(2) | 20:11

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

2020-05-23

anond:20200523125218

eval(parse(text=paste0(paste0(...

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

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

2020-05-09

anond:20200509091500

では横ですが、ワテクシの特技のRを少々……

eval(parse(text=paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(paste0(

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

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

2019-04-02

いま、この「自分の全記事を一括削除するスクリプト」は動かない?

anond:20130927152907

いま、この「はてな匿名ダイアリー自分の全記事を一括削除するスクリプト」は、動かない?

httphttps、URL などは、適切に直した。

・POSTに与える最後csrf を取ってくるparse が間違って、 rkm= が空になっている。正規表現parse していたのを直して、 o+XXXXXXXXXXXXXXX/g を拾ってくるようにした。

・POSTに与えるdelete=が元々の %8d%ed%8f%9c%82%b7%82%e9 でも削除できないし、「 %e5%89%8a%e9%99%a4%e3%81%99%e3%82%8b 」でも削除できなかったし、これってマジックナンバーなん?

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

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

2019-01-01

Graphviz を使ってPython抽象構文木を生成する。



1. こんな感じで使います


1.1.スクリプトとして使用する。

$pythonparser.py sample.py


1.2.モジュールとして使用する。

importparsercode ='''a  = 1 + 1print(a)'''graph =parser.create_graph(code)graph.render("sample")


2.ソースコードparser.py はこんな感じです。

importastimport sysimportgraphvizdefcreate_graph(lines):    graph =graphviz.Graph(format='png')root =ast.parse(lines)    node_list = [root]    _setup(graph, node_list)return graphdef_setup(graph, node_list):# node    node = node_list[-1]    node_identity =str(len(node_list))    node_name =type(node).__name__    graph.node(node_identity, node_name)# childrenfor childinast.iter_child_nodes(node):        node_list.append(child)        child_identity =str(len(node_list))        graph.edge(node_identity, child_identity)        _setup(graph, node_list)if __name__ =='__main__':    file_name = sys.argv[1]withopen(file_name)asfile:        lines =file.read()    graph = create_graph(lines)    graph.render(file_name)

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

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

2018-08-06

Facebook は買ったサービスを衰退させる)

FacebookVR の雄 Oculus も買っています。今はVR といえば Oculus ですが、VR にはどんどん大きな会社が参入してきています近いうちに Oculus の影響力は下がっていくことでしょう。それを見たFacebook経営層は、Parse と同じ判断をするはずです。その時、Oculus 用のソフトを開発していた人たちは、今のParse で開発していた人たちと同じ辛さを経験するでしょう。これを予見できる開発者たちは、早期に Oculusから撤退するはずです。そうするとVR に対する Oculus の影響力は加速度的に小さくなります

まり、何が言いたいかというと、今回の判断開発者Facebook 離れを引き起こす判断であり、Facebook に買われたサービスは衰退することを宿命づけてしまった大きな事件の一つだったということです。

もうFacebook は有望な会社は買わないでくれ!と本気で思う一件でした。

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

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

2018-03-17

anond:20180316232605

Excelを持っているならはてブJSONデータをそのまま取り込めるそうだからそのデータを使ってブクマが付いた時間グラフが描けそう。

例えばこんな感じでJSONデータが取れる。http://b.hatena.ne.jp/entry/jsonlite/https://anond.hatelabo.jp/20180315232737

Excel持ってないならスクリプトCSVにしてしまえばいい。

rubyスクリプトだとこんな感じ。(Mechanize無し版に差し替え。なぜMechanizeを使っていたかと言うとはてブUser-Agentが空だと値を返してくれないから。ちょっと長くなるが自前でUAを渡すようにした。)

#!/usr/bin/ruby

require 'uri'

require 'net/http'

require 'json'

require 'csv'

site =ARGV[0]

json_uri =URI.parse("http://b.hatena.ne.jp/entry/jsonlite/%s" % [site])

response =Net::HTTP.start(json_uri.host,json_uri.port) do |http|

http.get(json_uri.path, "User-Agent" => "Mozilla/5.0")

end

json_data =JSON.parse(response.body)

json_data['bookmarks'].each do |bookmark|

puts [bookmark['user'],bookmark['timestamp'],bookmark['comment'],bookmark['tags'].to_s].to_csv

end

引数に取得したいページのURLを入れる。hatebuapi-csv.rbという名前で保存したとしたらこんな感じで実行。

% hatebuapi-csv.rbhttps://anond.hatelabo.jp/20180315######## > 結果.csv

このケースでは朝の7時から爆発的にブクマが付き始める様子が分かる。

https://imgur.com/66FlJIB

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

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

2015-11-29

aliexpressをrubyスクレイピング

rubyスクレイピング

aliexpressの検索結果から

検索結果のURLを抜き取るのは、

結構簡単にできた。

ここから、ページ切り替えてURL収集する処理も追加すれば、

クローロング部分は完成。

あとは、各ページに対するスクレイピング問題



require 'open-uri'

require 'nokogiri'

#スクレイピング先のURL

url = 'http://ja.aliexpress.com/category/200003482/dresses.html?spm=2114.52010108.6.7.gT0qlW&addpid=32546825642&isOnSale=yes%22'

charset =nil

html =open(url) do |f|

charset = f.charset #文字種別を取得

f.read #htmlを読み込んで変数htmlに渡す

end

#htmlパース(解析)してオブジェクト作成

doc = Nokogiri::HTML.parse(html,nil, charset)

num=0

doc.css('a[class = "product "]').each do |product|

p product.attribute("href").text

p num = num+1

end

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

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

2014-12-24

イブクリスマスも予定のない俺とみんなのためのエロサイトを作った

作ったサイト

エロ動画を色々なところから収集するサイトです。

skrsvideo

http://skrsv.info/

サーバー選び

今回プログラミング言語Rubyを選択したため、基本的にはVPSクラウド的なサーバーLinuxが動作する環境を探しました。

エロサイト運営するにあたって問題になるのがサーバー選びです。

基本的日本レンタルサーバーではアダルトサイト運用を禁止しています

普段使っているさくらVPSが利用できず、AWSもなんだかグレーな感じ(東京リージョン以外なら・・・?)

そんなわけで探し、GMOグループWebkeepersを使いました。

Webkeepersのサーバー海外にあるらしいです。

質問アダルトサイト運用はできますか?

http://faq.webk.net/faq/index.php?qc=1&qc_sub=4&id=99

使っても良いよ〜というお墨付き

そして価格も手頃だったためここに決定。

システム

DBMariaDB
WebサーバNginx
フレームワークRuby on Rails

MariaDBを選んだ理由はなんとなく、MySQLとの違いはほぼありません。利用するGEMmysql2でいけます

NginxWebサーバで、ページキャッシュもしています

ちなみにJavaScriptは使わずすべてCSSで作る方針しました。

スマホPC対応のためにMedia Queryでレスポンシブにしています

Webの流れ

Nginx

unicorn

Ruby on Rails

MariaDB

という流れです

使っているGEM

gem 'mysql2'

gem 'rails_config'

gem 'kaminari'

gem 'haml-rails'

gem 'sass-rails'

gem 'nokogiri'

gem 'unicorn'

フロントhamlsassで、難しいことはしていないのでcompassはいれませんでした。

あとはデバッグ用にrails_config、pry系が入っています

クローリングスクレイピングでnokogiriを使います

クローラー

skrsvideoでは動画URLを取得するためにクローラーもどきスケジューリングして収集しています

スケジューリングにはcrontabを使用しています

crontabでRakeタスクを定期的に叩きます

コマンドはこんな感じ

RAILS_ENV=production bundle execrake item:search


Rakeタスクはnokogiriでxvideosへのリンクを集めています

doc = Nokogiri::XML(open(URI.parse(url)).read )

urls = []

doc.css('a').each do |link|

 urls.pushlink[:href] iflink[:href] =~ /xvideos.com\/video(\d+)/

end

Nokogiriのスクレイピングでaタグリンクを取得し、URLxvideosのものかチェックして保存って感じです。

動画を探し終えるとaタグからランダムピックアップし次のページに進んでいきます

動画が見つかったページはドメインDBに記録して、しばらくしたら再びクローリングをするようにし、収集効率化。

サイト機能

(45min)←コレの安心感は異常wwwwww

http://blog.livedoor.jp/dennououjo/archives/39873075.html

これを思い出して、動画時間を表示するようにしました。

30分以上の表示はちょっと頑張ったところ

http://skrsv.info/30_min_more


AV女優タグが表示されるようになっています

これはタイトル文字列から部分一致で引っかかったものを表示しています

AV女優名前を表示するためにWikipediaからとってきたら、ちょっと膨大な数になってしまったため断念。

どんだけ女優いるんだって感じですね。

DMMランキングに載っていた方だけをとりあえず入れています

タグも同様にDMMから

おわりに

1日でつくろうと思っていたら思った以上にサーバーが見つからないで、サーバー選びに1日かかってしまいました。

あとはFC2とか対応できたらいいなーと思います

Permalink |記事への反応(2) | 23:10

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

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

[8]ページ先頭

©2009-2025 Movatter.jp