Browse Source

Make this go get friendly (#3)

* add rosalind package that will be go get friendly

* update readme with new structure and approach

* moving data to rosalind dir

* add travis.yml file
master
Charles Reid 6 years ago committed by GitHub
parent
commit
1695a36aa4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      .travis.yml
  2. 60
      Readme.md
  3. 4
      rosalind/Readme.md
  4. 0
      rosalind/data/clump_finding.txt
  5. 0
      rosalind/data/frequent_words.txt
  6. 0
      rosalind/data/frequent_words_mismatch.txt
  7. 0
      rosalind/data/frequent_words_mismatch_complements.txt
  8. 0
      rosalind/data/hamming_distance.txt
  9. 0
      rosalind/data/minimum_skew.txt
  10. 0
      rosalind/data/neighbors.txt
  11. 0
      rosalind/data/number_to_pattern.txt
  12. 0
      rosalind/data/pattern_count.txt
  13. 0
      rosalind/data/pattern_matching.txt
  14. 0
      rosalind/data/pattern_to_number.txt
  15. 0
      rosalind/data/reverse_complement.txt
  16. 1019
      rosalind/rosalind_ba1.go
  17. 1152
      rosalind/rosalind_ba1_test.go
  18. 124
      rosalind/utils.go
  19. 39
      rosalind/utils_test.go

9
.travis.yml

@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
language: go
go_import_path: github.com/charlesreid1/go-rosalind/rosalind
go:
- 1.10.x
- 1.11.x
- tip
script:
- go test -v ./rosalind/...

60
Readme.md

@ -1,41 +1,49 @@ @@ -1,41 +1,49 @@
# Go-Rosalind
# go-rosalind
Solving problems from Rosalind.info using Go
_A Go (golang) package for solving bioinformatics problems._
## Organization
Each chapter has its own directory.
## Summary
Within the chapter directory, each problem has
its own driver program, which prints info about
the problem, loads the input file from Rosalind,
and prints the solution. Each problem also has
its own test suite using the examples provided
on Rosalind.info.
For example, the function that loads the
input file for problem BA1A is in `ba1a.go`
and the code to test the functionality
of the solution to BA1A is in `ba1a_test.go`.
This repository contains a Go (golang) library called `rosalind`
that provides a set of functions that are useful for solving
bioinformatics problems from Rosalind.info.
## Quick Start
To run all the tests in a chapter directory:
This library can be installed using `go get`:
```
go test -v
go get https://github.com/charlesreid1/go-rosalind/rosalind
```
To run only a particular problem:
The library can now be imported and its functions called directly.
Here is a brief example:
1. Edit `main.go` to call the right method
for the right problem with the right input
file name.
```
package main
2. Run `main.go` using `go run`, and point Go
to all the relevant Go files:
import "roslind"
func main() {
input := "AAAATGCGCTAGTAAAAGTCACTGAAAA"
k := 4
result, err := rosalind.MostFrequentKmers(input, k)
}
```
go run main.go utils.go rosalind.go <name-of-BA-file>
```
## Command Line Interface
TBA
## Organization
The repo contains the following directories:
* `chapter01/` - initial working directory; standalone code
* `chapter02/` - first set of solutions utilizing `rosalind` library
* `rosalind/` - contains Rosalind library
See the Readme file in each respective directory for more info.

4
rosalind/Readme.md

@ -0,0 +1,4 @@ @@ -0,0 +1,4 @@
# rosalind go package
This directory contains the `rosalind` Go package.

0
chapter01/data/clump_finding.txt → rosalind/data/clump_finding.txt

0
chapter01/data/frequent_words.txt → rosalind/data/frequent_words.txt

0
chapter01/data/frequent_words_mismatch.txt → rosalind/data/frequent_words_mismatch.txt

0
chapter01/data/frequent_words_mismatch_complements.txt → rosalind/data/frequent_words_mismatch_complements.txt

0
chapter01/data/hamming_distance.txt → rosalind/data/hamming_distance.txt

0
chapter01/data/minimum_skew.txt → rosalind/data/minimum_skew.txt

0
chapter01/data/neighbors.txt → rosalind/data/neighbors.txt

0
chapter01/data/number_to_pattern.txt → rosalind/data/number_to_pattern.txt

0
chapter01/data/pattern_count.txt → rosalind/data/pattern_count.txt

0
chapter01/data/pattern_matching.txt → rosalind/data/pattern_matching.txt

0
chapter01/data/pattern_to_number.txt → rosalind/data/pattern_to_number.txt

0
chapter01/data/reverse_complement.txt → rosalind/data/reverse_complement.txt

1019
rosalind/rosalind_ba1.go

File diff suppressed because it is too large Load Diff

1152
rosalind/rosalind_ba1_test.go

File diff suppressed because it is too large Load Diff

124
rosalind/utils.go

@ -0,0 +1,124 @@ @@ -0,0 +1,124 @@
package rosalind
import (
"bufio"
"fmt"
"os"
)
// readLines reads a whole file into memory
// and returns a slice of its lines.
func readLines(path string) ([]string, error) {
file, err := os.Open(path)
if err != nil {
return nil, err
}
defer file.Close()
var lines []string
scanner := bufio.NewScanner(file)
buf := make([]byte, 2)
// This is awkward.
// Scanners aren't good for big files,
// just simple stuff.
BIGNUMBER := 90000
scanner.Buffer(buf, BIGNUMBER)
for scanner.Scan() {
lines = append(lines, scanner.Text())
}
return lines, scanner.Err()
}
// writeLines writes the lines to the given file.
func writeLines(lines []string, path string) error {
file, err := os.Create(path)
if err != nil {
return err
}
defer file.Close()
w := bufio.NewWriter(file)
for _, line := range lines {
fmt.Fprintln(w, line)
}
return w.Flush()
}
// Utility function: check if two string arrays/array slices
// are equal. This is necessary because of squirrely
// behavior when comparing arrays (of type [1]string)
// and slices (of type []string).
func EqualStringSlices(a, b []string) bool {
if len(a) != len(b) {
return false
}
for i := 0; i < len(a); i++ {
if a[i] != b[i] {
return false
}
}
return true
}
// Utility function: check if two boolean arrays/array slices
// are equal. This is necessary because of squirrely
// behavior when comparing arrays (of type [1]bool)
// and slices (of type []bool).
func EqualBoolSlices(a, b []bool) bool {
if len(a) != len(b) {
return false
}
for i := 0; i < len(a); i++ {
if a[i] != b[i] {
return false
}
}
return true
}
// Check if two int arrays/array slices are equal.
func EqualIntSlices(a, b []int) bool {
if len(a) != len(b) {
return false
}
for i := 0; i < len(a); i++ {
if a[i] != b[i] {
return false
}
}
return true
}
// Compute the factorial of an integer.
func Factorial(n int) int {
if n < 2 {
// base case
return 1
} else {
// recursive case
return n * Factorial(n-1)
}
}
// Returns value of Binomial Coefficient Binom(n, k).
func Binomial(n, k int) int {
result := 1
// Since C(n, k) = C(n, n-k)
if k > (n - k) {
k = n - k
}
// Calculate value of:
// ( n * (n-1) * ... * (n-k+1) )
// -----------------------------
// ( k * (k-1) * ... * 1 )
for i := 0; i < k; i++ {
result *= n - i
result /= i + 1
}
return result
}

39
rosalind/utils_test.go

@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
package rosalind
import "testing"
func TestEqualStringSlices(t *testing.T) {
a := []string{"peanut", "butter", "jelly", "time"}
b := make([]string, 4)
b[0] = "peanut"
b[1] = "butter"
b[2] = "jelly"
b[3] = "time"
if !EqualStringSlices(a, b) {
msg := "Error: EqualStringSlices() is broken!"
t.Fatal(msg)
}
}
func TestEqualBoolSlices(t *testing.T) {
a := []bool{true, true, true, false, false, false, true, true, true}
b := make([]bool, 9)
b[0], b[1], b[2] = true, true, true
b[3], b[4], b[5] = false, false, false
b[6], b[7], b[8] = true, true, true
if !EqualBoolSlices(a, b) {
msg := "Error: EqualBoolSlices() is broken!"
t.Fatal(msg)
}
}
func TestEqualIntSlices(t *testing.T) {
a := []int{3, 1, 4, 1, 5, 9}
b := make([]int, 6)
b[0], b[1], b[2] = 3, 1, 4
b[3], b[4], b[5] = 1, 5, 9
if !EqualIntSlices(a, b) {
msg := "Error: EqualIntSlices() is broken!"
t.Fatal(msg)
}
}
Loading…
Cancel
Save