Java経験者が40日間、仕事の終わった後の時間を利用して大体60時間ぐらいPythonを勉強して「Python 3 エンジニア認定実践試験」を受けてまいりました。
試験結果は、見事合格しました!!
゚+。:.゚v(●^皿^●){合格シタッッ!!!}(○^皿^○)v゚.:。+゚
点数は?というと、この記事のサムネイル画像のような滑り込みぶりです。。
まあ、一応合格は合格ですので、これからはPythonを使ってさらに精進して行きます!
出題ポイント
それでは、また前回のように、実際出た問題をいくつか覚えてる範囲の内容を共有します。
- 日本時間のUTCに変換する方法
次のようなastimezone()やり方が正解のはずです。テキスト関連部分はP174です。
>>> import datetime >>> import zoneinfo >>> now = datetime.datetime.now() >>> now datetime.datetime(2023, 9, 30, 23, 23, 29, 17301) >>> now.astimezone(zoneinfo.ZoneInfo('UTC')) datetime.datetime(2023, 9, 30, 14, 23, 29, 17301, tzinfo=zoneinfo.ZoneInfo(key='UTC'))
次のような
timedelta
を使う選択肢もあったが、問題にはnow = datetime.datetime.now()
の記載があり、この中にはタイムゾーンの指定がなく、勝手に日本時間と解釈してはいけないかと思います。(そう解釈した張本人ですが、、)>>> now - datetime.timedelta(hours=9) datetime.datetime(2023, 9, 30, 14, 23, 29, 17301)
- 辞書型を用いてCSVファイルの読み込み
次のどれが正解だと思いますか?- csv.reader(csvfile)
- csv.reader(csvfile, dialect=’dict’)
- csv.DictReader(csvfile)
正解は3です!
間違えた人??はい、私です。。
2と3のどっちかなぁ〜とは悩んでいったが、、2を選びました。。dialectの意味を直訳すると「方言」になり、テキストP284ですが、以下3種類を指定できます。
- excel
- excel-tab
- unix
json_string
をjsonファイルに書き込む場合、どれが正しいでしょうか。-
with open('data.json', 'w') as f: json.loads(json_string, f)
-
with open('data.json', 'w') as f: json.load(json_string, f)
-
with open('data.json', 'w') as f: json.dumps(json_string, f)
-
with open('data.json', 'w') as f: json.dump(json_string, f)
正解は4番です。jsonオブジェクトするにはdumpsですが、ファイルに書き込むにはdumpです。
試験ではloadの選択肢はなかったが、そもそもloadかdumpかというところも私の中であやふやだったので、そこも含めて押さえておきましょう!-
- 高レベルなファイル操作を行うライブラリshutilを使ってディレクトリのコピーはどれでしょうか。
- shutil.copy()
- shutil.copy2()
- shutil.copytree()
- shutil.copyfile()
正解は3です。ディレクトリの再帰的コピーはcopytreeです。、わかりやすくtreeも付けてますが、まあ、それっぽくして正解ではない時だってあります。
ここは私が疑ってしまい、、見事にcopy2を選んでしまいました。。 - クラスやメソッドをモックで置き換えたい場合、
unittest.mock.patch()
関数をデコレーターまたはコンテキストマネージャーとして利用します。
テキストP382の内容ですが、太字にしたところに注意しましょう! - dataclassについて、自分の思い込みですが、次のように
age: int
にfloatを代入したエラーになると思ってました。。実際は以下の通り、Python的には型ヒントなので、、floatの値をintの属性に代入すると、intにもならず、floatのまま保持することになります。これはJavaとか型がきっちり決められる言語に受けた影響ですね。注意しましょう!
問題になるのは、デフォルト値が設定されていない場合、代入しないとエラーになります。>>> from dataclasses import dataclass >>> @dataclass ... class User: ... name: str ... age: int ... height: float ... >>> User(age=1, name="abc", height=2) User(name='abc', age=1, height=2) >>> User(age=1.2, name="abc", height=2) User(name='abc', age=1.2, height=2) >>> User(age=1, name="abc") Traceback (most recent call last): File "
", line 1, in TypeError: User.__init__() missing 1 required positional argument: 'height' - ユニットテストのsetUpとtearDownの順番は次のようにsetUpClass(1回)⇛(setUp⇛テスト⇛tearDown)(テスト分)⇛tearDownClass(1回)の順番だと押さえおきましょう!例:unittest1.py
import unittest class AddTest(unittest.TestCase): @classmethod def setUpClass(self): print("class setup") def setUp(self): print("setup") @classmethod def tearDownClass(self): print("class tearDown") def tearDown(self): print("tearDown") def test_assert_equal(self): self.assertEqual(1, 1) def test_assert_false(self): self.assertFalse([]) if __name__ == "__main__": unittest.main()
実行すると以下の通りです。
% python unittest1.py class setup setup tearDown .setup tearDown .class tearDown ---------------------------------------------------------------------- Ran 2 tests in 0.000s OK
- 列挙型について、テキストP202にありますが、列挙型の定数にはnameとvalueの属性があります。この2つの属性を取得して文字列としての比較も次のようにできますので注意しましょう!
また、len()を使ってサイズを取得できますが、valueが同じの項目は1としてカウントされるようです。>>> import enum >>> class AddEnum(enum.Enum): ... ABC = "abc" ... EFG = "efg" ... HIJ = "abc" ... >>> len(AddEnum) 2 >>> AddEnum.ABC.name 'ABC' >>> AddEnum.ABC.value 'abc' >>> AddEnum.ABC.value == "abc" True >>> AddEnum.ABC.value == "abc" and AddEnum.ABC == AddEnum.HIJ True >>> AddEnum.ABC != AddEnum.EFG True >>> AddEnum.ABC.name != AddEnum.EFG.name True
- ロガーの設定について、テキストP418にありますが、1つのロガーには複数ハンドラーを設定できますので注意しましょう!
- ロガーのレベルについて、テキストP415にありますが、次のようにデフォルトではWARNING(30)以上でないと出力されません。
>>> import logging >>> logging.debug("abc") >>> logging.info("abc") >>> logging.warning("abc") WARNING:root:abc >>> logging.error("abc") ERROR:root:abc >>> logging.critical("abc") CRITICAL:root:abc
- コードの実行時間測定について、戻り値がfloatではないものはどれかの問題がありました。
正しい回答の選択肢はあまり覚えていないですが、timeit.repeatの戻りはfloatのリストであることに気をつけましょう。
試験に出た選択肢は次のようにリストの後ろに[0]を付けてますので、当然ながらこれはfloatです。>>> import timeit >>> timeit.repeat('"test" in "This is a test."') [0.03717041801428422, 0.03409303998341784, 0.03424739197362214, 0.0343480070005171, 0.03429219697136432] >>> timeit.repeat('"test" in "This is a test."')[0] 0.04336309799691662
選択肢にはTimerあったか自信ありませんが、下記のようにTimerの戻り値はfloatではないですね。
>>> import timeit >>> timeit.Timer('char in text')
- インメモリテキストストリームStringIOについて、次のようにseek()してwrite()すると、末尾に追加されるので覚えておきましょう!
>>> import io >>> stream = io.StringIO('abc') >>> stream.seek(0, io.SEEK_END) 3 >>> stream.write('test') 4 >>> print(stream.getvalue()) abctest
まとめ
今回Python 3 エンジニア認定実践試験を受けることを通じて、Pythonに対して使えるようになった気がするところは言うまでもないかなと思いますので、そこは今回ので目標達成したかなと思います。
また、Javaや他の言語でできるから、概念が同じだという理由で勉強の過程で軽く考えすぎたのも1回目の失敗の原因かなと思います。前述のように、dumpかdumpsかとか、細かいところ聞かれますので、概念だけでは通じない世界になります。
また、2回試験受けて感じたこととして、問題はそれなりに被ります。半分いかないかもしれませんが、それに近い割合があるかもしれません。
ですので、もしあなたも過去にあいにく不合格となった結果があれば、是非間違った問題を思い出して、何が正解だったかを把握してから再チャレンジしましょう!高い割合でまた出会うからです。
今回の受験歴をこのようにブログに起こすことで、自分の勉強には役に立ったと思いますので、皆さんにも少しお役に立てられたら幸いです。
これから受験する方、ご健闘をお祈りしております!合格できましたら、コメントで教えていただけると嬉しいです!
コメントを残す