Re: [Tutor] Differences between while and for

2019-06-15 Thread Steven D'Aprano
On Sat, Jun 15, 2019 at 02:53:43PM +1000, mhysnm1...@gmail.com wrote:
> All,
> 
>  
> 
> In C, Perl and other languages. While only uses a conditional statement and
> for uses an iteration. In python while and for seems to be the same and I
> cannot see the difference.

Python ``while`` uses a conditional statement, and Python ``for`` uses 
iteration. Python's ``for`` is like "foreach" in some other languages.

while condition: ...

for x in values: ...


> Python does not have an until (do while) where
> the test is done at the end of the loop. Permitting a once through the loop
> block. Am I correct or is there a difference and if so what is it?

Correct, there is no "do until" in Python.

> Why doesn't Python have an until statement?

Because Guido didn't want one :-)

Because it is unnecessary: any "do until" can be written as a regular 
while loop, using a break:

# do...until with test at the end
while True:
do_something()
if test:
   break


# "loop and a half"
# https://users.cs.duke.edu/~ola/patterns/plopd/loops.html#loop-and-a-half
while True:
do_something()
if test:
break
do_something_else()



-- 
Steven
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] deleting elements out of a list.

2019-06-15 Thread Cameron Simpson

On 15Jun2019 14:51, Sean Murphy  wrote:
I am not sure how to tackle this issue. I am using Windows 10 and 
Python 3.6 from Activestate.


I have a list of x number of elements. Some of the elements are have similar
words in them. For example:

Dog food Pal
Dog Food Pal qx1323
Cat food kitty
Absolute cleaning inv123
Absolute Domestic cleaning inv 222
Absolute d 
Fitness first 02/19
Fitness first


I'm going to assume that you have a list of strings, each being a line 
from a file.



I wish to remove duplicates. I could use the collection.Count method. This
fails due to the strings are not unique, only some of the words are.


You need to define this more tightly. Suppose the above were your input.  
What would it look like after "removing duplicates"? By providing an 
explicit example of what you expect afterwards it is easier for us to 
understand you, and will also help you with your implementation.


Do you intend to discard the second occurence of every word, turning 
line 2 above into "qx1323"? Or to remove similar lines, for some 
definition of "similar",

which might discard line 2 above?

Your code examples below seem to suggest that your want to discard words 
you've already seen.



My
thinking and is only rough sudo code as I am not sure how to do this and


Aside: "pseudo", not "sudo".


wish to learn and not sure how to do without causing gtraceback errors. I
want to delete the match pattern from the list of strings. Below is my
attempt and I hope this makes sense.

description = load_files() # returns a list
for text in description:
   words = text.split()
   for i in enumerate(words):


enumerate() yields a sequence of (i, v), so you need i, v in the loop:

 for i, word in enumerate(words):

Or you need the loop variable to be a tuple and to pull out the 
enumeration counter and the associated value inside the loop:


 for x in enumerate(words):
   i, word = x


   Word = ' '.join(words[:i])


Variable names in Python are case sensitive. You want "word", not 
"Word".


However, if you really want each word of the line you've got that from 
text.split(). The expression "words[:i]" means the letters of word from 
index 0 through to i-1. For example, "kitt" if "i" were 4.


The join string operation joins an iterable of strings. Unfortunately 
for you, a string is itself iterable: you get each character, but as a 
string (Python does not have a distinct "character" type, it just has 
single character strings). So if "word" were "kitt" above, you get:


 "k i t t"

from the join. Likely not what you want.

What _do_ you want?


   print (word)
   answer = input('Keep word?')
   if answer == 'n':
   continue
   for i, v in enumerate(description):
   if word in description[i]:
   description.pop[i]


There are some problems here. The big one is that you're modifying a 
list while you're iterating over it. This is always hazardous - it 
usually leading to accidentally skipping elements. Or not, depending how 
the iteration happens.


It is generally safer to iterate over the list and construct a distinct 
new line to replace it, without modifying the original list. This way 
the enumerate cannot get confused. So instead of discarding from the 
list, you conditionally add to the new list:


 new_description = []
 for i, word in enumerate(description):
   if word not in description[i]:
 new_description.append(word)

Note the "not" above. We invert the condition ("not in" instead of "in") 
because we're inverting the action (appending something instead of 
discarding it).


However, I think  you have some fundamental confusion about what your 
iterating over.


I recommend that you adopt better variable names, and more formally 
describe your data.


