Przeglądaj źródła

:recycle: breaking functions out of generator

tags/0.0.1
j 4 lat temu
rodzic
commit
91dba97096

+ 29
- 0
backend/db/data-generator/classes.js Wyświetl plik

@@ -0,0 +1,29 @@
1
+class User {
2
+    constructor(id) {
3
+        this.user_id = id
4
+        this.user_name = ''
5
+        this.user_email = ''
6
+        this.is_admin = false
7
+        this.is_poster = false
8
+    }
9
+}
10
+class Profile {
11
+    constructor(id, override) {
12
+        this.user_id = override?.user_id ? override.user_id : id
13
+        this.profile_id = override?.profile_id ? override.profile_id + id : id
14
+    }
15
+}
16
+class Response {
17
+    constructor(id) {
18
+        this.response_id = id
19
+        this.profile_id = null
20
+        this.response_key_id = null
21
+        this.val = null
22
+    }
23
+}
24
+
25
+module.exports = {
26
+    User,
27
+    Profile,
28
+    Response,
29
+}

+ 46
- 0
backend/db/data-generator/config.js Wyświetl plik

@@ -0,0 +1,46 @@
1
+const mockOutputPath = './db/generated/_batch'
2
+const magic = 1000
3
+
4
+// Insert here how many users you would like to generate:
5
+const total = 20
6
+const batchSize = 10
7
+
8
+// Amount of responses for a complete survey
9
+const questions = 13
10
+
11
+// Seekers per 100 profiles
12
+const percentageOfSeekers = 90
13
+
14
+const scoreVals = [100, 140, 180, 220, 260, 400]
15
+
16
+const header = `/**
17
+* GENERATED MOCK SIIMEE DATA
18
+* Generated at: ${Date.now()}
19
+*/
20
+`
21
+
22
+const possibleZipcodes = [
23
+    '90065', // Glassel
24
+    '90012', // Chinatown
25
+    '90240', // Downey
26
+    '91030', // South Pasadena
27
+    '91201', // Glendale
28
+    '91399', // Woodland Hills
29
+    '91401', // Van Nuys
30
+    '90840', // Long Beach
31
+    '91001', // Altadena
32
+    '91011', // La Canada Flintridge
33
+    '97075', // Beaverton
34
+]
35
+
36
+module.exports = {
37
+    mockOutputPath,
38
+    magic,
39
+    total,
40
+    batchSize,
41
+    questions,
42
+    percentageOfSeekers,
43
+    scoreVals,
44
+    header,
45
+    possibleZipcodes,
46
+}

backend/db/generator.js → backend/db/data-generator/index.js Wyświetl plik

@@ -1,25 +1,14 @@
1 1
 const fs = require('fs')
2
-const cosineSimilarity = require('compute-cosine-similarity')
3
-const mockOutputPath = './db/generated/_batch'
4
-const magic = 1000
2
+const config = require('./config')
3
+const random = require('./random')
4
+const classes = require('./classes')
5
+const score = require('./score')
5 6
 
6
-// Insert here how many users you would like to generate:
7
-const total = 1000
8
-const batchSize = 100
9 7
 let batchCount = 1 // Counter to track how many things we've generated
10
-
11 8
 let extraProfilesToGenerate = 0
12 9
 let extraProfileCount = 0 // Counter to track how many EXTRA profiles we've generated
10
+let generatedResponseCount = 0 // Counter to track every response generated
13 11
 
14
-let generatedResponseCount = 0
15
-
16
-// Amount of responses for a complete survey
17
-const questions = 13
18
-
19
-// Seekers per 100 profiles
20
-const percentageOfSeekers = 90
21
-
22
-const scoreVals = [100, 140, 180, 220, 260, 400]
23 12
 // Values for responsess as strings
24 13
 const possibleResponses = {
25 14
     not_important: null,
@@ -31,22 +20,17 @@ const possibleResponses = {
31 20
 }
32 21
 for (let i = 0; i < Object.keys(possibleResponses).length; i++) {
33 22
     const key = Object.keys(possibleResponses)[i]
34
-    possibleResponses[key] = scoreVals[i].toString()
23
+    possibleResponses[key] = config.scoreVals[i].toString()
35 24
 }
36 25
 
37 26
 /**
38 27
  * Our initial file setup
39 28
  */
40
-const header = `/**
41
-* GENERATED MOCK SIIMEE DATA
42
-* Generated at: ${Date.now()}
43
-*/
44
-`
45 29
 const write = async (batchNum, outputDataObject) => {
46
-    await fs.writeFile(`${mockOutputPath}_${batchNum}.js`, '', () => {})
30
+    await fs.writeFile(`${config.mockOutputPath}_${batchNum}.js`, '', () => {})
47 31
     fs.appendFile(
48
-        `${mockOutputPath}_${batchNum}.js`,
49
-        header + 'module.exports = ' + JSON.stringify(outputDataObject),
32
+        `${config.mockOutputPath}_${batchNum}.js`,
33
+        config.header + 'module.exports = ' + JSON.stringify(outputDataObject),
50 34
         err => {
51 35
             if (err) {
52 36
                 console.error(err)
@@ -56,190 +40,44 @@ const write = async (batchNum, outputDataObject) => {
56 40
     )
57 41
 }
58 42
 
59
-/**
60
- * [100, 140, 180, 220, 260, 400]
61
- */
62
-const preComputedScores = {
63
-    100: {
64
-        100: 0,
65
-        140: 0,
66
-        180: 0,
67
-        220: 0,
68
-        260: 0,
69
-        400: 0,
70
-    },
71
-    140: {
72
-        100: 0,
73
-        140: 0,
74
-        180: 0,
75
-        220: 0,
76
-        260: 0,
77
-        400: 0,
78
-    },
79
-    180: {
80
-        100: 0,
81
-        140: 0,
82
-        180: 0,
83
-        220: 0,
84
-        260: 0,
85
-        400: 0,
86
-    },
87
-    220: {
88
-        100: 0,
89
-        140: 0,
90
-        180: 0,
91
-        220: 0,
92
-        260: 0,
93
-        400: 0,
94
-    },
95
-    260: {
96
-        100: 0,
97
-        140: 0,
98
-        180: 0,
99
-        220: 0,
100
-        260: 0,
101
-        400: 0,
102
-    },
103
-    400: {
104
-        100: 0,
105
-        140: 0,
106
-        180: 0,
107
-        220: 0,
108
-        260: 0,
109
-        400: 0,
110
-    },
111
-}
112
-const score2d = (a, b) => {
113
-    const aScorePlusBase = [100]
114
-    const bScorePlusBase = [100]
115
-    aScorePlusBase.push(a)
116
-    bScorePlusBase.push(b)
117
-    return Math.round(
118
-        Math.pow(cosineSimilarity(aScorePlusBase, bScorePlusBase), 10) * magic,
119
-    )
120
-}
121
-scoreVals.forEach(val => {
122
-    scoreVals.forEach(v => {
123
-        preComputedScores[val][v] = score2d(val, v)
124
-    })
125
-})
126
-
127
-const possibleZipcodes = [
128
-    '90065', // Glassel
129
-    '90012', // Chinatown
130
-    '90240', // Downey
131
-    '91030', // South Pasadena
132
-    '91201', // Glendale
133
-    '91399', // Woodland Hills
134
-    '91401', // Van Nuys
135
-    '90840', // Long Beach
136
-    '91001', // Altadena
137
-    '91011', // La Canada Flintridge
138
-    '97075', // Beaverton
139
-]
140
-
141 43
 // Helper functions
142
-const randomNumber = max => {
143
-    return Math.floor(Math.random() * max) < 1
144
-        ? 1
145
-        : Math.floor(Math.random() * max)
146
-}
147
-const randomValFrom = arr => arr[randomNumber(arr.length)]
148
-const randomEmail = (length = 5) => {
149
-    let chars =
150
-        'abcdefghijklmnopqrstuvwxyz-_abcdefghijklmnopqrstuvwxyz0123456789'
151
-    let str = ''
152
-    for (let i = 0; i < length + randomNumber(9); i++) {
153
-        str += chars.charAt(Math.floor(Math.random() * chars.length))
154
-    }
155
-    const suffixs = [
156
-        '@gmail.com',
157
-        '@aol.com',
158
-        '@yahoo.com',
159
-        '@apple.com',
160
-        '@hotmail.com',
161
-        '@rocket-mail.com',
162
-        '@mail.com',
163
-    ]
164
-    return str + randomValFrom(suffixs)
165
-}
166
-const randomName = (length = 4) => {
167
-    let chars = 'aeiouaeiouabcdefghijklmnoprstuvwyabcdefghijklmnopqrstuvwxyz'
168
-    let str = ''
169
-    for (let i = 0; i < length + randomNumber(9); i++) {
170
-        str += chars.charAt(Math.floor(Math.random() * chars.length))
171
-    }
172
-    return str
173
-}
174
-
44
+// const preComputedScores = score.precomputed
175 45
 const generate = (classObj, amount, meta) => {
176 46
     const instances = []
177 47
     for (let i = 0; i < amount; i++) {
178
-        let startFrom = meta?.starting ? meta.starting - batchSize : 0
48
+        let startFrom = meta?.starting ? meta.starting - config.batchSize : 0
179 49
         instances.push(new classObj(i + startFrom + 1, meta))
180 50
     }
181 51
     return instances
182 52
 }
183 53
 
184
-class User {
185
-    constructor(id) {
186
-        this.user_id = id
187
-        this.user_name = ''
188
-        this.user_email = ''
189
-        this.is_admin = false
190
-        this.is_poster = false
191
-    }
192
-}
193
-class Profile {
194
-    constructor(id, override) {
195
-        this.user_id = override?.user_id ? override.user_id : id
196
-        this.profile_id = override?.profile_id ? override.profile_id + id : id
197
-    }
198
-}
199
-class Response {
200
-    constructor(id) {
201
-        this.response_id = id
202
-        this.profile_id = null
203
-        this.response_key_id = null
204
-        this.val = null
205
-    }
206
-}
207
-
208 54
 console.log('\nStarting...\n---')
209 55
 
210
-for (let batch = batchSize; batch <= total; batch += batchSize) {
211
-    /**
212
-     * Generate Users
213
-     */
214
-    let users = generate(User, batchSize, {
215
-        starting: batchSize * batchCount,
56
+/**
57
+ * Generate Users
58
+ */
59
+const generateUsers = () => {
60
+    let users = generate(classes.User, config.batchSize, {
61
+        starting: config.batchSize * batchCount,
216 62
     })
217 63
     users.forEach(user => {
218
-        user.is_poster = randomNumber(100) > percentageOfSeekers ? 1 : 0
64
+        user.is_poster = random.number(100) > config.percentageOfSeekers ? 1 : 0
219 65
         if (user.is_poster) {
220
-            extraProfilesToGenerate = extraProfilesToGenerate + randomNumber(2)
66
+            extraProfilesToGenerate = extraProfilesToGenerate + random.number(2)
221 67
         }
222
-        user.user_name = randomName() + ' ' + randomName()
223
-        user.user_email = randomEmail()
68
+        user.user_name = random.name() + ' ' + random.name()
69
+        user.user_email = random.email()
224 70
     })
225
-    let jobPosterIds = users
226
-        .filter(user => user.is_poster > 0)
227
-        .map(user => user.user_id)
228 71
     console.log('COMPLETED: Generated Users...')
72
+    return users
73
+}
229 74
 
230
-    // Guarentee ONE job poster
231
-    if (!jobPosterIds.length) {
232
-        randomValFrom(users).is_poster = 1
233
-        jobPosterIds = users
234
-            .filter(user => user.is_poster > 0)
235
-            .map(user => user.user_id)
236
-    }
237
-
238
-    /**
239
-     * Generate Profiles
240
-     */
241
-    let profiles = generate(Profile, batchSize, {
242
-        starting: batchSize * batchCount,
75
+/**
76
+ * Generate Profiles
77
+ */
78
+const generateProfiles = jobPosterIds => {
79
+    let profiles = generate(classes.Profile, config.batchSize, {
80
+        starting: config.batchSize * batchCount,
243 81
         profile_id: extraProfileCount,
244 82
     })
245 83
     // Generate extra job posting profiles
@@ -248,12 +86,13 @@ for (let batch = batchSize; batch <= total; batch += batchSize) {
248 86
     if (extraProfilesToGenerate > 0) {
249 87
         let extras = []
250 88
         for (let l = 0; l < extraProfilesToGenerate; l++) {
251
-            const generatedExtraProfiles = generate(Profile, 1, {
89
+            const generatedExtraProfiles = generate(classes.Profile, 1, {
252 90
                 user_id:
253 91
                     jobPosterIds.length > 1
254
-                        ? randomValFrom(jobPosterIds)
92
+                        ? random.valFrom(jobPosterIds)
255 93
                         : jobPosterIds[0],
256
-                profile_id: batchSize * batchCount + extraProfileCount + l,
94
+                profile_id:
95
+                    config.batchSize * batchCount + extraProfileCount + l,
257 96
             })
258 97
             extras = [...extras, ...generatedExtraProfiles]
259 98
         }
@@ -263,43 +102,67 @@ for (let batch = batchSize; batch <= total; batch += batchSize) {
263 102
         })
264 103
     }
265 104
     console.log('COMPLETED: Generated Profiles...')
105
+    return profiles
106
+}
266 107
 
267
-    /**
268
-     * Generate Responses
269
-     */
108
+/**
109
+ * Generate Responses
110
+ */
111
+const generateResponses = profiles => {
270 112
     // Generate responses first, before filling in details
271 113
     let responses = generate(
272
-        Response,
273
-        (batchSize + extraProfilesToGenerate) * questions,
274
-        { starting: generatedResponseCount + batchSize },
114
+        classes.Response,
115
+        (config.batchSize + extraProfilesToGenerate) * config.questions,
116
+        { starting: generatedResponseCount + config.batchSize },
275 117
     )
276 118
     profiles.forEach((profile, i) => {
277
-        const startingIndex = i * questions
278
-        for (let k = 0; k < questions; k++) {
119
+        const startingIndex = i * config.questions
120
+        for (let k = 0; k < config.questions; k++) {
279 121
             const resToEdit = responses[startingIndex + k]
280 122
             resToEdit.response_key_id = k + 1
281 123
             resToEdit.profile_id = profile.profile_id
282 124
             resToEdit.val =
283
-                k + 1 == questions
284
-                    ? randomValFrom(possibleZipcodes)
285
-                    : randomValFrom(Object.values(possibleResponses))
125
+                k + 1 == config.questions
126
+                    ? random.valFrom(config.possibleZipcodes)
127
+                    : random.valFrom(Object.values(possibleResponses))
286 128
         }
287 129
     })
288 130
     generatedResponseCount = generatedResponseCount + responses.length
289 131
     console.log('COMPLETED: Generated Responses...')
132
+    return responses
133
+}
134
+
135
+/**
136
+ * Our main generator loop
137
+ */
138
+for (
139
+    let batch = config.batchSize;
140
+    batch <= config.total;
141
+    batch += config.batchSize
142
+) {
143
+    const users = generateUsers()
290 144
 
291
-    /**
292
-     * Our output format
293
-     */
294
-    const outputDataObject = { users, profiles, responses }
295
-    // const outputDataObject = { users, profiles, responses, match_queues }
296
-    write(batchSize * batchCount, outputDataObject)
145
+    let jobPosterIds = users
146
+        .filter(user => user.is_poster > 0)
147
+        .map(user => user.user_id)
148
+    // Guarentee ONE job poster
149
+    if (!jobPosterIds.length) {
150
+        random.valFrom(users).is_poster = 1
151
+        jobPosterIds = users
152
+            .filter(user => user.is_poster > 0)
153
+            .map(user => user.user_id)
154
+    }
155
+
156
+    const profiles = generateProfiles(jobPosterIds)
157
+    const responses = generateResponses(profiles)
158
+
159
+    write(config.batchSize * batchCount, { users, profiles, responses })
297 160
     batchCount++
298 161
 }
299 162
 
300
-// /**
301
-//  * Score all the profiles!
302
-//  */
163
+/**
164
+ * Score all the profiles!
165
+ */
303 166
 // const compareProfileResponses = (seeker, potentialMatch) => {
304 167
 //     const checkValCb = res => {
305 168
 //         const val = parseInt(res.val)

+ 39
- 0
backend/db/data-generator/random.js Wyświetl plik

@@ -0,0 +1,39 @@
1
+const randomNumber = max => {
2
+    return Math.floor(Math.random() * max) < 1
3
+        ? 1
4
+        : Math.floor(Math.random() * max)
5
+}
6
+const randomValFrom = arr => arr[randomNumber(arr.length)]
7
+const randomEmail = (length = 5) => {
8
+    let chars =
9
+        'abcdefghijklmnopqrstuvwxyz-_abcdefghijklmnopqrstuvwxyz0123456789'
10
+    let str = ''
11
+    for (let i = 0; i < length + randomNumber(9); i++) {
12
+        str += chars.charAt(Math.floor(Math.random() * chars.length))
13
+    }
14
+    const suffixs = [
15
+        '@gmail.com',
16
+        '@aol.com',
17
+        '@yahoo.com',
18
+        '@apple.com',
19
+        '@hotmail.com',
20
+        '@rocket-mail.com',
21
+        '@mail.com',
22
+    ]
23
+    return str + randomValFrom(suffixs)
24
+}
25
+const randomName = (length = 4) => {
26
+    let chars = 'aeiouaeiouabcdefghijklmnoprstuvwyabcdefghijklmnopqrstuvwxyz'
27
+    let str = ''
28
+    for (let i = 0; i < length + randomNumber(9); i++) {
29
+        str += chars.charAt(Math.floor(Math.random() * chars.length))
30
+    }
31
+    return str
32
+}
33
+
34
+module.exports = {
35
+    number: randomNumber,
36
+    valFrom: randomValFrom,
37
+    email: randomEmail,
38
+    name: randomName,
39
+}

+ 73
- 0
backend/db/data-generator/score.js Wyświetl plik

@@ -0,0 +1,73 @@
1
+const cosineSimilarity = require('compute-cosine-similarity')
2
+
3
+const config = require('./config')
4
+
5
+const preComputedScores = {
6
+    100: {
7
+        100: 0,
8
+        140: 0,
9
+        180: 0,
10
+        220: 0,
11
+        260: 0,
12
+        400: 0,
13
+    },
14
+    140: {
15
+        100: 0,
16
+        140: 0,
17
+        180: 0,
18
+        220: 0,
19
+        260: 0,
20
+        400: 0,
21
+    },
22
+    180: {
23
+        100: 0,
24
+        140: 0,
25
+        180: 0,
26
+        220: 0,
27
+        260: 0,
28
+        400: 0,
29
+    },
30
+    220: {
31
+        100: 0,
32
+        140: 0,
33
+        180: 0,
34
+        220: 0,
35
+        260: 0,
36
+        400: 0,
37
+    },
38
+    260: {
39
+        100: 0,
40
+        140: 0,
41
+        180: 0,
42
+        220: 0,
43
+        260: 0,
44
+        400: 0,
45
+    },
46
+    400: {
47
+        100: 0,
48
+        140: 0,
49
+        180: 0,
50
+        220: 0,
51
+        260: 0,
52
+        400: 0,
53
+    },
54
+}
55
+const score2d = (a, b) => {
56
+    const aScorePlusBase = [100]
57
+    const bScorePlusBase = [100]
58
+    aScorePlusBase.push(a)
59
+    bScorePlusBase.push(b)
60
+    return Math.round(
61
+        Math.pow(cosineSimilarity(aScorePlusBase, bScorePlusBase), 10) *
62
+            config.magic,
63
+    )
64
+}
65
+config.scoreVals.forEach(val => {
66
+    config.scoreVals.forEach(v => {
67
+        preComputedScores[val][v] = score2d(val, v)
68
+    })
69
+})
70
+
71
+module.exports = {
72
+    precomputed: preComputedScores,
73
+}

+ 1
- 1
backend/package.json Wyświetl plik

@@ -7,7 +7,7 @@
7 7
     "start": "nodemon server",
8 8
     "migrate": "knex migrate:latest",
9 9
     "unmigrate": "knex migrate:down",
10
-    "generate": "node ./db/generator.js",
10
+    "generate": "node ./db/data-generator/index.js",
11 11
     "seed": "knex seed:run",
12 12
     "test": "nyc ava --timeout=3000"
13 13
   },

Ładowanie…
Anuluj
Zapisz