And how is the input computed. Code below works. int main() { int a, b , c; prin
ID: 3527359 • Letter: A
Question
And how is the input computed. Code below works.
int main() { int a, b , c; printf("Enter integers a, b, c: "); scanf ("%i%i%i", &a, &b, &c); if( ((!a || !b++ && c)) == 1) printf("!a || !b++ && c: True "); else printf("!a || !b++ && c: False "); if ( ((a-1 || b/2) && (c*=2)) ==1) printf("(a-1 || b/2) && (c*=2): True "); else printf("(a-1 || b/2) && (c*=2): False "); if ( ((a-- || --b) && (c+=2)) ==1) printf("(a-- || --b) && (c+=2): True "); else printf("(a-- || --b) && (c+=2): False "); if ( (a || !(b && --c)) ==1) printf("a || !(b && --c): True "); else printf("a || !(b && --c): False "); return 0; }
Explanation / Answer
IF YOU FIND MY ANSWER HELPFUL FOR YOU THAN PLEASE RATE AND AWARD ME KARMA POINTS An iterator is an object representing a stream of data; this object returns the data one element at a time. A Python iterator must support a method called __next__() that takes no arguments and always returns the next element of the stream. If there are no more elements in the stream, __next__() must raise the StopIteration exception. Iterators don’t have to be finite, though; it’s perfectly reasonable to write an iterator that produces an infinite stream of data. The built-in iter() function takes an arbitrary object and tries to return an iterator that will return the object’s contents or elements, raising TypeError if the object doesn’t support iteration. Several of Python’s built-in data types support iteration, the most common being lists and dictionaries. An object is called an iterable object if you can get an iterator for it. You can experiment with the iteration interface manually: >>> L = [1,2,3] >>> it = iter(L) >>> it >>> it.__next__() 1 >>> next(it) 2 >>> next(it) 3 >>> next(it) Traceback (most recent call last): File "", line 1, in ? StopIteration >>> Python expects iterable objects in several different contexts, the most important being the for statement. In the statement for X in Y, Y must be an iterator or some object for which iter() can create an iterator. These two statements are equivalent: for i in iter(obj): print(i) for i in obj: print(i) Iterators can be materialized as lists or tuples by using the list() or tuple() constructor functions: >>> L = [1,2,3] >>> iterator = iter(L) >>> t = tuple(iterator) >>> t (1, 2, 3) Sequence unpacking also supports iterators: if you know an iterator will return N elements, you can unpack them into an N-tuple: >>> L = [1,2,3] >>> iterator = iter(L) >>> a,b,c = iterator >>> a,b,c (1, 2, 3) Built-in functions such as max() and min() can take a single iterator argument and will return the largest or smallest element. The "in" and "not in" operators also support iterators: X in iterator is true if X is found in the stream returned by the iterator. You’ll run into obvious problems if the iterator is infinite; max(), min(), and "not in" will never return, and if the element X never appears in the stream, the "in" operator won’t return either. Note that you can only go forward in an iterator; there’s no way to get the previous element, reset the iterator, or make a copy of it. Iterator objects can optionally provide these additional capabilities, but the iterator protocol only specifies the next() method. Functions may therefore consume all of the iterator’s output, and if you need to do something different with the same stream, you’ll have to create a new iterator. Data Types That Support Iterators We’ve already seen how lists and tuples support iterators. In fact, any Python sequence type, such as strings, will automatically support creation of an iterator. Calling iter() on a dictionary returns an iterator that will loop over the dictionary’s keys: >>> m = {'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4, 'May': 5, 'Jun': 6, ... 'Jul': 7, 'Aug': 8, 'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12} >>> for key in m: ... print(key, m[key]) Mar 3 Feb 2 Aug 8 Sep 9 Apr 4 Jun 6 Jul 7 Jan 1 May 5 Nov 11 Dec 12 Oct 10 Note that the order is essentially random, because it’s based on the hash ordering of the objects in the dictionary. Applying iter() to a dictionary always loops over the keys, but dictionaries have methods that return other iterators. If you want to iterate over values or key/value pairs, you can explicitly call the values() or items() methods to get an appropriate iterator. The dict() constructor can accept an iterator that returns a finite stream of (key, value) tuples: >>> L = [('Italy', 'Rome'), ('France', 'Paris'), ('US', 'Washington DC')] >>> dict(iter(L)) {'Italy': 'Rome', 'US': 'Washington DC', 'France': 'Paris'} Files also support iteration by calling the readline() method until there are no more lines in the file. This means you can read each line of a file like this: for line in file: # do something for each line ... Sets can take their contents from an iterable and let you iterate over the set’s elements: S = {2, 3, 5, 7, 11, 13} for i in S: print(i) Generator expressions and list comprehensions Two common operations on an iterator’s output are 1) performing some operation for every element, 2) selecting a subset of elements that meet some condition. For example, given a list of strings, you might want to strip off trailing whitespace from each line or extract all the strings containing a given substring. List comprehensions and generator expressions (short form: “listcomps” and “genexps”) are a concise notation for such operations, borrowed from the functional programming language Haskell (http://www.haskell.org/). You can strip all the whitespace from a stream of strings with the following code: line_list = [' line 1 ', 'line 2 ', ...] # Generator expression -- returns iterator stripped_iter = (line.strip() for line in line_list) # List comprehension -- returns list stripped_list = [line.strip() for line in line_list] You can select only certain elements by adding an "if" condition: stripped_list = [line.strip() for line in line_list if line != ""] With a list comprehension, you get back a Python list; stripped_list is a list containing the resulting lines, not an iterator. Generator expressions return an iterator that computes the values as necessary, not needing to materialize all the values at once. This means that list comprehensions aren’t useful if you’re working with iterators that return an infinite stream or a very large amount of data. Generator expressions are preferable in these situations. Generator expressions are surrounded by parentheses (“()”) and list comprehensions are surrounded by square brackets (“[]”). Generator expressions have the form: ( expression for expr in sequence1 if condition1 for expr2 in sequence2 if condition2 for expr3 in sequence3 ... if condition3 for exprN in sequenceN if conditionN ) Again, for a list comprehension only the outside brackets are different (square brackets instead of parentheses). The elements of the generated output will be the successive values of expression. The if clauses are all optional; if present, expression is only evaluated and added to the result when condition is true. Generator expressions always have to be written inside parentheses, but the parentheses signalling a function call also count. If you want to create an iterator that will be immediately passed to a function you can write: obj_total = sum(obj.count for obj in list_all_objects()) The for...in clauses contain the sequences to be iterated over. The sequences do not have to be the same length, because they are iterated over from left to right, not in parallel. For each element in sequence1, sequence2 is looped over from the beginning. sequence3 is then looped over for each resulting pair of elements from sequence1 and sequence2. To put it another way, a list comprehension or generator expression is equivalent to the following Python code: for expr1 in sequence1: if not (condition1): continue # Skip this element for expr2 in sequence2: if not (condition2): continue # Skip this element ... for exprN in sequenceN: if not (conditionN): continue # Skip this element # Output the value of # the expression. This means that when there are multiple for...in clauses but no if clauses, the length of the resulting output will be equal to the product of the lengths of all the sequences. If you have two lists of length 3, the output list is 9 elements long: >>> seq1 = 'abc' >>> seq2 = (1,2,3) >>> [(x,y) for x in seq1 for y in seq2] [('a', 1), ('a', 2), ('a', 3), ('b', 1), ('b', 2), ('b', 3), ('c', 1), ('c', 2), ('c', 3)] To avoid introducing an ambiguity into Python’s grammar, if expression is creating a tuple, it must be surrounded with parentheses. The first list comprehension below is a syntax error, while the second one is correct: # Syntax error [ x,y for x in seq1 for y in seq2] # Correct [ (x,y) for x in seq1 for y in seq2] Generators Generators are a special class of functions that simplify the task of writing iterators. Regular functions compute a value and return it, but generators return an iterator that returns a stream of values. You’re doubtless familiar with how regular function calls work in Python or C. When you call a function, it gets a private namespace where its local variables are created. When the function reaches a return statement, the local variables are destroyed and the value is returned to the caller. A later call to the same function creates a new private namespace and a fresh set of local variables. But, what if the local variables weren’t thrown away on exiting a function? What if you could later resume the function where it left off? This is what generators provide; they can be thought of as resumable functions. Here’s the simplest example of a generator function: def generate_ints(N): for i in range(N): yield i Any function containing a yield keyword is a generator function; this is detected by Python’s bytecode compiler which compiles the function specially as a result. When you call a generator function, it doesn’t return a single value; instead it returns a generator object that supports the iterator protocol. On executing the yield expression, the generator outputs the value of i, similar to a return statement. The big difference between yield and a return statement is that on reaching a yield the generator’s state of execution is suspended and local variables are preserved. On the next call to the generator’s .__next__() method, the function will resume executing. Here’s a sample usage of the generate_ints() generator: >>> gen = generate_ints(3) >>> gen >>> next(gen) 0 >>> next(gen) 1 >>> next(gen) 2 >>> next(gen) Traceback (most recent call last): File "stdin", line 1, in ? File "stdin", line 2, in generate_ints StopIteration You could equally write for i in generate_ints(5), or a,b,c = generate_ints(3). Inside a generator function, the return statement can only be used without a value, and signals the end of the procession of values; after executing a return the generator cannot return any further values. return with a value, such as return 5, is a syntax error inside a generator function. The end of the generator’s results can also be indicated by raising StopIteration manually, or by just letting the flow of execution fall off the bottom of the function. You could achieve the effect of generators manually by writing your own class and storing all the local variables of the generator as instance variables. For example, returning a list of integers could be done by setting self.count to 0, and having the __next__() method increment self.count and return it. However, for a moderately complicated generator, writing a corresponding class can be much messier. The test suite included with Python’s library, test_generators.py, contains a number of more interesting examples. Here’s one generator that implements an in-order traversal of a tree using generators recursively. # A recursive generator that generates Tree leaves in in-order. def inorder(t): if t: for x in inorder(t.left): yield x yield t.label for x in inorder(t.right): yield x Two other examples in test_generators.py produce solutions for the N-Queens problem (placing N queens on an NxN chess board so that no queen threatens another) and the Knight’s Tour (finding a route that takes a knight toRelated Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.