Skip to content

Commit 44a700a

Browse files
committed
L10n fr exercises on map/reduce, spies, blocking event loop
1 parent 693af4c commit 44a700a

File tree

11 files changed

+210
-11
lines changed

11 files changed

+210
-11
lines changed

exercises/blocking_event_loop/exercise.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
var path = require('path')
66
var runner = require('../runner')
77

8-
module.exports = runner.wrapWith(path.join(__dirname, 'wrapper.js'))
8+
module.exports = runner.wrapWith(path.join(__dirname, 'wrapper.js'), { localized: true })
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Défi
2+
3+
Modifiez la fonction récursive `repeat()`, fournie plus bas dans la base de travail, de façon à ce qu’elle ne bloque pas la boucle événementielle (c’est-à-dire pour qu’elle laisse passer les timers et gestionnaires E/S). Il vous faudra nécessairement en faire une fonction asynchrone.
4+
5+
Un timeout sera déclenché après une seconde, qui affichera les résultats du test et terminara le processus. `repeat()` doit relâcher son contrôle sur la boucle événementielle de telle sorte que ce timeout puisse s’exécuter avant que 1500 millisecondes soient passées.
6+
7+
Essayez d’exécuter l’opération passée à `repeat()` autant de fois que possible avant le timeout !
8+
9+
## Conditions
10+
11+
* N’utilisez ni boucle (`for`, `while`…) ni `Array.prototype.forEach`
12+
* Ne créez aucune fonction superflue
13+
14+
## Conseils
15+
16+
Si votre programme prend trop de temps à s’exécuter, vous avez probablement un souci. Utilisez Ctrl+C pour arrêter le processus Node.
17+
18+
## Ressources
19+
20+
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Timers
21+
22+
## Base de travail
23+
24+
```js
25+
function repeat(operation, num) {
26+
// modifiez cette fonction pour la rendre interruptible
27+
if (num <= 0) return
28+
operation()
29+
return repeat(operation, --num)
30+
}
31+
32+
module.exports = repeat
33+
```
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
function repeat(operation, num) {
2+
if (num <= 0) return
3+
4+
operation()
5+
6+
// relâcher le contrôle tous les 10 tours
7+
// (10 est une taille de lot arbitraire).
8+
if (num % 10 === 0) {
9+
setTimeout(function() {
10+
repeat(operation, --num)
11+
})
12+
} else {
13+
repeat(operation, --num)
14+
}
15+
}
16+
17+
module.exports = repeat
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
'use strict'
2+
3+
var path = require('path')
4+
5+
var repeat = require(path.resolve(process.cwd(), process.argv[2]))
6+
7+
var count = 0
8+
var CYCLES = 100000
9+
10+
function operation() {
11+
for (var i = 0; i < 1000000; i++) {} // burn some CPU cycles
12+
count++ // count how many times this function was called
13+
}
14+
15+
console.log()
16+
console.log('l’opération :')
17+
console.log(operation.toString())
18+
console.log()
19+
console.log('J’essaie de répéter l’opération %d fois…', CYCLES)
20+
console.log('Pressez Ctrl+C pour interrompre.')
21+
console.log()
22+
23+
var start = Date.now()
24+
repeat(operation, CYCLES)
25+
26+
setTimeout(function() {
27+
var end = Date.now()
28+
console.error('J’ai effectué %d opérations.', count)
29+
if (count === CYCLES) console.log('Raté ! Je n’aurais pas du pouvoir aller au bout !')
30+
if (end - start < 1500) console.log('Interruption au bout d’environ 1 seconde !')
31+
else console.log('Raté ! Interruption au bout de %d millisecondes', end - start)
32+
process.exit()
33+
}, 1000)

exercises/function_spies/exercise.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ var exercise = module.exports = runner.custom(function(Spy, input) {
1313
var parent = {
1414
test: function() {
1515
if (!deepEqual(slice.call(arguments), input[count])) {
16-
exercise.emit('fail', "Check you are passing ALL the arguments! Hint: Function#apply")
16+
exercise.emit('fail', exercise.__('not_all_args'))
1717
}
1818
if (this !== parent) {
19-
exercise.emit('fail', "Check the function's this! Hint: Function#apply")
19+
exercise.emit('fail', exercise.__('incorrect_this'))
2020
}
2121
return arguments
2222
}
@@ -29,10 +29,10 @@ var exercise = module.exports = runner.custom(function(Spy, input) {
2929
result.push(util.format.apply(util, args))
3030
count = i
3131
if (!deepEqual(originalFn.apply(parent, args), parent.test.apply(parent, args))) {
32-
exercise.emit('fail', "Check your function's return value!")
32+
exercise.emit('fail', exercise.__('incorrect_return'))
3333
}
3434
})
3535

36-
result.push(util.format('Method called %d times. ', spy.count))
36+
result.push(exercise.__('call_times', spy.count))
3737
return result
3838
}).quiet(input)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Défi
2+
3+
Ajoutez des capacités à une méthode précise sur un objet, tout en préservant son comportement d’origine : créez un espion qui garde la trace du nombre de fois que la fonction a été appelée.
4+
5+
## Exemple
6+
7+
```js
8+
var spy = Spy(console, 'error')
9+
10+
console.error('appel de console.error')
11+
console.error('appel de console.error')
12+
console.error('appel de console.error')
13+
14+
console.log(spy.count) // 3
15+
```
16+
17+
## Arguments
18+
19+
* `target` : un objet contenant la méthode `method`.
20+
* `method` : une `String` indiquant le nom de la méthode de `target` à espionner.
21+
22+
## Conditions
23+
24+
* N’utilisez ni boucle (`for`, `while`…) ni `Array.prototype.forEach`
25+
* Ne créez aucune fonction superflue
26+
27+
## Conseils
28+
29+
Les fonctions ont un contexte (une valeur de `this`), une entrée (les arguments) et une sortie (la valeur de retour). Assurez vous que vous préservez tous ces aspects pour la fonction que vous espionnez.
30+
31+
## Base de travail
32+
33+
```js
34+
function Spy(target, method) {
35+
// VOTRE SOLUTION ICI
36+
}
37+
38+
module.exports = Spy
39+
```
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
function Spy(target, method) {
2+
var originalFunction = target[method]
3+
4+
// Utilisons un objet pour pouvoir le renvoyer par référence,
5+
// et non par copie de valeur. Ainsi nous pouvons renvoyer
6+
// `result`, mais mettre à jour `count` depuis cette portée.
7+
var result = {
8+
count: 0
9+
}
10+
11+
// remplaçons la méthode par sa version « espion »
12+
target[method] = function() {
13+
// On comptabilise l’appel
14+
result.count++
15+
// On invoque la version d’origine
16+
return originalFunction.apply(this, arguments)
17+
}
18+
19+
return result
20+
}
21+
22+
module.exports = Spy
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Défi
2+
3+
Utilisez `Array#reduce()` pour implémenter une version simple de `Array#map()`.
4+
5+
## Résultat attendu
6+
7+
Une fonction `map()` applique une fonction quelconque à chaque élément d’un tableau, et renvoie le tableau des résultats obtenus.
8+
9+
```js
10+
var nums = [1,2,3,4,5]
11+
12+
// `map` est la fonction que vous exportez
13+
var output = map(nums, function double(item) {
14+
return item * 2
15+
})
16+
17+
console.log(output) // => [2,4,6,8,10]
18+
```
19+
20+
## Arguments
21+
22+
* `input` : un tableau de données quelconques, de types variés.
23+
* `operation` : une fonction quelconque, à appliquer aux éléments de `input`.
24+
25+
## Ressources
26+
27+
* https://en.wikipedia.org/wiki/Reduce_(higher-order_function)
28+
* https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Array/reduce
29+
30+
## Base de travail
31+
32+
```js
33+
module.exports = function arrayMap(arr, fn) {
34+
// VOTRE SOLUTION ICI
35+
}
36+
```

exercises/runner.js

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ var os = require('os')
88
var path = require('path')
99
var util = require('util')
1010

11-
var verbose = true, showInput = true, initFx, wrapUpFx, customFx, wrapperModulePath
11+
var verbose = true, showInput = true, initFx, wrapUpFx, customFx, wrapperModule
1212

1313
function runner() {
1414
var exercise = execute(filecheck(exerciser()))
@@ -36,10 +36,17 @@ function runner() {
3636
callback(null, true)
3737
});
3838

39-
if (wrapperModulePath) {
39+
if (wrapperModule && wrapperModule.path) {
4040
exercise.addSetup(function setupWrapperModule(mode, callback) {
41-
this.solutionCommand = [ wrapperModulePath, this.solution ].concat(this.solutionArgs)
42-
this.submissionCommand = [ wrapperModulePath, this.submission ].concat(this.submissionArgs)
41+
var modulePath = wrapperModule.path
42+
if (wrapperModule.options && wrapperModule.options.localized) {
43+
var localizedPath = modulePath.replace(/\.\w+$/, '_' + exercise.lang + '$&')
44+
if (fs.existsSync(path.resolve(process.cwd(), localizedPath))) {
45+
modulePath = localizedPath
46+
}
47+
}
48+
this.solutionCommand = [ modulePath, this.solution ].concat(this.solutionArgs)
49+
this.submissionCommand = [ modulePath, this.submission ].concat(this.submissionArgs)
4350

4451
if (input.length > 0) {
4552
var file = path.join(os.tmpdir(), path.basename(this.solution)) + '.input.json'
@@ -116,9 +123,9 @@ runner.quiet = function quiet() {
116123
return runner.apply(null, arguments)
117124
}
118125

119-
runner.wrapWith = function wrapWith(modulePath) {
126+
runner.wrapWith = function wrapWith(modulePath, options) {
120127
verbose = false
121-
wrapperModulePath = modulePath
128+
wrapperModule = { path: modulePath, options: options }
122129
return runner.apply(null, Array.prototype.slice.call(arguments, 1))
123130
}
124131

i18n/en.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@
2626
},
2727
"Higher Order Functions": {
2828
"call_log": "Called function %d times."
29+
},
30+
"Function Spies": {
31+
"call_times": "Method called %d times.",
32+
"incorrect_return": "Check your function's return value!",
33+
"incorrect_this": "Check the function's this! Hint: Function#apply",
34+
"not_all_args": "Check you are passing ALL the arguments! Hint: Function#apply"
2935
}
3036
}
3137
}

0 commit comments

Comments
 (0)