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
BeefofAges
Jun 5, 2004

Cry 'Havoc!', and let slip the cows of war.

Rocko Bonaparte posted:

There's a lot of modules in PyPi to work with subversion, so I was hoping somebody could recommend a few before I just try to figure what a bunch of them can or can't do. I have to deal with a situation where subversion is being used basically for software distribution (sad) to some Windows machines. So we'd use it to revert and update to a specific revision of the repository. Is there a general heavyweight module for this, or at least one more suitable for this kind of thing?

A friend of mine has had good experiences with pysvn. I've never used it myself, though.

Adbot
ADBOT LOVES YOU

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

BeefofAges posted:

A friend of mine has had good experiences with pysvn. I've never used it myself, though.

Thanks--I'll try to start there first.

Daynab
Aug 5, 2008

PySide/PyQt question, how do I clone widgets to add over and over? Because if you just try to add widgets already set up from a variable, it will just take it and move it somewhere else instead of making two.
For anyone not familiar with grid layouts the four numbers just represent row, col, row span and col span so nothing important in this example.
If I do grid.addWidget amount or desc again it will still only create one, not two.

Code:
Python code:
def initUI(self):

        grid = QGridLayout()

        separator = QFrame()
        separator.setFrameStyle(QFrame.VLine | QFrame.Raised)

        desc = QLineEdit()
        desc.setMinimumWidth(300)
        desc.setMaximumWidth(300)

        amount = QLineEdit()
        amount.setMaxLength(11)
        amount.setMinimumWidth(100)
        amount.setMaximumWidth(100)

        remove_btn = QPushButton('Del')
        remove_btn.setMaximumWidth(25)

        grid.addWidget(QLabel('Income'), 0, 0, 2, 3)
        grid.addWidget(desc, 3, 0)
        grid.addWidget(amount, 3, 1)
        grid.addWidget(remove_btn, 3, 2)
        grid.addWidget(separator, 0, 4, grid.rowCount(), 1)

        grid.addWidget(QLabel('Spending'), 0, 5, 2, 3)

        self.setLayout(grid)

        self.show()

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
Use a function to construct a QLineEdit with the correct properties, and call it a bunch of times. Cloning widgets is not supported, as it wouldn't be a good API.

Daynab
Aug 5, 2008

Suspicious Dish posted:

Use a function to construct a QLineEdit with the correct properties, and call it a bunch of times. Cloning widgets is not supported, as it wouldn't be a good API.

That makes so much sense and is so easy that I did not think about it :shobon: well, I'm learning! Thanks.

Pivotal Lever
Sep 9, 2003

Just checking to make sure that you aren't loving stupid enough to bet money on the type of bets that these faggots want you to make.. If you are actually stupid enough, you should prolly bet on motherfuckin winning bets, plenty enough missiles imo.

edit: i'll let this stand since it got quoted several times

Pivotal Lever fucked around with this message at 21:36 on Dec 19, 2013

Dominoes
Sep 20, 2007

Pivotal Lever posted:

Just checking to make sure that you aren't loving stupid enough to bet money on the type of bets that these faggots want you to make.. If you are actually stupid enough, you should prolly bet on motherfuckin winning bets, plenty enough missiles imo.
Go on.

semicolonsrock
Aug 26, 2009

chugga chugga chugga

Pivotal Lever posted:

Just checking to make sure that you aren't loving stupid enough to bet money on the type of bets that these faggots want you to make.. If you are actually stupid enough, you should prolly bet on motherfuckin winning bets, plenty enough missiles imo.

Yeah, I was gonna say the same thing.

Thermopyle
Jul 1, 2003

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

Pivotal Lever posted:

Just checking to make sure that you aren't loving stupid enough to bet money on the type of bets that these faggots want you to make.. If you are actually stupid enough, you should prolly bet on motherfuckin winning bets, plenty enough missiles imo.

Good point. Please tell us more.

The March Hare
Oct 15, 2006

Je rêve d'un
Wayne's World 3
Buglord

Pivotal Lever posted:

Just checking to make sure that you aren't loving stupid enough to bet money on the type of bets that these faggots want you to make.. If you are actually stupid enough, you should prolly bet on motherfuckin winning bets, plenty enough missiles imo.

Just sort of want to empty quote this post because it is maybe one of the best posts I've ever read and I would also like to hear more so please, keep posting.

NOTinuyasha
Oct 17, 2006

 
The Great Twist

Pivotal Lever posted:

Just checking to make sure that you aren't loving stupid enough to bet money on the type of bets that these faggots want you to make.. If you are actually stupid enough, you should prolly bet on motherfuckin winning bets, plenty enough missiles imo.

Missiles?

Pivotal Lever
Sep 9, 2003

I mistook CoC for GBS 2.1, sorry! This thread could use more missiles, tbh.

Pivotal Lever
Sep 9, 2003

So uh, I can't wait for Python 3.4, enum looks handy.

Jewel
May 2, 2009

Pivotal Lever posted:

So uh, I can't wait for Python 3.4, enum looks handy.

Python's getting an enum? Finally :monocle:

I can't believe this was the accepted method:

Python code:
class Materials, it's so hacky:
    Shaded, Shiny, Transparent, Matte = range(4)

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



Pivotal Lever posted:

I mistook CoC for GBS 2.1, sorry! This thread could use more missiles, tbh.

We need some sort of global lock to make sure output can only happen on one thread at a time.

BeefofAges
Jun 5, 2004

Cry 'Havoc!', and let slip the cows of war.

And then, to continue to post a lot, we can just create more python information forums, and then try to merge the results from them later.

Dominoes
Sep 20, 2007

Incase anyone was curious:

semicolonsrock
Aug 26, 2009

chugga chugga chugga

Dominoes posted:

Incase anyone was curious:



How did you scrape data for this? I'm having a hard time figuring out how to get data from webpages etc..

e: Thank you!

semicolonsrock fucked around with this message at 20:21 on Dec 20, 2013

Dominoes
Sep 20, 2007

Yahoo has a quasi-API (manipulating get URLs) for realtime and historical data. It can pull 200 stocks per query for realtime, and 1 for historical. Tradeking has realtime data with 2500+ stocks per query, as well as tools to monitor your account and place orders. Yahoo's API is open, Tradeking requires a brokerage account.

Guide on Yahoo realtime data
Tradeking API docs
Guide to using Pandas to pull Yahoo historical data. I haven't implemented it, but I verified it works.

The tradeking.py and yahoo.py modules here show my implementation. Most of the trouble and much of the code for both APIs involves exception handling for the weird results the APIs can return in nonstandard situations. Other bits are to standardize the input names and output format between APIs, which makes it easy to hot-swap them, or add a new one without messing with code outside the API modules. Note that the quote and real functions in both modules use the same API pull. The real functions are messier because they aggregate data from several pulls, to work around the stocks-per-query limits.

Here's how to find a single bit of realtime data for a single stock using Yahoo, and one stock's historical data, without the exception handling/formatting/name standardization etc.
Python code:
def quote(symbol, attribute):
    """Return the value of a single realtime attribute of one stock."""
    url = 'http://finance.yahoo.com/d/quotes.csv'
    payload = {'s': symbol, 'f': attribute}
    u = requests.get(url, params=payload).text
    quote_data = list(csv.reader(u.splitlines()))
    return quote_data[0][0]


def hist(symbol, start_date, end_date):
    url = 'http://ichart.yahoo.com/table.csv'
    payload = {'s': symbol, 'a': start_date.month - 1, 'b': start_date.day,
               'c': start_date.year, 'd': end_date.month - 1, 'e': end_date.day,
               'f': end_date.year, 'ignore': '.csv'}
    u = requests.get(url, params=payload).text
    return list(csv.reader(u.splitlines()))

Dominoes fucked around with this message at 19:49 on Dec 20, 2013

QuarkJets
Sep 8, 2008

Dominoes posted:

Incase anyone was curious:



That looks lovely! Well done!

Dren
Jan 5, 2001

Pillbug

Dominoes posted:

Incase anyone was curious:



This looks really nice are you going to add some charts? (I love charts)

Dominoes
Sep 20, 2007

Double-clicking an item from any of the trees brings up chart of that stock's historical data over the past year. I'm working on making it show useful info, like marking the buy and sell points for roundtrips, as well as what the optimal ones would have been. Marking lines of where the price would have to climb or fall before the program triggers a sell for a currently owned stock etc.

Dominoes fucked around with this message at 23:58 on Dec 20, 2013

Pollyanna
Mar 5, 2005

Milk's on them.


Dominoes posted:

Incase anyone was curious:



You dick, don't get ahead of me :byodood: (Nice job!)

===

Version 1.1 of my app is up, too!

http://rpazyaquian.herokuapp.com/stocks/NTDOY

There's a few problems with it at the moment, though:

  • If the URL is pointed to a stock symbol that does not exist, e.g. http://rpazyaquian.herokuapp.com/stocks/argleblargle , the page returns a 500 error. This needs to be changed so that a proper error page shows up, or the routing should properly handle an invalid symbol.

    When testing on Flask, the error is instead:

    code:
    Traceback (most recent call last):
      File "/Users/rebecca/anaconda/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
        return self.wsgi_app(environ, start_response)
      File "/Users/rebecca/anaconda/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
        response = self.make_response(self.handle_exception(e))
      File "/Users/rebecca/anaconda/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
        reraise(exc_type, exc_value, tb)
      File "/Users/rebecca/anaconda/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
        response = self.full_dispatch_request()
      File "/Users/rebecca/anaconda/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
        rv = self.handle_user_exception(e)
      File "/Users/rebecca/anaconda/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
        reraise(exc_type, exc_value, tb)
      File "/Users/rebecca/anaconda/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
        rv = self.dispatch_request()
      File "/Users/rebecca/anaconda/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
        return self.view_functions[rule.endpoint](**req.view_args)
      File "/Users/rebecca/Desktop/NerdStuff/Python/flask-heroku/app/routes.py", line 23, in lookup
        snippet = plots.build_plot(symbol)
      File "/Users/rebecca/Desktop/NerdStuff/Python/flask-heroku/app/plots.py", line 20, in build_plot
        data = web.DataReader(symbol, 'google', start, end)
      File "/Users/rebecca/anaconda/lib/python2.7/site-packages/pandas/io/data.py", line 76, in DataReader
        retry_count=retry_count, pause=pause)
      File "/Users/rebecca/anaconda/lib/python2.7/site-packages/pandas/io/data.py", line 424, in get_data_google
        adjust_price, ret_index, chunksize, 'google', name)
      File "/Users/rebecca/anaconda/lib/python2.7/site-packages/pandas/io/data.py", line 336, in _get_data_from
        hist_data = src_fn(symbols, start, end, retry_count, pause)
      File "/Users/rebecca/anaconda/lib/python2.7/site-packages/pandas/io/data.py", line 209, in _get_hist_google
        return _retry_read_url(url, retry_count, pause, 'Google')
      File "/Users/rebecca/anaconda/lib/python2.7/site-packages/pandas/io/data.py", line 169, in _retry_read_url
        "return a 200 for url %r" % (retry_count, name, url))
    IOError: after 3 tries, Google did not return a 200 for url 'http://www.google.com/finance/historical?q=ABBBABABBA&startdate=Jan+01%2C+2011&enddate=Dec+20%2C+2013&output=csv'
    
    I need to figure out how to create a proper error page for this, or otherwise figure out why it happens and return an exception. I know that Flask allows for error pages, but how?

  • I want to have the URL for accessing a certain stock symbol to instead be something like '/stocks?symbol=GOOG' as opposed to '/stocks/GOOG/. I don't know how, though. Flask supports the GET method, but I'm not sure how it would work in this situation:

    Python code:
    @app.route('/stocks', method=['GET'])
    def lookup(symbol):
    
        snippet = plots.build_plot(symbol)
    
        return render_template('stocks.html',
                               snippet=snippet)
    
    I'm guessing that's NOT going to work? How do I write it?

  • One drawback of how I approach the embed.js snippets is that every time a page is rendered, it creates a new embed.js file for reference. I can't help but think that this will become a problem in the future. What should I do to avoid this? Is there a way to add pure JS to the webpage to render the plot, or does that not make sense?

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb

Woohoo! Way to go!!

Pollyanna posted:

  • If the URL is pointed to a stock symbol that does not exist, e.g. http://rpazyaquian.herokuapp.com/stocks/argleblargle , the page returns a 500 error. This needs to be changed so that a proper error page shows up, or the routing should properly handle an invalid symbol.
  • I want to have the URL for accessing a certain stock symbol to instead be something like '/stocks?symbol=GOOG' as opposed to '/stocks/GOOG/. I don't know how, though. Flask supports the GET method, but I'm not sure how it would work in this situation:
  • One drawback of how I approach the embed.js snippets is that every time a page is rendered, it creates a new embed.js file for reference. I can't help but think that this will become a problem in the future. What should I do to avoid this? Is there a way to add pure JS to the webpage to render the plot, or does that not make sense?

#1 Maybe use a try/except and catch the IOError (should be caught anyways when communicating to external services in case they go down)
#2 I think you want request.args, haven't used Flask before though
#3 Probably a way to avoid generating an actual file each time, not familiar with that library though. Should be able to just stick it inside of a <script type="text/javascript">alert('hello world')</script> type of thing. If it turns out you have to actually generate a file, use a randomized filename so you don't run into an issue where two requests try to write to the same embed.js file each time (and make sure they are temp files so they get automatically cleaned up)

Pollyanna
Mar 5, 2005

Milk's on them.


I don't know what happened since I started working on v1.2, but now SA keeps flashing "hello world" alert boxes at me :(

fletcher posted:

Woohoo! Way to go!!


#1 Maybe use a try/except and catch the IOError (should be caught anyways when communicating to external services in case they go down)
#2 I think you want request.args, haven't used Flask before though
#3 Probably a way to avoid generating an actual file each time, not familiar with that library though. Should be able to just stick it inside of a <script type="text/javascript">alert('hello world')</script> type of thing. If it turns out you have to actually generate a file, use a randomized filename so you don't run into an issue where two requests try to write to the same embed.js file each time (and make sure they are temp files so they get automatically cleaned up)

v1.2 is up! http://rpazyaquian.herokuapp.com/stocks?symbol=AAPL Thanks for the help.

#1 and #2 have been addressed. #3, I'm still working on, but the file name is randomized so there shouldn't be a problem...

suffix
Jul 27, 2013

Wheeee!

Pollyanna posted:

[*]I want to have the URL for accessing a certain stock symbol to instead be something like '/stocks?symbol=GOOG' as opposed to '/stocks/GOOG/.

Out of curiosity, why do you want this? I think the latter version looks nicer.

Thermopyle
Jul 1, 2003

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

suffix posted:

Out of curiosity, why do you want this? I think the latter version looks nicer.

Yes, this is true.

The other way is old and uncool. Not having query parameters is new and cool.

Pollyanna
Mar 5, 2005

Milk's on them.


suffix posted:

Out of curiosity, why do you want this? I think the latter version looks nicer.

...Uh. I dunno :saddowns: Is this really that much of a bad thing?

Now that I think about it, maybe it IS easier the other way...but then how do I display multiple plots on a single page? Can't I submit an array of values for the get method? I can go ahead and display many plots that way.

Thermopyle
Jul 1, 2003

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

Make the last part of the url a comma separated list.

suffix
Jul 27, 2013

Wheeee!

Pollyanna posted:

...Uh. I dunno :saddowns: Is this really that much of a bad thing?

Now that I think about it, maybe it IS easier the other way...but then how do I display multiple plots on a single page? Can't I submit an array of values for the get method? I can go ahead and display many plots that way.

