create integer associated to a string in java - string

i've been programming for about three weeks on a game in Java.
The last days I was searching for a way to "connect" an integer value to an string and being abled to create new objects which are abled to hold this values aswell.
This would be needed to create item-objects holding an item-ID and the path for the item-image.
I got some inspiration from other people in my company aswell, who told me to use XML-Files or CSV-files to save the item-ID to the correct item-path, but before i learn to create an XML or use a CSV i wanted to know if there might be a better or easier way to create items without wasting more time in try and error to assign an Integer to an String...
Thanks for your Attention

Related

Pimcore 6 CSV Importing

Pimcore newbie here. I'm struggling a bit with the csv import procedure, the docs are a bit shallow and I couldn't find a more comprehensive developer reference.
I'm not getting how Resolver Settings work. What's the meaning of setting a strategy? (ID throws Pimcore\DataObject\Import\Resolver\ImportErrorException: Could not resolve object with id. Filename runs, but then it seems that I don't have control on how objects get labeled)
I have two date columns in my imported csv, so I'd like to fill my object with those. Still, the dates are written like "2016-05-30T14:36:03" so I guess that I need to process a bit to transform the string in a format that could be recognized by pimcore. Do I need to do this in Column Configuration (by converting the specific column as an Operator PHP Code. BTW, do I need to create a class for every column, or I can group them by data format?) or more globally by setting the Resolver Strategy as Code and editing all the row properties at once?
About the resolver
When importing a CSV, Pimcore has for each row basically two options: create a new DataObject or update an existing one. When you want Pimcore to update existing DataObjects then you need some logic to retrieve that specific DataObject based on some info in the CSV. That's where the Resolver comes in place.
Pimcore supports 5 different resolver strategies:
Id: your CSV needs to contain a column with the DataObject id, and that value is used to fetch the corresponding DataObject to update
Filename: same as above, but for the filename (= key) of the DataObject
Fullpath: same as above, but for the full path of the DataObject
GetByAttribute: same as above, but for a given attribute within the DataObject (for example if you have a field ProductCode in it)
Code: a custom PHP class containing logic to retrieve the existing DataObject
The Id operator has one drawback, which you are currently running into:
Resolves the objects via the object ID. The object has to exist, otherwise an error is thrown.
Based on your question, I have the feeling that you are only inserting new DataObjects (at least for now, maybe you might also want to update later on).
When creating DataObjects you need to specify a key/filename (most likely you already noticed that when creating an object manually), so your CSV should already (if it doesn't you should add it) contain a column with either that key/filename or with the full path for the new DataObjects. That same column can/should be used to resolve any (potentially already) existing DataObjects.
So you should use either the Filename or Fullpath Resolver. Both have options what to do if the object already exists (update it? ignore it?) and (more important in your situation) what to do when it doesn't exist yet.
About the dates
Looking at the code, any string that can be parsed by the PHP's method strtotime can be entered in your CSV. Your value 2016-05-30T14:36:03 parses just fine.

management of big number of parameters of a keyword in VBscript

I'm working on test automation using keyword driven framework. I have to add a keyword add_car. This keyword needs a big number of parameters that should be entered in the excel sheet as parameters for this keyword.
I want to find a solution to manage the big number of parameters(some of them are always required and the others are optional)
The below picture is an example of how the values of parameters are entered in the Excel sheet.
excel sheet example
Here is how I call this keyword in UFT
keyword Call in UFT
And in my Functions Library, I defined the instructions of my_keyword.
Is there any solution to manage this big number of parameters(I have more than 30 parameter in general some are optional and others are always required).
I'd advise walking through your worksheet to get all parameters and store them into a dictionary. Then you would call your functions by calling the dictionary instead of all parameters individually.
The way to manage all of the parameters to add them into dictionary would have to be handled in a separate function and you could then check if the parameters exist/have values inside your functions or even externally. It would actually be kind of a whole new framework just to work with it, but when you're done, you could reuse the functions anywhere you wanted.
At least that was the way implemented in the project I've worked (though I was not the one to implement it).
It is hard to provide a thorough answer about the topic because it is pretty extensive, but for starters, I'd recommend this link about working with dictionaries:
http://automated-360.com/qtpuft/advanced-concepts/everything-dictionary-object/
In a very brief way, Dictionary objects are sort of a collection of Key,Item pairs, where you could store your parameters like Parameter1,ParameterValue to use later.
It also allows you to sort your parameters, check for existence, store them in a Case Insensitive way, edit them, delete them and so forth.
This is what I can offer to you now.
Happy research and happy coding.
Not sure how many parameters do you have.
However, I have 600+ parameters required for 1 test case (I know... It's a huge end to end test that takes loads of parameters).
I have used different tabs in excel sheet to logically separate the test data parameters.
I read the excel as database (using ADODB.connection) and query each tab in excel to get the row that I need. I can write SQL join to query from multiple excel tabs at once.
Reference on reading excel as DB:
http://www.automation.ultimatetimepass.com/index.php/home/qtp/excel/qtp-read-excel-using-adodb-connection/10-qtp-excel
Few thoughts on this.
Possible solution 1: Text File Approach
You will have all the parameters are stored with key,value combination like given below in the text file.
Parameter1=abc
Parameter2=def
Parameter3=ghi
The advantage here is when any of your parameter not needed, just remove from the text file.That being said, Your framework engine should read the keyword "ReadFile" as function and return a collection of string from file.
sParameterList = ReadFile("")
Possible solution 2:
Define all the parameters with comma separated value.Split and pass it your function call.
Parameter1=abc,Parameter2=def,Parameter3=ghi

global identifiers? - iCloud + Core Data + Ensembles - duplicates when deleting objects

I am trying to implement iCloud sync in my Core Data app. I am not that pro in programming and this is really an advanced topic I learned... I found that Core Data sync Framework "Ensembles" by Drew McCormack. It seems to make iCloud Sync much easier.
I integrated it in my App and syncing does work quite well as long as I add new objects to my Core Data model. But when I delete an object, it creates duplicates. And then duplicates from duplicates. I ended up having the same Entry (object) like 3-4 times...
Why is that? What am I doing wrong? I did some research and my guess is that global identifiers could solve this?
What are global identifiers? My guess is that they help to avoid duplicates!? But how do I set this? I really have no idea, did a lot of research but couldn´t find an answer to that.
Thanks for help!
Update:
Thanks for help! I read the readme and the book, but since i am beginner not everything is clear to me.
I think I understand the use of global identifiers in Ensembles now, but I don´t know if I´m doing it correctly.
If I understand it right, I have to assign an identifier to each object. I can do this by storing it in an attribute. This identifier can be anything as long as it is unique and a NSString?
In my app the user can store different things, let´s say name, text, title, date and so on. The app is based on the Master-Detail-View template in Xcode and uses Core Data. My Core Data model has only a single entity with some attributes, most are strings and a NSDate. No relationships or anything. If the user hits "+" a new object is created and I store the things the user enters in the attributes.
What I did to add global identifiers is to add a new attribute that stores it.
So when a new object is created i do
/// I did find that to use as identifier !?
NSString *taskUniqueStringKey = newManagedObject.objectID.URIRepresentation.absoluteString;
/// and store it in the attribute.
[newManagedObject setValue:taskUniqueStringKey forKey:#"coreDataObjectID"];
Then i use this:
- (NSArray *)persistentStoreEnsemble:(CDEPersistentStoreEnsemble *)ensemble globalIdentifiersForManagedObjects:(NSArray *)objects
{
return [objects valueForKeyPath:#"coreDataObjectID"];;
}
This seems to work for me. But am I doing it right? Is this the right place to assign a global identifier? I have no awakeFromInsert !?
If this is working, I got the next problem. My app is already live and older entries that the user saved before the update will be missing the global identifier. What can I do about that? I thought what I already got and what is unique and the only thing I can think of is an attribute that saves [NSDate date] when the object is created.
I was trying to use this but I failed because Ensembles will only accept NSString and not NSDate!? Can I use this date attribute, is this unique enough and working as gloabl identifier? And if yes, could you please give me code example in how to convert this from date to string?
Syncing with Ensembles works quite good. No duplicates anymore, you can just switch off iCloud and the entries stay and switch it on again and it syncs like it should without loosing locally stored objects or so. Ensembles is really cool! I am seeing some minor strange behaviors like sometimes sync takes long, sometimes it´s really quick and if I edit things in a short time period on two different devices it gets a bit messed up like an object that I just deleted reappears. But I guess that´s normal? If I take some time between using the app on the different devices everything works fine.
Do I understand it right, there is only that one method to call for sync:
- (void)syncWithCompletion:(void(^)(void))completion
{
if (self.ensemble.isMerging) return;
if (!self.ensemble.isLeeched) {
[self.ensemble leechPersistentStoreWithCompletion:^(NSError *error) {
if (error) NSLog(#"Error in leech: %#", error);
if (completion) completion();
}];
}
else {
[self.ensemble mergeWithCompletion:^(NSError *error) {
if (completion) completion();
}];
}
and you just call it if needed? There is nothing else like doing merge without leeching before, or a method like "this is the actual status - save it like it is now" ?
There are different points in the app where you want to sync. On app start and when terminating will be a good point. In my app there are two points where I should sync I guess: when adding an object and save it to Core Data and when I save changes to the object. I could also provide a button like "sync now". Is this a good approach and do I always just call
[self syncWithCompletion:NULL];
Another question that came up. Can I exclude objects from sync with Ensembles? My app loads tutorial entries as objects once on first app start. I don´t want to sync them if that´s possible somehow?
Thanks a lot for your help! If I could help you with anything like localizing in german or so let me know ! ;)
Yes, this is almost certainly due to not setting up global identifiers for your objects, or at least not doing it properly.
When you leech your ensemble, the local persistent store is imported into the sync data. Without global identifiers, Ensembles will assign random ids to your objects, so it can track them across devices.
Duplicates arise when you leech a second device that has the same data. Ensembles has no way to know that the data represents the same logical objects as on the other device, so it again assigns random ids. Effectively, it treats the objects on each device as being completely independent, so that all end up in your data set after syncing.
The solution is global identifiers. By implementing a CDEPersistentStoreEnsemble delegate method, you can provide Ensembles with global ids, which it can use to identify which objects on different devices belong together.
What should you use for global ids? Often, just a UUID, though for singleton like objects you will just want to pick an id.
You can initialize them in awakeFromInsert. You can store the global ids in attributes on your entities. (Note that if you are migrating an existing app, you will want to check with a fetch if the global ids have been generated BEFORE you try to leech the store for syncing.)
More details are in the README on GitHub and in the book at leanpub.
Update
To answer your update questions:
Yes, an identifier just has to be a string, and immutable. It should not change once assigned.
The NSManagedObjectID is not a very good global identifier, in that it will be different on different devices. We really want something that is global across devices.
If you are starting from scratch, using NSUUID is a good approach. Just create a unique id, and store it in the object.
If you have an existing app, and it has been syncing via another mechanism, you need to come up with a way to provide the same global identifiers on each device. One way to do that is mash up the object properties in some way. Usually that will give you a pretty-close-to-unique value, and it will be good enough for the transition.
As an example, you do a quick fetch, and discover that your objects don't yet have global ids. You go through the objects, and set the global ids to a string comprised of creationDate + text. (You could even shorten this by taking a hash, but it probably isn't that important.) After this initial 'migration' to global identifiers, you would just use UUIDs for any newly created objects.
Note that you don't have to use awakeFromInsert. That is simply a convenient place to put it. As long as you assign the global identifier before saving the object you should be fine.
The easiest way to get a string from an NSDate is to call the description method, but another way would be to get a double using timeIntervalSince1970, and turning that into a string. (Be careful with dates as unique identifiers on their own: often objects created together will have the same creation date.)
You are correct about how you should do a sync: you can simply call syncWithCompletion:.
To answer the question about excluding objects: You can't exclude individual objects, mainly because it could become tricky when those objects have relationships to synced objects. You can handle these objects in one of two ways:
Put them in a separate persistent store, and add that store to the same persistent store coordinator.
Sync the objects, but give them global ids manually, so that the objects are treated the same on each device. Eg. You could just give global ids as 'Sample1', 'Sample2', etc.
To integrate Drew's answer, I guess the two steps are the following.
1 Implement CDEPersistentStoreEnsemble delegate method (see README)
- (NSArray *)persistentStoreEnsemble:(CDEPersistentStoreEnsemble *)ensemble
globalIdentifiersForManagedObjects:(NSArray *)objects {
return [objects valueForKeyPath:#"yourUniqueIdentifier"];
}
2 Generate the unique identifier for a NSManagedObject subclass
- (void)awakeFromInsert {
[super awakeFromInsert];
if (!self.yourUniqueIdentifier) {
self.yourUniqueIdentifier = [[NSUUID UUID] UUIDString];
}
}
In awakeFromInsert you can initialize special default property values, like for example an identifier.
The check is necessary, for example, when you have parent-child contexts. Otherwise you are overwriting the identifier previously set. See Why is awakeFromInsert called twice?.

Need to combine .getElementsByClass and .getElementsById to scrape data from website

I am writing a simple crawler using VBA. I found out that the data I am looking for correspond to the node <h6 class="country-name" id="Australia">.
I know that if I wanted to select data from, let us say, <div class="section-country">, I should use .getElementsByClassName("section-country") in my VBA macro.
In presence of both class and id in the node, which command should I insert in my VBA macro to scrape data?
Thanks a lot,
Avitus
EDIT: writing .getElementsByClassName("country-name").getElementsById("Australia") gives me an error. Why?
getElementsByID (plural) doesn't exist - there should only be one item with a given ID. Therefore, use getElementByID (singular) which does exist. If there happen to be multiple elements with the same ID, this function will return the first one.
As others have said, selecting by ID sounds more appropriate to what you want to do than selecting by class
There must be a method like getelementbyxpath you can use this method by using this xpath "//div[#class='country-name' and #id ='Australia']"
eg: getElementsByXpath("//div[#class='country-name' and #id ='Australia']")
Read More here how to set up a crawler for web scraping

Use of object vs string vs enum

I have a situation that may seem ridiculus but I have not been able to figure out a good enough solution. To simplify things the problem is something like this, suppose you have an object like Manufacturer that has a countryname property (like car.Manufacturer.CountryName) and you want to be sure that the countryname property can not have duplicates or misspellings or other errors.
It is basically a string property but a string can be anything which I do not want. An object seems like overkill and an enum means I have to recompile if new countries are to be added or existing countries to be changed.
I could easily control this in a GUI but I need to control this in the application code. So I have an object with a property that could be a string, an object or an enum (or other) and I cant decide which to use. So my options are something like this:
a) Control this in the GUI and do not check this in the application code, taking the risk that I can get "illegal" country names.
b) Make an object (Country) and use that, which is overkill and makes the code more complex, but I have complete control over duplicates and all that stuff.
c) Use an enum and hope that I do not have to recompile too often. It is simple and effective but a static solution.
d) Use an internal string list of valid country names and have CountryName as a string property and make sure that it is validated against that string. I get validation and CountryName is just a simple string, but what if I change that internal string of valid country names? Than I have to make code the revalidates all Manufacturer objects in the program too make sure they still have valid contry names.
I am not totally sure how important it is too have valid country names but the more I think about this the more I realize that I am in a grey zone. An object, or struct, is too much, an enum too static, a string too simple.
I could be totally overcomplicating things here but I would really like too know what to do, or rather how to think, when you get into this grey zone of object vs string vs enum.
Thankfully yours!
Hal
c) Use an enum and hope that I do not have to recompile too often. It is simple and effective but a static solution.
From this statement I can infer that your data can be subject to change. In these situations, I suggest using an external data store (a database, text file, XML file, whatever).
If country name data integrity is important to you I'd store a list of valid country names in a database or other persistence method, query and cache them inside the application.
Then you can add one post-deployment without recompiling or changing code and with caching you don't incur a lot of overhead for the extra database query.
Go with the object.
It really comes down to a case of do the 'complex' work now and life is easier later on or take the easy route now and life may be more 'complex' later.
Also considering you are actually worried about all the negatives of options b, c & d then just remove your worries!
Also as others have suggested your data should be stored externally to the code (database, xml file etc...) writing an object to wrap this would be your best solution.
I would use a dictionary stored as a separate file, like a XML property list, something like:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
<plist version="1.0">
<dict>
<key>UK</key>
<string>United Kingdom</string>
<key>FR</key>
<string>France</string>
<key>SP</key>
<string>Spain</string>
</dict>
</plist>
There might be another option:
use a list of Country names stored in an external (possibly human-readable) file. When your program starts, load the country names in an array of strings (or in some other ordered container), and use the order in the list to assign a number to each country (if you use an array, just use the index). A variable containing a country is now just an integer.
Another trick is to use a separate object (which has only one instance) to handle country names. This will ensure that all objects are using the most recent version of the list of country names. Manufacturer objects then do not have a string list, but a reference to the unique object containing the string list.

Resources