encrypting a file using shift - python

Not sure what im doing wrong here? the program asks for file name and reads the file but when it come to printing the encoded message it comes up blank. What am I missing, as if I change the phrase to just normal raw_input("enter message") the code will work, but this is not reading from the txt file.
letters = "a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
cshift = int(input("Enter a number: "))
phrase = open(raw_input("file name: "), 'r')
newPhrase = ""
for l in phrase:
if l in letters:
pos = letters.index(l) + cshift
if pos > 25:
pos = pos-26
newPhrase += letters[pos]
else:
newPhrase += " "
print(newPhrase)

The problem here is that the for-loop on this line:
for l in phrase:
will return complete lines, not individual characters.
As such you will have to loop through individual characters from those lines as well, or read the file binary, or use functions on the file object that will read one character at a time.
You could simply do this:
for line in phrase:
for l in line:
... rest of your code here

The open function does not return a string, but a handle to the opened file from which strings can be read. You should search for information on how to read a file into a string in Python and then try it in a REPL to make sure it returns a string and not something else.

Related

Reading line in a file that has been purposely changed

So let's say I have something like;
def scramble():
word = open("wordlist.txt", "a")
userword = input("Give me a word to scramble")
newword = userword.replace("a", "*")
newword2 = neword.replace("o", "0")
word.write(userword)
word.write(\n)
word.close
Take a word, replace characters with those in the code and append that to a file. How can I then create a different function where I ask the user to enter that word again, the code goes back to that file, almost "decrypts" the word and spits it back out at the user in the most simplest of terms. I don't care how messy I'm just completely lost.
I've attempted to reverse the scrambled word but every time I go to check the file for it, regardless of whether or not the word is in there it fails the check.
def unscramble():
word = open("wordlist.txt", "r")
userinput = input("Enter a word and I'll see if i have it")
userinput2 = userinput.replace("*","a")
userinput3 = userinput2.replace("0","o")
for line in word:
if userinput3 in line:
print("Yes, I do have that word. Would you like to see it scrambled?")
else:
print("Sorry, I don't have that")

File Reading and Variable Assignments

So I am trying to make a game where the 'GameMaster' picks the first word from a .txt file, then the user tries to guess the word. Once the user correctly guess the word, the GameMaster looks to the next line in the file and the user has to guess again, so on and so forth...
The problem I am having, is getting the program to assign variables as the game continues. The program should iteratively look until there are no more words to choose from, whether that be 2 or infinity.
Since I don't have much experience working with file interaction in python, the best example I have is something like this:
file "input.txt" will contain:
dog
cat
bird
rat
mouse
And I am looking at what in in the .txt file with this:
def file_read():
with open ('/Users/someone/Desktop/input.txt', 'r') as myfile:
data = myfile.read()
for line in data:
line.rstrip()
return data
Your function returns the entire contents of the file, unaltered. myfile.read() returns the data from the file as a string. The for loop then iterates over every character in that string, not the lines. Furthermore, rstrip() operates only on each character. It does not affect the contents of data because data is an immutable string and the return value of rstrip() is not stored anywhere.
Something like this would better suit:
def file_read():
with open('/Users/someone/Desktop/input.txt') as myfile:
return [line.rstrip() for line in myfile]
This will return a list of the stripped lines from the file. Your word guessing code would then iterate over the list.
The above will work, however, it is not very efficient if the input file is large because all of the file would be read into memory to construct the list. A better way is to use a generator which yields a stripped line one at a time:
def file_read():
with open('/Users/someone/Desktop/input.txt') as myfile:
for line in myfile:
yield line.rstrip()
Now that function is so simple, it seems pointless to bother with it. Your code could simply be:
with open('/Users/someone/Desktop/input.txt') as myfile:
for line in myfile:
user_guess_word(line.rstrip())
where user_guess_word() is a function that interacts with the user to guess what the word is, and returns once the guess it correct.
This way uses readlines to get file contents in a list line by line. readlines returns a list containing lines.
Now iterate through list to check if user input matches with line content (which is a word in this case).
with open ('/Users/someone/Desktop/input.txt', 'r') as myfile:
words = myfile.readlines()
while x < len(words):
if words[x] == input('Enter word to guess'):
print('Predicted word correctly')
else:
print('Wrong word. Try again')
x -= 1
x += 1
You can do it like,
def fun():
data = open('filename', 'r').readlines()
user_guess, i = None, 0
while i < len(data):
user_guess = input()
if user_guess not None and user_guess == data[i]:
i = i + 1
Please trim() / strip() also while you compare user_guess and data[i]

Cannot strip character using .strip() in python

