How would you do this?

notedop

Member
Licensed User
Longtime User
I'm working on this project to calculate genes inheritance and the chance of getting a specific outcome.

Each male and female have 2 blocks that represent the gene mutation.
There are 2 types of gene mutations, Dominant(D) and Recessives(R) beside the Standard (W).
For the dominants ones to show, you only require 1 of the 2 blocks to be in the child genes. If 1 block is present, you have a Single Factor, if 2 then Double factor
For the recessives to show, you require both blocks to be in the child genes to make the mutation visual.
If only 1 block is present, the child is split for that mutation. On 2 blocks, the mutation is visual.

On paper I am able to calculate the percentages, however I can't figure out how to write it to code.

Let's say we have a male RR, where each R is a block and stands for recessive. And we have a female WW where each W is a block and stands for standard.

if you would combine 1 block of the male and 1 block of the female, then all blocks will be RW. Which means the child will be 100% split to the mutation.
B4X:
female   w   w
male
   R   RW   RW
   R   RW   RW

Next example: in case the female is split to the mutation and the male is fully mutated, the children would have 50% chance of being exactly the same as daddy and 50% change of being exactly the same as mommy.
(2 times RR and 2 times RW.
Total is 4. 2 out of 4 is 50%)

B4X:
female   R   w

male   R   RR   RW
male   R   RR   RW

Additionally the following: Male is RW and female is RW.
The output on this would be 25% RR (visual Mutation) 50% Split and 25% standard. Problem is that WR and RW is basicly the same.

B4X:
female   R   w
male
   R   RR   RW
   w   WR   WW


Anyone a idea on a logic approach?
 

mc73

Well-Known Member
Licensed User
Longtime User
A very basic approach and not the most elegant one can give, yet, you'll get an idea, I think:
B4X:
'Activity module
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
Dim txt(2) As EditText
Dim cmd As Button

End Sub

Sub Activity_Create(FirstTime As Boolean)
For k=0 To 1
    txt(k).Initialize ("")
    txt(k).Hint ="enter r or w"
    txt(k).Text=""
    Activity.AddView (txt(k),0,40dip*k+10dip,20%x,40dip)
Next
cmd.Initialize ("cmd")
cmd.Text="calculate"
Activity.addview(cmd,0,150dip,20%x,40dip)
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub cmd_click
Dim flagError As Boolean 
flagError=False
Dim tempTxt(2) As String 
For k=0 To 1
    Dim temp As String 
    temp=txt(k).Text
    If temp.Length <>2 Then
    flagError=True
    Else
        For l=0 To 1
        Dim temp2 As String
        temp2=temp.CharAt (l)
        temp2=temp2.ToLowerCase 
            If temp2<>"r" AND temp2<>"w" Then 
                flagError=True
            End If
        Next
    End If
    If flagError=False Then
        tempTxt(k)=temp
    End If
Next
If flagError=True Then
    Msgbox("invalid input","error")
    Return
Else
' perform calc
Dim counters(3) As Int 
'0=rr, 1=rw-wr, 2=ww
For k=0 To 1
    Dim temp3 As String 
    temp3=txt(0).Text.CharAt (k)
    temp3=temp3.ToLowerCase 
    For l=0 To 1
        Dim temp4 As String 
        temp4=txt(1).Text.CharAt (l)
        temp4=temp4.ToLowerCase 
        If temp3.CompareTo (temp4)<>0 Then
            counters(1)=counters(1)+1
        Else
            If temp3.CompareTo ("r")=0 Then
                counters(0)=counters(0)+1
            Else
                counters(2)=counters(2)+1
            End If
        End If
    Next
Next
Msgbox("rr=" & Round(100*counters(0)/4) & "%, rw=" & Round(100*counters(1)/4) & "%, ww=" & Round(100*counters(2)/4) & "%.","results") 
                
End If
End Sub
 
Upvote 0

notedop

Member
Licensed User
Longtime User
Hi,

thank you for your input.
I've taken another approach.
It is more intensive as a lot of conditions have to be checked. But with this I can create more exceptions, which are needed.

Note that previously mentioned examples are only a tip of the iceberg of possibilitys. For the recessives I've done the below code:

The output of the function is a list containing values similar to this:
Blue (visual)
/Blue (split)
/Blue (split)
Green (visual - standard)

My next job is to loop through the list, count how many times the value occures and then see which percentage it is from the full list.

When that is done, i'll have to create the logic for the other mutation types. But I think below will work, allthough it will be code intensive.

After that I have to create a function that combines multiple mutation percentages. For instance, if the male has 2 mutation and the female 1, all mutation combinations can become member of the child.


B4X:
Sub Process_Globals
   'These global variables will be declared once when the application starts.
   'These variables can be accessed from all modules.
   Type mutation(name As String, inheritance As String, symbol As String, allelen As String, id As Int)
   Type genetics(id As Int, gender As String, choice As Boolean)
   Type calculation(id As Int, one(2) As String, two(2) As String, three(2) As String, four(2) As String)
   
   Dim mutlist As List

B4X:
Sub CompareGen(data As calculation)

Dim m1 As mutation
Dim m2 As mutation
Dim l As List
Dim outp As String

l.Initialize

Log(data.one(0))
Log(data.three(0))

m1=mutlist.get(data.one(0))
m2=mutlist.get(data.three(0))

Select m1.inheritance
   Case "do", "in"
   
      Select m2.inheritance
         Case "do", "in"
         
         
                  
         Case "re"
         
         
         
         Case "cd"
         
      End Select
      
      
      
   Case "re"
         
         Select m2.inheritance
         
            Case "do", "in"
            
            
                     
            Case "re"
            
'            first comparisation out of 4, we have 1-2 and 3-4 This is 1-3

            If (data.one(1) = data.three(1)) AND (data.one(0) = data.three(0)) Then
               If data.one(1) = 0 Then 
               outp = " green" 
               Else
               outp = " " & m1.name 'the mutation is visible
               End If               
            l.Add(outp)
            Else If (data.one(1) <> data.three(1)) AND (data.one(0) = data.three(0)) Then
            outp = "/" & m1.name 'the mutation is split
            l.Add(outp)
            Else If (data.one(1) = data.three(1)) AND (data.one(0) <> data.three(0)) Then
            outp = "/" & m1.name & "/" & m2.name 'two different recessive mutation so split for both
            l.Add(outp)
            End If
            
'            this is 1-4
            
            If (data.one(1) = data.four(1)) AND (data.one(0) = data.four(0)) Then
               If data.one(1) = 0 Then 
               outp = " green" 
               Else
               outp = " " & m1.name 'the mutation is visible
               End If         
            l.Add(outp)
            Else If (data.one(1) <> data.four(1)) AND (data.one(0) = data.four(0)) Then
            outp = "/" & m1.name 'the mutation is split
            l.Add(outp)
            Else If (data.one(1) = data.four(1)) AND (data.one(0) <> data.four(0)) Then
            outp = "/" & m1.name & "/" & m2.name 'two different recessive mutation so split for both
            l.Add(outp)
            End If
            
            
'            this Is 2-3

            If (data.two(1) = data.three(1)) AND (data.two(0) = data.three(0)) Then
               If data.two(1) = 0 Then 
               outp = " green" 
               Else
               outp = " " & m1.name 'the mutation is visible
               End If   
            l.Add(outp)
            Else If (data.two(1) <> data.three(1)) AND (data.two(0) = data.three(0)) Then
            outp = "/" & m1.name 'the mutation is split
            l.Add(outp)
            Else If (data.two(1) = data.three(1)) AND (data.two(0) <> data.three(0)) Then
            outp = "/" & m1.name & "/" & m2.name 'two different recessive mutation so split for both
            l.Add(outp)
            End If
            
'            this Is 2-4
            
            If (data.two(1) = data.four(1)) AND (data.two(0) = data.four(0)) Then
               If data.two(1) = 0 Then 
               outp = " green"
               Else
               outp = " " & m1.name 'the mutation is visible
               End If   
            l.Add(outp)
            Else If (data.two(1) <> data.four(1)) AND (data.two(0) = data.four(0)) Then
            outp = "/" & m1.name 'the mutation is split
            l.Add(outp)
            Else If (data.two(1) = data.four(1)) AND (data.two(0) <> data.four(0)) Then
            outp = "/" & m1.name & "/" & m2.name 'two different recessive mutation so split for both
            l.Add(outp)
            End If
            
'            get_percentages(l) 
            
'            Msgbox(outp, "test")
            
            Case "cd"
            
            
         End Select
         
         
   Case "cd"
         
         Select m2.inheritance
   
            Case "do", "in"
            
            
                     
            Case "re"
            
            
            
            Case "cd"
         End Select

End Select

   


End Sub
 
Upvote 0

mc73

Well-Known Member
Licensed User
Longtime User
I think you should code every single exception and anything else, into matrix notation, thus using arrays. Some times, it may look hard, but if you think twice, it will take you out of generalization problems that may occur.
 
Upvote 0
Top