Pregunta

So I need to create 3 functions for this assignment. The first should do the following

numCol(): When dealing with plain text (and data written in plain text), it can be helpful to have a “scale” that indicates the columns in which characters appear. We create a scale using two lines (or “rows”). In the second row, we print 1234567890 repeatedly. In the first row (i.e., the line above the second row), we write the “tens” digits above the zeros in the second row as shown in the listing below. This function takes one argument, an integer, and prints a scale the length of your quote. It doesn't return anything.

The second should

docQuote(): Takes three arguments: 1) the quote as a string, 2) the slice start value, and 3) the slice end value. It returns the doctored string.

The third should

main(): Takes no arguments and returns nothing. Prompts user for original quote and number of slices needed. Then in a for-loop, calls numCol() in such a way that the scale is the length of the quote, prompts the user for the start and end slice values (recall that the end value isn’t included in the slice), and then calls docQuote(). Finally, it prints the final doctored quote.

If the program is correct its output should look as follows:

1.  Enter quote: Money is the root of all evil.
2.  Enter the number of slices needed: 2
3.  1 2
4.  012345678901234567890123456789
5.  Money is the root of all evil.
6.  Start and end for slicing separated by a comma: 8, 20
7.  1
8.  012345678901234567
9.  Money is all evil.
10. Start and end for slicing separated by a comma: 12, 17
11. -> Money is all.

What I have so far: (Will update if I figure something out)

def numCol(x):
    col=[]
    for i in range(1,(round(n)//10)+1):
        col.append(str(i))
    print("         ","         ".join(col),end="")


def docQuote(x,y,z):
   return

def main():
   x=input("Enter quote: ")
   y=int(input("Enter the number of slices needed: "))
   numCol(len(x)-1)
   print(x)

main()
¿Fue útil?

Solución

Ok: you have to define a function called numCol which takes one integer argument:

def numCol(n):

then you have to print a line consisting of n characters, where every tenth character is an incrementing integer and every other character is a space.

    chars = []
    for i in range(1, n+1):
        if i % 10:
            chars.append(" ")
        else:
            chars.append(str((i % 100) // 10))
    print(''.join(chars))

and finally a row consisting of 'n' chars, being 1234567890 repeating:

    chars = []
    for i in range(1, n+1):
        chars.append(str(i % 10))
    print(''.join(chars))

which then runs as

>>> numCol(65)
         1         2         3         4         5         6     
12345678901234567890123456789012345678901234567890123456789012345

Edit:

In response to @AdamSmith:

Let's see some actual numbers:

from textwrap import dedent
from timeit import Timer

test_statements = [
    (
        "n = 65",
        """
        # as a for-loop
        chars = []
        for i in xrange(1, n+1):
            if i % 10:
                chars.append(" ")
            else:
                chars.append(str((i % 100) // 10))
        """
    ),
    (
        "n = 65",
        """
        # as a list comprehension
        chars = [" " if i%10 else str((i%100)//10) for i in xrange(1,n+1)]
        """        
    ),
    (
        "n = 65",
        """
        # extra cost of list-to-string
        chars = [" " if i%10 else str((i%100)//10) for i in xrange(1,n+1)]
        s = ''.join(chars)
        """        
    ),
    (
        "n = 65",
        """
        # vs cost of generator-to-string
        chars = (" " if i%10 else str((i%100)//10) for i in xrange(1,n+1))
        s = ''.join(chars)
        """        
    ),
    (
        "s = '         1         2         3         4         5         6     '",
        """
        # cost of actually displaying string
        print(s)
        """
    )
]

for setup,run in test_statements:
    res   = Timer(dedent(run), setup)
    times = res.repeat()   # 3 * 1000000 runs
    print("{:7.1f}".format(min(times))   # time of one loop in microseconds

on my system (i5-760, Win7 x64, Python 2.7.5 64bit) this gives

   15.1   # for-loop -> list of chars
   10.7   # list comprehension -> list of chars
   11.4   # list comprehension -> string
   13.6   # generator expression -> string
  132.1   # print the string

Conclusions:

  • a list comprehension is 29% faster than a for-loop at building a list of characters

  • a generator expression is 19.6% slower than a list comprehension at building a list of characters and joining to a string

  • it's pretty much irrelevant, because actually printing the output takes 9 times longer than generating it with any of these methods - by the time you print the string out, using a list comprehension (fastest) is just 2.9% faster than the for-loop (slowest).


@user3482104

If you really want to avoid if ... else, you can do

if stmt:
    do_a()
if not stmt:    # same effect as 'else:'
    do_b()

but be aware that this has to evaluate stmt twice where else only evaluates it once.

Also, because both loops are iterating over the same range (same start/end values), you can combine the loops:

def numCol(n):
    firstline  = []
    secondline = []

    for i in range(1, n+1):
        i %= 100
        tens, ones = i // 10, i % 10
        if ones:        # ones != 0
            firstline.append(" ")
        if not ones:    # ones == 0    # <= 'else:'
            firstline.append(str(tens))
        secondline.append(str(ones))

    print(''.join(firstline))
    print(''.join(secondline))
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top