parent
01405ea8a4
commit
c5b360ee23
@ -0,0 +1 @@
|
|||||||
|
--require spec_helper --fail-fast --format documentation
|
@ -0,0 +1,7 @@
|
|||||||
|
On the 9th. William Findley and David Redick--deputed by the Committee of Safety (as it is designated) which met on the 2d. of this month at Parkinson Ferry arrived in Camp with the Resolutions of the said Committee; and to give information of the State of things in the four Western Counties of Pennsylvania to wit--Washington Fayette Westd. & Alligany in order to see if it would prevent the March of the Army into them.
|
||||||
|
|
||||||
|
At 10 oclock I had a meeting with these persons in presence of Govr. Howell (of New Jersey) the Secretary of the Treasury, Colo. Hamilton, & Mr. Dandridge: Govr. Mifflin was invited to be present, but excused himself on acct. of business.
|
||||||
|
|
||||||
|
I told the Deputies that by one of the Resolutions it would appear that they were empowered to give information of the disposition & of the existing state of matters in the four Counties above men[tioned]; that I was ready to hear & would listen patiently, and with candour to what they had to say.
|
||||||
|
|
||||||
|
Mr. Findley began. He confined his information to such parts of the four Counties as he was best acquainted with; referring to Mr. Reddick for a recital of what fell within his knowledge, in the other parts of these Counties.
|
@ -0,0 +1,18 @@
|
|||||||
|
Maître Corbeau, sur un arbre perché,
|
||||||
|
Tenait en son bec un fromage.
|
||||||
|
Maître Renard, par l'odeur alléché,
|
||||||
|
Lui tint à peu près ce langage :
|
||||||
|
« Hé ! bonjour, Monsieur du Corbeau.
|
||||||
|
Que vous êtes joli ! Que vous me semblez beau !
|
||||||
|
Sans mentir, si votre ramage
|
||||||
|
Se rapporte à votre plumage,
|
||||||
|
Vous êtes le Phénix des hôtes de ces bois. »
|
||||||
|
A ces mots le Corbeau ne se sent pas de joie ;
|
||||||
|
Et pour montrer sa belle voix,
|
||||||
|
Il ouvre un large bec, laisse tomber sa proie.
|
||||||
|
Le Renard s'en saisit, et dit : « Mon bon Monsieur,
|
||||||
|
Apprenez que tout flatteur
|
||||||
|
Vit aux dépens de celui qui l'écoute :
|
||||||
|
Cette leçon vaut bien un fromage, sans doute. »
|
||||||
|
Le Corbeau, honteux et confus,
|
||||||
|
Jura, mais un peu tard, qu'on ne l'y prendrait plus.
|
@ -0,0 +1,46 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
def clean_text(text)
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse(text)
|
||||||
|
end
|
||||||
|
|
||||||
|
def count_occurencies(words)
|
||||||
|
end
|
||||||
|
|
||||||
|
def normalize(occurencies, total_count)
|
||||||
|
end
|
||||||
|
|
||||||
|
def display_top_20(frequencies)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Le code suivant s'execute uniquement lorsque ce fichier est le fichier
|
||||||
|
# principal en cours d'exécution (et non si il est requis ou chargé
|
||||||
|
# par un autre fichier)
|
||||||
|
if $0 == __FILE__
|
||||||
|
if ARGV.empty?
|
||||||
|
puts 'usage: frequency.rb <text_file>'
|
||||||
|
exit 0
|
||||||
|
end
|
||||||
|
|
||||||
|
file_path = ARGV[0]
|
||||||
|
|
||||||
|
# Lecture du fichier texte
|
||||||
|
file_content = File.read(file_path)
|
||||||
|
|
||||||
|
# Nettoyage du texte (pour la ponctuation par exemple
|
||||||
|
cleaned_text = clean_text(file_content)
|
||||||
|
|
||||||
|
# Séparation du texte en mots
|
||||||
|
words = parse(cleaned_text)
|
||||||
|
|
||||||
|
# Comptage des occurences des mots
|
||||||
|
occurencies = count_occurencies(words)
|
||||||
|
|
||||||
|
# Calcul des fréquences (normalisation des occurences)
|
||||||
|
frequencies = normalize(occurencies, words.size)
|
||||||
|
|
||||||
|
# Tri et affichage des 20 premiers résultats
|
||||||
|
display_top_20(frequencies)
|
||||||
|
end
|
@ -0,0 +1,46 @@
|
|||||||
|
Hast Du etwas Zeit für mich
|
||||||
|
Dann singe ich ein Lied für Dich
|
||||||
|
Von 99 Luftballons
|
||||||
|
Auf ihrem Weg zum Horizont
|
||||||
|
Denkst Du vielleicht grad' an mich
|
||||||
|
Dann singe ich ein Lied für Dich
|
||||||
|
Von 99 Luftballons
|
||||||
|
Und dass sowas von sowas kommt
|
||||||
|
|
||||||
|
99 Luftballons
|
||||||
|
Auf ihrem Weg zum Horizont
|
||||||
|
Hielt man fuer UFOs aus dem All
|
||||||
|
Darum schickte ein General
|
||||||
|
'ne Fliegerstaffel hinterher
|
||||||
|
Alarm zu geben, wenn's so waer
|
||||||
|
Dabei war'n da am Horizont
|
||||||
|
Nur 99 Luftballons
|
||||||
|
|
||||||
|
99 Duesenflieger
|
||||||
|
Jeder war ein grosser Krieger
|
||||||
|
Hielten sich fuer Captain Kirk
|
||||||
|
Das gab ein grosses Feuerwerk
|
||||||
|
|
||||||
|
|
||||||
|
Die Nachbarn haben nichts gerafft
|
||||||
|
Und fuehlten sich gleich angemacht
|
||||||
|
Dabei schoss man am Horizont
|
||||||
|
Auf 99 Luftballons
|
||||||
|
|
||||||
|
99 Kriegsminister
|
||||||
|
Streichholz und Benzinkanister
|
||||||
|
Hielten sich fuer schlaue Leute
|
||||||
|
Witterten schon fette Beute
|
||||||
|
Riefen: Krieg und wollten Macht
|
||||||
|
Mann, wer haette das gedacht
|
||||||
|
Dass es einmal soweit kommt
|
||||||
|
Wegen 99 Luftballons
|
||||||
|
|
||||||
|
99 Jahre Krieg
|
||||||
|
Liessen keinen Platz fuer Sieger
|
||||||
|
Kriegsminister gibt's nicht mehr
|
||||||
|
Und auch keine Duesenflieger
|
||||||
|
Heute zieh ich meine Runden
|
||||||
|
Seh' die Welt in Truemmern liegen
|
||||||
|
Hab' 'nen Luftballon gefunden
|
||||||
|
Denk' an Dich und lass' ihn fliegen
|
@ -0,0 +1,85 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
## Consigne : Ecrivez les fonctions décrites en dessous de leurs descriptions.
|
||||||
|
## Pour executer les tests relatifs au kata, executez 'rspec'
|
||||||
|
|
||||||
|
# Signature: add(a, b)
|
||||||
|
# Retourne l'addition de a et b
|
||||||
|
def add(a, b)
|
||||||
|
a + b
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# Signature: cat(a, b)
|
||||||
|
# Retourne la concaténation des deux chaines a et b
|
||||||
|
|
||||||
|
|
||||||
|
# Signature: words(s)
|
||||||
|
# Indice : Regarder la documentation de string
|
||||||
|
# Retourne les mots de la string s
|
||||||
|
|
||||||
|
|
||||||
|
# Signature: upcase!(s)
|
||||||
|
# Retourne true mais modifie la string s pour que
|
||||||
|
# toutes ses lettres soient en majuscules
|
||||||
|
|
||||||
|
|
||||||
|
# Signature: dot(arr)
|
||||||
|
# Retourne une chaine de caractère avec les éléments du tableau
|
||||||
|
# séparés par un point milieu · (Attention, ce n'est pas le point de votre clavier!)
|
||||||
|
# Indice : Regarder la documentation de array
|
||||||
|
# Exemple : dot(['aut', 'eur', 'trice']) => 'aut·eur·rice'
|
||||||
|
|
||||||
|
|
||||||
|
# Signature: minimum_length_4(s)
|
||||||
|
# Retourne une chaine de caractère où les mots de moins de 3 caractères
|
||||||
|
# sont supprimés
|
||||||
|
# Exemple : minimum_length_4('I do not like potatoes') => 'like potatoes'
|
||||||
|
|
||||||
|
|
||||||
|
# Signature: multiply_array(arr, n)
|
||||||
|
# Retourne un tableau qui contient tous les nombres de arr multipliés par n
|
||||||
|
# Exemple : multiply_array([1, 2, 3], 3) => [3, 6, 9]
|
||||||
|
# Obligation : utiliser l'opérateur #map
|
||||||
|
|
||||||
|
|
||||||
|
# Signature: sum(arr)
|
||||||
|
# Retourne la somme des nombres du tableau
|
||||||
|
# Exemple : sum([1, 2, -1, 3]) => 5
|
||||||
|
# Obligation : utiliser l'opérateur #reduce
|
||||||
|
|
||||||
|
|
||||||
|
# Signature: capitalize_words(s)
|
||||||
|
# Retourne la string s avec tous les mots en capitalize
|
||||||
|
# (première lettre en majuscule)
|
||||||
|
# Exemple : capitalize_words('thanks obama') => 'Thanks Obama'
|
||||||
|
|
||||||
|
|
||||||
|
# Signature: enumeration(n)
|
||||||
|
# Retourne un tableau qui contient tous les nombres
|
||||||
|
# de 1 à n
|
||||||
|
# Indice : Regardez les Range
|
||||||
|
# Exemple : enumeration(3) => [1, 2, 3]
|
||||||
|
|
||||||
|
|
||||||
|
# Signature: compte_repetitions(arr)
|
||||||
|
# Retourne le nombre de répétition de chaque mot
|
||||||
|
# Exemple : compte_repetitions([
|
||||||
|
# "oui", "bip", "bop", "bip", "blop", "oui",
|
||||||
|
# "je", "suis", "un", "robot", "oui", "robot"
|
||||||
|
# ])
|
||||||
|
# => { "oui" => 2, "bip" => 1, "robot" => 1, "bop" => 0, "blop" => 0, "je" => 0, ... }
|
||||||
|
|
||||||
|
|
||||||
|
# Signature: repetitions(s)
|
||||||
|
# Retourne le nombre de répétition dans la phrase
|
||||||
|
# Indice : Un nombre de répétition, c'est pas un nombre d'occurence.
|
||||||
|
# Indice 2 : Pensez à la casse et par quels caractères splitter`
|
||||||
|
# Exemple : repetitions("Oui bip bop bip blop. Oui, je suis un robot, oui robot.") => 4
|
||||||
|
|
||||||
|
|
||||||
|
# Signature: dictionnary(s)
|
||||||
|
# Retourne un hash qui contient les mots pour clés et
|
||||||
|
# leur définitions comme valeur.
|
||||||
|
# Exemple: dictionnary('Ours: Mammifère carnivore (ursidé)|Lapin: Mammifère rongeur très prolifique') =>
|
||||||
|
# { 'Ours' => 'Mammifère carnivore (ursidé)', 'Lapin' => 'Mammifère rongeur très prolifique' }
|
@ -0,0 +1,157 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe 'Katas' do
|
||||||
|
describe '#add' do
|
||||||
|
it 'adds the two values' do
|
||||||
|
expect(add(1, 2)).to eq 3
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'adds negatives correctly' do
|
||||||
|
expect(add(1, -1)).to eq 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#cat' do
|
||||||
|
it 'cats the two values' do
|
||||||
|
expect(cat('Hello, ', 'world')).to eq 'Hello, world'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#words' do
|
||||||
|
it 'returns the words' do
|
||||||
|
expect(words('Je suis une patate')).to eq ['Je', 'suis', 'une', 'patate']
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'correctly skips spaces the words' do
|
||||||
|
expect(words(' Vous ne passerez pas ')).to eq [
|
||||||
|
'Vous',
|
||||||
|
'ne',
|
||||||
|
'passerez',
|
||||||
|
'pas'
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#upcase!' do
|
||||||
|
let(:string) { 'khaaan' }
|
||||||
|
|
||||||
|
it 'returns true' do
|
||||||
|
expect(upcase!(string)).to be true
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'updates the string' do
|
||||||
|
upcase!(string)
|
||||||
|
expect(string).to eq 'KHAAAN'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#dot' do
|
||||||
|
it 'returns the merged string by a dot' do
|
||||||
|
expect(dot(['aut', 'eur', 'rice'])).to eq 'aut·eur·rice'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#minimum_length_4' do
|
||||||
|
it 'returns the string with only words of min length 4' do
|
||||||
|
expect(minimum_length_4('I do not like dwarves')).to eq 'like dwarves'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'can return an empty string if needed' do
|
||||||
|
expect(minimum_length_4('And my axe')).to eq ''
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#multiply_array' do
|
||||||
|
it 'multiply the array by the second argument' do
|
||||||
|
expect(multiply_array([1, 2, 3], 3)).to eq [3, 6, 9]
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'works if the multiplier is negative' do
|
||||||
|
expect(multiply_array([4, -2, 0], -2)).to eq [-8, 4, 0]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#sum' do
|
||||||
|
it 'sums the numbers' do
|
||||||
|
expect(sum([1, 2, 3])).to eq 6
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'works with an empty array' do
|
||||||
|
expect(sum([])).to eq 0
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'works with negatives' do
|
||||||
|
expect(sum([1, 2, -1, 3])).to eq 5
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#capitalize_words' do
|
||||||
|
it 'returns the string with the words capitalized' do
|
||||||
|
expect(capitalize_words('Je ne connais pas la ponctuation'))
|
||||||
|
.to eq 'Je Ne Connais Pas La Ponctuation'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#enumeration' do
|
||||||
|
it 'returns the correct enumeration between 1 and n' do
|
||||||
|
expect(enumeration(3)).to eq [1, 2, 3]
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'works with negatives' do
|
||||||
|
expect(enumeration(-1)).to eq [-1, 0, 1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#compte_repetitions' do
|
||||||
|
it 'returns the repetitions' do
|
||||||
|
mots = [
|
||||||
|
"oui", "bip", "bop", "bip", "blop", "oui",
|
||||||
|
"je", "suis", "un", "robot", "oui", "robot"
|
||||||
|
]
|
||||||
|
|
||||||
|
expect(compte_repetitions(mots)).to eq({
|
||||||
|
"bip" => 1,
|
||||||
|
"blop" => 0,
|
||||||
|
"bop" => 0,
|
||||||
|
"je" => 0,
|
||||||
|
"oui" => 2,
|
||||||
|
"robot" => 1,
|
||||||
|
"suis" => 0,
|
||||||
|
"un" => 0,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'supports an empty word list' do
|
||||||
|
mots = []
|
||||||
|
|
||||||
|
expect(compte_repetitions(mots)).to eq({})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#repetitions' do
|
||||||
|
it 'returns the total count of repetitions' do
|
||||||
|
s = 'Oui bip bop bip blop. Oui, je suis un robot, oui robot.'
|
||||||
|
expect(repetitions(s)).to eq 4
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'supports a string without repetitions' do
|
||||||
|
s = 'hello world'
|
||||||
|
expect(repetitions(s)).to eq 0
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'supports an empty string' do
|
||||||
|
s = ''
|
||||||
|
expect(repetitions(s)).to eq 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#dictionnary' do
|
||||||
|
it 'turns a specific string into a dictionnary' do
|
||||||
|
expect(dictionnary('Ours: Mammifère carnivore (ursidé)|Lapin: Mammifère rongeur très prolifique'))
|
||||||
|
.to eq({
|
||||||
|
'Ours' => 'Mammifère carnivore (ursidé)',
|
||||||
|
'Lapin' => 'Mammifère rongeur très prolifique',
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,112 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe 'Frequency' do
|
||||||
|
describe '#clean_text' do
|
||||||
|
let(:text) { "some«»text\.not,'\":;![really clean?]" }
|
||||||
|
it 'cleans the text' do
|
||||||
|
expect(clean_text(text)).to eq('some text not really clean ')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#parse' do
|
||||||
|
let(:text) { 'some text not really clean ' }
|
||||||
|
it 'splits the text' do
|
||||||
|
expect(parse(text)).to eq(%w[some text not really clean])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#count_occurencies' do
|
||||||
|
let(:words) { %w[some text not really clean and not really original] }
|
||||||
|
it 'counts occurencies of each word' do
|
||||||
|
expect(count_occurencies(words)).to eq(
|
||||||
|
'some' => 1,
|
||||||
|
'text' => 1,
|
||||||
|
'not' => 2,
|
||||||
|
'really' => 2,
|
||||||
|
'clean' => 1,
|
||||||
|
'and' => 1,
|
||||||
|
'original' => 1
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#normalize' do
|
||||||
|
let(:words) { %w[apple banana orange apple banana apple] }
|
||||||
|
let(:occurencies) do
|
||||||
|
{
|
||||||
|
'apple' => 3,
|
||||||
|
'banana' => 2,
|
||||||
|
'orange' => 1
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'computes frequencies' do
|
||||||
|
expect(normalize(occurencies, words.size)).to eq(
|
||||||
|
'apple' => 0.5,
|
||||||
|
'banana' => 0.333,
|
||||||
|
'orange' => 0.167
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#display_top_20' do
|
||||||
|
let(:frequencies) do
|
||||||
|
{
|
||||||
|
'layout' => 1,
|
||||||
|
'post' => 1,
|
||||||
|
'title' => 1,
|
||||||
|
'tp1' => 2,
|
||||||
|
'programmation' => 3,
|
||||||
|
'objet' => 4,
|
||||||
|
'interpr' => 2,
|
||||||
|
'entr' => 2,
|
||||||
|
'mati' => 2,
|
||||||
|
'categories' => 1,
|
||||||
|
'ruby' => 32,
|
||||||
|
'pour' => 21,
|
||||||
|
'but' => 2,
|
||||||
|
'vous' => 20,
|
||||||
|
'faire' => 2,
|
||||||
|
'pratiquer' => 1,
|
||||||
|
'les' => 26,
|
||||||
|
'bases' => 3,
|
||||||
|
'langage' => 5,
|
||||||
|
'particulier' => 1,
|
||||||
|
'prendre' => 2,
|
||||||
|
'main' => 1,
|
||||||
|
'que' => 12
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:expected_output) do
|
||||||
|
<<OUTPUT
|
||||||
|
ruby: 32
|
||||||
|
les: 26
|
||||||
|
pour: 21
|
||||||
|
vous: 20
|
||||||
|
que: 12
|
||||||
|
langage: 5
|
||||||
|
objet: 4
|
||||||
|
programmation: 3
|
||||||
|
bases: 3
|
||||||
|
tp1: 2
|
||||||
|
interpr: 2
|
||||||
|
entr: 2
|
||||||
|
mati: 2
|
||||||
|
but: 2
|
||||||
|
faire: 2
|
||||||
|
prendre: 2
|
||||||
|
layout: 1
|
||||||
|
post: 1
|
||||||
|
title: 1
|
||||||
|
categories: 1
|
||||||
|
OUTPUT
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'print the top 20 frequencies' do
|
||||||
|
expect do
|
||||||
|
display_top_20(frequencies)
|
||||||
|
end.to output(expected_output).to_stdout
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,8 @@
|
|||||||
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..'))
|
||||||
|
|
||||||
|
require 'katas'
|
||||||
|
require 'frequency'
|
||||||
|
|
||||||
|
RSpec.configure do |config|
|
||||||
|
|
||||||
|
end
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,208 @@
|
|||||||
|
---
|
||||||
|
layout: post
|
||||||
|
title: "TP1 de programmation objet interprétée - Entrée en matière"
|
||||||
|
categories: ruby-2a
|
||||||
|
---
|
||||||
|
|
||||||
|
# Entrée en matière
|
||||||
|
|
||||||
|
Ce TP a pour but de vous faire pratiquer les bases du langage Ruby, en particulier :
|
||||||
|
|
||||||
|
* Prendre en main l'environnement
|
||||||
|
* Bases de la bibliothèque standard
|
||||||
|
* Méthodes
|
||||||
|
* Hash et Map
|
||||||
|
* Une façon de tester
|
||||||
|
* Apprendre à mélanger intuition et parcours de la documentation pour découvrir le Ruby que l'on ignore encore
|
||||||
|
|
||||||
|
Ruby est un langage 100% objet, tout est objet, même nil (null) ! Mais avant de se lancer dans de la programmation objet, assurons nous d'avoir bien les bases : Amusons avec des scripts classiques, Ruby permet ça aussi !
|
||||||
|
|
||||||
|
## Outils
|
||||||
|
|
||||||
|
1. Votre éditeur de texte/IDE préféré! Pas de guerre de religion ici! (Liste non exhaustive en bas).
|
||||||
|
2. *irb* : le débogueur ruby. Idéal pour tester directement des commandes. Peut aussi servir à déboguer.
|
||||||
|
3. *pry*: irb, en mieux: avec debogueur et couleurs. Installable comme une gemmme (cf. votre cours).
|
||||||
|
3. *rspec* sera utile pour ce TP. C'est un outil de tests unitaires (ils vous sont fournis cette semaine).
|
||||||
|
3. *ri*: l'aide locale de ruby, plus rapide que le réseau mais moins jolie (exemple `ri String#scan`)
|
||||||
|
4. Une ancienne version d'un bon livre sur ruby a été ouverte. Vous la trouverez [là](http://ruby-doc.com/docs/ProgrammingRuby/). Elle ne couvre pas tous les ajouts récents mais toute la base du langage est toujours bonne, et bien expliquée.
|
||||||
|
5. Doc de référence: l'officielle sur [ruby-doc.org](https://ruby-doc.org/core-2.6/). Barre de recherche en haut à droite.
|
||||||
|
6. Un [cours de programmation](http://evc-cit.info/cit020/beginning-programming/index.html) écrit avec Ruby comme langage support.
|
||||||
|
|
||||||
|
Une rapide présentation des IDE ruby est disponible à la fin de ce document... Si vous avez un IDE préféré, il devrait faire l'affaire.
|
||||||
|
|
||||||
|
|
||||||
|
## 1 - Katas marrants
|
||||||
|
|
||||||
|
Télécharger les fichiers de ce répertoire (sujet, ainsi que les tests unitaires et fichiers de données nécessaires).
|
||||||
|
|
||||||
|
>De la même manière que pour un pratiquant d'art martiaux, les katas sont des exercices que font les développeurs pour améliorer leurs compétences via répétition et entraînement.
|
||||||
|
|
||||||
|
Vous devez éditer le fichier `katas.rb` qui contient une liste de fonctions à écrire.
|
||||||
|
|
||||||
|
Vous pouvez vérifier vos katas au fur et à mesure de votre dev avec les tests unitaires écrits pour cet usage. Pour cela, ouvrez un terminal, allez dans le dossier de votre projet et tapez simplement `rspec`. Si il n'est pas installé, regardez la section suivante
|
||||||
|
|
||||||
|
### Installation de `rspec`
|
||||||
|
|
||||||
|
On installe la gemme:
|
||||||
|
`gem install --user-install rspec`
|
||||||
|
|
||||||
|
On cherche le répertoire d'exécutables à ajouter au PATH:
|
||||||
|
|
||||||
|
~~~
|
||||||
|
find ~/.gem -name bin -type d
|
||||||
|
/home/delobel/.gem/ruby/2.7.0/bin
|
||||||
|
~~~
|
||||||
|
|
||||||
|
On ajoute le chemin au PATH dans le .bashrc (attention, vous n'avez pas forcément la même version de ruby).
|
||||||
|
`echo 'PATH="$PATH:/home/delobel/.gem/ruby/2.7.0/bin"' >> ~/.bashrc`
|
||||||
|
|
||||||
|
On relit le fichier de conf:
|
||||||
|
`source ~/.bashrc`
|
||||||
|
|
||||||
|
## 2 - Calcul de fréquences
|
||||||
|
### Consignes
|
||||||
|
|
||||||
|
Le but de cet application, c'est de prendre un nom de fichier en paramètre et de ressortir les fréquences (nombre d'occurence d'un mot par rapport au nombre de mots total) des 20 mots les plus courants du fichier, en ignorant les mots de moins de 3 caractères et bien sûr les ponctuations.
|
||||||
|
|
||||||
|
On veut donc pouvoir la lancer comme suit sur le fichier exemple `french_text.txt`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$>ruby frequency.rb french_text.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
Et avoir le résultat suivant :
|
||||||
|
|
||||||
|
```
|
||||||
|
corbeau: 0.029
|
||||||
|
que: 0.022
|
||||||
|
vous: 0.022
|
||||||
|
tes: 0.022
|
||||||
|
tre: 0.015
|
||||||
|
bec: 0.015
|
||||||
|
fromage: 0.015
|
||||||
|
renard: 0.015
|
||||||
|
peu: 0.015
|
||||||
|
monsieur: 0.015
|
||||||
|
sans: 0.015
|
||||||
|
votre: 0.015
|
||||||
|
ces: 0.015
|
||||||
|
sur: 0.007
|
||||||
|
arbre: 0.007
|
||||||
|
perch: 0.007
|
||||||
|
tenait: 0.007
|
||||||
|
son: 0.007
|
||||||
|
par: 0.007
|
||||||
|
odeur: 0.007
|
||||||
|
```
|
||||||
|
|
||||||
|
Attention, si on ne passe aucun paramètre au programme, un message d'erreur doit s'afficher sur le flux d'erreur (`$stderr`). Exemple :
|
||||||
|
|
||||||
|
```
|
||||||
|
$>ruby frequency.rb
|
||||||
|
usage: frequency.rb <text_file>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Quelques pistes...
|
||||||
|
|
||||||
|
L'utilisation de [Hash](https://docs.ruby-lang.org/en/2.0.0/Hash.html) pour le comptage des mots est particulièrement utile. Surtout si vous l'initialisez avec une valeur par défaut en cas de clef absente...
|
||||||
|
|
||||||
|
On ne peut que vous conseiller de séparer l'application en plusieurs responsabilités :
|
||||||
|
|
||||||
|
* Lecture du fichier texte
|
||||||
|
* Nettoyage du texte (pour la ponctuation par exemple)
|
||||||
|
* Séparation du texte en mots
|
||||||
|
* Comptage des occurences des mots
|
||||||
|
* Calcul des fréquences (normalisation des occurences)
|
||||||
|
* Tri et affichage des 20 premiers résultats
|
||||||
|
* Programme principal qui associe les différentes responsabilités ensemble
|
||||||
|
|
||||||
|
Pour nettoyer le texte, vous pouvez regarder ce que fait `String#gsub(motif, remplacement)`. Un motif peut être une expression rationnelle Ruby (`/^lapino?s/` par exemple).
|
||||||
|
|
||||||
|
Cela vous permettra d'écrire plusieurs petites fonctions que vous pourrez tester au fur et à mesure. N'hésitez pas à vous référer aux katas écrits avant.
|
||||||
|
|
||||||
|
### Variante (si vous avez été très rapide sur le précédent)
|
||||||
|
|
||||||
|
Ajoutez une option -l à votre programme qui permet de calculer la fréquence des différentes lettres du texte.
|
||||||
|
|
||||||
|
## 3 - Détection de langues
|
||||||
|
|
||||||
|
On vous fournit un fichier JSON `stop_words.json` qui contient les [mots vides](https://fr.wikipedia.org/wiki/Mot_vide) (ou *stopwords*) les plus courants dans les langues les plus courantes.
|
||||||
|
|
||||||
|
Les mots sont au format qui suit :
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"<label de la langue>": [
|
||||||
|
"<mot vide 1>",
|
||||||
|
"<mot vide 2>",
|
||||||
|
...
|
||||||
|
],
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
L'idée est de détecter quelle langue est utilisée dans un texte en fonction de ces mots vides. Ainsi, si le texte a la plus grande intersection avec des mots vides de la langue labellisée 'fr' (french), on pourra supposer que le texte est en Français.
|
||||||
|
|
||||||
|
L'algorithme est le suivant :
|
||||||
|
|
||||||
|
* charger le fichier cible, mettre les mots dans un tableau, supprimer les doublons
|
||||||
|
* pour chaque langue de la référence
|
||||||
|
* récupérer la liste des mots vide de la langue courante
|
||||||
|
* calculer l'intersection entre les mots vides de la langue courante et les mots du texte
|
||||||
|
* retenir la taille de l'intersection pour la langue courante (un conseil ici, utilisez un hash pour associer langue et taille)
|
||||||
|
* fin pour
|
||||||
|
|
||||||
|
trouver le maximum des intersections calculées
|
||||||
|
afficher le label du maximum des intersections
|
||||||
|
|
||||||
|
|
||||||
|
On va fournir un texte à analyser via un paramètre de l'application :
|
||||||
|
```
|
||||||
|
$>ruby detect_language.rb french_text.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
Et on s'attendra au résultat suivant :
|
||||||
|
```
|
||||||
|
Detected language: 'fr'
|
||||||
|
```
|
||||||
|
|
||||||
|
Attention, si on ne passe aucun paramètre au programme, je voudrais un message qui averti l'utilisateur. Exemple :
|
||||||
|
```
|
||||||
|
$>ruby detect_language.rb
|
||||||
|
usage: detect_language.rb <text_file>
|
||||||
|
```
|
||||||
|
|
||||||
|
Testez sur les fichiers `french_text.txt`, `english_text.txt` et `german_text.txt`
|
||||||
|
|
||||||
|
### Quelques pistes
|
||||||
|
On peut vous conseiller de séparer votre code en responsabilités différentes via des méthodes :
|
||||||
|
|
||||||
|
|Nom de la méthode|Paramètres|Détail|
|
||||||
|
|--------|--------|--------|
|
||||||
|
|load_reference|reference_file_path|Méthode qui renvoie le fichier JSON chargé dans un hash|
|
||||||
|
|load_text_file|text_file_path|Méthode qui fait le chargement, le nettoyage et la séparation du fichier texte en mots|
|
||||||
|
|intersection_sizes|reference, text_words| Méthode qui prend la référence et calcul l'intersection entre la liste de mots d'une langue et les mots du texte|
|
||||||
|
|detect_language|reference, text_words| Méthode qui appelle la méthode précédente et parcours les intersections pour trouver la plus grande et retourne son nom
|
||||||
|
|
||||||
|
|
||||||
|
* Attention lors de la lecture du fichier texte, se référer au deuxième exercice
|
||||||
|
* Un opérateur magique sur [Array](https://docs.ruby-lang.org/en/2.0.0/Array.html) existe... Il s'écrit comme le 'ET' binaire
|
||||||
|
* Ne vous laissez pas intimider par le [JSON](http://ruby-doc.org/stdlib-2.0.0/libdoc/json/rdoc/JSON.html), vous n'avez qu'une méthode statique à appeler sur le module pour parser le document. Cela vous renvoie un Hash qu'il vous suffira de parcourir.
|
||||||
|
* Pour charger une dépendance de Ruby, on utilise `require 'une_dependance'`. `une_dependance` est un fichier ruby qui peut être dans l'installation standard de Ruby (C'est le cas de JSON), ou une gemme (le système de paquets de ruby que l'on verra par la suite).
|
||||||
|
|
||||||
|
## IDE
|
||||||
|
|
||||||
|
Les goûts et les couleurs, ça ne se discute pas: il y a rarement d'IDE qui fasse l'unanimité pour un langage ouvert. Voici néanmoins quelques possibilités.
|
||||||
|
|
||||||
|
* Vim colore et indente vite.
|
||||||
|
* Emacs a de bons plugins Ruby, mais nécessite pas mal de configuration pour donner son plein potentiel.
|
||||||
|
* Geany est un éditeur de texte tout simple mais qui fait bien son boulot.
|
||||||
|
* Eclipse, Faut être patient au lancement, comme toujours, mais le plugin est correct (Partie de dltk - Dynamic Language ToolKit, qui gère aussi d'autres langages interprétés).
|
||||||
|
* [Atom](https://atom.io/) est un éditeur libre, développé par github, pas packagé sur debian.
|
||||||
|
* [Aptana](http://www.aptana.com), un IDE basé sur éclipse. Bonnes capacités aussi pour Ruby On Rails. Disponible aussi sous forme indépendante (un package tout pret).
|
||||||
|
* Orable a poussé Netbeans à se concentrer sur Java, mais la communauté a repris le développement d'un plugin Ruby & Rails disponible [sur le site officiel](http://plugins.netbeans.org/plugin/38549)
|
||||||
|
* [RubyMine](https://www.jetbrains.com/ruby/index.html), un IDE dédié à Ruby et Rails, par JetBrains, qui fait aussi IntelliJ, PHPStorm, Clion, etc.
|
||||||
|
* [Sapphire](http://www.sapphiresteel.com/Products/Ruby-In-Steel/Ruby-In-Steel-Developer-Overview.html), un IDE basé sur visual studio.
|
||||||
|
* [VS Code](https://code.visualstudio.com/) n'est pas disponible sous Debian, mais un paquet debian est disponible sur le site.
|
||||||
|
* [VSCodium](https://github.com/VSCodium/vscodium) est une rebuild de VSCode avec uniquement la configuration "comminity" (Sans le branding, la télémétrie, et en licence MIT). Sous ArchLinux, il est en d&pot `aur`, sous debian, vous trouverez les paquets [dans les release](https://github.com/VSCodium/vscodium/releases) du dépot.
|
||||||
|
|
Loading…
Reference in new issue