Zayef 🔥🇲🇦
🇲🇦 The first Ruby gem for generating authentic Moroccan data! Perfect for testing, development, and localization with 300+ real Moroccan names, cities, companies, and cultural elements. From traditional dishes to medical specialties - everything Moroccan! 🔥
🇲🇦 Zayef (زايف) - Generate authentic Moroccan data for testing, development, and localization
✨ What's New in v0.2.0
- 🎯 Complete refactoring following "Less Code, Better Result" philosophy
- 🔧 Generic helper methods (
pick,random_number,random_code,weighted_pick) - 📁 External data files for easy maintenance (JSON format)
- ⚡ Parameterized profiles with age, gender, and city constraints
- 🎲 Weighted sampling for realistic nationality distributions (85% Moroccan)
- 📊 Streaming support for large datasets (JSON/CSV)
- 🔄 Cached data loading for optimal performance
- 🏗️ Modern Ruby with keyword arguments and safe navigation
📦 Installation
Option 1: Bundler (Recommended)
Add this line to your application's Gemfile:
gem 'zayef'Then execute:
bundle installOption 2: RubyGems
Install it yourself as:
gem install zayefOption 3: Manual Installation
git clone https://github.com/merouaneamqor/zayef.git
cd zayef
bundle install🚀 Quick Start
Basic Data Generation
require 'zayef'
# Generate a full name
Zayef.name # => "Youssef Alaoui"
# Generate individual components
Zayef.first_name # => "Fatima"
Zayef.last_name # => "Bennani"
# Generate email with authentic Moroccan domains
Zayef.email # => "ayoub.kabbaj@menara.ma"
Zayef.email(first_name: "Ahmed", last_name: "El Fassi") # => "ahmed.el_fassi@iam.ma"
# Generate phone number (Moroccan format)
Zayef.phone # => "0612345678" or "0712345678"
# Generate address with real Moroccan streets and cities
Zayef.city # => "Casablanca"
Zayef.address # => "123, Av. Hassan II, Rabat"
# Generate Moroccan-specific identifiers
Zayef.cni_number # => "AB123456" (Carte Nationale d'Identité)
Zayef.bank_account # => "MA123456789012345678" (IBAN format)
Zayef.postal_code # => "20000"
Zayef.region # => "Casablanca-Settat"
Zayef.university # => "Université Mohammed V de Rabat"
Zayef.neighborhood # => "Medina"
Zayef.medical_specialty # => "Médecine générale"
Zayef.profession # => "Médecin"
Zayef.traditional_dish # => "Couscous"
Zayef.spice # => "Ras-el-hanout"
Zayef.souk # => "Souk Semmarine"
Zayef.bank # => "Attijariwafa Bank"
Zayef.restaurant # => "Café Clock"
Zayef.hotel # => "Riad Kniza"
Zayef.mosque # => "Mosquée Hassan II"
Zayef.school # => "Lycée Descartes"
Zayef.newspaper # => "Le Matin"
Zayef.festival # => "Festival de Marrakech"🎯 v0.2.0 Advanced Features
Parameterized Profile Generation
Generate profiles with specific constraints for more realistic data:
# Generate profiles with age, gender, and city constraints
profile = Zayef::Generator.profile(age_min: 25, age_max: 35, city: "Casablanca", gender: "Female")
business = Zayef::Generator.business_profile(city: "Rabat")
medical = Zayef::Generator.medical_profile(age_min: 30, age_max: 50)
cultural = Zayef::Generator.cultural_profile(city: "Fès")Bulk Data Generation & Export
Generate multiple records efficiently:
# Generate multiple profiles with constraints
profiles = Zayef::Generator.bulk_data(100, 'personal', city: "Marrakech")
# Export to JSON for API testing
json_data = Zayef::Generator.export_to_json(50, 'medical')
puts json_data
# Export to CSV for data analysis
csv_data = Zayef::Generator.export_to_csv(200, 'business')
puts csv_dataStreaming for Large Datasets
Handle thousands of records without memory issues:
# Generate 10,000 records without loading all in memory
File.open('large_dataset.json', 'w') do |file|
Zayef::Generator.stream_json(10000, 'personal') do |chunk|
file.write(chunk)
end
end
# Stream CSV for data processing pipelines
Zayef::Generator.stream_csv(50000, 'business') do |line|
# Process each line individually
puts line
endGeneric Helper Methods
Use DRY principle with powerful generic helpers:
# Instead of repetitive .sample calls
Zayef::Generator.pick(['option1', 'option2', 'option3'])
# Consistent number generation with constraints
Zayef::Generator.random_number(min: 18, max: 80)
# Pattern-based code generation
Zayef::Generator.random_code(format: 'AA######') # CNI format: "AB123456"
Zayef::Generator.random_code(format: 'MA##################') # IBAN: "MA123456789012345678"
# Weighted sampling for realistic distributions
Zayef::Generator.weighted_pick({
"Moroccan" => 85, # 85% probability
"French" => 5, # 5% probability
"Algerian" => 3, # 3% probability
"Other" => 7 # 7% probability
})Data Management & Customization
Access and manage the underlying data:
# Direct access to data sources
cities = Zayef.data_loader.cities # Array of Moroccan cities
names = Zayef.data_loader.first_names('male') # Male first names
banks = Zayef.data_loader.banks # Moroccan banks
# Reload data cache (useful after custom modifications)
Zayef.reload_data!
# Load custom data
custom_data = Zayef::DataLoader.load_json('path/to/custom_data.json')📊 Data Coverage
Zayef provides authentic Moroccan data across multiple categories:
🇲🇦 Geographic Data
- 91 Moroccan cities (from Casablanca to small towns)
- 12 administrative regions (Casablanca-Settat, Rabat-Salé-Kénitra, etc.)
- Districts by city for consistency (e.g., Casablanca-Anfa, Rabat-Agdal)
- Authentic street names (Av. Hassan II, Rue Mohammed V, etc.)
- Real postal codes (5-digit format)
👥 Personal Data
- 67 male first names + 98 female first names = 165 total names
- 67 authentic last names (Bennani, Alaoui, El Fassi, etc.)
- Gender-specific name generation with realistic distributions
- Age ranges with birth date calculation
- Personal attributes (height, weight, blood type, etc.)
🏢 Business & Professional Data
- Major Moroccan banks (Attijariwafa Bank, Banque Populaire, etc.)
- Industry categories (Technology, Healthcare, Tourism, etc.)
- Company size classifications (1-10 to 1000+ employees)
- Job titles and professions (Médecin, Ingénieur, etc.)
- Business types (SARL, SA, Auto-entrepreneur, etc.)
🏥 Medical Data (Perfect for DabaDoc!)
- 25 medical specialties (Médecine générale, Cardiologie, etc.)
- Complete medical profiles with consistent data
- Emergency contacts and insurance information
- Realistic age distributions for different medical contexts
🎭 Cultural Data
- Traditional dishes (Couscous, Tagine, Pastilla, etc.)
- Moroccan spices (Ras-el-hanout, Safran, Cumin, etc.)
- Famous souks and markets (Souk Semmarine, Souk El Attarine, etc.)
- Restaurants and cafés (Café Clock, Le Jardin, etc.)
- Hotels and riads (Riad Kniza, Hotel Sahrai, etc.)
- Mosques (Hassan II, Koutoubia, Al Quaraouiyine, etc.)
- Universities (Mohammed V, Hassan II, Cadi Ayyad, etc.)
- Festivals (Mawazine, Jazzablanca, Festival de Marrakech, etc.)
📱 Modern Data
- Social media platforms popular in Morocco
- Transportation methods (Taxi, Bus, Train, etc.)
- Hobbies and sports (Football, Basketball, etc.)
- Music genres (Chaabi, Gnawa, Rai, etc.)
🔧 Usage Examples
Basic Usage
require 'zayef'
# Generate a full name
Zayef.name # => "Youssef Alaoui"
# Generate individual components
Zayef.first_name # => "Fatima"
Zayef.last_name # => "Bennani"
# Generate email with authentic Moroccan domains
Zayef.email # => "ayoub.kabbaj@menara.ma"
Zayef.email(first_name: "Ahmed", last_name: "El Fassi") # => "ahmed.el_fassi@iam.ma"
# Generate phone number (Moroccan format)
Zayef.phone # => "0612345678" or "0712345678"
# Generate address with real Moroccan streets and cities
Zayef.city # => "Casablanca"
Zayef.address # => "123, Av. Hassan II, Rabat"
# Generate Moroccan-specific identifiers
Zayef.cni_number # => "AB123456" (Carte Nationale d'Identité)
Zayef.bank_account # => "MA123456789012345678" (IBAN format)
Zayef.postal_code # => "20000"
Zayef.region # => "Casablanca-Settat"
Zayef.university # => "Université Mohammed V de Rabat"
Zayef.neighborhood # => "Medina"
Zayef.medical_specialty # => "Médecine générale"
Zayef.profession # => "Médecin"
Zayef.traditional_dish # => "Couscous"
Zayef.spice # => "Ras-el-hanout"
Zayef.souk # => "Souk Semmarine"
Zayef.bank # => "Attijariwafa Bank"
Zayef.restaurant # => "Café Clock"
Zayef.hotel # => "Riad Kniza"
Zayef.mosque # => "Mosquée Hassan II"
Zayef.school # => "Lycée Descartes"
Zayef.newspaper # => "Le Matin"
Zayef.festival # => "Festival de Marrakech"Advanced Usage
Parameterized Profile Generation
# Generate profiles with specific constraints for more realistic data
profile = Zayef::Generator.profile(age_min: 25, age_max: 35, city: "Casablanca", gender: "Female")
business = Zayef::Generator.business_profile(city: "Rabat")
medical = Zayef::Generator.medical_profile(age_min: 30, age_max: 50)
cultural = Zayef::Generator.cultural_profile(city: "Fès")Bulk Data Generation & Export
# Generate multiple profiles with constraints
profiles = Zayef::Generator.bulk_data(100, 'personal', city: "Marrakech")
# Export to JSON for API testing
json_data = Zayef::Generator.export_to_json(50, 'medical')
puts json_data
# Export to CSV for data analysis
csv_data = Zayef::Generator.export_to_csv(200, 'business')
puts csv_dataStreaming for Large Datasets
# Generate 10,000 records without loading all in memory
File.open('large_dataset.json', 'w') do |file|
Zayef::Generator.stream_json(10000, 'personal') do |chunk|
file.write(chunk)
end
end
# Stream CSV for data processing pipelines
Zayef::Generator.stream_csv(50000, 'business') do |line|
# Process each line individually
puts line
endGeneric Helper Methods
# Instead of repetitive .sample calls
Zayef::Generator.pick(['option1', 'option2', 'option3'])
# Consistent number generation with constraints
Zayef::Generator.random_number(min: 18, max: 80)
# Pattern-based code generation
Zayef::Generator.random_code(format: 'AA######') # CNI format: "AB123456"
Zayef::Generator.random_code(format: 'MA##################') # IBAN: "MA123456789012345678"
# Weighted sampling for realistic distributions
Zayef::Generator.weighted_pick({
"Moroccan" => 85, # 85% probability
"French" => 5, # 5% probability
"Algerian" => 3, # 3% probability
"Other" => 7 # 7% probability
})🎯 Perfect for DabaDoc & Moroccan Apps
Zayef is specifically designed for Moroccan healthcare and business applications:
# Generate realistic patient profiles
patient = Zayef::Generator.medical_profile(age_min: 25, age_max: 65)
puts "Patient: #{patient[:patient_name]}"
puts "Age: #{patient[:age]}"
puts "Specialty: #{patient[:medical_specialty]}"
puts "Emergency Contact: #{patient[:emergency_contact]}"
# Generate doctor profiles
doctor = Zayef::Generator.medical_profile(age_min: 30, age_max: 70)
puts "Doctor: #{doctor[:doctor_name]}"
puts "Specialty: #{doctor[:medical_specialty]}"
puts "Clinic: #{doctor[:clinic_address]}"
# Generate realistic test data for Moroccan healthcare systems
patients = Zayef::Generator.bulk_data(1000, 'medical', city: "Casablanca")
appointments_json = Zayef::Generator.export_to_json(500, 'medical')🌟 Key Features
- 🇲🇦 Authentic Moroccan Data: Real names, cities, companies, and cultural elements
- ⚡ High Performance: Cached data loading and streaming support for large datasets
- 🎯 Parameterized Generation: Age, gender, city, and other constraints
- 📊 Multiple Export Formats: JSON, CSV, and streaming support
- 🔧 DRY Principle: Generic helper methods eliminate code duplication
- 🎲 Realistic Distributions: Weighted sampling for authentic data
- 🏥 DabaDoc Ready: Perfect for Moroccan healthcare applications
- 📱 Modern Data: Social media, transportation, hobbies, and more
- 🛠️ Easy Customization: External JSON files for data modification
- 💎 Modern Ruby: Keyword arguments, safe navigation, and best practices
📈 Performance & Scalability
Zayef is optimized for both small and large-scale data generation:
- Memory Efficient: Streaming support for datasets with millions of records
- Fast Generation: Cached data loading for optimal performance
- Bulk Operations: Generate hundreds of profiles with consistent constraints
- Export Ready: JSON and CSV export for integration with other systems
🤝 Contributing
We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Add your data to the appropriate JSON file in
data/ - Update the DataLoader if needed
- Add tests and update documentation
- Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments
- Moroccan Community for providing authentic cultural data
- Ruby Community for the excellent tooling and ecosystem
- DabaDoc for inspiring the medical data features
- All contributors who help make Zayef better
🔗 Links
- 📚 Documentation: https://github.com/merouaneamqor/zayef
- 💎 RubyGems: https://rubygems.org/gems/zayef
- 🐛 Bug Reports: https://github.com/merouaneamqor/zayef/issues
- 🚀 Source Code: https://github.com/merouaneamqor/zayef
- 📝 Changelog: https://github.com/merouaneamqor/zayef/blob/main/CHANGELOG.md
Made with ❤️ in Morocco 🇲🇦 | Built for the world 🌍