Append and replace objects in one string - python

I'm writing a text encoder/crypter (all by myself) and i can't understand how to append and replace characters in the string :-/
The code:
import os, sys, random
dig = 0
text_encoded = ""
text = ""
try:
if os.path.isfile(sys.argv[1]) == True:
with open(sys.argv[1], "r") as text:
text = text.readlines()
except:
pass
if text == "":
print("Write the text to encode")
text = input()
text = text.split()
for _ in range(len(text)):
text_encoded = text[dig].replace("qwertyuiopasdfghjklzxcvbnm ", "mnbvcxzlkjhgfdsapoiuytrewq#")
dig = dig+1
print("Your encoded text is:\n"+text_encoded)
Here is some output:
Write the text to encode
lo lolo lol lol
Your encoded text is:
lol
If you can help me in any way, thank you :-)

If I'm getting you correctly, you want to replace q with m, w with n and so on. Try the following
import os, sys, random
dig = 0
text_encoded = ""
text = ""
try:
if os.path.isfile(sys.argv[1]) == True:
with open(sys.argv[1], "r") as text:
text = text.readlines()
except:
pass
if text == "":
print("Write the text to encode")
text = input()
mychars=list("qwertyuiopasdfghjklzxcvbnm ")
myencode=list("mnbvcxzlkjhgfdsapoiuytrewq#")
charmap=zip(mychars,myencode)
_map = dict(charmap)
encoded_text = ''.join(_map.get(c) for c in text)
print("Your encoded text is:\n"+encoded_text)
The strings in your question mention that you want to replace ' ' with #. If you do not want to do that, just remove the last characters from both of the above strings.

have two lists instead of strings like from_ = "abc".split() and to_ = "def".split()
look for your char in from_ and get the index, get the same index char from to_ and stitch it to a new sentence.
example:
from_ = "abc".split()
to_ = "def".split()
old_msg = "ab ab"
new_msg = ""
for each in old_msg.split():
new_msg = new_msg + to_[from_.index(each)]
Hope this helps, please add missing char handling and any other edge cases

Or you can use str.translate
import os, sys, random
from pathlib import Path
TEXT_MAP = ("qwertyuiopasdfghjklzxcvbnm ", "mnbvcxzlkjhgfdsapoiuytrewq#")
def main():
text = ''
if len(sys.argv) > 1:
fname = sys.argv[1]
p = Path(fname)
if p.is_file():
text = p.read_text().strip()
print(f'Text from {p} is: {text}')
if not text:
text = input("Write the text to encode: ").strip()
trantab = str.maketrans(*TEXT_MAP)
text_encoded = text.translate(trantab)
print("Your encoded text is:\n"+text_encoded)
if __name__ == '__main__':
main()

Related

My word tally program only tallies the last word in a text file. Where did I go wrong?

I want to tally up the word freq. from text files. The issue I'm facing is that only the last word is tallied.
def main():
rep = input("Enter a text file: ")
infield = open(rep, 'r')
s = infield.read()
punctuation = [',',';','.',':','!',"'","\""]
for ch in punctuation:
s = s.replace(ch,' ')
s = s.split()
wordcount = {}
for word in s:
if word not in wordcount:
count_1 = s.count(word)
wordcount = {word:count_1}
#s.append(w:s.count(w))
print (wordcount)
main()
Expected: A tallied word count for words in a text file in a key-value format/ a dictionary.
Actual: {'fun': 2}
Fun is the last word of the text file and indeed comes up only twice.
Also, the indentation that is displayed isn't reflective of what I have.
Your problem is here:
wordcount = {word:count_1}
You're overwriting the dictionary on every loop iteration.
Make it:
wordcount[word] = count_1
Though, to be honest, the much better approach is to use the standard library's collections.Counter container.
def main():
import collections
rep = input("Enter a text file: ")
infield = open(rep, 'r')
s = infield.read()
punctuation = [',',';','.',':','!',"'","\""]
for ch in punctuation:
s = s.replace(ch,' ')
s = s.split()
wordcount = collections.Counter(s) # <===
print (wordcount.most_common()) # <===
main()
No point in manually doing something that is already done in the standard library (since Python 2.7):
from collections import Counter
import re
rep = input("Enter a text file: ")
infield = open(rep, 'r')
s = infield.read()
s = re.split(r'[ ,;.:!\'"]', s)
wordcount = Counter(s)
del wordcount['']
print (wordcount)
There is a difference between re.split() and string.split(): the former creates empty words when there are several delimiters in a row, the latter doesn't. That's why del wordcount['']
You had a couple of issues, but the most pressing one was this bit of code:
for word in s:
if word not in wordcount:
count_1 = s.count(word)
wordcount = {word:count_1}
You were setting wordcount to a single-key dictionary at every new word. This is how I would have written it...
def main():
punctuation = [',',';','.',':','!',"'","\""]
rep = input("Enter a text file: ")
with open(rep, 'r') as infield:
s = infield.read()
for ch in punctuation:
s = s.replace(ch, ' ')
s = s.split()
wordcount = {}
for word in s:
if word not in wordcount.keys():
wordcount[word] = 1
else:
wordcount[word] += 1
print(wordcount)
main()
Use wordcount.update({word: count_1}) instead: wordcount = {word:count_1}.
Full example:
# coding: utf-8
PUNCTUATION = [',', ';', '.', ':', '!', "'", "\""]
if __name__ == '__main__':
wordcount = {}
rep = input("Enter a text file: ")
infield = open(rep, 'r')
s = infield.read()
for ch in PUNCTUATION:
s = s.replace(ch, ' ')
s = s.split()
for word in s:
if word not in wordcount:
count_1 = s.count(word)
wordcount.update({word: count_1})
print(wordcount)

