疑念は探究の動機であり、探究の唯一の目的は信念の確定である。

数学・論理学・哲学・語学のことを書きたいと思います。どんなことでも何かコメントいただけるとうれしいです。特に、勉学のことで間違いなどあったらご指摘いただけると幸いです。 よろしくお願いします。くりぃむのラジオを聴くこととパワポケ2と日向坂46が人生の唯一の楽しみです。

C言語の文字列について: 完全攻略ガイド

概要
C言語において文字列の扱いは極めて難しい。
今回はC言語の文字列についてステップバイステップで説明する。

対象者
とりあえずC言語の配列やポインタを一通り勉強したけれども、まだ全然よくわからない人。


プログラム

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
    // STEP 1
    printf("-----STEP 1-----\n");
    printf("Hello, World!\n");
    printf("\n");

    // STEP 2: use place holders 
    printf("-----STEP 2-----\n");
    printf("%s\n", "Hello, World!!");
    printf("Addr of \"Hello, World!!\"  = %p\n", "Hello, World!!");
    printf("Addr of &\"Hello, World!!\" = %p\n", &"Hello, World!!");
    printf("\"Hello, World!!\"[0]  = %c\n", "Hello, World!!"[0]);
    printf("\"Hello, World!!\"[1]  = %c\n", "Hello, World!!"[1]);
    printf("\"Hello, World!!\"[2]  = %c\n", "Hello, World!!"[2]);
    printf("\"Hello, World!!\"[3]  = %c\n", "Hello, World!!"[3]);
    printf("\"Hello, World!!\"[4]  = %c\n", "Hello, World!!"[4]);
    printf("\"Hello, World!!\"[5]  = %c\n", "Hello, World!!"[5]);
    printf("\"Hello, World!!\"[6]  = %c\n", "Hello, World!!"[6]);
    printf("\"Hello, World!!\"[7]  = %c\n", "Hello, World!!"[7]);
    printf("\"Hello, World!!\"[8]  = %c\n", "Hello, World!!"[8]);
    printf("\"Hello, World!!\"[9]  = %c\n", "Hello, World!!"[9]);
    printf("\"Hello, World!!\"[10] = %c\n", "Hello, World!!"[10]);
    printf("\"Hello, World!!\"[11] = %c\n", "Hello, World!!"[11]);
    printf("\"Hello, World!!\"[12] = %c\n", "Hello, World!!"[12]);
    printf("\"Hello, World!!\"[13] = %c\n", "Hello, World!!"[13]);
    printf("\"Hello, World!!\"[14] = %c\n", "Hello, World!!"[14]);
    printf("\n");

    printf("\\x020 = %c\n", '\x020');
    printf("\\0 = %c\n", '\0');

    printf("Hello,\\x020World! = %s\n", "Hello,\x020World!");

    // STEP 3: use variables
    // 3.1: Initialize
    // Pointers 
    char *ptr_str_init  = "PTR INIT: Hello, World!!!";

    // Arrays
    char arr_str_init[] = "ARR INIT: Hello, World!!!";
    printf("-----STEP 3.1-----\n");
    printf("%s\n", arr_str_init);
    printf("%s\n", ptr_str_init);
    printf("\n");

    // 3.2: Declaration and Substitution
    // Pointers
    char *ptr_str_dec;
    ptr_str_dec = "PTR DEC: Hello, World!!!";

    // Arrays
    char arr_str_dec[30];
    arr_str_dec[0] = 'A';
    arr_str_dec[1] = 'R';
    arr_str_dec[2] = 'R';
    arr_str_dec[3] = ' ';
    arr_str_dec[4] = 'D';
    arr_str_dec[5] = 'E';
    arr_str_dec[6] = 'C';
    arr_str_dec[7] = ':';
    arr_str_dec[8] = ' ';
    arr_str_dec[9] = 'H';
    arr_str_dec[10] = 'e';
    arr_str_dec[11] = 'l';
    arr_str_dec[12] = 'l';
    arr_str_dec[13] = 'o';
    arr_str_dec[14] = ',';
    arr_str_dec[15] = ' ';
    arr_str_dec[16] = 'W';
    arr_str_dec[17] = 'o';
    arr_str_dec[18] = 'r';
    arr_str_dec[19] = 'l';
    arr_str_dec[20] = 'd';
    arr_str_dec[21] = '!';
    arr_str_dec[22] = '!';
    arr_str_dec[23] = '!';
    arr_str_dec[24] = '\0';

    // Mallocs
    char *mlc_str_dec;
    mlc_str_dec = malloc(30);
    mlc_str_dec[0] = 'M';
    mlc_str_dec[1] = 'L';
    mlc_str_dec[2] = 'C';
    mlc_str_dec[3] = ' ';
    mlc_str_dec[4] = 'D';
    mlc_str_dec[5] = 'E';
    mlc_str_dec[6] = 'C';
    mlc_str_dec[7] = ':';
    mlc_str_dec[8] = ' ';
    mlc_str_dec[9] = 'H';
    mlc_str_dec[10] = 'e';
    mlc_str_dec[11] = 'l';
    mlc_str_dec[12] = 'l';
    mlc_str_dec[13] = 'o';
    mlc_str_dec[14] = ',';
    mlc_str_dec[15] = ' ';
    mlc_str_dec[16] = 'W';
    mlc_str_dec[17] = 'o';
    mlc_str_dec[18] = 'r';
    mlc_str_dec[19] = 'l';
    mlc_str_dec[20] = 'd';
    mlc_str_dec[21] = '!';
    mlc_str_dec[22] = '!';
    mlc_str_dec[23] = '!';
    mlc_str_dec[24] = '\0';


    printf("-----STEP 3.2-----\n");
    printf("%s\n", ptr_str_dec);
    printf("%s\n", arr_str_dec);
    printf("%s\n", mlc_str_dec);
    printf("\n");
    free(mlc_str_dec);


    printf("-----STEP 4-----\n");
    // Pointers
    printf("Addr of \"PTR STO: Hello, World!!!!\" = %p\n", "PTR STO: Hello, World!!!!");
    char *ptr_str_sto;
    ptr_str_sto = "PTR STO: Hello, World!!!!";

    /* Notes:   */
    /*
    error: redefinition of 'ptr_str_sto'
    char *ptr_str_sto = "PTR STO: hello, world!!!!"; 
    */

    printf("Addr of ptr_str_sto       = %p\n", ptr_str_sto);
    printf("%s\n", ptr_str_sto);
    
    printf("Addr of \"ptr sto: hello, world!!!!\" = %p\n", "ptr sto: hello, world!!!!");
    ptr_str_sto = "ptr sto: hello, world!!!!"; 
    printf("Addr of ptr_str_sto                 = %p\n", ptr_str_sto);
    printf("%s\n", ptr_str_sto);
    
    
    /* -------- */
    char arr_str_sto[30] = {'A', 'R', 'R', ' ', 'S', 'T', 'O', ':', ' ', 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!', '!', '!', '!', '\0'};

    printf("Addr of arr_str_sto = %p\n", arr_str_sto);
    printf("%s\n", arr_str_sto);
    printf("\n");
    arr_str_sto[0] = 'a';
    arr_str_sto[1] = 'r';
    arr_str_sto[2] = 'r';
    arr_str_sto[4] = 's';
    arr_str_sto[5] = 't';
    arr_str_sto[6] = 'o';
    arr_str_sto[9] = 'h';
    arr_str_sto[16] = 'w';

    printf("Addr of arr_str_sto = %p\n", arr_str_sto);
    printf("%s\n", arr_str_sto);
    
   //copy
   int i = 1;
   int j = 2;
   printf("Addr of int i = %p\n", &i);
   printf("int i         = %d\n", i);
   i = j;
   printf("Addr of int i = %p\n", &i);
   printf("int i         = %d\n", i);

   char *mlc_string1 = malloc(10);
   char *mlc_string2 = malloc(10);
   mlc_string1[0] = 'H';
   mlc_string1[1] = 'e';
   mlc_string1[2] = 'l';
   mlc_string1[3] = 'l';
   mlc_string1[4] = 'o';

   mlc_string2[0] = 'h';
   mlc_string2[1] = 'e';
   mlc_string2[2] = 'l';
   mlc_string2[3] = 'l';
   mlc_string2[4] = 'o';

//Error: Abort   mlc_string2 = "hello";   
   printf("mlc_string1 = %s\n", mlc_string1);
   printf("mlc_string2 = %s\n", mlc_string2);
   
//Error: Abort   mlc_string1 = mlc_string2;

   printf("mlc_string1 = %s\n", mlc_string1);
   free(mlc_string1);
   free(mlc_string2);


    return 0;
}


