Is something wrong with My Python 3.3.2? - python

When using Python 3.3.2 shell
>>> temperature = 70
>>> if temperature > 60 and temperature < 75:
print ("Just right!!")
else:
SyntaxError: invalid syntax
>>>
what am I doing wrong?? This happen ever time after I type "else:" and press enter. Im stuck

You need to indent your code properly:
>>> temperature = 70
>>> if temperature > 60 and temperature < 75:
... print('Just right!')
... else:
... print('Oh no!')
...
Just right!
When you indent it properly the ... will automatically show up (so don't type those in).
Unlike most languages, in Python indentation is important. It is how the Python interpreter indentifies blocks of code. You might hear the phrase "whitespace is significant", it means the same thing. whitespace means things you type that don't print (like spaces, the tab character, etc).
So you should always line up the identifier of blocks of code (lines that end with :) at the left margin. It is not important how many spaces you indent the body of these blocks of code (in your example, the print function is in the body of the if statement). As long as there is one space, Python will work. However, the standard is to use 4 spaces; so better get into the habit putting four spaces whenever you want to indent code.

The else: statement needs to be at the same level of indentation as the if: statement that it refers to.
>>> temperature = 70
>>> if temperature > 60 and temperature < 75:
... print ("Just right!!")
... else:
... print ("Oh noes.")
...
Just right!!
This is correct behaviour - otherwise Python wouldn't know what an else: statement is referring to:
>>> if True:
... if False:
... print("Wha?")
... else:
... print("Yay.")
... else:
... print("Huh?")
...
Yay.

You don't even need "else" after your condition. You might need it if you want to print additional info if first condition is not met
temperature = 70
if temperature > 60 and temperature < 75:
print("Just right!!")

Like others have said, you don't need the else statement if you don't want to do anything with the else case.
But, if you want to have an else statement but doesn't want to do anything, you can put pass statement:
>>> temperature = 70
>>> if 60 < temperature < 75:
... print ("Just right!!")
... else:
... pass
...
Just right!!
>>>

Related

Python - How to count how many If/Else statements exist

I want to count how many If/Else statements are in my function.
My code looks like this:
def countdown(type):
if type == 1:
//code
elif type == 2:
//code
else:
print(f"You have reached the end of the script. "
f"The maximum type of countdowns are: {x}")
exit(1)
Where the x is, there should be the number of if queries (If/Else). In this case, there are 3 queries. It should serve that if I create another if/else query within this function, I don't have to change the warning at the bottom of the script.
Is that even possible?
I'm using Python 3.10
Don't use if..else, but a dict or list:
types = {
1: ...,
2: ...
}
try:
types[type]
except KeyError:
print(f"You have reached the end of the script. "
f"The maximum type of countdowns are: {len(types)}")
exit(1)
What exactly to put into the dict as values depends… Can you generalise the algorithm so you just need to put a value into the dict instead of actual code? Great. Otherwise, put functions into the dict:
types = {1: lambda: ..., 2: some_func, 3: self.some_method}
...
types[type]()
Since you are using Python 3.10 you can use a new match operator. An example:
def countdown(type):
match type:
case 1:
# code
case 2:
# code
case _:
print(f"You have reached the end of the script. "
f"The maximum type of countdowns are: {x}")
exit(1)
As for me, it is a more readable solution than a dict one.
What about counting the number of options, let's consider that we have n different and logically separated options. In this case, I'd advise you an enum:
from enum import IntEnum
class CountdownOption(IntEnum):
FIRST = 1
SECOND = 2
# ...
# ...
def countdown(type):
match type:
case CountdownOption.FIRST:
# code
case CountdownOption.SECOND:
# code
case _:
print(f"You have reached the end of the script. "
f"The maximum type of countdowns are: {len(CountdownOption)}")
exit(1)

if statement, print additional column in python

i am new to pythin and trying to work out an if statement for some data being collected.
import grovepi
import time
import datetime
import grovelcd
#headerline
print ("Time,Noise (db),Light (lux),Temperature (C),Humidity (rH)")
here i have the already existing header lines for when they are printed into a csv file.I want another displaying the information i outline below.
while True:
timestamp=time.time()
#read from a analog sensor on input 1
d= grovepi.analogRead(1)
#read from an analog sensor on input 2
a= grovepi.analogRead(2)
#read from an digital sensor on input 3
(t,h)=grovepi.dht(3,0)
above is the reading of each sensor
print ("%f,%d,%d,%f,%f"%(timestamp,d,a,t,h))
What i would like is an additional value, i am having issues getting an if statement to take the value and determine if it matches what i want. All these should be number values.
the idea i have is
if t > 35:
print("Warning")
if h > 50:
print("Warning")
if n > 75:
print("Warning")
else:
print("OK")
Essentially what i have looks like this output:
Noise Light Temperature Humidity
85 500 34 76
What im trying to achieve is this:
Noise Light Temperature Humidity Note
85 500 34 76 OK
Any help appreciated, i dont know python very well unfortunately.
If you want to print an extra column, like "1234567890,34.3,51.2,70.3,Warning" then you can do it with a simple boolean variable, like this:
while True:
...
warning = t > 35 or h > 50 or n > 75
print ("%f,%d,%d,%f,%f,%s" % (
timestamp, d, a, t, h, "Warning" if warning else "OK"
))
Above, I've defined warning as a boolean condition, and used if for the inline if operator to print either "Warning" or "OK".
If you need extra flexibility you can assign to a string variable:
while True:
...
# Note, only message for the first matching condition would display
if t > 35:
message = "Warning: T"
elif h > 50:
message = "Warning: H"
elif n > 75:
message = "Warning: N"
else:
message = "OK"
print ("%f,%d,%d,%f,%f,%s" % (timestamp, d, a, t, h, message))
And if you need to display multiple messages, you can collect a list, like this:
while True:
...
warnings = []
if t > 35:
warnings.append("WarnT")
if h > 50:
warnings.append("WarnH")
...
status = " ".join(warnings) if warnings else "OK"
print ("%f,%d,%d,%f,%f,%s" % (timestamp, d, a, t, h, status))
This would collect all warnings in a list (so it would be like ["WarnT", "WarnH"]), then if the list is not empty join with spaces (" ".join(warnings)) so it'll be "WarnT WarnH", and otherwise use "OK" as the message. Tune the output as you feel appropriate.
Hope this helps.
(BTW, you may consider using something like %0.2f instead of %f if you want a fixed number of digits. I believe you'd probably want to round to a sane precision, e.g. "59.03" instead of something like "59.031045032")

How can I control a fan with GPIO on a Raspberry Pi 3 using Python?

I am trying to basically write a simple script that will tell the fan (plugged into pin 4 on the GPIO) to turn on at a certain temp, and if anything less, turn the fan off. I am starting with something simple just to see if I can control the fan based on temperature. Here is what I have so far:
import os
from time import sleep
import signal
import sys
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(4, GPIO.OUT)
temp = os.popen('vcgencmd measure_temp').readline()
if temp > 65:
GPIO.output(4, True)
else:
GPIO.output(4, False)
When I run this, it either appears to run but the fan doesn't turn off even though the temp hasn't nearly reached the level I wrote, or it will tell me that the pin is already in use but it will continue anyways. Either way, the fan still runs regardless of current temp.
vgencmd returns as:
temp-37.0'C
How would I remove the non-numerical characters so I am stuck with an int? When I execute it I get this:
ValueError: invalid literal for int() with base 10: "temp=37.6'C\n"
NOTE: Some of the imported modules aren't in use yet, that's why they are there.
You're very close. These two lines are problematic:
temp = os.popen('vcgencmd measure_temp').readline()
if temp > 65:
Here, temp is a string. You need to convert temp to an integer before trying to compare it against an integer. Assuming the line you're reading is just a decimal string corresponding to some temperature, you simply call int(), like this:
temp = os.popen('vcgencmd measure_temp').readline()
temp = int(temp)
Update Since you posted the output you're actually trying to parse, we can use regular expressions to match the output, with the re module. We'll also put this in a function:
def measure_temp():
raw = os.popen('vcgencmd measure_temp').readline()
m = re.match("temp=(\d+\.?\d*)'C", raw)
if not m:
raise ValueError("Unexpected temperature string: " + raw)
return float(m.group(1))
temp = measure_temp()
Note that I used a capture group around the actual temperature decimal in the string, and accessed it using m.group(1).
Let's put it together now. Also, when your code isn't doing what you expect, it is extremely helpful to include some "debug prints", like this:
def measure_temp():
raw = os.popen('vcgencmd measure_temp').readline()
m = re.match("temp=(\d+\.?\d*)'C", raw)
if not m:
raise ValueError("Unexpected temperature string: " + raw)
return float(m.group(1))
temp = measure_temp()
print 'Temperature from vcgencmd: {}'.format(temp)
if temp > 65:
print 'Turning on GPIO 4'
GPIO.output(4, True)
else:
print 'Turning off GPIO 4'
GPIO.output(4, False)
Once you get the basics working, there are a few other things you're going to run into:
Your script checks the temperature and toggles the GPIO once. If you want this thing to operate like a thermostat, you're going to need to keep doing these actions, using a while loop.
If your while loop runs very fast, and the temperature fluctuates right around your setpoint (65), you're going to find your code rapidly turning the fan on/off. It may help to add a bit of hysteresis to the system. For example, if you set your home thermostat (heating) to 70 degrees, it may come on at 69, but turn off at 71. Or it may simply not change states if it has already changed states within the last X seconds.
The simplest solution would be to sleep() for a short period of time between checks:
while True: # Loop forever
# Read the current temperature
temp = os.popen('vcgencmd measure_temp').readline()
temp = int(temp)
print 'Temperature from vcgencmd: {}'.format(temp)
# Control the fan
if temp > 65:
print 'Turning on GPIO 4'
GPIO.output(4, True)
else:
print 'Turning off GPIO 4'
GPIO.output(4, False)
# Wait before the next iteration
time.sleep(5)

Else statement executing even the IF statement is TRUE

I have a problem in Python language that is described in a title.
for slovo in slova:
if pygame.mouse.get_pressed()[0] and slovo["rect"].collidepoint(pygame.mouse.get_pos()):
for i in range (len(randRijec)):
if slovo["name"] in randRijec[i]:
if i == 0:
slovo1 = randRijec[i].upper()
prvoSlovo = 1
...
...
else:
pogresnoBrojac += 1
slova.remove(slovo)
So, even this IF statement is true, ELSE statement is being executed! However, else statement should be skipped if the if statement is fulfilled.
How to fix this issue?
p.s. I've had this problem few times before and I was not able to solve it...
You have a mixture of tabs and spaces in your code:
Running cat -A test.py (on Unix) yields
for slovo in slova:$
if pygame.mouse.get_pressed()[0] and slovo["rect"].collidepoint(pygame.mouse.get_pos()):$
for i in range (len(randRijec)):$
if slovo["name"] in randRijec[i]:$
if i == 0:$
slovo1 = randRijec[i].upper()$
prvoSlovo = 1$
^I^I^I^I^I^I...$
^I^I^I^I^I^I...$
else:$
pogresnoBrojac += 1$
slova.remove(slovo)$
The ^I indicate tabs.
Thus, the else block is not being interpreted as being at the indentation level on which it appears to be.
Your python code should never mix tabs and spaces for indentation. You can check that your script is not mixing tabs and spaces by running python -t script.py.
In Python you must commit to using either only spaces or only tabs for indentation. PEP8 recommends spaces-only indentation.
You can convert tabs to spaces using the reindent.py program.
So, even this IF statement is true, ELSE statement is being executed!
I can assure you that this is not what happens.
I notice that in the outline of your code the if is inside a for loop. Make sure that in your actual code the else is not accidentally lined up with the for instead of the if. I've seen this mistake more than once.
In Python, for-else is a valid construct. For example, the following is perfectly valid Python:
for i in range(10):
if i < 100:
pass
else:
print 'In else clause'
When run, this prints out In else clause.
Contrast this with the following, which doesn't print anything when run:
for i in range(10):
if i < 100:
pass
else:
print 'In else clause'
It's a question from a long time ago and I stumbled upon it as I was troubleshooting the very same issue - the solution was actually pretty silly and most probably was also the case - as it's a for loop it iterates through every list element, if even one of those elements doesn't fulfill the if condition, it will automatically trigger the else - pretty self-evident but easy to miss for beginners.
Well at least that was the problem in my case :)
Next solution fixed my problem:
for slovo in slova:
if pygame.mouse.get_pressed()[0] and slovo["rect"].collidepoint(pygame.mouse.get_pos()):
xy = 0
for i in range (len(randRijec)):
if slovo["name"] in randRijec[i]:
xy = 1
if i == 0:
slovo1 = randRijec[i].upper()
prvoSlovo = 1
break
if i == 1:
slovo2 = randRijec[i].upper()
drugoSlovo = 1
break
slova.remove(slovo)
if xy == 0:
pogresnoBrojac += 1
...
...
...
xy = 1
pygame.display.update()
time.tick(value)
So, I have just added that xy counter that makes my code work how it should work. When IF statement is met, xy becomes 1, if IF statement isn't fulfilled, xy is set to 0 and then this "else" statement executes. At the end of the code, xy is set to 1 again to prevent executing this "else" (if xy == 0) block.

Executing Multiple Lines in Python

When Python is first installed, the default setting executes users' code input line-by-line. But sometimes I need to write programs that executes multiple lines at once. Is there a setting in Python where I can change the code execution to one block at once? Thanks
>>> if (n/2) * 2 == n:;
print 'Even';
else: print 'Odd'
SyntaxError: invalid syntax
When I tried to run the above code, I got an invalid syntax error on ELSE
Your indentation is wrong. Try this:
>>> if (n/2) * 2 == n:
... print 'Even'
... else: print 'Odd'
Also you might want to write it on four lines:
>>> if (n/2) * 2 == n:
... print 'Even'
... else:
... print 'Odd'
Or even just one line:
>>> print 'Even' if (n/2) * 2 == n else 'Odd'
One step towards the solution is to remove the semicolon after the if:
if True:; print 'true'; print 'not ok'; # syntax error!
if True: print 'true'; print 'ok'; # ok
You cannot have an else in the same line because it would be ambiguous:
if True: print 't'; if True: print 'tt; else: ... # <- which if is that else for??
It is also clearly stated in the docs that you need a DEDENT before the else statement can start.
Since python 2.5 you can do one line ifs
print ('Even' if n % 2 == 0 else 'Odd')
Still to answer your question you can either:
1. enter the code properly without syntax errors and your blocks will be executed as blocks regardless if they span multiple lines or not, even in interactive shell. See tutorials in dive into python
2. write code in the script and execute that script using either command line or some IDE (idle, eclipse, etc..)
One of the idea behind python is to prefer multiple lines and to aim for uniform formatting of source, so what you try to do is not pythonic, you should not aim to cram multiple statements into single line unless you have a good reason.
print n % 2 == 0 and 'Even' or 'Odd'
:-)

Categories

Resources