If "description" is actualy a list of descriptions then give it a plural 
name like "descriptions". When you iterate over it, you can then use the 
singular form for each element i.e.  "description" instead of "text".


Instead of writing loops like:

 for i, v in enumerate(descriptions):

give "v" a better name, like "description". That way your code inside 
the loop is better described, and mistakes more obvious because the code 
will suddenly read badly in some way.


The initial issues I see with the above is the popping of an element 
from

description list will cause a error.


It often won't. Instead if will mangle your iteration because after the 
pop the index "i" no longer refers to what you expect, it now points one 
word further along.


Towards the _end_ of the loop you'll get an error, but only once "i" 
starts to exceed the length of the list (because you've been shortening 
it).



If I copy the description list into a
new list. And use the new list for the outer loop. I will receive multiple
occurrences of the same text. This could be addressed by a if test. But I am
wondering if there is a better method.


The common idom is to leave the original unchanged and copy into a new 
list

Re: [Tutor] Differences between while and for

2019-06-15 Thread Cameron Simpson

On 15Jun2019 14:53, Sean Murphy  wrote:
In C, Perl and other languages. While only uses a conditional statement 
and

for uses an iteration. In python while and for seems to be the same and I
cannot see the difference.


No, they're really much as in other languages.

In general (most languages), a for loop is for iterating over some 
collection or list.  A while is not explicitly for iteration over some 
collection, it is for repeating an action until some condition fails (or 
the inverse of the condition is achieved).


Let's take C's for loop. It really is closely related to a while. That's 
because C is a pretty low level language. Early C is almost like a 
structured assembly language (well, it is a lot better, but it is 
deliberately close to the underlying machine). So C's for loop goes:


 for (setup; condition; advance)
   statement-or-block

You can leave any of these out. It is equivalent to this while loop:

 setup
 while condition:
   statement-or-block
   advance

but it is almost always used for iteration:

 s="foo"
 for (i=0; s[i]; i++)
   ...

which counts "i" along the string "s". You _can_ use of for arbitrary 
while loops, but idiomatically that is rarely done - it is conceptually 
useful to use "for" for various kinds of iteration and "while" for more 
arbitrary repetition.


Python is a bit more rigid. The "while" loop is just like "while" in 
other languages: do something while a condition holds. But a "for" loop 
in Python is inherently about iteration; it is defined as:


 for variable in iterable:
   suite

and applies to any "iterable", some object or expression which can be 
iterated over. Any object which is iterable may be used. So it is very 
oriented towards collections of various kinds: lists, tuples, dictionary 
(iterates over the keys) and so on.



Python does not have an until (do while) where
the test is done at the end of the loop. Permitting a once through the loop
block. Am I correct or is there a difference and if so what is it?


You're correct.


Why doesn't Python have an until statement?


Basicly because it isn't necessary. It is usually easy enough to work 
around the lack that nobody has made a conincing case (meaning nobody 
has convinced the core developers). It would probably be written:


 do:
   ...
 while condition

in some form if it ever came in to avoid using an new keyword ("until").

It does sometimes take a little contortion to make a do/while loop into 
a Python while - you usually have to perform some kind of hack to make 
the condition initially true. In the extreme case you just treat the 
first loop specially:


 first = True
 while first or the-actual-condition:
   ... do stuff ...
   first = False

if you want to use "first" during the "do stuff". Or you could be a bit 
more reliable and go:


 first_test = True
 while first_test or the-actual-condition:
   first_test = False
   ... do stuff ...

putting the flag up the top next to the condition.

Cheers,
Cameron Simpson 
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] Follow-up on my removing elements from lists question.

2019-06-15 Thread mhysnm1964
This is a follow-up on my previous question for removing elements. Below is
the code I am currently using. I am removing the elements at the end of the
outer loop. The data structure goes along this:

 

[ 

  ['123123',[2019-2-18', 'transaction text', 'amount'],

v  ['123123',[2019-2-18', 'transaction text', 'amount'],

  ['123123',[2019-2-18', 'transaction text', 'amount']

]

 

The 2nd column where the transaction text I am modifying the content and
using the end result of the built-up words as the string match as you will
see in the code. This is all working fine. The last loop in the code I am
trying to delete the elements in reverse order. This doesn't work. The
length of the list reduces by 1. When it should have reduced by 42. Is the
logic wrong? This is in Python 3.6 under windows 10.

 

unknown_transactions.sort(key=lambda x: x[2])

while True:

# re-initialise each time the current transaction text has been processed.

for row in unknown_transactions:

# remove common words from transactions which are not required. Such
as 'WITHDRAWAL' and 'DEPOSIT'.

line = regex_transaction(row[2])

# If the common words are not found, return a null and do not modify
the transaction description.

if line != '': # not a null string

# now find unique string and add it to the compare_transactions
list object.

words = line.split()

print ('List length:', len(unknown_transactions))

word = ''

for i, v in enumerate(words, start=1):

word = ' '.join(words[:i])

print (word)

answer = input('Use  word y, otherwise any other key
continues...')

if answer != 'y':

continue

# end if 

# end for 

# now loop through the unknown transactions and copy to
transaction dictionary

delete_transactions = []

for e, v in enumerate (unknown_transactions):

if word in unknown_transactions[e][2]:

if not word  in transaction:

transaction[word] = unknown_transactions

else:

transaction[word].append(unknown_transactions)

# end if  

delete_transactions.append (e)

# end if 

# end for 

print ('number of elements to remove:',
len(delete_transactions))

for del_element in reversed(delete_transactions):

unknown_transactions.pop(del_element)

# end if 

# end for 

if len(unknown_transactions) == 0:

break

# end if 

# end while

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Follow-up on my removing elements from lists question.

2019-06-15 Thread Alex Kleider

On 2019-06-15 02:35, mhysnm1...@gmail.com wrote:
This is a follow-up on my previous question for removing elements. 
Below is
the code I am currently using. I am removing the elements at the end of 
the

outer loop. The data structure goes along this:



[

  ['123123',[2019-2-18', 'transaction text', 'amount'],

v  ['123123',[2019-2-18', 'transaction text', 'amount'],

  ['123123',[2019-2-18', 'transaction text', 'amount']

]



I suggest you match up your single quote and your square bracket pairs.
It looks to me that you have one extra single quote and one extra 
opening square bracket in each line (or perhaps you're missing their 
closing partners.)

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Follow-up on my removing elements from lists question.

2019-06-15 Thread Mats Wichmann
On 6/15/19 3:35 AM, mhysnm1...@gmail.com wrote:

Data structure:

  ['123123',[2019-2-18', 'transaction text', 'amount'],

I presume the second opening brace is a typo and was supposed to be a
quote mark?

> The 2nd column where the transaction text I am modifying the content and
> using the end result of the built-up words as the string match as you will
> see in the code. This is all working fine. The last loop in the code I am
> trying to delete the elements in reverse order. This doesn't work. The
> length of the list reduces by 1. When it should have reduced by 42. Is the
> logic wrong? This is in Python 3.6 under windows 10.

There's a lot that looks odd in this code, let me poke at a few:

You _appear_ to be be trying to avoid modifying 'unknown_transactions'
while looping over it, which is admirable if that was the intent:

for e, v in enumerate (unknown_transactions):
if word in unknown_transactions[e][2]:
if not word  in transaction:
transaction[word] = unknown_transactions
else:
transaction[word].append(unknown_transactions)
delete_transactions.append (e)
for del_element in reversed(delete_transactions):
unknown_transactions.pop(del_element)

but that whole sequence is inside another loop over
'unknown_transactions'.  Is that intentional?  It seem odd to loop over
something inside a loop over that thing.

As a hint, if you want to modify a list while looping you can loop over
a copy of it, like

  for s in somelist[:]:

or if you don't like the slice notation,

  for s in list(somelist):

you're looping over 'unknown_transactions' here, but you're not using
the loop value 'v' at all in the body. Perhaps that's the thing you
wanted to add to 'transactions'? adding 'unknown_transactions' seems
strange.

usually if you're using multiple levels of indexing you're not
necessarily wrong, but leaving yourself (or others) hard to read code.
In the past I've written such things and a year later I come back to
look and wonder about the magic in something like [e][2]:

   if word in unknown_transactions[e][2]:

You can unpack each transaction list instead to avoid indexing it, and
if you are deleting on the spot, you don't need the enumerate value
either. So a possible rewrite could be:

  for u in unknown_transactions[:]:
  id, date, text, amount = u
  if word in text:
  if not word in transaction:
  transaction[word] = u
  else:
  transaction[word].append(u)
  unknown_transactions.remove(u)

the inner 'if' statement could become a try block as well if you wanted:

  try:
  transaction[word].append(u)
  except KeyError:
  transaction[word] = u

And you can save a level of indentation by inverting your early
if-statement, from

if line != '':
whole bunch of code

to

if not line:
continue
whole bunch of code

Just to make things a little more readable.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Differences between while and for

2019-06-15 Thread Alan Gauld via Tutor
On 15/06/2019 05:53, mhysnm1...@gmail.com wrote:

> In C, Perl and other languages. 

As a point of interest not all languages have these constructs.
Oberon, for example, only has a while loop because it can be
used to simulate all other loop types. Some Lisp dialects
don't even have a loop construct because recursion can be
used instead.

In addition to for, while and repeat/until some languages
(eg ADA and some BASICs) include a general loop construct.

And of course in assembler GOTO is the ultimate loop construct.

Don;t assume that just because one language supports a
particular construct that others will or should also support
it. The variety of control structures offered is one of the
defining features of any programming language.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] Installing Python v3 on a laptop Windows 10

2019-06-15 Thread Ken Green

It has been some 18 months that I last
installed Python onto my laptop Windows.

Having had freshly completely reinstalled
Windows 10 and its various updates. I already
installed PSREdit500 successfully several
weeks ago, I am now ready to install Python,
preferable the latest version of Python 3.

I understood there is a preferable method
of installing Python into Windows. I pray
tell on how about to do it, gentlemen.

I have been using Python v2.7.15 along with
Geany v1.32 in my computer running on Ubuntu
18.04.2. As you can see, there is a sharp
learning curve for me on how to use and learn
Python v3. Thanks.

Ken
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] deleting elements out of a list.

2019-06-15 Thread Alan Gauld via Tutor
On 15/06/2019 05:51, mhysnm1...@gmail.com wrote:

Caveat: I'm picking this up late in the day and only had a cursory look
at it, so may be missing some critical insight...

> I have a list of x number of elements. Some of the elements are have similar
> words in them. For example:

Define "similar".
It implies not identical. What is different? What makes them
similar? Every time you introduce vague inequalities you imply
the need for some kind of intelligent function that removes
the ambiguity and vagueness. it  definitively says that these
two items are similar or not similar.

Can you write such a function? If so the problem should become
relatively simple.


> Dog food Pal
> Dog Food Pal qx1323 
> Cat food kitty
> Absolute cleaning inv123
> Absolute Domestic cleaning inv 222
> Absolute d 
> Fitness first 02/19
> Fitness first
> 
> I wish to remove duplicates. 

So what would the output look like if the above is the input?
My guess of what you want is:

qx1323
Cat kitty
Domestic
d 
02/19

Is that right?
Or is my idea of similar and duplicate different to yours?

> I could use the collection.Count method. This
> fails due to the strings are not unique, only some of the words are. 

Sorry, I can't understand that. It makes no sense to me.
You need to define strings and words in this context

> description = load_files() # returns a list

A list of what? characters, words, lines?

> for text in description:
> words = text.split()
> for i in enumerate(words):
> Word = ' '.join(words[:i])

This is weird. enumerate returns tuples which you assign to i.
But then you use i in a slice opertion. But slice expects an
integer.


> print (word)
> answer = input('Keep word?')
> if answer == 'n':
> continue 
> for i, v in enumerate(description):
> if word in description[i]:
> description.pop[i]

Without any clue what the description data looks like we
can't really decipher what the code above does.

> description list will cause a error. If I copy the description list into a
> new list. And use the new list for the outer loop. I will receive multiple
> occurrences of the same text. 

I'm not sure thats true but it denends on what description looks like.

> 
> description = load_files() # returns a list
> 
> search_txt = description.copy() 
> 
> for text in search_txt:
> words = text.split()
> for i in enumerate(words):
> Word = ' '.join(words[:i])
> print (word)
> answer = input('Keep word (ynq)?')
> if answer == 'n':
> continue 
> elif answer = 'q':
> break
> 
> for i, v in enumerate(description):
> if word in description[i]:
> description.pop[i]

The usual way to remove things from a list is to create a
new list using a filter

newlist = filter(test_function, oldlist)

or a list comprehension

newlist = [item for item in oldlist if test_function(item)]

Which brings us back to the beginning. Can you write a test
function that unambiguously defines what needs to be removed?


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Follow-up on my removing elements from lists question.

2019-06-15 Thread David L Neil

On 15/06/19 9:35 PM, mhysnm1...@gmail.com wrote:

This is a follow-up on my previous question for removing elements. Below is
the code I am currently using. I am removing the elements at the end of the
outer loop. The data structure goes along this:
[
   ['123123',[2019-2-18', 'transaction text', 'amount'],
v  ['123123',[2019-2-18', 'transaction text', 'amount'],
   ['123123',[2019-2-18', 'transaction text', 'amount']
]
The 2nd column where the transaction text I am modifying the content and
using the end result of the built-up words as the string match as you will
see in the code. This is all working fine. The last loop in the code I am
trying to delete the elements in reverse order. This doesn't work. The
length of the list reduces by 1. When it should have reduced by 42. Is the
logic wrong? This is in Python 3.6 under windows 10.

unknown_transactions.sort(key=lambda x: x[2])
while True:
# re-initialise each time the current transaction text has been processed.
 for row in unknown_transactions:
 # remove common words from transactions which are not required. Such
as 'WITHDRAWAL' and 'DEPOSIT'.
 line = regex_transaction(row[2])
 # If the common words are not found, return a null and do not modify
the transaction description.



(from a very weak understanding of your previous question and the total 
code-base thus far)


Consideration nr1:
Write the code as comments first. Initially these will be at a fairly 
'high level'. These comments can later be turned into function/method 
names, and more comments added within those. Wash, rinse, and repeat. 
The idea is to help re-state your thinking into Python code, and to 
structure the code into functional units. Even skilled Python-coders 
often find that this helps to keep the use-case foremost in-mind.


Consideration nr2:
(assuming that the total data-volume is easily RAM-resident)
Rather than (appearing to) taking-in a 'group' of transactions and then 
select them according to ease/difficulty of 'translation', gradually 
removing/whittling the numbers down - hopefully to zero; why not 
consider adding another field to each record, which will note if it has 
already been processed (by whichever method) or conversely, which 
list-elements are yet to be completed? Thus each method of 
interpretation will first check the 'completed' field, and if not 
complete, apply the relevant analysis... Thus there is no concept of 
'removal' and no danger of 'losing' anything!


--
Regards =dn
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Installing Python v3 on a laptop Windows 10

2019-06-15 Thread Alan Gauld via Tutor
On 15/06/2019 22:23, Ken Green wrote:

> I understood there is a preferable method
> of installing Python into Windows. I pray
> tell on how about to do it, gentlemen.

It depends a bit on which python distribution you use,
there are several.

Personally for Windows I always recommend the ActiveState free
version. It bundles several useful extra Windows tools and
puts the docs in Windows help format for you.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Installing Python v3 on a laptop Windows 10

2019-06-15 Thread eryk sun
On 6/15/19, Alan Gauld via Tutor  wrote:
> On 15/06/2019 22:23, Ken Green wrote:
>
>> I understood there is a preferable method
>> of installing Python into Windows. I pray
>> tell on how about to do it, gentlemen.
>
> It depends a bit on which python distribution you use,
> there are several.
>
> Personally for Windows I always recommend the ActiveState free
> version. It bundles several useful extra Windows tools and
> puts the docs in Windows help format for you.

The compiled HTML (python*.chm) documentation is also included in the
official PSF (python.org) distribution. It's in the "Doc" folder. The
installer should create a shortcut to it in the start menu.

The current release of Windows 10 includes a `python` command that
installs the 3.7 app bundle from the Microsoft Store. This is a simple
one-click install method that should be easy for anyone. Unfortunately
the above-mentioned python37.chm file is not included in this
distribution.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Installing Python v3 on a laptop Windows 10

2019-06-15 Thread Mats Wichmann
On 6/15/19 3:23 PM, Ken Green wrote:\


You've already gotten some good answers, don't consider this as
contradictory.

> I understood there is a preferable method
> of installing Python into Windows. I pray
> tell on how about to do it, gentlemen.

There isn't, there are actually many ways, and to some extent it depends
on what you want to do.  For example, in addition to what you've heard,
these days there are a ton of people doing data analysis, Big Data, etc.
and they often prefer to install Python through the Anaconda
distribution, which has optimised for getting the particularly relevant
packages installed easily alongside and in sync with Python, and then
keeping those up to date.

In the near future, but maybe not quite there yet, Windows 10 will also
have a Python "app" preinstalled, which, when you launch it, installs
the current version of Python through the Microsoft Store.  I think you
can already install via the Microsoft Store, but it's not something that
magically appears on your system even before you think to look for it...
see here:

https://www.microsoft.com/en-us/p/python-37/9nj46sx7x90p?activetab=pivot:overviewtab

That looks like it wants later than the 1809 version, but should be
ready for the 1903 version of Windows 10?


and you wanted a simple answer

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor