UPDATE BELOW
I am currently in an introductory Swift course at my college and am struggling with functions. I thought I followed the instructions clearly, but I am getting a certain error about "use of an unresolved identifier."
This is the full error:
error: My Functions Playground 2 2.playground:23:8: error: use of unresolved identifier 'newGPA'
switch newGPA {
Here is my code (the original instructions are below):
var gpa: Int
var attemptedHours: Int
var earnedGradePoints: Int
// create your function here
func gpaUpdater(hours moreHours: Int, grade moreGPA: Int) {
let _: Int = attemptedHours + moreHours
let newGPA: Int = gpa + moreGPA
print(newGPA)
}
// call the function
gpaUpdater(hours: 16, grade: 60)
// add the new hours and grade points here and call the function again
switch newGPA {
case 0...1.8:
print("You will be placed on suspension")
case 1.8...2.0:
print("You will be placed on probation")
case 3.5...3.8:
print("You will be put on the dean's list.")
case 3.9:
print("You will be put on the president's list.")
default:
print("Carry on. Nothing to see here.")
}
Instructions:
We're going to track your GPA from one semester to the next. Assume at the end of your sophomore years, you have attempted 60 hours and have earned 222.5 grade points. Assign attempted hours and grade points to variables. Write a function that updates your current GPA and assigns it to the GPA var (you'll update it along the way). Label your function arguments. Print your new GPA from within the function.
At the end of the current semester, add 16 hours and 60 grade points to your record. Call the gpa function to update your overall gpa.
Test your gpa at the end of the year to see if any administrative action needs to be taken. If the gpa is less than 1.8, the student will need to be placed on suspension. If less than 2.0, we need to put the student on probation. If over 3.5, we'll put the student on the dean's list, and if over 3.9, we'll put the student on the president's list. Create a switch that prints the recommended adminstrative action. If no action is required, print, "Carry on. Nothing to see here." Create internal and external labels for your arguments.
Thank You for your help!
UPDATE
The function part of my Swift code is now correct, thank you all for the help. Now I am trying to fix my switch statement. Here is my code:
// add the new hours and grade points here and call the function again
switch gpa {
case gpa > 1.8:
print("You will be placed on suspension")
case 1.8...2.0:
print("You will be placed on probation")
case 3.5...3.8:
print("You will be put on the dean's list.")
case gpa > 3.9:
print("You will be put on the president's list.")
default:
print("Carry on. Nothing to see here.")
}
The problem, I think, is that my teacher wants GPA to be an int, but if I want to use values like 1.9 for the gpa, then it needs to be a double. Here is an error that I am getting:
error: My Functions Playground 2 2.playground:26:10: error: binary operator '>' cannot be applied to operands of type 'Int' and 'Double'
case gpa > 1.8
Scope. Scope. Scope.
newGPA is declared locally in the scope of gpaUpdater. It's not visible on the top level.
You could do
// create your function here
func gpaUpdater(hours moreHours: Int, grade moreGPA: Int) -> Int {
// let _: Int = attemptedHours + moreHours
return gpa + moreGPA
}
// call the function
let newGPA = gpaUpdater(hours: 16, grade: 60)
// add the new hours and grade points here and call the function again
switch newGPA { ...
No comment about the (unused) first parameter of gpaUpdater and the floating point cases switching over an Int 😉
I'm going to answer this from an assignment perspective; the other answers regarding returning the local variable value are correct for accessing your newGPA variable.
You missed the point in the assignment by creating the "newGPA" variable. The assignment states to "update" the global gpa variable with the new value from within the function.
If this is introductory coding, you may not have come across the concept of recursion. This is basically assigning some value by including itself in the calculation.
Instead of
let newGPA: Int = gpa + moreGPA
print(newGPA)
think
gpa = gpa + moreGPA
print(gpa)
which can also be written as
gpa += moreGPA
and then use gpa in your switch function.
What this does is updates your global gpa variable to a new value (by adding the moreGPA to it). This is one of the main strengths of a global variable. It can be accessed and modified from anywhere in your program.
That's my understanding based on the assignment instructions. That said, returning a value from a function is cleaner (in my opinion) since global variables can become conflicts in more complicated programs.
Related
I'm creating a math app and am trying to assign the correct answer to a variable. I've tried these two options below
#State private var correctAnswer1: Int {
number1L1 + number2L1
}
With this, I receive the error "Property wrapper cannot be applied to a computed property".
if currentLevel == 1
{
Text(" \(number1L1)")
.font(.system(size:70))
Text("+ \(number2L1)")
.font(.system(size:70))
Text("____")
.font(.system(size:70))
correctAnswer = number1L1 + number2L1
}
With this I receive the error "Type () cannot conform to 'View'"
How do I assign this variable without running into an error?
You really have two questions here. In the first case you have a property that is a computed property.
private var correctAnswer1: Int {
number1L1 + number2L1
}
Says that every time you ask for yourObject.correctAnswer1 the system should compute its value by running the code in the block.
Something a property that is attributed with #State, in contrast, is a box that holds a single value. You don't have a single value, you have a mechanism for computing a value. The compiler complains.
I the second case, you're laying out a View.
When you are working inside the body block of a SwiftUI View you are in a special environment called a ViewBuilder. Within that environment, each expression is expected to return some kind of View. The compiler collects them in a special way and will combine them together to make a user interface. (The environment also allows you some control-flow structures like if statements that are treated specially. If you are really curious you can search the web for information about Swift Result Builders)
In your case, you've included an expression that doesn't return a View in a place where Swift expects each expression to return one and Swift complains.
This class example was taken from here.
class Celsius:
def __init__(self, temperature = 0):
self.temperature = temperature
def to_fahrenheit(self):
return (self.temperature * 1.8) + 32
def get_temperature(self):
print("Getting value")
return self._temperature
def set_temperature(self, value):
if value < -273:
raise ValueError("Temperature below -273 is not possible")
print("Setting value")
self._temperature = value
temperature = property(get_temperature, set_temperature)
The idea here is that when we create an instance of Celsius and set the temperature attribute (e.g. foo = Celsus (-1000) ), we want to make sure that the attribute is not less than -273 BEFORE setting the temperature attribute.
I don't understand how it seems to bypass self.temperature = temperature and go straight to the last line. It seems to me like there are three attributes/properties created here: the Class attribute, temperature; the Instance attribute, temperature; and the set_temperature function which sets the attribute _temperature.
What I DO understand is that the last line (the assignment statement) must run the code property(get_temperature, set_temperature) which runs the functions get_temperature and set_temperature and intern sets the private attribute/property _temperature.
Moreover, if I run: foo = Celsius(100) and then foo.temperature, how is the result of foo.temperature coming from temperature = property(get_temperature, set_temperature) and thus _temperature AND NOT self.temperature = temperature? Why even have self.temperature = temperature if temperature = property(get_temperature, set_temperature) gets ran every time the foo.temperature call is made?
More questions...
Why do we have two attributes with the same name (e.g. temperature) and how does the code know to retrieve the value of _temperature when foo.temperature is called?
Why do we need private attributes/properties an not just temperature?
How does set_temperature(self, value) obtain the attribute for parameter value (e.g. the argument that replaces value)?
In short, please explain this to me like a three year old since I have only been programming a few months. Thank you in advance!
When we are first taught about classes/objects/attributes we are often told something like this:
When you look up an attribute like x.foo it first looks to see if
'foo' is an instance variable and returns it, if not it checks if
'foo' is defined in the class of x and returns that, otherwise an
AttributeError is raised.
This describes what happens most of the time but does not leave room for descriptors. So if you currently think the above is all there is about attribute lookup property and other descriptors will seem like an exception to these rules.
A descriptor basically defines what to do when looking up / setting an attribute of some instance, property is an implementation that lets you define your own functions to call when getting / setting / deleting an attribute.
When you do temperature = property(get_temperature, set_temperature) you are specifying that when x.temperature is retrieved it should call x.get_temperature() and the return value of that call will be what x.temperature evaluates to.
by specifying set_temperature as the setter of the property it states that when ever x.temperature is assigned to something it should call set_temperature with the value assigned as an argument.
I'd recommend you try stepping through your code in pythontutor, it will show you exactly when get_temerature and set_temperature are called after which statements.
I've searched on Stack Overflow and of course Google and nothing has come up (which surprises me).
I have an integer variable which constantly changes, and I want to run a certain function when the variable goes past a certain number. Infinite while loops will obviously just slow the phone down and possibly crash.
This variable is the acceleration variable from CMMotionManager, which gives the accelerometer data when displayed/printed. It is NOT a variable set by me.
For example:
if Example > 2 { // Example being the integer variable from another module
// do stuff here
}
Edit: No, waiting a few seconds and then checking again will NOT work in my situation.
Edit2: It is not a variable set by me, but a variable from another module.
Have you checked willSet and didSet options?
var _test : Int = 0 {
//First this
willSet {
println("Old value is \(_test), new value is \(newValue)")
}
//value is set
//Finaly this
didSet {
println("Old value is \(oldValue), new value is \(_test)")
}
}
More details here.
I'm fairly new to lua and have the following problem with an assignment from a class:
We currently extend lua to support objects and inheritance. The Syntax for that is
Class{'MyClass',
attribute1 = String,
attribute2 = Number
}
Class{'MySubClass', MyClass,
attribute3 = Number
}
This works perfectly fine. The real problem lies within the next task: We should support "recursive types", that means a call like
Class{'MyClass', attribute = MyClass}
should result in an class with a field of the same type as the class. When this "class-constructor" is called the variable MyClass is nil, thats why the parameter table doesnt't have an entry attribute. How is it possible to access this attribute?
My first thought was using some kind of nil-table which gets returned every time the global __index is called with an unset key. This nil-table should behave like the normal nil, but can be checked for in the "class-constructor". The problem with this approach are comparisons like nil == unknown. This should return true, but as the __eq meta method of the nil-table is never called we cannot return true.
Is there another approach I'm currently just ignoring? Any hint is greatly appreciated.
Thanks in advance.
Edit:
Here the relevant part of the "testfile". The test by which the code is rated in class is another one and gets published later.
three = 3
print( three == 3 , "Should be true")
print( unknown == nil , "Should be true" )
Class{'AClass', name = String, ref = AClass}
function AClass:write()
print("AClass:write(), name of AClass:", self.name)
end
aclass = AClass:create("A. Class")
aclass:write()
Since MyClass is just a lookup in the global table (_G), you could mess with its metatable's __index to return a newly-defined MyClass object (which you would later need to fill with the details).
However, while feasible, such an implementation is
wildly unsafe, as you could end up with an undefined class (or worse, you may end up inadvertantly creating an infinite lookup loop. Trust me, I've been there)
very hard to debug, as every _G lookup for a non-existing variable will now return a newly created class object instead of nil (this problem could somewhat be reduced by requiring that class names start with an uppercase character)
If you go that route, be sure to also override __newindex.
How about providing the argument in string form?
Class{'MyClass', attribute = 'MyClass'}
Detect strings inside the implementation of Class and process them with _G[string] after creating the class
Or alternatively, use a function to delay the lookup:
Class{'MyClass', attribute = function() return MyClass end}
I'm completely new to Lift. My goal is to make a small application which will let me enter data about scientific articles (studies) into a database.
I haven't gotten around to making a database yet, still playing with getting an entry form to work. So I decided that I will hold a few studies in memory, in a list of a companion object to the Study class. I also created an accumulator variable to dispense unique IDs, as long as I don't have a DBMS managing the IDs.
As a smoke test, I visited the page showing the list of studies (seeded with two studies in code), then visited the form page, entered a new study, and navigated again to the list of studies. I was surprised to see that my new study has the ID of 1 instead of 3, so at some point, my accumulator variable must have been reset. But the ListBuffer collecting studies was not reset, because it showed all three studies. Adding more studies results in the counter incrementing by 1 every time.
The literature I have found on Lift (the two free books on Liftweb, as well as Gilberto Garcia's Lift Application Development Cookbook) are incomplete and are more like a collection of mini-tutorials, they don't explain how Lift works.
So what is the actual lifecycle of my Study object, and why did one mutable variable get reset after re-opening the page but not another?
package org.rumtscho.litsuche
package study
import scala.collection.mutable.ListBuffer
class Study private[study](
val id: Int,
val handmadeAuthorRef: String,
val humanReadableDescription: String )
{
}
object Study {
val seedStudies = List(
new Study(dispenseNextFreeId, "Brooks1975", "Tells us that throwing more programmers at a project makes it run late, not early"),
new Study(dispenseNextFreeId, "Dijkstra1968", "Recognizes that we need structured code")
)
private var studiesList = seedStudies.to[ListBuffer]
private var currentId = 0
private def dispenseNextFreeId: Int = {
currentId = currentId + 1
return currentId
}
def allStudies = studiesList.toList
def addStudy(reference: String, description: String): Unit = {
studiesList += new Study(dispenseNextFreeId, reference, description)
}
}
Here is the representation of the three studies:
update My understanding of what is happening (could be wrong, of course):
I open the page showing the list of studies. This calls allStudies. studiesList is initialized to contain Brooks1975 and Dijkstra1968. During the construction of the studies, currentId is initialized to 0 and then incremented to 2.
I open the entry form and add a third study. addStudy retrieves allStudies from memory, without initializing it again. It initializes currentId to 0. I end up with a third study with the ID 1.
I display all studies, then return to the entry form page. This time, addStudy retrieves both allStudies and currentId from memory. I get a fourth study with the ID of 2.
The comments have pointed out that this is probably Scala-specific and not related to Lift. But still, I don't understand why currentId is initialized two times (in steps 1 and 2), and not either once (as soon as the object itself is created) or every time it is read. I would have expected the first behavior, but even reinitializing every time seems more logical than randomly reinitializing one time only.
Go into the scala REPL, enter paste mode (:paste) command, and put in the following:
def increment {
currentId = currentId + 1
}
increment
increment
var currentId = 0
then try
var currentId = 0
def increment {
currentId = currentId + 1
}
increment
increment
In the first example, currentId ends up with value 0. In the second, it ends up with value 2. Why does this happen? I'm not an expert on Scala declaration, but it seems that this is the same problem you are running in to.
It seems that the solution is as #jcern suggests. In general, I'd say put all your declarations at the top of your classes or objects, and always declare before using a variable, and not the other way around.