# -*- coding: utf-8 -*-
# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .jl
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Julia 0.5.0
#     language: julia
#     name: julia-0.5
# ---

# + [markdown] slideshow={"slide_type": "slide"}
# # A day with (the) Julia (language)
#
# ## Exercises

# + [markdown] slideshow={"slide_type": "slide"}
# ### I. Reescribir la función usando filter! y testear

# + slideshow={"slide_type": "fragment"}
function listaralineamientos(direccion, extension::Regex=r"\.fasta$"; vacios::Bool=false)
    alns = String[]
    for nombre in readdir(direccion)
        if ismatch(extension, nombre)
           
            if vacios || filesize(joinpath(direccion, nombre)) > 0
                push!(alns, nombre)
            end
            
        end
    end   
    alns
end

function list_alns_filter(direccion, extension::Regex=r"\.fasta$"; vacios::Bool=false)
    
    # COMPLETAR
end


# + [markdown] slideshow={"slide_type": "fragment"}
# **Pistas:** 
#
# - `filter!` elimina de un vector los elementos para los cuales una función retorna `false`. 
# - Si el primer argumento es una expresión regular, elimina los elementos que no son `ismatch` con esa `Regex`. 
# - Base.Test.@test da un error si la condición que sigue es falsa (sino retorna nothing, no muestra nada)

# + slideshow={"slide_type": "fragment"}
using Base.Test

# variable -> ... es la notación para una función anónima
@test filter!(r"\.fasta$", readdir("data")) == filter!(x -> ismatch(r"\.fasta$", x), readdir("data")) 

# + slideshow={"slide_type": "slide"}
function list_alns_filter(direccion, extension::Regex=r"\.fasta$"; vacios::Bool=false)
    alns = filter!(extension, readdir(direccion))
    if !vacios
        filter!(nombre -> filesize(joinpath(direccion, nombre)) > 0, alns)
    end
    alns
end

# + slideshow={"slide_type": "fragment"}
@test list_alns_filter("data") == listaralineamientos("data")
@test list_alns_filter("data", vacios=true) == listaralineamientos("data", vacios=true)
@test list_alns_filter("data", r"\.stockholm$") == listaralineamientos("data", r"\.stockholm$")

# + [markdown] slideshow={"slide_type": "slide"}
# ### II. Escribir una función para convertir un archivo Stockholm en FASTA.

# + [markdown] slideshow={"slide_type": "fragment"}
# **Pista:** En un archivo con formato [Stockholm](https://en.wikipedia.org/wiki/Stockholm_format), las secuencias son las únicas líneas que no comienzan con numeral **#=** ni **//**, la regex es: ```^(?![#=|//])```
#
# ```
# O31699/88-139           EVMLTDIPRLHINDPIMKGFGMVINN..GFVCVENDE
# #=GR O31699/88-139 AS   ________________*____________________
# //
# ```
#
# **Usar**: `match`, `@r_str`, `open`, `eachline`, `close`, `println` or `print`  
# **Opcional**: `chomp`

# + slideshow={"slide_type": "fragment"}
"""
Función para convertir un archivo Stockholm en FASTA (secuencia en una sola línea).
La función toma como argumentos la dirección/nombre de un archivo Stockholm y del archivo FASTA que se creara.
La función retorna la dirección/nombre del FASTA.
"""
function stockholm2fasta(sto, fas)
    
    # COMPLETAR
    
end

# + slideshow={"slide_type": "fragment"}
?stockholm2fasta

# + slideshow={"slide_type": "slide"}
"""
Función para convertir un archivo Stockholm en FASTA (secuencia en una sola línea).
La función toma como argumentos la dirección/nombre de un archivo Stockholm y del archivo FASTA que se creara.
La función retorna la dirección/nombre del FASTA.
"""
function stockholm2fasta(sto, fas)
    fh_in  = open(sto, "r")
    open(fas, "w") do fh_out
        for line in eachline(fh_in)
            m = match(r"^(?![#=|//])(\S+)\s+(\S+)", line)
            if m != nothing
                println(fh_out, ">", m.captures[1], "\n", m.captures[2])
            end
        end
    end
    close(fh_in)
    fas
end

# + slideshow={"slide_type": "fragment"}
stockholm2fasta("data/PF09645_full.stockholm", "data/out.fas")

# + slideshow={"slide_type": "fragment"}
run(`cat ./data/out.fas`)

# + [markdown] slideshow={"slide_type": "slide"}
# ### III. Escribir una función para convertir un archivo Stockholm en FASTA usando BioPython    
#   
# Usar [**PyCall**](https://github.com/stevengj/PyCall.jl) para importar BioPython en Julia. Un ejemplo similar en (Bio)Python está al final de la [wiki de AlignIO](http://biopython.org/wiki/AlignIO):  
#
# ```python
# from Bio import AlignIO
#  
# input_handle = open("example.phy", "rU")
# output_handle = open("example.sth", "w")
#  
# alignments = AlignIO.parse(input_handle, "phylip")
# AlignIO.write(alignments, output_handle, "stockholm")
#  
# output_handle.close()
# input_handle.close()
# ```
#   
# **Usar:** `AlignIO.parse`, `AlignIO.write`

# + slideshow={"slide_type": "fragment"}
using PyCall 

@pyimport Bio.AlignIO as AlignIO

"""Función para convertir un archivo Stockholm en FASTA usando BioPython.
La función toma como argumentos la dirección/nombre de un archivo Stockholm y del archivo FASTA que se creara.
La función retorna la dirección/nombre del FASTA."""
function py_stockholm2fasta(sto, fas)
    fh_in  = open(sto, "r")
    open(fas, "w") do fh_out
        
        # COMPLETAR
        
    end
    close(fh_in)
    fas
end

# + slideshow={"slide_type": "slide"}
using PyCall 

@pyimport Bio.AlignIO as AlignIO

"""
Función para convertir un archivo Stockholm en FASTA usando BioPython.
La función toma como argumentos la dirección/nombre de un archivo Stockholm y del archivo FASTA que se creara.
La función retorna la dirección/nombre del FASTA.
"""
function py_stockholm2fasta(sto, fas)
    fh_in  = open(sto, "r")
    open(fas, "w") do fh_out
        alignments = AlignIO.parse(fh_in, "stockholm")
        AlignIO.write(alignments, fh_out,"fasta")
    end
    close(fh_in)
    fas
end

# + slideshow={"slide_type": "fragment"}
py_stockholm2fasta("data/PF09645_full.stockholm", "data/py_out.fas")

# + slideshow={"slide_type": "fragment"}
run(`cat ./data/py_out.fas`)

StarcoderdataJupyterScriptsDedupFiltered