French Republican date conversion

This program converts a date given from the French Republican Calendar to the corresponding date in our standard Gregorian Calendar. I'm looking for some improvements that I should start making in my code as well as some tips on how to write less lengthy code.

For example, the RepubtoGregDate function is very long and I believe there is probably a more effective way of implementing it.

I'm very new to Python and have no prior knowledge in programming so it would nice to have some suggestions in how to improve my code.

#Python Assignment - French Republican to Gregorian Date Convertor
#Coded by - -
import sys

def Main():
Startup()
while True:
dayN, monthN, yearN, date = Date()
StopProgram(date)
ValidDate = DateVal(yearN, monthN, dayN)
ValLoop(ValidDate)
monthW = MonthNtoW(monthN)
yearRN = YearNtoRN(yearN)
RepubDate = FullRepubDate(dayN, monthW, yearRN)
Leap = LeapCheck(yearN)
GrDate = RepubtoGregDate(yearN, monthN, dayN, Leap)

def Startup():
print("Republican to Gregorian Date Converter\n")
print("This program will convert a date from the French Republican Calendar to the equivalent date in the Gregorian Calendar.")
print("To stop calculating dates and close the program, simply input: 0 0 0.\n")

# Asks for a Republican Date and returns day, month and year.
def Date():
print("Input a Republican Date in the format: dd mm yy.")
date = input("Please enter a Republican Date: ")
print("")
date = date.split()
dayN = int(date)
monthN = int(date)
yearN = int(date)
return(dayN, monthN, yearN, date)

# Ends the program if the sentinal is matched.
def StopProgram(date):
if date == ['0', '0', '0']:
sys.exit(print("Program Closed."))

# Validates the date, making sure it fits the Republican format and that
# the date is between the calendars real world use: 1793 - 1806.
def DateVal(yearN, monthN, dayN):
if yearN >= 1 and yearN <= 14:
ValidYear = True
else:
ValidYear = False
if monthN >= 1 and monthN <= 12:
ValidMonth = True
else:
ValidMonth = False
if dayN >= 1 and dayN <= 30:
ValidDay = True
else:
ValidDay = False
if yearN < 2 and monthN < 1 and dayN < 14:
InvalidDate = True
elif yearN > 14 and monthN > 4 and dayN > 11:
InvalidDate = True
else:
InvalidDate = False
if ValidYear == True and ValidMonth == True and ValidDay == True and InvalidDate == False:
ValidDate = True
else:
ValidDate = False
return(ValidDate)

# Repeats the Date() Function if the Date is invalid.
def ValLoop(ValidDate):
while ValidDate == False:
print("The entered date was not a valid gregorian date, please try again.")
dayN, monthN, yearN = Date()

# Finds the month number's corresponding month word.
def MonthNtoW(monthN):
MonthWDict = {1 : "Vendémiaire", 2 : "Brumaire", 3 : "Frimaire", 4 : "Nivôse", 5 : "Pluviôse", 6 : "Ventôse", 7 : "Germinal", 8 : "Floréal", 9 : "Prairial", 10 : "Messidor", 11 : "Thermidor", 12 : "Fructidor"}
monthW = MonthWDict[monthN]
return monthW

# Finds the year number's corresponding year in roman numerals.
def YearNtoRN(yearN):
YearRNDict = {1 : "I", 2 : "II", 3 : "III", 4 : "IV", 5 : "V", 6 : "VI", 7 : "VII", 8 : "VIII", 9 : "IX", 10 : "X", 11 : "XI", 12 : "XII", 13 : "XIII", 14 : "XIV"}
yearRN = YearRNDict[yearN]
return(yearRN)

# Outputs the Republican date in its written format.
def FullRepubDate(dayN, monthW, yearRN):
dayN = str(dayN)
RepubDate = dayN + " " + monthW + " an " + yearRN
print("The French Republican Date is: ", RepubDate)
dayN = int(dayN)
return(RepubDate)

# Checks if the year is a leap year.
def LeapCheck(yearN):
if yearN == 3 or yearN == 7 or yearN == 11:
Leap = True
else:
Leap = False
return(Leap)

# Converts the Republican date to a Gregorian date.
# It does this by converting the date to days in the year and then adds
# that to the day the Republican Calendar started in The Gregorian calendar.
def RepubtoGregDate(yearN, monthN, dayN, Leap):
monthL = 30
StartDate = 266
StartYear = 1792
YDays = 365
LYDays = 366

Year = StartYear + (yearN - 1)
Day = ((monthN - 1) * monthL) + dayN
if Leap == True and Day >= 60:
Day += 1

PH = StartDate + Day
if Leap == True:
if PH > LYDays:
Year += 1
Day = PH - LYDays
else:
Day = PH
if Leap == False:
if PH > YDays:
Year += 1
Day = PH - YDays
else:
Day = PH

if Leap == False:
if Day >= 1 and Day <= 31:
GregMonth = "January"
if Day >= 32 and Day <= 59:
Day -= 31
GregMonth = "February"
if Day >= 60 and Day <= 90:
Day -= 59
GregMonth = "March"
if Day >= 91 and Day <= 120:
Day -= 90
GregMonth = "April"
if Day >= 121 and Day <= 151:
Day -= 120
GregMonth = "May"
if Day >= 152 and Day <= 181:
Day -= 151
GregMonth = "June"
if Day >= 182 and Day <= 212:
Day -= 181
GregMonth = "July"
if Day >= 213 and Day <= 243:
Day -= 212
GregMonth = "August"
if Day >= 244 and Day <= 273:
Day -= 243
GregMonth = "September"
if Day >= 274 and Day <= 304:
Day -= 273
GregMonth = "October"
if Day >= 305 and Day <= 334:
Day -= 304
GregMonth = "November"
if Day >= 335 and Day <= 365:
Day -= 334
GregMonth = "December"

if Leap == True:
if Day >= 1 and Day <= 31:
GregMonth = "January"
if Day >= 32 and Day <= 60:
Day -= 32
GregMonth = "February"
if Day >= 61 and Day <= 91:
Day -= 60
GregMonth = "March"
if Day >= 92 and Day <= 121:
Day -= 91
GregMonth = "April"
if Day >= 122 and Day <= 152:
Day -= 121
GregMonth = "May"
if Day >= 153 and Day <= 182:
Day -= 152
GregMonth = "June"
if Day >= 183 and Day <= 213:
Day -= 182
GregMonth = "July"
if Day >= 214 and Day <= 244:
Day -= 213
GregMonth = "August"
if Day >= 245 and Day <= 274:
Day -= 244
GregMonth = "September"
if Day >= 275 and Day <= 305:
Day -= 274
GregMonth = "October"
if Day >= 306 and Day <= 335:
Day -= 305
GregMonth = "November"
if Day >= 336 and Day <= 366:
Day -= 335
GregMonth = "December"

Day = str(Day)
Year = str (Year)
GregDate = Day + " " + GregMonth + " " + Year
Day = int(Day)
Year = int(Year)
print("The Gregorian Date is: ", GregDate, "\n")
return(GregDate)

#Main
Main()
• dayN, monthN, yearN = Date() ValueError: too many values to unpack (expected 3) When I try to run, it will give me an error. Also unclear to me what Dates are valid... – Ludisposed Sep 11 '17 at 14:33

Running your code through PEP8 will produce alot of errors, you can see it for yourself.

Just to name a few PEP8 improvements:

1. Use indentation of 4 spaces, it looks cleaner
2. Functions should be named with lowerscore letters. Example: stop_program
3. You use a lot of if var == False: which could be rewritten to if not var:
4. Same goes for if var == True: which is just if var:
5. You have some calculations like if val > 0 and val < 12: which can be rewritten to if 0 < val < 12:
6. When using comments don't indent them! - #comment should be # comment

Other improvements:

When possible use libraries, be sure to check out datetime library

I thought I'd have a go at this. I've done it in c# - yes I know it's a different language but hold on - you should be able to draw some useful general principles from it.

