Avatar of hrodward

hrodward's solution

to Leap in the PL/SQL Track

Published at Nov 14 2019 · 0 comments
Instructions
Test suite
Solution

Given a year, report if it is a leap year.

The tricky thing here is that a leap year in the Gregorian calendar occurs:

on every year that is evenly divisible by 4
  except every year that is evenly divisible by 100
    unless the year is also evenly divisible by 400

For example, 1997 is not a leap year, but 1996 is. 1900 is not a leap year, but 2000 is.

If your language provides a method in the standard library that does this look-up, pretend it doesn't exist and implement it yourself.

Notes

Though our exercise adopts some very simple rules, there is more to learn!

For a delightful, four minute explanation of the whole leap year phenomenon, go watch this youtube video.

Setup

Go through the setup instructions for PL/SQL to get ready to code:

http://exercism.io/languages/plsql

Running the Tests

Execute the tests by calling the run method in the respective ut_<exercise># package. The necessary code should be contained at the end of the test package. As an example, the test for the hamming exercise would be run using

begin
  ut_hamming#.run;
end;
/

Source

JavaRanch Cattle Drive, exercise 3 http://www.javaranch.com/leap.jsp

Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

ut_leap#.plsql

create or replace package ut_year#
is
  procedure run;
end ut_year#;
/
 
create or replace package body ut_year#
is
  procedure test (
    i_descn                                       varchar2
   ,i_exp                                         varchar2
   ,i_act                                         varchar2
  )
  is
  begin
    if i_exp = i_act then
      dbms_output.put_line('SUCCESS: ' || i_descn);
    else
      dbms_output.put_line('FAILURE: ' || i_descn || ' - expected ' || nvl(i_exp, 'null') || ', but received ' || nvl(i_act, 'null'));
    end if;
  end test;
 
  procedure run
  is
  begin
    test(i_descn => 'test_leap_year'         , i_exp => 'Yes, 1996 is a leap year'   , i_act => year#.is_leap(1996));
    test(i_descn => 'test_non_leap_year'     , i_exp => 'No, 1997 is not a leap year', i_act => year#.is_leap(1997));
    test(i_descn => 'test_non_leap_even_year', i_exp => 'No, 1998 is not a leap year', i_act => year#.is_leap(1998));
    test(i_descn => 'test_century'           , i_exp => 'No, 1900 is not a leap year', i_act => year#.is_leap(1900));
    test(i_descn => 'test_fourth_century'    , i_exp => 'Yes, 2400 is a leap year'   , i_act => year#.is_leap(2400));
  end run;
end ut_year#;
/
 
begin
  ut_year#.run;
end;
/
create or replace package year#
is
  function is_leap (in_year pls_integer) return varchar2;
end year#;
/
create or replace package body year#
is
  function is_leap (in_year pls_integer) return varchar2 is
    is_leap boolean;
  begin
    is_leap := 
      case
        when mod(in_year, 100) = 0 then mod(in_year, 400) = 0
        else mod(in_year, 4) = 0
       end;
       
    return
      case is_leap
        when true then 'Yes, ' || in_year || ' is a leap year'
        else 'No, ' || in_year || ' is not a leap year'
      end;
  end;
end year#;
/

Community comments

Find this solution interesting? Ask the author a question to learn more.

What can you learn from this solution?

A huge amount can be learned from reading other people’s code. This is why we wanted to give exercism users the option of making their solutions public.

Here are some questions to help you reflect on this solution and learn the most from it.

  • What compromises have been made?
  • Are there new concepts here that you could read more about to improve your understanding?