diff --git a/src/pyluach/parshios.py b/src/pyluach/parshios.py index 630e328..3fd6930 100644 --- a/src/pyluach/parshios.py +++ b/src/pyluach/parshios.py @@ -371,3 +371,117 @@ def four_parshios(date, hebrew=False): if hebrew: return _FOUR_PARSHIOS_HEBREW[special_parsha] return _FOUR_PARSHIOS[special_parsha] + + +### added 12/2025 ### + +def _genreversetable(year, israel=False): + """Return OrderedDict mapping parsha numbers to date of Shabbos. + + The numbers start with Beraishis as 0. Double parshios are represented + twice - either reffering to the same date. + """ + parshalist = deque([51, 52] + list(range(52))) + table = OrderedDict() + leap = _is_leap(year) + pesachday = HebrewDate(year, 1, 15).weekday() + rosh_hashana = HebrewDate(year, 7, 1) + shabbos = rosh_hashana.shabbos() + if rosh_hashana.weekday() > 4: + parshalist.popleft() + + while shabbos.year == year: + parsha = parshalist.popleft() + table[parsha] = [shabbos] + if ( + ( + parsha == _Parshios_Enum.VAYAKHEL + and (HebrewDate(year, 1, 14) - shabbos) // 7 < 3 + ) + or ( + parsha in [ + _Parshios_Enum.TAZRIA, _Parshios_Enum.ACHAREI_MOS + ] and not leap + ) + or ( + parsha == _Parshios_Enum.BEHAR and not leap + and (not israel or pesachday != 7) + ) + or ( + parsha == _Parshios_Enum.CHUKAS + and not israel and pesachday == 5 + ) + or ( + parsha == _Parshios_Enum.MATTOS + and (HebrewDate(year, 5, 9)-shabbos) // 7 < 2 + ) + or ( + parsha == _Parshios_Enum.NITZAVIM + and HebrewDate(year+1, 7, 1).weekday() > 4 + ) + ): + # If any of that then it's a double parsha. + table[parshalist.popleft()].append(shabbos) + shabbos += 7 + return table + +DAYS = ["Shabbos", "Friday", "Thursday", "Wednesday", "Tuesday", "Monday", "Sunday"] +def getDateFromParshaIndex(Parsha: int, year: int, DOW="Shabbos", israel=False): + """Return the parsha for a given date. + + Returns the date on or before the given parsha. + + Parameters + ---------- + Parsha : int + The number of the parsha to get the date for. + + israel : bool, optional + ``True`` if you want the parsha according to the Israel schedule + (with only one day of Yom Tov). Defaults to ``False``. + + DOW : str, optional + The day of the week to return the date for. Default is "Shabbos". + + Returns + ------- + list of int or None + A list of the numbers of the parshios for the Shabbos of the given date, + beginning with 0 for Beraishis, or ``None`` if the Shabbos doesn't + have a parsha (i.e. it's on Yom Tov). + """ + table = _genreversetable(year, israel) + result = table[Parsha] + if result is None: + return None + return result - [DAYS.index(DOW)] + +def getDateFromParshaEng(Parsha: str, year, DOW="Shabbos", israel=False): + """function overload for getDateFromParshaIndex to accept Parsha name in English.""" + return getDateFromParshaIndex(PARSHIOS.index(Parsha), year, DOW, israel) + + +def getDateFromParshaHeb(Parsha: str, year, DOW="Shabbos", israel=False): + """function overload for getDateFromParshaIndex to accept Parsha name in Hebrew.""" + return getDateFromParshaIndex(PARSHIOS_HEBREW.index(Parsha), year, DOW, israel) + +def reverseparshatable(year, israel=False): + """Return a table of all the Shabbosos in the year + + Parameters + ---------- + year : int + The Hebrew year to get the parshios for. + + israel : bool, optional + ``True`` if you want the parshios according to the Israel + schedule (with only one day of Yom Tov). Defaults to ``False``. + + Returns + ------- + ~collections.OrderedDict + An ordered dictionary with the ``HebrewDate`` of each Shabbos + as the key mapped to the parsha as a list of ints, or ``None`` for a + Shabbos with no parsha. + """ + return _genreversetable(year, israel) \ No newline at end of file diff --git a/tests/test_reverseparshios.py b/tests/test_reverseparshios.py new file mode 100644 index 0000000..415b429 --- /dev/null +++ b/tests/test_reverseparshios.py @@ -0,0 +1,109 @@ +from pyluach import parshios, dates +from pyluach.parshios import _FourParshiosEnum + + +KNOWN_VALUES = { + 13 : (2016, 1, 7), + 21: (2017, 3, 21), + 22: (2017, 3, 21), + -1: None, + "Bara": None, +} + +KNOWN_VALUES_STRINGS = { + "Va'eira": (2016, 1, 7), + "Vayakhel, Pekudei": (2017, 3, 21), + "Bara": None + +} + + +class TestGetParsha: + + def test_getDateFromParshaIndex(self): + for key, value in KNOWN_VALUES.items(): + assert parshios.getDateFromParshaIndex(*key) == value + + def test_getDateFromParshaEng(self): + for key, value in KNOWN_VALUES_STRINGS.items(): + assert ( + parshios.getparsha_string(*key) == value + ) + +# def test_chukas_balak(self): +# chukas_balak = dates.HebrewDate(5780, 4, 12) +# assert parshios.getparsha(chukas_balak) == [38, 39] +# assert parshios.getparsha(chukas_balak, True) == [39, ] +# assert parshios.getparsha(chukas_balak - 8) == [37, ] +# assert parshios.getparsha(chukas_balak - 13, True) == [38, ] +# shavuos = dates.HebrewDate(5780, 3, 6) +# assert parshios.getparsha_string(shavuos, True) == 'Nasso' +# assert parshios.getparsha_string(shavuos) is None +# assert parshios. getparsha_string(shavuos + 7, True) == "Beha'aloscha" +# assert parshios.getparsha_string(shavuos + 7) == 'Nasso' + +# def test_eighth_day_pesach(self): +# eighth_day_pesach = dates.HebrewDate(5779, 1, 22) +# reunion_shabbos = dates.HebrewDate(5779, 5, 2) +# assert parshios.getparsha_string(eighth_day_pesach) is None +# assert ( +# parshios.getparsha_string(eighth_day_pesach, True) == 'Acharei Mos' +# ) +# assert parshios.getparsha(eighth_day_pesach + 7) == [28] +# assert parshios.getparsha(eighth_day_pesach + 7, True) == [29] +# assert parshios.getparsha_string(reunion_shabbos) == "Mattos, Masei" +# assert parshios.getparsha_string(reunion_shabbos, True) == 'Masei' + + +def test_parshatable(): + assert parshios.reverseparshatable(5777) == parshios._genreversetable(5777) + assert parshios.reverseparshatable(5778, True) == parshios._genreversetable(5778, True) + + +#def test_iterparshios(): +# year = 5776 +# parshalist = list(parshios.parshatable(year).values()) +# index = 0 +# for p in parshios.iterparshios(year): +# assert p == parshalist[index] +# index += 1 + + +#def test_get_parshastring_hebrew(): +# date = dates.HebrewDate(5781, 3, 28) +# assert parshios.getparsha_string(date, hebrew=True) == 'קרח' +# date2 = dates.GregorianDate(2021, 7, 10) +# assert parshios.getparsha_string(date2, hebrew=True) == 'מטות, מסעי' + + +#def test_shekalim(): +# date = dates.HebrewDate(5785, 11, 25) +# assert ( +# parshios._get_four_parshios(date) == _FourParshiosEnum.SHEKALIM +# ) +# assert parshios._get_four_parshios(date - 1) is None +# assert parshios._get_four_parshios(date + 7) != _FourParshiosEnum.SHEKALIM + + +#def test_zachor(): +# date = dates.HebrewDate(5785, 12, 2) +# assert ( +# parshios._get_four_parshios(date) == _FourParshiosEnum.ZACHOR +# ) + + +#def test_parah(): +# date = dates.HebrewDate(5785, 12, 21) +# assert parshios.four_parshios(date) == 'Parah' +# date = dates.HebrewDate(5784, 13, 14) +# assert parshios.four_parshios(date, hebrew=True) == 'פרה' +# assert parshios.four_parshios(date - 1) != 'Parah' +# date = dates.GregorianDate(2025, 3, 9) +# assert parshios.four_parshios(date) == '' + + +#def test_hachodesh(): +# date = dates.HebrewDate(5785, 12, 29) +# assert parshios._get_four_parshios(date) == _FourParshiosEnum.HACHODESH +# date = dates.HebrewDate(5782, 1, 1) +# assert parshios._get_four_parshios(date) == _FourParshiosEnum.HACHODESH