codecov[bot]: # [Codecov](https://codecov.io/gh/pgmpy/pgmpy/pull/1235?src=pr&el=h1) Report
> Merging [#1235](https://codecov.io/gh/pgmpy/pgmpy/pull/1235?src=pr&el=desc) into [dev](https://codecov.io/gh/pgmpy/pgmpy/commit/88ad46b1643fb50ffedef366563a60f9f4beafab?src=pr&el=desc) will **increase** coverage by `<.01%`.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/pgmpy/pgmpy/pull/1235/graphs/tree.svg?width=650&token=UaJMCdHaEF&height=150&src=pr)](https://codecov.io/gh/pgmpy/pgmpy/pull/1235?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##              dev    #1235      +/-   ##
==========================================
+ Coverage   92.03%   92.04%   +<.01%     
==========================================
  Files         135      135              
  Lines       13200    13207       +7     
==========================================
+ Hits        12149    12156       +7     
  Misses       1051     1051
```


| [Impacted Files](https://codecov.io/gh/pgmpy/pgmpy/pull/1235?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pgmpy/factors/discrete/DiscreteFactor.py](https://codecov.io/gh/pgmpy/pgmpy/pull/1235/diff?src=pr&el=tree#diff-cGdtcHkvZmFjdG9ycy9kaXNjcmV0ZS9EaXNjcmV0ZUZhY3Rvci5weQ==) | `97.95% <100%> (+0.06%)` | :arrow_up: |
| [...py/tests/test\_factors/test\_discrete/test\_Factor.py](https://codecov.io/gh/pgmpy/pgmpy/pull/1235/diff?src=pr&el=tree#diff-cGdtcHkvdGVzdHMvdGVzdF9mYWN0b3JzL3Rlc3RfZGlzY3JldGUvdGVzdF9GYWN0b3IucHk=) | `99.82% <100%> (ø)` | :arrow_up: |
| [pgmpy/models/BayesianModel.py](https://codecov.io/gh/pgmpy/pgmpy/pull/1235/diff?src=pr&el=tree#diff-cGdtcHkvbW9kZWxzL0JheWVzaWFuTW9kZWwucHk=) | `90.06% <100%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pgmpy/pgmpy/pull/1235?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/pgmpy/pgmpy/pull/1235?src=pr&el=footer). Last update [88ad46b...2b7cbad](https://codecov.io/gh/pgmpy/pgmpy/pull/1235?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

diff --git a/pgmpy/factors/discrete/DiscreteFactor.py b/pgmpy/factors/discrete/DiscreteFactor.py
index 7a8cc62d..dab8fbc3 100644
--- a/pgmpy/factors/discrete/DiscreteFactor.py
+++ b/pgmpy/factors/discrete/DiscreteFactor.py
@@ -2,6 +2,7 @@ from __future__ import division
 
 from itertools import product
 from collections import namedtuple
+from warnings import warn
 
 import numpy as np
 
@@ -415,6 +416,7 @@ class DiscreteFactor(BaseFactor, StateNameMixin):
         >>> phi.values
         array([0., 1.])
         """
+        # Check if values is an array
         if isinstance(values, str):
             raise TypeError("values: Expected type list or array-like, got type str")
 
@@ -423,10 +425,23 @@ class DiscreteFactor(BaseFactor, StateNameMixin):
                 "values: Expected type list of tuples, get type {type}", type(values[0])
             )
 
+        # Check if all variables in values are in the factor
+        for var, _ in values:
+            if var not in self.variables:
+                raise ValueError(f"The variable: {var} is not in the factor")
+
         phi = self if inplace else self.copy()
-        values = [
-            (var, self.get_state_no(var, state_name)) for var, state_name in values
-        ]
+
+        # Convert the state names to state number. If state name not found treat them as
+        # state numbers.
+        try:
+            values = [
+                (var, self.get_state_no(var, state_name)) for var, state_name in values
+            ]
+        except KeyError:
+            warn(
+                "Found unknown state name. Trying to switch to using all state names as state numbers"
+            )
 
         var_index_to_del = []
         slice_ = [slice(None)] * len(self.variables)
diff --git a/pgmpy/models/BayesianModel.py b/pgmpy/models/BayesianModel.py
index 270a7174..6f176823 100644
--- a/pgmpy/models/BayesianModel.py
+++ b/pgmpy/models/BayesianModel.py
@@ -508,10 +508,7 @@ class BayesianModel(DAG):
         <TabularCPD representing P(B:2) at 0x7fb98a7d5588>,
         <TabularCPD representing P(C:2 | A:2, B:2) at 0x7fb98a7b1f98>]
         """
-        from pgmpy.estimators import (
-            MaximumLikelihoodEstimator,
-            BaseEstimator,
-        )
+        from pgmpy.estimators import MaximumLikelihoodEstimator, BaseEstimator
 
         if estimator is None:
             estimator = MaximumLikelihoodEstimator

state_name and state_no in reduce()
### Subject of the issue
The value argument in reduce() function for TabularCPD and DiscreteFactor. It looks like right now the argument should be (var_name, var_state_name), but previously it's (var_name, var_state_no). However, in pre_compute_reduce() of Sampling.py, this for loop
```python
for state_combination in itertools.product(
            *[range(self.cardinality[var]) for var in variable_evid]
        ):
            states = list(zip(variable_evid, state_combination))
            cached_values[state_combination] = variable_cpd.reduce(
                states, inplace=False
            ).values
```
seems to use (var_name, var_state_no) as argument. 

### Your environment
* newest dev branch
* 3.6.8
* Ubuntu 18.04.2 LTS

### Steps to reproduce
I have a BayesianModel that has variable_state_name as str (not the same with variable_state_no). If I call likelihood_weighted_sample() on the model, which will call pre_compute_reduce(), it gives me key error, because reduce() calls self.get_state_no() like self.get_state_no(var_name, 0)
diff --git a/pgmpy/tests/test_factors/test_discrete/test_Factor.py b/pgmpy/tests/test_factors/test_discrete/test_Factor.py
index 1ed1b0e3..2f85510b 100644
--- a/pgmpy/tests/test_factors/test_discrete/test_Factor.py
+++ b/pgmpy/tests/test_factors/test_discrete/test_Factor.py
@@ -447,12 +447,12 @@ class TestFactorMethods(unittest.TestCase):
         self.assertRaises(TypeError, self.phi1.reduce, ["x10"])
 
     def test_reduce_scopeerror(self):
-        self.assertRaises(KeyError, self.phi1.reduce, [("x4", 1)])
-        self.assertRaises(KeyError, self.phi5.reduce, [((("x1", 0.1), 0))])
+        self.assertRaises(ValueError, self.phi1.reduce, [("x4", 1)])
+        self.assertRaises(ValueError, self.phi5.reduce, [((("x1", 0.1), 0))])
 
     def test_reduce_sizeerror(self):
-        self.assertRaises(KeyError, self.phi1.reduce, [("x3", 5)])
-        self.assertRaises(KeyError, self.phi5.reduce, [(("x2", "x3"), 3)])
+        self.assertRaises(IndexError, self.phi1.reduce, [("x3", 5)])
+        self.assertRaises(IndexError, self.phi5.reduce, [(("x2", "x3"), 3)])
 
     def test_identity_factor(self):
         identity_factor = self.phi.identity_factor()

pip install -e .[all]
parse_log_pytest
requirements.txt
pytest pytest-cov
3.6
requirements/runtime.txt requirements/tests.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs==22.2.0
black==22.8.0
certifi==2021.5.30
charset-normalizer==2.0.12
click==8.0.4
codecov==2.1.13
coverage==6.2
dataclasses==0.8
decorator==4.4.2
idna==3.10
importlib-metadata==4.8.3
importlib-resources==5.4.0
iniconfig==1.1.1
joblib==1.1.1
mock==5.2.0
mypy-extensions==1.0.0
networkx==2.5.1
numpy==1.19.5
packaging==21.3
pandas==1.1.5
pathspec==0.9.0
patsy==1.0.1
-e git+https://github.com/pgmpy/pgmpy.git@88ad46b1643fb50ffedef366563a60f9f4beafab#egg=pgmpy
platformdirs==2.4.0
pluggy==1.0.0
py==1.11.0
pyparsing==3.1.4
pytest==7.0.1
pytest-cov==4.0.0
python-dateutil==2.9.0.post0
pytz==2025.2
requests==2.27.1
scipy==1.5.4
six==1.17.0
statsmodels==0.12.2
tomli==1.2.3
torch==1.10.2
tqdm==4.64.1
typed-ast==1.5.5
typing_extensions==4.1.1
urllib3==1.26.20
xdoctest==1.1.6
zipp==3.6.0

name: pgmpy
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - attrs==22.2.0
      - black==22.8.0
      - charset-normalizer==2.0.12
      - click==8.0.4
      - codecov==2.1.13
      - coverage==6.2
      - dataclasses==0.8
      - decorator==4.4.2
      - idna==3.10
      - importlib-metadata==4.8.3
      - importlib-resources==5.4.0
      - iniconfig==1.1.1
      - joblib==1.1.1
      - mock==5.2.0
      - mypy-extensions==1.0.0
      - networkx==2.5.1
      - numpy==1.19.5
      - packaging==21.3
      - pandas==1.1.5
      - pathspec==0.9.0
      - patsy==1.0.1
      - platformdirs==2.4.0
      - pluggy==1.0.0
      - py==1.11.0
      - pyparsing==3.1.4
      - pytest==7.0.1
      - pytest-cov==4.0.0
      - python-dateutil==2.9.0.post0
      - pytz==2025.2
      - requests==2.27.1
      - scipy==1.5.4
      - six==1.17.0
      - statsmodels==0.12.2
      - tomli==1.2.3
      - torch==1.10.2
      - tqdm==4.64.1
      - typed-ast==1.5.5
      - typing-extensions==4.1.1
      - urllib3==1.26.20
      - xdoctest==1.1.6
      - zipp==3.6.0
prefix: /opt/conda/envs/pgmpy

pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_reduce_scopeerror pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_reduce_sizeerror
pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorInit::test_class_init pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorInit::test_class_init_int_var pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorInit::test_class_init_nonlist_statename pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorInit::test_class_init_repeated_statename pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorInit::test_class_init_sizeerror pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorInit::test_class_init_statenames pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorInit::test_class_init_typeerror pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorInit::test_init_size_var_card_not_equal pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_assignment pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_assignment_indexerror pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_complete_reduce pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_eq pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_eq1 pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_factor_divide pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_factor_divide_invalid pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_factor_divide_no_common_scope pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_factor_divide_non_factor_arg pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_factor_divide_truediv pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_factor_mul pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_factor_product pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_factor_product_non_factor_arg pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_get_cardinality pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_get_cardinality_scopeerror pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_get_cardinality_typeerror pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_hash pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_identity_factor pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_marginalize pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_marginalize_scopeerror pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_marginalize_shape pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_marginalize_typeerror pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_maximize_list pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_maximize_scopeerror pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_maximize_shape pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_maximize_single pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_maximize_typeerror pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_normalize pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_product pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_reduce pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_reduce1 pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_reduce_shape pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_reduce_typeerror pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestFactorMethods::test_scope pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestTabularCPDInit::test_cpd_init pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestTabularCPDInit::test_cpd_init_cardinality_not_specified pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestTabularCPDInit::test_cpd_init_event_card_not_int pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestTabularCPDInit::test_cpd_init_value_not_2d pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestTabularCPDMethods::test__repr__ pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestTabularCPDMethods::test_copy pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestTabularCPDMethods::test_copy_original_safe pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestTabularCPDMethods::test_copy_state_names pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestTabularCPDMethods::test_get_values pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestTabularCPDMethods::test_marginalize_1 pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestTabularCPDMethods::test_marginalize_2 pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestTabularCPDMethods::test_marginalize_3 pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestTabularCPDMethods::test_normalize pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestTabularCPDMethods::test_normalize_not_in_place pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestTabularCPDMethods::test_normalize_original_safe pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestTabularCPDMethods::test_reduce_1 pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestTabularCPDMethods::test_reduce_2 pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestTabularCPDMethods::test_reduce_3 pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestTabularCPDMethods::test_reduce_4 pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestTabularCPDMethods::test_reduce_5 pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestTabularCPDMethods::test_reorder_parents pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestTabularCPDMethods::test_reorder_parents_inplace pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestTabularCPDMethods::test_reorder_parents_no_effect pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestTabularCPDMethods::test_reorder_parents_warning pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestJointProbabilityDistributionInit::test_jpd_init pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestJointProbabilityDistributionInit::test_jpd_init_exception pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestJointProbabilityDistributionMethods::test_check_independence pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestJointProbabilityDistributionMethods::test_conditional_distribution_list pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestJointProbabilityDistributionMethods::test_get_independencies pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestJointProbabilityDistributionMethods::test_is_imap pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestJointProbabilityDistributionMethods::test_jpd_marginal_distribution_list pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestJointProbabilityDistributionMethods::test_marginal_distribution_str pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestJointProbabilityDistributionMethods::test_minimal_imap pgmpy/tests/test_factors/test_discrete/test_Factor.py::TestJointProbabilityDistributionMethods::test_repr
pgmpy/models/BayesianModel.py pgmpy/factors/discrete/DiscreteFactor.py
pgmpy/models/BayesianModel.py pgmpy/factors/discrete/DiscreteFactor.py