I am a biologist and need to make a quick script to process some files.
The file format is fasta:
>line1
ACCGAGCTACTAGXXXXX
>line2
ACGTAX
et cetera.
I want to remove all X characters and quickly put toghether this script:
print """Input file must be named FILE.fasta"""
fasta_file = raw_input('Input file name:') # Input fasta file
char = raw_input('Which sequence should be stripped?:')
OutFileName = fasta_file.strip('.fasta') + '_stripped.fasta'
OutFile = open(OutFileName, 'w')
WriteOutFile = True
data = open(fasta_file, "r")
for line in data:
if line.startswith('>'):
OutPut = line
else:
OutPut = line.strip(char)
print OutPut
OutFile.write(OutPut)
print(char)
OutFile.close()
quit()
It does not work and I can't figure out why. any help?
P.S. sorry for the terrible code.
The other answers specified better alternatives. But in your case, [Python 3.Docs]: Built-in Types - str.strip([chars]) didn't work because each line in a file ends with the EOLN terminator, so X is not actually at the end of the string.
The option that requires minimum of code changes, is to modify the 3rd line from:
char = raw_input('Which sequence should be stripped?:')
to:
char = raw_input('Which sequence should be stripped?:') + "\n"
Beware: the line fasta_file.strip('.fasta') might not do what you think it does. Here, it would be recommended to use:
fasta_file.replace('.fasta', '_stripped.fasta')
EDIT0:
I think that you need to add the EOLN back when writing to the output file, so you also need to replace this line:
OutPut = line.strip(char)
by:
OutPut = line.strip(char) + "\n"
Use line.replace(char,'') instead line.strip(char)
Strip function removes characters only from sides https://docs.python.org/2/library/string.html#string.strip
You could do this using regex:
import re
pattern = re.compile("(\w[^X]+)") # This groups everything but X
stripped = pattern.match(line).group()
For your case you can do something similar in the 'else' section of your code and replace the 'X' in "(\w[^X]+)" by your 'char' variable:
pattern = re.compile("(\w[^" + char + "]+)")

Reading a word from a file in a specific way

So I am trying to store a single word to a file (which i have already managed to figure out how to do). The program would then repeat and ask me to input another word. It should check if this word already exists in the file (which it should). I have it to the point where i have inputted a word and it has stored it in the file but when i input the same word again it doesn't realise that the word already exists in the file. (This is all in a def function so when i say the next time it goes round i mean the next time i call the function)
Here is the code:
def define():
testedWord = subject
lineNumber = 1
lineInFile = "empty"
exists = False
while lineInFile != "":
wordsFile = open("Words.txt", "a")
lineInFile = linecache.getline("Words.txt", lineNumber)
lineNumber = lineNumber + 1
lineInFile = lineInFile.replace("\n", "")
if lineInFile == subject:
definitionNumber = lineNumber
exists = True
if exists == False:
wordsFile.write(testedWord)
wordsFile.write("\n")
wordsFile.close()
subject = input("")
define()
##This whole thing basically gets repeated
Like i said, if i store a new word and then in the same program try and put in the same word again then it won't recognize that it has already stored this word. When i stop the program and restart it, it works (but i dont want to have to do that)
Thanks for you help (if it is possible to help lol)
Dan
I think you're making (almost) everything more complicated than it needs to be. Here is a different way of doing what you're trying to do:
def word_check(f_name, word):
with open(f_name) as fi:
for line in fi: # let Python deal with line iteration for you
if line.startswith(word):
return # return if the word exists
# word didn't exist, so reopen the file in append mode
with open(f_name, 'a') as fo:
fo.write("{}\n".format(word))
return
def main():
f_name = "test.txt"
with open(f_name, 'w') as fo:
pass # just to create the empty file
word_list = ['a', 'few', 'words', 'with', 'one',
'word', 'repeated', 'few'] # note that 'few' appears twice
for word in word_list:
word_check(f_name, word)
if __name__ == "__main__":
main()
This produces an output file with the following text:
a
few
words
with
one
repeated
In this example, I just created a list of words instead of using input to keep the example simple. Note how inefficient your current method is, though. You're reopening a file and reading every line for every word entered. Consider building your word list in memory instead, and writing it out at the end. Here's an implementation that takes advantage of the built-in set datatype. They don't allow repeated elements. If you're okay with writing out the file at the end of the program run instead of on-the-fly, you can do this instead:
def main():
word_set = set()
while True:
word = input("Please enter a word: ")
if word == 'stop': # we're using the word 'stop' to break from the loop
break # this of course means that 'stop' should be entered
# as an input word unless you want to exit
word_set.add(word)
with open('test.txt', 'w') as of:
of.writelines("{}\n".format(word) for word in word_set)
# google "generator expressions" if the previous line doesn't
# make sense to you
return
if __name__ == "__main__":
main()
Printed output:
Please enter a word: apple
Please enter a word: grape
Please enter a word: cherry
Please enter a word: grape
Please enter a word: banana
Please enter a word: stop
Produces this file:
grape
banana
cherry
apple

How to read multiple lines of raw input?

