I think this is a general question, however, in my case I'm working with PyQt5 and Python 3.
I'm setting up a small software, which is recording data with a measurement device. Before a measurement I have to put some data which are then validated by the software for correctness, like, is a mandatory field filled, or is the input value within the allowed range, or i.e., I have a start value A, a stop value B and a step width W, so I have to validate if W<=B-A
My question is, what's the most elegant way of checking the form? I can just simply do it one by one:
class Form:
...
def check_form(self):
if self.fieldA.text() == "":
return False
if not self.check_range(self.fieldB.text()):
return False
# Check fields one by one...
...
def check_range(self, val):
if val > self.max_val:
return False
else:
return True
But actually, this isn't really pretty, it's repeating code and a lot to write and hard to maintain. So my question is, is there a better way? One idea which came up was to define a object (maybe a dict), which contains all relevant form information, like label, default value, conditions and so on... I can put that form into a json file and then just load it and even generate the form when I need it. Maybe some obstacles may occur, especially I have to think how to handle drop down lists, but I think this is at least one approach.
Anyway. 100% someone else were struggling with this issue before me, so maybe there's a standard way how to solve this in an elegant way.
A good UX practice is to inform user the expectation of the software instead of making them guess, possiblly enter incorrect value and then informed/misinformed with cryptic error message that they don't understand!
In the situation you described here, clearly indicate an asterisk(*) next to input label to indicate it is a mandatory field. Possibly software should also come up with sensible default value. Also using correct widget to solve the particular problem you've described here would be a good idea. So instead of having three QLineEdit fields that take numerical inputs as text fields, I'd just use QSpinBox or QDoubleSpinBox that are designed to request a well constraint range of values.
Related
Sorry about the title gore, I'm not sure of a good way to phrase this question, but I'll try to provide a good amount of detail. So, my program takes in a "board state" for a game called Oska. The game is fairly simple, and I want to use an AI-based program that eventually will be able to play it. I began implementing it, but I ran into a few problems that I think would be solvable if I took in the starting board state differently.
The thing about Oska is that its board is weird, and it has varying sizes, so I can't construct an array as simply as I could for, lets say, checkers. This is what the starting input might look like:
['wwww','---','--','---','bbbb']
I'd like to create objects out of these pieces, with 4 for the white pieces (in this example) and 4 for the black. Ultimately, I want to use this to create a field of potential moves. Pieces in Oska move much like they do in checkers, with the main difference being that the board is missing chunks on either side. I am not familiar with creating classes in Python, so I don't know how it would work. I know in C/C++, you can make an object and save a next object, like root->right, which I think might help in this case? I'm not worried about the intelligence portion of this program yet, because I can always assign values to the different moves; what I am worried about is finding what moves are available to make. But, all I want to focus on for now is creating a class object for the board and the pieces. I have seen suggestions to do this, but not suggestions on how to do this. What should be in the class's __init__?
If someone has seen or done something similar for checkers, that would be a huge help. Try as I might, I haven't been able to find anything that can help me.
class wise the syntax might look like bellow in python, for the parsing of you list of strings, you may want to use a class or function to give the values to build your Tile instances. Hope this helps.
class Tile:
def __init__(self, row, column, next=None, previous=None):
self.row = row
self.column = column
if next is None:
next = []
self.next = next
if previous is None:
previous = []
self.previous = previous
I have a bunch of classes that all look somewhat like this:
class FakeAnalysis(Analysis):
def __init__(self, dbi, metric: str, constraints: dict) -> None:
super().__init__(dbi)
self.metric = metric
self.constraints = constraints.copy()
def load_data(self) -> pd.DataFrame:
data = self.dbi.select_data(
{"val"}, {"period"}, **self.constraints
)
return data
def run(self) -> namedtuple:
"""Do some form of dataframe transformation""""
data = self.load_data()
df = data.pivot_table(columns='period',values='val',index='product_tag')
return namedtuple("res", ['df'])(**{"df": df})
They all take in a metric, constraints and a database interface class (dbi) as __init__ arguments. They all load the data necessary by fetching the data through the dbi and then do some sort of data transformation on the resulting dataframe before returning it as a namedtuple containing the transformed data and any other byproducts (i.e. could be multiple dataframes).
The question is: what is the best way to unit test such code? The errors are usually the result of a combination of constraints resulting in unexpected data that the code does not know how to deal with. Should I just test each class with randomly generated constraints and see if it crashes? Or should I create a mock database interface which returns fixed data for a few different constraints and ensure the class returns the results expected for just these constraints? The latter doesn't seem of much use to me although it would be more along the lines of unit testing best practice...
Any better ideas?
This is what occurs to me.
You can validate the data first, and not worry about invalid data in your processing.
You can instead deal with invalid data, by not crashing, but using try blocks to generate reasonable output for the user, or log errors, whatever is proper.
Unit test what your code does. Make sure it does what it says. Do it by mocking and inpecting mock calls. Use mocks to return invalid data and test that they trigger the invalid data exceptions you provided.
If you find difficult to express all cases that could be wrong (maybe you have to generalize a bit here because of dealing with very large or infinite possible inputs), it may be useful to stretch the thing with lots of randomly generated data that will show you cases you have not imagined (trust me, this works).
Capture those to a reasonable amount, until (the typical size of your data, or 10x that, or more, you choose) random data does not seem to trigger errors. Keep your random tests running but reduce the tries to make your tests run fast again, while you go on coding the rest of the system.
Of course mock the database access for this.
At anytime you find that data errors still happen, you can fix that case, and increase the random tries to check better. This is better than writing lots of specific cases by hand.
I have a dataset which has items with the following layout/schema:
{
words: "Hi! How are you? My name is Helennastica",
ratio: 0.32,
importantNum: 382,
wordArray: ["dog", "cat", "friend"],
isItCorrect: false,
type: 2
}
where I have a lot of different types of data, including:
Arrays (of one type only, e.g an array of strings or array of numbers, never both)
Booleans
Numbers with fixed min/max (i.e on a scale of 0 to 1)
Limitless integers (any integer -∞ to ∞)
Strings, with some dictionary, some new, words
The task is to create an RNN (well, generally, a system that can quickly retrain when given one extra bit of data instead of reprocessing it all - I think an RNN is the best choice; see below for reasoning) which can use all of these factors to categorise any dataset into one of 4 categories - labelled by the type key in the above example, a number 0-3.
I have a set of lots of the examples in the above format (with answer provided), and I have a database filled with uncategorised examples. My intention is to be able to run the ML model on that set, and sort all of them into categories. The reason I need to be able to retrain quickly is because of the feedback feature: if the AI gets something wrong, any user can report it, in which case that specific JSON will be added to the dataset. Obviously, having to retrain with 1000+ JSONs just to add one extra on would take ages - if I am not mistaken, an RNN can get around this.
I have found many possible use-cases for something like this, yet I have spent literal hours browsing through Github trying to find an implementation, or some Tensorflow module/addon to make this easier/copy, but to no avail.
I assume this would not be too difficult using Tensorflow, and I understand a bit of the maths and logic behind it (but not formally educated, so I probably have gaps!), but unfortunately I have essentially no experience with using Tensorflow/any other ML frameworks (beyond copy-pasting code for some other projects). If someone could point me in the right direction in the form of a Github repo/Python framework, or even write some demo code to help solve this problem, it would be greatly appreciated. And if you're just going to correct some of my technical knowledge/tell me where I've gone horrendously wrong, I'd appreciate that feedback to (just leave it as a comment).
Thanks in advance!
I apologize in advance is this question is too broad, but I need some help conceptualizing.
The end result is that I want to enable radius-based searching. I am using Django. To do this, I have two classes: Users and Places. Inside the Users class is a function that defines the radius in which people want to search. Inside the Places class I have a function that defines the midpoint if someone enters a city and state and not a zip (i.e., if someone enters New York, NY a lot of zipcodes are associated with that so I needed to find the midpoint).
I have those two parts down. So now I have a radius where people want to search and I know (the estimate) of the places. Now, I am having a tremendous amount of difficulty combining the two, or even thinking about HOW to do this.
I attempted doing the searching against each other in the view, but I ran into a lot of trouble when I was looping through one model in the template but trying to display results based on an if statement of the other model.
It seemed like a custom template tags would be the solution for that problem, but I wanted to make sure I was conceptualizing the problem correctly in the first place. I.e.,
Do I want to do the displays based on an if statement in the template?
Or should I be creating another class based on the other two in my models file?
Or should I create a new column for one of the classes in the models file?
I suppose my ultimate question is, based on what it is I want to do (enable radius based searching), where/how should most of the work be done? Again, I apologize if the question is overly broad.
Perhaps you could put it in the view which renders the search page.
asuuming you have a view function like search you could:
get users radius request.user.get_radius
search for places based on that radius relevant_places = Places.get_all_places_in_radius
Render those places to a user
Based on what you are describing, I believe GeoDjango would be worth your time to look into: http://geodjango.org/
Especially if you want to enable radius based searching, most of the heavy lifting is already done by GeoDjango, you'll just have to invest some time learning how to use it (which is a small fraction of the time you would have had to spend "reinventing the wheel", so to speak)
I just decided to add the function to the view so that the information can be input directly into the model after a user enters it. Thanks for the help. I'll probably wind up looking into geodjango.
Which of these two strategies would be better for calculating upvotes/downvotes for a post:
These are model fields:
ups
downs
total
def save(self, *args, **kwargs): # Grab total value when needed
self.total = self.ups - self.downs
super.(yourmodel, self).save(*args, **kwargs)
Versus:
ups
downs
def total(ups, downs): # totals will just be computed when needed
return ups - downs # versus saved as a column
Is there really any difference? Speed? Style?
Thanks
I would do the latter. Generally, I wouldn't store any data that can be derived from other data in the database unless the calculation is time-consuming. In this case, it is a trivial calculation. The reason being that if you store derived data, you introduce the possibility for consistency errors.
Note that I would do the same with class instances. No need to store the total if you can make it a property. Less variables means less room for error.
I totally agree with #Caludiu. I would go with the second approach, but as always there are pros and cons:
The first approach seems harmless but it can give you some headaches in future. Think about your application evolution. What if you want to make some more calculous derived from values in your models? If you would want to be consistent, you will have to save them too in your database and then you will be saving a lot of "duplicated" information. The tables derived from your models won't be normalized and not only can grow unnecessarily but increase the posibility of consistency errors.
On the other hand, if you take the second approach, you won't have any problems about database design but you could fall into a lot of tough django queries because you need to do a lot of calculus to retrieve the information you want. These kind of calculus are riddiculy easy as an object method (or message, as you prefer) but when you want to do a query like this in django-style you will see how somethings get complicated.
Again, in my opinion, you should take the second approach. But it's on you to make the desicion you think fits better on your needs...
Hope it helps!