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
@@ -0,0 +1,85 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative '../lib/zayef'
|
5
|
+
|
6
|
+
puts "🎉 Zayef Generator - Refactored Version Demo"
|
7
|
+
puts "=" * 50
|
8
|
+
|
9
|
+
# Example 1: Basic usage with generic helpers
|
10
|
+
puts "\n1️⃣ Basic Data Generation:"
|
11
|
+
puts "Name: #{Zayef::Generator.name}"
|
12
|
+
puts "Email: #{Zayef::Generator.email}"
|
13
|
+
puts "Phone: #{Zayef::Generator.phone}"
|
14
|
+
puts "City: #{Zayef::Generator.city}"
|
15
|
+
puts "CNI: #{Zayef::Generator.cni_number}"
|
16
|
+
|
17
|
+
# Example 2: Parameterized profile generation
|
18
|
+
puts "\n2️⃣ Parameterized Profile (25-year-old from Rabat):"
|
19
|
+
profile = Zayef::Generator.profile(age_min: 25, age_max: 25, city: "Rabat")
|
20
|
+
puts "Name: #{profile[:name]}"
|
21
|
+
puts "Age: #{profile[:age]}"
|
22
|
+
puts "City: #{profile[:city]}"
|
23
|
+
puts "District: #{profile[:district]}"
|
24
|
+
puts "Email: #{profile[:email]}"
|
25
|
+
|
26
|
+
# Example 3: Gender-specific first names
|
27
|
+
puts "\n3️⃣ Gender-Specific Names:"
|
28
|
+
puts "Male name: #{Zayef::Generator.first_name('male')}"
|
29
|
+
puts "Female name: #{Zayef::Generator.first_name('female')}"
|
30
|
+
|
31
|
+
# Example 4: Business profile with consistency
|
32
|
+
puts "\n4️⃣ Business Profile:"
|
33
|
+
business = Zayef::Generator.business_profile(city: "Casablanca")
|
34
|
+
puts "Company: #{business[:company_name]}"
|
35
|
+
puts "City: #{business[:city]}"
|
36
|
+
puts "Address: #{business[:address]}"
|
37
|
+
|
38
|
+
# Example 5: Medical profile (perfect for DabaDoc)
|
39
|
+
puts "\n5️⃣ Medical Profile:"
|
40
|
+
medical = Zayef::Generator.medical_profile(age_min: 30, age_max: 50)
|
41
|
+
puts "Patient: #{medical[:patient_name]}"
|
42
|
+
puts "Age: #{medical[:age]}"
|
43
|
+
puts "Specialty: #{medical[:medical_specialty]}"
|
44
|
+
puts "Clinic: #{medical[:clinic_address]}"
|
45
|
+
|
46
|
+
# Example 6: Bulk data generation with options
|
47
|
+
puts "\n6️⃣ Bulk Data Generation:"
|
48
|
+
profiles = Zayef::Generator.bulk_data(3, 'personal', age_min: 20, age_max: 30, city: "Marrakech")
|
49
|
+
profiles.each_with_index do |profile, index|
|
50
|
+
puts "Profile #{index + 1}: #{profile[:name]} (#{profile[:age]} years, #{profile[:city]})"
|
51
|
+
end
|
52
|
+
|
53
|
+
# Example 7: Weighted nationality distribution
|
54
|
+
puts "\n7️⃣ Nationality Distribution (10 samples):"
|
55
|
+
10.times { puts "Nationality: #{Zayef::Generator.nationality}" }
|
56
|
+
|
57
|
+
# Example 8: Export to JSON
|
58
|
+
puts "\n8️⃣ JSON Export:"
|
59
|
+
json_data = Zayef::Generator.export_to_json(2, 'cultural', city: "Fès")
|
60
|
+
puts "JSON length: #{json_data.length} characters"
|
61
|
+
|
62
|
+
# Example 9: Data loader direct access
|
63
|
+
puts "\n9️⃣ Direct Data Access:"
|
64
|
+
puts "Available cities: #{Zayef::DataLoader.cities.length}"
|
65
|
+
puts "Available male names: #{Zayef::DataLoader.first_names('male').length}"
|
66
|
+
puts "Available female names: #{Zayef::DataLoader.first_names('female').length}"
|
67
|
+
|
68
|
+
# Example 10: Streaming for large datasets
|
69
|
+
puts "\n🔟 Streaming Example (first 3 records):"
|
70
|
+
count = 0
|
71
|
+
Zayef::Generator.stream_csv(100, 'business') do |line|
|
72
|
+
puts line.chomp if count < 3
|
73
|
+
count += 1
|
74
|
+
break if count >= 3
|
75
|
+
end
|
76
|
+
|
77
|
+
puts "\n✅ Refactoring Complete!"
|
78
|
+
puts "Key improvements:"
|
79
|
+
puts "- Generic helper methods (pick, random_number, random_code)"
|
80
|
+
puts "- External data files for easy maintenance"
|
81
|
+
puts "- Parameterized methods with constraints"
|
82
|
+
puts "- Consistent profile generation"
|
83
|
+
puts "- Weighted sampling for realistic distributions"
|
84
|
+
puts "- Streaming support for large datasets"
|
85
|
+
puts "- Cached data loading for performance"
|
@@ -0,0 +1,245 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'yaml'
|
5
|
+
|
6
|
+
module Zayef
|
7
|
+
class DataLoader
|
8
|
+
DATA_DIR = File.join(__dir__, '..', '..', 'data').freeze
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def load_json(filename)
|
12
|
+
file_path = File.join(DATA_DIR, filename)
|
13
|
+
return {} unless File.exist?(file_path)
|
14
|
+
|
15
|
+
JSON.parse(File.read(file_path), symbolize_names: true)
|
16
|
+
rescue JSON::ParserError => e
|
17
|
+
warn "Error parsing #{filename}: #{e.message}"
|
18
|
+
{}
|
19
|
+
end
|
20
|
+
|
21
|
+
def load_yaml(filename)
|
22
|
+
file_path = File.join(DATA_DIR, filename)
|
23
|
+
return {} unless File.exist?(file_path)
|
24
|
+
|
25
|
+
YAML.safe_load(File.read(file_path), symbolize_names: true)
|
26
|
+
rescue Psych::SyntaxError => e
|
27
|
+
warn "Error parsing #{filename}: #{e.message}"
|
28
|
+
{}
|
29
|
+
end
|
30
|
+
|
31
|
+
# Cached data loading
|
32
|
+
def names_data
|
33
|
+
@names_data ||= load_json('moroccan_names.json')
|
34
|
+
end
|
35
|
+
|
36
|
+
def geography_data
|
37
|
+
@geography_data ||= load_json('moroccan_geography.json')
|
38
|
+
end
|
39
|
+
|
40
|
+
def culture_data
|
41
|
+
@culture_data ||= load_json('moroccan_culture.json')
|
42
|
+
end
|
43
|
+
|
44
|
+
def business_data
|
45
|
+
@business_data ||= load_json('moroccan_business.json')
|
46
|
+
end
|
47
|
+
|
48
|
+
# Convenience methods for specific data
|
49
|
+
def first_names(gender = nil)
|
50
|
+
names = names_data[:first_names] || {}
|
51
|
+
return names.values.flatten if gender.nil?
|
52
|
+
|
53
|
+
case gender.to_s.downcase
|
54
|
+
when 'male', 'm'
|
55
|
+
names[:male] || []
|
56
|
+
when 'female', 'f'
|
57
|
+
names[:female] || []
|
58
|
+
else
|
59
|
+
names.values.flatten
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def last_names
|
64
|
+
names_data[:last_names] || []
|
65
|
+
end
|
66
|
+
|
67
|
+
def cities
|
68
|
+
geography_data[:cities] || []
|
69
|
+
end
|
70
|
+
|
71
|
+
def regions
|
72
|
+
geography_data[:regions] || []
|
73
|
+
end
|
74
|
+
|
75
|
+
def districts_by_city
|
76
|
+
geography_data[:districts_by_city] || {}
|
77
|
+
end
|
78
|
+
|
79
|
+
def neighborhoods
|
80
|
+
geography_data[:neighborhoods] || []
|
81
|
+
end
|
82
|
+
|
83
|
+
def landmarks
|
84
|
+
geography_data[:landmarks] || []
|
85
|
+
end
|
86
|
+
|
87
|
+
def traditional_dishes
|
88
|
+
culture_data[:traditional_dishes] || []
|
89
|
+
end
|
90
|
+
|
91
|
+
def spices
|
92
|
+
culture_data[:spices] || []
|
93
|
+
end
|
94
|
+
|
95
|
+
def souks
|
96
|
+
culture_data[:souks] || []
|
97
|
+
end
|
98
|
+
|
99
|
+
def restaurants
|
100
|
+
culture_data[:restaurants] || []
|
101
|
+
end
|
102
|
+
|
103
|
+
def hotels
|
104
|
+
culture_data[:hotels] || []
|
105
|
+
end
|
106
|
+
|
107
|
+
def mosques
|
108
|
+
culture_data[:mosques] || []
|
109
|
+
end
|
110
|
+
|
111
|
+
def schools
|
112
|
+
culture_data[:schools] || []
|
113
|
+
end
|
114
|
+
|
115
|
+
def universities
|
116
|
+
culture_data[:universities] || []
|
117
|
+
end
|
118
|
+
|
119
|
+
def newspapers
|
120
|
+
culture_data[:newspapers] || []
|
121
|
+
end
|
122
|
+
|
123
|
+
def festivals
|
124
|
+
culture_data[:festivals] || []
|
125
|
+
end
|
126
|
+
|
127
|
+
def music_genres
|
128
|
+
culture_data[:music_genres] || []
|
129
|
+
end
|
130
|
+
|
131
|
+
def movie_genres
|
132
|
+
culture_data[:movie_genres] || []
|
133
|
+
end
|
134
|
+
|
135
|
+
def hobbies
|
136
|
+
culture_data[:hobbies] || []
|
137
|
+
end
|
138
|
+
|
139
|
+
def sports
|
140
|
+
culture_data[:sports] || []
|
141
|
+
end
|
142
|
+
|
143
|
+
def social_media
|
144
|
+
culture_data[:social_media] || []
|
145
|
+
end
|
146
|
+
|
147
|
+
def transportation
|
148
|
+
culture_data[:transportation] || []
|
149
|
+
end
|
150
|
+
|
151
|
+
def pets
|
152
|
+
culture_data[:pets] || []
|
153
|
+
end
|
154
|
+
|
155
|
+
def colors
|
156
|
+
culture_data[:colors] || []
|
157
|
+
end
|
158
|
+
|
159
|
+
def banks
|
160
|
+
business_data[:banks] || []
|
161
|
+
end
|
162
|
+
|
163
|
+
def industries
|
164
|
+
business_data[:industries] || []
|
165
|
+
end
|
166
|
+
|
167
|
+
def company_sizes
|
168
|
+
business_data[:company_sizes] || []
|
169
|
+
end
|
170
|
+
|
171
|
+
def business_types
|
172
|
+
business_data[:business_types] || []
|
173
|
+
end
|
174
|
+
|
175
|
+
def job_titles
|
176
|
+
business_data[:job_titles] || []
|
177
|
+
end
|
178
|
+
|
179
|
+
def professions
|
180
|
+
business_data[:professions] || []
|
181
|
+
end
|
182
|
+
|
183
|
+
def work_schedules
|
184
|
+
business_data[:work_schedules] || []
|
185
|
+
end
|
186
|
+
|
187
|
+
def medical_specialties
|
188
|
+
business_data[:medical_specialties] || []
|
189
|
+
end
|
190
|
+
|
191
|
+
def education_levels
|
192
|
+
business_data[:education_levels] || []
|
193
|
+
end
|
194
|
+
|
195
|
+
def income_ranges
|
196
|
+
business_data[:income_ranges] || []
|
197
|
+
end
|
198
|
+
|
199
|
+
def languages
|
200
|
+
business_data[:languages] || []
|
201
|
+
end
|
202
|
+
|
203
|
+
def marital_statuses
|
204
|
+
business_data[:marital_statuses] || []
|
205
|
+
end
|
206
|
+
|
207
|
+
def blood_types
|
208
|
+
business_data[:blood_types] || []
|
209
|
+
end
|
210
|
+
|
211
|
+
def eye_colors
|
212
|
+
business_data[:eye_colors] || []
|
213
|
+
end
|
214
|
+
|
215
|
+
def hair_colors
|
216
|
+
business_data[:hair_colors] || []
|
217
|
+
end
|
218
|
+
|
219
|
+
def religions
|
220
|
+
business_data[:religions] || []
|
221
|
+
end
|
222
|
+
|
223
|
+
def nationality_weights
|
224
|
+
business_data[:nationalities] || {}
|
225
|
+
end
|
226
|
+
|
227
|
+
# Clear cache (useful for testing or when data files change)
|
228
|
+
def clear_cache!
|
229
|
+
@names_data = nil
|
230
|
+
@geography_data = nil
|
231
|
+
@culture_data = nil
|
232
|
+
@business_data = nil
|
233
|
+
end
|
234
|
+
|
235
|
+
# Reload all data
|
236
|
+
def reload!
|
237
|
+
clear_cache!
|
238
|
+
names_data
|
239
|
+
geography_data
|
240
|
+
culture_data
|
241
|
+
business_data
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
data/lib/zayef/version.rb
CHANGED
data/test_user_code.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Test the user's code
|
5
|
+
require 'zayef'
|
6
|
+
|
7
|
+
puts "🎉 Testing Zayef Generator"
|
8
|
+
puts "=" * 40
|
9
|
+
|
10
|
+
# Generate a single profile
|
11
|
+
puts "\n1️⃣ Single Profile:"
|
12
|
+
profile = Zayef::Generator.profile
|
13
|
+
puts "Generated profile with #{profile.keys.length} fields"
|
14
|
+
|
15
|
+
# Generate 5 profiles
|
16
|
+
puts "\n2️⃣ Bulk Data (5 profiles):"
|
17
|
+
profiles = Zayef::Generator.bulk_data(5)
|
18
|
+
puts "Generated #{profiles.length} profiles"
|
19
|
+
profiles.first(3).each_with_index do |p, i|
|
20
|
+
puts " Profile #{i+1}: #{p[:name]} (#{p[:age]} years, #{p[:city]})"
|
21
|
+
end
|
22
|
+
|
23
|
+
# Export 3 profiles to JSON
|
24
|
+
puts "\n3️⃣ JSON Export (3 profiles):"
|
25
|
+
json_data = Zayef::Generator.export_to_json(3)
|
26
|
+
puts "JSON data length: #{json_data.length} characters"
|
27
|
+
puts "Sample JSON: #{json_data[0..100]}..."
|
28
|
+
|
29
|
+
puts "\n✅ All methods work correctly!"
|
30
|
+
puts "\n📝 Additional Examples:"
|
31
|
+
puts "Zayef.name # #{Zayef.name}"
|
32
|
+
puts "Zayef.email # #{Zayef.email}"
|
33
|
+
puts "Zayef.phone # #{Zayef.phone}"
|
34
|
+
puts "Zayef.city # #{Zayef.city}"
|
35
|
+
puts "Zayef.cni_number # #{Zayef.cni_number}"
|
36
|
+
|
37
|
+
# Test parameterized profiles
|
38
|
+
puts "\n🔧 Parameterized Examples:"
|
39
|
+
puts "Profile (25-35, Casablanca): #{Zayef.profile(age_min: 25, age_max: 35, city: 'Casablanca')[:name]}"
|
40
|
+
puts "Business (Rabat): #{Zayef.business_profile(city: 'Rabat')[:company_name]}"
|
41
|
+
puts "Medical (30-50): #{Zayef.medical_profile(age_min: 30, age_max: 50)[:medical_specialty]}"
|
data/user_example.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'zayef'
|
5
|
+
|
6
|
+
puts "🎉 Zayef Generator - User Examples"
|
7
|
+
puts "=" * 40
|
8
|
+
|
9
|
+
# Generate a single profile
|
10
|
+
puts "\n1️⃣ Single Profile:"
|
11
|
+
profile = Zayef::Generator.profile
|
12
|
+
puts "Generated profile with #{profile.keys.length} fields:"
|
13
|
+
puts JSON.pretty_generate(profile)
|
14
|
+
|
15
|
+
# Generate 5 profiles
|
16
|
+
puts "\n2️⃣ Bulk Data (5 profiles):"
|
17
|
+
profiles = Zayef::Generator.bulk_data(5)
|
18
|
+
puts "Generated #{profiles.length} profiles:"
|
19
|
+
profiles.first(3).each_with_index do |p, i|
|
20
|
+
puts " Profile #{i+1}: #{p[:name]} (#{p[:age]} years, #{p[:city]})"
|
21
|
+
end
|
22
|
+
|
23
|
+
# Export 3 profiles to JSON
|
24
|
+
puts "\n3️⃣ JSON Export (3 profiles):"
|
25
|
+
json_data = Zayef::Generator.export_to_json(3)
|
26
|
+
puts "JSON data length: #{json_data.length} characters"
|
27
|
+
puts "Sample JSON: #{json_data[0..200]}..."
|
28
|
+
|
29
|
+
puts "\n✅ Your code works perfectly!"
|
30
|
+
puts "\n📚 More Examples:"
|
31
|
+
puts "Zayef::Generator.profile(age_min: 25, age_max: 35, city: 'Casablanca')"
|
32
|
+
puts "Zayef::Generator.business_profile(city: 'Rabat')"
|
33
|
+
puts "Zayef::Generator.medical_profile(age_min: 30, age_max: 50)"
|
34
|
+
puts "Zayef::Generator.cultural_profile(city: 'Fès')"
|
data/zayef.gemspec
CHANGED
@@ -19,6 +19,9 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.metadata["homepage_uri"] = spec.homepage
|
20
20
|
spec.metadata["source_code_uri"] = "https://github.com/merouaneamqor/zayef"
|
21
21
|
spec.metadata["changelog_uri"] = "https://github.com/merouaneamqor/zayef/blob/main/CHANGELOG.md"
|
22
|
+
spec.metadata["documentation_uri"] = "https://github.com/merouaneamqor/zayef/blob/main/README.md"
|
23
|
+
spec.metadata["bug_tracker_uri"] = "https://github.com/merouaneamqor/zayef/issues"
|
24
|
+
spec.metadata["rubygems_mfa_required"] = "true"
|
22
25
|
|
23
26
|
# Specify which files should be added to the gem when it is released.
|
24
27
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zayef
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.0
|
4
|
+
version: 0.2.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Merouane AMQOR
|
@@ -54,13 +54,22 @@ files:
|
|
54
54
|
- CHANGELOG.md
|
55
55
|
- CONTRIBUTING.md
|
56
56
|
- README.md
|
57
|
+
- REFACTORING.md
|
57
58
|
- Rakefile
|
58
59
|
- cliff.toml
|
60
|
+
- data/moroccan_business.json
|
61
|
+
- data/moroccan_culture.json
|
62
|
+
- data/moroccan_geography.json
|
63
|
+
- data/moroccan_names.json
|
59
64
|
- demo.rb
|
65
|
+
- examples/refactored_usage.rb
|
60
66
|
- lib/zayef.rb
|
67
|
+
- lib/zayef/data_loader.rb
|
61
68
|
- lib/zayef/generator.rb
|
62
69
|
- lib/zayef/version.rb
|
63
70
|
- sig/zayef.rbs
|
71
|
+
- test_user_code.rb
|
72
|
+
- user_example.rb
|
64
73
|
- vendor/bundle/ruby/3.0.0/bin/htmldiff
|
65
74
|
- vendor/bundle/ruby/3.0.0/bin/ldiff
|
66
75
|
- vendor/bundle/ruby/3.0.0/bin/rake
|
@@ -1416,6 +1425,9 @@ metadata:
|
|
1416
1425
|
homepage_uri: https://github.com/merouaneamqor/zayef
|
1417
1426
|
source_code_uri: https://github.com/merouaneamqor/zayef
|
1418
1427
|
changelog_uri: https://github.com/merouaneamqor/zayef/blob/main/CHANGELOG.md
|
1428
|
+
documentation_uri: https://github.com/merouaneamqor/zayef/blob/main/README.md
|
1429
|
+
bug_tracker_uri: https://github.com/merouaneamqor/zayef/issues
|
1430
|
+
rubygems_mfa_required: 'true'
|
1419
1431
|
rdoc_options: []
|
1420
1432
|
require_paths:
|
1421
1433
|
- lib
|