...

View Full Version : Input month name output number of days



tyu4
04-02-2012, 05:47 PM
I'm completely lost with this assignment code.
I'm trying to modify this program that asks the user for an input 1-12 for a calendar month, and it outputs the number of days in that month.
I want to modify this so that the user inputs the name of the month instead of the value, and the program outputs the number of days.
I also have to incorporate lines that asks the user to reenter the month if it is not a valid month, and to reenter the year if if the year is < 0 (negative).
I think the obvious method to tackle this code is to create a string array and search the list for the position in the array. Then use that position for the switch statement. But after hours of trying to crack this I've had no luck.
Thank you.


import jpb.*;

public class MonthLength1 {
public static void main (String[] args) {
String[] monthName = new String [] {"", "January", "February", "March", "April", "May", "June", "July",
"August", "September", "October", "November", "December"};
SimpleIO.prompt ("Enter the name of the month : ");
String userInput = SimpleIO.readLine ();
int month = Integer.parseInt (userInput);

if (month < 1 || month > 12) {
System.out.println ("Month must be between 1 and 12");
return;

SimpleIO.prompt ("Enter a year: ");
userInput = SimpleIO.readLine ();
int year = Integer.parseInt (userInput);
if (year < 0) {
System.out.println ("Year cannot be negative; try again.");
return;
}


int numberOfDays;
switch (month) {
case 2: // February
numberOfDays = 28;
if (year % 4 == 0) {
numberOfDays = 29;
if (year % 100 == 0 && year % 400 != 0)
numberOfDays = 28;
}
break;

case 4:
case 6:
case 9:
case 11:
numberOfDays = 30;
break;
default: numberOfDays = 31;
break;
}

System.out.println ("There are " + numberOfDays + " days in this month");
}
}

Fou-Lu
04-02-2012, 07:35 PM
The easiest way would be to implement a hashtable for your lookup.
I haven't a clue what SimpleIO does since its a custom class, but according to this you are simply asking for input and casting it to an integer. That's no good on a month entry of course as casting January to a number will fail.

That has to be compared against for a valid entry. Which is why I'd use a hashtable for simplicity:



Hashtable<String, Integer> htMonths = new Hashtable<String, Integer>();
htMonths.put("january", 1);
htMonths.put("february", 2);
//...
String sInput = "";
Integer iMonth = null;
do
{
SimpleIO.prompt ("Enter the name of the month : ");
sInput = SimpleIO.readline(); // assuming no linefeed as well.
if ((iMonth = htMonths.get(sInput.toLowerCase())) == null)
{
System.out.println("Invalid month, try again.");
}
} while (iMonth == null);


Whether you use an array check or a hashtable or whatever, always force it to lower case (or upper if you choose upper case, it doesn't matter). That way you don't need to concern yourself with entry like "JaNuaRy".

For using an array, I'd use Arrays.binarySearch to look for something. It will return the key if its found or a negative number of not. Otherwise, standard iteration and comparison.

tyu4
04-02-2012, 07:44 PM
The hashtable idea does look much much simpler than arrays.
Unfortunately I have not had the chance to read up on hashtables, so I have no idea how they work.
Which is why I decided to use a string array.
My complication was just that, casting a month like January to a number.
Is there a way to prompt the user for an input and search the list for the given month's position in the array, and use that position's value for the rest of the program?

Fou-Lu
04-02-2012, 07:51 PM
Yeah, you use Arrays.binarySearch to lookup a value from an array. It returns >= 0 if it exists in the list. I'd suggest making it lowercase so that the case match is irrelevant, or write a custom comparator to do so during the comparison.
While its not >= 0, the entered value isn't valid.
The alternative is a simple loop for the array. If it makes it to the end and doesn't find a valid index, then the month isn't valid.


Wait, in hindsight that won't work. Binary searches require sorted arrays.
You'll need to iterate it yourself and compare.

alykins
04-02-2012, 07:53 PM
I would use Fou-Lu's way- but I didn't think of it at first... here is a modification of what you have (I will leave it on you to translate)



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DaysDemo
{
class _DaysDemo
{
private string[] mo = new string[12]{"Jan", "Feb", "March","Apr","May","June","July","Aug","Sept","Oct","Nov","Dec"};

private enum Selector
{
Month,
Year,
_Throw
}

private bool[] done = new bool[2] {false, false};

private int[] days = new int[4] {28,29,30,31};

static void Main(string[] args)
{
_DaysDemo d = new _DaysDemo();
d.Demo();
Console.WriteLine("Fin...");
Console.ReadLine();
}

private void Demo()
{
int Month = 0;
int Year = 0;

while (!done[0])
{
while (!done[1])
{
Console.WriteLine("Enter month:");
try
{
Month = getInt(Selector.Month);
}
catch (Exception)
{
Console.WriteLine("Invalid Month!");
}
}

done[1] = false;

while (!done[1])
{
Console.WriteLine("Enter Year:");
try
{
Year = getInt(Selector.Year);
}
catch (Exception)
{
Console.WriteLine("Invalid Year!");
}
}
if ((Month != 0) && (Year > 0))
done[0] = determineDays(Month, Year);
else
{
throw new Exception();
}

}
}

private int getInt(Selector s)
{
int i;
switch (s)
{
case Selector.Month:
i = int.Parse(Console.ReadLine());
if (i < 1 || i > 12)
throw new Exception();
done[1] = true;
return i;
case Selector.Year:
i = int.Parse(Console.ReadLine());
if (i < 0)
throw new Exception();
done[1] = true;
return i;
case Selector._Throw:
throw new Exception();
}
return getInt(Selector._Throw);
}

private bool determineDays(int m, int y)
{
int Days = 0;
switch (m-1)
{
case 0:
case 2:
case 4:
case 6:
case 7:
case 9:
case 11:
Days = 31;
break;
case 3:
case 5:
case 8:
case 10:
Days = 30;
break;
case 1:
switch(y % 4)
{
case 0:
Days = 29;
break;
default:
Days = 28;
break;
}
break;
}

if (Days == 0)
{
Console.WriteLine("Error in program...");
return false;
}
else
{
Console.WriteLine("Month entered was {0}", mo[m - 1]);
Console.WriteLine("This month has {0} days!", Days);
return true;
}
}

}
}


or implement Fou-Lu's methodology (I felt you are/were clode enough to give a working solution- Note that is C#... only a little bit of translation for you to do)

tyu4
04-02-2012, 08:09 PM
So I went ahead and threw in my modifications based on the generous input I've been receiving. I hope I'm on the right track!
I'm getting an error for this line:


if (monthName[month].equals(userInput.toLowerCase)) {
break;
>>>>>> else {
System.out.println ("Illegal month name; try again.");
return;
}
}
'else' without 'if'

I must be missing something because I see the if statement directly above the else.
Thanks again!


import jpb.*;

public class MonthLength1 {
public static void main (String[] args) {
String[] monthName = new String [] {"", "january", "february", "march", "april", "may", "june", "july",
"august", "september", "october", "november", "december"};
int month = 0;
SimpleIO.prompt ("Enter a month name: ");
String userInput = SimpleIO.readLine (). trim ();
for (month = 0; month < monthName.length; month++) {
if (monthName[month].equals(userInput.toLowerCase)) {
break;
else {
System.out.println ("Illegal month name; try again.");
return;
}
}
}

SimpleIO.prompt ("Enter a year: ");
userInput = SimpleIO.readLine ();
int year = Integer.parseInt (userInput);
if (year < 0) {
System.out.println ("Year cannot be negative; try again.");
return;
}


int numberOfDays;
switch (month) {
case 2: // February
numberOfDays = 28;
if (year % 4 == 0) {
numberOfDays = 29;
if (year % 100 == 0 && year % 400 != 0)
numberOfDays = 28;
}
break;

case 4:
case 6:
case 9:
case 11:
numberOfDays = 30;
break;
default: numberOfDays = 31;
break;
}

System.out.println ("There are " + numberOfDays + " days in this month");
}
}

My second modification:
I added an extra if statement in order to test whether or not the user's input was a valid input.
The first trial if statement inside the for loop would keep printing out "Illegal month name; try again." I'm assuming.
I have yet to test this because I'm still getting the 'else' without 'if' error.

import jpb.*;

public class MonthLength1 {
public static void main (String[] args) {
String[] monthName = new String [] {"", "january", "february", "march", "april", "may", "june", "july",
"august", "september", "october", "november", "december"};
int month = 0;
SimpleIO.prompt ("Enter a month name: ");
String userInput = SimpleIO.readLine (). trim ();
for (month = 0; month < monthName.length; month++) {
if (monthName[month].equals(userInput.toLowerCase)) {
break;
}
if (month < monthName.length) {
break;
else {
System.out.println ("Illegal month name; try again.");
return;
}
}
}

SimpleIO.prompt ("Enter a year: ");
userInput = SimpleIO.readLine ();
int year = Integer.parseInt (userInput);
if (year < 0) {
System.out.println ("Year cannot be negative; try again.");
return;
}


int numberOfDays;
switch (month) {
case 2: // February
numberOfDays = 28;
if (year % 4 == 0) {
numberOfDays = 29;
if (year % 100 == 0 && year % 400 != 0)
numberOfDays = 28;
}
break;

case 4:
case 6:
case 9:
case 11:
numberOfDays = 30;
break;
default: numberOfDays = 31;
break;
}

System.out.println ("There are " + numberOfDays + " days in this month");
}
}

alykins
04-02-2012, 08:41 PM
just remove the else and the {} that go with it- it's redundant

o wait! actually you are missing a }



for (month = 0; month < monthName.length; month++) {
if (monthName[month].equals(userInput.toLowerCase)) {
break;
} // I am missing!!!!!
else {
System.out.println ("Illegal month name; try again.");
return;
}
}
}


but i still stand by the else is redundant (I think :p)

tyu4
04-02-2012, 08:51 PM
Wouldn't that give me an extra brace?
I set up a block with the curly braces such that the else statement is contained within the if statement.
Tried my best to label them with numbers.


for (month = 0; month < monthName.length; month++) { 1
if (monthName[month].equals(userInput.toLowerCase)) {2
break;
else {3
System.out.println ("Illegal month name; try again.");
return;
}3
}2
}1

alykins
04-02-2012, 09:05 PM
no... it is not an extra- I am not sure I am following your logic... try looking at this hybridization/defamation VB pseudo code thing... the closing statements and exit's might help...


For month as Integer = 0 To monthName.Length
If monthName[month].equals(userInput.toLowercase)
Exit For
Else
System.out.println("...")
return
End If
Next


or more intuitive- what you would need to make it work...


for (month = 0; month < monthName.length; month++) {
if (monthName[month].equals(userInput.toLowerCase)) {
if(something else) {
break;
}
else {
System.out.println ("Illegal month name; try again.");
return;
}
}
}


... but I think the loop you are really looking for is more of a loop in another loop or better yet a function...


if (_indexOf < 0)
System.out.println ("Illegal month name; try again.");

........................................................................
private int _indexOf()
{
for (month = 0; month < monthName.length; month++) {
if (monthName[month].equals(userInput.toLowerCase))
return month;
}
return -1;
}


