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

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

新規登録して質問してみよう
ただいま回答率
85.37%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

4回答

4709閲覧

pythonによる4桁乱数(ユニーク生成)について

Meteor

総合スコア18

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2018/11/27 14:14

python3 django2で商品管理システムを独学で作っています。

ある4桁の乱数をユニーク生成するコードなのですが、
必ず4桁にならなければいけないのですが0が前に来ると桁数が減ってしまいエラー原因になっています。

ハマってしまい、お知恵をお借りできれば幸いです。

また、こういう記述の方が良いよといったオススメの書き方があれば教えてください。

python

1def number(specified_uuid=None): 2 generate_number = lambda digits: ("{:0" + str(digits) + "d}").format(uuid.uuid4().int % 10 ** digits) 3 4 uuid_candidate = specified_uuid if specified_uuid else generate_number(4) 5 # DB に既に存在する乱数である場合、やり直す 6 if Model.objects.filter(number=uuid_candidate).exists(): 7 return new_number(generate_number(4)) 8 9 return uuid_candidate

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

単純に、

Python

1impoer random 2x = random.randrange(1000,9999)

ではどうでしょうか?

投稿2018/11/27 14:29

otn

総合スコア85773

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2018/11/27 15:07

ああ、失礼。 rangeと同じでしたね。
Meteor

2018/11/27 15:56

ご回答ありがとうございました。 9999までの全ての数字を含めるとどのような記述になるのでしょうか? また、ゼロパディングができる関数を見つけ欲していた機能でした。 例)1が出力された場合「0001」にしてくれる
otn

2018/11/27 16:41 編集

> 9999までの全ての数字を含めるとどのような記述になるのでしょうか? ?? 0以上9999以下と言うことですか? random.randrange(0,10000) random.randrange(10000) です。 > また、ゼロパディングができる関数を見つけ欲していた機能でした。 数値じゃなくて文字列で欲しいと言うことですね。 format(random.randrange(10000),"04")
guest

0

ベストアンサー

そもそもなのですが、今回の4桁程度の重複しない番号を振りたい場合はDB番号テーブルを用意すべきです。
これは0001~9999までをランダムにシャッフルして並べた以下のようなテーブルになります。

登録番号商品番号
10158
26437

このテーブルは運用開始時に1回だけ作ればよいです。たとえば以下のようなコードで作れます。

Python

1def make_number_table(n): 2 import random 3 nums = list(range(1,10**n)) 4 random.shuffle(nums) 5 6 DBに番号テーブルを新規作成する 7 8 for reg_num, product_num in enumerate(nums): 9 番号テーブルにレコード挿入する 10 # print( '{rn},{pn:{width}d}'.format(rn=reg_num,pn=product_num,width=n))

すると、番号を振り出すnumber関数は以下のようになります。

Python

1def number(specified_uuid=None): 2 3 if specified_uuid: 4 商品番号がspecified_uuidに一致する行にカーソルを移動する 5 else: 6 登録番号が最も小さい(テーブルの先頭)行にカーソルを移動する 7 8 if カーソルの指す行がない: 9 throw KeyError 10 11 uuid_candidate = カーソルの指す行の商品番号 12 カーソルの指す行を番号テーブルから削除する 13 14 return uuid_candidate

このような仕組みにすれば、番号の振り出し時にバッティングが発生しませんし
商品数が多くなっても(specified_uuid未指定なら)ほぼ定数時間で番号を振り出せます。

投稿2018/11/27 20:15

編集2018/11/27 20:30
can110

総合スコア38339

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

require random
random.randint(1000, 9999)
で 4 桁整数を得てから、DB 上のデータとの重複チェックをすればよいのでは?

質問文のコードで uuid を使っている理由は何でしょうか?

参考情報

  • Pythonでランダムな小数・整数を生成するrandom, randrange, randintなど

https://note.nkmk.me/python-random-randrange-randint/

...
random.randint()
randomモジュールの関数randint(a, b)はa <= n <= bのランダムな整数intを返す
,,,

投稿2018/11/27 14:44

katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

python

1>>> import random 2>>> import string 3>>> int(random.choice(string.digits[1:]) + "".join(random.choices(string.digits, k=3))) 48328 5

ゼロパディングしたいのなら

python

1>>> "{:0>4}".format(random.randrange(10000)) 2'5155'

これで'0000'から'9999'のランダムな文字列を返します。

投稿2018/11/27 14:22

編集2018/11/27 16:14
hayataka2049

総合スコア30935

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問