Re: [Tutor] extracting numbers from a list
Thank you Danny. I am going over your email and trying to understand (i am a biologist with bioinformatics training). I am not sure if I got your opinion about the way I solved. do you mean that there is something wrong with the way i solved it. I am not sure If I explained the problem correctly in terms of exons, transcripts. If not I would be happy to send you a pdf file with a figure. Thanks again. --- Danny Yoo [EMAIL PROTECTED] wrote: On Mon, 16 Oct 2006, kumar s wrote: I have a simple question to ask tutors: list A : a = [10,15,18,20,25,30,40] Hi Kumar, If you're concerned about correctness, I'd recommend that you try thinking about the problem inductively. An inductive definition for what you're asking is straightforward to state in about three or four lines of code. I'll try to go through it slowly so you see what the reasoning behind it is. The code sketch above uses a technique that you should already know called mathematical induction. http://en.wikipedia.org/wiki/Mathematical_induction Let's say we're designing a function called getSpans(). Here are some sample behavior we'd like from it: getSpans([10, 15]) = [(10, 15)] getSpans([10, 15, 18]) = [(10, 15), (16, 18)] getSpans([10, 15, 18, 20]) = [(10, 15), (16, 18), (19, 20)] Would you agree that this is reasonable output for a function like this? getSpans() takes a list of numbers, and returns a list of pairs of numbers. There is one base case to this problem. The smallest list we'd like to consider is a list of two elements. If we see that, then we're happy, because the answer is really simple: getSpans([a, b]) = [(a, b)] Otherwise, let's imagine a list that's a bit longer, with three elements. Concretely, we know that this is going to look like: getSpans([a, b, c]) = [(a, b), (b+1, c)] But another way to say this, though is that: getSpans([a, b, c]) = [(a, b)] + getSpans([b+1, c]) That is, we try to restate the problem in terms of smaller subproblems. Let's look at what the case for four elements might look like: getSpans([a, b, c, d]) = [(a, b), (b+1, c), (c+1, d)] Concretely, we know that that's the list of spans we'd like to see. But if we think about it, we might also restate this as: getSpans([a, b, c, d]) = [a, b] + getSpans([b+1, c, d]) because getSpans([b+1, c, d]) is going to give us: [(b+1, c), (c+1, d)] All we need to do is add on [(a, b)] to that to get the complete answer to getSpans([a, b, c, d]). Generally, for any particular list L that's longer than two elements: getExons(L) = [L[0:2]] + getExons([L[1] + 1] + L[2:]) When we work inductively, all we really need to think about is base case and inductive case: the solution will often just fall through from stating those two cases. An inductively-designed function is going to look something like: def solve(input): if input looks like a base-case: handle that directly in a base-case way else: break up the problem into smaller pieces that we assume can be solve()d by induction The inductive definition above is slightly inefficient because we're doing physical list slicing. Rewriting it to use loops and list indicies instead of slicing is a little harder, but not much harder. Another example: how do we add up a list of numbers? If there's just one number, that must be the sum. Otherwise, we can add up the first number to the sum of the rest of the numbers. # def mysum(L): if len(L) == 1: return L[0] else: return L[0] + mysum(L[1:]) # It's a funky way of doing this, but this is a real definition that works (modulo limits in Python's recursion implementation). It's inefficient, but it's easy to state and reason about. I'm assuming you're more interested in correctness than efficiency at the moment. Get it correct first, then if you really need to, work to get it fast. __ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] extracting numbers from a list
On Wed, 18 Oct 2006, kumar s wrote: I am not sure if I got your opinion about the way I solved. Hi Kumar, I was replying to your question: http://mail.python.org/pipermail/tutor/2006-October/050064.html in which you showed a program that had problems. I'm assuming that you haven't figured out what's wrong with the code in your post. I've presented an approach that shows how one might try to approach the problem without being brilliant. Did you understand every step in the program in: http://mail.python.org/pipermail/tutor/2006-October/050121.html or was there something there that you didn't understand? If so, please ask for clarification, because everything there should have been approachable to you. do you mean that there is something wrong with the way i solved it. Well... how do I put this gently? Your program doesn't work, so I can't really give a positive or negative opinion about its effectiveness until it does. I can sorta see what the code tries to do, but it's going about it in a complicated fashion. I can give my opinion that: ### fx = a[0] fy = a[1] b = a[2:] ai = iter(b) last = ai.next() for j in ai: print fy+1,last last = j ### seems to be juggling too many variables, too much state. I think the conceptual bug here is that the code fumbles around, trying to do something toward a goal, but it loses intentionality. I don't understand the intent of 'fx', since that variable is never used. I don't understand the expression 'fy+1' in the print statement, since 'fy' never changes. There's just a lot of little small things there that seem irrelevant to the problem at hand. I haven't tried to fix your program; rather, I've tried to show you an approach that can systematic attack these kinds of problems without much trouble. The problem I see that you've been having is that you're getting stuck as soon as the complexity of a problem reaches a threshold. I'm trying to show you techniques to compensate when problems get hard. I could just as easily have just fixed the above code, but how would this really help you? For you, it would be as if I just pulled that program out of thin air! But just to satisfy you, such a program would have looked like this: # x = a[0] for y in a[1:]: print x, y x = y + 1 # The relationship between this and your original program is somewhat there. But again, if I just showed this to you, how does that really help you to program better? The program here is written to conserve memory, but at the expense of being harder to develop, understand, and explain. And, if I were doing this as a computer scientist, I'd have to develop a loop invariant argument to feel satisfied that it was doing the right thing. In comparison, the inductive definition has the force of a proof behind it. I am not sure If I explained the problem correctly in terms of exons, transcripts. If not I would be happy to send you a pdf file with a figure. That's ok. I don't think it is necessary as long as you clearly explain the problem you're trying to solve. You should be able to communicate what you're trying to do. (And just as background: I've worked in the past as a bioinformatician at arabidopsis.org. The terminology that you've been using has not been an issue.) ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] extracting numbers from a list
In continuation to : Re: [Tutor] extracting numbers from a list hello list I have coordinates for exons (chunks of sequence). For instance: 10 - 50 A 10 - 20 B 35 - 50 B 60 - 70 A 60 - 70 B 80 - 100 A 80 - 100 B (The above coordinates and names are easier than in dat) Here my aim is to creat chunks of exons specific to A or B. For instance: 10 - 20,35 - 50 are common to both A and B, whereas 21 - 34 is specific only to A. The desired output for me is : 10 \t 20 A,B 21 \t 34 A 35 \t 50 A,B 60 \t 70 A,B 80 \t 100 A,B I just learned python frm a friend and he is also a novice. What I could get is the break up of chunks. A problem here I am getting number different from what I need: [10, 20] [10, 50] [21, 35] [10, 50] [36, 50] [10, 50] [60, 70] [60, 70] [80, 100] [80, 100] The list next to chunks is the pairs( the longer ones). could any one help me how can I correct [21, 35],[36, 50] to 21 \t 34 , 35 \t 50. I tried chaning the indexs in function chunker, it is not working for me. Also, how can I point chunks to their names. This is the abstract example of the complex numbers and their sequence names. I want to change the simple code and then go to the complex one. Thank you very much for your valuable time. REsult: what I am getting now: [10, 20] [10, 50] [21, 35] [10, 50] [36, 50] [10, 50] [60, 70] [60, 70] [80, 100] [80, 100] My code: from sets import Set dat = ['10\t50\tA', '10\t20\tB', '35\t50\tB', '60\t70\tA', '60\t70\tB', '80\t100\tA', '80\t100\tB'] # creating a dictionary with coordiates as key and NM_ as value # ekda = {} for j in dat: cols = j.split('\t') ekda.setdefault(cols[0]+'\t'+cols[1],[]).append(cols[2]) ## #getting tab delim numbers only and not the A,B bat = [] for j in dat: cols = j.split('\t') bat.append(cols[0]+'\t'+cols[1]) pairs = [ map(int, x.split('\t')) for x in bat ] # # this function takes pairs (from the above result)and longer blocks(exons). # For instance: # 10 - 20; 14 - 25; 19 - 30; 40 - 50; 45 - 60; 70 - 80 # a = [[10,20],[14,25],[19,30],[40,50],[45,60],[70,80]] # for j in exoner(a): # print j #The result would be: #10 - 30; 40 - 60; 70 - 80 # def exoner(pairs): pairs.sort() i = iter(pairs) last = i.next() for current in i: if current[0] in xrange(last[0],last[1]): if current[1] last[1]: last = [last[0], current[1]] else: last = [last[0],last[1]] else: yield last last = current yield last lon = exoner(pairs) # ## Here I am getting all the unique numbers in dat nums = [] for j in pairs: for k in j: nums.append(k) unm = Set(nums) unums = [] for x in unm: unums.append(x) unums.sort() # ### This function takes a list of numbers and breaks it in pieces ## For instance [10,15,20,25,30] # i = [10,15,20,25,30] # chunker(i) #[[10, 15], [16, 20], [21, 25], [26, 30]] def chunker(lis): res = [] res.append([lis[0],lis[1]]) for m in range(2,len(lis)): res.append([lis[m-1]+1,lis[m]]) return res # Here I take each pair (longer block) and roll over all the unique numbers ((unums) from dat) and check if that number is in#the range of pair, if so, I will break all those set of number in pair range into small blocks ## gdic = {} unums.sort() for pair in exoner(pairs): x = pair[0] y = pair[1]+1 sml = [] for k in unums: if k in range(x,y): sml.append(k) else: pass for j in chunker(sml): print j,pair __ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] extracting numbers from a list
On Mon, 16 Oct 2006, kumar s wrote: I have a simple question to ask tutors: list A : a = [10,15,18,20,25,30,40] Hi Kumar, If you're concerned about correctness, I'd recommend that you try thinking about the problem inductively. An inductive definition for what you're asking is straightforward to state in about three or four lines of code. I'll try to go through it slowly so you see what the reasoning behind it is. The code sketch above uses a technique that you should already know called mathematical induction. http://en.wikipedia.org/wiki/Mathematical_induction Let's say we're designing a function called getSpans(). Here are some sample behavior we'd like from it: getSpans([10, 15]) = [(10, 15)] getSpans([10, 15, 18]) = [(10, 15), (16, 18)] getSpans([10, 15, 18, 20]) = [(10, 15), (16, 18), (19, 20)] Would you agree that this is reasonable output for a function like this? getSpans() takes a list of numbers, and returns a list of pairs of numbers. There is one base case to this problem. The smallest list we'd like to consider is a list of two elements. If we see that, then we're happy, because the answer is really simple: getSpans([a, b]) = [(a, b)] Otherwise, let's imagine a list that's a bit longer, with three elements. Concretely, we know that this is going to look like: getSpans([a, b, c]) = [(a, b), (b+1, c)] But another way to say this, though is that: getSpans([a, b, c]) = [(a, b)] + getSpans([b+1, c]) That is, we try to restate the problem in terms of smaller subproblems. Let's look at what the case for four elements might look like: getSpans([a, b, c, d]) = [(a, b), (b+1, c), (c+1, d)] Concretely, we know that that's the list of spans we'd like to see. But if we think about it, we might also restate this as: getSpans([a, b, c, d]) = [a, b] + getSpans([b+1, c, d]) because getSpans([b+1, c, d]) is going to give us: [(b+1, c), (c+1, d)] All we need to do is add on [(a, b)] to that to get the complete answer to getSpans([a, b, c, d]). Generally, for any particular list L that's longer than two elements: getExons(L) = [L[0:2]] + getExons([L[1] + 1] + L[2:]) When we work inductively, all we really need to think about is base case and inductive case: the solution will often just fall through from stating those two cases. An inductively-designed function is going to look something like: def solve(input): if input looks like a base-case: handle that directly in a base-case way else: break up the problem into smaller pieces that we assume can be solve()d by induction The inductive definition above is slightly inefficient because we're doing physical list slicing. Rewriting it to use loops and list indicies instead of slicing is a little harder, but not much harder. Another example: how do we add up a list of numbers? If there's just one number, that must be the sum. Otherwise, we can add up the first number to the sum of the rest of the numbers. # def mysum(L): if len(L) == 1: return L[0] else: return L[0] + mysum(L[1:]) # It's a funky way of doing this, but this is a real definition that works (modulo limits in Python's recursion implementation). It's inefficient, but it's easy to state and reason about. I'm assuming you're more interested in correctness than efficiency at the moment. Get it correct first, then if you really need to, work to get it fast. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] extracting numbers from a list
I want to print 10 15 (first two elements) 16 18 (16 is last number +1) : fx = a[0] fy = a[1] b = a[2:] ai = iter(b) last = ai.next() for j in ai: ... print fy+1,last ... last = j ... 16 18 16 20 16 25 16 30 look very carefully at variables 'fy' vs. 'last', what you do with them, and when, and you should be able to figure out your homework assignment problem. hope this helps! -- wesley - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Core Python Programming, Prentice Hall, (c)2007,2001 http://corepython.com wesley.j.chun :: wescpy-at-gmail.com python training and technical consulting cyberweb.consulting : silicon valley, ca http://cyberwebconsulting.com ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] extracting numbers from a list
On 10/16/06, kumar s [EMAIL PROTECTED] wrote: hi :I have a simple question to ask tutors:list A :a = [10,15,18,20,25,30,40]I want to print10 15 (first two elements)16 18 (16 is last number +1)19 2021 2526 3031 40 fx = a[0] fy = a[1] b = a[2:] ai = iter(b) last = ai.next() for j in ai:... print fy+1,last... last = j ...16 1816 2016 2516 30can any one help please.thank you a = [10,15,18,20,25,30, 40] print a[0], a[1] for i in xrange(2, len(a)): print a[i-1] + 1, a[i] __Do You Yahoo!?Tired of spam?Yahoo! Mail has the best spam protection around http://mail.yahoo.com___Tutor maillist-Tutor@python.org http://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] extracting numbers from a list
kumar s [EMAIL PROTECTED] wrote a = [10,15,18,20,25,30,40] I want to print 10 15 (first two elements) 16 18 (16 is last number +1) 19 20 The simplest solution would seem to be a while loop: print a[0], a[1] # special case index = 1 while index len(a): print a[index-1]+1, a[index] index += 1 But that seems too straightforward to be the solution, so I assume I'm missing something? -- Alan Gauld Author of the Learn to Program web site http://www.freenetpages.co.uk/hp/alan.gauld ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] extracting numbers from a list
wesley chun [EMAIL PROTECTED] wrote in message look very carefully at variables 'fy' vs. 'last', what you do with them, and when, and you should be able to figure out your homework assignment problem. Hmmm, homework assignment was probably what I was missing Alan G. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] extracting numbers from a list
My solution : (i have tested it) list1 = [10,15,18,20,25,30,40] for i in range(len(list1)-1): print list1[i],list1[i+1]list1[i+1] += 1 Note: #print the consecutive elements;for thefirst pass of the loop the elements are unchanged, for the remaining we add one. On 10/16/06, kumar s [EMAIL PROTECTED] wrote: hi :I have a simple question to ask tutors:list A :a = [10,15,18,20,25,30,40] I want to print10 15 (first two elements)16 18 (16 is last number +1)19 2021 2526 3031 40 fx = a[0] fy = a[1] b = a[2:] ai = iter(b) last = ai.next() for j in ai:... print fy+1,last... last = j...16 1816 2016 2516 30can any one help please.thank you__ Do You Yahoo!?Tired of spam?Yahoo! Mail has the best spam protection aroundhttp://mail.yahoo.com___Tutor maillist- Tutor@python.orghttp://mail.python.org/mailman/listinfo/tutor-- To HIM you shall return. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] extracting numbers from a list
Asrarahmed Kadri wrote: My solution : (i have tested it) list1 = [10,15,18,20,25,30,40] for i in range(len(list1)-1): print list1[i],list1[i+1] list1[i+1] += 1 Note that this changes the original list, which may or may not be acceptable. Normally you would expect a printing function not to change the value being printed. Kent ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] extracting numbers from a list
I agree. Regards, Asrar On 10/17/06, Kent Johnson [EMAIL PROTECTED] wrote: Asrarahmed Kadri wrote: My solution : (i have tested it) list1 = [10,15,18,20,25,30,40] for i in range(len(list1)-1): print list1[i],list1[i+1] list1[i+1] += 1Note that this changes the original list, which may or may not beacceptable. Normally you would expect a printing function not to change the value being printed.Kent___Tutor maillist-Tutor@python.org http://mail.python.org/mailman/listinfo/tutor-- To HIM you shall return. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] extracting numbers from a list
On 17/10/06, Asrarahmed Kadri [EMAIL PROTECTED] wrote: My solution : (i have tested it) As long as we're all taking turns, what about a functional approach: a = [10, 15, 18, 20, 25, 30, 40] def pairs(lst): ... return list.__add__([(lst[0], lst[1])], zip(map((1).__add__, lst[1:]), lst[2:])) ... pairs(a) [(10, 15), (16, 18), (19, 20), (21, 25), (26, 30), (31, 40)] -- John. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor