Created
January 9, 2015 01:44
-
-
Save roktas/a29bd1acc67b643b0c8d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# Abecesel isim üret | |
# | |
# Gereksinimler: Ruby >= 2.1, turkish_support (gem) | |
require 'optparse' | |
require 'ostruct' | |
require 'yaml' | |
require 'turkish_support' | |
using TurkishSupport | |
def die(*lines) | |
$stderr.puts lines.map { |line| "E: #{line}" }.join("\n") | |
exit 1 | |
end | |
def cry(*lines) | |
$stderr.puts lines.map { |line| "W: #{line}" }.join("\n") | |
end | |
def log(*lines) | |
$stderr.puts lines.map { |line| "I: #{line}" }.join("\n") | |
end | |
class Generator # rubocop:disable Metrics/ClassLength | |
DICTIONARY = { | |
adjective: %w( | |
agresif | |
alafranga | |
alaturka | |
analog | |
anonim | |
antik | |
asil | |
avare | |
beklenen | |
belirsiz | |
benzersiz | |
bereketli | |
beyaz | |
bozuk | |
bulutsuz | |
cesur | |
cezbedici | |
ciddi | |
dar | |
dengesiz | |
derin | |
dev | |
dijital | |
dik | |
dogmatik | |
durgun | |
egzotik | |
elastik | |
engebeli | |
epik | |
eski | |
etnik | |
ezeli | |
fakir | |
geleneksel | |
geveze | |
gizemli | |
gri | |
grotesk | |
hafif | |
halsiz | |
hantal | |
homojen | |
huzurlu | |
ihtiyar | |
ilahi | |
ilkel | |
ince | |
iri | |
jenerik | |
kaotik | |
kaygan | |
kederli | |
kirli | |
korkutucu | |
kurak | |
kusursuz | |
kutsal | |
lacivert | |
lanetli | |
limitsiz | |
manyetik | |
masum | |
mavi | |
mekanik | |
mikro | |
mistik | |
monoton | |
mor | |
muhtelif | |
nazik | |
nemli | |
nevrotik | |
olgun | |
otomatik | |
parlak | |
patolojik | |
pembe | |
plastik | |
radyoaktif | |
rahat | |
ritmik | |
romantik | |
senfonik | |
serin | |
serseri | |
sert | |
sesli | |
sessiz | |
sihirli | |
sisli | |
siyah | |
sonsuz | |
tehlikeli | |
temiz | |
titrek | |
tombul | |
tropikal | |
turuncu | |
ucuz | |
ulu | |
unutulmaz | |
uyduruk | |
uzak | |
uzun | |
verimli | |
verimsiz | |
yabani | |
yapay | |
yatay | |
yeni | |
yitik | |
yorgun | |
yuvarlak | |
zarif | |
zehirli | |
zengin | |
zorlu | |
), | |
city: %w( | |
adana | |
adıyaman | |
afyonkarahisar | |
ağrı | |
aksaray | |
amasya | |
ankara | |
antalya | |
ardahan | |
artvin | |
aydın | |
balıkesir | |
bartın | |
batman | |
bayburt | |
bilecik | |
bingöl | |
bitlis | |
bolu | |
burdur | |
bursa | |
çanakkale | |
çankırı | |
çorum | |
denizli | |
diyarbakır | |
düzce | |
edirne | |
elazığ | |
erzincan | |
erzurum | |
eskişehir | |
gaziantep | |
giresun | |
gümüşhane | |
hakkari | |
hatay | |
ığdır | |
ısparta | |
istanbul | |
izmir | |
kahramanmaraş | |
karabük | |
karaman | |
kars | |
kastamonu | |
kayseri | |
kırıkkale | |
kırklareli | |
kırşehir | |
kilis | |
kocaeli | |
konya | |
kütahya | |
malatya | |
manisa | |
mardin | |
mersin | |
muğla | |
muş | |
nevşehir | |
niğde | |
ordu | |
osmaniye | |
rize | |
sakarya | |
samsun | |
siirt | |
sinop | |
sivas | |
şanlıurfa | |
şırnak | |
tekirdağ | |
tokat | |
trabzon | |
tunceli | |
uşak | |
van | |
yalova | |
yozgat | |
zonguldak | |
), | |
color: %w( | |
bej | |
beyaz | |
bordo | |
camgöbeği | |
gri | |
kahverengi | |
kırmızı | |
lacivert | |
mavi | |
mor | |
pembe | |
sarı | |
siyah | |
turkuvaz | |
turuncu | |
yeşil | |
), | |
element: %w( | |
aktinyum | |
altın | |
alüminyum | |
amerikyum | |
antimon | |
argon | |
arsenik | |
astatin | |
aynştaynyum | |
azot | |
bakır | |
baryum | |
berilyum | |
berkelyum | |
bizmut | |
bohriyum | |
bor | |
brom | |
cıva | |
çinko | |
darmstadtiyum | |
demir | |
disprozyum | |
dubniyum | |
erbiyum | |
evropiyum | |
fermiyum | |
flerovyum | |
flor | |
fosfor | |
fransiyum | |
gadolinyum | |
galyum | |
germanyum | |
gümüş | |
hafniyum | |
hassiyum | |
helyum | |
hidrojen | |
holmiyum | |
indiyum | |
iridyum | |
iterbiyum | |
itriyum | |
iyot | |
kadmiyum | |
kalay | |
kaliforniyum | |
kalsiyum | |
karbon | |
klor | |
kobalt | |
kopernikyum | |
kripton | |
krom | |
ksenon | |
kurşun | |
kükürt | |
küriyum | |
lantan | |
lavrensiyum | |
lityum | |
livermoryum | |
lutetyum | |
magnezyum | |
mangan | |
meitneriyum | |
mendelevyum | |
molibden | |
neodimyum | |
neon | |
neptünyum | |
nikel | |
niobyum | |
nobelyum | |
oksijen | |
osmiyum | |
paladyum | |
platin | |
plütonyum | |
polonyum | |
potasyum | |
praseodim | |
prometyum | |
protaktinyum | |
radon | |
radyum | |
renyum | |
rodyum | |
röntgenyum | |
rubidyum | |
rutenyum | |
rutherfordiyum | |
samaryum | |
seaborgiyum | |
selenyum | |
seryum | |
sezyum | |
silisyum | |
skandiyum | |
sodyum | |
stronsiyum | |
talyum | |
tantal | |
teknesyum | |
tellür | |
terbiyum | |
titanyum | |
toryum | |
tulyum | |
ununoktiyum | |
ununpentiyum | |
ununseptiyum | |
ununtriyum | |
uranyum | |
vanadyum | |
volfram | |
zirkonyum | |
), | |
fish: %w( | |
ahtapot | |
akya | |
barbunya | |
hamsi | |
istavrit | |
izmarit | |
kalamar | |
kalkan | |
karides | |
kefal | |
levrek | |
mersin | |
mezgit | |
midye | |
morina | |
orfoz | |
palamut | |
ringa | |
sardalya | |
sazan | |
somon | |
tekir | |
tirsi | |
torik | |
uskumru | |
vatoz | |
zargana | |
), | |
nato: %w( | |
alpha | |
bravo | |
charlie | |
delta | |
echo | |
foxtrot | |
golf | |
hotel | |
india | |
juliet | |
kilo | |
lima | |
mike | |
november | |
oscar | |
papa | |
quebec | |
romeo | |
sierra | |
tango | |
uniform | |
victor | |
whiskey | |
xray | |
yankee | |
zulu | |
), | |
noun: %w( | |
ada | |
ahtapot | |
akvaryum | |
asit | |
ay | |
aysberg | |
bakteri | |
balon | |
bayram | |
beyaz | |
bisiklet | |
bomba | |
bulmaca | |
buz | |
cin | |
cirit | |
cuma | |
cumartesi | |
cumhuriyet | |
dalgalar | |
damlalar | |
dans | |
dedikodu | |
deney | |
deniz | |
deprem | |
deve | |
dikenler | |
dil | |
dinozor | |
dua | |
duman | |
efsane | |
ego | |
ejderha | |
embriyo | |
esinti | |
fermuar | |
festival | |
gece | |
gergedan | |
gezegen | |
girdap | |
gramofon | |
gri | |
hayalet | |
hayat | |
hezeyan | |
hikaye | |
horoz | |
hortum | |
ikilem | |
iksir | |
ilkbahar | |
inek | |
izler | |
jeton | |
jilet | |
kader | |
kahve | |
kalem | |
kaos | |
kar | |
kaya | |
kedi | |
kelebek | |
kent | |
kertenkele | |
klarinet | |
koku | |
korku | |
krater | |
kumsal | |
kuyu | |
labirent | |
lacivert | |
leblebi | |
lokomotif | |
makine | |
manifesto | |
mavi | |
mehtap | |
melodi | |
mevsim | |
meydan | |
mor | |
nargile | |
nehir | |
nota | |
nutuk | |
oda | |
okyanus | |
opera | |
orkide | |
orman | |
otlar | |
ova | |
oyuncak | |
papatya | |
pazar | |
pazartesi | |
pembe | |
piyango | |
portakal | |
radar | |
randevu | |
rapsodi | |
robot | |
saatler | |
sabah | |
safari | |
sayfa | |
semaver | |
sinek | |
siyah | |
sokak | |
sonbahar | |
tayfun | |
telefon | |
tepe | |
tespih | |
topraklar | |
tsunami | |
turuncu | |
ufuk | |
uyku | |
vadi | |
vapur | |
volkan | |
yakamoz | |
yamyam | |
yapraklar | |
yarasa | |
yaz | |
yenilgi | |
yokluk | |
zafer | |
zambak | |
zombi | |
), | |
ottoman: %w( | |
ayn | |
be | |
cim | |
çim | |
dad | |
dal | |
elif | |
fe | |
gayn | |
gef | |
ha | |
he | |
hı | |
je | |
kaf | |
kef | |
lam | |
lamelif | |
mim | |
nef | |
nun | |
ra | |
sad | |
se | |
sin | |
şın | |
te | |
tı | |
vav | |
ye | |
ze | |
zel | |
zı | |
), | |
phonetic: %w( | |
adana | |
bolu | |
ceyhan | |
çanakkale | |
denizli | |
edirne | |
fatsa | |
giresun | |
hatay | |
ısparta | |
izmir | |
jandarma | |
kars | |
lüleburgaz | |
muş | |
niğde | |
ordu | |
ödemiş | |
polatlı | |
rize | |
sinop | |
şırnak | |
tokat | |
uşak | |
ünye | |
van | |
yozgat | |
zonguldak | |
), | |
roman: %w( | |
i | |
ii | |
iii | |
iv | |
v | |
vi | |
vii | |
viii | |
ix | |
x | |
xi | |
xii | |
xiii | |
xiv | |
xv | |
xvi | |
xvii | |
xviii | |
xix | |
xx | |
xxi | |
xxii | |
xxiii | |
xxiv | |
xxv | |
xxvi | |
xxvii | |
xxviii | |
xxix | |
xxx | |
xxxi | |
xxxii | |
xxxiii | |
xxxiv | |
xxxv | |
xxxvi | |
xxxvii | |
xxxviii | |
xxxix | |
xl | |
xli | |
xlii | |
xliii | |
xliv | |
xlv | |
xlvi | |
xlvii | |
xlviii | |
xlix | |
l | |
li | |
lii | |
liii | |
liv | |
lv | |
lvi | |
lvii | |
lviii | |
lix | |
lx | |
lxi | |
lxii | |
lxiii | |
lxiv | |
lxv | |
lxvi | |
lxvii | |
lxviii | |
lxix | |
lxx | |
lxxi | |
lxxii | |
lxxiii | |
lxxiv | |
lxxv | |
lxxvi | |
lxxvii | |
lxxviii | |
lxxix | |
lxxx | |
lxxxi | |
lxxxii | |
lxxxiii | |
lxxxiv | |
lxxxv | |
lxxxvi | |
lxxxvii | |
lxxxviii | |
lxxxix | |
xc | |
xci | |
xcii | |
xciii | |
xciv | |
xcv | |
xcvi | |
xcvii | |
xcviii | |
xcix | |
c | |
) | |
} | |
ALPHABET = 'abcçdefghıijklmnoöprsştuüvyz' | |
CATEGORIES = %i(adjective noun) | |
SEPARATOR = '-' | |
def self.alphabet | |
ALPHABET.chars | |
end | |
class MissingCategoriesError < StandardError; end | |
class WordsMissingError < StandardError; end | |
class WordsExhaustedError < StandardError; end | |
attr_reader :categories, :past | |
def initialize(categories: nil, past: nil, **_) | |
@categories = categories ? sanitize_categories(categories) : CATEGORIES | |
@past = past || [] | |
end | |
def suggest(letters = nil) | |
letters ||= self.class.alphabet | |
names, warnings = [], [] | |
letters.each do |letter| | |
begin | |
names << generate(letter) | |
rescue WordsMissingError => detail | |
warnings << detail.to_s | |
end | |
end | |
[names, warnings] | |
end | |
private | |
def sanitize_categories(given) | |
result, missings = [], [] | |
given.map(&:to_sym).each do |category| | |
if DICTIONARY.key? category | |
result << category | |
else | |
missings << category | |
end | |
end | |
return result if missings.empty? | |
fail MissingCategoriesError, "Varolmayan kategoriler: '#{missings.join(', ')}'." # rubocop:disable Metrics/LineLength | |
end | |
def prep_words(words) | |
words.map { |word| word.downcase.gsub(/\s+/, SEPARATOR) }.sort | |
end | |
def alphabetize(dictionary, letter) | |
result = {} | |
dictionary.each do |category, words| | |
result[category] = prep_words(words).select { |word| word[0] == letter } | |
end | |
missings = categories.select { |category| result[category].empty? } | |
unless missings.empty? | |
fail WordsMissingError, "'#{missings.join(', ')}' kategorilerinde " \ | |
"'#{letter}' ile başlayan kelime yok." | |
end | |
result | |
end | |
def generate(letter) | |
dictionary = alphabetize(DICTIONARY, letter) | |
result = nil | |
maximum_try(dictionary).times do | |
result = build(*sample(dictionary)) | |
break unless past.include? result | |
result = nil | |
end | |
return result if result | |
fail WordsExhaustedError, 'Maksimum deneme sınırına ulaşıldı.' | |
end | |
def maximum_try(dictionary) | |
n = 1 | |
categories.each do |category| | |
n *= dictionary[category].size | |
end | |
n | |
end | |
def build(*args) | |
args.join SEPARATOR | |
end | |
def sample(dictionary) | |
categories.map { |category| dictionary[category].sample } | |
end | |
def self.suggest(letters: nil, categories: nil, past: nil, **_) | |
Generator.new(categories: categories, past: past).suggest(letters) | |
rescue MissingCategoriesError, WordsExhaustedError => detail | |
die detail | |
end | |
end | |
class Directory | |
READMES = %w( | |
BENIOKU.md benioku.md BENIOKU benioku | |
README.md readme.md README readme | |
) | |
FRONTMATTER = 'abc' | |
IGNORED = READMES | |
attr_reader :directory, :past, :letters | |
def initialize(directory) | |
@directory = File.expand_path(directory) | |
@readme = locate | |
@cache = {} | |
@setup = setup | |
end | |
def categories | |
@setup[:categories] | |
end | |
def letters | |
Generator.alphabet.reject { |c| used_letters.include? c } | |
end | |
def past(extra_directories = []) | |
directories = @setup[:directories] || [] | |
directories += extra_directories | |
directories << directory | |
directories = directories.uniq.select { |d| Dir.exist? d } | |
result = [] | |
directories.each { |d| result += scan d } | |
result.uniq.sort | |
end | |
private | |
def setup | |
sanitize yaml | |
end | |
def locate | |
READMES.map { |f| File.join(directory, f) }.find { |f| File.exist? f } | |
end | |
def yaml | |
result = {} | |
return result unless (frontmatter = YAML.load_file(@readme)).is_a? Hash | |
frontmatter.each { |k, v| result[k.to_sym] = v } | |
result | |
rescue StandardError => detail | |
die "#{readme} dosyası yüklenirken hata oluştu.", detail | |
end | |
def sanitize(h) | |
result = {} | |
result[:directories] = array_from_array_or_string(h[:path]).map do |d| | |
File.absolute_path(d, directory) | |
end if h[:path] | |
result[:categories] = array_from_array_or_string(h[:names]) | |
result | |
end | |
def scan(directory, ignored = IGNORED) | |
return @cache[directory] if @cache.key? directory | |
result = [] | |
Dir[File.join(directory, '[' + Generator.alphabet.join + ']*')].each do |f| | |
next unless (name = filter(f, ignored)) | |
result << name | |
end | |
@cache[directory] = result.sort | |
end | |
def filter(file, ignored) | |
name = File.basename(file) | |
return if ignored.include? name | |
if File.directory? file | |
name | |
elsif name =~ /\.*$/ | |
File.basename(name, '.*') | |
end | |
end | |
def used_letters | |
scan(directory).map { |e| e[0] }.uniq.sort | |
end | |
def array_from_array_or_string(value, separator = /\s+/) | |
case value | |
when Array, NilClass then value | |
when String then value.split separator | |
else fail ArgumentError | |
end | |
end | |
end | |
module Main | |
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize | |
def self.option | |
o = OpenStruct.new(categories: nil, directories: [], | |
verbose: false, succeeding: false) | |
OptionParser.new do |option| | |
option.banner = "Kullanım: #{option.program_name} [seçenekler] [dizin]" | |
option.separator '' | |
option.separator 'Seçenekler:' | |
option.on( | |
'-cKATEGORİLER', '--categories=KATEGORİLER', ::Array, | |
'Virgülle ayrılmış kategori listesi' | |
) do |arg| | |
o.categories = arg | |
end | |
option.on( | |
'-n', '--next', | |
'Verilen dizinde kullanılmayan ilk harfle başlayan bir isim üret' | |
) { o.succeeding = true } | |
option.on( | |
'-pDİZİNYOLU', '--path=DİZİNYOLU', | |
'DİZİNYOLU içindeki dizinlerde üretilen bir ismin varlığını sına' | |
) do |arg| | |
arg.split(':').each do |d| | |
o.directories << File.expand_path(d) | |
end | |
end | |
option.on( | |
'-v', '--verbose', 'Ayrıntılı bilgi ver' | |
) { o.verbose = true } | |
option.on( | |
'-h', '--help', 'Bu yardımı göster' | |
) do | |
$stderr.puts option | |
exit 2 | |
end | |
option.parse! | |
o.categories.map!(&:to_sym) if o.categories | |
end | |
o | |
end | |
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize | |
def self.argument(o) | |
directory = ARGV.shift | |
if o.succeeding && !directory | |
die 'Sonraki isim üretimi için dizin verilmeli.' | |
end | |
return unless directory | |
die "Böyle bir dizin yok: '#{directory}" unless Dir.exist? directory | |
directory | |
end | |
def self.setup | |
o = option | |
return o unless (d = argument o) | |
directory = Directory.new d | |
o.past = directory.past(o.directories) | |
o.categories ||= directory.categories | |
o.letters = directory.letters | |
die "'#{d} dizininde kullanılmayan bir harf bulunamadı." if o.letters.empty? | |
o | |
end | |
def self.report(words, warnings, o) | |
if words.empty? && !warnings.empty? | |
die(*warnings, 'Kelime üretilemedi.') | |
false | |
elsif !warnings.empty? && o.verbose | |
cry warnings | |
true | |
end | |
end | |
def self.main | |
o = setup | |
words, warnings = Generator.suggest(o.marshal_dump) | |
exit 1 if report words, warnings, o | |
puts o.succeding ? words.first : words.join("\n") | |
end | |
end | |
Main.main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment