Code Review: App Interfaces

https://www.codecademy.com/courses/learn-c-sharp/projects/csharp-app-interfaces

I’m unsure if I have completed the first 12 steps correctly. Was hoping someone can skim over my code and tell me if I completed all steps correctly. One thing that concerns me is what the console looks like in the screenshot versus what step 13 shows.

Todos
--------
Eat
Sleep
Code

Password
-----------
***

Program.cs

using System;

namespace SavingInterface
{
  class Program
  {
    static void Main(string[] args)
    {
      TodoList tdl = new TodoList();
      tdl.Add("Invite friends");
      tdl.Add("Buy decorations");
      tdl.Add("Party");

      PasswordManager pm = new PasswordManager("iluvpie", true);
      
      //Make sure that both classes are printable, call Display() on tdl and pm.
      //tdl.Display();
      //pm.Display();
      //Call Reset() and Display() with tdl and pm. In other words, both objects should display, then reset, then display again.
      tdl.Display();
      tdl.Reset();
      tdl.Display();

      pm.Display();
      pm.Reset();
      pm.Display();
    }
  }
}

TodoList.cs

using System;

namespace SavingInterface
{
  class TodoList : IDisplayable, IResetable
  {
    public string[] Todos
    { get; private set; }

    private int nextOpenIndex;

    public TodoList()
    {
      Todos = new string[5];
      nextOpenIndex = 0;
    }

    public void Add(string todo)
    {
      Todos[nextOpenIndex] = todo;
      nextOpenIndex++;
    }
    //Define a method that satisfies the interface requirements
    public void Display()
    {
      foreach (string s in Todos)
      Console.WriteLine(s);
    }
    
    //Define a method to satisfy the interface.
    public void Reset()
    {
      Todos = new string[5];
      nextOpenIndex = 0;    
    }
  }
}

PasswordManager.cs

using System;

namespace SavingInterface
{
  class PasswordManager : IDisplayable, IResetable
  {
    private string Password
    { get; set; }

    public bool Hidden
    { get; private set; }

    public PasswordManager(string password, bool hidden)
    {
      Password = password;
      Hidden = hidden;
    }
    
    //Define a method that satisfies the interface requirements
    public void Display()
    {
      if (Hidden)
      {
        Console.WriteLine("*****");
      }
      else
      {
      Console.WriteLine(Password);
      }
    }
    //Define a method to satisfy the interface.
    public void Reset()
    {
      Password = "";
      Hidden = false;    
    }
  }
}

IDisplayable.cs

// Define IDisplayable in this file

using System;

namespace SavingInterface
{
  interface IDisplayable
  {
    //Within IDisplayable declare one method that returns nothing
    void Display();
  }
}

IResetable.cs

// Define IResetable in this file

using System;

namespace SavingInterface
{
  interface IResetable
  {
    //define an interface with one method it should return nothing
    void Reset();
  }
}

Bumping, hoping someone will reply.

No one at all has any idea with c#?

Hi @psmilliorn! I’m a Senior Curriculum Developer and I wrote this project. Super cool to see it be a part of your learning journey!

Your code fulfills steps 1-12. In fact it looks very similar to the solution code I originally intended :grin:

Your output doesn’t look like the output in step 13 because you haven’t done the extensions. You’ll get the output shown in step 13 once you finish the first extension given (the one about HeaderSymbol and extending the Display() method).

Hope that helps! Happy to clarify anything if you have more questions.

1 Like

Thank you for responding! Yes that does clarify my concerns up to step 13. I haven’t done step 13. I know I will be needing help with it when I get back to it since I recall not grasping what it is asking. But its been a few days so maybe it will make more sense when I revisit it. Hopefully you will be OK with me pinging you again for step 13 if I get stuck.

Absolutely!

Normally we would have a project walkthrough video ready for you, but it’s in production now.

I’m unsure how this is meant to be implemented. I get how to set it in IDisplayable.cs but not sure how the lesson wants to do the following.

Add a get-only property to IDisplayable called HeaderSymbol . This should be used in Display() as a header. For example, if the header symbol is - , then the apps should be displayed as:

Todos
--------
Eat
Sleep
Code

Password
-----------
***

Currently (if I comment out HeaderSymbol) my console looks like this.

Hey @psmilliorn sorry for the delayed response! It looks like you’re having a StackOverflowException, which may be a separate issue. Send me the Program.cs and PasswordManager.cs code and we can debug that first before getting into HeaderSymbol.

@nduckwiler

Program.cs

using System;

namespace SavingInterface
{
  class Program
  {
    static void Main(string[] args)
    {
      TodoList tdl = new TodoList();
      tdl.Add("Invite friends");
      tdl.Add("Buy decorations");
      tdl.Add("Party");

      PasswordManager pm = new PasswordManager("iluvpie", true);
      
      //Make sure that both classes are printable, call Display() on tdl and pm.
      //Call Reset() and Display() with tdl and pm. In other words, both objects should display, then reset, then display again.
      tdl.Display();
      tdl.Reset();
      tdl.Display();

      pm.Display();
      pm.Reset();
      pm.Display();
    }
  }
}

PasswordManager.cs

using System;

namespace SavingInterface
{
  class PasswordManager : IDisplayable, IResetable
  {
    private string Password
    { 
      get 
      { 
        return Password; 
      }
      set 
      {
        if (value.Length >= 8)
        {
          Password = value;
        }
      }
    }

    public bool Hidden
    { get; private set; }

    public PasswordManager(string password, bool hidden)
    {
      Password = password;
      Hidden = hidden;
    }
    //Define a method that satisfies the interface requirements
    public void Display()
    {
      if (Hidden)
      {
        Console.WriteLine("*****");
      }
      else
      {
      Console.WriteLine(Password);
      }
    }
    //Define a method to satisfy the interface.
    public void Reset()
    {
      Password = "";
      Hidden = false;    
    }
    //Add a method ChangePassword()
    public bool ChangePassword(string oldPass, string newPass)
    {
      return oldPass == newPass;
    }
  }
}

@psmilliorn Looks like the issue is in PasswordManager.cs. You are creating a property Password that tries to return the property Password. This creates a StackOverflowException - it’s sort of like an infinite loop but with method calls.

You’ll need to define a separate field and make the property Password set and get that field.

OK, so I believe I have cleared that up. I wanted to make sure that before we revisit…

Add a get-only property to IDisplayable called HeaderSymbol . This should be used in Display() as a header. For example, if the header symbol is - , then the apps should be displayed as:

…that the rest of step 13 is completed.

If you add more than five to-dos to the TodoList , it throws an error! Extend the Add() method so that it doesn’t add any more than five items to the Todos array.

I’m skeptical if I did this correctly based on output in console.

Currently a blank line is printed for each empty index in Todos . Change Display() in TodoList so that it prints [] instead of a blank line

Pretty sure that was done correctly.

Add a method ChangePassword() to PasswordManager .

Done.

Extend the Password property in PasswordManager

Unsure if this was correct.

Here is the following code changes.

TodoList.cs

using System;

namespace SavingInterface
{
  class TodoList : IDisplayable, IResetable
  {
    public string[] Todos { get; private set; }

    private int nextOpenIndex;

    public TodoList()
    {
      Todos = new string[5];
      nextOpenIndex = 0;
    }

    public void Add(string todo)
    {
      if (Todos.Length <= 5)
      {
        Todos[nextOpenIndex] = todo;
        nextOpenIndex++;
      }
    }
    //Define a method that satisfies the interface requirements
    public void Display()
    {
      foreach (string s in Todos)
      {
        if (String.IsNullOrEmpty(s))
        {
          //prints [] instead of a blank line.
          Console.WriteLine("[]");
        }
        else 
        {
          Console.WriteLine(s);
        }
      }
    }
    //Define a method to satisfy the interface.
    public void Reset()
    {
      Todos = new string[5];
      nextOpenIndex = 0;    
    }
  }
}

PasswordManager.cs

using System;

namespace SavingInterface
{
  class PasswordManager : IDisplayable, IResetable
  {
    string password;
    private string Password
    { 
      get 
      { 
        return password; 
      }
      set 
      {
        if (value.Length >= 8)
        {
          password = value;
        }
      }
    }

    public bool Hidden { get; private set; }

    public PasswordManager(string password, bool hidden)
    {
      Password = password;
      Hidden = hidden;
    }
    //Define a method that satisfies the interface requirements
    public void Display()
    {
      if (Hidden)
      {
        Console.WriteLine("*****");
      }
      else
      {
      Console.WriteLine(Password);
      }
    }
    //Define a method to satisfy the interface.
    public void Reset()
    {
      Password = "";
      Hidden = false;    
    }
    //Add a method ChangePassword() with two string parameters
    public bool ChangePassword(string oldPass, string newPass)
    {
      //if the first argument matches Password
      if (oldPass == Password)
      {
        //Reset Password to second argument
        Password = newPass;
      }
      //return true if password change success(first argument matched old password)
      return oldPass == newPass;
    }
  }
}

Thank you for all your help so far :smile:

@psmilliorn nice work so far! The short answer is: yes, you did both of those extensions in question. More detail below:

If you add more than five to-dos to the TodoList , it throws an error! Extend the Add() method so that it doesn’t add any more than five items to the Todos array.

You did this by adding the line:
if (Todos.Length <= 5)

Extend the Password property in PasswordManager

Technically you completed this too. Although, I would recommend setting password to a default value for if the input value is less than 8. This involves adding an else statement in your set method.

1 Like