Making a decryption program in python - python

So a little while ago I asked for some help with an encryption program,
And you guys were amazing and came up with the solution.
So I come to you again in search of help for the equivalent decryption program.
The code I have got so far is like this:
whinger = 0
bewds = raw_input ('Please enter the encrypted message: ')
bewds = bewds.replace(' ', ', ')
warble = [bewds]
print warble
wetler = len(warble)
warble.reverse();
while whinger < wetler:
print chr(warble[whinger]),
whinger += 1
But when I input
101 103 97 115 115 101 109
it comes up with the error that the input is not an integer.
What I need is when I enter the numbers it turns them into a list of integers.
But I don't want to have to input all the numbers separately.
Thanks in advance for your help :P

To convert input string into a list of integers:
numbers = [int(s) for s in "101 103 97 115 115 101 109".split()]

Here's almost the simplest way I can think of to do it:
s = '101 103 97 115 115 101 109'
numbers = []
for number_str in s.replace(',', ' ').split():
numbers.append(int(number_str))
It will allow the numbers to be separated with commas and/or one or more space characters. If you only want to allow spaces, leave the ".replace(',', ' ')" out.

Your problem is, that raw_input returns a string to you. So you have two options.
1, Use regular expression library re. E.G.:
import re
bewds = raw_input ('Please enter the encrypted message: ')
some_list = []
for find in re.finditer("\d+", bewds):
some_list.append(find.group(0))
2, Or you can use split method as described in the most voted answer to this question: sscanf in Python

You could also use map
numbers = map(int, '101 103 97 115 115 101 109'.split())
This returns a list in Python 2, but a map object in Python 3, which you might want to convert into a list.
numbers = list(map(int, '101 103 97 115 115 101 109'.split()))
This does exactly the same as J. F. Sebastian's answer.

Related

How does this code format the list to the desired output?

I'm a beginner python student and I'm having trouble with lists.
This was our last weeks' class and I need help understanding how does the commands on this code operate to change the list output.
The commands we were taught on lists and formatting are split() , strip() , slice() , append() and format()
More spesificly, the part I don't understand exactly is how does the program understand what part are the names and what parts are grades? Where does it split the names from the grades and what do we use the tuple for?
The list given to us is like this
Hopper, Grace 100 98 87 97
Knuth, Donald 82 87 92 81
Goldberg, Adele 94 96 90 91
Kernighan, Brian 89 74 89 77
Liskov, Barbara 87 97 81 85
and the desired output should look like this
Output
The code we wrote in class is:
exam1_score = 0
exam2_score = 0
exam3_score = 0
exam4_score = 0
name = ""
scores=[]
f=open("scores.txt","r")
for line in f:
temp_list = []
name = line[0:18]
list = line[19:len(line)].split()
ex1_score = int(list[0])
ex2_score = int(list[1])
ex3_score = int(list[2])
ex4_score = int(list[3])
avg_score = float(float(ex1_score+ex2_score+ex3_score+ex4_score)/float(4))
temp_list.append(name)
temp_list.append(ex1_score)
temp_list.append(ex2_score)
temp_list.append(ex3_score)
temp_list.append(ex4_score)
temp_list.append(avg_score)
scores.append(tuple(temp_list))
scores = sorted(scores)
print("{:20s}{:6s}{:6s}{:6s}{:6s}{:10s}".format("Name", "Exam1", "Exam2", "Exam3", "Exam4", "Mean"))
ex1_mean = 0
ex2_mean = 0
ex3_mean = 0
ex4_mean = 0
avg_mean = 0
for baslik in scores:
print ("{:20s}{:6d}{:6d}{:6d}{:6d}{:10.2f}".format(baslik[0],baslik[1],baslik[2],baslik[3],baslik[4],baslik[5]))
ex1_mean = ex1_mean+baslik[1]
ex2_mean = ex2_mean+baslik[2]
ex3_mean = ex3_mean+baslik[3]
ex4_mean = ex4_mean+baslik[4]
avg_mean = avg_mean+baslik[5]
print ("{:20s}{:6s}{:6s}{:6s}{:6s}{:10.2s}".format("Exam Mean",str(ex1_mean/len(scores)),str(ex2_mean/len(scores)),str(ex3_mean/len(scores)),str(ex4_mean/len(scores)),str(avg_mean/len(scores))))
f.close()
I guess that each input is on a different line, i.e.
Hopper, Grace 100 98 87 97
Knuth, Donald 82 87 92 81
Goldberg, Adele 94 96 90 91
Kernighan, Brian 89 74 89 77
Liskov, Barbara 87 97 81 85
where the first 18 characters include the name, because we have the line:
name = line[0:18]
Afterwards we split the remaining string with
list = line[19:len(line)].split()
So, the input is most likely formatted, such that you can hard-code the split of names and grades.
Sounds like you were never told what strings and characters are. Understanding those concepts will give you some background info to understand whats going on.
You can think of a word as a string. The letters in that word are the characters.
An sentence is a string as well. The only difference between a word and a string is the spaces between the words. The computer does not care if the character in the string is a space or a letter. We have to tell the computer to remove the spaces.
So all the split() function does (by default) is separate a sentence on the spaces. It takes all those words and puts them into a list.
For example, say the last sentence was stored in variable sentence.
In python that would look like:
sentence = "It takes all those words and puts them into a list"
Now say we just want each word in a list.
broken_sentence = sentence.split()
The result will be if you print broken_sentence with
print(broken_sentence)
You will get
('It','takes','all','those','words','and','puts','them','into','a','list')
Now the computer has a list. If you want the word It, you access that via index or slicing.
print(broken_sentence[0]) will print the FIRST element in the list which is 'It'.
Ask your teacher why counting starts with zero in computers, that should be a fun discussion.
Hope this breaks it down a little bit for you.

Groups in regex python

Below is a piece of code I have been working on and not getting the desired result. I would like to only use groups to split
elements into group 1 and group 2. For the last two elements I would like to only match 0567 and not 567 for group 2. I get the desired result for '+1 234 567' but not for '0567' or '567'. Please help with this.
regex_str = "^(?:\+1)?\s?([123456789]\d{2})\s?([123456789]\d{2})"
PATTERN = re.compile(regex_str)
num = ['+1 234 567','0567', '567']
for i in num:
m = PATTERN.match(i)
if m != None:
print (i," and ",m.group(1),m.group(2))
else:
print (i, " has no match")
output:
+1 234 567 and 234 567
0789 has no match
789 has no match
Use a ? after group 1 to make it optional.
regex_str = "^(?:\+1)?\s?([123456789]\d{2})?\s?([123456789]\d{2})"
Thanks for the suggestion using ? works to make group 1 optional. In addition, I had to use ?(1) to make sure group 1 has a correct match before proceeding to group 2 that gave me the answer I desired. Thanks for the help.

Python regex for UK number

Below given are the UK phone numbers need to fetch from text file:
07791523634
07910221698
But it only print 0779152363, 0791022169 skipping the 11th character.
Also it produce unnecessary values like ('')
Ex : '', '07800 854536'
Below is the regex I've used:
phnsrch = re.compile(r'\d{3}[-\.\s]??\d{3}[-\.\s]??\d{4}|\(\d{3}\)\s*\d{3}[-\.\s]??\d{5}|\d{3}[-\.\s]??\d{4}[-\.\s]??\d{4}|\d{5}[-\.\s]??\d{3}[-\.\s]??\d{3}|/^(?:(?:\(?(?:0(?:0|11)\)?[\s-]?\(?|\+)44\)?[\s-]?(?:\(?0\)?[\s-]?)?)|(?:\(?0))(?:(?:\d{5}\)?[\s-]?\d{4,5})|(?:\d{4}\)?[\s-]?(?:\d{5}|\d{3}[\s-]?\d{3}))|(?:\d{3}\)?[\s-]?\d{3}[\s-]?\d{3,4})|(?:\d{2}\)?[\s-]?\d{4}[\s-]?\d{4}))(?:[\s-]?(?:x|ext\.?|\#)\d{3,4})?$/|')
Need help to fetch the complete set of 11 numbers without any unnecessary symbols
Finally figured out the solution for matching the UK numbers below:
07540858798
0113 2644489
02074 735 217
07512 850433
01942 896007
01915222200
01582 492734
07548 021 475
020 8563 7296
07791523634
re.compile(r'\d{3}[-\.\s]??\d{4}[-\.\s]??\d{4}|\d{5}[-\.\s]??\d{3}[-\.\s]??\d{3}|(?:\d{4}\)?[\s-]?\d{3}[\s-]?\d{4})')
Thanks to those who helped me with this issue.
I think your regex is too long and can be more easier, try this regex instead:
^(07\d{8,12}|447\d{7,11})$

How can I match the whole regex not the subexpression

Say, I have the following regex to search a series of room number:
import re
re.findall(r'\b(\d)\d\1\b','101 102 103 201 202 203')
I want to search for the room number whose first and last digit are the same (101 and 202). The above code gives
['1','2']
which corresponding to the subexpression (\d). But how can it return the whole room number like 101 and 202?
import re
print [i for i,j in re.findall(r'\b((\d)\d\2)\b','101 102 103 201 202 203')]
or
print [i[0] for i in re.findall(r'\b((\d)\d\2)\b','101 102 103 201 202 203')]
You can use list comprehension here.You need only room numbers so include only i.basically re.findall return all groups in a regex.So you need 2 groups.The first is will have room numbers and second will be used for matching.So we can extract just the first out of the tuple of 2.

Split String with Python Regexp

If I have a string like:
"|CLL23|STR. CALIFORNIA|CLL12|AV. PHILADELFIA 438|CLL10|AV. 234 DEPTO 34|"
I need to separate the string form next:
CLL23|STR.CALIFORNIA
CLL12|AV. TEXAS 345
CLL10|AV. 234 DEPTO 24
Try the following form:
r=re.compile('(?<=[|])([\w]+)')
v_sal=r.findall(v_campo)
print v_sal
Result:
['CLL23', 'CLL12', 'CLL10']
That way you could get the rest of the string in Python?
Let's define your string:
>>> s = "|CLL23|STR. CALIFORNIA|CLL12|AV. PHILADELFIA 438|CLL10|AV. 234 DEPTO 34|"
Now, let's print the formatted form:
>>> print('\n'.join('CLL' + word.rstrip('|') for word in s.split('|CLL') if word))
CLL23|STR. CALIFORNIA
CLL12|AV. PHILADELFIA 438
CLL10|AV. 234 DEPTO 34
The above divides on |CLL. This seems to work for your sample input.
Another simple solution would be to split() the string at every '|' and then print them in chunks:
s="|CLL23|STR. CALIFORNIA|CLL12|AV. PHILADELFIA 438|CLL10|AV. 234 DEPTO 34|"
s1=filter(None, s.split('|')) #split string and filter empty strings
for x,y in zip(s1[0::2], s1[1::2]):
print x + '|' + y
Output:
>>>
CLL23|STR. CALIFORNIA
CLL12|AV. PHILADELFIA 438
CLL10|AV. 234 DEPTO 34

Categories