0

I am attempting to create a simple program that reads enzyme cuts from a dna sequence file. My problem is that I cannot get the first block to repeat in a loop. What am I doing wrong so I can turn this into a loop? Any help is greatly appreciated, thanks!!

sequence = open('sequence.txt').read().replace('\n','')
enzymes = {}
fh = open('enzymes.txt')
print('Restriction Enzyme Counter')
inez = input('Enter a Restricting Enzyme: ')
def servx():
    for line in fh.readlines():
        (name, site, junk, junk) = line.split()
        enzymes[name] = site 
        if inez in line:
            xcr = site
            print('Active Bases:', site)
    for line in sequence.split():
        if xcr in line:
            bs = (sequence.count(xcr))
            print('Enzyme', inez, 'appears', bs, 'times in Sequence.')
servx()
inez = input('Find another Enzyme? [Yes/No]:')
if inez is 'Yes':
    servx()
fh.close()
martineau
  • 119,623
  • 25
  • 170
  • 301
Joker
  • 21
  • 3
  • 2
    How do you know your loop isn't running? – Falmarri Oct 13 '16 at 20:26
  • 1
    generally more readable if you put your function at the top and then after that put a couple of blank lines then the code as it runs. – Sam Redway Oct 13 '16 at 20:28
  • I wouldn't really call this a "simple loop" – OneCricketeer Oct 13 '16 at 20:28
  • 1
    Note that you call your `servx` function two times, but the second time you call it, the `fh` file handle will already be exhausted, and thus the loop will not run. Is this the problem? The first time you call it it should run fine, though. – tobias_k Oct 13 '16 at 20:30
  • Here is my output: Restriction Enzyme Counter Enter a Restricting Enzyme: AarI Active Bases: CACCTGC Enzyme AarI appears 12 times in Sequence. Find another Enzyme? [Yes/No]: Its entirely skipping over the 'def' value, and exiting... – Joker Oct 13 '16 at 20:31
  • 2
    It does _not_ skip the loop, otherwise you would not get the "Enzyme AarI appears 12 times in Sequence" output. It is only skipping the loop the second time you call the function, which is just as I said because the file iterator is already exhausted. Looking for duplicate to close. – tobias_k Oct 13 '16 at 20:33
  • 1
    This is massively inefficent even with the corrections. You should look into dictionaries and do all the pre-processing in one step before the repeated loop. Even then it will only run one extra time. – roganjosh Oct 13 '16 at 20:36

2 Answers2

0

You have which might not do what you think it does:

for line in fh.readlines():

.readlines() read the whole file and returns what it read. So when you do that, your line variable in the loop, isn't just one line of the file, it's the whole file at once. So your for loop only runs once since there's nothing else to iterate in the file after the first loop, since you read to End of file. Basically you did read one line from the file but you exhausted the whole file in one go.

I think what you wanted to do is read one line at a time until end of file:

for line in fh:

Or a better way of reading files all together is:

with open('filename.txt') as fh:
    for line in fh:
        print(line)

The last method doesn't require you to fh.close() the file it handles it for you. But notice how the last method also uses for line in fh:

MooingRawr
  • 4,901
  • 3
  • 24
  • 31
0

Here is an issue in your code which will prevent your function servx() from ever running more than once:

if inez is 'Yes':

This checks if inez is the same instance as the literal string 'Yes'. This will, for all intents and purposes, always return false. What you want is this instead:

if inez == 'Yes'

That checks if the strings match, as opposed to the object instances themselves, according to this question here: Why does comparing strings in Python using either '==' or 'is' sometimes produce a different result?

Community
  • 1
  • 1
Random Davis
  • 6,662
  • 4
  • 14
  • 24
  • `inez is 'Yes'` will return `True`, try it yourself. The variable is sort of a reference to the literal string. See `id(a)` and `id('foo')`. – solarc Oct 13 '16 at 21:23
  • @solarc I tried it in the python console and it returned `False` for me. Do you know why that would be, then? I'm basing this off of this question here: http://stackoverflow.com/questions/1504717/why-does-comparing-strings-in-python-using-either-or-is-sometimes-produce – Random Davis Oct 13 '16 at 21:28
  • interesting. Seems like `id('yes')` is different from `id(''.join(('y','e','s')))`. I thought they would end up being the same. This will lead to `'yes' == ''.join(('y','e','s'))` being true but `'yes' is ''.join(('y','e','s'))` false. I learned something new today. – solarc Oct 14 '16 at 15:15