pycall 0.1.0.alpha.20170711 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.travis.yml +13 -1
  4. data/CHANGES.md +35 -0
  5. data/Gemfile +0 -5
  6. data/README.md +41 -49
  7. data/Rakefile +22 -1
  8. data/appveyor.yml +9 -26
  9. data/examples/classifier_comparison.rb +52 -52
  10. data/examples/hist.rb +11 -11
  11. data/examples/notebooks/classifier_comparison.ipynb +51 -66
  12. data/examples/notebooks/forest_importances.ipynb +26 -49
  13. data/examples/notebooks/iruby_integration.ipynb +15 -36
  14. data/examples/notebooks/lorenz_attractor.ipynb +16 -47
  15. data/examples/notebooks/polar_axes.ipynb +29 -64
  16. data/examples/notebooks/sum_benchmarking.ipynb +109 -103
  17. data/examples/notebooks/xkcd_style.ipynb +12 -12
  18. data/examples/plot_forest_importances_faces.rb +8 -8
  19. data/examples/sum_benchmarking.rb +15 -19
  20. data/ext/pycall/extconf.rb +3 -0
  21. data/ext/pycall/gc.c +74 -0
  22. data/ext/pycall/libpython.c +217 -0
  23. data/ext/pycall/pycall.c +2184 -0
  24. data/ext/pycall/pycall_internal.h +700 -0
  25. data/ext/pycall/range.c +69 -0
  26. data/ext/pycall/ruby_wrapper.c +432 -0
  27. data/lib/pycall.rb +91 -19
  28. data/lib/pycall/dict.rb +28 -82
  29. data/lib/pycall/error.rb +10 -0
  30. data/lib/pycall/import.rb +45 -40
  31. data/lib/pycall/init.rb +44 -20
  32. data/lib/pycall/libpython.rb +6 -380
  33. data/lib/pycall/libpython/finder.rb +170 -0
  34. data/lib/pycall/list.rb +21 -51
  35. data/lib/pycall/pretty_print.rb +9 -0
  36. data/lib/pycall/pyerror.rb +14 -20
  37. data/lib/pycall/pyobject_wrapper.rb +157 -158
  38. data/lib/pycall/python/PyCall/__init__.py +1 -0
  39. data/lib/pycall/python/PyCall/six.py +23 -0
  40. data/lib/pycall/pytypeobject_wrapper.rb +79 -0
  41. data/lib/pycall/slice.rb +3 -22
  42. data/lib/pycall/tuple.rb +1 -7
  43. data/lib/pycall/version.rb +1 -1
  44. data/lib/pycall/wrapper_object_cache.rb +61 -0
  45. data/pycall.gemspec +4 -2
  46. data/tasks/pycall.rake +7 -0
  47. metadata +65 -27
  48. data/lib/pycall/eval.rb +0 -57
  49. data/lib/pycall/exception.rb +0 -13
  50. data/lib/pycall/pyobject.rb +0 -58
  51. data/lib/pycall/ruby_wrapper.rb +0 -137
  52. data/lib/pycall/type_object.rb +0 -11
  53. data/lib/pycall/types.rb +0 -19
  54. data/lib/pycall/utils.rb +0 -106
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a62b597bfd316247a0a32c28b46fb219f7271a6a
4
- data.tar.gz: a7356ff5c08cf2d519519908d77341e07d90ecfe
3
+ metadata.gz: 3989138be85724905ddd029fb3f74a7168070c02
4
+ data.tar.gz: 8ab3173bf2d1c2f92deec6b98241cc28d9768a03
5
5
  SHA512:
6
- metadata.gz: d56553cb58f507bf421074aff630f0204361013b1700f0b30a3238db1ca9f0c12ed0e883438f33b616b156d95dbe93a3f116c7465090073ae198edaebb337b9f
7
- data.tar.gz: 5b5b5693f3f82724d78549a1d1aa645bf155c2c7e7d6e834c6efb5644fe8854a5c6fddc2b3847b7b2ad6891fa4b99b2ce1c0078c11bf65e947700e668f000f19
6
+ metadata.gz: 574f866b421b1010e907ff83ca9ce45725cd642af94004a1ab979a2b24f1605dfdeaa29c6090a159a6ac713d97cb9be4f20dc343e8edc21156e143b3845e8b95
7
+ data.tar.gz: fb03c20e8e60bc674c484f871848106ffe2ab5722ac1ba2331ea6f77075743320eef7d0bc9d320744486b1698a00a9c801182b4442d0e2f85905822d5f83818f
data/.gitignore CHANGED
@@ -8,3 +8,6 @@
8
8
  /spec/reports/
