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.
 
  • Post
  • Reply
baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

CheckIo is pretty great for problems once you get into it. I tried HackerRank for a bit with Java 8 and some of the questions were shockingly bad, like they were taking community submissions with no quality control. No idea what the Python section's like though!

But those kinds of things tend to be isolated problems, Eela's suggestion is good because you get practice actually designing and building an application in Python, working with classes and messing with command-line args and whatever else. So you're ready to just dive in and build whatever the interviewer wants, without being unfamiliar with some of the basic language stuff

Adbot
ADBOT LOVES YOU

SurgicalOntologist
Jun 17, 2004

laxbro posted:

Newbie question: I'm trying to build a web scraper with Beautiful Soup that pulls table rows off of the roster pages for a variety of college sports teams. I've got it working with regular HTML pages, but it doesn't seem to work with what appear to be Angular pages. Some quick googling makes it seem like I will need to use a python library like selenium to virtually load the page in order to scrape the html tables on the page. Would a work around be to first use Beautiful Soup, but if a table row returns as None, then call a function to try scraping the page using something like selenium. Or, should I just try to scrape all of the pages with selenium or a similar library?

Load the page with Chrome deveoper tools open. The Network tab, I think, is where you can inspect requests. You might be able figure out how the page is fetching the data. I've been in a similar situation and found that the site was making a request to some JSON API before loading the data. In developer tools you can see what the request headers and response looks like. In the easiest case you can just hit the API url and get JSON back. In a more complicated case you can examine the request headers and mimic them in your scraper.

onionradish
Jul 6, 2006

That's spicy.

laxbro posted:

Newbie question: I'm trying to build a web scraper with Beautiful Soup that pulls table rows off of the roster pages for a variety of college sports teams. I've got it working with regular HTML pages, but it doesn't seem to work with what appear to be Angular pages. Some quick googling makes it seem like I will need to use a python library like selenium to virtually load the page in order to scrape the html tables on the page. Would a work around be to first use Beautiful Soup, but if a table row returns as None, then call a function to try scraping the page using something like selenium. Or, should I just try to scrape all of the pages with selenium or a similar library?
As a suggestion, the way I've done this in the past is to write your parsing based on HTML with Beautiful Soup or lxml so it doesn't matter how the HTML is acquired. For sites that can be scraped without Javascript/selenium, the HTML can just be fetched with requests; for those that need selenium, the webdriver instance's page_source attribute will have the final JavaScript-manipulated HTML (as long as you wait for or detect that page loading is complete).

I also typically separate the HTML collection from the parsing, saving the HTML to disk so I can fine-tune the parsing without hitting the server. And if the site layout changes in the future, the captured HTML is available so I can update the parsing rules.

baka kaba posted:

Also Selenium was a real pain last time I used it, they updated something so the Firefox webdriver wasn't included anymore and everything broke. There might be a better scraper out there?

Setting up selenium now involves an extra step. It isn't hard, but seems to be really poorly described. Essentially, you need a middleware geckodriver in addition to selenium, and either specify the path to that driver when initializing the webdriver or just add it to your PATH. I've always just added it to PATH, but the other way is supposed to be as simple as this:

code:
from selenium import webdriver
driver = webdriver.Firefox(executable_path=r'your\path\geckodriver.exe')
driver.get('http://inventwithpython.com')
For selenium, you can optionally set up the Firefox QuickJava Extension to selectively disable loading/processing of images, Flash, CSS, Java and other things that slow down scraping. Here's an excerpt from one of my scripts that uses that plugin to initialize the driver and blocks some of the Firefox "welcome" screens.:

code:
class Browser(webdriver.Firefox):
    """
    Wrapper for selenium.webdriver.Firefox browser that adds custom
    methods

    :param use_javascript: True to allow browser to use Javascript
    """

    def __init__(self, use_javascript=False):
        profile = webdriver.FirefoxProfile()
        profile.set_preference("javascript.enabled", use_javascript)

        # disable annoying firefox "welcome/startup" page
        # http : //stackoverflow.com/questions/33937067/
        #   firefox-webdriver-opens-first-run-page-all-the-time#34622056
        profile.set_preference("browser.startup.homepage", "about:blank")
        profile.set_preference("startup.homepage_welcome_url", "about:blank")
        profile.set_preference("startup.homepage_welcome_url.additional", "about:blank")

        fx_to_disable = ['Images', 'AnimatedImage', 'CSS', 'Cookies', 
                         'Flash', 'Java', 'Silverlight']
        disable_fx(profile, fx_to_disable)

        super(Browser, self).__init__(profile)

def disable_fx(firefox_profile, fx_to_disable):
    valid_fx = {'Images', 'AnimatedImage', 'CSS', 'Cookies', 'Flash', 'Java', 
                'JavaScript', 'Silverlight', 'Proxy'}
    
    try:
        # QUICKJAVA_XPI_PATH set to filepath of QuickJava XPI file from
        # https : //addons.mozilla.org/en-us/firefox/addon/quickjava/
        #   curVersion
        firefox_profile.add_extension(QUICKJAVA_XPI_PATH)
	# prevents loading the 'thank you for installing screen'
        firefox_profile.set_preference(
            "thatoneguydotnet.QuickJava.curVersion", "2.0.6.1") 
    except (NameError, IOError):
        return firefox_profile

    fx_to_disable = [
        'thatoneguydotnet.QuickJava.startupStatus.{}'.format(fx)
        for fx in fx_to_disable if fx in valid_fx
    ]
    
    for fx in fx_to_disable:
        firefox_profile.set_preference(fx, 2)
    
    return firefox_profile
EDIT: To clarify on the QuickJava plugin, I downloaded (or installed and copied) the XPI file and specify the path in QUICKJAVA_XPI_PATH. The version string in disable_fx() will need to match whatever version you use if you want to block the "thanks for installing" screen.

onionradish fucked around with this message at 15:40 on Apr 23, 2017

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

pathlib is cool, Path.iterdir() is not because it's not sorted. Is there a natural sort I'm missing (where 'file2' < 'file10') or do I need to screw around parsing numbers from filenames here

Symbolic Butt
Mar 22, 2009

(_!_)
Buglord

baka kaba posted:

do I need to screw around parsing numbers from filenames here

Most likely yes. If you make it explicit that the number part is an integer you'll get the sorting you want:

>>> ('file', 2) < ('file', 10)
True
>>> ('file', '2') < ('file', '10')
False

Space Kablooey
May 6, 2009


Symbolic Butt posted:

Most likely yes. If you make it explicit that the number part is an integer you'll get the sorting you want:

>>> ('file', 2) < ('file', 10)
True
>>> ('file', '2') < ('file', '10')
False

I didn't know you could compare tuples like that. :aaa:

Cingulate
Oct 23, 2012

by Fluffdaddy
Why is there no natural sort in standardlib!?!!!

Death Zebra
May 14, 2014

EDIT: query deleted. Instead of getting an inexplicable error for the list item I said, I was getting a very easily explained error for the value after it. I should have read my own code more closely as well as restored the try and except clauses I removed yesterday while trying to diagnose another error.

Death Zebra fucked around with this message at 19:59 on Apr 24, 2017

Eela6
May 25, 2007
Shredded Hen

baka kaba posted:

pathlib is cool, Path.iterdir() is not because it's not sorted. Is there a natural sort I'm missing (where 'file2' < 'file10') or do I need to screw around parsing numbers from filenames here

pathlib Paths are hashable and orderable (and therefore sortable) so you can just call sorted!

EX:
code:

 Directory of C:\exampledir

04/24/2017  11:44 AM    <DIR>          .
04/24/2017  11:44 AM    <DIR>          ..
04/24/2017  11:44 AM                 0 barfile.txt
04/24/2017  11:37 AM    <DIR>          definitely_not_porn
04/24/2017  11:37 AM    <DIR>          folder_0
04/24/2017  11:37 AM    <DIR>          folder_1
04/24/2017  11:44 AM                 0 foofile.txt
04/24/2017  11:37 AM    <DIR>          not_porn
               2 File(s)              0 bytes
               6 Dir(s)  93,747,830,784 bytes free
