Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #51847 > unrolled thread

Correct Way to Write in Python

Started bypunk.sagar@gmail.com
First post2013-08-02 23:18 -0700
Last post2013-08-03 17:21 +0100
Articles 8 — 5 participants

Back to article view | Back to comp.lang.python


Contents

  Correct Way to Write in Python punk.sagar@gmail.com - 2013-08-02 23:18 -0700
    Re: Correct Way to Write in Python Peter Otten <__peter__@web.de> - 2013-08-03 08:47 +0200
      Re: Correct Way to Write in Python Sagar Varule <punk.sagar@gmail.com> - 2013-08-03 00:09 -0700
        Re: Correct Way to Write in Python Peter Otten <__peter__@web.de> - 2013-08-03 11:04 +0200
          Re: Correct Way to Write in Python Sagar Varule <punk.sagar@gmail.com> - 2013-08-03 09:07 -0700
    Re: Correct Way to Write in Python Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-08-03 08:20 +0000
      Re: Correct Way to Write in Python Sagar Varule <punk.sagar@gmail.com> - 2013-08-03 08:59 -0700
        Re: Correct Way to Write in Python Chris Angelico <rosuav@gmail.com> - 2013-08-03 17:21 +0100

#51847 — Correct Way to Write in Python

Frompunk.sagar@gmail.com
Date2013-08-02 23:18 -0700
SubjectCorrect Way to Write in Python
Message-ID<daaa64d5-3366-48b4-980c-cd91a440aa90@googlegroups.com>
Hi All,

Im new to Python. Im coming from C# background and want to learn Python.
I was used to do following thing in C# in my previous experiences. I want to know how do I implement below example in Python. How these things are done in Python.
[code]
public class Bank 
{
	
	public List<Customer> lstCustomers = new List<Customer>();
	private string micrcode;
	
	public void Bank()
	{
		customer
	}

}

public class Customer
{
	private srting customername;
	
	public string CustomerName
	
	{
		get { return customername; }
		set { customername = value; }
	}
}

main()
{
	Customer objCustomer = new Customer;
	objCustomer.CustomerName = "XYZ"
	
	Bank objBank = new Bank();
	objBank.lstCustomer.Add(objCustomer);
	
}
[/code]

[toc] | [next] | [standalone]


#51848

FromPeter Otten <__peter__@web.de>
Date2013-08-03 08:47 +0200
Message-ID<mailman.149.1375512468.1251.python-list@python.org>
In reply to#51847
punk.sagar@gmail.com wrote:

> Hi All,
> 
> Im new to Python. Im coming from C# background and want to learn Python.
> I was used to do following thing in C# in my previous experiences. I want
> to know how do I implement below example in Python. How these things are
> done in Python.
> [code]
> public class Bank
> {
> 
> public List<Customer> lstCustomers = new List<Customer>();
> private string micrcode;
> 
> public void Bank()
> {
> customer
> }
> 
> }
> 
> public class Customer
> {
> private srting customername;
> 
> public string CustomerName
> 
> {
> get { return customername; }
> set { customername = value; }
> }
> }
> 
> main()
> {
> Customer objCustomer = new Customer;
> objCustomer.CustomerName = "XYZ"
> 
> Bank objBank = new Bank();
> objBank.lstCustomer.Add(objCustomer);
> 
> }
> [/code]

While I don't know C# I doubt that this is good C# code ;)
Here's a moderately cleaned-up Python version:

class DuplicateCustomerError(Exception):
    pass

class Customer:
    def __init__(self, name):
        self.name = name

class Bank:
    def __init__(self):
        self.customers = {}
    def add_customer(self, name):
        if name in self.customers:
            raise DuplicateCustomerError
        customer = Customer(name)
        self.customers[name] = customer
        return customer

if __name__ == "__main__":
    bank = Bank()
    bank.add_customer("XYZ")

I'm assuming a tiny bank where every customer has a unique name and only one 
program is running so that you can ignore concurrency issues.

[toc] | [prev] | [next] | [standalone]


#51849

FromSagar Varule <punk.sagar@gmail.com>
Date2013-08-03 00:09 -0700
Message-ID<f5f5b848-005c-4aaa-bc96-49dbc3fe4583@googlegroups.com>
In reply to#51848
On Saturday, August 3, 2013 12:17:49 PM UTC+5:30, Peter Otten wrote:
> punk.sagar@gmail.com wrote:
> 
> 
> 
> > Hi All,
> 
> > 
> 
> > Im new to Python. Im coming from C# background and want to learn Python.
> 
> > I was used to do following thing in C# in my previous experiences. I want
> 
> > to know how do I implement below example in Python. How these things are
> 
> > done in Python.
> 
> > [code]
> 
> > public class Bank
> 
> > {
> 
> > 
> 
> > public List<Customer> lstCustomers = new List<Customer>();
> 
> > private string micrcode;
> 
> > 
> 
> > public void Bank()
> 
> > {
> 
> > customer
> 
> > }
> 
> > 
> 
> > }
> 
> > 
> 
> > public class Customer
> 
> > {
> 
> > private srting customername;
> 
> > 
> 
> > public string CustomerName
> 
> > 
> 
> > {
> 
> > get { return customername; }
> 
> > set { customername = value; }
> 
> > }
> 
> > }
> 
> > 
> 
> > main()
> 
> > {
> 
> > Customer objCustomer = new Customer;
> 
> > objCustomer.CustomerName = "XYZ"
> 
> > 
> 
> > Bank objBank = new Bank();
> 
> > objBank.lstCustomer.Add(objCustomer);
> 
> > 
> 
> > }
> 
> > [/code]
> 
> 
> 
> While I don't know C# I doubt that this is good C# code ;)
> 
> Here's a moderately cleaned-up Python version:
> 
> 
> 
> class DuplicateCustomerError(Exception):
> 
>     pass
> 
> 
> 
> class Customer:
> 
>     def __init__(self, name):
> 
>         self.name = name
> 
> 
> 
> class Bank:
> 
>     def __init__(self):
> 
>         self.customers = {}
> 
>     def add_customer(self, name):
> 
>         if name in self.customers:
> 
>             raise DuplicateCustomerError
> 
>         customer = Customer(name)
> 
>         self.customers[name] = customer
> 
>         return customer
> 
> 
> 
> if __name__ == "__main__":
> 
>     bank = Bank()
> 
>     bank.add_customer("XYZ")
> 
> 
> 
> I'm assuming a tiny bank where every customer has a unique name and only one 
> 
> program is running so that you can ignore concurrency issues.

Thanks a lot Peter. I appreciate your Help. You mentioned that C# code above is not good. If you can point me why it is not good, would help me learn new approaches as this type of Code I use to see long back(when i was fresher). There may be better approaches or concepts i am not aware of. If you can point me in that direction it would be gr8.

[toc] | [prev] | [next] | [standalone]


#51851

FromPeter Otten <__peter__@web.de>
Date2013-08-03 11:04 +0200
Message-ID<mailman.150.1375520649.1251.python-list@python.org>
In reply to#51849
Sagar Varule wrote:

> On Saturday, August 3, 2013 12:17:49 PM UTC+5:30, Peter Otten wrote:
>> punk.sagar@gmail.com wrote:

> Thanks a lot Peter. I appreciate your Help. You mentioned that C# code
> above is not good. If you can point me why it is not good, would help me
> learn new approaches as this type of Code I use to see long back(when i
> was fresher). There may be better approaches or concepts i am not aware
> of. If you can point me in that direction it would be gr8.

As I said, I don't know C#  -- but I already tried to fix some of the 
potential issues in my code snippet.

- A list is not the best choice to store the customers -- there should be a 
lookup by some kind of ID (I picked the name to keep it simple)
- Is it really necessary to expose that container in a language that 
provides "privacy"?
- Is there ever a customer without name/ID? I'd say no, so these should be 
passed as constructor arguments.
- Renaming a customer is a delicate process, you may need to keep track of 
the old name, the reason for the name, update your database etc., so I 
wouldn't allow setting the attribute and instead add a method

Bank.rename_customer(...)

or

Bank.customers.rename_customer(...)

Asking to translate code might make sense if you are a wizzard in the 
"other" language and want to see how a particular construct is written 
idomatically in Python, but to rewrite very basic C# code in Python is a bit 
like trying to learn a natural language by replacing one word after another 
in a text with the word in the new language that you looked up in a dict. 
The result tends to be underwhelming.

I recommend that you read the tutorial and then try to solve a simple task 
in Python. Whenever you run into a problem you can come here for help. 
Because there's a real problem behind your code there will be different ways 
to solve it in Python, and you'll learn much more about the possibilites 
Python has to offer while your code gradually becomes more idiomatic.

[toc] | [prev] | [next] | [standalone]


#51867

FromSagar Varule <punk.sagar@gmail.com>
Date2013-08-03 09:07 -0700
Message-ID<bd42aeb1-2ec1-46d6-9bb1-fc78c5ce2e6f@googlegroups.com>
In reply to#51851
On Saturday, August 3, 2013 2:34:10 PM UTC+5:30, Peter Otten wrote:
> Sagar Varule wrote:
> 
> 
> 
> > On Saturday, August 3, 2013 12:17:49 PM UTC+5:30, Peter Otten wrote:
> 
> >> punk.sagar@gmail.com wrote:
> 
> 
> 
> > Thanks a lot Peter. I appreciate your Help. You mentioned that C# code
> 
> > above is not good. If you can point me why it is not good, would help me
> 
> > learn new approaches as this type of Code I use to see long back(when i
> 
> > was fresher). There may be better approaches or concepts i am not aware
> 
> > of. If you can point me in that direction it would be gr8.
> 
> 
> 
> As I said, I don't know C#  -- but I already tried to fix some of the 
> 
> potential issues in my code snippet.
> 
> 
> 
> - A list is not the best choice to store the customers -- there should be a 
> 
> lookup by some kind of ID (I picked the name to keep it simple)
> 
> - Is it really necessary to expose that container in a language that 
> 
> provides "privacy"?
> 
> - Is there ever a customer without name/ID? I'd say no, so these should be 
> 
> passed as constructor arguments.
> 
> - Renaming a customer is a delicate process, you may need to keep track of 
> 
> the old name, the reason for the name, update your database etc., so I 
> 
> wouldn't allow setting the attribute and instead add a method
> 
> 
> 
> Bank.rename_customer(...)
> 
> 
> 
> or
> 
> 
> 
> Bank.customers.rename_customer(...)
> 
> 
> 
> Asking to translate code might make sense if you are a wizzard in the 
> 
> "other" language and want to see how a particular construct is written 
> 
> idomatically in Python, but to rewrite very basic C# code in Python is a bit 
> 
> like trying to learn a natural language by replacing one word after another 
> 
> in a text with the word in the new language that you looked up in a dict. 
> 
> The result tends to be underwhelming.
> 
> 
> 
> I recommend that you read the tutorial and then try to solve a simple task 
> 
> in Python. Whenever you run into a problem you can come here for help. 
> 
> Because there's a real problem behind your code there will be different ways 
> 
> to solve it in Python, and you'll learn much more about the possibilites 
> 
> Python has to offer while your code gradually becomes more idiomatic.

Thanks Peter for helping me out,
Your Questions and suggestions are thoughts provoking and will help me every time I write a new Class. I will keep your suggestions. I am happy and amazed that Im getting help from strangers, But I got none when I approached programmers in my office....Thanks a Lot...!!!!!

[toc] | [prev] | [next] | [standalone]


#51850

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-08-03 08:20 +0000
Message-ID<51fcbd58$0$30000$c3e8da3$5496439d@news.astraweb.com>
In reply to#51847
On Fri, 02 Aug 2013 23:18:47 -0700, punk.sagar wrote:

> Hi All,
> 
> Im new to Python. Im coming from C# background and want to learn Python.
> I was used to do following thing in C# in my previous experiences. I
> want to know how do I implement below example in Python. How these
> things are done in Python. 

I am not an expert on C#, but I'll try to translate the following code to 
Python.


> [code]
> public class Bank
> {
> 	
> 	public List<Customer> lstCustomers = new List<Customer>();
> 	private string micrcode;
> 	
> 	public void Bank()
> 	{
> 		customer
> 	}
> 
> }
> 
> public class Customer
> {
> 	private srting customername;
> 	public string CustomerName

Do you mean "private string" rather than "private srting"?


> 	{
> 		get { return customername; }
> 		set { customername = value; }
> 	}
> }
> 
> main()
> {
> 	Customer objCustomer = new Customer;
> 	objCustomer.CustomerName = "XYZ"
> 	
> 	Bank objBank = new Bank();
> 	objBank.lstCustomer.Add(objCustomer);
> 	
> }
> [/code]


Here is a literally translation, as best as I can understand the C# code. 
(But note that this is not the best Python code.)


class Bank:
    def __init__(self):
        self.lstCustomers = []  # Empty list of customers.
        self._micrcode = ''  # Does this actually get used?

class Customer:
    def __init__(self):
        self._customername = ''

    @property
    def CustomerName(self):
        return self._customername

    @CustomerName.setter
    def CustomerName(self, value):
        if not instance(value, str):
            raise TypeError('names must be strings')
        self._customername = value


if __name__ == '__main__':
    # Running as a script, call the main function.
    objCustomer = Customer()
    objCustomer.CustomerName = "XYZ"

    objBank = Bank()
    objBank.lstCustomers.append(objCustomer)



But this isn't how I would write it in Python. For starters, our naming 
conventions are different. Everything in Python is an object, even simple 
types like ints and strings, and even classes, so it isn't meaningful to 
prefix instances with "obj".

We tend to avoid anything which even vaguely looks like Hungarian 
Notation, so "lstCustomer" is right out. Instead, we use plural for 
collections (lists, sets, dicts, whatever) of things, and singular for 
individual instances.

Also, while we can use the "property" decorator to make computed 
attributes, we very rarely do just to enforce private/public variables. 
Our philosophy is, if you want to shoot yourself in the foot, we're not 
going to stop you. (People spend far too much time trying to work around 
private names in other languages for Python to spend too much effort in 
this area.) Instead, we have "private by convention": names starting with 
a single underscore are "private", so don't touch them, and if you do, 
you have nobody but yourself to blame when you shoot yourself in the foot.

Similarly, the language doesn't spend much time enforcing type 
restrictions. Python is a dynamic language, and type restrictions go 
against that philosophy. If you have a good reason to put a non-string as 
the customer name, you can do so, but don't come crying to me if you 
break your code. So here is how I would write the above:



class Bank:
    def __init__(self):
        self.customers = []
        self._micrcode = ''  # Does this actually get used?

class Customer:
    def __init__(self, name):
        # This type-check is optional.
        if not instance(name, str):
            raise TypeError('names must be strings')
        self.name = name


if __name__ == '__main__':
    # Running as a script, call the main function.
    customer = Customer("XYX")

    bank = Bank()
    bank.customers.append(customer)


The above is still not what I call professional quality -- no doc strings 
(documentation), and the bank doesn't actually do anything, but it's a 
start.


-- 
Steven

[toc] | [prev] | [next] | [standalone]


#51866

FromSagar Varule <punk.sagar@gmail.com>
Date2013-08-03 08:59 -0700
Message-ID<e9fb4f84-6b19-42ef-8f78-cc46e204e3f3@googlegroups.com>
In reply to#51850
On Saturday, August 3, 2013 1:50:41 PM UTC+5:30, Steven D'Aprano wrote:
> On Fri, 02 Aug 2013 23:18:47 -0700, punk.sagar wrote:
> 
> 
> 
> > Hi All,
> 
> > 
> 
> > Im new to Python. Im coming from C# background and want to learn Python.
> 
> > I was used to do following thing in C# in my previous experiences. I
> 
> > want to know how do I implement below example in Python. How these
> 
> > things are done in Python. 
> 
> 
> 
> I am not an expert on C#, but I'll try to translate the following code to 
> 
> Python.
> 
> 
> 
> 
> 
> > [code]
> 
> > public class Bank
> 
> > {
> 
> > 	
> 
> > 	public List<Customer> lstCustomers = new List<Customer>();
> 
> > 	private string micrcode;
> 
> > 	
> 
> > 	public void Bank()
> 
> > 	{
> 
> > 		customer
> 
> > 	}
> 
> > 
> 
> > }
> 
> > 
> 
> > public class Customer
> 
> > {
> 
> > 	private srting customername;
> 
> > 	public string CustomerName
> 
> 
> 
> Do you mean "private string" rather than "private srting"?
> 
> 
> 
> 
> 
> > 	{
> 
> > 		get { return customername; }
> 
> > 		set { customername = value; }
> 
> > 	}
> 
> > }
> 
> > 
> 
> > main()
> 
> > {
> 
> > 	Customer objCustomer = new Customer;
> 
> > 	objCustomer.CustomerName = "XYZ"
> 
> > 	
> 
> > 	Bank objBank = new Bank();
> 
> > 	objBank.lstCustomer.Add(objCustomer);
> 
> > 	
> 
> > }
> 
> > [/code]
> 
> 
> 
> 
> 
> Here is a literally translation, as best as I can understand the C# code. 
> 
> (But note that this is not the best Python code.)
> 
> 
> 
> 
> 
> class Bank:
> 
>     def __init__(self):
> 
>         self.lstCustomers = []  # Empty list of customers.
> 
>         self._micrcode = ''  # Does this actually get used?
> 
> 
> 
> class Customer:
> 
>     def __init__(self):
> 
>         self._customername = ''
> 
> 
> 
>     @property
> 
>     def CustomerName(self):
> 
>         return self._customername
> 
> 
> 
>     @CustomerName.setter
> 
>     def CustomerName(self, value):
> 
>         if not instance(value, str):
> 
>             raise TypeError('names must be strings')
> 
>         self._customername = value
> 
> 
> 
> 
> 
> if __name__ == '__main__':
> 
>     # Running as a script, call the main function.
> 
>     objCustomer = Customer()
> 
>     objCustomer.CustomerName = "XYZ"
> 
> 
> 
>     objBank = Bank()
> 
>     objBank.lstCustomers.append(objCustomer)
> 
> 
> 
> 
> 
> 
> 
> But this isn't how I would write it in Python. For starters, our naming 
> 
> conventions are different. Everything in Python is an object, even simple 
> 
> types like ints and strings, and even classes, so it isn't meaningful to 
> 
> prefix instances with "obj".
> 
> 
> 
> We tend to avoid anything which even vaguely looks like Hungarian 
> 
> Notation, so "lstCustomer" is right out. Instead, we use plural for 
> 
> collections (lists, sets, dicts, whatever) of things, and singular for 
> 
> individual instances.
> 
> 
> 
> Also, while we can use the "property" decorator to make computed 
> 
> attributes, we very rarely do just to enforce private/public variables. 
> 
> Our philosophy is, if you want to shoot yourself in the foot, we're not 
> 
> going to stop you. (People spend far too much time trying to work around 
> 
> private names in other languages for Python to spend too much effort in 
> 
> this area.) Instead, we have "private by convention": names starting with 
> 
> a single underscore are "private", so don't touch them, and if you do, 
> 
> you have nobody but yourself to blame when you shoot yourself in the foot.
> 
> 
> 
> Similarly, the language doesn't spend much time enforcing type 
> 
> restrictions. Python is a dynamic language, and type restrictions go 
> 
> against that philosophy. If you have a good reason to put a non-string as 
> 
> the customer name, you can do so, but don't come crying to me if you 
> 
> break your code. So here is how I would write the above:
> 
> 
> 
> 
> 
> 
> 
> class Bank:
> 
>     def __init__(self):
> 
>         self.customers = []
> 
>         self._micrcode = ''  # Does this actually get used?
> 
> 
> 
> class Customer:
> 
>     def __init__(self, name):
> 
>         # This type-check is optional.
> 
>         if not instance(name, str):
> 
>             raise TypeError('names must be strings')
> 
>         self.name = name
> 
> 
> 
> 
> 
> if __name__ == '__main__':
> 
>     # Running as a script, call the main function.
> 
>     customer = Customer("XYX")
> 
> 
> 
>     bank = Bank()
> 
>     bank.customers.append(customer)
> 
> 
> 
> 
> 
> The above is still not what I call professional quality -- no doc strings 
> 
> (documentation), and the bank doesn't actually do anything, but it's a 
> 
> start.
> 
> 
> 
> 
> 
> -- 
> 
> Steven

Thanks Steven for your Time and Effort. You have cleared many doubts and concepts for that I was struggling, since I started learning python. But I am falling in love for Python. Your explanation for private and public access modifier was awesome as I was having harding time finding why we dont have access modifier for python....Thanks a lot

[toc] | [prev] | [next] | [standalone]


#51868

FromChris Angelico <rosuav@gmail.com>
Date2013-08-03 17:21 +0100
Message-ID<mailman.162.1375546877.1251.python-list@python.org>
In reply to#51866
On Sat, Aug 3, 2013 at 4:59 PM, Sagar Varule <punk.sagar@gmail.com> wrote:
> Your explanation for private and public access modifier was awesome as I was having harding time finding why we dont have access modifier for python....Thanks a lot

It's a huge saving in time and effort. The C++ convention is: Make
everything private, then hand-write getters and setters for them all,
just in case you want to put extra code onto them. (I don't know C#
but it seems to be pretty much the same.) The Python convention is:
We're all consenting adults. Make stuff public, then if you need to
add code to something, make a @property that simulates the old
behaviour.

Personally, I've started to adopt the Python style in my C++ code as
well. I use struct instead of class, avoid making anything private,
and document the things that must not be done - for instance, I
created a class that had one particular pointer that must never be
advanced other than by the provided member function, but may be
retarded. No reason to fiddle with member privacy even there.

(The same technique has benefit in a quite different area, too:
separation of code and data. Not in C++, but I have systems that let
me load new code into a running process, and there it's extremely
helpful to just do everything as a simple structure, and then the new
code can slide in and work with the old data structure, happily
extending it with whatever it now needs. Again, everything's public.)

ChrisA

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web