github.com/Johannestj/minyr@v0.0.0-20230414065407-214b2a4bca49/yr/yr.go (about)

     1  package yr
     2  
     3  import (
     4  	"bufio"
     5  	"encoding/csv"
     6  	"fmt"
     7  	"io"
     8  	"math"
     9  	"os"
    10  	"strconv"
    11  	"strings"
    12  	"github.com/Johannestj/funtemps/conv"
    13  	)
    14  
    15  // konverterer temperatur fra Celsius til Fahrenheit
    16  
    17  
    18  func Convert() error {
    19  	// Sjekker om output filen eksisterer
    20  	if _, err := os.Stat("yr/kjevik-temp-fahr-20220318-20230318.csv"); !os.IsNotExist(err) {
    21  		var regenerate string
    22  		fmt.Print("Output filen eksisterer fra før av, ønsker du å regenerere den? (j/n): ")
    23  		fmt.Scanln(&regenerate)
    24  		if regenerate != "j" && regenerate != "J" {
    25  			fmt.Println("Avbryt uten å generere ny fil.")
    26  			return nil
    27  		}
    28  	}
    29  
    30  	// Åpner input csv filen
    31  	inputFile, err := os.Open("yr/kjevik-temp-celsius-20220318-20230318.csv")
    32  	if err != nil {
    33  		fmt.Println("Feil med åpning av input fil:", err)
    34  	}
    35  	defer inputFile.Close()
    36  
    37  	// Lager en ny scanner for å lese input csv filen
    38  	inputScanner := bufio.NewScanner(inputFile)
    39  
    40  	// lag en ny csv writer for å skrive til output csv filen
    41  	outputFile, err := os.Create("yr/kjevik-temp-fahr-20220318-20230318.csv")
    42  	if err != nil {
    43  		fmt.Println("Feil under generering av output fil:", err)
    44  	}
    45  	defer outputFile.Close()
    46  
    47  	outputWriter := csv.NewWriter(outputFile)
    48  	defer outputWriter.Flush()
    49  
    50  	// Skriver ut første linje i input csv filen
    51  	if inputScanner.Scan() {
    52  		firstLine := inputScanner.Text()
    53  		if err = outputWriter.Write(strings.Split(firstLine, ";")); err != nil {
    54  			fmt.Println("Feil under skriving av første linje:", err)
    55  		}
    56  	}
    57  
    58  	// Loop gjennom hver linje i input csv filen
    59  	lineNo := 2 // Starter på linje 2 siden linje 1 allerede er skrevet
    60  	for inputScanner.Scan() {
    61  		// Sjekker om linje nummer overstiger 16755 og bryter ut av loopen hvis det gjør det
    62  		if lineNo > 16755 {
    63  			break
    64  		}
    65  
    66  		// Splitter linjen i felt
    67  		fields := strings.Split(inputScanner.Text(), ";")
    68  
    69  		// Sjekker at feltet har minst 4 elementer
    70  		if len(fields) != 4 {
    71  			fmt.Printf("Error on line %d: Invalid input format.\n", lineNo)
    72  			continue
    73  		}
    74  
    75  		// Henter ut siste siffer fra fjerde kolonne
    76  		temperatureField := fields[3]
    77  		if temperatureField == "" {
    78  			fmt.Printf("Feil på linje %d: Tempraturfeilt er tomt.\n", lineNo)
    79  			continue
    80  		}
    81  		temperature, err := strconv.ParseFloat(temperatureField, 64)
    82  		if err != nil {
    83  			fmt.Printf("Feil på linje %d: %v\n", lineNo, err)
    84  			continue
    85  		}
    86  		if math.IsNaN(temperature) {
    87  			fmt.Printf("Feil på linje %d: Tempratur er ikke gyldig float64 verdi.\n", lineNo)
    88  			continue
    89  		}
    90  
    91  		lastDigit := temperature
    92  
    93  		// Konverterer Celsius til Fahrenheit
    94  		// fahrenheit := conv.CelsiusToFarenheit(lastDigit) //
    95  		fahrenheit := conv.CelsiusToFahrenheit(lastDigit)
    96  
    97  		// Skriver output til CSV filen
    98  		fields[3] = fmt.Sprintf("%.1f", fahrenheit)
    99  		if err = outputWriter.Write(fields); err != nil {
   100  			fmt.Println("Feilet under skriving av output fil:", err)
   101  			return err
   102  		}
   103  
   104  		lineNo++
   105  	}
   106  
   107  	dataText := "Data er basert paa gyldig data (per 18.03.2023) (CC BY 4.0) fra Meteorologisk institutt (MET); endringen er gjort av Johannes Tjøstheim,,,"
   108  	err = outputWriter.Write([]string{dataText})
   109  	if err != nil {
   110  		fmt.Println("Error writing data text to output file:", err)
   111  
   112  	}
   113  
   114  	return nil
   115  }
   116  
   117  func Average(unit string) (float64, error) {
   118  	var filename string
   119  	var tempColumn int
   120  	var delimiter rune
   121  
   122  	if unit == "c" {
   123  		filename = "yr/kjevik-temp-celsius-20220318-20230318.csv"
   124  		tempColumn = 3
   125  		delimiter = ';'
   126  	} else if unit == "f" {
   127  		filename = "yr/kjevik-temp-fahr-20220318-20230318.csv"
   128  		tempColumn = 3
   129  		delimiter = ','
   130  	} else {
   131  		return 0, fmt.Errorf("Ugyldig verdi: %s", unit)
   132  	}
   133  
   134  	file, err := os.Open(filename)
   135  	if err != nil {
   136  		return 0, err
   137  	}
   138  	defer file.Close()
   139  
   140  	reader := csv.NewReader(file)
   141  	reader.Comma = delimiter
   142  
   143  	var total float64
   144  	var count int
   145  
   146  	// Looper gjennom hver linje i CSV filen
   147  	for i := 1; ; i++ {
   148  		record, err := reader.Read()
   149  		if err == io.EOF {
   150  			break
   151  		}
   152  		if err != nil {
   153  			return 0, err
   154  		}
   155  
   156  		if i < 2 || i > 16755 {
   157  			// hopper over linjer utenfor rangen
   158  			continue
   159  		}
   160  
   161  		if len(record) <= tempColumn {
   162  			return 0, fmt.Errorf("Ugyldig data i filen %s", filename)
   163  		}
   164  
   165  		temp, err := strconv.ParseFloat(record[tempColumn], 64)
   166  		if err != nil {
   167  			return 0, err
   168  		}
   169  
   170  		total += temp
   171  		count++
   172  	}
   173  
   174  	if count == 0 {
   175  		return 0, fmt.Errorf("Ingen tempratur ble funnet i filen %s", filename)
   176  	}
   177  
   178  	return total / float64(count), nil
   179  }