This thread is not intended to deal with administrative or procedural issues (use the general forum for those).
Since HW assignment #3 includes a number of questions that would potentially have lambda calls, I have been getting a lot of questions regarding the caveat of lambdas, where if if variables not created in the lambda's scope are used in the lambda, it is saved as a pointer, which causes some misunderstanding such as infinite loops and extremely erratic functions.
Perhaps this was talked about, but if this was not talked about in lecture/tutorial, I believe some mention should be given to it, since it is not intuitive to most people.
I mean, for example
i = 1 f = lambda: i i = 2 f()
f will return 2, not 1 as most would expect.
why would you expect f() to return 1?
lets say it does return 1, what's the possible reasoning behind that?
I don't think lambda freezes everything everywhere the moment it is created and deals with values as they were at that moment in the space-runtime continuum.
I personally would not expect it to return 1. Dynamically created functions in any language I know act the same way.
This doesnt change the fact that many people are unsure of this.
*Note that i was talking about lambdas, but this same reaction would occur with normally defined functions too, in Python.
Personally I would have left dynamic functions out of a basic CompSci course, since they are not representative of most programming languages and most practical programming, but I trust in the experience and knowledge and experience of the lecturers in knowing what to teach when. (If we're mentioning things i would not teach- the eval function, which in my opinion causes more problems than it ever solves (security, error-handling…))
Im staying out of his one :)
Just wanted to say that in your example, 'i' acts as a global variable to the lambda and therefore f is expected to return 2
In any case, in general I think this course up till now has gone over things very well.
We will most probably not get much deeper into questions regarding scopes of lambda calls. The example given above is interesting, yet seems quite pathological. It definitely will cause more confusion than clarity for many students at this stage. The elective programming languages course is a venue where these issues are dealt with in more depth.
We will have additional chances to experience unexpected infinite loops when dealing with linked lists, and later with iterators.
My question is about: rec_binary_search(key,lst,lower,upper) in slide 11
Can you clarify whats the purpose/meaning of "lower"&"upper" , i didn't understand that from the slide…
In this course, for all code benchmarking, you use a function called elapsed, which uses time.clock() and eval.
Instead of using elapsed, the recommended module to use for code benchmarking in python is timeit, which stops some surrounding background actions of the python sandbox such as not letting the Garbage Collector run a collection cycle in the middle of the code and such..
Of course, for our uses elapsed is surely enough, but why not teach the recommended and real-world benchmarking solution?
Thanks for this comment, pseudorandom.
We did use timeit in previous semesters (this is even mentioned in one of the lectures).
However, since time.clock() looks a bit more intuitive, it took over.
Throughout the course, there are various technical/programming issues that we tend to neglect, to keep us (that is - you) focused on the main topics.
We should re-consider this one, I suppose.
If you wish to learn about the Python debugger (actually a somewhat different mode than studied in class) a bit more, e.g. about debugging vs. printing, etc., you may watch this talk, by Nathan Yergler, from PyCon US, April 2014:
You can use the Python standard manual https://docs.python.org/2/library/pdb.html as a reference.
Hi, in lecture 19 slide 5 you talk about Unicode falsely. You state that unicode is an encoding where characters ASCII characters will still take up only one byte. This is incorrect.
Unicode is the specification of the character table. In the original Unicode specification, an encoding is given, which is widely referred to as Unicode, but is better called UTF-16. UTF-16 is NOT ASCII compatible. What you are talking about is UTF-8. There are two more, less used, encodings for Unicode characters, UTF-32 and UTF-7.
UTF-16 and UTF-8 are both widely used, and both variable length, so it is incorrect to mention Unicode and say there is only ONE encoding that WORKS with ASCII. If you mention Unicode, in my opinion you should mention at least UFT-16 and UTF-8, or at least while talking about one, mention its not the only one and that each one has their pros and cons.
Also, it was stated that one could not write Hebrew in ASCII. This is also false. ASCII was released before the first modern CPUs and memory modules, before the 8-bit systems. Since it is 7-bit, people from other countries quickly realized that one could use the additional bit to add their own characters. This is known as Extended ASCII, and works with a character page which has to be local on the system. This obviously caused much trouble since if you got a message from Russia, it would look like Hebrew to you, since you are both using the first bit to add your language. While Unicode solved this issue, these character sheets are still used today, and exist on every home PC.
Im sorry if i'm being picky but i've come across too many bugs due to incorrect understanding of these terms and encodings.
Our intro course, CS1001.py is mostly about the ideas underlying Computer Science. As emphasized a number of times, it is not about very fine details of the Python language, or, for that matter, extended ascii encoding, or UTF-x vs. UTF-y.
We are going to explicitly use UTF-8 when discussing Huffman in lecture 20, since we convert characters downloaded from the web to UTF-8 encoding. But, for example, we will assume down the line that ascii is 7 bits fixed length encoding, even if in practice, an extra bit is used. It is important to distinguish between essential ideas and inessential details. If we do not make such distinction, the ideas will be lost in such details for the vast majority of the students.
I truly appreciate the clarification made by you and by other knowledgable students. In line with Amir's response, I myself would use a "softer" terminology than your "falsely".
In LZ algorithm, I didn't get the idea of it being a greedy algorithm.
Lets say I have this text: 'ctgabctgfctgab' so what is the compression, this: [c,t,g,a,b,(5,3),f,(4,3),a,b] or this:
Greedy by meaning that if it finds a repetition it immediately compresses it, or it goes through the whole window to find the longest match?
You can figure out the answer yourself if you read the code of maxmatch() which was shown in class + Tirgul.
This function always chooses the maximum length match within the relevant window, and therefore the second option will be chosen.
Our algorithm is “greedy” in the sense that if the maximum length match which begins at the current character is long enough, we immediately encode it as a repetition. We do so despite the fact that it may interfere with a longer repetition which is lurking right ahead, beginning at one of the next characters.
Lecture Presentation 14 slides: 48-53
Why does at the beginning of functions get_item, find (slides 50, 51) "p" was assignment as "self.next" (instead of "self" like in slides 48,49,52), doesn't it prevent from the first item to be found?
thanks in advance
p.next is the first element.
Note that p is not a node (type Node), it is a linked list (type Linked_list).
Linked_list uses the same field name as in Node "self.next = None", so does the change in the field name of Linked_list-"self.L_next = None" would lead to (Lecture Presentation 14 slide 52) "p.L_next = p.L_next.L_next"?