Notas de evaluación acumulada
La evaluación acumulada, las notas se calculan recursivamente con la siguiente función
1 2 |
N(1) = E(1) N(k) = máximo(E(k), 0.4*N(k-1)+0.6*E(k)) |
donde E(k) es la nota del examen k. Por ejemplo, si las notas de los exámenes son [3,7,6,3] entonces las acumuladas son [3.0,7.0,6.4,4.4]
Las notas e los exámenes se encuentran en ficheros CSV con los valores separados por comas. Cada línea representa la nota de un alumno, el primer valor es el identificador del alumno y los restantes son sus notas. Por ejemplo, el contenido de examenes.csv es
1 2 3 |
juaruigar,3,7,9,3 evadialop,3,6,7,4 carrodmes,0,9,8,7 |
Definir las funciones
1 2 |
acumuladas :: [Double] -> [Double] notasAcumuladas :: FilePath -> FilePath -> IO () |
tales que
- (acumuladas xs) es la lista de las notas acumuladas (redondeadas con un decimal) de los notas de los exámenes xs. Por ejemplo,
1 2 3 4 |
acumuladas [2,5] == [2.0,5.0] acumuladas [5,2] == [5.0,3.2] acumuladas [3,7,6,3] == [3.0,7.0,6.4,4.4] acumuladas [3,6,7,3] == [3.0,6.0,7.0,4.6] |
- (notasAcumuladas f1 f2) que escriba en el fichero f2 las notas acumuladas correspondientes a las notas de los exámenes del fichero f1. Por ejemplo, al evaluar
1 |
notasAcumuladas "examenes.csv" "acumuladas.csv" |
escribe en el fichero acumuladas.csv
1 2 3 |
juaruigar,3.0,7.0,9.0,5.4 evadialop,3.0,6.0,7.0,5.2 carrodmes,0.0,9.0,8.4,7.6 |
Soluciones
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
import Text.CSV import Data.Either -- Definicioń de acumuladas -- ======================== acumuladas :: [Double] -> [Double] acumuladas = reverse . aux . reverse where aux [] = [] aux [x] = [x] aux (x:xs) = conUnDecimal (max x (0.6*x+0.4*y)) : y : ys where (y:ys) = aux xs -- conUnDecimal 7.26 == 7.3 -- conUnDecimal 7.24 == 7.2 conUnDecimal :: Double -> Double conUnDecimal x = fromIntegral (round (10*x)) / 10 -- 1ª definición de notasAcumuladas -- ================================ notasAcumuladas :: FilePath -> FilePath -> IO () notasAcumuladas f1 f2 = do cs <- readFile f1 writeFile f2 (unlines (map ( acumuladaACadena . notaAAcumuladas . listaANota . cadenaALista ) (contenidoALineasDeNotas cs))) -- λ> contenidoALineasDeNotas "juaruigar,3,7,6,3\nevadialop,3,6,7,3\n\n \n" -- ["juaruigar,3,7,6,3","evadialop,3,6,7,3"] contenidoALineasDeNotas :: String -> [String] contenidoALineasDeNotas = filter esLineaDeNotas . lines where esLineaDeNotas = elem ',' -- cadenaALista "a,b c,d" == ["a","b c","d"] -- cadenaALista "juaruigar,3,7,6,3" == ["juaruigar","3","7","6","3"] cadenaALista :: String -> [String] cadenaALista cs | tieneComas cs = d : cadenaALista ds | otherwise = [cs] where (d,_:ds) = span (/=',') cs tieneComas = elem ',' -- λ> listaANota ["juaruigar","3","7","6","3"] -- ("juaruigar",[3.0,7.0,6.0,3.0]) listaANota :: [String] -> (String,[Double]) listaANota (x:xs) = (x,map read xs) -- λ> notaAAcumuladas ("juaruigar",[3.0,7.0,6.0,3.0]) -- ("juaruigar",[3.0,7.0,6.4,4.4]) notaAAcumuladas :: (String,[Double]) -> (String,[Double]) notaAAcumuladas (x,xs) = (x, acumuladas xs) -- λ> acumuladaACadena ("juaruigar",[3.0,7.0,6.4,4.4]) -- "juaruigar,3.0,7.0,6.4,4.4" acumuladaACadena :: (String,[Double]) -> String acumuladaACadena (x,xs) = x ++ "," ++ tail (init (show xs)) -- 2ª definición de notasAcumuladas -- ================================ notasAcumuladas2 :: FilePath -> FilePath -> IO () notasAcumuladas2 f1 f2 = do cs <- readFile f1 let (Right csv) = parseCSV f1 cs let notas = [xs | xs <- csv, length xs > 1] writeFile f2 (unlines (map ( acumuladaACadena . notaAAcumuladas . listaANota ) notas)) |