Jacob Bender | 1 Mar 2011 01:02
Picon

Re: Socket and Changing IP's

On 2/28/2011 6:57 PM, Wayne Werner wrote:
On Mon, Feb 28, 2011 at 5:49 PM, Jacob Bender <benderjacob44 <at> gmail.com> wrote:
Tutors,

   I was looking into network programming, and I came across a problem. Socket programs need an IP address to function correctly, right? Well, IP addresses are always changing, so how should I go about making sockets that will work for an extended period of time? Thanks in advance!

If your IP address is changing that frequently, something is probably wrong!

Your IP should basically stay the same from the time you connect to the internet until the time you disconnect - longer if you use static IPs.

What are you attempting to program?

-Wayne
    I'm trying to be a host without having to keep the computer on ALL of the time. Acting as a "Dropbox" would be an example. My IP doesn't change very often. It's stayed the same for days.
_______________________________________________
Tutor maillist  -  Tutor <at> python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
David Hutto | 1 Mar 2011 01:04
Picon

Re: Socket and Changing IP's

On Mon, Feb 28, 2011 at 7:02 PM, Jacob Bender <benderjacob44 <at> gmail.com> wrote:
> On 2/28/2011 6:57 PM, Wayne Werner wrote:
>
> On Mon, Feb 28, 2011 at 5:49 PM, Jacob Bender <benderjacob44 <at> gmail.com>
> wrote:
>>
>> Tutors,
>>
>>    I was looking into network programming, and I came across a problem.
>> Socket programs need an IP address to function correctly, right? Well, IP
>> addresses are always changing, so how should I go about making sockets that
>> will work for an extended period of time? Thanks in advance!
>
> If your IP address is changing that frequently, something is probably wrong!
> Your IP should basically stay the same from the time you connect to the
> internet until the time you disconnect - longer if you use static IPs.
> What are you attempting to program?
> -Wayne
>
>     I'm trying to be a host without having to keep the computer on ALL of
> the time.

If you don't want your computer on, and you want your hosting services
allocated elsewhere, then why are you worried about that particular
dynamically changing address?

Go static with "offsite".

 Acting as a "Dropbox" would be an example. My IP doesn't change
> very often. It's stayed the same for days.
>
> _______________________________________________
> Tutor maillist  -  Tutor <at> python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>
>

--

-- 
According to theoretical physics, the division of spatial intervals as
the universe evolves gives rise to the fact that in another timeline,
your interdimensional counterpart received helpful advice from me...so
be eternally pleased for them.
_______________________________________________
Tutor maillist  -  Tutor <at> python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Alan Gauld | 1 Mar 2011 02:20

Re: Timer with exe command

"Kaden McLaws" <killerpancakes <at> msn.com> wrote

> I would like to set up the following using python:
> A timer that is activated when a user logs on to our computer,
> then shuts the computer down when the timer runs out

You can do that from the Operating System, no programming
required. But hopw you do it wioll depend on which Operating
System you are running, which is about the only thing you
omit to mention!

Assuming it's Windows take a look at the 'at' command...
If its Linux or MacOS try 'cron'

> parsing. It would be effective if the last time the timer activated
> was recorded in a txt file, logged, so that the program can
> check and ensure that the last time the timer ended was
> at least 12 hours ago, so the computer just isnt turned
> right back on for another 90 mins repeatedly.

That's a little bit more tricky but doable in a startup script.
Python might be a suitable medium for that task.

> Is there also a way to run the python hidden in the
> background so he cannot just figure out how to close it?

Not really. If he knows how to drive the OS well then pretty
much anything you do can be traced. You can of course
disguise the name of the script so it looks harmless, but
you can't hide the interpreter - unless you have a
separate copy with an obscure name...

HTH,

Alan G. 

_______________________________________________
Tutor maillist  -  Tutor <at> python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

David | 1 Mar 2011 07:49
Picon

A class that instantiates conditionally ?

I have an idea that might clean up my code slightly, if I can make one
of my classes
clever enough to refuse to instantiate itself if a necessary condition
is not met.

Below I propose some example code that seems to achieve this, and I am
asking here
for feedback on it, because I have not written much python. So I might be doing
something unwise due to fiddling with things I don't totally understand.

My aim is that instead of writing this:

	class MyClass:
		pass

	condition = 0

	if condition:
		my_object = MyClass()
	else:
		my_object = None

I could instead write this:

	class MyClass_2:
		# put the if-test here inside the class

	my_object_2 = MyClass_2(condition)

to achieve the goal that (my_object_2 == None) when (condition == False).

I read the (ver 2.6) Python Language Reference
 Section 3.4.1. Basic customization
 Section 3.4.3. Customizing class creation

Most of the content there is way beyond my current understanding, but I came up
with the following code, which seems to work:

	class MyClass_2(object):
		def __new__(self, condition):
			if condition:
				return object.__new__(self)
			else:
				return None

	condition = 0
	my_object_2 = MyClass_2(condition)
	print my_object_2
	condition = 1
	my_object_2 = MyClass_2(condition)
	print my_object_2

Can anyone see any technical or style issues with that? Or
alternatively reassure me that it is completely ok?
Thanks.
_______________________________________________
Tutor maillist  -  Tutor <at> python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Sander Sweers | 1 Mar 2011 08:25
Picon

Re: Socket and Changing IP's

On Tue,  1 Mar 2011, 01:02:23 CET, Jacob Bender <benderjacob44 <at> gmail.com> wrote:
>          I'm trying to be a host without having to keep the computer on ALL
> of the time. Acting as a "Dropbox" would be an example. My IP doesn't
> change very often. It's stayed the same for days.

The best solution here is to get a hostname from a service like dyndns.org. It has easy ways to update the ip address off the hostname. Then from your script connect to the hostname instead of the ip directly.

Br
sander

_______________________________________________
Tutor maillist  -  Tutor <at> python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Christopher Brookes | 1 Mar 2011 09:49
Picon

Re: Multiples python files

Thank you all for answers. Again.

2011/2/28 Alan Gauld <alan.gauld <at> btinternet.com>

"Christopher Brookes" <chris.klaitos <at> gmail.com> wrote


I don't understand

<at> classmethod
  def DisplayAll(cls, herosAll):

What is cls ?

This is one of the advanced techniques I referred to a few days ago.

Basically the "best"(?) solution to your problem is to store the list of characters inside the Character class as what is known as a class variable.

Then everytime you create a new Character you can  add it to the list by the init method. And when a character is deleted you remove it via the del method.

You can then define class methods to read/print the list, find out how many characters exist etc.

This is much cleaner than keeping a separate global variable since the code for managing characters is all in one place with the classs definition. But it does introduce a bunch of new syntax features which I didn't think you were ready for yet! :-)

One thing you will need to be very careful about as you go forward is namespaces. Remember that everytime you import a module you need to precede any names in that module with the module name. And names inside a class need to be preceded by the class name. And names inside objects need to be preceded by the object (variable) name.
If the class is inside a module you need to use both module and class. Thus if the Character class is defined inside character.py you would have something like this in main.py:

import character
myObj = character.Character(....)
print myObj.display()
print character.Character.displayAll()

etc.

You can simplify it by using the "from m import v" style:

from character import Character
myObj = Character(....)
myObj.display()
Character.displayAll()

etc.

HTH,

--
Alan Gauld
Author of the Learn to Program web site
http://www.alan-g.me.uk/



_______________________________________________
Tutor maillist  -  Tutor <at> python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor



--
Brookes Christopher.
_______________________________________________
Tutor maillist  -  Tutor <at> python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Hanlie Pretorius | 1 Mar 2011 10:21
Picon

Accessing a DLL from python

Hi Python Tutors,

I'm using a storm water modelling program, EPA SWMM, to model the
hydrology and hydraulics of a study area.

SWMM reports its results in a binary (.out) file that contains the
results for each element in the model at each time step in the model
run. According to the SWMM interface manual
(http://www.epa.gov/ednnrmrl/models/swmm/swmm5_iface.zip), one can use
a DLL file to read the .out file. I want to do this so that I can read
the state of a river at a specific time and plot its water level in a
GIS.

After some searching on the Internet, I came across ctypes, which I
have tried. According to the SWMM manual:

[manual]
Opening the Output File
----------------------------------
A function named OpenSwmmOutFile(outFile) that performs these tasks is
contained in the example code files that accompany this guide. The
argument to the function is the name of the binary output file. The
return value from the function is an integer code with the following
meanings:
0 - the run was successful
1 - the run was terminated with an error
2 - the output file could not be opened.
[/manual]

So, I tried the following python code:
[code]
In [14]: swmmdll = cdll.LoadLibrary("C:\\Hanlie\\model\\SWMM\\swmm5_0_018.dll")

In [15]: results_file="C:\\Hanlie\\model\\SWMM\\c83a_v0\\c83a_v0.3.out"

In [16]: open_file=swmmdll.OpenSwmmOutFile(results_file)
------------------------------------------------------------
Traceback (most recent call last):
  File "<ipython console>", line 1, in <module>
  File "C:\Python26\lib\ctypes\__init__.py", line 366, in __getattr__
    func = self.__getitem__(name)
  File "C:\Python26\lib\ctypes\__init__.py", line 371, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
AttributeError: function 'OpenSwmmOutFile' not found
[/code]

Can anyone perhaps help me to access the functions in this DLL?

The manual also states:
[manual]
The following files are needed for applications that call functions
from the swmm5.dll library:
· swmm5.h for C/C++ applications
 · swmm5.bas for Visual Basic applications
 · swmm5.pas for Delphi applications.
[/manual]

And they give an example in C, Basic and Pascal to use the interface.
I have appended the C example to this message.

Thanks
Hanlie

[code]
// swmm5_iface.c
//
// Example code for interfacing SWMM 5 with C/C++ programs.
//
// Remember to #include the file swmm5_iface.h in the calling program.

#include <stdio.h>
#include <windows.h>
#include "swmm5.h"

int    SWMM_Nperiods;                  // number of reporting periods
int    SWMM_FlowUnits;                 // flow units code
int    SWMM_Nsubcatch;                 // number of subcatchments
int    SWMM_Nnodes;                    // number of drainage system nodes
int    SWMM_Nlinks;                    // number of drainage system links
int    SWMM_Npolluts;                  // number of pollutants tracked
double SWMM_StartDate;                 // start date of simulation
int    SWMM_ReportStep;                // reporting time step (seconds)

int    RunSwmmExe(char* cmdLine);
int    RunSwmmDll(char* inpFile, char* rptFile, char* outFile);
int    OpenSwmmOutFile(char* outFile);
int    GetSwmmResult(int iType, int iIndex, int vIndex, int period,
float* value);
void   CloseSwmmOutFile(void);

static const int SUBCATCH = 0;
static const int NODE     = 1;
static const int LINK     = 2;
static const int SYS      = 3;
static const int RECORDSIZE = 4;       // number of bytes per file record

static int SubcatchVars;               // number of subcatch reporting variables
static int NodeVars;                   // number of node reporting variables
static int LinkVars;                   // number of link reporting variables
static int SysVars;                    // number of system reporting variables

static FILE*  Fout;                    // file handle
static int    StartPos;                // file position where results start
static int    BytesPerPeriod;          // bytes used for results in each period
static void   ProcessMessages(void);

//-----------------------------------------------------------------------------
int RunSwmmExe(char* cmdLine)
//-----------------------------------------------------------------------------
{
  int exitCode;
  STARTUPINFO si;
  PROCESS_INFORMATION  pi;

  // --- initialize data structures
  memset(&si, 0, sizeof(si));
  memset(&pi, 0, sizeof(pi));
  si.cb = sizeof(si);
  si.wShowWindow = SW_SHOWNORMAL;

  // --- launch swmm5.exe
  exitCode = CreateProcess(NULL, cmdLine, NULL, NULL, 0,
			 0, NULL, NULL, &si, &pi);

  // --- wait for program to end
  exitCode = WaitForSingleObject(pi.hProcess, INFINITE);

  // --- retrieve the error code produced by the program
  GetExitCodeProcess(pi.hProcess, &exitCode);

  // --- release handles
  CloseHandle(pi.hProcess);
  CloseHandle(pi.hThread);
  return exitCode;
}

//-----------------------------------------------------------------------------
int RunSwmmDll(char* inpFile, char* rptFile, char* outFile)
//-----------------------------------------------------------------------------
{
  int err;
  double elapsedTime;

  // --- open a SWMM project
  err = swmm_open(inpFile, rptFile, outFile);
  if (!err)
  {
    // --- initialize all processing systems
    err = swmm_start(1);
    if (err == 0)
    {
      // --- step through the simulation
      do
      {
        // --- allow Windows to process any pending events
        ProcessMessages();

        // --- extend the simulation by one routing time step
        err = swmm_step(&elapsedTime);

        /////////////////////////////////////////////
        // --- call progress reporting function here,
        //     using elapsedTime as an argument
        /////////////////////////////////////////////

      } while (elapsedTime > 0.0 && err == 0);

      // --- close all processing systems
      swmm_end();
    }
  }

  // --- close the project
  swmm_close();
  return err;
}

//-----------------------------------------------------------------------------
void ProcessMessages(void)
//-----------------------------------------------------------------------------
{

/****  Only use this function with a Win32 application *****
  MSG msg;
  while (TRUE)
  {
    if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
      if (msg.message == WM_QUIT) break;
      else
      {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
      }
    }
    else break;
  }
***********************************************************/

}

//-----------------------------------------------------------------------------
int OpenSwmmOutFile(char* outFile)
//-----------------------------------------------------------------------------
{
  int magic1, magic2, errCode, offset, offset0, version;
  int err;

  // --- open the output file
  Fout = fopen(outFile, "rb");
  if (Fout == NULL) return 2;

  // --- check that file contains at least 14 records
  fseek(Fout, 0L, SEEK_END);
  if (ftell(Fout) < 14*RECORDSIZE)
  {
    fclose(Fout);
    return 1;
  }

  // --- read parameters from end of file
  fseek(Fout, -5*RECORDSIZE, SEEK_END);
  fread(&offset0, RECORDSIZE, 1, Fout);
  fread(&StartPos, RECORDSIZE, 1, Fout);
  fread(&SWMM_Nperiods, RECORDSIZE, 1, Fout);
  fread(&errCode, RECORDSIZE, 1, Fout);
  fread(&magic2, RECORDSIZE, 1, Fout);

  // --- read magic number from beginning of file
  fseek(Fout, 0L, SEEK_SET);
  fread(&magic1, RECORDSIZE, 1, Fout);

  // --- perform error checks
  if (magic1 != magic2) err = 1;
  else if (errCode != 0) err = 1;
  else if (SWMM_Nperiods == 0) err = 1;
  else err = 0;

  // --- quit if errors found
  if (err > 0 )
  {
    fclose(Fout);
    Fout = NULL;
    return err;
  }

  // --- otherwise read additional parameters from start of file
  fread(&version, RECORDSIZE, 1, Fout);
  fread(&SWMM_FlowUnits, RECORDSIZE, 1, Fout);
  fread(&SWMM_Nsubcatch, RECORDSIZE, 1, Fout);
  fread(&SWMM_Nnodes, RECORDSIZE, 1, Fout);
  fread(&SWMM_Nlinks, RECORDSIZE, 1, Fout);
  fread(&SWMM_Npolluts, RECORDSIZE, 1, Fout);

  // Skip over saved subcatch/node/link input values
  offset = (SWMM_Nsubcatch+2) * RECORDSIZE  // Subcatchment area
             + (3*SWMM_Nnodes+4) * RECORDSIZE  // Node type, invert & max depth
             + (5*SWMM_Nlinks+6) * RECORDSIZE; // Link type, z1, z2,
max depth & length
  offset = offset0 + offset;
  fseek(Fout, offset, SEEK_SET);

  // Read number & codes of computed variables
  fread(&SubcatchVars, RECORDSIZE, 1, Fout); // # Subcatch variables
  fseek(Fout, SubcatchVars*RECORDSIZE, SEEK_CUR);
  fread(&NodeVars, RECORDSIZE, 1, Fout);     // # Node variables
  fseek(Fout, NodeVars*RECORDSIZE, SEEK_CUR);
  fread(&LinkVars, RECORDSIZE, 1, Fout);     // # Link variables
  fseek(Fout, LinkVars*RECORDSIZE, SEEK_CUR);
  fread(&SysVars, RECORDSIZE, 1, Fout);     // # System variables

  // --- read data just before start of output results
  offset = StartPos - 3*RECORDSIZE;
  fseek(Fout, offset, SEEK_SET);
  fread(&SWMM_StartDate, sizeof(double), 1, Fout);
  fread(&SWMM_ReportStep, RECORDSIZE, 1, Fout);

  // --- compute number of bytes of results values used per time period
  BytesPerPeriod = 2*RECORDSIZE +      // date value (a double)
                   (SWMM_Nsubcatch*SubcatchVars +
                    SWMM_Nnodes*NodeVars+
                    SWMM_Nlinks*LinkVars +
                    SysVars)*RECORDSIZE;

  // --- return with file left open
  return err;
}

//-----------------------------------------------------------------------------
int GetSwmmResult(int iType, int iIndex, int vIndex, int period, float* value)
//-----------------------------------------------------------------------------
{
  int offset;

  // --- compute offset into output file
  *value = 0.0;
  offset = StartPos + (period-1)*BytesPerPeriod + 2*RECORDSIZE;
  if ( iType == SUBCATCH )
  {
    offset += RECORDSIZE*(iIndex*SubcatchVars + vIndex);
  }
  else if (iType == NODE)
  {
    offset += RECORDSIZE*(SWMM_Nsubcatch*SubcatchVars +
                          iIndex*NodeVars + vIndex);
  }
  else if (iType == LINK)
  {
    offset += RECORDSIZE*(SWMM_Nsubcatch*SubcatchVars +
                          SWMM_Nnodes*NodeVars +
                          iIndex*LinkVars + vIndex);
  }
  else if (iType == SYS)
  {
    offset += RECORDSIZE*(SWMM_Nsubcatch*SubcatchVars +
                          SWMM_Nnodes*NodeVars +
                          SWMM_Nlinks*LinkVars + vIndex);
  }
  else return 0;

  // --- re-position the file and read the result
  fseek(Fout, offset, SEEK_SET);
  fread(value, RECORDSIZE, 1, Fout);
  return 1;
}

//-----------------------------------------------------------------------------
void CloseSwmmOutFile(void)
//-----------------------------------------------------------------------------
{
  if (Fout != NULL)
  {
    fclose(Fout);
    Fout = NULL;
  }
}
[/code]
_______________________________________________
Tutor maillist  -  Tutor <at> python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Hanlie Pretorius | 1 Mar 2011 13:22
Picon

Re: Accessing a DLL from python

I see that I have misread the manual and that I need to reproduce the
code in the C example in python. The SWMM DLL doesn't contain
ready-made functions to open files etc.

Apologies for posting before I was completely sure of the problem.

Hanlie

2011/3/1, Hanlie Pretorius <hanlie.pretorius <at> gmail.com>:
> Hi Python Tutors,
>
> I'm using a storm water modelling program, EPA SWMM, to model the
> hydrology and hydraulics of a study area.
>
> SWMM reports its results in a binary (.out) file that contains the
> results for each element in the model at each time step in the model
> run. According to the SWMM interface manual
> (http://www.epa.gov/ednnrmrl/models/swmm/swmm5_iface.zip), one can use
> a DLL file to read the .out file. I want to do this so that I can read
> the state of a river at a specific time and plot its water level in a
> GIS.
>
> After some searching on the Internet, I came across ctypes, which I
> have tried. According to the SWMM manual:
>
> [manual]
> Opening the Output File
> ----------------------------------
> A function named OpenSwmmOutFile(outFile) that performs these tasks is
> contained in the example code files that accompany this guide. The
> argument to the function is the name of the binary output file. The
> return value from the function is an integer code with the following
> meanings:
> 0 - the run was successful
> 1 - the run was terminated with an error
> 2 - the output file could not be opened.
> [/manual]
>
> So, I tried the following python code:
> [code]
> In [14]: swmmdll =
> cdll.LoadLibrary("C:\\Hanlie\\model\\SWMM\\swmm5_0_018.dll")
>
> In [15]: results_file="C:\\Hanlie\\model\\SWMM\\c83a_v0\\c83a_v0.3.out"
>
> In [16]: open_file=swmmdll.OpenSwmmOutFile(results_file)
> ------------------------------------------------------------
> Traceback (most recent call last):
>   File "<ipython console>", line 1, in <module>
>   File "C:\Python26\lib\ctypes\__init__.py", line 366, in __getattr__
>     func = self.__getitem__(name)
>   File "C:\Python26\lib\ctypes\__init__.py", line 371, in __getitem__
>     func = self._FuncPtr((name_or_ordinal, self))
> AttributeError: function 'OpenSwmmOutFile' not found
> [/code]
>
> Can anyone perhaps help me to access the functions in this DLL?
>
> The manual also states:
> [manual]
> The following files are needed for applications that call functions
> from the swmm5.dll library:
> · swmm5.h for C/C++ applications
>  · swmm5.bas for Visual Basic applications
>  · swmm5.pas for Delphi applications.
> [/manual]
>
> And they give an example in C, Basic and Pascal to use the interface.
> I have appended the C example to this message.
>
> Thanks
> Hanlie
>
> [code]
> // swmm5_iface.c
> //
> // Example code for interfacing SWMM 5 with C/C++ programs.
> //
> // Remember to #include the file swmm5_iface.h in the calling program.
>
> #include <stdio.h>
> #include <windows.h>
> #include "swmm5.h"
>
> int    SWMM_Nperiods;                  // number of reporting periods
> int    SWMM_FlowUnits;                 // flow units code
> int    SWMM_Nsubcatch;                 // number of subcatchments
> int    SWMM_Nnodes;                    // number of drainage system nodes
> int    SWMM_Nlinks;                    // number of drainage system links
> int    SWMM_Npolluts;                  // number of pollutants tracked
> double SWMM_StartDate;                 // start date of simulation
> int    SWMM_ReportStep;                // reporting time step (seconds)
>
> int    RunSwmmExe(char* cmdLine);
> int    RunSwmmDll(char* inpFile, char* rptFile, char* outFile);
> int    OpenSwmmOutFile(char* outFile);
> int    GetSwmmResult(int iType, int iIndex, int vIndex, int period,
> float* value);
> void   CloseSwmmOutFile(void);
>
> static const int SUBCATCH = 0;
> static const int NODE     = 1;
> static const int LINK     = 2;
> static const int SYS      = 3;
> static const int RECORDSIZE = 4;       // number of bytes per file record
>
> static int SubcatchVars;               // number of subcatch reporting
> variables
> static int NodeVars;                   // number of node reporting
> variables
> static int LinkVars;                   // number of link reporting
> variables
> static int SysVars;                    // number of system reporting
> variables
>
> static FILE*  Fout;                    // file handle
> static int    StartPos;                // file position where results start
> static int    BytesPerPeriod;          // bytes used for results in each
> period
> static void   ProcessMessages(void);
>
> //-----------------------------------------------------------------------------
> int RunSwmmExe(char* cmdLine)
> //-----------------------------------------------------------------------------
> {
>   int exitCode;
>   STARTUPINFO si;
>   PROCESS_INFORMATION  pi;
>
>   // --- initialize data structures
>   memset(&si, 0, sizeof(si));
>   memset(&pi, 0, sizeof(pi));
>   si.cb = sizeof(si);
>   si.wShowWindow = SW_SHOWNORMAL;
>
>   // --- launch swmm5.exe
>   exitCode = CreateProcess(NULL, cmdLine, NULL, NULL, 0,
> 			 0, NULL, NULL, &si, &pi);
>
>   // --- wait for program to end
>   exitCode = WaitForSingleObject(pi.hProcess, INFINITE);
>
>   // --- retrieve the error code produced by the program
>   GetExitCodeProcess(pi.hProcess, &exitCode);
>
>   // --- release handles
>   CloseHandle(pi.hProcess);
>   CloseHandle(pi.hThread);
>   return exitCode;
> }
>
>
> //-----------------------------------------------------------------------------
> int RunSwmmDll(char* inpFile, char* rptFile, char* outFile)
> //-----------------------------------------------------------------------------
> {
>   int err;
>   double elapsedTime;
>
>   // --- open a SWMM project
>   err = swmm_open(inpFile, rptFile, outFile);
>   if (!err)
>   {
>     // --- initialize all processing systems
>     err = swmm_start(1);
>     if (err == 0)
>     {
>       // --- step through the simulation
>       do
>       {
>         // --- allow Windows to process any pending events
>         ProcessMessages();
>
>         // --- extend the simulation by one routing time step
>         err = swmm_step(&elapsedTime);
>
>         /////////////////////////////////////////////
>         // --- call progress reporting function here,
>         //     using elapsedTime as an argument
>         /////////////////////////////////////////////
>
>       } while (elapsedTime > 0.0 && err == 0);
>
>       // --- close all processing systems
>       swmm_end();
>     }
>   }
>
>   // --- close the project
>   swmm_close();
>   return err;
> }
>
>
> //-----------------------------------------------------------------------------
> void ProcessMessages(void)
> //-----------------------------------------------------------------------------
> {
>
> /****  Only use this function with a Win32 application *****
>   MSG msg;
>   while (TRUE)
>   {
>     if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
>     {
>       if (msg.message == WM_QUIT) break;
>       else
>       {
>         TranslateMessage(&msg);
>         DispatchMessage(&msg);
>       }
>     }
>     else break;
>   }
> ***********************************************************/
>
> }
>
>
> //-----------------------------------------------------------------------------
> int OpenSwmmOutFile(char* outFile)
> //-----------------------------------------------------------------------------
> {
>   int magic1, magic2, errCode, offset, offset0, version;
>   int err;
>
>   // --- open the output file
>   Fout = fopen(outFile, "rb");
>   if (Fout == NULL) return 2;
>
>   // --- check that file contains at least 14 records
>   fseek(Fout, 0L, SEEK_END);
>   if (ftell(Fout) < 14*RECORDSIZE)
>   {
>     fclose(Fout);
>     return 1;
>   }
>
>   // --- read parameters from end of file
>   fseek(Fout, -5*RECORDSIZE, SEEK_END);
>   fread(&offset0, RECORDSIZE, 1, Fout);
>   fread(&StartPos, RECORDSIZE, 1, Fout);
>   fread(&SWMM_Nperiods, RECORDSIZE, 1, Fout);
>   fread(&errCode, RECORDSIZE, 1, Fout);
>   fread(&magic2, RECORDSIZE, 1, Fout);
>
>   // --- read magic number from beginning of file
>   fseek(Fout, 0L, SEEK_SET);
>   fread(&magic1, RECORDSIZE, 1, Fout);
>
>   // --- perform error checks
>   if (magic1 != magic2) err = 1;
>   else if (errCode != 0) err = 1;
>   else if (SWMM_Nperiods == 0) err = 1;
>   else err = 0;
>
>   // --- quit if errors found
>   if (err > 0 )
>   {
>     fclose(Fout);
>     Fout = NULL;
>     return err;
>   }
>
>   // --- otherwise read additional parameters from start of file
>   fread(&version, RECORDSIZE, 1, Fout);
>   fread(&SWMM_FlowUnits, RECORDSIZE, 1, Fout);
>   fread(&SWMM_Nsubcatch, RECORDSIZE, 1, Fout);
>   fread(&SWMM_Nnodes, RECORDSIZE, 1, Fout);
>   fread(&SWMM_Nlinks, RECORDSIZE, 1, Fout);
>   fread(&SWMM_Npolluts, RECORDSIZE, 1, Fout);
>
>   // Skip over saved subcatch/node/link input values
>   offset = (SWMM_Nsubcatch+2) * RECORDSIZE  // Subcatchment area
>              + (3*SWMM_Nnodes+4) * RECORDSIZE  // Node type, invert & max
> depth
>              + (5*SWMM_Nlinks+6) * RECORDSIZE; // Link type, z1, z2,
> max depth & length
>   offset = offset0 + offset;
>   fseek(Fout, offset, SEEK_SET);
>
>   // Read number & codes of computed variables
>   fread(&SubcatchVars, RECORDSIZE, 1, Fout); // # Subcatch variables
>   fseek(Fout, SubcatchVars*RECORDSIZE, SEEK_CUR);
>   fread(&NodeVars, RECORDSIZE, 1, Fout);     // # Node variables
>   fseek(Fout, NodeVars*RECORDSIZE, SEEK_CUR);
>   fread(&LinkVars, RECORDSIZE, 1, Fout);     // # Link variables
>   fseek(Fout, LinkVars*RECORDSIZE, SEEK_CUR);
>   fread(&SysVars, RECORDSIZE, 1, Fout);     // # System variables
>
>   // --- read data just before start of output results
>   offset = StartPos - 3*RECORDSIZE;
>   fseek(Fout, offset, SEEK_SET);
>   fread(&SWMM_StartDate, sizeof(double), 1, Fout);
>   fread(&SWMM_ReportStep, RECORDSIZE, 1, Fout);
>
>   // --- compute number of bytes of results values used per time period
>   BytesPerPeriod = 2*RECORDSIZE +      // date value (a double)
>                    (SWMM_Nsubcatch*SubcatchVars +
>                     SWMM_Nnodes*NodeVars+
>                     SWMM_Nlinks*LinkVars +
>                     SysVars)*RECORDSIZE;
>
>   // --- return with file left open
>   return err;
> }
>
>
> //-----------------------------------------------------------------------------
> int GetSwmmResult(int iType, int iIndex, int vIndex, int period, float*
> value)
> //-----------------------------------------------------------------------------
> {
>   int offset;
>
>   // --- compute offset into output file
>   *value = 0.0;
>   offset = StartPos + (period-1)*BytesPerPeriod + 2*RECORDSIZE;
>   if ( iType == SUBCATCH )
>   {
>     offset += RECORDSIZE*(iIndex*SubcatchVars + vIndex);
>   }
>   else if (iType == NODE)
>   {
>     offset += RECORDSIZE*(SWMM_Nsubcatch*SubcatchVars +
>                           iIndex*NodeVars + vIndex);
>   }
>   else if (iType == LINK)
>   {
>     offset += RECORDSIZE*(SWMM_Nsubcatch*SubcatchVars +
>                           SWMM_Nnodes*NodeVars +
>                           iIndex*LinkVars + vIndex);
>   }
>   else if (iType == SYS)
>   {
>     offset += RECORDSIZE*(SWMM_Nsubcatch*SubcatchVars +
>                           SWMM_Nnodes*NodeVars +
>                           SWMM_Nlinks*LinkVars + vIndex);
>   }
>   else return 0;
>
>   // --- re-position the file and read the result
>   fseek(Fout, offset, SEEK_SET);
>   fread(value, RECORDSIZE, 1, Fout);
>   return 1;
> }
>
>
> //-----------------------------------------------------------------------------
> void CloseSwmmOutFile(void)
> //-----------------------------------------------------------------------------
> {
>   if (Fout != NULL)
>   {
>     fclose(Fout);
>     Fout = NULL;
>   }
> }
> [/code]
>
_______________________________________________
Tutor maillist  -  Tutor <at> python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Hanlie Pretorius | 1 Mar 2011 13:33
Picon

Re: Accessing a DLL from python

Can anyone perhaps suggest the easiest way of translating the C code
into Python, bearing in mind that I'm rather a beginner?

Thanks
Hanlie

2011/3/1, Hanlie Pretorius <hanlie.pretorius <at> gmail.com>:
> I see that I have misread the manual and that I need to reproduce the
> code in the C example in python. The SWMM DLL doesn't contain
> ready-made functions to open files etc.
>
> Apologies for posting before I was completely sure of the problem.
>
> Hanlie
>
> 2011/3/1, Hanlie Pretorius <hanlie.pretorius <at> gmail.com>:
>> Hi Python Tutors,
>>
>> I'm using a storm water modelling program, EPA SWMM, to model the
>> hydrology and hydraulics of a study area.
>>
>> SWMM reports its results in a binary (.out) file that contains the
>> results for each element in the model at each time step in the model
>> run. According to the SWMM interface manual
>> (http://www.epa.gov/ednnrmrl/models/swmm/swmm5_iface.zip), one can use
>> a DLL file to read the .out file. I want to do this so that I can read
>> the state of a river at a specific time and plot its water level in a
>> GIS.
>>
>> After some searching on the Internet, I came across ctypes, which I
>> have tried. According to the SWMM manual:
>>
>> [manual]
>> Opening the Output File
>> ----------------------------------
>> A function named OpenSwmmOutFile(outFile) that performs these tasks is
>> contained in the example code files that accompany this guide. The
>> argument to the function is the name of the binary output file. The
>> return value from the function is an integer code with the following
>> meanings:
>> 0 - the run was successful
>> 1 - the run was terminated with an error
>> 2 - the output file could not be opened.
>> [/manual]
>>
>> So, I tried the following python code:
>> [code]
>> In [14]: swmmdll =
>> cdll.LoadLibrary("C:\\Hanlie\\model\\SWMM\\swmm5_0_018.dll")
>>
>> In [15]: results_file="C:\\Hanlie\\model\\SWMM\\c83a_v0\\c83a_v0.3.out"
>>
>> In [16]: open_file=swmmdll.OpenSwmmOutFile(results_file)
>> ------------------------------------------------------------
>> Traceback (most recent call last):
>>   File "<ipython console>", line 1, in <module>
>>   File "C:\Python26\lib\ctypes\__init__.py", line 366, in __getattr__
>>     func = self.__getitem__(name)
>>   File "C:\Python26\lib\ctypes\__init__.py", line 371, in __getitem__
>>     func = self._FuncPtr((name_or_ordinal, self))
>> AttributeError: function 'OpenSwmmOutFile' not found
>> [/code]
>>
>> Can anyone perhaps help me to access the functions in this DLL?
>>
>> The manual also states:
>> [manual]
>> The following files are needed for applications that call functions
>> from the swmm5.dll library:
>> · swmm5.h for C/C++ applications
>>  · swmm5.bas for Visual Basic applications
>>  · swmm5.pas for Delphi applications.
>> [/manual]
>>
>> And they give an example in C, Basic and Pascal to use the interface.
>> I have appended the C example to this message.
>>
>> Thanks
>> Hanlie
>>
>> [code]
>> // swmm5_iface.c
>> //
>> // Example code for interfacing SWMM 5 with C/C++ programs.
>> //
>> // Remember to #include the file swmm5_iface.h in the calling program.
>>
>> #include <stdio.h>
>> #include <windows.h>
>> #include "swmm5.h"
>>
>> int    SWMM_Nperiods;                  // number of reporting periods
>> int    SWMM_FlowUnits;                 // flow units code
>> int    SWMM_Nsubcatch;                 // number of subcatchments
>> int    SWMM_Nnodes;                    // number of drainage system nodes
>> int    SWMM_Nlinks;                    // number of drainage system links
>> int    SWMM_Npolluts;                  // number of pollutants tracked
>> double SWMM_StartDate;                 // start date of simulation
>> int    SWMM_ReportStep;                // reporting time step (seconds)
>>
>> int    RunSwmmExe(char* cmdLine);
>> int    RunSwmmDll(char* inpFile, char* rptFile, char* outFile);
>> int    OpenSwmmOutFile(char* outFile);
>> int    GetSwmmResult(int iType, int iIndex, int vIndex, int period,
>> float* value);
>> void   CloseSwmmOutFile(void);
>>
>> static const int SUBCATCH = 0;
>> static const int NODE     = 1;
>> static const int LINK     = 2;
>> static const int SYS      = 3;
>> static const int RECORDSIZE = 4;       // number of bytes per file record
>>
>> static int SubcatchVars;               // number of subcatch reporting
>> variables
>> static int NodeVars;                   // number of node reporting
>> variables
>> static int LinkVars;                   // number of link reporting
>> variables
>> static int SysVars;                    // number of system reporting
>> variables
>>
>> static FILE*  Fout;                    // file handle
>> static int    StartPos;                // file position where results
>> start
>> static int    BytesPerPeriod;          // bytes used for results in each
>> period
>> static void   ProcessMessages(void);
>>
>> //-----------------------------------------------------------------------------
>> int RunSwmmExe(char* cmdLine)
>> //-----------------------------------------------------------------------------
>> {
>>   int exitCode;
>>   STARTUPINFO si;
>>   PROCESS_INFORMATION  pi;
>>
>>   // --- initialize data structures
>>   memset(&si, 0, sizeof(si));
>>   memset(&pi, 0, sizeof(pi));
>>   si.cb = sizeof(si);
>>   si.wShowWindow = SW_SHOWNORMAL;
>>
>>   // --- launch swmm5.exe
>>   exitCode = CreateProcess(NULL, cmdLine, NULL, NULL, 0,
>> 			 0, NULL, NULL, &si, &pi);
>>
>>   // --- wait for program to end
>>   exitCode = WaitForSingleObject(pi.hProcess, INFINITE);
>>
>>   // --- retrieve the error code produced by the program
>>   GetExitCodeProcess(pi.hProcess, &exitCode);
>>
>>   // --- release handles
>>   CloseHandle(pi.hProcess);
>>   CloseHandle(pi.hThread);
>>   return exitCode;
>> }
>>
>>
>> //-----------------------------------------------------------------------------
>> int RunSwmmDll(char* inpFile, char* rptFile, char* outFile)
>> //-----------------------------------------------------------------------------
>> {
>>   int err;
>>   double elapsedTime;
>>
>>   // --- open a SWMM project
>>   err = swmm_open(inpFile, rptFile, outFile);
>>   if (!err)
>>   {
>>     // --- initialize all processing systems
>>     err = swmm_start(1);
>>     if (err == 0)
>>     {
>>       // --- step through the simulation
>>       do
>>       {
>>         // --- allow Windows to process any pending events
>>         ProcessMessages();
>>
>>         // --- extend the simulation by one routing time step
>>         err = swmm_step(&elapsedTime);
>>
>>         /////////////////////////////////////////////
>>         // --- call progress reporting function here,
>>         //     using elapsedTime as an argument
>>         /////////////////////////////////////////////
>>
>>       } while (elapsedTime > 0.0 && err == 0);
>>
>>       // --- close all processing systems
>>       swmm_end();
>>     }
>>   }
>>
>>   // --- close the project
>>   swmm_close();
>>   return err;
>> }
>>
>>
>> //-----------------------------------------------------------------------------
>> void ProcessMessages(void)
>> //-----------------------------------------------------------------------------
>> {
>>
>> /****  Only use this function with a Win32 application *****
>>   MSG msg;
>>   while (TRUE)
>>   {
>>     if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
>>     {
>>       if (msg.message == WM_QUIT) break;
>>       else
>>       {
>>         TranslateMessage(&msg);
>>         DispatchMessage(&msg);
>>       }
>>     }
>>     else break;
>>   }
>> ***********************************************************/
>>
>> }
>>
>>
>> //-----------------------------------------------------------------------------
>> int OpenSwmmOutFile(char* outFile)
>> //-----------------------------------------------------------------------------
>> {
>>   int magic1, magic2, errCode, offset, offset0, version;
>>   int err;
>>
>>   // --- open the output file
>>   Fout = fopen(outFile, "rb");
>>   if (Fout == NULL) return 2;
>>
>>   // --- check that file contains at least 14 records
>>   fseek(Fout, 0L, SEEK_END);
>>   if (ftell(Fout) < 14*RECORDSIZE)
>>   {
>>     fclose(Fout);
>>     return 1;
>>   }
>>
>>   // --- read parameters from end of file
>>   fseek(Fout, -5*RECORDSIZE, SEEK_END);
>>   fread(&offset0, RECORDSIZE, 1, Fout);
>>   fread(&StartPos, RECORDSIZE, 1, Fout);
>>   fread(&SWMM_Nperiods, RECORDSIZE, 1, Fout);
>>   fread(&errCode, RECORDSIZE, 1, Fout);
>>   fread(&magic2, RECORDSIZE, 1, Fout);
>>
>>   // --- read magic number from beginning of file
>>   fseek(Fout, 0L, SEEK_SET);
>>   fread(&magic1, RECORDSIZE, 1, Fout);
>>
>>   // --- perform error checks
>>   if (magic1 != magic2) err = 1;
>>   else if (errCode != 0) err = 1;
>>   else if (SWMM_Nperiods == 0) err = 1;
>>   else err = 0;
>>
>>   // --- quit if errors found
>>   if (err > 0 )
>>   {
>>     fclose(Fout);
>>     Fout = NULL;
>>     return err;
>>   }
>>
>>   // --- otherwise read additional parameters from start of file
>>   fread(&version, RECORDSIZE, 1, Fout);
>>   fread(&SWMM_FlowUnits, RECORDSIZE, 1, Fout);
>>   fread(&SWMM_Nsubcatch, RECORDSIZE, 1, Fout);
>>   fread(&SWMM_Nnodes, RECORDSIZE, 1, Fout);
>>   fread(&SWMM_Nlinks, RECORDSIZE, 1, Fout);
>>   fread(&SWMM_Npolluts, RECORDSIZE, 1, Fout);
>>
>>   // Skip over saved subcatch/node/link input values
>>   offset = (SWMM_Nsubcatch+2) * RECORDSIZE  // Subcatchment area
>>              + (3*SWMM_Nnodes+4) * RECORDSIZE  // Node type, invert & max
>> depth
>>              + (5*SWMM_Nlinks+6) * RECORDSIZE; // Link type, z1, z2,
>> max depth & length
>>   offset = offset0 + offset;
>>   fseek(Fout, offset, SEEK_SET);
>>
>>   // Read number & codes of computed variables
>>   fread(&SubcatchVars, RECORDSIZE, 1, Fout); // # Subcatch variables
>>   fseek(Fout, SubcatchVars*RECORDSIZE, SEEK_CUR);
>>   fread(&NodeVars, RECORDSIZE, 1, Fout);     // # Node variables
>>   fseek(Fout, NodeVars*RECORDSIZE, SEEK_CUR);
>>   fread(&LinkVars, RECORDSIZE, 1, Fout);     // # Link variables
>>   fseek(Fout, LinkVars*RECORDSIZE, SEEK_CUR);
>>   fread(&SysVars, RECORDSIZE, 1, Fout);     // # System variables
>>
>>   // --- read data just before start of output results
>>   offset = StartPos - 3*RECORDSIZE;
>>   fseek(Fout, offset, SEEK_SET);
>>   fread(&SWMM_StartDate, sizeof(double), 1, Fout);
>>   fread(&SWMM_ReportStep, RECORDSIZE, 1, Fout);
>>
>>   // --- compute number of bytes of results values used per time period
>>   BytesPerPeriod = 2*RECORDSIZE +      // date value (a double)
>>                    (SWMM_Nsubcatch*SubcatchVars +
>>                     SWMM_Nnodes*NodeVars+
>>                     SWMM_Nlinks*LinkVars +
>>                     SysVars)*RECORDSIZE;
>>
>>   // --- return with file left open
>>   return err;
>> }
>>
>>
>> //-----------------------------------------------------------------------------
>> int GetSwmmResult(int iType, int iIndex, int vIndex, int period, float*
>> value)
>> //-----------------------------------------------------------------------------
>> {
>>   int offset;
>>
>>   // --- compute offset into output file
>>   *value = 0.0;
>>   offset = StartPos + (period-1)*BytesPerPeriod + 2*RECORDSIZE;
>>   if ( iType == SUBCATCH )
>>   {
>>     offset += RECORDSIZE*(iIndex*SubcatchVars + vIndex);
>>   }
>>   else if (iType == NODE)
>>   {
>>     offset += RECORDSIZE*(SWMM_Nsubcatch*SubcatchVars +
>>                           iIndex*NodeVars + vIndex);
>>   }
>>   else if (iType == LINK)
>>   {
>>     offset += RECORDSIZE*(SWMM_Nsubcatch*SubcatchVars +
>>                           SWMM_Nnodes*NodeVars +
>>                           iIndex*LinkVars + vIndex);
>>   }
>>   else if (iType == SYS)
>>   {
>>     offset += RECORDSIZE*(SWMM_Nsubcatch*SubcatchVars +
>>                           SWMM_Nnodes*NodeVars +
>>                           SWMM_Nlinks*LinkVars + vIndex);
>>   }
>>   else return 0;
>>
>>   // --- re-position the file and read the result
>>   fseek(Fout, offset, SEEK_SET);
>>   fread(value, RECORDSIZE, 1, Fout);
>>   return 1;
>> }
>>
>>
>> //-----------------------------------------------------------------------------
>> void CloseSwmmOutFile(void)
>> //-----------------------------------------------------------------------------
>> {
>>   if (Fout != NULL)
>>   {
>>     fclose(Fout);
>>     Fout = NULL;
>>   }
>> }
>> [/code]
>>
>
_______________________________________________
Tutor maillist  -  Tutor <at> python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Stefan Behnel | 1 Mar 2011 13:53
Picon
Favicon

Re: Accessing a DLL from python

Hanlie Pretorius, 01.03.2011 13:33:
> Can anyone perhaps suggest the easiest way of translating the C code
> into Python, bearing in mind that I'm rather a beginner?

A beginner of what? Python? Programming in general?

The C code you posted doesn't look too complex, so you could try to 
translate it (mostly literally) into Python syntax and use Cython to wrap 
that in a binary extension.

Cython is basically Python, but it allows you to call directly into C code. 
Here's a tutorial:

http://docs.cython.org/src/tutorial/clibraries.html

Stefan

_______________________________________________
Tutor maillist  -  Tutor <at> python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Gmane