Giter Club home page Giter Club logo

py-nepali's Introduction

nepali

PyPI version CI status Downloads codecov

nepali is a python package containing features that will be useful for Nepali projects.

The major feature of this package is nepalidatetime, which is compatible with python's datetime feature. It helps nepali date to english, parsing nepali datetime, nepali timezone, and timedelta support in nepali datetime.

Example

import datetime
from nepali import phone_number
from nepali.datetime import nepalidate, parser

nepali_datetime = parser.parse('2079-02-15')
# 2079-02-15 00:00:00

date = datetime.date(2017, 3, 15)
nepali_date = nepalidate.from_date(date)
# 2073-12-02

phone_number.parse("+977-9845217789")
# {
#     'type':      'Mobile',
#     'number':    '9845217789',
#     'operator':  <Operator: Nepal Telecom>
# }

Requirements

Python >= 3

Installation

pip install nepali

Features

  1. Date and Time
  2. Numbers
  3. Phone Number
  4. Locations
  5. For Django Template

Date and Time

date_converter

Date converter module converts english date to nepali and nepali date to english. It doesn't contain any extra functionality.

Convert English date to Nepali date

from nepali.date_converter import converter

np_year, np_month, np_date = converter.english_to_nepali(en_year, en_month, en_date)

Example

from nepali.date_converter import converter

np_year, np_month, np_date = converter.english_to_nepali(2023, 2, 7)
print(np_year, np_month, np_date) # 2079 10 24

Convert Nepali date to English date

from nepali.date_converter import converter

en_year, en_month, en_date = converter.nepali_to_english(np_year, np_month, np_date)

Example

from nepali.date_converter import converter

en_year, en_month, en_date = converter.nepali_to_english(2079, 10, 24)
print(en_year, en_month, en_date) # 2023 2 7

nepalidate

Creating a new nepalidate object

from nepali.datetime import nepalidate

# nepalidate object with year, month, day
np_date = nepalidate(year, month, day)

# nepalidate object with today's date
np_date = nepalidate.today()

# parse nepali date
np_date = nepalidate.strptime('2078-01-18', format='%Y-%m-%d')

Getting nepalidate object from python datetime

# from date object
np_date = nepalidate.from_date(date_obj)

# from datetime object
np_date = nepalidate.from_datetime(datetime_obj)

Attributes and Methods

np_date.year                       # 2078 (year)
np_date.month                      # 1 (month)
np_date.day                        # 18 (day)

np_date.to_date()                  # datetime.date object
np_date.to_datetime()              # datetime.datetime object
np_date.to_nepalidatetime()        # nepalidatetime object

np_date.strftime("%Y-%m-%d")       # 2078-01-18
np_date.strftime_ne("%Y-%m-%d")    # २०७८-०१-१८

np_date.weekday()                  # Sunday => 0, Monday => 1, ..., Saturday => 6

nepalidatetime

Creating a new nepalidatetime object

from nepali.datetime import nepalidatetime

# nepalidate object with year, month, day, hour, minute, second
np_datetime = nepalidatetime(year, month, day[, hour[, minute[, second]]])

# nepalidate object with current date and time
np_datetime = nepalidate.now()
np_datetime = nepalidate.today()

# parse nepali datetime
np_datetime = nepalidatetime.strptime('2078-01-12 13:12', format='%Y-%m-%d %H:%M')

Getting nepalidatetime object from python datetime

# from date object
np_datetime = nepalidatetime.from_date(date_obj)

# from datetime object
np_datetime = nepalidatetime.from_datetime(datetime_obj)

Getting nepalidatetime object from nepalidate

np_datetime = nepalidatetime.from_nepalidate(nepali_date)

Attributes and Methods

np_date.year                             # 2078 (year)
np_date.month                            # 1 (month)
np_date.day                              # 18 (day)
np_date.hour                             # 23 (hour)
np_date.minute                           # 59 (minute)
np_date.second                           # 59 (day)

np_date.to_date()                        # datetime.date object
np_date.to_datetime()                    # datetime.datetime object
np_date.to_nepalidate()                  # nepalidatetime object
np_date.to_time()                        # nepalitime object (datetime.time compatible)

np_date.strftime("%Y-%m-%d %H:%M")       # 2078-01-18 23:59
np_date.strftime_ne("%Y-%m-%d %H:%M")    # २०७८-०१-१८ २३:५९

np_date.weekday()                        # Sunday => 0, Monday => 1, ..., Saturday => 6

Timedelta support

# timedelta addition and subtraction
np_datetime - datetime.timedelta(days=3)       # returns nepalidatetime

# comparison between two dates
np_datetime1 - np_datetime2                    # returns timedelta object
np_datetime1 < np_datetime2                    # returns bool (True/False)
np_datetime1 >= datetime.datetime.now()        # returns bool (True/False)
...

