How do I make my program print the answers on separate lines + with what key the line corresponds to?
def break_crypt(message):
for key in range(1,27):
for character in message:
if character in string.uppercase:
old_ascii=ord(character)
new_ascii=(old_ascii-key-65)%26+65
new_char=chr(new_ascii)
sys.stdout.write(new_char),
elif character in string.lowercase:
old_ascii=ord(character)
new_ascii=(old_ascii-key-97)%26+97
new_char=chr(new_ascii)
sys.stdout.write(new_char),
else:
sys.stdout.write(character),
to jump a line simply use "\n"
for instance:
sys.stdout.write("a\nb")
will write a and b in differents lines
use + to add a string to another
sys.stdout.write("a"+variable+"b")
there is other "more advanced" ways like
sys.stdout.write("a%sb" % variable)
or
sys.stdout.write("a{0}b".format(variable)
also in your code if there is no point of using sys.stdout.write don't use it
this may helps you
https://docs.python.org/2/tutorial/introduction.html
If you simply add the following at the end of the outer loop, then it'll both print the key and go to the next line:
print '', key
Then the output will look like this:
Sghr hr z sdrs 1
Rfgq gq y rcqr 2
Qefp fp x qbpq 3
.
.
.
Uijt jt b uftu 25
This is a test 26
But I would really build the whole string for the current key in a string variable and then print it at once.
Related
I have a txt file with three debug signature present on them.
x = 'task cocaLc Requested reboot'
y = 'memPartFree'
z = 'memPartAlloc'
import re
f = open('testfile.txt','r')
searchstrings = ('task cocaLc Requested reboot', 'memPartFree', 'memPartAlloc')
for line in f():
for word in searchstrings:
if any (s in line for s in searchstrings):
print 'defect'
I want to create a short script to scan through the file and print 'defect' only if all these three strings are present.
I was trying creating with different ways, but unable to meet the requirement.
First, there is a small error on line 4 of the example code. f is not callable, and thus you shouldn't be using parenthesis next to it.
If you have a file with the following in it:
task cocaLc Requested reboot
memPartFree
memPartAlloc
It will print out "defect" 9 times because you're checking once for each line, and once for each search string. So three lines, times three search strings is 9.
The any() function will return True any time the file contains at least one of the defined search strings. Thus, this code will print out "defect" once for each line, multiplied by the number of search strings you've defined.
To resolve this, the program will need to know if/when any of the particular search strings have been detected. You might do something like this:
f = open('testfile.txt','r')
searchstrings = ['task cocaLc Requested reboot', 'memPartFree', 'memPartAlloc']
detections = [False, False, False]
for line in f:
for i in range(0, len(searchstrings)):
if searchstrings[i] in line: #loop through searchstrings using index numbers
detections[i] = True
break #break out of the loop since the word has been detected
if all(detections): #if every search string was detected, every value in detections should be true
print "defect"
In this code, we loop through the lines and the search strings, but the detection variable serves to tell us which search strings have been detected in the file. Thus, if all elements in that list are true, that means all of the search strings have been detected in the file.
I am trying to run the following code:
fname = raw_input ('Enter file name:')
fh = open (fname)
count = 0
for line in fh:
if not line.startswith ('X-DSPAM-Confidence:') : continue
else:
count = count + 1
new = fh #this new = fh is supposed to be fh stripped of the non- x-dspam lines
for line in new: # this seperates the lines in new and allows `finding the floats on each line`
numpos = new.find ('0')
endpos = new.find ('5', numpos)
num = new[numpos:endpos + 1]
float (num)
# should now have a list of floats
print num
The intention of this code is to prompt the user for a file name, open the file, read through the file, compile all the lines that start with X-DSPAM, and extract the float number on these lines. I am fairly new to coding so I realise I may have committed a number of errors, but currently when I try to run it, after putting in the file name I get the return:
I looked around and I have seen that mode 'r' refers to different file modes in python in relation to how the end of the line is handled. However the code I am trying to run is similar to other code I have formulated and it does not have any non-text files inside, the file being opened is a .txt file. Is it something to do with converting a list of strings line by line to a list of float numbers?
Any ideas on what I am doing wrong would be appreciated.
The default mode of handling a file is 'r' - which means 'read', which is what you want. It means the program is going to read the file (as opposed to 'w' - write, or 'a' - append, for example - which would allow you to overwrite the file or append to it, which you don't want in this case).
There are some bugs in your code, which I've tried to indicate in the edited code below.
You don't need to assign new = fh - you're not grabbing lines and passing them to a new file. Rather, you're checking each line against the 'XDSPAM' criteria and if it's a match, you can proceed to parse out the desired numbers. If not, you ignore it and go to the next line.
With that in mind, you can move all of the code from the for line in new to be part of the original if not ... else block.
How you find the end of the number is also a bit off. You set endpos by searching for an occurence of the number 5 - but what I think you want is to find a position 5 characters from the start position (numpos + 5).
(There are other ways to parse the line and pull the number, but I'm going to stick with your logic as indicated by your code, so nothing fancy here.)
You can convert to float in the same statement where you slice the number from the line (as below). It's acceptable to do:
num = line[numpos:endpos+1]
float_num = float(num)
but not necessary. In any event, you want to assign the conversion (float(num)) to a variable - just having float(num) doesn't allow you to pass the converted value to another statement (including print).
You say that you should have 'a list of floats' - the code as corrected below - will give you a display of all the floats, but if you want an actual Python list, there are other steps involved. I don't think you wanted a Python list, but just in case:
numlist = [] # at the beginning, declare a new, empty list
...
# after converting to float, append number to list
XDSPAM.append(num)
print XDSPAMs # at end of program, to print full list
In any event, this edited code works for me with an appropriate file of test data, and outputs the desired float numbers:
fname = raw_input ('Enter file name:')
fh = open (fname)
count = 0
for line in fh:
if not line.startswith ('X-DSPAM-Confidence:') : continue
else:
# there's no need to create the 'new' variable
# any lines that meet the criteria can be processed for numbers
count = count + 1
numpos = line.find ('0')
# i think what you want here is to set an endpoint 5 positions to the right
# but your code was looking for the position of a '5' in the line
endpos = numpos + 5
# you can convert to float and slice in the same statement
num = float(line[numpos:endpos+1])
print num
I am having trouble understanding how one of the for loops works in Learn Python the Hard Way ex.41. http://learnpythonthehardway.org/book/ex41.html Below is the code from the lesson.
The loop that I am confused about is for i in range(0, snippet.count("###")):
Is it iterating over a range of 0 to snippet (of which there are 6 snippet), and adding the extra value of the count of "###"? So for the next line of code param_count = random.randint(1,3) the extra value of "###" is applied? Or am I way off!?
Cheers
Darren
import random
from urllib import urlopen
import sys
WORD_URL = "http://learncodethehardway.org/words.txt"
WORDS = []
PHRASES = {
"class %%%(%%%):":
"Make a class named %%% that is-a %%%.",
"class %%%(object):\n\tdef __init__(self, ***)" :
"class %%% has-a __init__ that takes self and *** parameters.",
"class %%%(object):\n\tdef ***(self, ###)":
"class %%% has-a function named *** that takes self and ### parameters.",
"*** = %%%()":
"Set *** to an instance of class %%%.",
"***.***(###)":
"From *** get the *** function, and call it with parameters self, ###.",
"***.*** = '***'":
"From *** get the *** attribute and set it to '***'."
}
# do they want to drill phrases first
PHRASE_FIRST = False
if len(sys.argv) == 2 and sys.argv[1] == "english":
PHRASE_FIRST = True
# load up the words from the website
for word in urlopen(WORD_URL).readlines():
WORDS.append(word.strip())
def convert(snippet, phrase):
class_names = [w.capitalize() for w in
random.sample(WORDS, snippet.count("%%%"))]
other_names = random.sample(WORDS, snippet.count("***"))
results = []
param_names = []
for i in range(0, snippet.count("###")):
param_count = random.randint(1,3)
param_names.append(', '.join(random.sample(WORDS, param_count)))
for sentence in snippet, phrase:
result = sentence[:]
# fake class names
for word in class_names:
result = result.replace("%%%", word, 1)
# fake other names
for word in other_names:
result = result.replace("***", word, 1)
# fake parameter lists
for word in param_names:
result = result.replace("###", word, 1)
results.append(result)
return results
# keep going until they hit CTRL-D
try:
while True:
snippets = PHRASES.keys()
random.shuffle(snippets)
for snippet in snippets:
phrase = PHRASES[snippet]
question, answer = convert(snippet, phrase)
if PHRASE_FIRST:
question, answer = answer, question
print question
raw_input("> ")
print "ANSWER: %s\n\n" % answer
except EOFError:
print "\nBye"
snippet.count("###") returns the number of times "###" appears in snippet.
If "###" appears 6 times, then the for-loop iterates from 0 to 6.
"try except" block runs the program until the user hits ^ D.
"While True" loop inside "try" stores list of keys from PHRASES dictonary into snippets. The order of keys is different each time (because of shuffle method). "for loop" inside that "While loop" is to go through each snippet and call convert method on key and value of that snippet.
All "convert method" does it to replace %%%, ***, and ### of that key and value with a random word from the url list of words and return a list (results) consists of two strings: one made from the key and one made from the value.
Then the program prints one of the strings as a question, then gets user input (using raw_input("> ")), but no matter what the user entered, it prints the other returned string as the answer.
Inside convert method, we have three different lists : class_names, other_names, and param_names.
To make class_names, the program counts the number of %%% isnide that key (or value, but they are the same numbers of %%% in them anyways). class_names will be a random list of words in the size of the count of %%%.
other_names is a random list of words again. How many words? in the number of *** found in key (or value, does not matter which one because it is the same in any pairs of them)
param_names is a list of strings in the size of the number of ### found. Each string consists of one, two or three different words seperated by ,.
'result' is a string. The program goes over the three lists (class_names, param_names and other_names), and replace something in result string with what it already made ready for it. Then append this into results list. The (for sentence in snippet, phrase:) loop runs two times because 'snippet' and 'phrase' are two different strings. So, 'result' string is being made two times (one for question one for answer).
I put one part of this program to a smaller sub program to clarify how a list of a certain size from random words in the url is created:
https://github.com/MahshidZ/python-recepies/blob/master/random_word_set.py
Finally, I suggest to put print statements any where in code that you need to understand better. An an example, for this code I printed a number of variables to get exactly what is going on. This is a good way of debugging without a debugger: (look for the boolean variable DEBUG in my code)
DEBUG = 1
if DEBUG:
print "snippet: " , snippet
print "phrase: ", phrase
print "class names: ", class_names
print "other names: " , other_names
print "param names: ", param_names
I have a list of terms in a file that I want to read, modify each term and output the new terms to a new file. The new terms should look like this: take the first two characters of the original term put them in quotes, add a '=>' then the original term in quotes and a comma.
This is the code I'm using:
def newFile(newItem):
original = line
first = line[0:2]
newItem = first+'=>'+original+','
return newItem
input = open('/Users/george/Desktop/input.txt', 'r')
output = open('/Users/george/Desktop/output.txt', 'w')
collector = ''
for line in input:
if len(line) != 0:
collector = newFile(input)
output.write(''.join(collector))
if len(line) == 0:
input.close()
output.close()
For example:
If the terms in the input.txt file are these:
term 1
term 2
term 3
term 4
The output is this:
te=>term 1
,te=>term 2
,te=>term 3
,te=>term 4
,
How can I add '' to the first two letters and to the term? And why the second, third and forth terms have ,te not te like it should?
Instead of using collector and newFile() you can use new variable:
modified_line = "'%s'=>'%s'," % (line[:2], line.strip())
and in your loop try this:
...
if len(line) > 2:
output.write('%s\n' % (modified_line))
Also:
if possible do not hard code file names in your program, use sys.argv, standard input/output or config file; of course if you are sure of input/output names then use them
in line[0:2] you can ommit 0 and use line[:2]
you should use try: - open file - read file etc. finally: close file
you don't need to check if len(line) == 0, for loop do it already and you will receive line with CRLF for empty lines, but end of input file is when for loop ends
I'm working on a simple Python game where the computer tries to guess a number you think of. Every time it guesses the right answer, it saves the answer to a txt file. When the program is run again, it will guess the old answers first (if they're in the range the user specifies).
try:
f = open("OldGuesses.txt", "a")
r = open("OldGuesses.txt", "r")
except IOError as e:
f = open("OldGuesses.txt", "w")
r = open("OldGuesses.txt", "r")
data = r.read()
number5 = random.choice(data)
print number5
When I run that to pull the old answers, it grabs one item. Like say I have the numbers 200, 1242, and 1343, along with spaces to tell them apart, it will either pick a space, or a single digit. Any idea how to grab the full number (like 200) and/ or avoid picking spaces?
The r.read() call reads the entire contents of r and returns it as a single string. What you can do is use a list comprehension in combination with r.readlines(), like this:
data = [int(x) for x in r.readlines()]
which breaks up the file into lines and converts each line to an integer.