/// <summary> /// Regresa una lista de las olimpiadas en las que la escuela instanciada /// fue la escuela sede /// </summary> /// <returns>La lista de olimpiadas</returns> public List <Olimpiada> obtenerOlimpiadasSede() { List <Olimpiada> list = new List <Olimpiada>(); Acceso db = new Acceso(); StringBuilder query = new StringBuilder(); query.Append(" select numero from Olimpiada where escuela = "); query.Append(clave); query.Append(" and clase = "); // Mientras las OMIS y OMIPS no sean aparte, las sedes se cargan de OMIS query.Append(Cadenas.comillas(TipoOlimpiada.OMI.ToString().ToLower())); db.EjecutarQuery(query.ToString()); DataTable table = db.getTable(); if (table.Rows.Count == 0) { return(list); } foreach (DataRow r in table.Rows) { string numero = DataRowParser.ToString(r[0]); Olimpiada o = Olimpiada.obtenerOlimpiadaConClave(numero, TipoOlimpiada.OMI); list.Add(o); } return(list); }
/// <summary> /// Dado que las olimpiadas son pocas y a que se hacen muchas llamadas a la base para obtener estos objetos /// los cargamos una vez por aplicacion y los dejamos ahi /// </summary> /// <returns></returns> private static Dictionary <string, Olimpiada> getOlimpiadas(TipoOlimpiada tipoOlimpiada) { Dictionary <string, Olimpiada> olimpiadas; string application = obtenerApplicationString(tipoOlimpiada); olimpiadas = (Dictionary <string, Olimpiada>)HttpContext.Current.Application[application]; if (olimpiadas == null) { olimpiadas = cargarOlimpiadas(tipoOlimpiada); HttpContext.Current.Application[application] = olimpiadas; // Cargamos las instrucciones en caso de que haya un scoreboard activo List <OmegaUp> polls = OmegaUp.obtenerInstrucciones(OmegaUp.Instruccion.POLL); foreach (OmegaUp p in polls) { if (p.tipoOlimpiada == tipoOlimpiada) { Olimpiada o = Olimpiada.obtenerOlimpiadaConClave(p.olimpiada, p.tipoOlimpiada); o.liveResults = true; } } } return(olimpiadas); }
private static Dictionary <string, Olimpiada> cargarOlimpiadas(TipoOlimpiada tipoOlimpiada) { Dictionary <string, Olimpiada> lista = new Dictionary <string, Olimpiada>(); Acceso db = new Acceso(); StringBuilder query = new StringBuilder(); TipoOlimpiada tipoQuery = tipoOlimpiada; query.Append(" select * from olimpiada "); query.Append(" where clase = "); query.Append(Cadenas.comillas(tipoQuery.ToString().ToLower())); query.Append(" order by año desc,"); query.Append(" numero desc"); db.EjecutarQuery(query.ToString()); DataTable table = db.getTable(); foreach (DataRow r in table.Rows) { Olimpiada o = new Olimpiada(); o.llenarDatos(r); lista.Add(o.numero, o); } return(lista); }
/// <summary> /// Copia todos los datos precalculados del objeto old a este objeto /// </summary> /// <param name="old"></param> public void copiarDatosPrecalculados(Olimpiada old) { this.logo = old.logo; this.mostrarResultadosPorDia = old.mostrarResultadosPorDia; this.mostrarResultadosPorProblema = old.mostrarResultadosPorProblema; this.mostrarResultadosTotales = old.mostrarResultadosTotales; this.problemasDia1 = old.problemasDia1; this.problemasDia2 = old.problemasDia2; }
/// <summary> /// Obtiene la tabla de estados generales, similar a las que se ve en wikipedia /// </summary> /// <param name="tipoOlimpiada">El tipo de olimpiada</param> /// <param name="cabeceras">Un arreglo donde cada elemento /// inidica si la olimpiada tiene resultados para cualquier estado</param> /// <returns>El diccionario de los estados</returns> public static Dictionary <string, Dictionary <string, Medallero> > obtenerTablaEstadosGeneral(TipoOlimpiada tipoOlimpiada, out bool[] cabeceras) { Dictionary <string, Dictionary <string, Medallero> > estados = new Dictionary <string, Dictionary <string, Medallero> >(); Acceso db = new Acceso(); StringBuilder query = new StringBuilder(); query.Append(" select * from Medallero where tipo = "); query.Append((int)TipoMedallero.ESTADO_POR_OMI); query.Append(" and clase = "); query.Append(Cadenas.comillas(tipoOlimpiada.ToString().ToLower())); db.EjecutarQuery(query.ToString()); DataTable table = db.getTable(); // Un hashset para poder construir el arreglo de cabeceras HashSet <string> olimpiadasConResultados = new HashSet <string>(); foreach (DataRow r in table.Rows) { // Obtengo los datos de la tabla a un objeto medallero Medallero m = new Medallero(); m.llenarDatos(r); string estado = m.clave.Substring(0, 3); // Obtengo el medallero del estado Dictionary <string, Medallero> medallero; if (!estados.TryGetValue(estado, out medallero)) { medallero = new Dictionary <string, Medallero>(); estados.Add(estado, medallero); } // Agrego el medallero con la olimpiada medallero.Add(m.omi, m); // Ponemos que la olimpiada tiene resultados en el hashset if (!olimpiadasConResultados.Contains(m.omi)) { olimpiadasConResultados.Add(m.omi); } } // Construimos el arreglo de cabeceras List <Olimpiada> olimpiadas = Olimpiada.obtenerOlimpiadas(tipoOlimpiada); cabeceras = new bool[olimpiadas.Count]; for (int i = 0; i < olimpiadas.Count; i++) { cabeceras[i] = olimpiadasConResultados.Contains(olimpiadas[i].numero); } return(estados); }
private void llenarDatos(int usuario, TipoOlimpiada tipoOlimpiada = TipoOlimpiada.OMI) { // Primero obtenemos la persona this.persona = Persona.obtenerPersonaConClave(usuario); Acceso db = new Acceso(); StringBuilder query = new StringBuilder(); query.Append(" select olimpiada, medalla, estado from Resultados where concursante = "); query.Append(usuario); query.Append(" and clase = "); query.Append(Cadenas.comillas(tipoOlimpiada.ToString().ToLower())); query.Append(" order by medalla"); db.EjecutarQuery(query.ToString()); DataTable table = db.getTable(); medallas = new List <KeyValuePair <Olimpiada, Resultados.TipoMedalla> >(); estados = new HashSet <string>(); foreach (DataRow r in table.Rows) { Resultados.TipoMedalla medalla = DataRowParser.ToTipoMedalla(DataRowParser.ToString(r["medalla"])); if (medalla == Resultados.TipoMedalla.NADA) { continue; } Olimpiada o = Olimpiada.obtenerOlimpiadaConClave(DataRowParser.ToString(r["olimpiada"]), tipoOlimpiada); medallas.Add(new KeyValuePair <Olimpiada, Resultados.TipoMedalla>(o, medalla)); string estado = DataRowParser.ToString(r["estado"]); if (!estados.Contains(estado)) { estados.Add(estado); } if (medalla == Resultados.TipoMedalla.BRONCE) { bronces++; } else if (medalla == Resultados.TipoMedalla.PLATA) { platas++; } else { oros++; } } }
/// <summary> /// Regresa el objeto olimpiada relacionado con la clave mandada como parametro /// </summary> /// <param name="clave">La clave de la olimpiada</param> /// <param name="tipoOlimpiada">El tipo de olimpiada que se busca</param> /// <returns>El objeto olimpiada</returns> public static Olimpiada obtenerOlimpiadaConClave(string clave, TipoOlimpiada tipoOlimpiada) { Dictionary <string, Olimpiada> olimpiadas = getOlimpiadas(tipoOlimpiada); Olimpiada o = null; if (clave == null) { return(null); } olimpiadas.TryGetValue(clave.Trim(), out o); return(o); }
private void actualizaOMIPS(TipoOlimpiada tipoOlimpiada, string clave) { Olimpiada omi = obtenerOlimpiadaConClave(this.numero, tipoOlimpiada); if (omi == null) { nuevaOMI(tipoOlimpiada); omi = obtenerOlimpiadaConClave(TEMP_CLAVE, tipoOlimpiada); clave = TEMP_CLAVE; } omi.numero = this.numero; omi.año = this.año; omi.claveEstado = this.claveEstado; omi.ciudad = this.ciudad; omi.inicio = this.inicio; omi.fin = this.fin; omi.datosPublicos = this.datosPublicos; omi.puntosDesconocidos = this.puntosDesconocidos; omi.alsoOmips = this.alsoOmips; omi.alsoOmipsOnline = this.alsoOmipsOnline; omi.claveEscuela = this.claveEscuela; omi.relacion = this.relacion; omi.video = this.video; omi.reporte = this.reporte; omi.logo = this.logo; omi.poster = this.poster; if (tipoOlimpiada == TipoOlimpiada.OMIPO || tipoOlimpiada == TipoOlimpiada.OMISO) { omi.esOnline = true; omi.puntosDetallados = false; } else { omi.registroActivo = this.registroActivo; omi.registroSedes = this.registroSedes; omi.esOnline = this.esOnline; omi.puntosDetallados = this.puntosDetallados; } omi.diplomasOnline = this.diplomasOnline; omi.ordenarPorPuntos = this.ordenarPorPuntos; omi.guardarDatos(clave); }
/// <summary> /// Usa las variables en el objeto para calcular las medallas basadas en lo que hay en la base de datos /// </summary> /// </param name="tipoOlimpiada">El tipo de olimpiada para el que se requieren los tipos</param> public static void calcularMedallas(TipoOlimpiada tipoOlimpiada, string olimpiada, bool ordenarPorPuntos) { if (tipoOlimpiada == TipoOlimpiada.NULL) { return; } Acceso db = new Acceso(); StringBuilder query = new StringBuilder(); query.Append(" delete medallero where clase = "); query.Append(Cadenas.comillas(tipoOlimpiada.ToString().ToLower())); query.Append(" and (tipo <> "); query.Append((int)TipoMedallero.ESTADO_POR_OMI); query.Append(" or clave like '%_"); query.Append(olimpiada); query.Append("%')"); // Primero borramos todo lo que está en la base de datos // a excepción de otros tipos de olimpiada u otros estado-olimpiada db.EjecutarQuery(query.ToString()); // Obtenermos todos los resultados List <Resultados> resultados = Resultados.cargarResultados(null, tipoOlimpiada, cargarObjetos: true); // Diccionarios para los diferentes tipos de medalleros Dictionary <int, Medallero> personas = new Dictionary <int, Medallero>(); Dictionary <int, Medallero> instituciones = new Dictionary <int, Medallero>(); Dictionary <string, Medallero> estados = new Dictionary <string, Medallero>(); Dictionary <string, Medallero> estadosPorOlimpiada = new Dictionary <string, Medallero>(); // Recorremos todos los resultados agregando contadores foreach (Resultados resultado in resultados) { Medallero persona; Medallero institucion; Medallero estado; Medallero estadoPorOlimpiada = null; bool aplicaAOlimpiada = olimpiada == resultado.omi; string estadoPorOlimpiadaClave = resultado.estado + "_" + resultado.omi; if (!personas.TryGetValue(resultado.usuario, out persona)) { persona = new Medallero(); persona.clave = resultado.usuario.ToString(); persona.tipoOlimpiada = tipoOlimpiada; persona.tipoMedallero = TipoMedallero.PERSONA; personas.Add(resultado.usuario, persona); } if (resultado.escuela != null) { if (!instituciones.TryGetValue(resultado.escuela.clave, out institucion)) { institucion = new Medallero(); institucion.clave = resultado.escuela.clave.ToString(); institucion.tipoOlimpiada = tipoOlimpiada; institucion.tipoMedallero = TipoMedallero.INSTITUCION; instituciones.Add(resultado.escuela.clave, institucion); } } else { // Agregamos un dummy para evitar if's abajo institucion = new Medallero(); } Estado e = Estado.obtenerEstadoConClave(resultado.estado); if (!estados.TryGetValue(resultado.estado, out estado)) { estado = new Medallero(); estado.clave = resultado.estado; estado.tipoOlimpiada = tipoOlimpiada; estado.tipoMedallero = TipoMedallero.ESTADO; estados.Add(resultado.estado, estado); } if (aplicaAOlimpiada) { if (!estadosPorOlimpiada.TryGetValue(estadoPorOlimpiadaClave, out estadoPorOlimpiada)) { estadoPorOlimpiada = new Medallero(); estadoPorOlimpiada.clave = estadoPorOlimpiadaClave; estadoPorOlimpiada.tipoOlimpiada = tipoOlimpiada; estadoPorOlimpiada.omi = resultado.omi; estadoPorOlimpiada.ordenarPorPuntos = ordenarPorPuntos; estadoPorOlimpiada.tipoMedallero = TipoMedallero.ESTADO_POR_OMI; estadoPorOlimpiada.count = 0; estadoPorOlimpiada.puntos = 0; estadoPorOlimpiada.promedio = 0; estadoPorOlimpiada.hayUNKs = false; if (!e.extranjero) { estadosPorOlimpiada.Add(estadoPorOlimpiadaClave, estadoPorOlimpiada); } } } if (resultado.medalla != Resultados.TipoMedalla.DESCALIFICADO) { switch (resultado.medalla) { case Resultados.TipoMedalla.ORO_3: case Resultados.TipoMedalla.ORO_2: case Resultados.TipoMedalla.ORO_1: case Resultados.TipoMedalla.ORO: { persona.oros++; estado.oros++; institucion.oros++; if (aplicaAOlimpiada) { estadoPorOlimpiada.oros++; } break; } case Resultados.TipoMedalla.PLATA: { persona.platas++; estado.platas++; institucion.platas++; if (aplicaAOlimpiada) { estadoPorOlimpiada.platas++; } break; } case Resultados.TipoMedalla.BRONCE: { persona.bronces++; estado.bronces++; institucion.bronces++; if (aplicaAOlimpiada) { estadoPorOlimpiada.bronces++; } break; } default: { persona.otros++; estado.otros++; institucion.otros++; break; } } if (aplicaAOlimpiada) { if (resultado.clave.StartsWith(Resultados.CLAVE_DESCONOCIDA)) { estadoPorOlimpiada.hayUNKs = true; } // No se han guardado mas de 4 lugares if (estadoPorOlimpiada.count < 4) { // En algunas olimpiadas, hubo invitados que se pusieron en el medallero, estos no se cuentan en el total if (!resultado.clave.EndsWith("I")) { Olimpiada o = Olimpiada.obtenerOlimpiadaConClave(resultado.omi, resultado.tipoOlimpiada); // Si solo tenemos los datos de los medallistas, no podemos hacer nada con los puntos if (o.noMedallistasConocidos) { // En las OMIs con puntos desconocidos, se guarda en los puntos del día 2, los puntos de los estados if (o.puntosDesconocidos) { estadoPorOlimpiada.puntos += resultado.totalDia2; } else { estadoPorOlimpiada.count++; estadoPorOlimpiada.puntos += resultado.total; } } } } } } } // Guardamos los contadores en la base de datos // Primero las personas foreach (Medallero persona in personas.Values) { if (persona.clave != "0") { persona.guardarDatos(); } } // Después las instituciones foreach (Medallero institucion in instituciones.Values) { if (institucion.clave != "0") { institucion.guardarDatos(); } } // Los estados (general) foreach (Medallero estado in estados.Values) { estado.guardarDatos(); } // Finalmente, para los estados por olimpiada, hay que hacer un par de cosas List <Medallero> sortedEstados = new List <Medallero>(estadosPorOlimpiada.Values); if (sortedEstados.Count > 0) { string lastOMI = sortedEstados[0].omi; bool invalido = false; int firstEstadoInOmi = 0; // Los necesitamos ordenados primero por olimpiada sortedEstados.Sort(); // Necesitamos reordenarlos por promedio for (int i = 0; i < sortedEstados.Count; i++) { Medallero estado = sortedEstados[i]; if (estado.omi != lastOMI) { // Si algún estado en la olimpiada tiene un // promedio invalido, ningún promedio es valido if (invalido) { for (int j = firstEstadoInOmi; j < i; j++) { sortedEstados[j].promedio = 0; } } firstEstadoInOmi = i; invalido = false; lastOMI = estado.omi; } if (!estado.hayUNKs && estado.count > 0) { estado.promedio = (float?)Math.Round((double)(estado.puntos / estado.count), 2); } invalido |= estado.promedioEsInvalido(); } sortedEstados.Sort(); lastOMI = ""; int lugarActual = 0; Medallero ultimoEstado = null; // Vamos por cada estado para asignarles el lugar foreach (Medallero estado in sortedEstados) { // Estamos recibiendo los estados de todas las olimpiadas if (estado.omi != lastOMI) { lastOMI = estado.omi; lugarActual = 0; ultimoEstado = null; } lugarActual++; // Revisamos si hay empates entre estados if (ultimoEstado == null || ultimoEstado.oros != estado.oros || ultimoEstado.platas != estado.platas || ultimoEstado.bronces != estado.bronces || (int)Math.Round((double)ultimoEstado.puntos) != (int)Math.Round((double)estado.puntos)) { estado.lugar = lugarActual; } else { estado.lugar = ultimoEstado.lugar; } ultimoEstado = estado; estado.guardarDatos(); } } // Al final hacemos los ajustes hardcodeados hardcode(tipoOlimpiada, olimpiada); }