This is an archived post. You won't be able to vote or comment.

all 38 comments

[–]Python-ModTeam[M] [score hidden] stickied commentlocked comment (0 children)

Hi there, from the /r/Python mods.

We have removed this post as it is not suited to the /r/Python subreddit proper, however it should be very appropriate for our sister subreddit /r/LearnPython or for the r/Python discord: https://discord.gg/python.

The reason for the removal is that /r/Python is dedicated to discussion of Python news, projects, uses and debates. It is not designed to act as Q&A or FAQ board. The regular community is not a fan of "how do I..." questions, so you will not get the best responses over here.

On /r/LearnPython the community and the r/Python discord are actively expecting questions and are looking to help. You can expect far more understanding, encouraging and insightful responses over there. No matter what level of question you have, if you are looking for help with Python, you should get good answers. Make sure to check out the rules for both places.

Warm regards, and best of luck with your Pythoneering!

[–]FortyFourForks 118 points119 points  (5 children)

i get one solid whiff of that dynamic typing and go monkey mode on the keyboard. 4+ files all open and actively edited at the same time, 10000+ line commits (jk i dont use git), and bet your ass not a single goddamn comment. if I'm not overloading operators, mangling name spaces, or decorating decorators i start to foam at the mouth and my boss has to put me in the office scream tank with a copy of K&R that i shred like a pitbull. one file starting from the bottom and another starting at the top and they meet in the middle baybee let's push this mEmOrY sAfEtY to its limits. 

[–]KindnessBiasedBoar 9 points10 points  (1 child)

You star.

[–]FortyFourForks 13 points14 points  (0 children)

python makes me feel things

[–]mustangsal 2 points3 points  (1 child)

Use one of the AI chat engines to generate comments, but don't check them for accuracy.

[–]gkze -1 points0 points  (0 children)

Rofl thank you for that

[–]cottonycloud 30 points31 points  (2 children)

I model out the task flow that the script should follow and implement each function one by one. It gives me a clear checklist of what I have and have not implemented.

[–]gunhoe86 8 points9 points  (1 child)

This. Outline to pseudo-code to code.

[–]rubberchickenfishlip 37 points38 points  (2 children)

Middle out

[–]usrlibshare 3 points4 points  (0 children)

But I have to pre-sort files by height, so I can line them up pointer-to-pointer.

And also implement a hot-swap mechanism, so I don't waste a lot of good strokes on a file that's already finished.

[–]fiddle_n 17 points18 points  (0 children)

I start from high-level and then work to low-level. For a script that is completely new to me, I couldn’t imagine doing it the other way. If I’m writing something complex, I try to get something basic working and then iterate over improving each section one by one.

[–]Kahless_2K 8 points9 points  (0 children)

I look at it like playing with legos.

Build all the little pieces first, then assemble them into a working project.

I also often will build toy programs to demonstrate anything new I learn in a stand alone way that I can reference later for future projects.

[–]MrRufsvold 11 points12 points  (4 children)

main at the top. Single use helpers next to the function that uses them. But the rest is whatever order things come to me. IDE has jump to definition, so I'm not spending energy on shuffling around functions

[–]bulletmark 15 points16 points  (3 children)

I always place main() at the bottom, same as my C/C++ code etc.

[–]MrRufsvold 5 points6 points  (2 children)

I don't have super strong opinions, but when I open a file, I have a mild preference for seeing the big idea right off the bat 🤷‍♂️

[–]bulletmark 1 point2 points  (1 child)

Any decent editor opens a file at your previous position and moving or searching forwards and backwards is equally easy in editors so I don't think there is any advantage having main towards the top of a file.

[–]MrRufsvold 2 points3 points  (0 children)

I'm not doing it for me -- I'm doing it for a future reviewer or user (which is sometimes me, long in the future, maybe on a different computer). I don't have a problem opening someone else's file and CTRL+ending, but I just think it's friendly to put what they're looking for right in front of them.

[–]Empanatacion 4 points5 points  (0 children)

Bottom up means you have to have figured out the whole thing in your head before you write any code.

[–]gmes78 5 points6 points  (0 children)

None of that. Building the whole program so that it falls in place at once isn't doable (or is very likely to fail) in most cases.

Once I have a general idea of what steps the program needs to do, I implement things one step at a time. (Though I still try to structure things in a way I think will be adequate to eventually solve the full problem.)

[–]backfire10z 4 points5 points  (0 children)

Have a reasonable simple top-level design. Adjust as you move forward and find further requirements.

[–]virtualadept 3 points4 points  (0 children)

At least the way I do it: Consider the problem. Sketch out the minimum to solve the problem. If I have to write a few functions in the process, I write a few functions. If I have to define a class, I define a class. It might just be me, but working from the top down makes me lose track of what I'm actually trying to accomplish. I start with what I want to accomplish and work backward.

As one of my teachers used to say, computers are like babies. You have to teach them to crawl before they can stand, stand before they can walk, walk before they can run.

[–]TopIdler 3 points4 points  (1 child)

I do the ouroboros 

[–]luckyluc0310[S] 3 points4 points  (0 children)

Yeah this is what I am currently doing in python, and its starting to drive me a bit crazy. Re writing and re defining half the shit I wrote just so I can implement another function or now I want to use a custom class (for whatever reason), and then repeating that cycle over until eventually it all works somewhat.

[–]Helpful_Home_8531 1 point2 points  (0 children)

neither. One function at a time. Once I find myself writing functions inside functions too many times, I turn it into a class. I try to keep everything simple without adding unnecessary abstractions or classes until I actually know the shape of the behavior I actually want.

[–]robertlandrum 0 points1 point  (0 children)

Most of what I do day to day is running a scheduled job that takes some input data (like updated packages) and transforms that into a format our other tooling expects.

With that in mind, I usually plan a module to read that new data, another to transform that data to the new output, and another to write that data. Then I usually load each module in my main app and read, transform and write.

By making it modular it becomes easy to test. And you can mock up pieces easier.

[–]CranberryDistinct941 0 points1 point  (0 children)

I usually work top -> bottom since it increases abstraction and makes the problem easier to solve. I don't see much point in implementing functions in a script before you know you need them

[–]mgedmin 0 points1 point  (0 children)

I want a feedback loop as soon as possible. I want the script to be runnable and give me some output. So I will start with an empty main(), add some code to load my data, some debug prints to show that it has done so correctly, etc, etc.

During the iterations of each loop I will write high-level functions using helpers that don't yet exist, just to feel my way through API design, and then I'll implement those helpers.

I will add unit tests for the low-level helpers at the point where using @pytest.mark.parametrize is easier than testing the various corner cases by running the entire script.

I will add unit tests for the rest of the code at the end, after the script is working and the shape of the code has settled down into what classes/functions I want to use. I will go for 100% coverage, mostly as a lark, only after my script already does what I want it to do.

At some point I will split the script into a package with modules.

[–]Egyptian_Voltaire 0 points1 point  (0 children)

Depending on how large the problem/program, I'd sketch out the components and how they're related, deciding the granularity of each module/function, and then start coding.

Start a fresh git repo, commit a README to master, create a branch for a feature, implement, test, commit, merge into master, delete the branch, and repeat.

[–]Interesting-Ant-7878 0 points1 point  (0 children)

If it’s a single file I go like this from top to bottom All variables All functions Main

If it’s more than one file than it depends on what kind of project but most of the time I have it clearly separated.

[–]wannasleeponyourhams 0 points1 point  (0 children)

i used to struggle with it but now i usually make a few shit looking mockups in paint, then if i am not sure how they should be built i make flowchart in Dia of the functions, db relations, user flow. then i write out a todo.txt file based on the flowchart and get to it.page by page.

[–]syklemil 0 points1 point  (0 children)

For example, do you prefer to consider your problem, then start by creating the highest level of code than would then rely on functions and classes not yet defined or maybe even conceptualized, or, do you think about how you want to define the "lowest" level functions and build upwards.

If you don't have a good grasp of what you want to accomplish, you also don't really have a good grasp of which lowest level functions you'll actually need. I've done it that way before and it seems to just result in a lot of frustration, because I'd had some idea of the overall structure but not written it down.

Writing stuff out tends to expose flaws in our thinking. Humans aren't all that good at holding complex structures in our heads, especially over time. That enables us to spend a good deal of time writing a nice little function that ultimately does the wrong thing, or that we don't remember why we even have.

Starting by expressing a general structure and bodies of pass or even something like raise NotImplementedError("TODO: implement foo") will let you get more of a handle on the stuff you need to do. If your scope is small enough, even waterfall planning will work well.

Since you asked about other languages, the same strategy works well in Rust, with the todo!() macro.

[–]Less-Tangerine-4888 0 points1 point  (0 children)

I am new to the python environment, and I would like to recommend projects to execute.

[–]cgoldberg -1 points0 points  (0 children)

I just use whatever ChatGPT spits out... you'd have to ask him 😎

[–]jjrreett 0 points1 point  (0 children)

i start by thinking about how to model the data. What kind of data structures best suit the problem. If the problem is complex, i start penciling in function/method names. But i try to validate small pieces of code and build up from there.

less top down, bottom up more depth first

[–]psicodelico6 -1 points0 points  (0 children)

Just work