I got some troubles making a method that transfer money from object to another
which is mainly was to make a class that simulates a tester class that do the following
public class BankAccountTest
{
public void main()
{
// Create an account with an opening balance of 5000 AED for Mr. Said
BankAccount acc1 = new BankAccount("Said", 5000);
acc1.withdraw(1000);
acc1.printAccountInfo(); // Should display on the screen: "Said's blanace is 4000"
// Create an accoutn with an initial balance of ZERO for Mr. Shady
BankAccount acc2 = new BankAccount("Shady");
acc2.deposit(2000);
// Transfer 3000 from acc2 to acc1. If successful, the method returns 0, otherwise -1
int code = acc2.transfer(acc1, 3000);
if(code !=0) {
System.out.println("Insufficient Fund!");
}
System.our.println(acc1.balance() );
System.our.println(acc2.balance() );
}
}
So here is my code
public class BankAccount
{
public int balance;
private int deposite;
private int withdraw;
private String name;
public BankAccount(String name)
{ balance = 5000;
}
public BankAccount(String nameName, int balance)
{
name = nameName;
this.balance = balance;
deposite = 0;
withdraw = 0;
}
public void DepostieMoney (int deposite)
{ this.balance = balance + deposite;}
public void WithdrawMoney(int withdraw)
{ this.balance = balance - withdraw;
}
public void printAccountInfo()
{
System.out.println(this.name + "'s balance is " + balance);
}
public void TransferMoney(BankAccount that , int balance)
{ this.balance= this.balance - balance;
}
}
what I couldn't able to figure is how to make the following method transfer the items of the first object to the second object
public void TransferMoney(BankAccount that , int balance)
{ this.balance= this.balance - balance;
So how actually I can specify methods for specific object ?.
edited withdrawMoney method
public void withdrawMoney(int balance)
{if ( balance <= this.balance)
this.balance = this.balance - balance;
else
{System.out.println("insfufficient funds");}
}
First of all, the Java coding style suggests:
Methods should be verbs, in mixed case with the first letter
lowercase, with the first letter of each internal word capitalized (e.g run(); runFast(); getBackground(); )
Now, for you question, you're trying to transfer the money from the one account to the other, so the method called on one object should call the second object in order to complete the transaction.
public void transferMoney(BankAccount that , int balance)
{
//sanity check here
if (this == that || that == null)
return;
If (withdrawMoney(balance)) {
that.depositeMoney(balance);
}
}
As you see I choose not to use the variables directly but through the methods. The reason is that the logic around the method could be more than simply updating the variable, for example you may want to print the action. This way you only need to update once the code in your method, the transferMoney method will remain the same.
Related
We have a scenario like delivery the new order and pickup the old order from same visit. For this scenario we have added pickCapacity and deliveryCapacity and also calculating accumulated capacity(weightUsedAtEndOfVisit) at end of visit in ArrivalTimeUpdatingVariableListener class.
This is working fine, But some times weightUsedAtEndOfVisit values are not getting updated in previous chain when visit change one chain to another.
TimeWindowedVisit
#PlanningEntity
public class TimeWindowedVisit{
protected Long dropWeight;
protected Long pickupWeight;
private Long weightUsedAtEndOfVisit;
#CustomShadowVariable(variableListenerRef = #PlanningVariableReference(variableName = "arrivalTime"))
public Long getWeightUsedAtEndOfVisit() {
return weightUsedAtEndOfVisit;
}
public void setWeightUsedAtEndOfVisit(Long weightUsedAtEndOfVisit) {
this.weightUsedAtEndOfVisit = weightUsedAtEndOfVisit;
}
}
ArrivalTimeUpdatingVariableListener
public class ArrivalTimeUpdatingVariableListener implements VariableListener<TimeWindowedPlanningVisit> {
#Override
public void afterEntityAdded(ScoreDirector scoreDirector, TimeWindowedPlanningVisit planningVisit) {
updateUsedCapacityAtVisit(scoreDirector, planningVisit);
}
#Override
public void afterVariableChanged(ScoreDirector scoreDirector, TimeWindowedPlanningVisit planningVisit) {
updateUsedCapacityAtVisit(scoreDirector, planningVisit);
}
...
protected void updateUsedCapacityAtVisit(ScoreDirector<?> scoreDirector, TimeWindowedPlanningVisit sourcePlanningVisit) {
TimeWindowedPlanningVisit shadowPlanningVisit;
if (sourcePlanningVisit.getPreviousStandstill() != null) {
shadowPlanningVisit = sourcePlanningVisit;
while (shadowPlanningVisit != null) {
if (shadowPlanningVisit.getPreviousStandstill() instanceof TimeWindowedPlanningVisit) {
shadowPlanningVisit = (TimeWindowedPlanningVisit) shadowPlanningVisit.getPreviousStandstill();
} else {
break;
}
}
//calculate the first stop in the chain, will be needed to get a running capacity total at each stop
//we broadcast the running total so that we can determine if we ever exceed vehicle capacity
TimeWindowedPlanningVisit firstVisit = shadowPlanningVisit;
// begin at the first stop and evaluate all of the stops to see what capacity we will be leaving the depot with
// the capacity will be a sum of all the items that need to be dropped (delivered) at the location.
long runningCapacity = 0;
while (shadowPlanningVisit != null) {
if (shadowPlanningVisit.isWarehousePickup()) {
runningCapacity += shadowPlanningVisit.getDropWeight();
}
shadowPlanningVisit = shadowPlanningVisit.getNextPlanningVisit();
}
shadowPlanningVisit = firstVisit;
// now that we know the full capcity we will be leaving the depot with, calculate the capacity at each
// stop, accounting for capacity being dropped (delivered) and picked up (returned) along the way
while (shadowPlanningVisit != null) {
runningCapacity -= shadowPlanningVisit.getDropWeight();
runningCapacity += shadowPlanningVisit.getPickupWeight();
if (!Objects.equals(runningCapacity, shadowPlanningVisit.getWeightUsedAtEndOfVisit())) {
scoreDirector.beforeVariableChanged(shadowPlanningVisit, "weightUsedAtEndOfVisit");
shadowPlanningVisit.setWeightUsedAtEndOfVisit(runningCapacity);
scoreDirector.afterVariableChanged(shadowPlanningVisit, "weightUsedAtEndOfVisit");
}
shadowPlanningVisit = shadowPlanningVisit.getNextPlanningVisit();
}
}
}
}
Constraint Class
protected Constraint vehicleCapacityStopLevel(ConstraintFactory factory) {
System.out.println("vehicleCapacityStopLevel...");
return factory.from(TimeWindowedPlanningVisit.class)
.filter(visit -> visit.getWeightUsedAtEndOfVisit() > visit.getVehicle().getWeight())
.penalizeLong("vehicle capacity exceeded at stop",
BendableLongScore.ofHard(2, 1, 0, 1),
visit -> visit.getWeightUsedAtEndOfVisit() - visit.getVehicle().getWeight());
}
Your #CustomShadowVariable should have a sources field, and not a variableListenerRef value. The latter is to piggy-back on another custom shadow variable's variable listener.
This is also an issue in optaplanner, because a variableListenerRef should fail fast if it doesn't lead to a custom shadow variable. We'll confirm and fix that.
This is my first Solidity project.
I'm trying to create a kind of supply chain, more than anything just practice code.
I came across a problem that I couldn't solve or find the solution online.
Problem: I want to get the user ID and save it in each function so it would look like...
function Customer() public {
checked = Process.Received;
status = Process.NotPaid;
//userid = Process.< THE ID >
}
I tried with this ...
function getStruct() public
view
returns (string, uint)
{
return (User);
}
But keeps on asking me to have the data located in memory. Which I tried but won't work for me.
Full code:
pragma solidity ^0.5.1;
contract SupplyChain {
enum Process {
Unknown,
Checked,
Received,
Paid,
NotPaid
}
Process public status;
Process public checked;
Process public userid;
address user;
struct User {
uint _id;
string _firstName;
string _lastName;
}
constructor() public {
status = Process.Unknown;
user = tx.origin;
}
function addUser(
uint256 id,
string memory _firstName,
string memory _lastName
) public{
}
// NOT FINISHED NEED TO RETURN USER ID TO PRINT IN TRACKERS.
function getStruct() public
view
returns (string, uint)
{
return (User);
}
function Factory() public {
checked = Process.Checked;
status = Process.NotPaid;
// print userid
}
function TransportOne() public {
checked = Process.Checked;
status = Process.NotPaid;
// print userid
}
function Deposit() public {
checked = Process.Checked;
status = Process.NotPaid;
// print userid
}
function TransportTwo() public {
checked = Process.Checked;
status = Process.NotPaid;
// print userid
}
function Customer() public {
checked = Process.Received;
status = Process.NotPaid;
// print userid
}
}
There is no print in solidity, you can try to use events for logging.
If you just want to debug, you can try Remix IDE.
I am having troubles incrementing the value of my instance variables. I tried making a method so that for every pet I buy, it will add that much to how many I already have. But when I print dogs variable, it says 0 even though I added 2. I'd appreciate any help. Thanks!
public class myStuff
static int dogs;
static int cats;
public static void main(String[] args) {
myStuff.buy(dogs, 2);
System.out.println(dogs);
}
public static void buy(int pet, int howMany) {
pet = pet + howMany;
}
}
you cant do that in java, since it is pass-by-value
In Java, method parameters are passed by value (which means the value of dogsin your case is passed in the first Place, but never touched). Objects however, are manipulated by reference. So, if you want to increase the number of pets, you could use a class Pet with a value count
public class Pet {
private int count;
public Pet(int count) {
this.count = count;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
If you then pass an instance of Pet to your buy function and increase the count via setCount, the value will be saved.
I wrote a static class that auto-increments the id of a RealmObject by 1.
public class AutoIncrementKey {
public static int Next(Class<? extends RealmObject> c)
{
Realm realm = Realm.getDefaultInstance();
Number maxId = realm.where(c).max("id");
realm.close();
if(maxId == null)
{ // no object exists, so return 0
return 0;
}
return maxId.intValue() + 1;
}
}
However, when I set the default value of a RealmObject's ID like so:
#PrimaryKey private int id = AutoIncrementKey.Next(PresetSelect.class);
It never works! Specifically the first time it goes to create a new class via realm.createObject(IExtendRealmObject.class) the value is 0, but AutoIncrementKey.Next(...) returns the id as 1!
So id is never set to 1. It's always 0, and trying to create more objects causes it to throw an error "index already exists: 0"
What gives?
The AutoIncrementKey.Next() function IS being called. It IS finding the next key to be 1. The value returned simply isn't carried through though.
Edit:
So now that I've managed to create more than one object in my Realm, I'm finding that setting the id to a default value isn't the only issue.
Setting ANY member of a class extending RealmObject with a default value is IGNORED. Whats the deal with that?
That's because instead of
realm.createObject(IExtendRealmObject.class)
You're supposed to use
realm.createObject(IExtendRealmObject.class, primaryKeyValue)
But I think your method
public class AutoIncrementKey {
public static int Next(Class<? extends RealmObject> c)
{
Realm realm = Realm.getDefaultInstance();
Number maxId = realm.where(c).max("id");
realm.close();
if(maxId == null)
{ // no object exists, so return 0
return 0;
}
return maxId.intValue() + 1;
}
}
Would be more stable as
public class AutoIncrementKey {
public static int Next(Realm realm, Class<? extends RealmModel> c)
{
Number maxId = realm.where(c).max("id");
if(maxId == null)
{ // no object exists, so return 0
return 0;
}
return maxId.intValue() + 1; // why not long?
}
}
If you meet the condition that when you call AutoIncrementKey.Next(realm, Some.class), then a write transaction is in progress.
Hell, you might even add
public class AutoIncrementKey {
public static int Next(Realm realm, Class<? extends RealmModel> c)
{
if(!realm.isInTransaction()) {
throw new IllegalStateException("Realm is not in a transaction.");
}
// continue as mentioned
It should work well for your needs
I tried it in HZ 3.4 and 3.4.1 but with the same output
I`m trying to import dummy data to my Hazelcast cluster, with following function
HazelcastInstance cluster = HazelcastClient.newHazelcastClient(this.conf);
Map<String, Customer> mapCustomers = cluster.getMap("customers");
System.out.println(mapCustomers.size());
System.out.println("hello world");
for (int customerID = 0; customerID < 2000; customerID++) {
Customer p = new Customer();
mapCustomers.put(Integer.toString(customerID), p);
System.out.println("inserted customer number " + Integer.toString(customerID));
}
cluster.shutdown();
when I first run this code, there are no issues and the output is something like this
0
hello world
inserted customer number 0
inserted customer number 1
inserted customer number 2
inserted customer number 3
the problem is if I try to run the import function if there are data already - everytime I got
4
hello world
Exception in thread "main"
com.hazelcast.nio.serialization.HazelcastSerializationException: No DataSerializerFactory registered for namespace: 1
at com.hazelcast.nio.serialization.DataSerializer.read(DataSerializer.java:98)
at com.hazelcast.nio.serialization.DataSerializer.read(DataSerializer.java:39)
at com.hazelcast.nio.serialization.StreamSerializerAdapter.toObject(StreamSerializerAdapter.java:65)
at com.hazelcast.nio.serialization.SerializationServiceImpl.toObject(SerializationServiceImpl.java:260)
at com.hazelcast.client.spi.ClientProxy.toObject(ClientProxy.java:173)
at com.hazelcast.client.spi.ClientProxy.invoke(ClientProxy.java:128)
at com.hazelcast.client.proxy.ClientMapProxy.put(ClientMapProxy.java:352)
at com.hazelcast.client.proxy.ClientMapProxy.put(ClientMapProxy.java:200)
at com.test.queries.Importer.importDummyData(Importer.java:42)
at run_import.main(run_import.java:9)
I am using DataSerializableFactory
public class SerializerFactory implements DataSerializableFactory {
public static final int FACTORY_ID = 1;
public static final int CUSTOMER_TYPE = 1;
public static final int ORDER_TYPE = 2;
#Override
public IdentifiedDataSerializable create(int typeId) {
switch (typeId) {
case CUSTOMER_TYPE:
return new Customer();
case ORDER_TYPE:
return new Order();
}
return null;
}
}
public class Customer implements IdentifiedDataSerializable {
....
#Override
public int getFactoryId() {
return SerializerFactory.FACTORY_ID;
}
#Override
public int getId() {
return SerializerFactory.CUSTOMER_TYPE;
}
....
}
and my xml config:
....
<serialization>
<data-serializable-factories>
<data-serializable-factory factory-id="1">
SerializerFactory
</data-serializable-factory>
</data-serializable-factories>
<portable-version>0</portable-version>
</serialization>
....
You have to configure the DataSerializableFactory on both ends, servers and clients. That also means the code needs to be available at both positions :)