Okay, yeah, supporting multiple plots a fair reason to use query parameters. Other typical reasons are to use web forms, or because it's easier to set up with PHP or CGI scripts.

There's little practical difference, but in a traditional RESTful URI layout you have a resource, like GOOG, and a canonical path to that resource, like "/stocks/GOOG". That gets messy for queries and multi-gets, so query strings are often better for that, IMO.

Mostly when people do stuff like "?p=index", it's because it's the easier way in PHP, so I was curious why you were doing that when you get pretty URIs for free.

For multiple plots, you could use comma separation, like "?symbols=GOOG,AAPL", or repeated parameters, like "?symbol=GOOG&symbol=AAPL".

Pollyanna
Mar 5, 2005

Milk's on them.


Trying to do ?symbols=GOOG,AAPL gets me an error where it returns the whole thing as a single string. For example, this code

Python code:
@app.route('/stocks')
def lookup():
    symbol = request.args.get('symbol')

    print symbol

    try:
        len(symbol)
    except TypeError:
        return render_template('stocks.html',
                               error='Please request a stock symbol.')

    snippet_list = []

    for i in symbol:

        print i

        try:
            snippet_list.append(plots.build_plot(i))
        except IOError:
            return render_template('stocks.html',
                                   error='Symbol(s) not found.')

    return render_template('stocks.html',
                           snippet_list=snippet_list)
used with /stocks?symbol=AAPL returns a single string "AAPL". If I try and iterate over that, I get four plots for A, A, P, and L :downs:

With /stocks?symbol=AAPL,GOOG, it tries to go through every character in "AAPL,GOOG" and dies after failing to find the plot for ",". This is the way to pass a comma separated list in HTTP, right? Or do I have it wrong?

Jewel
May 2, 2009

Pollyanna posted:

Trying to do ?symbols=GOOG,AAPL gets me an error where it returns the whole thing as a single string. For example, this code

Python code:
@app.route('/stocks')
def lookup():
    symbol = request.args.get('symbol')

    print symbol

    try:
        len(symbol)
    except TypeError:
        return render_template('stocks.html',
                               error='Please request a stock symbol.')

    snippet_list = []

    for i in symbol:

        print i

        try:
            snippet_list.append(plots.build_plot(i))
        except IOError:
            return render_template('stocks.html',
                                   error='Symbol(s) not found.')

    return render_template('stocks.html',
                           snippet_list=snippet_list)
used with /stocks?symbol=AAPL returns a single string "AAPL". If I try and iterate over that, I get four plots for A, A, P, and L :downs:

With /stocks?symbol=AAPL,GOOG, it tries to go through every character in "AAPL,GOOG" and dies after failing to find the plot for ",". This is the way to pass a comma separated list in HTTP, right? Or do I have it wrong?

for i in symbol.split(",")

Edit: I've used php far too long (because when I was a lot younger that was all I had or knew about) and every time i want to make a quick easy web demo I default to php because I'm too lazy to learn a framework. I think seeing that code makes me wanna give flask a shot finally, since I already know python. Guess I'll see how that goes!

Jewel fucked around with this message at 08:52 on Dec 21, 2013

Pollyanna
Mar 5, 2005

Milk's on them.


Jewel posted:

for i in symbol.split(",")

Is there a :downs: version of that slowly growing :pwn: image? Cause that's how I feel right now.

It works now :shobon: Thanks!

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb

Pollyanna posted:

I don't know what happened since I started working on v1.2, but now SA keeps flashing "hello world" alert boxes at me :(

Hmmm that's not good...XSS vulnerability on here? I'm not getting any alerts on this page.

Pivotal Lever
Sep 9, 2003

Pollyanna posted:

Is there a :downs: version of that slowly growing :pwn: image? Cause that's how I feel right now.

It works now :shobon: Thanks!

Well done, Pollyanna, I've watched you grow in this thread from someone most posters rolled their eyes at, to someone who created a working heroku app. Keep it up! </sincere>