nepalihumanize

Returns readable form of nepali date.

from nepali.datetime import nepalihumanize


nepalihumanize(datetime, [threshold, format])

The threshold is and optional field and is in seconds and the format is for the strftime format. If the datetime object crosses the threshold it print the date with the format. The format is also an optional and is %B %d, %Y in default.

Example

from nepali.datetime import nepalihumanize, nepalidatetime

np_datetime = nepalidatetime(2079, 10, 5)
output = nepalihumanize(np_datetime)
# output: ३ महिना अघि

output = nepalihumanize(np_datetime, threshold=1400)
# 1400 = 2 * 30 * 24; two months threshold
# output: माघ ०५, २०७९

timezone

NepaliTimeZone You can use NepaliTimeZone directly to your datetime object.

from nepali.timezone import NepaliTimeZone

datetime.datetime(2018, 8, 12, 16, 23, tzinfo=NepaliTimeZone())

now Returns current datetime object with timezone

from nepali import timezone

timezone.now()

datetime.now() vs timezone.now(): datetime.now() doesn't contain timezone, but timezone.now() will contain timezone of the system.

utc_now Returns current UTC datetime object (with timezone UTC)

from nepali import timezone

timezone.utc_now()

parse

Parses date with commonly used date formats. Auto detects date format. If you are sure about the format, please use strptime.

from nepali.datetime.parser import parse

np_datetime = parse(datetime_str)

Example

np_datetime = parse("2079-02-15")                     # 2079-02-15 00:00:00
np_datetime = parse("२०७८-०१-१८")                      # 2078-01-15 00:00:00
np_datetime = parse("2079/02/15")                     # 2079-02-15 00:00:00
np_datetime = parse("2079-02-15 15:23")               # 2079-02-15 15:23:00
np_datetime = parse("2079-02-15 5:23 AM")             # 2079-02-15 05:23:00
np_datetime = parse("2079-02-15 5:23 AM")             # 2079-02-15 05:23:00
np_datetime = parse("Jestha 15, 2079")                # 2079-02-15 00:00:00

strftime() and strptime() Format Codes

Directive Meaning Example
%a Weekday as locale’s abbreviated name. Sun, Mon, …, Sat (आइत, सोम, …)
%A Weekday as locale’s full name. Sunday, Monday, …, Saturday
%d Day of the month as a zero-padded decimal number. 01, 02, …, 31
%-d Day of the month as a decimal number. 1, 2, …, 31
%B Month as locale’s full name. Baishakh, Jestha, …, Chaitra
%m Month as a zero-padded decimal number. 01, 02, …, 12
%-m Month as a decimal number. 1, 2, …, 12
%y Year without century as a zero-padded decimal number. 00, 01, …, 99
%Y Year with century as a decimal number. 2001, 2078, 2079, …, 2099
%H Hour (24-hour clock) as a zero-padded decimal number. 00, 01, …, 23
%-H Hour (24-hour clock) as a decimal number. 0, 1, 2, …, 23
%I Hour (12-hour clock) as a zero-padded decimal number. 01, 02, …, 12
%-I Hour (12-hour clock) as a decimal number. 1, 2, …, 12
%p Locale’s equivalent of either AM or PM. AM, PM (en_US)
%M Minute as a zero-padded decimal number. 00, 01, …, 59
%-M Minute as a decimal number. 0, 1, 2, …, 59
%S Second as a zero-padded decimal number. 00, 01, …, 59
%-S Second as a decimal number. 0, 1, 2, …, 59
%f Microsecond as a decimal number, zero-padded to 6 digits. 000000, 000001, …, 999999
%% A literal '%' character. %

Numbers

from nepali import number

convert Converts english number to nepali.

np_number = number.convert("1234567890")  # १२३४५६७८९०

revert Converts english number to nepali.

en_number = number.revert("१२३४५६७८९०")  # 1234567890

add_comma Adds comma in nepali numbers.

number_text = number.add_comma("1234567890")  # 1,23,45,67,890

nepalinumber

nepalinumber is a new data type, which can be used to represent Nepali (Devanagari) numbers. It allows us to perform arithmetic operations, just like with int and float. Additionally, it can be used to parse numbers and output them in Devanagari format.

from nepali.number import nepalinumber

Parsing

a = nepalinumber("१८.२७")
print(a)  # 18.27

b = nepalinumber(15)
print(b)  # 15

Nepali (Devanagari) output

a = nepalinumber("18.27")
print(a.str_ne())  # १८.२७

Arithmetic operations

a = nepalinumber("1")
b = nepalinumber("२")
c = a + b * 3
print(c)  # 7

Phone Number

from nepali import phone_number

is_valid Checks is the given number is a valid nepali phone number.

phone_number.is_valid("9851377890")      # True
phone_number.is_valid("+977-142314819")  # True

