Q:

Python subsetting sequence using list of numbers

I am trying to write a program that takes a file that has a list of numbers and use each of these numbers to subset a part of a string. When I try to call my function (below) I get the error:
TypeError: unsupported operand type(s) for -: 'str' and 'int'

I tried changing the i in the for loop to int(i) in case, for some reason, i wasn't an integer but that resulted in the following error:
ValueError: invalid literal for int() with base 10: ''

Code:
#Function Collects Sequences and Writes to a Files
def gen_insertion_seq(index, seq, gene):
    output = open("%s_insertion_seq.txt" % gene, 'w')
    indices = index.read()
    sequence = seq.read()
    for i in indices:
        site = sequence[i-9:i+15]
        output.write(site + '\n')

#Open Index Files
shaker_index = open("212_index.txt")
kir2_index = open("214_index.txt")
asic1a_index = open("216_index.txt")
nachra7_index = open("252_index.txt")

#Open Sequence Files
shaker_seq = open("212_seq.txt")
kir2_seq = open("214_seq.txt")
asic1a_seq = open("216_seq.txt")
nachra7_seq = open("252_seq.txt")
#Call function on Index and Sequence Files - Should output list of generated Sequences for insertion sites.
#Must hand check first couple
gen_insertion_seq(shaker_index, shaker_seq, 'shaker')

Sample input files:
212_index.txt
1312
210
633
696
1475
637
1198
645
1504
361
651
...

212_seq.txt
ATGGCCGCCGTGGCACTGCGAGAACAACAGCTCCAACGAAATAGTCTGGATGGATACGGTTCACTGCCTAAACTGTCTAGCCAAGACGAAGAAGGTGGCGCCGGCCATGGCTTCGGTGGGGGC

A:

The errors in your code are caused by the fact that read does not do quite what you seem to expect. Called without parameters, it reads the entire file into a string. You then iterate over the characters in the string instead of the numbers in the file. The TypeError happens when you do '1' - 9 in the index to the sequence.
Your intuition to convert the iterated values to int is basically correct. However, since you are still iterating over characters, you get int('1'), int('3'), int('1'), int('2'), followed by a ValueError from int('\n'). read reads in the entire file as-is, newlines and all.
Fortunately, the file object is iterable over the lines in the file. This means that you can do something like for line in file: ..., and line will take on the string value of each index you want to parse. It has the added bonus that line endings are stripped from the line, meaning that you could pass it directly into int with no further modification, for example.
There are a number of additional improvements you can make to your code, including the corrections that would make it work properly.

As per @Acccumulation's advice, open files in a with block to ensure that they get cleaned up properly if the program crashes, e.g. from an I/O error. It will also close the file automatically when the block ends, which is something you are currently not doing at all (but should be)
Conceptually, there is no need for you to pass around file objects at all. You only use each one in one place for one purpose. I would even extend this to recommend that you write a small function to parse each file type into a usable format and pass that around instead.
Files are iterable by line in Python. This is especially handy for your index files, which are a very line-oriented format. You do not need to do a full read at all, and can save a couple of steps from @MaximTitarenko's comment.
You can use str.join directly on a file to combine any sequences that have line breaks in them.

Combining all that advice, you could do the following:
def read_indices(fname):
    with open(fname, 'r') as file:
        return [int(index) for index in file]

def read_sequence(fname):
    with open(fname, 'r') as file:
        return ''.join(file)

Since files are iterables of strings, you can use them in list comprehensions and string join operations like that. The rest of your code will now look much cleaner:

def gen_insertion_seq(index, seq, gene):
    indices = read_indices(index)
    sequence = read_sequence(seq)
    with open("%s_insertion_seq.txt" % gene, 'w') as output:
        for i in indices:
            site = sequence[i-9:i+15]
            output.write(site + '\n')

gen_insertion_seq('212_index.txt', '212_seq.txt', 'shaker')
gen_insertion_seq('214_index.txt', '214_seq.txt', 'kir2')
gen_insertion_seq('216_index.txt', '216_seq.txt', 'asic1a')
gen_insertion_seq('252_index.txt', '252_seq.txt', 'nachra7')

Your main function is now easier to understand because it focuses only on the sequences and not on things like I/O and parsing. You also don't have a bunch of open file handles floating around, waiting for an error. In fact, the file operations are all self contained, away from the real task.
If you had sequences (in the Python sense) of file IDs and gene names, you could further simplify the call to your function with a loop:
for id, gene in zip((212, 214, 216, 252), ('shaker', 'kir2', 'asic1a', 'nachra7')):
    gen_insertion_seq('%d_index.txt' % id, '%d_seq.txt' % id, gene)

PS. The I/O section in the Python tutorial is really nice. The section on files may be of especial interest to you.