something like that

tyu4
04-02-2012, 09:14 PM
Here's the finished code!
Thanks so much Alykins and Fou-Lu :thumbsup:


import jpb.*;

public class MonthLength1 {
public static void main (String[] args) {
String[] monthName = new String [] {"january", "february", "march", "april", "may", "june", "july",
"august", "september", "october", "november", "december"};
int month = 0;
SimpleIO.prompt ("Enter a month name: ");
String userInput = SimpleIO.readLine (). trim ();
for (month = 0; month < monthName.length; month++) {
if (monthName[month].equalsIgnoreCase(userInput)) {
break;
}
}
if (month == monthName.length) {
System.out.println ("Illegal month name; try again.");
return;
}

SimpleIO.prompt ("Enter a year: ");
userInput = SimpleIO.readLine ();
int year = Integer.parseInt (userInput);
if (year < 0) {
System.out.println ("Year cannot be negative; try again.");
return;
}


int numberOfDays;
switch (month) {
case 1:
case 2: // February
numberOfDays = 28;
if (year % 4 == 0) {
numberOfDays = 29;
if (year % 100 == 0 && year % 400 != 0)
numberOfDays = 28;
}
break;
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
numberOfDays = 30;
break;
case 12:
default: numberOfDays = 31;
break;
}

System.out.println ("There are " + numberOfDays + " days in this month");
}
}



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum