Android Question Resumable Sub? Right or wrong [Solved: Apparently wrong]

Shelby

Well-Known Member
Licensed User
Longtime User
I have workable code to calculate the square footage of a wall, save that result, repeat for more walls and add the areas of the previous walls to the lastly calculated wall and display a running total of all wall areas. Now I have a problem: some walls have different heights so I have to find the average of those two heights to use for calculating the newest wall. After some reading, I think I will have to use a resumable sub like a previous tutorial of Erel's e.g.
https://www.b4x.com/android/forum/t...hat-return-values-resumablesub.82670/#content

Here is my code with an attempt to start with the resumable sub between the rows of dotted lines.

B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules. Public by default.SSS
    Public TotalArea As Double
    Type Walls(Width As Double, Height As Double, Area As Double)
    Public lstWalls As List
    Public WallIndex = 1 As Int
End Sub

Sub Globals
    'Variables always Private in this sub SSS
  
    Private lblWall, lblFind, lblArea, lblTotalArea, lblWallNumber As Label
    Private edtHeight, edtWidth As EditText
    Private btnCalc As Button
    'Private pnlBitmap As Panel
          
    Private ltvWalls As ListView
End Sub
'---------------------------------------------------
'SS New attempt to find average of different wall heights
Sub Button1_Click
    Wait For(Sum(1, 2)) Complete (Result As Int)
    'I also want to divide that sum by 2 (how is that written?)
    Log("result: " & Result)
    Log("after sum")
End Sub

Sub Sum(a As Int, b As Int) As ResumableSub
    Sleep(100)
    Log(a + b)
    Return a + b  'Also divide by 2
End Sub

'SS End new attempt....
'-----------------------------------------------------
Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("Wall1_2")
  
    lstWalls.Initialize
    ltvWalls.SingleLineLayout.Label.TextSize = 18
    ltvWalls.SingleLineLayout.ItemHeight = 30dip
  
    NewWall
  
  

'    pnlBitmap.Initialize ("")
'    Activity.AddView (pnlBitmap, 0%x, 270dip, 72%y, 190dip)
'    Private bdwBitmap As BitmapDrawable
'    bdwBitmap.Initialize(LoadBitmap(File.DirAssets, "Framing.jpg"))
'    bdwBitmap.Gravity = Gravity.FILL
'    pnlBitmap.Background = bdwBitmap 
  
    Log($"Today's Date  $date{DateTime.Now}"$)
    'Above is  smart string (using $ symbols)
  
    'Not smart
    Log("Also today is " & DateUtils.GetDayOfWeekName(DateTime.Now))
    '***
  
  
    'Below is smart string time
    Log ($"The Time $Time{DateTime.Now}"$)
          
End Sub

Sub Activity_Resume
  
End Sub

Sub Activity_Pause (UserClosed As Boolean)
  
End Sub

Private Sub NewWall
    Private Wall As Walls
    Wall.Area = 0
    Wall.Height = 0
    Wall.Width = 0
    lstWalls.Add(Wall)
    ltvWalls.AddSingleLine("Wall #" & WallIndex & "  W = " & Wall.Width  & "   H = " & Wall.Height& " Area = " & NumberFormat(Wall.Area, 1, 2))
    WallIndex = lstWalls.Size
  
    lblArea.text = " Will Display Here"
End Sub

Sub btnCalc_Click
    Private Wall As Walls
    Wall.Width = edtWidth.Text
    Wall.Height = edtHeight.Text
    Wall.Area = Wall.Width * Wall.Height
    TotalArea = TotalArea + Wall.Area
    lblArea.Text = NumberFormat(Wall.Area, 1, 0)  & "  Square Feet"
    lstWalls.Set(WallIndex - 1, Wall)
    UpdateWallList
    CalculateTotalArea
    lblTotalArea.Text = NumberFormat(TotalArea, 1, 2) & "   s.f."
End Sub

Private Sub btnNewWall_Click
    NewWall
    UpdateNewWallScreen
    UpdateWallList
End Sub

Sub ltvWalls_ItemClick (Position As Int, Value As Object)
    WallIndex = Position  + 1
    UpdateWallScreen
End Sub

Private Sub UpdateWallScreen
    Private Wall As Walls
  
    Wall = lstWalls.Get(WallIndex - 1)
    lblWallNumber.Text = WallIndex
    If Wall.Width = 0 Then
        edtWidth.Text = ""
    Else
        edtWidth.Text = Wall.Width
    End If
    If Wall.Height = 0 Then
        edtHeight.Text = ""
    Else
        edtHeight.Text = Wall.Height
    End If
    lblArea.Text =  NumberFormat(Wall.Area, 1, 0) & " Square Feet"
    lblTotalArea.Text = NumberFormat(TotalArea, 1, 2)
End Sub

Private Sub UpdateNewWallScreen
    lblWallNumber.Text = WallIndex
    edtWidth.Text = ""
    edtHeight.Text = ""
End Sub

Private Sub UpdateWallList
    Private i As Int
  
    ltvWalls.Clear
    For i = 0 To lstWalls.Size - 1
        Private Wall As Walls
        Wall = lstWalls.Get(i)
        ltvWalls.AddSingleLine("Wall #" & (i + 1) & "  W = " & Wall.Width  & "   H = " & Wall.Height & " Area = " & NumberFormat(Wall.Area, 1, 2))
    Next
End Sub

Private Sub CalculateTotalArea
    Private i As Int
  
    TotalArea = 0
    For i = 0 To lstWalls.Size - 1
        Private Wall As Walls
        Wall = lstWalls.Get(i)
        TotalArea = TotalArea + Wall.Area
      
        Log (TotalArea)
      
    Next
End Sub

My most immediate questions are: 1) Is the resumable sub what I need for calculating and then returning to the original main module?
2) Do I need an additional module for the calculating of the average height for my original area calculation?
3) Do I need another designer (.bal file) for the calculation of the average height?
I have a floor area app published and this wall area app is my next attempt at app building.
Thanks

Here is my full app (before the resumable sub code) file attached
 

Attachments

  • Area_Walls_Calculator.zip
    11.6 KB · Views: 213
Last edited:

emexes

Expert
Licensed User
Resumable Sub is more appropriate for long-running background calculations, so that the calculation doesn't halt the rest of your program and make it look like it's locked up.

So the answer to your question is:
- if the calculation was something like brute-force solving a sudoku, "right"
- if the calculation can be done in a small fraction of a second, "wrong"

But maybe I am missing something about this average. Is there something about it that is more complex than usual? I'm currently in the midst of factoring large numbers, so I empathize that sometimes what looks like a simple problem, isn't ;-)
 
Last edited:
Upvote 0

Shelby

Well-Known Member
Licensed User
Longtime User
By taking the average of a wall's 2 heights with a slanted ceiling , I am turning it into a rectange to calculate the area e.g. width X height. Hopefully I'm not imagining a postulation in geometry.
 
Upvote 0

emexes

Expert
Licensed User
By taking the average of a wall's 2 heights with a slanted ceiling , I am turning it into a rectange to calculate the area e.g. width X height. Hopefully I'm not imagining a postulation in geometry.
Nope, that's correct. Geometrically, you can turn it into a rectangle by taking the top-half-triangle of the high side and turning it upside down to fill in the low side.

AverageHeight = (LeftHeight + RightHeight) / 2
WallArea = WallLength * AverageHeight

or just put it all together:

WallArea = WallLength * (LeftHeight + RightHeight) / 2
 
Upvote 0

emexes

Expert
Licensed User
postulation in geometry
If the room is a rectangle with a(n orthagonally?) slanted ceiling, then curiously* the average height of all four walls is also (Height1 + Height2) / 2, regardless of the relative lengths of the walls ie whether it is a long narrow room or a square room or anything in-between.


* and conveniently
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
My most immediate questions are: 1) Is the resumable sub what I need for calculating and then returning to the original main module?
2) Do I need an additional module for the calculating of the average height for my original area calculation?
3) Do I need another designer (.bal file) for the calculation of the average height?
1) No, not at all.
2) No, you need to enter two heights and calculate the area with Area = Width * (Height1 + Height2) / 2.
3) No, if you enter directly the two heights.

Where and how do you intent to enter the second height?

I suggest you to add:
1) To Add an option to enter two heights instead of one, and keep them.
2) Enter systematically two heights, and set the second one the same as the first one by default and change it if needed.
This could be disturbing for the user.

This means that you need to change the Walls Type declaration adding a second height.
 
Upvote 0

Shelby

Well-Known Member
Licensed User
Longtime User
Thanks both Emexes and Klaus. My dilemma is that I feel that my phone screen is filled up with buttons and views so I was hoping I could use perhaps an if statement which would send the user to a new screen if the wall in question has two different heights. Then she or he could enter the two different heights only in the uneven wall heights scenario, after which the average height could be calculated and then automatically fill in the wall height edtHeight box on the original screen. Much of the time the wall will have the same height on the two sides but much of the time it won't (i.e. cathedral ceilings). Here's an image of my existing code emulator before adding the potential code to calculate the uneven wall heights scenario. In the image it seems as though there is plenty of space but the phone (via B4A bridge) gets a bit crowded.
Happy ThanksForGiving me feedback...!
 

Attachments

  • Walls_App_shot2.png
    Walls_App_shot2.png
    40.7 KB · Views: 196
Last edited:
Upvote 0

klaus

Expert
Licensed User
Longtime User
Why not something like this, a checkbox allowing to enter one or two height values ?

upload_2019-11-28_16-39-13.png
upload_2019-11-28_16-39-23.png


Unfortunately, the checkbox doesn't look good with your layout colors.

The text size in your buttons is awfully small, they are increased in the pictures above.
You might hide the Next Wall button for a new wall.
The user can press many times on it and this adds a new empty wall each time.
 
Upvote 0

Shelby

Well-Known Member
Licensed User
Longtime User
So if the user clicks the checkbox 2, then your lower screen pops up? I think that's adequate. I'll see if I can incorporate the code you guys furnished above and test it. Maybe you have additional code to cause the new view to appear but I'll try what you have generously given already.
Thanks Klaus.

Perhaps I can use an if statement like:

Sub clickCheckbox
private htLeft, htRight = int
if clickCheckbox = true
then Height = (htLeft + htRight) /2
I'm still imagining and inventing more code............

End Sub
 
Last edited:
Upvote 0

Shelby

Well-Known Member
Licensed User
Longtime User
The primary glitch that exists now is that if a wall with a level top is being calculated, where the checkbox 2 is not needed, an error pops up saying
Error Height 2 is not a
number!
This forces the user to use the checkbox or else. Perhaps the solution might be some added information or change of information for the cbxTwoHeights sub. Here's the sub:

B4X:
Private Sub cbxTwoHeights_CheckedChange(Checked As Boolean)
    edtHeight2.Visible = Checked
End Sub

Sub ltvWalls_ItemClick (Position As Int, Value As Object)
    WallIndex = Position  + 1
    UpdateWallScreen
End Sub

Or, judging from my student mentality, maybe some change is needed here:

B4X:
Private Sub GetWallData As Walls
    Private Wall As Walls
 
    Wall.Width = edtWidth.Text
    Wall.TwoHeights = cbxTwoHeights.Checked
    If Wall.TwoHeights = False Then
        Wall.Heights = Array As Double (edtHeight1.Text, edtHeight1.Text)
        Wall.Area = Wall.Width * Wall.Heights(0)
    Else
        Wall.Heights = Array As Double (edtHeight1.Text, edtHeight2.Text)
        Wall.Area = Wall.Width * (Wall.Heights(0) + Wall.Heights(1)) / 2
    End If
 
    Return Wall
End Sub

Or thirdly this following sub might seem suspect:

B4X:
Sub btnCalc_Click
    If Not(IsNumber(edtWidth.Text)) Then
        MsgboxAsync("Width is not a number !", "E R R O R")
        Return
    End If  
   
    If Not(IsNumber(edtHeight1.Text)) Then
        MsgboxAsync("Height is not a number !", "E R R O R")
        Return
    End If
   
    If cbxTwoHeights.Checked = False Then
        If Not(IsNumber(edtHeight2.Text)) Or Not(IsNumber(edtHeight2.Text)) Then
            MsgboxAsync("Height 2 is not a number !", "E R R O R")
            Return
        End If
    End If

    If flgNewWall = True Then
        AddANewWall
    Else
        UpdateAWall
    End If
    UpdateWallListView
   
    CalculateTotalArea
    lblTotalArea.Text = NumberFormat(TotalArea, 1, 2) & "   s.f."

    btnNewWall.Visible = True
End Sub
 
Last edited:
Upvote 0

Shelby

Well-Known Member
Licensed User
Longtime User
Super! Thanks again Klaus
Just tested it and viola! Success
Bonne Nuit?
à propos de l'heure du coucher je suppose.
 
Last edited:
Upvote 0

Shelby

Well-Known Member
Licensed User
Longtime User
Sometimes I can barely believe how helpful so many of you are. I will always treasure the kindness that is expressed on this forum. Thanks to all of you, especially you Klaus, Don Manfred, Erel, and Emexes for your generous guidance.
 
Upvote 0
Top