9
9
  /tmp/
10
10
  __pycache__
11
+ *.bundle
12
+ *.so
13
+ *.o
data/.travis.yml CHANGED
@@ -9,9 +9,12 @@ rvm:
9
9
  - 2.1.10
10
10
 
11
11
  env:
12
+ global:
13
+ - PYCALL_DEBUG_FIND_LIBPYTHON=1
14
+ matrix:
12
15
  - PYTHON=python
13
16
  - PYTHON=python3 LIBPYTHON=wrong_value
14
- - LIBPYTHON=/usr/lib/libpython3.2mu.so.1
17
+ - LIBPYTHON=/opt/python/3.5.3/lib/libpython3.5m.so
15
18
 
16
19
  addons:
17
20
  apt:
@@ -19,11 +22,20 @@ addons:
19
22
  - python3
20
23
  - python3-dev
21
24
  - python3-all
25
+ - python3-all-dev
22
26
 
23
27
  before_install:
24
28
  - gem update --system
25
29
  - gem update bundler
26
30
 
27
31
  before_script:
32
+ - bundle exec rake clobber compile
28
33
  - echo === python investigator.py ===
29
34
  - python lib/pycall/python/investigator.py
35
+ - python3 lib/pycall/python/investigator.py
36
+ - pip install numpy
37
+ - pip3 install numpy
38
+
39
+ matrix:
40
+ allow_failures:
41
+ - env: PYTHON=python # Ignore failed on python 2.7
data/CHANGES.md ADDED
@@ -0,0 +1,35 @@
1
+ # The change history of PyCall
2
+
3
+ ## 1.0.0
4
+
5
+ * `#[]` and `#[]=` accept a `Range` and an `Enumerable`, which is genated by
6
+ `Range#step`, as a slice.
7
+
8
+ * Rewrite almost all fundamental parts of PyCall as C extension.
9
+
10
+ * PyCall now calls `Py_DecRef` in the finalizer of `PyCall::PyPtr`.
11
+
12
+ * Change the system of object mapping between Python and Ruby, drastically.
13
+ Now PyCall does not have `PyObject` class for wrapper objects.
14
+ Instead, PyCall generally makes `Object` instances and extends them by
15
+ `PyObjectWrapper` module.
16
+ But for Python module objects, PyCall makes anonymous `Module` instances
17
+ that are extended by `PyObjectWrapper` module.
18
+ Moreover for Python type objects, PyCall makes `Class` instances and extends
19
+ them by `PyTypeObjectWrapper` module.
20
+
21
+ * Change `PyCall.eval` to be a wrapper of `__builtins__.eval` in Python.
22
+ This means that `filename:` and `input_type:` parameters are dropped.
23
+ Instead, two new parameters `globals:` and `locals:` are introduced.
24
+ `globals:` is used for specifying a dictionary that is the global
25
+ namespace referred by the evaluated expression.
26
+ `locals:` is used for specifying a mapping object that is the local
27
+ namespace referred by the evaluated expression.
28
+
29
+ * Add `PyCall.exec` for the replacement of the former `PyCall.eval`
30
+ with `input_type: :file`.
31
+ It has `globals:` and `locals:` parameters for the same meaning as
32
+ the new `PyCall.eval` described above.
33
+
34
+ * Drop `PyCall.wrap_ruby_callable` and `PyCall.wrap_ruby_object` always
35
+ craetes a callable Python object taht has an ID of the given Ruby object.
data/Gemfile CHANGED
@@ -2,8 +2,3 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in pycall.gemspec
4
4
  gemspec
