Answers.Body: <p>I figured it out:</p>
  <pre class="lang-python prettyprint-override"><code>from Bio import SeqIO
  #import pprint
  import textwrap
  
  my_id_file     = open('sample_files2/fasta_id_records.txt','r')
  my_fasta_file  = open('sample_files2/fasta_file.fasta','r')
  result_file    = open('sample_files2/results.fasta', &quot;w&quot;)
  
  my_dictionary = {} # fasta IDs are keys, value can be anything.
  for line in my_id_file:
      my_dictionary[line[:-1]] = 'value'
  
  #pprint.pprint(my_dictionary)
  for seq_record in SeqIO.parse(my_fasta_file, &quot;fasta&quot;):
      if seq_record.id in my_dictionary:      
          #use this line to write standard fasta record using SeqIO.write
          SeqIO.write(seq_record, result_file, &quot;fasta&quot;)
  
  my_fasta_file.close()
  my_id_file.close()
  result_file.close()
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-21T22:13:32.863Z
Answers.Text: I'm not 100% sure you can because that will be taken care within SeqIO.write(). The obvious `seq_record.seq = textwrap.fill(str(seq_record.seq) , width=60)` is unlikely to work.
Answers.UserDisplayName: M__
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-21T22:14:59.927Z
Answers.Text: The only way to do it is within a straight write to disk in you first code ... but (obviously) write rather than print.
Answers.UserDisplayName: M__
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-22T12:00:18.793Z
Answers.Text: it wraps to 60 by default in Biopython 1.8 at least, if saves as 'fasta-2line' uses a single line for the seq
Answers.UserDisplayName: pippo1980
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-21T19:20:38.793Z
Answers.LastActivityDate: 2023-01-21T19:20:38.793Z
Answers.UserDisplayName: Supertech
Answers.Body: <p>You could instead pass in a generator that yields <a href="https://biopython.org/wiki/SeqRecord" rel="nofollow noreferrer">SeqRecords</a>. This avoids storing the entire list of  sequences in memory and is usually the way to go assuming that you need to handle large files containing thousands of records. This example use a generator expression, which is a bit like a list comprehension, but instead of creating a list, it creates a generator:</p>
  <pre><code>import argparse
  import contextlib
  import pathlib
  import sys
  
  from Bio import SeqIO
  </code></pre>
  <pre><code>def get_argument_parser():
  
      parser = argparse.ArgumentParser()
  
      parser.add_argument(
          &quot;fasta_file&quot;,
          type=pathlib.Path,
          metavar='FILE',
          help=&quot;Extract sequence records from FILE&quot;,
      )
      parser.add_argument(
          &quot;ids_file&quot;,
          type=pathlib.Path,
          metavar='FILE',
          help=&quot;Sequence record IDs/names to extract, one per line&quot;,
      )
      parser.add_argument(
          &quot;-o&quot;,
          &quot;--output&quot;,
          type=pathlib.Path,
          metavar='FILE',
          default=&quot;-&quot;,
          help=&quot;Write extracted sequences to FILE (default: stdout)&quot;,
      )
      parser.add_argument(
          &quot;-f&quot;,
          &quot;--force&quot;,
          action='store_true',
          help=&quot;Overwrite the output file if it exists&quot;,
      )
  
      return parser
  </code></pre>
  <pre><code>def main():
  
      parser = get_argument_parser()
      args = parser.parse_args()
  
      with contextlib.ExitStack() as stack:
  
          ids_file = stack.enter_context(open(args.ids_file))
          fasta_file = stack.enter_context(open(args.fasta_file))
  
          if args.output != '-':
              out = stack.enter_context(open(args.output, 'w' if args.force else 'x'))
          else:
              out = sys.stdout
  
          record_ids = {line.rstrip('\n') for line in ids_file}
  
          fasta = SeqIO.parse(fasta_file, &quot;fasta&quot;)
          records = (rec for rec in fasta if rec.id in record_ids)
  
          SeqIO.write(records, out, &quot;fasta&quot;)
  
  if __name__ == &quot;__main__&quot;:
      main()
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-22T12:59:41.647Z
Answers.Text: cool never eard about ExitStack till now https://docs.python.org/3/library/contextlib.html#contextlib.ExitStack
Answers.UserDisplayName: pippo1980
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-22T13:03:26.013Z
Answers.Text: A better description about what it does is here https://www.rath.org/on-the-beauty-of-pythons-exitstack.html @pippo1980
Answers.UserDisplayName: M__
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-22T13:11:22.750Z
Answers.Text: I think I need to ask another question on this code. It's certainly professional code. What I'm wondering is how the if-condition tuple comprehension is a generator because thats the "workhorse" of the code.
Answers.UserDisplayName: M__
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-22T13:21:45.870Z
Answers.Text: @M__ The parentheses just make it a generator expression. Brackets would have made it a list comprehension: https://peps.python.org/pep-0289/
Answers.UserDisplayName: Steve
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-22T16:17:07.647Z
Answers.Text: @Steve, gave me a code to study.
Answers.UserDisplayName: Supertech
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-22T12:21:28.767Z
Answers.LastActivityDate: 2023-01-22T13:02:31.890Z
Answers.LastEditDate: 2023-01-22T13:02:31.890Z
Answers.UserDisplayName: Steve
Answers.Body: <p>my attempt at changing the way Biopython formats fasta file sequence width,
  read into code to figure out standard behaviour:</p>
  <pre><code>from Bio import SeqIO, __version__
  #import pprint
  # import textwrap
  
  print('Biopython version : ' , __version__)
  
  # my_id_file     = open('sample_files2/fasta_id_records.txt','r')
  # my_fasta_file  = open('sample_files2/fasta_file.fasta','r')
  #result_file    = open('sample_files2/results.fasta', &quot;w&quot;)
  ### CHANGED TO:
      
  my_id_file     = open('fasta_id_records.txt','r')
  my_fasta_file  = open('fasta_file.fasta','r')
  result_file    = open('results.fasta', &quot;w&quot;)
  
  
  my_dictionary = {} # fasta IDs are keys, value can be anything.
  for line in my_id_file:
      my_dictionary[line[:-1]] = 'value'
  
  #expected lenght of sequences in my fasta
  length = 10
  
  #pprint.pprint(my_dictionary)
  for seq_record in SeqIO.parse(my_fasta_file, &quot;fasta&quot;):
      if seq_record.id in my_dictionary:      
          
          
          ########################################################################################
          #use this line to write standard fasta record using SeqIO.write
          
          # SeqIO.write(seq_record, result_file, &quot;fasta-2line&quot;) # writes fasta in 2 line format
          
          # SeqIO.write(seq_record, result_file, &quot;fasta&quot;) # writes fasta with width of 60 as standard biopython format
          
          ### NOT POSSIBLE !!!!!!!!!!!!
          # seq_record.seq = textwrap.fill(seq_record.seq , width=10) ### --&gt; AttributeError: 'Seq' object has no attribute 'expandtabs'
          
          # print(seq_record.seq, type(seq_record.seq), dir(seq_record.seq))
          
          sequence = str(seq_record.seq)
          
          result_file.write('&gt;'+seq_record.id+'\n')
          
          while len(sequence) &gt; 0:
              result_file.write(sequence[:length]+'\n') 
              sequence = sequence[length:]
          result_file.write('\n')
          
          
          ### if you try to add EOL inside seq_record.seq of course you get 
          ### TypeError: SeqRecord (id=seq1) has an invalid sequence.
          # SeqIO.write(seq_record, result_file, &quot;fasta&quot;) # writes fasta with sequence width as 60   !!!! TypeError: SeqRecord (id=seq1) has an invalid sequence.
  
  my_fasta_file.close()
  my_id_file.close()
  result_file.close()
  </code></pre>
  <p>input files :</p>
  <p><code>fasta_id_records.txt</code>:</p>
  <pre><code>seq1
  seq2
  seq3
  </code></pre>
  <p><code> fasta_file.fasta</code>:</p>
  <pre><code>&gt;seq0
  AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  &gt;seq1
  TTTT
  TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
  TTTTTTTTTTTTTTT
  &gt;seq3
  CCCCCCCCCCCCCCCCCGGGGGGGGGGGGGGGGGGGGGGGGGGGGCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCGGGGGGGG
  GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
  GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
  </code></pre>
  <p>output file:</p>
  <p><code>v </code>:</p>
  <pre><code>&gt;seq1
  TTTTTTTTTT
  TTTTTTTTTT
  TTTTTTTTTT
  TTTTTTTTTT
  TTTTTTTTTT
  TTTTTTTTTT
  TTTTTTTTTT
  TTTTTTTTTT
  TTT
  
  &gt;seq3
  CCCCCCCCCC
  CCCCCCCGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGCCCCC
  CCCCCCCCCC
  CCCCCCCCCC
  CCCCCCCCCC
  CCCCCCCCCG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  G
  
  
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-22T12:53:39.803Z
Answers.LastActivityDate: 2023-01-22T13:01:45.073Z
Answers.LastEditDate: 2023-01-22T13:01:45.073Z
Answers.UserDisplayName: pippo1980
Body: <p><strong>Update:</strong>
  Biopython document says that &quot;Bio.SeqIO.FastaIO.FastaWriter&quot; class is obsolete. Now my question becomes how to I use <code>Bio.SeqIO.write()</code> fucntion do achive the same thing I asked.</p>
  <p>I use the following code to extract specific FASTA records from a file based on a list of FASTA IDs given in another file. The script works just fine. However, I want to able to write the results using &quot;Bio.SeqIO.FastaIO.FastaWriter&quot; class into a file instead of Python's print or write function. How can I do that in my last if statement?</p>
  <pre class="lang-python prettyprint-override"><code>from Bio import SeqIO
  #import pprint
  import textwrap
  
  my_id_file     = open('sample_files2/fasta_id_records.txt','r')
  my_fasta_file  = open('sample_files2/fasta_file.fasta','r')
  
  my_dictionary = {} # fasta IDs are keys, value can be anything.
  for line in my_id_file:
      my_dictionary[line[:-1]] = 'value'
  #pprint.pprint(my_dictionary)
  
  for seq_record in SeqIO.parse(my_fasta_file, &quot;fasta&quot;):
      if seq_record.id in my_dictionary:
          sequence = str(seq_record.seq)
          fasta_record = textwrap.fill(sequence, width=60)
          print(f&quot;&gt;{seq_record.id}\n{fasta_record}&quot;)
  
  my_fasta_file.close()
  my_id_file.close()
  </code></pre>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2023-01-22T18:57:55.673Z
Comments.Text: I was considering modifying the title. I am glad you edited it @gringer. Thank you.
Comments.UserDisplayName: Supertech
Tags: <python><fasta><biopython>
Title: How to write FASTA records using "Bio.SeqIO.write()"
ThreadText: # How to write FASTA records using "Bio.SeqIO.write()"
  
  (Asked by: username_0 on 2023-01-21)
  
  **Update:**
  Biopython document says that "Bio.SeqIO.FastaIO.FastaWriter" class is obsolete. Now my question becomes how to I use `Bio.SeqIO.write()` fucntion do achive the same thing I asked.
  
  I use the following code to extract specific FASTA records from a file based on a list of FASTA IDs given in another file. The script works just fine. However, I want to able to write the results using "Bio.SeqIO.FastaIO.FastaWriter" class into a file instead of Python's print or write function. How can I do that in my last if statement?
  
  ```python
  from Bio import SeqIO
  #import pprint
  import textwrap
  
  my_id_file     = open('sample_files2/fasta_id_records.txt','r')
  my_fasta_file  = open('sample_files2/fasta_file.fasta','r')
  
  my_dictionary = {} # fasta IDs are keys, value can be anything.
  for line in my_id_file:
      my_dictionary[line[:-1]] = 'value'
  #pprint.pprint(my_dictionary)
  
  for seq_record in SeqIO.parse(my_fasta_file, "fasta"):
      if seq_record.id in my_dictionary:
          sequence = str(seq_record.seq)
          fasta_record = textwrap.fill(sequence, width=60)
          print(f">{seq_record.id}\n{fasta_record}")
  
  my_fasta_file.close()
  my_id_file.close()
  
  ```
  
  **Tags:** python, fasta, biopython
  
  > **Comments:**
  > **username_0**: I was considering modifying the title. I am glad you edited it @gringer. Thank you.  
  
  ---
  
  ## 3 answers
  
  ### Answer by username_0 on 2023-01-21. Score: 4
  
  I figured it out:
  
  ```python
  from Bio import SeqIO
  #import pprint
  import textwrap
  
  my_id_file     = open('sample_files2/fasta_id_records.txt','r')
  my_fasta_file  = open('sample_files2/fasta_file.fasta','r')
  result_file    = open('sample_files2/results.fasta', "w")
  
  my_dictionary = {} # fasta IDs are keys, value can be anything.
  for line in my_id_file:
      my_dictionary[line[:-1]] = 'value'
  
  #pprint.pprint(my_dictionary)
  for seq_record in SeqIO.parse(my_fasta_file, "fasta"):
      if seq_record.id in my_dictionary:      
          #use this line to write standard fasta record using SeqIO.write
          SeqIO.write(seq_record, result_file, "fasta")
  
  my_fasta_file.close()
  my_id_file.close()
  result_file.close()
  
  ```
  
  > **Comments:**
  > **username_1**: I'm not 100% sure you can because that will be taken care within SeqIO.write(). The obvious `seq_record.seq = textwrap.fill(str(seq_record.seq) , width=60)` is unlikely to work.  
  > **username_1**: The only way to do it is within a straight write to disk in you first code ... but (obviously) write rather than print.  
  > **username_2**: it wraps to 60 by default in Biopython 1.8 at least, if saves as 'fasta-2line' uses a single line for the seq  
  
  ---
  
  ### Answer by username_3 on 2023-01-22. Score: 2
  
  You could instead pass in a generator that yields [SeqRecords](https://biopython.org/wiki/SeqRecord). This avoids storing the entire list of sequences in memory and is usually the way to go assuming that you need to handle large files containing thousands of records. This example use a generator expression, which is a bit like a list comprehension, but instead of creating a list, it creates a generator:
  
  ```
  import argparse
  import contextlib
  import pathlib
  import sys
  
  from Bio import SeqIO
  
  ```
  
  ```
  def get_argument_parser():
  
      parser = argparse.ArgumentParser()
  
      parser.add_argument(
          "fasta_file",
          type=pathlib.Path,
          metavar='FILE',
          help="Extract sequence records from FILE",
      )
      parser.add_argument(
          "ids_file",
          type=pathlib.Path,
          metavar='FILE',
          help="Sequence record IDs/names to extract, one per line",
      )
      parser.add_argument(
          "-o",
          "--output",
          type=pathlib.Path,
          metavar='FILE',
          default="-",
          help="Write extracted sequences to FILE (default: stdout)",
      )
      parser.add_argument(
          "-f",
          "--force",
          action='store_true',
          help="Overwrite the output file if it exists",
      )
  
      return parser
  
  ```
  
  ```
  def main():
  
      parser = get_argument_parser()
      args = parser.parse_args()
  
      with contextlib.ExitStack() as stack:
  
          ids_file = stack.enter_context(open(args.ids_file))
          fasta_file = stack.enter_context(open(args.fasta_file))
  
          if args.output != '-':
              out = stack.enter_context(open(args.output, 'w' if args.force else 'x'))
          else:
              out = sys.stdout
  
          record_ids = {line.rstrip('\n') for line in ids_file}
  
          fasta = SeqIO.parse(fasta_file, "fasta")
          records = (rec for rec in fasta if rec.id in record_ids)
  
          SeqIO.write(records, out, "fasta")
  
  if __name__ == "__main__":
      main()
  
  ```
  
  > **Comments:**
  > **username_2**: cool never eard about ExitStack till now https://docs.python.org/3/library/contextlib.html#contextlib.ExitStack  
  > **username_1**: A better description about what it does is here https://www.rath.org/on-the-beauty-of-pythons-exitstack.html @username_2  
  > **username_1**: I think I need to ask another question on this code. It's certainly professional code. What I'm wondering is how the if-condition tuple comprehension is a generator because thats the "workhorse" of the code.  
  > **username_3**: @username_1 The parentheses just make it a generator expression. Brackets would have made it a list comprehension: https://peps.python.org/pep-0289/  
  > **username_0**: @username_3, gave me a code to study.  
  
  ---
  
  ### Answer by username_2 on 2023-01-22. Score: 2
  
  my attempt at changing the way Biopython formats fasta file sequence width,
  read into code to figure out standard behaviour:
  
  ```
  from Bio import SeqIO, __version__
  #import pprint
  # import textwrap
  
  print('Biopython version : ' , __version__)
  
  # my_id_file     = open('sample_files2/fasta_id_records.txt','r')
  # my_fasta_file  = open('sample_files2/fasta_file.fasta','r')
  #result_file    = open('sample_files2/results.fasta', "w")
  ### CHANGED TO:
      
  my_id_file     = open('fasta_id_records.txt','r')
  my_fasta_file  = open('fasta_file.fasta','r')
  result_file    = open('results.fasta', "w")
  
  my_dictionary = {} # fasta IDs are keys, value can be anything.
  for line in my_id_file:
      my_dictionary[line[:-1]] = 'value'
  
  #expected lenght of sequences in my fasta
  length = 10
  
  #pprint.pprint(my_dictionary)
  for seq_record in SeqIO.parse(my_fasta_file, "fasta"):
      if seq_record.id in my_dictionary:      
          
          
          ########################################################################################
          #use this line to write standard fasta record using SeqIO.write
          
          # SeqIO.write(seq_record, result_file, "fasta-2line") # writes fasta in 2 line format
          
          # SeqIO.write(seq_record, result_file, "fasta") # writes fasta with width of 60 as standard biopython format
          
          ### NOT POSSIBLE !!!!!!!!!!!!
          # seq_record.seq = textwrap.fill(seq_record.seq , width=10) ### --> AttributeError: 'Seq' object has no attribute 'expandtabs'
          
          # print(seq_record.seq, type(seq_record.seq), dir(seq_record.seq))
          
          sequence = str(seq_record.seq)
          
          result_file.write('>'+seq_record.id+'\n')
          
          while len(sequence) > 0:
              result_file.write(sequence[:length]+'\n') 
              sequence = sequence[length:]
          result_file.write('\n')
          
          
          ### if you try to add EOL inside seq_record.seq of course you get 
          ### TypeError: SeqRecord (id=seq1) has an invalid sequence.
          # SeqIO.write(seq_record, result_file, "fasta") # writes fasta with sequence width as 60   !!!! TypeError: SeqRecord (id=seq1) has an invalid sequence.
  
  my_fasta_file.close()
  my_id_file.close()
  result_file.close()
  
  ```
  
  input files :
  
  `fasta_id_records.txt`:
  
  ```
  seq1
  seq2
  seq3
  
  ```
  
  `fasta_file.fasta`:
  
  ```
  >seq0
  AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  >seq1
  TTTT
  TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
  TTTTTTTTTTTTTTT
  >seq3
  CCCCCCCCCCCCCCCCCGGGGGGGGGGGGGGGGGGGGGGGGGGGGCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCGGGGGGGG
  GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
  GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
  
  ```
  
  output file:
  
  `v` :
  
  ```
  >seq1
  TTTTTTTTTT
  TTTTTTTTTT
  TTTTTTTTTT
  TTTTTTTTTT
  TTTTTTTTTT
  TTTTTTTTTT
  TTTTTTTTTT
  TTTTTTTTTT
  TTT
  
  >seq3
  CCCCCCCCCC
  CCCCCCCGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGCCCCC
  CCCCCCCCCC
  CCCCCCCCCC
  CCCCCCCCCC
  CCCCCCCCCG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  GGGGGGGGGG
  G
  
  ```
  
  
  ---
  
  