Re: [Tutor] online interactive Py resource?
On 29/11/2018 01:49, Mats Wichmann wrote: > It occurs to me it would be cool to work interactively in a distributed > Internet editing environment that could run Python code. Why not just share your desktop? I assume you trust the person you are mentoring?! I don't recall exactly how you do that but we used it a lot when I was working in a Windows world Netmeeting maybe? -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] writer overloaded
Steve, I read your reply in which you address selected parts of my earlier message. I conclude I am either not writing as clearly as I hoped or your interpretation is sometimes not what I intend. And, I can also be wrong or incomplete! I won't reply in-line or comment much on what I accept or agree with. Your comment about a good reason for the change in error handling makes perfect sense. But it relates to what I said in a way. The sequence of values allowed is a tuple of any length but it there are two or more, it gets ambiguous whether the last one is a special one used as a variable name you assign the particular error to or yet another kind of error. Adding "as" changes the syntax to "tuple [as name]" which is unambiguous and also allows "name" to be a reuse of a name that might otherwise happen to be an Error that wouldn't happen in this context but does exist. My focus is on what I said about Mathematics. I have very specific approaches to what I mean by mathematics and it is a very broad field with many seemingly different kinds which may overlap on careful study but which can each have their own use of concepts and symbols. Yes, mathematics as in routine algebra and geometry has a fairly serious focus on equality, often tautology, especially in higher and more abstract forms as when making proofs step by step. There are related concepts like congruence where you might not use an equals sign or inequalities where you use variants like <=. When a mathematician wants to SET a variable to a value, they often say things like: Given: Y = 5 Or Let Y = 5 when X = 10 be the sides of a rectangle then the Area = X*Y Or other phrases like "assuming" where the meaning remains that the combined expression on either side of the equals sign evaluates to the same thing. (X+1)*(X-1) = X^2 - 1 literally tells you there are at least two ways to say something that are the same no matter what X is. tan(x) =- sin(x)/cos(x) Is the same idea but maybe not exactly for the reason you mention that you can calculate it that way. The definition of the sin(x) is based on a Euclidean right triangle where you have two other angles that are not 90 degrees (or pi/2 radians) and you pick one of those angles and call it x. For each such angle, there are two sides of the triangle that delineate the angle with one being called the "hypotenuse" (the longest one) and one being called "adjacent". I know this is very basic geometry trending into trigonometry but trying to be very clear here. The third side sort of "opposite" the angle is called that. Now the definition of sin(x) is the ratio of opposite/hypotenuse. When the angle is 0, there is no triangle, As it opens up wider toward 90 degrees, the ratio climbs from 0 to as high as 1, asymptotically. At the same time as the opposite side lengthens, the adjacent side gets smaller and the cos(x) is defined as adjacent/hypotenuse and moves from 1 down towards 0. If you define the tangent as opposite/adjacent, it can go towards plus and minus infinity but someone can show that the ratio of: sin(x)/cos(x) = (opposite/hypotenuse)/(adjacent/hypotenuse) the latter part can be converted from a division to a multiplication by using the reciprocal and other allowed mathematical conversions in the context of this algebra. = opposite/hypotenuse * hypotenuse/ adjacent = (opposite*hypotenuse)/(adjacent*hypotenuse) = (opposite/adjacent)*(hypotenuse/hypotenuse) = (opposite/adjacent) + 1 = opposite/adjacent = tan(x) There are many details in the proof above, or similar ones like when you are allowed to use associative or commutative laws because the real numbers over the operators of addition and multiplication form a ring which has been proven to allow the steps above but you get the idea. So, yes, one of many ways to calculate a tangent is to use the sine or cosine for a particular known angle but there are deeper ways such as evaluating enough terms of the right infinite series. I repeat. In most of mathematics "=" means they are equal or assumed to be equal with any assignment taking place sort of off stage. Feel free to disagree on what may be a mostly philosophical point but that is why many places in mathematics do not feel a need for a second operator. I am trying to keep this as "text" since the mailing list does not tolerate rich formats so it is harder to illustrate. But there are mathematical operators that make provisional assignments possible. The upside-down A can be used to mean "for all x" and the backwards E can mean "there exists an x" and there are ways to specify conditions and intended results and so on. So yes, Mathematics as a whole can say the kind of things you want. But generally the way you might say to do something to x and store the results is to introduce a different variable such as x' and then x''. Programming languages definitely need a way to rebind b
Re: [Tutor] online interactive Py resource?
Mats, This may not be a direct answer to your question but I have used more generic tools in a way that might make some sense. You can use a videoconference tool such as SKYPE to connect and have one of you share your screen with the otgher so you can see whatever is open such as an editor they are editing code in and another running python interactively as well as any pop-up windows and so on. You can talk them through things like change the next line ... You can also have part of the screen on which you can do text chat such as sending them some text to paste into their program or even push a download of files or receive them. Not quite the same shared editing experience but there are ways to use something like Google Docs to collaborate and perhaps even set up to run python directly on the remote file or just copy/paste it. Of course, the shared editor would ideally not be a full-blown text processor or even understand python code. There are also ways to take over their computer (with permission) and have it accept your commands as you demonstrate things. I recall a web site I once used in a course that allowed me to crerate and save python code that it ran remotely: http://www.codeskulptor.org/ Each time you save a file, you get a URL like this: http://www.codeskulptor.org/#user45_M9Oefx1vom_0.py If you click on that URL it should show the minor code I made and let you edit it and then I can click and see the change. This being an open forum, multiple people may do so. On that screen, the leftmost small menu item near the top runs the code with output on the right panel. The second saves the current code under the same URKL that you maybe would bookmark. Other controls let you save a local copy, etc. Note there is a version 3 version to use at: https://py3.codeskulptor.org/ Some of these techniques may be helpful for anyone wanting some interaction but I do not claim they handle well having two people edit files at the same time. You can always GIT. Avi -Original Message- From: Tutor On Behalf Of Mats Wichmann Sent: Wednesday, November 28, 2018 8:50 PM To: tutor Subject: [Tutor] online interactive Py resource? I'm going to end up tutoring someone (family member) learning Python in the new year. Look forward to it. It will be a remote arrangement. Haven't trained anyone in the whole picture (as opposed to bits and bobs of possibly helpful advice on demand, like here) since I wrote and delivered a training course for a commercial training company, the last instance of which was pre-historic in tech terms (2002 in calendar terms). That those were very much hands-on, in-person. It occurs to me it would be cool to work interactively in a distributed Internet editing environment that could run Python code. Are there such? There are distributed editing environments, like Etherpad, Gobby, (cough) Google Docs. There are online interactive Python environments, such as the ones from the nice folks at PythonAnywhere. is there something that combines the two? I'm not completely sure PythonAnywhere doesn't have that capability... but I'm looking for some wisdom and experiences (and maybe best practices) from the other tutors around here. cheers, -- mats ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] writer overloaded
On 29/11/2018 02:04, Avi Gross wrote: [another massive snip] Please take this some place else as I see no place on this *TUTOR* list for your ramblings. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Search error code in a logfile and print all lines until the error code
Hi All , I need some help to print error lines from a log file : for example the following logfile : SQL> SQL> SET PAGESIZE 0 SQL> SELECT 'Starting apply for patch 26925263/21857460 on ' || 2 SYSTIMESTAMP FROM dual; Starting apply for patch 26925263/21857460 on 28-JUN-18 07.46.34.893957 PM -05:00 1 row selected. SQL> SET PAGESIZE 10 SQL> SQL> BEGIN 2 dbms_sqlpatch.patch_initialize(p_patch_id => 26925263, 3 p_patch_uid => 21857460, 4 p_flags => '&flags', 5 p_description => '&description', 6 p_action=> 'APPLY', 7 p_logfile => '&full_logfile', 8 p_bundle_series => '&bundle_series'); 9 END; 10 / BEGIN * ERROR at line 1: ORA-20001: set_patch_metadata not called ORA-06512: at "SYS.DBMS_SQLPATCH", line 647 ORA-06512: at line 2 SQL> SQL> COLUMN install_file NEW_VALUE sql_script SQL> SQL> SQL> ALTER SESSION SET CURRENT_SCHEMA = SYS; Session altered. So here I want to open the log file and find the error and print all the lines from starting till the error : ORA-20001: set_patch_metadata not called f4 = open (r"file1.log", 'r') string2=f4.readlines() for i in range(len(string2)): position=i lastposition =position+1 while True: if re.search('ORA-20001: set_patch_metadata not called',string2[lastposition]): break elif lastposition==len(string2)-1: break else: lastposition += 1 errorcheck=string2[position:lastposition] print errorcheck It gives me error : IOPub data rate exceeded. The notebook server will temporarily stop sending output to the client in order to avoid crashing it. To change this limit, set the config variable `--NotebookApp.iopub_data_rate_limit`. Current values: NotebookApp.iopub_data_rate_limit=100.0 (bytes/sec) NotebookApp.rate_limit_window=3.0 (secs) the first for loop will search for the error and provide me the position of the error . I think the logic I am using is correct but need some expert comment to make it work also some guidance on how to print all the lines until the error is received . Please advice, -- Asad Hasan +91 9582111698 ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Trouble about creating database
I can't create a database even tough I imported pymysql. I have Xammp on my Mac and I already started MySQL Database. What could be the problem? Thanks have a nice day. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Trouble about creating database
On 29/11/2018 09:24, Muhammed Esen wrote: I can't create a database even tough I imported pymysql. I have Xammp on my Mac and I already started MySQL Database. What could be the problem? Thanks have a nice day. Please help us to help you by providing a small code snippet that reproduces the problem and either the complete traceback or the error message. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Trouble about creating database
On 29/11/2018 09:24, Muhammed Esen wrote: > I can't create a database even tough I imported pymysql. I have Xammp on my > Mac and I already started MySQL Database. What could be the problem? Just about anything since you haven't shown us your code. It could be a syntax error, a problem with arguments to one of the functions, an access control error with passwords etc A network or server problem, etc... We can't begin to guess unless you show us the code you used and the full error message.. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Search error code in a logfile and print all lines until the error code
On 29/11/2018 12:53, Asad wrote: > Hi All , > > I need some help to print error lines from a log file : I don;t have time right now for a detailed analysis but there are some obvious starting points: > f4 = open (r"file1.log", 'r') > string2=f4.readlines() > for i in range(len(string2)): Its usually easier to just use for line in f4: process line here... > position=i > lastposition =position+1 > while True: > if re.search('ORA-20001: set_patch_metadata not > called',string2[lastposition]): You don;t need to use regular expressions for fixed strings. A regular string search will be more efficient. if searchString in line > break > elif lastposition==len(string2)-1: If you uyse the for line in file idiom you don't need this check. The loop will never run off the end. > break That break is not indented so will always exit the loop on the first go round. I'll assume for now its just a typo or email glitch... > else: > lastposition += 1 > errorcheck=string2[position:lastposition] > print errorcheck > I think the logic I am using is correct but need some expert comment to > make it work also some guidance on how to print all the lines until the > error is received . The easiest way to do this is usually to set a flag True when you hit the start line and then false when you hit the end. print while the flag is True for line in file: if isStart(line): flag = True if isEnd(line): flag = False if flag: print line Now write the isStart(line) and isEnd(line) functions and you should be good to go. Sorry if I'm missing something key, as I said I just skimmed this. gotta run, -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Error Python version 3.6 does not support this syntax.
On 11/29/18 12:20 PM, srinivasan wrote: > Dear Python Experts, > > With the below code snippet, I am seeing the below error, I am using > python 3.6, could you please what could be the issue? > self.child = pexpect.spawn("bluetoothctl", echo = False) ... > self.child.send(command + "\n") > time.sleep(pause) > start_failed = self.child.expect(["bluetooth", pexpect.EOF]) ... > return self.child.before.split("\r\n") > ---> > the issue seems to be here > line 27, in get_output > return self.child.before.split("\r\n") > TypeError: a bytes-like object is required, not 'str' your types don't match. it's Python 3 so what you get back from talking to an external process is a bytes object. you're calling the split method on that object, but passing it a string to split on - that's what the error is saying. It shouldn't be any more complicated to fix that than to give it a byte object: return self.child.before.split(b"\r\n") or... decode the object to a str before splitting on a string. but since you're specifically splitting on lines, you may as well use the splitlines method instead of the split method, since that's what it is designed for. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Error Python version 3.6 does not support this syntax.
On 30Nov2018 02:19, srinivasan wrote: Thanks a lot for your quick responses, again the below line seems to be throwing the same error, is that should I again decode the line where am facing the issue to str? or could you please let me if there is any alternative solution for the same or workaround in python 3.6? Code Snippet: def parse_device_info(self, info_string): """Parse a string corresponding to a device.""" device = {} block_list = ["[\x1b[0;", "removed"] string_valid = not any(keyword in info_string for keyword in block_list) ---> Again this line seems to be the same issue [...] def get_paired_devices(self): """Return a list of tuples of paired devices.""" try: out = self.get_output("paired-devices") except BluetoothctlError as e: print(e) return None else: paired_devices = [] for line in out: device = self.parse_device_info(line) [...] Your problem is basicly that reading from command output gets you bytes data, not text (str) data. This is because pipes transfer bytes; that the command may issue text simply means that those bytes are an encoding of the text. Your entire process treats the output as text, because the commands issue textual output. Therefore, the most sensible thing to do at this point is to _decode_ the bytes into text as soon as you get them from the command, and then the rest of your programme can work in text (str) from then on. So I would be inclined to change: for line in out: device = self.parse_device_info(line) into (untested): for line_b in out: line = line_b.decode(errors='replace') device = self.parse_device_info(line) That will turn line_b (a bytes object holding the line) into text before you try to do any parsing. From that point onward, everything is text (str) and you do not need to put any bytes->str stuff elsewhere in your programme. Some remarks: That decode line above uses the default bytes->str decoding, which is 'utf-8'. That is probably how your system works, but if it is not you need to adjust accordingly. If the command ussues pure ASCII you'll be fine regardless. The decode uses "errors='replace'", which means that if the bytes data are _not_ correct UTF-8 encoded text, the decoder will put some replacement characters in the result instead of raising an exception. This simplifies your code, and since you're parsing the output anyway for infomation the replacements should show up to your eye. The default decode mode is 'strict', which would raise an exception on an invalid encoding. Purists might decode the output stream ("out") before the for-loop, but in most encodings including UTF-8, you can split on newlines (byte code 10, ASCII NL) safely anyway, so we just split first and decode each "bytes" line individually. In the loop I deliberately iterate over "line_b", and have the decoded text in "line", instead of doing something like: for line in out: line = line.decode() That way I am always sure that I intend to talk about bytes in one place (line_b) and text (line) in another. Having variable that might contain bytes _or_ text leads to confusion and difficult debugging. The core takeaway here is that you want to keep in mind whether you're working in bytes or text (str). Keep the division clean, that way all you other code can be written appropriately. So: the command pipe output is bytes. COnvert it to text before passing to your text parsing code. That way all the parsing code can work in text (str) and have no weird conversion logic. Cheers, Cameron Simpson ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Error Python version 3.6 does not support this syntax.
Dear Python Experts, With the below code snippet, I am seeing the below error, I am using python 3.6, could you please what could be the issue? Code Snippet: --- import time import pexpect import subprocess import sys class BluetoothctlError(Exception): """This exception is raised, when bluetoothctl fails to start.""" pass class Bluetoothctl: """A wrapper for bluetoothctl utility.""" def __init__(self): out = subprocess.check_output("rfkill unblock bluetooth", shell = True) self.child = pexpect.spawn("bluetoothctl", echo = False) def get_output(self, command, pause = 0): """Run a command in bluetoothctl prompt, return output as a list of lines.""" self.child.send(command + "\n") time.sleep(pause) start_failed = self.child.expect(["bluetooth", pexpect.EOF]) if start_failed: raise BluetoothctlError("Bluetoothctl failed after running " + command) return self.child.before.split("\r\n") ---> the issue seems to be here def start_scan(self): """Start bluetooth scanning process.""" try: out = self.get_output("scan on") except BluetoothctlError as e: print(e) return None if __name__ == "__main__": print("Init bluetooth...") bl = Bluetoothctl() print("Ready!") bl.start_scan() print("Scanning for 10 seconds...") for i in range(0, 10): print(i) time.sleep(1) Error Logs: - /home/srinivasan/Downloads/bt_tests/qa/venv/bin/python /home/srinivasan/Downloads/bt_tests/qa/test_library/bt_tests.py Init bluetooth... Ready! Traceback (most recent call last): File "/home/srinivasan/Downloads/bt_tests/qa/test_library/bt_tests.py", line 169, in bl.start_scan() File "/home/srinivasan/Downloads/bt_tests/qa/test_library/bt_tests.py", line 32, in start_scan out = self.get_output("scan on") File "/home/srinivasan/Downloads/bt_tests/qa/test_library/bt_tests.py", line 27, in get_output return self.child.before.split("\r\n") TypeError: a bytes-like object is required, not 'str' Process finished with exit code 1 On Wed, Nov 28, 2018 at 12:17 AM Mats Wichmann wrote: > > On 11/27/18 5:50 AM, srinivasan wrote: > > Dear Python Experts, > > > > As still I am newbie and learning python, I am trying to reuse the > > Bluetoothctl wrapper in Python from the link ( > > https://gist.github.com/egorf/66d88056a9d703928f93) I am using python3.6 > > version, In pycharm editor on the bold highlighted code snippets I see the > > error message "Python version 3.6 does not support this syntax.", > > once again you've posted in a way that inserts lots of extra crud, you > avoided that last time. > > The syntax change is simple (and works on most older Pythons too): > > except ErrorType, e: > > becomes > > except ErrorType as e: > > > > > > Could you please how help me how the below highlighted lines of code can be > > can be ported to python3.6 version? > > > > *except BluetoothctlError, e:* > > > > *print(e)* > > *return None* > > ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Error Python version 3.6 does not support this syntax.
Dear Mats, Thanks a lot for your quick responses, again the below line seems to be throwing the same error, is that should I again decode the line where am facing the issue to str? or could you please let me if there is any alternative solution for the same or workaround in python 3.6? Code Snippet: def parse_device_info(self, info_string): """Parse a string corresponding to a device.""" device = {} block_list = ["[\x1b[0;", "removed"] string_valid = not any(keyword in info_string for keyword in block_list) ---> Again this line seems to be the same issue if string_valid: try: device_position = info_string.index("Device") except ValueError: pass else: if device_position > -1: attribute_list = info_string[device_position:].split(" ", 2) device = { "mac_address": attribute_list[1], "name": attribute_list[2] } return device def get_paired_devices(self): """Return a list of tuples of paired devices.""" try: out = self.get_output("paired-devices") except BluetoothctlError as e: print(e) return None else: paired_devices = [] for line in out: device = self.parse_device_info(line) if device: paired_devices.append(device) return paired_devices if __name__ == "__main__": print("Init bluetooth...") bl = Bluetoothctl() print("Ready!") bl.start_scan() print("Scanning for 10 seconds...") for i in range(0, 10): print(i) time.sleep(1) bl.pair("64:A2:F9:06:63:79") print("Pairing for 10 seconds...") for i in range(0, 10): print(i) time.sleep(1) # Seems to be an issue -- bl.get_paired_devices() print("Getting Paired devices for 10 seconds...") for i in range(0, 10): print(i) time.sleep(1) Error Logs: Traceback (most recent call last): , in parse_device_info string_valid = not any(keyword in info_string for keyword in block_list) File "/home/srinivasan/Downloads/bt_tests/qa/test_library/bt_tests.py", line 52, in string_valid = not any(keyword in info_string for keyword in block_list) TypeError: a bytes-like object is required, not 'str' On Fri, Nov 30, 2018 at 1:18 AM Mats Wichmann wrote: > > On 11/29/18 12:20 PM, srinivasan wrote: > > Dear Python Experts, > > > > With the below code snippet, I am seeing the below error, I am using > > python 3.6, could you please what could be the issue? > > > self.child = pexpect.spawn("bluetoothctl", echo = False) > ... > > self.child.send(command + "\n") > > time.sleep(pause) > > start_failed = self.child.expect(["bluetooth", pexpect.EOF]) > ... > > return self.child.before.split("\r\n") > > ---> > > the issue seems to be here > > line 27, in get_output > > return self.child.before.split("\r\n") > > TypeError: a bytes-like object is required, not 'str' > > your types don't match. it's Python 3 so what you get back from talking > to an external process is a bytes object. you're calling the split > method on that object, but passing it a string to split on - that's what > the error is saying. It shouldn't be any more complicated to fix that > than to give it a byte object: > > return self.child.before.split(b"\r\n") > > or... decode the object to a str before splitting on a string. > > but since you're specifically splitting on lines, you may as well use > the splitlines method instead of the split method, since that's what it > is designed for. > > > > > ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Error Python version 3.6 does not support this syntax.
On Fri, Nov 30, 2018 at 02:19:25AM +0530, srinivasan wrote: > Dear Mats, > > Thanks a lot for your quick responses, again the below line seems to > be throwing the same error, is that should I again decode the line > where am facing the issue to str? or could you please let me if there > is any alternative solution for the same or workaround in python 3.6? You don't need a "workaround", you need to fix the bug in your code: > Traceback (most recent call last): > , in parse_device_info > string_valid = not any(keyword in info_string for keyword in block_list) > File "/home/srinivasan/Downloads/bt_tests/qa/test_library/bt_tests.py", > line 52, in > string_valid = not any(keyword in info_string for keyword in block_list) > TypeError: a bytes-like object is required, not 'str' You get that error when you wrongly try to test for a string inside a bytes object: py> 'string' in b'bytes' Traceback (most recent call last): File "", line 1, in TypeError: a bytes-like object is required, not 'str' You fix that by making sure both objects are strings, or both are bytes, which ever is better for your program: py> 'a' in 'abc' # string in string is okay True py> b'a' in b'abc' # bytes in bytes is okay True py> 'a' in b'abc' # string in bytes is NOT OKAY Traceback (most recent call last): File "", line 1, in TypeError: a bytes-like object is required, not 'str' py> b'a' in 'abc' # bytes in string is NOT OKAY Traceback (most recent call last): File "", line 1, in TypeError: 'in ' requires string as left operand, not bytes Don't mix strings and bytes. It won't work. -- Steve ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor