ryanjg80
Posts: 7
Joined: Wed Jun 10, 2020 4:18 am

Newbie's code works in IDLE but not python

Mon Jun 29, 2020 11:09 pm

I've tried a bunch of different things but I'm having a few problems. 2 issues...
1 - The following code runs just fine in IDLE and Pycharm on my PC (except the GPIO parts, of course) but when run in python, the string manipulation parts don't function as intended. (See comments in code)
2 - I tried using GPIO.cleanup() under an eventually: in the try: loop. It says nothing to clean up. However, without it, the second time I run this it says channels are in use. I cheated and added a GPIO.setwarnings(False) in, but I'd like to know how to avoid that.

Any help would be GREATLY appreciated!

Code: Select all

import RPi.GPIO as GPIO
import time
from datetime import datetime

in1 = 16
in2 = 18

GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
GPIO.setup(in1, GPIO.OUT)
GPIO.setup(in2, GPIO.OUT)

GPIO.output(in1, True)
GPIO.output(in2, True)

mem_num = ""
valid_card = False
mem_file = open("members.txt", "r")
mem_list = mem_file.readlines()
mem_file.close()

while True:
    try:
        mem_num = input("?")
        if mem_num == "1":
            break
        valid_card = mem_num.startswith("VHA1")
       #The following line seems to be where my trouble is.
        mem_num = str(mem_num.replace("VHA100", ""))
        #Any valid card scanned start withs 'VHA100'. The following line
        #in Python returns the entire original string, including the 'VHA100' prefix.
        print(mem_num)
        if (mem_num + "\n") in mem_list and valid_card:
            print("Valid")
            GPIO.output(in1, False)
            GPIO.output(in2, False)
            time.sleep(.5)
            GPIO.output(in1, True)
            GPIO.output(in2, True)
            
    except Exception as err:
        now = datetime.now()
        dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
        print (err, "***", dt_string)
I know my error-trapping is terrible, but I wasn't sure what Exceptions to look for, so I figured I'd add them as they popped up.

pidd
Posts: 257
Joined: Fri May 29, 2020 8:29 pm
Location: Wirral, UK

Re: Newbie's code works in IDLE but not python

Tue Jun 30, 2020 3:02 am

Must be something funny getting scanned on the input, try partially filtering one extra character at a time.

Code: Select all

mem_num = str(mem_num.replace("V", ""))
then

Code: Select all

mem_num = str(mem_num.replace("VH", ""))
etc

and see what happens.

Or try casting the input to a string to make sure it is (I don't know python, this might need changing)

Code: Select all

 mem_num = str(input("?"))

ryanjg80
Posts: 7
Joined: Wed Jun 10, 2020 4:18 am

Re: Newbie's code works in IDLE but not python

Tue Jun 30, 2020 4:13 am

First suggestion didn't work. The type should automatically be string. The only reason I added a type conversion is because the code did not work as expected, but for debugging purposes, I tried type(mem_num) and it returned string.

pidd
Posts: 257
Joined: Fri May 29, 2020 8:29 pm
Location: Wirral, UK

Re: Newbie's code works in IDLE but not python

Tue Jun 30, 2020 4:27 am

I guessed you had put the str() in out of desperation but then I wondered if the result was all number whether it could be auto-casted as an integer.

The code seems fine, it must be something strange with the input string, possibly the old utf8/ascii/iso. problems?

ryanjg80
Posts: 7
Joined: Wed Jun 10, 2020 4:18 am

Re: Newbie's code works in IDLE but not python

Tue Jun 30, 2020 5:26 am

I don’t know about old problems. How do I fix it?
Every card scanned in the testing phase returned a string with the type() test. If it didn’t return a string (because it was completely numerical) it’s supposed to fail the validation anyway, hence the valid_card boolean test. I’m at a loss.

hippy
Posts: 7433
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: Newbie's code works in IDLE but not python

Tue Jun 30, 2020 11:55 am

ryanjg80 wrote:
Mon Jun 29, 2020 11:09 pm
The following code runs just fine in IDLE and Pycharm on my PC (except the GPIO parts, of course) but when run in python, the string manipulation parts don't function as intended. (See comments in code)
You don't say what results you are getting. You could try with simpler code - This works for me; enter VHA100123 and it prints 123 etc -

Code: Select all

while True:
  mem_num = input("?")
  if mem_num == "1":
    break
  mem_num = mem_num.replace("VHA100", "")
  print(mem_num)
Maybe you aren't running with Python 3 ? If run with Python 2 it will error with some rather peculiar error messages -

Code: Select all

pi@Pi3B:~/tmp $ python2 test.py
?VHA100123
Traceback (most recent call last):
  File "y.py", line 2, in <module>
    mem_num = input("?")
  File "<string>", line 1, in <module>
NameError: name 'VHA100123' is not defined
Or, with your error trapping -

Code: Select all

pi@Pi3B:~/tmp $ python2 y.py 
?VHA100123
(NameError("name 'VHA100123' is not defined",), '***', '30/06/2020 12:53:31')
If that's what you're seeing; run with "python3" rather than "python".

ryanjg80
Posts: 7
Joined: Wed Jun 10, 2020 4:18 am

Re: Newbie's code works in IDLE but not python

Tue Jun 30, 2020 4:16 pm

I did say in the in the code comment that I’m getting the original string back, not the manipulated one I’m looking for. The scanner inputs “VHA1000123”. I want to get back only the last 4 characters of that, but it’s still returning the entire original string. I’m not getting any error messages (now that I’ve suppressed the GPIO ones). As far as the version of python, how do I know which I’m running? If it’s a matter of updates, these are very new installs, and I’ve run ‘sudo apt update’ on them recently.

pcmanbob
Posts: 9279
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: Newbie's code works in IDLE but not python

Tue Jun 30, 2020 5:28 pm

I took your posted code and stripped out most of it leaving just the bit that asks for input and does the string replacement.

Code: Select all

import RPi.GPIO as GPIO
import time
from datetime import datetime

while True:
    try:
        mem_num = input("?")
        if mem_num == "1":
            break
        valid_card = mem_num.startswith("VHA1")
       #The following line seems to be where my trouble is.
        mem_num = str(mem_num.replace("VHA100", ""))
        #Any valid card scanned start withs 'VHA100'. The following line
        #in Python returns the entire original string, including the 'VHA100' prefix.
        print(mem_num)

            
    except Exception as err:
        now = datetime.now()
        dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
        print (err, "***", dt_string)
        
I saved this as ryan.py and then ran it from the command line with

Code: Select all

python3 ryan.py
and this was the output from this code

pi@BusterPi:~ $ python3 ryan.py
?VHA1000234
0234
?VHA1000123
0123
?VHA1001234
1234
?
So to me it looks like it works just fine......

as for which python your are running the code under,

python = python2
python3 = python3
We want information… information… information........................no information no help
The use of crystal balls & mind reading are not supported

User avatar
B.Goode
Posts: 10163
Joined: Mon Sep 01, 2014 4:03 pm
Location: UK

Re: Newbie's code works in IDLE but not python

Tue Jun 30, 2020 5:30 pm

ryanjg80 wrote:
Tue Jun 30, 2020 4:16 pm
I did say in the in the code comment that I’m getting the original string back, not the manipulated one I’m looking for. The scanner inputs “VHA1000123”. I want to get back only the last 4 characters of that, but it’s still returning the entire original string. I’m not getting any error messages (now that I’ve suppressed the GPIO ones). As far as the version of python, how do I know which I’m running? If it’s a matter of updates, these are very new installs, and I’ve run ‘sudo apt update’ on them recently.

New installs of what?

The IDLE IDE is not installed by default in any of the 3 variants of the 2 most recent releases of the RasPiOS Buster Operating System.



The IDLE IDE is written in, and invokes, the Python2 interpreter. When you start IDLE it tells you what version of Python it is using as the very first line on the default Python Shell window. When you start the Python interpreter from a shell (command line) prompt it will give the same information -

Code: Select all

pi@RPi3BplusOffice:~ $ python
Python 2.7.13 (default, Sep 26 2018, 18:42:22)
[GCC 6.3.0 20170516] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
Last edited by B.Goode on Tue Jun 30, 2020 5:38 pm, edited 1 time in total.

ghp
Posts: 1487
Joined: Wed Jun 12, 2013 12:41 pm
Location: Stuttgart Germany
Contact: Website

Re: Newbie's code works in IDLE but not python

Tue Jun 30, 2020 5:34 pm

To check python version, place the snippet at the top of your file.

Code: Select all

import sys

print (sys.version)
assert sys.version_info >= (3, 7)

hippy
Posts: 7433
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: Newbie's code works in IDLE but not python

Tue Jun 30, 2020 7:12 pm

ryanjg80 wrote:
Tue Jun 30, 2020 4:16 pm
I did say in the in the code comment that I’m getting the original string back, not the manipulated one I’m looking for. The scanner inputs “VHA1000123”. I want to get back only the last 4 characters of that, but it’s still returning the entire original string. I’m not getting any error messages (now that I’ve suppressed the GPIO ones).
Maybe post a complete transcript of you starting the code, entering your input and getting back the results because it works for me and for pcmanbob. There's no obvious reason why it's not working for you.

There's no reason mem_num = str(mem_num.replace("VHA100", "")) would not remove the "VHA100" from your string unless that "VHA100" isn't actually in the string, even though it may appear to be there when printed on screen.

From "The scanner inputs" I am guessing you aren't typing in at the command line, but receiving from some other device ?

If so that might be introducing non-printable, invisible, characters into the string.

Perhaps add this immediately after your mem_num = input("?") ...

Code: Select all

        for n in range(len(mem_num)):
           print(str(n) + " : " + hex(ord(mem_num[n])))
That will show exactly what's in each string being input, may give a clue.

One final thought: It's not an 'oh' instead of 'zero' or 'ell' for 'one', or vice-versa, issue is it?

pidd
Posts: 257
Joined: Fri May 29, 2020 8:29 pm
Location: Wirral, UK

Re: Newbie's code works in IDLE but not python

Tue Jun 30, 2020 8:30 pm

hippy wrote:From "The scanner inputs" I am guessing you aren't typing in at the command line, but receiving from some other device ?

If so that might be introducing non-printable, invisible, characters into the string.

I came to the same conclusion as you, there must be something hiding in the input string. I was wondering if the scanner outputs utf8 or something but I haven't got the knowledge of Python to know how that deals with other character sets and I haven't got the correct words to describe it other than saying multi-byte.

hippy
Posts: 7433
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: Newbie's code works in IDLE but not python

Wed Jul 01, 2020 2:58 pm

pidd wrote:
Tue Jun 30, 2020 8:30 pm
I came to the same conclusion as you, there must be something hiding in the input string.
However, and I had forgotten about this -
ryanjg80 wrote:
Mon Jun 29, 2020 11:09 pm
The following code runs just fine in IDLE and Pycharm on my PC (except the GPIO parts, of course) but when run in python, the string manipulation parts don't function as intended.
I'm not sure what would be causing 'input()' to return something different in IDLE and PyCharm and when run from the command line. That just adds to the mystery rather than solves anything.

It could be input data is being typed in when run in IDLE or PyCharm is coming from the scanner device when run at the command line.

pidd
Posts: 257
Joined: Fri May 29, 2020 8:29 pm
Location: Wirral, UK

Re: Newbie's code works in IDLE but not python

Wed Jul 01, 2020 3:31 pm

hippy wrote:
pidd wrote:
Tue Jun 30, 2020 8:30 pm
I came to the same conclusion as you, there must be something hiding in the input string.
However, and I had forgotten about this -
ryanjg80 wrote:
Mon Jun 29, 2020 11:09 pm
The following code runs just fine in IDLE and Pycharm on my PC (except the GPIO parts, of course) but when run in python, the string manipulation parts don't function as intended.
I'm not sure what would be causing 'input()' to return something different in IDLE and PyCharm and when run from the command line. That just adds to the mystery rather than solves anything.

It could be input data is being typed in when run in IDLE or PyCharm is coming from the scanner device when run at the command line.
My lack of knowledge of Python means I would not know, but it doesn't seem unreasonable that a later version of a language had improved character set handling and now allows say UTF8 in an input instead of filtering it to ASCII? I avoid anything to do with character sets, life is complicated enough.

hippy
Posts: 7433
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: Newbie's code works in IDLE but not python

Wed Jul 01, 2020 4:55 pm

pidd wrote:
Wed Jul 01, 2020 3:31 pm
My lack of knowledge of Python means I would not know, but it doesn't seem unreasonable that a later version of a language had improved character set handling and now allows say UTF8 in an input instead of filtering it to ASCII? I avoid anything to do with character sets, life is complicated enough.
Absolutely agree with that last sentence. Annoyingly Python 3 often means one has to. I've been battling those issues for the last few days when porting Python 2 code which handles 8-bit data bytes via serial to Python 3.

I'm also not familiar with 'input()', IDLE or PyCharm. It could be a version issue but I was under the impression that those Python IDE's use the system installed version/sub-versions rather than their own versions. That doesn't mean there can't be version/sub-version issues but it would surprise me if that.

dbrion06
Posts: 56
Joined: Tue May 28, 2019 11:57 am

Re: Newbie's code works in IDLE but not python

Wed Jul 01, 2020 5:09 pm

w/r python version:
the command line

Code: Select all

python --version
gives the version (one can mess up python 3 and 2...)

w/r encoding:

http://sametmax.com/lencoding-en-python ... our-toute/ (sorry, it is in colloquial French) advises
a) to begin each python script, whatever the version, with the following line:

Code: Select all

# coding: utf-8 
(this is the default verion for python3, but NOT with python2
b) every chain should be prefixed with u ex: u"VIHCOVID" works with python 3.8.1 and python 2.6.6 (likely between)
c) every input should be decoded in python2 (does not work with python3) ex:

Code: Select all

Python 2.6.6 (r266:84292, Jun 20 2019, 14:14:55)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-23)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> input("?").decode('utf8')
?"salut à tous"
u'salut \xe0 tous'

ryanjg80
Posts: 7
Joined: Wed Jun 10, 2020 4:18 am

Re: Newbie's code works in IDLE but not python

Wed Jul 01, 2020 8:35 pm

I ran the code using python3. It worked! I had no idea there were different versions. I am indeed using a barcode scanner for the input. I apologize for not supplying enough information.

So, first problem solved. Now what about the GPIO stuff? I’m currently cheating by suppressing the warnings, but how would I properly use GPIO.cleanup()?

hippy
Posts: 7433
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: Newbie's code works in IDLE but not python

Wed Jul 01, 2020 8:48 pm

ryanjg80 wrote:
Wed Jul 01, 2020 8:35 pm
Now what about the GPIO stuff? I’m currently cheating by suppressing the warnings, but how would I properly use GPIO.cleanup()?
Just put that at the end of the code though I wouldn't worry about it, would just keep using GPIO.setwarnings(False).

