Re: [Tutor] smtp project
On So, 2010-01-17 at 15:45 -0500, Kirk Z Bailey wrote: > I am writing a script that will send an email message. This will > run in a windows XP box. The box does not have a smtp server, so > the script must crete not merely a smtp client to talk to a MTA, > it must BE one for the duration of sending the message- then shut > off, we don't need no bloody op0en relays here! Twisted is the obvious choice for a server daemon, but it should be good enough for what you do, too. What you need isn't a "SMTP server", it's a "SMTP sender", which is more like a client than a server in the usual model. As you don't want it to run as a daemon, first consider how you want it to behave if the server (SMTP receiver, the destination or a server that is willing to relay the message) is not responding or responds with an error. A message queue (in terms of days not seconds) is out of the question for a fire-and-forget service like the one you want, so you probably want the transfer synchronously, i.e. somewhere between receiving the user's input (or whatever triggers the script) and the output (or the end of the lifetime of whatever script was triggered). If you're dealing with real users, though, this can mean an unexpected pause of several seconds, depending on how long the delivery takes (or how long it takes to notice it's not going anywhere). This is bad if the user isn't expecting it (zero progress can be interpreted as a freeze). Anyway. Take a look at Twisted or other libraries for SMTP senders or "clients". Actual SMTP servers are mostly concerned with accepting mail via SMTP and doing something with them (if they are capable of relaying, they can also act as SMTP senders, otherwise they probably just deliver the mail locally or forward them to a local message queue for a separate SMTP sender). Hope that helped a bit, Alan Plum ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] get (x)range borders
On Do, 2010-01-28 at 12:16 +0100, spir wrote: > Is there a way to retrieve an (x)range's borders? > (Eg if I want to print out "m..n" instead of "xrange(m, n)".) You mean like this? >>> m = 20 >>> n = 30 >>> a = xrange(m, n) >>> a xrange(20, 30) >>> a[0] 20 >>> a[-1] 29 Please note that the border will always be one step off if you're looking for the values you originally provided: the endpoint is always given as exclusive. If you want to know the step, you probably need to calculate it: >>> a = xrange(20, 30, 2) >>> step = a[1] - a[0] >>> step 2 Cheers, Alan Plum ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] language aid
On Do, 2010-02-04 at 16:11 +, Owain Clarke wrote: > Thanks for your input. I had discounted the idea of a dictionary > because all the keys need to be unique, so whether the key is the > English or non-English word, it couldn't cope with for example "too", > or a similar word in the other language. I recently began writing a word trainer myself. I used YAML files as source, but the problems were the same. If you have word pairs where either word can be duplicate (e.g. "love" as a verb or a noun) you can deal with that by using a list of tuples. words = [] w = ('aimer', 'love') words.append(w) The only problem with this approach is that it's not as easy to use as a dict, but as I was doing a word trainer, it was supposed to be randomly accessed anyway. Cheers, Alan Plum ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] string to list
On Mi, 2010-02-10 at 16:57 +, Owain Clarke wrote: > I would love a really clear explanation of lambda! Generally, lambdas are anonymous functions. In Python specifically, however, they are limited to simple expressions (i.e. only what you can put on the right-hand side of an assignment). myfunction = lambda : is roughly equivalent to: def myfunction(): return (note that the function definition becomes invalid if you leave out the function name, lambdas OTOH don't need to be assigned to a named variable and don't contain a name in their definition) The point here is that the expression is evaluated and the result returned by the lambda, much like the expression following a return statement in a normal function: the equivalent function's body consists of a single return statement with the lambda's body as return value. There's not much to understanding how lambdas work. They just make one-offs easier when all you really want to do is pass a value where a callable is required or if you want to do something like accessing an index or sub-index or member variable of each object in a list (which is what the sorting function's key argument is usually used for). In the case of your code, your lambda was: lambda x: x[0] and lambda x: x[1] If applied to a tuple or list, this works like this: >>> mytuple = ('a','b') >>> l1 = lambda x: x[0] >>> l2 = lambda x: x[1] >>> l1(mytuple) 'a' >>> l2(mytuple) 'b' Hope that helps. Alan Plum ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] os.environ question
Ahoy! On Do, 2009-11-12 at 06:34 +0300, Khalid Al-Ghamdi wrote: > can anyone tell me why on python 2.6 i can enter os.environ and then > get all the items that that pertain to the os while on python 3 you > just get the following: > > with no items? Seems like os.environ has changed a little since Python 2.x. Try this: >>> import os >>> for env in os.environ: ...print('%s: %s' % (env, os.environ[env])) That should do the trick. Cheers, Alan ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Should a beginner learn Python 3.x
Ahoy! On Sa, 2009-11-14 at 20:49 +, Stephen Nelson-Smith wrote: > He's an absolute beginner with no programming experience at all. I > think he might be following 'Python Programming for the Absolute > Beginner", or perhaps some online guides. Should I advise him to > stick with 2.6 for a bit, since most of the material out there will > be for 2.x? Or since he's learning from scratch, should he jump > straight to 3.x In which case what can you recommend for him to work > through - I must stress he has absolutely no clue at all about > programming, no education beyond 16 yrs old, but is keen to learn. It's too early for Python 3.x. He should probably learn Python 2.6 for now, possibly with future imports (though they probably take a bit longer to explain). 3.x will probably cause too many problems for him for now. A lot of the reference material he can find on the web expects 2.x and many of the "cool" libraries aren't quite ported to 3.x yet. That's just confusing. He'll learn about the differences between 2.x and 3.x eventually, but he shouldn't have to worry about it for the time being. Cheers Alan ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Unexpected iterator
On So, 2009-11-15 at 15:12 +, Stephen Nelson-Smith wrote: > > To upack your variables a and b you need an iterable object on the right > > side, which returns you exactly 2 variables > > What does 'unpack' mean? I've seen a few Python errors about packing > and unpacking. What does it mean? Unpacking refers to taking a collection of values and assigning it to a collection of variables. (a,b) = (1,2,3) # this won't work Let's see what it actually means (in pseudo-code): (a,b)[0] = (1,2,3)[0] # a = 1 (a,b)[1] = (1,2,3)[1] # b = 2 (a,b)[2] = (1,2,3)[2] # undefined! = 3 Same goes for the inverse: (a,b,c) = (1,2) # this won't work either in pseudo code: (a,b,c)[0] = (1,2)[0] # a = 1 (a,b,c)[1] = (1,2)[1] # b = 2 (a,b,c)[2] = (1,2)[2] # c = undefined! Basically, just make sure your len(variables) == len(values) before trying to use the unpacking syntax: (a,b,c) = (1,2,3) # this works (a,b) = (1,2) # this works, too Cheers Alan ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] opening a file directly from memory
Dammit. Meant to send this over the list. Sorry, Alan. On Di, 2009-11-17 at 21:33 +, Alan Gauld wrote: > Unices, like Linux have file association tables - but these > are often associated with the desktop environment - KDE, Gnome etc. > Finally for text files you should check the EDITOR and VISUAL > environment variables - although these are increasingly not > used or respected nowadays. I find mimemagic to be quite reliable. File can be silly at times (it routinely diagnoses my python scripts as Java source files). In my gopher server I rely on mimemagic to make an educated guess and only use file(1) as a last resort to find out whether it's a binary file or ASCII text (some gopher clients don't support UTF8). I'm not sure whether mimemagic is also available on other OSes, tho. Cheers Alan ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to get new messages from maildir?
Ahoy! On Di, 2009-11-24 at 23:47 +, chombee wrote: > I'm using the standard mailbox module to read a maildir, but it seems to > be quite difficult to do some simple things. Is there any way to > identify a message as new, unread, unseen or something similar? What > about finding the most recent message? AFAIR, the new (i.e. unread or unseen -- not sure which) messages should be in Maildir/new rather than Maildir/cur. Flags are a bit trickier, because they're simply appended to the file name, so you'd have to check each name in the directory to figure that out. Don't get me started on how subfolders are implemented in Maildir. > My aim is to write a program that will print out the From: and Subject: > headers of new (or unread, or unseen, whatever I can get) messages, in > chronological order. Or failing that, just print out all messages in > chronological order. The easiest(!) way would be to iterate over the folder, read the headers (i.e. everything up to \r\n\r\n) of each message and parse them. MUAs (Thunderbird, Evolution, Outlook etc) often don't rely on maildirs to store that kind of meta data, they actually parse the maildir once and then store the parsed data locally in a more usable format (i.e. some kind of flat file database). > As far as I can tell there's no way to do the first, and to do the > second you would have to use the date strings in the messages, > converting them to datetimes with strptime first, although on my system > there doesn't seem to be a valid strftime format for python that matches > the date strings in my emails. They end like "+ (GMT)", which I > believe is "%z (%Z)" in strftime, but python will not accept the %z in > the strftime pattern. Dare I say "regular expressions"? Normally, %z should work in strftime, though. Maybe the problem is the " (%Z)" bit -- Python might be using different names than the MDA. Cheers, Alan ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] working with bit arrays
On Mi, 2009-12-02 at 13:08 -0500, Robert Berman wrote: > Hi, > > I am trying to represent a number as a list of bits: for example the > bit representation of the integer 8. I did find a number of articles > pertaining to a module called bitarray but I was unable to > download/install that package. I am using Linux on Ubuntu 9.10; Python > 2.6.2. > > I am almost certain there is a relatively easy way to convert an > integer that can be represented by 32 bits into an array of bits that > I can iterate over looking for switched on bits or switched off bits. If all you want is to treat integers as lists of bits, you could create a wrapper class around an integer and implement the __getitem__ and __setitem__ methods to make it behave like a list. Using the bitwise operators, you could make the setter actually modify the bit in question (you'd probably have to either make sure you only receive 1 or 0 as value or you could simply use booleans instead). For a challenge you could try to extend the built-in integer type this way. I'm not sure why you'd need to be able to address bits directly like that, though. Normally the bitwise &, |, << and >> should suffice for all intents and purposes. Making an ACTUAL lists of ACTUAL integers representing the bits would be overkill, though. We're talking several bytes worth of nulls to represent a single bit. I'm all for late optimisation, but this just doesn't feel right. Cheers, Alan ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] When max() doesn't work as expected
On Fr, 2009-12-04 at 08:21 +0100, spir wrote: > By the way, is there any reason why the compare func parameter is called > 'key'? I'd guess because what you provide creates keys for the values in the collection to sort them by. What else to call it? "Comparators" compare two values, "hashes" don't need to provide information relevant to ordering, and "indexes" are not directly related to the value at all. Cheers, Alan ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] mod_python authentication
On Mo, 2009-12-07 at 09:35 -0400, Rayon wrote: > How do I Check for an active login session on every page that requires > authentication > > Been at this for days and it’s holding me back can someone plz help > me with some code examples. To understand sessions you first need to understand that HTTP is a stateless protocol: you connect, send your request, receive a response and the connection is closed. Sessions add a layer of abstraction to create functionality the protocol doesn't provide: multiple requests are grouped and treated as belonging together. There are several ways to accomplish this. The most straightforward way would be remembering the client's IP and persisting variables as relative to that IP -- problem is, IPs are unreliable, can be faked, and do not provide a strong indicator of identity (while an IP only resolves to one machine at a time, that machine may be acting as a gateway or proxy for multiple users connected from other machines -- also, many IPs are dynamically allocated thanks to ISPs). Another method is putting the session's ID in the URLs you display to your users. This creates a lot of problems, though: the session is only maintained as long as the user uses exactly the URLs you provide (they won't stay logged in, for example, if they bookmark a plain URL without the session ID) and it may accidentally be shared between different users by passing the URL verbatim (most users don't know enough about URLs to clean session IDs out of them before sending them to other people -- or don't care!). The fix for this is usually to restrict the session to an IP (which is why you often see the checkbox "Restrict my session to this IP" in log-in forms), but that screws you over if your IP may randomly change between consecutive requests and thus may break the illusion. The most common and reliable choice is the good old session cookie: a cookie (a small data string) is sent to the browser, containing just the session ID (and, sometimes, non-critical data such as accessibility settings if the website provides them). Because the browser is normally restricted to a single user, the session ID is stored in a safe place -- except it isn't really because some people use e.g. internet cafés and such which may not dispose of session data regularly. Also, a user may access the same site from different devices or places, therefore hoarding cookies for different sessions creating consistency problems. Still, cookies are the easiest and most reliable way to store a session ID and non-critical data. If you couple them with IP restrictions and a conservative expiry time (i.e. duration of inactivity until the session becomes invalid or "expired" and all associated variables are wiped) and provide a fallback mechanism for users who disabled (or can't accept) cookies, you should have most scenarios covered (although some sites actually just stick to cookies and provide no fallbacks). So once you've decided on a mechanism to persist the session ID, let's see what a session actually is. In most cases you want to use them for a log-in mechanism: the user enters their username and password, successfully, and is welcomed by a personal greeting and a new navigation subtree that was previously unavailable. In this case it may be tempting to simply store the user's ID and log-in state in a cookie, but that'd be incredibly silly because the user can easily edit them if he knows about cookies (even worse things can happen if you provide useful variables like "is_admin: False"). Instead you should store those variables in a safe place ("persist" them) like a database or special session files. The session ID acts as a key to the session file or database entry, so you need to make sure it's not easily guessable: many websites use very long seemingly-randomly generated strings (a hash of the user's IP and the millisecond time of the session's creation may yield good results). Also, if you want to persist something, make sure it's easily persistable. A string variable is child's play, an open file on the other hand may cause locking problems and if you deal with large volumes of data (e.g. binary file uploads kept in memory) you may quickly run out of space. If you don't want to have to deal with all of these considerations and instead prefer something shrinkwrapped and ready for use, Google is your friend. Depending on what you use there are plenty of CGI-compatible packages and WSGI frameworks to choose from. Cheers, Alan Plum ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] mod_python authentication
On Mo, 2009-12-07 at 23:10 -0500, Marc wrote: > While I agree with the cookie (as long as it has a short expiration), > another way to do this is by using expiring tokenization (credentials+ some > unique data for the transaction) in the URL header (see section 14.8 at > http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html). Tokenization > substitutes some random string for confidential data (such as credentials). This is essentially what I said about passing variables in the URL. The important thing still is information hiding, though: you don't want the user to have any clue what those variables mean so they can't modify them too easily. This is also why you should never expose critical variables (e.g. user ID) to possible modification. > The payment card industry uses this in the form of an authorization code for > card transactions. Add to the data represented by the token some unique > data (maybe a random number or some data from the last transaction - it > doesn't matter as the token does not expose the data in any way) for each > http transaction so you have unique token in each header and you can get an > essentially stateful session with a method of checking authentication that > has some spoof protection built in. The problem to keep in mind, though, is that your users may be multi-tabbing, i.e. keeping several pages open at the same time. Don't ever rely on a linear experience unless you're dealing with something inherently linear like a survey (though in that case you should probably try to keep it to one page, possibly updated with JavaScript requests if the form doesn't look too friendly on one page) or a check-out process. > Wrap it all in SSL/TLS and then you've > got something. Granted, this requires some serious server side work, and is > probably not a good beginner exercise, but if this level is what you > need I have never coded anything like this in Python, but I can see > abstractly how it could be done (I'm a novice with Python). If you're bored, > you can read http://www.shift4.com/pdf/TokenizationWhitePaper.pdf especially > sec1:7. I agree that if you're going for high security/safety tokenization can help, but for most intents and purposes it really isn't necessary. The idea is to avoid re-submission (especially of counter-intuitively side-effect non-free actions like GET requests) and make each action uniquely identifiable, if I understand the method correctly. This is normally only necessary for things like checkouts (keep track of the order ID and make sure the customer can't accidentally place an order twice e.g. by double-clicking the submit button or re-clicking it if the connection hangs) or form submission that affects the server state (e.g. posting a message to a forum, sending an e-mail, ...). SSL/TLS is also usually overkill for most purposes. Certificates provided by many non-commercial authorities will still trigger security warnings in most browsers, so the only way to get one that isn't counter-productive (i.e. diminishes trust rather than increasing it -- dodgy certificates are still valid certificates) is to shell out the big money -- and unless you're into serious business (i.e. anything big enough to justify the expenses), you probably can't be arsed. Cheers, Alan Plum ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] print IP address range to stdout
On Di, 2009-12-22 at 10:53 +0100, MK wrote: > Hi there, > > i have some logical problem. I dont get it done to write my for loops in > that way that the ip address range which is given as arguments are > correct processed. Meaning that only the ips are printed which the > user defines as argument. I tried to make an if statement to stop > at the end_adress but it didnt work as it will stop at the end range > every time. > > Here is my program so far: > The start_adress and end_adress are the ip-range. > > For example: > printdomains.py -s 192.168.178.0 -e 193.170.180.4 > > This should make all ips and stop at the end_adress. > > Maybe you can help. > > Thank you. > > Mac > > ___ > Tutor maillist - Tutor@python.org > To unsubscribe or change subscription options: > http://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] print IP address range to stdout
On Di, 2009-12-22 at 10:53 +0100, MK wrote: > Here is my program so far: > Please translate comments if you post to an English list. Not everyone speaks German. > The start_adress and end_adress are the ip-range. > > For example: > printdomains.py -s 192.168.178.0 -e 193.170.180.4 > > This should make all ips and stop at the end_adress. IP addresses consist of four blocks of values between 0 and 255 (inclusive). This means they can easily be translated into a hexadecimal value: 255.255.255.0 is ff.ff.ff.00 or 0xff00. Knowing this, you could simplify the problem: each block of the start address is offset by 8 bits from the next, so we can do something like this: # Translate the start address blocks into integers: start_blocks = [int(block) for block in start_address.split('.')] # Now offset the blocks and add them together: start = 0 for k, block in enumerate(start_blocks): start += block << (8 * k) # Do the same for the end address: end_blocks = [int(block) for block in end_address.split('.')] end = 0 for k, block in enumerate(end_blocks): end += block << (8 * k) # Now generate the addresses: for ip in range(start, end+1): blocks = [] for i in range(4): blocks.append((ip & (0xff << (8 * i))) >> (8 * i)) print '.'.join(blocks) Hope this helps. I haven't run this code, so you might want to make sure it works correctly before using it. Cheers, Alan Plum ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] print IP address range to stdout
Hi again, On Di, 2009-12-22 at 12:46 +0100, Alan Plum wrote: > # Now generate the addresses: > for ip in range(start, end+1): > blocks = [] > for i in range(4): > blocks.append((ip & (0xff << (8 * i))) >> (8 * i)) > print '.'.join(blocks) I just realised this gives you the blocks in reverse order. You probably want to use prepend() rather than append() -- or just use reversed() before you print. Also note that there's probably a better way to create the actual blocks from the integer, but this should suffice. If you're not familiar with the bitwise operators: the double brackets are shift operators (left shift and right shift respectively) and shift the value by a number of bits (`8 * i for i in range(4)`, i.e. `for j in [0,8,16,24]`). The ampersand is a bitwise AND which "switches off" all bits other than the ones you select (in this case 0xff, i.e. one block of 8 bits). By combining them you first define the bits you want (0xff shifted by i bits to the left, i.e. [0x00ff, 0xff00, 0x00ff, 0xff00]. Then you apply the mask to the integer, switching off all the bits that are not part of the block you want. Then you shift the result back (i.e. to the right) the number of bits you shifted the mask to the left, leaving the exact block value (otherwise your block value would be off by several orders of hexadecimal magnitude, i.e. 256 (256^1) for the second (counting from the right), 256*256 (256^2) for the third and 256*256*256 (256^3) for the fourth. Also, range() takes endpoints to be exclusive, which is why you iterate over range(start, end+1) rather than range(start, end). Provided you want it to behave that way. Cheers, Alan Plum ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to open the closed file again?
On Di, 2010-01-05 at 16:24 +0800, 朱淳 wrote: > I found that after closing files some closed files were left in the > list: Why don't you use a dictionary mapping filenames to open file objects instead? files = {'/path/to/file1': None, '/path/to/file2': None} def openFiles(): for f in files.keys(): if files[f] is not None: continue files[f] = open(f) def closeFiles(): for f in files.keys(): if files[f] is None: continue files[f].close() files[f] = None Although you'll probably want to refactor this into an object. Cheers, Alan Plum ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor