Re: [Tutor] Python 3.6 Extract Floating Point Data from a Text File

2017-04-30 Thread Stephen P. Molnar

On 04/30/2017 02:02 PM, Steven D'Aprano wrote:

On Sun, Apr 30, 2017 at 06:09:12AM -0400, Stephen P. Molnar wrote:
[...]

I would have managed to extract input data from another calculation (not
a Python program) into the following text file.

LOEWDIN ATOMIC CHARGES
  --
 0 C :   -0.780631
 1 H :0.114577
 2 Br:0.309802
 3 Cl:0.357316
 4 F :   -0.001065

What I need to do is extract the floating point numbers into a Python file


I don't quite understand your question, but I'll take a guess. I'm going
to assume you have a TEXT file containing literally this text:

#  cut here 

LOEWDIN ATOMIC CHARGES
--
0 C :   -0.780631
1 H :0.114577
2 Br:0.309802
3 Cl:0.357316
4 F :   -0.001065

#  cut here 


and you want to extract the atomic symbols (C, H, Br, Cl, F) and
charges as floats. For the sake of the exercise, I'll extract them into
a dictionary {'C': -0.780631, 'H': 0.114577, ... } then print them.

Let me start by preparing the text file. Of course I could just use a
text editor, but let's do it with Python:


data = """LOEWDIN ATOMIC CHARGES
--
0 C :   -0.780631
1 H :0.114577
2 Br:0.309802
3 Cl:0.357316
4 F :   -0.001065
"""

filename = 'datafile.txt'
with open(filename, 'w') as f:
 f.write(data)


(Of course, in real life, it is silly to put your text into Python just
to write it out to a file so you can read it back in. But as a
programming exercise, its fine.)

Now let's re-read the file, processing each line, and extract the data
we want.

atomic_charges = {}
filename = 'datafile.txt'
with open(filename, 'r') as f:
 # Skip lines until we reach a line made of nothing but ---
 for line in f:
 line = line.strip()  # ignore leading and trailing whitespace
 if set(line) == set('-'):
 break
 # Continue reading lines from where we last got to.
 for line in f:
 line = line.strip()
 if line == '':
 # Skip blank lines.
 continue
 # We expect lines to look like:
 #   1 C :   0.12345
 # where there may or may not be a space between the
 # letter and the colon. That makes it tricky to process,
 # so let's force there to always be at least one space.
 line = line.replace(':', ' :')
 # Split on spaces.
 try:
 number, symbol, colon, number = line.split()
 except ValueError as err:
 print("failed to process line:", line)
 print(err)
 continue  # skip to the next line
 assert colon == ':', 'expected a colon but found something else'
 try:
 number = float(number)
 except ValueError:
 # We expected a numeric string like -0.234 or 0.123, but got
 # something else. We could skip this line, or replace it
 # with an out-of-bounds value. I'm going to use an IEEE-754
 # "Not A Number" value as the out-of-bounds value.
 number = float("NaN")
 atomic_charges[symbol] = number

# Finished! Let's see what we have:
for sym in sorted(atomic_charges):
 print(sym, atomic_charges[sym])





There may be more efficient ways to process the lines, for example by
using a regular expression. But its late, and I'm too tired to go
messing about with regular expressions now. Perhaps somebody else will
suggest one.




Steve

Thanks for your reply to my, unfortunately imprecisely worded, question.

Here are the results of applying you code to my data:

Br 0.309802
C -0.780631
Cl 0.357316
F -0.001065
H 0.114577

I should have mentioned that I already have the file, it's part if the 
output from the Orca Quantum Chemistry Program.


As soon as I understand teh code I'm going to have to get rid of the 
atomic symbols and get the charges in the same order as they are in the 
original LOEWDIN ATOMIC CHARGES file.  The Molecular Transform suite of 
programs depends on the distances between pairs of bonded atoms, hence 
the order is important.


Again, many thanks for your help.

Regards,

Steve

--
Stephen P. Molnar, Ph.D.Life is a fuzzy set
www.molecular-modeling.net  Stochastic and multivariate
(614)312-7528 (c)
Skype: smolnar1
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] Fwd: Re: Python 3.6 Extract Floating Point Data from a Text File

2017-04-30 Thread Alan Gauld via Tutor
How, embarrassing,  I forgot to CC the list! :-)

On 30/04/17 11:09, Stephen P. Molnar wrote:

> I would have managed to extract input data from another calculation (not 
> a Python program) into the following text file.
> 
> LOEWDIN ATOMIC CHARGES
>   --
>  0 C :   -0.780631
>  1 H :0.114577
> 
> What I need to do is extract the floating point numbers into a Python file

