Ken’s Learning Projects

色々なスキルや資格の取得を実践・展開します!

edXを利用して新しいスキルを習得する (Programming- 008)

先日、edXで学習した2つ目のコースである、"Introduction to Computer Science and Programming Using Python" を最後までやり遂げました。"How to Write an Essay" よりかなり分量も難しさもありましたが、ひとまず Programming や Python がどんなものなのかを学ぶことができて満足です。また、Certificate も得ることができました。そこで、これからの2回は、このコースの内容と感想を記載していきたいと思います。

 

今回は、最初の Unit 1 から Midterm Exam までを記載します。だいたい週に1回新しい Unit に入り、その最後にテストがあります。講義はVideoとそれに付随するミニテストからなり、1個の Unit には2つの項目があります。まずはその目次です。

 

 

それでは一つづつみていきましょう。

 

Unit 1: Python Basics

  1. Introduction to Python / 2. Core Elements of Programs

まずはじめに、コンピュータとは何か、プログラムとは何か、といった基本的な知識から、用語の解説まで行っていきます。ここまでは「ふんふん、そーかー」などとしていて大丈夫です。そこから、 "if" や "else" 、"print" や "input" 等の使い方といった、初歩的なところを解説していきます。さらにこの Unit の終盤では、"while" や "for" を用いた繰り返しの方法を学びます。最終的には、ランダムな文字列からアルファベット順になっている部分の中でもっとも長いものを抽出するプログラムを書くところまで行います。

"""
アルファベット順に文字が並んだsの最も長い部分文字列を表示するプログラムを書いてください。
例えば、s = 'azcbobobegghakl' の場合、プログラムは次のように表示します。
Longest substring in alphabetical order is: beggh
"""

s = 'azcbobobegghakl'
count = 0
maxcount = 0
result = 0

for char in range(len(s) -1):
    if (s[char] <= s[char + 1]):
        count += 1
        if count > maxcount:
            maxcount = count
            result = char + 1
    else:
        count = 0
startposition = result - maxcount
print("Longest substring in alphabetical order is:" ,s[startposition:result + 1])

 

Longest substring in alphabetical order is: beggh

 

Unit 2: Simple Programs

  3. Simple Algorithms / 4. Functions

 このUnitでは、"while" や "for" の復習から始まり、新しいこととしてはまず "bisection search" を学習します。これがなかなか理解が難しく、最初の難関でした。ここら辺から正しく理解していないとミニテストですら普通に間違えるようになります。また、ここから頻繁に出てくる Function の使い方を学習します。"Tower of Hanoi" やおなじみの "Fibonacci" 、そして "Palindrome" (回文)を例にしながら、特に "iteration" と "recursion" の違いについて解説してくれます。最終的には、負債があると仮定した時に、いくらづつ返済すれば12ヶ月で返却できるかを返してくれるプログラムをbisection search を用いて書きます。下の表が実際に出てきた例です。

Month Balance Minimum Payment Unpaid Balance Interest
0 5000.00 100 (= 5000 * 0.02) 4900 (= 5000 - 100) 73.50 (= 0.18/12.0 * 4900)
1 4973.50 (= 4900 + 73.50) 99.47 (= 4973.50 * 0.02) 4874.03 (= 4973.50 - 99.47) 73.11 (= 0.18/12.0 * 4874.03)
2 4947.14 (= 4874.03 + 73.11) 98.94 (= 4947.14 * 0.02) 4848.20 (= 4947.14 - 98.94) 72.72 (= 0.18/12.0 * 4848.20)

 

"""
balance: クレジットカードの未決済残高
annualInterestRate: 10進数で表した年利率
**Monthly interest rate = (Annual interest rate) / 12.0
**Monthly payment lower bound = Balance / 12
**Monthly payment upper bound = (Balance * (1 + Monthly interest rate)12) / 12.0
これらの範囲とbisection searchを使って、セントに対する最小の月々の支払い額を求めるプログラムを書いてください。
"""

balance = 320000   # random
annualInterestRate = 0.2   # random

init_balance = balance
monthlyInterestRate = annualInterestRate / 12
lower = init_balance / 12
upper = (init_balance * (1 + monthlyInterestRate)**12 / 12.0
epsilon = 0.03

while abs(balance) > epsilon:
    monthlyPaymentRate = (upper + lower) / 2
    balance = init_balance
    for i in range(12):
        balance = balance - monthlyPaymentRate + ( (balance - monthlyPaymentRate) * monthlyInterestRate)
        if balance > epsilon:
            lower = monthlyPaymentRate
        elif balance < -epsilon:
            upper = monthlyPaymentRate
        else:
            break

print("Lowest Payment:", round(monthlyPaymentRate, 2))

 

Lowest Payment: 29157.09

 

Unit 3: Structured Types

  5. Tuples and Lists / 6. Dictionaries

 ここでは、"Tuple" や "List"、そして"Dictionary"を学習します。それぞれの特徴などから始まり、"List" では、"append" や "remove", "pop" を用いることでその中身を変化させることができることを学びます。"Dictionary" の部分では、曲の中で同じ単語が何回出てくるかを抽出するプログラムを通じてその用法について説明されます。最終的には、"Hangman" という単語あてゲームを作成します。

import random

WORDLIST_FILENAME = "words.txt"

def loadWords():   

    """   
    単語のリストを返してください。単語は、小文字の文字列です。
    単語リストの量によっては、この関数が終了するまでに時間がかかる場合があります。

    """ 

    print("Loading word list from file...")   
    inFile = open(WORDLIST_FILENAME, 'r')   
    line = inFile.readline()   
    wordlist = line.split()   
    print("  ", len(wordlist), "words loaded.")   
    return wordlist

def chooseWord(wordlist):
    """
    wordlist (list): list of words (strings)
    ランダムな単語のリストを返してください。
    """
    return random.choice(wordlist)

wordlist = loadWords()

def isWordGuessed(secretWord, lettersGuessed):
    '''
    secretWord: ユーザが推測する単語
    lettersGuessed: これまでに推測された文字リスト
    returns: boolean, secretWordの全ての文字がlettersGuessedに含まれている場合はTrue

      そうでない場合は、False

    '''
    for i in secretWord:
        if i not in lettersGuessed:
            return False
    return True

def getGuessedWord(secretWord, lettersGuessed):
    '''
    secretWord: 文字列、ユーザーが推測する単語
    lettersGuessed: これまでに推測された文字リスト
    returns: 文字とアンダースコアで構成される文字列
     これまでにsecretWordのどの文字が推測されたかを表す
    '''
    result = [ ]
    for i in secretWord:
        if i in lettersGuessed:
            result.append(i)
        else:
            result.append('_')
    return ''.join(result)

import string
alph = string.ascii_lowercase

def getAvailableLetters(lettersGuessed):
    '''
    lettersGuessed: これまでに推測された文字リスト
    returns: まだ推測されていない文字を表す文字で構成された文字列

    '''
    remain = [ ]
    for i in alph:
        if i not in lettersGuessed:
            remain.append(i)
    return ''.join(remain)

def hangman(secretWord):
    '''
    secretWord: 文字列、推測するための秘密の単語
    ハングマンのインタラクティブなゲームを開始します。
    * ゲームの開始時に、ユーザーに secretWord に含まれる文字数を知らせます。
    * ユーザーには、1 ラウンドにつき 1 つの推測文字を提供するよう求めます。
    * ユーザーは、各推測の直後に、自分の推測がコンピュータの単語に含まれているかどうかのフィードバックを受け取る必要があります。
    * 各ラウンドの後、ユーザーには、これまでに部分的に推測された単語と、ユーザーがまだ推測していない文字も表示する必要があります。
    '''
    print("Welcome to the game, Hangman!")
    print("I am thinking of a word that is", len(secretWord), "letters long.")
    mistakesMade = 0
    lettersGuessed = [ ]

    while 8 - mistakesMade > 0:
        if isWordGuessed(secretWord, lettersGuessed) == True:
            print("------------")
            print("Congratulations, you won!")
            break
        else:
            print("------------")
            print("You have", 8 - mistakesMade, "guesses left.")
            print("Available letters:", getAvailableLetters(lettersGuessed))
            guess = str(input("Please guess a letter:")).lower()
            if guess in secretWord and guess not in lettersGuessed:
                lettersGuessed.append(guess)
                print("Good guess:", getGuessedWord(secretWord, lettersGuessed))
            elif guess in lettersGuessed:
                print("Oops! You've already guessed that letter:", getGuessedWord(secretWord, lettersGuessed))
            elif guess not in secretWord:
                print("Oops! That letter is not in my word:", getGuessedWord(secretWord, lettersGuessed))
                lettersGuessed.append(guess)
                mistakesMade += 1
        if 8 - mistakesMade == 0:
            print("------------")
            print("Sorry, you ran out of guesses. The word was", secretWord)
            break
        else:
            continue


secretWord = chooseWord(wordlist).lower()hangman(secretWord)

 

Midterm Exam

中間試験となるこの Midterm Exam は、ある期間内ならいつでも受けられます。問題はランダムで出されるようですが、その難しさは一定とのことです。制限時間は8時間で、開始したら終わるまで通しでおこなわなければなりません。実際にプログラムを書くのは3題ありました。正解まですぐにたどり着けばいいですが、こんがらがるとなかなかきついです。

ですが、これまでのプログラムをみてもらえばわかる通り、事前に説明やヒントが書かれています。問題には、def PROGRAM_NAME(object): で書いてね!と説明があり、さらにどのような解を返すものであるべきかが書かれています。自分が受けた時は以下の3題が出題されました。

"""
Problem 4

aListに含まれる文字列のうち、4文字以下のサブリストを返すPython関数を書いてみましょう。例えば、aList = ["apple", "cat", "dog", "banana"] の場合、関数は["cat", "dog"]のように返す必要があります。
この関数は、文字列のリストを受け取り、文字列のリストを返します。aListを変更してはいけません。
"""
def lessThan4(aList):
    bList =
    for i in range(len(aList)):
        if len(aList[i]) <=3:
            bList.append(aList[i])
    return bList

 

"""
Problem 5

aDict内のキーのリストを返すPython関数を書いてください。そのkeyは固有な整数値に対応しています。返したkeyのリストは昇順にソートされていなければなりません。(aDictに固有な値が含まれていない場合は、空のリストを返す必要があります)。
"""
def uniqueValues(aDict):
    tmp = {}
    result =
    for value in aDict.values():
        if(value in tmp.keys()):
            tmp[value] += 1
        else:
            tmp[value] = 1
    for key in aDict.keys():
        if(tmp[aDict[key]] == 1):
            result.append(key)
return sorted(result)

 

"""
Problem 6

リストを平滑化する関数を書いてください。リストには他のlist、str、またはintが含まれます。例えば、[[1,'a',['cat'],2],[[[3]],'dog'],4,5]は、[1,'a','cat',2,3,'dog',4,5]に平滑化されます。
"""
def flatten(aList):
    newList = []
    for item in aList:
        if type(item) != list:
            newList.append(item)
        else:
            newList.extend(flatten(item))
    return newList

 

前半戦いかがだったでしょうか。正直なところ、この全てが当時できたわけではなく、今回改めてこのBlogに書こうとした時に書き直したものもあります。さらには知人に聞いたり、ネットで調べたりかなりしました。ただ、このedXのいいところは、自分で考えなければならない場所がある、というところです。論理性がものをいうプログラミングにおいて、本当に自分の頭を使って考えることができるようになります。

次回は後半戦の、Unit 4から Final Exam を記載しようと思います。

コードが引用を使って書いたので見辛かったらすいません。デバイスによっては改行されてしまい、インデントがおかしくなると思われます。ご参考までに。

 

f:id:KenSuzuki1:20210211005354p:plain