× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



If pip has already been upgraded, I wouldn't touch it. We'll be pushing
out an update to prevent the upgrade check, so this should not be an issue
in the future.
 
Looks like the code was modified from one of my examples, probably taken
from a slide. I regularly have to massage the python formatting to fit
examples on to slides. I use the trim_col function in a contrived example
to show how Python's list comprehensions _can_ be used, though I agree
that using SQL to trim them would likely be more efficient.
 
The list comprehension works fine when using a normal cursor object, but
not when using the wrapper since it is now a dictionary instead of a
tuple. In addition, you would want to do the inverse of what the wrapper
is doing to create the list of column values or your CSV may end up with a
different order of outputs as the order of items in dictionaries is not
guaranteed (at least not until 3.7). Changing the wrapper to create an
OrderedDict
([1]https://docs.python.org/3/library/collections.html#collections.OrderedDict)
would ensure that across versions, though.
 

----- Original message -----
From: John Yeung <gallium.arsenide@xxxxxxxxx>
Sent by: "OpenSource" <opensource-bounces@xxxxxxxxxxxxxxxxxx>
To: IBMi Open Source Roundtable <opensource@xxxxxxxxxxxxxxxxxx>
Cc:
Subject: Re: [IBMiOSS] [EXTERNAL] Re: beginning python
Date: Wed, Dec 18, 2019 12:30 PM
 
> So I had already updated PIP prior to [Kevin Adler's] reply.   Should
I try to uninstall PIP and reinstall via  YUM, or just leave well enough
alone?

I will let him answer that, as he's the expert.

I do have a lot of comments about Python, though:

> Also, Thanks for the wrapper.  I have it implemented, but I'm still
having issues.  I can now print my fields, but can't make it write to a
.csv.

Personally, I would have suggested not using the wrapper to start
with. At least not until you understand what it's giving you, which is
a dictionary.

> I'm stuck on the csvf.writerow line at the bottom.
> Am I reading this correctly, that it is doing a for loop passing in
the column name to trim_col?

Basically, yes. But it's doing quite a bit more. It's creating a list
by doing a(n implicit) `for` loop and appending to the list on each
iteration.

> When it writes, it produces the column headings, not the values.
> I can't figure out how to pass the values

You need to understand Python dictionaries. They are pretty much the
bread-and-butter of the language.

A dictionary is a collection of (key, value) pairs. Iteration over a
dictionary is defined as iteration over the keys only. In other words,

    for x in mydict:
        pass

is equivalent to

    for x in mydict.keys():
        pass

This is a design decision that perhaps not everyone would have made,
but it was carefully considered and deemed a good balance between
readability and convenience for real-world use.

If you want to get the values, the most straightforward change to your
code is probably

    csvf.writerow([trim_col(col) for col in row.values()])

But there are a number of other tips I'd like to share:

> from csv import writer, QUOTE_NONNUMERIC

If you want Excel-compatible CSVs (that is, CSVs that are formed the
way that Excel writes them), then you shouldn't bother with any of the
configuration constants. QUOTE_NONNUMERIC is generally superfluous and
will make your CSVs slightly bigger (due to extra quotes that Excel
wouldn't have written). Excel is somewhat forgiving when reading CSVs,
so it shouldn't hurt to use the extra quotes when writing, but it's
unnecessary clutter at best.

> query = "select uiiac, umsts, uiasd, count(umsts) as reccount from
mslib.uact \
>          left outer join mslib.uast on umsts = uiasc \
>          group by uiiac, umsts, uiasd with rollup \
>          order by uiiac, umsts"

Continuing long lines with backslash is considered by most Python
programmers the least desirable way to handle long lines.

In the specific case of strings, it's definitely preferred to use
triple-quotes. You could, for example, write the above as

    query = '''
        select uiiac, umsts, uiasd, count(umsts) as reccount from
mslib.uact
        left outer join mslib.uast on umsts = uiasc
        group by uiiac, umsts, uiasd with rollup
        order by uiiac, umsts'''

Note that triple-quotes *do* include the newlines, whereas backslashes
do not. But for SQL statements (and HTML), extra whitespace of any
kind is semantically collapsed to a single space, so it doesn't
matter. If you needed to precisely control the whitespace in a string
literal yourself, you could use the implicit line continuation
afforded by parentheses, combined with the implicit concatenation of
adjacent string literals, like so:

    query = (
        'select uiiac, umsts, uiasd, count(umsts) as reccount from
mslib.uact'
        ' left outer join mslib.uast on umsts = uiasc'
        ' group by uiiac, umsts, uiasd with rollup'
        ' order by uiiac, umsts')

Notice that if you do this, you need to have the separating whitespace
either at the end of each string fragment other than the last, or at
the beginning of each fragment other than the first. (I've done the
latter above.)

Also, as a style note, most Python programmers would not indent quite
like I've done in either of those examples (even though I would, and
actually do in my own code). Most of them would assume a monospaced
font, keep the `select` on the same line as `query`, and line up the
subsequent lines with the `select`. Also, many would put the closing
paren on the left edge, to line up with `query`.

> # Strip trailing spaces as applicable
> def trim_col(s):
>     return s.rstrip() if hasattr(s, 'rstrip') else s

This is a handy thing to use, and it's particularly helpful if you
have a lot of columns; but if you only need to trim a few columns, I
recommend doing it in SQL rather than in Python. (In general, the SQL
engine is fast and Python is slow, so it's preferable to give more of
the load to the SQL engine.)

> with open('actbysts.csv', 'w', newline='') as file:
>     csvf = writer(file, quoting=QUOTE_NONNUMERIC)
>     for row in CursorByName(cur):
>     if row['UIIAC'] is not None  and row['UMSTS'] is not None and
row['UIASD'] is not None:
>         csvf.writerow([trim_col(col) for col in row])

When sharing Python code, it is especially important to watch the
indentation. As written, the above contains a syntax error, because
there is no body to the (explicit) `for` loop. I know that the code
you actually executed doesn't have this problem, because you got
*something* to write in your CSV, rather than a syntax error. But it
won't always be the case that an indentation error produces a syntax
error. Very often, it will simply indicate different semantics than
what you intended, but still be valid Python code.

Oh, and finally, it's best to avoid using the word "file" as a
variable name if you can help it, because that is the name of a
built-in function in Python. By convention, almost everyone simply
uses the letter `f` in cases like the code snippet above.

OK, I'm sure that's much longer than anyone wanted to read. Give
yourself a gold star if you've made it to the end.

John Y.
--
This is the IBMi Open Source Roundtable (OpenSource) mailing list
To post a message email: OpenSource@xxxxxxxxxxxxxxxxxx
To subscribe, unsubscribe, or change list options,
visit: [2]https://lists.midrange.com/mailman/listinfo/opensource ;
or email: OpenSource-request@xxxxxxxxxxxxxxxxxx
Before posting, please take a moment to review the archives
at [3]https://archive.midrange.com/opensource ;.

Help support midrange.com by shopping at amazon.com with our affiliate
link: [4]https://amazon.midrange.com ;
 

 

References

Visible links
1. https://docs.python.org/3/library/collections.html#collections.OrderedDict
2. https://lists.midrange.com/mailman/listinfo/opensource
3. https://archive.midrange.com/opensource
4. https://amazon.midrange.com/

As an Amazon Associate we earn from qualifying purchases.

This thread ...


Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.