Re: [Tutor] python memory management

2016-09-03 Thread monik...@netzero.net

By:
"reference cycles: if one object has a reference to another, and 
that second object also has a reference to the first, that's a cycle."

Is this what you mean? 
a = 5
b = a
a = b

I just want to make sure I understand.
Thank you very much for your explanation. 
Monika

-- Original Message --
From: Steven D'Aprano 
To: tutor@python.org
Subject: Re: [Tutor] python memory management
Date: Fri, 2 Sep 2016 04:10:02 +1000

On Thu, Sep 01, 2016 at 02:12:11PM +, monik...@netzero.net wrote:
> Hi:
> Can somebody please explain how memory is managed by python? What kind 
> of memory it uses? What structures use what kind of memory?
> If many people work on the same project and have many instances of the 
> same object how do they ensure that all instances are killed before 
> the programs exit? Apparently if one of the programmer leaves a 
> reference to object it might not be automatically deleted by python on 
> exit. What is the command to do this?
> 
> Could somebody please explain how this works, especially on projects 
> involving multiple programmers?


In general, you (almost) never need to care about memory management, 
Python will do it for you.

The number of programmers writing the code doesn't matter. What matters 
is how many times the program is running *at the same time*. Each time 
it runs, your computer's operating system (Windows, Linux, Mac OS X) 
will start what is called "a process", running the Python interpreter. 
When the process exits at the end, the OS will reclaim all the memory 
used and make it available for the next process.

While the program is running, the OS has to allocate memory between many 
different processes. On my computer, right now, I have over 200 
processes running. Most of them are handled by the OS, but the others 
include my email program, my web browser, a few text editors, my desktop 
manager, and many others. The OS manages the memory allocation.

As far as Python is concerned, it manages its own memory from what the 
OS gives it. When you assign a value:

name = "Inigo Montoya"

the Python interpreter allocates a chunk of memory in the memory heap to 
hold the string. It then tracks whether or not the string is being used. 
So long as the string is being used by your program, or *could possibly* 
be used, Python will hold onto that string, forever.

But as soon as it sees that it can no longer be used, it will free the 
memory and reuse it.

This process is called "garbage collection". You can google for more 
information, or ask here. Different Python interpreters use different 
garbage collectors:

IronPython uses the .Net garbage collector;

Jython uses the Java garbage collector;

PyPy has a few different ones that you can choose from;

and the CPython (that's the standard Python you are probably running) 
interpreter has two, a simple "reference counter" GC that works very 
fast but not very thoroughly, and a more thorough GC that picks up 
anything the reference counter can't handle.

(Mostly reference cycles: if one object has a reference to another, and 
that second object also has a reference to the first, that's a cycle. 
The reference counter can't deal with that, but the second GC can.)


Let's track the life-span of a chunk of memory. Suppose you write the 
following code in a module:


name = "Inigo Montoya"
print(name)
name = "The Dread Pirate Roberts"


The second assignment frees up the string "Inigo Montoya", as no part of 
your program can possibly access the old value any more, since it has 
been replaced by the new value. So the garbage collector frees that 
chunk of memory and makes it available for something else. This happens 
automatically, and virtually instantly.

You never need to care about allocating or deallocating memory. The 
interpreter has its own memory manager to do that, with a garbage 
collector to deallocate memory.

So, when do you need to care about memory?

- If you are writing a C extension, you have to manage your own memory.

- If you're using the ctypes module, you have access to the C code of 
  the interpreter, so you have to care about managing your own memory.

- If you're creating massively huge strings or lists, you might have to 
  worry about running out of memory.

For example, I once locked up my computer by foolishly creating a HUGE 
list:

# Don't try this at home!
L = list(range(100**100))


That would need to find enough memory for a list with one hundred 
trillion trillion trillion trillion trillion trillion trillion trillion 
trillion trillion trillion trillion trillion trillion trillion trillion 
trillion trillion trillion trillion trillion trillion entries. Each 
entry will take at least four bytes, so the total is ... well, it's a 
lot. Much more than my poor computer has.

On Windows, this will fail quite quickly with a MemoryError, no real 
harm done, but on Linux (which I use) the OS will gamely, or perhaps 
stupidly, try very hard to allocate a trillion trill

[Tutor] What's the correct way to define/access methods of a member variable in a class pointing to an object?

2016-09-03 Thread Sharad Singla
Hi Pythonistas

What's the correct way to define/access methods of a member variable in a
class pointing to an object?

For example, I have a class Foo that has a method foo_method:

class Foo:
def foo_method(self):
return 'bar'

Now, in another class Bar, I'd like to store an object to this class (I do
not want Bar to inherit Foo).

What is the correct/recommended way to define class Bar?

class Bar:
def __init__(self):
self.foo = Foo()
# OR
class Bar:
def __init__(self):
self.foo = Foo()

def bar_method(self):
return self.foo.bar()

The former will allow me to use:

x = Bar()
x.foo.foo_method()

But, with this I'm directly accessing methods of a member variable (strong
coupling).

The benefits I see with this approach are:

   - I don't have to wrap every new method that gets added to class Foo.
   - Bar may contain more member variables pointing to other classes. Not
   wrapping them keeps Bar smaller and manageable in size.
   - The auto-completion facility from IDE (PyCharm, etc.) or IPython helps
   inspect bar like a menu (x.foo) followed by a sub-menu (
   x.foo.foo_method(), x.bar.foobar(), etc.) making it easier to develop
   code.
   - Functional programming look-n-feel (not sure if this a pro or con)

The cons are strong coupling, not encapsulating internal details of foo,
etc.

I wanted to check if this a recommended practice? And/or if there are any
guidelines related to this (kind of implementing a composite pattern)?

There may be more classes (Bat(), etc.) in future and I'd like to extend
Foo in future to store an object of these classes. Foo() is a part of a
library and my intent is to make Foo() as the entry point for the target
users (to allow them auto-completion via dotted notation) rather than
having them remember all the classes Bar(), Bat(), etc.

Any inputs/pointers will be highly appreciated!


Regards

Sharad


PS> I've posted this in SO at
http://stackoverflow.com/questions/39231932/whats-the-correct-way-to-access-methods-of-a-member-variable-in-a-class-pointin/39237874#39237874
but I'm looking for more information/ideas/thoughts/opinions on this.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] What's the correct way to define/access methods of a member variable in a class pointing to an object?

2016-09-03 Thread Steven D'Aprano
On Sat, Sep 03, 2016 at 11:25:07AM +0530, Sharad Singla wrote:
> Hi Pythonistas
> 
> What's the correct way to define/access methods of a member variable in a
> class pointing to an object?

Python recommends that you start with the simplest thing that will work 
first, which is direct attribute access, and only do something more 
complex if and when you need to. Python makes it easy to change the 
implementation without changing the interface! See more comments below.


> For example, I have a class Foo that has a method foo_method:
> 
> class Foo:
[snip implementation of class Foo]

> Now, in another class Bar, I'd like to store an object to this class (I do
> not want Bar to inherit Foo).
> 
> What is the correct/recommended way to define class Bar?
> 
> class Bar:
> def __init__(self):
> self.foo = Foo()

Usually this one, with a few exceptions.



> The former will allow me to use:
> 
> x = Bar()
> x.foo.foo_method()

Correct.


> But, with this I'm directly accessing methods of a member variable (strong
> coupling).

This is true, but the warning against coupling is a little more subtle 
than just "don't do it". 

The problem is that often you have to duplicate the interface to avoid 
coupling the *interface* of Bar class to Foo class. Imagine if Foo has, 
not one method, but fifty:

class Bar:
def __init__(self):
self._foo = Foo()  # Keep it private.

def bar_method(self):
return self._foo.bar_method()

def baz_method(self):
return self._foo.baz_method()

def bing_method(self):
return self._foo.bing_method()

def spam_method(self):
return self._foo.spam_method()

def eggs_method(self):
return self._foo.eggs_method()

def cheese_method(self):
return self._foo.cheese_method()


... and so on, for 44 more duplicate methods. At this point, you should 
ask yourself: what is Bar class adding? It's just a middle-man, which 
adds complexity to your code and run-time inefficiency.

(In Java, middle-man classes still add complexity, but they don't add 
run-time ineffeciency. The Java compiler can resolve a long chain of dot 
accesses like:

instance.foo.bar.baz.foobar.fe.fi.fo.fum.spam.eggs.cheese.ardvaark_method()

into a fast and efficient call direct to ardvaark_method(), but in 
Python every one of those dots has to be resolved at runtime. You 
really don't want enormously long chains of dot method calls in 
Python! A few dots is fine, but don't write Java style.)

So middle-man classes have a cost, and they have to pay their way. If 
they don't pay their way, it is better to dump them, and just work with 
Foo directly. The same goes for attribute access: you have to weigh up 
the added complexity of hiding the foo attribute against the benefit 
gained, and only hide it behind getter and setter methods if you really 
need to.

Python also takes the philosophy that public attributes are usually a 
good thing. You will often see classes where an attribute is a dict, or 
a list. For example, in Python 3, there is a class collections.ChainMap 
which stores a list of dicts. Rather than doing something like this:

class ChainMap:
def list_sort(self):
self._maps.sort()
def list_reverse(self):
self._maps.reverse()
def list_get(self, i):
return self._maps[i]
# etc.

the class just exposes the list directly to the caller. Its a list. You 
know how to sort lists, and extract items. There's no need to hide it. 
The interface will never change, it will always be a list. Just access 
the "maps" attribute, and work with it directly.

But generally this applies to relatively simple objects with well-known 
interfaces, like lists, dicts, and so forth. You might find you have 
good reason to hide Foo behind a middle-man. Perhaps Foo has a complex, 
ugly, un-Pythonic interface and you want to provide a more pleasant 
interface. Or perhaps you want the freedom to change the Foo interface 
at will, without changing the Bar interface.

So while it is *usual* to just do direct attribute access in Python, it 
is not forbidden to do it the other way. Just make sure you have a good 
reason, better than "because that's what my Comp Sci 101 professor told 
me to always do".


> The benefits I see with this approach are:
> 
>- I don't have to wrap every new method that gets added to class Foo.
>- Bar may contain more member variables pointing to other classes. Not
>wrapping them keeps Bar smaller and manageable in size.
>- The auto-completion facility from IDE (PyCharm, etc.) or IPython helps
>inspect bar like a menu (x.foo) followed by a sub-menu (
>x.foo.foo_method(), x.bar.foobar(), etc.) making it easier to develop
>code.
>- Functional programming look-n-feel (not sure if this a pro or con)

Exactly. That's why Python programmers tend to expose attributes as part 
of the public interface by default, and only hide them if justified by 
other concerns.


> The cons a

Re: [Tutor] python memory management

2016-09-03 Thread Peter Otten
monik...@netzero.net wrote:

> 
> By:
> "reference cycles: if one object has a reference to another, and
> that second object also has a reference to the first, that's a cycle."
> 
> Is this what you mean?
> a = 5
> b = a
> a = b

No. int instances are immutable. The assignments above bind both /names/ a 
and b to the same instance of int -- 5. The last statement a = b is 
redundant as a is already bound to 5.

For a reference cycle you need something in an object x to refer to another 
y and vice versa. x and y here are not Python names, but the actual objects.

An example using lists:

>>> a = ["a"]
>>> b = ["b"]

Let's append b to a:
>>> a.append(b)
>>> a[1]
['b']
>>> a[1][1]
Traceback (most recent call last):
  File "", line 1, in 
IndexError: list index out of range

We don't have a cycle yet, so Python eventually complains.
Now let's complete the cycle by appending b to a.

>>> b.append(a)
>>> a[1][1]
['a', ['b', [...]]]
>>> a[1][1][1][1][1]
['b', ['a', [...]]]

We can keep accessing x[1] forever, and if Python weren't smart enough to 
detect the cycle instead of producing the [...] it would continue building 
the string representation for the nested lists until all available memory 
was consumed or the stack overflowed.

Another example with a custom class:

>>> class C:
...def __init__(self, name): self.name = name
...def __repr__(self): return self.name
... 
>>> a = C("a")
>>> b = C("b")
>>> a
a
>>> b
b
>>> a.b = b
>>> b.a = a
>>> a.b.a.b.a.b.a.b.a.b.a
a

A cycle may of course consist of more than two objects:

>>> a = C("a")
>>> b = C("b")
>>> c = C("c")
>>> a.b = b
>>> b.c = c
>>> c.a = a
>>> c.a.b.c
c
>>> c.a.b.c.a.b.c.a.b.c
c

The minimal cycle consists of an object referencing itself:

>>> a = C("a")
>>> a.a = a
>>> a.a.a.a.a.a.a
a


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


Re: [Tutor] What's the correct way to define/access methods of a member variable in a class pointing to an object?

2016-09-03 Thread khalil zakaria Zemmoura
Hi,

Composition is a technique that allows you to express the 'has a'
relationship between your object.

I'm not a specialist of the OOP but I can see some issues in the model that
you expose in your mail.

Encapsulation and abstraction are all about designing an API. It allows you
to expose simple usable API'S and hiding all the complexity from the user
of your classes.

If a user have to use your classes in inheritance or composition, he/she
doesn't have to worry about the internal details.

Wrapping methods of class Foo is a good thing I think.

In the case you don't use encapsulation:

If Foo is used in Bar, Bat, Baf and after that, the three classes are used
anywhere in your code, if you change the API of Foo, you'll end up making
changes in all the places where Foo is mentioned! and that's tedious

Now, if you use encapsulation

The same scenario is not a big deal anymore because you'll end up making
less changes than before. That's makes the life easier

Abstracting irrelevant details also makes the process of developing easier
because you don't have to deal with low level of details to make a code
working and helps you to reason about your code in a more efficient way.

That techniques lower the level of complexity you have to deal with.

I hope that helps a little bit.

Regards.

Le 3 sept. 2016 10:24, "Sharad Singla"  a écrit :

> Hi Pythonistas
>
> What's the correct way to define/access methods of a member variable in a
> class pointing to an object?
>
> For example, I have a class Foo that has a method foo_method:
>
> class Foo:
> def foo_method(self):
> return 'bar'
>
> Now, in another class Bar, I'd like to store an object to this class (I do
> not want Bar to inherit Foo).
>
> What is the correct/recommended way to define class Bar?
>
> class Bar:
> def __init__(self):
> self.foo = Foo()
> # OR
> class Bar:
> def __init__(self):
> self.foo = Foo()
>
> def bar_method(self):
> return self.foo.bar()
>
> The former will allow me to use:
>
> x = Bar()
> x.foo.foo_method()
>
> But, with this I'm directly accessing methods of a member variable (strong
> coupling).
>
> The benefits I see with this approach are:
>
>- I don't have to wrap every new method that gets added to class Foo.
>- Bar may contain more member variables pointing to other classes. Not
>wrapping them keeps Bar smaller and manageable in size.
>- The auto-completion facility from IDE (PyCharm, etc.) or IPython helps
>inspect bar like a menu (x.foo) followed by a sub-menu (
>x.foo.foo_method(), x.bar.foobar(), etc.) making it easier to develop
>code.
>- Functional programming look-n-feel (not sure if this a pro or con)
>
> The cons are strong coupling, not encapsulating internal details of foo,
> etc.
>
> I wanted to check if this a recommended practice? And/or if there are any
> guidelines related to this (kind of implementing a composite pattern)?
>
> There may be more classes (Bat(), etc.) in future and I'd like to extend
> Foo in future to store an object of these classes. Foo() is a part of a
> library and my intent is to make Foo() as the entry point for the target
> users (to allow them auto-completion via dotted notation) rather than
> having them remember all the classes Bar(), Bat(), etc.
>
> Any inputs/pointers will be highly appreciated!
>
>
> Regards
>
> Sharad
>
>
> PS> I've posted this in SO at
> http://stackoverflow.com/questions/39231932/whats-the-
> correct-way-to-access-methods-of-a-member-variable-in-a-
> class-pointin/39237874#39237874
> but I'm looking for more information/ideas/thoughts/opinions on this.
> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] python memory management

2016-09-03 Thread Random832
On Fri, Sep 2, 2016, at 23:25, monik...@netzero.net wrote:
> 
> By:
> "reference cycles: if one object has a reference to another, and 
> that second object also has a reference to the first, that's a cycle."
> 
> Is this what you mean? 
> a = 5
> b = a
> a = b
> 
> I just want to make sure I understand.
> Thank you very much for your explanation. 
> Monika

No, an object that holds reference to other objects is something like a
list, tuple, dict.

e.g. if you had:
a = []
b = [a]
a.append(b)

you've got two lists, and each one has a reference to the other one.
These exist independent of the variables - you could del b and it would
still exist in a[0].
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] What's the correct way to define/access methods of a member variable in a class pointing to an object?

2016-09-03 Thread Alan Gauld via Tutor
On 03/09/16 06:55, Sharad Singla wrote:

> What's the correct way to define/access methods of a member variable in a
> class pointing to an object?

Steven has already given you a long and comprehensive
answer based on pragmatic python programming. But since
you use the term "correct" I'll give you an alternative
view based on generic/theoretical OOP practice. The caveat
is that theoretical best practice does not always transfer
to the real world and you must compromise. Just ensure you
compromise in the full knowledge that it is a compromise...

The first thing to do is point out that what you
are asking about is the Law of Demeter on OOP.
See Wikipedia for a full description. In essence
it says that the user of an object should not
directly access that object's internal attributes/state.
So ideally you only access foo via a call to a method of
Bar.

BUT... that does not mean you should expose all
of foo's interface as methods of Bar. After all Bar
should only have an instance of Foo to support its
own behaviour. In other words whatever methods you
call on Bar may manipulate Foo *behind the scenes*.
(If Foo is not being used by Foo's methods then what
is it doing in Bar at all?!)

So if you really want to change some aspect of
Bar's Foo instance then it should only be happening
as a result of you doing something to your Bar instance.

If you really, really need to modify the Foo instance
directly (and this should be fairly rare) the "correct"
OOP way to do that is for Bar to provide a getFoo()
accessor method and for you to fetch the Foo instance
and then manipulate it directly

b = Bar()
f = b.getFoo()
f.someMethod()
f.someAttribute = 42
# etc...
b.setFoo(f)   # put it back when you are done.

This then keeps Bar's use of foo hidden (you don't know
if Bar is returning a reference to its internal Foo
or creating a copy for you to play with.) In python
we tend to use direct access rather than getFoo/setFoo.
We'd just say b.foo, but that means if Bar wants to
return a copy of Foo then it needs to implement foo
as a property.

So to summarise, the Law of Demeter states that you
should provide foo access via Bar's interface but the
expectation is that you only create operations(methods)
on Bar that modify Foo as a part of that operation,
not that you simply expose all of Foo via Bar.

One huge exception to all of this is where you create
Bar explicitly as a manager of Foo objects and its
role is only to provide access to Foos (an example
might be an object pool in a server application).
But in that case there probably should be get/set
methods which will do some sanity checking before
handing over a Foo to you to play with, or storing
a foo that you have been messing about with.

HTH
-- 
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] python memory management

2016-09-03 Thread Alan Gauld via Tutor
On 03/09/16 04:25, monik...@netzero.net wrote:

> Is this what you mean? 
> a = 5
> b = a
> a = b

No, you are confusing variable names with objects.
Here you only have one object - the number 5.
For a cycle you need at least 2 objects and those
objects must be able to reference another object.
In practice that means a collection or an instance
of a class.

a = []
b = [a]
a.append(b)

The two lists are now cyclically referring to each
other. We can now delete the names a and b and
the two list objects will continue to exist
in memory even though no variables refer to them.
This is where the second garbage collector comes
into play, it can recognise the link between the
lists and the fact that no variable refers to them.

-- 
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] python memory management

2016-09-03 Thread Steven D'Aprano
On Thu, Sep 01, 2016 at 08:21:36PM +, monik...@netzero.net wrote:

> Thank you for your explanation. It is very clear and confirms what I 
> thought I knew. However, I had a job interview and the interview said 
> it was a mistake that I did not say that in cases when there are 
> multiple programmers, there might be some objects/references left and 
> not deallocated from the memory by python. He asked me how this should 
> be handles.

Without being there, I cannot be sure precisely what he meant. But 
frankly it sounds like the interviewer doesn't know what he is talking 
about. The number of programmers who work on a project has nothing to do 
with how it manages memory. Whether you have one person who writes the 
code, or a hundred people writing the code, memory is managed exactly 
the same way.

Perhaps you misunderstood the question, or perhaps the interviewer 
simply wasn't as knowledgable or smart as he thought he was.


> So I told him that python has its automatic garbage collection which 
> keeps track of all objects and references and deletes them as 
> appropriate (similar what you state). I added that programmers can 
> keep track of occurrences of object and make sure that it goes down to 
> 0. And if it does not then use del to delete. However, he did not like 
> my answer.

What you say is technically correct, but if you find yourself using del 
more than very occasionally, I suggest that you need to think hard about 
what you are doing. It is not normally necessary to use del.


> So Im trying to learn from my mistakes and learn if an 
> object or reference are still at the end of the program how they 
> should be deleted.

A thought comes to mind... 

When Python shuts down, it has to deallocate all your remaining objects, 
giving them a chance to run any finaliser methods. But sometimes the 
finaliser methods don't get to run until Python has already deallocated 
the global variables, including modules you might want to use. So for 
example:

import math

class Widget:
def __del__(self):
# Finaliser
print(math.sin(10))


but if your widget doesn't get deallocated until the end of your 
application, it may be that math has been set to None and math.sin is no 
longer available.

Perhaps he was asking about that?

What sort of job were you asking for? I expect that would be counted as 
an extremely advanced corner of Python, not something that most people 
know or need to know.

> I had problem understanding him too well since he 
> was calling from overseas (there was interference) and I could not 
> understand his accent well. But I need to learn this for future 
> interviews.
>
> Your posting states that this is not a problem but according to the 
> interviewer it is. (I do not mean to be un-nice to you, sorry) So how 
> this situation should be handled?

There's no way to know the right way.

Some interviewers think they know more than they actually do. When you 
tell them the right answer, they think it is wrong because they are 
ignorant.

Some interviewers are deliberately testing you with really obscure, 
complex corners of the language. Maybe he was right, and there is some 
tiny corner where what I told you was incorrect.

Maybe you misunderstood the question.

Maybe the interviewer was deliberately testing you with false 
information, to see what you would do. Would you argue with him? Get 
frustrated? Agree with him even if you knew the answer was actually 
wrong?

There's no way of knowing what they are looking for. Do they want people 
who will push back and stand their ground when they know they are right, 
or people who will be good little employees who will agree when the boss 
says that milk is purple and England is the capital of China?


I guess the only thing you can do is answer as best you can, ask for 
clarifications, and hope.


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


Re: [Tutor] python projects

2016-09-03 Thread Steven D'Aprano
On Thu, Sep 01, 2016 at 05:35:33AM +, monik...@netzero.net wrote:
> Hi:
> I have been taking python classes for overa year now and studying and 
> studying it all days long. However, I still cannot get a job as a 
> python automation qa (despite of many years of experience in qa) 
> because everybody is looking for a senior python developers for 
> automation qa jobs. Entry level positions are rare. Is there a website 
> where I could maybe do some python projects for somebody, for free or 
> for low pay? Pretty soon I will have to take a survival job since my 
> savings are ending and when that happens I will not have much time to 
> practice python and all my hard work will go to waste.

I really, really feel sympathy for you. I think that a lot of people are 
in situations like yours. I am lucky enough to have a job that gives me 
time to practice Python, but that is the silver lining in a dark cloud: 
I have time to practice Python because I only work part time (not by 
choice). Very occasionally I get to use my Python skills as part of my 
work, but not often.

So I share your pain.

I'll be honest, I'm not sure what software QA is supposed to do, or what 
skills you have, so I'll have to guess.

I don't know of any *paid* Python projects looking with entry-level QA 
positions, I am sorry, but you might consider helping with some 
open-source projects or even the Python language itself. The work is 
unpaid, but you can list it on your CV and gain experience.

Pick some open-source Python projects run by volunteers, and see if they 
need help with testing and QA. Most small projects need help with 
testing and documentation -- there are lots of programmers who can write 
code but are no good (or, let's be honest, too lazy) to write tests and 
documentation.

Do you have lots of experience with a testing framework like Nose? Maybe 
you can volunteer to work on the framework, and get some skills and 
useful contacts and something to put on your CV. Again, as these 
projects are all run by volunteers, there is unlikely to be any pay for 
it.


Or look at the Python bug tracker:

http://bugs.python.org/

Can you find some issues that you can work on? Bugs that you can fix? 
Find issues that are waiting for tests and write some tests, and put 
them on the bug tracker.

As a beginner, expect that senior developers will want to check your 
work. Sometimes they are extremely busy and patches languish in the bug 
tracker, waiting for somebody to review them.

More about contributing to Python here:

https://docs.python.org/devguide/#contributing

Don't forget the Job Board:

https://jobs.python.org/


And good luck!




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


Re: [Tutor] What's the correct way to define/access methods of a member variable in a class pointing to an object?

2016-09-03 Thread Steven D'Aprano
On Sat, Sep 03, 2016 at 02:51:22PM +0100, Alan Gauld via Tutor wrote:

[...]
> The first thing to do is point out that what you
> are asking about is the Law of Demeter on OOP.
> See Wikipedia for a full description. In essence
> it says that the user of an object should not
> directly access that object's internal attributes/state.
> So ideally you only access foo via a call to a method of
> Bar.


That's a very important answer too, thanks Alan for reminding me of it, 
but remember that the Law of Demeter is more of a guideline, and we 
should understand it, not just blindly quote it.

One classic example of the Law Of Demeter is:

"If you want your dog to come to you, don't talk to your dog's legs, 
talk to the dog."

class Dog:
...


fido = Dog()
# I want the dog to come here.
fido.left_front_leg.lift()
fido.left_front_leg.forward()
fido.left_front_leg.down()
fido.right_back_leg.lift()
...


Arggh, no, that's terrible! That violates the Law Of Demeter, and you 
shouldn't expect your users to do that. The caller shouldn't have to 
care about *how the dog walks*.

fido.command("come here boy!")

Or perhaps:

fido.heel()


whatever is most appropriate. The details of how the dog walks is 
encapsulated inside the Dog class.

Another classic example is of a transaction where the paper boy gives 
you a newspaper and you pay him a dollar:


newspaper = paperboy.get_paper()
paperboy.balance += 1.0
customer.trousers.wallet.balance -= 1.0


No! Would you really let the paperboy reach into your trousers, grab 
your wallet, open it up, and take money out? Again, another Demeter 
violation. Better to re-write your Customer class:

class Customer:
def pay(self, amount):
if amount > self.wallet.balance:
raise ValueError
self.wallet.balance -= amount
return amount

paperboy.receive(customer.pay(1.0))


But sometimes the Law Of Demeter should not apply. Sometimes you are 
expected to tinker with the internals of an object.

car = Car()
# replace the engine with a bigger one
car.engine = Engine("800 horsepower of throbbing nitro-fueled POWER")
car.engine.inject(nitro=True)


but as I suggested in an earlier email, that mostly applies when the 
attribute is a fairly simple object like a list, a dict, or similar.




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


Re: [Tutor] What's the correct way to define/access methods of a member variable in a class pointing to an object?

2016-09-03 Thread Alan Gauld via Tutor
On 03/09/16 18:17, Steven D'Aprano wrote:

> One classic example of the Law Of Demeter is:
> 
> "If you want your dog to come to you, don't talk to your dog's legs, 
> talk to the dog."

I love that, I've never seen it before but a great example.

> But sometimes the Law Of Demeter should not apply. Sometimes you are 
> expected to tinker with the internals of an object.
> 
> car = Car()
> # replace the engine with a bigger one
> car.engine = Engine("800 horsepower of throbbing nitro-fueled POWER")
> car.engine.inject(nitro=True)

Yep, although in that case I'd take the engine "out of the car"

engine = car.engine
engine.inject()
car.engine = engine

Of course in python(or Java) the last line is usually not needed
because we work with references to the real object
rather than copies...

Its not necessary to get the extra reference but for me I
like the code to reflect the intent as well as the need.
So by creating an external reference to the engine it reminds
me that I am tinkering with a different object to the car.

-- 
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] 'int' object has no attribute 'items'

