I have this structure:
Structure Candidat
Public Nume As String
Public Scoala As String
Public Localitatea As String
Public Optiuni As String
Public Nota1 As Integer
Public Nota2 As Integer
End Structure
Public cd(100) As Candidat
I need to print the elements of the structure in a txt file, but ordered by name (by cd.Nume)
For i = 0 to some_number
PrintLine(1, cd(i).Nume, TAB(20), cd(i).Scoala, TAB(40), cd(i).Localitatea, TAB(60), cd(i).Optiuni, TAB(80), cd(i).Nota1, TAB(90), cd(i).Nota2)
Next
I saw something here but I don't understand.
Assuming you use vb.net as the programming language.
From the post you reference - the accepted answer is (by #Fredrik Mörk):
"
Assuming that the structure has a property called MPH:
cars = cars.OrderBy(Function(c) c.MPH)
Note: the above code was auto-converted from the following c# code (in case it contains errors):
cars = cars.OrderBy(c => c.MPH);
"
so you'll need to call
cd = cd.OrderBy(c => c.Nume); right before the printing for loop.
Related
Reading various answers here and elsewhere, I pieced together this bit to get the file metadata that I need:
Public Class windows_metadata_helper
Public Shared shell As New Shell32.Shell
Public Shared indices_of_interest As New Dictionary(Of Integer, String)
Public Shared path_index As Integer
Shared Sub New()
'snipped long piece code for figuring out the indices of the attributes that I need, they are stored in indices_of_interest, for example 0:Name
End Sub
Public Shared Function get_interesting_data(path) As Dictionary(Of String, String)
Dim fi As New IO.FileInfo(path)
Dim f_dir = shell.NameSpace(fi.DirectoryName)
Dim data As New Dictionary(Of String, String)
For Each item In f_dir.Items()
If f_dir.GetDetailsOf(item, path_index) = fi.FullName Then
For Each kvp In indices_of_interest
Dim val = f_dir.GetDetailsOf(item, kvp.Key)
If Not String.IsNullOrEmpty(val) Then data.Add(kvp.Value, val)
Next
Exit For
End If
Next
Return data
End Function
End Class
Its not the most efficient code in the world, namely getting the path attribute of each file in the directory to identify the file I'm actually interested in. Optimizing this to only read the path attribute of each file once makes it around 50% faster (tested by letting it take the first file it finds whether its the right one or not) but regardless, its far slower than expected.
It needs to fetch 24 attributes from each file and it needs to find around 20k files from within ~100k, currently this takes an entire hour.
Profiling tells me that CPU is the bottleneck and whatever is taking up the cycles I can't see since its 99% inside the Shell32.Folder.GetDetailsOf method.
Is there a faster way to get the metadata? Answer doesn't have to be vb or .net specific.
Since you are seeking maximum speed, I suggest that you enable Option Strict for your code and make the necessary modifications that will be suggested by the IDE. This will eliminate unnecessary type conversions.
For instance,
Public Shared Function get_interesting_data(path) As Dictionary(Of String, String)
should be:
Public Shared Function get_interesting_data(path As String) As Dictionary(Of String, String)
Instead of enumerating the Shell32.Folder.Items collection, use the Shell32.Folder.ParseName Method to directly retrieve a FolderItem object. This object can be cast to a Shell32.ShellFolderItem that will allow using the ShellFolderItem.ExtendedProperty method.
There are two ways to specify a property. The first is to assign the
property's well-known name, such as "Author" or "Date", to sPropName.
However, each property is a member of a Component Object Model (COM)
property set and can also be identified by specifying its format ID
(FMTID) and property ID (PID). An FMTID is a GUID that identifies the
property set, and a PID is an integer that identifies a particular
property within the property set.
Specifying a property by its FMTID/PID values is usually more
efficient than using its name. To use a property's FMTID/PID values
with ExtendedProperty, they must be combined into an SCID. An SCID is
a string that contains the FMTID/PID values in the form "FMTID**PID",
where the FMTID is the string form of the property set's GUID. For
example, the SCID of the summary information property set's author
property is "{F29F85E0-4FF9-1068-AB91-08002B27B3D9} 4".
Many FMTID/PID values can be found under links presented at Windows Properties.
You can find the full property table here (scroll down).
Putting this together for some selected properties:
Public Shared Function get_interesting_data(path As String) As Dictionary(Of String, String)
Dim fi As New IO.FileInfo(path)
Dim f_dir As Shell32.Folder = shell.NameSpace(fi.DirectoryName)
' instead of enumerating f_dir.Items to find the file of interest
' directly retrieve the item reference
Dim item As Shell32.ShellFolderItem = DirectCast(f_dir.ParseName(fi.Name), Shell32.ShellFolderItem)
Dim scid_Bitrate As String = "{64440490-4C8B-11D1-8B70-080036B11A03} 4" ' Audio: System.Audio.EncodingBitrate
Dim scid_Title As String = "{F29F85E0 - 4.0FF9-1068-AB91-08002B27B3D9} 2" ' Core: System.Title
Dim scid_Created As String = "{B725F130-47EF-101A-A5F1-02608C9EEBAC} 15" ' Core: System.DateCreated
Dim scid_Copyright As String = "{64440492-4C8B-11D1-8B70-080036B11A03} 11" ' Core: System.Copyright
Dim scid_Publisher As String = "{64440492-4C8B-11D1-8B70-080036B11A03} 30" ' Media: System.Media.Publisher
Dim scid_FullDetails As String = "{C9944A21-A406-48FE-8225-AEC7E24C211B} 2" ' PropList: System.PropList.FullDetails
Dim bitrate As Object = item.ExtendedProperty(scid_Bitrate)
Dim title As Object = item.ExtendedProperty(scid_Title)
Dim created As Object = item.ExtendedProperty(scid_Created)
Dim copyright As Object = item.ExtendedProperty(scid_Copyright)
Dim publisher As Object = item.ExtendedProperty(scid_Publisher)
Dim fullDetails As Object = item.ExtendedProperty(scid_FullDetails)
Dim data As New Dictionary(Of String, String)
' save the retrieved properties
Return data
End Function
I do not know if this technique of retrieving the properties is faster than you have currently using GetDetailsOf, but the other changes should make some improvement.
How do I test for the correct test results when my returned array is unordered? My test fails because the order they are in the array is different on each test run. How can I fix this or account for an unordered array?
mockMvc.perform(delete("/deleteSomeObject" + "/objIdLong" + "/objFKeyString"))
.
.
.andExpect(jsonPath("$[0].id.objIdLong", is(533252)))
.andExpect(jsonPath("$[0].id.objFKeyString", is("SomeString")))
.andExpect(jsonPath("$[1].id.objIdLong", is(642654252)))
.andExpect(jsonPath("$[1].id.objFKeyString", is("ThisString")))
.andExpect(jsonPath("$[2].id.objIdLong", is(4624352)))
.andExpect(jsonPath("$[2].id.objFKeyString", is("SomeOtherString")));
You could use the 'any element' instruction and to prevent false positives where one element has the expected objIdLong and another element has the expected objFKeyString you could combine the accessors.
Something like this:
.andExpect(jsonPath('$.id[?(#.objIdLong == 533252 && #.objFKeyString == \'SomeString\')]').exists())
.andExpect(jsonPath('$.id[?(#.objIdLong == 642654252 && #.objFKeyString == \'ThisString\')]').exists())
.andExpect(jsonPath('$.id[?(#.objIdLong == 4624352 && #.objFKeyString == \'SomeOtherString\')]').exists())
These assertions will be deemed true as long as the returned JSON contains:
An id sub document with objIdLong=533252 and objFKeyString="SomeString"
An id sub document with objIdLong=642654252 and objFKeyString="ThisString"
An id sub document with objIdLong=4624352 and objFKeyString="SomeOtherString"
At the time of writing there was an easier way of doing it .andExpect(content().json(expected_response))
.json(expected_response) validation has an option to do a strict or a lenient checking. This is helpful for arrays where you do not care about response ordering which can change. If you want to turn strict checking it on you can turn it on like .json(expected_response,true) . Also you can load your whole response from a file reader and do a direct assert without having to tediously write json path. Here is a complete example.
#Test
#DisplayName("invalid fields")
void invalidfields() throws Exception {
String request = getResourceFileAsString("test-data/http-request/invalid-fields.json");
String response_file_path = "test-data/http-response/error-messages/invalid-fields.json";
String expected_response = getResourceFileAsString(response_file_path);
mockMvc.perform(evaluateRulesOnData(TRACKING_ID.toString(), request))
.andExpect(status().isBadRequest())
.andExpect(content().json(expected_response));
}
helper function to load test files from classpath
public static String getResourceFileAsString(String fileName) throws IOException {
Resource resource = new ClassPathResource(fileName);
File file = resource.getFile();
return new String(Files.readAllBytes(file.toPath()));
}
The expected response has an array with many elements in the list which are matched despite being in random order during each test run.
I have tried to know the reason in online but i didnt get it.
I want to know the reason why '%s' used in xpath instead of giving text message
I hope some one can help me on this.
see my scenario:
By.xpath(("//div[contains(text(),'%s')]/following-sibling::div//input"))
It's called wildcard.
E.g. you have
private final String myId = "//*[contains(#id,'%s')]";
private WebElement idSelect(String text) {
return driver.findElement(By.xpath(String.format(myId, text)));
}
Then, you can make a function like:
public void clickMyId(idName){
idSelect(idName.click();
}
And call
clickMyId('testId');
The overall goal of the %s is not using the string concatenation, but to use it injected into a string.
Sometimes, there are many locators for web elements which are of same kind, only they vary with a small difference say in index or String.
For e.g., //div[#id='one']/span[text()='Mahesh'] and
//div[#id='one']/span[text()='Jonny']
As it can been seen in the above example that the id is same for both the element but the text vary.
In that case, you can use %s instead of text. Like,
String locator = "//div[#id='one']//span[text()='%s']";
private By pageLocator(String name)
{
return By.xpath(String.format(locator, name));
}
So in your case,
By.xpath(("//div[contains(text(),'%s')]/following-sibling::div//input"))
the text is passed at runtime as only the text vary in the locator.
'%s' in XPath is used as String Replacement.
Example:
exampleXpath = "//*[contains(#id,'%s')]"
void findElement(String someText)
{
driver.findElement(By.xpath(String.format(exampleXpath, someText)));
}
So it will replace %s with someText passed by user.
Question 1
How to get a class given a class name as a string ?
For example, say Product class has do_something method:
str = "product"
<what should be here based on str?>.do_something
Question 2
How to get object's field given a field name as a string ?
For example, say Product class has price field:
str = "price"
product = Product.new
product.<what should be here based on str?> = 1200
Jacob's answer to the first question assumes that you're using Rails and will work fine if you are. In case you're not you can call Kernel::const_get(str) to find an existing constant by name.
send is a pure ruby. There's no need to intern your strings with send though (convert them to symbols), straight strings work fine.
Use capitalize and constantize:
str.capitalize.constantize.do_something
Use send:
product.send(str + '=', 1200)
I'm using T4 to generate some class definitions and find that I'm getting an underscore in front of my field names.
I have set
code.CamelCaseFields = true;
just to be safe (even though I understand that's the default) but still end up with _myField rather than myField.
How can I generate a field name without the '_' character?
Also, where is the documentation for T4? I'm finding plenty of resources such as
Code Generation and Text Templates and numerous blogs, but I have not found the class-by-class, property-by-property documentation.
You're probably talking about EF4 Self Tracking Entities. The CodeGenerationTools class is included via the <## include file="EF.Utility.CS.ttinclude"#> directive, which you can find at "[VSInstallDir]\Common7\IDE\Extensions\Microsoft\Entity Framework Tools\Templates\Includes\EF.Utility.CS.ttinclude".
The FieldName function is defined as such:
private string FieldName(string name)
{
if (CamelCaseFields)
{
return "_" + CamelCase(name);
}
else
{
return "_" + name;
}
}
The "_" is hardcoded in the function. Coding your own shouldn't be difficult. Note that the CodeGenerationTools class is specific to this ttinclude file and isn't a generic and embedded way to generate code in T4.
I've written the following method to make first character upper case, remove spaces/underscores and make next character upper case. See samples below. Feel free to use.
private string CodeName(string name)
{
name = name.ToLowerInvariant();
string result = name;
bool upperCase = false;
result = string.Empty;
for (int i = 0; i < name.Length; i++)
{
if (name[i] == ' ' || name[i] == '_')
{
upperCase = true;
}
else
{
if (i == 0 || upperCase)
{
result += name[i].ToString().ToUpperInvariant();
upperCase = false;
}
else
{
result += name[i];
}
}
}
return result;
}
input/output samples:
first_name = FirstName,
id = Id,
status message = StatusMessage
This is good advice however it doesn't help you in knowing WHERE the right place to put such a function is...
Is there any guidance on DECOMPOSING the EF .tt files or stepping through the output generation to see how it builds the output?
I was able to use the above function successfully by plugging it into a function called
(Ef4.3)
public string Property(EdmProperty edmProperty)
Which appears to be used to output the lines like "public int fieldname { get; set; }"
and changed the 3rd (index {2}) param to the formating to wrap with the function to modify the name, like this:
_typeMapper.GetTypeName(edmProperty.TypeUsage), //unchanged
UnderScoreToPascalCase(_code.Escape(edmProperty)), //wrapped "name"
_code.SpaceAfter(Accessibility.ForGetter(edmProperty)), // unchanged
This is not perfect, eg: it doesn't keep existing "Ucasing" and doesn't care about things like this:
customerIP
outputs: Customerip
which IMO is not very readable...
but its better than what I WAS looking at which was a nightmare because the database was intermingled mess of camelCase, PascalCase and underscore separation, so pretty horrific.
anyway hope this helps someone...