人工知能って要は確率とか統計学じゃん。


スポンサーリンク

自然言語処理とか統計学の勉強初めて思ったことがある。世の中で一般的に「人工知能」とか言われているものはただの数学」の産物であるということ。

 

自然言語処理という言葉を知らない人のために軽く言葉について説明する。google検索とかsiri、アマゾンアレクサみたいな「音声認識」「文字検索」といったこれらの技術に使用されているものだ。これらには全て「自然言語処理」が使われている。

  >>自然言語処理の基本と技術 (仕組みが見えるゼロからわかる)
     

 

      >>言語処理のための機械学習入門 (自然言語処理シリーズ)
       

 

人間が生み出した言語とはプログラミング言語とかがあるが、それらではなく我々が普段話している言語のことを「自然言語」という。

それを数学(主に確率、統計学)の知識を使って統計処理しコンピュータに理解させるために「色々」することを「自然言語処理」という。

 

ここでいう「色々」というのは自分でも全てを述べることはできないが、例えばネット上にある大量の文章をコンピューターに読みこませることで、「この語とこの語のあとはだいたいこのパターンが~%だな」とか「この単語が多い文章はこのカテゴリーに属するな」とかそう言ったことを学習させる。そのために、文章を単語に分解させることから始まり、どの単語が何回出現するかとか、そういったことをプログラミングで処理させるのが一例だろう。

 


スポンサーリンク

 

もちろん大量の文章を学習させれば、そのうち前後の単語から品詞の推測や、適切な単語の意味を予測すると言ったこともできるわけである。最近ではgoogle翻訳などにももちろん、このような確率論の基礎的な知識が使われているわけである。

 

長くなったが上で述べてきたようなことが、自然言語処理とか統計学を自学してわかったのである。

 

人工知能というより、その正体を知っている人からしたらただの「数学」である。

やっていることは

  1. 文章ファイルをコンピュータに読み込ませる
  2. 数学的に処理できるように文章を色々分解したりする(自然言語処理)
  3. 数学的に記憶させ(データを蓄積させ)、新しいデータを与える
  4. 新しいデータが与えられた時に、何かしらの出力を返すようにソフトウェアを作る

最後のプロセスは文章のカテゴリー判別が目的ならカテゴリーを表示するようにするし、正答率などの数値的な指標を知ることが目的なら、それを表示するようにする可能性もある。

一般的な検索エンジンでは、単語が検索バーに入力された時に、「その単語を含む記事かつ、webページの評価が高いものを出力する」ようにアプリケーションが設計されているわけだ。

webページの評価指標には色々あるが、一番有名なのはgoogleの創始者のラリーペイジが開発した「ページランク」が有名だろう。

 

googleの創始者の一人「ラリーペイジ」

 

「ページランク」はより多くの人にアクセスされたり、別の記事内で引用されたりすると評価が高くなるものである。webページとラリーペイジがうまくかかっている笑

 

以上のことからも理解できると思うが、ただの数学だ。

 

しかしその挙動が、「我々の日常的なスピードよりも速く、大量の計算を実行し、オートに何かしらの出力を返す」からあたかも生きているように見えるのだ。

 

しかもオートに出力するように設計しているのは我々人間である。

 

それが人工知能の正体だ。

 

この名前に違和感があるので、別の名前にしてほしいと思う今日この頃笑

 

 

 

記事が役に立ったらシェア!

CodingBatで自然言語処理の勉強~その1~

codingBatのつまづいた所のメモです。

Warmup-1 

  • missing_char

Given a non-empty string and an int n, return a new string where the char at index n has been removed. The value of n will be a valid index of a char in the original string (i.e. n will be in the range 0..len(str)-1 inclusive).

ex)

missing_char(‘kitten’, 1) → ‘ktten’
missing_char(‘kitten’, 0) → ‘itten’
missing_char(‘kitten’, 4) → ‘kittn’

要するに、「二つ目の引数で与えられた数字番目の文字を抜かせ」ということだ。

sliceを使って、抜かした文字列の前と後ろで分けて、足してやれば良い

実行するとこんな感じ。

 

  • front_back

Given a string, return a new string where the first and last chars have been exchanged.

ex)
front_back(‘code’) → ‘eodc’
front_back(‘a’) → ‘a’
front_back(‘ab’) → ‘ba’

要するに、与えた文字列の最初と最後を入れ替えろということ

 

答えの文字列を「最後の文字」+「最後と最初以外の真ん中の文字列」+ 「最初の文字」と分割して考えているところがみそ。

実行するとこんな感じ。

 

  • front3

Given a string, we’ll say that the front is the first 3 chars of the string. If the string length is less than 3, the front is whatever is there. Return a new string which is 3 copies of the front.

ex)
front3(‘Java’) → ‘JavJavJav’
front3(‘Chocolate’) → ‘ChoChoCho’
front3(‘abc’) → ‘abcabcabc’

要は、与えられた文字列の前文字を三回繰り返すものを作成しろということ。

特に難しくない.

実行結果はこんな感じ。

 

Warmup-2

 

  • string_splosion

Given a non-empty string like “Code” return a string like “CCoCodCode”.

ex)
string_splosion(‘Code’) → ‘CCoCodCode’
string_splosion(‘abc’) → ‘aababc’
string_splosion(‘ab’) → ‘aab’

要は、与えられた文字列の「前1文字抜き出す+前2文字抜き出し+前3文字抜き出し…+最終文字まで抜き出す」 というのを繰り返した文字列を生成しろということ。

for文で最終文字(lenで長さを取得する)番目まで抜き出すのを繰り返し、それまでのを足していくだけ。

実行結果はこんな感じ。

 

  • last2
Given a string, return the count of the number of times that a substring length 2 appears in the string and also as the last 2 chars of the string, so “hixxxhi” yields 1 (we won’t count the end substring).

last2(‘hixxhi’) → 1
last2(‘xaxxaxaxx’) → 1
last2(‘axxxaaxx’) → 2

要は、最後2文字と同じものが「最後2文字をのぞいたところで、見つかればそれをカウントする」

以下の例であれば、「SS」は「1文字目+2文字目」「2文字目+3文字目」「3文字目+4文字目」と合計三回見つかるので、3が出力されれば正解である。

 

2文字のngramなので、与えられた文字列を2文字ごとに最終文字である「SS」とあっているか確認すれば良い。

実行結果がいかになれば良い。

 


Coding Bat PythonのWarmup1の途中からWarmup2の途中までやりました。

また勉強したら更新しようと思います。



スポンサードリンク

 

記事が役に立ったらシェア!

言語処理100本ノック(第3章前半)



スポンサードリンク

第2章後半の続きです。どうやらここからが本番のようです。正規表現という初めて触れるので他の方のサイトを参考にしながらゆっくりやっていきたいです。

参考にさせていただいたサイトはこちら

 

Wikipediaの記事を以下のフォーマットで書き出したファイルjawiki-country.json.gzがある.

  • 1行に1記事の情報がJSON形式で格納される
  • 各行には記事名が”title”キーに,記事本文が”text”キーの辞書オブジェクトに格納され,そのオブジェクトがJSON形式で書き出される
  • ファイル全体はgzipで圧縮される

以下の処理を行うプログラムを作成せよ.


20. JSONデータの読み込み

Wikipedia記事のJSONファイルを読み込み,「イギリス」に関する記事本文を表示せよ.問題21-29では,ここで抽出した記事本文に対して実行せよ.

ファイルを読み込み、一行ずつ処理するところはこれまでもやってきたので問題ないと思います。

ファイルがjson形式なので、json.loads()関数を用いてjson形式に変換しています。

問題はarticle_dict[“title”]==[“イギリス”]の部分です。

どうやらこれは記事内で利用されている、htmlタグを指定するときに利用するらしい。htmlファイルには

実際に

みたいな感じでいろいろなタグが使われている。

今回は要するにファイル内の

となっている部分について読むということであろう。

実行結果:

とこんな感じになっていればおっけー。

 

21. カテゴリ名を含む行を抽出

『記事中でカテゴリ名を宣言している行を抽出せよ.』

 

特に難しい処理はしていないが、自分的には11行目の”Category” in line:のところが気になった。

lineはlinesの時点で文字列として扱われているので”Category”としていきなりif文の中で宣言して構わないみたいだ。

if の条件文で””を使うことがなかったので、慣れないが自然言語処理なら普通のことなのだろう。

実行結果:

for文を使っているためlineがリスト型になってしまうのは否めない。

 



スポンサードリンク

22. カテゴリ名の抽出

『記事のカテゴリ名を(行単位ではなく名前で)抽出せよ.』

module化しなくてもいけるが、インデントが多くなるのでモジュール化しました。

正規表現を扱うためにreモジュールをインポートします。正規表現とは文字列の並びやパターンを特定するもの。

どんな使い方するのだろうかとかは、こちらの方のサイトを見ていただけるとわかると思います。

ちょっとこれは新しい情報が多すぎて混乱しそうです。そもそもなんでこんなめんどいことしなきゃいけないのか?など聞きたいことは山ほどあります。

compileというコマンドで正規表現パターンを定義してやるぞって意味。

findall()は上で指定した正規表現パターンを()内の引数から抽出するための関数。

正直なところ^とか. とか意味がわからない。おそらく今回のデータが文章構造になっていて一行ごとに読み込み、処理をするようになっているので行頭を指定してやる必要があるのだと思う。

.*で任意の文字0回以上と指定しています。どんな文字でも何回でもおっけーよってことだと思うが、それ指定する必要ねーじゃんって思ってしまう。

独学の限界を少々感じるが、理解できたらおいおい更新していきます。

 

23. セクション構造

『記事中に含まれるセクション名とそのレベル(例えば”== セクション名 ==”なら1)を表示せよ.』

セクションとは記事の見出しです。第1章とか通常の文章部分よりもでかい文字で書いたりする部分のことです。なのでセクション構造とはその文章の章構成とか目次みたいなもんです。

レベルというのはその章とか目次がどの階層にいるかというのを表したものです。一番上の階層が「1」ということです。

正規表現部分は慣れませんが、実際に自分でやった方が早いのでしょう。一発でなんか絶対うまく行かないと思いますが笑

の部分はセクション名が==セクション名==という形式で書かれているため、2個以上という意味で2が入ります。もう一個階層が下がると=== サブセクション名===という感じでしょうか。

これがないと、例えば

==セクション構造== ===サブセクション=== ====サブサブセクション====みたいな階層構造の場合、最後まで一気に読み込んでしまうということだろうか。?は直前の正規表現で指定したパターンの最小回数(1回)でのマッチングを意味するものなので、次に==が出てきた瞬間とこまでしかマッチングしない。

こちらのサイトを参考にすると理解できそうです。

後方参照というものらしく、終わりと開始が同じパターンならそれを利用して\numberで開始を指定してマッチングさせることができるものらしい。

== セクション名 ==みたいな感じで空白があるものがデータに含まれていたため以下のような空白除去が必要らしい

実行結果:

こんな感じ。

 

24. ファイル参照の抽出

『記事から参照されているメディアファイルをすべて抜き出せ.』

メディアファイルが何を意味しているのかわからなかったのですが、jpgとかsvgファイルのことらしいです。そしてそれらのファイルの前にファイルとかfileとか書かれているのでそれを指定する正規表現が上の一行です。

verboseは正規表現を便利に書きやすくするための関数です。公式ドキュメントにも

「パターンの論理的なセクションを視覚的に区切り、コメントも入れることができます。」と書かれています。

今回はこれまでのができていれば簡単にできる問題です。

実行結果:

とこんな感じです。

次は第3章後半です。


スポンサードリンク

 

 

記事が役に立ったらシェア!

Graham Neubigの自然言語処理チュートリアル(第一回)



スポンサードリンク

自然言語処理100本ノックがだんだんと難しくなり、やる気が失せてきたので復習がてらグラムニュービッグさんのチュートリアルに手を出してみることにしました。

全部で14問あるみたいで、今日はその第一問目です。

「ファイルの中身の文章中に現れる単語の出現頻度をカウントせよ」

ファイル形式(text.txt)は

です。

解法

  1. ファイルを一行ずつ読み込み、split()で単語にわける
  2. Counter()関数でカウント
  3. counter.most_common()で辞書型にプリント

って感じでしょうか。

とりあえず作ってみた(間違っている)

実行すると

なぜかthisが別々にカウントされている。他にも色々おかしい。

本当は上のようになるはず。


スポンサードリンク

原因

これだと、同じ単語が来てもそれを同じと判断することができずに別々にカウントしてしまう。

同じ行内ならば同じ単語は追加のものとして加算してくれるみたいだが、行が違うと同じ単語でもダメみたいです。

だから、2行目に読み込んだpenは2回にカウントされている。

正解

実行結果

counter.most_common()はご丁寧に回数の多い順に出力してくれるみたいです。

やはりCounter()関数はかなり使いどころが多いのと、extendの使い方についても知ることができました。appendにして何回も詰まりました笑。

そんなに難しくない問題なのにこの程度で詰まるなんて、まだまだですね。精進します。

以上Graham Neubigさんのチュートリアル第一回目を終わりにします。



スポンサードリンク

 

 

記事が役に立ったらシェア!

言語処理100本ノック(第二章後半)



スポンサードリンク

第2章前半の続きです。

第2章UNIXコマンドの基礎

15. 末尾のN行を出力

自然数Nをコマンドライン引数などの手段で受け取り,入力のうち末尾のN行だけを表示せよ.確認にはtailコマンドを用いよ

 

ここまでの知識でできる問題です。特に難しくないです。コマンドライン引数で指定した、数字をhogeとして受け取りそれを使うだけです。

実行結果(コマンドライン引数に6を入力した場合):

 

UNIXコマンドでの確認:

数字の前に- をつけましょう。

 

16. ファイルをN分割する

『自然数Nをコマンドライン引数などの手段で受け取り,入力のファイルを行単位でN分割せよ.同様の処理をsplitコマンドで実現せよ.』

コマンドライン引数を用いない場合:

input関数は、コマンドラインで入力したデータを文字列として扱うものです。そして入力した文字列をしようし、プログラム内で用いることができます。

math.ceil()は切り上げです。4/3でしたら、1.3333 となり四捨五入なら1となりますが、切り上げなので2になります。

コマンドライン引数を用いる場合:

ファイル分割数を2番目のコマンドライン引数で入力した場合のやり方です。

分割の入力方法が異なるので、unitの指定の仕方が少し異なるだけです。これまでの知識のみで書けます。

実行結果(分割数が4の場合):

上を実行すると、child_0*のファイルが作成されます。ここでは4分割されたファイルのうち一つのファイルの中身を示します。

unitで計算している通り、行数が (hightemp.txtの行数/分割数)になっていれば良いはずです。

24/4=6なので成功です。

UNIXコマンドでの確認:

out.*でファイルが作成されます。

注意しなければならないのは、ここでの4は分割数ではなくsplitの数(何行ごとに分割するかの数)なので、24/4=6となり、ファイルが6つ作成されるはずです。

17. 1列目の文字列の異なり

『1列目の文字列の種類(異なる文字列の集合)を求めよ.確認にはsort, uniqコマンドを用いよ.』

最初まず問題の意味を理解するのに苦労しました笑。要するに24つのデータのうち、何県のデータかということです。県がダブっているデータもあるので、そういうのをダブりでカウントしないようにするにはどうすれば良いかということです。

set()コマンドで一発。そうすることで、list型のデータが集合型 に置き替わります。

データを集合として扱う場合,このsetコマンドはかなり重宝されます。

実行結果:

相変わらず和歌山県のところだけおかしいですが、hightemp.txtの問題なので、無視します笑

UNIXコマンドでの確認:

uniqは連続して重複している行を一つにまとまるコマンドで、sortは辞書順に並び替えてくれるものです。

離れたデータの重複を一つにまとめる時は両方を組み合わせます。二つのコマンドを組み合すことで、かなり便利なものになりますね。



スポンサードリンク

18. 各行を3コラム目の数値の降順にソート

各行を3コラム目の数値の逆順で整列せよ(注意: 各行の内容は変更せずに並び替えよ).確認にはsortコマンドを用いよ(この問題はコマンドで実行した時の結果と合わなくてもよい)

温度の高い順にデータを並び替えろということです。

無名関数(lambda)を使っています。

無名関数は「その場限りの関数」で自在に使えればかなり柔軟なプログラムがかけます。

オーダーメイドのスーツを作っても、自分以外の人にとっては無意味なイメージです。ただし、自分にとってはちょーぜつ大事ですよね。

sorted()でデータを並び替えますが、その並び替え方をlambdaを使って指定しています。

数学チックに説明すると、xは変数です。このxにいろんな値が入ります。今なら各行のデータです。1行目も、2行目も、3行目もこの.split()[2]を使います、という意味です。

.split()[2]はこれまでの知識で理解できますね。分割したデータ集合のうち3番目のデータ(list型は0から始まります。)、すなわち温度のデータに注目してデータを sort(並び替えましょう)という意味です。

最後に「数値の逆順」と言っているので、reverse=Trueと書きます。

実行結果:

温度の高い順になっているのがわかります。

 

UNIXコマンドでの確認:

pythonプログラムと実行結果が異なると思います。

19. 各行の1コラム目の文字列の出現頻度を求め,出現頻度の高い順に並べる

『各行の1列目の文字列の出現頻度を求め,その高い順に並べて表示せよ.確認にはcut, uniq, sortコマンドを用いよ.』

listデータの出現回数を求めるのはcollectionsライブラリのCounter()コマンドで数えることが可能です。

単語と単語の出現回数を表示させるにはcounterに格納されているデータを用いるのですが、その際に.most_common()という引数を用います。決まり文句として覚えて構わないでしょう。

出力するのは単語(県名)とその出現数なので、for文の変数を二つ指定します。

実行結果:

 

UNIXコマンドでの確認:

uniq -c で重複行をカウントしてくれるみたいです。

| sort -r なしで実行すると、カウントはしてくれますが、出現回数の多い順に並び替えされないので、いります。

最初のsortはあくまでuniqで重複行をカウントするためのものです。(uniqは縦に連続したデータの重複を数えるから。県名が同じでも離れたデータであれば、別に別にカウントしてしまいます。)

 

以上で2章は終了です。続きはこちら→3章前半!



スポンサードリンク

記事が役に立ったらシェア!

言語処理100本ノック(第2章前半)



スポンサードリンク

第1章の続きです。

第2章UNIXコマンドの基礎

hightemp.txtは,日本の最高気温の記録を「都道府県」「地点」「℃」「日」のタブ区切り形式で格納したファイルである.以下の処理を行うプログラムを作成し,hightemp.txtを入力ファイルとして実行せよ.さらに,同様の処理をUNIXコマンドでも実行し,プログラムの実行結果を確認せよ.』

hightemp.txt の中身は以下です。

10. 行数のカウント

『行数をカウントせよ.確認にはwcコマンドを用いよ.』

プログラムを実行するときに引数を渡すことができます。これをコマンドライン引数と言います。

sys.argv[]でコマンドライン引数を取得できます。ついでに引数が0は実行ファイル名が入ることに注意。

実行結果:

UNIXコマンドでの確認:

単純に行数を数えるだけならば、「wc -l ファイル名」 の方が早いらしい。

 

11. タブをスペースに置換

『タブ1文字につきスペース1文字に置換せよ.確認にはsedコマンド,trコマンド,もしくはexpandコマンドを用いよ』

replaceというコマンドを用いるだけ。便利ですね!

実行結果:

UNIXコマンドでの確認:

 

12. 1列目をcol1.txtに,2列目をcol2.txtに保存

『各行の1列目だけを抜き出したものをcol1.txtに,2列目だけを抜き出したものをcol2.txtとしてファイルに保存せよ.確認にはcutコマンドを用いよ.』

特に難しいことはしてないです。ファイルをopenし1行ずつ読み込み、0番目(左から1列目)の要素と1番目(左から2列目)の要素だけファイルに書き込むように書いています。zip関数とか使ったらもう少し簡潔にかけそうです。

実行結果:

col1.txt

col2.txt

 いくつかおかしな箇所がありますが、おそらくhightemp.txtの形式に問題があり、プログラムの問題ではないでしょう。

UNIXコマンドでの確認:

 



スポンサードリンク

13. col1.txtとcol2.txtをマージ

『12で作ったcol1.txtとcol2.txtを結合し,元のファイルの1列目と2列目をタブ区切りで並べたテキストファイルを作成せよ.確認にはpasteコマンドを用いよ.』

これはだいぶ手こずりました笑。まずopenにこんな使い方があるのを知らなかったのと、readline()もこんな風に使えるなんて知りませんでした。

あとはちょくちょく出てくるzip関数ですね笑とりあえず、二つ配列やらリスト型のデータがあって、二つに同様のfor文処理をさせる時は『zip』って覚えますかね。

実行結果:

UNIXコマンドでの確認:

 

14. 先頭からN行を出力

『自然数Nをコマンドライン引数などの手段で受け取り,入力のうち先頭のN行だけを表示せよ.確認にはheadコマンドを用いよ』

コマンドライン引数と言っているので、sys.argv[]を使います。

問題はコマンドライン引数で取得した数値(文字列)をどうやって数値(数字)として読み込むかですね。8行目のようなint(”数値”)でいけます。

実行結果:第二引数にN = 5を入力した場合

UNIXコマンドでの確認:

以上で2章の前半は終了です。続きはこちら→2章後半!



スポンサードリンク

記事が役に立ったらシェア!

言語処理100本ノック(第1章)



スポンサードリンク

最近、自然言語処理の勉強を始めたので、東北大学のある教授?が作成した100本ノックをやってみることにしました。

00. 文字列の逆順

「文字列”stressed”の文字を逆に(末尾から先頭に向かって)並べた文字列を得よ.」

特に難しいことはないです。strの引数を[::-1]とすることに注意。

実行結果:

 

01. 「パタトクカシーー」

『「パタトクカシーー」という文字列の1,3,5,7文字目を取り出して連結した文字列を得よ.』

配列の要素番号は0から始まることに注意です。strの最後の「2」は2つおきに(奇数なので)、[0,2,4,…]ということです。

実行結果:

 

02. 「パトカー」+「タクシー」=「パタトクカシーー」

『「パトカー」+「タクシー」の文字を先頭から交互に連結して文字列「パタトクカシーー」を得よ.』

自分はzip関数というものを知らなかったので、だいぶ手こずりました笑。どうやら二つのリストの要素ごとに、同時にfor文で回せるようです。

これを知らなかったので、自分は二つのfor文を書き無駄にてこづっていました。

実行結果:

 

03. 円周率

『”Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics.”という文を単語に分解し,各単語の(アルファベットの)文字数を先頭から出現順に並べたリストを作成せよ.』

スペースキーでsplitしたいときは、split(” “)ですね。ついでにタブでsplitしたいときは、split(“\t”)です。

実行結果:

04. 元素記号