2016-09-03 Thread Chidinma via Tutor
Hello,Am trying to solve a problem, but keep getting different errors.
Country X calculates tax for its citizens using a graduated scale rate as shown 
below:   
   - Yearly Income: 0 - 1000Tax Rate: 0%
   - Yearly Income: 1,001 - 10,000Tax Rate: 10%
   - Yearly Income: 10,001 - 20,200Tax Rate: 15%
   - Yearly Income: 20,201 - 30,750Tax Rate: 20%
   - Yearly Income: 30,751 - 50,000Tax Rate: 25%
   - Yearly Income: Over 50,000Tax Rate: 30%
Am trying to write a Python function that will calculate tax rate.
def calculate_tax(dict_inp):  result = {}  if dict_inp == {}:    result = 
"Please enter valid inputs"  else:    for k, v in dict_inp.items():      try:   
     x = int(dict_inp[k])      except ValueError:        print("That's not an 
int!")        break      if(x):        if x > 5:          tax = ((x - 
5) * 0.3) + 4812.5 + 2110 + 1530 + 900          result[k] = tax        elif 
x > 30750:          tax = ((x - 30750) * 0.25) + 2110 + 1530 + 900          
result[k] = tax        elif x > 20200:          tax = ((x - 20200) * 0.2) + 
1530 + 900          result[k] = tax        elif x > 1:          tax = ((x - 
1) * 0.15) + 900          result[k] = tax        elif x > 1000:          
tax = ((x - 1000) * 0.1)          result[k] = tax        else:          tax = 0 
         result[k] = tax      else:        print("Yearly income is not an 
integer")    return result    dict_inp = {'Alex': 500,'James': 
20500,'Kinuthia': 7}#dict_inp = {200: 1500,300: 20500,400: 
7}print(calculate_tax(dict_inp))

But I get the result:

THERE IS AN ERROR/BUG IN YOUR CODE
Results: Internal Error: runTests aborted: TestOutcomeEvent(handled=False, 
test=, result=, outcome='error', exc_info=(, AttributeError("'int' object has 
no attribute 'items'",), ), reason=None, expected=False, shortLabel=None, 
longLabel=None) is not JSON serializable{'James': 2490.0, 'Alex': 0, 
'Kinuthia': 15352.5}
But when i take away the .items(), i get:
for k, v in dict_inp:
ValueError: too many values to unpack
Please I need help.I am using windows 10, python 3.5.2, Thanks
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] python memory management

2016-09-03 Thread monik...@netzero.net
So what does [...] mean?

-- Original Message --
From: Peter Otten <__pete...@web.de>
To: tutor@python.org
Subject: Re: [Tutor] python memory management
Date: Sat, 03 Sep 2016 14:26:12 +0200

monik...@netzero.net wrote:

> 
> By:
> "reference cycles: if one object has a reference to another, and
> that second object also has a reference to the first, that's a cycle."
> 
> Is this what you mean?
> a = 5
> b = a
> a = b

No. int instances are immutable. The assignments above bind both /names/ a 
and b to the same instance of int -- 5. The last statement a = b is 
redundant as a is already bound to 5.

For a reference cycle you need something in an object x to refer to another 
y and vice versa. x and y here are not Python names, but the actual objects.

An example using lists:

>>> a = ["a"]
>>> b = ["b"]

Let's append b to a:
>>> a.append(b)
>>> a[1]
['b']
>>> a[1][1]
Traceback (most recent call last):
  File "", line 1, in 
IndexError: list index out of range

We don't have a cycle yet, so Python eventually complains.
Now let's complete the cycle by appending b to a.

>>> b.append(a)
>>> a[1][1]
['a', ['b', [...]]]
>>> a[1][1][1][1][1]
['b', ['a', [...]]]

We can keep accessing x[1] forever, and if Python weren't smart enough to 
detect the cycle instead of producing the [...] it would continue building 
the string representation for the nested lists until all available memory 
was consumed or the stack overflowed.

Another example with a custom class:

>>> class C:
...def __init__(self, name): self.name = name
...def __repr__(self): return self.name
... 
>>> a = C("a")
>>> b = C("b")
>>> a
a
>>> b
b
>>> a.b = b
>>> b.a = a
>>> a.b.a.b.a.b.a.b.a.b.a
a

A cycle may of course consist of more than two objects:

>>> a = C("a")
>>> b = C("b")
>>> c = C("c")
>>> a.b = b
>>> b.c = c
>>> c.a = a
>>> c.a.b.c
c
>>> c.a.b.c.a.b.c.a.b.c
c

The minimal cycle consists of an object referencing itself:

>>> a = C("a")
>>> a.a = a
>>> a.a.a.a.a.a.a
a


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


howlifeworks.com (Sponsored by Content.Ad)
Why Women Are Flocking to This Incredible New Shopping Site
http://thirdpartyoffers.netzero.net/TGL3241/57cb3e00e29ee3e000c94st01duc
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] What's the correct way to define/access methods of a member variable in a class pointing to an object?

2016-09-03 Thread Sharad Singla
@Steven, @Khalil, @Alan
Thanks for the inputs/explanations.
Appreciate it!

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


Re: [Tutor] python memory management

2016-09-03 Thread zakaria
Is there any practical usage of using reference cycling?


On Sat, 2016-09-03 at 14:56 +0100, Alan Gauld via Tutor wrote:
> On 03/09/16 04:25, monik...@netzero.net wrote:
> 
> > 
> > Is this what you mean? 
> > a = 5
> > b = a
> > a = b
> 
> No, you are confusing variable names with objects.
> Here you only have one object - the number 5.
> For a cycle you need at least 2 objects and those
> objects must be able to reference another object.
> In practice that means a collection or an instance
> of a class.
> 
> a = []
> b = [a]
> a.append(b)
> 
> The two lists are now cyclically referring to each
> other. We can now delete the names a and b and
> the two list objects will continue to exist
> in memory even though no variables refer to them.
> This is where the second garbage collector comes
> into play, it can recognise the link between the
> lists and the fact that no variable refers to them.
> 
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] python memory management

2016-09-03 Thread Alan Gauld via Tutor
On 03/09/16 22:16, monik...@netzero.net wrote:
> So what does [...] mean?

Its Python's way of telling you that you have a
self referential data structure. Its just a
representational thing but without it Python
would end up printing an infinite sequence
of values.

HTH

-- 
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] python memory management

2016-09-03 Thread Alan Gauld via Tutor
On 03/09/16 23:20, zakaria wrote:
> Is there any practical usage of using reference cycling?

There are a (very) few cases where data structures require the
creation of cyclic references. One example I've used is in
managing comms networks where nodes are multiply and/or
cyclically linked and you need to build those linkages into
your data model. In those cases you need to manage the
cleanup yourself.

But most cyclic references occur by accident, the programmer
probably didn't intend them to exist but it just so happened that
one object points to another which happens to point at another
which in turn points at the first. The cycle can span many objects.
Think of a directory tree where a deeply nested node has a link
pointing back at a root level node. But the root also indirectly
points at that low level node by means of the tree structure...

As a specific example, It often happens in GUIs where widgets
hold references to other widgets higher in the widget
parent/child tree.

-- 
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] 'int' object has no attribute 'items'

2016-09-03 Thread Steven D'Aprano
Hi Chidinma,

I'm afraid it is very difficult for me to understand your code, because 
your email program (Yahoo mail perhaps?) has mangled the code and put it 
all on one single line:

On Sat, Sep 03, 2016 at 09:45:17PM +, Chidinma via Tutor wrote:

> def calculate_tax(dict_inp):  result = {}  if dict_inp == {}:    result = 
> "Please enter valid inputs"  else:    for k, v in dict_inp.items():      try: 
>        x = int(dict_inp[k])      except ValueError:        print("That's not 
> an int!")        break      if(x):        if x > 5:          tax = ((x - 
> 5) * 0.3) + 4812.5 + 2110 + 1530 + 900          result[k] = tax        
> elif x > 30750:          tax = ((x - 30750) * 0.25) + 2110 + 1530 + 900       
>    result[k] = tax        elif x > 20200:          tax = ((x - 20200) * 0.2) 
> + 1530 + 900          result[k] = tax        elif x > 1:          tax = 
> ((x - 1) * 0.15) + 900          result[k] = tax        elif x > 1000:     
>      tax = ((x - 1000) * 0.1)          result[k] = tax        else:          
> tax = 0          result[k] = tax      else:        print("Yearly income is 
> not an integer")    return result    dict_inp = {'Alex': 500,'James': 
> 20500,'Kinuthia': 7}#dict_inp = {200: 1500,300: 20500,400: 
> 7}print(calculate_tax(dict_inp))

You may be able to prevent that by turning of "formatted text", or "rich 
text", or "HTML email", or whatever your email program calls this 
feature.


> But I get the result:
> 
> THERE IS AN ERROR/BUG IN YOUR CODE

How are you running this? Python doesn't normally print "THERE IS AN 
ERROR/BUG IN YOUR CODE". My guess is that you are using one of the 
on-line Python courses where you type your code into the web page. Am I 
right? Which one?


> Results: Internal Error: runTests aborted: TestOutcomeEvent(handled=False, 
> test=, result=, outcome='error', exc_info=(, AttributeError("'int' object has 
> no attribute 'items'",), ), reason=None, expected=False, shortLabel=None, 
> longLabel=None) is not JSON serializable{'James': 2490.0, 'Alex': 0, 
> 'Kinuthia': 15352.5}

That error doesn't seem to have anything to do with your code. Are you 
sure it is connected to the code you give above?

If you are using a website, it might be a bug in the website.



> But when i take away the .items(), i get:
> for k, v in dict_inp:
> ValueError: too many values to unpack

The first thing to confirm that dict_inp is a dict. Run:

print( isinstance(dict_inp, dict) )

just before that "for ..." line. If it prints True, then change the for 
line to:

for k, v in dict_inp.items():

What happens then?


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