Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
Mrs. Wynand
Nov 23, 2002

DLT 4EVA

BigRedDot posted:

Every feature of a language should be used judiciously. Python dictionaries are wonderful, but their over-allocation growth is extremely aggressive. If you don't understand this you can easily write extremely suboptimal code.
I dunno about "easily" - most applications don't need to go nuts with dict inits. You certainly shouldn't break out slots until you have a positive reason to (supported by actual profiling data based on the actual production usage patterns).

quote:

Can you expand or provide some examples for why decorators in particular are different? Right now this admonishment sounds like a "just-so" story.

They aren't fundamentally different, like I said, it's a matter of "some more than others". It's based on their potential of abuse and how much damage that abuse can cause. Dicts are not very easy to abuse (unless you start using them in lieu of classes or something ridiculous like that). I think decorator abuse is more common. I have both seen people do it and been guilty of it myself.

(since you asked for specifics, this is going to get long)

Something about decorators just sort of makes them look like good fits for solving certain kinds of problems but there are significant drawbacks associated with them which are not really obvious (until you've ran into them). Authorization frameworks and caching are some usual suspects for making you fall into these traps IMO. I guess it's because at first glance it looks like a neat separation of concerns - e.g. "oh this method is actually all about doing this one specific thing, and figuring out authorization/caching/logging is just incidental to that! I know, I'll break those out in a decorator, leaving the method body with just a single responsibility and encouraging code-reuse by having a generic auth/cache/logging framework! How wonderful!"

This may well be the case except whereas before you had two simple problems (do this one thing, and also cache that one thing), you now have one simple problem (do the one thing) and one much more complex one (a general, re-usable caching framework that has to adapt to currently unknowable requirements). You'll notice this as you find your decorators more and more complicated to configure. What started out as @memoize quickly becomes @memoize(expiration=123) which then becomes @memoize(expiration=123, invalidate_on=signal) which then becomes @memoize(expiration_strategy=(memoize.rule('user-cache-invalidation-signals @ invalidated') && memoize.rule('oh god what I done'))).

You also tend to run into fact that these little ancillary concerns actually depend on some runtime state that you easily have access to inside your method body, but not outside of it (at :airquote:compile:airquote: time), so now you have to decide between tightly coupling your fancy decorators to specific method signatures or doing something generic but really really complicated.

So... you could do that. Or you could just put an if statement inside your method body.

You can of course also go off the rails into architecture-space-journey inside your method body as well, but I really think you are a lot less likely to do so since you have so much more freedom to go with a much simpler situation-specific solution. You can also use decorators in some places and forgo them for simple local solution as needed. And of course there are always going to be applications where decorators really are the best solution, e.g. because you specifically need access to some metadata outside the method body execution. The separation of concerns they can bring isn't imagined either - it really can be a much better way to write your app, you just need to be aware of what you're committing to. Like I said, it's just a matter of judicious use and "some more than others".

The most egregious abuse of decorators I've seen was this auto-html-admin type builder for an API where the average ratio of decorators to method bodies was easily 5:1. You configured the whole page in the decorator - the widgets used, the tables being generated, the validation and data marshaling rules. It was loving nuts. The actual method body would be some piss-trivial operation like adding the given item to some list. It is way past the point of practical unfucking, the only way forward is to add even more generic configurability to it. I'd bet my right hand that thing started with something like "hmm, I could probably use decorators for this, it will be so neat".

This may be why I err on the side of being conservative when it comes to decorators ;). Also just in general I've been burned by "time saving" magic far more often than I've been noticeably helped by it, so I tend to be skeptical (though hopefully not outright dismissive) about cool language tricks as a rule.

Mrs. Wynand fucked around with this message at 06:45 on Dec 3, 2013

Adbot
ADBOT LOVES YOU

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb
That was a great post to read, well done :)

I think I'll stick with the if statement for now.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
:swoon:PyCharm Community Edition:swoon:

I hate an IDE war as much as everybody else, but I just used PyCharm for the first time today. I didn't want to fork $ for it back when it was closed for development at home. Now at work I am so fed up with not have ReSharper-like power with Python source that I was about to go start a trial license. Then I found out the community edition had happened.

I had to merge 2 months of garbage code into a branch manually and make some tactful decisions along the way, and it just ate it right up. I was assuming it was going to take me over two hours just to get that first pass done, but I had it done in 40 minutes, starting with opening up PyCharm for the first time. I imagine it's overkill for some smaller stuff, but for doing code archaeology, I couldn't imagine anything else. Okay, I have to see what happens when I try to use the debugger . . .

Dominoes
Sep 20, 2007

My Rhythmic Crotch posted:

I think the simplest solution would be one table to hold the symbols, then another table that has a column for date, one column for each kind of attribute, and then a foreign key to the symbol table.

Stepping up one level in complexity would be one table to hold symbols, one table to hold attribute names, and a third table would hold a foreign key to symbol, a foreign key to attribute name, have a column for the value of the attribute, and one column for the date.
Would the tables in your second example look like this? In JSON, repeating the symbol, date, and attribute names increases the file size and slows down reading/writing, so things like abbreviating 'close' to 'c' speed things up. I assumed databases would avoid this, but it appears like this is repeating info as well. Or perhaps it's not as stored, since the repetitive 'GOOG' entries are just references to one 'GOOG'? Or would I use integer ids that tie it to the symbols and attributes instead of the symbol/attribute names themselves?

Dominoes fucked around with this message at 12:06 on Dec 3, 2013

Dren
Jan 5, 2001

Pillbug
Dominoes, I don't have a class to recommend but this is one of those times where you could probably get a huge benefit from taking a step back from your problem to run through a quick intro to relational databases class or tutorial.

Eggie
Aug 15, 2010

Something ironic, I'm certain
Is there any way of calling an object by a parameter value? (For example, if I needed to find a 'baseball' object with the highest 'size' attribute.)

Vulture Culture
Jul 14, 2003

I was never enjoying it. I only eat it for the nutrients.

Rocko Bonaparte posted:

:swoon:PyCharm Community Edition:swoon:

I hate an IDE war as much as everybody else, but I just used PyCharm for the first time today. I didn't want to fork $ for it back when it was closed for development at home. Now at work I am so fed up with not have ReSharper-like power with Python source that I was about to go start a trial license. Then I found out the community edition had happened.

I had to merge 2 months of garbage code into a branch manually and make some tactful decisions along the way, and it just ate it right up. I was assuming it was going to take me over two hours just to get that first pass done, but I had it done in 40 minutes, starting with opening up PyCharm for the first time. I imagine it's overkill for some smaller stuff, but for doing code archaeology, I couldn't imagine anything else. Okay, I have to see what happens when I try to use the debugger . . .
All of the JetBrains IDEs are insane. I use WebStorm for all my day-to-day stuff, and it's incredible. They're the only company out there making IDEs that really understands how to use keyboard shortcuts productively.

evensevenone
May 12, 2001
Glass is a solid.
I just wish PyCharm didn't look like poo poo on Linux. Apparently to get anti-aliased fonts, you have to patch the Java VM. You also have to use Oracle Java.

The completer is amazing though, really wish I could get the same results in Sublime.

Mrs. Wynand
Nov 23, 2002

DLT 4EVA

Eggie posted:

Is there any way of calling an object by a parameter value? (For example, if I needed to find a 'baseball' object with the highest 'size' attribute.)

Just like, finding the largest value of a property from a list of objects?

max(baseball.size from baseball in baseballs) is probably more idiomatic.

You can also do max(baseballs, key=lambda baseball: baseball.size) or max(baseballs, key=operators.attrgetter('size') if you want something slightly more like ruby's crazy baseballs.max(&:size).

Lysidas
Jul 26, 2002

John Diefenbaker is a madman who thinks he's John Diefenbaker.
Pillbug

evensevenone posted:

I just wish PyCharm didn't look like poo poo on Linux. Apparently to get anti-aliased fonts, you have to patch the Java VM. You also have to use Oracle Java.

I exclusively use PyCharm on Linux, and I've never had any complaints about its appearance, nor have I had to patch the JVM to have antialiased fonts.


In my experience, JetBrains' IDEs work perfectly fine with OpenJDK 7 -- I mainly use the Oracle JVM to avoid having to remove the OpenJDK check from the launcher shell script every time I update the IDE.

Computer viking
May 30, 2011
Now with less breakage.

Eggie posted:

Is there any way of calling an object by a parameter value? (For example, if I needed to find a 'baseball' object with the highest 'size' attribute.)

Uh, could you restate that, perhaps with a small bit of example code? I wrote something like Mr. Wynand's reply, but on re-reading I'm still not sure if that's what you're asking for. :)

