LoginSignup
5
1

More than 1 year has passed since last update.

pythonでテスト駆動開発をしながらAtcoderを解くABC071

Last updated at Posted at 2019-06-26

今日の目標

前回テストの大切さを知ったので、テスト駆動開発で競技プログラミングを解くことを試してみる

事前に考えたこと

競技プログラミングはそんなに処理が多くないから無駄じゃない?
→自分はその簡単な処理でもエラーを起こすので必要
→問題を適切な単位に分割する練習になる

コードが長くなるよね?
→それはしょうがない。諦める

開発環境整備

https://qiita.com/NaokiHamada/items/0689cd85fb3e1adcda1a
を参考にした。
 1.別にドキュメントはいらないとも思ったが、この方法だと、1つのファイルで(テストケースを記述したファイルとかを必要なく)できる。
 2. "if name == 'main':" を以下のように末尾につけることでそのまま提出コードにすることができる。

def print_ans(s):
---
中略
---
if __name__ == '__main__':
 s = input()
 print_ans(s)

の2点からこれにしました。(他にいい方法あったら教えてください)

ちなみにSphinixのインストールには少し手間取りました。
sphinx-quickstart 
を押して基本はEnterを押すだけでいいのですが、一回目にやったときはautodocumentをNo(デフォルト)にしてから、あとでconf.pyを書き換えたからなのか、テストが実行できませんでした。

問題セット ABC072

A

X-tと0の大きい方の数を出力するだけです。
テストのやり方としては、"""(”または’を3つ)でコメントアウトした中に、
”>>> ”でインタラクティブ実行で入力と出力を書いてテストする流れになります。

シンプルでいいですね。

実行は

python -m doctest examples.py

です。

ちなみに、失敗するといくつのテストで失敗したかが表示され、成功したら何も表示されません。

a.py
def print_ans(X,t):
    """Print max(X-t,0)

    Parameters
    --------------

    Examples
    ------------
    >>> print_ans(3,0)
    3
    >>> print_ans(3,2)
    1
    >>> print_ans(2,5)
    0
    """
    print(max(0,X-t))

if __name__ == '__main__':
    X,t = map(int,input().split())
    print_ans(X,t)

B

文字列を受け取って、1,3,5,7..の文字を繋げた文字列を返します。]
range(0,len(s),2)でステップ数(ループを回る時の回り方)を1つ飛ばしに指定しています。

b.py
def print_ans(s):
    """Print substring of s, odd_th char

    Parameters
    --------------
    Examples
    >>> print_ans("a")
    a
    >>> print_ans("ab") 
    a
    >>> print_ans("aibc")
    ab

    """
    for i in range(0,len(s),2):
        print(s[i],end="")

if __name__ == '__main__':
    s = input()
    print_ans(s)

C

 数字が要素のリストを受け取って、x-1<= a <=x+1 となるリストの要素a がもっとも大きくなる x を求め、その時の条件を満たす要素a の個数を出力します。

 単純にxの値を1ずつ増やしていくとTLE(時間制限エラー)だったので、そーとして、リストの要素の値でループを回したのですが、それでもTLEでした。

 値は正しいのですが、TLEが解決できなくて諦めました。
O(N)にはなってると思うんだけど。。

c.py
def print_ans(s):
    """Print substring of s, odd_th char
    >>> print_ans([1])
    1
    >>> print_ans([1,4])
    1
    >>> print_ans([0,3,4,5])
    3
    >>> print_ans([1,2,3,2,5,6])
    4

    """
    b = list(set(s))
    ans = 1
    """TLE 
    for i in range(b[0],b[-1]+1):
        ans = max(b.count(i)+b.count(i+1)+b.count(i+2),ans)
    """

    for i in range(len(b)):
        ans = max(ans,s.count(b[i])+s.count(b[i]+1)+s.count(b[i]+2))
    print(ans)

if __name__ == '__main__':
    N = input()
    a = list(map(int,input().split()))
    print_ans(a)

振り返り

 とりあえず、テスト駆動開発でできるようになったのでよかった。
今は全体のコードをテストしているが、今後細かく分けて(関数を細かく分けて)テストできるようになる。

 あとは、C問題で詰まって次に行けなかったので、回答を見ても良いからCまでときたい。
 

参考
https://qiita.com/NaokiHamada/items/0689cd85fb3e1adcda1a

5
1
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1