adds file handling and login generator
This commit is contained in:
parent
8dc74e59e8
commit
83e42b682c
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,56 @@
|
|||
import random
|
||||
import string
|
||||
|
||||
|
||||
def load_file(filename):
|
||||
"""
|
||||
We load a file and make a list out of it. Note that the same function is
|
||||
used for both files (both adjectives and subjects). Functions should be
|
||||
made as generic as possible.
|
||||
|
||||
There IS a problem you can fix, some logins will have spaces in them. Try
|
||||
to remove them in this function!
|
||||
"""
|
||||
words = []
|
||||
with open(filename, "r") as fp:
|
||||
lines = fp.readlines()
|
||||
for line in lines:
|
||||
words.append(line.strip()) # what does strip() do, what does append() do? remember CTRL+Q!
|
||||
return words
|
||||
|
||||
|
||||
def generate_username():
|
||||
"""
|
||||
We'll generate a random pair of adjectives and subjects from two wordlists.
|
||||
You NEED to have both files in you python project for this to work! Note
|
||||
the capitalize method call to make it all prettier...
|
||||
"""
|
||||
adjectives = load_file("./adjectives.txt")
|
||||
subjects = load_file("./subjects.txt")
|
||||
adjective = random.choice(adjectives)
|
||||
subject = random.choice(subjects)
|
||||
username = adjective.capitalize() + subject.capitalize()
|
||||
return username
|
||||
|
||||
|
||||
def generate_password(length=10, complictated=True):
|
||||
"""
|
||||
We generate a password with default settings. You can overide these by
|
||||
changing the arguments in the function call.
|
||||
"""
|
||||
password = ""
|
||||
if complictated:
|
||||
chars = string.ascii_letters + string.digits + string.punctuation
|
||||
else:
|
||||
chars = string.ascii_letters
|
||||
for i in range(0, length):
|
||||
password += random.choice(chars)
|
||||
return password
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# let's do some testing!
|
||||
username_test = generate_username()
|
||||
print(username_test)
|
||||
password_test = generate_password()
|
||||
print(password_test)
|
|
@ -0,0 +1,61 @@
|
|||
import login_generator
|
||||
|
||||
|
||||
def prompt():
|
||||
"""
|
||||
We prompt but you KNOW how this works!
|
||||
"""
|
||||
response = ""
|
||||
while not response.isdigit():
|
||||
response = input("how many login pairs would you like to create?")
|
||||
return int(response)
|
||||
|
||||
|
||||
def how_long():
|
||||
"""
|
||||
And again... (we could combine both prompts, but how?)
|
||||
"""
|
||||
response = ""
|
||||
while not response.isdigit():
|
||||
response = input("how long should the password be?")
|
||||
return int(response)
|
||||
|
||||
|
||||
def complex_or_not():
|
||||
response = ""
|
||||
while response.lower() not in ["y", "n"]:
|
||||
response = input("you want complex passwords? (y/n)")
|
||||
if response.lower() == "y":
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def create_login(length, complicated):
|
||||
"""
|
||||
We use our library to generate the username and password. The double return
|
||||
might look confusing but just look at the for loop in the generate_logins
|
||||
functions and you'll see how it unpacks...
|
||||
"""
|
||||
username = login_generator.generate_username()
|
||||
password = login_generator.generate_password(length, complicated)
|
||||
return username, password
|
||||
|
||||
|
||||
def generate_logins(number, length, complicated):
|
||||
"""
|
||||
Easy no? But what does the i do? Do we really need it's value?
|
||||
"""
|
||||
for i in range(0, number):
|
||||
username, password = create_login(length, complicated)
|
||||
print("username {}: {}".format(i, username))
|
||||
print("password {}: {}".format(i, password))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Here we go!
|
||||
number_of_logins = prompt()
|
||||
complicted = complex_or_not()
|
||||
length = how_long()
|
||||
generate_logins(number_of_logins, length, complicted)
|
||||
|
|
@ -0,0 +1,239 @@
|
|||
Aardvark
|
||||
African elephant
|
||||
Albatross
|
||||
Alley cat
|
||||
Alligator
|
||||
Amphibian
|
||||
Ant
|
||||
Anteater
|
||||
Antelope
|
||||
Ape
|
||||
Armadillo
|
||||
Asian elephant
|
||||
Baboon
|
||||
Badger
|
||||
Bat
|
||||
Bear
|
||||
Beaver
|
||||
Beetle
|
||||
Billy goat
|
||||
Bison
|
||||
Boar
|
||||
Bobcat
|
||||
Bovine
|
||||
Bronco
|
||||
Buck
|
||||
Buffalo
|
||||
Bug
|
||||
Bull
|
||||
Bunny
|
||||
BunnyCalf
|
||||
Camel
|
||||
Canary
|
||||
Canine
|
||||
Caribou
|
||||
Cat
|
||||
Caterpillar
|
||||
Centipede
|
||||
Chanticleer
|
||||
Cheetah
|
||||
Chick
|
||||
Chimpanzee
|
||||
Chinchilla
|
||||
Chipmunk
|
||||
Clam
|
||||
Cockatiel
|
||||
Colt
|
||||
Condor
|
||||
Cougar
|
||||
Cow
|
||||
Coyote
|
||||
Crab
|
||||
Crane
|
||||
Creature
|
||||
Crocodile
|
||||
Crow
|
||||
Cub
|
||||
Cur
|
||||
Cygnet
|
||||
Deer
|
||||
Dingo
|
||||
Dodo
|
||||
Doe
|
||||
Dog
|
||||
Dolphin
|
||||
Donkey
|
||||
Dove
|
||||
Drake
|
||||
Duck
|
||||
Eagle
|
||||
Egret
|
||||
Elephant
|
||||
Elk
|
||||
Emu
|
||||
Ewe
|
||||
Falcon
|
||||
Fawn
|
||||
Feline
|
||||
Ferret
|
||||
Flamingo
|
||||
Flee
|
||||
Flies
|
||||
Foal
|
||||
Fowl
|
||||
Fox
|
||||
Frog
|
||||
Gander
|
||||
Gazelle
|
||||
Gelding
|
||||
Gerbil
|
||||
Gibbon
|
||||
Giraffe
|
||||
Goat
|
||||
Goose
|
||||
Gopher
|
||||
Gorilla
|
||||
Grizzly bear
|
||||
Guinea pig
|
||||
Hamster
|
||||
Hare
|
||||
Hawk
|
||||
Hedgehog
|
||||
Heifer
|
||||
Hippopotamus
|
||||
Horse
|
||||
Hound
|
||||
Hummingbird
|
||||
Hyena
|
||||
Ibis
|
||||
Iguana
|
||||
Jackal
|
||||
Jackrabbit
|
||||
Jaguar
|
||||
Javalina
|
||||
Jellyfish
|
||||
Jenny
|
||||
Joey
|
||||
Kangaroo
|
||||
Kid
|
||||
Kitten
|
||||
Kiwi
|
||||
Koala
|
||||
Komodo dragon
|
||||
Krill
|
||||
Lamb
|
||||
Lemming
|
||||
Lemur
|
||||
Leopard
|
||||
Lion
|
||||
Lioness
|
||||
Llama
|
||||
Lobster
|
||||
Lynx
|
||||
Macaw
|
||||
Manatee
|
||||
Marmoset
|
||||
Marmot
|
||||
Mink
|
||||
Minnow
|
||||
Mite
|
||||
Mockingbird
|
||||
Mole
|
||||
Mongoose
|
||||
Mongrel
|
||||
Monkey
|
||||
Moose
|
||||
Mouse
|
||||
Mule
|
||||
Mustang
|
||||
Mutt
|
||||
Nag
|
||||
Narwhale
|
||||
Newt
|
||||
Ocelot
|
||||
Octopus
|
||||
Opossum
|
||||
Orangutan
|
||||
Orca
|
||||
Osprey
|
||||
Ostrich
|
||||
Otter
|
||||
Owl
|
||||
Ox
|
||||
Pachyderm
|
||||
Panda
|
||||
Panther
|
||||
Parakeet
|
||||
Parrot
|
||||
Peacock
|
||||
Pelican
|
||||
Penguin
|
||||
Pheasant
|
||||
Pig
|
||||
Pigeon
|
||||
Piglet
|
||||
Platypus
|
||||
Pony
|
||||
Pooch
|
||||
Porcupine
|
||||
Porpoise
|
||||
Primate
|
||||
Puppy
|
||||
Pussycat
|
||||
Rabbit
|
||||
Raccoon
|
||||
Ram
|
||||
Rat
|
||||
Reptiles
|
||||
Rhinoceros
|
||||
Robin
|
||||
Rooster
|
||||
Salamander
|
||||
Sea lion
|
||||
Seagull
|
||||
Seal
|
||||
Sheep
|
||||
Sidewinder
|
||||
Skunk
|
||||
Sloth
|
||||
Snail
|
||||
Snake
|
||||
Songbird
|
||||
Sow
|
||||
Spider
|
||||
Squid
|
||||
Squirrel
|
||||
Stallion
|
||||
Steer
|
||||
Stork
|
||||
Stork
|
||||
Swan
|
||||
Tadpole
|
||||
Tapir
|
||||
Terrapin
|
||||
Thoroughbred
|
||||
Tiger
|
||||
Toad
|
||||
Tortoise
|
||||
Toucan
|
||||
Turkey
|
||||
Uakari
|
||||
Unicorn
|
||||
Vixen
|
||||
Vole
|
||||
Vulture
|
||||
Wallaby
|
||||
Walrus
|
||||
Warthog
|
||||
Wasp
|
||||
Weasel
|
||||
Whale
|
||||
Wildebeast
|
||||
Wolf
|
||||
Wombat
|
||||
Woodpecker
|
||||
Worm
|
||||
X-ray fish
|
||||
Yak
|
||||
Zebra
|
||||
|
|
@ -1509,23 +1509,129 @@ print(digits)
|
|||
|
||||
# Handling files
|
||||
|
||||
When we `import` a library python will read and execute the file in question.
|
||||
We can also just *read* a simple text file and *use* the data that's in the file.
|
||||
There are two ways of reading a file, one more *pythonic* and one more linear.
|
||||
I'll outline both and you can use whichever seems more logical to you.
|
||||
|
||||
## Reading from a file
|
||||
|
||||
### In-line way
|
||||
|
||||
The builtin function `open` is what's new here.
|
||||
It takes two arguments, one is the [path](https://en.wikipedia.org/wiki/Path_(computing)) and the other is a *mode*.
|
||||
The most used modes are **read** or **write**, and this as either **text** or **binary**.
|
||||
Have a look at the documentation to discover more modes.
|
||||
|
||||
```python3
|
||||
fp = open("./examples/data.txt", "r")
|
||||
data = fp.readlines()
|
||||
print("file contains: {}".format(data))
|
||||
fp.close()
|
||||
```
|
||||
|
||||
### Pythonic way
|
||||
|
||||
The *exact* same thing can be done in a more pythonic way as follows.
|
||||
The beauty of the `with` syntax is that the `close` function call is implied by the indentation.
|
||||
I personally prefer this way of reading and writing files but you do you!
|
||||
|
||||
```python3
|
||||
file_to_open = "./examples/data.txt"
|
||||
|
||||
with open(file_to_open, "r") as fp:
|
||||
data = fp.readlines()
|
||||
print("file contains: {}".format(data))
|
||||
|
||||
print("{} has {} lines".format(file_to_open, len(data)))
|
||||
```
|
||||
|
||||
## Writing to a file
|
||||
|
||||
## csv, JSON and yaml
|
||||
Writing to a file can also be done in two ways, a pythonic and *less* pythonic way.
|
||||
As I prefer the pythonic way I'll only showcase that one but you'll be able to easily adapt the code yourself.
|
||||
The only difference is the **mode** we use to `open` the file.
|
||||
|
||||
## pickle
|
||||
```python3
|
||||
first_name = input("what's your first name? ")
|
||||
last_name = input("what's your last name? ")
|
||||
birthday = input("what's your date of birth? ")
|
||||
|
||||
data = [first_name, last_name, birthday]
|
||||
|
||||
file_to_open = "./examples/test.tmp"
|
||||
|
||||
with open(file_to_open, "w") as fp:
|
||||
for element in data:
|
||||
fp.write("{}\n".format(element))
|
||||
print("done!")
|
||||
```
|
||||
|
||||
There is also a way to write a batch of lines to a file in one go.
|
||||
This is done as follows.
|
||||
But, you'll notice there is no **newline** added after each element.
|
||||
|
||||
```python3
|
||||
data = ["wouter", "gordts", "1986"]
|
||||
|
||||
file_to_open = "./examples/test.tmp"
|
||||
|
||||
with open(file_to_open, "w") as fp:
|
||||
fp.writelines(data)
|
||||
```
|
||||
|
||||
# Coding challenge - Login generator
|
||||
|
||||
TODO write a login generator as a library with a cli as program
|
||||
BONUS argparse, save to file, read from file
|
||||
Can you write me a program that creates random, but easy to remember, usernames?
|
||||
Plus, for each username also a *not-so-easy-to-remember* password?
|
||||
Maybe with a bit of flexibility?
|
||||
For example variable password length?
|
||||
|
||||
This is an exercise you can take pretty far if you plan it out properly.
|
||||
I would advise you to write the **generator** functions as a library.
|
||||
Then import those functions into the program where you implement the user facing logic.
|
||||
By doing so you can reuse your code for multiple interfaces (CLI, TUI, [argparse](https://docs.python.org/3/howto/argparse.html)).
|
||||
If you want to you can also **save** your logins to a file!
|
||||
|
||||
An example of the output I expect:
|
||||
|
||||
```
|
||||
how many login pairs would you like to create?3
|
||||
you want complex passwords? (y/n)y
|
||||
how long should the password be?32
|
||||
username 0: EarnestCrocodile
|
||||
password 0: :sdGV&[FDYZZ|RXUpZeo`J&t@*Z>^fEW
|
||||
username 1: AbstractedDragon
|
||||
password 1: 32hz5&C@<o\OMa9tnET(lk(3wF%d?$Dy
|
||||
username 2: MeekStallion
|
||||
password 2: +;^di8a":AD;_b4^w$Fj'RVkI`CoG,LX
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Spoiler warning</summary>
|
||||
|
||||
This spoiler warning is in multiple steps.
|
||||
If you're unsure how to generate the *random-yet-easy-to-remember* have a look at [this file](./assets/subjects.txt) and [this file](./assets/adjectives.txt).
|
||||
|
||||
**Stop here and try it out!**
|
||||
|
||||
If you're unsure how to tackle the *library part* of this exercise, have a look at [this file](./assets/login_generator.py).
|
||||
Don't just copy this code, read it and recreate it yourself!
|
||||
|
||||
**Stop here and try it out!**
|
||||
|
||||
Once the library is done you can code the *interface*.
|
||||
For some inspiration for a simple question/response system you can have a look [here](./assets/pwd_cli.py).
|
||||
|
||||
|
||||
</details>
|
||||
|
||||
# Dictionaries as data containers
|
||||
|
||||
TODO adapt the login generator to output a dict
|
||||
|
||||
## csv, JSON and yaml
|
||||
|
||||
# Creating our own classes
|
||||
|
||||
## Class examples
|
||||
|
|
Loading…
Reference in New Issue