zayef 0.2.0 → 0.2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +269 -337
- data/REFACTORING.md +220 -0
- data/data/moroccan_business.json +97 -0
- data/data/moroccan_culture.json +127 -0
- data/data/moroccan_geography.json +99 -0
- data/data/moroccan_names.json +65 -0
- data/examples/refactored_usage.rb +85 -0
- data/lib/zayef/data_loader.rb +245 -0
- data/lib/zayef/version.rb +1 -1
- data/test_user_code.rb +41 -0
- data/user_example.rb +34 -0
- data/zayef.gemspec +3 -0
- metadata +13 -1
data/README.md
CHANGED
@@ -3,7 +3,10 @@
|
|
3
3
|
**🇲🇦 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! 🔥
|
4
4
|
|
5
5
|
[](https://badge.fury.io/rb/zayef)
|
6
|
-
[](https://github.com/merouaneamqor/zayef/actions)
|
7
|
+
[](https://opensource.org/licenses/MIT)
|
8
|
+
|
9
|
+
> 🇲🇦 **Zayef (زايف)** - Generate authentic Moroccan data for testing, development, and localization
|
7
10
|
|
8
11
|
## ✨ What's New in v0.2.0
|
9
12
|
|
@@ -11,26 +14,39 @@
|
|
11
14
|
- 🔧 **Generic helper methods** (`pick`, `random_number`, `random_code`, `weighted_pick`)
|
12
15
|
- 📁 **External data files** for easy maintenance (JSON format)
|
13
16
|
- ⚡ **Parameterized profiles** with age, gender, and city constraints
|
14
|
-
- 🎲 **Weighted sampling** for realistic nationality distributions
|
17
|
+
- 🎲 **Weighted sampling** for realistic nationality distributions (85% Moroccan)
|
15
18
|
- 📊 **Streaming support** for large datasets (JSON/CSV)
|
16
19
|
- 🔄 **Cached data loading** for optimal performance
|
17
20
|
- 🏗️ **Modern Ruby** with keyword arguments and safe navigation
|
18
21
|
|
19
|
-
## Installation
|
22
|
+
## 📦 Installation
|
20
23
|
|
24
|
+
### Option 1: Bundler (Recommended)
|
21
25
|
Add this line to your application's Gemfile:
|
22
26
|
|
23
27
|
```ruby
|
24
28
|
gem 'zayef'
|
25
29
|
```
|
26
30
|
|
27
|
-
|
31
|
+
Then execute:
|
28
32
|
|
29
|
-
|
33
|
+
```bash
|
34
|
+
bundle install
|
35
|
+
```
|
30
36
|
|
31
|
-
|
37
|
+
### Option 2: RubyGems
|
38
|
+
Install it yourself as:
|
32
39
|
|
33
|
-
|
40
|
+
```bash
|
41
|
+
gem install zayef
|
42
|
+
```
|
43
|
+
|
44
|
+
### Option 3: Manual Installation
|
45
|
+
```bash
|
46
|
+
git clone https://github.com/merouaneamqor/zayef.git
|
47
|
+
cd zayef
|
48
|
+
bundle install
|
49
|
+
```
|
34
50
|
|
35
51
|
## 🚀 Quick Start
|
36
52
|
|
@@ -46,22 +62,21 @@ Zayef.name # => "Youssef Alaoui"
|
|
46
62
|
Zayef.first_name # => "Fatima"
|
47
63
|
Zayef.last_name # => "Bennani"
|
48
64
|
|
49
|
-
# Generate email
|
50
|
-
Zayef.email # => "ayoub.kabbaj@
|
51
|
-
Zayef.email(first_name: "Ahmed", last_name: "El Fassi") # => "ahmed.el_fassi@
|
65
|
+
# Generate email with authentic Moroccan domains
|
66
|
+
Zayef.email # => "ayoub.kabbaj@menara.ma"
|
67
|
+
Zayef.email(first_name: "Ahmed", last_name: "El Fassi") # => "ahmed.el_fassi@iam.ma"
|
52
68
|
|
53
69
|
# Generate phone number (Moroccan format)
|
54
|
-
Zayef.phone # => "0612345678"
|
70
|
+
Zayef.phone # => "0612345678" or "0712345678"
|
55
71
|
|
56
|
-
# Generate address
|
72
|
+
# Generate address with real Moroccan streets and cities
|
57
73
|
Zayef.city # => "Casablanca"
|
58
74
|
Zayef.address # => "123, Av. Hassan II, Rabat"
|
59
75
|
|
60
|
-
# Generate Moroccan-specific
|
61
|
-
Zayef.cni_number # => "AB123456"
|
62
|
-
Zayef.bank_account # => "MA123456789012345678"
|
76
|
+
# Generate Moroccan-specific identifiers
|
77
|
+
Zayef.cni_number # => "AB123456" (Carte Nationale d'Identité)
|
78
|
+
Zayef.bank_account # => "MA123456789012345678" (IBAN format)
|
63
79
|
Zayef.postal_code # => "20000"
|
64
|
-
Zayef.company_name # => "Groupe Maroc"
|
65
80
|
Zayef.region # => "Casablanca-Settat"
|
66
81
|
Zayef.university # => "Université Mohammed V de Rabat"
|
67
82
|
Zayef.neighborhood # => "Medina"
|
@@ -79,30 +94,41 @@ Zayef.newspaper # => "Le Matin"
|
|
79
94
|
Zayef.festival # => "Festival de Marrakech"
|
80
95
|
```
|
81
96
|
|
82
|
-
|
97
|
+
## 🎯 v0.2.0 Advanced Features
|
98
|
+
|
99
|
+
### Parameterized Profile Generation
|
100
|
+
|
101
|
+
Generate profiles with specific constraints for more realistic data:
|
83
102
|
|
84
|
-
#### Parameterized Profile Generation
|
85
103
|
```ruby
|
86
|
-
# Generate profiles with
|
104
|
+
# Generate profiles with age, gender, and city constraints
|
87
105
|
profile = Zayef::Generator.profile(age_min: 25, age_max: 35, city: "Casablanca", gender: "Female")
|
88
106
|
business = Zayef::Generator.business_profile(city: "Rabat")
|
89
107
|
medical = Zayef::Generator.medical_profile(age_min: 30, age_max: 50)
|
90
108
|
cultural = Zayef::Generator.cultural_profile(city: "Fès")
|
91
109
|
```
|
92
110
|
|
93
|
-
|
111
|
+
### Bulk Data Generation & Export
|
112
|
+
|
113
|
+
Generate multiple records efficiently:
|
114
|
+
|
94
115
|
```ruby
|
95
|
-
# Generate multiple profiles
|
116
|
+
# Generate multiple profiles with constraints
|
96
117
|
profiles = Zayef::Generator.bulk_data(100, 'personal', city: "Marrakech")
|
97
118
|
|
98
|
-
# Export to JSON
|
119
|
+
# Export to JSON for API testing
|
99
120
|
json_data = Zayef::Generator.export_to_json(50, 'medical')
|
121
|
+
puts json_data
|
100
122
|
|
101
|
-
# Export to CSV
|
123
|
+
# Export to CSV for data analysis
|
102
124
|
csv_data = Zayef::Generator.export_to_csv(200, 'business')
|
125
|
+
puts csv_data
|
103
126
|
```
|
104
127
|
|
105
|
-
|
128
|
+
### Streaming for Large Datasets
|
129
|
+
|
130
|
+
Handle thousands of records without memory issues:
|
131
|
+
|
106
132
|
```ruby
|
107
133
|
# Generate 10,000 records without loading all in memory
|
108
134
|
File.open('large_dataset.json', 'w') do |file|
|
@@ -110,380 +136,286 @@ File.open('large_dataset.json', 'w') do |file|
|
|
110
136
|
file.write(chunk)
|
111
137
|
end
|
112
138
|
end
|
139
|
+
|
140
|
+
# Stream CSV for data processing pipelines
|
141
|
+
Zayef::Generator.stream_csv(50000, 'business') do |line|
|
142
|
+
# Process each line individually
|
143
|
+
puts line
|
144
|
+
end
|
113
145
|
```
|
114
146
|
|
115
|
-
|
147
|
+
### Generic Helper Methods
|
148
|
+
|
149
|
+
Use DRY principle with powerful generic helpers:
|
150
|
+
|
116
151
|
```ruby
|
117
152
|
# Instead of repetitive .sample calls
|
118
153
|
Zayef::Generator.pick(['option1', 'option2', 'option3'])
|
119
154
|
|
120
|
-
# Consistent number generation
|
155
|
+
# Consistent number generation with constraints
|
121
156
|
Zayef::Generator.random_number(min: 18, max: 80)
|
122
157
|
|
123
158
|
# Pattern-based code generation
|
124
|
-
Zayef::Generator.random_code(format: 'AA######') # CNI format
|
125
|
-
Zayef::Generator.random_code(format: 'MA##################') # IBAN
|
159
|
+
Zayef::Generator.random_code(format: 'AA######') # CNI format: "AB123456"
|
160
|
+
Zayef::Generator.random_code(format: 'MA##################') # IBAN: "MA123456789012345678"
|
126
161
|
|
127
162
|
# Weighted sampling for realistic distributions
|
128
163
|
Zayef::Generator.weighted_pick({
|
129
|
-
"Moroccan" => 85,
|
130
|
-
"French" => 5,
|
131
|
-
"Algerian" => 3,
|
132
|
-
"Other" => 7
|
164
|
+
"Moroccan" => 85, # 85% probability
|
165
|
+
"French" => 5, # 5% probability
|
166
|
+
"Algerian" => 3, # 3% probability
|
167
|
+
"Other" => 7 # 7% probability
|
133
168
|
})
|
134
169
|
```
|
135
170
|
|
136
|
-
###
|
171
|
+
### Data Management & Customization
|
137
172
|
|
138
|
-
|
139
|
-
# Personal attributes
|
140
|
-
Zayef.age # => 34
|
141
|
-
Zayef.gender # => "Male"
|
142
|
-
Zayef.marital_status # => "Marié"
|
143
|
-
Zayef.blood_type # => "A+"
|
144
|
-
Zayef.height # => 175
|
145
|
-
Zayef.weight # => 70
|
146
|
-
Zayef.eye_color # => "Marron"
|
147
|
-
Zayef.hair_color # => "Noir"
|
148
|
-
Zayef.religion # => "Musulman"
|
149
|
-
Zayef.nationality # => "Marocaine"
|
150
|
-
Zayef.language # => "Français"
|
151
|
-
Zayef.education_level # => "Licence"
|
152
|
-
Zayef.income_range # => "10000-15000 MAD"
|
153
|
-
Zayef.birth_date # => #<Date: 1989-03-15>
|
154
|
-
```
|
155
|
-
|
156
|
-
### 🆕 NEW: Business & Professional Data
|
173
|
+
Access and manage the underlying data:
|
157
174
|
|
158
175
|
```ruby
|
159
|
-
#
|
160
|
-
Zayef.
|
161
|
-
Zayef.
|
162
|
-
Zayef.
|
163
|
-
Zayef.work_experience # => 8
|
164
|
-
Zayef.salary # => 15000
|
165
|
-
Zayef.work_schedule # => "CDI"
|
166
|
-
Zayef.business_type # => "SARL"
|
167
|
-
Zayef.tax_id # => "RC123456"
|
168
|
-
Zayef.trade_register # => "TR789012"
|
169
|
-
```
|
176
|
+
# Direct access to data sources
|
177
|
+
cities = Zayef.data_loader.cities # Array of Moroccan cities
|
178
|
+
names = Zayef.data_loader.first_names('male') # Male first names
|
179
|
+
banks = Zayef.data_loader.banks # Moroccan banks
|
170
180
|
|
171
|
-
|
181
|
+
# Reload data cache (useful after custom modifications)
|
182
|
+
Zayef.reload_data!
|
172
183
|
|
173
|
-
|
174
|
-
|
175
|
-
Zayef.hobby # => "Football"
|
176
|
-
Zayef.sport # => "Natation"
|
177
|
-
Zayef.music_genre # => "Chaabi"
|
178
|
-
Zayef.movie_genre # => "Comédie"
|
179
|
-
Zayef.social_media # => "Instagram"
|
180
|
-
Zayef.transportation # => "Voiture personnelle"
|
181
|
-
Zayef.pet # => "Chat"
|
182
|
-
Zayef.favorite_color # => "Bleu"
|
184
|
+
# Load custom data
|
185
|
+
custom_data = Zayef::DataLoader.load_json('path/to/custom_data.json')
|
183
186
|
```
|
184
187
|
|
185
|
-
|
186
|
-
|
188
|
+
## 📊 Data Coverage
|
189
|
+
|
190
|
+
Zayef provides authentic Moroccan data across multiple categories:
|
191
|
+
|
192
|
+
### 🇲🇦 Geographic Data
|
193
|
+
- **91 Moroccan cities** (from Casablanca to small towns)
|
194
|
+
- **12 administrative regions** (Casablanca-Settat, Rabat-Salé-Kénitra, etc.)
|
195
|
+
- **Districts by city** for consistency (e.g., Casablanca-Anfa, Rabat-Agdal)
|
196
|
+
- **Authentic street names** (Av. Hassan II, Rue Mohammed V, etc.)
|
197
|
+
- **Real postal codes** (5-digit format)
|
198
|
+
|
199
|
+
### 👥 Personal Data
|
200
|
+
- **67 male first names** + **98 female first names** = **165 total names**
|
201
|
+
- **67 authentic last names** (Bennani, Alaoui, El Fassi, etc.)
|
202
|
+
- **Gender-specific name generation** with realistic distributions
|
203
|
+
- **Age ranges** with birth date calculation
|
204
|
+
- **Personal attributes** (height, weight, blood type, etc.)
|
205
|
+
|
206
|
+
### 🏢 Business & Professional Data
|
207
|
+
- **Major Moroccan banks** (Attijariwafa Bank, Banque Populaire, etc.)
|
208
|
+
- **Industry categories** (Technology, Healthcare, Tourism, etc.)
|
209
|
+
- **Company size classifications** (1-10 to 1000+ employees)
|
210
|
+
- **Job titles and professions** (Médecin, Ingénieur, etc.)
|
211
|
+
- **Business types** (SARL, SA, Auto-entrepreneur, etc.)
|
212
|
+
|
213
|
+
### 🏥 Medical Data (Perfect for DabaDoc!)
|
214
|
+
- **25 medical specialties** (Médecine générale, Cardiologie, etc.)
|
215
|
+
- **Complete medical profiles** with consistent data
|
216
|
+
- **Emergency contacts** and insurance information
|
217
|
+
- **Realistic age distributions** for different medical contexts
|
218
|
+
|
219
|
+
### 🎭 Cultural Data
|
220
|
+
- **Traditional dishes** (Couscous, Tagine, Pastilla, etc.)
|
221
|
+
- **Moroccan spices** (Ras-el-hanout, Safran, Cumin, etc.)
|
222
|
+
- **Famous souks and markets** (Souk Semmarine, Souk El Attarine, etc.)
|
223
|
+
- **Restaurants and cafés** (Café Clock, Le Jardin, etc.)
|
224
|
+
- **Hotels and riads** (Riad Kniza, Hotel Sahrai, etc.)
|
225
|
+
- **Mosques** (Hassan II, Koutoubia, Al Quaraouiyine, etc.)
|
226
|
+
- **Universities** (Mohammed V, Hassan II, Cadi Ayyad, etc.)
|
227
|
+
- **Festivals** (Mawazine, Jazzablanca, Festival de Marrakech, etc.)
|
228
|
+
|
229
|
+
### 📱 Modern Data
|
230
|
+
- **Social media platforms** popular in Morocco
|
231
|
+
- **Transportation methods** (Taxi, Bus, Train, etc.)
|
232
|
+
- **Hobbies and sports** (Football, Basketball, etc.)
|
233
|
+
- **Music genres** (Chaabi, Gnawa, Rai, etc.)
|
234
|
+
|
235
|
+
## 🔧 Usage Examples
|
236
|
+
|
237
|
+
### Basic Usage
|
187
238
|
```ruby
|
188
|
-
|
189
|
-
Zayef.province # => "Casablanca"
|
190
|
-
Zayef.district # => "Casablanca-Anfa"
|
191
|
-
Zayef.district(city: 'Rabat') # => "Rabat-Hassan"
|
192
|
-
Zayef.landmark # => "Mosquée Hassan II"
|
193
|
-
Zayef.climate # => "Méditerranéen"
|
194
|
-
Zayef.timezone # => "GMT+1"
|
195
|
-
Zayef.currency # => "MAD (Dirham Marocain)"
|
196
|
-
```
|
197
|
-
|
198
|
-
### 🆕 NEW: Complete Profile Generation
|
239
|
+
require 'zayef'
|
199
240
|
|
200
|
-
|
201
|
-
#
|
202
|
-
personal_profile = Zayef.profile
|
203
|
-
# => {
|
204
|
-
# name: "Youssef Alaoui",
|
205
|
-
# age: 34,
|
206
|
-
# gender: "Male",
|
207
|
-
# email: "youssef.alaoui@gmail.com",
|
208
|
-
# phone: "0612345678",
|
209
|
-
# city: "Casablanca",
|
210
|
-
# region: "Casablanca-Settat",
|
211
|
-
# profession: "Ingénieur",
|
212
|
-
# education_level: "Licence",
|
213
|
-
# income_range: "10000-15000 MAD",
|
214
|
-
# hobby: "Football",
|
215
|
-
# # ... and more
|
216
|
-
# }
|
217
|
-
|
218
|
-
# Medical profile (perfect for DabaDoc)
|
219
|
-
medical_profile = Zayef.medical_profile
|
220
|
-
# => {
|
221
|
-
# patient_name: "Fatima Bennani",
|
222
|
-
# age: 28,
|
223
|
-
# gender: "Female",
|
224
|
-
# blood_type: "A+",
|
225
|
-
# height: 165,
|
226
|
-
# weight: 60,
|
227
|
-
# medical_specialty: "Pédiatrie",
|
228
|
-
# doctor_name: "Dr. Ahmed El Fassi",
|
229
|
-
# clinic_address: "123, Av. Hassan II, Rabat",
|
230
|
-
# # ... and more
|
231
|
-
# }
|
232
|
-
|
233
|
-
# Business profile
|
234
|
-
business_profile = Zayef.business_profile
|
235
|
-
# => {
|
236
|
-
# company_name: "Groupe Maroc",
|
237
|
-
# industry: "Technologie",
|
238
|
-
# company_size: "51-200 employés",
|
239
|
-
# business_type: "SARL",
|
240
|
-
# tax_id: "RC123456",
|
241
|
-
# # ... and more
|
242
|
-
# }
|
243
|
-
|
244
|
-
# Cultural profile
|
245
|
-
cultural_profile = Zayef.cultural_profile
|
246
|
-
# => {
|
247
|
-
# name: "Amina Chakir",
|
248
|
-
# city: "Marrakech",
|
249
|
-
# traditional_dish: "Couscous",
|
250
|
-
# music_genre: "Gnawa",
|
251
|
-
# festival: "Festival de Marrakech",
|
252
|
-
# # ... and more
|
253
|
-
# }
|
254
|
-
```
|
241
|
+
# Generate a full name
|
242
|
+
Zayef.name # => "Youssef Alaoui"
|
255
243
|
|
256
|
-
|
244
|
+
# Generate individual components
|
245
|
+
Zayef.first_name # => "Fatima"
|
246
|
+
Zayef.last_name # => "Bennani"
|
257
247
|
|
258
|
-
|
259
|
-
#
|
260
|
-
|
261
|
-
# => Array of 10 personal profiles
|
248
|
+
# Generate email with authentic Moroccan domains
|
249
|
+
Zayef.email # => "ayoub.kabbaj@menara.ma"
|
250
|
+
Zayef.email(first_name: "Ahmed", last_name: "El Fassi") # => "ahmed.el_fassi@iam.ma"
|
262
251
|
|
263
|
-
#
|
264
|
-
|
265
|
-
# => JSON string with 5 medical profiles
|
252
|
+
# Generate phone number (Moroccan format)
|
253
|
+
Zayef.phone # => "0612345678" or "0712345678"
|
266
254
|
|
267
|
-
#
|
268
|
-
|
269
|
-
# =>
|
255
|
+
# Generate address with real Moroccan streets and cities
|
256
|
+
Zayef.city # => "Casablanca"
|
257
|
+
Zayef.address # => "123, Av. Hassan II, Rabat"
|
270
258
|
|
271
|
-
#
|
272
|
-
|
273
|
-
# =>
|
259
|
+
# Generate Moroccan-specific identifiers
|
260
|
+
Zayef.cni_number # => "AB123456" (Carte Nationale d'Identité)
|
261
|
+
Zayef.bank_account # => "MA123456789012345678" (IBAN format)
|
262
|
+
Zayef.postal_code # => "20000"
|
263
|
+
Zayef.region # => "Casablanca-Settat"
|
264
|
+
Zayef.university # => "Université Mohammed V de Rabat"
|
265
|
+
Zayef.neighborhood # => "Medina"
|
266
|
+
Zayef.medical_specialty # => "Médecine générale"
|
267
|
+
Zayef.profession # => "Médecin"
|
268
|
+
Zayef.traditional_dish # => "Couscous"
|
269
|
+
Zayef.spice # => "Ras-el-hanout"
|
270
|
+
Zayef.souk # => "Souk Semmarine"
|
271
|
+
Zayef.bank # => "Attijariwafa Bank"
|
272
|
+
Zayef.restaurant # => "Café Clock"
|
273
|
+
Zayef.hotel # => "Riad Kniza"
|
274
|
+
Zayef.mosque # => "Mosquée Hassan II"
|
275
|
+
Zayef.school # => "Lycée Descartes"
|
276
|
+
Zayef.newspaper # => "Le Matin"
|
277
|
+
Zayef.festival # => "Festival de Marrakech"
|
274
278
|
```
|
275
279
|
|
276
|
-
|
277
|
-
|
278
|
-
### 🎯 **Personal Information**
|
279
|
-
- 🏠 **Moroccan Names**: 80+ authentic first names (masculin & féminin) + 50+ family names
|
280
|
-
- 📧 **Email Generation**: Realistic emails with Moroccan domains (menara.ma, iam.ma, orange.ma)
|
281
|
-
- 📱 **Phone Numbers**: Moroccan mobile format (06/07 prefixes)
|
282
|
-
- 🏙️ **Cities & Addresses**: 50+ real Moroccan cities + authentic street names
|
283
|
-
- 🏡 **Neighborhoods**: Famous districts (Medina, Gueliz, Maarif, etc.)
|
284
|
-
- 🆔 **CNI Numbers**: Moroccan ID format (2 letters + 6 digits)
|
285
|
-
- 🏦 **Bank Accounts**: Moroccan format with MA prefix
|
286
|
-
- 📮 **Postal Codes**: 5-digit Moroccan postal codes
|
287
|
-
|
288
|
-
### 🆕 **Enhanced Personal Data**
|
289
|
-
- 👤 **Demographics**: Age, gender, marital status, nationality, religion
|
290
|
-
- 🩸 **Medical Info**: Blood type, height, weight, eye/hair color
|
291
|
-
- 🎓 **Education**: Education levels from primary to doctorate
|
292
|
-
- 💰 **Financial**: Income ranges in Moroccan Dirhams
|
293
|
-
- 🌍 **Languages**: Languages spoken in Morocco
|
294
|
-
- 📅 **Dates**: Birth dates with realistic age ranges
|
295
|
-
|
296
|
-
### 🏢 **Professional & Business**
|
297
|
-
- 👨⚕️ **Medical Specialties**: 25+ Moroccan medical specialties (DabaDoc integration)
|
298
|
-
- 👔 **Professions**: Common Moroccan professions (médecin, ingénieur, etc.)
|
299
|
-
- 🏢 **Company Names**: Authentic Moroccan business naming patterns
|
300
|
-
- 🏦 **Banks**: All major Moroccan banks (Attijariwafa, BCP, BMCI, etc.)
|
301
|
-
- 📰 **Newspapers**: Moroccan media outlets (Le Matin, L'Économiste, etc.)
|
302
|
-
|
303
|
-
### 🆕 **Enhanced Business Data**
|
304
|
-
- 🏭 **Industries**: 16+ Moroccan industries (Agriculture, Technology, Tourism, etc.)
|
305
|
-
- 💼 **Job Titles**: 18+ common job titles and positions
|
306
|
-
- 📊 **Company Info**: Company sizes, business types (SARL, SA, etc.)
|
307
|
-
- 💼 **Work Details**: Work experience, salary ranges, work schedules
|
308
|
-
- 🆔 **Legal IDs**: Tax IDs, trade register numbers
|
309
|
-
- 📈 **Professional**: Career progression and employment data
|
310
|
-
|
311
|
-
### 🎓 **Education & Culture**
|
312
|
-
- 🗺️ **Regions**: All 12 Moroccan administrative regions
|
313
|
-
- 🎓 **Universities**: 12+ major Moroccan universities with full names
|
314
|
-
- 🏫 **Schools**: Famous Moroccan schools and lycées
|
315
|
-
- 🎭 **Festivals**: Major Moroccan cultural festivals
|
316
|
-
- 🕌 **Mosques**: Famous Moroccan mosques (Hassan II, Koutoubia, etc.)
|
317
|
-
|
318
|
-
### 🆕 **Enhanced Cultural & Lifestyle**
|
319
|
-
- 🍲 **Traditional Dishes**: Famous Moroccan cuisine (couscous, tagine, pastilla, etc.)
|
320
|
-
- 🌶️ **Spices**: Moroccan spices and ingredients (ras-el-hanout, safran, etc.)
|
321
|
-
- 🏪 **Souks**: Traditional Moroccan markets (Souk Semmarine, Bahia, etc.)
|
322
|
-
- ☕ **Cafés/Restaurants**: Famous Moroccan cafés and restaurants
|
323
|
-
- 🏨 **Hotels/Riads**: Moroccan hotels and traditional riads
|
324
|
-
- ⚽ **Sports & Hobbies**: 20+ sports and recreational activities
|
325
|
-
- 🎵 **Entertainment**: Music genres, movie preferences, social media
|
326
|
-
- 🚗 **Transportation**: Common transportation methods in Morocco
|
327
|
-
- 🐾 **Pets**: Popular pets and animals
|
328
|
-
- 🎨 **Preferences**: Favorite colors and personal tastes
|
329
|
-
|
330
|
-
### 🆕 **Geographic & Location Data**
|
331
|
-
- 🗺️ **Provinces**: 40+ Moroccan provinces and administrative divisions
|
332
|
-
- 🏘️ **Districts**: Smart district generation with city-specific districts
|
333
|
-
- 🏛️ **Landmarks**: 25+ famous Moroccan landmarks and tourist sites
|
334
|
-
- 🌤️ **Climate**: 7 different climate types across Morocco
|
335
|
-
- ⏰ **Timezone**: Moroccan timezone information
|
336
|
-
- 💱 **Currency**: Moroccan Dirham information
|
337
|
-
|
338
|
-
### 🆕 **Profile Generation & Utilities**
|
339
|
-
- 👤 **Complete Profiles**: Personal, business, medical, and cultural profiles
|
340
|
-
- 📊 **Bulk Generation**: Generate multiple records at once
|
341
|
-
- 📤 **Export Features**: Export to JSON and CSV formats
|
342
|
-
- 🎲 **Random Data**: Category-based random data generation
|
343
|
-
- 🏥 **Medical Profiles**: Specialized profiles for DabaDoc integration
|
344
|
-
- 🏢 **Business Profiles**: Complete business information packages
|
345
|
-
|
346
|
-
### 📊 **Enhanced Statistics**
|
347
|
-
- **Total Data Points**: 500+ authentic Moroccan entries
|
348
|
-
- **Categories**: 50+ different data types
|
349
|
-
- **Profile Types**: 4 complete profile generators
|
350
|
-
- **Export Formats**: JSON and CSV support
|
351
|
-
- **100% Moroccan**: Everything is authentically Moroccan
|
352
|
-
- **No Duplicates**: All data is unique and varied
|
353
|
-
- **DabaDoc Ready**: Perfect for medical system integration
|
354
|
-
|
355
|
-
## Development
|
356
|
-
|
357
|
-
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
358
|
-
|
359
|
-
### 🧪 Testing
|
360
|
-
|
361
|
-
Zayef has comprehensive test coverage with 69 RSpec tests covering all functionality.
|
362
|
-
|
363
|
-
```bash
|
364
|
-
# Run all tests
|
365
|
-
bundle exec rspec
|
366
|
-
|
367
|
-
# Run tests with coverage report
|
368
|
-
COVERAGE=true bundle exec rspec
|
369
|
-
|
370
|
-
# Run specific test file
|
371
|
-
bundle exec rspec spec/zayef/generator_spec.rb
|
280
|
+
### Advanced Usage
|
372
281
|
|
373
|
-
|
374
|
-
|
282
|
+
#### Parameterized Profile Generation
|
283
|
+
```ruby
|
284
|
+
# Generate profiles with specific constraints for more realistic data
|
285
|
+
profile = Zayef::Generator.profile(age_min: 25, age_max: 35, city: "Casablanca", gender: "Female")
|
286
|
+
business = Zayef::Generator.business_profile(city: "Rabat")
|
287
|
+
medical = Zayef::Generator.medical_profile(age_min: 30, age_max: 50)
|
288
|
+
cultural = Zayef::Generator.cultural_profile(city: "Fès")
|
375
289
|
```
|
376
290
|
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
- ✅ **Cultural Elements**: Traditional dishes, spices, souks, festivals
|
382
|
-
- ✅ **Business Data**: Banks, companies, newspapers, schools
|
383
|
-
- ✅ **Integration Tests**: End-to-end functionality testing
|
384
|
-
- ✅ **Error Handling**: Edge cases and validation
|
385
|
-
|
386
|
-
**Current Coverage**: 90%+ with comprehensive test suite
|
387
|
-
|
388
|
-
### 📝 Automated Changelog
|
389
|
-
|
390
|
-
Zayef uses [git-cliff](https://github.com/orhun/git-cliff) for automated changelog generation based on conventional commits.
|
391
|
-
|
392
|
-
#### Installation
|
393
|
-
|
394
|
-
Install git-cliff:
|
395
|
-
```bash
|
396
|
-
# Using cargo (recommended)
|
397
|
-
cargo install git-cliff
|
291
|
+
#### Bulk Data Generation & Export
|
292
|
+
```ruby
|
293
|
+
# Generate multiple profiles with constraints
|
294
|
+
profiles = Zayef::Generator.bulk_data(100, 'personal', city: "Marrakech")
|
398
295
|
|
399
|
-
#
|
400
|
-
|
296
|
+
# Export to JSON for API testing
|
297
|
+
json_data = Zayef::Generator.export_to_json(50, 'medical')
|
298
|
+
puts json_data
|
401
299
|
|
402
|
-
#
|
300
|
+
# Export to CSV for data analysis
|
301
|
+
csv_data = Zayef::Generator.export_to_csv(200, 'business')
|
302
|
+
puts csv_data
|
403
303
|
```
|
404
304
|
|
405
|
-
####
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
# Generate changelog for latest version
|
415
|
-
./bin/generate-changelog --latest
|
416
|
-
|
417
|
-
# Generate changelog up to specific tag
|
418
|
-
./bin/generate-changelog --tag v1.0.0
|
305
|
+
#### Streaming for Large Datasets
|
306
|
+
```ruby
|
307
|
+
# Generate 10,000 records without loading all in memory
|
308
|
+
File.open('large_dataset.json', 'w') do |file|
|
309
|
+
Zayef::Generator.stream_json(10000, 'personal') do |chunk|
|
310
|
+
file.write(chunk)
|
311
|
+
end
|
312
|
+
end
|
419
313
|
|
420
|
-
#
|
421
|
-
|
314
|
+
# Stream CSV for data processing pipelines
|
315
|
+
Zayef::Generator.stream_csv(50000, 'business') do |line|
|
316
|
+
# Process each line individually
|
317
|
+
puts line
|
318
|
+
end
|
422
319
|
```
|
423
320
|
|
424
|
-
####
|
321
|
+
#### Generic Helper Methods
|
322
|
+
```ruby
|
323
|
+
# Instead of repetitive .sample calls
|
324
|
+
Zayef::Generator.pick(['option1', 'option2', 'option3'])
|
425
325
|
|
426
|
-
|
326
|
+
# Consistent number generation with constraints
|
327
|
+
Zayef::Generator.random_number(min: 18, max: 80)
|
427
328
|
|
428
|
-
|
429
|
-
#
|
430
|
-
|
329
|
+
# Pattern-based code generation
|
330
|
+
Zayef::Generator.random_code(format: 'AA######') # CNI format: "AB123456"
|
331
|
+
Zayef::Generator.random_code(format: 'MA##################') # IBAN: "MA123456789012345678"
|
431
332
|
|
432
|
-
#
|
433
|
-
|
333
|
+
# Weighted sampling for realistic distributions
|
334
|
+
Zayef::Generator.weighted_pick({
|
335
|
+
"Moroccan" => 85, # 85% probability
|
336
|
+
"French" => 5, # 5% probability
|
337
|
+
"Algerian" => 3, # 3% probability
|
338
|
+
"Other" => 7 # 7% probability
|
339
|
+
})
|
340
|
+
```
|
434
341
|
|
435
|
-
|
436
|
-
git commit -m "docs: update README with new examples"
|
342
|
+
## 🎯 Perfect for DabaDoc & Moroccan Apps
|
437
343
|
|
438
|
-
|
439
|
-
git commit -m "feat!: change API interface (breaking change)"
|
344
|
+
Zayef is specifically designed for Moroccan healthcare and business applications:
|
440
345
|
|
441
|
-
|
442
|
-
|
346
|
+
```ruby
|
347
|
+
# Generate realistic patient profiles
|
348
|
+
patient = Zayef::Generator.medical_profile(age_min: 25, age_max: 65)
|
349
|
+
puts "Patient: #{patient[:patient_name]}"
|
350
|
+
puts "Age: #{patient[:age]}"
|
351
|
+
puts "Specialty: #{patient[:medical_specialty]}"
|
352
|
+
puts "Emergency Contact: #{patient[:emergency_contact]}"
|
353
|
+
|
354
|
+
# Generate doctor profiles
|
355
|
+
doctor = Zayef::Generator.medical_profile(age_min: 30, age_max: 70)
|
356
|
+
puts "Doctor: #{doctor[:doctor_name]}"
|
357
|
+
puts "Specialty: #{doctor[:medical_specialty]}"
|
358
|
+
puts "Clinic: #{doctor[:clinic_address]}"
|
359
|
+
|
360
|
+
# Generate realistic test data for Moroccan healthcare systems
|
361
|
+
patients = Zayef::Generator.bulk_data(1000, 'medical', city: "Casablanca")
|
362
|
+
appointments_json = Zayef::Generator.export_to_json(500, 'medical')
|
443
363
|
```
|
444
364
|
|
445
|
-
|
365
|
+
## 🌟 Key Features
|
446
366
|
|
447
|
-
|
367
|
+
- **🇲🇦 Authentic Moroccan Data**: Real names, cities, companies, and cultural elements
|
368
|
+
- **⚡ High Performance**: Cached data loading and streaming support for large datasets
|
369
|
+
- **🎯 Parameterized Generation**: Age, gender, city, and other constraints
|
370
|
+
- **📊 Multiple Export Formats**: JSON, CSV, and streaming support
|
371
|
+
- **🔧 DRY Principle**: Generic helper methods eliminate code duplication
|
372
|
+
- **🎲 Realistic Distributions**: Weighted sampling for authentic data
|
373
|
+
- **🏥 DabaDoc Ready**: Perfect for Moroccan healthcare applications
|
374
|
+
- **📱 Modern Data**: Social media, transportation, hobbies, and more
|
375
|
+
- **🛠️ Easy Customization**: External JSON files for data modification
|
376
|
+
- **💎 Modern Ruby**: Keyword arguments, safe navigation, and best practices
|
448
377
|
|
449
|
-
|
450
|
-
# Prepare release (generate changelog, bump version)
|
451
|
-
rake release:prepare
|
378
|
+
## 📈 Performance & Scalability
|
452
379
|
|
453
|
-
|
454
|
-
rake release:publish
|
380
|
+
Zayef is optimized for both small and large-scale data generation:
|
455
381
|
|
456
|
-
|
457
|
-
|
458
|
-
|
382
|
+
- **Memory Efficient**: Streaming support for datasets with millions of records
|
383
|
+
- **Fast Generation**: Cached data loading for optimal performance
|
384
|
+
- **Bulk Operations**: Generate hundreds of profiles with consistent constraints
|
385
|
+
- **Export Ready**: JSON and CSV export for integration with other systems
|
459
386
|
|
460
|
-
|
387
|
+
## 🤝 Contributing
|
461
388
|
|
462
|
-
|
463
|
-
# Run all quality checks
|
464
|
-
rake
|
389
|
+
We welcome contributions! Please see our [Contributing Guide](https://github.com/merouaneamqor/zayef/blob/main/CONTRIBUTING.md) for details.
|
465
390
|
|
466
|
-
|
467
|
-
|
391
|
+
1. Fork the repository
|
392
|
+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
393
|
+
3. Add your data to the appropriate JSON file in `data/`
|
394
|
+
4. Update the DataLoader if needed
|
395
|
+
5. Add tests and update documentation
|
396
|
+
6. Commit your changes (`git commit -m 'Add amazing feature'`)
|
397
|
+
7. Push to the branch (`git push origin feature/amazing-feature`)
|
398
|
+
8. Open a Pull Request
|
468
399
|
|
469
|
-
|
470
|
-
rake git:commit
|
400
|
+
## 📄 License
|
471
401
|
|
472
|
-
|
473
|
-
rake changelog:check
|
474
|
-
```
|
402
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
475
403
|
|
476
|
-
##
|
404
|
+
## 🙏 Acknowledgments
|
477
405
|
|
478
|
-
|
406
|
+
- **Moroccan Community** for providing authentic cultural data
|
407
|
+
- **Ruby Community** for the excellent tooling and ecosystem
|
408
|
+
- **DabaDoc** for inspiring the medical data features
|
409
|
+
- **All contributors** who help make Zayef better
|
479
410
|
|
480
|
-
|
411
|
+
## 🔗 Links
|
481
412
|
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
413
|
+
- **📚 Documentation**: https://github.com/merouaneamqor/zayef
|
414
|
+
- **💎 RubyGems**: https://rubygems.org/gems/zayef
|
415
|
+
- **🐛 Bug Reports**: https://github.com/merouaneamqor/zayef/issues
|
416
|
+
- **🚀 Source Code**: https://github.com/merouaneamqor/zayef
|
417
|
+
- **📝 Changelog**: https://github.com/merouaneamqor/zayef/blob/main/CHANGELOG.md
|
486
418
|
|
487
|
-
|
419
|
+
---
|
488
420
|
|
489
|
-
|
421
|
+
**Made with ❤️ in Morocco** 🇲🇦 | **Built for the world** 🌍
|