見出し画像

文系でも分かる!Pythonプログラミング - module / import / random

← preview

next →

module

module.

prime

>> prime ( プライム )
= 主要な。最上の。〔数〕素数。

素数」というものを覚えておいででしょうか。

「1」と「その数」でしか割り切れない数
の事でしたね。

素数は「2,3,5,7,11,13,17,19,23...」こんな風に続いていきます。


テキトーに選んだ数字が
素数かどうかを確認するのには
かなり時間が掛かってしまいます。

例えばテキトーな数「643」が
素数かどうかを判定するには

(643÷1)
643÷2
643÷3
(643÷4)
643÷5
(643÷6)
643÷7
...
(643÷640)
643÷641
(643÷642)
643÷643

こんな風に「2」〜「643」の範囲内で

「643」を割り切れる数が見つかるまで

割り算を繰り返さなければなりません。

※4で割り切れるけど
2で割り切れない数というものは無いので
割る数が素数でないものは括弧書きになっています。


「100000」までの素数を全て調べるということは

「2÷2」
「3÷2」「3÷3」
「4÷2」「4÷3」「4÷4」
「5÷2」「5÷3」「5÷4」「5÷5」
「6÷2」「6÷3」「6÷4」「6÷5」「6÷6」
...
「100÷2」〜「100÷100」
「101÷2」〜「101÷101」
...
「99998÷1」〜「99998÷99998」
「99999÷1」〜「99999÷99999」
「100000÷1」〜「100000÷100000」

こんな風に物凄い量の計算を
しなければならないということ。


以下のような記述をすることで

100000までの素数をリスト化して
その個数を調べることができるのですが

実行してもすぐに結果は出ません。

11inch iPad Proでは40秒くらいかかりました。

stop = 100000
primes = []

for i in range(2,stop+1):   # 1
	primes.append(i).       # 2
	for p in range(2,i):    # 3
		if i % p == 0:      # 4
		   primes.remove(i) # 5
			break           # 6

print(primes)
print(f"{len(primes)}個")

#-----------------------------------#

# 1. 2~100000の中から値を取り出して変数(i)に代入

# 2. 「取り出した数(i)」をリストに追加する

# 3. 「2」から「i」までの範囲の値を取り出して変数「p」に代入

# 4. もし、「i」を「p」で割り切れるなら、以下の処理を実行

# 5. リストから「i」を削除
 
# 6. (もう素数じゃないことが分かったので)繰り返しを強制終了

これが「stop = 1000000 (100万) 」になったら
処理に数十分〜1時間近くかかってしまうと思います。
(マシンの性能による)

( 前々回 appendメソッド を学びましたが、
リストから特定の値を削除する
removeメソッド というものもあります。
記述方法は appendメソッド と同様なので
今回は説明しません。)


こんな風に、自分で考えて時間をかけて
プログラムコードを書くこともできます。

しかし、正しい計算結果が得られるコードを書くためには
それなりの知識や試行錯誤が必要です。

自分にとってプラスになるのは間違いありません。

しかし、これから料理をしようというときに
調理器具や材料を作るところから始める人がいないように

ゲームを作ろうという時に
わざわざ計算ができるシステムから作ろう
なんて人はいません。

そんな時に「モジュール」というものを使います。


module

>> module ( モジュール ) 

= 交換可能な部品等の集まり。(構成要素)

ハードウェアやソフトウェアにおいて、
まとまった機能や要素を持ったもの。

〔略〕MOD(モッド)。

例えば、

科学計算をする機能を持った
「 numpy ( ナムパイ/ナンパイ ) 」

記号計算をする機能を持った
「 sympy ( シムパイ ) 」

データグラフなどを作成する機能を持った
「matplotlib ( マットプロットリブ ) 」

などがある。


import

import...

import

>> import ( インポート )
= 輸入。外部にあるファイルを読み込む作業の事。

モジュールを使いたい時は、
 import文 」というものを書いて
そのモジュールを先に読み込んでおく
必要があります。

例えば、先程紹介した
numpy」を呼び出してみましょう。

import numpy

これだけです。

numpyの中にある関数(メソッド)を呼び出すには

import numpy

print(numpy.sqrt(2))  # square root : 平方根

# >>> 1.41421356237

「 numpy.関数名( 引数 ) 」

このような形で記述します。


import ○○ as 〜

>> as 〜 ( アズ )
= 〜として。

インポートした(読み込んだ)モジュールの
関数(メソッド)を使うには

numpy.array( )
numpy.sqrt( )
numpy.arange( )

のように「numpy.○○( )」という形で書くわけですが...

それが「matplotlib」のような長い名前のモジュールだった場合、
関数を使うたびに「matplotlib.○○( )」と書くことになります。

文字数が長いとスペルミスをする確率が上がりますし、
その分間違いを見つけるのが困難になります。

そこで、「as」という記述を使います。

この「as」を使うことで
モジュール名に〔略称〕を付ける事ができます。

そしてそれ以降、
〔略称〕でモジュールを呼び出せるようになります。

import numpy as np

import matplotlib as plt


print(np.sqrt(2))   # 略称.関数名(引数)

# >>> 1.41421356237

このように

import モジュール名 as 略称

という書き方をすればOK。

「 モジュール を 〔略称 として 読み込む 

という意味になります。


from ○○ import △△ as 〜

>> from 〜 ( フロム )
= 〜から、〜より。

例えば、

「科学計算をするMOD」「データグラフを作成するMOD」など
モジュールごとに機能が異なるわけですが、

「科学計算」「データグラフ」自体にも
様々な種類があるわけです。

モジュールの中にある特定の
クラス(※)」や「関数」だけを呼び出す方法もあります。

※「クラス」は別記事で説明します。
簡単に言えば、メソッドの集まりがクラスで
クラスの集まりがモジュールです。

from sympy import sqrt as rt

print(rt(2))  # モジュール名は書かなくていい。

# >>> 1.41421356237

この記述では、

sympyモジュールからsqrt関数を「rt」として読み込む

という命令を意味しています。


primerange( )

sympyには素数を扱う機能も用意されています。

その中でも今回使いたいのは
primerange( )」というものです。

range( )のように、
「開始位置」「終了位置」を指定してやると
その範囲内の素数を返してくれます。

試しに1〜100の範囲で
素数がどれくらいあるのか調べてみましょう。

※ range( )がそうだったように
primerange( )も リ ス ト で は な い ので

リストにしたい時はlist関数を使って
リスト化してやる必要がある事には注意しましょう。

from sympy import primerange   # primerange関数だけを読み込む


primes = list(primerange(1,101))   # リスト化を忘れないで。


print(primes)
print(len(primes))

# >>> [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 
#      43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
# >>> 25 個
import sympy as sp  # sympyをspという略称で読み込む


primes = list(sp.primerange(1,101))  # リスト化を忘れないで。


print(primes)
print(len(primes))

# >>> [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 
#      43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
# >>> 25 個

上記のどちらの記述でも結果は同じになります。

処理速度も先程のプログラムよりも圧倒的に早いです。
結果が出るまで数時間かかっていた計算が
数秒〜数分でできるくらい早いです。

これは使わないわけにはいかないでしょう。


random_module

random.

random.randint( )

>> random ( ランダム ) 
= デタラメの。乱数。

「ゾロ目が出たらもう一本!」
と書かれた自動販売機で飲み物を買った事はありますか?

規則性が無くテキトーに選ばれるため
予測する事ができない数字を「乱数」と言います。

pythonでランダムな整数を扱うには
randomモジュールrandint関数を使います。

import random

print(random.randint(1,10))

# >>> 6 など

ここで注意してほしいことがあります。

range( 1, 10 )では、「1〜9」の数を扱っていましたが
randint( 1, 10 )では、「1〜10」の数が扱われます。

range( )が「 範囲 」を示しているのに対して

randint( )

「 ここからここまでのint型オブジェクト 
を示しています。

randint( )int型オブジェクトなのに対して
range( )はrange型オブジェクト


もっとイメージしやすく書くと、
randint( 1 , 10 ) では

1〜10の数字が書かれたボールが
ボックスだったりビンゴマシーン内に
ゴチャゴチャと入っている

という感じ。

もしrange( )のように
エンドポイントの「10」を含まないなら、

「10」というint型オブジェクトが確実にそこにあるのに
絶対に選ばれないということになってしまいます。

これがオーディションなら
「10」番になっただけで落選確定です。

可哀想過ぎる。


注意点はまだあります。

ランダムな整数を1つ返す randint( ) 

range( )のように
スタートポイントを省略する事ができません。

もしも、

「選択肢1〜10番の中から1つ選んでください」
と言われたら選べますが

「選択肢10から1つ選んでください」
と言われたら「は?」と思いますよね。

しっかりと最初と最後の数を指定してやりましょう。

range( )に関しては、「10の範囲」ですから、
イメージ的には数直線の方が近いかもしれません。


そしてもう一つ注意点が。

randint( ) は int型オブジェクト になるので、
[ iterable_object ]  ではありません。

つまりfor文には使えませんし、
list関数を使ってリストにする事もできません。

もし、

「 1〜10の中からランダムに1つ選ぶ 
という処理を5回繰り返して、

さらに、選ばれたint型オブジェクトをリストにまとめる

という処理がしたければ、

以下のような書き方をする必要があります。

import random   # 1 

int_list = []   # 2

for i in range(5):                 # 3
	number = random.randint(1,10)  # 4  
	int_list.append(number)        # 5


print(int_list)

# >>> [3, 10, 4, 5, 8] など


#------------------------------------#

# 1. randomモジュールを読み込み

# 2. 空のリストを生成

# 3. 以下の処理を5回繰り返す

# 4. 1~10の中から1つ選んで変数(number)に代入

# 5. numberに代入された値を空のリストに追加

random.randrange( )

range( )の時にチラッとだけ紹介したのですが、

range( )
は開始位置、終了位置、差分を指定する事ができます。

しかし、randint( ) は 第3引数(差分)が設定できません。

そこは気をつけたいですね。

TypeError : radint( ) takes 3 positional arguments but 4 were given

しかしそれでは、

 偶数、奇数の中からランダムに1つ数字を選ぶ 

みたいな処理をしたい時に困ってしまいます。

1つ飛ばし、10個飛ばしみたいな
差分
を設定したい時は、

randomモジュール 

randrange関数 を使いましょう。

import random   # importを忘れずに。 

int_list = []

for i in range(100):  # 以下の処理を100回繰り返す
	number = random.randrange(10,100,10)  # 差分も設定
	int_list.append(number)

print(int_list)

# >>> [40, 40, 80, 70, 20, 30, 30, 10, 80, 20, 
#      80, 40, 60, 80, 70, 40, 10, 30, 30, 20, 
#      60, 40, 30, 50, 80, 90, 10, 70, 40, 60, 
#      70, 60, 60, 10, 40, 80, 70, 60, 90, 60, 
#      10, 60, 30, 20, 60, 20, 90, 30, 30, 20, 
#      20, 10, 40, 50, 50, 20, 90, 80, 90, 30, 
#      90, 40, 20, 50, 20, 30, 20, 20, 60, 60, 
#      50, 40, 60, 30, 70, 80, 40, 50, 10, 60, 
#      60, 50, 60, 90, 30, 70, 20, 20, 70, 30, 
#      40, 50, 30, 60, 40, 80, 80, 60, 90, 70]

range( )と同じ範囲や差分が適用されるので

randrange( 10, 100, 10 ) と書くと

範囲 : 10〜99 , 差分 : +10

になります。

エンドポイントの「100」は含まれないわけですね。

10,20,30,40,50,60,70,80,90

の中から1つ選ぶということになりますから

もし「100」も含めたい場合は、

randrange( 10, 101, 10 )

と書けばよいですね。


random.choice( )

>> choice ( チョイス )
= 選ぶこと。選択。

ランダムに選びたいのは
整数型オブジェクトだけではありませんよね。

リストやタプルなどの [ iterable_object ] の中から
値を1つ選びたい事もあります。

そんな時に使うのが、
randomモジュール の choice関数 です。

import random

menu = ["肉じゃが","餃子","すき焼き","鯖の味噌煮","お好み焼き"]

print(f"今日は、{random.choice(menu)}にしましょう。")

# >>> 今日は、お好み焼きにしましょう。

これは非常に分かりやすくて使い勝手も良さそうですね。

ちなみに、str型オブジェクト
range型オブジェクト も [ iterable ] なので
引数にする事ができます。

import random

print(random.choice("あいうえお")) # >>> え など

print(random.choice(range(10))) # >>> 4 など

こんな風に書くこともできます。


random.sample( )

random.choice( )を使っていると、
ランダムに選ぶのはいいけれど、
一度に複数の値を取り出したいと思う事があります。

そんな時に使えるのが sample( ) です。

import random

data = ["a","b","c","d","e","f","g"]

abc = random.sample(data,k=3)

print(abc)		# >>> ['g''a''b']

この sample( ) は、上記コードのように

第2引数に「 k = ○ 」というように書くことで
1度に取り出したい値の個数を指定する事ができます。

第1引数の [ iterable_object ] から取り出せる値の
個数を超えた数を指定する事は当然ながらできません。 


random.random( )

random.random( ) は、

0.0以上 ,1.0未満 のランダムな
float型オブジェクトを返してきます。

引数を設定することはできません。

import random

print(random.random())	# >>> 0.3123680149089294
print(random.random())	# >>> 0.4801883690729809
print(random.random())	# >>> 0.5774704498417526
print(random.random())	# >>> 0.14955135247513962
print(random.random())	# >>> 0.7359531830715661
print(random.random())	# >>> 0.49511801817114287
print(random.random())	# >>> 0.40449507162237786

「いつ使うん?」と思うかもしれませんが、
僕にもよくわかりません。

その時が来たら喜んで使いましょう。


random.uniform( )

>> uniform ( ユニフォーム )

= 同じ形の、揃いの。一定の、一様な、均一の。
〔数〕 一様な、平等な。

任意の範囲の連続一様分布から
浮動小数点数の乱数を生成する関数です。

という説明なのですが、

簡単に言えば、この関数を使うと
さっきのrandom( )とrange( )が
組み合わされたような乱数が得られます。

random( ) が 0以上1未満だったのに対して、

uniform( )
自分で範囲を好きに決めることができます。

import random

print(random.uniform(1,100))	# >>> 45.38149671505253
print(random.uniform(1,100))	# >>> 6.93682021373735
print(random.uniform(1,100))	# >>> 3.419903836414667
print(random.uniform(1,100))	# >>> 38.562237009388845
print(random.uniform(1,100))	# >>> 23.65635214197221
print(random.uniform(1,100))	# >>> 98.71768565399249

Program : randomモジュールを使ってクジを作る

goods.

こんなプログラムを作ってみましょう。

● 000〜999の中からランダムに1つの数が選ばれる

● 3つの数字がゾロ目になったら「当たり!」と表示

● 当たりが出た場合、月咬ライト、月咬コイト、月咬ミライの中から1つをランダムに選ぶ

● その後にマグカップ、ぬいぐるみ、クリアファイル、マグネット、
ストラップ、タオルの中からランダムにグッズを3つ選択

● ゾロ目出ない場合「ハズレ...😭 また挑戦してね!」と表示

● ゾロ目が出た場合 「当たり!🥳 月咬○○○の(グッズ名)をプレゼント!」と表示


import random

tukigami = ("月咬ライト","月咬コイト","月咬ミライ")
merchandise = ("マグカップ","ぬいぐるみ","クリアファイル","マグネット","ストラップ","タオル")


for i in range(100):
	
	n_1 = random.randint(0,9)
	n_2 = random.randint(0,9)
	n_3 = random.randint(0,9)
	
	print(f"結果 👉 {n_1}{n_2}{n_3}")
	
	if n_1 == n_2 == n_3:
		print("当たり!🥳")
		
		tuki = random.choice(tukigami)
		merch = random.sample(merchandise,k=3)
		a,b,c = merch

		print(f"{tuki}の\n{a}{b}{c}\nをプレゼント!")
	
 #else :
	 #print ("ハズレ...😭 また挑戦してね!")
日本人はゾロ目が好き。

random.sample( )の使い勝手の良さが光っていますね。


次の記事へ。

この記事が気に入ったらサポートをしてみませんか?