IN:
Python code:
from pathlib import Path
p = Path(r'C:/exampledir')
for path in sorted(p.iterdir())
    print(path)
OUT:
code:
C:\exampledir\barfile.txt
C:\exampledir\definitely_not_porn
C:\exampledir\folder_0
C:\exampledir\folder_1
C:\exampledir\foofile.txt
C:\exampledir\not_porn
(Note that I am on a windows rather than POSIX system)

Death Zebra, can you give us the full stack trace?

Eela6 fucked around with this message at 19:50 on Apr 24, 2017

Space Kablooey
May 6, 2009


Eela6 posted:

pathlib Paths are hashable and orderable (and therefore sortable) so you can just call sorted!
*snip*

Death Zebra, can you give us the full stack trace?

How does it deal with a folder that has file1, file9, file10 and so on?

Eela6
May 25, 2007
Shredded Hen
Ordering is lexigrapic according to the path of the file. It works 'like you would expect' - file0 < file1 < file9.

More specifically, Lexigraphic ordering of strings and paths works more or less as follows:

Note that
Python code:

def __eq__(self, other):
        if len(self) == len(other) and all(ord(c) < ord(k) for c, k in zip(self, other)):
             return True
        return False

def __lt__(self, other):
          return any(ord(c) < ord(k) for c, k in zip(self, other)) or( 
               len(self) < len(other) and all(c == k for c, k in zip(self, other))
           )
       
(This is true at least for ASCII and the corresponding part of UTF-8.

EDIT: Oh, I see, your files aren't left-padded with zeros! I'm dumb. You can fix this by re-labeling the files. I'll have a solution up in a jiffy.

Eela6 fucked around with this message at 20:32 on Apr 24, 2017

Death Zebra
May 14, 2014

Eela6 posted:

Death Zebra, can you give us the full stack trace?

Thanks but that won't be necessary. Turns out the search term I used afterwards was getting no results. I really should have put something in to account for that already.

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

HardDiskD posted:

How does it deal with a folder that has file1, file9, file10 and so on?

Badly, I was using sorted() until I realised my data was out of order, tracked it down to the files coming in all file1, file10, file11. That's why I was hoping a natural sort was lurking in the standard library :bahgawd:

Oh well, maybe I can work around it with that split tuple suggestion up there, thanks! It just feels bad because it's brittle and Windows does natural sort ordering, missed opportunities

Eela6
May 25, 2007
Shredded Hen

baka kaba posted:

Badly, I was using sorted() until I realised my data was out of order, tracked it down to the files coming in all file1, file10, file11. That's why I was hoping a natural sort was lurking in the standard library :bahgawd:

Oh well, maybe I can work around it with that split tuple suggestion up there, thanks! It just feels bad because it's brittle and Windows does natural sort ordering, missed opportunities

This is kind of an overwrought solution but it should work just fine. I'm sure a REGEX wizard can do this in three lines if not less.
Python code:
from pathlib import Path
def by_file_number(path):
    parent, name = path.parent, path.name
    digits = frozenset(str(x) for x in range(10))
    for i, char in enumerate(reversed(name), 1):
        if char == '.':
            break
    else: # NO BREAK
        raise ValueError('no extension in filename')
    extension = name[-i:]
    for k, char in enumerate(reversed(name[:-i])):
        if char not in digits:
            break
    try:
        number = int(name[(-k-i):-i])
    except ValueError:
        number = None # We choose None since it is NOT ordered.
    prefix = name[:(-k-i)]
    return (parent, (prefix, number, extension))
    # Note we're returning a tuple of a the form (str, (str, union[int, None], str))
IN:
Python code:
filenames = (
        'C:\exampledir/file0.bat', 'C:\exampledir/file1.txt',
        'C:\exampledir/file2.txt', 
        'C:\exampledir/file10.txt', 
        'C:\exampledir/file11.txt', 
        'C:\otherdir/file21.txt',
        'C:\exampledir/foobar.jar')
paths = sorted((Path(name) for name  in filenames), key = by_file_number)
for path in paths:
    print(path)
OUT:
code:
C:\exampledir\file0.bat
C:\exampledir\file1.txt
C:\exampledir\file2.txt
C:\exampledir\file10.txt
C:\exampledir\file11.txt
C:\exampledir\foobar.jar
C:\otherdir\file21.txt

Eela6 fucked around with this message at 21:14 on Apr 24, 2017

Space Kablooey
May 6, 2009



Just had a quick glance at it, but you could use os.path.splitext to check the file extension. use the suffix property from Path.

Space Kablooey fucked around with this message at 21:21 on Apr 24, 2017

Vivian Darkbloom
Jul 14, 2004


baka kaba posted:

CheckIo is pretty great for problems once you get into it. I tried HackerRank for a bit with Java 8 and some of the questions were shockingly bad, like they were taking community submissions with no quality control. No idea what the Python section's like though!

But those kinds of things tend to be isolated problems, Eela's suggestion is good because you get practice actually designing and building an application in Python, working with classes and messing with command-line args and whatever else. So you're ready to just dive in and build whatever the interviewer wants, without being unfamiliar with some of the basic language stuff

I wish I had any completed applications to port! I've been messing around with small projects so I won't have nothing to show off, but I have not been great, historically, at finishing personal projects.

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Cheers Eela! I ended up doing a regex to grab the digits and everything else from the filename, but it's good to see other solutions because it feels like there should be a neat way of solving it in general

HardDiskD posted:

Just had a quick glance at it, but you could use os.path.splitext to check the file extension. use the suffix property from Path.

Yeah that and stem are handy (I've been messing around in that drat library for a couple of days)

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Vivian Darkbloom posted:

I wish I had any completed applications to port! I've been messing around with small projects so I won't have nothing to show off, but I have not been great, historically, at finishing personal projects.

Hell it's less about finishing them and more about starting them - I'm just thinking of an interview situation where they want you to model some data where you need a class, or they want a basic command-line tool that handles arguments, or they want you to to create a simple utility library where you only expose certain functions. Are you comfortable hitting the ground running with that stuff?

A lot of problem sites are more like 'here's some input and your function needs to provide a result' and you just write a function or two - which is great, but it doesn't touch on the design side of things too much. So I was just thinking it would be good to do some stuff where you have to handle that side of things, just for the practice and so you're not lost if they start expecting that kind of thing

ynohtna
Feb 16, 2007

backwoods compatible
Illegal Hen
Here's my common snippet to convert an iterable into natural sort order:
Python code:
import re
def sorted_nicely(iter):
    """ Sort the given iterable in the way that humans expect."""
    convert = lambda text: int(text) if text.isdigit() else text
    alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ]
    return sorted(iter, key=alphanum_key)
Usage is:
Python code:
    for p in sorted_nicely(seen_paths):
        print(p)

dougdrums
Feb 25, 2005
CLIENT REQUESTED ELECTRONIC FUNDING RECEIPT (FUNDS NOW)
code:
$ pip3 search make sandwich

pysandwich (0.1.2) 		python sandwiches.
panini (2.4.6) 	 		The Simple Sandwich Maker. (https://panini.io)
libsandwich (0.1)  		Wrapper for libsandwich
sandwich-python (3.13.2) 	Python module for crossway multi-aspect production patterns.
yasm (1.4) 			Yet Another Sandwich Maker
pysw (1) 			makes yto samwitch!!!
sandwichmaker (2.0) 		easy to use sandwich maker
...

Eela6
May 25, 2007
Shredded Hen

ynohtna posted:

Here's my common snippet to convert an iterable into natural sort order:
Python code:
import re
def sorted_nicely(iter):
    """ Sort the given iterable in the way that humans expect."""
    convert = lambda text: int(text) if text.isdigit() else text
    alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ]
    return sorted(iter, key=alphanum_key)
Usage is:
Python code:
    for p in sorted_nicely(seen_paths):
        print(p)

Ooh, this one is nice.

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Oh yeah, that's swish as hell

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!

dougdrums posted:

code:

$ pip3 search make sandwich

pysandwich (0.1.2) 		python sandwiches.
panini (2.4.6) 	 		The Simple Sandwich Maker. ([url]https://panini.io[/url])
libsandwich (0.1)  		Wrapper for libsandwich
sandwich-python (3.13.2) 	Python module for crossway multi-aspect production patterns.
yasm (1.4) 			Yet Another Sandwich Maker
pysw (1) 			makes yto samwitch!!!
sandwichmaker (2.0) 		easy to use sandwich maker
...

How come when I search pip it always shows me like a list of 648383628 packages, most of which don't even have what I searched for in the title or short description? Or maybe it does and I just don't see it because the list is just so huge that I gloss over everything.

dougdrums
Feb 25, 2005
CLIENT REQUESTED ELECTRONIC FUNDING RECEIPT (FUNDS NOW)
I'm not sure, but you might be able to put searchable keywords or something into the setup.py. I know that if the package name is not the same as the module name, and I search for the module name, I will still get the package even if it's not in the description.

I decided to enter python's gates of dependency hell and it's a fuckin blast.

dougdrums fucked around with this message at 18:37 on Apr 25, 2017

Vivian Darkbloom
Jul 14, 2004


I'm finding how hard it is to make a cross-platform console interface that isn't horrible for a little strategy game project, so it's time to get a basic GUI framework set up. I just read the Python Wiki page on GUI programming and I am looking at pyjs as a possibility, since targeting web browsers might be easier than rolling my own GUI entirely. Not sure, though -- ideally I'd like something that's programmer-friendly and doesn't require a lot of setup for a user running my program. Any recommendations on what might be the best GUI choice?

accipter
Sep 12, 2003

Vivian Darkbloom posted:

I'm finding how hard it is to make a cross-platform console interface that isn't horrible for a little strategy game project, so it's time to get a basic GUI framework set up. I just read the Python Wiki page on GUI programming and I am looking at pyjs as a possibility, since targeting web browsers might be easier than rolling my own GUI entirely. Not sure, though -- ideally I'd like something that's programmer-friendly and doesn't require a lot of setup for a user running my program. Any recommendations on what might be the best GUI choice?

What are you envisioning in terms of the GUI?

Vivian Darkbloom
Jul 14, 2004


accipter posted:

What are you envisioning in terms of the GUI?

A central canvas, a few lines of text underneath, and a few buttons horizontally arranged beneath the text. The canvas would need to be updated to recolor different areas on the board. Don't really need the ability to read clicks from the canvas or interact with any fancy widgets -- just whipping up a demo.

e: I am thinking tkinter will be ok for what I need.

Vivian Darkbloom fucked around with this message at 02:49 on Apr 26, 2017

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb
I want to deploy a python package to my private pypi repo. Is this guide a decent one to follow? http://peterdowns.com/posts/first-time-with-pypi.html

QuarkJets
Sep 8, 2008

Vivian Darkbloom posted:

A central canvas, a few lines of text underneath, and a few buttons horizontally arranged beneath the text. The canvas would need to be updated to recolor different areas on the board. Don't really need the ability to read clicks from the canvas or interact with any fancy widgets -- just whipping up a demo.

e: I am thinking tkinter will be ok for what I need.

Can tkinter handle those canvas operations you described? That sounds more like something you'd use Qt for (which is multi-platform but would create a pyqt dependency)

VikingofRock
Aug 24, 2008




ynohtna posted:

Here's my common snippet to convert an iterable into natural sort order:
Python code:
import re
def sorted_nicely(iter):
    """ Sort the given iterable in the way that humans expect."""
    convert = lambda text: int(text) if text.isdigit() else text
    alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ]
    return sorted(iter, key=alphanum_key)
Usage is:
Python code:
    for p in sorted_nicely(seen_paths):
        print(p)

It took me a little bit to prove to myself that you would never end up comparing a string and an int with this, but yeah, you never do so this is totally valid. Nice!

Vivian Darkbloom
Jul 14, 2004


QuarkJets posted:

Can tkinter handle those canvas operations you described? That sounds more like something you'd use Qt for (which is multi-platform but would create a pyqt dependency)

Yeah you're right, but I can replicate the functionality by using tkinter to render the board as a bunch of buttons. Ugly but fine for what I need.

Vivian Darkbloom
Jul 14, 2004


Confused about an issue with passing functions. This might be related to tkinter weirdness, but I might just be doing something else wrong.

code:
import tkinter as tk
root = tk.Tk()
for i in range(10):
    tk.Button(root,text=i,command=lambda:print(i)).pack(side=tk.LEFT)
root.mainloop()
When I click any button it prints 9, even though each button was initialized with its own print function. Why is it behaving like this, and not instead printing the appropriate number for each button?

Vivian Darkbloom fucked around with this message at 08:31 on Apr 26, 2017

ynohtna
Feb 16, 2007

backwoods compatible
Illegal Hen
Python's closures are late binding: the values of variables used within them are looked up at the time the inner function/closure is called.

It feels a bit of a hack, but I've seen a default argument used as a common workaround (the default value is bound at the time of definition), i.e.:

Python code:
for i in range(10):
    tk.Button(root, text=i, command=lambda i=i: print(i)).pack(side=tk.LEFT)
functools.partial is probably the proper way to do it, but may reduce readability in some cases.

Tigren
Oct 3, 2003

Vivian Darkbloom posted:

Confused about an issue with passing functions. This might be related to tkinter weirdness, but I might just be doing something else wrong.

code:
import tkinter as tk
root = tk.Tk()
for i in range(10):
    tk.Button(root,text=i,command=lambda:print(i)).pack(side=tk.LEFT)
root.mainloop()
When I click any button it prints 9, even though each button was initialized with its own print function. Why is it behaving like this, and not instead printing the appropriate number for each button?

IMO, if you're going to be learning the GUI library from scratch you'd be much better served going with a small Flask app and learning the basics of HTML/CSS/JS.

That's an actual marketable skill with virtually infinite learning resources vs some weird, arcane language on top of a language that produces interfaces from 1995.

huhu
Feb 24, 2006
I've just finished my first Flask project for my new job which is basically a page with a form that allows users to do CRUD operations on a database table. It took me about a week to create. Of course there was a bunch of stuff like having to learn MySQL, JavaScript form validation, navigate their code base, etc. along the way so it took a bit of time. I was just able to recreate what took me about a week with Flask Admin in an hour and was even able to add additionally functionality like a list view, searching, and filtering. I feel like this was deceptively simple though and when I start working on more complex projects I'd be better off writing the SQL and JS myself. Is that correct?

QuarkJets
Sep 8, 2008

Tigren posted:

That's an actual marketable skill with virtually infinite learning resources vs some weird, arcane language on top of a language that produces interfaces from 1995.

These descriptions both describe Flask

Space Kablooey
May 6, 2009


huhu posted:

I've just finished my first Flask project for my new job which is basically a page with a form that allows users to do CRUD operations on a database table. It took me about a week to create. Of course there was a bunch of stuff like having to learn MySQL, JavaScript form validation, navigate their code base, etc. along the way so it took a bit of time. I was just able to recreate what took me about a week with Flask Admin in an hour and was even able to add additionally functionality like a list view, searching, and filtering. I feel like this was deceptively simple though and when I start working on more complex projects I'd be better off writing the SQL and JS myself. Is that correct?

At some point yes, you will have to customize something or other, but Flask Admin really is that powerful.

dougdrums
Feb 25, 2005
CLIENT REQUESTED ELECTRONIC FUNDING RECEIPT (FUNDS NOW)
Python code:
noisymodule.print = lambda x : None

Haha take that noisy module!

Tigren
Oct 3, 2003

QuarkJets posted:

These descriptions both describe Flask

Touche. But you're not going to find a lot of employers impressed by your Tcl/Tk skills.

Adbot
ADBOT LOVES YOU

Vivian Darkbloom
Jul 14, 2004


ynohtna posted:

Python's closures are late binding: the values of variables used within them are looked up at the time the inner function/closure is called.

It feels a bit of a hack, but I've seen a default argument used as a common workaround (the default value is bound at the time of definition), i.e.:

Python code:
for i in range(10):
    tk.Button(root, text=i, command=lambda i=i: print(i)).pack(side=tk.LEFT)
functools.partial is probably the proper way to do it, but may reduce readability in some cases.

Thanks, that helped a lot. It's kind of an odd feature, I'll have to read more on it.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply