IndexError: index out of range: 0

Hi All,

I’m getting an IndexError in the RPS console:

Exception: System.IndexOutOfRangeException: index out of range: 0

when trying to get the single material in my list called material. I used the usual syntax mat = material[0] to get this material from the list, but it doesn’t seem to be working!!?

Here my code:

import math
from Autodesk.Revit.DB import *
from System.Collections.Generic import IList, List
uidoc = __revit__.ActiveUIDocument

doc = uidoc.Document

materials = FilteredElementCollector(doc).WherePasses(ElementCategoryFilter(BuiltInCategory.OST_Materials))

material = [i for i in materials if i.Name == "Béton - Coulé sur place - Béton20"]

if len(material) > 0:
    mat = material[0]
    m_Id = mat.Id
else:
    with Transaction(doc, 'Get/create concrete material') as t:
        t.Start()
        m_Id = Material.Create(doc, "Béton - Coulé sur place - Béton20")
        mat = doc.GetElement(m_Id)
        mat.MaterialClass = "Béton"
        mat.MaterialCategory = "Béton"
        mat.Color = Color(192,192,192)
        mat.Shininess = 128
        mat.Smoothness = 50
        asset = StructuralAsset("ConcreteStructuralAsset", StructuralAssetClass.Concrete)
        asset.ConcreteCompression = UnitUtils.ConvertToInternalUnits(20, UnitTypeId.Megapascals)
        asset.Density = UnitUtils.ConvertToInternalUnits(2500, UnitTypeId.KilogramsPerCubicMeter)
        asset.SetPoissonRatio(0.2)
        asset.SetYoungModulus(UnitUtils.ConvertToInternalUnits(11000*20**(1/3), UnitTypeId.Megapascals))
        struc = PropertySetElement.Create(doc, asset)
        mat.SetMaterialAspectByPropertySet(MaterialAspect.Structural, struc.Id)
        appar_Id = ElementId(177984)
        mat.AppearanceAssetId = appar_Id
        t.Commit()

Any Help would be appreciated

Thanks.

To help you debug before your if statement

print(material)
print(len(material))
print(type(material))

What do you want to do?
It seems you want to do this:

IF the material exists: 
check and set the specs.

ELSE 
create a new material with that name and set the specs of the new material?

But if your code should do as you put it:

material will return false if no materials match your i.Name. So please don’t use len to check that.

# why not use pyrevit modules?

# # math not used, don't include it.
# import math
from Autodesk.Revit.DB import *
# from System.Collections.Generic import IList, List
uidoc = __revit__.ActiveUIDocument

doc = uidoc.Document

material_check = "Béton - Coulé sur place - Béton20
materials = FilteredElementCollector(doc).WherePasses(ElementCategoryFilter(BuiltInCategory.OST_Materials))
material = [i for i in materials if i.Name == material_check]

if material:
    mat = material[0]
    m_Id = mat.Id
else:
    with Transaction(doc, 'Get/create concrete material') as t:
        t.Start()
        m_Id = Material.Create(doc, material_check)
        ....
        t.Commit()

This code below works just fine.

from pyrevit import revit, DB

selection = revit.get_selection()

material_check = "material_name_here"
materials = DB.FilteredElementCollector(revit.doc).WherePasses(DB.ElementCategoryFilter(DB.BuiltInCategory.OST_Materials))
materials_matching = [i for i in materials if i.Name == material_check]

#if materials_matching:
#    for material_matching in materials_matching: 
#        print material_matching.Name

if materials_matching:
    print materials_matching[0].Name

        
else:
    print "no material found with the name '{}'".format(material_check)

Thx @jvandermeulen for your replay, I practically used the same approach as you

I finally solved the issue in my main script (which includes a part for getting/creating material). Sorry, @Jean-Marc, I was wrong—the issue was due to the level elevation, which does not return the same value when I switched from the Architecture to the Structure template to test my script. I have now fixed it.

I’m coming from Dynamo, and I’m not yet familiar with the pyrevit modules.

Thanks for All.