WorldSkills: avis du participant de l'Olympiade


Bonjour, Habr!

Chaque programmeur veut pomper ses compétences et chaque entreprise veut voir des spécialistes qualifiés, mais comment y parvenir? Les olympiades viennent à la rescousse, cet article portera sur la participation à l'une d'entre elles.

Retraite


L'article s'est avéré volumineux, donc tout le code et la plupart des images sont sous les spoilers. Tester toujours le format de soumission de l'article. Si ce format vous semble inconfortable, veuillez en parler. De plus, toutes les images sont cliquables.

À propos du concours


WorldSkills est un concours dont le but est d'identifier des professionnels dans un domaine spécifique. Le concours prend ses racines avec WorldSkills International (WSI), l'association internationale à but non lucratif.

La participation au concours est gratuite. L'âge des participants est de 18 à 28 ans, étudiants des collèges ou universités.

La compétition à l'université dure 5 jours: le premier jour, l'ouverture et la vérification des emplois, puis trois jours de compétition, le dernier jour - résumé et clôture.

À propos de la sélection des compétences et de la formation


J'ai découvert les Jeux olympiques par hasard lors d'une des entraînements à l'université en 2ème année. J'ai été invité à participer à la compétence «Développement de solutions logicielles pour les entreprises». Pour résoudre les problèmes, des connaissances en C # ou Java, en travaillant avec une base de données, et comme je l'ai découvert lors des premiers Jeux Olympiques Android, étaient nécessaires. L'ouverture des Jeux olympiques était prévue pour début juin et la fenêtre était déjà fin avril. À ce moment, je ne savais absolument rien de ce qui était nécessaire.

Ma surprise ne connaissait pas de limites lorsque tous les participants potentiels étaient réunis pour la formation. Il y avait 7 personnes dans le public, dont 6 étaient déjà des étudiants de troisième année, et j'étais la septième. Pourquoi ai-je été si surpris? En troisième année, les étudiants suivent un cours sur les bases de données, qui dure 2 semestres, ce qui signifie que tout le monde a eu plus d'un an de pratique. Je ne voulais pas refuser, j'ai donc demandé aux enseignants un livre sur la base de données, trouvé un cours de C # sur Internet et commencé à me préparer, apparaissant périodiquement dans les classes préparatoires.

Deux semaines avant le début de l'Olympiade, nous avons appris que trois personnes au maximum pouvaient participer de notre département. Passé le tour de qualification. En 1,5 heure, nous avons dû créer une base de données dans le système de gestion de base de données MSSQL en utilisant le modèle ER, importer des données à partir d'un fichier Excel et les afficher dans l'application. En un mot, j'ai été autorisé à participer à l'Olympiade de notre département.

Maintenant sur la compétition


Le premier jour de la compétition ou «C -1»


La découverte tant attendue a eu lieu ce jour-là. Tous les participants étaient réunis dans l'auditorium, où ils ont raconté l'histoire et les compétences de WorldSkills et présenté tous les experts avec les participants.
Après cette cérémonie, tout le monde s'est rendu sur leurs sites pour vérifier l'équipement. Un «rituel de dédicace» a eu lieu, dans lequel nous avons sélectionné nos emplois et signé pour la sécurité. À ce moment-là, je ne savais pas ce que je pouvais vérifier dans le logiciel, donc immédiatement après le tirage, je suis parti pour me préparer pour le lendemain.

Le deuxième jour du concours ou le début du concours


Quels étaient les Jeux olympiques?

Pour notre compétence, en 2 jours (trois pour les autres compétences), pendant 6 heures, avec des pauses, nous avons dû écrire une application client-serveur en C # / Java avec des requêtes dans la base de données. Plus précisément, dire "tout ce que nous avons le temps d'écrire", puisque le principe de l'Olympiade est "faites ce que vous pouvez et comment vous pouvez".

Selon les experts, les critères étaient de plusieurs dizaines de pages A4. Les critères ne sont émis qu’après la fin de la session et uniquement aux experts, je ne peux donc rien dire à leur sujet.

Passons aux événements du deuxième jour. Pour la première session, il a été nécessaire de mettre en œuvre les éléments suivants:

  • Créer une base de données à l'aide d'un diagramme ER bien connu
  • Importez des données à partir de fichiers Excel dans la base de données
  • Créez 4 écrans pour les mises en page dans la présentation

Et pour le second, composez cinq autres écrans pour les mises en page.

En bref, toutes les tâches ont été résolues, à l'exception de l'affichage des images de la base de données et de la création d'une liste personnalisée d'éléments.

Quelques captures d'écran:




L'interface vous permet de trouver des joueurs par nom (même la première lettre), saison et équipe. En double-cliquant sur une image qui n'a pas été implémentée, des informations détaillées sur le lecteur sont ouvertes. Maintenant, je voudrais l'implémenter via DataGridViewImageColumn.




Comment j'ai enregistré des images
private void download_Click(object sender, EventArgs e) { SaveFileDialog saveFile = new SaveFileDialog(); saveFile.DefaultExt = ".jpg"; saveFile.AddExtension = true; //   - / saveFile.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.CommonPictures); saveFile.Filter = "Bitmap files (*.bmp)|*.bmp|Image files (*.jpg;*.png)|*.jpg;*.png"; if (saveFile.ShowDialog() == DialogResult.OK) { if (!saveFile.FileName.Equals("")) { String[] arr = saveFile.FileName.Split('.'); //       "\"  String filepath = arr[0].Substring(0, arr[0].LastIndexOf('\\') + 1); for (int i = 1; i <= imageList1.Images.Count; i++) { Image image = Image.FromFile("..\\Pictures\\" + (i + offset) + ".jpg"); image.Save(filepath + i + "." + arr[1]); } } } } 


Plus de captures d'écran, de texte et de code



L'interface est l'écran principal, vous permettant de sélectionner le rôle de "Utilisateur" ou "Administrateur", ainsi que de regarder les meilleurs moments des matchs. Comment placer les éléments au centre n'a pas pu trouver.

Implémentation de téléchargement d'image
 private int countImages() { sqlConnection = new SqlConnection(connectionString); using (sqlConnection) { sqlConnection.Open(); String sqlcomm = "SELECT Count(*) FROM [Pictures$]"; SqlCommand command = new SqlCommand(sqlcomm, sqlConnection); int result = (int)command.ExecuteScalar(); return result; } } private void loadPage() { sqlConnection = new SqlConnection(connectionString); using (sqlConnection) { sqlConnection.Open(); String sqlcomm = "SELECT [Img] , [CreateTime] FROM [Pictures] P" + " Order By P.CreateTime Desc" + " Offset @click Rows FETCH NEXT @svm ROWS ONLY"; SqlCommand cmd = new SqlCommand(sqlcomm, sqlConnection); cmd.Parameters.AddWithValue("@click", click); cmd.Parameters.AddWithValue("@svm", svm); dataAdapter.SelectCommand = cmd; DataSet data = new DataSet(); dataAdapter.Fill(data); imageList1.Images.Clear(); listView1.Clear(); for (int i = 0; i < data.Tables[0].Rows.Count; i++) { imageList1.Images.Add(Image.FromFile("..\\Pictures\\" + data.Tables[0].Rows[i].ItemArray[0].ToString())); } listView1.LargeImageList = imageList1; for (int i = 0; i < imageList1.Images.Count; i++) listView1.Items.Add("").ImageIndex = i; } } private void left_Click(object sender, EventArgs e) { if (click > 0) { if (!right.Enabled) { right.Enabled = true; } click -= svm; loadPage(); } else { left.Enabled = false; } } private void right_Click(object sender, EventArgs e) { if (click + svm < totalPhotos) { if (!left.Enabled) { left.Enabled = true; } click += svm; loadPage(); } else { right.Enabled = false; } } 





Une interface pour l'autorisation des administrateurs techniques et des organisateurs de matchs, vous permettant de vous souvenir du dernier nom d'utilisateur et mot de passe entré. Dans mon cas, j'ai écrit des données dans un fichier sur le disque dur sans chiffrement.

Vérification de l'existence du nom d'utilisateur et du mot de passe saisis dans la base de données
  private int checkData(string jobnumber, string password) { //  SQL-Injection     String sqlchecked = "if (Isnull((Select RoleId From Admin$ Where Jobnumber like(@Jobnumber) and Passwords like(@Password)) , 0) = 0)" + " Select 0 " + " else " + " Select RoleId From Admin$ Where Jobnumber like(@Jobnumber) and Passwords like(@Password)"; sqlConnection = new SqlConnection(connectionString); int result = 0; using (sqlConnection) { sqlConnection.Open(); SqlCommand command = new SqlCommand(sqlchecked, sqlConnection); //     command.Parameters.AddWithValue("@Jobnumber", jobnumber); command.Parameters.AddWithValue("@Password", password); //        result = (int)command.ExecuteScalar(); } return result; } 


Si vous connaissez la meilleure façon de vérifier les données, veuillez écrire dans les commentaires.




Et voici à quoi ressemble l'écran inachevé, ici je viens de jeter des composants sur le formulaire en fonction de la mise en page. Pouvez-vous me dire comment créer une telle liste personnalisée en C #?




L'écran le plus difficile pour moi, car il y avait du travail avec des graphiques auxquels je ne me préparais pas.

Le troisième jour du concours ou une rencontre inattendue avec Android


La veille pouvait être considérée comme un échauffement par rapport à la troisième. À 3 séances, 8 autres écrans devaient être crédités. Et lors de la dernière session, il y a eu un changement de plans, et au lieu d'une présentation sur le produit développé, nous avons commencé à faire une version simplifiée pour Android. À savoir, une galerie avec des photos téléchargées de la base de données. Maintenant, cela semble facile, mais à ce moment-là, j'étais heureux que la session ait eu 15 minutes pour accéder à Internet. En 3 heures, une GridView a été créée avec des éléments sous la forme d'une ImageView, un tableau d'images d'identification a été transféré vers l'adaptateur et l'interface OnItemClickListener a été redéfinie pour créer une nouvelle activité avec une image.

Quelques captures d'écran supplémentaires:




L'interface pour l'administrateur, vous permettant de visualiser les informations sur les joueurs. L'écran le plus inutile, à mon avis, car vous ne pouvez pas apporter de modifications.

| | |

Ma galerie «parfaite» en 3 heures en utilisant Internet et sans compétences en programmation pour Android.

Plus d'images, de texte et de code.
Code pour créer une galerie lorsque vous ne savez pas comment travailler avec la base de données
 class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) setSupportActionBar(toolbar) // id  var images = ArrayList<Int>() images.add(R.drawable.a1) //... images.add(R.drawable.a12) listView.adapter = CustomAdapter(images.toTypedArray()) listView.onItemClickListener = AdapterView.OnItemClickListener { _: AdapterView<*>, _: View, i: Int, _: Long -> var intent = Intent(this, FullscreenActivity::class.java) // id ,    intent.putExtra("id",images[i]) startActivity(intent) } } } class CustomAdapter internal constructor(var images: Array<Int>) : BaseAdapter() { override fun getCount(): Int { return images.size } //    override fun getItem(position: Int): Int { return images[position] } // id   override fun getItemId(position: Int): Long { return position.toLong() } //   override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { //    var view: View? = convertView // ,   if (view == null) { val inflater = LayoutInflater.from(parent.context) view = inflater.inflate(R.layout.item, parent, false) } view!!.findViewById<ImageView>(R.id.imageView).setImageResource(images[position]) return view } } class FullscreenActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_fullscreen) // id  var id = intent.getIntExtra("id",-1) imageView2.setImageResource(id) } } 





En cliquant sur une saison (tableau de droite), des informations détaillées sur tous les matchs s'affichent.




Une interface pour les administrateurs qui vous permet d'apporter des modifications à la liste des commandes et d'exporter des données vers Excel.

Comment j'ai exporté des données vers Excel
 private void exportExcel_Click(object sender, EventArgs e) { SaveFileDialog saveFileDialog = new SaveFileDialog(); saveFileDialog.Filter = "Excel (*.xls)|*.xls|All files (*.*)|*.*"; saveFileDialog.DefaultExt = ".xls"; if (saveFileDialog.ShowDialog() != DialogResult.OK) return; if (saveFileDialog.FileName.Equals("")) return; DataTable dt = (DataTable)dataGridView2.DataSource; //  StreamWriter wr = new StreamWriter(saveFileDialog.FileName); try { for (int i = 0; i < dt.Columns.Count; i++) { wr.Write(dt.Columns[i].ToString().ToUpper() + "\t"); } wr.WriteLine(); //    Excel for (int i = 0; i < (dt.Rows.Count); i++) { for (int j = 0; j < dt.Columns.Count; j++) { if (dt.Rows[i][j] != null) { wr.Write(Convert.ToString(dt.Rows[i][j]) + "\t"); } else { wr.Write("\t"); } } //    wr.WriteLine(); } //  wr.Close(); } catch (Exception ex) { MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } 



Résumé


À 12 heures, une cérémonie de clôture a eu lieu, où tous les participants ont reçu des certificats et des médailles avec diplômes attendaient les gagnants et les lauréats. Dans notre compétence, j'ai pris la 2ème place. Entre l'attribution des compétences, les élèves ont joué avec des chansons et des danses.

Conclusion


Au cours du mois de préparation, j'ai maîtrisé les équipes DDL et DML SQL, ce qui a grandement simplifié le travail sur les paires de bases de données en troisième année. Les connaissances acquises en C # et Windows Form laissent beaucoup à désirer, sauf pour travailler avec des bases de données et l'interface utilisateur, je n'ai eu à travailler avec rien.

Cette année, j'ai également participé à l'Olympiade WorldSkills et pris la 1ère place, mais à ce sujet, les tâches compliquées et les conséquences de la déconnexion d'Internet sur les sites dans le prochain article.

Source: https://habr.com/ru/post/fr460819/


All Articles