Variables in a loop, Newby question

V

vanommen.robert

Hello, for the first time I'm trying te create a little Python program. (on a raspberri Pi)

I don't understand the handling of variables in a loop with Python.


Lets say i want something like this.

x = 1
while x <> 10
var x = x
x = x + 1

The results must be:

var1 = 1
var2 = 2

enz. until var9 = 9

How do i program this in python?
 
J

Joel Goldstick

Hello, for the first time I'm trying te create a little Python program.
(on a raspberri Pi)

I don't understand the handling of variables in a loop with Python.


Lets say i want something like this.

x = 1
while x <> 10
var x = x
x = x + 1

The results must be:

var1 = 1
var2 = 2

enz. until var9 = 9

How do i program this in python?

You might want to go to python.org and check out the documentation. I
don't really understand what you are trying to do. The var1, var2 stuff
doesn't make sense

In python you can loop like this:

for x in range(10):
print x

This will print the numbers from 0 to 9.

But your best bet is to find a brief tutorial to get started.
 
T

Tobias M.

Hello, for the first time I'm trying te create a little Python program. (on a raspberri Pi)

I don't understand the handling of variables in a loop with Python.


Lets say i want something like this.

x = 1
while x <> 10
var x = x
x = x + 1

The results must be:

var1 = 1
var2 = 2

enz. until var9 = 9

How do i program this in python?
You could do:

x = 1
while x < 10:
print(x)
x += 1

But that would be very "unpythonic".
Instead I would use a for loop and the range() function:

for x in range(1,10):
print(x)

This is really short and readable.

I recommend reading the python tutorial to understand the basics:
http://docs.python.org/3/tutorial/
 
P

Peter Otten

Hello, for the first time I'm trying te create a little Python program.
(on a raspberri Pi)

I don't understand the handling of variables in a loop with Python.


Lets say i want something like this.

x = 1
while x <> 10
var x = x
x = x + 1

The results must be:

var1 = 1
var2 = 2

enz. until var9 = 9

How do i program this in python?

You are trying to generate a variable name programatically. While this is
possible in Python
.... exec("var{} = x".format(x))
.... x = x + 1
....7

this is a really bad idea that you probably picked up from old code in a
lesser language. Don't do it that way!

In Python you should use a dict or a list, for example:
var = [] # an empty list
x = 0
while x < 10:
.... var.append(x) # append an item to the list
.... x += 1
....[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

This can be simplified to a single line:

A few usage examples:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range

As you can see list indices are zero-based. A list of length 10 has items 0
to 9.
var[7] += 42
var [0, 1, 2, 3, 4, 5, 6, 49, 8, 9]
sum(var)
87
 
B

bob gailer

Hello, for the first time I'm trying te create a little Python program. (on a raspberri Pi)

I don't understand the handling of variables in a loop with Python.


Lets say i want something like this.

x = 1
while x <> 10
var x = x
x = x + 1

The results must be:

var1 = 1
var2 = 2

enz. until var9 = 9

How do i program this in python?
The larger question is "why do you want to do that". It can be done but
it is almost always a bad idea. Tell us what your goal is and we can
tell you how we'd go about it.

BTW when checking a condition in a while statement it is better practice
to say while x < 10. In the above case it does not matter but if you
were incrementing x by 2 your code would be in an infinite loop, mine
would still stop.
 
V

vanommen.robert

import time
global Sens_Raw1, Sens_Raw2, Sens_Raw3, Sens_Raw4, Sens_Raw5, Sens_Raw6, Sens_Raw7, Sens_Raw8, Sens_Raw9, Sens_Raw10
while True:
sensorids = ["28-0000054c4932", "28-0000054c9454", "28-0000054c9fca", "28-0000054c4401", "28-0000054dab99", "28-0000054cf9b4", "28-0000054c8a03", "28-0000054d$
avgtemperatures = []
for sensor in range (len(sensorids)):
temperatures = []
Sens_Raw = []
text = '';
while text.split("\n")[0].find("YES") == -1:
tfile = open("/sys/bus/w1/devices/"+ sensorids[sensor] +"/w1_slave")
text = tfile.read()
tfile.close()
time.sleep(0.1)
secondline = text.split("\n")[1]
temperaturedata = secondline.split(" ")[9]
temperature = float(temperaturedata [2:])
temperatures.append(temperature / 1000)
print "Sensor ", sensor + 1, temperatures
# Sens_Raw(sensor) = temperatures



This is the program I am trying to adjust. The goal is to make Sens_Raw1 to 10 global so I can use it in other programs on the Raspberry Pi. The print Sensor wordks fine.

Thanks for any help!
 
J

Joel Goldstick

import time
global Sens_Raw1, Sens_Raw2, Sens_Raw3, Sens_Raw4, Sens_Raw5, Sens_Raw6,
Sens_Raw7, Sens_Raw8, Sens_Raw9, Sens_Raw10
while True:
sensorids = ["28-0000054c4932", "28-0000054c9454",
"28-0000054c9fca", "28-0000054c4401", "28-0000054dab99", "28-0000054cf9b4",
"28-0000054c8a03", "28-0000054d$

It looks like the previous line is clipped at the end. It needs a closing
" and a closing ] at least.

avgtemperatures = []

What is the above line for. It never reappears below
for sensor in range (len(sensorids)):
temperatures = []
You never use this either

Sens_Raw = []
Or this.

text = '';

No semicolon in python!

while text.split("\n")[0].find("YES") == -1:
tfile = open("/sys/bus/w1/devices/"+
sensorids[sensor] +"/w1_slave")
text = tfile.read()
tfile.close()
time.sleep(0.1)
secondline = text.split("\n")[1]
temperaturedata = secondline.split(" ")[9]
temperature = float(temperaturedata [2:])
temperatures.append(temperature / 1000)
print "Sensor ", sensor + 1, temperatures
# Sens_Raw(sensor) = temperatures



This is the program I am trying to adjust. The goal is to make Sens_Raw1
to 10 global so I can use it in other programs on the Raspberry Pi. The
print Sensor wordks fine.

Again, not clear what you need. You certainly don't need globals. You may
want to collect all of the Sens_Raw stuff in a list. If you want that list
to useful to other code, you will need to put it in a module. Read about
namespaces.
There is nothing wrong with naming things with underscores between the
words. In fact its recommended.

Sorry, my brain is spinning. This code is useless. Why don't you try to
explain what you are trying to accomplish, and you will get better
answers. As it stands, you perhaps copied this from somewhere. What is
the data that gets written to text? Have you any programming skill,
perhaps with another language?
 
V

vanommen.robert

Indeed this is code what I found on the web to read temperatures from 10 DS18B20 singlewire sensors.

My only programming (little) experience is VBA (Excel mostly).

avgtemperatures = [] is indeed from the original code where this line

'avgtemperatures.append(sum(temperatures) / float(len(temperatures)))'

was added. i removed it.

You're right about the line sensorids. There are 10 sensors:

sensorids = ["28-0000054c4932", "28-0000054c9454", "28-0000054c9fca", "28-0000054c4401", "28-0000054dab99", "28-0000054cf9b4", "28-0000054c8a03", "28-0000054d6780", $00054ccdfa", "28-0000054c4f9d"]


In this script i want to read the temperatures and make them available to other scripts.

One script to controll my solar water boiler and other heat exchangers connected to this boiler. (fire place for example)
And in the future I want to make the temperatures available on a website and log them in a mysql database online.

But as I said before, I am just a few days trying to learn how to do it.

Thanks for your time.

greetings Robert
 
D

Dave Angel

You should always start by mentioning python version and o.s.
import time
global Sens_Raw1, Sens_Raw2, Sens_Raw3, Sens_Raw4, Sens_Raw5,
Sens_Raw6, Sens_Raw7, Sens_Raw8, Sens_Raw9, Sens_Raw10

The global statement makes no sense here, as you're not inside a
function. Everything you've written is global. That means global to
one module or source file. If you need to access data from another
module you'll use import, and if you need to share with another
process you'll need to use a file, a pipe, a queue, or some other
mechanism.
while True:
sensorids = ["28-0000054c4932", "28-0000054c9454",
"28-0000054c9fca", "28-0000054c4401", "28-0000054dab99",
"28-0000054cf9b4", "28-0000054c8a03", "28-0000054d$
avgtemperatures = []
for sensor in range (len(sensorids)):
temperatures = []
Sens_Raw = []

You're clobbering the list every time around the loop. Move this
line before the loop.
text = '';
while text.split("\n")[0].find("YES") == -1:
tfile =
open("/sys/bus/w1/devices/"+ sensorids[sensor] +"/w1_slave")
text = tfile.read()
tfile.close()
time.sleep(0.1)
secondline = text.split("\n")[1]
temperaturedata = secondline.split(" ")[9]
temperature = float(temperaturedata [2:])
temperatures.append(temperature / 1000)
print "Sensor ", sensor + 1, temperatures
# Sens_Raw(sensor) = temperatures

Use Sens_Raw.append () to add to the end of the list.




This is the program I am trying to adjust. The goal is to make
Sens_Raw1 to 10 global so I can use it in other programs on the
Raspberry Pi. The print Sensor wordks fine.
 
D

Denis McMahon

In this script i want to read the temperatures and make them available
to other scripts.

The "global" keyword doesn't do that.

"global" is used inside a function definition in python to tell the
function that it is working with a global (to the program unit) variable.

If you want this process to provide data to other processes, you might
want to look at using a socket so they can request it as needed.
 
C

Cameron Simpson

In this script i want to read the temperatures and make them available
to other scripts. [...]
If you want this process to provide data to other processes, you might
want to look at using a socket so they can request it as needed.

Or just write it to a file for another process to open and read...
 
P

Peter Otten

Indeed this is code what I found on the web to read temperatures from 10
DS18B20 singlewire sensors.

My only programming (little) experience is VBA (Excel mostly).

avgtemperatures = [] is indeed from the original code where this line

'avgtemperatures.append(sum(temperatures) / float(len(temperatures)))'

was added. i removed it.

You're right about the line sensorids. There are 10 sensors:

sensorids = ["28-0000054c4932", "28-0000054c9454", "28-0000054c9fca",
"28-0000054c4401", "28-0000054dab99", "28-0000054cf9b4",
"28-0000054c8a03", "28-0000054d6780", $00054ccdfa", "28-0000054c4f9d"]


In this script i want to read the temperatures and make them available to
other scripts.

One script to controll my solar water boiler and other heat exchangers
connected to this boiler. (fire place for example) And in the future I
want to make the temperatures available on a website and log them in a
mysql database online.

But as I said before, I am just a few days trying to learn how to do it.

Thanks for your time.

greetings Robert

(Warning: all untested code -- I don't have a Raspberry Pi)

When you use constants as sensor ids your code will only work for one
machine, with one configuration. I recommend that you read the sensor ids
once at startup of the script and then operate with these.

For the code poste below I assume that the output of the sensors looks like
the examples on this page:

http://www.gtkdb.de/index_7_2035.html

Namely the list of sensors...

pi@raspberrypi ~ $ cat /sys/devices/w1_bus_master1/w1_master_slaves
10-000801e1799b
10-000801e17146
10-000801e17bc6

and the state of a single sensor:

pi@raspberrypi ~ $ cat /sys/devices/w1_bus_master1/10-000801e1799b/w1_slave
2d 00 4b 46 ff ff 02 10 19 : crc=19 YES
2d 00 4b 46 ff ff 02 10 19 t=22625

You can then deal with the "lowlevel" stuff in a module like the
following...

$ cat sensors.py
def read_sensorids():
with open("/sys/devices/w1_bus_master1/w1_master_slaves") as f:
return [line.strip() for line in f]

def read_sensor(sensorid):
with open("/sys/bus/w1/devices/{}/w1_slave".format(sensorid)) as f:
temperature = f.read().rpartition("=")[-1]
return float(temperature) / 1000.0

def read_sensors(sensorids=None):
if sensorids is None:
sensorids = read_sensorids()

temperatures = {}
for sensorid in sensorids:
temperatures[sensorid] = read_sensor(sensorid)

return temperatures

def print_temperatures(sensorids=None):
for k, v in read_sensors(sensorids).items():
print("Sensor {}: {}".format(k, v))

.... and use it like so:

$ cat sensors_demo.py
import sensors
import time

def demo1():
print "Demo1: detect sensors and print temperatures"
print "current temperatures:"
sensors.print_temperatures()
print

def demo2():
print "Demo 2, detect available sensors"
print "found the following sensors:"
for sensor in sensors.read_sensorids():
print sensor
print

def demo3():
print "Demo 3, choose a sensor and read its temperature every second"
print "found the following sensors:"
sensorids = sensors.read_sensorids()
for index, sensor in enumerate(sensorids):
print " {}: {}".format(index, sensor)

index = int(raw_input("Choose an index "))

follow_sensor = sensorids[index]
print "following", follow_sensor
while True:
print sensors.read_sensor(follow_sensor)
time.sleep(1)


if __name__ == "__main__":
demo1()
demo2()
demo3()

A (simulated, as you might guess from the odd variations in temperature) run
of the above:

$ python sensors_demo.py
Demo1: detect sensors and print temperatures
current temperatures:
Sensor 10-000801e1799b: 45.052
Sensor 10-000801e17146: 23.841
Sensor 10-000801e17bc6: 45.5

Demo 2, detect available sensors
found the following sensors:
10-000801e1799b
10-000801e17146
10-000801e17bc6

Demo 3, choose a sensor and read its temperature every second
found the following sensors:
0: 10-000801e1799b
1: 10-000801e17146
2: 10-000801e17bc6
Choose an index 1
following 10-000801e17146
12.744
39.557
17.345
16.49
49.73
27.925
35.007
44.142
37.187
10.261
44.359
^CTraceback (most recent call last):
File "sensors_demo.py", line 36, in <module>
demo3()
File "sensors_demo.py", line 30, in demo3
time.sleep(1)
KeyboardInterrupt

Again, as I don't have a machine to test the above some of my assumptions
may be false -- or worse, true nine times out of ten.
 
D

Denis McMahon

In this script i want to read the temperatures and make them
available to other scripts. [...]
If you want this process to provide data to other processes, you might
want to look at using a socket so they can request it as needed.

Or just write it to a file for another process to open and read...

That can cause io sync errors, eg if another process has the file opened
for read when you try to write, or you are writing when they try to read.

For inter process communication, sockets are generally better than files.
 
D

Dennis Lee Bieber

import time
global Sens_Raw1, Sens_Raw2, Sens_Raw3, Sens_Raw4, Sens_Raw5, Sens_Raw6, Sens_Raw7, Sens_Raw8, Sens_Raw9, Sens_Raw10

This statement does nothing... In Python, "global" is used /inside/ a
function to indicate that the function is referring to a name that exists
outside of the function (but inside the same module/file as the function).
This is the program I am trying to adjust. The goal is to make Sens_Raw1 to 10 global so I can use it in other programs on the Raspberry Pi. The print Sensor wordks fine.

To make them available to "other programs" means you'll have to save
them to a file that the other programs can read.
 
C

Cameron Simpson

On Tue, 24 Dec 2013 10:27:13 -0800, vanommen.robert wrote:
In this script i want to read the temperatures and make them
available to other scripts. [...]
If you want this process to provide data to other processes, you might
want to look at using a socket so they can request it as needed.

Or just write it to a file for another process to open and read...

That can cause io sync errors, eg if another process has the file opened
for read when you try to write, or you are writing when they try to read.

Well, obviously synchronisation of some kind is needed. The easiest
is write-new-file-with-temp-name followed by rename(). Atomic. Lock
files are also not too hard, etc.
For inter process communication, sockets are generally better than files.

Except for agreement about the ports etc etc, and the need to write
a (possible trite) protocol. At least the filesystem gives great
and ergonomic flexibility about naming the communication point, and
offers file permissions to control who can access stuff instead of
needing some kind of authentication protocol. And of course a file
needs no connect/listen/accept daemon/thread to facilitate
communication.

Of course, a named pipe or UNIX cdomain socket may give the best of both
worlds, depending on the use case.

Cheers,
 
C

Chris Angelico

On Tue, 24 Dec 2013 10:27:13 -0800, vanommen.robert wrote:
In this script i want to read the temperatures and make them
available to other scripts. [...]
If you want this process to provide data to other processes, you might
want to look at using a socket so they can request it as needed.

Or just write it to a file for another process to open and read...

That can cause io sync errors, eg if another process has the file opened
for read when you try to write, or you are writing when they try to read.

Well, obviously synchronisation of some kind is needed. The easiest
is write-new-file-with-temp-name followed by rename(). Atomic. Lock
files are also not too hard, etc.

Does anyone else have the vague feeling that the OP's problem might be
better served by simply importing the script (thus making those values
available to another Python script) than by any of these rather more
complicated theories?

Of course, this requires a little more clarification from the OP, but
I'd rather posit the simple idea and see it knocked down before going
on to the complex :)

ChrisA
 
S

Steven D'Aprano

Chris said:
Does anyone else have the vague feeling that the OP's problem might be
better served by simply importing the script (thus making those values
available to another Python script) than by any of these rather more
complicated theories?

Damn yes!
 
M

Michael Torrie

Indeed this is code what I found on the web to read temperatures from
10 DS18B20 singlewire sensors.

My only programming (little) experience is VBA (Excel mostly).

Definitely you'll want to learn python before you go much farther in
this project. Check out the online docs, tutorials, etc.
In this script i want to read the temperatures and make them
available to other scripts.

Here's some almost runnable code that might help you get down the right
track. You'll have to fill in some of the stuff.

temperatures.py:
import time
sensorids = [...] #fill in these with your ids

def _read_sensor(id):
# open /sys/bus/w1/deevices/id/slave
text = ''
while text.split("\n")[0].find("YES") == -1:
tfile = open("/sys/bus/w1/devices/"+ id +"/w1_slave")
text = tfile.read()
tfile.close()
time.sleep(0.1)
temperaturedata = text.split("\n")[1].split(" ")[9]it(" ")[9]
temperature = float(temperaturedata [2:]) / 1000
return temperature

def get_temperatures():
# not using list comprehensions but we could
temps = []
for sensor in sensorids:
temps.append(_read_sensor(sensor))

Then in your other python modules (scripts):

import temperatures

print temperatures.get_temperatures() # should print a list

Hope this gives you a bit of structure you can use. All the code you
need to fill in can come from the code you posted previously.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top