Universidad de Costa Rica
Escuela de Ciencias de la
Computación e Informática
Profesor Adolfo Di Mare
CI-1201
II Semestre 2002
[<=] [home] [<>] [\/] [=>]
CI-1201 Programación II

Tarea #4 [solución]

Datos de prueba para la lista circular

 L->last ───────────────────────────────────────┐
                                                │
┌────────────┐   ┌────────────┐   ┌───────────┐ │
│            v   │            v   │           v v
│ ┌────────┬───┐ │ ┌────────┬───┐ │ ┌────────┬───┐
│ │ elem_1 │ ├─┼─┘ │ elem_2 │ ├─┼─┘ │ elem_3 │ ├─┼─┐
│ └────────┴───┘   └────────┴───┘   └────────┴───┘ │
│            ^               next              ^   │
│            │                                 │   │
│          first                             last  v
└───────<───────────────<────────────────<─────────┘
Figura 1: Lista circular, con puntero al último nodo

      Determine los casos de prueba para la lista circular que usted implementó en la tarea anterior. Luego, determine los datos de prueba, y haga un programa para determinar si los métodos de la clase lista están correctamente implementados. En su documentación explique cómo y por qué obtuvo cada caso de prueba, y cada dato de prueba, tanto los de caja blanca como en caja negra.

Myers, Glenford
"The Art of Software Testing"; John Wiley & Sons; 1978.

{ PbRevLst.pas (c) 2002 adolfo@di-mare.com }

{ RESULTADO
Les adjunto un pedazo de programa llamado PbRevLst.pas que
contiene varios procedimientos que pueden ayudarles a hacer los
datos de prueba para la tarea programada.

Test_Reverse() es el procedimiento principal, en donde están los
datos de prueba en formato (E|S). Para que funcione, necesita de
List_Assign(), que permite asignarle el valor a un a lista a
partir de una hilera.

Yo programé List_Assign() usando un truco de Pascal; me imagino
que para sacar los valores ustedes preferirán usar una hilera, de
tipo char*. Por eso, no se fijen mucho en la forma en que está
implementado List_Assign().

Por último, Check_Equal() verifica que las dos listas que recibe
sean iguales. Para facilitarles un poco el trabajo, les incluyo la
implementación de la operación de comparación de listas en Pascal,
llamada Equal().

Les indico, eso sí, que este código NO compila en Pascal, pues lo
armé pegando pedazos de programas diferentes. Se los adjunto para
facilitarles el trabajo. }

PROCEDURE Test_Reverse;
{ RESULTADO
  Prueba la operación List.Reverse().
  - Para esto usa al procedimiento List_Assign() para
    generar varios casos de prueba a partir de hileras
    que contienen los valores que debe estar
    almacenados en la lista después de cada invocación
    a List.Reverse(). }

VAR
  L : Tlist;

BEGIN { Test_Reverse }
  L.Init;

  List_Assign(L, '()');
  L.Reverse;
  Check_Equal(L, '()');

  List_Assign(L, '( a)');
  L.Reverse;
  Check_Equal(L, '( a)');

  List_Assign(L, '( a b)');
  L.Reverse;
  Check_Equal(L, '( b a)');

  List_Assign(L, '( a b c)');
  L.Reverse;
  Check_Equal(L, '( c b a)');

  List_Assign(L, '( a b c d)');
  L.Reverse;
  Check_Equal(L, '( d c b a)');

  List_Assign(L, '( a b c d e)');
  L.Reverse;
  Check_Equal(L, '( e d c b a)');

  L.Done;
END;  { Test_Reverse }

PROCEDURE List_Assign(
  {?} VAR L : TList;     { SELF }
  {+}     s : STRING     { valor a asignar a L }
);
{ RESULTADO
  Toma el valor que está almacenado en la hilera "s",
  y lo almancena como contenido de la lista "L".
  - Se presume que "s" es una hilera que fue obtenida
    leyendo un archivo de texto escrito por medio de
    L.Print(). }
VAR
  F : TEXT;