In fact, having multiple programs running using RPi.GPIO, I find calling GPIO.cleanup() causes more problems than it solves so I never use it. YMMV.

ryanjg80
Posts: 7
Joined: Wed Jun 10, 2020 4:18 am

Re: Newbie's code works in IDLE but not python

Thu Jul 02, 2020 4:53 am

Got it! I’ll just leave well enough alone. Thank you all so much for your help! When I get some more time to toy around with it, I’ll add the string testing functions posted earlier and run it in Python (not 3) just to help clear up the mystery. I’m actually a bartender. Wrote this code to validate cards at a private club where I work. Definitely worth the time and effort now that I don’t have to stop what I’m doing to press a button to let someone in.

dbrion06
Posts: 56
Joined: Tue May 28, 2019 11:57 am

Re: Newbie's code works in IDLE but not python

Thu Jul 02, 2020 1:40 pm

run it in Python (not 3) just to help clear up the mystery
You should keep with python3: things are likely to get worse and worse with python2 (the same way migrating from hoses driven cars to fuel cars made things terrible for horse drivers): new stuff -ex : within 5 years, a better card reader will, may be , exist -will get only python3 support : manufacturers have no time for python 2....

ryanjg80
Posts: 7
Joined: Wed Jun 10, 2020 4:18 am

Re: Newbie's code works in IDLE but not python

Fri Jul 03, 2020 6:40 am

Oh no. I will continue to use Python3 to run the system. I meant to solve the mystery surrounding this, I’ll add those functions to the string input by the scanner and run in on my system at home. I don’t want to leave anyone hanging if they’re curious.

Return to “Python”