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
QuarkJets
Sep 8, 2008

That repo structure seems fine, I like to further group modules into sensibly named submodules if I have enough of them

Adbot
ADBOT LOVES YOU

SurgicalOntologist
Jun 17, 2004

Consider making command line entry points for the scripts in setup.py.

Then instead of running python rectify.py you can run companytool rectify-widgets. A small difference, but it will feel more professional.

nitsuga
Jan 1, 2007

Cool, I'll have to look into that.

So it's not an entirely crazy workflow I take it. From that standpoint, then within the Python scripts themselves, I would use relative paths for the various .cfgs we use?

SurgicalOntologist
Jun 17, 2004

If they're packaged with the library, use importing.resources. If it's something the user is supplying, let them specify by path.

QuarkJets
Sep 8, 2008

I haven't looked at making C/C++ bindings in a long time, does anyone have a sense for what the latest and greatest is? Last I recall the norm for C code was to just use ctypes and Swig had some popularity for C++. Now I'm reading that there are like a dozen of these tools

KICK BAMA KICK
Mar 2, 2009

SurgicalOntologist posted:

If they're packaged with the library, use importing.resources. If it's something the user is supplying, let them specify by path.
Had never noticed this (assume you mean importlib?) -- you'd use it in place of constructing a path out of like os.path.join(os.path.dirname(__file__), 'test_data/stuff.txt')?

Thermopyle
Jul 1, 2003

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

KICK BAMA KICK posted:

Had never noticed this (assume you mean importlib?) -- you'd use it in place of constructing a path out of like os.path.join(os.path.dirname(__file__), 'test_data/stuff.txt')?

Just in case you didn't know about pathlib:

Python code:
from pathlib import Path

Path(__file__).parent / 'test_data' / 'stuff.txt'

KICK BAMA KICK
Mar 2, 2009

poo poo, I do use Paths all the time but didn't know that stuff with the / operator either.

Csixtyfour
Jan 14, 2004

taqueso posted:

Trying not to spoil it completely: you want to make a loop that asks for numbers, and instead of recording each number in its own variable, you want to keep track of them in a dictionary or set or list. That way you can handle any number of inputs.

You could check at the end or you can check each time a new number is added.

e: Oh, the assignment does say it will always be five numbers. Using a loop is still a good idea, so you don't have to write the logic five times.

e2: if you haven't learned about loops and sets/dicts yet then your solution is probably what they expect to see

I came up with :
code:
numbers = []

for x in range(5): 
    print("Enter a integer: ")
    item = int(input())
    numbers.append(item)

if len(set(numbers)) == len(numbers):
    print("ALL UNIQUE")
else:
    print("DUPLICATES")
Would this work or do I need to keep working on it?

Thanks Sad Pandas, better named variables would make a lot more sense.

nullfunction
Jan 24, 2005

Nap Ghost

Csixtyfour posted:

Would this work or do I need to keep working on it?

Perfectly acceptable for a student IMO.

If you wanted to continue poking at it, you could move your prompt into the input() call, and do input('Enter an integer: ') so you don't have to call print() as a separate statement. I would probably replace the "x" in your loop with an underscore, since you're not actually using it anywhere and some IDEs will complain that you didn't use x anywhere.

KICK BAMA KICK
Mar 2, 2009

Only thing I would add is, unless I'm missing something the list isn't really serving any purpose -- just start with a set(), put the numbers the user enters into it with the add method instead of append (the different method names reflect that lists are ordered while sets are not, but they do the same thing), and then at the end check whether the set contains five values.

(A further improvement, unnecessary but a good habit to get into, would be to assign a name to 5 (N would suffice) near the top of your script -- always ask yourself whether any literal value you're using, like a number or a string, would be more readable if given a name, and if you're using it in more than one place the answer is almost always yes.)

SurgicalOntologist
Jun 17, 2004

KICK BAMA KICK posted:

Had never noticed this (assume you mean importlib?) -- you'd use it in place of constructing a path out of like os.path.join(os.path.dirname(__file__), 'test_data/stuff.txt')?

You make test_data into a package (i.e. containing an __init__.py), import it, and then you can do importlib.resources.read_text(test_data, 'stuff.txt').

It's one step beyond pathlib, which is great, but importlib.resources is preferred in the case that the data is packaged with the code.

Also it's a sub package of of importlib itself, which is for programmatically manipulating the import statement.

SurgicalOntologist fucked around with this message at 09:08 on Feb 4, 2020

Wallet
Jun 19, 2006

KICK BAMA KICK posted:

Only thing I would add is, unless I'm missing something the list isn't really serving any purpose -- just start with a set(), put the numbers the user enters into it with the add method instead of append (the different method names reflect that lists are ordered while sets are not, but they do the same thing), and then at the end check whether the set contains five values.

(A further improvement, unnecessary but a good habit to get into, would be to assign a name to 5 (N would suffice) near the top of your script -- always ask yourself whether any literal value you're using, like a number or a string, would be more readable if given a name, and if you're using it in more than one place the answer is almost always yes.)

Really you would combine these two improvements so you're setting N once and both using that as your range and also checking the length of your set against it.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

nitsuga posted:

Without getting too E/N, what's the best way to structure these scripts in a repo? I'd love to be able to have people clone the repo, set up a virtual environment, and install the requirements and go. Is that a terrible way to do it? I figure this way we can just update the repo on our computers when we make minor changes rather than our current system which relies on them being in specific directories.
What you have for a repository structure is fine--possibly to the point of saying a best practice. I work in an environment with hundreds (thousands?) of electrical engineers that causes tons of problems when this starts to mutate in different ways. The amount of people in itself isn't the problem but the diversity of things they try to do is. Here are some things to worry about :
1. Requiring large, collateral files as inputs.
2. (a similar problem to #1, really) Depending on having specific binary files installed.
3. A class of culture between those that always need the super-duper latest now now now versus people that want to freeze on something consistent.

Your repository structure might not change for any of that, but you will have to improve packaging and release method if that stuff creeps in. One of Python's great virtues is being able to distribute basically a repo snapshot as a release. One of Python's greatest vices is being able to distribute a repo snapshot as a release.

mbt
Aug 13, 2012

if users are also expected to contribute to the code, and the code changes on a somewhat frequent basis, you're looking at a regular rear end git repo being your best bet, just run gitlab off a local server. you dont want to deal with john q public editing line 50 because he found a better way to do it

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
Does anybody know a procedure for doing coverage analysis across multiple invocations? It looks like I have to do some digging into coverage.py if I want to do this but I was hoping somebody had an impression to share about it. I'd have different entry points I have to kick off to see all the possibilities.

Edit: Does anybody else got the impression that their Google search results improve after posting a question about their problem?

Rocko Bonaparte fucked around with this message at 23:24 on Feb 4, 2020

Wallet
Jun 19, 2006

Rocko Bonaparte posted:

Edit: Does anybody else got the impression that their Google search results improve after posting a question about their problem?

Yes but mostly because after I have formulated it into a question I don't feel embarrassed to ask other humans I have a better sense of the specific thing I actually want an answer to.

mbt
Aug 13, 2012

is there a good guide on publishing python code in academic journals? presumably you want to add sensible comments and have someone who doesn't know what it does attempt to learn it to see if you did a good job. hell i'll take any tips in general

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
Yesterday, I learned that assignment operators internally aren't any more efficient. It makes sense given what I know about loads and stores, but I find it amusing that the main difference between BINARY_ADD and INPLACE_ADD is one tries to invoke __add__ and the other invokes __iadd__. Both put their result on the stack and then get stored into the variable, so a += 2 is something like a = a iadd 2.

UraniumAnchor
May 21, 2006

Not a walrus.
This might be a little too Django specific but this thread seems a lot more active and it’s a question about setuptools so I’m gonna ask it here.

I have a Django app that I’m trying to make easier to install, but one of the critical assets when you actually go and deploy the thing is the webpack-built bundle, the finished result of which is NOT checked into source control, and I don’t want that to be the answer. Does it make sense to hook into sdist and have it include the built bundle in the distribution, or should the source distribution include the files necessary to build the bundle (webpack config, package.json, yarn lock file, etc) and tell the user “hey you need to install node just so you can build this bundle, otherwise the app won’t actually work”. Or is that more what bdist is for? This is the first time I’ve actually tried to package this thing properly (besides telling people to just check out master and follow the 15 steps) so I’m unclear on the distinction or intent of sdist vs bdist and what the resulting files are supposed to look like.

LuckySevens
Feb 16, 2004

fear not failure, fear only the limitations of our dreams

I've been reading a financial modeling book that ostensibly teaches python, and I'm starting to realise the author may not be setting a good example.

code:
import math
import numpy as np

class StockOption(object):
 def __init__(self, S0, K, r, T, N, params):
  self.S0 = S0
  self.K = K
  self.r = r
  self.T = T
  self.N = max(1, N) # Ensure N have at least 1 time step
  self.STs = None # Declare the stock prices tree

   """ Optional parameters used by derived classes """
   self.pu = params.get("pu", 0) # Probability of up state
   self.pd = params.get("pd", 0) # Probability of down state
   self.div = params.get("div", 0) # Dividend yield
   self.sigma = params.get("sigma", 0) # Volatility
   self.is_call = params.get("is_call", True) # Call or put
   self.is_european = params.get("is_eu", True) # Eu or Am
    """ Computed values """
   self.dt = T/float(N) # Single time step, in years
   self.df = math.exp(
   -(r-self.div) * self.dt) # Discount factor

class BinomialEuropeanOption(StockOption):
 def __setup_parameters__(self):
  """ Required calculations for the model """
  self.M = self.N + 1 # Number of terminal nodes of tree
  self.u = 1 + self.pu # Expected value in the up state
  self.d = 1 - self.pd # Expected value in the down state
  self.qu = (math.exp((self.r-self.div)*self.dt) -
  self.d) / (self.u-self.d)
  self.qd = 1-self.qu

 def _initialize_stock_price_tree_(self):
    # Initialize terminal price nodes to zeros
    self.STs = np.zeros(self.M)
    # Calculate expected stock prices for each node
    for i in range(self.M):
    self.STs[i] = self.S0*(self.u**(self.N-i))*(self.d**i)

 def _initialize_payoffs_tree_(self):
  # Get payoffs when the option expires at terminal nodes
  payoffs = np.maximum(0, (self.STs-self.K) 
  if self.is_call
  else(self.K-self.STs))
  return payoffs

 def _traverse_tree_(self, payoffs):
  #  Starting from the time the option expires, traverse
  # backwards and calculate discounted payoffs at each node
  for i in range(self.N):
  payoffs = (payoffs[:-1] * self.qu +  payoffs[1:] * self.qd) * self.df
  return payoffs

 def __begin_tree_traversal__(self):
  payoffs = self._initialize_payoffs_tree_()
  return self._traverse_tree_(payoffs)
This code creates a binomial tree for pricing options.

I doubt it even works. It's an abomination. Here's how he runs it:

code:
Let's take the values from the two-step binomial tree example discussed earlier to
price the European put option:

>>> from StockOption import StockOption
>>> from BinomialEuropeanOption import BinomialEuropeanOption
>>> eu_option = BinomialEuropeanOption
... 50, 50, 0.05, 0.5, 2,
... {"pu": 0.2, "pd": 0.2, "is_call": False})
>>> print option.price()
4.82565175126

Using the binomial option pricing model gives us a present value of $4.826 for the
European put option.
So I decided to do some practice and rewrite it with some pythonic thinking and experiment with dataclasses:

code:
import math
import numpy as np
from dataclasses import dataclass

@dataclass
class StockOption:
    """s0 is stock price, k is strike price, r is risk-free rate, t is time to maturity
    n is """
    s0:      float
    k:       float
    r:       float
    t:       float
    n:       int = field(default=1)
    STs:     float = field(default=0)
    pu:      float = field(default=0)
    pd:      float = field(default=0)
    div:     float = field(default=0)
    sigma:   float = field(default=0)
    is_call: bool = field(default=True)
    
    dt: float = self.t / float(self.n)
    df: float = math.exp( -(r-self.div) * self.t / float(self.n) )

@dataclass
class BinomialEuropeanOption(StockOption):
    nodes:      int = self.n - 1
    upstate:    float = 1 + self.pu
    downstate:  float = 1 - self.pd
    qu:         float = math.exp((self.r-self.div)*self.dt - self.downstate / (self.upstate-self.downstate))
    qd:         float = 1 - self.qu
    
    def stock_tree(self):
       intree = np.zeros(self.nodes)
       numbertree = [newtree+self.s0*(self.upstate**(self.n-1)) for newtree in range(self.nodes)]
       return numbertree
    
    def payoff_tree(self):
        if is_call: # Check if call, if not, reverse for put
          payoffs = np.maximum(0, self.STs-self.k)
        else:
          payoffs = np.maximum(0, self.k-self.STs)
        
    def traverse_tree(self, payoffs): # __init__payoffs_tree
        for i in range(self.n):
            payoffs = (payoffs[:-1] * self.qu + payoffs[1:] * self.qd)
        yield payoffs 
    
    
    def calc_price(self):
        freshtree = stock_tree()
        optionvalue = traverse_tree(freshtree)
        
        print(optionvalue[0])
  

stockdata = StockOption(50, 50, 0.05, 0.5, 2, {"pu": 0.2, "pd": 0.2, "is_call":False})
eu_option = BinomialEuropeanOption()
   
eu_option.calc_price()
Rewriting this code was very difficult, and I should have started over from scratch. Nonetheless, I used the author's model because I'd have to go learning about tree implementations and most of the examples from google weren't a whole lot better.

So, how did I do? Am I thinking about this right? Or is there a severe flaw here that should get me to think differently about the whole thing.

LuckySevens fucked around with this message at 15:49 on Feb 6, 2020

mbt
Aug 13, 2012

LuckySevens posted:

So, how did I do? Am I thinking about this right? Or is there a severe flaw here that should get me to think differently about the whole thing.

dataclasses are good

code:
stockdata = StockOption(50, 50, 0.05, 0.5, 2, {"pu": 0.2, "pd": 0.2, "is_call":False})
you should probably turn those positional arguments into keyword arguments

mr_package
Jun 13, 2000
I dumped dataclasses for attrs and never looked back. It really does do everything dataclasses do and then add a bunch of stuff that you won't need on day 1 but when you're months into a project whose scope is growing you will be glad to have. e.g. recurse=True parameter of attrs.asdict() method, among others. Stuff dataclasses just doesn't have, and if they do get it you'll need to do a Python upgrade to get it.

attrs is a dependency of pytest so most of us probably already have it too.

edit: also cattrs is good (or at least it is sometimes good) if you're working with attrs.

Thermopyle
Jul 1, 2003

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

Dependencies are bad. Reference: npm.

I agree attrs is very good, but really evaluate if you're going to need it.

It makes me nervous when someone talks about having packages they install for every project.

There's a difference between having a dependency on pytest and a dependency on attrs. Pytest can be a dev dependency only.

Dominoes
Sep 20, 2007

LuckySevens posted:

I've been reading a financial modeling book that ostensibly teaches python, and I'm starting to realise the author may not be setting a good example.

Rewriting this code was very difficult, and I should have started over from scratch. Nonetheless, I used the author's model because I'd have to go learning about tree implementations and most of the examples from google weren't a whole lot better.

So, how did I do? Am I thinking about this right? Or is there a severe flaw here that should get me to think differently about the whole thing.
Be careful. Finances remains a bastion of pseudoscience and witchcraft in a world increasingly made transparent by open communication and the scientific method. Many people who tend to be intelligent and rational fall victim.

Dominoes fucked around with this message at 19:31 on Feb 6, 2020

mr_package
Jun 13, 2000

Thermopyle posted:

Dependencies are bad. Reference: npm.

I agree attrs is very good, but really evaluate if you're going to need it.

It makes me nervous when someone talks about having packages they install for every project.

There's a difference between having a dependency on pytest and a dependency on attrs. Pytest can be a dev dependency only.
In any project of moderate complexity you will reach the point where you need to either install a third-party module, or re-implement something that a third-party module already does, because of a limitation of the standard library. Both of these are a waste of time: you should just use the thing that works to begin with. And once you've installed one module you are going to have to figure out packaging anyway so you might as well install any others if you know they are better or faster to work with than the standard library.

I suppose many are written as drop-in replacements, so the time/pain to switch over is not so bad. I just grew frustrated at the debugging of these gotchas that don't even exist in third-party modules where the code is updated more frequently. With attrs porting was more work but I had not used attrs before so now that I'm past that learning curve maybe it works to start with the standard library and only install something when absolutely needed. But based on my recent experience I wouldn't even waste my time trying unless I knew the project was very very small.

Regarding attrs/pytest I was just letting people knew we (devs) probably have it already, not that you could expect it everywhere on deployment machines.

LuckySevens
Feb 16, 2004

fear not failure, fear only the limitations of our dreams

Meyers-Briggs Testicle posted:

code:
stockdata = StockOption(50, 50, 0.05, 0.5, 2, {"pu": 0.2, "pd": 0.2, "is_call":False})
you should probably turn those positional arguments into keyword arguments

Oops, I just copy and pasted his style instead of rewriting, which was silly.


Dominoes posted:

Be careful. Finances remains a bastion of pseudoscience and witchcraft in a world increasingly made transparent by open communication and the scientific method. Many people who tend to be intelligent and rational fall victim.

This is true. I'm only trying to build familiarity with how some models are built with python, not intending to ever go out and actually trade.


Also, is there a more pythonic way to do this?

code:
class StockOption:
   ......
    is_call: bool = field(default=True)
Since I'm using the European option class, is there a way to do an isinstance check for inheritance when I establish my dataclass init stuff?

LuckySevens fucked around with this message at 00:17 on Feb 7, 2020

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
Is there something in the Python grammar implying there's supposed to be an @ operator?

https://docs.python.org/3/reference/grammar.html

code:
term: factor (('*'|'@'|'/'|'%'|'//') factor)*
This is popping up in the section where the other operators looks like they should be treated as multiplication, division, and modulo.

SurgicalOntologist
Jun 17, 2004

Yep, it was introduced in 3.5 and is used by numpy for matrix multiplication. I believe the dunder method is __matmul__.

Edit: yep. https://www.python.org/dev/peps/pep-0465/

DoctorTristan
Mar 11, 2006

I would look up into your lifeless eyes and wave, like this. Can you and your associates arrange that for me, Mr. Morden?

LuckySevens posted:

Oops, I just copy and pasted his style instead of rewriting, which was silly.


This is true. I'm only trying to build familiarity with how some models are built with python, not intending to ever go out and actually trade.


Also, is there a more pythonic way to do this?

code:
class StockOption:
   ......
    is_call: bool = field(default=True)
Since I'm using the European option class, is there a way to do an isinstance check for inheritance when I establish my dataclass init stuff?

What are you trying to achieve with this isinstance that isn’t achieved by just having the one dataclass inherit from another? Is there something you want to do in __init__ that the dataclass isn’t doing?

Imo you’re exposing too much of the implementation here. traverse_tree and stock_tree should have a leading underscore to indicate they’re ‘private’ and calc_price should be the only ‘public’ method (Might also want to rename that to something like calc_price_using_tree, since there are other methods to calculate an option price and you might want to extend the class to include those)

Also the trees used in binomial option pricing method aren’t especially complicated and can easily be represented with an array and some moderately clever indexing - generic tree data structures aren’t necessarily (and could be quite tricky to adapt, since nodes in the binomial tree can have two parents). If you wanted you could create a generic price_option_using_tree() method in the base class that calls the methods of the derived class(es) to calculate the payoffs in each node.

Malcolm XML
Aug 8, 2009

I always knew it would end like this.

Thermopyle posted:

Dependencies are bad. Reference: npm.

I agree attrs is very good, but really evaluate if you're going to need it.

It makes me nervous when someone talks about having packages they install for every project.

There's a difference between having a dependency on pytest and a dependency on attrs. Pytest can be a dev dependency only.

Counterpoint: dependencies are good. cf stdlib

NPM/JS culture around dependencies is driven by a) the lack of dead code elimination ("tree shaking" to abuse a tangentially related compiler term) at anything but the module level b) the overwhelming need to remove unused code since it's deployed across the wire

Thus JS has a shitload of tiny packages.


Python deps are larger and make a lot more sense to use. Batteries included, right? (the stdlib is full of quasi-unmaintained garbage tho)

NinpoEspiritoSanto
Oct 22, 2013




Yeah it's not a big deal imo that certain libs are best in class at what they do and aren't part of stdlib and there's plenty of argument for nor should they be. Attrs, pendulum and such things (trio is fast my default for anything async now) are no brainers and benefit well from their own release cycles instead of being stuck on stdlib time.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

SurgicalOntologist posted:

Yep, it was introduced in 3.5 and is used by numpy for matrix multiplication. I believe the dunder method is __matmul__.

Edit: yep. https://www.python.org/dev/peps/pep-0465/

Yeap. I don't feel major pressure to implement it for what I'm trying to do but since I have the hood open for implementing all the operators, I was thinking of giving it a try. I guess there's also an assignment operator for it, but I didn't find it when I was originally digging through the grammar.

Dominoes
Sep 20, 2007

Doesn't really matter; get the job done. Dataclass is lovely and I see no need to use Attrs as a consequence, but I wouldn't fault someone for doing so if they prefer it. Rust takes the opposite of the `batteries-included` approach, in that the std lib is designed to be minimal, with much standard functionality, including done by the main dev team, are dependencies. here's the reasoning:

quote:

Keeping std small. There is a widespread desire to keep the standard library reasonably small, and for good reason: the stability promises made in std are tied to the versioning of Rust itself, as are updates to it, meaning that the standard library has much less flexibility than other crates enjoy. While we do plan to continue to grow std, and there are legitimate reasons for APIs to live there, we still plan to take a minimalistic approach. See this discussion for more details.

The desire to keep std small is in tension with the desire to provide high-quality libraries that belong to the whole Rust community and cover a wider range of functionality. The poster child here is the regex crate, which provides vital functionality but is not part of the standard library or basic Rust distribution -- and which is, in principle, under the control of the whole Rust community.

This RFC resolves the tension between a "batteries included" Rust and a small std by treating rust-lang crates as, in some sense, "the rest of the standard library". While this doesn't solve the entire problem of curating the library ecosystem, it offers a big step for some of the most significant/core functionality we want to commit to.

This reminds me a bit of the reasoning behind keeping Requests out of the Py std lib.

I think one of Python's biggest faults is its messy std lib.

Thermopyle
Jul 1, 2003

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

Dominoes posted:

Doesn't really matter; get the job done. .

This is fine when you're doing one off data analysis or small projects.

It definitely matters when you're on a project with many developers, many-year lifespans, and used to run a business.

That's not to say you shouldn't use libraries, but it matters enough to do some real planning and see what you're gaining by adding a dependency.

Dominoes
Sep 20, 2007

Thermopyle posted:

This is fine when you're doing one off data analysis or small projects.

It definitely matters when you're on a project with many developers, many-year lifespans, and used to run a business.

That's not to say you shouldn't use libraries, but it matters enough to do some real planning and see what you're gaining by adding a dependency.
Agree on many-dev/time projects giving points to std-lib when able.

KICK BAMA KICK
Mar 2, 2009

Think I encountered my first Heisenbug today -- was writing a Django view that takes a POST from a template using a ModelForm to create an instance of a model where one of the fields should be unique and a corresponding test. On my first try I did not notice that ModelForm.is_valid() already checks the uniqueness constraint for such a field, and the test where I was checking that POSTing a duplicate entry resulted in a 422* was failing because my view function was taking the else: branch on if form.is_valid(): and not the one where I assumed the form was valid and was explicitly testing whether an object with that field's value already existed.

Thing is, the test failed as it should have when I ran it in PyCharm, and when I ran it externally at a terminal, but it passed when I set a breakpoint inside the view function and stepped through it in PyCharm's debug mode. Any idea why?

* Seems like the appropriate HTTP code for such an occurrence is the subject of some debate?
** Also I get that my test and implementation are probably bad in various ways but you know, whatever

OnceIWasAnOstrich
Jul 22, 2006

Is it possible to use Jupyter on a machine where the home folder is a NFS/SMB mounted network share? It seems to extensively use sqlite databases for random things which causes issues doing something as simple as running a ipython/jupyter console when the home folder is network mapped.

QuarkJets
Sep 8, 2008

I believe setting JUPYTER_CONFIG_DIR lets you change the location of .jupyter

Adbot
ADBOT LOVES YOU

fuf
Sep 12, 2004

haha
this is some real programming 101 poo poo and I'm embarrassed to ask but... what's the best way to check if a function has finished successfully before running a second function?

I'm using pysftp to
1) copy files from a local directory to a remote directory, then
2) move the files out of the local directory.

So like:
code:
def push():
        sftp.put_r(local_outtray, remote_intray)


def cleanup():
	# move local files
But obviously cleanup() should only happen if push() was successful.

I thought maybe push() could use try / except to return true or false depending on whether it gets an error, like:
code:
def push():
    try:
        sftp.put_r(local_outtray, remote_intray)
    except IOError:
        return False
    except OSError:
        return False
    else:
        return True

if push():
    cleanup()
else:
    # uh oh, push didn't work
But it seems weird to call push() in a conditional like that? Maybe it's normal but it seems harder to parse.

Something like this would be easier to parse:
code:
try:
   push()
except:
   # uh oh, push didn't work
else:
   cleanup()
But not sure how to write the push() function to get that working...

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