Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 56 additions & 7 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,13 +1,62 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.logs/
.Python
*.txt
*.py[cod]
*$py.class

# Database locks / journals / temp backups (do NOT ignore faker_pk/faker_pk.db itself)
*.db-journal
*.db-wal
*.db-shm
*.db.bak

# Distribution / packaging
build/
develop-eggs/
dist/
*.egg-info
downloads/
eggs/
.eggs/
build/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# Virtual environments
venv/
.env
.venv/
.venv
ENV/
env/
active_env/

# Testing / coverage
.pytest_cache/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.run/

# Editors and IDEs
.vscode/
.idea/
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

.vscode/
# Miscellaneous
.DS_Store
*.logs
63 changes: 35 additions & 28 deletions faker_pk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@
from .address import city, province, full_address
from .company import company_name, industry_name, iban, bank_name, salary, job_title_with_industry, job_title
from .provider import FakerPKProvider


from .education import institution, student_dob, student_profile



class FakerPK:
"""Generate fake Pakistani names, addresses, CNICs, phone numbers, and more."""
def _generate_multiple(self, func, count):

def _generate_multiple(self, func, count, **kwargs):
"""Generate one or many values based on count."""
if count == 1:
return func()
return [func() for _ in range(count)]
return func(**kwargs)
return [func(**kwargs) for _ in range(count)]

# --------------------
# Personal Info
Expand All @@ -22,11 +24,11 @@ def male_name(self, count=1):
def female_name(self, count=1):
return self._generate_multiple(female_name, count)

def cnic(self, count=1):
return self._generate_multiple(cnic, count)
def cnic(self, count=1, gender=None):
return self._generate_multiple(cnic, count, gender=gender)

def phone_number(self, count=1):
return self._generate_multiple(phone_number, count)
def phone_number(self, count=1, provider=None):
return self._generate_multiple(phone_number, count, provider=provider)

def sim_provider(self, count=1):
return self._generate_multiple(sim_provider, count)
Expand All @@ -43,44 +45,49 @@ def dob(self, count=1):
# --------------------
# Address Info
# --------------------
def city(self, count=1):
return self._generate_multiple(city, count)
def city(self, count=1, province=None):
return self._generate_multiple(city, count, province=province)

def province(self, count=1):
return self._generate_multiple(province, count)
def province(self, count=1, city=None):
return self._generate_multiple(province, count, city=city)

def full_address(self, count=1):
return self._generate_multiple(full_address, count)
def full_address(self, count=1, city=None, province=None):
return self._generate_multiple(full_address, count, city=city, province=province)

# --------------------
# Company Info
# --------------------
def company_name(self, count=1):
return self._generate_multiple(company_name, count)
def company_name(self, count=1, industry=None):
return self._generate_multiple(company_name, count, industry=industry)

def industry_name(self, count=1):
return self._generate_multiple(industry_name, count)

def bank_name(self, count=1):
return self._generate_multiple(bank_name, count)

def iban(self, count=1):
return self._generate_multiple(iban, count)
def iban(self, count=1, bank=None):
return self._generate_multiple(iban, count, bank=bank)

# --------------------
# Job Info
# --------------------
def job_title(self, count=1, industry=None):
if count == 1:
return job_title(industry=industry)
return [job_title(industry=industry) for _ in range(count)]

return self._generate_multiple(job_title, count, industry=industry)

def job_title_with_industry(self, count=1):
return self._generate_multiple(job_title_with_industry, count)

def salary(self, count=1, industry=None):
"""Generate random salary from company.py."""
if count == 1:
return salary(industry=industry)
return [salary(industry=industry) for _ in range(count)]
return self._generate_multiple(salary, count, industry=industry)

# --------------------
# Institution Info
# --------------------
def institution(self, count=1, level=None, city=None, province=None):
return self._generate_multiple(institution, count, level=level, city=city, province=province)

def student_profile(self, count=1, level=None, province=None):
return self._generate_multiple(student_profile, count, level=level, province=province)

__all__ = ["FakerPK", "FakerPKProvider"]
90 changes: 41 additions & 49 deletions faker_pk/address.py
Original file line number Diff line number Diff line change
@@ -1,52 +1,44 @@
import random

# Mapping of provinces to their major cities/towns
PROVINCE_CITIES = {
"Punjab": [
"Lahore", "Faisalabad", "Rawalpindi", "Multan", "Gujranwala",
"Sialkot", "Bahawalpur", "Sargodha", "Sahiwal", "Dera Ghazi Khan"
],
"Sindh": [
"Karachi", "Hyderabad", "Sukkur", "Larkana", "Mirpur Khas",
"Nawabshah", "Shikarpur", "Khairpur", "Jacobabad", "Thatta"
],
"Khyber Pakhtunkhwa": [
"Peshawar", "Mardan", "Abbottabad", "Swat", "Charsadda",
"Bannu", "Kohat", "Dera Ismail Khan", "Haripur", "Mansehra"
],
"Balochistan": [
"Quetta", "Gwadar", "Sibi", "Khuzdar", "Turbat",
"Chaman", "Zhob", "Bela", "Makran", "Pasni"
],
"Gilgit Baltistan": [
"Gilgit", "Skardu", "Hunza", "Ghizer", "Diamer",
"Astore", "Shigar", "Kharmang"
],
"Islamabad Capital Territory": ["Islamabad"]
}


def city_and_province():
"""Return a tuple of (city, province) based on accurate mapping."""
province_name = random.choice(list(PROVINCE_CITIES.keys()))
city_name = random.choice(PROVINCE_CITIES[province_name])
return city_name, province_name


def city():
"""Return a random Pakistani city."""
return city_and_province()[0]


def province():
"""Return the province corresponding to the random city."""
return city_and_province()[1]


def full_address():
"""Generate a realistic full Pakistani address."""
import random
from .utils import query_value, query_row


def city(province=None):
"""Return a random Pakistani city. Optionally filter by province."""
if province:
return query_value(
"SELECT city FROM locations WHERE province = ? ORDER BY RANDOM() LIMIT 1",
(province,)
)
return query_value("SELECT city FROM locations ORDER BY RANDOM() LIMIT 1")


def province(city=None):
"""Return a random province. If city is given, return its matching province."""
if city:
return query_value(
"SELECT province FROM locations WHERE city = ? LIMIT 1", (city,)
)
return query_value("SELECT province FROM locations ORDER BY RANDOM() LIMIT 1")


def full_address(city=None, province=None):
"""Generate a realistic full Pakistani address with real postal code."""
if city:
row = query_row(
"SELECT city, province, postal_code FROM locations WHERE city = ? LIMIT 1",
(city,)
)
elif province:
row = query_row(
"SELECT city, province, postal_code FROM locations WHERE province = ? ORDER BY RANDOM() LIMIT 1",
(province,)
)
else:
row = query_row(
"SELECT city, province, postal_code FROM locations ORDER BY RANDOM() LIMIT 1"
)

city_name, province_name, postal_code = row
house_no = f"House No. {random.randint(1, 999)}"
street = f"Street No. {random.randint(1, 30)}"
city_name, province_name = city_and_province()
postal_code = random.randint(10000, 99999)
return f"{house_no}, {street}, {city_name}, {province_name}, {postal_code}"
Loading