PyQオフィシャルブログ

Pythonのオンライン学習プラットフォームPyQのオフィシャルブログです

Pythonで obj[...][...] ってしてるのは何?

こんにちは。PyQ開発チームの清原 id:hirokiky です。

今日も PyQ のメールサポートで何度かいただいた質問の紹介をします。 複雑なところですが、こういった疑問を通して深いPythonスキルを鍛えていってもらえればと思います。

質問

14-8の演習問題 2問目で

detail[item_name]['count'] += 1

という記述があるのですがこれは何ですか?

回答

この問題は少し難しいですね。ご説明いたします。

これの前の問題では値の集計として total、count 変数の2つを使って合計と個数を数えました。 ご質問いただいた2問目では 商品ごとに 、totalとcountという2つの値を集計しています。

  • コーラ: 320円、2個
  • コーヒー: 360円、3個

このように商品ごとに数を数えるため、detail という辞書を使っています。 detail は以下のような、 辞書の辞書 になります。

{ “コーラ”: {“total”: 320, “count”: 2}, “コーヒー”: {“total”: 360, “count”: 3} }

これは辞書の中に辞書を入れた値です。

if 文をもう一度見てみましょう。

if item_name in detail:
     detail[item_name]["total"] += data["price"]
     detail[item_name]["count"]+=1
else:
     detail[item_name]={"total":data["price"], "count":1}

if 内は、商品がすでに辞書 detail 内にある場合:

  • detail["コーラ"]["total"] += 160 のように値段を足す
  • detail["コーラ"]["count"] += 1 のように個数を1つ増やしている

detail["コーラ"] で内側の {"total": 320, "count": 1} の辞書を取り出しています。 detail["コーラ"]["count"] で、内側の辞書の 21 を追加しています。

else 内は、商品が辞書 detail 内に無い場合:

  • detail["コーラ"] = {"total": 160, "count": 1} のように初期化

商品の total, count を入れておく辞書(内側の辞書)を作っています。

他にもよく使う構造

この 辞書の辞書 はよく使われます。

他には例えば {ID値: {情報}} のような値です。 CSVやデータベースから取り出した値を、ID値で取り出しやすくした形です。

users = {
    1: {"name": "hirokiky", "birthday": date(1991, 11, 5)},
    2: {"name": "haruo860"...},
}

この場合 users[1]["name"] が「IDが1のユーザーの名前」ということになります。

あとは、「辞書のリスト」もよく使われます。 上記と似た例ですが、データベースやCSVから取り出したときの値でよくあります。

[
    {"id": 1, "name": "hirokiky", "birthday": date(1991, 11, 5)},
    {"id": 2, "name": "haruo860"...},
]

この場合、各行(内側の辞書)の順序は保持されますが、ID値でユーザー情報をすぐ取り出すようなことはできません。

いかがでしょうか?

辞書の辞書というところがポイントになります。 難しいところですが、辞書やリストのより複雑な使い方を身に付ければどんな値でもうまく扱えるようになります。

良い値、データの表し方、扱い方ができていればプログラムの処理自体はとても簡単に、簡潔に書けるようになります。 ぜひPyQでそのような深い技術も身に着けていってください。

pyq.jp

関連クエスト機能

こんにちは、カメちゃんです。そろそろお盆休みも終わりですね。まだまだ暑い日が続きそうですが、朝晩は涼しくなってきたので学習するには良い気候ですね。

今日はPyQの関連クエスト機能の紹介です。

PyQは同じ項目を何度も書くことによりプログラムを書く力を身に着けていく構成になっています。 しかし、1度学習しただけで記憶するのは難しいです。 そこで、以前に出た文法などを振り返るために利用されている文法の項目を関連クエストとして問題の下部にまとめて表示しています。

f:id:kamekokamekame:20170814164323p:plain

タイトルをクリックすると、学習内容の概要を確認できます。 更に詳しく学習を行う場合は、「別ウィンドウでクエストを復習」リンクをクリックします。

f:id:kamekokamekame:20170814164329p:plain

別ウィンドウが開き、対応するクエストの実装を確認できます。

f:id:kamekokamekame:20170814164332p:plain

また、同一クエスト内の別の問題に移動したい場合は、画面下中央の「このクエストの問題一覧」をクリックしてください。 判定済みのクエストの問題文と解説の振り返りができます。

f:id:kamekokamekame:20170814165034p:plain

PyQはこれからも改善を重ね学習しやすい機能をどんどん追加していきます。 ご意見、ご要望は、画面右下をクリックいただくとフィードバックから投稿できます。 お待ちしています。(*^_^*)ノ

pyq.jp