BEGIN { List_Assign }
  StrTEXT.AssignStr(F, s);
  Reset(F);
  Read_List(L, F);
END;  { List_Assign }

PROCEDURE Check_Equal(
  {?} VAR L : TList;     { SELF }
  {+}     s : STRING     { valor a asignar a L }
);
{ RESULTADO
  Verifica que el valor de "L" sea el que aparece como
  valor en la hilera "s".
  - Utiliza a List_Assign() para obtener el valor de
    la lista que representa "s".
  - List_Assign(L, '( a b)'); resulta en que la lista "L" tiene
    queda como una lista de 2 elementos, con valores "a" y "b".
  - List_Assign(L, '()'); deja en "L" la lista nula. }
VAR
  LL: TList;
BEGIN { Check_Equal }
  LL.Init;

  List_Assign(LL, s);

  IF NOT L.OK THEN BEGIN
    WriteLn('Check_Equal(FALSE) ==> NOT L.OK');
  END;

  IF NOT LL.OK THEN BEGIN
    WriteLn('Check_Equal(FALSE) ==> NOT LL.OK');
  END;

  IF NOT Equal(LL,L) OR NOT Equal(L,LL) THEN BEGIN
    WriteLn('Check_Equal(FALSE)');
    Write('  L  = '); L.Print(OUTPUT);    WriteLn;
    Write('  LL = '); LL.Print(OUTPUT);
    HALT;
  END;

  LL.Done;
END;  { Check_Equal }

FUNCTION  Equal(         { EXPORT }     { ADH }
  {+} VAR x : TList;     { SELF }
  {+} VAR y : TList      { listas a comparar }
) {>>>>>>>} : BOOLEAN;
{ RESULTADO
  Devuelve TRUE si "x = y" y FALSE en otro caso.
  - dos listas son iguales si tienen a los
    mismos elementos y estos aparecen en cada
    lista en el mismo orden. }
VAR
  p,q : PNode;
BEGIN { Equal }
  IF x._last = y._last THEN BEGIN
    RETURN TRUE; { Son la misma lista }
  END;           { o las dos están vacías }

  IF (x._last = NIL) OR (y._last = NIL)
  THEN BEGIN
    { evita dereferenciar NIL cuando SOLO }
    { una de las listas está vacía        }
    RETURN FALSE;
  END;

  { Compara todos los elementos }
  p := x._last;
  q := y._last;
  REPEAT
    p := p^.next;
    q := q^.next;
    IF p^._val <> q^._val THEN BEGIN
      RETURN FALSE;
    END;
  UNTIL  (p = x._last) OR  (q = y._last);

  RETURN (p = x._last) AND (q = y._last);
END;  { Equal }

PROCEDURE Read_List(     { LOCAL }     { ADH }
  {+} VAR L : TList;     { SELF }
  {?} VAR F : TEXT       { archivo de trabajo }
);
{ RESULTADO
  Lee los elementos de la lista. Se usa una sencilla notación
  de lista. El valor impreso se ve así:
    []
    [ a b c]
    [ 1  2  3  4]              }
VAR
  e : T;
  ch: CHAR;
  _done: BOOLEAN;
BEGIN { Read_List }

  e.Init();

  System.Read(F, ch);    { lee el primer '(' }

  _done := FALSE;
  WHILE NOT _done DO BEGIN
    System.Read(F, ch);   { lee el delimitador }
    CASE ch OF
      ')' : _done := TRUE;
      ']' : _done := TRUE;
      ' ' : System.Read(e, F); L.Push_Back(e);
    END;
  END;

  e.Done();
END;  { Read_List }

{ EOF: PbRevLst.pas }
Figura 1:

      Entregue su tarea por correo electrónico, como lo hizo anteriormente.

[mailto:] Entrega de Tareas

Tiempo de entrega: 1 semana
Modalidad: Individual

Soluciones

[mailto:] Adolfo Di Mare <adolfo@di-mare.com>.
Copyright © 2002
Derechos de autor reservados © 2002
[home] <> [/\]