Re: [Tutor] Fwd: Re: Using files to read data

2017-06-27 Thread Mats Wichmann
On 06/27/2017 05:01 AM, Alan Gauld via Tutor wrote:
> Forwarding to list
> 
> Please always use ReplyAll or ReplyList when responding to list mail.
> 
> 
> 
>  Forwarded Message 
> 
> i apologize.  i guess it didn’t attach correctly.
> my issue is how do i get it out of my file and use it. 
> 
> *the json file, its only about a fifth of it but it should serve its
> purpose*
> [
> 0.9889,
> 0.02,
> "Mon Jun 26 20:37:34 2017"
> ]


A few thoughts here...

suggest storing the time not as a datetime string, but as a time value.
That is, use time.time() to generate it; you can always convert that
value to a string later if needed.

if you're going to write as json, then you should read as json, don't
create your own reader.

in order to get data serialized in a more usable form, you could define
a class, and serialize the class instances, this way you get the
variable name stored along with the data. Since json only understands a
limited number of data types, one cheap approach is to fish out the
dictionary of data from the instance object - json does understand
dicts. I'm using vars() for that.  So here's a cheap example, not
fleshed out to use any of your code:

import time
import json

class Point(object):
def __init__(self, x, y):
self.x = x
self.y = y
self.time = time.time()

# create a few points
A = Point(0.03, 0.9777)
B = Point(0.02, 0.9889)

print(json.dumps(vars(A)))
print(json.dumps(vars(B)))

You'll see you get formatted data that json.loads() ought to be able to
make use of:

{"y": 0.9777, "x": 0.03, "time":
1498577730.524801}
{"y": 0.9889, "x": 0.02, "time":
1498577730.524802}

You don't need a class for that, you can just build the dict yourself,
it was just a cheap way to illustrate.

Simulated read:

 >>> import json
 >>> point = json.loads('{"y": 0.9777, "x":
0.03, "time": 1498577980.382325}')
 >>> print(point['x'])
 0.0
 >>> print(point['y'])
 0.9778
 >>> print(point(['time'])
 1498577980.38
 >>>


I wouldn't open/close the json file you're writing to each time, that
seems a bit wasteful.

And do take on board some of the refactoring suggestions already made.

Dividing the heading by 90 using integer division (//) will give you
four possible values, 0-3, you can then base your definitions/decisions
on that, instead of your "if heading in range(1, 91):"  selections.
range actually generates the values, which you don't really need.

Best of luck!



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


Re: [Tutor] Fwd: Re: Using files to read data

2017-06-27 Thread Peter Otten
Alan Gauld via Tutor wrote:

> Forwarding to list
> 
> Please always use ReplyAll or ReplyList when responding to list mail.
> 
> 
> 
>  Forwarded Message 
> 
> i apologize.  i guess it didn’t attach correctly.
> my issue is how do i get it out of my file and use it.
> 
> *the json file, its only about a fifth of it but it should serve its
> purpose*

> [
> 0.9889,
> 0.02,
> "Mon Jun 26 20:37:34 2017"
> ]
> [
> 0.9777,
> 0.03,
> "Mon Jun 26 20:37:34 2017"
> ]

The problem with this data is that it's not proper json which allows only 
one toplevel data structure, e. g.

[
> [
> 0.9889,
> 0.02,
> "Mon Jun 26 20:37:34 2017"
> ]
,
> [
> 0.9777,
> 0.03,
> "Mon Jun 26 20:37:34 2017"
> ]
]

If you stick to that file format you need to split it into parts that are 
valid json before you can process them with the standard library's json 
module.

If you can rely on your records always consisting of five lines the 
following should work


import json

records = []

def read_five_lines(f):
return "".join(f.readline() for i in range(5))

with open("xyz_save.json") as f:
while True:
chunk = read_five_lines(f)
if not chunk:  # empty string --> reached end of file
break
records.append(json.loads(chunk))

print(records)

Another option would be to change your writing script so that it writes one 
record per line, e. g.

[0.24446, 0.8556, "Tue Jun 27 14:21:44 2017"]
[-0.29333, 1.907, "Tue Jun 27 14:21:44 2017"]

This can be achieved by omitting the indent=0 argument in your json.dump() 
calls. Then your reader can be simplified:

import json

records = []

with open("xyz_save.json") as f:
for line in f:
records.append(json.loads(line))

print(records)



> if heading in range(1, 91):

Did you know that

>>> 1.5 in range(1, 91)
False

? If you want to accept non-integral values you better write the above as

if 0 <= heading < 90:  # swap operators if want to exclude the lower 
   # and include the upper bound
...

or similar.

> north = heading
> east = 90 - heading
> y = (north / 90) * forward_time
> x = (east / 90) * forward_time
> now_time = time.ctime()
> 
> xyz = [x, y, now_time]
> 
> xyz_save = "xyz_save.json"
> 
> 
> with open(xyz_save, "a") as stamp:
> json.dump(xyz, stamp, indent=0)
> stamp.write("\n")
> 
> return xyz
> 
> elif heading in range(91, 181):
> east = heading - 90
> south = 180 - heading
> y = (south / 90) * forward_time
> x = (east / -90) * forward_time
> now_time = time.ctime()
> 
> xyz = [x, y, now_time]
> 
> xyz_save = "xyz_save.json"
> 
> 
> with open(xyz_save, "a") as stamp:
> json.dump(xyz, stamp, indent=0)
> stamp.write("\n")
> 
> return xyz

There's *a* *lot* of repetition here. At the very least you should move the 
parts that are completely identical to the end of the if ... elif ... chain:

if heading in range(1, 91):
north = heading
east = 90 - heading
y = (north / 90) * forward_time
x = (east / 90) * forward_time
elif heading in range(91, 181):
east = heading - 90
south = 180 - heading
y = (south / 90) * forward_time
x = (east / -90) * forward_time
 ...

else: 
# handling the case where no condition matches
print("unhandled heading", heading, file=sys.stderr)
return

now_time = time.ctime()
xyz = [x, y, now_time]
xyz_save = "xyz_save.json"

with open(xyz_save, "a") as stamp:
json.dump(xyz, stamp)
stamp.write("\n")

return xyz

PS:

> north = heading
> east = 90 - heading
> y = (north / 90) * forward_time
> x = (east / 90) * forward_time

I wonder whether there should be a sin() and cos() somewhere...

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


[Tutor] Fwd: Re: Using files to read data

2017-06-27 Thread Alan Gauld via Tutor
Forwarding to list

Please always use ReplyAll or ReplyList when responding to list mail.



 Forwarded Message 

i apologize.  i guess it didn’t attach correctly.
my issue is how do i get it out of my file and use it. 

*the json file, its only about a fifth of it but it should serve its
purpose*
[
0.9889,
0.02,
"Mon Jun 26 20:37:34 2017"
]
[
0.9777,
0.03,
"Mon Jun 26 20:37:34 2017"
]
[
0.9667,
0.0,
"Mon Jun 26 20:37:34 2017"
]
[
0.9556,
0.06,
"Mon Jun 26 20:37:34 2017"
]
[
0.9444,
0.0,
"Mon Jun 26 20:37:34 2017"
]
[
0.9333,
0.06667,
"Mon Jun 26 20:37:34 2017"
]
[
0.9223,
0.07778,
"Mon Jun 26 20:37:34 2017"
]
[
0.9111,
0.08889,
"Mon Jun 26 20:37:34 2017"
]
[
0.9,
0.1,
"Mon Jun 26 20:37:34 2017"
]
[
0.,
0.,
"Mon Jun 26 20:37:34 2017"
]
[
0.8778,
0.1,
"Mon Jun 26 20:37:34 2017"
]
[
0.8667,
0.1,
"Mon Jun 26 20:37:34 2017"
]
[
0.8555,
0.14443,
"Mon Jun 26 20:37:34 2017"
]
[
0.8444,
0.15556,
"Mon Jun 26 20:37:34 2017”

*the code that creates it*

import json
import time

def xyz(heading, forward_time):
"""get x and y increments of 360 degrees"""

if heading in range(1, 91):
north = heading
east = 90 - heading
y = (north / 90) * forward_time
x = (east / 90) * forward_time
now_time = time.ctime()

xyz = [x, y, now_time]

xyz_save = "xyz_save.json"


with open(xyz_save, "a") as stamp:
json.dump(xyz, stamp, indent=0)
stamp.write("\n")

return xyz

elif heading in range(91, 181):
east = heading - 90
south = 180 - heading
y = (south / 90) * forward_time
x = (east / -90) * forward_time
now_time = time.ctime()

xyz = [x, y, now_time]

xyz_save = "xyz_save.json"


with open(xyz_save, "a") as stamp:
json.dump(xyz, stamp, indent=0)
stamp.write("\n")

return xyz

elif heading in range(181, 271):
south = heading - 180
west = 270 - heading
y = (south / -90) * forward_time
x = (west / -90) * forward_time
now_time = time.ctime()

xyz = [x, y, now_time]

xyz_save = "xyz_save.json"


with open(xyz_save, "a") as stamp:
json.dump(xyz, stamp, indent=0)
stamp.write("\n")

return xyz

elif heading in range(271, 361):
west = heading - 270
north = 360 - heading
y = (north / -90) * forward_time
x = (west / 90) * forward_time
now_time = time.ctime()

xyz = [x, y, now_time]

xyz_save = "xyz_save.json"


with open(xyz_save, "a") as stamp:
json.dump(xyz, stamp, indent=0)
stamp.write("\n")

return xyz
 

*One of multiple loads I’ve got. *
*
*
', '0', ':', '3', '7', ':', '3', '4', ' ', '2', '0', '1', '7', '"',
'\n', ']', '\n', '[', '\n', '0', '.', '0', '2', '2', '2', '2', '2', '2',
'2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '3', ',', '\n', '0',
'.', '9', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
'7', '7', '7', ',', '\n', '"', 'M', 'o', 'n', ' ', 'J', 'u', 'n', ' ',
'2', '6', ' ', '2', '0', ':', '3', '7', ':', '3', '4', ' ', '2', '0',
'1', '7', '"', '\n', ']', '\n', '[', '\n', '0', '.', '0', '1', '1', '1',
'1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '2',
',', '\n', '0', '.', '9', '8', '8', '8', '8', '8', '8', '8', '8', '8',
'8', '8', '8', '8', '8', '9', ',', '\n', '"', 'M', 'o', 'n', ' ', 'J',
'u', 'n', ' ', '2', '6', ' ', '2', '0', ':', '3', '7', ':', '3', '4', '
', '2', '0', '1', '7', '"', '\n', ']', '\n', '\n’]
*
*
*
*
*
*
*the closest i have got is this*
*
*
[
0.07778,
0.9223,
"Mon Jun 26 20:37:34 2017"
]
[
0.06667,
0.9333,
"Mon Jun 26 20:37:34 2017"
]
[
0.0,
0.9444,
"Mon Jun 26 20:37:34 2017"
]
[
0.06,
0.9556,
"Mon Jun 26 20:37:34 2017"
]
[
0.0,
0.9667,
"Mon Jun 26 20:37:34 2017"
]
[
0.03,
0.9777,
"Mon Jun 26 20:37:34 2017"
]
[
0.02,
0.9889,
"Mon Jun 26 20:37:34 2017”

*with this code*

filename = "xyz_save.json"
with open(filename) as f_obj:
lines = f_obj.read()

print(lines)
*
*
*
*
*
*
*i guess my ultimate question is how do i take all the x and y values
and use them.*
*i apologize for my ignorance as this is my first post about something
very new to me.*
*i also appreciate your patience*
*
*
*
*
*
*








> On Jun 27, 2017, at 1:56 AM, Alan Gauld