[ cyb / tech / λ / layer ] [ zzz / drg / lit / diy / art ] [ w / rpg / r ] [ q ] [ / ] [ popular / ???? / rules / radio / $$ / news ] [ volafile / uboa / sushi / LainTV / lewd ]

λ - programming

/lam/bda /lam/bda duck
Name
Email
Subject
Comment
File
Password (For file deletion.)

BUY LAINCHAN STICKERS HERE

STREAM » LainTV « STREAM
Ok, who did it?

[Return][Go to bottom]

File: 1446031423306.jpg (39.77 KB, 300x300, good habits.jpg) ImgOps Exif iqdb

 No.11083

What habits should each coder have to make his programing as clean, effective, good as possible?
I'm just starting to learn programming, Python on 2.7, and want to develop good habits from the beginning instead of adopting them later and possibly having to get rid of bad habits.
any ideas?
>>

 No.11086

>>11083
A few are:
> define functions instead of writing it like a script (t will save you time and cause less pain)
> always keep pure functions separate from ones with side-effects
> comment your code (after the line not above unless it's describing the function)
> avoid nested if statements
> use subfunctions to construct larger ones... don't put all code in one function
> read your code more than once (it helps a lot)
> always try to simplify your code
> do not reinvent the wheel (unless you are learning how it works)

Also you should read SICP (maybe before learning python) as it covers how to think about a problem and solve it. It also goes through program design and data structures which are important. You only really need to read the first three chapters of it to pick most things up (btw.. chapter 4 and 5 is where the fun is but you need to read the others first).

>>

 No.11087

Your names should be clear. A function named "process_data" tells me almost nothing. It's often said that good code documents itself and a large part of this is the fact that you can write "postcount++;" rather than "x++;". On that note documentation is important. The first thing to do with any library/language/other tool is RTFM.

I thought there would be more to write than this but really when you're just learning it's not that great to stick to a lot of the practices that you'll eventually develop. The reason for this is learning. If somebody says to you that you should never use globals and you never do you never learn why they said it. It's better to write a large project scattered with globals and see the problems they cause. It's important that you actually really understand these traps because it's so easy to come up with soykaf methods of "not using globals" like passing large data structures to nearly every part of the program or similar and these methods end up having all of the same problems, in many cases exacerbated.

>>

 No.11088

>Python

It's easy then. Python has an opinionated style guide:

https://www.python.org/dev/peps/pep-0008/

>>

 No.11091

File: 1446038993677.png (134.58 KB, 780x765, solutions.png) ImgOps iqdb

>>11083
I recommend reading "Thinking Forth" by Leo Brodie.
http://thinking-forth.sourceforge.net/
http://thinking-forth.sourceforge.net/thinking-forth-ans.pdf

Even if you're not interested in Forth, it is full of excellent general programming advice.

An example is storing a phone number as a normal number, rather than a string. It takes much less space and is still easy to pretty print. So use 1234567 instead of "1234567" or, worse, "123-4567". Numbers are much easier to verify for correctness than strings. You're going to need to print it in some way anyway, so a little extra calculation there is no issue, especially if it saves calculations elsewhere.

>>

 No.11092

>>11083
I would say that learning Python on the old 2.X branch is a bad habit, since it's deprecated. Even the developers say to avoid using it unless you have to (e.g. you use a library which hasn't been ported to 3.X yet)

You would be a lot better off learning the modern 3.X version.

In general, learning the current version of a language / tool / OS / etc. and keeping up to date as things improve is a good habit to be in. Otherwise you end up with stuff like business-critical software which only runs in a very specific outdated environment and can't be modernised due to crippling technical debt. That sort of thing can be very costly to upgrade.

Sometimes (admittedly rarely) you hear about companies which are stuck using environments tied to physical hardware (e.g. manufacturing devices which run DOS and don't work with modern hardware, or ERP systems running on an old OS which hasn't had new drivers produced since the mid-90's)

>>

 No.11100

>>11083
If you haven't already, make sure you read "The Pragmatic Programmer" at some point.
It's a cliché at this point, but there is a reason that everyone recommends it.
The best summary for it is that most books try to teach you how to write correct software.
PP is one of the few books that strives to teach you how to *correctly* write software.
It's not a bible and far to many people treat it that way, but will write better code having read it.

>>

 No.11112

>>11092
thanks! do you recommend any reading material for learning 3.X ? I was learning 2.X with Byte of Python, but I am unable to find the one for 3.X (there is a version to learn 3.X with byte of python but it's in Russian)

>>

 No.11113

>>11112
nevermind, reddit was my friend

>>

 No.11121

File: 1446091580375.pdf (3.7 MB, Starting Out with Python -….pdf)

>>11112
>>11113
This is the textbook we used for our introductory programming course at uni. It's based on Python 3. I do not know if there is a more recent edition of this book, but I doubt there would be any significant changes.

(find textbook attached)

>>

 No.11130

>>11121
beautiful, thank you. I'll use it as well as Think Python:How to Think Like a Computer Scientist based on 3.X too

>>

 No.11147

>>11091
But phone numbers aren't mathematical numbers. Important details like leading zeroes get lost if you use an actual numeric type.

Sorry, but you're not going to be able to convince me that using a numeric type for phone numbers is anything other than a terrible idea. Why not use floats for money while you're at it?

>>

 No.11149

File: 1446155571441.gif (15.8 KB, 385x560, no-design.gif) ImgOps iqdb

>>11083
Avoid mission creep.
You want to program X. Program X. Y and Z can wait.

You NEED to complete X to replenish your motivation before starting Y. Otherwise chaos and failure.

Write down what you are doing on paper I AM DOING X. If you can't define X then you can't be doing X, so DEFINE X.

Also take your first prediction of how long it will take, double it, and then increase by an order of magnitude. 2 minutes = 4hours. 1 day = 2 weeks. This is fact.


Finally. Don't optimise your code before it is complete. Is this loop slow? A super fast efficient loop is worth fuarrrk all if the code doesn't do X. Achieve X. Only after achieving X you can profile and make it faster if needed.

>>

 No.11155

>>11149
Is that some graphviz?

>>

 No.11161

File: 1446198499902.pdf (17.4 MB, Systems Analysis and Desig….pdf)

>>11149
I'd like to add to this:

Plan out software before you start writing it. Get some paper, or a whiteboard (a big pane of glass also works really well with whiteboard markers), and draw out your program in as much detail as you can about how it will work.

This doesn't matter so much for small programs but for anything of medium to large complexity it can save so much time and effort to plan ahead (in a class we did on software project management I think they said something that costs 1x resource to change in the initial design would cost 50x or 100x resources/effort if you need to change it after most of the code is already written)

Check out the textbook attached.

>>

 No.11163

>>11155
Yep. I do love a bit o' graphviz.

>>11161
I've never learnt to design properly because all the texts are so damn boring.

I just start coding and do a full re-write 3 times. Not great.

Are there any resources that are actually enjoyable to read? Preferably with humour.

>>

 No.11165

>>11163
Unfortunately I'm not aware of any such resources. The problem with systems analysis and design is that it's at an intersection of human (e.g. the requirements gathering) and computing (the software design) fields.

You can probably just skip the human-focused stuff e.g. surveying, quizzes, etc. But I would recommend reading the technical parts of the book, regarding the systems design, since knowing that stuff will definately make you a better programmer.

>>

 No.11167

>>11086
> comment your code
No. Try to write code that doesn't need explanation and don't explain obvious things.
Bad example:
i = i+1;  // add 1 to i


Bonus: comments are not checked by compiler. You can write some bull soykaf in your comments like this:
int * l[2]; /*  Pointer to an array of two integers */

Why would you do that? Imagine you write something, then you change something and forgot to change some comment.
The only good answer to question about comments is: as few as you can, but no fewer.

>>

 No.11168

>>11086
> comment your code (after the line not above unless it's describing the function)
Uh, can you quote a style guide or something for this? I've never seen anyone do it and it seems pretty counterintuitive

>>

 No.11171

>>11167
Those
 i = i + 1;//adds 1 to i 
types of comments are bad, but it's wrong to say you should avoid using comments as much as possible. Consider instead:
 
//This sections is responsible for doing SOMETHING, using WHATEVER and SOMETHING ELSE to compute SOME RESULT
{
//code here ...
{


So the comments are more of a "this is a general description of what this code snippet is doing, and why" type of thing than a per-line description.

>>11168
Same, I've never seen this before.

>>

 No.11186

>>11171
Why not

int SOMETHING(char *WHATEVER, int SOMETHING_ELSE) {
// code here ...
}

where SOMETHING, WHATEVER, SOMETHING_ELSE are short, meaningful and descriptive names?

>it's wrong to say you should avoid using comments as much as possible

I know I'm exaggerating a little and one should write some comments, but I still think that 90% of comments are useless.

>>

 No.11189

File: 1446223261421-0.png (220.77 KB, 2049x1590, overgeneralization.png) ImgOps iqdb

File: 1446223261421-1.png (767.66 KB, 1940x2228, top-down.png) ImgOps iqdb

File: 1446223261421-2.png (297.69 KB, 1848x2108, commenting.png) ImgOps iqdb

Avoiding feature creep is good advice since it keeps things simple and focused, but bottom-up design is nicer in my opinion.

When designing a program, consider the primitives you know you will need and design them first. Implement some later if you want. Build your program from increasingly abstracted facilities that you develop as you make your own specialized language from these primitives.
This works best in programming languages that can properly hide implementation details and allow for metaprogramming, like Forth. Primitives can easily be modified transparently without affecting the words that call them.
I've seen a decent amount of C code, as an example, and it often doesn't properly hide the implementation of data structures or approaches to problems because it can't. Data structures tend to be accessed and modified directly in many different parts of the program, marrying it to the decision. Static typing also forces design decisions in places that inhibit the late redesign characteristic of bottom-up design. It's not trivial to take a typical C program and change all arrays to linked lists, as an example.

When it comes to commenting, I don't do it. I always write documentation strings for my functions in languages that have them, but that's the extent of it. Have good documentation in a separate document and preferably try to automatically generate much of it as possible from whatever you have in the documentation strings. Random comments strewn about the code should be avoided. Comments can lie and your code probably needs refactoring if you feel the need to explain a line or few beyond what can be inferred from reading the program alone.

>>

 No.11193

>>11091
>>11147
>But phone numbers aren't mathematical numbers. Important details like leading zeroes get lost if you use an actual numeric type.
Yes! Sorry >>1091 but it's a horrible idea. Allow me to illustrate:
https://www.mjt.me.uk/posts/falsehoods-programmers-believe-about-addresses/
So what have we learned?
>Assume NOTHING AT ALL about addresses (and also people's names btw) except that they are a UNICODE STRING of some kind

With phone numbers you can go as far as saying they must be an ASCII string but don't fuarrrk around with phone numers otherwise. E.g. mine is in the format of

+41 79 123 45 67
or
0041 79 123 45 67

This varies from country to country but it makes perfect sense for me as the "+41/0041" is the country code, "79" is the mobile phone provider and I'm used to phone numers grouped in 3-2-2 digits
And no, it doesn't fit a freaking integer.

>>11189
>>11167
>>11161
>>11149
>>11087
>>11086
Great advice ITT. I'm proud of you lainons!

>>

 No.11196

Two more of those things:
http://blog.erratasec.com/2012/06/falsehoods-programmers-believe-about.html#.VjOlyitsmUk

http://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/

it's important. Also learn python3 it has better strings (unicode by default or something)


>>

 No.11199

>>11147
I didn't notice your reply until now.
All I can tell you is I've never seen a phone number that begins with a zero.
If you ever actually encounter such an edge case, then use a different approach.
The approach is sufficient for every phone number I expect to ever require handling. An approach is valid if you can prove it will be sufficient in all cases that are to be handled and this is true for me.

You should not handle an edge case when you know it won't happen.

>>11193
I'm also >>11189. You're welcome for the advice.
>And no, it doesn't fit a freaking integer.
In Forth, this depends on the size of the cell. If you were needing to address the issue, you could use two cells or require a 64-bit cell.

As above, don't over generalize. If an approach works for all valid inputs, use it instead of the more general approach that will never actually be needed.

Both of you have also failed to consider a basic scheme that calculates the number of leading zeroes, if any, required, based on the current length of the number.
With this said, I will continue to insist that the approach is both adequate and easily changed to also cover your uncommon case.

Lastly, Forth pictured numeric output is created backwards, so calculating the remaining leading zeroes would be fairly easy.

>>

 No.11226

>>11091
I would think a phone number makes more sense as a series of 4-bit values, so as to emulate any sequence of DTMF signals.

>>

 No.11230

>>11199
It's better to do the research early and plan for all the edge cases rather than have to add support later.

Seriously, just store the phone number as a string. You can do a basic regex to ensure only valid chars are allowed (numbers obviously, and also allow users to do stuff like enter + symbols for country codes), and worse case if your application has to pass the numbers to a dialer you can just iterate over the character array and check to make sure you only 'dial' numbers. It really doesn't cost that much computationally and saves a lot of other hassles.

This all comes back to the "don't prematurely optimise" principle.

>>

 No.11231

>>11091
>calculating over data structures
Actually a very important and increasingly neglected idea, certainly not one helped by languages that emphasize data structures like Java (or Python etc). I recently came up with an algorithm for finding certain musical scales that uses numbers to represent scales (their binary representation reflects the notes contained in the scale, with the least significant bit representing the 1st note). It found millions of scales rather than thousands, and the critical parts were ~20 lines of code instead of close to 150! The math involved was elegant and clear. Over-engineering can be a serious problem.

I've found Forth to be a rather inaccessible language unfortunately. Someday I want to learn it properly and try a large project with it, but I'm not nearly capable right now. Using memory allocation in Forth is confusing to me. Maybe I'll try to rework the music scales code to work in Forth, just to see how it goes; I don't think I'd need to use conditionals or data structures given all that I've learned.

>>

 No.11238

>>11231
>I've found Forth to be a rather inaccessible language unfortunately.
>Using memory allocation in Forth is confusing to me.
While there is an optional memory allocation word set that provides allocate, free, and resize in the same vein as malloc, free, and realloc (gforth even implements them directly with the C functions) you really shouldn't need them in many cases. Most memory management in Forth should adhere to the stack model.
You should obviously use the data stack for most things and you can even use the return stack, as long as you don't need the values below it, meaning you can use the return stack and call other words without issue. You just need to pop your value from the return stack before you need to return from the word that placed it there.
As for allocating arrays, you should generally use allot when creating a word to associate the space with it. Allot, ,, and c, all use here to determine where the next data space address starts and reserve contiguous space from there.
Here's one way to define an array:
create array 20 allot
Here's one way to create a defining word that defines arrays:
: array ( n "name<space>" -- )  create allot
does> ( n -- addr ) + ;
This word doesn't check array bounds, but this would be easy to add by also storing the length of the array in the newly-defined word and adding a check. All DOES> does is define the behavior of the CREATEd word and places the address of the data space of said word on the stack when being executed. This makes it easy to get the indexed address by simply adding.

I know I went on a tangent really, but I don't really have anyone else to talk to about these things. My main point is memory management in Forth is actually really easy. If you're coming from a GC'd language, you just have to understand that a static memory model isn't that hard to deal with and is usually sufficient. You just have to process certain data in chunks instead of all at once.

>>

 No.11249

>>11238
Thanks for the advice.
>If you're coming from a GC'd language, you just have to understand that a static memory model isn't that hard to deal with and is usually sufficient
I think this is my main struggle. I probably overcomplicate problems because I don't understand how to do things with just static memory.



Delete Post [ ]
[ cyb / tech / λ / layer ] [ zzz / drg / lit / diy / art ] [ w / rpg / r ] [ q ] [ / ] [ popular / ???? / rules / radio / $$ / news ] [ volafile / uboa / sushi / LainTV / lewd ]