I want to access the barcode variable from the addItemToStore method and change the string to be "" in the clearPressed method, but I am having trouble figuring out how to call the variable from the method.
class SelfCheckout {
var numList = List[String]()
var numEnter: String = ""
var clearBarcode: String = ""
def addItemToStore(barcode: String, item: Item): Unit = {
}
def numberPressed(number: Int): Unit = {
numList = numList :+ number.toString
}
def clearPressed(): Unit = {
numList = List()
}
You can use the = operator to assign something to a variable. What you are trying to do is achieved in the following code:
class SelfCheckout {
var numList = List[String]()
var numEnter: String = ""
var clearBarcode: String = ""
def addItemToStore(barcode: String, item: Item): Unit = {
clearBarcode = barcode // HERE...
}
def numberPressed(number: Int): Unit = {
numList = numList :+ number.toString
}
def clearPressed(): Unit = {
numList = List()
clearBarcode = "" // ..AND HERE
}
}
The following tests pass, giving you confidence that the changes have the effect you were looking for:
val checkout = new SelfCheckout
assert(checkout.clearBarcode == "")
checkout.addItemToStore("some_barcode", item)
assert(checkout.clearBarcode == "some_barcode")
checkout.clearPressed()
assert(checkout.clearBarcode == "")
If you want to play around with this code, you can find it here on Scastie.
As a side note, someone in a comment mentioned that you may probably want to consider the idea of designing your object to be immutable. That's a very useful programming concept that enables you to more easily write code which is easy to test and run in parallel. Immutability is a very important concept in Scala, because many parts of its ecosystem (including its powerful Collection API) rely on the concept. You might want to read more about immutability on the Scala book here, but you'll find a lot of resources on the matter with a simple search.
Related
I want to return the name of the corresponding uop according to the ordinal number of the uop.
I have tried various methods without success. I feel that there is a problem with the type usage of chisel and scala.
After I've relearned scala and chisel's use of variables, I'm still not quite sure what to do.
object GetUopcStr
{
def apply(uopc: UInt) = {
val uopStr = VecInit("uopNOP","uopLD","uopSTA","uopSTD")
uopStr(uopc)
}
}
object GetUopcStr
{
def apply(uopc: UInt) = {
val uopStr = Seq("uopNOP","uopLD","uopSTA","uopSTD")
val multiVec = VecInit(for(string <- uopStr) yield string)
// or
// val multiVec = VecInit(strings)
multiVec(uopc)
}
}
object GetUopcStr
{
def apply(uopc: UInt) = {
val uopStr = Seq("uopNOP","uopLD","uopSTA","uopSTD")
uopStr(uopc)
}
}
Both methods above have errors. I guess the above is a function in scala syntax. I'm supposed to generate the circuit inside. So in the end it should be chisel's Vec type.
Below here the code snippet, where I want to avoid using the 'var'. Not sure if there is a good way to do that
var randomInt = Random.nextInt(100)
private def getRandomInt(createNew:Boolean):Int = {
if(createNew){
randomInt = Random.nextInt(100)
}
randomInt
}
Create an "infinite" Iterator of random numbers. Advance to the next() only when needed.
val randomInt = Iterator.continually(Random.nextInt(100)).buffered
private def getRandomInt(createNew:Boolean):Int = {
if (createNew) randomInt.next()
randomInt.head
}
The class below holds the current random value and provides a method to return an instance holding the next random value.
It only uses immutable values, although the Random.nextInt(...) function isn't pure, because it doesn't return the same result for the same input.
The class is a direct translation of your 3 requirements:
to retrieve the previously generated number.
to generate a new number.
avoid using the 'var'.
This shows the basic technique of returning a new immutable instance instead of mutating a variable, although I find the infinite iterator answer by jwvh to be a more elegant solution.
import scala.util.Random
// A random number generator that remembers its current value.
case class RandomInt(size: Int) {
val value = Random.nextInt(size)
def nextRandomInt(): RandomInt = RandomInt(size)
}
// Test case
object RandomInt {
def main(args: Array[String]): Unit = {
val r0 = RandomInt(100)
(0 to 99).foldLeft(r0)((r, i) => {
println(s"[$i] ${r.value}")
r.nextRandomInt()
})
}
}
Not sure what changes you are open too, you can simply just add a parameter
val randomInt = Random.nextInt(100)
private def getRandomInt(createNew:Boolean,previous:Int):Int = {
if(createNew) Random.nextInt(100) else previous
}
I have a function which constructs a map by reflection from an object literal (the purpose is to make porting some JavaScript code easier). The function works fine, but I have found a case in which the reflections lists variables from an enclosing scope between members:
def mapFromObject[T](m: Any): Map[String, T] = {
import scala.reflect.runtime.currentMirror
def listMembers(m: Any) = {
import scala.reflect.runtime.currentMirror
val anyMirror = currentMirror.reflect(m)
val items = for {
symbol <- currentMirror.classSymbol(m.getClass).toType.members
if symbol.isTerm && !symbol.isMethod && !symbol.isModule
} yield {
val field = anyMirror.reflectField(symbol.asTerm)
symbol.name.decodedName.toString
}
items
}
def convertLiteral() = {
val par_some = ""
val literal = new {
var item = new {}
var item2 = new {
var value = par_some
}
}
println(listMembers(literal))
}
convertLiteral()
}
I expect to get result item, item2, but I get par_some$1, item2, item instead.
Why is par_some$1 listed as a member of the class?
How can I check for such member, so that I can ignore it? I have tried various methods of Symbol, including isSynthetic and isImplementationArtifact, but nothing I have tried seems to be different from normal members.
Scastie repro: https://scastie.scala-lang.org/uiv4DBIERIKnZaiViZ0Aaw
I'm learning Scala and am making some Stack implementations as practice. I made this and there are some apparent issues.
class LinkedStack[T] extends Stack[T] {
var current: Node = null
var n: Int = 0
private class Node(e: T, prev: Node) {
val element: T = e
var previous: Node = prev
}
override def pop(): T = {
if (n == 0) {
throw new NoSuchElementException
}
val popNode: Node = current
current = current.previous
popNode.previous = null
n -= 1
popNode.element
}
override def peek(): T = {
if (n == 0) {
throw new NoSuchElementException
}
current.element
}
override def push(element: T): Unit = {
if (element == null) {
throw new NullPointerException
}
val newNode: Node = new Node(element, current)
current = newNode
n += 1
}
override def size(): Int = {
n
}
override def toString(): String = {
val builder = new StringBuilder("Stack top [")
var temp: Node = current
if (n == 0) {
builder.append("]")
return builder.toString()
}
while (temp.previous != null) {
builder.append(temp.element).append(", ")
temp = temp.previous
}
builder.append(temp.element).append("]")
builder.toString()
}
}
The trait includes all of the elements except toString. My main problem is that I'm using null pretty liberally. I know this shouldn't be done at all in Scala, and the line
var current: Node = null
in the constructor generates a compile error. How should I implement a constructor to create an empty stack? What's the best substitution for null?
Edit:
You may have noticed that the Node class should be rewritten as
private class Node(val element: T, var previous: Node) {}
I realized this after reading Rex Kerr's answer. I forgot that I was programming in Scala when I first wrote that.
There's nothing terribly wrong with using null as part of the internals for your class as long as those nulls never leak out and the logic is straightforward enough so you can be sure of that.
But if you want to not use null for practice, you have two choices. One is to use a built-in alternative: instead of Node use Option[Node] and use None for null. Given that your list is invariant, this is the easier way.
Second, you can replace Node with a hierarchy like so:
trait Node
class Elt(val element: T, val previous: Node) extends Node {}
object End extends Node
And then you use End wherever you use null now, and match on the Node any time you need to walk or do something, e.g.
def peek = current match {
case End => throw new NoSuchElementException
case Elt(e, _) => e
}
Of course this means each list has to create an extra object (End), and there are various other drawbacks, most of which can be gotten around to some extent. But for an exercise in avoiding null, you can ignore those complications.
i'm also scala learning my stack implementation ,it;s simple i used scala mutable array buffer
object Stack{
var stack=scala.collection.mutable.ArrayBuffer[Int]()
def isEmpty():Boolean={
if(stack.length==0) true
else false
}
def push(input:Int):Unit={
stack+=input
}
def size():Int={
stack.length
}
def pop():Int={
stack.remove(stack.length-1)
}
def peek()={
stack(stack.length-1)
}
}
Please find below a short example which puzzles me.
I must concede that I have some difficulties to manipulate existential types in Scala.
How should I solve the type mismatch line 56 ?
proposer is OK type _$1 while proposers is of type _$1 <: Individual
Thanks in advance,
Maxime.
class Individual(n: String) {
protected val name=n
var preferred: Individual = this
override def toString(): String=name
}
class Man(n: String) extends Individual(n) { }
class Woman(n: String) extends Individual(n) { }
class Marriage(m: Man, w: Woman){
private val man=m
private val woman=w
def this(w: Woman, m: Man) = this(m,w)
override def toString(): String = man+"--"+woman
}
class Matching(){
private var list: List[Marriage] = Nil
def add(m: Marriage): Unit = { list = m ::list }
override def toString(): String= {
var s: String = ""
for (elm<-list) s=s+elm+" "
return s
}
}
object Test{
protected var male = true
def main(args: Array[String]): Unit = {
val al = new Man("Al")
val bob = new Man("Bob")
val alice = new Woman("Alice")
val barbara = new Woman("Barbara")
al.preferred = alice
bob.preferred = barbara
alice.preferred = bob
barbara.preferred = al
val men = Set(al, bob)
val women = Set(alice, barbara)
val m = new Matching()
//var proposers=women
var proposers: Set[_ <:Individual] = Set[Individual]()
if (male) proposers = men
else proposers = women
while (!proposers.isEmpty) {
for(proposer <- proposers) {
val proposer=proposers.head
if (proposer.isInstanceOf[Man])
m.add(new Marriage(
proposer.asInstanceOf[Man],
proposer.preferred.asInstanceOf[Woman]
))
else
m.add(new Marriage(
proposer.asInstanceOf[Woman],
proposer.preferred.asInstanceOf[Man]
))
proposers-=proposer//There is an error here
}
}
println(m)
}
}
This code is messy. It's poorly formatted, it mixes tabs and spaces, and it uses mutability even in the most trivial of places where a functional solution requires little thought.
This code also won't scale internationally to countries where same-sex marriage is a possibility.
Working from the top down...
I suspect you'll never want to directly instantiate an Individual, only ever a Man or a Woman. So a algebraic data type makes more sense, this is done with a sealed trait and case class subtypes.
I'll also drop the preferred property, as it can lead to circular references. Dealing with this in immutable data is beyond the level I'm willing to go in this answer.
sealed trait Individual {
def name: String
override def toString(): String=name
}
//as it's a case class, `name` becomes a val,
//which implements the abstract `def name` from the trait
case class Man(name: String) extends Individual
case class Woman(name: String) extends Individual
Marriage can also be a case class, and let's drop the clumsy duplication of class parameters into vals - it's just pointless boilerplate. This is also a good time to move the auxiliary constructor to a factory method in the companion object:
case class Marriage(man: Man, woman: Woman) {
override def toString(): String = man + "--" + woman
}
object Marriage {
def apply(w: Woman, m: Man) = new Marriage(m,w)
}
Matching is almost pointless, an entire class just to wrap a List? This kind of thing made sense in pre-Generics Java, but not any more. I'll keep it anyway (for now) so I can fix up that toString implementation, which is painfully mutable and uses return for no good reason:
case class Matching(){
private var list: List[Marriage] = Nil
def add(m: Marriage): Unit = { list ::= m }
override def toString() = list.mkString(" ")
}
Finally, the "meat" of the problem. Comments are inline, but you'll note that I don't need (or use) Matching. It's replaced in its entirety by the final println
object Test{
//better name, and a val (because it never changes)
protected val menPropose = true
def main(args: Array[String]): Unit = {
// `new` not required for case classes
val al = Man("Al")
val bob = Man("Bob")
val alice = Woman("Alice")
val barbara = Woman("Barbara")
// remember how preference was removed from `Individual`?
val mprefs = Map( al -> alice, bob -> barbara )
val fprefs = Map( alice -> bob, barbara -> al )
val men = Set(al, bob)
val women = Set(alice, barbara)
// nicely immutable, and using the returned value from if/else
val proposers = if (menPropose) men else women
// no while loop, name shadowing, or mutability.
// just a simple for-comprehension
val marriages = for(proposer <- proposers) yield {
//pattern-matching beats `isInstanceOf`... every time
proposer match {
case m: Man => Marriage(m, mprefs(m))
case f: Woman => Marriage(f, fprefs(f))
}
}
println(marriages mkString " ")
}
}
There's more that can be done here, way more. What of same-sex relationships? What if two or more people share the same preference? What if someone has no preference?
I could also encode the type of someone's preference into Individual instances. But that's getting a bit more advanced.