Upload
others
View
2
Download
0
Embed Size (px)
Citation preview
1
COMP61511(Fall2017)SoftwareEngineeringConcepts
InPracticeWeek2
BijanParsia&ChristosKotselidis< , @manchester.ac.uk>
(bugreportswelcome!)bijan.parsia christos.kotselidis
2.3
ARationalFizzBuzzLet'sconsidera"standard"implementation
NotsillyNotgolfy
I.e.,asimplelooporientedimplementation
2.4
DRY"Don'tRepeatYourself"
AfundamentalprincipleofSEItisagainst
CutandPastereuseNotInventedHeresyndrome
Isour DRY?currentversion
2.5
ADryerVersionWerepeati % 3 == 0andi % 5 == 0Let's !abstractthatout
2.6
EVENDRIER!!!Werepeatthe_ % _ == 0pattern!WesayprintalotWecan !fixit
2.7
ParameterizationBasicsoftwareprinciple:Don'thardcodestuff!
Makeyourcodeparameterisable!Thecurrentversionhardcodesalot,e.g.,
Wehavetomodifythesourcecodeifwewanttochangethis!Whatelseishardcoded?Wecan !
FIZZ = 'Fizz'BUZZ = 'Buzz'
fixit
2.8
StillHardCoding!ThekindoftestishardcodedWecanfix !that
2.9
ThePathToHell......ispavedwithgoodintentions!Eachchoicewassomehowreasonable
WeappliedgoodSEprinciplesWemadechoicesthatareoftengood
ButweendedupinnonsenselandLocalsenseledtoglobalnonsense
2.10
JudgementSoftwareengineerscan'tjustfollowrulesGoodsoftwareengineeringrequiresjudgementWhentoapplywhichrulesWhentobreakrules*HowtoapplyorbreakthemThereasonforeachrule
Andwhetheritmakessensenow
2.11
AcknowledgementThislecturewasderivedfromtheexcellentblogpost
byTomDalling.FizzBuzzInTooMuch
Detail
TomusesRubyandgoesacoupleofstepsfurther.Wortharead!
3.1
IntellectualProperty
3.2
WhoOwnsYourCode?Youwrotesomecode!
Allweek!Bothsystemsandtests!
Akeyquestion:Whoownsthatcode?
Ordifferentbitsofit?Whatkindofownership?
3.3
IntellectualProperty(IP)Intellectualproperty is anyarticulable, tangible productionofamindwhosephysical realisationsare restrictedby law (inproduction,distribution,etc.)
Wedon'tcontrolwhatotherpeoplethink!Wecancontrolwhattheydowithcertainthoughts.IntellectualPropertyrightsgivepowertocertainpeopletocontrolwhatotherpeopledo
Forexample,whethertheycandistributeabook,song,orprogram
3.4
KindsOfIntellectualPropertyName Establishment Enforcement
Copyright Automatic,immediate CivilandCriminal
Patent Application;exposurebeforeapplicationdestroysit
Mostlycivil
Trademark Applicationandvigorousdefense MostlycivilTradeSecret
Automatic(bynottellingpeople)andNDAs Mostlycivil
3.5
CopyrightCopyright isa licensablemonopolyoftangible expressionofan idea with respect to reproduction, derivation, display,distribution,andthelike.
ProtectstheexpressionnottheideaThoughthesebluratthelimit
Someplagiarismisacopyrightviolation;someisnotTypicallyautomaticallyassignedatcreationtime
No"notice"or"registration"neededThoughthesemighthelpwithlawsuits
3.6
PatentsApatent isa licensablemonopolyof theuseorsaleofa"non-obvious"invention(ofaprocess,machine,design(sometimes),mechanism,procedure,etc.
ApatentisanincentivetodiscloseManypatentableinventionscouldbeexploited"secretly"Goalistoaddtoourcommonknowledge
PriorartdestroysapatentIncludingyourown
Defensivepatenting"common"Independentinventionnodefense
3.7
TradeSecretAtradesecretisaninventionwhichisnotdisclosed
PersistsforeverUnlessleakedOrreinvented
TypicallyprotectedbysecrecyOrspecificcontracts
"Non-DisclosureAgreements"(NDAs)
3.8
WhoOwnsYourCode?Copyrightstartswiththecreator
I.e.,you!Cheap!(Eventoregister)Unlessyoucreateitaswork-for-hire
OrotherwisetransferitPatentsbelongtothepatenter
Expensive(ish)tosecureTradesecretsbelongtotheinventor
AreYouWorkingForHire?Not !quite
3.9
3.10
WhatToKeepInMind(Now)SoftwareengineerstypicallyproduceIP
Evenifnotprotected,ouroutputis"intellectual"VariousformsofIPdriveproductvalueemployee/entrepreneurvalue
SoftwareengineerstypicallyuseIPAllsortsandinallwaysIPconsiderationsaconstraintonthedesignspace
4.2
Comprehension?Wecandistinguishtwoforms:
Know-thatYoubelieveatrueclaimaboutthesoftware...withappropriateevidence
Know-howYouhaveacompetancywithrespecttothesoftwareE.g.,youknow-howtorecompileitforadifferentplatform
TheyareinterrelatedBothrequiresignificanteffort!
4.3
QualityLevelsWetalkedaboutdifferentkindsofquality
Butforeachkindtherecanbedegreesorlevelsthereof"Easy"example:Highvs.Lowperformance
MostqualitiesinprinciplearequantifiableMostthingsarequantifiableinsomesense
Butreasonablequantificationisn'talwayspossibleOrworthitBeingclearaboutyourvaguenessisessential!
4.4
ClarityOurdiscussionwillbeadequate if ithasasmuchclearnessas the subject-matter admits of, for precision is not to besought for alike in all discussions, any more than in all theproducts of the crafts...for it is the mark of an educated[person]tolookforprecisionineachclassofthingsjustsofarasthenatureofthesubjectadmits...—Aristotle,NicomachaenEthics,Book1,3
4.5
Clarity(2)We demand rigidly defined areas of doubt anduncertainty!—DouglasAdams,TheHitchhiker'sGuidetotheGalaxy
4.6
DefectsAsQualityLacksA defect in a software system is a quality level (for somequality)thatisnotacceptable.
QualitylevelsneedtobeelicitedandnegotiatedAllpartiesmustagreeonwhattheyare,theiroperationaldefinitiontheirsignificance
Whatcountsasadefectisoftendeterminedlateinthegame!
4.7
QuestionIfyourprogramcrashesthenit
1. definitelyhasabug.2. ishighlylikelytohaveabug.3. mayormaynothaveabug.
4.8
QuestionIfyourprogramcrashes,andthecauseisinyourcode,thenit
1. definitelyhasabug.2. ishighlylikelytohaveabug.3. mayormaynothaveabug.
4.9
BugOrFeature?( —scrollforthecartoonsaswellasthewisdom.)DoesQAhateyou?
Evenacrashingcodepathcanbeafeature!Contentionariseswhenthestakesarehigh
andsometimethestakescanseemhightosomepeople!defectrectificationcoststhesame
whetherthedefectisdetected......orafeatureisredefined
Defects(evenredefinedfeatures)aren'tpersonal
ProblemDefinition
Thisisalogical,nottemporal,order.
4.10
4.11
ProblemDefinitionThe penalty for failing to define the problem is that you canwastealotoftimesolvingthewrongproblem.Thisisadouble-barreledpenaltybecauseyoualsodon'tsolvetherightproblem.—McConnell,3.3
4.12
QualityAssuranceDefectAvoidanceorPrevention
"Prerequisite"workcanhelpRequirementnegotiationDesignTechchoice
MethodologyDefectDetection&Rectification
Ifadefectexists,FinditFixit
4.13
ThePointsOfQuality1. Defectprevention
Designcare,codereviews,etc.2. Defectappraisal
Detection,triaging,etc.3. Internalrectification
Wefix/mitigatebeforeshipping4. Externalrectification
Wecopeaftershipping
4.14
DefectDetectionTechniques
4.15
DefectDetectionTechniques
4.16
ExperiencingSoftwareIt'sonetoknowthattherearebugsAllsoftwarehasbugs!
It'sanothertobeabletotriggerabugNotjustaspecificbug!Ifyouunderstandthesoftware
Youknowhowtobreakit.Similarly,formakingchanges
tweaks,extensions,adaptions,etc.Themorecommand,themoremodalitiesofmastery
4.17
FormsOfKnowledge(Manifestations)Humaninterpretable
Comments,designdocs,userstories,javadocSourcecode
Both,awrittendescriptionanda"live"objectAlsothingslikedemocode,examples,testsuites,ec.
Diagrams"Mere"picturestosemi-formaltoformaldiagrams:ERdocs,UML,etc.
FormalspecificationsCompetencies
Icanmakeitcrash
4.18
SourcesOfKnowledge(Modalities)Analyticalknowledge
DerivedfrominspectionandreasoningCanbeautomatedusingformalmethods
ExperimentalknowledgeDerivedfromtheconductofexperimentsTypicallytests
ExperientialknowledgeDerivedfrompersonalinteractionwiththesoftwareStrong"know-how"component
5.2
RevisitingRainfallWe'regoingtolookatyourrainfallsbeforediscussingitindetail.
We'regoingtodoacodereview!
You'regoingtoworkin2-personteams!
5.3
ThreeTasks1. Doacodereview!2. Writesometestsbasedonyourcodereview!3. Doanessayreview!
Tothelab!Materialintheusualplace.
6.2
RainfailKeypoint:0outof47programspassedall13tests
1programpassed8tests2passed75passed60passed5or45passed33passed21passed115passed011"hadaproblemwithsubmission"4"Wecouldnotcompileyourcode."
Therainfallproblemisstillachallenge!
6.3
Let'sTalkTestingYouhadlimitedtime
Sotestgenerationhadtobequick!Typicallyadhoc
Canwedobetter?Howtestableisrainfall.py?
Youwereresponsibleonlyforaverage_rainfall(input_list)Onlythisunit!Canignoreallelse!
Perfectfordoctest
6.4
ProblemStatementDesign a program called rainfall that consumes a list ofnumbers representing daily rainfall amounts as entered by auser. The list may contain the number -999 indicating theend of thedataof interest.Produce theaverageof thenon-negativevalues in the listup to the first -999(if it showsup).Theremaybenegativenumbersotherthan-999inthelist.
6.5
SetUpdef average_rainfall(input_list): """>>> average_rainfall(<<FIRST TEST INPUT>>) <<FIRST EXPECTED RESULT>> """ # Here is where your code should go return "Your computed average as a integer" #<-- change this!
$ python 1setup.py Your computed average as a integer
6.6
FirstTestRun$ python -m doctest 1setup.py **********************************************************************File "/Users/bparsia/Documents/2018/Teaching/COMP61511/labs/lab1/followup/1setup.py", line 2, in 1setup.average_rainfallFailed example: average_rainfall(<<FIRST TEST INPUT>>)Exception raised: Traceback (most recent call last): File "//anaconda/lib/python3.5/doctest.py", line 1320, in __run compileflags, 1), test.globs) File "<doctest 1setup.average_rainfall[0]>", line 1 average_rainfall(<<FIRST TEST INPUT>>) ^ SyntaxError: invalid syntax**********************************************************************1 items had failures: 1 of 1 in 1setup.average_rainfall***Test Failed*** 1 failures.
6.7
FirstTestWheredowegetourfirstrealtest?
Hint:Readthedocs:
6.8
ConvertToAppropriateDoctestForasystemtest,we'dneedtousesubprocessetc.
Butwecanjusttestourunit!average_rainfall(input_list)Butittakesalistnotastringasinput!
'2 3 4 67 -999'==>[2, 3, 4, 67, -999]Wehadtomassagetheinputtogetourtest!
6.9
TestedAverage_rainfallV2def average_rainfall(input_list): """>>> average_rainfall([2,3,4,67, -999]) 19.0 """ # Here is where your code should go return "Your computed average as a integer" #<-- change this!
$ python 1setup.py Your computed average as a integer
6.10
SecondTestRun$ python -m doctest 2firstfull.py **********************************************************************File "/Users/bparsia/Documents/2018/Teaching/COMP61511/labs/lab1/followup/2firstfull.py", line 2, in 2firstfull.average_rainfallFailed example: average_rainfall([2,3,4,67, -999])Expected: 19.0Got: 'Your computed average as a integer'**********************************************************************1 items had failures: 1 of 1 in 2firstfull.average_rainfall***Test Failed*** 1 failures.
6.11
Yay!Wehavearealandreasonabletest!
AndaclearformatforsubsequenttestsAndaninfrastructurethatmakesiteasytoruntests
WehaveabrokenimplementationAswitnessedbyatest!
WeCanFixIt!
6.12
RosieSez
6.13
FirstImplementationdef average_rainfall(input_list): """>>> average_rainfall([2,3,4,67, -999]) 19.0 """ # Here is where your code should go return sum(input_list)/len(input_list)
Willthisfailthistest?Isthereatestthatitwillpass?
6.14
FirstImplementationWithTestdef average_rainfall(input_list): """>>> average_rainfall([2,3,4,67, -999]) 19.0 >>> average_rainfall([2,3,4,67]) 19.0 """ # Here is where your code should go return sum(input_list)/len(input_list)
6.15
ThirdTestRun$ python -m doctest 4firstimpl2.py **********************************************************************File "/Users/bparsia/Documents/2018/Teaching/COMP61511/labs/lab1/followup/4firstimpl2.py", line 2, in 4firstimpl2.average_rainfallFailed example: average_rainfall([2,3,4,67, -999])Expected: 19.0Got: -184.6**********************************************************************1 items had failures: 1 of 2 in 4firstimpl2.average_rainfall***Test Failed*** 1 failures.
6.16
SecondImplementationdef average_rainfall(input_list): """>>> average_rainfall([2,3,4,67, -999]) 19.0 >>> average_rainfall([2,3,4,67]) 19.0 """ # Here is where your code should go return sum(input_list[:-1])/len(input_list[:-1])
Fixesonetestbutnottheother!Testsworktogether
6.17
ThirdImplementationdef average_rainfall(input_list): """>>> average_rainfall([2, 3, 4, 67, -999]) 19.0 >>> average_rainfall([2, 3, 4, 67]) 19.0 """ rainfall_sum = 0 count = 0 for i in input_list: if i == -999: break else: rainfall_sum += i count += 1 # Here is where your code should go return rainfall_sum/count
6.18
FourthTestRun$ python -m doctest 5secondimpl.py **********************************************************************File "/Users/bparsia/Documents/2018/Teaching/COMP61511/labs/lab1/followup/5secondimpl.py", line 2, in 5secondimpl.average_rainfallFailed example: average_rainfall([2,3,4,67, -999])Expected: 19.0Got: 19.0**********************************************************************1 items had failures: 1 of 2 in 5secondimpl.average_rainfall***Test Failed*** 1 failures.
Whaaaaaaaaaaaaaaaaaat?!
6.19
ABug!Therewasabuginourtests
Allalong!
vs.
Earliertestsfailedfortworeasons!
Onebugconcealedtheother!!!
def average_rainfall(input_list):""">>> average_rainfall([2, 3, 4, 67, -999])19.0
def average_rainfall(input_list):""" >>> average_rainfall([2, 3, 4, 67, -999])19.0
6.20
Yay!$ python -m doctest 6secondimpl2.py $$ python -m doctest -v 6secondimpl2.py Trying: average_rainfall([2,3,4,67, -999])Expecting: 19.0okTrying: average_rainfall([2,3,4,67])Expecting: 19.0ok1 items had no tests: 6secondimpl21 items passed all tests: 2 tests in 6secondimpl2.average_rainfall2 tests in 2 items.2 passed and 0 failed.Test passed.
6.21
NextTests?Thesetestsclearlyaren'tenoughWhatnext?
Lookforboundaryconditions([-999])Lookfor"oddequivalents"
Is[-999, 1]thesameas[-999]?Howabout[]and[-999]?Howabout[-999]and[-999, 0]
Lookfornormalcasesyouhaven'tcovered[-1 0 10]Foreachnewfeatureiteratetheearliermoves!
e.g.,is[-1 -2 -3 -999 1]thesameas[]?
7.1
AClassificationOfTests
7.2
AClassificationOfTestsBasedona5W+Happroachby (archived)Who(Programmervs.customervs.managervs...)What(Correctnessvs.Performancevs.Useabilityvs...)When(Beforewritingcodeorafter)
Orevenbeforearchitecting!Where(Unitvs.Componentvs.Integrationvs.System)
Orlabvs.fieldWhy(Verificationvs.specificationvs.design)How(Manualvs.automated)
Ondemandvs.continuous
RaySinnema
7.3
Who?Sinnema:Testsgiveconfidenceinthesystem
I.e.,theyareevidenceofaqualityWhoisgettingtheevidence?Users?Testsfocusonexternalqualities
CanIacceptthissoftware?Programmers?Testsfocusoninternalqualities
CanIcheckinthiscode?Managers?Both?
ArewereadytoreleaseButalso,whoiswritingthetest?
Abugreportisa(typicallypartial)testcase!
7.4
What?WhichqualitiesamItryingtoshow?
Internalvs.externalFunctionalvs.non-functional?Mostdevelopertestingisfunctional(i.e.,correctness)
AndattheunitlevelDoesthisclassbehaveasdesigned
7.5
When?Whenisthetestwritten?Beforethecodeiswritten?Afterthecodeiswritten?
PerhapsabetterdistinctionTestswrittenwithexistingcode/designinmindTestwrittenwithoutregardforexistingcode/designThisisrelatedtowhitevs.blackboxtesting
MaindifferenceiswhetheryourespecttheexistingAPI
7.6
Where?Unit
Smallest"chunk"ofcoherentcodeMethod,routine,sometimesaclass
:"theexecutionofacompleteclass,routine,orsmallprogramthathasbeenwrittenbyasingleprogrammerorteamofprogrammers,whichistestedinisolationfromthemorecompletesystem"
Component(McConnellspecific,Ithink)"workofmultipleprogrammersorprogrammingteams"andinisolation
McConnell
7.7
Where?(Ctnd)Integration
Testingtheinteractionoftwoormoreunits/componentsSystem
TestingthesystemasawholeInthelab
I.e.,inacontrolledsettingInthefield
I.e.,in"natural",uncontrolledsettings
7.8
Where?(CtndEncore)Regression
AbitofafunnyoneBackwardlookingandchangeoriented
Ensureachangehasn'tbrokenanythingEsppreviousfixes.
7.9
Why?Threebigreasons1. Verification(orvalidation)
Doesthesystempossessaqualitytoacertaindegree?2. Design
ImposeconstraintsonthedesignspaceBothstructureandfunction
3. ComprehensionHowdoesthesystemwork?
ReverseengineeringHowdoIworkwiththesystem?
7.10
How?Manual
TypicallyinteractiveHumanintervationformorethaninitiation
ExpectationsflexibleAutomated
ThetestexecutesandevaluatesoninitiationAutomaticallyrun(i.e.,continuously)
8.2
Bill Sempf@sempf
QA Engineer walks into a bar. Orders a beer. Orders 0 beers. Orders 999999999 beers. Orders a lizard. Orders -1 beers. Orders a sfdeljknesv.6:56 PM - Sep 23, 2014
21.1K 29.9K people are talking about this
Coverage
Esp.forfinegrainedtests,generalityisaproblemWewantasetofteststhat
determinessomepropertyatareasonablelevelofconfidence
Thistypicallyrequirescoverage
8.3
CoverageAndRequirementsConsideracceptancetesting
ForatestsuitetosupportacceptanceItneedstoprovideinformationaboutallthecriticalrequirements
ConsidertestdrivendevelopmentWheretestsdrivedesignWhathappenswithoutrequirementscoverage?
8.4
CodeCoverageAtestcase(orsuite)coversalineofcode
iftherunningofthetestexecutestheLOCCodecoverageisaminimalsortofcompleteness
SeeMcConnellon"basis"testingAimforminimaltestsuitewithfullcodecoverage
SeeTrickybittypicallyinvolvesbranches
Themorebranches,thehardertoachievecodecoverage
coverage.py
8.5
InputCoverageInputspacesare(typically)toolargetocoverdirectly
SoweneedasamplePuresampleprobablyinadequate
SpacetoolargeanduninterestingWewantabiasedsample
E.g.,wherethebugsareHence,attentiontoboundarycases
E.g.,commoninputsThatis,what'slikelytobeseen
8.6
Situation/ScenarioCoverageInputsaren'teverything
MachineconfigurationHistoryofuseInteractionpatterns
FieldtestinghelpsHencealphaplusnarrowandwidebetatesting
Systemtestsanswertothis!
8.7
LimitsOf(Developer)TestingTestingalwayshaslimits
TestsarewrongTestsarebuggyTestsareincomplete
"Self"Testingsubjecttocognitivebiases:Weinterpretwrongly
:Weinfluenceotherstointerpretincorrectly
:Welookinthewrongplace
ConfirmationbiasObserver-expectancyeffect/Experimenterbias
Congruencebias
8.8
DevelopingTestStrategiesHaveone!Howeverpreliminary
AdhoctestingrarelyworksoutwellReviewitregularly
YoumayneedadjustementsbasedonIndividualorteampsychologySituation
TheMcConnell (22.2)isagooddefaultbasicstrategy
8.9
DeveloperTestStrategiesMcConnell:22.2RecommendedApproachtoDeveloperTesting
"Testforeachrelevantrequirementtomakesurethattherequirementshavebeenimplemented.""Testforeachrelevantdesignconcerntomakesurethatthedesignhasbeenimplemented...asearlyaspossible""Use"basistesting"...Ataminimum,youshouldtesteverylineofcode.""Useachecklistofthekindsoferrorsyou'vemadeontheprojecttodateorhavemadeonpreviousprojects."Designthetestcasesalongwiththeproduct.
8.10
WhatAboutInputCoverageInWC?ByreverseengineeringwcweaimforanalternativepythonimplementationWithaclearspecaccordingtoCW1Howcanweachievefunctionalcorrectnessofminiwc?
Byachieving100%inputcoveragetosatisfythespecificationLet'sseesomeexamples...
8.11
EmptyTextFile
8.12
CommonCase:1Line
8.13
CommonCase:2Lines
8.14
VisualisingPotentialErrorsGuardagainstprograminput
Whatkindoffile?Differenttypes,wrongnames...Contentsoffile?
ProvideinputcoverageforeveryoutputdimensionNumberoflines(single,multiple)Numberofcharacters(commoncase,large,small)Numberofwords(howarewordscounted?)Numberofbytes(encoding?)
9.2
CourseworkActivitiesReadingQ1
MostlyrelatedtoreadingMostly"Recall"...withsomeinterpretation
TheywillgohigherontheBloomtaxonomy!SE1
ReadingandanalysingCW1ReverseengineeredaspecificationReengineeredminiwcfromthespec
Programconstruction
9.3
ANoteOnMarksUKmarksrunfrom0-100%
<=49=Failing(<40%seriousfailure)50-59=Pass60-69=Meritover70=DistinctionNOTETHEWIDEBANDATTHETOPANDBOTTOM
A65%isagoodmarkAn85%isexceedinglyrareOver70%isfairlyrare
9.4
Q1Meanof3.57(71%)
Lastyear:3.71(74%)Wewilldosome"inexamconditions"Let'sdelve
9.5
SimplifiedProblemThiswasasmallproblem
WithclearboundariesEvenhere:
WeendedupwithsupportprogramsAndcornerscut
Softwareengineeringis(complex)systemengineeringOnboththeproductandprojectsidesWeuseacomplexinfrastructure!
9.6
ChallengesWhatwerethechallengesyouencountered?
Whatchallengeswereinherenttotheproblem?
Whatchallengeswereenvironmental?
9.7
CW1MarksInBlackboard!Average:4/10(40%)Max:8>70%660%s1450%s5<49%26
Notunusualforfirstassignment!LearningcurveFinalcourseworkaveagetendstobe≈62%
9.8
CW1FeedbackFeedbackisinBlackboardFeedbackisdetailedbutabstract
There seems to be a miniwc.py: 0.5/0.5 points. There seems to be a doctest_miniwc.py and test files: 0.5/0.5 points. Prohibited libraries have been used: 0/1 points. Formatting was correct: 1/1 points.The script passed 35.7% of miniwc simple tests: 2/5 points. The script passed 0.0% of miniwc binary tests: 0/1 points. The script passed 0.0% of miniwc unicode tests: 0/1 points. Penalties: none. Total marks: 4.0/10.0
9.9
NextWe'regoingtodomorewc
Job1istofixyourminiwc.py(nowcalledwc.py)Fixyourtests!Addmoretests!
Unicode!Binary!Job2istoaddnewfunctionality
Flags!MultipleinputfilesJob3istoupdateyourtests
NotethatJob3isn't*temporallylast!Youwilldoacodereviewofminiwc.pyDiscussthefeedback!Thisistheonlytimeyoucantalkwithaclassmateaboutit!
9.10
OtherCourseworkSE2!
YouneedtoreadNoSilverBulletSE1!
TAsareavailabletodiscuss