Brute force password breaker

create a list of word strings by reading this file. Then loop over each word in this list, passing it to the decrypt() method. If this method returns the integer 0, the password was wrong and your program should continue to the next password. If decrypt() returns 1, then your program should break out of the loop and print the hacked password. You should try both the uppercase and lower-case form of each word.
This dictionary.txt file contains words in capital letters.
> import PyPDF2
pdfFile = open('reverse.pdf', 'rb')
pdfReader = PyPDF2.PdfFileReader(pdfFile)
pdfWriter = PyPDF2.PdfFileWriter()
for pageNum in range(pdfReader.numPages):
pdfWriter.addPage(pdfReader.getPage(pageNum))
wrd = input('Please enter one word as a password: ')
pdfWriter.encrypt(wrd)
resultPdf = open('encryptedreverse.pdf', 'wb')
pdfWriter.write(resultPdf)
resultPdf.close()
print(pdfReader.isEncrypted)
helloDict = open('dictionary.txt')
helloDictCont = helloDict.read().splitlines()
liDict = []
for word in helloDictCont:
liDict.extend(word.split())
PdfFile2 = open('encryptedreverse.pdf', 'rb')
pdfReader2 = PyPDF2.PdfFileReader(PdfFile2)
print(pdfReader2.isEncrypted)
for word in liDict:
if pdfReader2.decrypt(word) == 1:
break
print(word)
elif pdfReader2.decrypt(word.lower()) == 1:
break
print(word)
After a few minutes processing ends and I neither get a password printed nor the pdf file is decrypted. Any idea what am I doing wrong?
This works fine for me:
import PyPDF2
pdfFile = open('reverse.pdf', 'rb')
pdfReader = PyPDF2.PdfFileReader(pdfFile)
pdfWriter = PyPDF2.PdfFileWriter()
for pageNum in range(pdfReader.numPages):
pdfWriter.addPage(pdfReader.getPage(pageNum))
wrd = input('Please enter one word as a password: ')
pdfWriter.encrypt(wrd)
resultPdf = open('encryptedreverse.pdf', 'wb')
pdfWriter.write(resultPdf)
resultPdf.close()
print(pdfReader.isEncrypted)
helloDict = open('t.txt')
helloDictCont = helloDict.read().splitlines()
liDict = []
for word in helloDictCont:
liDict.extend(word.split())
PdfFile2 = open('encryptedreverse.pdf', 'rb')
pdfReader2 = PyPDF2.PdfFileReader(PdfFile2)
print(pdfReader2.isEncrypted)
for word in liDict:
if pdfReader2.decrypt(word) == 1:
print('The correct PWD as upper case: ' + word)
break
elif pdfReader2.decrypt(word.lower()) == 1:
print('The correct PWD as lower case: ' + word)
break
else:
print('PWD is not correct: ' + word)
Here's my solution:
'''
Brute-Force PDF Password Breaker
Say you have an encrypted PDF that you have forgotten the password to,
but you remember it was a single English word. Trying to guess your forgot-
ten password is quite a boring task. Instead you can write a program that
will decrypt the PDF by trying every possible English word until it finds one
that works. This is called a brute-force password attack. Download the text file
dictionary.txt from https://nostarch.com/automatestuff2/. This dictionary file
contains over 44,000 English words with one word per line.
Using the file-reading skills you learned in Chapter 9, create a list of
word strings by reading this file. Then loop over each word in this list, pass -
ing it to the decrypt() method. If this method returns the integer 0, the pass-
word was wrong and your program should continue to the next password.
If decrypt() returns 1, then your program should break out of the loop and
print the hacked password. You should try both the uppercase and lower-
case form of each word. (On my laptop, going through all 88,000 uppercase
and lowercase words from the dictionary file takes a couple of minutes. This
is why you shouldn’t use a simple English word for your passwords.)
'''
import PyPDF2
import time
import os
import sys
def decrypt():
ok = False
print(f'Working... {time.asctime()}')
start = time.time()
passwords = open(dictionary).read().split('\n')
pdfReader = PyPDF2.PdfFileReader(pdf)
if pdfReader.isEncrypted:
for password in passwords:
if pdfReader.decrypt(password) or pdfReader.decrypt(password.lower()):
print(f'Password: {password}')
ok = True
break
end = time.time()
hours = int((end - start) / 3600)
minutes = int((end - start) / 60)
secondes = int(end - start - (hours * 3600) - (minutes * 60))
if ok:
print(f'Has been decrypted in {hours}H:{minutes}M:{secondes}S!')
else:
print(f'{pdf} hasn\'t been decrypted... Maybe need a better dictionary?')
else:
print(f'{pdf} isn\'t encrypted')
if len(sys.argv) == 3:
dictionary, pdf = sys.argv[1], sys.argv[2]
if os.path.isfile(dictionary) and dictionary.endswith('.txt'):
if os.path.isfile(pdf) and pdf.endswith('.pdf'):
decrypt()
else:
print('Invalid path to pdf or pdf file')
else:
print('Invalid path to dictionary or dictionary file')
else:
print('Please enter arguments as example:\
\ndictionaryName.txt pdfName.pdf')

Search a String in text file in python

import os
import random
import sys
def search(a):
datafile = open("test.txt","r")
quote = datafile.read()
quote_list = quote.split(" ")
d = len(quote_list)
print(quote_list)
for x in range(0,4):
string = quote_list.pop()
print(string)
if(string==a):
return 0
else:
continue
print("Enter the word to search")
b = sys.stdin.readline()
c=search(b)
if(c==0):
print("Found")
else:
print("Not Found")
This code for searching a particular string in a text file is not working. Please help me to rectify the issue.
Try changing the line:
c=search(b)
to:
c=search(b.strip())
The newline in the user-input is probably what's getting in your way.
Other than that you probably want to change:
for x in range(0,4):
to:
for x in quote_list:
and get rid of the parameter d

Chatbot using Markov Chains

Hello fellow developers,
I am trying to build a chatbot using markov chains and I am stuck at a problem. I the code below, I have made a random sentence generator that learns from movie scripts. The problem is, how do I get this sentence generator to not be random and to respond to the user's input? How should I go about doing this? Is it something to do with input/output training like this:
In: how are you today
Out: I'm good thanks how are you
Here is my code. Most of the functions are used to put the data in a csv file so don't mind those.
from collections import defaultdict
import random, itertools, nltk, pandas, csv, string, re, os, time
class Chatbot:
def __init__(self, name, txt_transcript_filedir, character=None):
self.name = name
self.txt_transcript_filedir = txt_transcript_filedir
self.character = character
print("Hello my name is " + name + ".")
def parse_transcript(self):
parsed_lines = []
self.csv_transcript_filedir = self.txt_transcript_filedir.replace('.txt', '.csv')
with open(self.txt_transcript_filedir, encoding='utf-8') as txt_file:
lines = txt_file.readlines()
for line in lines:
line = line.replace(', ', ' ')
line = re.sub(r'\[.*?\]', '', line)
if ': ' in line:
line = line.replace(': ', ',')
parsed_lines.append(line)
with open(self.csv_transcript_filedir, 'w', encoding='utf-8') as csv_file:
writer = csv.writer(csv_file)
writer.writerow(['person', 'text'])
for line in parsed_lines:
csv_file.write(line)
def tokenize_transcript(self):
csv_file = pandas.read_csv(self.csv_transcript_filedir)
textss = []
final_sents = []
if self.character == None:
texts = csv_file['text']
for text in texts:
sent = nltk.sent_tokenize(text)
textss.append(sent)
else:
char_sets = csv_file[csv_file['person'] == self.character]
texts = char_sets['text']
for text in texts:
sent = nltk.sent_tokenize(text)
textss.append(sent)
for text in textss:
for sent in text:
if sent[0] == ' ':
sent = sent[1:]
final_sent = [w for w in sent if w not in string.punctuation]
final_sent = ''.join(final_sent)
final_sents.append(final_sent)
self.training_data = [sent for sent in final_sents]
def learn(self):
self.parse_transcript()
self.tokenize_transcript()
self.make_word_dict(self.training_data)
def make_word_dict(self, text):
word_dict = defaultdict(list)
for sent in text:
words = nltk.word_tokenize(sent)
for i in range(len(words) - 1):
if i+2 >= (len(words)):
word_dict[(words[i], words[i+1])].append('<end>')
else:
word_dict[(words[i], words[i+1])].append(words[i+2])
self.vocabulary = word_dict
def generate_text(self, num):
for i in range(0, num):
start_key = random.choice(list(self.vocabulary.keys()))
text = []
text.append(start_key[0])
text.append(start_key[1])
for i in itertools.count():
key = (text[i], text[i+1])
if key[1] == '<end>':
break
else:
text.append(random.choice(self.vocabulary[text[i], text[i+1]]))
text = ' '.join(text)
if text.endswith('<end>'):
text = text[:-6]
text = text + '.'
return text
def say(self, text):
os.system('say -v Oliver ' + text)
def main():
num = 100
bot = Chatbot("J.A.R.V.I.S", "avengers_age_of_ultron.txt", "JARVIS")
bot.learn()
for i in range(num):
text = bot.generate_text(1)
print(text)
if __name__ == '__main__':
main()

Converting this Python code into a visual GUI?

I have a python code that a friend made , as I have very small knowledge of python..
I want to convert it into a GUI as we will distribute the code as a program for it to be beginner-friendly .
anyways here's the code:
import time, os, sys
try:
if len(sys.argv) < 2:
fn = raw_input("Enter the name of the file you want to edit: ")
else: fn = sys.argv[1]
f = open(fn)
b = f.read()
for i in b[:300]:
print hex(ord(i))[2:],
f.close()
line = str(0x15c)+'-'+str(0x15f)
if len(sys.argv)<3:
hexcode = raw_input("3 bytes color hex number: ")
else: hexcode = sys.argv[2]
if not hexcode.startswith('0x'):
hexcode = '0x'+hexcode
hexstr = '0x'
start = int(line.split('-')[0])
end = int(line.split('-')[1])
for i in b[start:end]:
hexstr+=hex(ord(i))[2:]
ascii = ''
for i in range(2,len(hexcode),2):
char = chr(int(hexcode[i:i+2],16))
ascii+=char
b = b[:start]+ascii+b[end:]
for i in b[:300]:
print hex(ord(i))[2:],
except Exception, x:
print x
time.sleep(3)
finally:
f = open(fn,'wb')
f.write(b)
f.close()
Now I found this on a tutorial but don't know how to use it:
#simple GU0I
from Tkinter import *
root = Tk()
root.title("BreffHexReplace")
root.geometry("400x200")
app = Frame(root)
app.grid()
label = Label(app, text = "This is a label!")
label.grid()
root.mainloop()
Any help?
thanks!
also one more thing , in this code , after I type in the name or the replacor hex , it shows me a list of hex , how can I make it not shown?
thanks!
Because this program is so simple, you can try EasyGui( easygui.sourceforge.net/ ). To start, add import easygui as eg. This line loads the EasyGui module. Next, replace fn = raw_input("Enter the name of the file you want to edit: ") with fn = eg.fileopenbox(title = 'HexReplace', msg = 'Browse to the file you wish to edit'). This opens a box to browse to the wanted file. Also replace hexcode = raw_input("3 bytes color hex number: ") with hexcode = eg.enterbox(msg = '3 bytes color hex number', title = 'HexReplace'). This pops up an input box. Replace print x with eg.msgbox(title = 'HexReplace', msg = x). This shows a message box with the exception. The title argument is the window title. To remove the hex list, add between the imports and the try block: null = open(os.devnull, 'W's); oldstdout = system.stdout; sys.stdout = null
This will silence all print messages.

Categories