diff --git a/capacities.csv b/capacities.csv deleted file mode 100644 index ae622cf..0000000 --- a/capacities.csv +++ /dev/null @@ -1,4 +0,0 @@ -"Partner ID","Capacity (in GB)" -P1 ,350 -P2 ,500 -P3 ,1500 diff --git a/input.csv b/input.csv index 3f1c8fa..bce0344 100644 --- a/input.csv +++ b/input.csv @@ -1,4 +1,7 @@ -D1,150,T1 -D2,325,T2 -D3,510,T1 -D4,700,T2 +delivery_id,size,theatre_id +D1,100,T1 +D2,300,T1 +D3,350,T1 +D1, 70, T1 +D2, 300, T1 +D1, 70, T3 \ No newline at end of file diff --git a/main.go b/main.go new file mode 100644 index 0000000..2964966 --- /dev/null +++ b/main.go @@ -0,0 +1,199 @@ +package main + +import ( + "encoding/csv" + "fmt" + "log" + "os" + "strconv" + "strings" +) + +type EssentialData struct { + TheatreID string + SizeSlab string + MinCost int + CostPerGB int + PartnerID string +} +type InputDetails struct { + DeliveryID string + Size int + TheatreID string +} + +func main() { + mydir, err := os.Getwd() + if err != nil { + log.Println(err) + } + database, err := ParseDatabase(fmt.Sprintf("%s/%s", mydir, "pretty.csv")) + if err != nil { + log.Printf("error reading csv file %w", err) + return + } + inputData, err := ReadInputData(fmt.Sprintf("%s/%s", mydir, "input.csv")) + if err != nil { + log.Printf("error reading input csv file %w", err) + return + } + result := FindValidPartner(database, inputData) + WriteOutput(result) +} + +func WriteOutput(output [][]string) { + csvFile, err := os.Create("output.csv") + + if err != nil { + log.Fatalf("failed creating file: %s", err) + } + + csvwriter := csv.NewWriter(csvFile) + + for _, empRow := range output { + _ = csvwriter.Write(empRow) + } + csvwriter.Flush() + csvFile.Close() +} + +// FindValidPartner :- function to generate effective partners of corrsponding theaters +func FindValidPartner(database []EssentialData, inputData []InputDetails) (outputList [][]string) { + outputList = append(outputList, []string{"delivery_id", "delivery_possible", "cost_of_delivery", "partner_id"}) + for _, input := range inputData { + var ( + validCost int + ) + + activeIndex := -1 + for index, dataRow := range database { + sizes := strings.Split(dataRow.SizeSlab, "-") + low, _ := strconv.Atoi(sizes[0]) + high, _ := strconv.Atoi(sizes[1]) + if low <= input.Size && high >= input.Size && dataRow.TheatreID == input.TheatreID { + deliveryCost := input.Size * dataRow.CostPerGB + if validCost > deliveryCost || validCost == 0 { + if deliveryCost < dataRow.MinCost { + validCost = dataRow.MinCost + } else { + validCost = deliveryCost + } + + activeIndex = index + } + } + } + if activeIndex != -1 { + outputList = append(outputList, []string{input.DeliveryID, "true", fmt.Sprintf("%d", validCost), database[activeIndex].PartnerID}) + } else { + outputList = append(outputList, []string{input.DeliveryID, "false"}) + } + + } + return +} + +// ReadDataFromInput :- read headers and conents from csv +func ReadDataFromInput(fileName string) ([]map[string]string, error) { + var inputData []map[string]string + csvfile, err := os.Open(fileName) + if err != nil { + log.Printf("error reading csv file due to error %w", err) + return inputData, err + } + + defer csvfile.Close() + + reader := csv.NewReader(csvfile) + + rawCSVdata, err := reader.ReadAll() + if err != nil { + log.Printf("error reading row data due to error %w", err) + return inputData, err + } + header := []string{} + for lineNum, line := range rawCSVdata { + if lineNum == 0 { + for _, title := range line { + header = append(header, strings.TrimSpace(title)) + } + } else { + rowValues := map[string]string{} + for i, value := range line { + rowValues[header[i]] = value + } + inputData = append(inputData, rowValues) + } + } + return inputData, nil +} + +// ParseDatabase :- extract the contents from csv and parse it to the variable +func ParseDatabase(fileName string) ([]EssentialData, error) { + var inputData []EssentialData + csvfile, err := os.Open(fileName) + if err != nil { + log.Printf("error reading csv file due to error %w", err) + return inputData, err + } + + defer csvfile.Close() + + reader := csv.NewReader(csvfile) + + rawCSVdata, err := reader.ReadAll() + if err != nil { + log.Printf("error reading row data due to error %w", err) + return inputData, err + } + + for lineNum, line := range rawCSVdata { + if lineNum > 0 { + cost, _ := strconv.Atoi(line[2]) + costPerGB, _ := strconv.Atoi(line[3]) + rowValues := EssentialData{ + TheatreID: line[0], + SizeSlab: line[1], + MinCost: cost, + CostPerGB: costPerGB, + PartnerID: line[4], + } + inputData = append(inputData, rowValues) + } + } + return inputData, nil + +} + +//ReadInputData :- function to read input csv file +func ReadInputData(fileName string) ([]InputDetails, error) { + var inputData []InputDetails + csvfile, err := os.Open(fileName) + if err != nil { + log.Printf("error reading csv file due to error %w", err) + return inputData, err + } + + defer csvfile.Close() + + reader := csv.NewReader(csvfile) + + rawCSVdata, err := reader.ReadAll() + if err != nil { + log.Printf("error reading row data due to error %w", err) + return inputData, err + } + + for lineNum, line := range rawCSVdata { + if lineNum > 0 { + size, _ := strconv.Atoi(strings.TrimSpace((line[1]))) + rowValues := InputDetails{ + DeliveryID: strings.TrimSpace(line[0]), + Size: size, + TheatreID: strings.TrimSpace(line[2]), + } + inputData = append(inputData, rowValues) + } + } + return inputData, nil +} diff --git a/output.csv b/output.csv new file mode 100644 index 0000000..d8b7bf9 --- /dev/null +++ b/output.csv @@ -0,0 +1,7 @@ +delivery_id,delivery_possible,cost_of_delivery,partner_id +D1,true,2000,P1 +D2,true,4500,P1 +D3,true,5250,P1 +D1,true,1750,P2 +D2,true,4500,P1 +D1,false diff --git a/output1.csv b/output1.csv deleted file mode 100644 index 7c7b275..0000000 --- a/output1.csv +++ /dev/null @@ -1,4 +0,0 @@ -D1,true ,P1,2000 -D2,true ,P1,3250 -D3,true ,P3,15300 -D4,false,"","" diff --git a/output2.csv b/output2.csv deleted file mode 100644 index adcd15b..0000000 --- a/output2.csv +++ /dev/null @@ -1,4 +0,0 @@ -D1,true ,P2,3000 -D2,true ,P1,3250 -D3,true ,P3,15300 -D4,false,"","" diff --git a/partners.csv b/partners.csv deleted file mode 100644 index 3ea8c59..0000000 --- a/partners.csv +++ /dev/null @@ -1,17 +0,0 @@ -Theatre,Size Slab (in GB),Minimum cost,Cost Per GB,Partner ID -T1 ,0-100 ,1500 ,20 ,P1 -T1 ,100-200 ,2000 ,13 ,P1 -T1 ,200-300 ,2500 ,12 ,P1 -T1 ,300-400 ,3000 ,10 ,P1 -T2 ,0-100 ,1500 ,20 ,P1 -T2 ,100-200 ,2000 ,15 ,P1 -T2 ,200-300 ,2500 ,12 ,P1 -T2 ,300-400 ,3000 ,10 ,P1 -T1 ,0-200 ,1000 ,20 ,P2 -T1 ,200-400 ,2500 ,15 ,P2 -T2 ,0-200 ,2500 ,20 ,P2 -T2 ,200-400 ,3500 ,10 ,P2 -T1 ,100-200 ,800 ,25 ,P3 -T1 ,200-600 ,1200 ,30 ,P3 -T2 ,100-200 ,900 ,15 ,P3 -T2 ,200-400 ,1000 ,12 ,P3 diff --git a/pretty.csv b/pretty.csv new file mode 100644 index 0000000..38f4708 --- /dev/null +++ b/pretty.csv @@ -0,0 +1,7 @@ +theatre,size_slab,minimum_cost,cost_per_gb,partner_id +T1,0-200,2000,20,P1 +T1,200-400,3000,15,P1 +T3,100-200,4000,30,P1 +T3,200-400,5000,25,P1 +T5,100-200,2000,30,P1 +T1,0-400,1500,25,P2 \ No newline at end of file