-3

I have a python script that uses two functions but one of these does not work as desired. main() calls the first function Define_and_Collect_1_WireData(): and this works as intended. However I am unable to pass the string variable data_stream_logfile from function Define_and_Collect_1_WireData(): to function log_file().

I have not used return as I am not certain that this keeps the variable local rather than global.

I have tried many combinations / variations available on this site: none that I could understand worked.

How can I do this?

#!/usr/bin/env python

import time

# Create a useful time stamp for logging to the log file 
timestamp = time.strftime("%d/%m/%Y %H:%M:%S")


def Define_and_Collect_1_WireData():
    tfile = open("/sys/bus/w1/devices/28-0000052c29e1/w1_slave")
    text = tfile.read()
    tfile.close()
    temperature_data = text.split()[-1]
    temperature = float(temperature_data[2:])
    temperature1 = round(temperature / 1000,1)

    #for the purposes of testing. Temperature1 will be pulled from the Dallas 1-wire bus 
    temperature1=13.1

    # Create data_stream_logfile string
    data_stream_logfile = str(temperature1) + "," + str(timestamp)

    # Print output to a terminal
    print "Raw temperature data as written to log file:"
    print data_stream_logfile
    print " "

def log_file():
    # Open the text log datafile
    datafile_temperature_log = open("log_cron_temperature_data.log", "a", 1)
    datafile_temperature_log.write(data_stream_logfile + "\n")
    datafile_temperature_log.close()



def main():

    Define_and_Collect_1_WireData()

    log_file()

main()
Kes
  • 285
  • 2
  • 17

7 Answers7

3

You should return it from your first function and pass it into the second function:

def Define_and_Collect_1_WireData():
    # stuff...

    # Create data_stream_logfile string
    data_stream_logfile = str(temperature1) + "," + str(timestamp)

    # More stuff
    return data_stream_logfile

def log_file(data_stream_logfile):
    # Open the text log datafile
    datafile_temperature_log = open("log_cron_temperature_data.log", "a", 1)
    datafile_temperature_log.write(data_stream_logfile + "\n")
    datafile_temperature_log.close()



def main():

    data_stream_logfile = Define_and_Collect_1_WireData()

    log_file(data_stream_logfile)

main()

So, always, always, always do your best to not use global variables!!!!

quamrana
  • 37,849
  • 12
  • 53
  • 71
  • Thanks @quamrana If I had 10 variables to pass between these functions, would i return them all, one by one, or is there another way? – Kes Nov 28 '17 at 20:40
  • 1
    You could return them as parts of an object, or a list or a tuple. It depends how the variables relate to one another. See this **question:** https://stackoverflow.com/questions/354883/how-do-you-return-multiple-values-in-python – quamrana Nov 28 '17 at 20:42
2

You need to return the value of data_stream_logfile in the Define_and_Collect_1_WireData function and use that to pass it to log_file():

def Define_and_Collect_1_WireData():
  ...
  data_stream_logfile = str(temperature1) + "," + str(timestamp)
  return data_stream_logfile

def log_file(data_stream):
  ...

def main():
    data_stream = Define_and_Collect_1_WireData()
    log_file(data_stream)
Cyzanfar
  • 6,997
  • 9
  • 43
  • 81
1
#!/usr/bin/env python

import time

# Create a useful time stamp for logging to the log file 
timestamp = time.strftime("%d/%m/%Y %H:%M:%S")


def Define_and_Collect_1_WireData():
    tfile = open("/sys/bus/w1/devices/28-0000052c29e1/w1_slave")
    text = tfile.read()
    tfile.close()
    temperature_data = text.split()[-1]
    temperature = float(temperature_data[2:])
    temperature1 = round(temperature / 1000,1)

    #for the purposes of testing. Temperature1 will be pulled from the Dallas 1-wire bus 
    temperature1=13.1

    # Create data_stream_logfile string
    data_stream_logfile = str(temperature1) + "," + str(timestamp)

    # Print output to a terminal
    print "Raw temperature data as written to log file:"
    print data_stream_logfile
    print " "

    return data_stream_logfile

def log_file(data_stream_logfile):
    # Open the text log datafile
    datafile_temperature_log = open("log_cron_temperature_data.log", "a", 1)
    datafile_temperature_log.write(data_stream_logfile + "\n")
    datafile_temperature_log.close()



def main():

    log_file (Define_and_Collect_1_WireData())

main()
Jacques de Hooge
  • 6,750
  • 2
  • 28
  • 45
1

You can write to a local data_stream_logfile and return it to the caller. Then call log_file(data_stream_logfile)

Or you could call your log_file()in your first function with the argument data_stream_logfile.

Or you can make it a global variable to get access from both your functions. Just remember to put global data_stream_logfile to each of your functions.

The last one is discouraged since it is error-prone.

D. Jones
  • 461
  • 2
  • 16
1

It's an issue with scope. When you call DaC1WD (because that's a REALLY long function name), it makes a variable within it for the log. When the function finishes, everything within it is lost. What you need to do is return the log file and then call the logger with the log file as an arg.

Jakob Lovern
  • 1,301
  • 7
  • 24
0

You should use return values and parameters in your functions. For example you could rewrite your script as follows:

#!/usr/bin/env python

import time

# Create a useful time stamp for logging to the log file 
timestamp = time.strftime("%d/%m/%Y %H:%M:%S")


def define_and_collect_1_wire_data():
    tfile = open("/sys/bus/w1/devices/28-0000052c29e1/w1_slave")
    text = tfile.read()
    tfile.close()
    temperature_data = text.split()[-1]
    temperature = float(temperature_data[2:])
    temperature1 = round(temperature / 1000,1)

    #for the purposes of testing. Temperature1 will be pulled from the Dallas 1-wire bus 
    temperature1=13.1

    # Create data_stream_logfile string
    data_stream_logfile = str(temperature1) + "," + str(timestamp)

    # Print output to a terminal
    print "Raw temperature data as written to log file:"
    print data_stream_logfile
    print " "
    return data_stream_logfile

def log(message):
    # Open the text log datafile
    datafile_temperature_log = open("log_cron_temperature_data.log", "a", 1)
    datafile_temperature_log.write(message + "\n")
    datafile_temperature_log.close()



def main():

    log_file(define_and_collect_1_wire_data())

main()
  • you should rename `data_stream_logfile` to `message` in your `log` function since you are using `message` as your argument name. – D. Jones Nov 28 '17 at 20:41
-1

You have to make the variable global as it is currently local to that specific function.

global data_stream_logfile
data_stream_logfile = str(temperature1) + "," + str(timestamp)

This will make it so you can use it anywhere else in the program

Hope I could help :3

esp
  • 39
  • 6