プログラミング1 コンピュータ科学科 夏休み課題

以下に示す動作をする Python のプログラムを作成せよ.

提出は求めないし全問を解く必要はないが,以下の問題の中から最低1問は試験に出題することを予告しておく. なお,春2期『情報セキュリティとリテラシ2』の講義の範囲外の内容もあるが,そうした問題を解く場合は各自で調べて対処せよ.

☆が付いている問題は,それが多いほど難しいことを示している.

1章 整数

1. 数の表示

1から100までの数を昇順に表示せよ.なお,各数の後にはコンマとスペースを入れること.

2. FizzBuzz問題

1から100までの数を順番に表示せよ.ただし,3で割り切れる場合は「Fizz」,5で割り切れる場合は「Buzz」,両者で割り切れる場合(すなわち15で割り切れる場合)は「FizzBuzz」と表示せよ.

3. 逆順でのループ

100から1までの数を降順に表示せよ.なお,各数の後にはコンマとスペースを入れること.

4. 奇数・偶数の判定

入力された整数が奇数か偶数かを判定し,表示せよ.

5. 総和

1から入力された整数までを順番に足したときの合計を表示せよ. ただし,1より小さな数が入力された場合はエラーを表示せよ.

6. 階乗

入力された非負整数の階乗を表示せよ.

7. 最大公約数☆

入力された二つの正の整数の最大公約数を表示せよ.

8. 素数判定

入力された整数(ただし,1より大きなものに限る)が素数か否かを判定し,表示せよ.

9. 素数の一覧

入力された整数(ただし,1より大きなものに限る)より,小さな素数をすべて表示せよ.

10. 素因数分解☆☆

入力された1より大きな整数を素因数分解せよ.

2章 リスト・タプル・辞書型

この章の問題では,あらかじめ以下のリスト items をプログラムの先頭に記述して解答せよ. これは,商品名,単価,個数がリスト形式で表されたものである.

items = [["apple",  200, 38],
         ["kiwi",   130, 40],
         ["orange",  90, 20],
         ["grape",  380, 30],
         ["peach",  400, 10],
         ["cherry", 300,  5],
         ["banana",  80, 36],
         ["lemon",  150, 20]]

11. 小計の表示

商品名,単価,個数,小計(単価×個数)を,商品ごとに1行ずつ表示せよ. なお,数字は右揃えで表示せよ. 以下は出力例である.

$ ./11.py
apple    200      38     7600
kiwi     130      40     5200
orange    90      20     1800
grape    380      30    11400
peach    400      10     4000
cherry   300       5     1500
banana    80      36     2880
lemon    150      20     3000

12. 特定の項目だけの表示

問11と同じ課題に関して,単価が 150以上のものだけ表示せよ.

13. 合計

問11と同じ課題に加えて,最後に個数と小計の合計を表示せよ. 以下は出力例である.

$ ./13.py 
apple    200      38     7600
kiwi     130      40     5200
orange    90      20     1800
grape    380      30    11400
peach    400      10     4000
cherry   300       5     1500
banana    80      36     2880
lemon    150      20     3000
total            199    37380

14. ソート

問11と同じ課題を,商品名を辞書順に並べ替えて表示せよ.

15. 降順ソート

問11と同じ課題を,小計の金額が大きいものから順に表示せよ. 以下は出力例である.

$ ./15.py 
grape    380      30    11400
apple    200      38     7600
kiwi     130      40     5200
peach    400      10     4000
lemon    150      20     3000
banana    80      36     2880
orange    90      20     1800
cherry   300       5     1500

16. 辞書型への変換

items の内容を変換し,キーを商品名,値を単価する辞書型 prices を作成せよ. 確認のため,最後に print(prices) を実行せよ. 以下は出力例である.(キーの順番は同じになるとは限らない)

$ ./16.py 
{'kiwi': 130, 'grape': 380, 'apple': 200, 'peach': 400, 'cherry': 300, 'orange': 90, 'lemon': 150, 'banana': 80}

17. 辞書型への変換2

items の内容を変換し,キーを商品名,値を単価と個数のタプルとする辞書型 sales を作成せよ. 確認のため,最後に print(sales) を実行せよ. 以下は出力例である.(キーの順番は同じになるとは限らない)

$ ./17.py
{'kiwi': (130, 40), 'grape': (380, 30), 'apple': (200, 38), 'peach': (400, 10), 'cherry': (300, 5), 'orange': (90, 20), 'lemon': (150, 20), 'banana': (80, 36)}

18. タプルの利用

問17で作成した sales を利用して,小計を表示せよ.ただし,消費税8%を加算せよ. 以下は出力例である.(順番は同じになるとは限らない)

$ ./18.py
kiwi     5616
grape   12312
apple    8208
peach    4320
cherry   1620
orange   1944
lemon    3240
banana   3110

19. 複雑な割引

問18と同様の計算をせよ. ただし,30個以上を購入する場合1割引とせよ. さらに,peach と cherry の場合は,10個以上で1割引とせよ. 以下は出力例である.(順番は同じになるとは限らない)

$ ./19.py
kiwi     5054
grape   11080
apple    7387
peach    3888
cherry   1620
orange   1944
lemon    3240
banana   2799

20. 辞書型からリストへの変換と比較☆☆

sales を以下のように宣言する.

sales = {'kiwi': (130, 40), 'grape': (380, 30), 'apple': (200, 38), 'peach': (400, 10), 'cherry': (300, 5), 'orange': (90, 25), 'lemon': (160, 20), 'banana': (80, 36)}

これを items と同様の商品名,単価,個数の3項組からなるリストのリストに変換し, items と比較した上で,単価もしくは個数が異なる商品名を表示せよ.

3章 文字列処理

この章の問題では,2章に引き続き items を利用するので,あらかじめプログラムの先頭に items を記述して解答せよ.

21. 小文字→大文字

items の商品名を順番に表示せよ.その際,すべての文字を大文字にせよ.

22. 先頭の大文字化

items の商品名を順番に表示せよ.その際,先頭の文字だけを大文字にせよ.

23. 文字列の反転

items の商品名を順番に表示せよ.その際,apple → elppa のように逆さ書きにして表示せよ.

24. 文字列の連結

items の商品名をコンマ(,)で連結して変数 names に代入せよ.その際,先頭や末尾に余分なコンマを付加してはならない. 確認のため,最後に print(names) を実行せよ.

25. 数字の連結

items の単価をコンマ(,)で連結して変数 unit_prices に代入せよ.その際,先頭や末尾に余分なコンマを付加してはならない. 確認のため,最後に print(unit_prices) を実行せよ.

26. 文字列から数字への変換

以下のようにコンマ区切りの文字列として,変数 s に与えられるとする.

s = "20,32,10,17,13,10,20,25"

個数をこの s から読み出して,問11を実行せよ. 以下は出力例である.

$ ./26.py
apple    200      20     4000
kiwi     130      32     4160
orange    90      10      900
grape    380      17     6460
peach    400      13     5200
cherry   300      10     3000
banana    80      20     1600
lemon    150      25     3750

27. 文字列から数字への変換2

問26と同じ問題を,以下の変数 s について実行せよ. 問26と異なり,今回の数値は空白区切りで,なおかつ3桁区切りにカンマがあるものとする. また,出力時にも3桁区切りのカンマを付加せよ.


s = "2,000 620 800 900 300 200 3,500 650"

以下は出力例

$ ./27.py
apple    200    2,000   400,000
kiwi     130      620    80,600
orange    90      800    72,000
grape    380      900   342,000
peach    400      300   120,000
cherry   300      200    60,000
banana    80    3,500   280,000
lemon    150      650    97,500

28. コマンドライン引数の処理

コマンドライン引数として1個の文字列を受け取り,それを反転して表示せよ.

29. キャメル・ケース

コマンドライン引数として複数の文字列を受け取り,先頭だけ大文字としスペースなしで連結したものを表示せよ. なお,このような形式をラクダのコブに見えることから,キャメル・ケースと呼ぶ.

$ ./29.py camel Case STYLE
CamelCaseStyle

30. スネーク・ケース

コマンドライン引数として複数の文字列を受け取り,すべての文字列を小文字にし,かつアンダースコア(_)を間にいれて連結したものを表示せよ. なお,このような形式をスネーク・ケースと呼ぶ.

$ ./30.py snake Case STYLE
snake_case_style

4章 ファイル入出力

31. 行数

constitution.txt を読み込み,その行数を表示せよ. なお,正解は Unix の wc というコマンドで確認できる.

32. 文字列マッチ

constitution.txt を読み込み,Constitution という文字列を含む行だけ表示せよ. なお,constitutions にように小文字で始まっていたり,複数形になっているものは表示しなくて良い.

33. 単語マッチ☆

constitution.txt を読み込み,law という単語を含む行だけ表示せよ. その際には,大文字で書かれた LAW や複数形の laws が含まれる行の表示せよ. 一方で,lawful のように単語の途中に law が含まれる行は表示しないようにせよ.

34. 単語数☆

constitution.txt を読み込み,単語の個数を表示せよ. この場合は空白・タブ・改行で区切られ単位が単語である. なお,正解は Unix の wc というコマンドで確認できる.

35. 単語の出現数☆☆

