|
| 1 | +package main |
| 2 | + |
| 3 | +import ( |
| 4 | + "fmt" |
| 5 | + "sort" |
| 6 | + "strings" |
| 7 | + "time" |
| 8 | +) |
| 9 | + |
| 10 | +/* |
| 11 | +# * EJERCICIO: |
| 12 | +# * Explora el concepto de funciones de orden superior en tu lenguaje |
| 13 | +# * creando ejemplos simples (a tu elección) que muestren su funcionamiento. |
| 14 | +# * |
| 15 | +# * DIFICULTAD EXTRA (opcional): |
| 16 | +# * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y |
| 17 | +# * lista de calificaciones), utiliza funciones de orden superior para |
| 18 | +# * realizar las siguientes operaciones de procesamiento y análisis: |
| 19 | +# * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre |
| 20 | +# * y promedio de sus calificaciones. |
| 21 | +# * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes |
| 22 | +# * que tienen calificaciones con un 9 o más de promedio. |
| 23 | +# * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven. |
| 24 | +# * - Mayor calificación: Obtiene la calificación más alta de entre todas las |
| 25 | +# * de los alumnos. |
| 26 | +# * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales). |
| 27 | +# */ |
| 28 | + |
| 29 | +// Pasar una función como argumento a otra función. |
| 30 | + |
| 31 | +// Interface |
| 32 | +func Func_root(x interface{}, y interface{}, f func(interface{}, interface{}) interface{}) interface{} { |
| 33 | + return f(x, y) |
| 34 | +} |
| 35 | + |
| 36 | +func sum_number(n1 interface{}, n2 interface{}) interface{} { |
| 37 | + return n1.(int) + n2.(int) |
| 38 | +} |
| 39 | + |
| 40 | +func sum_string(s1 interface{}, s2 interface{}) interface{} { |
| 41 | + return fmt.Sprintf("%v %v\n", s1.(string), s2.(string)) |
| 42 | +} |
| 43 | + |
| 44 | +// Genereic |
| 45 | +func Func_rootG[Gen any](x, y Gen, f func(Gen, Gen) Gen) Gen { |
| 46 | + return f(x, y) |
| 47 | +} |
| 48 | + |
| 49 | +func sum_numberG(n1 int, n2 int) int { |
| 50 | + return n1 + n2 |
| 51 | +} |
| 52 | + |
| 53 | +func sum_stringG(s1 string, s2 string) string { |
| 54 | + return fmt.Sprintf("%v %v\n", s1, s2) |
| 55 | +} |
| 56 | + |
| 57 | +// Devolver funciones |
| 58 | + |
| 59 | +func Return_Func(x int) func(int) int { |
| 60 | + return func(number int) int { |
| 61 | + return number * x |
| 62 | + } |
| 63 | + |
| 64 | +} |
| 65 | + |
| 66 | +// implementacion de map, filter porque en go no existe nativamente |
| 67 | +// map |
| 68 | +func mapF[T any](f func(T) T, slice []T) []T { |
| 69 | + result := []T{} |
| 70 | + for _, i := range slice { |
| 71 | + result = append(result, f(i)) |
| 72 | + } |
| 73 | + return result |
| 74 | + |
| 75 | +} |
| 76 | + |
| 77 | +func Qua2(x int) int { |
| 78 | + return x * x |
| 79 | +} |
| 80 | + |
| 81 | +// filter |
| 82 | + |
| 83 | +func filterF[T any](slice1 []T, f func(T) bool) []T { |
| 84 | + |
| 85 | + result := []T{} |
| 86 | + for _, i := range slice1 { |
| 87 | + |
| 88 | + if f(i) { |
| 89 | + result = append(result, i) |
| 90 | + } |
| 91 | + |
| 92 | + } |
| 93 | + return result |
| 94 | +} |
| 95 | + |
| 96 | +func even_number(x int) bool { |
| 97 | + return x%2 == 0 |
| 98 | +} |
| 99 | + |
| 100 | +func odd_number(x int) bool { |
| 101 | + return x%2 != 0 |
| 102 | +} |
| 103 | + |
| 104 | +// reduce |
| 105 | + |
| 106 | +func reduceF[T any](slice1 []T, f func(x, y T) T) T { |
| 107 | + var result T |
| 108 | + for _, i := range slice1 { |
| 109 | + result = f(result, i) |
| 110 | + |
| 111 | + } |
| 112 | + return result |
| 113 | +} |
| 114 | + |
| 115 | +// Extra |
| 116 | + |
| 117 | +type kv struct { |
| 118 | + key string |
| 119 | + value float64 |
| 120 | +} |
| 121 | + |
| 122 | +type Student struct { |
| 123 | + name string |
| 124 | + dateBorn time.Time |
| 125 | + note map[string]float64 |
| 126 | + averageNote float64 |
| 127 | + bestMateria kv |
| 128 | +} |
| 129 | + |
| 130 | +// promedio de calidicaciones, usare reduceF |
| 131 | + |
| 132 | +func (s *Student) AverageNote() { // point when variable is a map |
| 133 | + noteValue := []float64{} |
| 134 | + for _, v := range s.note { |
| 135 | + noteValue = append(noteValue, v) |
| 136 | + } |
| 137 | + |
| 138 | + sumNote := reduceF(noteValue, func(acc, n float64) float64 { |
| 139 | + return acc + n |
| 140 | + }) |
| 141 | + s.averageNote = sumNote / float64(len(noteValue)) |
| 142 | + |
| 143 | +} |
| 144 | + |
| 145 | +func (s *Student) OrderNote() { |
| 146 | + KV := []kv{} |
| 147 | + for k, v := range s.note { |
| 148 | + KV = append(KV, kv{k, v}) |
| 149 | + } |
| 150 | + sort.Slice(KV, func(x, y int) bool { |
| 151 | + return KV[x].value > (KV[y].value) |
| 152 | + }) |
| 153 | + |
| 154 | + for _, v := range KV { |
| 155 | + fmt.Printf("Materia: %v, Note: %v\n", v.key, v.value) |
| 156 | + } |
| 157 | + s.bestMateria = KV[0] |
| 158 | + |
| 159 | +} |
| 160 | + |
| 161 | +type Students []Student |
| 162 | + |
| 163 | +func BestStudient(student Student) bool { |
| 164 | + return student.averageNote >= 9.0 // aqui paso como argumento el elemnto que paso en el slice de filterF |
| 165 | + // no puedo pasar la nota, porque el slice esta compuesto de Student y eso es lo que paso |
| 166 | +} |
| 167 | + |
| 168 | +func (s Students) SortByDateBorn() { |
| 169 | + sort.Slice(s, func(i, j int) bool { |
| 170 | + return s[i].dateBorn.Before(s[j].dateBorn) // Ordena en orden ascendente |
| 171 | + }) |
| 172 | +} |
| 173 | + |
| 174 | +func (s Students) Display() { |
| 175 | + for _, i := range s { |
| 176 | + fmt.Printf("\tName: %v, Ano: %v, Mes : %v, Dia : %v\n", i.name, i.dateBorn.Year(), i.dateBorn.Month(), i.dateBorn.Day()) |
| 177 | + fmt.Printf("Promedio: %.2f,mejor asignatura: %v, Notas: %v\n", i.averageNote, i.bestMateria, i.note) |
| 178 | + } |
| 179 | +} |
| 180 | + |
| 181 | +func main() { |
| 182 | + f1 := Func_root(21, 21, sum_number) |
| 183 | + fmt.Println(f1) |
| 184 | + f1 = Func_root("Resba", "loso", sum_string) |
| 185 | + fmt.Println(f1) |
| 186 | + |
| 187 | + f1 = Func_rootG(210, 210, sum_numberG) |
| 188 | + fmt.Println(f1) |
| 189 | + f1 = Func_rootG("Resbaloso", "tiburcio", sum_stringG) |
| 190 | + fmt.Println(f1) |
| 191 | + |
| 192 | + f2 := Return_Func(100) //return_func retorna una funcion |
| 193 | + fmt.Println(f2(2)) // f2 es una funcion retornada que recibe parametro |
| 194 | + |
| 195 | + // map |
| 196 | + list1 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9} |
| 197 | + Q_list := mapF(Qua2, list1) |
| 198 | + fmt.Println(Q_list) |
| 199 | + |
| 200 | + list2 := []string{"mama", "loka"} |
| 201 | + Q_list2 := mapF(func(n string) string { |
| 202 | + return strings.ToUpper(n) |
| 203 | + |
| 204 | + }, list2) |
| 205 | + fmt.Println(Q_list2) |
| 206 | + |
| 207 | + // filter |
| 208 | + Q_list3 := filterF(list1, even_number) |
| 209 | + Q_list4 := filterF(list1, odd_number) |
| 210 | + fmt.Printf("Even Number: %v\n Odd NUmber : %v\n", Q_list3, Q_list4) |
| 211 | + |
| 212 | + // reduce |
| 213 | + list4 := []string{"r", "e", "s", "b", "a"} |
| 214 | + Q_list5 := reduceF(list1, func(x, y int) int { |
| 215 | + return x + y |
| 216 | + }) |
| 217 | + |
| 218 | + Q_list6 := reduceF(list4, func(x, y string) string { |
| 219 | + return x + y |
| 220 | + }) |
| 221 | + |
| 222 | + fmt.Println(Q_list5) |
| 223 | + fmt.Println(Q_list6) |
| 224 | + |
| 225 | + // Extra |
| 226 | + |
| 227 | + student := Students{ |
| 228 | + Student{ |
| 229 | + "perico 3", |
| 230 | + time.Date(2001, 1, 1, 0, 0, 0, 0, time.UTC), |
| 231 | + map[string]float64{ |
| 232 | + "ma": 9.0, |
| 233 | + "l": 5.6, |
| 234 | + "EF": 9.9, |
| 235 | + }, |
| 236 | + 0, |
| 237 | + kv{"", 0.0}, |
| 238 | + }, |
| 239 | + Student{ |
| 240 | + "perico 2", |
| 241 | + time.Date(2000, 10, 10, 0, 0, 0, 0, time.UTC), |
| 242 | + map[string]float64{ |
| 243 | + "ma": 9.2, |
| 244 | + "l": 9.5, |
| 245 | + "EF": 8.7, |
| 246 | + }, |
| 247 | + 0, |
| 248 | + kv{"", 0.0}, |
| 249 | + }, |
| 250 | + Student{ |
| 251 | + "perico 1", |
| 252 | + time.Date(2011, 12, 12, 0, 0, 0, 0, time.UTC), |
| 253 | + map[string]float64{ |
| 254 | + "ma": 9.0, |
| 255 | + "l": 9.3, |
| 256 | + "EF": 8.0, |
| 257 | + }, |
| 258 | + 0, |
| 259 | + kv{"", 0.0}, |
| 260 | + }} |
| 261 | + |
| 262 | + fmt.Println(" EXTRA ") |
| 263 | + fmt.Println() |
| 264 | + fmt.Println("Promedio de Calificaciones") |
| 265 | + for i, _ := range student { |
| 266 | + student[i].AverageNote() |
| 267 | + fmt.Printf("\tName: %v, Average: %v\n", student[i].name, student[i].averageNote) |
| 268 | + } |
| 269 | + |
| 270 | + fmt.Println() |
| 271 | + fmt.Println("Mejores estudiantes") |
| 272 | + |
| 273 | + best := filterF(student, BestStudient) //uso la misma funcion filterF generica con T any y lo que paso es el elemento del slice a la funcion que paso como argumento |
| 274 | + for _, i := range best { |
| 275 | + fmt.Printf("\tName: %v, Average: %v\n", i.name, i.averageNote) |
| 276 | + } |
| 277 | + |
| 278 | + fmt.Println() |
| 279 | + fmt.Println("Sin Ordenar") |
| 280 | + student.Display() |
| 281 | + fmt.Println() |
| 282 | + fmt.Println("Ordenados por fecha de Nacimiento") |
| 283 | + student.SortByDateBorn() |
| 284 | + student.Display() |
| 285 | + |
| 286 | + fmt.Println() |
| 287 | + fmt.Println("Calificacion mas alta por alumno") |
| 288 | + for i, _ := range student { |
| 289 | + student[i].OrderNote() |
| 290 | + |
| 291 | + } |
| 292 | + student.Display() |
| 293 | +} |
0 commit comments