Access Count : 1379
Copyright © 2021 TAKEHANA TADASHI
著作日時: 2021.03.13.土. 16:24:00 著作者、竹花 忠
インターフェースの整合について:
型のインターフェースの整合は、型情報が取得されれば、それを照合して確定できる。
論理のインターフェースの整合は、定理・公式・論理・ストーリー、が取得されれば、それに基づいて確定できる。
ある情報を取得するための、論理・公式・定理・ストーリー、が既知でないなら、点検検証によって導出する必要がある。
そのためには、目的とする・目指す、ある情報についての定義が必要である。
定義とは、これこれのものをこう言う、というものである。
なので、定義がわかれば、こう言うものを取得するには、これこれの条件を満たしたものを用意すればいい、ということが確定できる。
定理・公式・論理・ストーリー、とは、こう言うものはこれこれの、操作・手続き・手順、によって得られる、というものである。
取得を目指している・目的としている、情報は、どういう情報・どういうもの、なのか。それが明確化される必要がある。
それが明確化されれば、取得を目指している情報・目的としている情報、を得るために・確定するために、必要な条件が手に入る。
そうすれば、その条件を満たしたものを取得する、操作・手続き・手順、の、確定・構築、が可能となる。
それによって、論理・公式・定理・ストーリー、に当たるものである、操作・手続き・手順、が手に入る。
論理・公式・定理・ストーリー、が手に入ったら、あとはそれに合わせて、コンピュータープログラミング言語に、転化・転写、してゆけば、コンピュータープログラムが、構築されてゆく・完成する。
まずは作成しようとするコンピュータープログラムの定義である。
キーワードをプログラムのパラメーターとして取得する。
対象ファイル名をプログラムのパラメーターとして取得して、そのファイル名を使って、そのファイルの内容を文字列として取得する。
取得した文字列の中の、直近の句点までを1文とする。句点が出現しないなら、直近の改行までを1文とする。
句点の直後に改行文字の時には、そこまでを1文とする。
キーワードを含んだ文と、その前後の1文ずつを次々に抽出するプログラムが作成されるべきプログラムである。
ただし、キーワード含有文の直後の文もキーワード含有文だった場合には、キーワードを含まない文になるまで、どんどん含有文の個数を増大させてゆくこととする。
結果ファイル名は毎回、ファイル名が重複しないものにする。
そのようなファイル名で、抽出結果を出力する。
以上がこれから作成しようとするコンピュータープログラムについての定義である。
となると、たとえば、プログラムのバラメーターから、対象ファイル名とキーワードを取得することが必要だとわかる。
また、各文がキーワードを含んでいるか調べることが必要だということがわかる。
あるいは、文字列から各文を取得する処理が必要だということがわかる。
キーワードを含んでいるか調べてみて、含んでいなかったから、それを前文とすればいいということにもなる。
キーワードを含んでいたらその文をキーワードの含有文とすればいい。
またそれぞれ、後続の文字列について処理を続行することも必要である。
含有文が発見された状態においての、後続の文がキーワードを含んでいるかの調査で、キーワードを含んでいない。その時には、現状では空の後文に、調査した文を連結することで後文を更新する。そして、前文と含有文と後文を連結して出力する。そしてさらに後続文にキーワードが含まれいるかの調査へ。その際の前文は、今回、後文に連結した文である。また、含有文は空にリセットしておく。
含有文が発見された状態においての、後続の文がキーワードを含んでいるかの調査で、キーワードを含んでいた。その時には、後文に、調査した含有文を連結する。そしてさらに後続の文にキーワードが含まれているかの調査へ。
また、キーワードの含有文が空の状態で、後続の文が空となったら、出力すべき文がないので[]を出力して、調査の続行の必要もないのでこの処理は終了する。
キーワードの含有文が設定されていて、後続の文が空となったら、前文と含有文と後文を出力してこの処理を終了する。
概略、以上によって、キーワードの含有文とその前後の1文ずつから成る文字列、を要素とするリストが取得される。
定義から、そういう、論理・公式・定理・ストーリー、のパーツが判明してゆく。
日時をファイル名に盛り込めば、異なった日時にファイル名の作成が行われることで、異なったファイル名が得られる。
文献調査の結果、日付に基づく文字列を生成する関数がある。また、時間に基づく文字列を生成する関数も確認。
なので、この2つの関数から取得した文字列をファイル名に盛り込んで、結果ファイルの名前を生成。
ファイルに出力できるのは文字列である。文字列を要素とするリストを出力することはできない。
そういう与件というか、制約条件というか、がある。
なので、文字列を要素としたリストを、その要素の文字列を連結してただ1つの文字列に変換する。
その上で、結果ファイルに出力する。
プログラムのパラメーターから、対象ファイル名を取得する。
対象ファイル名を使用して、そのファイルの全内容を、1連なりの文字列として取得する。
その文字列を先頭から1文字ずつ調べてゆく。
直近の句点の位置を検出する。
直近の改行文字の位置を検出する。
句点の位置が改行文字の直前なら、その改行文字までを1文として出力する。
句点の位置の方が先なら、そこまでを、1文として出力する。
改行文字の位置の方が先なら、そこまでを、1文として出力する。
なお、それぞれ、後続の1連なりの文字列も、後続の処理のために出力する。
定義から、たとえば、以上のように、論理・公式・定理・ストーリー、のパーツを確定させていく。
論理のインターフェースの整合は、必要とされるものを、必要とされているところの前までに、出力・取得、してとおくという前後関係によって判定する。
あるいは、必要なものが揃ったところに、それを使用する処理を配置するという前後関係によって判定する。
この前後関係に食い違いがないようにすることが、求められる・必要である。
だから、たとえば、下記のような、論理・公式・定理・ストーリー、となる。
プログラムのバラメーターから、対象ファイル名とキーワードを取得する。
日付に基づく文字列を生成。また、時間に基づく文字列を生成。
この2つの文字列をファイル名に盛り込んで、結果ファイルの名前を生成。
プログラムのパラメーターから、対象ファイル名を取得する。
対象ファイル名を使用して、そのファイルの全内容を、1連なりの文字列として取得する。
※
その文字列を先頭から1文字ずつ調べてゆく。
直近の句点の位置を検出する。
直近の改行文字の位置を検出する。
句点の位置が改行文字の直前なら、その改行文字までを1文として出力する。
句点の位置の方が先なら、そこまでを、1文として出力する。
改行文字の位置の方が先なら、そこまでを、1文として出力する。
なお、それぞれ、後続の1連なりの文字列も、後続の処理のために出力する。
取得された1文がキーワードを含んでいるか調べる。
キーワードを含んでいるか調べてみて、含んでいなかったから、それを前文とする。
キーワードを含んでいたらその文をキーワードの含有文とする。
またそれぞれ、後続の文字列について処理を続行する。
含有文が発見された状態においての、後続の文がキーワードを含んでいるかの調査で、キーワードを含んでいない。その時には、現状では空の後文に、調査した文を連結することで後文を更新する。そして、前文と含有文と後文を連結して出力する。そしてさらに後続文にキーワードが含まれいるかの調査へ。調査のためには※の位置へ進ませる。そして下へと進む。その際、前文には、今回、後文に連結した文を設定しておく。また、含有文は空にリセットしておく。
含有文が発見された状態においての、後続の文がキーワードを含んでいるかの調査で、キーワードを含んでいた。その時には、後文に、調査した含有文を連結する。そしてさらに後続の文にキーワードが含まれているかの調査へ。調査のためにはやはり、※の位置へ進ませる。そして下へと進む。
また、キーワードの含有文が空の状態で、後続の文が空となったら、出力すべき文がないので[]を出力して、調査の続行の必要もないのでこの処理は終了する。
キーワードの含有文が設定されていて、後続の文が空となったら、前文と含有文と後文を出力してこの処理を終了する。
概略、以上によって、キーワードの含有文とその前後の1文ずつから成る文字列、を要素とするリストが取得される。ただし、後文が含有文だった時には、未含有文に出くわすまで出力が増大するが。
文字列を要素としたリストを、その要素の文字列を連結してただ1つの文字列に変換する。
その上で、結果ファイルに出力する。
ここまでで、プログラムの全容を成す、論理・公式・定理・ストーリー、の完成。
このあと、この、論理・公式・定理・ストーリー、に合わせて、コンピュータープログラミング言語に、転化・転写、してゆく作業を進めれば、コンピュータープログラムとして完成する。
下記が、そのプログラムの完成例である。
import System.FilePath
import Data.List
import Data.Char
import System.IO
import System.Directory
import System.Environment
import Control.Exception
import Control.Monad
import Data.Time
main = do
[fnam, keyw] <- getArgs
day <- utctDay <$> getCurrentTime
daytime <- utctDayTime <$> getCurrentTime
let
outFile = outputfileName day daytime
contents <- readFile fnam
let
result = skimming contents [] [] [] keyw
output = concat result
writeFile outFile output
putStrLn $ "Output : " ++ outFile
bun_And_zanyobun :: String -> (String, String)
bun_And_zanyobun [] = ([], [])
bun_And_zanyobun zenbun =
let
(kuh, kut) = break (=='。') zenbun
kusz = length kuh
(lnh, lnt) = break (=='\n') zenbun
lnsz = length lnh
in
if kusz == (lnsz - 1)
then case lnt == [] of
True -> (lnh, [])
False -> ((lnh ++ "\n"), tail lnt)
else if kusz < lnsz
then ((kuh ++ "。"), tail kut)
else case lnt == [] of
True -> (lnh, [])
False -> ((lnh ++ "\n"), tail lnt)
skimming :: String -> String -> String -> String -> String -> [String]
skimming [] [] _ _ _ = []
skimming [] hitbun maebun atobun _ = [maebun ++ hitbun ++ atobun ++ "\n\n\n\n"]
skimming zenbun [] maebun atobun keyw =
let
(bun, zanyobun) = bun_And_zanyobun zenbun
in
case (isInfixOf keyw bun) of
False -> skimming zanyobun [] bun [] keyw
True -> skimming zanyobun bun maebun "" keyw
skimming zenbun hitbun maebun atobun keyw =
let
(bun, zanyobun) = bun_And_zanyobun zenbun
postatobun = atobun ++ bun
in
case (isInfixOf keyw bun) of
False -> (maebun ++ hitbun ++ postatobun ++ "\n\n\n\n") : skimming zanyobun [] bun [] keyw
True -> skimming zanyobun hitbun maebun postatobun keyw
outputfileName :: Day -> DiffTime -> FilePath
outputfileName day daytime =
let
date = show day
datetime = show daytime
in
"skimming" ++ date ++ datetime ++ ".TXT"
なお、プログラムコードを以下に一通り説明しておく。
[fnam, keyw] <- getArgs、は、プログラムの第1パラメーターの文字列をfnamに、第2パラメーターの文字列をkeywに受け取る。
したがって、プログラムの第1引数には、対象ファイル名を、第2引数には、キーワードを、タイプ入力する必要がある。
day <- utctDay <$> getCurrentTime、は、Day型の年月日データーを取得する。
daytime <- utctDayTime <$> getCurrentTime、は、DiffTime型のその日の経過秒数のデーターを取得する。
outFile = outputfileName day daytime、上記の2つのデーターをパラメーターにしてoutputfileName関数を呼び出す。
outputfileName関数では、パラメーターでわたされたデーターをそれぞれshow関数で文字列に変換。
skimmingという文字列のあとに、それらの文字列を連結。さらに、.TXT文字列を連結して、日時情報に基づく文字列を盛り込んだ結果ファイル名を作成している。
それが、左辺のoutFileに格納される。
contents <- readFile fnam、は、対象ファイル名のファイルを開いて、その内容を文字列として、contentsに取得する。
result = skimming contents [] [] [] keywは、処理対象文字列であるファイルの内容を第1パラメーターに設定し、第2バラメーターに含有文は空で、第3パラメーターの前文も空で、第4パラメーターの後文も空で、そして、第5パラメーターにキーワードを設定して、skimming関数を呼び出している。
skimming関数によって、含有文とその前後の1文ずつが改行文字4個をセパレーターにして、ことごとく抽出される。
その抽出結果は、resultに格納される。
skimming関数の詳細については後述する。
output = concat resultは、先の抽出結果のresultが、前文からセパレーターまでの文字列を要素とするリストであったものを、それぞれの要素の文字列を順に連結してただ1個の文字列に変換している。
その、ただ1個の文字列に結果が変換されたものが、outputに格納される。
writeFile outFile outputは、上記の結果の文字列を、結果ファイルに書き出している。
putStrLn $ "Output : " ++ outFileは、出力した結果ファイルの名前を、画面に表示している。
以上がメイン関数であり、これによって、処理が完了する。
以下に、メイン関数で使用されている関数の説明をする。
bun_And_zanyobun関数は、処理対象文字列から、その先頭の1文とその後続の文字列を返す。
(kuh, kut) = break (=='。') zenbun、は、句点でなかった間の文字の連なりがkuhへ。初めに句点が検出されてからの文字列がkutへ。
kusz = length kuh、は、句点直前までの文字列の長さをkuszに格納している。
(lnh, lnt) = break (=='\n') zenbun、は、改行文字でなかった間の文字の連なりがlnhへ。初めに改行文字が検出されてからの文字列がlntへ。
lnsz = length lnh、は、改行文字直前までの文字列の長さをlnszに格納している。
if kusz == (lnsz - 1)
then case lnt == [] of
True -> (lnh, [])
False -> ((lnh ++ "\n"), tail lnt)
は、句点で処理対象文字列が終わっていた時には、句点までの文字列を先頭の1文とし、残余の文字列には[]を返している。また、句点の直後が改行文字だった時には、改行文字までの文字列を先頭の1文とし、残余の文字列には、その後続の文字列を返している。
else if kusz < lnsz
then ((kuh ++ "。"), tail kut)
else case lnt == [] of
True -> (lnh, [])
False -> ((lnh ++ "\n"), tail lnt)
は、句点が改行文字の2個以上手前か、句点のあとに文字が1文字以上あった時、句点までの文字列を先頭の1文とし、残余の文字列にはその後続の文字列を返している。
また、句点でも改行文字でもないまま処理対象文字列が終わっていた時は、それすべてを先頭の1文とし、残余の文字列には[]を返している。
また、句点より前に改行文字が検出された時は、改行文字までの文字列を先頭の1文とし、残余の文字列にはその後続の文字列を返している。
以上によって、bun_And_zanyobun関数は、パラメーターでわたされた処理対象文字列、の先頭の1文とその残余の文字列を返す。
skimming関数は、含有文とその前後の1文ずつを改行文字4個をセパレーターにして、ことごとく抽出する。
skimming [] [] _ _ _ = []
skimming関数は、第1パラメーターの処理対象文字列が空で、第2パラメーターの含有文が未検出で、呼び出された時には、[]を返す。
skimming [] hitbun maebun atobun _ = [maebun ++ hitbun ++ atobun ++ "\n\n\n\n"]
skimming関数は、第1パラメーターの処理対象文字列が空で、第2パラメーターの含有文が検出済みで、呼び出された時には、最後の抽出データーの文字列に改行文字4個を付加したものをリストに入れて返す。
skimming zenbun [] maebun atobun keyw =
let
(bun, zanyobun) = bun_And_zanyobun zenbun
in
case (isInfixOf keyw bun) of
False ->
skimming zanyobun [] bun [] keyw
True -> skimming zanyobun bun maebun "" keyw
skimming関数が、第1パラメーターに処理対象文字列が設定されて、第2パラメーターの含有文が未検出で、呼び出された時には、まず、bun_And_zanyobun zenbunにて、bunにzenbunの先頭の1文、そしてzanyobunに残余の文字列を取得する。
次に、その1文がキーワードを含有していないなら、その1文を第3パラメーターの前文に設定し、第1パラメーターには残余文字列を設定するなどして、skimming関数を再度呼び出す。
また、その1文がキーワードを含有していたなら、その1文を第2パラメーターの含有文に設定し、第1パラメーターには残余文字列を設定するなどして、skimming関数を再度呼び出す。
skimming zenbun hitbun maebun atobun keyw =
let
(bun, zanyobun) = bun_And_zanyobun zenbun
postatobun = atobun ++ bun
in
case (isInfixOf keyw bun) of
False ->
(maebun ++ hitbun ++ postatobun ++ "\n\n\n\n") : skimming zanyobun [] bun [] keyw
True -> skimming zanyobun hitbun maebun postatobun keyw
skimming関数が、第1パラメーターに処理対象文字列が設定されて、第2パラメーターに含有文が設定されて、呼び出された時には、やはりまず、bun_And_zanyobun zenbunにて、bunにzenbunの先頭の1文、そしてzanyobunに残余の文字列を取得する。
次に、第4パラメーターの後文に取得した1文を連結してpostatobunに格納する。
それから、1文がキーワードを含有していなかったなら、キーワードを含まない後文の確定なので、それによって抽出成分がすべて揃ったので、maebunからpostatobunまでを連結し、改行文字4個を付加して出力し、そして、1文を第3パラメーターの前文に、次回の処理のために設定し、第1パラメーターには残余文字列を設定し、第2パラメーターの含有文と第4パラメーターの後文は空に設定するなどして、skimming関数を再度呼び出す。
また、1文がキーワードを含有していたなら、キーワードを含まない後文が確定しないので、何も出力はせず、第4パラメーターの後文をpostatobunに設定し、第1パラメーターの処理対象文字家列には残余文字列を設定し、それ以外のパラメーターの設定は変更しないで、skimming関数を再度呼び出す。
以上によって、skimming関数は、パラメーターでわたされた処理対象文字列、から、含有文とその前後のキーワードを含有しない1文と改行文字4個からなる文字列を要素が通常、複数個から成るリストを返す。
outputfileName関数については説明省略。
各関数を、メイン関数の中に記述したように使用することで、対象ファイルから、キーワードの含有文とその前後のキーワードを含有しない1文とから成る文字列、と改行文字4個とから成る文字列が、順次、検出されただけ連なったものが、結果ファイルに出力される。
そういプログラムが完成する。
このプログラムの核心部分であるskimming関数の構成は、前文、含有文、後文、が出揃うまでそれぞれを各パラメーターに設定して持ちまわる。
そして、出揃ったところで、結果リストの要素として出力する。
そしてさらに、後続の処理の遂行のために、再度、残余の文字列を第1パラメーターに設定して、skimming関数を呼び出す。
処理すべき文字列が空になったら、リストを返すだけにして、関数の再度の呼び出しはせずに終了へ。
そういう構成である。
以上でプログラムの説明を終わる。