I came across a project geared toward starters like myself - creating a CLI passwordcreator.
I have with the help of a few guides completed the generator and added a few of my own features, however there is one feature I can't seem to figure out how to implement; saving the output to a file.
In the terminal the passwords shows up perfectly fine line by line, however if I try to save the output to a file it only saves the last password, and it seperates each letter by line.
My code is below, together with examples of output from both the terminal and a .txt file.
import string
import random
from os import system, name
letters = list(string.ascii_letters)
digits = list(string.digits)
special_characters = list("!##$%^&*()£")
characters = list(string.ascii_letters + string.digits + '!##$%^&*()£')
def clear():
if name == 'nt':
_ = system('CLS')
else:
_ = system('clear')
def generate_random_password():
clear()
length = int(input("Enter password length: "))
amount = int(input('Enter amount of passwords: '))
letters_count = int(input("Enter letter count: "))
digits_count = int(input("Enter digits count: "))
special_characters_count = int(input("Enter special characters count: "))
character_count = letters_count + digits_count + special_characters_count
if character_count > length -1:
print("Characters total count is greater than desired password length")
exit()
clear()
password = []
print("Following passwords saved to Passwords.txt, please move the file before generating new passords, as a new generation will overwrite existing")
print('\n')
for pwd in range(amount):
password = []
for c in range(digits_count):
password.append(random.choice(digits))
for c in range(letters_count):
password.append(random.choice(letters))
for c in range(special_characters_count):
password.append(random.choice(special_characters))
if character_count < length:
random.shuffle(characters)
for c in range(length - character_count):
password.append(random.choice(characters))
random.shuffle(password)
if str(password) < str(length):
return()
else:
print("".join(password))
with open('Passowrds.txt', 'w') as file:
for line in ("".join(password)):
file.write(line)
file.write('\n')
#file = open('Passwords.txt', 'w')
#str1 = repr(password)
#file.write('\n' + str1 + '\n')
#file.close
#f = open('Passwords.txt', 'r')
#if f .mode == 'r':
# contents=f.read
generate_random_password()
This is what the output from the terminal looks like:
Following passwords saved to Passwords.txt, please move the file
before generating new passords, as a new generation will overwrite
existing
gtBVA3QDcUohDc£TfX(zVt*24
KD8PnMD£)25hvHh#3xj79$qZI
Dx^*2£srcLvRx5g3B3(nq0H&9
&r6^3MEsaV1RuDHzxq*(h3nO)
However what is saved in the .txt file looks like this:
&
r
6
^
3
M
E
s
a
V
1
R
u
D
H
z
x
q
*
(
h
3
n
O
)
The reason why your script is saving only 1 password is because you are opening the file to be written (which clears the contents of the file) for every password you are generating.
You want to do something along the lines of:
passwords = []
for _ in range(num_passwords):
password = ...
passwords.append(password)
with open("password.txt", "w") as f:
f.writelines(passwords)
Although there is nothing terrible about the way you're using the random library, I recommend taking a look at random.sample (without replacement) or random.choices (with replacement).
Also, using shuffling your characters list isn't adding additional randomness to your random.choice.
You don't have to convert the strings to lists in order to run choice:
>>> import random
>>> random.choice("abc")
'b'
A fuller example:
def generate_random_password():
clear()
length = int(input("Enter password length: "))
amount = int(input("Enter amount of passwords: "))
letters_count = int(input("Enter letter count: "))
digits_count = int(input("Enter digits count: "))
special_characters_count = int(input("Enter special characters count: "))
character_count = letters_count + digits_count + special_characters_count
if character_count > length - 1:
print("Characters total count is greater than desired password length")
exit()
clear()
passwords = []
for _ in range(amount):
chosen_digits = random.choices(digits, k=digits_count)
chosen_letters = random.choices(letters, k=letters_count)
chosen_special_characters = random.choices(
special_characters, k=special_characters_count
)
extra_characters_count = length - character_count
extra_characters = random.choices(characters, k=extra_characters_count)
password = (
chosen_digits
+ chosen_letters
+ chosen_special_characters
+ extra_characters
)
random.shuffle(password)
passwords.append("".join(password))
with open("Passwords.txt", "w") as f:
f.writelines(passwords)
Related
import random
chars = "abcdefghijklmnopqrstuvwxyz"
numbers = "123456789"
while 1:
password_len = int(input(" What length for the passwords: "))
password_count = int(input(" How many passwords would you like to generate: "))
txtfile = open('passwords.txt','w')
for x in range(0,password_count):
password = ""
for x in range(0,password_len):
password_char = random.choice(chars + numbers)
password = password + password_char
txtfile.write(password + '\n')
txtfile.close()
print("Generated: ") #<--counter`
I would want some help, bellow is a gif with the live counter.
https://i.stack.imgur.com/UzULp.gif
This prints the count every 1,000 lines:
for x in range(password_count):
password = ""
for _ in range(password_len):
password += random.choice(chars + numbers)
if x % 1000 == 0:
print(x,end='\r')
txtfile.write(password + '\n')
For 100,000 passwords, it only takes 2.5 seconds, so there's not much to see.
I am working on some code for a homework assignment where I have to take the numbers in a the file, calculate the sum of them all, the average and how many lines there are. This is what I've come up with so far
invalidEntry= True
#Input validation
while (invalidEntry) :
try:
total = 0
lines = 0
Validate= input("Please enter the name of the text file. : ")
if Validate ==("Random.txt") :
red= open( 'Random.txt', 'r')
for count in red:
strip = line.strip("\n")
lines += 1
average = total/200
total = total + int(count)
print("The number of lines is : ",lines)
print ("The total sum is : " ,total)
print("The average is :" , average
invalidEntry= False
except:
print("This isn't a valid file!")
I keep getting a syntax error for the except function and I'm unsure if I have the input validation set up properly. Any help would be appreciated.
Try with:
except Exception as err:
Try this, fixed a few bugs for you:
import os
total = 0
lines = 0
# Input the file
IfValidate = False
while IfValidate == False:
validate = input("Please enter the name of the text file: ")
if os.path.isfile(validate) == True:
IfValidate = True
# Open the file
f = open(validate, 'r')
# Read every line and make it a list
f = f.readlines()
for line in f:
# Strip of \n
strip = line.strip("\n")
# Make the number a number
num = int(strip)
lines += 1
average = total / 200
total = total + int(num)
print("The number of lines is : ", lines)
print ("The total sum is : " , total)
print("The average is :" , average)
Ok this function works perfectly, I just need to know how do i make it so it so the random integers that are generated, are written to the mynumbers.txt file.
def main():
#Open a file for writing
outfile = open ('mynumbers.txt' , 'w')
#Generate random integer number
from random import randint
number = randint(6, 12)
print("Write will create", number, "random numbers")
import random
i = 0
while i < 11:
# Get random number in range 10 through 20.
n = random.randint(10, 20)
print(n)
i += 1
#Write the numbers to the file
foo = ""
while (i):
#find n
foo += str(n) + " "
outFile.write(foo)
#Call the main function
main()
Is this right?
Try opening the file with the append option instead: outfile=Open("[FileName]", "a") Then you can do a outfile.write(str(n) + " ") where n is the number you wish to write. Of course you can pick a deliminator other than " ".
Alternatively, you could store all of the numbers in a string. And write them all at the end.
foo = ""
while (looping):
#find n
foo += str(n) + " "
outFile.write(foo)
===REVISED===
import random
output = ""
deliminator = "\n" #Put a line-break after each number
filepath = "mynumbers.txt"
i = 0
while i < 11:
# Get random number in range 10 through 20.
n = random.randint(10, 20)
print(n) #is this necessary?
i += 1
output += str(n) + deliminator
#Write the numbers to the file
with open(filepath, 'w') as file:
file.write(output)
So I recently coded this as a little challenge to see how quick I could do it. Now since its working an such I want to speed it up. It finds all the proper devisors of a number, the highest proper devisor and times how long it all takes. The problem is with number like 5000 it takes 0.05 secs but with numbers like 99999999999 it takes 1567.98 secs.
this the old code I have made a new and improved version below
import time
def clearfile(name):
file = open(name + ".txt", "r")
filedata = file.read()
file.close()
text_file = open(name + ".txt", "w")
text_file.write("")
text_file.close()
def start():
num = input("Enter your Number: ")
check(num)
def check(num):
try:
intnum = int(num)
except ValueError:
error(error = "NON VALID NUMBER")
if(intnum < 0):
error(error = "POSITIVE NUMBERS ONLY")
else:
finddivisor(intnum)
def finddivisor(intnum):
starttimer = time.time()
i = 1
print("\nThe divisors of your number are:"),
while i <= intnum:
if (intnum % i) == 0:
print(i)
file = open("numbers.txt", "r")
filedata = file.read()
file.close()
text_file = open("numbers.txt", "w")
text_file.write(str(i) +"\n"+ filedata)
text_file.close()
i += 1
properdivisor(starttimer)
def properdivisor(starttimer):
file = open("numbers.txt", "r")
highest = file.readlines()
print("\nThe Highest Proper Divisor Is\n--------\n" + highest[1] + "--------" + "\nIt took" ,round(time.time() - starttimer, 2) ,"seconds to finish finding the divisors.\n")
restart(errorrestart = "false")
def restart(errorrestart):
if errorrestart == "false":
input("Do You Want Restart?\nPress Enter To Restart Or Close The Programe To Leave")
start()
elif errorrestart == "true":
input("\nThere Was An Error Detected.\nPress Enter To Restart Or Close The Programe To Leave")
start()
def error(error):
print("\n----------------------------------\nERROR - " + error + "\n----------------------------------")
restart(errorrestart = "true")
clearfile(name = "numbers")
start()
Can someone speed it up for me
EDIT 1
so after looking over it I have now edited it to be moving it away from a file to an array
import time
from array import *
def programme():
num = input("Enter your Number: ")
try:
intnum = int(num)
except ValueError:
error("NOT VALID NUMBER")
if(intnum < 0):
error("POSITIVE NUMBERS ONLY")
else:
numbers = array("i",[])
starttimer = time.time()
i = 1
print("\nThe divisors of your number are:"),
while i <= intnum:
if (intnum % i) == 0:
numbers.insert(0,i)
print(i)
i += 1
print("\nThe Highest Proper Divisor Is\n--------\n" + str(numbers[1]) + "\n--------" + "\n\nIt took" ,round(time.time() - starttimer, 2) ,"seconds to finish finding the divisors.\n")
def error(error):
print("\n----------------------------------\nERROR - " + error + "\n----------------------------------\n")
running = True
while(running == True):
programme()
print("----------------------------------")
restart = input("Do You Want Restart?")
restart = restart.lower()
if restart in ("yes", "y", "ok", "sure", ""):
print("Restarting\n----------------------------------")
else:
print("closing Down")
running = False
New Edit
import time, math
from array import *
def programme():
num = input("Enter your Number: ")
try:
intnum = int(num)
if(intnum < 0):
error("POSITIVE NUMBERS ONLY")
else:
numbers = array("i",[])
starttimer = time.time()
i = 1
print("\nThe divisors of your number are:"),
while i <= math.sqrt(intnum):
if (intnum % i) == 0:
numbers.insert(0,i)
numbers.insert(0,int(intnum/i))
print(i,":", int(intnum/i))
i += 1
numbers = sorted(numbers, reverse = True)
print("The Highest Proper Divisor Is\n--------\n",str(numbers[1]) , "\n--------\nIt took" ,round(time.time() - starttimer, 2) ,"seconds to finish finding the divisors." )
except ValueError:
error("NOT VALID NUMBER")
except OverflowError:
error("NUMBER IS TO LARGE")
except:
error("UNKNOWN ERROR")
def error(error):
print("\n----------------------------------\nERROR - " + error + "\n----------------------------------\n")
running = True
while(running):
programme()
print("----------------------------------")
restart = input("Do You Want Restart?")
restart = restart.lower()
if restart in ("yes", "y", "ok", "sure", ""):
print("Restarting\n----------------------------------")
else:
print("closing Down")
running = False
If you have divisor a of number n then you can tell one more divisor of n b = n / a. Moreover if a <= sqrt(n) then b >= sqrt(n) and vice versa. It means in your finddivisor function you can iterate while i * i <= n and print both divisors i and n / i.
By the way, you shouldn't open, read and close files in cycle. Open it once before cycle and close after if you need to read/write several times.
You don't need to read and rewrite the entire file every time you want to put a single entry into it. You can just do it once when you know what change you want. Also you could just append to it. Maybe something like this:
def finddivisor(intnum):
starttimer = time.time()
print("\nThe divisors of your number are:")
divs = set()
for i in range(1, int(math.sqrt(intnum)) +1):
if intnum % i == 0:
print(i)
divs.add(i)
divs.add(intnum // i)
with open("numbers.txt", "a") as file:
file.writelines("{}\n".format(ln) for ln in sorted(divs, reverse=True))
also your program flow is building a very deep stack. Try and flatten it with something like
def start():
clearfile()
while True:
n = get_number()
starttimer = time.time()
finddivisor(n)
properdivisor(starttimer)
input("Press Enter To Restart Or Close The Programe To Leave")
in properdivisor you dont need to read the whole file either, you just need the first line. so maybe something like:
def properdivisor(starttimer):
with open(FILENAME, "r") as file:
highest = file.readline().strip()
print "\nThe Highest Proper Divisor Is"
print "--------%s--------" % highest
print "It took %0.2f seconds to finish finding the divisors.\n" % (time.time() - starttimer)
AFTER EDIT
Something like this is how I would do it, and it runs less then a second on my box:
import math
def get_divisors(n):
yield 1
sqroot = int(math.sqrt(n))
for x in xrange(2, sqroot):
if n % x == 0:
yield x
yield n / x
if sqroot**2 == n:
yield sqroot
divisors = sorted(get_divisors(999999999999))
print divisors
I am working on a Hangman game, but I am having trouble replacing the dashes with the guessed letter. The new string just adds on new dashes instead of replacing the dashes with the guessed letter.
I would really appreciate it if anyone could help.
import random
import math
import os
game = 0
points = 4
original = ["++12345","+*2222","*+33333","**444"]
plusortimes = ["+","*"]
numbers = ["1","2","3"]
#FUNCTIONS
def firstPart():
print "Welcome to the Numeric-Hangman game!"
def example():
result = ""
ori = random.choice(original)
for i in range(2,len(ori)):
if i % 2 == 0:
result = result + ori[i] + ori[0]
else:
result = result + ori[i] + ori[1]
return ori
# def actualGame(length):
#TOP LEVEL
firstPart()
play = raw_input("Do you want to play ? Y - yes, N - no: ")
while (play == "Y" and (points >= 2)):
game = game + 1
points = points
print "Playing game #: ",game
print "Your points so far are: ",points
limit = input("Maximum wrong guesses you want to have allowed? ")
length = input("Maximum length you want for the formulas (including symbols) (must be >= 5)? ")
result = "" #TRACE
ori = random.choice(original)
for i in range(2,len(ori)):
if i % 2 == 0:
result = result + ori[i] + ori[0]
else:
result = result + ori[i] + ori[1]
test = eval(result[:-1])
v = random.choice(plusortimes) #start of randomly generated formula
va = random.choice(plusortimes)
formula = ""
while (len(formula) <= (length - 3)):
formula = formula + random.choice(numbers)
formula2 = str(v + va + formula)
kind = ""
for i in range(2,len(formula2)):
if i % 2 == 0:
kind = kind + formula2[i] + formula2[0]
else:
kind = kind + formula2[i] + formula2[1]
formula3 = eval(kind[:-1])
partial_fmla = "------"
print " (JUST TO TRACE, the program invented the formula: )" ,ori
print " (JUST TO TRACE, the program evaluated the formula: )",test
print "The formula you will have to guess has",length,"symbols: ",partial_fmla
print "You can use digits 1 to 3 and symbols + *"
guess = raw_input("Please enter an operation symbol or digit: ")
a = 0
new = ""
while a<limit:
for i in range(len(formula2)):
if (formula2[i] == partial_fmla[i]):
new = new + partial_fmla[i]
elif (formula2[i] == guess):
new[i] = guess
else:
new[i] =new + "-"
a = a+1
print new
guess = raw_input("Please enter an operation symbol or digit: ")
play = raw_input("Do you want to play ? Y - yes, N - no: ")
The following block seems problematic:
elif (formula2[i] == guess):
new[i] = guess
else:
new[i] =new + "-"
Python does not allow modification of characters within strings, as they are immutable (cannot be changed). Try appending the desired character to your new string instead. For example:
elif formula2[i] == guess:
new += guess
else:
new += '-'
Finally, you should put the definition of new inside the loop directly under, as you want to regenerate it after each guess.