実行結果

-----STEP 1-----
Hello, World!

-----STEP 2-----
Hello, World!!
Addr of "Hello, World!!"  = 0x103f71b99
Addr of &"Hello, World!!" = 0x103f71b99
"Hello, World!!"[0]  = H
"Hello, World!!"[1]  = e
"Hello, World!!"[2]  = l
"Hello, World!!"[3]  = l
"Hello, World!!"[4]  = o
"Hello, World!!"[5]  = ,
"Hello, World!!"[6]  =  
"Hello, World!!"[7]  = W
"Hello, World!!"[8]  = o
"Hello, World!!"[9]  = r
"Hello, World!!"[10] = l
"Hello, World!!"[11] = d
"Hello, World!!"[12] = !
"Hello, World!!"[13] = !
"Hello, World!!"[14] = 

\x020 =  
\0 = 
Hello,\x020World! = Hello, World!
-----STEP 3.1-----
ARR INIT: Hello, World!!!
PTR INIT: Hello, World!!!

-----STEP 3.2-----
PTR DEC: Hello, World!!!
ARR DEC: Hello, World!!!
MLC DEC: Hello, World!!!

-----STEP 4-----
Addr of "PTR STO: Hello, World!!!!" = 0x103f71e77
Addr of ptr_str_sto       = 0x103f71e77
PTR STO: Hello, World!!!!
Addr of "ptr sto: hello, world!!!!" = 0x103f71edb
Addr of ptr_str_sto                 = 0x103f71edb
ptr sto: hello, world!!!!
Addr of arr_str_sto = 0x7ffeebc8f860
ARR STO: Hello, World!!!!

Addr of arr_str_sto = 0x7ffeebc8f860
arr sto: hello, world!!!!
Addr of int i = 0x7ffeebc8f834
int i         = 1
Addr of int i = 0x7ffeebc8f834
int i         = 2
mlc_string1 = Hello
mlc_string2 = hello
mlc_string1 = Hello


(未完)

PythonでChromeDriverを自動更新するプログラムを作った。

概要
Seleniumchrome driverを使ってスクレイピングをおこなうが、Googleクロムのアプリは自動的に最新版となる。それによって、chrome driverのバージョンとクロムのバージョンが異なることによって、次のようなエラーが生じる。

selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 83

通常は最新のchrome driverをウェブ上からダウンロードして新しいchrome driverに替えなければならない。
今回はchrome driverを最新版のバージョンに自動的にアップデートするようなプログラムをrequestsBeautifulSoupなどを用いて作る。


プログラム

### import Selenium
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys

import subprocess
import re
import os
import urllib.request
import requests
from bs4 import BeautifulSoup

### get the current chrome version
def get_chrome_version():
    chrome = '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'

    chrome_data = subprocess.run([chrome, '--version'], stdout=subprocess.PIPE, encoding='UTF-8')

    chrome_str  = chrome_data.stdout
    ch_reg_exp  = re.findall('\d+', chrome_str)
    ch_full_ver = '.'.join(ch_reg_exp)
    ch_int_ver  = ch_reg_exp[0]

    chrome_version = ch_full_ver, ch_int_ver

    return chrome_version


### download the suitable chrome driver
def download_chrome_driver(chrome_version):
    download_return = False
    download_dir = '/Users/USERNAME_XXXXX/Downloads'
    url = 'https://chromedriver.chromium.org/downloads'
    res   = requests.get(url)
    soup  = BeautifulSoup(res.text, 'html.parser')
    list_notes_txt = soup.find_all('a', href=re.compile('notes.txt'))

    download_url = None
    mac_file     = '/chromedriver_mac64.zip'
    for notes_txt in list_notes_txt:
        match = re.search(r'\d+', notes_txt.get('href'))
        if match.group(0) == chrome_version:
            notes_txt = notes_txt.get('href')
            download_url = os.path.dirname(notes_txt) + mac_file
            break

    if download_url != None:
        new_chrome_driver = download_dir + mac_file
        ### download
        urllib.request.urlretrieve(download_url, new_chrome_driver)

        ### unzip the file 'chromedriver_mac64.zip'
        subprocess.run(['unzip', new_chrome_driver], stdout=subprocess.PIPE, encoding='UTF-8')

        ### delete the zip file
        subprocess.run(['rm', new_chrome_driver])

        ### Because the unzipped chrome driver lies in the current directory, move it to the directory 'download_dir'
        subprocess.run(['mv', './chromedriver', download_dir])
        download_return = True

    return download_return

### change the new chrome driver
def change_new_chrome_driver():
    old_chrome_driver = '/Users/USERNAME_XXXXX/opt/anaconda3/lib/python3.7/site-packages/chromedriver_binary/chromedriver'
    new_chrome_driver = '/Users/USERNAME_XXXXX/Downloads/chromedriver'

    subprocess.run(['open', new_chrome_driver])
    subprocess.run(['rm', old_chrome_driver])
    subprocess.run(['mv', new_chrome_driver, old_chrome_driver])

### main
### Initialize Chrome
try:
    ### Success
    DRIVER_PATH = r'/Users/USERNAME_XXXXX/opt/anaconda3/lib/python3.7/site-packages/chromedriver_binary/chromedriver'
    options = Options()
    options.add_argument('--headless')

    driver = webdriver.Chrome(executable_path=DRIVER_PATH, options=options)

except Exception:
    #### Version Error
    ### STEP 1: get the current chrome version
    ret_val_1 = get_chrome_version()

    ### STEP 2: download the suitable chrome driver
    ret_val_2 = download_chrome_driver(ret_val_1[1])

    ### STEP 3: change the new chrome driver
    if ret_val_2 == True:
        change_new_chrome_driver()


プログラムの方針
STEP 1: 現在のGoogle Chromeのバージョンを取得する。
1.1: subprocessを使って、Chromeのバージョンを取得する。
ターミナル上で次のコマンドを打つと、現在使用中のChromeのバージョンがわかる。

$ Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --version
$ Google Chrome 87.0.4280.67

このコマンド操作をsubprocessを使って、Pythonのファイルでおこなう。

1.2: reを使って、取得したChromeの情報からバージョンの数値のみを取得する。
(87.0.4280.67, 87)


STEP 2: requestsBeautifulSoupで適切なバージョンのchrome driverを取得する。
2.1: バージョンに合うURLを取得する。
https://chromedriver.storage.googleapis.com/87.0.4280.88/chromedriver_mac64.zip

2.2: urllib.request.urlretrieveを使って、ダウンロードする(requestsでもできると思う)。

2.3: subprocessを使って、zip形式を解凍して、zipファイルを捨てる。


STEP 3: subprocessを使って、すでにあるchrome driverをDownloads配下にある最新のchrome driverに変更させる。

(だいたい完)

C言語の構造体とtypedefとsizeofについて

C言語の構造体の書き方についてまとめました。
また、構造体のサイズを取得するときのsizeofについてまとめました。
typedefをtypedefすることは基本的にないそうです。
また、構造体をsizeofをすると自動的にパディングします。余計なビットが加わります。

ソースコード

#include <stdio.h>

// without typedef
struct st_example {
    char char_;
    int  int_;
};

// with typedef (1)
typedef struct {
    char char_;
    short short_;
} st_example_typedef;


//with typedef (2)
typedef struct _st_example {
    char char_;
    int int_;
} st_example_;

// we do not define typedef struct st_example_ *example_ptr;
typedef struct _st_example *example_ptr;

int main(void) {

// without typedef
struct st_example ins;
ins.char_ = 'a';
ins.int_ = 1;

printf("ins.char_ = %c\n", ins.char_);
printf("ins.int_ = %d\n", ins.int_);
printf("sizeof(struct st_example) = %lu\n", sizeof(struct st_example));
printf("-------------------\n");

// with typedef (1)
st_example_typedef ins_td;
ins_td.char_ = 'b';
ins_td.short_ = 2; 

printf("ins_td.char_ = %c\n", ins_td.char_);
printf("ins_td.short_ = %d\n", ins_td.short_);

printf("sizeof(st_example_typedef) = %lu\n", sizeof(st_example_typedef));


実行結果

ins.char_ = a
ins.int_ = 1
sizeof(struct st_example) = 8
ーーーーーーーーーー
ins_td.char_ = b
ins_td.short_ = 2
sizeof(st_example_typedef) = 4

最初の構造体st_exampleのサイズはintが4バイトであるため、charの1バイトプラス3バイト分、追加されます。したがって、sizeof(struct st_example)は4 + 1 + 3 = 8バイトとなります。

一方で、次の構造体st_example_typedefのサイズはshortが2バイトですので、charの1バイトプラス1バイト分、追加されます。したがって、sizeof(st_example_typedef)は2 + 1 + 1 = 4バイトとなります。


また、一度typedefしたものをさらにtypedefはしないそうです。
つまり、typedef struct _st_example *example_ptr;はしますが、typedef st_example_ *example_ptr;はしません。理由はよくわかりませんが。



僕から以上

PythonのSeleniumでWebスクレイピングをする(Mac): 基本編

概要
PythonSeleniumはウェブ上のサイトを自動で探索する。それを利用して必要なデータを自動的に取得するプログラムをつくる。
今回はSeleniumの使用する環境構築を主として述べる。
Seleniumのテスト試験として次のようなプログラムを作成する。つまり、Googleのホームページに入って、検索欄に「ゼロからはじめるPython」を入力して、検索ボタンを押すというものである。

さらに、よく使う機能をまとめる。


ソースコード

# test.py

import time 
from selenium import webdriver

# 1) Initialize Chrome
# DRIVER_PATH is dependent on your environment.

DRIVER_PATH = '/Users/USERNAME/opt/anaconda3/lib/python3.7/site-packages/chromedriver_binary/chromedriver'
driver = webdriver.Chrome(DRIVER_PATH)

# 2) Open the Google page
driver.get('https://www.google.com')

#### Fig.1

# 3) Wait until the page
time.sleep(3) 

# 4) Get an object of the search box
q = driver.find_element_by_name('q')

# 5) Send the key to the search box
q.send_keys('ゼロからはじめるPython')

#### Fig.2

# 6) submit the form
q.submit()

# 7) Wait in 10 seconds
time.sleep(10)

#### Fig.3

# 8) Finalize the driver
driver.quit()


実行結果
(1) Googleのホームページが自動的に立ち上がる
f:id:yoheiwatanabe0606:20200930200413p:plain
Fig.1


(2) 検索欄に「ゼロからはじめるPython」が自動的に入る
f:id:yoheiwatanabe0606:20200930200418p:plain
Fig.2


(3) 自動的にクリックされて検索結果が表示される
f:id:yoheiwatanabe0606:20200930200424p:plain
Fig.3


(4) 10秒待って、終わるページが消える

  • はじめに
  • 注意点
  • 環境構築の方法
    • STEP 1: Google Chromeをインストール
    • STEP 2: pipでseleniumおよびchromedriver-binaryをインストール
    • STEP 3: chromedriverの場所を見つける。
      • 3.1: Finderからcommand + Fを押す(Find)
      • 3.2: Searchボックスに「chromedriver」と検索する
      • 3.3: chromedriverをクリックして、パスを右クリックする
      • 3.4: 「Copy "chromedriver" as Pathname」をクリック
    • STEP 4: テストソースを書く
  • うまくいかなかった場合の対処法
  • よく使うテクニック
  • 最後に
続きを読む

書評: 齋藤孝著『「自己中」の正体』

一言書評: いろいろな自己チュウの正体を明らかにしているが、その処方箋は多くない。


今回は齋藤孝著『「自己中」の正体』の書評です。

「自己中」の正体 ~自分の"エゴ"と折り合いをつける生き方とは!?~

「自己中」の正体 ~自分の"エゴ"と折り合いをつける生き方とは!?~

  • 作者:齋藤 孝
  • 発売日: 2019/11/12
  • メディア: 単行本(ソフトカバー)

本書要約

本書は6章あるが、第1章から4章まで自己チュウの分析に紙幅を割いている。
第5章と第6章で自己チュウに対する対処法を示している。しかし、結局、対処法はわずかしかない。

自己チュウというエゴは悪い面だけでなくいい面もある。どのようなエゴがあるのか、どのような悪い面やよい面があるのかという分析が本書の多くの割いている。
エゴの向き合い方は、エゴというエネルギーを増やしつつ、それをコントロールすることであると著者は結論づける(おわりに)。
だが、どのように具体的にエゴをコントロールするのかという方法論(手続き論)は極めてお粗末である。有益な情報はほとんどない。

自己チュウには個人のものだけでなく、集団の自己チュウ(会社の自己チュウ/世代の自己チュウ/国家の自己チュウ)があると指摘をしている。少子化は企業のエゴと高齢者のエゴの結果であり、先の戦争は国家のエゴの結果であると批判する。

少子化は高齢者のエゴイズムであり、企業のエゴイズムでもあるのです。

第4章 人間はエゴから抜け出せないのか
第1節 出生率の低下は究極のエゴ

国家として日本は、明治維新以後、一気に近代化して急速に発展したわけですが、それとともに日本は朝鮮半島や中国大陸にに深く関わり合っていきます。そして日清戦争日露戦争という戦争を経て第二次世界大戦の悲劇へとつながります。
 それは、ある意味、自国中心主義が強かったということだろうと思います。

第2章 歴史は「自己チュウ」で創られる
第2節 国家「自己チュウ」が国民を不幸のどん底


社会は少しずつよくなってきているが、最近の人たちは、メンタルが弱いので、心が折れやすい。人慣れをしていないと、自己チュウが肥大化してしまうため、個人の「自己チュウ」からの対処法は、「人慣れ・場慣れ」をして、メンタルを鍛えることであると答える。

■心が折れやすい
そう考えると、世の中は、時代とともに良くなりつつあるわけです。世の中全体としては良くなっているのですが、問題は、個人のメンタルが弱くなり、心が折れやすくなっていることでしょう。とくに、若い人はそうです。


■「人慣れ」しないと「自己チュウ」が肥大化する
人々のメンタルが弱く、心が折れやすくなっている昨今、必要なことは何か。それは、「人慣れ・場慣れ」をすることです。
自分を外にさらせない、他人と関わるのがつらい、学校にも行けない、会社に勤めることもくたびれるということになると、「自己チュウ」がどんどん肥大化してしまいます。そういう20代を過ごすと、30代以降で就職するのは非常に難しく、中高年の引きこもりも社会問題になっています。
(中略)
ですから、「人慣れ・場慣れ」をすることは、社会に出て働くことができるということなので、自分自身で「自己チュウ」をコントロールすることにもつながるわけです。


■令和は「場慣れ」の大切さを知る時代
中には、さほど病的な事態ではないのに精神的に支障があるということにして、それで自分は社会の中で生きなくていいのだと開き直ってしまうような人もいます。そこまで極端でないにせよ、自分はメンタルが弱いと決めつけて避難所を作ってしまうと、いよいよ人慣れしなくなります。「人慣れ・場慣れ」することは、じつに大事です。その威力を、平成から令和にかけての人は知ったほうがいいでしょう。
(中略: 昭和のときは色々な人と自然と関わってきた)
こうした環境に乏しい今の時代は、とりあえず何かしらの社会に属する必要があり、そこで「人慣れ・場慣れ」をするしかありません。


■「人慣れ」「場慣れ」のチェックポイント
社会に飛び出すにあたり、自分はどれだけ「人慣れ・場慣れ」をしているかを知るチェックポイントは、いくつかあります。
たとえば、
・人前で堂々と話せるか
・人の話がちゃんと聞けるか
・集団で仕事しようとしている時に、わがままを言わずに自分の役割を果たせるか
・少々の無理はきくか
・チームの一員としてやっていける人間か
などがそれに当たります。そうした能力を獲得するために、まず、「人慣れ・場慣れ」をするような環境に自分の身を置きましょう。
(中略)
それと同じように、練習によって「人慣れ・場慣れ」をしておけば、社会の中で人と関わっていくのも難しくないと私は思います。


■「自己チュウ」はコミュニケーション技術で克服
今の時代は、パソコンの仕事が増えたからといって、パソコンを相手の仕事だけで生きていけると思ったら大間違いです。フリーランスになったら、余計、人づき合いがうまくないと、仕事は絶対に来ません。
(中略)
「自己チュウ」というものは、そのようにして、じつはコミュニケーション技術として克服していけるものです。社会の一員としてやっていける時点で、自分は「自己チュウ」ではないと思えばいいでしょう。本当に「自己チュウ」なら、周りから排除されているはずだからです。


■胸を張って生きる
時代が進むにしたがって対応すべきことが増えてきたのだから、ある程度、やることを絞ることも大切です。そして、「人慣れ・場慣れ」をして、メンタルを強くしましょう。そうすれば、自分が「自己チュウ」になることも、「自己チュウ」な他人の犠牲になることもなく、自立した大人として新しい時代を乗り切っていけるはずです。

第6章 エゴの本性とは
第4節 令和時代の新人間像を探究する

気になった箇所

三色ボールペンでのところの「自分が気になった箇所」を羅列する。

評者には歴史を知らないので判断は避けるが、人によっては「なんという歴史観だ!」と憤激するだろうなと思った。

孔子の「己の欲せざるところは人に施すなかれ」という教えを考えるなら、植民地化されるのがイヤで近代化した日本は、他国へ出て行って植民地化はやめるべきという発想になるべきだったのです。ところが朝鮮半島満洲に出て行ってしまった。それで、日清戦争日露戦争が起こるわけです。


この一連の戦争に、大勝利ではないにせよ、たまたま勝利したことに日本国民は酔ってしまい、「いける!」という誇大妄想を抱いた結果、最終的には太平洋戦争に突入していきました。
(中略)
当時も今でもそうですが、アメリカは最強国です。そんなアメリカと戦争をするというのは愚かな決断でした。
歴史的に見ても、ハルノートが太平洋戦争突入のひとつのキッカケと言われていますが、「本当にアメリカと日本に戦争する理由があったのか」という問いに対する答えは、歴史家の間でも見つかりません。アメリカも、太平洋戦争が終わった時に、戦うべき相手は日本ではなかったことに気づきます。

第2章 歴史は「自己チュウ」で創られる
第2節 国家「自己チュウ」が国民を不幸のどん底

一応、この引用文の後に、ルーズベルトの側近にソ連のスパイがいたことは補足しているが、このような見解は、右翼から見れば「自虐史観」と言われるのだろうなと思った。

資本主義社会が矛盾を抱えて、それに対抗する社会主義共産主義が台頭して支持を得た。そして実際にソ連などの社会主義体制ができた。だが、結局、社会主義体制は崩壊した。それでは「どうして、社会主義社会がダメだったのか」と問われたら、しばしば次のように答えられる。それは「働いても働かなくても報酬は同じであるから、人々はノルマの達成のみの仕事しか行わず、経済が発展しなかったからだ」というものである。

・これでは労働者は、まるで奴隷のようではないかということで、それを是正するマルクス主義は、多くの労働者たちの共感を得たのです。そして各国で社会主義政権・共産主義政権が生まれました。その"壮大な実験"を見たところ、平等で繁栄した社会がつくられたかというと、ソビエト連邦の崩壊を見ればわかるように、うまくいかなかったということです。それはなぜか。極端な話、人間は働いても、働かなくても報酬は平等という前提の元では、一生懸命に労働に従事しようとは思いません。ただ、表面的なノルマだけを達成すればいいということになるのです。そうすると、経済は発展しません。


・平等を主張する社会主義共産主義になったら解決するでしょうか。もしもそうなって、どんな仕事をしても、労働成果に関係なく年収は同じということになれば、人は努力をしなくなるはずです。

第4章 人間はエゴから抜け出せないのか
第4節 労働者は企業エゴとどう立ち向かうべきか

こういうのをいつも聞くたびに思うのだが、このような当たり前のことを---つまり、報酬が同じならばまともに働かなくなるという人間の惰性を---マルクスをはじめとする頭のいい人が、どうして想定しなかったのかということである(それとも想定してた?)。そのぐらい想定済みではなかったのか、そんなことなんか織り込み済みで、社会主義体制を作ろうとしなかったのか。それとも「人間」というものを綺麗なものと思っていたのだろうか。

学生たちも、誰かが「あそこはブラック企業らしいよ」と言うと、就職試験は受けなくなります。すると、その会社の社業はだいたい傾いていきます。ブラックな部分を減らさないと、採用すら危うくなるということです。
今は、そういう情報がインターネットで一気に流れますので、インターネットによる情報の共有が時代を動かしていると言えるでしょう。


第4章 人間はエゴから抜け出せないのか
第4節 労働者は企業エゴとどう立ち向かうべきか

そんなこと言っていいの?
それなら、わざと「あの会社ブラックだよ」と吹聴して、悪評を作って潰すこともできるけど?
行ったこともないお店に低評価をつけて、店の評価を下げるという似たような話は実際にある。

  • 自己チュウではなく自己本位で生きる

■「自己本位」な生き方
ですから、「まず自分に戻ろう」という個人主義も、悪いものではありません。この個人主義は単なるエゴとは違います。漱石は日本を背負っていますので、エゴイスティックな人ではもちろんないわけですが、個人主義がもたらす精神の安定もあるわけです。
(中略)
つまり夏目漱石にとって、「自己本位」あるいは「自分本位」という言葉は、一見すると自己中心的のようですが、いい意味での個人主義を確立した言葉だったのです。
(中略)
ですから、人目を気にしてしまう対他者意識の強い人は、むしろ「自分本位」になって個人主義を確立したほうがいいでしょう。出発点は自分なのです。自分のありのままの姿を認めることは、自分を愛することであり、自分の思うことをすることは悪いことではありません。
(中略)
人目を気にして悩んでいる人は、他者の評価に生きるのはやめて、もっと自分を中心に据えたほうがいいのではないでしょうか。私は、自己中心的になることを勧めているのではなく、自分は自分でいいという、「自分本位な生き方」をすることを勧めているのです。

第6章 エゴの本性とは
第3節 文学からエゴを読み解く

ごもっとな話だが、自己チュウと個人主義の違いとは何か、それほど明確ではないと思う。

  • 就活しない学生への叱責

職業は、人へのサービスとして行うからお金が貰えるのです。大学生の中には時々、「自分の好きなことをやりたいけれど、それがまだ見つからないので、卒業が近づいても就職活動ができません」という人がいますが、漱石の論理からすると、それは違うということになります。「今、キミがやろうとしていることは、道楽かね?」と、漱石なら言うでしょう。
もちろん、歌のうまい人が歌手になるとか、野球が好きな人が野球の選手になるほど、自分の好きなことが職業になることもあるでしょう。でも、歌手になってもCDが売れないかもしれないし、ドラフト1位でプロ入りした野球選手でも、1軍の試合に一度も出ずに引退するケースだってあります。そのように、好きなことを仕事にした場合でも厳しさというものは伴います。それはプロの世界ほど厳しいのです。
そうすると、「これは自分に向いている」というくらいのところが、職業としては結構いいのではないでしょうか。他のことをするより、これをしたほが疲れないということは、誰にでもあるはずです。
たとえば、営業は疲れないけれど経理は疲れるという人は、当然、営業職に就いたほうがいいですし、その逆の人は経理の仕事に就いたほうがいい。ですが、どんな職業も人のために行うのですから、人の要求に合わせる苦労はつきものです。自分のために、自分の好きなことだけやれる道楽でお金を貰うという考えは、「それは甘い!」と、漱石は教えてくれているのです。

第6章 エゴの本性とは
第3節 文学からエゴを読み解く

これは自分で言いたいことを他人の権威で言っている典型である。「そんな甘いこと抜かすな!」と自分で言うのではなく、漱石のフンドシで言っているのである。少なくとも自分の意見は曖昧でごまかしている。このような言い方が著者の特徴である。

  • 監視カメラの設置の肯定

■身勝手な不正や犯罪を防ぐ社会に進む
...公共の場所においては、監視カメラの設置はむしろフェアになるのです。

第6章 エゴの本性とは
第4節 令和時代の新人間像を探究する

マジか!! まさかの監視社会の肯定か!!!

■「自己実現」ではなく「他者実現」を感じる
しかも、会社はだんだん厳しくなりつつあり、その動きを変えることは難しい。その中で自分が生き残っていくために必要な能力は、他者のリクエストをちゃんと感じ取る能力です。空気を読むのではなく、他者のリクエストをちゃんと感じ取ること。「自己実現」ではなく、「他者実現」というのがポイントです。
他者の要望を実現させ続けている人は、どんどん仕事が来ます。
(中略)
その結果、「他者実現」を続けていくと、「自己実現」がしやすくなっていくのです。最初から「自己実現」を目指すと、その実現は難しいということです。

第6章 エゴの本性とは
第4節 令和時代の新人間像を探究する

人のために尽くすことが己のために尽くすことであるという、手垢のついた説教である。

  • フランスの出生率の高さについて

フランスで出生率が高いのは知っている。
その原因は結局、移民による流入カトリックが離婚を禁止しているため事実婚を容認しているからと思っていた。
だから、フランスを真似ようというのは文化や背景が違うから無理なことだと思っていた。
だが、フランスでは制度として「産みやすく育てやすい環境」となっていることを知った(補助金や大学まで学費の無料など)。
ただ、フランスでは週35時間労働が義務づけられているのは意外だった。
第4章 人間はエゴから抜け出せないのか
第1節 出生率の低下は究極のエゴ

  • 「己の欲せざるところ、人に施すなかれに」ついて

■小学1年生で、一番人気のあった言葉
以前、私が小学1年生に『論語』を教えた時に、一番人気があったのもこの「己の欲せざるところ、人に施すなかれ」という言葉でした。たとえば、人のお菓子を横取りするとか、みんなが並んでいる列に横から割って入るといったことは、誰でも嫌です。だから、そういうことは絶対にしないでおこうというのは、1年生でも全員が納得します。小学生は意外に道徳心が強いのです。

第3章 論語・宗教が「自己チュウ」否定の道徳を養う
第1節 「天命」を自覚してエゴを乗り越える

コメントはあるが....省略(まだちゃんと考えがまとまっていないから)。
立場がわからなければ、何が人に施してはならないものなのかわからない。

  • その他

どこかの箇所で「クレームつける人がいるなら、言いたくないことをその人に代わりに言ってもらえばいい。そういう使い方がある」とアドバイスした箇所があった。


感想 本書を読んだ動機

評者は「新たな自己本位」の可能性を見出した。それを詳細に述べることはできないが、それは「自分のために徹底的におこなうことが、翻って他人のためにもなっている(自己利益の実現、すなわち他者利益という思想)」という可能性である。
この考えは普通ではなく、容易に「自己中心的な考え」と非難されるものである。そこで「自己チュウ」にかんする本を読んで自分の考えを深めようと思ったからである。

結局、著者は「自己をコントロールしろ」「他人のために働け」「人慣れ・場慣れして、メンタルを強くしろ」という常識的な結論だった。それは評者とは対極の考えであった。そのような一般的な考えを知ることができてよかった。
Kindleで買って、風呂場で1時間読んで、風呂上りに1時間読んで、1日で読み切った。その程度の内容なので、暇つぶしにはちょうどいいのかもしれない。そこに書かれている個別の知識はあまり真に受けないほうがいいだろう。著者の専門の教育以外は「薄く広く」知っているに過ぎないのであるから。



僕から以上

Linux: ディレクトリやファイルの検索について

ノート
ディレクトリやファイルの名称がわかるが、どこにあるかわからない場合。

検索する方法

#ディレクトリ構成
.
├── directory1
│   ├── subdirectory1
│   │   └── file1.txt
│   └── subdirectory2
│       └── file2.txt
└── directory2


#ファイルの検索
#ファイルありの場合
$ find ./ -name "file1.txt"
.//directory1/subdirectory1/file1.txt

#ファイルなしの場合
$ find ./ -name "file3.txt"
$


#ディレクトリの検索
#ディレクトリありの場合
$ find ./ -name "subdirectory1"
.//directory1/subdirectory1

#ディレクトリなしの場合
$ find ./ -name "subdirectory3"
$

僕から以上

読書感想#16: 西郷甲矢人&田口茂著『<現実>とは何か』(1)

今回は書評ですが、細かい内容はまたいつか書く。
今はとりあえずブログの更新。

〈現実〉とは何か (筑摩選書)

〈現実〉とは何か (筑摩選書)

本当は読み終わった直後の今年の1月に書くべきでした。最悪でも今月(2020年7月号)の『現代思想』が出版される前に書評すべきでしたが、時間がなかったので今更になりました。


私と彼らの関係は意外に深いのですので、詳細に書きます。

評者と著者との関係

まず、評者と著者の関係について述べよう。これは本書の評論とは直接的には関係ないが、評者が知っている限りの本書成立の裏話を知るのも悪くないと思うからである。

田口先生は北大に赴任されて、私は先生の現象学の授業を取った。知り合いになりフッサールの『危機』第9節を一緒に討論なさってくれた。とてもお世話になった方である。
夏休みのある日、先生の研究室に呼ばれた。そこに行くとある人を紹介してくださった。その人が西郷さん(先生とは呼んだことはないのでそのような敬称にさせていただく)であった。西郷さんとはその一度きりの出会いであったが、強烈な印象を覚えた。
「こちらが西郷さんだ」と紹介され、西郷さんは「よろしく」と言われた。

初めて西郷さんと会った日の直前、『数学セミナー』に記載されていた「圏論の歩き方」というシリーズに西郷さんの論文『すべての人に矢印を!』が出ていた。それを読んだことを伝えた。その論文はのちに『圏論の歩き方』という本に収録された。

圏論の歩き方

圏論の歩き方

  • 発売日: 2015/09/09
  • メディア: 単行本
私はカバンの中にあった遠山啓(とおやまひらく)の『行列論』を手元の出してた。それを見た西郷さんはすかさず「遠山啓の本読んでいるの?」と話された。「ええ、そうです。今、勉強しています。遠山啓は尊敬は…していませんが、ぶっ飛んでいて好きです」と答えた。すると、西郷さんもこの本を読んだことがあるらしく、ベクトル空間の基底数が同じであるという定理の証明方法がいくつかあってね、この本ではこういうふうに証明しているけど別の教科書ではね…と話された。そのあとこう言われた。
「俺も遠山啓好きでさ。自分の息子に「啓」とつけたんだ。ただ、これをそのまま「ひらく」というのは安直すぎるから「けい」って息子に名付けたんだ」
遠山啓のことを知っている人がいるだけでも驚いたのに、好きすぎで自分の息子に同じ漢字を当てたとは!なんて人だ!それが西郷さんの第一印象であった。

西郷さんは他にもこう言われた。
「ベクトル空間の基底数が一定って、かなりすごいと思うんだ。基底の取り方はたくさんある。たくさんの基底はある。それにもかかわらずその数は変わらないって」
そのときは何も思わなかった。しかし、圏論を学んだ後に振り返ると、それはベクトル空間 {V} のデュアルなベクトル空間 {V^*} はキャノニカルな同型ではないが、ダブルデュアル {V^{**}} はキャノニカルな同型である、つまり自然変換であるということを意図した話だったのかなと思った。けれども、ニュアンスはそうではなかったと思う。たぶん関係ないと思う。

田口先生と西郷さんとの出会いはそのときに教えてくれた。彼らの出会いの詳細は本書の後書きに書かれている。私はただ「ピート・ハットという人から紹介してもらった。話し始めたら意気投合したんだ。彼とは馬が合うんだ。それで今、圏論の哲学を共同で研究している。圏論現象学の類似性に驚いている。いつどこで発表できるかはわからないけど、いつか発表ができたらいい」ということを田口先生からうかがった。だから、今回、このように本として出版されたことをとても嬉しく思う。

ちなみに西郷さんの人となりは、『圏論の道案内』という本の序文と後書きを読めばわかると思う。どうして西郷さんがしきりに「仏教」について興味を持っていたり、論じているのかも理由がわかった。西郷さんの父親は芸術家らしく、書斎に仏教や東洋哲学の本が大量にあり、小さい頃から西郷さんはそれらの本を読んでいたそうだ。



他にも『圏論の歩き方』でもわかると思う。西郷さんは研究者の間でも、いろいろな意味で群を抜いていることがわかる。
圏論の歩き方』にはディスカッションの章(座談会)がある。ディスカッションに登場している人たちはペンネームで書かれている(ブルバキに倣ったらしい)。「二条」や「祇園」などである。西郷さんも『圏論の歩き方』のメンバーの一人なのだが、その中で唯一、西郷さんは本名の「西郷」となっている。「どうして僕だけ本名なんですか?」と西郷さんが聞いている箇所があるのだが、「だって、西郷さんは西郷さんでしょ?」みたいな感じに返答されていた。

研究室で挨拶をしたあと、近くのタイ料理店で私と田口先生と西郷さんとで昼食を取った。私はそのとき奢ってもらった。そこで何を話したかは全然覚えていないけれども、唯一覚えているのは、田口先生が「渡邉くん、パクチー大丈夫? もし無理ならば僕にちょうだい。僕、パクチー大好きだから」とおっしゃったことである。

食事を終えて、研究室に戻るときに私は西郷さんにこう言った。
「僕は『数学とは線形の科学である』と考えています。僕が知っている線形性は『微積』と『線形代数』です。つまり、関数の線形性と空間の線形性です。
数学には他にどのような線形性がありますか?」

そのとき西郷さんはもう一つの線形性を指摘された。確か「ベクトル束」のことを言ったと思う。ベクトル束のことを説明してくれたけれども、結局何を言ったのかは理解できなかった。

一度きりの昼食会はそれで終わった。その後、田口先生に会うたびに、先生は圏論の哲学の研究の近況を報告してくださった。話を聞いて「所詮その程度か」とがっかりしたこともある。だからこそ、今回、唯一無二の哲学研究を上梓され、嬉しく思う。


西郷さんの話には続きがあるだが、それはいつか別のところで書こう。もしかしたら書かないかもしれないが。


本書の総括
本書に貫かれている大きなテーマの一つは「実体論からの脱却」(p.159)である。
もう一つは個(individuals)と普遍(universals)の関係である。本書を読んでいるとき、評者はベクトル空間の基底変換の定理を思い浮かんでいた。

{V} {n} 次元のベクトル空間とする。
{\mathscr{B}_1 = \{ e_1, \ldots, e_n \} } および {\mathscr{B}_2 = \{ f_1, \ldots, f_n \} }{V} の2つの基底とする。
このとき、ただ一つの写像 {A: \mathbb{R}^n \to \mathbb{R}^n} (基底変換)
 {(e_1, \ldots, e_n) A = (f_1, \ldots, f_n)}
が存在する。

他にも線形写像の表現定理も思い浮かんでいた。

個としての基底はたくさんあり、それぞれである。だが、それらはただ存在するだけではなく、一定の普遍的な関係(つまり基底変換)がある。だが、基底変換という普遍は最初からあるのではなく、個々の基底があって初めて意味をなす。基底なしの基底変換自体を考えるのは意味がない。つまり、個のない普遍を考えるのは無意味である。


圏論の特徴に「普遍性」という考え方がある。例えばデカルト積(直積集合) {A \times B} とその射影 {p_A: A\times B\to A, p_B: A\times B\to B} は次の普遍性を有する。

任意の写像 {f: X\to A, g: Y\to B} に対して、ある写像 {h: X\to A\times B} がただひとつ存在して、
{p_A\circ h = f} かつ {p_B\circ h = g}
が成り立つ。

実際、集合論において、{h(x) = (f(x), g(x) )} とおけば上の等式が成り立つし、そのような写像がただひとつであることも明らかである。

このような普遍性は数学で(特に代数学)でしばしば出てくる。例えば、テンソル積などである。

集合論において、デカルト積はまず順序対 {(a, b)} を定義してから(クラトフスキーの定義)、 {A\times B = \{ (a, b) | a\in A, b\in B \}} として定義する。そして標準的な射影 {p_A: A\times B\to A, p_B: A\times B\to B} が定義される。そしてそこから「定理」として普遍性が導かれる。
これはテンソル積などでも同様で、集合論的に定義した後に普遍性の定理が導かれる。テンソル積は集合論的に少なくとも2通りの定義の仕方がある。

だが、圏論は逆に、この普遍性を「定義」として採用する。ある概念をある普遍性を満たすものとして定義する。デカルト積は上の普遍性を満たすものとして定義する。テンソル積もある普遍性で定義する。


本書には圏論の普遍性について議論している箇所はほとんどなかったと思う。この普遍性の哲学的意義について今後の研究で明らかにしてほしいと思う。
(未完)