「いちばんやさしいPythonの教本」発売記念、コラボレーション問題リリース!

こんにちは、カメちゃんです。明日は山の日ですね。三連休やお盆休みに勉強して何か身につけたい!と考えている方もいらっしゃるでしょう。そんなあなたに朗報です。

本日、「いちばんやさしいPythonの教本」がインプレス社より発売されました!!

この本は弊社の鈴木たかのりを中心に執筆されました。PyQチームの清原 id:hirokikyも一部のコラムを執筆しています。私もレビューに参加させていただきました。

プログラミングの知識が無い方を対象にしており、ステップバイステップでとてもわかり易い内容になっています。PyQの学習とあわせてご利用いただきたい一冊となってます。

f:id:kamekokamekame:20170803120739p:plain:w250f:id:kamekokamekame:20170809103456p:plain:w250

book.impress.co.jp

実は書籍発売を記念いたしまして、PyQにコラボレーション問題をリリースいたしました!

書籍に含まれる問題が一部PyQ上で実施できます。また、書籍の問題に+αの課題も用意しました。 また、本をご購入頂きました方には本のどこかに記載されていますキャンペーンコードを入力頂きますと3日間無料でPyQをお試しいただけます。 PyQの通常ユーザー様もコラボレーション問題にチャレンジしてください!!

f:id:kamekokamekame:20170809103555p:plain:w150f:id:kamekokamekame:20170809103559p:plain:w400

f:id:kamekokamekame:20170809103601p:plain:w500

書籍ではBottleを利用している『pybot Webアプリケーション』を、PyQではDjangoを用いて動作させる問題も用意しました。

f:id:kamekokamekame:20170809103609p:plain:w500 あいさつを返す f:id:kamekokamekame:20170809103604p:plain 西暦年に対応した干支を表示する f:id:kamekokamekame:20170809103607p:plain

これからもコラボレーションを増やしていきます! ご興味のある方のご連絡お待ちしております(*^_^*)ノ

pyq.jp

長年のノウハウを学びたい - PyQが「設計」のノウハウを学べるコンテンツを追加

f:id:hirokiky:20170803171026p:plain

こんにちは。PyQ開発チームの清原 id:hirokiky です。 プログラムを書く中でこんな悩みはありませんか?

  • 「書いてみたけどキレイにまとめられないな。。」
  • 「この処理ちょっとネストが深すぎるかな。。」
  • 「この関数、再利用性があまりよくないかもな。。」

これはプログラミングしている常についてくる悩みだと思います。 自分のプログラムを見直したときや、レビューを依頼する・される場合にも常に悩ましいことだと思います。

とくに仕事で複数人と協力してプログラミングする場合や、中長期的にプログラムを改良していく場合に必要なスキルです。

それが 「設計」 です。

ですが設計のノウハウや勘所を学ぶには、それなりな時間や経験が必要だと思います。 人に教えるのも難しい点だと思います。

それを学べる学習コンテンツを追加しました。 以下のリンクから学習いただけます。

pyq.jp

PyQで学べる「設計」とは

今回はPyQに「設計」を学べる学習コンテンツを追加しました。

  • Pythonのプログラムをキレイに書き直す方法
  • 関数に分離するポイントと設計の勘所
  • Pythonファイルの分割する基準
  • クラスの使いどころと利点
  • コマンドとして使いやすく設計するポイント

Pythonプログラムの過剰なネストをやめる書き方や、関数への分離する際の基準、Pythonファイルを分割する際の基準などについて学べます。 ただし大規模なシステムの設計やテーブル設計については学べません。 あくまでもプログラムの書き方を通してPythonプログラムの 設計の基本 を学んでもらうコンテンツになります。

  • Pythonを学ぶ人へ: 関数やPythonファイルをどうまとめれば良いのか分からないので知りたい、という人へオススメします
  • Pythonを教えたい人へ: OJTやレビューで伝える前に設計の基本について知っていておいて欲しい、という人へオススメします

「設計」をなぜ伝えたいのか

設計というのは何よりも学ぶ・教えるのが難しい内容なので、PyQで学習できるようにしたいという思いがありました。 「設計」について詳しく書かれた本は抽象的であったり、実務やコーディングを通しながら 設計を会得できる 教材は無いように思います。

「設計」や良いプログラムの書き方を教えるよくある方法は、職場でのOJTやソースコードレビューを通して伝えていくことだと思います。 個人の学び方としては、他の人のプログラムを読んで勘所を徐々に学んでいく方法があります。

ですが2点問題があります

  • 学ぶのに時間がかかる
  • 良いプログラムや師に巡り会えないと学べない
  • 人の「好み」が強く意見の対立が発生しやすい

という点です。

こういった問題を解決するため、長年のノウハウを簡単に学べて、かつ「共通認識」を作れるコンテンツとしてPythonの「設計」を作りました。

共通認識・常識としての教材の大切さ

例えば「リーダブルコード」という本があります。この本はプログラミングにおいて一般的な「良い書き方」を教えてくれる本です。 この本を読めば簡潔なプログラムの書き方を学べますし、「リーダブルコードに書いてたでしょ」という共通認識を作ることもできます。

これは非常に重要なことです。プログラミングスキルが今後より一般的になる中で「底上げ」になる学習教材はすごく大事ですし、共通認識・常識として広まれば業界全体のコミュニケーションコストも下がります (他にも「現場で役立つシステム設計の原則」や「SQLアンチパターン」、も同じ意味でも良い本です)。

PyQの「設計」で実現したいこと

Pythonにおいても関数の分離やファイルの分離、クラスの使い所や定数の置き方などのノウハウがたくさんあります。 ですがそれらが「形」として世に出ていないのは残念です。 そのためにPyQでPythonでの「設計」が学べるコンテンツを作りました。

  • 長い時間が必要と言われていた 勘所までPyQですぐに学習 できた
  • 「PyQの『設計』に書いてたでしょ」とレビューで言える ようになった

そういった使われ方をされると嬉しいなと思っています。

もちろん、より深い設計のノウハウやシステムレベルの設計は今のPyQでは学習できません。 簡単に伝えられる知見だけでもありませんので難しい面もあると思います。 まだまだ私自身や弊社のノウハウを、学習コンテンツとして書き出しきれていない部分も多分にあります。

ですがその1歩目として「設計」を学習できるように作りました。今後も拡充していきたいと思っております。

「長年の勘所」にすら「知の高速道路」を

プログラミングの技量には、単に文法を知っているかや、プログラムを単純に書けるか以上のものがあります。 そういった長年の努力が必要だった「ノウハウ」や「勘所」も含めて学べる「知の高速道路」を、PyQを通して提供できればと思っています。

pyq.jp

PythonのTypeError: list indices must be integers or slices, not strは何ですか?

こんにちは。PyQ開発チームの清原 id:hirokiky です。

プログラミングをする中で一番大変で、時間がかかるのはデバッグしている時間ではないかと思います。 Pythonにもいくつかエラーがありますが TypeError 、とくに TypeError: list indices must be integers or slices, not str について解説します。 PyQのメールサポートでいただいた質問から、一部を抜粋して解説します。 (質問をくれた方には掲載の許可をいただいています)

質問

book_user = []
with open("input/room.csv", encoding="utf-8") as f:
    for row in f:
        columns = row.rstrip().split(",")
        name = columns[1]
        
        if name in book_user:
            book_user[name] += 1
        else:
            book_user[name] = 1

自分なりにコードを書いてみたんですけど、うまくいきません。 同じ名前を追加しないようにするには、どうしたらいいのかわからないんですが…

回答

これは book_user に、重複しないように name を入れる処理ですね。

まず、エラーの内容について解説します。

TypeErrorの内容

TypeError: list indices must be integers or slices, not str.

TypeErrorというエラーは「型(文字列、数字、リストや辞書)の種類が違いませんか?」というエラーです。

エラーの内容は「リストに [] するときは文字列は使えませんよ。数字かスライス ([3:8]のようなもの)にしてください」ということです。

ここで book_user はリストで、 name はファイルから読み込んできた文字列なのでTypeErrorになります。

変更するなら

上記のプログラムであれば、以下のように書き換えられそうです。

book_user = []
with open("input/room.csv", encoding="utf-8") as f:
    for row in f:
        columns = row.rstrip().split(",")
        name = columns[1]
        
        if name not in book_user:
            book_user.append(name)

これで、 book_user にユニークな name を追加する処理ができます。

もしくは、 book_user に集合を使っても良いですね。 こちらの方が辞書を使っているので動作は速くなります。

book_user = set()
with open("input/room.csv", encoding="utf-8") as f:
    for row in f:
        columns = row.rstrip().split(",")
        name = columns[1]
        
        book_user.add(name)

おわりに

エラーの内容を見て、読んでプログラムを修正するのもプログラミングに必要なスキルです。 PyQではプログラミングを学ぶとき、エラーを実際の環境と同じように表示してくれるので、エラーの読み解き方の勉強にもなります。 ぜひ、エラーを味方につけるプログラマーになりましょう。

お困りのことがあればぜひPyQと、PyQのメール、メンターサポートをご利用ください。

pyq.jp