Strings won't compare properly - python

I'm new to python so excuse any poor code you may find
The problem I'm having is that I'm trying to compare two strings, one from a file and one from user input, to see if they match. However, when comparing what seem to me identical strings, the if statement returns false. I have used the str() function to turn both of the values into strings, but it still doesn't want to play ball.
For reference, the line of the file is two strings, separated by a comma, and the 'question' part is before the comma and the 'answer' after it. At present, both the strings are test strings, and so have the values of 'Question' and 'Answer'
import linecache
def askQuestion(question, answer):
choice = input(question)
str(choice)
if choice == answer:
print("Correct")
else:
print("Bad luck")
file = "C://questions.txt"
text = linecache.getline(file, 1)
question = text.split(",", 1)[0]
answer = text.split(",", 1)[-1]
str(answer)
askQuestion(question, answer)
I am typing in exactly what the file has i.e. capital letters in the right place, for note.
I'm sure the answer obvious, but I'm at a loss, so any help would be kindly appreciated.
Thanks!

text = linecache.getline(file, 1)
question = text.split(",", 1)[0]
answer = text.split(",", 1)[-1]
this is more commonly written
text = linecache.getline(file, 1)
question, answer = text.split(",", 1)
The results will be a string. There is no interpretation happening. Also, you need to store the result of str().
my_string = str(number)
By calling str() but not saving it the result is being lost. Not important here, but something to keep in mind.
As Alex mentions in the comment above you are missing the call to strip to remove the newline. How do I know? I tried it in the interpreter.
$ python
>>> import linecache
>>> line = linecache.getline("tmpfile", 1)
>>> line
'* Contact Numbers\n'
See that '\n' there? That is your problem.
Another way would have been to invoke pdb the Python Debugger. Just add
import pdb; pdb.set_trace()
where you want to stop the execution of a Python script.
Good luck.

Related

Python won't accept two same strings as the same

I'm quite a newcomer to Python and I am stuck in the following situation:
I want to hash a password and compare it with the masterhash. Unfortunately Python doesn't accept them as the same:
import hashlib
h=hashlib.sha512()
username='admin'
username=username.encode('utf-8')
h.update(username)
hexdigest=h.hexdigest()
hlist=open("database.txt")#masterhash
lines=hlist.readlines()
userhash=lines[0]#masterhash in line 0
if userhash == hexdigest: # it doesent accept them as the same
text = "True"
else:
text="False"
I already checked the objectypes: both string
The hash, both times:
c7ad44cbad762a5da0a452f9e854fdc1e0e7a52a38015f23f3eab1d80b931dd472634dfac71cd34ebc35d16ab7fb8a90c81f975113d6c7538dc69dd8de9077ec
I really don't understand the problem.
The problem is this line:
lines = hlist.readlines()
Each value in this list will have a trailing newline (which you may not notice when printing). Make sure you strip that off.
userhash = lines[0].strip()
readlines() returns lines with newlines at their ends. You are comparing "A" with "A\n". Try this:
if userhash.strip() == hexdigest
When you use readlines() you get a list of the lines with the new line character at the end of each line, you can do one of two options:
Option #1:
lines = hlist.readlines()
userhash = lines[0].rstrip()
Option #2:
lines = hlist.read().splitlines()
userhash = lines[0]

How do I compare a variable to a string in python? [duplicate]

This question already has an answer here:
Why doesn't the result from sys.stdin.readline() compare equal when I expect it to?
(1 answer)
Closed 6 years ago.
Im new to this so Im sorry if this isn't the best way to ask the question...
here is the code -
import sys
print("What is ur name?")
name = sys.stdin.readline()
answer = "jack"
if name is answer :
print("ur awesome")
exit();
right now when I run it in cmd I don't get anything printed even though
I input - jack? thank you in advance
Firstly, replace is with ==. is checks whether the two underlying strings are the same entity (in memory) whereas == just wants to check if they have the same value.
Because the source of "jack" is coming from two sources (one from the user, another hard-coded by you) they are two seperate objects.
As #dawg mentioned you also have to use the .strip() to get rid of the newline when using sys.stdin.readline() for input. The best way to read input is to use the input() method in python3, or raw_input() in python2.
name = input('What is your name?\n')
Use == for string comparison. Also, readline() will include the newline at the end of the string. You can strip it with e.g.
name = name.strip()
Alternatively, you can use raw_input() (input() in python 3) instead of readline(), as it will not include the newline to begin with.
name = raw_input("What is your name?\n")
It's helpful to be able to print a string to see if it has any extra whitespace, e.g.
print("name: [%s]\n" % name)

Function creation - "Undefined name" - Python

I'm writing some code that reads words from a text file and sorts them into a dictionary. It actually all runs fine, but for reference here it is:
def find_words(file_name, delimiter = " "):
"""
A function for finding the number of individual words, and the most popular words, in a given file.
The process will stop at any line in the file that starts with the word 'finish'.
If there is no finish point, the process will go to the end of the file.
Inputs: file_name: Name of file you want to read from, e.g. "mywords.txt"
delimiter: The way the words in the file are separated e.g. " " or ", "
: Delimiter will default to " " if left blank.
Output: Dictionary with all the words contained in the given file, and how many times each word appears.
"""
words = []
dictt = {}
with open(file_name, 'r') as wordfile:
for line in wordfile:
words = line.split(delimiter)
if words[0]=="finish":
break
# This next part is for filling the dictionary
# and correctly counting the amount of times each word appears.
for i in range(len(words)):
a = words[i]
if a=="\n" or a=="":
continue
elif dictt.has_key(a)==False:
dictt[words[i]] = 1
else:
dictt[words[i]] = int(dictt.get(a)) + 1
return dictt
The problem is that it only works if the arguments are given as string literals, e.g, this works:
test = find_words("hello.txt", " " )
But this doesn't:
test = find_words(hello.txt, )
The error message is undefined name 'hello'
I don't know how to alter the function arguments such that I can enter them without speech marks.
Thanks!
Simple, you define that name:
class hello:
txt = "hello.txt"
But joking aside, all the argument values in a function call are expressions. If you want to pass a string literally you'll have to make a string literal, using the quotes. Python is not a text preprocessor like m4 or cpp, and expects the entire program text to follow its syntax.
So it turns out I just misunderstood what was being asked. I've had it clarified by the course leader now.
As I am now fully aware, a function definition needs to be told when a string is being entered, hence the quote marks being required.
I admit full ignorance over my depth of understanding of how it all works - I thought you could pretty much put any assortment of letters and/or numbers in as an argument and then you can manipulate them within the function definition.
My ignorance may stem from the fact that I'm quite new to Python, having learned my coding basics on C++ where, if I remember correctly (it was well over a year ago), functions are defined with each argument being specifically set up as their type, e.g.
int max(int num1, int num2)
Whereas in Python you don't quite do it like that.
Thanks for the attempts at help (and ridicule!)
Problem is sorted now.

Write text to file in columns

As an attorney I am a total newbie in programimg. As an enthusiastic newbie, I learn a lot. (what are variables, ect.) ).
So I'm working a lot with dir() and I'm looking into results. It would by nicer if I could see the output in one or more columns. So I want to write my first program which write for example dir(sys) in a output file in columns.
So far I've got this:
textfile = open('output.txt','w')
syslist = dir(sys)
for x in syslist:
print(x)
The output on display is exactly what I want, but when I use the .write like:
textfile = open('output.txt','w')
syslist = dir(sys)
for x in syslist:
textfile.write(x)
textfile.close()
The text is in lines.
Can anyone pleaase help me, how to write the output of dir(sys) to a file in columns?
If I can ask you, please write the easysiet way, because I really have to look almost after for every word you write in documentation. Thanks in advance.
print adds a newline after the string printed by default, file.write doesn't. You can do:
for x in syslist: textfile.write("%s\n" % x)
...to add newlines as you're appending. Or:
for x in syslist: textfile.write("%s\t" % x)
...for tabs in between.
I hope this is clear for you "prima facie" ;)
The other answers seem to be correct if they guess that you're trying to add newlines that .write doesn't provide. But since you're new to programming, I'll point out some good practices in python that end up making your life easier:
with open('output.txt', 'w') as textfile:
for x in dir(sys):
textfile.write('{f}\n'.format(f=x))
The 'with' uses 'open' as a context manager. It automatically closes the file it opens, and allows you to see at a quick glance where the file is open. Only keep things inside the context manager that need to be there. Also, using .format is often encouraged.
Welcome to Python!
The following code will give you a tab-separated list in three columns, but it won't justify the output for you. It's not fully optimized so it should be easier to understand, and I've commented the portions that were added.
textfile = open('output.txt','w')
syslist = dir(sys)
MAX_COLUMNS = 3 # Maximum number of columns to print
colcount = 0 # Track the column number
for x in syslist:
# First thing we do is add one to the column count when
# starting the loop. Since we're doing some math on it below
# we want to make sure we don't divide by zero.
colcount += 1
textfile.write(x)
# After each entry, add a tab character ("\t")
textfile.write("\t")
# Now, check the column count against the MAX_COLUMNS. We
# use a modulus operator (%) to get the remainder after dividing;
# any number divisible by 3 in our example will return '0'
# via modulus.
if colcount % MAX_COLUMNS == 0:
# Now write out a new-line ("\n") to move to the next line.
textfile.write("\n")
textfile.close()
Hope that helps!
I'm a little confused by your question, but I imagine the answer is as simple as adding in tabs. So change textfile.write(x) to textfile.write(x + "\t"), no? You can adjust the number of tabs based on the size of the data.
I'm editing my answer.
Note that dir(sys) gives you an array of string values. These string values do not have any formatting. The print x command adds a newline character by default, which is why you are seeing them each on their own line. However, write does not. So when you call write, you need to add in any necessary formatting. If you want it to look identical to the output of print, you need to add in write(x + "\n") to get those newline characters that print was automatically including.

Incorporating multiple lists in one text file

I am new to coding and I ran in trouble while trying to make my own fastq masker. The first module is supposed to trim the line with the + away, modify the sequence header (begins with >) to the line number, while keeping the sequence and quality lines (A,G,C,T line and Unicode score, respectively).
class Import_file(object):
def trim_fastq (self, fastq_file):
f = open('path_to_file_a', 'a' )
sanger = []
sequence = []
identifier = []
plus = []
f2 = open('path_to_file_b')
for line in f2.readlines():
line = line.strip()
if line[0]=='#':
identifier.append(line)
identifier.replace('#%s','>[i]' %(line))
elif line[0]==('A' or 'G'or 'T' or 'U' or 'C'):
seq = ','.join(line)
sequence.append(seq)
elif line[0]=='+'and line[1]=='' :
plus.append(line)
remove_line = file.writelines()
elif line[0]!='#' or line[0]!=('A' or 'G'or 'T' or 'U' or 'C') or line[0]!='+' and line[1]!='':
sanger.append(line)
else:
print("Danger Will Robinson, Danger!")
f.write("'%s'\n '%s'\n '%s'" %(identifier, sequence, sanger))
f.close()
return (sanger,sequence,identifier,plus)
Now for my question. I have ran this and no error appears, however the target file is empty. I am wondering what I am doing wrong... Is it my way to handle the lists or the lack of .join? I am sorry if this is a duplicate. It is simply that I do not know what is the mistake here. Also, important note... This is not some homework, I just need a masker for work... Any help is greatly appreciated and all mentions of improvement to the code are welcomed. Thanks.
Note (fastq format):
#SRR566546.970 HWUSI-EAS1673_11067_FC7070M:4:1:2299:1109 length=50
TTGCCTGCCTATCATTTTAGTGCCTGTGAGGTGGAGATGTGAGGATCAGT
+
hhhhhhhhhhghhghhhhhfhhhhhfffffe`ee[`X]b[d[ed`[Y[^Y
Edit: Still unable to get anything, but working at it.
Your problem is with your understanding of the return statement. return x means stop executing the current function and give x back to whoever called it. In your code you have:
return sanger
return sequence
return identifier
return plus
When the first one executes (return sanger) execution of the function stops and sanger is returned. The second through fourth return statements never get evaluated and neither does your I/O stuff at the end. If you're really interested in returning all of these values, move this after the file I/O and return the four of them packed up as a tuple.
f.write("'%s'\n '%s'\n '%s'" %(identifier, sequence, sanger))
f.close()
return (sanger,sequence,identifier,plus)
This should get you at least some output in the file. Whether or not that output is in the format you want, I can't really say.
Edit:
Just noticed you were using /n and probably want \n so I made the change in my answer here.
You have all sorts of errors beyond what #Brian addressed. I'm guessing that your if and else tests are trying to check the first character of line? You'd do that with
if line[0] == '#':
etc.
You'll probably need to write more scripts soon, so I suggest you work through the Python Tutorial so you can get on top of the basics. It'll be worth your while.

Categories

Resources