grydra 0.1.2 → 0.1.3
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/lib/gr/core.rb +354 -2
- data/lib/gr/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6c7c8176630e8f46bc755437bf28829564123d4c7b2c352a789abc257bd625f2
|
|
4
|
+
data.tar.gz: c69e061a5b621989d15e7163878cd9302939a69043b4a4f228adbba41ba20563
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 034f93c0e54bf6f2209b20efdcb4d0e0670cca1634808b3dab4b8563adb7ec82d071a0e0dea0939a7b00f6b8f3cdd66ee3a6f6b960920a0a8b8950195b1dbc8b
|
|
7
|
+
data.tar.gz: 807c70832d2d0abd31b402dd51b9b28031360ea1ae89cbba2c6b6f68ccc86fc13cd1a7b9acc3a997c6b1fd94e7af18e0e1906328363574681764f6b31f56356e
|
data/lib/gr/core.rb
CHANGED
|
@@ -538,7 +538,7 @@ module GR
|
|
|
538
538
|
{entrada: [[0.1, 0.2]], salida: [[0.3]]},
|
|
539
539
|
{entrada: [[0.5, 0.6]], salida: [[0.7]]}
|
|
540
540
|
]
|
|
541
|
-
red = GR::RedPrincipal.new(true) <-- (true) es para que
|
|
541
|
+
red = GR::RedPrincipal.new(true) <-- (true) es para que imprima el umbral de error
|
|
542
542
|
red.agregar_subred([2, 3, 1])
|
|
543
543
|
red.agregar_subred([2, 2, 1])
|
|
544
544
|
red.entrenar_subredes(datos, 0.01, 1000, paciencia: 5)
|
|
@@ -576,7 +576,7 @@ module GR
|
|
|
576
576
|
{altura: 170, edad: 25, peso: 65},
|
|
577
577
|
{altura: 160, edad: 30, peso: 60}
|
|
578
578
|
]
|
|
579
|
-
red = GR::FacilRed.new(true) <-- (true) es para que
|
|
579
|
+
red = GR::FacilRed.new(true) <-- (true) es para que imprima el umbral de error
|
|
580
580
|
red.entrenar_hashes(datos_hash, [:altura, :edad], :peso, [[4, 1]], 0.05, 15000, :max)
|
|
581
581
|
EX
|
|
582
582
|
},
|
|
@@ -695,4 +695,356 @@ module GR
|
|
|
695
695
|
end
|
|
696
696
|
print "\e[0m"
|
|
697
697
|
end
|
|
698
|
+
|
|
699
|
+
#Función para generar ejemplos de uso con la libreria
|
|
700
|
+
def self.generar_ejemplo(num_ejemplo, nombre_archivo = "ejemplo", extension = "rb", path = File.dirname(__FILE__))
|
|
701
|
+
case num_ejemplo
|
|
702
|
+
when 1
|
|
703
|
+
contenido = <<-RUBY
|
|
704
|
+
require 'grydra'
|
|
705
|
+
|
|
706
|
+
|
|
707
|
+
# Datos de entrenamiento
|
|
708
|
+
datos_entrenamiento = [
|
|
709
|
+
{ nombre: "Empresa 1", numero_empleados: 5, es_nuevo: false, sitio: true, etiqueta: 0 },
|
|
710
|
+
{ nombre: "Empresa 2", numero_empleados: 4, es_nuevo: true, sitio: false, etiqueta: 0 },
|
|
711
|
+
{ nombre: "Empresa 3", numero_empleados: 4, es_nuevo: false, sitio: false, etiqueta: 1 },
|
|
712
|
+
{ nombre: "Empresa 4", numero_empleados: 20, es_nuevo: false, sitio: false, etiqueta: 1 },
|
|
713
|
+
{ nombre: "Empresa 5", numero_empleados: 60, es_nuevo: false, sitio: false, etiqueta: 1 },
|
|
714
|
+
{ nombre: "Empresa 6", numero_empleados: 90, es_nuevo: false, sitio: false, etiqueta: 0 },
|
|
715
|
+
{ nombre: "Empresa 7", numero_empleados: 33, es_nuevo: true, sitio: false, etiqueta: 0 },
|
|
716
|
+
{ nombre: "Empresa 8", numero_empleados: 33, es_nuevo: false, sitio: true, etiqueta: 0 },
|
|
717
|
+
{ nombre: "Empresa 9", numero_empleados: 15, es_nuevo: false, sitio: false, etiqueta: 1 },
|
|
718
|
+
{ nombre: "Empresa 10", numero_empleados: 40, es_nuevo: false, sitio: true, etiqueta: 0 },
|
|
719
|
+
{ nombre: "Empresa 11", numero_empleados: 3, es_nuevo: false, sitio: false, etiqueta: 0 },
|
|
720
|
+
{ nombre: "Empresa 12", numero_empleados: 66, es_nuevo: false, sitio: true, etiqueta: 0 },
|
|
721
|
+
{ nombre: "Empresa 13", numero_empleados: 15, es_nuevo: true, sitio: false, etiqueta: 0 },
|
|
722
|
+
{ nombre: "Empresa 13", numero_empleados: 10, es_nuevo: false, sitio: false, etiqueta: 1 },
|
|
723
|
+
{ nombre: "Empresa 13", numero_empleados: 33, es_nuevo: false, sitio: false, etiqueta: 1 },
|
|
724
|
+
{ nombre: "Empresa 13", numero_empleados: 8, es_nuevo: false, sitio: false, etiqueta: 1 },
|
|
725
|
+
]
|
|
726
|
+
|
|
727
|
+
# Creamos el modelo
|
|
728
|
+
modelo = GR::FacilRed.new(true) # true para que imprima el error cada 1000 épocas
|
|
729
|
+
|
|
730
|
+
# Entrenamos directamente usando datos tipo hash
|
|
731
|
+
modelo.entrenar_hashes(
|
|
732
|
+
datos_entrenamiento,
|
|
733
|
+
[:numero_empleados, :es_nuevo, :sitio], # claves a usar como entrada
|
|
734
|
+
:etiqueta, # clave de salida
|
|
735
|
+
[[3, 4, 1]], # estructura de subred: 3 entradas → capa oculta de 4 → 1 salida
|
|
736
|
+
0.05, # tasa de aprendizaje
|
|
737
|
+
12000 # épocas
|
|
738
|
+
)
|
|
739
|
+
|
|
740
|
+
|
|
741
|
+
# Guardamos el modelo entrenado
|
|
742
|
+
GR.guardar_modelo(modelo, "modelo_empresas")
|
|
743
|
+
|
|
744
|
+
puts "Entrenamiento completado y modelo guardado exitosamente." #Mensaje de depuración para comprobar la ejecución adecuada
|
|
745
|
+
RUBY
|
|
746
|
+
when 2
|
|
747
|
+
contenido = <<-RUBY
|
|
748
|
+
require 'grydra'
|
|
749
|
+
modelo = nil
|
|
750
|
+
modelo = GR.cargar_modelo("modelo_empresas")
|
|
751
|
+
|
|
752
|
+
# Nuevos datos de empresas a evaluar
|
|
753
|
+
nuevos_datos = [
|
|
754
|
+
{ nombre: "Nueva Empresa A", numero_empleados: 12, es_nuevo: true, sitio: true },
|
|
755
|
+
{ nombre: "Nueva Empresa B", numero_empleados: 50, es_nuevo: false, sitio: false },
|
|
756
|
+
{ nombre: "Nueva Empresa C", numero_empleados: 7, es_nuevo: false, sitio: false },
|
|
757
|
+
{ nombre: "Nueva Empresa D", numero_empleados: 22, es_nuevo: true, sitio: true }
|
|
758
|
+
]
|
|
759
|
+
|
|
760
|
+
# Hacemos predicciones
|
|
761
|
+
predicciones = modelo.predecir_hashes(nuevos_datos, [:numero_empleados, :es_nuevo, :sitio])
|
|
762
|
+
|
|
763
|
+
# Mostrar resultados
|
|
764
|
+
nuevos_datos.each_with_index do |empresa, i|
|
|
765
|
+
prediccion = predicciones[i].first.round(3)
|
|
766
|
+
puts "Empresa: \#{empresa[:nombre]} → Predicción: \#{prediccion} (\#{prediccion >= 0.5 ? 'Etiqueta 1 (Sí)' : 'Etiqueta 0 (No)'})"
|
|
767
|
+
end
|
|
768
|
+
RUBY
|
|
769
|
+
|
|
770
|
+
when 3
|
|
771
|
+
contenido = <<-RUBY
|
|
772
|
+
require 'grydra'
|
|
773
|
+
|
|
774
|
+
# Crear red principal
|
|
775
|
+
red = GR::RedPrincipal.new #Sin el true, simplemente no se imprimen las epocas
|
|
776
|
+
|
|
777
|
+
# Agregar una subred con estructura [2 entradas, 2 ocultas, 1 salida]
|
|
778
|
+
red.agregar_subred([2, 3, 1], [:tanh, :tanh])
|
|
779
|
+
red.agregar_subred([2, 4, 1], [:sigmoid, :sigmoid])
|
|
780
|
+
|
|
781
|
+
# Datos XOR
|
|
782
|
+
entradas = [
|
|
783
|
+
[0, 0],
|
|
784
|
+
[0, 1],
|
|
785
|
+
[1, 0],
|
|
786
|
+
[1, 1]
|
|
787
|
+
]
|
|
788
|
+
|
|
789
|
+
salidas = [
|
|
790
|
+
[0],
|
|
791
|
+
[1],
|
|
792
|
+
[1],
|
|
793
|
+
[0]
|
|
794
|
+
]
|
|
795
|
+
|
|
796
|
+
|
|
797
|
+
# Entrenamiento
|
|
798
|
+
epocas = 6000
|
|
799
|
+
tasa_aprendizaje = 0.9
|
|
800
|
+
|
|
801
|
+
red.entrenar_subredes(
|
|
802
|
+
[
|
|
803
|
+
{entrada: entradas, salida: salidas},
|
|
804
|
+
{entrada: entradas, salida: salidas},
|
|
805
|
+
],
|
|
806
|
+
tasa_aprendizaje,
|
|
807
|
+
epocas,
|
|
808
|
+
batch_size: 1, #Número de datos con los que va a entrenar al mismo tiempo
|
|
809
|
+
paciencia: 100, #Si los resultados no mejoran en (n cantidad) de epocas, entonces pasa
|
|
810
|
+
decay: 0.995 #Número por el cual multiplica
|
|
811
|
+
)
|
|
812
|
+
|
|
813
|
+
# Evaluación
|
|
814
|
+
puts "\\nEvaluación XOR:"
|
|
815
|
+
entradas.each do |entrada|
|
|
816
|
+
salida = red.combinar_resultados(entrada)
|
|
817
|
+
puts "Entrada: \#{entrada} => Salida: \#{salida.map { |v| v.round(3) }}" #>0.5 en este caso seria 1
|
|
818
|
+
end
|
|
819
|
+
RUBY
|
|
820
|
+
when 4
|
|
821
|
+
contenido = <<-RUBY
|
|
822
|
+
require 'grydra'
|
|
823
|
+
|
|
824
|
+
# Datos originales (temperatura Celsius y Fahrenheit)
|
|
825
|
+
datos_in = [[0], [10], [20], [30], [40], [50], [-10], [-20], [100], [-30], [-5], [-40]]
|
|
826
|
+
datos_ou = [[32], [50], [68], [86], [104], [122], [14], [-4], [212], [-22], [23], [-40]]
|
|
827
|
+
|
|
828
|
+
# Encontrar valores máximos para normalizar (método :max)
|
|
829
|
+
max_in = GR.calcular_maximos(datos_in, :max) # {0 => valor}
|
|
830
|
+
max_ou = GR.calcular_maximos(datos_ou, :max) # {0 => valor}
|
|
831
|
+
|
|
832
|
+
# Normalizar datos
|
|
833
|
+
datos_in_no = GR.normalizar_varios(datos_in, max_in, :max)
|
|
834
|
+
datos_ou_no = GR.normalizar_varios(datos_ou, max_ou, :max)
|
|
835
|
+
|
|
836
|
+
# Crear red principal
|
|
837
|
+
red_principal = GR::RedPrincipal.new
|
|
838
|
+
|
|
839
|
+
# Agregar subredes
|
|
840
|
+
red_principal.agregar_subred([1, 4, 1], [:sigmoid, :tanh])
|
|
841
|
+
red_principal.agregar_subred([1, 3, 1], [:relu, :tanh])
|
|
842
|
+
red_principal.agregar_subred([1, 2, 1], [:tanh, :tanh])
|
|
843
|
+
|
|
844
|
+
puts "Entrenando subredes..."
|
|
845
|
+
red_principal.entrenar_subredes(
|
|
846
|
+
[
|
|
847
|
+
{ entrada: datos_in_no, salida: datos_ou_no },
|
|
848
|
+
{ entrada: datos_in_no, salida: datos_ou_no },
|
|
849
|
+
{ entrada: datos_in_no, salida: datos_ou_no }
|
|
850
|
+
],
|
|
851
|
+
0.2, # tasa aprendizaje
|
|
852
|
+
25000, # épocas
|
|
853
|
+
batch_size: 5,
|
|
854
|
+
paciencia: 500,
|
|
855
|
+
decay: 0.995
|
|
856
|
+
)
|
|
857
|
+
|
|
858
|
+
puts "\\nIngrese los grados Celsius separados por espacio:"
|
|
859
|
+
print "<< "
|
|
860
|
+
entrada_usuario = gets.chomp.split.map(&:to_f)
|
|
861
|
+
|
|
862
|
+
# Normalizar entradas
|
|
863
|
+
entrada_usuario_no = entrada_usuario.map { |e| [e] }
|
|
864
|
+
entrada_usuario_no = GR.normalizar_varios(entrada_usuario_no, max_in, :max)
|
|
865
|
+
|
|
866
|
+
puts "\\nResultados combinados:"
|
|
867
|
+
entrada_usuario_no.each_with_index do |entrada_norm, i|
|
|
868
|
+
prediccion_norm = red_principal.combinar_resultados(entrada_norm)
|
|
869
|
+
prediccion = [prediccion_norm[0] * max_ou[0]]
|
|
870
|
+
puts "\#{entrada_usuario[i]} °C : \#{prediccion[0].round(2)} °F"
|
|
871
|
+
end
|
|
872
|
+
RUBY
|
|
873
|
+
when 5
|
|
874
|
+
contenido = <<-RUBY
|
|
875
|
+
require 'grydra'
|
|
876
|
+
=begin
|
|
877
|
+
NOTA IMPORTANTE:
|
|
878
|
+
Si se usa la normalización con zscore, debemos ser mas minusiosos y lo recomendable
|
|
879
|
+
es bajar y subir constantmente la tasa de aprendizaje, pues con zscore una vez llegando
|
|
880
|
+
a los resultados esperados se mantendra por ese margen. La tasa se puede bajar y subir
|
|
881
|
+
tanto como uno quiera, ejemplo:
|
|
882
|
+
0.003, 0.3, 0.9, 0.2, 0.223, 0.00008
|
|
883
|
+
=end
|
|
884
|
+
# Crear instancia de la clase FacilRed
|
|
885
|
+
red = GR::FacilRed.new(true) # true para imprimir las épocas y errores
|
|
886
|
+
|
|
887
|
+
# Datos originales (temperatura Celsius y Fahrenheit)
|
|
888
|
+
datos_in = [[0], [10], [20], [30], [40], [50], [-10], [-20], [100], [-30], [-5], [-40]]
|
|
889
|
+
datos_out = [[32], [50], [68], [86], [104], [122], [14], [-4], [212], [-22], [23], [-40]]
|
|
890
|
+
|
|
891
|
+
# Definir estructuras de subredes (capas ocultas)
|
|
892
|
+
estructuras = [
|
|
893
|
+
[2, 4, 1], # capa oculta con 4 neuronas, salida 1
|
|
894
|
+
[1, 3, 1], # otra subred, 3 neuronas capa oculta
|
|
895
|
+
[2, 7, 1] # y otra más pequeña
|
|
896
|
+
]
|
|
897
|
+
|
|
898
|
+
puts "Entrenando red..."
|
|
899
|
+
red.entrenar_numericos(datos_in, datos_out, estructuras, 0.5, 30000, :zscore)
|
|
900
|
+
#red.entrenar_numericos(datos_in, datos_out, estructuras, 0.5, 30000, :max)
|
|
901
|
+
|
|
902
|
+
puts "\nIngrese los grados Celsius separados por espacio:"
|
|
903
|
+
print "<< "
|
|
904
|
+
entrada_usuario = gets.chomp.split.map(&:to_f).map { |v| [v] }
|
|
905
|
+
|
|
906
|
+
predicciones = red.predecir_numericos(entrada_usuario, :zscore)
|
|
907
|
+
#predicciones = red.predecir_numericos(entrada_usuario, :max)
|
|
908
|
+
|
|
909
|
+
puts "\\nResultados:"
|
|
910
|
+
entrada_usuario.each_with_index do |entrada, i|
|
|
911
|
+
f = predicciones[i][0]
|
|
912
|
+
puts "\#{entrada[0]} °C : \#{f.round(2)} °F"
|
|
913
|
+
end
|
|
914
|
+
RUBY
|
|
915
|
+
when 6
|
|
916
|
+
contenido = <<-RUBY
|
|
917
|
+
require 'grydra'
|
|
918
|
+
|
|
919
|
+
# Crear datos de entrada y salida
|
|
920
|
+
datos_entrada = [
|
|
921
|
+
[170, 25],
|
|
922
|
+
[160, 30],
|
|
923
|
+
[180, 22],
|
|
924
|
+
[150, 28],
|
|
925
|
+
[175, 24]
|
|
926
|
+
]
|
|
927
|
+
|
|
928
|
+
# Peso correspondiente a cada persona (kg)
|
|
929
|
+
datos_salida = [
|
|
930
|
+
[65],
|
|
931
|
+
[60],
|
|
932
|
+
[75],
|
|
933
|
+
[55],
|
|
934
|
+
[70]
|
|
935
|
+
]
|
|
936
|
+
|
|
937
|
+
# Definir estructuras de las subredes
|
|
938
|
+
# Cada subred tiene: 2 entradas → 3 neuronas ocultas → 1 salida
|
|
939
|
+
estructuras = [
|
|
940
|
+
[3, 1],
|
|
941
|
+
[4, 1]
|
|
942
|
+
]
|
|
943
|
+
|
|
944
|
+
# Crear red usando la interfaz fácil
|
|
945
|
+
red = GR::FacilRed.new(true) # true para que imprima error por época
|
|
946
|
+
|
|
947
|
+
# Entrenar la red
|
|
948
|
+
red.entrenar_numericos(
|
|
949
|
+
datos_entrada,
|
|
950
|
+
datos_salida,
|
|
951
|
+
estructuras,
|
|
952
|
+
0.05, # tasa de aprendizaje
|
|
953
|
+
15000, # épocas
|
|
954
|
+
:max # tipo de normalización
|
|
955
|
+
)
|
|
956
|
+
|
|
957
|
+
# Predecir para un nuevo individuo
|
|
958
|
+
nuevos_datos = [[172, 26]]
|
|
959
|
+
|
|
960
|
+
predicciones = red.predecir_numericos(nuevos_datos, :max)
|
|
961
|
+
|
|
962
|
+
puts "\\nResultado:"
|
|
963
|
+
puts "Altura: \#{nuevos_datos[0][0]}, Edad: \#{nuevos_datos[0][1]} ⇒ Peso estimado: \#{predicciones[0][0].round(2)} kg"
|
|
964
|
+
RUBY
|
|
965
|
+
when 7
|
|
966
|
+
contenido = <<-RUBY
|
|
967
|
+
require 'grydra'
|
|
968
|
+
|
|
969
|
+
# Datos de entrenamiento: [altura (cm), edad (años)]
|
|
970
|
+
datos_entrada = [
|
|
971
|
+
[170, 25],
|
|
972
|
+
[160, 30],
|
|
973
|
+
[180, 22],
|
|
974
|
+
[175, 28],
|
|
975
|
+
[165, 35],
|
|
976
|
+
[155, 40],
|
|
977
|
+
[185, 20]
|
|
978
|
+
]
|
|
979
|
+
|
|
980
|
+
# Peso real en kg
|
|
981
|
+
datos_salida = [
|
|
982
|
+
[65],
|
|
983
|
+
[60],
|
|
984
|
+
[75],
|
|
985
|
+
[70],
|
|
986
|
+
[62],
|
|
987
|
+
[58],
|
|
988
|
+
[80]
|
|
989
|
+
]
|
|
990
|
+
|
|
991
|
+
# Estructuras para las subredes: capas ocultas y salida
|
|
992
|
+
estructuras = [
|
|
993
|
+
[4, 1],
|
|
994
|
+
[3, 1],
|
|
995
|
+
[6, 1],
|
|
996
|
+
[2, 1]
|
|
997
|
+
]
|
|
998
|
+
|
|
999
|
+
# Crear red Fácil
|
|
1000
|
+
red = GR::FacilRed.new # true para ver el progreso de entrenamiento
|
|
1001
|
+
|
|
1002
|
+
# Vamos a asignar activación 'sigmoid' en la última capa para limitar la salida entre 0 y 1
|
|
1003
|
+
# Ajustamos internamente en el método agregar_subred
|
|
1004
|
+
|
|
1005
|
+
estructuras.each do |estructura|
|
|
1006
|
+
# Definimos activaciones: ocultas con :tanh, salida con :sigmoid
|
|
1007
|
+
activaciones = Array.new(estructura.size - 1, :tanh) + [:sigmoid]
|
|
1008
|
+
red.red.agregar_subred([datos_entrada.first.size, *estructura], activaciones)
|
|
1009
|
+
end
|
|
1010
|
+
|
|
1011
|
+
# Normalización :max (fácil de desnormalizar)
|
|
1012
|
+
red.entrenar_numericos(datos_entrada, datos_salida, estructuras, 0.01, 10000, :max)
|
|
1013
|
+
|
|
1014
|
+
# Nueva muestra para predecir: altura=172 cm, edad=26 años
|
|
1015
|
+
nuevos_datos = [[172, 26]]
|
|
1016
|
+
|
|
1017
|
+
# Hacemos predicción (normalizada internamente)
|
|
1018
|
+
predicciones = red.predecir_numericos(nuevos_datos, :max)
|
|
1019
|
+
|
|
1020
|
+
# Las predicciones ya están desnormalizadas por FacilRed, solo redondeamos
|
|
1021
|
+
puts "Predicción peso (kg) para altura \#{nuevos_datos[0][0]} cm y edad \#{nuevos_datos[0][1]} años:"
|
|
1022
|
+
print predicciones.map { |p| p[0].round(2) }
|
|
1023
|
+
GR.guardar_modelo(red, "peso_promedio")
|
|
1024
|
+
RUBY
|
|
1025
|
+
when 8
|
|
1026
|
+
contenido = <<-RUBY
|
|
1027
|
+
# predecir.rb
|
|
1028
|
+
require 'grydra'
|
|
1029
|
+
|
|
1030
|
+
# Cargar el modelo previamente guardado
|
|
1031
|
+
modelo = GR.cargar_modelo("peso_promedio")
|
|
1032
|
+
|
|
1033
|
+
# Datos de entrada para predecir: altura=172 cm, edad=26 años
|
|
1034
|
+
nuevos_datos = [[172, 26]]
|
|
1035
|
+
|
|
1036
|
+
# Normalización que usaste (puede ser :max o :zscore, según entrenaste)
|
|
1037
|
+
normalizacion = :max
|
|
1038
|
+
|
|
1039
|
+
# Realizar predicción
|
|
1040
|
+
predicciones = modelo.predecir_numericos(nuevos_datos, normalizacion)
|
|
1041
|
+
|
|
1042
|
+
puts "Predicción peso (kg) para altura \#{nuevos_datos[0][0]} cm y edad \#{nuevos_datos[0][1]} años:"
|
|
1043
|
+
puts predicciones.map { |p| p[0].round(2) }
|
|
1044
|
+
RUBY
|
|
1045
|
+
end
|
|
1046
|
+
File.write("#{nombre_archivo}.#{extension}", contenido)
|
|
1047
|
+
puts "Ejemplo generado y guardado en \e[33m#{path}/#{nombre_archivo}\e[0m"
|
|
1048
|
+
end
|
|
698
1049
|
end
|
|
1050
|
+
|
data/lib/gr/version.rb
CHANGED