I've tried to make it more readable and implemented an OOP approach. Although I would have liked to make inroads in simplifying the actual algorithm which does the conversion, I think you'll probably see what I've done.

See the link attached - i'm hoping it is a little more readable - in terms of having small methods which do a particular job. IsValid(), IsDayValid() IsYearValid() etc are all small methods which do a particular and improve readability.

using System;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main(string[] args)
{
// prints welcome
// gets date input
DateConverter dc = new DateConverter();

dc.PrintConvertedDate();
dc.PrintRepublicanDate();

}
}

public class DateConverter
{
public RepublicanDate republicDate { get; set; }

public DateConverter()
{
PrintWelcome();
this.republicDate = GetDate();
}

public void PrintWelcome()
{
Console.WriteLine("\nRepublican to Gregorian Date Converter");
Console.WriteLine("\nThis program will convert a date from the French Republican Calendar to the equivalent date in the Gregorian Calendar.");
Console.WriteLine("\nTo stop calculating dates and close the program, simply input: 0 0 0.\n");
}

public DateTime ConvertDate()
{
return republicDate.ConvertToGregorianDate();
}

public void PrintConvertedDate()
{
// prints converted date
Console.WriteLine("This converted gregorian date is: " + this.ConvertDate());
}

public void PrintRepublicanDate()
{
// prints the republic date in its original string format.
Console.WriteLine(republicDate.ToString());
}

private RepublicanDate GetDate()
{
RepublicanDate date;

// repeat untill we get a valid date value
do
{
date = new RepublicanDate();
} while (date.IsInvalid());

return date;
}
}

public class RepublicanDate
{
private DayMonthYear input;

public RepublicanDate()
{
input = GetInputDate();
}

private DayMonthYear GetInputDate()
{
Console.WriteLine("Input a Republican Date in the format: 'dd mm yy'. Please enter a republican date: \n");
string date = Console.ReadLine();
string[] dateArray = date.Split(' ');

int day = int.Parse(dateArray);
int month = int.Parse(dateArray);
int year = int.Parse(dateArray);

DayMonthYear dt = new DayMonthYear(day, month, year);

return dt;
}

#region Validity methods

public bool IsInvalid()
{
if (IsYearInvalid(input))
{
return true;
}
else if (IsMonthInvalid(input))
{
return true;
}
else if (IsDayInvalid(input))
{
return true;
}
else
{
return false;
}
}

private bool IsDayInvalid(DayMonthYear input)
{
if (input.Day >= 1 && input.Day <= 30)
{
return false;
}
else
{
return true;
}
}

private bool IsMonthInvalid(DayMonthYear input)
{
if (input.Month >= 1 && input.Month <= 12)
{
return false;
}
else
{
return true;
}
}

private bool IsYearInvalid(DayMonthYear input)
{
if (input.Year >= 1 && input.Year <= 14)
{
return false;
}
else
{
return true;
}
}

#endregion Validity methods

public override string ToString()
{
return String.Format("The french Rpublic Date is: {0} {1} and {2}", input.Day, GetFrenchMonth(input.Month), GetFrenchYear(input.Year));
}

#region To String Helper methods

private string GetFrenchMonth(int monthNumber)
{
switch (monthNumber)
{
case 1:
return "Vendémiaire";

case 2:
return "Brumaire";

case 3:
return "Frimaire";

case 4:
return "Nivôse";

case 5:
return "Pluviôse";

case 6:
return "Ventôse";

case 7:
return "Germinal";

case 8:
return "Floréal";

case 9:
return "Prairial";

case 10:
return "Messidor";

case 11:
return "Thermidor";

case 12:
return "Fructidor";

default:
throw new ArgumentOutOfRangeException("\n The months should only be between 1 and 12");
}
}

private string GetFrenchYear(int YearNumber)
{
switch (YearNumber)
{
case 1:
return "I";

case 2:
return "II";

case 3:
return "III";

case 4:
return "IV";

case 5:
return "V";

case 6:
return "VI";

case 7:
return "VII";

case 8:
return "VIII";

case 9:
return "IX";

case 10:
return "X";

case 11:
return "XI";

case 12:
return "XII";

case 13:
return "XIII";

case 14:
return "XIV";

default:
throw new ArgumentOutOfRangeException("\n The year should only be between 1 and 14");
}
}

#endregion To String Helper methods

public DateTime ConvertToGregorianDate()
{
// just returned a dummy value, but all your conversion logic could go here:
return new DateTime();

// I can't comment too much on the logic seeing i don't understand it
// but it looks like  you can certain break it up
// to make it more readable and understandable.

// all the conversion logic should go here.
//monthL = 30
//StartDate = 266
//StartYear = 1792
//YDays = 365
//LYDays = 366

//Year = StartYear + (yearN - 1)
//Day = ((monthN - 1) * monthL) + dayN
//if Leap == True and Day >= 60:
//  Day += 1

//PH = StartDate + Day
//if Leap == True:
//  if PH > LYDays:
//    Year += 1
//    Day = PH - LYDays
//  else:
//    Day = PH
//if Leap == False:
//  if PH > YDays:
//    Year += 1
//    Day = PH - YDays
//  else:
//    Day = PH

//if Leap == False:
//  if Day >= 1 and Day <= 31:
//      GregMonth = "January"
//  if Day >= 32 and Day <= 59:
//      Day -= 31
//      GregMonth = "February"
//  if Day >= 60 and Day <= 90:
//      Day -= 59
//      GregMonth = "March"
//  if Day >= 91 and Day <= 120:
//      Day -= 90
//      GregMonth = "April"
//  if Day >= 121 and Day <= 151:
//      Day -= 120
//      GregMonth = "May"
//  if Day >= 152 and Day <= 181:
//      Day -= 151
//      GregMonth = "June"
//  if Day >= 182 and Day <= 212:
//      Day -= 181
//      GregMonth = "July"
//  if Day >= 213 and Day <= 243:
//      Day -= 212
//      GregMonth = "August"
//  if Day >= 244 and Day <= 273:
//      Day -= 243
//      GregMonth = "September"
//  if Day >= 274 and Day <= 304:
//      Day -= 273
//      GregMonth = "October"
//  if Day >= 305 and Day <= 334:
//      Day -= 304
//      GregMonth = "November"
//  if Day >= 335 and Day <= 365:
//      Day -= 334
//      GregMonth = "December"

//if Leap == True:
//  if Day >= 1 and Day <= 31:
//      GregMonth = "January"
//  if Day >= 32 and Day <= 60:
//      Day -= 32
//      GregMonth = "February"
//  if Day >= 61 and Day <= 91:
//      Day -= 60
//      GregMonth = "March"
//  if Day >= 92 and Day <= 121:
//      Day -= 91
//      GregMonth = "April"
//  if Day >= 122 and Day <= 152:
//      Day -= 121
//      GregMonth = "May"
//  if Day >= 153 and Day <= 182:
//      Day -= 152
//      GregMonth = "June"
//  if Day >= 183 and Day <= 213:
//      Day -= 182
//      GregMonth = "July"
//  if Day >= 214 and Day <= 244:
//      Day -= 213
//      GregMonth = "August"
//  if Day >= 245 and Day <= 274:
//      Day -= 244
//      GregMonth = "September"
//  if Day >= 275 and Day <= 305:
//      Day -= 274
//      GregMonth = "October"
//  if Day >= 306 and Day <= 335:
//      Day -= 305
//      GregMonth = "November"
//  if Day >= 336 and Day <= 366:
//      Day -= 335
//      GregMonth = "December"

//Day = str(Day)
//Year = str (Year)
//GregDate = Day + " " + GregMonth + " " + Year
//Day = int(Day)
//Year = int(Year)
//print("The Gregorian Date is: ", GregDate, "\n")
//return(GregDate)
}
}

public struct DayMonthYear
{
public int Day { get; set; }
public int Month { get; set; }
public int Year { get; set; }

public DayMonthYear(int day, int month, int year)
: this()
{
this.Day = day;
this.Month = month;
this.Year = year;
}
}
}