fork download
  1. using System;
  2. using System.IO;
  3. using System.Linq;
  4. using System.Text.Json;
  5. using System.Collections.Generic;
  6.  
  7. /*
  8. 1. Un centro de estudios quiere desarrollar su propia solución
  9. en cuanto a preparación automatizada de exámenes.
  10. Es necesario desarrollar las clases Pregunta y Examen.
  11. En cuanto a la clase Pregunta, contiene una propiedad Enunciado
  12. de solo lectura que se puede configurar al crear el objeto.
  13. La propiedad Respuestas lleva una lista de cadenas de caracteres,
  14. también de solo lectura excepto al comienzo.
  15. La propiedad NumCorrecta de solo lectura excepto al comienzo
  16. lleva el número de respuesta correcta de entre las respuestas almacenadas.
  17. Count devuelve el número de respuestas almacenadas.
  18. El método Inserta(r: string) permite insertar una nueva respuesta.
  19. El método ToString() devuelve una cadena de caracteres
  20. con el enunciado en la primera línea, una línea en blanco,
  21. las respuestas (una por línea), una línea en blanco,
  22. y finalmente la línea “Correcta: x“, donde x es
  23. el índice de la respuesta correcta (basado en cero).
  24. La clase Examen tiene una propiedad de solo lectura
  25. pero modificable al principio para el Nombre del examen.
  26. Igualmente, guarda una lista de objetos Pregunta,
  27. que son las Preguntas del examen.
  28. La propiedad Count devuelve el número de preguntas.
  29. El método Inserta(p: Pregunta) añade una nueva pregunta.
  30. El método ToString() devuelve texto con el nombre
  31. del examen en la primera línea, una línea en blanco,
  32. y a continuación las respuestas separadas por una línea en blanco.
  33. */
  34. public class Pregunta {
  35. public Pregunta()
  36. {
  37. this._respuestas = new List<string>( 4 );
  38. }
  39.  
  40. public /*required*/ string Enunciado { get; init; } = "";
  41. public IList<string> Respuestas {
  42. get => ( (List<string>) this._respuestas ).AsReadOnly();
  43. init {
  44. foreach(var r in value) {
  45. this._respuestas.Add( r );
  46. }
  47. }
  48. }
  49.  
  50. public void Inserta(string r)
  51. {
  52. this._respuestas.Add( r );
  53. }
  54.  
  55. public /*required*/ int NumCorrecta { get; init; }
  56.  
  57. /*
  58.   3. Reescriba el método Pregunta.GetHashCode().
  59.   Este método debe devolver el mismo valor para
  60.   dos objetos Pregunta iguales. Reescriba el método Pregunta.Equals(o?),
  61.   teniendo en cuenta que se considerarán el enunciado,
  62.   el número de respuesta correcta, y todas las respuestas,
  63.   tanto en número como contenido.
  64.   */
  65. public override int GetHashCode()
  66. {
  67. return this.Enunciado.GetHashCode()
  68. + 11 * this.Respuestas.Select( x => x.GetHashCode() ).Sum()
  69. + 13 * this.NumCorrecta.GetHashCode();
  70. }
  71.  
  72. public int Count => this._respuestas.Count;
  73.  
  74. /*
  75.   2. Cree el indexer para acceder a los respuestas como una lista en Pregunta.
  76.   Cree el indexer para acceder a las preguntas como una lista en Examen.
  77.   */
  78. public string this[int i] {
  79. get {
  80. if ( i < 0
  81. || i >= this.Count )
  82. {
  83. throw new ArgumentOutOfRangeException( i + "??" );
  84. }
  85.  
  86. return this._respuestas[ i ];
  87. }
  88. }
  89.  
  90. public override bool Equals(object? o)
  91. {
  92. bool toret = false;
  93.  
  94. if (o is Pregunta otro) {
  95. if ( otro.Enunciado == this.Enunciado
  96. && otro.NumCorrecta == this.NumCorrecta
  97. && otro.Count == this.Count )
  98. {
  99. toret = true;
  100.  
  101. if ( !ReferenceEquals( this, otro ) ) {
  102. for(int i = 0; i < otro.Count; ++i) {
  103. if ( this[ i ] != otro[ i ] ) {
  104. toret = false;
  105. }
  106. }
  107. }
  108. }
  109. }
  110.  
  111. return toret;
  112. }
  113.  
  114. public override string ToString()
  115. {
  116. return $"{this.Enunciado}"
  117. + $"\n\n{string.Join('\n', this.Respuestas)}"
  118. + $"\n\nCorrecta: {this.NumCorrecta}";
  119. }
  120.  
  121. private IList<string> _respuestas;
  122. }
  123.  
  124.  
  125. public class Examen {
  126. public Examen()
  127. {
  128. this._preguntas = new List<Pregunta>();
  129. }
  130.  
  131. public /*required*/ string Nombre { get; init; } = "";
  132.  
  133. public IList<Pregunta> Preguntas {
  134. get => ( (List<Pregunta>) this._preguntas ).AsReadOnly();
  135. init {
  136. foreach(var p in value) {
  137. this._preguntas.Add( p );
  138. }
  139. }
  140. }
  141.  
  142. public void Inserta(Pregunta p)
  143. {
  144. this._preguntas.Add( p );
  145. }
  146.  
  147. public int Count => this._preguntas.Count;
  148.  
  149. /*
  150.   2. Cree el indexer para acceder a los respuestas como una lista en Pregunta.
  151.   Cree el indexer para acceder a las preguntas como una lista en Examen.
  152.   */
  153. public Pregunta this[int i] {
  154. get {
  155. if ( i < 0
  156. || i >= this.Count )
  157. {
  158. throw new ArgumentOutOfRangeException( i + "??" );
  159. }
  160.  
  161. return this._preguntas[ i ];
  162. }
  163. }
  164.  
  165. public override string ToString()
  166. {
  167. return this.Nombre + "\n\n" + string.Join( "\n\n", this.Preguntas );
  168. }
  169.  
  170. /*
  171.   5. Para un Examen t debe existir la posibilidad de añadir un Pregunta.
  172.   Sobrecargue el operador ‘+’ de forma que dado t,
  173.   sea posible ejecutar una operación como t + p,
  174.   siendo p un objeto Pregunta
  175.   (nótese que un operador devuelve un nuevo objeto).
  176.   */
  177. public static Examen operator+(Examen t, Pregunta p)
  178. {
  179. var toret = new Examen{ Nombre = t.Nombre };
  180.  
  181. foreach(var p2 in t.Preguntas) {
  182. toret.Inserta( p2 );
  183. }
  184.  
  185. toret.Inserta( p );
  186. return toret;
  187. }
  188.  
  189. private IList<Pregunta> _preguntas;
  190. }
  191.  
  192.  
  193. /*
  194. Cree la clase JsonPregunta. Tendrá una propiedad de solo lectura Pregunta,
  195. que se inicializará en el momento de la creación.
  196. El método ToJson(): string, serializa el objeto en la propiedad Pregunta
  197. en una cadena de caracteres. El método Save(nf: string),
  198. utilizando el método ToXml(), crea un archivo de texto con el nombre nf y el contenido JSON generado. El método estático FromJson(txtJson: string): Examen? Crea un objeto Examen a partir de la cadena de caracteres pasado por parámetro. El método estático Load(nf: string): Examen?, utilizando FromJson(), leerá un archivo de texto y devolverá el objeto Examen serializado en él.
  199. */
  200. public class JsonExamen {
  201. public /*required*/ Examen Examen { get; init; }
  202.  
  203. public string ToJson()
  204. {
  205. return JsonSerializer.Serialize( this.Examen );
  206. }
  207.  
  208. public void Save(string nf)
  209. {
  210. File.WriteAllTextAsync( nf, this.ToJson() );
  211. }
  212.  
  213. public static Examen? Load(string nf)
  214. {
  215. return FromJson( File.ReadAllText( nf ) );
  216. }
  217.  
  218. public static Examen? FromJson(string txtJson)
  219. {
  220. return JsonSerializer.Deserialize<Examen>( txtJson );
  221. }
  222. }
  223.  
  224.  
  225. static class Ppal {
  226. static void Main()
  227. {
  228. var t = new Examen {
  229. Nombre = "Parcial 2",
  230. Preguntas = new Pregunta[] {
  231. new Pregunta{ Enunciado = "¿Crees que vas a aprobar el examen?",
  232. Respuestas = new List<string>( new string[] {
  233. "Sí", "No", "Quizás" }),
  234. NumCorrecta = 2 },
  235. new Pregunta{ Enunciado = "¿Cuál es la pregunta más difícil?",
  236. Respuestas = new List<string>( new string[] {
  237. "La 1", "La 2", "La 3",
  238. "Todas son fáciles",
  239. "Todas son difíciles" }),
  240. NumCorrecta = 3 },
  241. }};
  242.  
  243. t.Inserta(
  244. new Pregunta{ Enunciado = "¿Es lo mismo una propiedad que un atributo?",
  245. Respuestas = new List<string>( new string[] {
  246. "Sí", "No", "Quizás", "Ni idea",
  247. "Todas son correctas" }),
  248. NumCorrecta = 1 });
  249.  
  250. t += new Pregunta{ Enunciado =
  251. "¿Puedo devolver una lista como resultado de un método?",
  252. Respuestas = new List<string>( new string[] {
  253. "Sí", "No",
  254. "Mejor si la duplicas antes",
  255. "Mejor si la devuelvas con .AsReadOnly()",
  256. "Todas son incorrectas" }),
  257. NumCorrecta = 0 };
  258.  
  259. new JsonExamen{ Examen = t }.Save( "examen.json" );
  260. Console.WriteLine( JsonExamen.Load( "examen.json" ) );
  261. }
  262. }
  263.  
  264.  
  265. // Código de tests ----------------------------------------
  266.  
  267. // Clases necesarias para que compilen los Tests en IDEOne.
  268. class TestFixture: Attribute {}
  269. class Test: Attribute {}
  270. class SetUp: Attribute {}
  271. class Assert {
  272. public static void That(object o1, object o2)
  273. {}
  274. }
  275.  
  276. class Is {
  277. public static object EqualTo(object o)
  278. { return o; }
  279. }
  280.  
  281.  
  282. [TestFixture]
  283. public class TestProject {
  284. [SetUp]
  285. public void SetUp()
  286. {
  287. this._enunciadoP1 = "Pregunta tensa";
  288. this._p1 = new Pregunta{ Enunciado = this._enunciadoP1,
  289. NumCorrecta = 0 };
  290. this._respuestas = new string[] { "Sí", "No", "Quizás" };
  291. }
  292.  
  293. [Test]
  294. public void TestCreacion()
  295. {
  296. Assert.That( this._p1.Enunciado, Is.EqualTo( this._enunciadoP1 ) );
  297. Assert.That( 0, Is.EqualTo( this._p1.NumCorrecta ) );
  298. Assert.That( 0, Is.EqualTo( this._p1.Count ) );
  299. }
  300.  
  301. private void AddRespuestas(Pregunta p, string[] resps)
  302. {
  303. foreach(var r in resps) {
  304. p.Inserta( r );
  305. }
  306. }
  307.  
  308. [Test]
  309. public void TestAddRespuestas()
  310. {
  311. int numResps = this._respuestas.Length;
  312.  
  313. this.AddRespuestas( this._p1, this._respuestas );
  314.  
  315. IList<string> resps = this._p1.Respuestas;
  316. Assert.That( numResps, Is.EqualTo( this._p1.Count ) );
  317.  
  318. for(int i = 0; i < numResps; ++i) {
  319. Assert.That( this._respuestas[ i ], Is.EqualTo( this._p1[ i ] ) );
  320. Assert.That( this._respuestas[ i ], Is.EqualTo( resps[ i ] ) );
  321. }
  322. }
  323.  
  324. private string BuildToString(Pregunta p)
  325. {
  326. return this._p1.Enunciado
  327. + "\n\n" + string.Join( '\n', this._p1.Respuestas )
  328. + "\n\nCorrecta: " + this._p1.NumCorrecta;
  329. }
  330.  
  331. [Test]
  332. public void TestToString()
  333. {
  334. Assert.That( this.BuildToString( this._p1 ),
  335. Is.EqualTo( this._p1.ToString() ) );
  336.  
  337. this.AddRespuestas( this._p1, this._respuestas );
  338.  
  339. Assert.That( this.BuildToString( this._p1 ),
  340. Is.EqualTo( this._p1.ToString() ) );
  341. }
  342.  
  343. private Pregunta _p1;
  344. private string _enunciadoP1;
  345. private string[] _respuestas;
  346. }
  347.  
  348.  
  349. [TestFixture]
  350. public class TestExamen {
  351. [SetUp]
  352. public void SetUp()
  353. {
  354. this._nombre = "Parcial 2";
  355. this._examen = new Examen { Nombre = this._nombre };
  356. this._preguntas = new Pregunta[] {
  357. new Pregunta { Enunciado = "Pregunta Tensa",
  358. Respuestas = new string[] { "Sí", "No", "Quizás" },
  359. NumCorrecta = 0 },
  360.  
  361. };
  362. }
  363.  
  364. [Test]
  365. public void TestCreacion()
  366. {
  367. Assert.That( this._nombre, Is.EqualTo( this._examen.Nombre ) );
  368. Assert.That( 0, Is.EqualTo( this._examen.Count ) );
  369. }
  370.  
  371. [Test]
  372. public void TestAddPreguntas()
  373. {
  374. Assert.That( 0, Is.EqualTo( this._examen.Count ) );
  375.  
  376. this.AddPreguntas( this._examen, this._preguntas );
  377.  
  378. IList<Pregunta> pregs = this._examen.Preguntas;
  379. Assert.That( this._preguntas.Length, Is.EqualTo( this._examen.Count ) );
  380. Assert.That( this._preguntas.Length, Is.EqualTo( pregs.Count ) );
  381.  
  382. for(int i = 0; i < this._preguntas.Length; ++i) {
  383. Assert.That( this._examen[ i ], Is.EqualTo( this._preguntas[ i ] ) );
  384. Assert.That( this._examen[ i ], Is.EqualTo( pregs[ i ] ) );
  385. }
  386. }
  387.  
  388. private string BuildToString(Examen t)
  389. {
  390. return t.Nombre + "\n\n" + string.Join( "\n\n", t.Preguntas );
  391. }
  392.  
  393. private void AddPreguntas(Examen t, Pregunta[] ps)
  394. {
  395. foreach(var p in ps) {
  396. t.Inserta( p );
  397. }
  398. }
  399.  
  400. [Test]
  401. public void TestToString()
  402. {
  403. Assert.That( this.BuildToString( this._examen ),
  404. Is.EqualTo( this._examen.ToString() ) );
  405.  
  406. this.AddPreguntas( this._examen, this._preguntas );
  407.  
  408. Assert.That( this.BuildToString( this._examen ),
  409. Is.EqualTo( this._examen.ToString() ) );
  410. }
  411.  
  412. private string _nombre;
  413. private Examen _examen;
  414. private Pregunta[] _preguntas;
  415. }
  416.  
  417.  
Success #stdin #stdout 0.13s 34840KB
stdin
Standard input is empty
stdout
Parcial 2

¿Crees que vas a aprobar el examen?

Sí
No
Quizás

Correcta: 2

¿Cuál es la pregunta más difícil?

La 1
La 2
La 3
Todas son fáciles
Todas son difíciles

Correcta: 3

¿Es lo mismo una propiedad que un atributo?

Sí
No
Quizás
Ni idea
Todas son correctas

Correcta: 1

¿Puedo devolver una lista como resultado de un método?

Sí
No
Mejor si la duplicas antes
Mejor si la devuelvas con .AsReadOnly()
Todas son incorrectas

Correcta: 0