1

I'm new in python and I'm writing a simple script to work with Firebase but I'm stuck on a simple if statement that seems not working as expected:

## check for max values
if humidity > maxHumidity:
    firebase.put("/Controls/Sensors", "/Humidity/max_inside", ""+humidity+"%")
    print("Updating Humidity max_inside")

if temperature > maxTemperature:
    firebase.put("/Controls/Sensors", "/Temperature/max_inside", ""+temperature+"C")
    print("Updating Temperature max_inside")

## check for min values
if humidity < minHumidity:
    firebase.put("/Controls/Sensors", "/Humidity/min_inside", ""+humidity+"%")
    print("Updating Humidity min_inside")

if temperature < minTemperature:
    firebase.put("/Controls/Sensors", "/Temperature/min_inside", ""+temperature+"C")
    print("Updating Temperature min_inside")

The problem is that the first two if statements are working as expected, the last two not.. If the humidity < minHumidity, nothing happens.

The value that I'm using are double like 70.50..

Edit

##retrieve max & min humidity (remove the %)
maxHumidity = firebase.get("/Controls/Sensors/Humidity/max_inside", None)
maxHumidity = maxHumidity[:-1]
maxHumidity = float(maxHumidity)

minHumidity = firebase.get("/Controls/Sensors/Humidity/min_inside", None)
minHumidity = minHumidity[:-1]
minHumidity = float(minHumidity)

#retrieve max & min temperature (remove the C)
maxTemperature = firebase.get("/Controls/Sensors/Temperature/max_inside", None)
maxTemperature = maxTemperature[:-1]
maxTemperature = float(maxTemperature)

minTemperature = firebase.get("/Controls/Sensors/Temperature/min_inside", None)
minTemperature = minTemperature[:-1]
minTemperature = float(minTemperature)

#add current value
humidity, temperature = readDHT22()
firebase.put("/Controls/Sensors", "/Humidity/current_inside", ""+humidity+"%")
firebase.put("/Controls/Sensors", "/Temperature/current_inside", ""+temperature+"C")

##check for max values
if humidity > maxHumidity:
    firebase.put("/Controls/Sensors", "/Humidity/max_inside", ""+humidity+"%")
    print("Updating Humidity max_inside")
if temperature > maxTemperature:
    firebase.put("/Controls/Sensors", "/Temperature/max_inside", ""+temperature+"C")
    print("Updating Temperature max_inside")

## cehck for min values
if humidity < minHumidity:
    firebase.put("/Controls/Sensors", "/Humidity/min_inside", ""+humidity+"%")
    print("Updating Humidity min_inside")
if temperature < minTemperature:
    firebase.put("/Controls/Sensors", "/Temperature/min_inside", ""+temperature+"C")
    print("Updating Temperature min_inside")

Tried to use float but seems still not working! Is not going into the min ifs.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
dvdciri
  • 441
  • 6
  • 19
  • 1
    where do you assign your variables? – patrick May 21 '16 at 14:24
  • 1
    Make sure, that both humidity and minHumidity are of float type. You can check it with type(humidity) and type(minHumidity). – Jacobian May 21 '16 at 14:24
  • 1
    It looks like your `humidity` and `temperature` are strings, not floats. – PM 2Ring May 21 '16 at 14:25
  • 3
    Clearly, `humidity` and `temperature` are *strings* (or you couldn't concatenate them with other strings). If `maxHumidity`, etc. are strings too, then they'll be compared *lexicographically*; `'10'` is sorted before `'2'`, so `'10' < '2'` is *true*. If the other variables are not strings and this is Python 2, then you are comparing *by type*, where numbers are sorted before other types. – Martijn Pieters May 21 '16 at 14:27
  • I'm going to post more code so you'll understand better.. btw they humidity and minHumidity are value taken from the firebase db.. they are string actually but is working with the maximum comparison.. and not with the min comparison... – dvdciri May 21 '16 at 14:27
  • However, we can't help you without proper samples for the inputs here. Give us `print(repr(variable))` results for each no we can see the type and value for each, and tell us what outcome you expected. Only then does your question become answerable. – Martijn Pieters May 21 '16 at 14:28
  • Okay i think i've found the problem, they are strings, and i thought that maybe python was automatically parsing them into int, so this is why is working with the >.. instead is just comparing the leght as @MartijnPieters said.. thanks... in this case, what can i do for parse the string to double/float??? – dvdciri May 21 '16 at 14:29
  • `float(num_str)`. Floating point numbers are usually implemented using double in C – Simon Fromme May 21 '16 at 14:31
  • Martijn didn't say it was comparing the string lengths, he said it was comparing them [_lexicographically_](https://en.wikipedia.org/wiki/Lexicographical_order) – PM 2Ring May 21 '16 at 14:34
  • @dvdciri: Indeed, Python is *strongly* typed; types are generally not converted (there are some exceptions where (virtual) subclasses can be converted to parent types, like `int` to `float` in arithmetic mixing those types). This differs from Perl or JavaScript, that try to guess, sometimes with [very confusing results](http://stackoverflow.com/q/8318911). Python requires explicit conversions, use `float()` to convert a string to a floating point number. – Martijn Pieters May 21 '16 at 14:35
  • Okay, sorry @PM2Ring.. Anyway, i'm going to update the question with the new code that is still not working.. thanks for the help – dvdciri May 21 '16 at 14:35
  • @dvdciri: and no, strings are *not* compared by length. They are compared as per *sorting order*. `'Alphabet' < 'Anti'` because `l` sorts before `n` in the alphabet. This is generally known as [lexicographical ordering](https://en.wikipedia.org/wiki/Lexicographical_order). – Martijn Pieters May 21 '16 at 14:37
  • Thanks @MartijnPieters for the explanation, i'm really new to python, i've been working on Java for years and everything seems really restricted and strong with python, but i'll get use to it =) – dvdciri May 21 '16 at 14:37
  • @dvdciri: Java is, if anything, more strongly typed still. – Martijn Pieters May 21 '16 at 14:38
  • That's also true.. anyway can you tell me why is still not working, what am i doing wrong? – dvdciri May 21 '16 at 14:39
  • In your new code you forgot to convert `humidity` and `temperature` to float. – PM 2Ring May 21 '16 at 14:39
  • @dvdciri: you are still comparing `float` with `str` objects. You didn't convert `temperature` or `humidity` to float. Python 2 always sorts numbers before strings, so any `str < float` test is *always* false, any `float < str` test is always true. This is an implementation detail, Python 3 no longer lets you do this and it'll throw an exception instead. – Martijn Pieters May 21 '16 at 14:39

1 Answers1

1

You are comparing strings with floating point numbers.

minTemperature, maxTemperature, minHumidity and maxHumidity are all float objects because you converted them. But temperature and humidity are strings, because otherwise Python would have thrown an exception when you tried concatenating them with other strings.

Compare float to float by converting either in the test:

if float(humidity) > maxHumidity:

etc. or by converting humidity and temperature to floats and converting them back to strings when inserting into Firebase.

In Python 2, different types of objects are always consistently sorted, with numbers coming before other types. This means that < and > comparisons are true or false based on the sort order of the two operands, and since numbers in Python 2 are sorted first, any comparison with another type is done with the number considered smaller:

>>> 3.14 < "1.1"
True

Python 3 does away with trying to make everything orderable; comparing a float to a string gives you a TypeError exception instead.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343