evensevenone
May 12, 2001
Glass is a solid.

Lysidas posted:

I exclusively use PyCharm on Linux, and I've never had any complaints about its appearance, nor have I had to patch the JVM to have antialiased fonts.



Weird. I'll post a screenshot when I get to work, but for me only the editor is antialiased; the menus and even the tree on the left are not (and very ugly). I'm using xubuntu but I can't really imagine that's a factor.

This indicates that I'm not alone in this: http://youtrack.jetbrains.com/issue/IDEA-57233 .

What distro are you using?

Lysidas
Jul 26, 2002

John Diefenbaker is a madman who thinks he's John Diefenbaker.
Pillbug
Kubuntu 13.10 on all of my machines, and PyCharm has always looked great even as far back as 11.04.

salisbury shake
Dec 27, 2011
If you're running the Infinality freetype patches you need to use the Oracle java package + need to patch a file or edit a config or something.

I said this last page, but Jetbrains are very lenient w/r/t handing out full licenses for open-source projects.

My Rhythmic Crotch
Jan 13, 2011

Holy poo poo PyCharm is awesome, don't know how I didn't hear about the community edition until now

Mrs. Wynand
Nov 23, 2002

DLT 4EVA
Does the community edition do that remote interpeter vagrant magic? I sort of discounted using pycharm out of hand since I assumed it needed to run on the local python env and I always always always run the actual servers in a headless VM. But turns out it can absolutely do that that workflow, so now I am interested.

Mrs. Wynand
Nov 23, 2002

DLT 4EVA
Also I had no idea python 3 introduces advisory type annotations (and some people, notably jetbrains, are actually trying to build tools on top of that).

I'd love me a type-inferred python with generics and poo poo.

I now care about python 3.

Thern
Aug 12, 2006

Say Hello To My Little Friend

Mr. Wynand posted:

Does the community edition do that remote interpeter vagrant magic? I sort of discounted using pycharm out of hand since I assumed it needed to run on the local python env and I always always always run the actual servers in a headless VM. But turns out it can absolutely do that that workflow, so now I am interested.

According to this, it doesn't:
http://www.jetbrains.com/pycharm/features/editions_comparison_matrix.html

Although the VM integration is pretty sweet as it allows you to even init, start, stop, and destroy vagrant instances. The one problem I have is whenever I install a new package to the remote interpreter, the inspections doesn't pick up on the new package at all. The only way I've been able to fix it is by restarting PyCharm.

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

Mr. Wynand posted:

Also I had no idea python 3 introduces advisory type annotations (and some people, notably jetbrains, are actually trying to build tools on top of that).

I'd love me a type-inferred python with generics and poo poo.

I now care about python 3.

You can also get pycharm to prompt you about type issues on python 2.x projects by including type hints in docstrings.

http://www.jetbrains.com/pycharm/webhelp/type-hinting-in-pycharm.html

Mrs. Wynand
Nov 23, 2002

DLT 4EVA

Thermopyle posted:

You can also get pycharm to prompt you about type issues on python 2.x projects by including type hints in docstrings.

http://www.jetbrains.com/pycharm/webhelp/type-hinting-in-pycharm.html

Neat-o!

Does their JS editor do this sort of thing as well? (I actually use jsdoc somewhat consistently) I assume they also make stand-alone fancy js/node editors.

Eggie
Aug 15, 2010

Something ironic, I'm certain

Computer viking posted:

Uh, could you restate that, perhaps with a small bit of example code? I wrote something like Mr. Wynand's reply, but on re-reading I'm still not sure if that's what you're asking for. :)

If you'll ignore my baseball example earlier, I'm trying to code a pathfinding program using the A* method. So far my program can take a starting node and calculate the FGH values of all adjacent nodes. The step I'm stuck at is calling the node with the lowest F value.

At the risk of letting everyone see my ugly code, here's the for-loop that takes all nodes in the Open List and calculates their FGH values by comparing their x, y positions to an ending node.

code:
for node in open_list:
		
	#This is not the true method of calculating the G value.
	node.g = 1
		
	#The H calculation is as follows.
	x_len = node.coord[0] - end.coord[0]
	y_len = node.coord[1] - end.coord[1]
	
	#This bit of code ensures that the x_len and y_len values are positive so they can be properly compared when the max function determines which length is greater.
	if x_len < 0:
		x_len *= -1
	if y_len < 0:
		y_len *= -1

	node.h = max(x_len, y_len)
	
	node.f = node.g + node.h
So what I want to happen next is have my program figure out which node has the lowest F score and check the FGH scores of its adjacent nodes, thus repeating the process.

Mrs. Wynand
Nov 23, 2002

DLT 4EVA
Ok then yes, that thing I said (except using min instead of max if you want lowest obvs).

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb

fletcher posted:

Python code:
class Thingy():
  cached_expensive_stuff = None

  def get_expensive_stuff(self):
    if self.cached_expensive_stuff is None:
      self.cached_expensive_stuff = []
      # expensive operation to fill the array with goodies
    return self.cached_expensive_stuff
I want to be able to call get_expensive_stuff() all willy nilly...is this an alright way to go about that? Or is there a better way?

After reading about this a bit more, I'm a little confused.

I was thinking cached_expensive_stuff = None was initializing an instance variable, not a class variable. I don't want different instances of Thingy using the same cached_expensive_stuff. But from my test, it doesn't seem like they are using the same cached_expensive_stuff, so it works like I intended?

Python code:
import uuid


class Thingy(object):
    cached_expensive_stuff = None

    def get_expensive_stuff(self):
        if self.cached_expensive_stuff is None:
            print('Doing expensive operation')
            self.cached_expensive_stuff = uuid.uuid4()
        return self.cached_expensive_stuff


print(Thingy.cached_expensive_stuff)

print('firstThing')

firstThing = Thingy()
print(firstThing.get_expensive_stuff())
print(firstThing.cached_expensive_stuff)

print('secondThing')

secondThing = Thingy()
print(secondThing.get_expensive_stuff())
print(secondThing.cached_expensive_stuff)

print('firstThing again')

print(firstThing.get_expensive_stuff())
print(firstThing.cached_expensive_stuff)

print(Thingy.cached_expensive_stuff)
Results:
code:
None
firstThing
Doing expensive operation
b62b35dd-0ecf-4aa5-9e3f-745ab27ed0d7
b62b35dd-0ecf-4aa5-9e3f-745ab27ed0d7
secondThing
Doing expensive operation
68b1ab53-0bb7-4e56-aa56-0ca18e720762
68b1ab53-0bb7-4e56-aa56-0ca18e720762
firstThing again
b62b35dd-0ecf-4aa5-9e3f-745ab27ed0d7
b62b35dd-0ecf-4aa5-9e3f-745ab27ed0d7
None
Is it both an instance and a class variable or something? I'm coming from Java land if that matters.

Pollyanna
Mar 5, 2005

Milk's on them.


"Python 3 to Javascript translator written in Python that produces fast portable javascript code."

Correct me if I'm wrong, but if it's possible to translate between languages, then why can't you just write an entire project in one language and then translate it into another?

Although it's prolly cause 1. machine translation isn't that great and 2. working backwards from what a language creates is a pain, especially if it's compiled. Right?

Lurchington
Jan 2, 2003

Forums Dragoon

fletcher posted:

Is it both an instance and a class variable or something? I'm coming from Java land if that matters.

