I'm writing a mini diceware program designed to take inputs from the users with real dice, look up the values, and print out their diceware passphrase.
The code I have at the moment works fine and pulls the number and words from a wordlist by searching for the 5-digit diceware identifier (e.g. 34465 jilt).
But, I'm hoping to make the pass phrase print as one line without the number association. e.g. as
"jilt load re open snap" instead of
34465 jilt
load
etc.
At the moment this is that code I'm using:
p_length = int(raw_input("How many dicewords?"))
roll_list = []
for i in range(p_length):
seq1 = (raw_input("roll 1:"), raw_input("roll 2:"),
raw_input("roll 3:"), raw_input("roll 4:"),
raw_input("roll 5:"))
str1 = "".join(seq1)
roll_list.append(str1)
print roll_list
with open("name_list.txt") as f:
for line in f:
for x in roll_list:
if x in line:
print line
Any suggestions on how to change the last few lines there to do what I'm hoping?
Thanks for the split() advice. Here is my solution:
passphrases = []
with open("name_list.txt") as f:
for line in f:
for x in roll_list:
if x in line:
var1 = line.split(" ")
var2 = var1.pop( )
passphrases.append(var2.rstrip('\n'))
print " ".join(passphrases)
You can use any here.Updated for just fixing.
for line in f:
if any(i for i in roll_list if i in line.strip()):
print line.strip().split(" ")[-1]
>>>hold romeo
You can use split to break up a line and extract just the word w/o the number.
Related
So I want to make this script look for a word, which you can determine, and its line number. I want it to print out the text in this line and the two following ones. How do I code the last part (print the next three lines)?
def search_passwords():
file = open("D:\\Libaries\\Documents\\resources_py\\pw.txt", "r")
print()
search = input("Enter service: ")
print()
for line in file:
if search in line:
print(the next three lines)
There are some corner cases that you did not mention.
What if multiple lines have the searching word? What is your expected behavior?
What if the line right after the matching line has the searching word?
How large is the file and could you load it in memory?
If there's only one matching, or there won't be any matching in the lines you print right after, then you can use a single counter
def search_passwords():
file = open("D:\\Libaries\\Documents\\resources_py\\pw.txt", "r")
print()
search = input("Enter service: ")
print()
counter = 0
for line in file:
if counter > 0:
counter -= 1
print(line)
if search in line:
counter = 2
print(line)
However, this will double print the lines if the following lines containing the searching word. You can of course make the second if elif, but then it will just ignore the following matching pattern.
And, if you only need the first or only appearance, you should break out of the loop once you print everything, not read the whole file.
Just like I said, you need to know the expected behavior and the requirement better, to write a solid program.
There could be a better solution but this is a bit more flexible with a nigher amount of following rows.
def search_passwords():
file = open("D:\\Libaries\\Documents\\resources_py\\pw.txt", "r")
print()
search = input("Enter service: ")
print()
counter = 3
found = False
for line in file:
if search in line:
found = True
if found:
if counter > 0:
counter -= 1
print(line, counter)
if counter == 0:
break
Yet another approach with not found error handling:
with open('file.txt', 'r') as f:
lines = [line.strip() for line in f.readlines()]
try:
i = lines.index(input('Enter service: '))
for j in range(i, i+3):
try:
print(lines[j])
except IndexError:
pass
except ValueError:
print('Service not found!')
I'm doing a database using txt files in which the data is stores like this: idTheme|Name|Hours.
For example: 45|Object Oriented Programming|12
I need to print the line of text with the idTheme I'm given, so I did this:
print("Give me the ID")
id_search = input("> ")
for line in file:
for x in line:
if id_search != x:
break
else:
print(line)
break
Since the ID is always the first character in each line I thought thst would work.
Problem is, this only works when the ID is 1 character long.
I was thinking on putting the info on a list and using a split("|") to divide it but that would put all the info in the list, not only the IDs.
Any suggestions are apreciated.
You could use split as you said and just use index 0 to get the ID.
for line in file:
id = line.split("|")[0]
if id_search == id:
print(line)
You can invert your if statement so if the id is equal to the search term it prints the line, otherwise nothing happens. You also avoid looping through the entire line.
You can use somethign like:
with open("text.txt") as f:
lines = [x.strip() for x in list(f) if x]
print("Give me the ID")
id_search = input("> ").strip()
if id_search:
for line in lines:
id, name, otherid = line.split("|")
if id_search == id:
print(line)
break
Demo
So, I have an issue that I have been trying to solve countless times over the past few hours which is:
I have been trying to have the program pick a certain line in a text file, and once it has done that, it needs to use the line number that it has selected to use in another file.
So let's say that the file is called "a.txt" and the other file is called "b.txt", I need the program to pick a random line (1,50) and then display the line it picked out, but then it needs to do the same with the other file, so that the same line number is picked in both files.
The code that I currently have:
import random
with open("a.txt") as word_file:
words = word_file.read().split()
randomw = random.choice(words)
with open("b.txt") as artist_file:
words = artist_file.read().split()
randname=random.choice(words)
print(randomw +" "+ randname)
Thanks for any help!
Basically, you need random.randint:
import random
with open('a.txt') as f1, open('b.txt') as f2:
data1 = f1.readlines()
index = random.randint(0, len(data1))
line1 = data1[index]
try:
line2 = f2.readlines()[index]
except IndexError:
line2 = None
print("Not enough lines, dude!")
You were pretty close.
import random
with open("a.txt") as word_file:
words = word_file.read().split()
random_line = random.choice(range(0, len(words))
randomw = words[random_line]
with open("b.txt") as artist_file:
words = artist_file.read().split()
randname=words[random_line]
print(randomw +" "+ randname)
Pick a random number first, and refer to that when you read your lines.
Additionally, if this is a real world problem where you won't always know the line count, you might want to get the line count of each file, sort those two numbers, and force your random line to be within the range of the shorter (by line count) file.
Using enumerate to get the line and the line number while iterating:
import random
with open("a.txt") as word_file:
number, line1 = random.choice([(number, line) for number, line in enumerate(word_file)])
with open("b.txt") as artist_file:
line2 = artist_file.readlines()[number]
Zip the two files together, then pick a tuple
with open("a.txt") as word_file, open("b.txt") as artist_file:
randomw, randname = random.choice(list(zip(word_file, artist_file)))
It's concise, but comes at a price: random.choice requires the full contents to be read into memory.
If you know how many lines there are, you can simply choose a line number at random.
# n == number of lines
random_line = random.randint(0, n-1)
with open("a.txt") as word_file, open("b.txt") as artist_file:
for i, pair in enumerate(zip(word_file, artist_file)):
if i == random_line:
break
randomw, randname = pair
I have a file I'm searching through and printing the results to a file. I'm wondering if it's possible to amend the code below to read in multiple search terms i.e. print any line that has "test" or "hello" (user will specify) in it but have Python create a new output file for each search term?
i.e. Ofile1 would hold all lines containing "test"
Ofile2 would hold all lines containing "hello" and so on
f = open('file3.txt') #input file
term = raw_input("What would you like to search for?") #takes an input to be searched
for line in f:
if term in line:
print (line) #print line of matched term
f.close() #close file
Is this possible to do?
Based of #new user code (improved some error) you could do something like this:
terms = raw_input("What would you like to search for?")
terms = terms.split(" ")
for term in terms:
f = open('text.txt')
filename = '{}_output.txt'.format(term)
o = open(filename, 'w')
for line in f:
if term in line:
o.write(line)
o.close()
f.close()
Maybe you can think that is better open the file once and check some term per each line. Depending of number of terms it will be more or less efficient, if you want could research about it using really big files to check execution times and learn a bit more.
Split your term by spaces. then use a for loop to loop through all of the terms.
ex:
terms = term.split(" ")
for t in terms:
filename = t +"_output.txt"
o = open(filename,'w')
for line in f:
if t in line:
o.write(line) #print line of matched term
o.close()
import random
com=input("")
if com.startswith("/tip"):
numlines=sum(1 for line in open("C:\\Users\\Jace\\Desktop\\Python Programs\\Quote\\tip.txt"))-1
randomint=random.randint(0, numlines)
with open("C:\\Users\\Jace\\Desktop\\Python Programs\\Quote\\tip.txt", "r") as f:
i=1
for line in f:
if i==randomint:
break
i+=1
print(line.strip("\n"))
This is the part of the code for my random tips from a file so far. I wish to add another part of code where it adds all strings with any occurrence of the input placed after "/tip ", for example, if I were to type "/tip Hello", it would compile all lines in the text file with "Hello" in the string and do a random.choice() from the list, printing the one chosen. I don't really know where to start with this, any help would be appreciated. Thanks in advance!
You don't have to store all of the lines in a list. You can read the lines, selecting one at random and discarding the rest. This is called "resevoir sampling".
Your code might look like this:
import random
def random_line(iterator):
result = None
for n, item in enumerate(iterator):
if random.randint(0,n) == 0:
result = item
return result
# A random line
with open('tip.txt') as f:
print random_line(f) or "No tip for you!"
# A random line that has 'Hello'
with open('tip.txt') as f:
print random_line(line for line in f if 'Hello' in line) or "nothin!"
As a more special case, this code randomly chooses a matching line from the tips file, but falls back to a random non-matching line if no match exists. It has the advantages of reading the input file exactly once, and not having to store the entire tips file in memory.
import random
def random_line_with_fallback(iterator, match = lambda x: True):
result_match = None
result_all = None
n_match = n_all = 0
for item in iterator:
if match(item):
if random.randint(0, n_match) == 0:
result_match = item
n_match += 1
if random.randint(0, n_all) == 0:
result_all = item
n_all += 1
return (result_match or result_all).strip()
# A random line
with open('tip.txt') as f:
print random_line_with_fallback(f)
# Another way to do a random line. This depends upon
# the Python feature that "'' in line" will always be True.
com = ''
with open('tip.txt') as f:
print random_line_with_fallback(f, lambda line: com in line)
# A random line that has 'Hello', if possible
com = 'Hello'
with open('tip.txt') as f:
print random_line_with_fallback(f, lambda line: com in line)
References:
https://stackoverflow.com/a/23840292/8747
https://en.wikipedia.org/wiki/Reservoir_sampling
I think this is what you want, process each line of a text file, checking if the line has the word you're looking for. If so, add it to a list, and the randomly select one "line" for all possible "lines".
lines = []
with open("tip.txt", "r") as f:
for line in f:
if com in line:
lines.append(line)
print(random.choice(lines))