投稿者: koji

  • 人類社会を変えた発明の4分類

    まえがき

    『歴史を振り返ると「人類社会を変えた発明」と呼べるものがたくさん見つかります。ここでは便宜上、大きく4つのジャンルに分類してみましょう。』

    リスト

    あとがき

    まえがきを含めて、Rootport『人類を変えた7つの発明史 火からAIまで技術革新と歩んだホモ・サピエンスの20万年』 (KADOKAWA、2024年)より。リストは本文からの要約・引用です。

    「人類社会を変えた発明」を少数のカテゴリに分類してみる。なんとも心躍る取り組みです。当サイトにとっては書名の「7つの発明」よりもこちらのほうが価値あるリスト。

    ひとつだけ補足。犬や猫が「人類にはできなかったことをできるようにした発明」とされているのは、犬を家畜化してその嗅覚を狩りに使ったり、猫を家畜化してその体臭で小動物を忌避させたりしたことを指しています。

    一方で馬は、ものを運んだり畑を耕したり戦場を駆けたりと、人ができることを拡張したと言えるので第4分類。

    境界線上にいくつか悩ましい例があるのでは……などと考えを巡らせたくなるところも含めてユニークなリスト。

    • 動物実験の3R原則

      まえがき

      『3Rは、製品テストや科学研究における動物のより倫理的な使用を導く原則です。これらは1959年にW. M. S. ラッセルとR. L. バーチによって初めて唱えられました。』

      リスト

      あとがき

      まえがきは “Three Rs (animal research)” (Wikipedia) から、リストは “3Rs for the public” (National Centre for the 3 Rs) からの翻訳・引用です。わかりやすさを優先して「動物実験の3R原則」と題しましたが、「科学研究に動物を用いる場合の3R原則」という感じ。

      スチュアート・リッチー『Science Fictions あなたが知らない科学の真実』 (ダイヤモンド社、2024年)の注釈部分に次のような文章がありました。

      動物実験全般が非道徳的だと考える人も多い。やむを得ず動物を使う場合、科学者は研究をできるだけ倫理的なものにするために一連の原則に従う。これは「3つのR」として知られているもので、

      そして紹介されていたのがこちら。

      • Replacement(代替/動物以外のもの、たとえば、普通は同意が得られる人間を研究に使おうと努めること)
      • Reduction(削減/できるだけ少ない数の動物からできるだけ多くの有用な情報を得ようとすること)
      • Refinement(洗練/動物が研究に使用されているあいだ、苦痛を軽減して動物の幸せをできるだけ高く保つこと)

      第1項目は「動物の代わりに人間で実験すべき、なぜなら動物からは同意が得られないから」と書かれているように読めます。不思議に思って少々検索してみました。

      もっとも権威があると思われるのは、本書でも名が挙がっていた “National Centre for the 3 Rs” というサイトです。3Rの定義は更新されていますが、もっともオリジナルに近いと思われるものを訳しました。たしかに動物実験の代替手段の例に人間(ボランティア)が挙がっていますね。他の例と併せて見せられると納得。

      この本からの他のリスト

    • X(Twitter)への投稿字数を調整する

      概要

      LOTD(今日のリスト)を X(Twitter) に投稿する際、140字に切り詰める処理を実装した。

      背景

      これまで外部サービスを使っていたLOTDのXへの自動投稿を、お手製のプログラムに切り替えました。下記のような内容を、メール配信と同じタイミングで投稿します。

      [今日のリスト] 【タイトル】: 【抜粋】
      【パーマリンク】
      【ハッシュタグ化したタグ】

      たとえば「4つの元型(ユング)」であれば次のような感じです。

      [今日のリスト] 4つの元型(ユング): 『元型は、カール・グスタフ・ユングが提唱した概念。世界中の神話や夢や芸術などに普遍的に見られるパターンのこと。元型は、個人的な無意識ではなく、人類に共通する「集合的無意識」から発生するとされる。』
      https://listfreak.com/list/20747
      #ユング #人格 #元型 #無意識 #脳科学

      しかし、これをTwitter APIに送ると403エラーが返ってきます。不親切なことに「字数が長いよ」ではなく「投稿は許されない」という抽象的なエラーメッセージだったので、字数オーバーであること自体に気づくのに時間がかかりました。

      投稿が長い場合には、抜粋で調整しようと思います。たとえば下記のように。

      [今日のリスト] 4つの元型(ユング): 『元型は、カール・グスタフ・ユングが提唱した概念。世界中の神話や夢や芸術などに普遍的に見られるパターンのこと。元型は、個人的な無意識ではなく、人類に共通する「集合的無意識」から発生す…
      https://listfreak.com/list/20747
      #ユング #人格 #元型 #無意識 #脳科学

      内容

      「字数」と「重み付き字数」

      Xでは日本語140字(characters)、英語280字まで投稿できると言われます。これは日本語1字に2字ぶんの「重み」(weight)が付けられているからです。

      なので「あいuえお」の字数(length)は5字ですが、Xの数え方では9字です。ややこしいので、Xの数え方に従った字数を「重み付き字数」と称します。「あいuえお」の字数は5字、「重み付き字数」は9字です。

      全角=2字、半角=1字というわけでもない

      PHPには半角文字を 1、全角文字を 2 として字幅を数える mb_strwidth() や、同じ数え方で指定した字幅で文字列を丸める mb_strimwidth() があります。しかしPHPでは字数 1 と判定される「…」が重み付き字数では2になるなど、字の数え方が X とすこし異なります。

      twitter-text がルールブック

      X の公式サイトによると、ポストの字数制限は twitter-text というオープンソースライブラリで提供しているとのこと。しかし残念ながらPHPのライブラリはありません。そこで構成ファイルだけを借りて軽量なクラスを作りました。

      class LF_Twitter_Text {
      
        // twitter-text configuration
        private static $tt = null;
      
        // 初期化
        public static function init() {}
      
        // 構成内容の取得
        public static function get() {}
      
        // 文字列の重み付き字数を数える
        public static function count_str( $string ) {}
      
        // 文字列の後ろを指定された重み付き字数ぶん切り落とす
        public static function truncate( $string, $length ) {}
      
        // 渡された1文字の重み付き字数を返す
        private static function count_char( $char ) {}
      }

      初期化メソッドは次のようにしました。構成情報をファイルに置くと置き場所を考えるのが面倒だしめったに変わる情報ではないのでハードコード。versionが上がったらJSON部分を入れ替えます。

      public static function init() {
      
        // 重複して呼ばれ得るので、すでに値が入っていればそれを返す
        if ( self::$tt ) {
          return self::$tt;
        }
      
        self::$tt = json_decode( '
      {
        "version": 3,
        "maxWeightedTweetLength": 280,
        "scale": 100,
        "defaultWeight": 200,
        "emojiParsingEnabled": true,
        "transformedURLLength": 23,
        "ranges": [
          {
            "start": 0,
            "end": 4351,
            "weight": 100
          },
          {
            "start": 8192,
            "end": 8205,
            "weight": 100
          },
          {
            "start": 8208,
            "end": 8223,
            "weight": 100
          },
          {
            "start": 8242,
            "end": 8247,
            "weight": 100
          }
        ]
      }'
        );
      }

      字数カウントの核となる、重み付き字数のカウント部分はこのような感じにしました。大部分が日本語、次が英数字などいわゆる半角文字なので、その順番にヒットして処理を終了できるようにちょっと工夫をしました。

      private static function count_char( $char ) {
      
        // UTF-8のコードポイントを取得
        if ( false === $code = mb_ord( $char, 'UTF-8' ) ) {
          return false;
        }
      
        // 大部分を占める日本語をまず判定
        // ranges 配列の最後のメンバーのendとまず比較する
        if ( end( self::$tt->ranges )->end < $code ) {
          return self::$tt->defaultWeight / self::$tt->scale;
        }
      
        // 次に多いと思われるメジャーな半角文字から判定する
        foreach ( self::$tt->ranges as $range ) {
          if ( $range->start <= $code && $code <= $range->end ) {
            return $range->weight / self::$tt->scale;
          }
        }
      
        // 残りは全て2字幅
        return self::$tt->defaultWeight / self::$tt->scale;
      }

      これらのメソッドを使って下記のような感じで投稿する文字列を作成しました。

      // Twitter-Text configuration の内容を取得する
      $tt = LF_Twitter_Text::get();
      
      // パート1: [今日のリスト] タイトル: 抜粋
      $xpost_part1       = '[今日のリスト] '.$post->post_title.': '.$post->post_excerpt;
      $width_part1       = LF_Twitter_Text::count_str( $xpost_part1 );
      
      // パート2: (改行)permalink(改行)ハッシュタグ
      $xpost_part2       = PHP_EOL.$post_url.PHP_EOL.$hash_tags_str;
      // パート2の文字幅を計算する。URLは固定長文字列をダミーとしてあてがう
      $xpost_part2_dummy = PHP_EOL.str_repeat( '-', $tt->transformedURLLength ).PHP_EOL.$hash_tags_str;
      $width_part2       = LF_Twitter_Text::count_str( $xpost_part2_dummy );
      
      // 必要ならパート1の文字数を削る
      if ( 0 < $over_width = $width_part1 + $width_part2 - $tt->maxWeightedTweetLength ) {
        $xpost_part1 = LF_Twitter_Text::truncate( $xpost_part1, $over_width );
      }
      
      // X投稿
      $xpost = $xpost_part1.$xpost_part2;
    • 抽象化の3側面

      まえがき

      『人類がこれまで飛躍的な知的進化を遂げてきた背景にこの抽象化能力がある。(略)「抽象化」という言葉はなにげなく使われる割に厳密な定義は難しいが、大きく以下の3つの側面が考えられる。』

      リスト

      あとがき

      まえがきを含めて、細谷功『アナロジー思考』 (東洋経済新報社、2011年)より。リストは本文からの要約・引用です。

      たしかに『「抽象化」という言葉はなにげなく使われる割に厳密な定義は難しい』と思いますが、それでもこうやって定義をかたちづくってみせるところに著者の力量を感じます。

      この3側面の中では「構造化」が本書のテーマであるアナロジー思考にとって必要とのことでした。

      まさに表面的類似性を意識することなく構造的類似性を探り当てる能力こそ抽象化能力に他ならない。抽象化能力の中でも構造化という思考はアナロジー思考を用いる上では特に必要な思考能力といえる。

      • タイトルアナロジー思考
      • 著者: 細谷功(著)
      • 出版社: 東洋経済新報社
      • 出版日: 2011-07-28
      • ビジネスにおける雑談の目的

        まえがき

        『雑談をする際には、確認作業だけでなく、4つの大きな「目的」があることを知っておく必要があります。 しっかりと目的意識を持っていないと、雑談は細切れの会話になり、方向性を見失うことになるのです。』

        リスト

        あとがき

        まえがきを含めて、ピョートル・フェリクス・グジバチ『世界の一流は「雑談」で何を話しているのか』 (クロスメディア・パブリッシング、2023年)より。

        実のところ、ビジネスの場では日本語でいう「雑談」ではなく、成果に向けて意図や目的をもった対話をしようという趣旨。

        世界のビジネスシーンで、一流のビジネスマンが交わしているのは、日本的な雑談ではなく、「dialogue」 に近いものだと思います。ダイアログとは、「対話」という意味ですが、単なる情報のやりとりだけでなく、話す側と聞く側がお互いに理解を深めながら、 行動や意識を変化させるような創造的なコミュニケーション……を目指した会話です。

        「世界のビジネスシーン」とか「一流のビジネスマン」とか書かれるとなぜか気恥ずかしい気持ちになります。それはさておき主張はまっとうでわかりやすいものでした。

        講義なんかで休憩の後にすこし雑談の時間を設けるようにしています。そのときに参考になりそうなので収集しました。

        • 判断するのが苦手な人の4つの特性

          まえがき

          『大事なことは、(判断が)うまくできない「場面」を並べ立てるだけでなく、「それらに通底している(どの場面にも共通している)」自分自身の社会生活に最も障壁となっている特性をきちんと把握することなのです。(略)ここでは、特に「判断すること」に影響があると思われる特性を挙げてみたいと思います。』

          リスト

          あとがき

          まえがきを含めて、佐藤 恵美『「判断するのが怖い」あなたへ 発達障害かもしれない人が働きやすくなる方法』 (ディスカヴァー・トゥエンティワン、2020年)より。リストは本文からの引用です。まえがきは「(判断が)」のみ追加しています。

          意思決定が本業でのテーマでもあるので興味を持って読みました。著者は、発達障害という診断を受けていない人も対象読者であるとして、本書の目的を次のように述べています。

          「発達障害特性」という切り口で自分を見直すことによって(略)社会の中でどう自分を嫌いにならずに生きていくか、自分とどううまくつき合って生きていくか、ということに希望を持ってもらうことを目的としています。

          ではこれらの特性を裏返すと優れた判断者になれるのかというと、そうでもないところが面白いですね。

          第1項目については、よい判断をするために『「だいたいこれくらい」で済ませない』トレーニングをしたりします。「速い判断」を阻害する特性ではあっても「正確な判断」をするうえでは助けになる特性かもしれません。

          一方で第2項目以降は、誰しも意識したいところかなと思います。あれもこれもごちゃごちゃにしていないか、固定的に考えていないか、ワーキングメモリを十分に使っているか。特性という定義からすると努力で直接改善することは難しいわけですが、意識することで補える方法はあるわけで、本書のようなガイドブックがそれを支援してくれます。

          • 病気の体験における3つのポイント

            まえがき

            『病気を科学的、医学的に見れば、「細胞・組織・器官レベルでの失調」ということになるでしょう。しかし、病気を当人の立場から見るとき、それはどういう体験なのでしょうか。』

            リスト

            あとがき

            まえがきを含めて、西 研『NHK出版 学びのきほん しあわせの哲学』 (NHK出版、2021年)より。引用元は行岡 哲男『医療とは何か: 現場で根本問題を解きほぐす』 (河出書房新社、2012年)とのこと。行岡の定義に著者が解釈を添えた文章を編集・引用しています。

            病気という「できごと」を、人はどう「体験」するか。病気に限らず、失敗や挫折、老化などが人生の物語の書き換えにつながるメカニズムを端的に表しているように思えます。

            この本からの他のリスト

            参考文献

              (2024年出版の新装版へのリンクを貼っています)

            • 死の特徴(ハイデガー)

              まえがき

              『つまり〈死とは、あらゆる生の可能性を喪失してしまうという可能性である〉とハイデガーは言うのです。(略)ハイデガーは、死について、さらに次のように指摘しています。』

              リスト

              あとがき

              まえがきを含めて、西 研『NHK出版 学びのきほん しあわせの哲学』 (NHK出版、2021年)より。リストは本文からそのまま引用しています。本書の引用元はハイデガー『存在と時間II』 (中央公論新社、2003年)からの模様。

              死とは、いつか確実に、いまこの瞬間にも訪れ得る、誰にも代わってもらえず、だれとも分かち合えない、生の可能性の喪失。端的で網羅的で相互排他的。いっそ詩的とも感じられる死の定義です。

              NHK出版の「学びのきほん」シリーズは良書が多いように思います。その中にあって本書は内容の豊かさと読みやすさにおいてシリーズの中でもかなり上位にあるのでは。

              この本からの他のリスト

              参考文献

              • タイトル存在と時間II
              • 著者: ハイデガー(著)、原 佑(翻訳)、渡邊 二郎(翻訳)
              • 出版社: 中央公論新社
              • 出版日: 2003-05-10
              • 経済学者の公的責任

                まえがき

                『以下に、経済学者の公的責任を要約した。(略)私たち経済学者は、自分も社会に参加していることを忘れないと同時に、一般市民の利益のためにできる限り公平な行動を心がけ、その立派な志を持ち続けなければならない。』

                リスト

                あとがき

                まえがきを含めて、ダイアン・コイル『経済学オンチのための現代経済学講義』 (筑摩書房、2024年)より。リストは本文中の箇条書きからの引用です。

                経済学者のみならず、専門家の心得として有用なリストかなと感じたので収集しました。

                • Xに投稿する機能を作る

                  概要

                  LOTDをX(Twitter)に自動ポストするために使っていたサービスが停止されたので代替機能を作りました。

                  経緯

                  LOTD(今日のリスト)は、システム的には「lotd というカテゴリに入っている(唯一の)投稿」であり、毎日 0:00 に入れ替えています。このような仕様にしたのは、WordPressがカテゴリごとに RSS フィードを作ってくれるからでした。

                  当サイトをWordPressに乗せ換えた当時はフィードをツイートしてくれる無料サービスの選択肢が多かったため、LOTDだけのフィードさえ作れれば、追加の開発なしで LOTD の tweet bot が実現するのは容易でした。

                  dlvr.it はそのような配信サービスの一つでした。毎日いい感じに巡回してきてくれて、フィードが更新されていたらツイートしてくれました。Twitter が X になり、ツイートがポストと呼ばれるようになっても、ちゃんと動いてくれました。しかし残念ながら運営者から「1週間後に free plan はおしまいにするよ」というメールが来ました。ずいぶん急な話です。

                  いくつかプラグインを検討したのですが、特定のカテゴリの投稿だけを毎日ポストしてくれる軽量プラグインが見あたらず、自作することにしました。

                  Twitter APIライブラリのインストール

                  PHPでXに投稿するためのライブラリとしては TwitterOAuth が超定番のようです。公式ページによれば composer という依存関係管理ツールで次のようにインストールするのがおすすめとのこと。

                  composer require abraham/twitteroauth

                  しかしこの方法では 0.5.4 という、かなり古いバージョンの TwitterOAuth がインストールされてしまいます。どうも composer が参照するPHPのバージョンが古く、そのバージョンのPHPで動くバージョンの TwitterOAuth がインストールされている模様。さすが依存関係管理ツール。

                  当サイトはレンタルサーバー上で動いているので、/usr/bin の下にはいろいろなバージョンのPHPが混在しています。古いバージョンでも機能すればよいのですが、このバージョンは Twitter API v2 に対応していないようなので、新しい TwitterOAuth をインストールしなければならないようです。

                  あれこれ調べた結果、構成ファイル composer.json を以下のように作り、composer install することで、新しいバージョンの TwitterOAuth をインストールできました。

                  {
                      "config": {
                          "platform": {
                              "php": "8.2"
                          }
                      },
                      "require": {
                          "abraham/twitteroauth": "^7.0"
                      }
                  }

                  実のところもっとも時間がかかったのは、この新しいバージョンの TwitterOAuth をインストールする作業でした。いったん環境が整えば、次のようにかなり少ない手数でポストできます。

                  // TwitterOAuthインスタンスの作成
                  $X = new TwitterOAuth(
                    '(API Key)', 
                    '(API Key Secret)',
                    '(Access Token)',
                    '(Access Token Secret)'
                  );
                  
                  // API v2 を指定
                  $X->setApiVersion( '2' );
                  
                  // 投稿内容
                  $post = '[今日のリスト] ';
                  
                  // ツイートを投稿
                  $response = $X->post( 'tweets', [ 'text' => $post ] );
                  
                  // 成功なら 201 (Created) が返ってくる
                  if ($connection->getLastHttpCode() !== 201) {
                  	// エラー処理
                  }

                  この処理を、LOTDのメール配信の次に実施することにしました。投稿内容もRSSフィードの転送でなくゼロから組み立てるので、リストに付けたタグをXのハッシュタグにするなど、工夫もしやすくなりました。

                  [lf_load_syntax_highlighter]