the tl;dr version, is that:
- there's a class attribute set to None, and new instances of that class will have None as the value.
- instances of this class can read the value of class attribute given a name using "self.name", "self.__class__.name" or "cls.name" (in a class method)
- a particular instance has the ability to "shadow" the class attribute by setting an instance attribute of the same name using "self.name = new_value.
-- conceptually, this is similar to "monkey patching" (http://stackoverflow.com/a/5626250/171094)

Lurchington fucked around with this message at 03:03 on Dec 4, 2013

My Rhythmic Crotch
Jan 13, 2011

Pollyanna posted:

"Python 3 to Javascript translator written in Python that produces fast portable javascript code."

Correct me if I'm wrong, but if it's possible to translate between languages, then why can't you just write an entire project in one language and then translate it into another?

Although it's prolly cause 1. machine translation isn't that great and 2. working backwards from what a language creates is a pain, especially if it's compiled. Right?
Writing in one language and executing in another is perfectly possible. Normally, compilers are used to build machine code from high level code.

Google is doing something very similar to get their Dart scripting language going - it can optionally output javascript so that browsers that don't understand Dart can still run Dart apps.

Pollyanna
Mar 5, 2005

Milk's on them.


My Rhythmic Crotch posted:

Writing in one language and executing in another is perfectly possible. Normally, compilers are used to build machine code from high level code.

Google is doing something very similar to get their Dart scripting language going - it can optionally output javascript so that browsers that don't understand Dart can still run Dart apps.

Ohh. Well...that's not so bad really. Maybe I'll check it out.

Also, I have a problem with virtualenv. I'm trying to install packaged from a requirements.txt, which includes numpy and matplotlib, and I get this error:

code:
(dataenv)Rebeccas-MacBook-Pro:dataviz rebecca$ pip install -r requirements.txt
Downloading/unpacking numpy (from -r requirements.txt (line 2))
Cleaning up...
Exception:
Traceback (most recent call last):
  File "/Users/rebecca/Desktop/NerdStuff/Tutorials/new-coder/dataviz/dataenv/lib/python2.7/site-packages/pip/basecommand.py", line 134, in main
    status = self.run(options, args)
  File "/Users/rebecca/Desktop/NerdStuff/Tutorials/new-coder/dataviz/dataenv/lib/python2.7/site-packages/pip/commands/install.py", line 236, in run
    requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle)
  File "/Users/rebecca/Desktop/NerdStuff/Tutorials/new-coder/dataviz/dataenv/lib/python2.7/site-packages/pip/req.py", line 1085, in prepare_files
    url = finder.find_requirement(req_to_install, upgrade=self.upgrade)
  File "/Users/rebecca/Desktop/NerdStuff/Tutorials/new-coder/dataviz/dataenv/lib/python2.7/site-packages/pip/index.py", line 201, in find_requirement
    page = self._get_page(main_index_url, req)
  File "/Users/rebecca/Desktop/NerdStuff/Tutorials/new-coder/dataviz/dataenv/lib/python2.7/site-packages/pip/index.py", line 554, in _get_page
    return HTMLPage.get_page(link, req, cache=self.cache)
  File "/Users/rebecca/Desktop/NerdStuff/Tutorials/new-coder/dataviz/dataenv/lib/python2.7/site-packages/pip/index.py", line 671, in get_page
    resp = urlopen(url)
  File "/Users/rebecca/Desktop/NerdStuff/Tutorials/new-coder/dataviz/dataenv/lib/python2.7/site-packages/pip/download.py", line 176, in __call__
    response = self.get_opener(scheme=scheme).open(url)
  File "/Users/rebecca/Desktop/NerdStuff/Tutorials/new-coder/dataviz/dataenv/lib/python2.7/site-packages/pip/download.py", line 238, in get_opener
    headers.append(("User-agent", build_user_agent()))
  File "/Users/rebecca/Desktop/NerdStuff/Tutorials/new-coder/dataviz/dataenv/lib/python2.7/site-packages/pip/download.py", line 35, in build_user_agent
    _implementation = platform.python_implementation()
  File "/Users/rebecca/anaconda/lib/python2.7/platform.py", line 1499, in python_implementation
    return _sys_version()[0]
  File "/Users/rebecca/anaconda/lib/python2.7/platform.py", line 1464, in _sys_version
    repr(sys_version))
ValueError: failed to parse CPython sys.version: '2.7.5 (default, Aug 25 2013, 00:04:04) \n[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)]'

Storing complete log in /Users/rebecca/.pip/pip.log
I have no idea what this means. :confused: Can anyone explain to me what's going on?

Computer viking
May 30, 2011
Now with less breakage.

Pollyanna posted:

Ohh. Well...that's not so bad really. Maybe I'll check it out.

Quite a lot of languages used to compile down to C, since there are C compilers available for ca. everything ever. Some still do, I think. Javascript fills a similar "available everywhere"-niche, so it's not surprising that there's a bunch of "compile to JS" projects. :)


As for the error, does this look vaguely relevant?
https://github.com/ContinuumIO/anaconda-issues/issues/33
If I understand it right, the problem is that is runs code from /Users/rebecca/anaconda/ , but the python interpreter isn't the anaconda one. Somewhere in their code they're parsing the python version string, and the one produced by whichever python version you use doesn't quite fit their assumptions.

Computer viking fucked around with this message at 12:20 on Dec 4, 2013

Pollyanna
Mar 5, 2005

Milk's on them.


Well, being able to compile to JS from Python makes writing a simple game in JS a lot easier at the very least. :v:

Computer viking posted:

As for the error, does this look vaguely relevant?
https://github.com/ContinuumIO/anaconda-issues/issues/33
If I understand it right, the problem is that is runs code from /Users/rebecca/anaconda/ , but the python interpreter isn't the anaconda one. Somewhere in their code they're parsing the python version string, and the one produced by whichever python version you use doesn't quite fit their assumptions.

Dang. How do I change my current Python version, again? I tried editing .bash_profile but it didn't change whether or not I used Anaconda.

As for the current interpreter, calling sys.version tells me that it's the Anaconda interpreter. v:confused:v

QuarkJets
Sep 8, 2008

Pollyanna posted:

Well, being able to compile to JS from Python makes writing a simple game in JS a lot easier at the very least. :v:


Dang. How do I change my current Python version, again? I tried editing .bash_profile but it didn't change whether or not I used Anaconda.

As for the current interpreter, calling sys.version tells me that it's the Anaconda interpreter. v:confused:v

You mean when you type 'python somemodule'? Try changing your PATH. If you're using a shebang ('#!/usr/bin/env python') and typing './somemodule' then you can just specify the specific Python you want directly

onionradish
Jul 6, 2006

That's spicy.
I built a basic web app using BaseHTTPServer that does simple formatting based on an sqlite database. It works totally fine as is, and importantly automatically launches my browser when I run the script:
Python code:
...
httpd = HTTPServer(('', 8080), RequestHandler)
webbrowser.open('http://localhost:8080')
httpd.serve_forever()
I'd like to move up to a light web framework and am trying to convert the code to bottle (single-file dependency is valued, which is why I'm not jumping to flask). However, since bottle's 'run()' method blocks, I'm not sure how to invoke webbrowser.open() once the server is active, if it's even possible.

Houston Rockets
Apr 15, 2006

Use multiprocess or threading.

ArcticZombie
Sep 15, 2010
I want to make a browser interface for an invoicing thing I've made. I know nothing about web development. The interface being a way to edit old / add new invoices to an sql database and to run invoice program on the selected invoice to spit out the PDF. I'm not going to be running it actually over any sort of network, I just want a browser interface on the local machine. Is bottle/flask the sort of thing I want for this? Is using an sql database to store the invoice information overkill?

Mrs. Wynand
Nov 23, 2002

DLT 4EVA

ArcticZombie posted:

I want to make a browser interface for an invoicing thing I've made. I know nothing about web development. The interface being a way to edit old / add new invoices to an sql database and to run invoice program on the selected invoice to spit out the PDF. I'm not going to be running it actually over any sort of network, I just want a browser interface on the local machine. Is bottle/flask the sort of thing I want for this? Is using an sql database to store the invoice information overkill?

Serious question: Have you considered just using an existing invoicing app? It is quite possibly one of the most oft-developed types of app ever. I like harvestapp myself, and unless your company is Deloitte & Touche or something, I assure you there will be one for your specific needs as well.

Barring that, you could use one of those magic & wizards graphical DYI relational database builders - like good ol' MS Access, or FileMaker (there's a bunch of hip new web-based ones as well, but I couldn't recommend you a specific one). It's a very very very very common problem to solve.

Barring that as well, you probably want something that can auto-generate an admin UI, probably django, but good luck packaging that up to run painlessly on, say, a windows desktop. I would just host it on heroku or something, tis not expensive (can even be free if you barely ever use it).

a lovely poster
Aug 5, 2011

by Pipski

Pollyanna posted:

Well, being able to compile to JS from Python makes writing a simple game in JS a lot easier at the very least. :v:

How so? You're still going to need to understand whatever JS library you're using thoroughly in order to build any kind of game. You're just adding another layer of difficulty on top of it imo. If you want to make a game in JS, make a game in JS. http://www.antonoffplus.com/coding-an-html5-game-for-30-minutes-or-an-introduction-to-the-phaser-framework/

narthollis
May 7, 2013

onionradish posted:

I built a basic web app using BaseHTTPServer that does simple formatting based on an sqlite database. It works totally fine as is, and importantly automatically launches my browser when I run the script:
Python code:
...
httpd = HTTPServer(('', 8080), RequestHandler)
webbrowser.open('http://localhost:8080')
httpd.serve_forever()
I'd like to move up to a light web framework and am trying to convert the code to bottle (single-file dependency is valued, which is why I'm not jumping to flask). However, since bottle's 'run()' method blocks, I'm not sure how to invoke webbrowser.open() once the server is active, if it's even possible.

Something like this should do what you need.

Python code:
import os

pid = os.fork()
if pid > 0:
    app.run()
else:
    webbrowser.open('http://localhost:8080')

Dominoes
Sep 20, 2007

PyCharm PEP 8 flagger issue:

PEP8 posted:

If operators with different priorities are used, consider adding whitespace around the operators with the lowest priority(ies). Use your own judgment; however, never use more than one space, and always have the same amount of whitespace on both sides of a binary operator.

Yes:

i = i + 1
submitted += 1
x = x*2 - 1
hypot2 = x*x + y*y
c = (a+b) * (a-b)

PyCharm's PEP8 analyzer flags not using whitespace in the example above. Is there a way to correct this behaviour without disabling the "missing whitespace around arithmetic operator" entirely? Seems like a bug.

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

Dominoes posted:

PyCharm PEP 8 flagger issue:


PyCharm's PEP8 analyzer flags not using whitespace in the example above. Is there a way to correct this behaviour without disabling the "missing whitespace around arithmetic operator" entirely? Seems like a bug.

PyCharm doesn't flag those for me.

I'm running version 131.618.

ArcticZombie
Sep 15, 2010

Mr. Wynand posted:

Serious question: Have you considered just using an existing invoicing app? It is quite possibly one of the most oft-developed types of app ever. I like harvestapp myself, and unless your company is Deloitte & Touche or something, I assure you there will be one for your specific needs as well.

Barring that, you could use one of those magic & wizards graphical DYI relational database builders - like good ol' MS Access, or FileMaker (there's a bunch of hip new web-based ones as well, but I couldn't recommend you a specific one). It's a very very very very common problem to solve.

Barring that as well, you probably want something that can auto-generate an admin UI, probably django, but good luck packaging that up to run painlessly on, say, a windows desktop. I would just host it on heroku or something, tis not expensive (can even be free if you barely ever use it).

The primary reason I started this was a learning experience, not because there's any pressing need for a poo poo hot invoicing application. Making my work life a little easier whilst learning seems like a win-win to me.

VV Thanks.

ArcticZombie fucked around with this message at 17:57 on Dec 5, 2013

Adbot
ADBOT LOVES YOU

My Rhythmic Crotch
Jan 13, 2011

ArcticZombie posted:

I want to make a browser interface for an invoicing thing I've made. I know nothing about web development. The interface being a way to edit old / add new invoices to an sql database and to run invoice program on the selected invoice to spit out the PDF. I'm not going to be running it actually over any sort of network, I just want a browser interface on the local machine. Is bottle/flask the sort of thing I want for this? Is using an sql database to store the invoice information overkill?
Yes, flask is fine for that. A SQL DB is not overkill.

  • Locked thread