>From previous posts we know you can extract a line of text so really you
are asking how to extract a floating point number from a string.

>>> s = ' 0 C :   -0.780631'
>>> fps = s.split()[-1]   # get the last item from the split string
>>> val = float(fps)
>>> print( val )

Or in one line:

val = float( line.split()[-1] )

Obviously if the number were not at the end you would have to use
the appropriate index instead of -1...

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Python 3.6 Extract Floating Point Data from a Text File

2017-04-30 Thread Steven D'Aprano
On Sun, Apr 30, 2017 at 06:09:12AM -0400, Stephen P. Molnar wrote:
[...]
> I would have managed to extract input data from another calculation (not 
> a Python program) into the following text file.
> 
> LOEWDIN ATOMIC CHARGES
>  --
> 0 C :   -0.780631
> 1 H :0.114577
> 2 Br:0.309802
> 3 Cl:0.357316
> 4 F :   -0.001065
> 
> What I need to do is extract the floating point numbers into a Python file

I don't quite understand your question, but I'll take a guess. I'm going 
to assume you have a TEXT file containing literally this text:

#  cut here 

LOEWDIN ATOMIC CHARGES
--
   0 C :   -0.780631
   1 H :0.114577
   2 Br:0.309802
   3 Cl:0.357316
   4 F :   -0.001065

#  cut here 


and you want to extract the atomic symbols (C, H, Br, Cl, F) and 
charges as floats. For the sake of the exercise, I'll extract them into 
a dictionary {'C': -0.780631, 'H': 0.114577, ... } then print them.

Let me start by preparing the text file. Of course I could just use a 
text editor, but let's do it with Python:


data = """LOEWDIN ATOMIC CHARGES
--
   0 C :   -0.780631
   1 H :0.114577
   2 Br:0.309802
   3 Cl:0.357316
   4 F :   -0.001065
"""

filename = 'datafile.txt'
with open(filename, 'w') as f:
f.write(data)


(Of course, in real life, it is silly to put your text into Python just 
to write it out to a file so you can read it back in. But as a 
programming exercise, its fine.)

Now let's re-read the file, processing each line, and extract the data 
we want.

atomic_charges = {}
filename = 'datafile.txt'
with open(filename, 'r') as f:
# Skip lines until we reach a line made of nothing but ---
for line in f:
line = line.strip()  # ignore leading and trailing whitespace
if set(line) == set('-'):
break
# Continue reading lines from where we last got to.
for line in f:
line = line.strip()
if line == '': 
# Skip blank lines.
continue
# We expect lines to look like:
#   1 C :   0.12345
# where there may or may not be a space between the 
# letter and the colon. That makes it tricky to process,
# so let's force there to always be at least one space.
line = line.replace(':', ' :')
# Split on spaces.
try:
number, symbol, colon, number = line.split()
except ValueError as err:
print("failed to process line:", line)
print(err)
continue  # skip to the next line
assert colon == ':', 'expected a colon but found something else'
try:
number = float(number)
except ValueError:
# We expected a numeric string like -0.234 or 0.123, but got
# something else. We could skip this line, or replace it
# with an out-of-bounds value. I'm going to use an IEEE-754
# "Not A Number" value as the out-of-bounds value.
number = float("NaN")
atomic_charges[symbol] = number

# Finished! Let's see what we have:
for sym in sorted(atomic_charges):
print(sym, atomic_charges[sym])





There may be more efficient ways to process the lines, for example by 
using a regular expression. But its late, and I'm too tired to go 
messing about with regular expressions now. Perhaps somebody else will 
suggest one.



-- 
Steve
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Python 3.6 Extract Floating Point Data from a Text File

2017-04-30 Thread boB Stepp
Hello Stephen!

On Sun, Apr 30, 2017 at 5:09 AM, Stephen P. Molnar
 wrote:
>
> I am using the Spyder v-3.1.2 IDE and porting a FORTRAN program that I wrote
> about 20 years ago to Python  Unfortunately, I am very much a novice in
> Python .
>
> I would have managed to extract input data from another calculation (not a
> Python program) into the following text file.
>
> LOEWDIN ATOMIC CHARGES
>  --
> 0 C :   -0.780631
> 1 H :0.114577
> 2 Br:0.309802
> 3 Cl:0.357316
> 4 F :   -0.001065
>
> What I need to do is extract the floating point numbers into a Python file
>
> What I need to do is extract the floating point numbers into a Python file.

It is not clear to me what you mean by "Python file" (Twice over!
~(:>)) ).  But I would think a possible outline for your problem would
be:

1)  Open your data file for reading and open another (empty) file for appending.

2)  Loop over each line of your data file, ignoring the first two lines.

3)  Process one line at a time.  Use the split() string method to
split each line on the colon.  Strip all white space from the part you
are interested in.  Append the desired part to your write file.

4)  Close the files, or, better yet, setup the above with the "with"
context manager, which will handle the file closing automatically.

If you are not familiar with file I/O in Python 3, the tutorial has a
section on it:

https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files

It is possible your actual problem is better addressed by the csv
module in the standard library.  The docs for this are at:

https://docs.python.org/3/library/csv.html

For instance, instead of using a comma as the field separator, you
could use a colon.

As to how you want to write the extracted data, that depends on what
you really want.  The above approach suffices for writing to another
text file or  to a binary file.  If you need something different then
you need to let us know what direction you need to go.

Finally, when you need to actually use the extracted string resembling
a float, you will have to convert that string using the float()
function.

Hope that something above is helpful!

Cheers!

-- 
boB
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Tkinter layout question

2017-04-30 Thread Alan Gauld via Tutor
On 26/04/17 07:56, Phil wrote:

>> Your messages come into the moderation queue, I'm
> 
> Thanks Alan, maybe the reason ...is because I'm 
> on the bounces list.

I don;t know what bounces list you mean but it looks
like your messages are going through directly now,
I don't know what changed...

Post a test to see. Messages typically arrive within
5-15 minutes of posting if not moderated.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Another set question

2017-04-30 Thread Alan Gauld via Tutor
On 30/04/17 00:58, Phil wrote:

> Thank you Ben. A rethink of the problem during the 20 hours since 
> I posted my most recent question has led to a solution.

You don;t say what so i'll go with what you say below...

> The strings are the given numbers while the sets are 
> the likely candidates.

I would probably combine both such that for each cell you
have a tuple containing the given number and the set of
candidates. In some cases the number may be a sentinel
(such as -1) to indicate no number yet, and for some
cells the set will be empty.

But by always having both available your data handling
becomes consistent, you always know that you get a tuple
and you know can easily test the sentinel to see3 if
the value is set or not. And you never need to
test types.

Everything should become much more consistent. (The storage
overhead is minimal for a suduko game - it might be different
if you were doing something with a massive grid...)

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] How to display radiobutton window with no buttons selected?

2017-04-30 Thread Alan Gauld via Tutor
On 25/04/17 12:39, boB Stepp wrote:

>>> I wish the displayed window to initially display with no button
>>> selected.  What am I missing here?
>>
>> It looks like the empty string is special. On my (linux) system all buttons
>> appear grayed (while a selected button would be black). Any other string
>> should give the desired result, probably because every button "thinks" that
>> another button is currently selected.

There is a simple solution.
Use a hidden butrtpon to represent no selection. Here is an example:


###
from tkinter import *

top = Tk()

rbVar = IntVar()

rb0 = Radiobutton(top, text="hidden", variable=rbVar, value=0)
rb1 = Radiobutton(top, text='one', variable=rbVar, value=1)
rb1.pack()
rb2 = Radiobutton(top, text='two', variable=rbVar, value=2)
rb2.pack()
rb3 = Radiobutton(top, text='three', variable=rbVar, value=3)
rb3.pack()

Button(top,text='reset', command=lambda : rbVar.set(0)).pack()

top.mainloop()

##

I was going to post this last week but typing it into a
tablet with no way to test it was too much so here is
a belated option...


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] Python 3.6 Extract Floating Point Data from a Text File

2017-04-30 Thread Stephen P. Molnar


I am using the Spyder v-3.1.2 IDE and porting a FORTRAN program that I 
wrote about 20 years ago to Python  Unfortunately, I am very much a 
novice in Python .


I would have managed to extract input data from another calculation (not 
a Python program) into the following text file.


LOEWDIN ATOMIC CHARGES
 --
0 C :   -0.780631
1 H :0.114577
2 Br:0.309802
3 Cl:0.357316
4 F :   -0.001065

What I need to do is extract the floating point numbers into a Python file

What I need to do is extract the floating point numbers into a Python file.

Googling the problem has not resulted on any insight as to the solution, 
and any help will be much appreciated.


Thanks in advance.

--
Stephen P. Molnar, Ph.D.Life is a fuzzy set
www.molecular-modeling.net  Stochastic and multivariate
(614)312-7528 (c)
Skype: smolnar1
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] Thread Object integration with GPIO

2017-04-30 Thread Marc Eymard
Hello there,

I have hooked up an ultrasonic sensor to my Raspberry Pi-enabled robot
in order to get continuous distance-to-obstacle reading.

The sensor is properly connected via GPIO and already reads the distance
properly when running a simple script.

However, I need to integrate the sensor reading logic to an existing
script provided by PiBorg called YetiBorg.py

The way I have decided to go about implementing the sensor reading is by
creating a Thread object and update the distance attribute of this very
same object from the run() function. The idea is to encapsulate the
distance reading within the sensor object as much as possible by i.
creating a sensor/thread object and by ii. avoiding global variables.

Below the script I have come up along with the error print.
I believe there are multiple issues, but at least it gives an idea of
what I currently want to achieve and how.

Can a charitable soul advise whether my approach makes sense and whether
I am using the right type of object for the task at hands?

I am looking for guidance and willing try completely different
approach/objects if necessary.

Thanks in advance for sending me into the right direction.
Marc

Python Shell

2.7.9

OS-

Raspian Pixel on Raspberry Pi Zero



---traceback



Traceback (most
recent call last):

File
"/home/pi/Desktop/distance sensor class object.py", line
57, in 


SensorA = Sensor(interval=1, gpio_trig=23, gpio_echo=24)

File"/home/pi/Desktop/distance sensor class object.py", line
23, in __init__self.start()


RuntimeError:
thread.__init__() not called





--sensor.py-


import threading
import RPi.GPIO as GPIO
import time

#GPIO Mode (BOARD / BCM)
GPIO.setmode(GPIO.BCM)

class Sensor(threading.Thread):

"""ultrasonic sensor continous distance reading at given interval in 
seconds"""

def __init__(self,interval, gpio_trig, gpio_echo):
self.inter = interval
self.trig = gpio_trig
self.echo = gpio_echo

#set GPIO pins direction (IN / OUT)
GPIO.setup(gpio_trig, GPIO.OUT)
GPIO.setup(gpio_echo, GPIO.IN)

self.dist = 0
self.terminated = False
self.start()

def run(self):
while not self.terminated:
# set Trigger to HIGH
GPIO.output(gpio_trig, True)

# set Trigger to LOW after 0.01ms
time.sleep(0.1)
GPIO.output(gpio_trig, False)

StartTime = time.time()
StopTime = time.time()

# save StartTime
while GPIO.input(gpio_echo) == 0:
StartTime = time.time()

# save time of arrival
while GPIO.input(gpio_echo) == 1:
StopTime = time.time()

# time difference between start and arrival
TimeElapsed = StopTime - StartTime
# multiply by sonic speed (34300 cm/s)
# and divide by 2, because there and back
self.dist = (TimeElapsed * 34300) / 2

time.sleep(self.inter)

def get_dist(self):
return self.dist

#Sensor object "instanciated" with GPIO programmable pins 23 and 24
SensorA = Sensor(interval=1, gpio_trig=23, gpio_echo=24)

try:
while True:
print("Measured Distance = %.1f cm" % SensorA.get_dist())
except KeyboardInterrupt:
GPIO.cleanup()
SensorA.terminated = True



___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Thread Object integration with GPIO

2017-04-30 Thread Steven D'Aprano
On Sat, Apr 29, 2017 at 06:26:28PM +, Marc Eymard wrote:

> The way I have decided to go about implementing the sensor reading is by 
> creating a Thread object and update the distance attribute of this very 
> same object from the run() function. The idea is to encapsulate the 
> distance reading within the sensor object as much as possible by i. 
> creating a sensor/thread object and by ii. avoiding global variables.

That's not a bad approach, but I'd take it one step further: move all 
the logic into another object, and just have the thread call it. That 
lets you change your mind later, and replace threads with an external 
process, or async code, or whatever technology is best. It also allows 
you to add whatever smarts or features you need into the object 
collecting values, without the thread needing to care about it.

Something like this untested code:



from threading import Thread

class Collector(object):
# Object to collect readings.

def __init__(self):
self.values = []

def store(self, value):
# If you need any data validation or other processing,
# put it here.
self.values.append(value)

def run(self):
print("Starting collecting...")
while True:
value = ... # collect the data somehow
if value == -1:
 # No more data?
 break
self.store(value)
print("...finished collecting.")

def report(self):
print("I have %d values" % len(self.values))



Now, you can have your main function create a Collector, pass it to the 
thread, and process it as needed:

def main():
 c = Collector()
 t = Thread(target=c.run, name='my thread')
 t.start()
 t.join()
 c.report()



> Attached the script I have come up with

Alas, this mailing list doesn't accept attachments. You should reduce 
the script to the smallest amount of code you can, and re-post it, 
together with the entire stack trace of the errors.



-- 
Steve
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor