基本情報処理技術者試験 Python のサンプル問題を外部ライブラリを使用せず実装しました


基本情報処理技術者試験(FE)午後試験 Python のサンプル問題が下記のURLで公開されました。
https://www.jitec.ipa.go.jp/1_00topic/topic_20191028.html

matplotlibという外部ライブラリを使っています。
Python3をインストールしただけでは、このサンプルは実行できません。
そこで、外部ライブラリを使わず、turtleモジュールだけで実装しました。
紹介いたします。

"""
命令列はファイルから読み込む
ファイル名はコマンド引数で指定する
"""
import sys
import turtle
import re

def parse(str): 
    return [(x[0], int(x[1:])) for x in str.split(';')] 

def draw_init():
    turtle.shape('turtle')
    turtle.home()
    turtle.clear()

def draw(str): 
    opelist = parse(str) 
    stack = [] 
    openo = 0 
    while openo < len(opelist): 
        code, num = opelist[openo] 
        if code == 'U': 
            turtle.penup() 
        elif code == 'D': 
            turtle.pendown() 
        elif code == 'F': 
            turtle.forward(num) 
        elif code == 'B': 
            turtle.backward(num) 
        elif code == 'T': 
            turtle.left(num) 
        elif code == 'H':
            turtle.home() 
        elif code == 'X':
            turtle.setx(num) 
        elif code == 'Y':
            turtle.sety(num) 
        elif code == 'R': 
            stack.append({'openo': openo, 'rest': num}) 
        elif code == 'E': 
            if stack[-1]['rest'] > 1: 
                openo = stack[-1]['openo']
                stack[-1]['rest'] -= 1 
            elif stack[-1]['rest'] <= 1: 
                stack.pop() #stackの末尾の要素を削除する
        openo += 1 

#コマンド引数からファイル名を取り出す
filename = sys.argv[1]
#ファイルを開き、操作の文字列を読み込む
try:
    file = open(filename)
    opestr = file.read()
    opestr = re.sub('#.*\n', '', opestr)            #コメントを行末まではぎ取る
    opestr = re.sub(' \t\n', '', opestr)            #空白行をはぎ取る
    opestr = re.sub(r"([A-Z]{1})", r";\1", opestr)  #区切りのセミコロンを挿入する
    opestr = opestr.lstrip(";")                     #先頭の余分なセミコロンを削除する
#描画する
    draw_init()
    draw(opestr)
#例外の処理を行う
except Exception as e:
    print(e)
#ファイルを閉じる
finally:
    file.close()

次に操作するためのファイルの例を紹介します。

#点線の星を描く
R5
    R20
        D0
        F5
        U0
        F5
    E0
    T216
E0

<実行結果>