LoginSignup
2
5

More than 5 years have passed since last update.

【python】100本ノックにチャレンジ!(010〜014)

Last updated at Posted at 2017-08-18

これまでの経緯などについて

最初の投稿を参照ください

ノック状況

9/24追加

第2章: UNIXコマンドの基礎

hightemp.txtは,日本の最高気温の記録を「都道府県」「地点」「℃」「日」のタブ区切り形式で格納したファイルである.以下の処理を行うプログラムを作成し,hightemp.txtを入力ファイルとして実行せよ.さらに,同様の処理をUNIXコマンドでも実行し,プログラムの実行結果を確認せよ.

010. 行数のカウント

行数をカウントせよ.確認にはwcコマンドを用いよ.

wc_010.py
#-*- coding:utf-8 -*-

import subprocess
import codecs

if __name__=="__main__":
    filename = 'hightemp.txt'
    basepath = '/Users/masassy/PycharmProjects/Pywork/training/'
    f = codecs.open(filename,'r','utf-8')

#\nの数を数える。配列は0から始まるので、最後に+1
    for index,data in enumerate(f):
        data.split('\n')

    print("ファイル内の行数は",index+1)

# wcコマンドで出力を確認する
    output = subprocess.check_output(["wc","-l",basepath+filename])
    print(output.decode('utf-8'))

result
ファイル内の行数は 24
      24 /Users/masassy/PycharmProjects/Pywork/training/hightemp.txt

感想:ファイルを開いて改行コードをindexで数える。文字コード指定で読み込めるcodecsは便利。

011. タブをスペースに置換

タブ1文字につきスペース1文字に置換せよ.確認にはsedコマンド,trコマンド,もしくはexpandコマンドを用いよ.

tab2space_011.py
-*- coding:utf-8 -*-

import subprocess
import codecs

if __name__=="__main__":
    filename = 'hightemp.txt'
    basepath = '/Users/masassy/PycharmProjects/Pywork/training/'
    f = codecs.open(filename,'r','utf-8')
#readは1字ずつ全部、readlineは1行、readlinesは全ての行を読む
    r = f.read()
    space_data=''
    for tab_data in r:
        if(tab_data=='\t'):
            space_data += " "
            continue
        else:
            space_data += tab_data

    print(space_data)
# sedコマンドで出力を確認する
    output =subprocess.check_output(["sed","-e" ,"s/\t/ /g",basepath+filename])
    print(output.decode('utf-8'))

result
高知県 江川崎 41 2013-08-12
埼玉県 熊谷 40.9 2007-08-16
岐阜県 多治見 40.9 2007-08-16
(結果が長いので略)

高知県 江川崎 41 2013-08-12
埼玉県 熊谷 40.9 2007-08-16
岐阜県 多治見 40.9 2007-08-16
(結果が長いので略)

Process finished with exit code 0

感想:read()とreadline()とreadlines()の違いを確認できた。コマンドを利用できるsubprocessはホント便利。

012. 1列目をcol1.txtに,2列目をcol2.txtに保存

各行の1列目だけを抜き出したものをcol1.txtに,2列目だけを抜き出したものをcol2.txtとしてファイルに保存せよ.確認にはcutコマンドを用いよ.

cut_012.py
# -*- coding:utf-8 -*-

import codecs
import subprocess

if __name__ == "__main__":
    filename = 'hightemp.txt'
    writename1='col1.txt'
    writename2='col2.txt'
    basepath = '/Users/masassy/PycharmProjects/Pywork/training/'
    f = codecs.open(filename,'r','utf-8')
    r = f.readlines()
    word_list1= []
    word_list2= []

#splitで\t毎に分けてリストに追加する
    for temp1 in r:
        word_list1.append(temp1.split('\t')[0])
    f.close
    f = codecs.open(writename1,'w','utf-8')
    for word in word_list1:
        f.write(word+'\n')
    f.close

    for temp2 in r:
        word_list2.append(temp2.split('\t')[1])
    f.close
    f = codecs.open(writename2,'w','utf-8')
    for word in word_list2:
        f.write(word+'\n')
    f.close

#cutコマンドで出力を確認する
    output = subprocess.check_output(["cut","-f","1,2",basepath+filename])
    print(output.decode('utf-8'))

result
*cutコマンドでは1〜2列目をわざと同時に出力
高知県   江川崎
埼玉県   熊谷
岐阜県   多治見
(結果が長いので略)

Process finished with exit code 0

col1.txt
高知県
埼玉県
岐阜県
(結果が長いので略)

col2.txt
江川崎
熊谷
多治見
(結果が長いので略)

感想:処理をcol1.txtとcol2.txtで分けたけど、なんかうまい処理がありそう...

013. col1.txtとcol2.txtをマージ

12で作ったcol1.txtとcol2.txtを結合し,元のファイルの1列目と2列目をタブ区切りで並べたテキストファイルを作成せよ.確認にはpasteコマンドを用いよ.

merge_013.py
#-*- conding:utf-8 -*-

import codecs
import subprocess
basepath = '/Users/masassy/PycharmProjects/Pywork/training/'
filename1 = 'col1.txt'
filename2 = 'col2.txt'
filename3 = 'col3.txt'

#readlinesでファイルを読み込みリスト化
f1 = codecs.open(filename1,'r','utf-8')
r1 = f1.readlines()
f1.close()

f2 = codecs.open(filename2,'r','utf-8')
r2 = f2.readlines()
f2.close()

s_r1=''
s_r2=''

#リストを文字列に変更し、r1の\nは\tに変更(\tが番兵になる)
for data in r1:
    s_r1 += str(data)
    s_r1=s_r1.replace('\n','\t')

#リストを文字列に変更(\nは番兵のためそのまま残す)
for data in r2:
    s_r2 += str(data)

address=''
i=0
#s_r1を1文字ずつ評価し、番兵(\t)がくるまでaddressにデータを追加
for temp in s_r1:
    if(temp!='\t'):
        address+=temp
    else:
# addressにs_r2のデータを番兵(\n)がくるまで追加
        address+='\t'
        while(s_r2[i]!='\n'):
            address+=s_r2[i]
            i+=1
        else:
            address+='\n'
            i+=1
            continue

f3=codecs.open(filename3,'w','utf-8')
f3.write(address)
f3.close()

output=subprocess.check_output(["paste",basepath+filename1,basepath+filename2])
print(output.decode('utf-8'))

result
高知県   江川崎
埼玉県   熊谷
岐阜県   多治見
(結果が長いので略)
Process finished with exit code 0

感想:2重ループでデータを追加していく。

014. 先頭からN行を出力

自然数Nをコマンドライン引数などの手段で受け取り,入力のうち先頭のN行だけを表示せよ.確認にはheadコマンドを用いよ.

head_014.py
#-*- coding:utf-8 -*-

import codecs
import subprocess

def head(data,N):
    i=0
    j=0
    msg=''
    while(i<N):
        for temp in data[j]:
            if(temp!='\n'):
                msg += temp
                j+=1
            else:
                msg += '\n'
                i+=1
                j+=1
                break
    else:
        return msg

if __name__=="__main__":
    filename = 'hightemp.txt'
    basepath = '/Users/masassy/PycharmProjects/Pywork/training/'
    f = codecs.open(filename,'r','utf-8')
    r=f.read()
    N=4
    msg = head(r,N)
    print(msg)

#headコマンドで確認
    output=subprocess.check_output(["head","-n",str(N),basepath+filename])
    print(output.decode('utf-8'))

result
高知県   江川崎   41  2013-08-12
埼玉県   熊谷  40.9    2007-08-16
岐阜県   多治見   40.9    2007-08-16
山形県   山形  40.8    1933-07-25

高知県   江川崎   41  2013-08-12
埼玉県   熊谷  40.9    2007-08-16
岐阜県   多治見   40.9    2007-08-16
山形県   山形  40.8    1933-07-25

Process finished with exit code 0

感想:なんかC言語みたいな書き方になってしまった。。。

2
5
2

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
2
5