I want to create a Python program which takes in multiple lines of user input. For example:
This is a multilined input.
It has multiple sentences.
Each sentence is on a newline.
How can I take in multiple lines of raw input?
sentinel = '' # ends when this string is seen
for line in iter(input, sentinel):
pass # do things here
To get every line as a string you can do:
'\n'.join(iter(input, sentinel))
Python 2:
'\n'.join(iter(raw_input, sentinel))
Alternatively, you can try sys.stdin.read() that returns the whole input until EOF:
import sys
s = sys.stdin.read()
print(s)
Keep reading lines until the user enters an empty line (or change stopword to something else)
text = ""
stopword = ""
while True:
line = raw_input()
if line.strip() == stopword:
break
text += "%s\n" % line
print text
Just extending this answer https://stackoverflow.com/a/11664652/4476612
instead of any stop word you can just check whether a line is there or not
content = []
while True:
line = raw_input()
if line:
content.append(line)
else:
break
you will get the lines in a list and then join with \n to get in your format.
print '\n'.join(content)
Try this
import sys
lines = sys.stdin.read().splitlines()
print(lines)
INPUT:
1
2
3
4
OUTPUT:
['1', '2', '3', '4']
*I struggled with this question myself for such a long time, because I wanted to find a way to read multiple lines of user input without the user having to terminate it with Control D (or a stop word).
In the end i found a way in Python3, using the pyperclip module (which you'll have to install using pip install)
Following is an example that takes a list of IPs
*
import pyperclip
lines = 0
while True:
lines = lines + 1 #counts iterations of the while loop.
text = pyperclip.paste()
linecount = text.count('\n')+1 #counts lines in clipboard content.
if lines <= linecount: # aslong as the while loop hasn't iterated as many times as there are lines in the clipboard.
ipaddress = input()
print(ipaddress)
else:
break
For me this does exactly what I was looking for; take multiple lines of input, do the actions that are needed (here a simple print) and then break the loop when the last line was handled. Hope it can be equally helpful to you too.
sys.stdin.read() can be used to take multiline input from user. For example
>>> import sys
>>> data = sys.stdin.read()
line one
line two
line three
<<Ctrl+d>>
>>> for line in data.split(sep='\n'):
print(line)
o/p:line one
line two
line three
The easiest way to read multiple lines from a prompt/console when you know exact number of lines you want your python to read, is list comprehension.
lists = [ input() for i in range(2)]
The code above reads 2 lines. And save inputs in a list.
Its the best way for writing the code in python >3.5 version
a= int(input())
if a:
list1.append(a)
else:
break
even if you want to put a limit for the number of values you can go like
while s>0:
a= int(input())
if a:
list1.append(a)
else:
break
s=s-1
A more cleaner way (without stop word hack or CTRL+D) is to use Python Prompt Toolkit
We can then do:
from prompt_toolkit import prompt
if __name__ == '__main__':
answer = prompt('Paste your huge long input: ')
print('You said: %s' % answer)
It input handling is pretty efficient even with long multiline inputs.
The Python Prompt Toolkit is actually a great answer, but the example above doesn't really show it. A better example is get-multiline-input.py from the examples directory:
#!/usr/bin/env python
from prompt_toolkit import prompt
from prompt_toolkit.formatted_text import HTML
def prompt_continuation(width, line_number, wrap_count):
"""
The continuation: display line numbers and '->' before soft wraps.
Notice that we can return any kind of formatted text from here.
The prompt continuation doesn't have to be the same width as the prompt
which is displayed before the first line, but in this example we choose to
align them. The `width` input that we receive here represents the width of
the prompt.
"""
if wrap_count > 0:
return " " * (width - 3) + "-> "
else:
text = ("- %i - " % (line_number + 1)).rjust(width)
return HTML("<strong>%s</strong>") % text
if __name__ == "__main__":
print("Press [Meta+Enter] or [Esc] followed by [Enter] to accept input.")
answer = prompt(
"Multiline input: ", multiline=True, prompt_continuation=prompt_continuation
)
print("You said: %s" % answer)
Using this code you get multiline input in which each line can be edited even after subsequent lines are entered. There are some nice additional features, too, such as line numbers. The input is ended by hitting the escape key and then the enter key:
~/Desktop ❯ py prompt.py
Press [Meta+Enter] or [Esc] followed by [Enter] to accept input.
Multiline input: first line of text, then enter
- 2 - second line of text, then enter
- 3 - third line of text, arrow keys work to move around, enter
- 4 - and lines can be edited as desired, until you
- 5 - press the escape key and then the enter key
You said: first line of text, then enter
second line of text, then enter
third line of text, arrow keys work to move around, enter
and lines can be edited as desired, until you
press the escape key and then the enter key
~/Desktop ❯
How do you like this? I mimicked telnet.
The snippet is highly self-explanatory :)
#!/usr/bin/env python3
my_msg = input('Message? (End Message with <return>.<return>) \n>> ')
each_line = ''
while not each_line == '.':
each_line = input('>> ')
my_msg += f'\n{each_line}'
my_msg = my_msg[:-1] # Remove unwanted period.
print(f'Your Message:\n{my_msg}')
With Python 3, you can assign each line to data:
while data := input():
print("line", data)
Simple, do
lst = [x for x in input("Enter numbers seperated by spaces").split("\n")]
line = input("Please enter lines: ")
lines = ""
while line:
lines += "\n" + line
line = input()
print(lines)
def sentence_maker(phrase):
return phrase
results = []
while True:
user_input = input("What's on your mind: ")
if user_input == '\end':
break
else:
results.append(sentence_maker(user_input))
print('\n'.join(map(str, results)))

Categories

Resources