Python100本ノック(〜62本目)
「自作Python100本ノック7日目(31本目〜40本目)」
「自作Python100本ノック8日目(41本目〜52本目)」
「自作Python100本ノック9日目(53本目〜62本目)」
Q31 :集合内包表記を使って、range(10)の奇数の集合を作れ
odd = {number for number in range(10) if number % 2 != 0}
odd
Q32 :rage(10)の数値に対しては、”Got”と数値を返すジェネレータ関数を作れ。
条件:・ ジェネレータ内包表記を使うこと ・ for文を使って反復処理すること 出力例:Got 0, Got 1, Got 2 ・・・・・
for thing in ("Got %s" % number for number in range(10)):
print(thing)
Q33 :range(10)から奇数を返すジェネレータ関数を定義し、for文を使って、返された3番目の値を見つけて表示せよ。
def get_odds():
for number in range(1, 10, 2):
yield number
for count, number in enumerate(get_odds(), 1):
if count == 3:
print(number)
break
Q34 :デコレータの定義
問題:関数が呼び出された時に”start”、終了した時に”end”を表示するtestというデコレータを定義せよ
def test(func):
def new_func(*args, **kwargs):
print("start")
result = func(*args, **kwargs)
print("end")
return result
return new_func
@test
def greeting():
print("Hello")
greeting()
Q35 :例外のキャッチ
問題:以下のコードには例外が含まれる。例外に対するエラー処理を2つ追加せよ。
#問題のコード
short_list = [1,2,3]
while True:
value = input("Position [q to qui]? ")
if value == "q":
break
positon = int(value)
print(short_list[position])
#エラー処理を加えたもの
short_list = [1,2,3]
while True:
value = input("Position [q to qui]? ")
if value == "q":
breakt
try:
positon = int(value)
print(short_list[position])
except IndexError as err:
print("Bad index:", position)
except Exception as other:
print("something else broke:", other)
Q36 :zip()を使ってmoviesという辞書を作れ
条件: 辞書は、titles = [“Creature of Habit”, “Crewel Fate”]というリストと plots = [“A nun turns into a monster”, “A haunted yarn shop”]というリストを組み合わせて作るものとする。
titles = ["Creature of Habit", "Crewel Fate"]
plots = ["A nun turns into a monster", "A haunted yarn shop"]
movies = dict(zip(titles, plots))
movies
Q37 :クラスのオブジェクト辞書から直接初期化しよう
条件:以下のクラスと辞書を使用。
引数の特別な形式に注意ですね・ *args: 任意の固定引数が入ったタプル **kwargs: 任意のキーワード引数が入った辞書
#クラス
class Elements:
def __init__(self, name, symbol, number):
self.name = name
self.symbol = symbol
self.number = number
#辞書
el_dict = {"name": "Hydrogem", "symbol": "H", "number": 1 }
#解答
#辞書から初期化
hydrogem = Elements(**el_dict) # 辞書を引数に渡すときは「**」 をつける
hydrogem.name
Q38 :クラスを編集しprint(hydrogem)だけでオブジェクト属性の値が表示されるようにせよ
str()
のメソッドが使えているかの練習ですね。 以下str()
の使い方の説明です。
str()は、Pythonの特殊メソッドの1つ。 print関数は、オブジェクトに、str() メソッドがなければ、親であるObjectクラスのデフォルトメソッドを使う。 (その場合、”< main.Element object at Ox1006f5310 >” のような文字列を返す)
#問題のクラス
class Elements:
def __init__(self, name, symbol, number):
self.name = name
self.symbol = symbol
self.number = number
#解答
class Elements:
def __init__(self, name, symbol, number):
self.name = name
self.symbol = symbol
self.number = number
def __str__(self):
return ("name: %s, symbol: %s, number: %s" % (self.name, self.symbol, self.number))
el_dict = {"name": "Hydrogem", "symbol": "H", "number": 1 }
hydrogem = Elements(**el_dict)
print(hydrogem)
Q39 :クラスを編集し、name,symbol,number属性を非公開にし、そしてそれぞれいついて値を返すゲッターを定義せよ。
#問題
class Elements:
def __init__(self, name, symbol, number):
self.__name = name
self.__symbol = symbol
self.__number = number
#解答
class Elements:
def __init__(self, name, symbol, number):
self.__name = name
self.__symbol = symbol
self.__number = number
@property#属性を非公開にする
def name(self):
return self.__name
def symbol(self):
return self.__symbol
def number(self):
return self.__number
el_dict = {"name": "Hydrogem", "symbol": "H", "number": 1 }
hydrogem = Elements(**el_dict)
hydrogem.name
hydrogem.__name
Q40 :Bear, Rabbit, Octothorpeの3つのクラスを定義せよ。
条件: それぞれについて唯一のメソッド、eats()
を定義する。 eats()
は、”berries”(Bear)、”clover”(Rabbit)、”campers”(Octothorpe)を返すものとする。 それぞれのクラスからオブジェクトを作り、何を食べるのかを表示せよ。
簡単なクラスの定義ですね。
class Bear:
def eats(self):
return "berries"
class Rabbit:
def eats(self):
return "clover"
class Octothorpe:
def eats(self):
return "campers"
b = Bear()
r = Rabbit()
o = Octothorpe()
print(b.eats())
print(r.eats())
print(o.eats())
Q41: Laser、Claw、SmartPhoneクラスを定義せよ。
条件: 3つのクラスは唯一のメソッドとしてdoes()を持っている。 does()は、”disintegrate” (Laser)、 “crush”(Claw) “shoot” (gun)を返す。 次に、これらのインスタンス(オブジェクト)をひとつずつ持つRobotクラスを定義する。
#Laserクラス
class Laser:
def does(self):
return "disintegrate"
#Clawクラス
class Claw:
def does(self):
return "crush"
#Gunクラス
class Gun:
def does(self):
return "shoot"
#Robotクラス
class Robot:
def __init__(self):
self.laser = Laser()
self.claw = Claw()
self.gun = Gun()
def does(self):
return '''I have many attachments: My laser is to: %s, My claw is to: %s , My gun is to: %s ''' % (
self.laser.does(),
self.claw.does(),
self.gun.does() )
robbie = Robot()
print(robbie.does())
Q42: secretというUnicode文字列を作り、”\U0001f4a9”という値を代入して、表示せよ
また、secretのUnicode名を調べよう。
secret = "\U0001f4a4"
secret
#Unicode名の表示
import unicodedata
print(unicodedata.name(secret))
Q43: UTF-8を使い()、secretをpop_bytesというbytes変数にエンコードせよ。
pop_bytes = secret.encode("utf-8")
pop_bytes
Q44: UTF-8を使って、pop_bytesをデコードし、pop_stringを表示せよ。
pop_string = pop_bytes.decode("utf-8")
pop_string
正規表現の基本
次の文について各問に答えよ sentence = "Chicken Little"
Q45: ソースの先頭が、指定したパターンと一致しているか
import re
sentence = "Chicken Little"
#ソースの先頭が、指定したパターンと一致しているか
m = re.match("Chi", sentence)
if m:
print(m.group())
Q46: ソース内に、指定したパターンと一致しているか
#ソース内に、指定したパターンと一致しているか
m1 = re.match(".*ttle", sentence)# .*(ワイルドカード)を加えることによって先頭じゃない場合もヒットさせることができる、
if m1:
print(m1.group())
ms = re.search("ttle", sentence) # search()を使うとワイルドカード不要
if ms:
print(ms.group())
Q47: 文字列の中に”n”を含むの文字列が何個あるか
#”n”という文字だけヒット
m3 = re.findall("n", sentence)
m3
print(len(m3))
#"n"の後ろに任意の文字1字
#sentenceの最後の"n"がマッチしていないことに注目
m4 = re.findall("n.", sentence)
m4
# 最後の"n"もマッチさせたい場合
m5 = re.findall("n.?", sentence) # 0か1文字の直線の文字にマッチする(オプション)
m5
Q48: “n”を”s”に置きかえよ
m = re.sub("n", "s", sentence)
m
Q49: 正規表現の活用
以下の詩を元に各問に答えよ
poetry = "We have seen thee, queen of cheese,
Lying quietly at your ease,
Gently fanned by evening breeze,
Thy fair form no flies dare seize.
All gaily dressed soon you'll go
To the great Provincial show,
To be admired by many a beau
In the city of Toronto.
Cows numerous as a swarm of bees,
Or as the leaves upon the trees,
It did require to make thee please,
And stand unrivalled, queen of cheese.
May you not receive a scar as
We have heard that Mr. Harris
Intends to send you off as far as
The great world's show at Paris.
Of the youth beware of these,
For some of them might rudely squeeze
And bite your cheek, then songs or glees
We could not sing, oh! queen of cheese.
We'rt thou suspended from balloon,
You'd cast a shade even at noon,
Folks would think it was the moon
About to fall and crush them soon."
Q49:cから始まる全ての単語を表示
pat = r'\bc\w*'
re.findall(pat, poetry)
#\bで単語同と日非単語の境界を先頭にするという意味である。単語の先頭か末尾を指定するために使う。
#リテラルのcは探している単語の先頭文字.
#\wは任意の単語文字
#*は、前の単語の文字が0個以上という意味
#rは未処理の文字列。(これがないと\bをバックスペースだと認識してしまうので、サーチは失敗する)
Q50: cで始まる全ての4文字単語を表示
par = r'\bc\w{3}\b'
re.findall(par, poetry)
#\bをつけると「単語」のみ取り出せる。つけないとcで始まる全ての単語の4文字が返されてしまう。
Q51: rで終わる全ての単語を見つけよう。
pat_3 = r'\b\w*r\b'
re.findall(pat_3, poetry)
Q52: 3個の連続した母音を含む全ての単語を見つけよう
pat_4 = r'\b\w*[aiueo]{3}[^aiueo\s]\w*\b'
re.findall(pat_4, poetry)
Q53: 以下の16進文字列が有名なGIFファイルであるか確認せよ。
問題: 以下の16進文字列をbytes変数に変換し、その先頭が、”GIF89a”(有名なGIFファイル)という文字列になっているか確認せよ。
以前やった16進数ダンプのやり方と同じですね。
#16進文字列
hex_str = '47494638396101000100800000000000ffffff21f90401000000002c000000000100010000020144003b'
import binascii
gif = binascii.unhexlify(hex_str)
gif[:6] == b'GIF89a'
#Unicode文字列ではなく、バイト列を定義するためにbを使わなければならないことに注意
#バイト列をバイト列を比較することはできるが、バイト列と文字列を比較することはできない。
Q54:test.txtというファイルにtest1の内容を書き込みなさい
以前、ファイルの読み込みはやったので今回は書き込むバージョンです。 with
を使ったやり方も練習しておきましょう。
#text1
test1 = "This is a test of the emergency text system"
outfile = open("test.txt", "wt")
outfile.write(test1)
outfile.close()
#withを使うとclose呼び出しを避けることができる
with open("test.txt", "wt") as outfile:
outfile.write(test1)
Q55:test.txtをtest2変数に読み出し、test1とtest2が同じになっているか確認せよ
条件:with
を使うこと
ほとんど前にやった問題とかぶっていますがご了承ください。
with open("test.txt", "rt") as infile:
test2 = infile.read()
test2
Q56:次のテキストをbooks.csvというファイルに保存した後、その内容を変数booksに読み込み、booksの内容を表示しよう。
条件:csvモジュールとそのDictReaderメソッドを使うこと
csvファイルの読み込み方の練習です。
##テキスト
text = '''author, book
J R R Tolkien, The Hobbit
Lynne Truss, "Eats, Shoots & Leaves" '''
#保存
with open("books.csv", "wt") as outfile:
outfile.write(text)
#読み込み
import csv
with open("books.csv", "rt") as infile:
books = csv.DictReader(infile)
for book in books:
print(book)
Q57: テクストファイルの中から、行番号で指定した行を読みたい
import linecache
theline = linecache.getline("text.txt", 3)
theline
Q58: ファイルの行数を計算したい
count = len(open("text.txt", "rU").readlines())
count
Q59: many_books.dbというSQLiteデータベースを作り、その中にtitle(文字列)、”author”(文字列)、”year”(整数)というフィールドをもつbookというテーブルを作れ
条件:sqlite3モジュールを使うこと
SQLはGUIのアプリを使うことが多いと思うので実用性があるかわかりませんが一応。 (ちなみに私はPostgreSQLを使っていました。)
#データベースの作成
import sqlite3
db = sqlite3.connect("books.db")# connect():データベースへの接続を開設する(ユーザー名、パスワード、サーバーアドレス、その他引数が指定可能)
curs = db.cursor()#クエリーを管理するカーソルオブジェクトを作る
curs.execute('''create table book (title text, author text, year int)''')# データベースに対してSQLコマンドを実行する
db.commit()
Q60: 次のテキストをmany_books.csvというファイルに保存し、そのデータをbookテーブルに挿入せよ。
テキスト
text = ‘'’title,author,year
The Weirdstone of Brisingamen, Alan Garner, 1960
Perdido Street Station, ChinaMiéville,2000
Thud!, Terry Pratchett,2005
The Spellman Files, Lisa Lutz,2007
Small Gods, Terry Pratchett, 1992
#csvファイルの作成
with open("many_books.csv", "wt") as outfile:
outfile.write(text)
#読み取り、挿入
import csv
import sqlite3
ins_str = "insert into book values(?, ?, ?)"
with open("many_books.csv", "rt") as infile:
books = csv.DictReader(infile)
for book in books:
curs.execute(ins_str, (book["title"], book["author"], book["year"]))
db.commit()
Q61: bookテーブルのtitle列を選択し、アルファベット順に表示せよ。
sql = "select title from book order by title asc"
for row in db.execute(sql):
print(row)
Q62: 連続した数かどうか
問題:1118 のような、3 つ以上の同じ数字が連続して並んだ 4 桁の整数を 良い整数 とします。 4 桁の整数 N が与えられるので、N が 良い整数 かどうかを答えてください。
def good_number(n):
n = str(n)
if n[0] == n[1] == n[2] or n[1] == n[2] == n[3]:
print("Yes, it is a good number")
else:
print("No, it isn't good nomber")
good_number(1116)
[参考]やるだけPython競プロ日誌