『”Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can.”という文を単語に分解し,1, 5, 6, 7, 8, 9, 15, 16, 19番目の単語は先頭の1文字,それ以外の単語は先頭に2文字を取り出し,取り出した文字列から単語の位置(先頭から何番目の単語か)への連想配列(辞書型もしくはマップ型)を作成せよ.』

連想配列を作成する方法はいくつかありますが、今回は辞書型と言われているので、ループする際にインデックスつきで要素を得られるenumurate(ループする際にインデックスつきで要素を得ることができる)を用いれば良いです。

for 文の引数を指定するときに、単語のnumberと単語自身のnum,word と二つ指定しなければいけないことに注意。このforの後に二つの引数を使うタイプに慣れていないです笑

実行結果:

 



スポンサードリンク

05. n-gram

『与えられたシーケンス(文字列やリストなど)からn-gramを作る関数を作成せよ.この関数を用い,”I am an NLPer”という文から単語bi-gram,文字bi-gramを得よ.』

バイグラム以外のngramを一瞬で解析できます。ngram()の引数を変えるだけですね。

ついでにこの場合の文字バイグラムは空白(スペース)も一文字としてカウントしています。実行結果を見てもらえればわかると思います。

実行結果:

 

06. 集合

『”paraparaparadise”と”paragraph”に含まれる文字bi-gramの集合を,それぞれ, XとYとして求め,XとYの和集合,積集合,差集合を求めよ.さらに,’se’というbi-gramがXおよびYに含まれるかどうかを調べよ.』

ngramの関数は前の問題で作成したものを用いています。

setコマンドは重複を許さない配列の要素を作成します。

さらに二つの配列の中身を比較する際、リスト型からセット型に変換すると、&,-,等の記号だけで集合演算ができます。知らなかった!笑

実行結果:

 



スポンサードリンク

07. テンプレートによる文生成

『引数x, y, zを受け取り「x時のyはz」という文字列を返す関数を実装せよ.さらに,x=12, y=”気温”, z=22.4として,実行結果を確認せよ』

format関数を用いることで、変数の文字列の埋め込みが可能になります。format関数を用いずにやろうとすると、”気温”が数字ではなく文字列なのでエラーになります。

実行結果:

 

08. 暗号文

『与えられた文字列の各文字を,以下の仕様で変換する関数cipherを実装せよ.

  • 英小文字ならば(219 – 文字コード)の文字に置換
  • その他の文字はそのまま出力

この関数を用い,英語のメッセージを暗号化・復号化せよ.』

最初は、暗号文?なんだそれって感じでしたので、時間がかかりました。

chr()コマンドで暗号文に変換します。ord(c)は暗号化前の文字列です。ifで英小文字の範囲内ならjoin(chr(219-ord(c)、else ならそのまま”c”ということです。

さらにifとfor  を内包表記で書いています。この方がコードが複雑になってきたときの可読性が上がるので、この書き方にも慣れないといけませんね!

実行結果:

 

09. Typoglycemia

『スペースで区切られた単語列に対して,各単語の先頭と末尾の文字は残し,それ以外の文字の順序をランダムに並び替えるプログラムを作成せよ.ただし,長さが4以下の単語は並び替えないこととする.適当な英語の文(例えば”I couldn’t believe that I could actually understand what I was reading : the phenomenal power of the human mind .”)を与え,その実行結果を確認せよ.』

いくつかコマンドについて説明します。

  • itertools.permutations():iterable の要素からなる順列 (permutation) を連続的に返す。
  • random.randint(a,b):a <= N <= b であるようなランダムな整数 N を返す。

難しいところは、単語を連想配列にして番号と記憶させるのと、文字の並び替えの組み合わせを順列で計算し、各組を乱数で番号付しているところでしょうか。

ここでも連想配列が登場しましたね。

実行結果:

以上で第1章は終わりです。続きはこちら>>>第二章前半。



スポンサードリンク

記事が役に立ったらシェア!