1

I'm try to run a Python script I wrote from a Ruby on Rails controller using RubyPython

Version numbers are

Ruby 2.1.2p95
Rails 4.1.6
RubyPython 0.6.3
Python 3.2.3

The Python class isn't stored in the controller directory however I have two symbolic links to the Python script instead.

lrwxrwxrwx 1 pi pi 30 Sep 16 22:17 current_lamp_state.py -> ../../../current_lamp_state.py
lrwxrwxrwx 1 pi pi 30 Sep 16 22:33 CurrentLampState.py -> ../../../current_lamp_state.py

When I try and import the Python class with one of the symbolic links I get one of the following error

ImportError: No module named current_lamp_state
or
ImportError: No module named CurrentLampState

I have also tried placing the Python code in the controller directory but I get the same error

The code for the Python script is

import unittest
import os
from lamp_state import LampState

class CurrentLampState(unittest.TestCase):
  CURRENT_STATE_FILENAME = 'current_lamp_state.txt'

  def get(self):
    if(os.path.isfile(self.CURRENT_STATE_FILENAME)):
      file = open(self.CURRENT_STATE_FILENAME, "r")
      value = file.readline()
      file.close()
      return int(value)
    else:
      lampState = LampState()
      return lampState.OFF

  def set(self, newState):
    file = open(self.CURRENT_STATE_FILENAME, "w")
    file.write(str(newState))
    file.close()

  def test_givenTheLampStateIsUnknown_whenGetIsCalled_thenTheCurrentLampStateShouldBeOff(self):
    if(os.path.isfile(self.CURRENT_STATE_FILENAME)):
      os.remove(self.CURRENT_STATE_FILENAME)
    lampState = LampState()
    expected = lampState.OFF
    actual = self.get()
    self.assertEqual(expected, actual)

  def test_givenTheLampStateOfHigh_whenGetIsCalled_thenTheCurrentLampStateShouldBeHigh(self):
    lampState = LampState()
    expected = lampState.HIGH
    self.set(expected)
    actual = self.get()
    self.assertEqual(expected, actual)

  def test_givenALampState_whenSetIsCalled_thenTheLampStateShouldBeSaved(self):
    lampState = LampState()
    expected = lampState.LOW
    self.set(expected)
    actual = self.get()
    self.assertEqual(expected, actual)

if __name__ == '__main__':
  unittest.main()

The Ruby code for the controller is

require "rubypython"

class LampController < ApplicationController
  def lamp
    RubyPython.start
    lamp_state = RubyPython.import 'current_lamp_state'
    RubyPython.stop
  end
end

I'm new to Ruby and Rails and I've never really use Python in anger so I know I'm doing something wrong, I just don't know what. Any advice would be greatly appreciated.

PS I don't really like the unit tests in the same file as the class, but from what I have read that is the Python way of doing it.

TheLukeMcCarthy
  • 2,253
  • 2
  • 25
  • 34
  • 1
    Are you running the ruby script from inside that directory? If not you must add that directory to the `PYTHONPATH`. – Bakuriu Sep 17 '14 at 08:46
  • in your controller try `lamp_state = RubyPython.import 'lamp_state'` instead of `'current_lamp_state'` I have never used so not sure – Gagan Gami Sep 17 '14 at 08:48
  • @Bakuriu thanks for the help, if you add it as an answer I will mark it as the correct answer. – TheLukeMcCarthy Sep 17 '14 at 13:00

0 Answers0