hi i'm trying to write a function to decode a message the user entered
decypherbook = {'0000':8, '0001':1, '0010':0, '0011':9, '0100':5, '0101':3, '0110':7, '0111':2, '1110':4, '1111':6}
userdecode = raw_input("Enter the number you want to de-cypher: ")
def decode(cypher, msg):
length = len(msg)
decoded = ""
key_index = 0 ## starting position of a key in message
while key_index < length:
key = msg[key_index:key_index + 4]
decoded += str(cypher[key])
key_index += 4
return decoded
print "After de-cypher: ", decode(decypherbook, userdecode)
but if the user input a message like "0001,0001", which i would like the result be "1,1". How could i make my code temporarily ignore punctuation so it doesn't mess up with my indexing +4 in my code and still able to print out the punctuation later?
You can check if the next characeter is an integer. If not, just add it to the string and continue to the next character:
def decode(cypher, msg):
length = len(msg)
decoded = ""
key_index = 0 ## starting position of a key in message
while key_index < length:
key = msg[key_index:key_index + 4]
decoded += str(cypher[key])
key_index += 4
# Pass every non digit after
while key_index < length and not msg[key_index].isdigit():
decoded += msg[key_index]
key_index += 1
return decoded
Here is an example of execution:
>>> def decode(cypher, msg):
... # ...
>>> decode(decypherbook, '0001,0010')
'1,0'
Side note: You could also prefer to make a list as a buffer instead of recreating a string every time (string are immutable, every += creates a new object) and do ''.join(buffer) at the end. Just for performance purpose.
Use split method from string object
userdecode = raw_input("Enter the number you want to de-cypher: ")
userdecode_list = userdecode.split(",")
And than call your function like this with join method from string object
print "After de-cypher: ", decode(decypherbook, "".join(userdecode_list))
I feel like replace matches your need more.
def decode(cypher, msg):
for key, value in cypher.items():
msg = msg.replace(key, str(value))
return msg
A fun-one-liner (which assumes userdecode is guaranteed to be of the form r"(\d{4},)*")
def decode(cypher, msg):
return ",".join([str(cypher[x]), for x in userdecode.split(",")])
Related
I am trying to create a loop that compares strings from a list I have already created. The list is of passwords, and the same passwords hashed with md5. I have a function that does the hashing, and another that prints out the list of both passwords. The new function "findmd5" is supposed to compare each md5 encrypted value of the password list with the encrypted string that is passed in. "pass2check" is a predetermined string that I am trying to use in the loop, its md5 value should return the password "football". The code in my new function is very incomplete because I am lost on the next steps to take..
import hashlib
passwordlist = ["password","123456","12345678","1234","qwerty","12345",
"baseball","football","letmein","monkey","abc123","mustang","michael"]
def makemd5(key_string):
new_key_string = key_string.encode('utf-8')
return (hashlib.md5 ( new_key_string ).hexdigest())
def createmd5list(passwordlist):
for passlist in passwordlist:
hashlist = makemd5(passlist)
print (passlist,",",hashlist)
def findmd5(pass2check):
for line in open(passwordlist + hashlist):
if pass2check in line:
print(True)
else:
print(False)
def main():
pass2check = "37b4e2d82900d5e94b8da524fbeb33c0"
main ()
you can try this ():
import hashlib
passwordlist = ["password","123456","12345678","1234","qwerty","12345",
"baseball","football","letmein","monkey","abc123","mustang","michael"]
def listOfHashs():
return [hashlib.md5(item.encode('utf-8')).hexdigest() for item in passwordlist]
def main():
pass2check = "37b4e2d82900d5e94b8da524fbeb33c0"
index = listOfHashs().index(pass2check)
print(passwordlist[index] if index >= 0 else "Hash not found !")
main()
in this version i've tried to modify your code:
import hashlib
passwordlist = ["password","123456","12345678","1234","qwerty","12345",
"baseball","football","letmein","monkey","abc123","mustang","michael"]
def makemd5(key_string):
new_key_string = key_string.encode('utf-8')
return (hashlib.md5 ( new_key_string ).hexdigest())
def createmd5list(passwordlist):
hashlist = []
for passlist in passwordlist:
hashlist += [makemd5(passlist)]
return hashlist
def findmd5(pass2check):
for index, line in enumerate(createmd5list(passwordlist)):
if pass2check in line:
return index
return -1
def main():
pass2check = "37b4e2d82900d5e94b8da524fbeb33c0"
index = findmd5(pass2check)
if index >= 0:
print passwordlist[index]
else:
print "Hash not found !"
main()
You do not need to create the list of hashed passwords. Instead, you build the digest and filter inside the list comprehension and the final list only contains the valid solutions.
Reworking your own code, it could look like
import hashlib
passwordlist = ["password","123456","12345678","1234","qwerty","12345",
"baseball","football","letmein","monkey","abc123","mustang","michael"]
def findmd5(pass2check):
result = [password for password in passwordlist
if hashlib.md5(password).hexdigest() == pass2check
]
if len(result):
print("The answer is")
for password in result:
print(password)
else:
print("Password not found")
def main():
pass2check = "37b4e2d82900d5e94b8da524fbeb33c0"
findmd5(pass2check)
main ()
This will print all the valid solutions
I am trying to create a function that receives input from a user, re-prompts until one character is entered. Strip() is used to removed whitespace so only characters are counted.
Here is my current code:
def inputSomething(prompt, errorMessage = 'Atleast one character must be used'):
while True:
value = (prompt)
Response = value.strip()
if len(Response) >=1:
print ('Valid')
else:
print(errorMessage)
continue
inputSomething(input('Enter str: '))
The problem I'm having is with the loop. Right now it loops the result infinitely. Should I not be using if else?
The problem is that the input is outside the loop:
import sys
def inputSomething(prompt, errorMessage = 'Atleast one character must be used'):
while True:
value = input(prompt)
Response = value.strip()
if Response:
print ('Valid')
return Response
else:
print(errorMessage, file=sys.stderr)
something = inputSomething('Enter str: ')
Note that an empty string equates to False.
I was confused with recursion, because of the indentation used in your question.
Change:
inputSomething(input('Enter str: '))
To:
inputSomething(lambda : input('Enter str: '))
And:
value = (prompt)
To:
value = prompt()
This way you pass a function and then call it, instead of passing the result of a called function.
For future references, another way that also includes retries:
import sys
def inputSomething(prompt, retries = 2, errorMessage = 'Atleast one character must be used'):
while retries > 0:
value = input("Enter str: ")
Response = value.strip()
if Response:
print ('Valid')
retries -= 1
continue
#return Response
else:
print(errorMessage, file=sys.stderr)
retries -= 1
inputSomething('prompt')
I'm writing a program that encodes and decodes a text chosen by the user. My decoder function seems to work fine when I input unicode codes to it to return the character but my encoder function is not working.
Simply put, what I'm trying to accomplish is:
ask the user if they want to encode or decode
if they want to encode, i want to gather a string of phrases until the user enters 'done', append them to the list, then encode them using my encode function, then finally print out the encoded list.
if they want to decode, i want to gather a series of intergers that are actually unicode codes until the user enters 'done', append them to list2, then decode them using my decode function and print out that decoded list.
Here is my code.
def encode(character):
code = ord(character)
new_code = code * 4 + 10 // 2
return new_code
def decode(character):
code2 = character * 2 - 10 // 4
new_code2 = chr(code2)
return new_code2
def main():
encoded_list = []
decoded_list = []
choice = input('Hello! Do you want to encode or decode? ').lower()
if choice == 'encode':
text = input('Enter text to encode or "done": ')
while text != 'done':
encoded = encode(text)
encoded_list.append(encoded)
text = input('Enter text to encode or "done": ')
if text == 'done':
print(encoded_list)
elif choice == 'decode':
text2 = input('Enter characters to decode or "done": ')
while text2 != 'done':
text2 = int(text2)
decoded = decode(text2)
decoded_list.append(decoded)
text2 = input('Enter characters to decode or "done": ')
if text2 == 'done':
print(decoded_list)
else:
print('Please enter a valid response')
main()
thanks so much!
The main problem is that you have to encode each character of the string separately. The ord function can only take a single character, so instead of:
encoded = encode(text)
you want:
encoded = ""
for char in text:
encoded += encode(text)
Also (this is unrelated to the error you're getting), you forgot to account for order of operations. You put code * 4 + 10 // 2 instead of
(code * 4 + 10) // 2, so the code is really equivalent to code * 4 + 5. You did a similar thing for decode.
You need to use ord on each character of the string, not the whole string at once:
def encode(character):
code = map(ord,character)
new_code = [(x * 4 + 10) // 2 for x in code]
return new_code
def decode(character):
code2 = [(x * 2 - 10) // 4 for x in character]
new_code2 = "".join([chr(x) for x in code2])
return new_code2
import sys
import pickle
import string
def Menu():
print ("***********MENU************")
print ("0. Quit")
print ("1. Read text file")
print ("2. Display counts")
print ("3. Display statistics of word lengths")
print ("4. Print statistics to file")
def readFile():
while True:
fileName = input("Please enter a file name: ")
if (fileName.lower().endswith(".txt")):
break
else:
print("That was an incorrect file name. Please try again.")
continue
return fileName
THE_FILE = ""
myDictionary = 0
def showCounts(fileName):
numCount = 0
dotCount = 0
commaCount = 0
lineCount = 0
wordCount = 0
with open(fileName, 'r') as f:
for line in f:
wordCount+=len(line.split())
lineCount+=1
for char in line:
if char.isdigit() == True:
numCount+=1
elif char == '.':
dotCount+=1
elif char == ',':
commaCount+=1
print("Number count: " + str(numCount))
print("Comma count: " + str(commaCount))
print("Dot count: " + str(dotCount))
print("Line count: " + str(lineCount))
print("Word count: " + str(wordCount))
def showStats(fileName):
temp1 = []
temp2 = []
lengths = []
myWords = []
keys = []
values = []
count = 0
with open(fileName, 'r') as f:
for line in f:
words = line.split()
for word in words:
temp2.append(word)
temp1.append(len(word))
for x in temp1:
if x not in lengths:
lengths.append(x)
lengths.sort()
dictionaryStats = {}
for x in lengths:
dictionaryStats[x] = []
for x in lengths:
for word in temp2:
if len(word) == x:
dictionaryStats[x].append(word)
for key in dictionaryStats:
print("Key = " + str(key) + " Total number of words with " + str(key) + " characters = " + str(len(dictionaryStats[key])))
return dictionaryStats
def printStats(aDictionary):
aFile = open("statsWords.dat", 'w')
for key in aDictionary:
aFile.write(str(key) + " : " + str(aDictionary[key]) + "\n")
aFile.close()
choice = -1
while choice !=0:
Menu()
choice = (int(input("Please choose 1-4 to perform function. Press 0 to exit the program. Thank you. \n")))
if choice == 0:
print ("Exit program. Thank you.")
sys.exit
elif choice == 1:
THE_FILE = readFile()
elif choice == 2:
showCounts(THE_FILE)
elif choice == 3:
showStats(THE_FILE)
elif choice == 4:
printStats(myDictionary)
else:
print ("Error.")
I'm trying to open a file, have it display the statistics of the word lengths, and then have it make a new file with the statistics of the word lengths. I can read the file and have it display the statistics, but when I print the statistics to file I get an error - "int" object is not iterable. Any ideas? Thanks guys!
Error:
Traceback (most recent call last):
File "hw4_ThomasConnor.py", line 111, in <module>
printStats(myDictionary)
File "hw4_ThomasConnor.py", line 92, in printStats
for key in aDictionary:
TypeError: 'int' object is not iterable
The problem is that you set myDictionary to 0 at the top of your program, and then are sending it to your file writing function here printStats(myDictionary).
In this function you have this line for key in aDictionary, and since you passed in 0, this is effectively for key in 0 which is where the error comes from.
You need to send the result of the showStats function to your printStats function.
As this is looking like homework, I will leave it at that for now.
Sorry I am confused. in the showStats function I have to somehow say
"send results to printStats function" and then in the printStats
function I have to call the results? How would I do that exactly?
The printStats function is expecting a dictionary to print. This dictionary is generated by the showStats function (in fact, it returns this dictionary).
So you need to send the result of the showStats function to the printStats function.
To save the return value of a method, you can assign it on the LHS (left hand side) of the call expression, like this:
>>> def foo(bar):
... return bar*2
...
>>> def print_results(result):
... print('The result was: {}'.format(result))
...
>>> result = foo(2) # Save the returned value
Since result is just like any other name in Python, you can pass it to any other function:
>>> print_results(result)
The result was: 4
If we don't want to store the result of the function, and just want to send it to another function, then we can use this syntax:
>>> print_results(foo(2))
The result was: 4
You need to do something similar in your main loop where you execute the functions.
Since the dictionary you want to print is returned by the showStats function, you must call the showStats function first before calling the printStats function. This poses a problem if your user selects 4 before selecting 3 - make sure you find out a work around for this. A simple work around would be to prompt the user to calculate the stats by selecting 3 before selecting 4. Try to think of another way to get around this problem.
Here:
THE_FILE = ""
myDictionary = 0
you set integer to myDictionary.
and later you do:
printStats(myDictionary)
and as you try to interate over keys of dictionary inside, you fail.
I'm trying to replace the letters in key with the letters in alpha (and vice versa):
alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
key = "XPMGTDHLYONZBWEARKJUFSCIQV"
I am trying to change a string to become encoded (and the other way around), so say "Hello" would become "LTZZE". Any idea how to do this? This is my current code:
usrInput = 0
alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
key = "XPMGTDHLYONZBWEARKJUFSCIQV"
def menu():
print "SECRET DECODER MENU"
print ""
print "1) Quit"
print "2) Encode"
print "3) Decode"
usrInput = raw_input("What would you like to do?")
return usrInput
def encodeWord():
plain = plain.upper()
length = len(plain)
encode = plain.encode(alpha, key)
return encode
def decodeWord():
coded = coded.upper()
length = len(coded)
decode = coded.decode(key, alpha)
return decode
def main():
keepGoing = True
while keepGoing:
usrInput = menu()
if usrInput == "2":
plain = raw_input("Text you want to be encoded: ")
encodeWord()
print encode(plain)
elif usrInput == "3":
coded = raw_input("Code you need to be decyphered: ")
decodeWord()
print decode(coded)
elif usrInput == "1":
print "Thanks for doing super secret spy stuff with me. No one seems to want to anymore. Goodbye. ):"
keepGoing = False
else:
print "I don't know what to do! Ahhh!"
main()
Note this is a homework assignment for a computer science class. I created the assignment, and I'm aware it's on stack overflow. If you turn it in as your own work, I will know. You will earn a zero for the assignment and we will begin academic misconduct proceedings.
(If you're playing along at home, this is indeed a string manipulation assignment, and explicitly NOT to be considered a good cryptographic practice. We also are not allowing maketrans() for this assignment, because it's a string manipulation and function exercise for beginning programmers.)
If you're really desperate for help, come see me or one of the recitation leaders we're paying to help you.
Use str.maketrans and str.translate. If you use Python 2 this functions are in string (here (maketrans) and here (translate)).
Example (python 3):
alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
key = "XPMGTDHLYONZBWEARKJUFSCIQV"
enc = str.maketrans(alpha, key)
usrInput = 'HELLO'
print(usrInput.translate(enc))
Example (python 2)
import string
alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
key = "XPMGTDHLYONZBWEARKJUFSCIQV"
enc = string.maketrans(alpha, key)
inp = 'HELLO'
print string.translate(inp, enc)
Output:
LTZZE