edit: I say this as someone this thread would've rolled their eyes at during my most enthusiastic Python phase :) It's a compliment, my friend!

Pivotal Lever fucked around with this message at 11:38 on Dec 21, 2013

Dren
Jan 5, 2001

Pillbug

Pivotal Lever posted:

Well done, Pollyanna, I've watched you grow in this thread from someone most posters rolled their eyes at, to someone who created a working heroku app. Keep it up! </sincere>

edit: I say this as someone this thread would've rolled their eyes at during my most enthusiastic Python phase :) It's a compliment, my friend!

GEEZ DAD. Err, uhh, umm.... GEEZ WEIRD INTERNET DAD.

SurgicalOntologist
Jun 17, 2004

Is there a better way to hack a makefile to support virtualenv than
Bash code:
sed -i 'N; s@PYTHON_MODULE_DIR := $(shell $(PYTHON_CONFIG) --exec-prefix)/lib/python$(PYTHON_VERSION)/lib-dynload@ifdef VIRTUAL_ENV\
\tPYTHON_MODULE_DIR := $(VIRTUAL_ENV)/lib/python$(PYTHON_VERSION)/site-packages\
else\
\tPYTHON_MODULE_DIR := $(shell $(PYTHON_CONFIG) --exec-prefix)/lib/python$(PYTHON_VERSION)/lib-dynload\
endif@g' GNUmakefile
Follow-up: Is it a bad idea to install common dependencies into the base python, and use --use-global-site-packages or whatever? To save space installing crap, make it quicker to create new virtualenvs, and easier to update common dependencies? With a rule like "only current stable releases in the base python, install into the env if you need anything else"? This is on a machine that is basically "production", and will see very little development. It will only have 2 projects for now, and will probably never have more than 15-20.

Edit: Maybe not, these are scientific projects and it would be nice if each came with a snapshot of its environment ~~forever~~. Is there a middle ground? I don't want to be mucking with symlinks because I don't trust other people so I want to keep it simple.


Another question:
Python code:
try:
    import vrpn
except ImportError:
    pass
Why does PyCharm say 'vrpn' in try block with 'except ImportError' should also be defined in except block? This is in an 'input' module, vrpn has the interfaces to some input devices, but not others (e.g. mouse). This way it can run without vrpn but only using a limited number of input devices. What should I define vrpn as in the except block? A class that raises an informative exception any time it is accessed? Seems unnecessary.

\/ \/ :doh:

SurgicalOntologist fucked around with this message at 18:40 on Dec 21, 2013

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
Python code:
try:
	import vrpn
except ImportError:
	pass

if vrpn:
	print('do stuff with vrpn')

print('do stuff with or without vrpn')
code:
Traceback (most recent call last):
  File "test.py", line 6, in <module>
    if vrpn:
NameError: name 'vrpn' is not defined
Python code:
try:
	import vrpn
except ImportError:
	vrpn = None

if vrpn:
	print('do stuff with vrpn')

print('do stuff with or without vrpn')
code:
do stuff with or without vrpn

Mustach
Mar 2, 2003

In this long line, there's been some real strange genes. You've got 'em all, with some extras thrown in.

Thermopyle posted:

Make the last part of the url a comma separated list.
Seriously, please change it back to the nice way. '?symbols=GOOG,AAPL' and '?symbol=GOOG&symbol=AAPL' are worse than 'GOOG,AAPL', at the very least because the first have three characters that are a pain to type on a phone.

Adbot
ADBOT LOVES YOU

Thermopyle
Jul 1, 2003

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

Mustach posted:

Seriously, please change it back to the nice way. '?symbols=GOOG,AAPL' and '?symbol=GOOG&symbol=AAPL' are worse than 'GOOG,AAPL', at the very least because the first have three characters that are a pain to type on a phone.

Yep.

Pollyanna, to be clear, your URL should look like:

http://rpazyaquian.herokuapp.com/stocks/GOOG,AAPL,MSFT

  • Locked thread