Answers.Body: <p>This is because you are also parsing your output file. Remember, the first rule of debugging is to print all the things! Most bugs are because some variable doesn't actually have the value you think it has, and printing them is the best way of finding the problem. I reproduced what (I am guessing) is your setup here:</p>
  <pre><code>$ ls
  OG0015396-PROT.fa  OG0020551-PROT.fa  OG0025647-PROT.fa
  </code></pre>
  <p>I then ran your script with an extra <code>print</code> statement:</p>
  <pre class="lang-py prettyprint-override"><code>#!/usr/bin/env python3
  import os
  from pathlib import Path
  from Bio import SeqIO
  
  with open('output.fasta', 'w') as output:
         for file in os.listdir(&quot;.&quot;):
                print(&quot;FF:&quot;,file)
                seq = SeqIO.parse(file, 'fasta')
                ortog = Path(file).stem
                for record in seq:
                       record.description = ortog
                SeqIO.write(record, output, 'fasta')
  </code></pre>
  <p>Which printed:</p>
  <pre><code>$ foo.py
  FF: OG0015396-PROT.fa
  FF: OG0020551-PROT.fa
  FF: output.fasta
  FF: OG0025647-PROT.fa
  </code></pre>
  <p>As you can see, since the <code>output.fasta</code> file is created by the <code>open()</code> call, by the time you use <code>listdir</code>, it's already there and included. This results in duplicated sequences (not always the last one). I'm sure there are more elegant solutions, but a simple workaround is to skip the output file name:</p>
  <pre><code>#!/usr/bin/env python3
  import os
  from pathlib import Path
  from Bio import SeqIO
  
  with open('output.fasta', 'w') as output:
         for file in os.listdir(&quot;.&quot;):
                if file == &quot;output.fasta&quot;:
                       continue
                seq = SeqIO.parse(file, 'fasta')
                ortog = Path(file).stem
                for record in seq:
                       record.description = ortog
                SeqIO.write(record, output, 'fasta')
  </code></pre>
  <p>Of course, this whole thing is a bit overkill for such a simple task and you could just use <code>sed</code> and the shell instead:</p>
  <pre><code>for file in *fa; do sed &quot;1s|$| ${file//.fa}|&quot; &quot;$file&quot;; done &gt; output.fasta 
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-10-21T20:26:09.033Z
Answers.Text: Thank you! It makes so much sense now. I managed to solve the problem by changing the identation of the SeqIO.write() function to the last for loop, but I didn't understand what was wrong before. Your resolution makes it clearer.
Answers.UserDisplayName: Eduardo Menotti
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-10-21T20:32:13.690Z
Answers.Text: You're welcome @EduardoMenotti. But please also take M__'s advice, I'm sure he's right about using the `id` and he makes a very good point about not using `seq` as a variable name. Just make sure to skip the output file or simply save the output to a different directory or just write to standard output and redirect to a file.
Answers.UserDisplayName: terdon
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-10-21T20:19:05.517Z
Answers.LastActivityDate: 2022-10-21T20:19:05.517Z
Answers.UserDisplayName: terdon
Body: <p>I have several fasta files that represent the proteins from different orthogroups. However, the orthogroup that each of the proteins belongs to is not indicated within the files. I am leveraging <a href="https://biopython.org" rel="nofollow noreferrer">BioPython</a> and I want to add this information to the header of each sequence in the fasta files.</p>
  <pre class="lang-py prettyprint-override"><code>import os
  from pathlib import Path
  from Bio import SeqIO
  
  with open('output.fasta', 'w') as output:
      for file in os.listdir(dirname):
          seq = SeqIO.parse(file, 'fasta')
          ortog = Path(file).stem
          for record in seq:
              record.description = ortog
          SeqIO.write(record, output, 'fasta')
  </code></pre>
  <p>However, the output always appears with the last sequence duplicated. In the case of three fasta files, the output appears as:</p>
  <pre><code>&gt;BBC_8_672 OG0015396-PROT
  MKFSSVTAITLATVATVATAKKGEHDFTTTLTLSSDGSLTTTTSTHTTHKYGKFNKTSKS
  KTPNHTGTHKYGKFNKTSKSKTP
  &gt;CAT_6_3128 OG0020551-PROT
  MEKIKEKLNSLKLESESWQEKYEELREQLKELEQSNTEKENEIKSLSAKNEQLDSEVEKL
  ESQLSDTKQLAEDSNNLRSNNENYTKKNQDLEQQLEDSEAKLKEAMDKLKEADLNSEQMG
  RRIVALEEERDEWEKKCEEFQSKYEEAQKELDEIANSLENL
  &gt;ZSA_0_3121 OG0025647-PROT
  LLLQYQLHPALLPKALLLQYQLHQALLLKALLLQ*PALLLKALLLQYQLHQALLLKALLL
  QYQLHPALLLKALLLQYQLHP
  &gt;ZSA_0_3121 OG0025647-PROT
  LLLQYQLHPALLPKALLLQYQLHQALLLKALLLQ*PALLLKALLLQYQLHQALLLKALLL
  QYQLHPALLLKALLLQYQLHP
  </code></pre>
  <p>Could anyone tell me why this is happening?</p>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2022-10-21T20:08:17.500Z
Comments.Text: So what do you see when you add `print(file)` in the `for file` loop? Are some of the file names repeated?
Comments.UserDisplayName: terdon
Tags: <python><phylogenetics><orthologues><multi-fasta>
Title: Add file name to FASTA file header using SeqIO
ThreadText: # Add file name to FASTA file header using SeqIO
  
  (Asked by: username_0 on 2022-10-21)
  
  I have several fasta files that represent the proteins from different orthogroups. However, the orthogroup that each of the proteins belongs to is not indicated within the files. I am leveraging [BioPython](https://biopython.org) and I want to add this information to the header of each sequence in the fasta files.
  
  ```py
  import os
  from pathlib import Path
  from Bio import SeqIO
  
  with open('output.fasta', 'w') as output:
      for file in os.listdir(dirname):
          seq = SeqIO.parse(file, 'fasta')
          ortog = Path(file).stem
          for record in seq:
              record.description = ortog
          SeqIO.write(record, output, 'fasta')
  
  ```
  
  However, the output always appears with the last sequence duplicated. In the case of three fasta files, the output appears as:
  
  ```
  >BBC_8_672 OG0015396-PROT
  MKFSSVTAITLATVATVATAKKGEHDFTTTLTLSSDGSLTTTTSTHTTHKYGKFNKTSKS
  KTPNHTGTHKYGKFNKTSKSKTP
  >CAT_6_3128 OG0020551-PROT
  MEKIKEKLNSLKLESESWQEKYEELREQLKELEQSNTEKENEIKSLSAKNEQLDSEVEKL
  ESQLSDTKQLAEDSNNLRSNNENYTKKNQDLEQQLEDSEAKLKEAMDKLKEADLNSEQMG
  RRIVALEEERDEWEKKCEEFQSKYEEAQKELDEIANSLENL
  >ZSA_0_3121 OG0025647-PROT
  LLLQYQLHPALLPKALLLQYQLHQALLLKALLLQ*PALLLKALLLQYQLHQALLLKALLL
  QYQLHPALLLKALLLQYQLHP
  >ZSA_0_3121 OG0025647-PROT
  LLLQYQLHPALLPKALLLQYQLHQALLLKALLLQ*PALLLKALLLQYQLHQALLLKALLL
  QYQLHPALLLKALLLQYQLHP
  
  ```
  
  Could anyone tell me why this is happening?
  
  **Tags:** python, phylogenetics, orthologues, multi-fasta
  
  > **Comments:**
  > **username_1**: So what do you see when you add `print(file)` in the `for file` loop? Are some of the file names repeated?  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2022-10-21. Score: 0 | Accepted answer
  
  This is because you are also parsing your output file. Remember, the first rule of debugging is to print all the things! Most bugs are because some variable doesn't actually have the value you think it has, and printing them is the best way of finding the problem. I reproduced what (I am guessing) is your setup here:
  
  ```
  $ ls
  OG0015396-PROT.fa  OG0020551-PROT.fa  OG0025647-PROT.fa
  
  ```
  
  I then ran your script with an extra `print` statement:
  
  ```py
  #!/usr/bin/env python3
  import os
  from pathlib import Path
  from Bio import SeqIO
  
  with open('output.fasta', 'w') as output:
         for file in os.listdir("."):
                print("FF:",file)
                seq = SeqIO.parse(file, 'fasta')
                ortog = Path(file).stem
                for record in seq:
                       record.description = ortog
                SeqIO.write(record, output, 'fasta')
  
  ```
  
  Which printed:
  
  ```
  $ foo.py
  FF: OG0015396-PROT.fa
  FF: OG0020551-PROT.fa
  FF: output.fasta
  FF: OG0025647-PROT.fa
  
  ```
  
  As you can see, since the `output.fasta` file is created by the `open()` call, by the time you use `listdir`, it's already there and included. This results in duplicated sequences (not always the last one). I'm sure there are more elegant solutions, but a simple workaround is to skip the output file name:
  
  ```
  #!/usr/bin/env python3
  import os
  from pathlib import Path
  from Bio import SeqIO
  
  with open('output.fasta', 'w') as output:
         for file in os.listdir("."):
                if file == "output.fasta":
                       continue
                seq = SeqIO.parse(file, 'fasta')
                ortog = Path(file).stem
                for record in seq:
                       record.description = ortog
                SeqIO.write(record, output, 'fasta')
  
  ```
  
  Of course, this whole thing is a bit overkill for such a simple task and you could just use `sed` and the shell instead:
  
  ```
  for file in *fa; do sed "1s|$| ${file//.fa}|" "$file"; done > output.fasta 
  
  ```
  
  > **Comments:**
  > **username_0**: Thank you! It makes so much sense now. I managed to solve the problem by changing the identation of the SeqIO.write() function to the last for loop, but I didn't understand what was wrong before. Your resolution makes it clearer.  
  > **username_1**: You're welcome @username_0. But please also take M__'s advice, I'm sure he's right about using the `id` and he makes a very good point about not using `seq` as a variable name. Just make sure to skip the output file or simply save the output to a different directory or just write to standard output and redirect to a file.  
  
  ---
  
  