How do I enable 'doctest.ELLIPSIS' at the Python prompt? - python

I often see examples that use doctest.ELLIPSIS to limit output in interactive examples of Python use,
>>> print range(20) # doctest:+ELLIPSIS
[0, 1, ..., 18, 19]
and see here how to enable the feature in modules; but I can't figure out how to enable this feature interactvely.
How do I enable doctest.ELLIPSIS at the Python or IPython prompt?

It's not limiting the output, it's telling doctest it doesn't need to check all of it. That line of code will still produce the full output:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
But doctest will only check the bits before and after the ....
I don't know of anything to limit the output like that in interactive sessions, though if you use Python 3, you could write your own implementation of print() to do it.

Related

found this sample code tried to run it but it did not work

my_favorite_numbers = [4, 8, 15, 16, 42]
for number in my_favorite_numbers:
my_favorite_numbers.append(1)
THE COMPILER IS NOT SHOWING ANY RESULTS I TRIED TO USE CMD , PYCHARM,SUBLIME AND AN ONLINE ONE TOO
add print function in your code
print(my_favourite_numbers)
and you can check python official tutorial
You are running an infinite loop. I assume you need something like that:
my_favorite_numbers = [4, 8, 15, 16, 42]
for number in range(len(my_favorite_numbers)):
my_favorite_numbers.append(1)
print(my_favorite_numbers)
Output: [4, 8, 15, 16, 42, 1, 1, 1, 1, 1]
Although the goal of this code is still not clear to me.

How to do i print some numbers using .sample() from the random built in module in python

I working on a problem where I'm supposed to generate ten random but unique numbers that range from 1 to 15 inclusive. The thing is, I'm supposed to write everything in one line and to also get this output:
[2, 4, 6, 7, 8, 9, 11, 12, 13, 15]
Below I have some code I wrote but, it's not getting the output I want. What am I doing wrong and can I perhaps see a solution with a break so I know how to do this going down the road?
import random
print(sorted(random.sample(range(1,16),15)))
Output:
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
The output I want is:
[2,4,6,7,8,9,11,12,13,15]
How do I get this in one line of code?
>>> help(random.sample)
sample(population, k): method of random.Random instance
Chooses k unique random elements from a population sequence or set.
I'm supposed to write everything in one line and to also get this output:
[2, 4, 6, 7, 8, 9, 11, 12, 13, 15]
>>> sorted(__import__('random').Random(4225).sample(range(1, 16), 10))
[2, 4, 6, 7, 8, 9, 11, 12, 13, 15]
If you want to generate ten numbers in range 1-15, change
print(sorted(random.sample(range(1,16),15)))
to
print(sorted(random.sample(range(1,16),10)))
# From the documentation :
# random.sample(population, k)
import random
population = range(16)
how_may_sample = 10
random.sample(population, how_many_sample)
# Now in one line
random.sample(range(16), 10)

How do I make this into a for loop?

So basically I am trying to replace this:
board = {
0:[0, 1, 2, 9, 10, 11, 18, 19, 20],
1:[3, 4, 5, 12, 13, 14, 21, 22, 23],
2:[6, 7, 8, 15, 16, 17, 24, 25, 26]}
with a for loop that will automatically create it. Sorry if this seems obvious, but I'm a bit of a noob and I'm having a lot of trouble with this.
It looks like you're generating the first 27 integers (starting at 0) and then grouping them. Let's write it like that.
def group_by_threes(n=27, group_count=3):
# The end result will be a dict of lists. The number of lists
# is determined by `group_count`.
result = {}
for x in range(group_count):
result[x] = []
# Since we're using subgroups of 3, we iterate by threes:
for x in range(n // 3):
base = 3 * x
result[x % 3] += [base, base + 1, base + 2]
# And give back the answer!
return result
This code could be made better by making the size of groups (three in this case) an argument, but I'll leave that as an exercise to the reader. ;)
The advantage of this method is that it's much more modular and adaptable than just writing a one-off method that generates the exact list you're looking for. After all, if you only wanted to ever generate that one list you showed, then it'd probably be better to hardcode it!
def create_list(x):
a = [x,x+1,x+2,x+9,x+9+1,x+9+2,x+18,x+18+1,x+18+2]
return a
output = {}
for i in range(3):
output[i*3] = create_list(i*3)
print output
please try this you get desired output
def create_list(x):
res = []
for i in xrange(0,3):
for j in xrange(0,3):
res.append(3*x+ 9*i + j)
return res
dictionary={}
for i in xrange(0,3):
dictionary[i]=create_list(i)
print dictionary
Result:
{0: [0, 1, 2, 9, 10, 11, 18, 19, 20], 1: [3, 4, 5, 12, 13, 14, 21, 22, 23], 2: [6, 7, 8, 15, 16, 17, 24, 25, 26]}

Python itertools with multiprocessing - huge list vs inefficient CPUs usage with iterator

I work on n elements (named "pair" below) variations with repetition used as my function's argument. Obviously everything works fine as long as the "r" list is not big enough to consume all the memory. The issue is I have to make more then 16 repetitions for 6 elements eventually. I use 40 cores system in cloud for this.
The code looks looks like the following:
if __name__ == '__main__':
pool = Pool(39)
r = itertools.product(pairs,repeat=16)
pool.map(f, r)
I believe i should use iterator instead of creating the huge list upfront and here the problem starts..
I tried to solve the issue with the following code:
if __name__ == '__main__':
pool = Pool(39)
for r in itertools.product(pairs,repeat=14):
pool.map(f, r)
The memory problem goes away but the CPUs usage is like 5% per core. Now the single core version of the code is faster then this.
I'd really appreciate if you could guide me a bit..
Thanks.
Your original code isn't creating a list upfront in your own code (itertools.product returns a generator), but pool.map is realizing the whole generator (because it assumes if you can store all outputs, you can store all inputs too).
Don't use pool.map here. If you need ordered results, using pool.imap, or if result order is unimportant, use pool.imap_unordered. Iterate the result of either call (don't wrap in list), and process the results as they come, and memory should not be an issue:
if __name__ == '__main__':
pool = Pool(39)
for result in pool.imap(f, itertools.product(pairs, repeat=16)):
print(result)
If you're using pool.map for side-effects, so you just need to run it to completion but the results and ordering don't matter, you could dramatically improve performance by using imap_unordered and using collections.deque to efficiently drain the "results" without actually storing anything (a deque with maxlen of 0 is the fastest, lowest memory way to force an iterator to run to completion without storing the results):
from collections import deque
if __name__ == '__main__':
pool = Pool(39)
deque(pool.imap_unordered(f, itertools.product(pairs, repeat=16)), 0)
Lastly, I'm a little suspicious of specifying 39 Pool workers; multiprocessing is largely beneficial for CPU bound tasks; if you're using using more workers than you have CPU cores and gaining a benefit, it's possible multiprocessing is costing you more in IPC than it gains, and using more workers is just masking the problem by buffering more data.
If your work is largely I/O bound, you might try using a thread based pool, which will avoid the overhead of pickling and unpickling, as well as the cost of IPC between parent and child processes. Unlike process based pools, Python threading is subject to GIL issues, so your CPU bound work in Python (excluding GIL releasing calls for I/O, ctypes calls into .dll/.so files, and certain third party extensions like numpy that release the GIL for heavy CPU work) is limited to a single core (and in Python 2.x for CPU bound work you often waste a decent amount of that resolving GIL contention and performing context switches; Python 3 removes most of the waste). But if your work is largely I/O bound, blocking on I/O releases the GIL to allow other threads to run, so you can have many threads as long as most of them delay on I/O. It's easy to switch too (as long as you haven't designed your program to rely on separate address spaces for each worker by assuming you can write to "shared" state and not affect other workers or the parent process), just change:
from multiprocessing import Pool
to:
from multiprocessing.dummy import Pool
and you get the multiprocessing.dummy version of the pool, based on threads instead of processes.
The second code example is slower because you're submitting a single pair to a Pool of 39 works. Only one worker will be processing your request and the other 38 will do nothing! Will be slower because you'll have overhead in piping data from the main thread to the workers processes.
You can "buffer" some pairs, then execute the set of pairs to balance out memory usage but still get advantage of the multiprocess environment.
import itertools
from multiprocessing import Pool
def foo(x):
return sum(x)
cpus = 3
pool = Pool(cpus)
# 10 is buffer size multiplier - the number of pair that each process will get
buff_size = 10*cpus
buff = []
for i, r in enumerate(itertools.product(range(20), range(10))):
if (i % buff_size) == (buff_size-1):
print pool.map(foo, buff)
buff = []
else:
buff.append(r)
if len(buff) > 0:
print pool.map(foo, buff)
buff = []
The output of the above will look like this
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 5, 6, 7, 8, 9, 10, 11, 12, 13]
[6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 8, 9, 10, 11, 12, 13, 14, 15, 16]
[9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 11, 12, 13, 14, 15, 16, 17, 18, 19]
[12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 14, 15, 16, 17, 18, 19, 20, 21, 22]
[15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 17, 18, 19, 20, 21, 22, 23, 24, 25]
[18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28]
Play with the buff_size multiplier to get the right balance for your system!

My print function syntax is causing an error in python 3

I have a list of lists with tuples. I want to get the length of a tuple using:
item1=(4, 8, 16, 30)
list6=[[(4, 8, 16, 29)], [(4, 8, 16, 30)], [(4, 8, 16, 32)]]
print("list6.index((4, 8, 16, 29)):",list6.index([item1]))
print("len(list6[1]):"), len(list6[1])
Output:
list6.index((4, 8, 16, 29)): 1
len(list6[1]):
There is no value for len(list6[1]). Can someone show me the correct syntax for this?
The code works fine in Python 2. If you are using Python 3, there is an issue with last line, because print is a function. So, because of where you've put the close parenthesis, only the first part is actually passed to print. Try this instead
print("len(list6[1]):", len(list6[1]))

Categories

Resources