-1

Python の学習を開始し、サンプル コード ブロックの実験を開始しました。私はそれを数回編集し、最後に行った編集で、オプションのランダム パスワード ジェネレーターを追加しました。次に、パスワードジェネレーターを別のドキュメントに入れる方が理にかなっていると判断したため、必要なコードをコピーして新しいドキュメントを作成しました。ただし、編集後、パスワードに偶数桁を生成できません。

ペーストビン

問題のあるコードのコピー (Pastebin)

import math
import random
alpha = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
print('Would you like a random password suggestion generator', 'Yes or No')
permissionRandomGenerator = input().lower()
print('How long do you want your password?')
lengthRandomGenerator = int(input())
if permissionRandomGenerator == 'yes':
    def randInt():
        return math.floor(random.random()*10)
    def randChar():
        return alpha[math.floor(random.random()*27)]
    randPasswordList = []
    listInsert = 0
    def changeCase(f):
        g = round(random.random())
        if g == 0:
            return f.lower()
        elif g == 1:
            return f.upper()
    while listInsert < lengthRandomGenerator:
        randPasswordList.insert(listInsert, randInt())
        listInsert = listInsert + 1
        if listInsert >= lengthRandomGenerator:
            break
        randPasswordList.insert(listInsert, randChar())
        randPasswordList[listInsert] = changeCase(randPasswordList[listInsert])
        listInsert = listInsert + 1
        continue
    listInsert = 0
    printList = 0
    if lengthRandomGenerator <= 0:
        print('It has to be longer than that')
    elif lengthRandomGenerator >= 25:
        print('I can\'t generate a password that long')
    elif math.isnan(lengthRandomGenerator):
        print('error: not valid data type')
    else:
        while printList < (len(randPasswordList)-1):
            printItem = randPasswordList[printList]
            print(printItem)
            printList = printList + 1
    printList = 0
    randPasswordList = []
elif permissionRandomGenerator == 'no':
    print('Too bad...')
else:
    print('You had to answer Yes or No')
4

3 に答える 3

2

私はあなたのプログラムを少しリファクタリングし、多くの不必要なステップと矛盾を取り除きました。ここにすべてがあります。次に、各部分について説明します。

import random
import string
import sys

possible_chars = string.ascii_letters + string.digits + string.punctuation

def nextchar(chars):
    return random.choice(chars)

yes_or_no = input("""
Would you like a random password suggestion generated?
Type Yes to continue: """).lower()

if yes_or_no == 'yes':
    try:
        pwd_len = int(input('How long do you want your password? '))
    except ValueError:
        sys.exit("You need to enter an integer. Please start the program over.")

    if 0 < pwd_len < 26:
        new_pwd = ""
        for _ in range(pwd_len):
            new_pwd += nextchar(possible_chars)
        print("Your new password is:\n" + new_pwd)

    else:
        print("I can only generate passwords between 1 and 25 characters long.")

else:
    print("Well then, why did you run me?")

Python は単なる構文や組み込み関数ではなく、標準ライブラリまたは stdlib でもあります。stdlib のモジュールを常に使用することになるため、標準ライブラリを使用する予定がある場合は、ドキュメントを読んでください。モジュール、その使用目的、その履歴と変更点 (特定の関数が追加されたバージョンなど)、およびモジュールに含まれるすべてのクラス、関数、および属性について学習します。必ず全体を読んでください(どれもそれではありませ長い)そして、それぞれが何をするのかについて少なくとも基本的な考えをつかむようにしてください. そうすれば、この場合のように、ジョブに最適な機能を選択できるようになります。私が余暇にやりたいことの 1 つは、ランダムなモジュールを選んでドキュメントを読んで、ただ学ぶことです。それらは一般的にかなりよく書かれており、通常はかなり包括的です。Monty Python のリファレンスに慣れてください。どこにでもあります。

import random
import string
import sys

インポートは最初にあり、ほとんどの場合、一番上にあるはずです。私は自分のモジュールをアルファベット順に並べるのが好きです。stdlib を一番上に置き、次に空白行を置き、次にサードパーティ モジュール (自作のものを含む) を次に配置します。インポートの後にも空白行を 1 ~ 2 行入れます。覚えておくべきことの 1 つは、コメントで述べたことです。読みやすさが重要です。コードは機械だけでなく、人間にも読み取られるように設計されています。必要に応じてコメントしてください。コード、関数、クラス、ブロックなどの関連するビットを区切るために、空白を多めに使用してください (空白はPythonでも構文に重要であるため、適切にインデントする必要があることも忘れないでください)。PythonスタイルガイドであるPEP-8について考えてみてください。その推奨事項は絶対的なものではありません、しかし、コーディング標準を強制する多くのプロジェクトはそれに依存しています。できるだけ従うようにしてください。1 行が 83 文字に達したとしても、気にしないで、自分が何をしているのかに注意してください。

私がドキュメントを読むことでこれほど大きなことをした理由は、次の数行です。

possible_chars = string.ascii_letters + string.digits + string.punctuation

def nextchar(chars):
    return random.choice(chars)

彼らはあなたのコードの約半分を取り除きます. string文字列を操作するための定義済みの定数が多数含まれています。私が選んだ 3 つはすべて有効なパスワード文字である必要があります。句読点を取らないシステムを使用している場合は、それを削除してください。これは文字列であることに注意してください。possible_charsタプル、リスト、ディクテーションと同様に、文字列は反復可能であるため、可能な文字ごとに個別のリストを作成する必要はありません。

randInt()次は関数です。これは、 、randChar()、およびchangeCase()関数を、一連のインライン コードと一緒に置き換えます。文字が大文字か小文字かを判断するためにあなたが思いついた方法は気に入りましたが、残りの部分はrandom.choice()上記のstring定数を使用すると非常に手間がかかりました.

yes_or_no = input("""
Would you like a random password suggestion generated?
Type Yes to continue: """).lower()

気付いていないかもしれませんが、print()user を取得する前に説明文字列を指定する必要はありませんinput()。文字列を単一の引数として に渡すだけでinput()、同じ効果が得られます。また、トリプル クォート """(使用可能) で囲まれた文字列リテラルも使用しました。これは、含まれる改行やタブをエスケープする必要がない'''という点で、より一般的なシングル クォート'やダブルクォートで囲まれた文字列リテラルとは異なります。"今のところ覚えておくべきことは、数行のテキストを書くことができるということですprint()

    try:
        pwd_len = int(input('How long do you want your password? '))
    except ValueError:
        sys.exit("You need to enter an integer. Please start the program over.")

try/except次のパーツにはブロックを使用しました。ユーザーが入力プロンプトで整数以外の up を入力すると、int()関数は . で失敗しValueErrorます。私は、可能な限り簡単な対処方法を選びました。エラーが発生した場合は、メッセージを出力して終了します。エラーが発生した場合にプログラムが再度入力を求めるようにすることもできますが、それはこの演習の範囲を超えていると考えました。

    if 0 < pwd_len < 26:
        new_pwd = ""
        for _ in range(pwd_len):
            new_pwd += nextchar(possible_chars)
        print("Your new password is:\n" + new_pwd)

    else:
        print("I can only generate passwords between 1 and 25 characters long.")

ここですべてのアクションが行われます。ブロックを使用してif/else、必要なパスワードの長さをテストし、それが 1 ~ 25 (任意の上限) の場合、パスワードを生成します。これは、forループとrange()関数で行われます (正確にどのように機能するかについては、ドキュメントを参照してください)。ループで一般的な Python イディオムを使用していることに気付くでしょう。for実際にはによって生成された数値は必要ないため、変数の代わりにアンダースコア文字を使用しrange()「破棄」しています。_最後に、elseステートメントは代替を処理します - pwd_len0 以下、または 26 以上です。

else:
    print("Well then, why did you run me?")

プログラムの最後に来ました!これelseif yes_or_no == 'yes':ステートメントと対になっています - ユーザーが入力プロンプトで yes 以外を入力しました。

これにより、Python の仕組みと、Python を使用して効率的にプログラミングする方法について、少しでも理解を深めることができれば幸いです。もっと簡単であるべきだと思うものを実装するのに少し時間がかかりすぎていると感じたら、それはおそらく正しいことです。Python の多くの利点の 1 つは、「バッテリーを含む」という哲学です。stdlib でできることは非常に多岐にわたります。

于 2016-05-04T20:56:32.660 に答える
0

この単純な問題に対してなぜ複雑になりすぎているのかわかりません。stringオブジェクトによって提供される定数を使用できます。ランダムなパスワードを生成するには、次のプログラムが必要です

import random, sys, string

def pgen(length=8):
    if length < 8:
        length = 8 
    keys = list(string.printable[:-6])
    random.shuffle(keys)
    return ''.join(keys)[:length]


if __name__ == '__main__':
    try:
        print( pgen(int(sys.argv[1])))
    except Exception as e:
        print("Provide length of password \n passwordgen.py <length_of_password>")

出力

magautam@nix1947:/tmp$ python passwordgen.py 12
HNLxi!{.qe=b

magautam@nix1947:/tmp$ python passwordgen.py 45
}w5u?+C=e[DfI.n'*1G(m{r0FH|UBKz/@kL>;Sh`tEW8-
于 2016-07-01T10:47:49.063 に答える
0

いくつかの小さな編集を行いましたが、私のコードは現在機能しているようです。完成品は次のとおりです (コードが何をするかを示すためにコメントを入れ、編集をマークします):

import math
import random                                 #Import necessary modules
alpha = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']  #List with alphabet
print('Would you like a random password suggestion generator', 'Yes or No')  #Prints the question for permission
permissionRandomGenerator = input().lower()   #Stores the answer of the above question in lower case
if permissionRandomGenerator == 'yes':        #Generates a password if the answer of the first question is 'yes'
print('How long do you want your password?')  #Asks for length
lengthRandomGenerator = int(input())          #Stores length as an integer
    def randInt():                            #Creates a random integer
        return math.floor(random.random()*10)
    def randChar():                          #Selects a random string from the list with the alphabet
        return alpha[math.floor(random.random()*27) - 1]
    randPasswordList = []                    #Creates a list to store the password
    listInsert = 0                           #Creates a list index variable
    def changeCase(f):                       #Defines a function to randomly change the case of letters before adding them to the list randPasswordList
        g = round(random.random())
        if g == 0:
            return f.lower()
        elif g == 1:
            return f.upper()
    while listInsert < lengthRandomGenerator + 1:  #Creates a random password and inserts it into randPasswordList  (I added `+ 1` here)
        randPasswordList.insert(listInsert, randInt())
        listInsert = listInsert + 1
        if listInsert >= lengthRandomGenerator:
            break
        randPasswordList.insert(listInsert, randChar())
        randPasswordList[listInsert] = changeCase(randPasswordList[listInsert])    #Calls the changeCase function whenever it inserts a letter
        listInsert = listInsert + 1
        continue
    listInsert = 0
    printList = 0
    if lengthRandomGenerator <= 0:           #If the length it 0 or less (for example, negatives) the password will not generate (I need to fix this a little bit.  Currently the code attempts to create a password beforehand)
        print('It has to be longer than that')
    elif lengthRandomGenerator >= 25:
        print('I can\'t generate a password that long')
    elif math.isnan(lengthRandomGenerator):  #Currently this doesn't do anything, it needs to be moved farther forward
        print('error: not valid data type')
    else:
        while printList < (len(randPasswordList)-1):    #Prints the list item by item
            printItem = randPasswordList[printList]
            print(printItem)
            printList = printList + 1
    printList = 0                             #Resets the variables
    randPasswordList = []
elif permissionRandomGenerator == 'no':
    print('Too bad...')
else:
    print('You had to answer Yes or No')

注: このコードは、純粋に実験を行い、Python の基本的な側面をよりよく学習するために作成しました。このコードは最適化されておらず、私が作成できる (そして作成する) ほどランダムでもありません。

PS コメントが不完全な場合は申し訳ありません。私はまだこの言語を学んでいます。

于 2016-05-04T21:03:58.320 に答える