5
-
6
- group :development do
7
- gem 'guard-rspec', require: false
8
- gem 'terminal-notifier-guard', require: false
9
- end
data/README.md CHANGED
@@ -3,7 +3,10 @@
3
3
  [![Build Status](https://travis-ci.org/mrkn/pycall.svg?branch=master)](https://travis-ci.org/mrkn/pycall)
4
4
  [![Build status](https://ci.appveyor.com/api/projects/status/071is0f4iu0vy8lp/branch/master?svg=true)](https://ci.appveyor.com/project/mrkn/pycall/branch/master)
5
5
 
6
- This library provides the features to directly call and partially interoperate with Python from the Ruby language. You can import arbitrary Python modules into Ruby modules, call Python functions with automatic type conversion from Ruby to Python.
6
+ This library provides the features to directly call and partially interoperate
7
+ with Python from the Ruby language. You can import arbitrary Python modules
8
+ into Ruby modules, call Python functions with automatic type conversion from
9
+ Ruby to Python.
7
10
 
8
11
  ## Installation
9
12
 
@@ -23,77 +26,66 @@ Or install it yourself as:
23
26
 
24
27
  ## Usage
25
28
 
26
- Here is a simple example to call Python's `math.sin` function and compare it to the `Math.sin` in Ruby:
29
+ Here is a simple example to call Python's `math.sin` function and compare it to
30
+ the `Math.sin` in Ruby:
27
31
 
28
32
  require 'pycall/import'
29
33
  include PyCall::Import
30
34
  pyimport :math
31
- math.sin.(math.pi / 4) - Math.sin(Math::PI / 4) # => 0.0
32
- # ^ This period is necessary
35
+ math.sin(math.pi / 4) - Math.sin(Math::PI / 4) # => 0.0
33
36
 
34
- Type conversions from Ruby to Python are automatically performed for numeric, boolean, string, arrays, and hashes.
37
+ Type conversions from Ruby to Python are automatically performed for numeric,
38
+ boolean, string, arrays, and hashes.
35
39
 
36
- ### Python function call
40
+ ## PyCall object system
37
41
 
38
- In this version of pycall, the all of functions and methods in Python is wrapped as callable objects in Ruby. It means we need to put a priod between the name of function and `(` like `math.sin.(...)` in the above example.
42
+ PyCall wraps pointers of Python objects in `PyCall::PyPtr` objects.
43
+ `PyCall::PyPtr` class has two subclasses, `PyCall::PyTypePtr` and
44
+ `PyCall::PyRubyPtr`. `PyCall::PyTypePtr` is specialized for type (and classobj
45
+ in 2.7) objects, and `PyCall::PyRubyPtr` is for the objects that wraps pointers
46
+ of Ruby objects.
39
47
 
40
- This unnatural notation is a temporary specification, so we should be able to write `math.sin(...)` in the future.
48
+ These `PyCall::PyPtr` objects are used mainly in PyCall infrastructure.
49
+ Instead, we usually treats the instances of `Object`, `Class`, `Module`, or
50
+ other classes that are extended by `PyCall::PyObjectWrapper` module.
41
51
 
42
- ## Wrapping Python classes
43
-
44
- **NOTE: Currently I'm trying to rewrite class wrapping system, so the content of this section will be changed.**
45
-
46
- Using `PyCall::PyObjectWrapper` module, we can create incarnation classes for Python classes in Ruby language. For example, the following script defines a incarnation class for `numpy.ndarray` class.
47
-
48
- ```ruby
49
- require 'pycall'
50
-
51
- class Ndarray
52
- import PyCall::PyObjectWrapper
53
- wrap_class PyCall.import_module('numpy').ndarray
54
- end
55
- ```
56
-
57
- Defineing incarnation classes using `wrap_class` registeres automatic type conversion, so it changes the class of wrapper object. For example:
58
-
59
- require 'pycall/import'
60
- include PyCall::Import
61
- pyimport :numpy, as: :np
62
- x1 = np.array(PyCall.tuple(10))
63
- x1.class # => PyCall::PyObject
64
-
65
- class Ndarray
66
- import PyCall::PyObjectWrapper
67
- wrap_class PyCall.import_module('numpy').ndarray
68
- # NOTE: From here, numpy.ndarray objects are converted to Ndarray objects
69
- end
70
-
71
- x2 = np.array(PyCall.tuple(10))
72
- x2.class # => Ndarray
73
-
74
-
75
- **NOTE: I will write an efficient wrapper for numpy by RubyKaigi 2017.**
52
+ `PyCall::PyObjectWrapper` is a mix-in module for objects that wraps Python
53
+ objects. A wrapper object should have `PyCall::PyPtr` object in its instance
54
+ variable `@__pyptr__`. `PyCall::PyObjectWrapper` assumes the existance of
55
+ `@__pyptr__`, and provides general translation mechanisms between Ruby object
56
+ system and Python object system. For example, `PyCall::PyObjectWrapper`
57
+ translates Ruby's coerce system into Python's swapped operation protocol.
76
58
 
77
59
  ### Specifying the Python version
78
60
 
79
- If you want to use a specific version of Python instead of the default, you can change the Python version by setting the `PYTHON` environment variable to the path of the `python` executable.
61
+ If you want to use a specific version of Python instead of the default,
62
+ you can change the Python version by setting the `PYTHON` environment variable
63
+ to the path of the `python` executable.
80
64
 
81
65
  ## Development
82
66
 
83
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
67
+ After checking out the repo, run `bin/setup` to install dependencies.
68
+ Then, run `rake spec` to run the tests. You can also run `bin/console`
69
+ for an interactive prompt that will allow you to experiment.
84
70
 
85
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
71
+ To install this gem onto your local machine, run `bundle exec rake install`.
72
+ To release a new version, update the version number in `version.rb`,
73
+ and then run `bundle exec rake release`, which will create a git tag for the
74
+ version, push git commits and tags, and push the `.gem` file to
75
+ [rubygems.org](https://rubygems.org).
86
76
 
87
77
  ## Contributing
88
78
 
89
- Bug reports and pull requests are welcome on GitHub at https://github.com/mrkn/pycall.
79
+ Bug reports and pull requests are welcome on GitHub at
80
+ https://github.com/mrkn/pycall.
90
81
 
91
82
 
92
83
  ## Acknowledgement
93
84
 
94
- [PyCall.jl](https://github.com/JuliaPy/PyCall.jl) is referred too many times to implement this library.
85
+ [PyCall.jl](https://github.com/JuliaPy/PyCall.jl) is referred too many times
86
+ to implement this library.
95
87
 
96
88
  ## License
97
89
 
98
- The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
99
-
90
+ The gem is available as open source under the terms of the
91
+ [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile CHANGED
@@ -1,8 +1,29 @@
1
- require "bundler/gem_tasks"
1
+ require "bundler"
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require "rake"
5
+ require "rake/extensiontask"
2
6
  require "rspec/core/rake_task"
3
7
 
4
8
  Dir[File.expand_path('../tasks/**/*.rake', __FILE__)].each {|f| load f }
5
9
 
10
+ gem_spec = eval(File.read('pycall.gemspec'))
11
+ Rake::ExtensionTask.new('pycall', gem_spec) do |ext|
12
+ ext.lib_dir = File.join(*['lib', ENV['FAT_DIR']].compact)
13
+ ext.cross_compile = true
14
+ ext.cross_platform = %w[x86-mingw32 x64-mingw32]
15
+ ext.cross_compiling do |s|
16
+ s.files.concat %w[lib/2.2/pycall.so lib/2.3/pycall.so lib/2.4/pycall.so]
17
+ end
18
+ end
19
+
20
+ desc "Compile binaries for mingw platform using rake-compiler-dock"
21
+ task 'build:mingw' do
22
+ require 'rake_compiler_dock'
23
+ RakeCompilerDock.sh "bundle && rake cross native gem RUBY_CC_VERSION=2.1.6:2.2.2:2.3.0:2.4.0"
24
+ end
25
+
6
26
  RSpec::Core::RakeTask.new(:spec)
7
27
 
8
28
  task :default => :spec
29
+ task spec: :compile
data/appveyor.yml CHANGED
@@ -6,10 +6,6 @@ environment:
6
6
  PYTHONDIR: "C:\\Python27"
7
7
  PYTHON: "C:\\Python27\\python.exe"
8
8
 
9
- - ruby_version: "21"
10
- PYTHONDIR: "C:\\Python33"
11
- PYTHON: "C:\\Python33\\python.exe"
12
-
13
9
  - ruby_version: "21"
14
10
  PYTHONDIR: "C:\\Python34"
15
11
  PYTHON: "C:\\Python34\\python.exe"
@@ -27,10 +23,6 @@ environment:
27
23
  PYTHONDIR: "C:\\Python27-x64"
28
24
  PYTHON: "C:\\Python27-x64\\python.exe"
29
25
 
30
- - ruby_version: "21-x64"
31
- PYTHONDIR: "C:\\Python33-x64"
32
- PYTHON: "C:\\Python33-x64\\python.exe"
33
-
34
26
  - ruby_version: "21-x64"
35
27
  PYTHONDIR: "C:\\Python34-x64"
36
28
  PYTHON: "C:\\Python34-x64\\python.exe"
@@ -48,10 +40,6 @@ environment:
48
40
  PYTHONDIR: "C:\\Python27"
49
41
  PYTHON: "C:\\Python27\\python.exe"
50
42
 
51
- - ruby_version: "22"
52
- PYTHONDIR: "C:\\Python33"
53
- PYTHON: "C:\\Python33\\python.exe"
54
-
55
43
  - ruby_version: "22"
56
44
  PYTHONDIR: "C:\\Python34"
57
45
  PYTHON: "C:\\Python34\\python.exe"
@@ -69,10 +57,6 @@ environment:
69
57
  PYTHONDIR: "C:\\Python27-x64"
70
58
  PYTHON: "C:\\Python27-x64\\python.exe"
71
59
 
72
- - ruby_version: "22-x64"
73
- PYTHONDIR: "C:\\Python33-x64"
74
- PYTHON: "C:\\Python33-x64\\python.exe"
75
-
76
60
  - ruby_version: "22-x64"
77
61
  PYTHONDIR: "C:\\Python34-x64"
78
62
  PYTHON: "C:\\Python34-x64\\python.exe"
@@ -90,10 +74,6 @@ environment:
90
74
  PYTHONDIR: "C:\\Python27"
91
75
  PYTHON: "C:\\Python27\\python.exe"
92
76
 
93
- - ruby_version: "23"
94
- PYTHONDIR: "C:\\Python33"
95
- PYTHON: "C:\\Python33\\python.exe"
96
-
97
77
  - ruby_version: "23"
98
78
  PYTHONDIR: "C:\\Python34"
99
79
  PYTHON: "C:\\Python34\\python.exe"
@@ -111,10 +91,6 @@ environment:
111
91
  PYTHONDIR: "C:\\Python27-x64"
112
92
  PYTHON: "C:\\Python27-x64\\python.exe"
113
93
 
114
- - ruby_version: "23-x64"
115
- PYTHONDIR: "C:\\Python33-x64"
116
- PYTHON: "C:\\Python33-x64\\python.exe"
117
-
118
94
  - ruby_version: "23-x64"
119
95
  PYTHONDIR: "C:\\Python34-x64"
120
96
  PYTHON: "C:\\Python34-x64\\python.exe"
@@ -144,12 +120,19 @@ build: off
144
120
  install:
145
121
  - "SET PATH=%PYTHONDIR%;%PYTHONDIR%\\Scripts;%PATH%"
146
122
  - "SET PATH=C:\\Ruby%ruby_version%\\bin;%PATH%"
147
- - bundle install
123
+ - "bundle install"
124
+ - "pip install numpy"
148
125
 
149
126
  before_test:
127
+ - "bundle exec rake -rdevkit clobber compile"
150
128
  - ECHO "=== python investigator.py ==="
151
129
  - "python lib\\pycall\\python\\investigator.py"
152
130
 
153
131
  test_script:
154
- - "SET DEBUG_FIND_LIBPYTHON=1"
132
+ - "SET PYCALL_DEBUG_FIND_LIBPYTHON=1"
155
133
  - rake
134
+
135
+ matrix:
136
+ allow_failures:
137
+ - PYTHONDIR: "C:\\Python27"
138
+ - PYTHONDIR: "C:\\Python27-x64"
@@ -34,18 +34,18 @@ names = [
34
34
  ]
35
35
 
36
36
  classifiers = [
37
- KNeighborsClassifier.(3),
38
- SVC.(kernel: 'linear', C: 0.025),
39
- SVC.(gamma: 2, C: 1),
40
- DecisionTreeClassifier.(max_depth: 5),
41
- RandomForestClassifier.(max_depth: 5, n_estimators: 10, max_features: 1),
42
- AdaBoostClassifier.(),
43
- GaussianNB.(),
44
- LinearDiscriminantAnalysis.(),
45
- QuadraticDiscriminantAnalysis.()
37
+ KNeighborsClassifier.new(3),
38
+ SVC.new(kernel: 'linear', C: 0.025),
39
+ SVC.new(gamma: 2, C: 1),
40
+ DecisionTreeClassifier.new(max_depth: 5),
41
+ RandomForestClassifier.new(max_depth: 5, n_estimators: 10, max_features: 1),
42
+ AdaBoostClassifier.new(),
43
+ GaussianNB.new(),
44
+ LinearDiscriminantAnalysis.new(),
45
+ QuadraticDiscriminantAnalysis.new()
46
46
  ]
47
47
 
48
- x, y = make_classification.(
48
+ x, y = *make_classification(
49
49
  n_features: 2,
50
50
  n_redundant: 0,
51
51
  n_informative: 2,
@@ -53,83 +53,83 @@ x, y = make_classification.(
53
53
  n_clusters_per_class: 1
54
54
  )
55
55
 
56
- np.random.seed.(42)
57
- x += 2 * np.random.random_sample.(x.shape)
58
- linearly_separable = PyCall.tuple(x, y)
56
+ np.random.seed(42)
57
+ x += 2 * np.random.random_sample(x.shape)
58
+ linearly_separable = PyCall.tuple([x, y]) # FIXME: allow PyCall.tuple(x, y)
59
59
 
60
60
  datasets = [
61
- make_moons.(noise: 0.3, random_state: 0),
62
- make_circles.(noise: 0.2, factor: 0.5, random_state: 1),
61
+ make_moons(noise: 0.3, random_state: 0),
62
+ make_circles(noise: 0.2, factor: 0.5, random_state: 1),
63
63
  linearly_separable
64
64
  ]
65
65
 
66
- fig = plt.figure.(figsize: PyCall.tuple(27, 9))
66
+ fig = plt.figure(figsize: [27, 9])
67
67
  i = 1
68
- all = PyCall.slice(nil)
68
+ all = 0..-1
69
69
  datasets.each do |ds|
70
- x, y = ds
71
- x = StandardScaler.().fit_transform.(x)
72
- x_train, x_test, y_train, y_test = train_test_split.(x, y, test_size: 0.4)
70
+ x, y = *ds
71
+ x = StandardScaler.new.fit_transform(x)
72
+ x_train, x_test, y_train, y_test = train_test_split(x, y, test_size: 0.4)
73
73
 
74
- x_min, x_max = np.min.(x[all, 0]) - 0.5, np.max.(x[all, 0]) + 0.5
75
- y_min, y_max = np.min.(x[all, 1]) - 0.5, np.max.(x[all, 1]) + 0.5
74
+ x_min, x_max = np.min(x[all, 0]) - 0.5, np.max(x[all, 0]) + 0.5
75
+ y_min, y_max = np.min(x[all, 1]) - 0.5, np.max(x[all, 1]) + 0.5
76
76
 
77
- xx, yy = np.meshgrid.(
78
- np.linspace.(x_min, x_max, ((x_max - x_min)/h).round),
79
- np.linspace.(y_min, y_max, ((y_max - y_min)/h).round),
77
+ xx, yy = np.meshgrid(
78
+ np.linspace(x_min, x_max, ((x_max - x_min)/h).round),
79
+ np.linspace(y_min, y_max, ((y_max - y_min)/h).round),
80
80
  )
81
- mesh_points = np.dstack.(PyCall.tuple(xx.ravel.(), yy.ravel.()))[0, all, all]
81
+ mesh_points = np.dstack(PyCall.tuple([xx.ravel(), yy.ravel()]))[0, all, all]
82
82
 
83
83
  # just plot the dataset first
84
- cm = plt.cm.RdBu
85
- cm_bright = mplc.ListedColormap.(["#FF0000", "#0000FF"])
86
- ax = plt.subplot.(datasets.length, classifiers.length + 1, i)
84
+ cm = plt.cm.__dict__[:RdBu]
85
+ cm_bright = mplc.ListedColormap.new(["#FF0000", "#0000FF"])
86
+ ax = plt.subplot(datasets.length, classifiers.length + 1, i)
87
87
  # plot the training points
88
- ax.scatter.(x_train[all, 0], x_train[all, 1], c: y_train, cmap: cm_bright)
88
+ ax.scatter(x_train[all, 0], x_train[all, 1], c: y_train, cmap: cm_bright)
89
89
  # and testing points
90
- ax.scatter.(x_test[all, 0], x_test[all, 1], c: y_test, cmap: cm_bright, alpha: 0.6)
90
+ ax.scatter(x_test[all, 0], x_test[all, 1], c: y_test, cmap: cm_bright, alpha: 0.6)
91
91
 
92
- ax.set_xlim.(np.min.(xx), np.max.(xx))
93
- ax.set_ylim.(np.min.(yy), np.max.(yy))
94
- ax.set_xticks.(PyCall.tuple())
95
- ax.set_yticks.(PyCall.tuple())
92
+ ax.set_xlim(np.min(xx), np.max(xx))
93
+ ax.set_ylim(np.min(yy), np.max(yy))
94
+ ax.set_xticks(PyCall.tuple())
95
+ ax.set_yticks(PyCall.tuple())
96
96
  i += 1
97
97
 
98
98
  # iterate over classifiers
99
99
  names.zip(classifiers).each do |name, clf|
100
- ax = plt.subplot.(datasets.length, classifiers.length + 1, i)
101
- clf.fit.(x_train, y_train)
102
- scor = clf.score.(x_test, y_test)
100
+ ax = plt.subplot(datasets.length, classifiers.length + 1, i)
101
+ clf.fit(x_train, y_train)
102
+ scor = clf.score(x_test, y_test)
103
103
 
104
104
  # Plot the decision boundary. For that, we will assign a color to each
105
105
  # point in the mesh [x_min, x_max]x[y_min, y_max]
106
106
  begin
107
107
  # not implemented for some
108
- z = clf.decision_function.(mesh_points)
108
+ z = clf.decision_function(mesh_points)
109
109
  rescue
110
- z = clf.predict_proba.(mesh_points)[all, 1]
110
+ z = clf.predict_proba(mesh_points)[all, 1]
111
111
  end
112
112
 
113
113
  # Put the result into a color plot
114
- z = z.reshape.(xx.shape)
115
- ax.contourf.(xx, yy, z, cmap: cm, alpha: 0.8)
114
+ z = z.reshape(xx.shape)
115
+ ax.contourf(xx, yy, z, cmap: cm, alpha: 0.8)
116
116
 
117
117
  # Plot also the training points
118
- ax.scatter.(x_train[all, 0], x_train[all, 1], c: y_train, cmap: cm_bright)
118
+ ax.scatter(x_train[all, 0], x_train[all, 1], c: y_train, cmap: cm_bright)
119
119
  # and testing points
120
- ax.scatter.(x_test[all, 0], x_test[all, 1], c: y_test, cmap: cm_bright, alpha: 0.6)
120
+ ax.scatter(x_test[all, 0], x_test[all, 1], c: y_test, cmap: cm_bright, alpha: 0.6)
121
121
 
122
- ax.set_xlim.(np.min.(xx), np.max.(xx))
123
- ax.set_ylim.(np.min.(yy), np.max.(yy))
124
- ax.set_xticks.(PyCall.tuple())
125
- ax.set_yticks.(PyCall.tuple())
126
- ax.set_title.(name)
122
+ ax.set_xlim(np.min(xx), np.max(xx))
123
+ ax.set_ylim(np.min(yy), np.max(yy))
124
+ ax.set_xticks(PyCall.tuple())
125
+ ax.set_yticks(PyCall.tuple())
126
+ ax.set_title(name)
127
127
 
128
- ax.text.(np.max.(xx) - 0.3, np.min.(yy) + 0.3, "%.2f" % scor, size: 15, horizontalalignment: 'right')
128
+ ax.text(np.max(xx) - 0.3, np.min(yy) + 0.3, "%.2f" % scor, size: 15, horizontalalignment: 'right')
129
129
 
130
130
  i += 1
131
131
  end
132
132
  end
133
133
 
134
- fig.subplots_adjust.(left: 0.02, right: 0.98)
135
- plt.show.()
134
+ fig.subplots_adjust(left: 0.02, right: 0.98)
135
+ plt.show()