Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/01walid/py-dz-phone-number
Algerian phone numbers as a value object implementation in Python
https://github.com/01walid/py-dz-phone-number
algeria dz landline mobile phone regex telephone-numbers value-object
Last synced: about 2 months ago
JSON representation
Algerian phone numbers as a value object implementation in Python
- Host: GitHub
- URL: https://github.com/01walid/py-dz-phone-number
- Owner: 01walid
- License: mit
- Created: 2020-06-14T15:23:50.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2020-06-16T13:45:13.000Z (over 4 years ago)
- Last Synced: 2024-08-10T20:35:03.493Z (5 months ago)
- Topics: algeria, dz, landline, mobile, phone, regex, telephone-numbers, value-object
- Language: Python
- Homepage:
- Size: 19.5 KB
- Stars: 28
- Watchers: 3
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Algerian phone numbers as a value object
Inspired from [the PHP implementation](https://github.com/cherifGsoul/php-algerian-mobile-phone-number) with some differences (see below).
------------
Algerian phone numbers as a value object implementation in Python. This can be used in your domain models or be integrated with your favorite framework.
What is value object?
> In computer science, a value object is a small object that represents a simple entity whose equality is not based on identity: i.e. two value objects are equal when they have the same value, not necessarily being the same object.Read more on [wikipedia](https://en.wikipedia.org/wiki/Value_object).
## Installation:
```
pip install dz-phone-numbers
```## Usage:
```python
from dz_phone_number import DZPhoneNumberdz_phone_number = DZPhoneNumber("0599000000") # or DZPhoneNumber.from_string("0599000000")
dz_phone_number.indicative #
dz_phone_number.operator_or_region #
dz_phone_number.suffix # '99000000'dz_phone_number.is_mobile() # True
dz_phone_number.is_landline() # a.k.a Fixe. False
dz_phone_number.is_ooredoo() # True
dz_phone_number.is_djezzy() # false
dz_phone_number.is_annaba() # falseDZPhoneNumber("038123456").is_annaba() # True
# repr:
# str:
str(dz_phone_number) # 0599000000
```### Equality
```python
DZPhoneNumber("0599000000") == DZPhoneNumber("+213 599000000") # True
DZPhoneNumber("(0) 599000000") == DZPhoneNumber("0 599-00-00-00") # True
DZPhoneNumber("(0) 599000000") == DZPhoneNumber("(0) 699000000"") # False
```### Correctness
```Python
try:
DZPhoneNumber("09 12 34 56 78")
except ValueError: # ValueError can catch it
pass
# Otherwise you can also expect `InvalidDZPhoneNumber` (an alias of ValueError).
```
### ImmutabilityThe object can't be modified if you try to modify of its members, a `TypeError` will be raised:
```python
dz_phone_number.number = '038123456' # will raise TypeError.
```# Understanding the regex
03 main parts of the full number are categorized into three groups: indicative (Country Code), Operator or Region (e.g. Ooredoo or Annaba), and the rest of the dial number.
The regex uses Python's [capturing group](https://docs.python.org/3/howto/regex.html#grouping) feature built in its regex engine. Where "Country Code", "Operator or Region" and the "Number" are put into numbered groups when matched.
The regex also uses a conditional statemet in the form of `(?(1)yes|no)` where `(1)` is the capturing group number. The following picture explain how it's working:
## Differences from the PHP implementation (as of writing this):
- This raises a `ValueError` (Python built-in) instead of the broad `Exception` `InvalidDZPhoneNumber` is an alias of `ValueError`.
- A different version of regex with support for landline (a.k.a fixe) numbers.
- Enums are used to both limit landline possible values, and make it extensible (e.g. very easy if, say, a new operator got into Algeria).
- This uses Python regex "capturing groups" feature. Where "Country Code", "Operator or Region" and the "Number" are put in groups when matched.
- pytest are used instead of any other spec or behavior testing.
- Immutability is achieved through `__slots__` and overriding `__setattr__` and `__delattr__`. This was a bit more flexibile that `@dataclass(frozen=True)`.# Bonuses
This is a simple, self-contained problem. One of the reasons I wrote this is to serve as a python package example for the Algerian Python community where:
- The code is [Black](https://github.com/psf/black)-formatted.
- Type annotated code using Python type hints. Checked with [MyPy](http://mypy-lang.org/).
- The project structure follows what's common for Python projects. See the [Hitchhiker guide](https://docs.python-guide.org/writing/structure/).
- A simple `Makefile` within to show how to build this (with Python wheels support) and how to release a package to pypi. Just issue `make` to see the available commands.
- Example `setup.py`
- Testing with pytest.