unable to remove range of items in a list - list

I am setting the items which i want to Remove from list as null and then sorting list through IComparable method CompareTo so that null items would be at the top ... then using RemoveRange function on list but unable to so so ... i see no problem in following code:
try
{
foreach (Invoice item in inv)
{
if (item.qty == 0)
{
item.CustomerName = null;
item.qty = 0;
i++;
}
}
inv.Sort();
inv.RemoveRange(0, i);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
#region IComparable<Invoice> Members
public int CompareTo(Invoice other)
{
return this.CustomerName.CompareTo(other.CustomerName);
}
#endregion
error occurs at inv.RemoveRange(0,i); saying that :Failed to compare two elemets in array
Why is it so??

public int CompareTo(Invoice other)
{
if (other == null || other.CustomerName == null) return 1;
if (this.CustomerName == null) return -1;
return this.CustomerName.CompareTo(other.CustomerName);
}
or
public int CompareTo(Invoice other)
{
//if other Invoide is null, instance is bigger.
if (other == null) return 1;
if (this.CustomerName == null) {
//if both CustomerName are null, instance equals other. Of only instance CustomerName is null, other is bigger.
return other.CustomerName == null ? 0 : -1;
}
//if other.CustomerName is null (and instance.CustomerName is not null), instance is bigger.
if (other.CustomerName == null) return 1;
//both CustomerName are not null, call basic string.CompareTo
return this.CustomerName.CompareTo(other.CustomerName);
}

Related

c++ how to get depth of a binary tree recursively

I wrote a code that suposed to return the depth of a binary tree from the root to the node who called the function. using recursive way but I faced a problem about how to count the number of times that the function gets called so I whould know how much convexity I passed. Someone know how can I do that?
int BSNode::getDepth(const BSNode& root) const
{
if (this != nullptr)
{
if (root.getData() > this->_data)
{
this->getDepth(*root.getRight());
}
else if (root.getData() < this->_data)
{
this->getDepth(*root.getLeft());
}
else if (root.getData() == this->_data)
{
// return the number that the function counted
}
}
else
{
return 0;
}
}
You should at least return something in every case. And when you arrive at the intended node (having the data you are looking for), then return 0. In all other cases, return what you get from recursion plus 1. If the value is not found then indeed -1 should be returned. And if this -1 is coming back from recursion, it should be returned like that also to the caller (without adding 1).
Here is the code adapted:
int BSNode::getDepth(const BSNode& root) const
{
int temp;
if (this != nullptr)
{
if (root.getData() > this->_data)
{
temp = this->getDepth(*root.getRight());
return temp == -1 ? -1 : temp + 1;
}
else if (root.getData() < this->_data)
{
temp = this->getDepth(*root.getLeft());
return temp == -1 ? -1 : temp + 1;
}
else if (root.getData() == this->_data)
{
return 0;
}
}
else
{
return -1;
}
}

Find specific node height in tree c++

I am trying traverse over tree and check for specific (rel_name) and return his height, but my function traverse over "mother" branch and checks only fathers branch.
The result is that my program return exception() and core dumping.
how do I fix my function to not core dump and check mothers branch too?
string treeHeight(Person* root, string rel_name, int height){
height++;
if(root == nullptr) {
throw exception();
}
else if(root->name == rel_name) return to_string(height);
return treeHeight(root->father, rel_name, height);
return treeHeight(root->mother, rel_name, height);
}
Someone has already pointed out, but if your code reaches a leaf and goes a little bit further, according to your base case it would throw an exception and exit the program.
I revised your code a little bit:
int treeHeight(Person* root, const string& rel_name){
if(root == nullptr) {
return -1;
}
else if(root->name == rel_name) return 0;
int leftHeight = treeHeight(root->father, rel_name);
int rightHeight = treeHeight(root->mother, rel_name);
if (leftHeight == -1 && rightHeight == -1) {
return -1;
} else {
return (leftHeight > rightHeight ? leftHeight : rightHeight) + 1;
}
}
Hope it helps.
In your code , you are not allowing the code to go the mother node, its directly from the father node call and thus its not getting executed ahead.
Try this below :
string treeHeight(Person* root, string rel_name, int height){
height++;
if(root == nullptr) {
throw exception();
}
else if(root->name == rel_name) return to_string(height);
int person_height = treeHeight(root->father, rel_name, height);
if(person_height!=0) return height; ---------> You need to apply this check
return treeHeight(root->mother, rel_name, height);
}

MP3 Tagging ID3v2_3 Id3v2_4

I use the JID3 library which works fine for IDv2_3 but when it is asked to update a tracks tags which are V2_4, it simply wipes the Id3v2_4 tags. How can I test which version of tagging a track has.
Example of setting the ratings and times played in the POPULARIMETER tag
public String setmp3RatingTag(Context context, File SourceFile, String email, int rating, int timesPlayed) throws Exception {
String error = null;
if (timesPlayed < 0) {
timesPlayed = 0;
}
try {
MediaFile MediaFile = new MP3File(SourceFile);
ID3V2_3_0Tag ID3V2_3_0Tag = (org.blinkenlights.jid3.v2.ID3V2_3_0Tag) MediaFile.getID3V2Tag();
POPMID3V2Frame popmid3V2Frame = new POPMID3V2Frame(email, rating, timesPlayed);
popmid3V2Frame.setPopularity(email, rating, timesPlayed);
if (ID3V2_3_0Tag != null) {
frames = ID3V2_3_0Tag.getPOPMFrames();
if (frames != null) {
if (frames.length > 0) {
String emailtouser[]=getmp3Email(SourceFile);
for (int i = 0; i < frames.length; i++) {
if (frames[i] != null) {
ID3V2_3_0Tag.removePOPMFrame(emailtouser[i]);
}
}
}
}
} else {
ID3V2_3_0Tag = new ID3V2_3_0Tag();
}
ID3V2_3_0Tag.addPOPMFrame(popmid3V2Frame);
MediaFile.setID3Tag(ID3V2_3_0Tag);
MediaFile.sync();
} catch (ID3Exception | OutOfMemoryError e) {
e.printStackTrace();
error = e.getMessage();
}
error = finish(context, SourceFile);
return error;
}
For anyone using the jid3 library, I added another method to the class MP3File.java
#Override
public int testforVerion() {
int iMinorVersion=0;
try {
InputStream oSourceIS = new BufferedInputStream(m_oFileSource.getInputStream());
ID3DataInputStream oID3DIS = new ID3DataInputStream(oSourceIS);
try
{
// check if v2 tag is present
byte[] abyCheckTag = new byte[3];
oID3DIS.readFully(abyCheckTag);
if ((abyCheckTag[0] == 'I') && (abyCheckTag[1] == 'D') && (abyCheckTag[2] == '3'))
{
// check which version of v2 tags we have
iMinorVersion = oID3DIS.readUnsignedByte();
}
else
{
return iMinorVersion;
}
}
finally
{
oID3DIS.close();
}
} catch (IOException e) {
e.printStackTrace();
}
return iMinorVersion;
}
simply check for value 3 for ID3V2_3 and 4 for ID3V2_4

Override default DateTime 12:00 AM or 12:00PM to current Time?

As in my picture I have DateTime of SLA and Finish Date, and Finish Date is the same value of SLA but it allows user to add or change the DateTime. When I change the DateTime on Finish Date, it got the default value of Time was 12:00 PM or 12:00 AM. Is there any way to change the default time to current time? and will there be any impact if user changes the user locale format?
This is my UsrFinishDate default value:
UsrFinishDate (New Field)
[PXDBDate(PreserveTime = true)]
[PXUIField(DisplayName="Finish Date")]
protected void CRCase_UsrFinishDate_FieldDefaulting(PXCache cache, PXFieldDefaultingEventArgs e)
{
CRCase row = e.Row as CRCase;
CRCaseExt rowExt = PXCache<CRCase>.GetExtension<CRCaseExt>(row);
if (row == null || row.AssignDate == null) return;
if (row.ClassID != null && row.Severity != null)
{
var severity = (CRClassSeverityTime)PXSelect<CRClassSeverityTime,
Where<CRClassSeverityTime.caseClassID, Equal<Required<CRClassSeverityTime.caseClassID>>,
And<CRClassSeverityTime.severity, Equal<Required<CRClassSeverityTime.severity>>>>>
.Select(Base, row.ClassID, row.Severity);
if (severity != null && severity.TimeReaction != null)
{
e.NewValue = row.SLAETA;
e.Cancel = true;
}
}
if (row.Severity != null && row.ContractID != null)
{
var template = (Contract)PXSelect<Contract, Where<Contract.contractID, Equal<Required<CRCase.contractID>>>>.Select(Base, row.ContractID);
if (template == null) return;
var sla = (ContractSLAMapping)PXSelect<ContractSLAMapping,
Where<ContractSLAMapping.severity, Equal<Required<CRCase.severity>>,
And<ContractSLAMapping.contractID, Equal<Required<CRCase.contractID>>>>>
.Select(Base, row.Severity, template.TemplateID);
if (sla != null && sla.Period != null)
{
e.NewValue = row.SLAETA;
e.Cancel = true;
}
}
}
and this is my other event rowSelected:
protected void CRCase_RowUpdated(PXCache cache, PXRowUpdatedEventArgs e)
{
var row = e.Row as CRCase;
var oldRow = e.OldRow as CRCase;
CRCaseExt rowExt = PXCache<CRCase>.GetExtension<CRCaseExt>(row);
if (row == null || oldRow == null) return;
if (row.OwnerID == null)
{
row.AssignDate = null;
row.SLAETA = null;
rowExt.UsrFinishDate = null;
}
else if (oldRow.OwnerID == null)
{
row.AssignDate = PXTimeZoneInfo.Now;
if (row == null || row.AssignDate == null) return;
if (row.ClassID != null && row.Severity != null)
{
var severity = (CRClassSeverityTime)PXSelect<CRClassSeverityTime,
Where<CRClassSeverityTime.caseClassID, Equal<Required<CRClassSeverityTime.caseClassID>>,
And<CRClassSeverityTime.severity, Equal<Required<CRClassSeverityTime.severity>>>>>.
Select(Base, row.ClassID, row.Severity);
if (severity != null && severity.TimeReaction != null)
{
row.SLAETA = ((DateTime)row.AssignDate).AddMinutes((int)severity.TimeReaction);
rowExt.UsrFinishDate = ((DateTime)row.AssignDate).AddMinutes((int)severity.TimeReaction);
}
}
if (row.Severity != null && row.ContractID != null)
{
var template = (Contract)PXSelect<Contract, Where<Contract.contractID, Equal<Required<CRCase.contractID>>>>.Select(Base, row.ContractID);
if (template == null) return;
var sla = (ContractSLAMapping)PXSelect<ContractSLAMapping,
Where<ContractSLAMapping.severity, Equal<Required<CRCase.severity>>,
And<ContractSLAMapping.contractID, Equal<Required<CRCase.contractID>>>>>.
Select(Base, row.Severity, template.TemplateID);
if (sla != null && sla.Period != null)
{
row.SLAETA = ((DateTime)row.AssignDate).AddMinutes((int)sla.Period);
rowExt.UsrFinishDate = ((DateTime)row.AssignDate).AddMinutes((int)sla.Period);
}
}
}
}
Here is the definition of the field I added to the Case screen, note the PreserveTime = true which I think might be what you are missing.
public class CRCaseExt : PXCacheExtension<PX.Objects.CR.CRCase>
{
#region UsrFinishDate
[PXDBDate(PreserveTime = true)]
[PXUIField(DisplayName = "Finish Date")]
public virtual DateTime? UsrFinishDate { get; set; }
public abstract class usrFinishDate : IBqlField { }
#endregion
}
And here is an easy way to set the current time when the UsrFinishDate value is changed. Don't forget to set the CommitChanges for that field.
protected virtual void CRCase_UsrFinishDate_FieldUpdating(PXCache sender, PXFieldUpdatingEventArgs e)
{
CRCase currentCase = (CRCase)e.Row;
var caseExt = PXCache<CRCase>.GetExtension<CRCaseExt>(currentCase);
if (caseExt == null)
{
return;
}
e.NewValue = new DateTime(caseExt.UsrFinishDate.Value.Year,
caseExt.UsrFinishDate.Value.Month,
caseExt.UsrFinishDate.Value.Day,
DateTime.Now.Hour,
DateTime.Now.Minute,
DateTime.Now.Second);
}

Best way to check if one of other objects is true or not

I am looking for best way to implement this scenario:
I have 4 objects that have Boolean member that in the flow of the app sometimes they are set to true and sometimes are set to false depending on conditions;
Then I have final function that gets 1 of this objects and needs to check if in the other 3 objects one of them has the member set to true .
The problem is I know how to do the dirty check , and I am searching for cleaner way here is my code for the final function:
class Obj
{
public :
Obj(int _id) : id(_id)
bool status;
int id // only 4 objects are created 0,1,2,3
}
m_obj0 = new Obj(0) ;
m_obj1 = new Obj(1) ;
m_obj2 = new Obj(2) ;
m_obj3 = new Obj(3) ;
bool check(Obj* obj)
{
if(obj->id == 0)
{
if(m_obj1->status || m_obj2->status || m_obj3->status)
{
return true;
}
return false;
}else if(obj->id == 1)(
if(m_obj0->status || m_obj2->status || m_obj3->status)
{
return true;
}
return false;
}else if(obj->id == 2)(
if(m_obj0->status || m_obj1->status || m_obj3->status)
{
return true;
}
return false;
}else if(obj->id == 3)(
if(m_obj0->status || m_obj1->status || m_obj2->status)
{
return true;
}
return false;
}
is there a shorter and cleaner way to accomplish this check function ?
You can set m_obj as an array. Then use a for loop to check
bool check(Obj* obj)
{
for (int i = 0; i < 4; i ++) {
if (obj->id == i) continue;
if (m_obj[i]->status == true)
return true;
}
return false;
}
Or add them together, then subtract m_obj[obj->id]->status。Check the result is zero or not
bool check(Obj* obj)
{
int result = m_obj[0]->status+m_obj[1]->statusm_obj[2]->status
+m_obj[3]->status-m_obj[obj->id]->status;
return (result!=0);
}