This commit is contained in:
2020-01-14 13:10:06 +11:00
parent a1327ef122
commit 6425d4b7db
5 changed files with 94 additions and 8 deletions
+24
View File
@@ -0,0 +1,24 @@
FROM golang:1.13-alpine3.10 AS build
RUN apk add --no-cache git openssh
ENV GOOS=linux
ENV GOARCH=amd64
WORKDIR /app
COPY . .
RUN go build -o analyser cmd/main.go
FROM alpine:3.10
RUN adduser -D -u 1000 myapp
WORKDIR /home/myapp
USER myapp
COPY --from=build /app/analyser analyser
CMD ["/home/myapp/analyser"]
+62 -1
View File
@@ -1 +1,62 @@
#
# File Analyser
## Brief introduction
This command line program simply take a plain text file path as input and will process it, then work out the words appeared with frequencies, finally it will print out the top `10` words with hightest frequencies.
## About the design
I used a `map[string]int` to store all the unique words and their frequencies when the program read the data from the file.
Then I transformed the data type from `map` to internal `dataRow` and sorted the data by frequency and alphabetic order. By doing so, we can do more compicated operations against the data.
Finally, called the `Output` method to revert and transform the internal data structure to final output format.
I also created a custom `func` type `HandleLine`, so we can have different functions to process data with different rules. Tried to make the program less coupled.
By the way, The reason why I add docker version is we don't need to worry about whether we have correct Go version anymore, also reduce the manual steps like installing dependencies or compiling the program especially for bigger projects.
## How to run
### Running with Go
```bash
go run cmd/main.go ./README.md
# You can also specify how many lines you would like to print out
go run cmd/main.go ./README.md 15
# Against some other files
go run cmd/main.go ./test_files/valid_input.txt
```
### Docker
Build the docker image
```bash
docker build -t redhat-analyser .
```
Run against docker image
```bash
docker run --rm -it -v $(pwd):/home/myapp/myfiles redhat-analyser ./analyser myfiles/README.md
```
If you want to parse other files please replace the directory you'd like to mount from `$(pwd)` to some other directory.
Then update the input file `myfiles/README.md` to some other values.
## Run the tests
```bash
go test ./... -cover
```
## Something I would like to improve if had more time
- Better Logging rather than just use `fmt.Println`
- Handle different errors with different actions, currently I just print out error message and exit the program
+5 -6
View File
@@ -2,10 +2,10 @@ package main
import (
"fmt"
"github.com/wahyd4/redhat"
"os"
"strconv"
"syscall"
"github.com/wahyd4/redhat"
)
const defaultTopLines = 10
@@ -22,19 +22,18 @@ func main() {
if len(args) == 3 {
topLinesParam, err := strconv.Atoi(args[2])
if err != nil {
panic("Number of top result param must be a number")
panic("The number of top lines param must be a number")
}
topLines = topLinesParam
}
analyser, err := redhat.InitFromFile(filepath)
if err != nil {
panic("can not init the program:" + err.Error())
panic("can not init the program due to file is invalid: " + err.Error())
}
if err = analyser.AnalyseData(); err != nil {
fmt.Println("fail to process and analyse data:" + err.Error())
syscall.Exit(1)
panic("fail to process and analyse data:" + err.Error())
}
for _, outputLine := range analyser.Output(topLines) {
+3
View File
@@ -0,0 +1,3 @@
module github.com/wahyd4/redhat
go 1.13
-1
View File
@@ -20,7 +20,6 @@ func (fa *FileAnalyser) getResultRows(topLines int) []dataRow {
if len(fa.dataRows) < topLines {
return fa.dataRows[0:len(fa.dataRows)]
}
return fa.dataRows[0:topLines]
}