phone_number.is_valid("8251377890")      # False

parse Parse phone number and returns details of the number.

phone_number.parse("9851377890")
# {'type': 'Mobile', 'number': '9851377890', 'operator': <Operator: Nepal Telecom>}

phone_number.parse("+977-142314819")
# {'type': 'Landline', 'number': '0142314819', 'area_code': '01'}

Locations

Provides details of Nepal's Province, District, and Municipality.

from nepali.locations import provinces, districts, municipalities
from nepali.locations.utils import get_province, get_district, get_municipality

# Province
get_province(name="Bagmati")
# Bagmati Province

# District
get_district(name="Kathmandu")
# Kathmandu

# Municipality
get_municipality(name="Kathmandu")
# Kathmandu Metropolitan City

# Municipality
get_municipality(name_nepali="विराटनगर")
# Biratnagar Metropolitan City

For Django

We have created a new Django package called django-nepali to support nepali package. For more information, please visit django-nepali.

Contribution

We appreciate feedback and contribution to this package. To get started please see our contribution guide

py-nepali's People

Contributors

aj3sh avatar dipin-bajra avatar shakyaankit avatar subashcs avatar sugat009 avatar sumanchapai avatar surajrisal avatar theoctober19th avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

py-nepali's Issues

Add type hints and doc strings

Use Case
This Python package doesn't contain proper type hints and doc strings. A proper type hint and doc string help the end user to use the package. Furthermore, it will also help generate the docs through the codes.

Challenges
As this task involves all the files within the repository. The chances of occurring merge conflicts are high.

Proposed Solution
Partial changes with partial PR will help reduce the merge conflicts. That is to say, only one file will be refactored at once. If anyone is picking to refactor a file, Please comment on this PR.

Create a feature for nepali months with nepalimonth class

The class nepalimonth help us to parse the Nepali month data and allow different formatting and operations on it.

Example:

Initialization:

month = nepalimonth(1)  # Baishakh
month = nepalimonth("Baishakh")
month = nepalimonth("बैशाख")

Usage:

month.value        # 1
month.name         # Baishakh
month.name_ne      # बैशाख

Remove pytz dependencies

pytz is an external package and it is not related to this project. As we maintain our own timezone and date times, it is better to remove this package and its dependencies.

Fix flake8 C901 on datetime.parser.validators.transform

While running the flake8 linting on this repo through the GitHub actions, an error C901 is raised. Below is the detailed error log.

./nepali/datetime/parser/validators.py:141:1: C901 'transform' is too complex (21)
1     C901 'transform' is too complex (21)

The file nepali/datetime/parser/validators.py contains the logic for date parsing and the transform method is part of it.

Major Flake8 issues were fixed through PR #44, but a cognitive complexity issue was still detected and left to be addressed in this issue.

Here is the code.

def transform(data: dict):
    """
    transforms different format data to uniform data

    eg.
    INPUT:
    data = {
        "Y": 2078,
        "b": "Mangsir",
        "d": 12,
        ...
    }

    OUTPUT:
    {
        "year": 2078,
        "month": 8,
        "day": 12,
        ...
    }
    """

    year = None
    month = day = 1
    hour = minute = second = fraction = 0
    weekday = None

    for date_key in data.keys():
        if date_key == "y":
            year = int(data["y"])
            year += 2000
        elif date_key == "Y":
            year = int(data["Y"])
        elif date_key == "m":
            month = int(data["m"])
        elif date_key == "B":
            month = nepalimonth(data["B"])
        elif date_key == "b":
            month = nepalimonth(data["b"])
        elif date_key == "d":
            day = int(data["d"])
        elif date_key == "H":
            hour = int(data["H"])
        elif date_key == "I":
            hour = int(data["I"])
            ampm = data.get("p", "").lower()
            # If there was no AM/PM indicator, we'll treat this like AM
            if ampm in ("", "am"):
                # We're in AM so the hour is correct unless we're
                # looking at 12 midnight.
                # 12 midnight == 12 AM == hour 0
                if hour == 12:
                    hour = 0
            elif ampm == "pm":
                # We're in PM so we need to add 12 to the hour unless
                # we're looking at 12 noon.
                # 12 noon == 12 PM == hour 12
                if hour != 12:
                    hour += 12
        elif date_key == "M":
            minute = int(data["M"])
        elif date_key == "S":
            second = int(data["S"])
        elif date_key == "f":
            s = data["f"]
            # Pad to always return microseconds.
            s += "0" * (6 - len(s))
            fraction = int(s)
        elif date_key == "A":
            weekday = nepaliweek(data["A"])
        elif date_key == "a":
            weekday = nepaliweek(data["a"])
        elif date_key == "w":
            weekday = int(data["w"])
            if weekday == 0:
                weekday = 6
            else:
                weekday -= 1
    return {
        "year": year,
        "month": month,
        "day": day,
        "hour": hour,
        "minute": minute,
        "second": second,
        "microsecond": fraction,
        "weekday": weekday,
    }

Implement CLI for date conversion

Let's implement CLI for date conversion, English to Nepali (AD to BS), and Nepali to English (BS to AD).

An example of a CLI would be:

ad2bs 2023-04-29
# Output: 2080-01-16

bs2ad 2080-01-16
# Output: 2023-04-29

We can also decorate the output, with something like the below:

Nepali Date:
Saturday, Baishak 16, 2080
शनिबार, बैशाख १६, २०८०

English Date:
Saturday, April 29, 2023

Support for Python 3.12

Python 3.12 is scheduled for release in October 2023 and will introduce a variety of new features, optimizations, and bug fixes. It is crucial for our 'nepali' package to keep up with the latest Python version to ensure compatibility and provide the best experience for our users.

This update will enable our users to take advantage of the new capabilities offered by Python 3.12 and ensure that our package remains current within the Python ecosystem.

Action Items:

  • Update the project's documentation and README to indicate support for Python 3.12.
  • Update the package's dependencies and ensure compatibility with Python 3.12.
  • Thoroughly test the package against Python 3.12 to identify and address any potential issues or incompatibilities.
  • Update GitHub actions: replace Python 3.9 with Python 3.12.

Write new tests for nepalidate with full coverage

There are tests written for nepalidate. But the tests are mostly positive test cases and don't have full code coverage.

This task includes writing completely new tests for nepalidate. Also, maintain the test directory according to the package structure. For instance, for nepali.datetime.nepalidate the test will be something like this, tests/test_datetime/test_nepalidate.py

Create a feature for nepali week days with nepaliweek class

The class nepaliweek help us to parse the Nepali week data and allow different formatting and operations on it.

Example:

Initialization:

week = nepaliweek(1)  # Sunday
week = nepaliweek("Sunday")
week = nepaliweek("आइतबार")
week = nepaliweek("आइत")

Usage:

week.value          # 1
week.name           # Sunday
week.abbr           # Sun
week.name_ne        # आइतबार
week.abbr_ne        # आइत

Create a new package for supporting django

Maintaining Django support on the nepali package is hectic. It isn't easy to write test cases for it. Therefore, let's create a new package django-nepali to support this package. This ensures that the nepali package is not responsible for any issues with different frameworks.

For backward compatibility, we will deprecate the support of Django templates and remove it in version 2.X.X. We will redirect the use of Django to another package through our README file.

Note: We had some Django template tag issues in version 1.0.0.

Create a feature for nepali numbers with nepalinumber class

Let's create nepalinumber class which will be compatible with python's int, float, etc numbers. The major features will be comparison, addition, subtraction, multiplication, and division. A lot of features can be added later.

Here are some basic example of this class

from nepali.number import nepalinumber

# initialization
np_number = nepalinumber(1234)
np_number = nepalinumber("1234")
np_number = nepalinumber("१२३४")
np_number = nepalinumber("12.34")

# comparison
np_number == 10
np_number >= nepalinumber("१२")

# addition, subscription, multiplication, division
a = np_number / 10 * nepalinumber("४") + 300 - nepalinumber("१.२")

# output
float(a)
int(a)
str(a)
a.str_ne()  # returns Devanagari number format
a.str_en()  # return in English number format

Proposal for removing locations from py-nepali and creating a new repository for maintaining locations.

Problem Statement

The APIs for the locations don’t seem right in this py-nepali project. Nepali locations are data, not functional code, and this data should be able to be used by any other programming language or project.

Proposed Solution

Let’s create a new repository nepali-locations. This repository will be fully responsible for maintaining the nepali locations, whether it is a typo, incorrect information, or updates from the government.

Advantages

  • Remains as a central database.
  • Can be used in multiple projects, regardless of its programming language or technology.
  • Versions can be maintained if the data gets updated.
  • The data can be served via Github pages.

Disadvantages

  • Projects cannot directly integrate with the data.
    • We will have to download the data and integrate it into their project manually
    • Or, we can use the data URL, but the cost of HTTPS requests is too high in terms of performance and time.
  • If there is any issue with the data, we will have to download the new version data and replace the existing data.

Directory Structure

|---src/
|   |---main.yaml
|
|---dist/
|   |---provinces.json
|   |---districts.json
|   |---municipalities.json
|
|---scripts/
|
|---Makefile
|---README.md
|---LICENSE

Write new tests for nepalidatetime with full coverage

There are tests written for nepalidatetime. But the tests are mostly positive test cases and don't have full code coverage.

This task includes writing completely new tests for nepalidatetime. Also, maintain the test directory according to the package structure. For instance, for nepali.datetime.nepalidatetime the test will be something like this, tests/test_datetime/test_nepalidatetime.py

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.