質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.80%

pythonのファイルについての質問です。

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 449

namikko

score 12

こんにちは。Pythonのファイルについての質問です。学校の課題でどうしても分からずにに困っております。。。
やりたいことは、
1、使用者にファイル名を聞く
2、そのファイルがなければそこで終了
3、もしそのファイルがあれば使用者に行を聞く
4、もし行がなければそこで終了
5、もしインプットしたデータ(行)が正しければそのインプットされた行から100行を新しいファイルに入力する。その時に単語の数も一緒にカウントする。

英語ではこのように書かれております。
Ask user to type the name of the file text. If the file does not exist, print a message and finish.

If the file exist, ask for the first row to be read. If there is no such row, print a message and finish.

If input data is correct, write 100 rows from the user's given number to a new file. Add word count to each row. If there is less than 100 rows, write as many as there are.

try, except , else を使うのはわかるのですが、どのようにコードを書いたらいいのか不明です。

プログラミング言語は必須で全くの初心者なのにこのような課題が出て頭を悩ませております。。
どなたかご教授をお願い申し上げます。
バージョンは3.7.2です。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kou0179

    2019/04/12 21:43

    英語があまり得意でないのでお聞きしたいのですが、行の指定は、「何行目か?」という指定で良いのでしょうか?

    キャンセル

  • namikko

    2019/04/12 21:50

    kou0179 様
    はい、おっしゃる通りです。例えば私が1000とインプットしたら1000行目+そこから100行をプリントできるようにコードを書きたいです。もし曖昧であれば申し訳ございません。。

    キャンセル

  • 退会済みユーザー

    2019/04/12 22:45

    複数のユーザーから「やってほしいことだけを記載した丸投げの質問」という意見がありました
    「質問を編集する」ボタンから編集を行い、調査したこと・試したことを記入していただくと、回答が得られやすくなります。

回答 1

checkベストアンサー

-3

必要知識

  • 標準入出力
  • ファイルの開き方、読み込み方
  • 例外処理の仕方
  • Listの使い方
  • ファイルの書き込み方

注意点

正常な動作はテストしましたが、保証は致しかねます。
あくまでも以下に掲載するソースコードは解答例として参考にして頂き、
ご自身で、「何故こう動くのか」という事を意識した上で一行一行読んでいただけたら幸いです。

以下、ソースコード(解答例)

import sys

# ファイル名を聞く
print("Please enter a file name")
file_name = input()

try:
    # ファイルを開けてみる
    file = open(file_name, "r")
except IOError:
    # 開けれないならエラーを出力し、IO閉じて、エラーコードを返し終了
    print(file_name+" is not found")
    sys.exit(1)

# 読み込んだファイルを一行ずつリストに入れる
file_rows = file.readlines()
# IOをクローズする
file.close()

# 何行目から読み込みたいか聞く
# 読み込み直後にint型へ変換し、配列インデックスに合せ-1しとく
print("What line does start row say that?")
start_row = int(input())-1

try:
    # 指定された行にアクセスしてみる
    _ = file_rows[start_row]
except IndexError:
    # アクセスできないならエラーを出力し、エラーコードを返し終了
    print("The row is not found")
    sys.exit(1)

# 書き込み用にファイルを開く。本来であれば例外処理すべきだが指定が無いのであえてそのまま
# 尚、"a"は追記モード
new_file = open("count_"+file_name,"a")

# 100回繰り返す、iには0、1、2、...98、99の順で値が入る
for i in range(100):
    try:
        # 指定行の内容を変数にいれとく
        current_row = file_rows[start_row + i]
    except IndexError:
        # もし100行満たす前に最後の行まで来てしまったら
        # IOクローズして正常終了
        new_file.close()
        sys.exit(0)

    # 現在行の内容をスペースで区切ってリスト化しその要素数を求める(=単語数を求める)
    current_row_word_len = len(current_row.split())

    # 単語数を追加した、新しいファイルに書き込むための行を構築する
    current_row = str(current_row_word_len) + " words | " + current_row
    # ファイルに書き込む
    new_file.write(current_row)

#IOを閉じる
new_file.close()
#正常終了
sys.exit(0)

仕様

  • ファイル名を標準入力で受け付け開きます。存在しない場合は終了します。
  • 何行目から読み込むか標準入力で受け付けます。存在しない行が指定された場合は終了します。
  • 指定された行から100行、単語数のカウント を行先頭に追記したファイルを「count_元ファイル名」で保存します。
  • 指定された行から、元ファイルの最後行が100行未満の場合は、最後行まで上述の処理を行います。

追加質問回答

追加質問①

一つ目は単語の数の表示なのですが、
I am a Japanese. (4)
このように表示するにはどうすればいいのでしょうか?

回答欄ソースコード、コメント,空行を除く、下から4行目あたりに

 current_row = str(current_row_word_len) + " words | " + current_row 

というコードがあるのは分かりますか?
この部分で、current_rowには最初、元のテキストのある一行がそのまま入ってますが、これに文字列結合でただ単語数を追加してるだけです!

まず、

current_row = str(current_row_word_len) + " words | " + current_row


この行は、current_rowへ「何か」を代入する行というのはお分かりいただけると思います。

そして、その「何か」、すなわち、
 str(current_row_word_len) + " words | " + current_row 
は何をしているかというと、
次に以下3つを結合しています。

  • str(current_row_word_len) current_row_word_lenを文字列型へ変換したもの
  •  words |  単純な文字列
  • current_row 文字列型変数(現在処理中の元ファイルの行の文字列)

それら結合した物を、current_rowへぶち込みなおす処理をしてます。

なので、I am a Japanese. (4)という表示にしたければ

current_row = current_row + " (" + str(current_row_word_len) + ")"

で、いけそうですが、無理です。(私はこれでいけると思った・・・)
なぜならば、current_rowの一番最後の文字に改行コードが入ってしまっています。

よって、以下のようにcurrent_row最後の改行を消して、さらに改行コードを連結すればいけます。

current_row = current_row.rstrip('\n') + " (" + str(current_row_word_len) + ")\n"


ポイントとしては

  • current_row.rstrip('\n')で改行コードを消してる
  • ")\n"で最後にカッコを閉じるだけでなく改行を入れてあげる
    です。
追加質問②

二つ目は

try:
# 指定された行にアクセスしてみる
_ = file_rows[start_row]


の初めの_の部分はどういうことを表しているのでしょうか?

これは特にPythonでは意味は無いです。紛らわしくてごめんなさい。
一部のプログラミング言語では、ブランク識別子等と呼ばれ、要は捨てるための変数と考えて頂けると分かりやすいです。
ただ、Pythonにはその概念が無いのでこのようにして使いました。
もっとスマートなやり方あれば教えてください笑

今回の場合、別に今すぐにはfile_rows[start_row]に対して用事は無いけど、
もし存在しなかったら困るから念のためtry:の中でいったんアクセスしてみる、ために使ってます。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/04/13 00:07

    kou0179様
    無事に書き込まれました!
    本当に申し訳ないのですがもう二つ質問があります。
    一つ目は単語の数の表示なのですが、
    I am a Japanese. (4)
    このように表示するにはどうすればいいのでしょうか?
    二つ目は
    try:
    # 指定された行にアクセスしてみる
    _ = file_rows[start_row]
    の初めの_の部分はどういうことを表しているのでしょうか?
    本当に度々申し訳ございません。
    当方、海外在住で時差の関係があり、返事が遅れることがございます。
    大変夜遅くに質問してご迷惑をおかけします。

    キャンセル

  • 2019/04/13 00:35

    追加質問、回答いたしました。分からなければ、またこちらのコメント欄へ。
    最初丸投げかと思ってましたが理解しようとしてくれて嬉しいです!笑

    お時間は週末なのでお気になさらず!

    キャンセル

  • 2019/04/13 00:43

    本当に申し訳ないくらいご丁寧にコードも説明も書いていただきありがとうございました!!!!
    画面の前で頭を下げました(笑)
    大変お世話になりました!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.80%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る