How to convert a train running program from synchronous to asynchronous?

2019-04-26 Thread Arup Rakshit
I have modelled which starts running once drivers and stations are assigned to 
it. Otherwise, it doesn’t run, really don’t care if passengers are boarded or 
not at this moment. :) I think this program can help me to introduce to the 
Python async programming domain.

Here is my program:

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
# train.py
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

import time
import random

from user import User

class NotReadyToDeparture(Exception):
pass

class Train:
def __init__(self, name, category):
self.name = name
self.category = category
self.__drivers = []
self.__stations = []

@property
def drivers(self):
return self.__drivers

@drivers.setter
def drivers(self, coachmen):
self.__drivers = coachmen

@property
def stations(self):
return self.__stations

@stations.setter
def stations(self, places):
self.__stations = places

def next_stoppage(self):
return self.stations[0]

def run(self):
total_run_time = 0
if len(self.drivers) == 0:
raise NotReadyToDeparture('Drivers are not yet boarded')

if len(self.stations) == 0:
raise NotReadyToDeparture('Stoppage stations are not yet scheduled')

for station in range(len(self.stations[:])):
run_time_to_next_stoppage = random.randint(2, 6)
time.sleep(run_time_to_next_stoppage)
total_run_time += run_time_to_next_stoppage
print("Train Reached at {0} in {1} 
seconds".format(self.stations.pop(0), run_time_to_next_stoppage))

print(f"Train {self.name} is reached the destination in 
{total_run_time} seconds.")

if __name__ == "__main__":
train = Train("Digha Express", "Express")
train.drivers = [ 
User(f_name="Manish", l_name="Jha"),
User(f_name="Deepak", l_name="Das")
]
train.stations = [f'Station {letter}' for letter in ['A', 'B', 'C', 'D']]
train.run()

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
# user.py
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

class User:
def __init__(self, f_name, l_name):
self.f_name = f_name
self.l_name = l_name

def full_name(self):
return f"{self.f_name} {self.l_name}”

Drivers are modelled as users. When I do call the `run` method it behaves as:

Train Reached at Station A in 4 seconds
Train Reached at Station B in 4 seconds
Train Reached at Station C in 3 seconds
Train Reached at Station D in 4 seconds
Train Digha Express is reached the destination in 15 seconds.


What I am looking for is that once I do call train.run() I get the control 
back, and keep querying what the next stoppage is. something like this:

train.run()
while len(train.stations) is not 0:
print(f"Next stoppage is {train.stations[0]}")

How should I modify this current program to meet my goal?

Thanks,

Arup Rakshit
a...@zeit.io



-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Why not being able to call modules from lib folder into test folder although I have __init__.py file both?

2019-04-26 Thread Arup Rakshit

On 26/04/19 11:14 AM, dieter wrote:

Arup Rakshit  writes:

I am not able to call modules from lib folder in my test folder, but outside of 
tests folder I can access them. How should I fix this?

Mocks$ tree .
.
├── lib
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-37.pyc
│   │   └── product.cpython-37.pyc
│   └── product.py
└── tests
 ├── __init__.py
 └── product_test.py

3 directories, 6 files
Mocks$ python3
...

from lib.product import ProductionKlass

...

ProductionKlass()


...
Mocks$ python3 tests/product_test.py
Traceback (most recent call last):
   File "tests/product_test.py", line 4, in 
 from lib.product import ProductionKlass
ModuleNotFoundError: No module named 'lib'

Python's import is controlled by "sys.path" -- typically a sequence of
folders where Python should look for modules/packages to import.

When you start a Python script, it puts the folder containing
the script automatically on "sys.path" (to facilitate imports
by this script). When you start Python interactively, it puts
the current working directory on "sys.path".

These differences explain your observations.
In the first case, "lib" can be imported because
the current working directory has been put on "sys.path".
In the second case, "lib" cannot be imported because the subfolder
"tests" has been put on "sys.path" (not the current working directory
itself).


A modern approach to avoid such situations looks like:

  * make your project into a package
(see "https://packaging.python.org/";)

  * use either package relative imports or absolute imports with
the package as prefix to access modules in your package

  * install your package into a Python installation
(use "virtualenv" to get a light weight local Python installation,
if necessary)

  * have tiny script wrappers for scripts in your package.
Packageing tools (such as "setuptools"
--> "https://setuptools.readthedocs.io/en/latest/";)
can create thoses wrappers for you on installation.

Thanks for explaining this. I read this and couple of internet blogs on  
this, one of them is https://alex.dzyoba.com/blog/python-import/ . I get it.


--
Thanks,

Arup Rakshit

--
https://mail.python.org/mailman/listinfo/python-list