学生向けプログラミング入門

学生向けにプログラミングを解説。Java、C++、Ruby、PHP、データベース、Ruby on Rails, Python, Django

Python | 11 | メソッドが複数あるプログラム

<<前  [TOP]  次>>


メソッドとは、ある特定の一連の処理をまとめたプログラムの構造の1つです。

  • メソッドは何個でも自由に記述できます。
  • メソッドを記述する順序は処理の順序とは全く関係ありません。
  • メソッドの名前は自由に付けることができます。


    次のプログラムを作ってみましょう。


    【sort3.py】

    # sort3.py
    
    def main(array):
    
    	sort(array)
    
    	for i in range(0,len(array)):
    		print( str(i+1) + ':' + str(array[i]))
    
    
    def sort(array):
    	for i in range(0,len(array)):
    		maxN(array,i)
    
    def maxN(array,n):
    
    	max = array[n]
    	maxIndex = n
    
    	for  j in range((n+1),len(array)):
    		if ( int(array[j]) > int(max)) :
    			max = array[j]
    			maxIndex = j
    
    	array[maxIndex] = array[n]
    	array[n] = max
    
    data = [10, 75, 24, 32, 98, 72, 88, 43, 60, 35, 54, 62, 2, 12, 82]
    
    main(data)
    



    このプログラムでは、メソッドが三つあります。
    一つめはsort( )、二つめはmaxN( )、もう一つはmain( )です。


    メソッド名の後の括弧( )の中に引数を入れます。
    引数はメソッドの呼び出しの時に入れる引数とイコールの関係を持っています。


    ではプログラムを見ながら説明します。


    mainメソッドの中に次の記述があると思います。

    sort(array)
    

    これがメソッドの呼び出しです。
    このようにメソッドを呼び出すには、メソッド名とその括弧( )の中に与えたい引数を記述するだけで良いのです。
    sort(array)が処理されると、そのメソッドが処理されます。

    def sort(array):
    	for i in range(0,len(array)):
    		maxN(array,i)
    

    このメソッドの中では、dataがarrayとなって処理されるのです。
    このメソッドではすぐfor文でループすることになります。
    ループするごとに今度はmaxNメソッドが呼び出されています。
    引数はarrayと i です。
    次にmaxNメソッドに処理が移り、一番大きな数字を探して前の方と入れ替える作業をします。
    それらの作業を受けて、mainメソッドで出力する作業を行っています。


    出力結果を確認してみましょう。

    sort3.py
    sort3.py



    次のプログラムを作ってみましょう。


    【sort4.py】

    # sort4.py
    
    def main( array ):
    
    	sort( array )
    
    	for i in range(0,len(array)):
    		print(str((i+1)) + ':' + str(array[i]))
    
    def sort( array ):
    
    	tmp=0
    
    	for i in range(0,len(array)):
    
    		for j in range(0,len(array)-(i+1)):
    
    			if (int(array[j]) < int(array[j+1])) :
    				tmp = array[j]
    				array[j] = array[j+1]
    				array[j+1] = tmp
    
    
    data =[10, 75, 24, 32, 98, 72, 88, 43, 60, 35, 54, 62, 2, 12, 82]
    
    main(data)
    



    このプログラムは、sort2.pyをmainメソッドとsortメソッドに分けて書き直したプログラムです。
    作業ごとにメソッドを分けるのは、プログラムが見やすくなるというメリットがあります。


    出力結果です。

    sort4.py
    sort4.py



    次のプログラムを作ってみましょう。


    【sort5.py】

    # sort5.py
    
    def main( array, tmp0 ):
    
    	sort( array, tmp0 )
    
    	for i in range(0,len(array)-1):
    		print( str((i+1)) + ':' + str(array[i]))
    
    def sort( array, tmp0 ):
     	sort2( array, 0, len(array)-1, tmp0 )
    
    
    def sort2( array, min, max, tmp0 ):
    	if ( (max - min) < 5 ) :
    
    		sort3( array, min, max )
    		return
    
    	m = average( array, min, max )
    	largeCount=0
    	smallCount=0
    
    	for i in range(min, max+1) :
    		if ( float(array[i]) > float(m) ):
    			tmp0[ min+largeCount ] = array[i]
    			largeCount += 1
    				
    		else:
    			tmp0[ max-smallCount ] = array[i]
    			smallCount += 1
    
    	for i in range(min, max+1) :
    		array[i] = tmp0[i]
    
    	sort3( array, min, min+largeCount-1 )
    	sort3( array, max-smallCount+1, max-1 )
    
    
    def sort3( array, min, max ) :
    
    	for i in range(min, max) :
    		for j in range(min, (max-(i-min))) :
    			if ( array[j] < array[j+1] ):
    				tmp = array[j]
    				array[j] = array[j+1]
    				array[j+1] = tmp
    
    
    def average( array, min, max ):
    
    	sum = 0.0
    
    	for i in range(min, max+1) :
    		sum += array[i]
    
    	return float(sum/( max - min + 1))
    
    
    data = [10, 75, 24, 32, 98, 72, 88, 43, 60, 35, 54, 62, 2, 12, 82]
    
    tmp = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    
    main(data, tmp)
    



    tmp = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]はこのあとtmp配列を使えるように定義しています。
    作業領域用データを作成しています。


    まずmain( )からsort()に入ります。
    sort() では、sort2( array, 0, len(array)-1, tmp0 )という様にして引数を4つ与えているだけの処理を行っています。
    これにより、 sort2()に入ります。
    ここで、min=0,max=14に置き換わります。(今回のプログラムのみ。与えられるdataの数によって異なります。)


    次に、m = average( array, min, max )より、average()が呼び出され、i=0〜14まで繰り返します。
    データの平均が出てreturnします。
    ここで、m = 平均値となります。


    returnについて説明します。
    averageの型がfloatになっているのに注目してください。
    return文を使ってfloat型の戻り値を返しています。
    今回の場合は、return (sum/( max - min + 1)).to_fという記述がこの処理にあたります。
    戻り値としてreturn float(sum/( max - min + 1))というfloat型の値を返しています。


    次の記述を見てください。

    		if ( float(array[i]) > float(m) ):
    			tmp0[ min+largeCount ] = array[i]
    			largeCount += 1
    				
    		else:
    			tmp0[ max-smallCount ] = array[i]
    			smallCount += 1
    

    これにより平均値より大きいものはtmp0[0]から順に入っていき、小さいものはtmp0[14]からtmp0[13],tmp0[12]・・と入っていきます。
    0〜14まで調べると次に進みます。

    	for i in range(min, max+1) :
    		array[i] = tmp0[i]
    

    これにより配列tmp0の値が配列arrayに代入されます。


    sort3( array, min, min+largeCount-1 )によりmin=0,max=largeCount-1(たぶん7)となりまた再びsort3( array, max-smallCount+1, max-1 )に入ります。
    同時にsort3( array, max-smallCount+1, max-1 )によりmin=max-smallCount+1(たぶん8)、max-1=14となり sort3() に入ります。
    この時点で、2つのブロックに分けられました。
    そして、この2つに分けられたブロックのそれぞれの平均値が出され、それよりも大きいもの、小さいものに分けられます。
    この時点で4つのグループに分けられます。
    そのとき、if ( (max - min) < 5 )の条件に当てはまり、sort3()に入って並び替えされます。


    この並び替えの特徴は、ブロックで分けることによりsort3で処理される並び替えの動作が少なくなることにあります。
    ちょっと複雑ですが、並び替えは今までのプログラムより早くできます。


    出力結果です。

    sort5.py
    sort5.py



    次のプログラムを作ってみましょう。


    【sort6.py】

    # sort6.py
    
    def main( array, tmp0 ):
    
    	sort( array, tmp0 )
    
    	for i in range(0,len(array)-1):
    		print( str(i+1) + ':' + str(array[i]))
    
    def sort( array, tmp0 ):
    
    	sort2( array, 0, len(array)-1, tmp0 )
    
    def sort2( array, min, max, tmp0 ):
    
    	if ( int(max - min) < 5 ):
    
    		sort3( array, min, max )
    		return
    
    	if (tmp0 == [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ):
    
    		size = max - min + 1
    		half = int(size/2 + size%2)
    	
    		sort3( array, min, min+half-1 )
    		sort3( array, min+half, max )
    
    		counter1 = 0
    		counter2 = 0
            
    		for i in range(min, max+1):
    
    			if ( counter1 > (half-1) ):
    				tmp0[i] = array[ min+half+counter2 ]
    				counter2 += 1
    
    			elif ( int(counter2) > int(max-min-half) ) :
    				tmp0[i] = array[ min+counter1 ]
    				counter1 += 1
    
    			elif (int(array[min+counter1]) > int(array[ min+half+counter2])):
    				tmp0[i] = array[ min+counter1 ]
    				counter1 += 1
                    
    			else:
    				tmp0[i] = array[ min+half+counter2 ]
    				counter2 += 1
    
    	for i in range(min, max+1):
    		array[i] = tmp0[i]
    
    def sort3( array, min, max ) :
    
    	for i in range(min, max):
    		for j in range(min, (max-(i-min))):
    			if ( int(array[j]) < int(array[j+1])):
    				tmp = array[j]
    				array[j] = array[j+1]
    				array[j+1] = tmp
    
    data = [10, 75, 24, 32, 98, 72, 88, 43, 60, 35, 54, 62, 2, 12, 82]
    tmp = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    
    main(data, tmp)
    



    tmp = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]で作業領域用データtmpを作ります。
    まずmain()からsort()にはいります。


    sort() でsort2()に入ります。
    ここで、min=0,max=14に置き換わります。


    最初はtmp = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]なのでif (tmp0 == [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ):がtureになります。
    size=15,half=8となり、sort3( array, min, min+half-1 )でmin=0,max=7,sort( array, min+half, max )でmin=8,max=14となり、それぞれsort3()に入ります。


    sort3( array, min, min+half-1 )では、min=0,max=7なので、またmin=0,max=3とmin=4,max=7の2つに分けられます。
    sort3( array, min+half, max )では、min=8,max=14なので、min=8,max=11とmin=12,max=14の2つに分けられます。
    それぞれ再びsort3() に入ります。
    ここで、配列は次の4つの組に分けられています。


    1組 10, 75, 24, 32
    2組 98, 72, 88, 43
    3組 60, 35, 54, 62
    4組 2, 12, 82


    return文 でループは終わります。


    ここのreturn文は戻り値を返すためではなく、この処理を終わらせる意味を持っています。
    このreturn文がないと、このメソッドの繰り返しループが永遠に繰り返されてしまい、最終的にはメモリを食い尽くしてしまう恐れがあります。
    このreturn文があることで、sort3( array, min, min+half-1 )とsort3( array, min+half, max )のそれぞれの場所まで戻ります。
    同じメソッドを繰り返して使うときは、最後の処理の時にreturn文をつけなければうまく動かなくなりますので気をつけてください。


    ソートされた4組はループに入る前まで戻され、min=0,max=7, とmin=8,max=14の2組がそれぞれsort3()にはいります。


    出力結果です。

    sort6.py
    sort6.py



    <<前  [TOP]  次>>