constitution.txt を読み込み,各単語の出現回数を数え上げ,多い順に表示せよ. 大文字はすべて小文字に変更してから数える. つまり,Constitution と constitution は同じ単語とする. ただし,law と laws のような変化形は,すべて別単語とする. なお,単語の前後にある約物(コンマ,ピリオド,括弧など)はすべて取り除く.

36. 棒グラフ表示☆☆☆

問35の結果を棒グラフで表示せよ. グラフの表示には Matplotlib を利用したり,gnuplot を呼び出したりするなどの方法がある. また,全単語を表示すると見難いので,上位50語だけを表示するなど工夫せよ. 以下は Matplotlib の pyplot で表示した解答例である.

単語の出現回数

37. CSV形式の読み込み

nagoya201707.csv には,2017年7月の名古屋の気温が記載されている. このファイルを読み込み,最高気温が1番高い日とその最高気温,最低温度が一番低い日とその最低気温を表示せよ. なお,このファイルのように値がコンマで区切られたデータ形式をCSV (Comma Separated Values) 形式と呼ぶ.

38. CSV形式での出力☆

irago201707.csvinabu201707.csvには,それぞれ伊良湖と稲武の2017年7月の気温が,nagoya201707.csvと同じ形式で記載されている. この3個のファイルをまとめて,各行に以下のデータをコンマ区切りで出力せよ.

つまり,このプログラムの出力形式はCSV形式になる. out38.csvは,その出力結果である.

39. 折れ線グラフ表示☆☆☆

nagoya201707.csvirago201707.csvinabu201707.csv をそれぞれ読み込み,横軸を日,縦軸を各地点の平均気温とした折れ線グラフを描画せよ. 以下は pyplot で表示した解答例である.

各地の平均気温

40. 画像の表示☆☆

問39の解答例にある画像をダウンロードし,これを自分のPC上で表示するプログラムを作成せよ.

5章 ライブラリの利用 日時の処理

この章の問題では,Python に付属のライブラリを利用することを前提としている. ただし,ライブラリを利用せず,自分でプログラムを作成しても良い.

41. 今日の日付の表示

実行したときに,今日の日付を表示するプログラムを作成せよ.

42. 現在時刻の表示

実行したときに,現在の時刻を日付を含めて表示するプログラムを作成せよ.

43. 100日後

実行したときに,今日から数えて100日後の日付を表示するプログラムを作成せよ.

44. 文字列から日付への変換

コマンドライン引数として,"2019/7/7"のように年・月・日をスラッシュで区切る文字列が与えられたとき,それから100日後の日付を表示するプログラムを作成せよ. 出力も,年・月・日をスラッシュで区切る形式とせよ.

45. 曜日の表示

コマンドライン引数として,"2019.7.7"のように年・月・日をピリオドで区切る文字列が与えられたとき,その日付の曜日を表示するプログラムを作成せよ.

46. 西暦から和暦への変換

コマンドライン引数として,"20190707"のように年・月・日を8桁の数値表現として表したものが与えられたとき,それを和暦に変換して表示するプログラムを作成せよ. 出力は"令和元年7月7日"のように,年月日を漢字で表示せよ. なお,変換できる範囲は1945年以降でよい.つまり,昭和・平成・令和への変換ができれば充分である.

47. 和暦から西暦への変換

コマンドライン引数として,"R010707"のようにアルファベット1文字+6桁の年月日表現が与えられたとき,それを西暦に変換して表示するプログラムを作成せよ. ここで,アルファベットはM,T,S,H,R が入力される可能性があり,それぞれ「明治」「大正」「昭和」「平成」「令和」を表す. なお,"H310701"のように存在しない年月日であったもエラーを出す必要はない.

48. 平成から令和への変換

コマンドライン引数として,平成の年月日を示す"H310707"のような"H"+6桁の年月日表現が与えられ.それが平成31年5月1日より前を示す場合はそのまま表示し,平成31年5月1日以降を示す場合は適切な令和の年月日に変更して表示せよ. 例えば,"H310707"が入力された場合は "R010707" を表示せよ.

49. 年齢の日数での表示

コマンドライン引数として誕生日を入力したとき,今日が生まれてから何日目かを表示するプログラムを作成せよ. コマンドライン引数での年月日の対応範囲は自由に定めて良い.

50. 日付によるソート☆☆

accident.csv は,1日ごとの事故の発生件数を記録したファイルである.ただし,フォーマットが定まっていなかったため,日付の表記方法がバラバラである. 日付の表記方法を統一し,なおかつ日時の新しい順に並びかえて表示するプログラムを作成せよ.

6章 関数の作成 さいころ

51. さいころ(6面体)

さいころを表す関数dice()を作成せよ. この関数は,引数は0個で,返り値として1から6までの整数のいずれか1個をランダムに返す. つまり,実行するたびに返り値は異なり,それぞれの値が返ってくる確率はいずれも約6分の1であるようにせよ.

52. さいころ(n面体)

さいころを表す関数dice(n)を作成せよ. ただし,nは正の整数とし,1からnまでの整数のいずれか1個をランダムに返す. dice(6)とした場合,問51とまったく同じ動作をする.

53. 引数の省略

問52の関数を修正し,引数が省略された場合は,引数が6であるとして動作するようにせよ.つまり,この関数は問51と問52の両方の解答になるものである.

54. 複数のさいころの和

問53の関数を修正し,複数のさいころの和を返す関数を考える. 関数dice(n, m)は,1からnまでの整数のいずれか1個をランダムに返すさいころを,m個振ったときの合計を返すものとする. つまりdice(6, 3)は6面体のさいころ3個を振った和を返す関数となる. なお,引数が1個の場合は,それはnの値を指定し,n面体のさいころ1個を振った結果を返すようにせよ.つまり,引数が1個の場合,2個目の引数mは1とみなす. また,n と m の両方を省略した場合,つまり引数が0個の場合は dice(6, 1) の結果を返すようにせよ.

55. さいころの出目の分布

出現したさいころの目を数え上げる関数 count_dice(n, m, l)を作成せよ.この関数は,問54の関数dice(n, m)を引数l回実行し,返り値がそれぞれ何回出現したかをリストで返す.例えば,print(count_dice(6, 1, 300)) の結果は以下のようになる.

[0, 49, 46, 57, 50, 46, 52]

これはdice(6, 1)を300回実行(6面体のさいころ1個を300回振ることと同義)したとき,1が49回,2が46回,3が57回,4が50回,5が46回,6が52回出現したことを表す. 乱数を用いるため,実行するたびに結果は異なる. ただし,このdice()では0が返り値になることはないので,リストの先頭の値は常に0である.

また,print(count_dice(6, 2, 300)) の結果の一例を以下に示す.

[0, 0, 9, 12, 26, 42, 36, 39, 51, 41, 24, 13, 7]

期待値を考えると,7が最も多く出現すると思われるが,上記の例では7が39回,8が51回と8の方が多く出現している. 300回程度の試行回数では,このような結果はときどき出現する.

56. さいころの出目の分布のヒストグラ☆

問55の関数count_dice(6, 2, 300)の返り値を表示するプログラムを考える. 今回は,さいころの目(2〜12)を表示し,その右にその出現回数だけアスタリスク * を表示する. 例えば,実行結果は以下のようになる.

 2:***********
 3:********************
 4:*************************
 5:************************************
 6:*******************************
 7:******************************************************
 8:*******************************************
 9:************************
10:************************
11:*********************
12:***********

57. さいころの出目の分布のヒストグラム2☆☆☆

問54の関数dice(n, m) をl回実行したときの返り値の分布をMatplotlibを用いてヒストグラムで表せ. 問55のcount_dice(n, m, l)を利用して,自分で棒グラフを描いてもよいし,Matplotlib のヒストグラムを表示するメソッド hist()を利用しても良い. 後者の方が簡単であるが,その場合は bins (表示する棒の数)の値を適切に指定する必要がある. 以下は n = 6, m = 2, l = 10000 のときの実行結果である.

さいころの出目の分布

問55の例で示した通り,試行回数 l が小さなときは綺麗なグラフにならないことがあるので,各自確認してみること.

58. 当たるまでの籤引き

当たるまでクジを引く関数 until_i_win(l, n) を作成せよ. これは l以下の数が出るまでn面体のさいころを振るとき,何回目でl以下の数が出たかを返す関数である. until_i_win(1, 100) は,当選確率1%のクジを当たるまで引いたとき,何回クジを引くかをシミュレートすることになる. 関数 until_i_win(n, l) の内部で,問54の dice(n, m)を呼び出すようにせよ. (今回の場合 m = 1なので,2番目の引数は省略して構わない.)

59. 当たるまでの籤引き2☆

問58の関数を使い, until_i_win(1,100)を1,000回実行せよ. (100面体さいころ1個を100回振るのではなく,1が出るまで100面体さいころ1個を振る試行を1,000回繰り返す) このとき,返り値の最小値,最大値,平均,返り値が101以下だった回数を表示するプログラムを作成せよ.

最後の数値は,当選確率100分の1の籤を100回引いても当たらない可能性がどの程度あるかを示すものである.

60. 当選までの試行回数の分布☆☆☆

問59のプログラムを修正し,until_i_win(1,100)を10,000回実行したときの返り値の出現回数をヒストグラムで表示せよ.