programing advice for a class example - java

i am a basic programing student and i need help on how to make a particular program.
The scenario is: people go in and out of an event and i need to keep track of them. the limit of people allowed is 100. People can come alone or en masse. As people go in and out the total should change. people should be denied access after limit is reached.
everything will be going into JOptionPane.
not sure if im looking at the best site for help but, any advice would help.
i know i will make a while loop for this.
import javax.swing.JOptionPane;
public class HwTwoPt2 {
public static void main(String[] args) {
int enter, exit, total;
int maxCapacity = 106;
int count = 0;
int groupAmt = 0;
while(count != maxCapacity){
groupAmt = Integer.parseInt(JOptionPane.showInputDialog("Enter total amount in the group: "));
}
}
}

If you're wanting to deny people access once a limit has been hit you'll want to change your while loop to something like:
while(count < maxCapacity)
If you go with != maxCapacity, a value of 107 would pass and allow people entry.
You will also want to verify groupAmt before adding it to maxCapacity.
if((count + groupAmt) < maxCapacity)
{
count += groupAmt;
}

I'd advise you to encapsulate all this into an object. Java's an object-oriented language. Better to get used to thinking in terms of encapsulation and information hiding early.
Something like this:
public class CapacityTracker {
private static final int DEFAULT_MAX_CAPACITY = 100;
private int currentCapacity;
private int maxCapacity;
public CapacityTracker() {
this(DEFAULT_MAX_CAPACITY);
}
public CapacityTracker(int maxCapacity) {
this.maxCapacity = ((maxCapacity <= 0) ? DEFAULT_MAX_CAPACITY : maxCapacity);
this.currentCapacity = 0;
}
public int getCurrentCapacity() { return this.currentCapacity; }
public void addAttendees(int x) {
if (x > 0) {
if ((this.currentCapacity+x) > this.maxCapacity) {
throw new IllegalArgumentException("max capacity exceeded");
} else {
this.currentCapacity += x;
}
}
}
}
I'd keep adding methods to make this more convenient for me to use.
I might create a custom CapacityExceededException as well.

Related

Is it possible to do 2 actions with ternary operator In java

I am trying to make each number 7 to turn into a letter as well. ex:57 75 157
Right now it gives me the word that divided by 7
public class Boomtest {
public static int boom () {
int boom2 = 0;
String boom7 = "Boombala";{
for (boom2 = 0; boom2 <= 200; ++boom2) {
String print = boom2 % 7 == 0 ? boom7 : Integer.toString(boom2);
}
}
return boom2;
}
}
Is it possible to do it in ternary?
how can I run it without the String print, it feels like I am missing something.
I know that there are other answers that say NO, like this one: Multiple Statements in the Ternary Operator but you can use your imagination to do it, for example you can create methods that make the actions, something like this
public static int boom(){
...
int numberToDelete = (/*conditional here*/)?actions01():actions02();
...
}
public static int actions01(){
/*Multiple actions here*/
return 0;
}
public static int actions02(){
/*Multiple actions here*/
return 0;
}
Anyway I don't recommend you to do that.
PS: Try to correct your identation

Java – repeating a method from user-input

I want to write a program that keeps track of how many times a bus is late.
So the user is asked to enter an int value, indicating how many minutes late.
Once a negative int is entered, the program should stop.
What I’m having trouble with is making the program repeat only for inputs of 0 or more.
The program repeats regardless of what int is inputted.
I did something like below:
import java.util.Scanner;
public class LateBus {
public static void main(String[] args) {
int enter_minutes = enterMinutes();
loop(enter_minutes);
}
public static int enterMinutes() {
Scanner enter = new Scanner(System.in);
System.out.print("How many minutes late was the bus? ");
int late = enter.nextInt();
return late;
}
public static void loop(int a) {
while (a >= 0) {
enterMinutes();
}
}
}
Let's look at this function:
public static void loop(int a) {
while (a >= 0) {
enterMinutes();
}
}
The value of a never changes. a >= 0 will always be true or never be true depending on the initial value for a. Since a is used internally to this function, you should not pass it in as a parameter. And you should be sure to change it:
public static void loop() {
int a = enterMinutes();
while (a >= 0) {
a = enterMinutes();
}
}
Now you call the function like this:
public static void main(String[] args) {
loop();
}
Note:
Everyone makes logic mistakes in their code as they write it. To find them, you need to learn how to debug. I suggest that you read https://ericlippert.com/2014/03/05/how-to-debug-small-programs/ for some tips on how to debug your code so that you can find these kinds of problems on your own.
The while loop will stop when a is negative, but you do not change its value.
Do it like this
while (a >= 0) {
a = enterMinutes();
}
now the value changes to what the user inputs.

Is it possible to reasonably emulate yield-syntax, perhaps with help of Java 8?

I was experimenting with this question today, from Euler Problems:
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.
Find the largest palindrome made from the product of two 3-digit numbers.
I thought about it and it can of course be done with for-loops, however I want to use Java 8 as it opens up new options.
However first of all, I do not know how to generate an IntStream that produces such elements, so I still ended up using normal for-loops:
public class Problem4 extends Problem<Integer> {
private final int digitsCount;
private int min;
private int max;
public Problem4(final int digitsCount) {
this.digitsCount = digitsCount;
}
#Override
public void run() {
List<Integer> list = new ArrayList<>();
min = (int)Math.pow(10, digitsCount - 1);
max = min * 10;
for (int i = min; i < max; i++) {
for (int j = min; j < max; j++) {
int sum = i * j;
if (isPalindrome(sum)) {
list.add(sum);
}
}
}
result = list.stream().mapToInt(i -> i).max().getAsInt();
}
private boolean isPalindrome(final int number) {
String numberString = String.valueOf(number);
String reversed = new StringBuilder(numberString).reverse().toString();
return (numberString.equals(reversed));
}
#Override
public String getName() {
return "Problem 4";
}
}
As you can see I might be a bit lazy, bit really the IntStream::max is a very nice method and I think it is better to use that, as to write it yourself.
Here comes the issue though, I need to have a list now to be able to obtain the maximum in this manner, which means I need to store data, where I really should not do so.
So, the question now, would it be possible to implement this in Java 8?
for (int i = min; i < max; i++) {
for (int j = min; j < max; j++) {
yield i * j;
}
}
And then out of that method create an PrimitiveIterator.OfInt (unboxes version of Iterator<Integer>, or create an IntStream directly?
Then getting the answer with streamFromYield.filter(this::isPalindrome).max().getAsInt() would be really easy to implement.
Lastly, I know this question has been asked before, however the last time is already quite a bit ago and now Java 8 is going to happen very soon, where they have added as big concept Stream<T> and the new language construct, called lambdas.
So making such code may be very different now than when people were making it for Java 6 or 7.
Well, I think we've gotten carried away using the Streams API from the "outside," using flatMap, optimizing the palindrome-finding algorithm, etc. See answers from Boris the Spider and assylias. However, we've sidestepped the original question of how to write a generator function using something like Python's yield statement. (I think the OP's nested-for example with yield was using Python.)
One of the problems with using flatMap is that parallel splitting can only occur on the outermost stream. The inner streams (returned from flatMap) are processed sequentially. We could try to make the inner streams also parallel, but they'd possibly compete with the outer ones. I suppose nested splitting could work, but I'm not too confident.
One approach is to use the Stream.generate or (like assylias' answer) the Stream.iterate functions. These create infinite streams, though, so an external limit must be supplied to terminate the stream.
It would be nice if we could create a finite but "flattened" stream so that the entire stream of values is subject to splitting. Unfortunately creating a stream is not nearly as convenient as Python's generator functions. It can be done without too much trouble, though. Here's an example that uses the StreamSupport and AbstractSpliterator classes:
class Generator extends Spliterators.AbstractIntSpliterator {
final int min;
final int max;
int i;
int j;
public Generator(int min, int max) {
super((max - min) * (max - min), 0);
this.min = min;
this.max = max;
i = min;
j = min;
}
public boolean tryAdvance(IntConsumer ic) {
if (i == max) {
return false;
}
ic.accept(i * j);
j++;
if (j == max) {
i++;
j = min;
}
return true;
}
}
public static void main(String[] args) {
Generator gen = new Generator(100, 1000);
System.out.println(
StreamSupport.intStream(gen, false)
.filter(i -> isPalindrome(i))
.max()
.getAsInt());
}
Instead of having the iteration variables be on the stack (as in the nested-for with yield approach) we have to make them fields of an object and have the tryAdvance increment them until the iteration is complete. Now, this is the simplest form of a spliterator and it doesn't necessarily parallelize well. With additional work one could implement the trySplit method to do better splitting, which in turn would enable better parallelism.
The forEachRemaining method could be overridden, and it would look almost like the nested-for-loop-with-yield example, calling the IntConsumer instead of yield. Unfortunately tryAdvance is abstract and therefore must be implemented, so it's still necessary to have the iteration variables be fields of an object.
How about looking at it from another direction:
You want a Stream of [100,1000), and for each element of that Stream you want another Stream of that element multiplied by each of [100, 1000). This is what flatMap is for:
public static void main(final String[] args) throws Exception {
OptionalInt max = IntStream.range(100, 1000).
flatMap((i) -> IntStream.range(i, 1000).map((j) -> i * j)).
unordered().
parallel().
filter((i) -> {
String forward = Integer.toString(i);
String backward = new StringBuilder(forward).reverse().toString();
return forward.equals(backward);
}).
max();
System.out.println(max);
}
Not sure if getting a String and then the reverse is the most efficient way to detect palindromes, off the top of my head this would seem to be faster:
final String asString = Integer.toString(i);
for (int j = 0, k = asString.length() - 1; j < k; j++, k--) {
if (asString.charAt(j) != asString.charAt(k)) {
return false;
}
}
return true;
It gives the same answer but I haven't put it under an rigorous testing... Seems to be about 100ms faster on my machine.
Also not sure this problem is big enough for unordered().parallel() - removing that gives a little boost to speed too.
Was just trying to demonstrate the capabilities of the Stream API.
EDIT
As #Stuart points out in the comments, as multiplication is commutative, we only need to IntStream.range(i, 1000) in the sub-stream. This is because once we check a x b we don't need to check b x a. I have updated the answer.
There always have been ways to emulate that overrated yield feature, even without Java 8. Basically it is about storing the state of an execution, i.e. the stack frame(s), which can be done by a thread. A very simple implementation could look like this:
import java.util.Iterator;
import java.util.NoSuchElementException;
public abstract class Yield<E> implements Iterable<E> {
protected interface Flow<T> { void yield(T item); }
private final class State implements Runnable, Iterator<E>, Flow<E> {
private E nextValue;
private boolean finished, value;
public synchronized boolean hasNext() {
while(!(value|finished)) try { wait(); } catch(InterruptedException ex){}
return value;
}
public synchronized E next() {
while(!(value|finished)) try { wait(); } catch(InterruptedException ex){}
if(!value) throw new NoSuchElementException();
final E next = nextValue;
value=false;
notify();
return next;
}
public void remove() { throw new UnsupportedOperationException(); }
public void run() {
try { produce(this); }
finally {
synchronized(this) {
finished=true;
notify();
}
}
}
public synchronized void yield(E next) {
while(value) try { wait(); } catch(InterruptedException ex){}
nextValue=next;
value=true;
notify();
}
}
protected abstract void produce(Flow<E> f);
public Iterator<E> iterator() {
final State state = new State();
new Thread(state).start();
return state;
}
}
Once you have such a helper class, the use case will look straight-forward:
// implement a logic the yield-style
Iterable<Integer> y=new Yield<Integer>() {
protected void produce(Flow<Integer> f) {
for (int i = min; i < max; i++) {
for (int j = min; j < max; j++) {
f.yield(i * j);
}
}
}
};
// use the Iterable, e.g. in a for-each loop
int maxPalindrome=0;
for(int i:y) if(isPalindrome(i) && i>maxPalindrome) maxPalindrome=i;
System.out.println(maxPalindrome);
The previous code didn’t use any Java 8 features. But it will allow using them without the need for any change:
// the Java 8 way
StreamSupport.stream(y.spliterator(), false).filter(i->isPalindrome(i))
.max(Integer::compare).ifPresent(System.out::println);
Note that the Yield support class above is not the most efficient implementation and it doesn’t handle the case if an iteration is not completed but the Iterator abandoned. But it shows that such a logic is indeed possible to implement in Java (while the other answers convincingly show that such a yield logic is not necessary to solve such a problem).
I'll give it a go. Version with a loop then with a stream. Although I start from the other end so it's easier because I can limit(1).
public class Problem0004 {
public static void main(String[] args) {
int maxNumber = 999 * 999;
//with a loop
for (int i = maxNumber; i > 0; i--) {
if (isPalindrome(i) && has3DigitsFactors(i)) {
System.out.println(i);
break;
}
}
//with a stream
IntStream.iterate(maxNumber, i -> i - 1)
.parallel()
.filter(i -> isPalindrome(i) && has3DigitsFactors(i))
.limit(1)
.forEach(System.out::println);
}
private static boolean isPalindrome(int n) {
StringBuilder numbers = new StringBuilder(String.valueOf(n));
return numbers.toString().equals(numbers.reverse().toString());
}
private static boolean has3DigitsFactors(int n) {
for (int i = 999; i > 0; i--) {
if (n % i == 0 && n / i < 1000) {
return true;
}
}
return false;
}
}

How to tell if an int has been changed

I want to know how to tell if an int has been changed (during the program).
Like with an if statement.
int i = 2;
int a = 1;
while(1 < 2) {
if(i % 100 == 0) i++;
}
if(i //Then checks if it changed) {
System.out.println("Changed :D");
}
Is there a way to tell if the variable i is changed DURING the program?
Since this is Java, are these variables data members of a class? In that case give them private access and provide getters and setters. Your setter can notify you if you so desire.
int i = 0;
boolean valueChanged = false;
while(some good condition) {
if (i % 100 == 0) {
i++;
valueChanged = true;
}
}
if(valueChanged) {
System.out.println("Changed :D");
}
// Your int variable
int i = 0;
// A scratch variable
int prev_value_of_i = i;
// Call this code to check whether i has changed since last call
if(i != prev_value_of_i) {
System.out.println("Changed :D");
prev_value_of_i = i;
}
Keep track of the original value of i in a separate variable and compare i to that?
This seems redundant, since the programmer should know when and where values are stored. If you don't, maybe step through with a debugger? #shoover's answer is the most flexible, handling however many unexpected times you might change the value without requiring adding lines of code inside your infinite loop.
class TalkativeInt{
private int x;
TalkativeInteger(int x){
this.x = x;
}
public void set(int a){
System.out.println("Changed!! "+x+" to "+a);
x = a;
}
public int get(){
//System.out.println("Accessed - that tickles");
return x;
}
}

Recursively keeping count in Java - Simple

I know that I'm overlooking something incredibly fundamental and elementary, but I need help with creating a mean function that, using only one parameter (the list containing the integers- in this case), calculates the mean of the given integers.
public static double mean (Cons lst) {
int total = (Integer) lst.data;
int count = //something to keep count through the recursion
if(lst.next == null) {
return total / count;
}
else return mean(lst.next); // return statement isn't correct, need help here as well
}
Any help would be great. If the easiest way to explain is by writing the method itself, then that'd be wonderful, but I'm just trying to figure out how to recursively keep a running count without adding params.
Thanks a lot.
You are developing your recursive mean function as a method of a Java Class. Why don't you declare your count and total local variables as attributes of that class?
class Mean {
static int total = 0;
static int count = 0;
public static double mean (Cons lst) {
total += (Integer) lst.data;
count += 1;
if(lst.next == null) {
double ret = total/count;
total = 0;
count = 0;
return ret;
}
return mean(lst.next); // return statement isn't correct, need help here as well
}
}
Other option is to include "count" as a second parameter of your recursive method. If you don't want the user to pass more parameters use two methods: "mean" method, with one parameter (your list), should call the second method "recursiveMean(list, 0)" containing your implementation.
public static double mean (Cons lst) {
return recursiveMean (lst, 0, 0)
}
public static double recursiveMean (Cons lst, int count, int total) {
total += (Integer) lst.data;
count += 1;
if(lst.next == null) {
return total / count;
}
return mean(lst.next,count,total); // return statement isn't correct, need help here as well
}
Nevertheless, I don't see why you are implementing a mean function as a recursive function unless it is some kind of educational exercise.

Categories